HEX
Server: Microsoft-IIS/8.5
System: Windows NT YDAWBH120 6.3 build 9600 (Windows Server 2012 R2 Standard Edition) AMD64
User: tentjecom_web (0)
PHP: 7.4.14
Disabled: NONE
Upload Files
File: D:/HostingSpaces/SBogers10/hours.komma.pro/wwwroot/js/app.js.map
{"version":3,"sources":["jquery.form-validator.js"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"app.js","sourcesContent":["(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n/** File generated by Grunt -- do not modify\n *  JQUERY-FORM-VALIDATOR\n *\n *  @version 2.3.77\n *  @website http://formvalidator.net/\n *  @author Victor Jonsson, http://victorjonsson.se\n *  @license MIT\n */\n/**\n */\n(function ($, window, undefined) {\n\n  var disableFormSubmit = function () {\n      return false;\n    },\n    lastFormEvent = null,\n    HaltManager = {\n      numHalted: 0,\n      haltValidation: function($form) {\n        this.numHalted++;\n        $.formUtils.haltValidation = true;\n        $form\n          .unbind('submit', disableFormSubmit)\n          .bind('submit', disableFormSubmit)\n          .find('*[type=\"submit\"]')\n            .addClass('disabled')\n            .attr('disabled', 'disabled');\n      },\n      unHaltValidation: function($form) {\n        this.numHalted--;\n        if (this.numHalted === 0) {\n          $.formUtils.haltValidation = false;\n          $form\n            .unbind('submit', disableFormSubmit)\n            .find('*[type=\"submit\"]')\n              .removeClass('disabled')\n              .removeAttr('disabled', 'disabled');\n        }\n      }\n    };\n\n  function AsyncValidation($form, $input) {\n    this.$form = $form;\n    this.$input = $input;\n    this.reset();\n    $input.on('change paste', this.reset.bind(this));\n  }\n\n  AsyncValidation.prototype.reset = function() {\n    this.haltedFormValidation = false;\n    this.hasRun = false;\n    this.isRunning = false;\n    this.result = undefined;\n  };\n\n  AsyncValidation.prototype.run = function(eventContext, callback) {\n    if (eventContext === 'keyup') {\n      return null;\n    } else if (this.isRunning) {\n      lastFormEvent = eventContext;\n      if (!this.haltedFormValidation) {\n        HaltManager.haltValidation();\n        this.haltedFormValidation = true;\n      }\n      return null; // Waiting for result\n    } else if(this.hasRun) {\n      //this.$input.one('keyup change paste', this.reset.bind(this));\n      return this.result;\n    } else {\n      lastFormEvent = eventContext;\n      HaltManager.haltValidation(this.$form);\n      this.haltedFormValidation = true;\n      this.isRunning = true;\n      this.$input\n        .attr('disabled', 'disabled')\n        .addClass('async-validation');\n      this.$form.addClass('async-validation');\n\n      callback(function(result) {\n        this.done(result);\n      }.bind(this));\n\n      return null;\n    }\n  };\n\n  AsyncValidation.prototype.done = function(result) {\n    this.result = result;\n    this.hasRun = true;\n    this.isRunning = false;\n    this.$input\n      .removeAttr('disabled')\n      .removeClass('async-validation');\n    this.$form.removeClass('async-validation');\n    if (this.haltedFormValidation) {\n      HaltManager.unHaltValidation(this.$form);\n      if (lastFormEvent === 'submit') {\n        this.$form.trigger('submit');\n      } else {\n        this.$input.trigger('validation.revalidate');\n      }\n    }\n  };\n\n  AsyncValidation.loadInstance = function(validatorName, $input, $form) {\n    // Return async validator attached to this input element\n    // or create a new async validator and attach it to the input\n    var asyncValidation,\n      input = $input.get(0);\n\n    if (!input.asyncValidators) {\n      input.asyncValidators = {};\n    }\n\n    if (input.asyncValidators[validatorName]) {\n      asyncValidation = input.asyncValidators[validatorName];\n    } else {\n      asyncValidation = new AsyncValidation($form, $input);\n      input.asyncValidators[validatorName] = asyncValidation;\n    }\n\n    return asyncValidation;\n  };\n\n  $.formUtils = $.extend($.formUtils || {}, {\n\n    /**\n     * @deprecated\n     * @param validatorName\n     * @param $input\n     * @param $form\n     */\n    asyncValidation: function(validatorName, $input, $form) {\n      // @todo: Remove when moving up to version 3.0\n      this.warn('Use of deprecated function $.formUtils.asyncValidation, use $.formUtils.addAsyncValidator() instead');\n      return AsyncValidation.loadInstance(validatorName, $input, $form);\n    },\n\n    /**\n     * @param {Object} asyncValidator\n     */\n    addAsyncValidator: function (asyncValidator) {\n      var validator = $.extend({}, asyncValidator),\n        originalValidatorFunc = validator.validatorFunction;\n      validator.async = true;\n      validator.validatorFunction = function (value, $el, config, language, $form, eventContext) {\n        var asyncValidation = AsyncValidation.loadInstance(this.name, $el, $form);\n        return asyncValidation.run(eventContext, function(done) {\n          originalValidatorFunc.apply(validator, [\n            done, value, $el, config, language, $form, eventContext\n          ]);\n        });\n      };\n      this.addValidator(validator);\n    }\n  });\n\n  // Tag elements having async validators\n  $(window).bind('validatorsLoaded formValidationSetup', function (evt, $form) {\n    if (!$form) {\n      $form = $('form');\n    }\n    $form.find('[data-validation]').each(function () {\n      var $input = $(this);\n      $input.valAttr('async', false);\n      $.each($.split($input.attr('data-validation')), function (i, validatorName) {\n        var validator = $.formUtils.validators['validate_'+validatorName];\n        if (validator && validator.async) {\n          $input.valAttr('async', 'yes');\n        }\n      });\n    });\n  });\n\n})(jQuery, window);\n\n/**\n * Deprecated functions and attributes\n * @todo: Remove in release of 3.0\n */\n(function ($, undefined) {\n\n  'use strict';\n\n  /**\n   * @deprecated\n   * @param language\n   * @param conf\n   */\n  $.fn.validateForm = function (language, conf) {\n    $.formUtils.warn('Use of deprecated function $.validateForm, use $.isValid instead');\n    return this.isValid(language, conf, true);\n  };\n\n  $(window)\n    .on('formValidationPluginInit', function(evt, config) {\n      convertDeprecatedLangCodeToISO6391(config);\n      addSupportForCustomErrorMessageCallback(config);\n      addSupportForElementReferenceInPositionParam(config);\n    })\n    .on('validatorsLoaded formValidationSetup', function(evt, $form) {\n      if( !$form ) {\n        $form = $('form');\n      }\n      addSupportForValidationDependingOnCheckedInput($form);\n    });\n\n\n  function addSupportForCustomErrorMessageCallback(config) {\n    if (config &&\n        config.errorMessagePosition === 'custom' &&\n        typeof config.errorMessageCustom === 'function') {\n\n      $.formUtils.warn('Use of deprecated function errorMessageCustom, use config.submitErrorMessageCallback instead');\n\n      config.submitErrorMessageCallback = function($form, errorMessages) {\n        config.errorMessageCustom(\n            $form,\n            config.language.errorTitle,\n            errorMessages,\n            config\n        );\n      };\n    }\n  }\n\n  function addSupportForElementReferenceInPositionParam(config) {\n    if (config.errorMessagePosition && typeof config.errorMessagePosition === 'object') {\n      $.formUtils.warn('Deprecated use of config parameter errorMessagePosition, use config.submitErrorMessageCallback instead');\n      var $errorMessageContainer = config.errorMessagePosition;\n      config.errorMessagePosition = 'top';\n      config.submitErrorMessageCallback = function() {\n        return $errorMessageContainer;\n      };\n    }\n  }\n\n  function addSupportForValidationDependingOnCheckedInput($form) {\n    var $inputsDependingOnCheckedInputs = $form.find('[data-validation-if-checked]');\n    if ($inputsDependingOnCheckedInputs.length) {\n      $.formUtils.warn(\n        'Detected use of attribute \"data-validation-if-checked\" which is '+\n        'deprecated. Use \"data-validation-depends-on\" provided by module \"logic\"'\n      );\n    }\n\n    $inputsDependingOnCheckedInputs\n      .on('beforeValidation', function() {\n\n        var $elem = $(this),\n          nameOfDependingInput = $elem.valAttr('if-checked');\n\n        // Set the boolean telling us that the validation depends\n        // on another input being checked\n        var $dependingInput = $('input[name=\"' + nameOfDependingInput + '\"]', $form),\n          dependingInputIsChecked = $dependingInput.is(':checked'),\n          valueOfDependingInput = ($.formUtils.getValue($dependingInput) || '').toString(),\n          requiredValueOfDependingInput = $elem.valAttr('if-checked-value');\n\n        if (!dependingInputIsChecked || !(\n              !requiredValueOfDependingInput ||\n              requiredValueOfDependingInput === valueOfDependingInput\n          )) {\n          $elem.valAttr('skipped', true);\n        }\n\n      });\n    }\n\n    function convertDeprecatedLangCodeToISO6391(config) {\n      var deprecatedLangCodes = {\n        se: 'sv',\n        cz: 'cs',\n        dk: 'da'\n      };\n\n      if (config.lang in deprecatedLangCodes) {\n        var newLangCode = deprecatedLangCodes[config.lang];\n        $.formUtils.warn(\n          'Deprecated use of lang code \"'+config.lang+'\" use \"'+newLangCode+'\" instead'\n        );\n        config.lang = newLangCode;\n      }\n    }\n\n})(jQuery);\n\n/**\n * Utility methods used for displaying error messages (attached to $.formUtils)\n */\n(function ($) {\n\n  'use strict';\n\n  var dialogs = {\n\n    resolveErrorMessage: function($elem, validator, validatorName, conf, language) {\n      var errorMsgAttr = conf.validationErrorMsgAttribute + '-' + validatorName.replace('validate_', ''),\n        validationErrorMsg = $elem.attr(errorMsgAttr);\n\n      if (!validationErrorMsg) {\n        validationErrorMsg = $elem.attr(conf.validationErrorMsgAttribute);\n        if (!validationErrorMsg) {\n          if (typeof validator.errorMessageKey !== 'function') {\n            validationErrorMsg = language[validator.errorMessageKey];\n          }\n          else {\n            validationErrorMsg = language[validator.errorMessageKey(conf)];\n          }\n          if (!validationErrorMsg) {\n            validationErrorMsg = validator.errorMessage;\n          }\n        }\n      }\n      return validationErrorMsg;\n    },\n    getParentContainer: function ($elem) {\n      if ($elem.valAttr('error-msg-container')) {\n        return $($elem.valAttr('error-msg-container'));\n      } else {\n        var $parent = $elem.parent();\n        if($elem.attr('type') === 'checkbox' && $elem.closest('.checkbox').length) {\n          $parent = $elem.closest('.checkbox').parent();\n        } else if($elem.attr('type') === 'radio' && $elem.closest('.radio').length) {\n          $parent = $elem.closest('.radio').parent();\n        }\n        if($parent.closest('.input-group').length) {\n          $parent = $parent.closest('.input-group').parent();\n        }\n        return $parent;\n      }\n    },\n    applyInputErrorStyling: function ($input, conf) {\n      $input\n        .addClass(conf.errorElementClass)\n        .removeClass(conf.successElementClass);\n\n      this.getParentContainer($input)\n        .addClass(conf.inputParentClassOnError)\n        .removeClass(conf.inputParentClassOnSuccess);\n\n      if (conf.borderColorOnError !== '') {\n        $input.css('border-color', conf.borderColorOnError);\n      }\n    },\n    applyInputSuccessStyling: function($input, conf) {\n      $input.addClass(conf.successElementClass);\n      this.getParentContainer($input)\n        .addClass(conf.inputParentClassOnSuccess);\n    },\n    removeInputStylingAndMessage: function($input, conf) {\n\n      // Reset input css\n      $input\n        .removeClass(conf.successElementClass)\n        .removeClass(conf.errorElementClass)\n        .css('border-color', '');\n\n      var $parentContainer = dialogs.getParentContainer($input);\n\n      // Reset parent css\n      $parentContainer\n        .removeClass(conf.inputParentClassOnError)\n        .removeClass(conf.inputParentClassOnSuccess);\n\n      // Remove possible error message\n      if (typeof conf.inlineErrorMessageCallback === 'function') {\n        var $errorMessage = conf.inlineErrorMessageCallback($input, false, conf);\n        if ($errorMessage) {\n          $errorMessage.html('');\n        }\n      } else {\n        $parentContainer\n          .find('.' + conf.errorMessageClass)\n          .remove();\n      }\n\n    },\n    removeAllMessagesAndStyling: function($form, conf) {\n\n      // Remove error messages in top of form\n      if (typeof conf.submitErrorMessageCallback === 'function') {\n        var $errorMessagesInTopOfForm = conf.submitErrorMessageCallback($form, false, conf);\n        if ($errorMessagesInTopOfForm) {\n          $errorMessagesInTopOfForm.html('');\n        }\n      } else {\n        $form.find('.' + conf.errorMessageClass + '.alert').remove();\n      }\n\n      // Remove input css/messages\n      $form.find('.' + conf.errorElementClass + ',.' + conf.successElementClass).each(function() {\n        dialogs.removeInputStylingAndMessage($(this), conf);\n      });\n    },\n    setInlineMessage: function ($input, errorMsg, conf) {\n\n      this.applyInputErrorStyling($input, conf);\n\n      var custom = document.getElementById($input.attr('name') + '_err_msg'),\n        $messageContainer = false,\n        setErrorMessage = function ($elem) {\n          $.formUtils.$win.trigger('validationErrorDisplay', [$input, $elem]);\n          $elem.html(errorMsg);\n        },\n        addErrorToMessageContainer = function() {\n          var $found = false;\n          $messageContainer.find('.' + conf.errorMessageClass).each(function () {\n            if (this.inputReferer === $input[0]) {\n              $found = $(this);\n              return false;\n            }\n          });\n          if ($found) {\n            if (!errorMsg) {\n              $found.remove();\n            } else {\n              setErrorMessage($found);\n            }\n          } else if(errorMsg !== '') {\n            $message = $('<div class=\"' + conf.errorMessageClass + ' alert\"></div>');\n            setErrorMessage($message);\n            $message[0].inputReferer = $input[0];\n            $messageContainer.prepend($message);\n          }\n        },\n        $message;\n\n      if (custom) {\n        // Todo: remove in 3.0\n        $.formUtils.warn('Using deprecated element reference ' + custom.id);\n        $messageContainer = $(custom);\n        addErrorToMessageContainer();\n      } else if (typeof conf.inlineErrorMessageCallback === 'function') {\n        $messageContainer = conf.inlineErrorMessageCallback($input, errorMsg, conf);\n        if (!$messageContainer) {\n          // Error display taken care of by inlineErrorMessageCallback\n          return;\n        }\n        addErrorToMessageContainer();\n      } else {\n        var $parent = this.getParentContainer($input);\n        $message = $parent.find('.' + conf.errorMessageClass + '.help-block');\n        if ($message.length === 0) {\n          $message = $('<span></span>').addClass('help-block').addClass(conf.errorMessageClass);\n          $message.appendTo($parent);\n        }\n        setErrorMessage($message);\n      }\n    },\n    setMessageInTopOfForm: function ($form, errorMessages, conf, lang) {\n      var view = '<div class=\"{errorMessageClass} alert alert-danger\">'+\n                    '<strong>{errorTitle}</strong>'+\n                    '<ul>{fields}</ul>'+\n                '</div>',\n          $container = false;\n\n      if (typeof conf.submitErrorMessageCallback === 'function') {\n        $container = conf.submitErrorMessageCallback($form, errorMessages, conf);\n        if (!$container) {\n          // message display taken care of by callback\n          return;\n        }\n      }\n\n      var viewParams = {\n            errorTitle: lang.errorTitle,\n            fields: '',\n            errorMessageClass: conf.errorMessageClass\n          };\n\n      $.each(errorMessages, function (i, msg) {\n        viewParams.fields += '<li>'+msg+'</li>';\n      });\n\n      $.each(viewParams, function(param, value) {\n        view = view.replace('{'+param+'}', value);\n      });\n\n      if ($container) {\n        $container.html(view);\n      } else {\n        $form.children().eq(0).before($(view));\n      }\n    }\n  };\n\n  $.formUtils = $.extend($.formUtils || {}, {\n    dialogs: dialogs\n  });\n\n})(jQuery);\n\n/**\n * File declaring all methods if this plugin which is applied to $.fn.\n */\n(function($, window, undefined) {\n\n  'use strict';\n\n  var _helpers = 0;\n\n\n  /**\n   * Assigns validateInputOnBlur function to elements blur event\n   *\n   * @param {Object} language Optional, will override $.formUtils.LANG\n   * @param {Object} conf Optional, will override the default settings\n   * @return {jQuery}\n   */\n  $.fn.validateOnBlur = function (language, conf) {\n    var $form = this,\n        $elems = this.find('*[data-validation]');\n\n    $elems.each(function(){\n      var $this = $(this);\n      if ($this.is('[type=radio]')){\n        var $additionals = $form.find('[type=radio][name=\"' + $this.attr('name') + '\"]');\n        $additionals.bind('blur.validation', function(){\n          $this.validateInputOnBlur(language, conf, true, 'blur');\n        });\n        if (conf.validateCheckboxRadioOnClick) {\n          $additionals.bind('click.validation', function () {\n            $this.validateInputOnBlur(language, conf, true, 'click');\n          });\n        }\n      }\n    });\n\n    $elems.bind('blur.validation', function () {\n      $(this).validateInputOnBlur(language, conf, true, 'blur');\n    });\n\n    if (conf.validateCheckboxRadioOnClick) {\n      // bind click event to validate on click for radio & checkboxes for nice UX\n      this.find('input[type=checkbox][data-validation],input[type=radio][data-validation]')\n        .bind('click.validation', function () {\n          $(this).validateInputOnBlur(language, conf, true, 'click');\n        });\n    }\n\n    return this;\n  };\n\n  /*\n   * Assigns validateInputOnBlur function to elements custom event\n   * @param {Object} language Optional, will override $.formUtils.LANG\n   * @param {Object} settings Optional, will override the default settings\n   * * @return {jQuery}\n   */\n  $.fn.validateOnEvent = function (language, config) {\n    var $elements = this[0].nodeName === 'FORM' ? this.find('*[data-validation-event]') : this;\n    $elements\n      .each(function () {\n        var $el = $(this),\n          etype = $el.valAttr('event');\n        if (etype) {\n          $el\n            .unbind(etype + '.validation')\n            .bind(etype + '.validation', function (evt) {\n              if( (evt || {}).keyCode !== 9 ) {\n                $(this).validateInputOnBlur(language, config, true, etype);\n              }\n            });\n        }\n      });\n    return this;\n  };\n\n  /**\n   * fade in help message when input gains focus\n   * fade out when input loses focus\n   * <input data-help=\"The info that I want to display for the user when input is focused\" ... />\n   *\n   * @param {String} attrName - Optional, default is data-help\n   * @return {jQuery}\n   */\n  $.fn.showHelpOnFocus = function (attrName) {\n    if (!attrName) {\n      attrName = 'data-validation-help';\n    }\n\n    // Add help text listeners\n    this.find('textarea,input').each(function () {\n      var $elem = $(this),\n        className = 'jquery_form_help_' + (++_helpers),\n        help = $elem.attr(attrName);\n\n      // Reset\n      $elem\n        .removeClass('has-help-text')\n        .unbind('focus.help')\n        .unbind('blur.help');\n\n      if (help) {\n        $elem\n          .addClass('has-help-txt')\n          .bind('focus.help', function () {\n            var $help = $elem.parent().find('.' + className);\n            if ($help.length === 0) {\n              $help = $('<span />')\n                .addClass(className)\n                .addClass('help')\n                .addClass('help-block') // twitter bs\n                .text(help)\n                .hide();\n\n              $elem.after($help);\n            }\n            $help.fadeIn();\n          })\n          .bind('blur.help', function () {\n            $(this)\n              .parent()\n              .find('.' + className)\n              .fadeOut('slow');\n          });\n      }\n    });\n\n    return this;\n  };\n\n  /**\n   * @param {Function} cb\n   * @param {Object} [conf]\n   * @param {Object} [lang]\n   */\n  $.fn.validate = function(cb, conf, lang) {\n    var language = $.extend({}, $.formUtils.LANG, lang || {});\n    this.each(function() {\n      var $elem = $(this),\n        closestFormElem = $elem.closest('form').get(0) || {},\n        formDefaultConfig = closestFormElem.validationConfig || $.formUtils.defaultConfig();\n\n      $elem.one('validation', function(evt, isValid) {\n        if ( typeof cb === 'function' ) {\n          cb(isValid, this, evt);\n        }\n      });\n\n      $elem.validateInputOnBlur(\n        language,\n        $.extend({}, formDefaultConfig, conf || {}),\n        true\n      );\n    });\n  };\n\n  /**\n   * Tells whether or not validation of this input will have to postpone the form submit ()\n   * @returns {Boolean}\n   */\n  $.fn.willPostponeValidation = function() {\n    return (this.valAttr('suggestion-nr') ||\n      this.valAttr('postpone') ||\n      this.hasClass('hasDatepicker')) &&\n      !window.postponedValidation;\n  };\n\n  /**\n   * Validate single input when it loses focus\n   * shows error message in a span element\n   * that is appended to the parent element\n   *\n   * @param {Object} [language] Optional, will override $.formUtils.LANG\n   * @param {Object} [conf] Optional, will override the default settings\n   * @param {Boolean} attachKeyupEvent Optional\n   * @param {String} eventContext\n   * @return {jQuery}\n   */\n  $.fn.validateInputOnBlur = function (language, conf, attachKeyupEvent, eventContext) {\n\n    $.formUtils.eventType = eventContext;\n\n    if ( this.willPostponeValidation() ) {\n      // This validation has to be postponed\n      var _self = this,\n        postponeTime = this.valAttr('postpone') || 200;\n\n      window.postponedValidation = function () {\n        _self.validateInputOnBlur(language, conf, attachKeyupEvent, eventContext);\n        window.postponedValidation = false;\n      };\n\n      setTimeout(function () {\n        if (window.postponedValidation) {\n          window.postponedValidation();\n        }\n      }, postponeTime);\n\n      return this;\n    }\n\n    language = $.extend({}, $.formUtils.LANG, language || {});\n    $.formUtils.dialogs.removeInputStylingAndMessage(this, conf);\n\n    var $elem = this,\n      $form = $elem.closest('form'),\n      result = $.formUtils.validateInput(\n        $elem,\n        language,\n        conf,\n        $form,\n        eventContext\n      );\n\n    var reValidate = function() {\n      $elem.validateInputOnBlur(language, conf, false, 'blur.revalidated');\n    };\n\n    if (eventContext === 'blur') {\n      $elem\n        .unbind('validation.revalidate', reValidate)\n        .one('validation.revalidate', reValidate);\n    }\n\n    if (attachKeyupEvent) {\n      $elem.removeKeyUpValidation();\n    }\n\n    if (result.shouldChangeDisplay) {\n      if (result.isValid) {\n        $.formUtils.dialogs.applyInputSuccessStyling($elem, conf);\n      } else {\n        $.formUtils.dialogs.setInlineMessage($elem, result.errorMsg, conf);\n      }\n    }\n\n    if (!result.isValid && attachKeyupEvent) {\n      $elem.validateOnKeyUp(language, conf);\n    }\n\n    return this;\n  };\n\n  /**\n   * Validate element on keyup-event\n   */\n  $.fn.validateOnKeyUp = function(language, conf) {\n    this.each(function() {\n      var $input = $(this);\n      if (!$input.valAttr('has-keyup-event')) {\n        $input\n          .valAttr('has-keyup-event', 'true')\n          .bind('keyup.validation', function (evt) {\n            if( evt.keyCode !== 9 ) {\n              $input.validateInputOnBlur(language, conf, false, 'keyup');\n            }\n          });\n      }\n    });\n    return this;\n  };\n\n  /**\n   * Remove validation on keyup\n   */\n  $.fn.removeKeyUpValidation = function() {\n    this.each(function() {\n      $(this)\n        .valAttr('has-keyup-event', false)\n        .unbind('keyup.validation');\n    });\n    return this;\n  };\n\n  /**\n   * Short hand for fetching/adding/removing element attributes\n   * prefixed with 'data-validation-'\n   *\n   * @param {String} name\n   * @param {String|Boolean} [val]\n   * @return {String|undefined|jQuery}\n   * @protected\n   */\n  $.fn.valAttr = function (name, val) {\n    if (val === undefined) {\n      return this.attr('data-validation-' + name);\n    } else if (val === false || val === null) {\n      return this.removeAttr('data-validation-' + name);\n    } else {\n      name = ((name.length > 0) ? '-' + name : '');\n      return this.attr('data-validation' + name, val);\n    }\n  };\n\n  /**\n   * Function that validates all inputs in active form\n   *\n   * @param {Object} [language]\n   * @param {Object} [conf]\n   * @param {Boolean} [displayError] Defaults to true\n   */\n  $.fn.isValid = function (language, conf, displayError) {\n\n    if ($.formUtils.isLoadingModules) {\n      var $self = this;\n      setTimeout(function () {\n        $self.isValid(language, conf, displayError);\n      }, 200);\n      return null;\n    }\n\n    conf = $.extend({}, $.formUtils.defaultConfig(), conf || {});\n    language = $.extend({}, $.formUtils.LANG, language || {});\n    displayError = displayError !== false;\n\n    if ($.formUtils.errorDisplayPreventedWhenHalted) {\n      // isValid() was called programmatically with argument displayError set\n      // to false when the validation was halted by any of the validators\n      delete $.formUtils.errorDisplayPreventedWhenHalted;\n      displayError = false;\n    }\n\n    /**\n     * Adds message to error message stack if not already in the message stack\n     *\n     * @param {String} mess\n     * @para {jQuery} $elem\n     */\n    var addErrorMessage = function (mess, $elem) {\n        if ($.inArray(mess, errorMessages) < 0) {\n          errorMessages.push(mess);\n        }\n        errorInputs.push($elem);\n        $elem.valAttr('current-error', mess);\n        if (displayError) {\n          $.formUtils.dialogs.applyInputErrorStyling($elem, conf);\n        }\n      },\n\n      /** Holds inputs (of type checkox or radio) already validated, to prevent recheck of mulitple checkboxes & radios */\n      checkedInputs = [],\n\n      /** Error messages for this validation */\n      errorMessages = [],\n\n      /** Input elements which value was not valid */\n      errorInputs = [],\n\n      /** Form instance */\n      $form = this,\n\n      /**\n       * Tells whether or not to validate element with this name and of this type\n       *\n       * @param {String} name\n       * @param {String} type\n       * @return {Boolean}\n       */\n      ignoreInput = function (name, type) {\n        if (type === 'submit' || type === 'button' || type === 'reset') {\n          return true;\n        }\n        return $.inArray(name, conf.ignore || []) > -1;\n      };\n\n    // Reset style and remove error class\n    if (displayError) {\n      $.formUtils.dialogs.removeAllMessagesAndStyling($form, conf);\n    }\n\n    // Validate element values\n    $form.find('input,textarea,select').filter(':not([type=\"submit\"],[type=\"button\"])').each(function () {\n      var $elem = $(this),\n        elementType = $elem.attr('type'),\n        isCheckboxOrRadioBtn = elementType === 'radio' || elementType === 'checkbox',\n        elementName = $elem.attr('name');\n\n      if (!ignoreInput(elementName, elementType) && (!isCheckboxOrRadioBtn || $.inArray(elementName, checkedInputs) < 0)) {\n\n        if (isCheckboxOrRadioBtn) {\n          checkedInputs.push(elementName);\n        }\n\n        var result = $.formUtils.validateInput(\n          $elem,\n          language,\n          conf,\n          $form,\n          'submit'\n        );\n\n        if (!result.isValid) {\n          addErrorMessage(result.errorMsg, $elem);\n        } else if (result.isValid && result.shouldChangeDisplay) {\n          $elem.valAttr('current-error', false);\n          $.formUtils.dialogs.applyInputSuccessStyling($elem, conf);\n        }\n      }\n\n    });\n\n    // Run validation callback\n    if (typeof conf.onValidate === 'function') {\n      var errors = conf.onValidate($form);\n      if ($.isArray(errors)) {\n        $.each(errors, function (i, err) {\n          addErrorMessage(err.message, err.element);\n        });\n      }\n      else if (errors && errors.element && errors.message) {\n        addErrorMessage(errors.message, errors.element);\n      }\n    }\n\n    // Reset form validation flag\n    $.formUtils.isValidatingEntireForm = false;\n\n    // Validation failed\n    if (errorInputs.length > 0) {\n      if (displayError) {\n        if (conf.errorMessagePosition === 'top') {\n          $.formUtils.dialogs.setMessageInTopOfForm($form, errorMessages, conf, language);\n        } else {\n          $.each(errorInputs, function (i, $input) {\n            $.formUtils.dialogs.setInlineMessage($input, $input.valAttr('current-error'), conf);\n          });\n        }\n        if (conf.scrollToTopOnError) {\n          $.formUtils.$win.scrollTop($form.offset().top - 20);\n        }\n      }\n    }\n\n    if (!displayError && $.formUtils.haltValidation) {\n      $.formUtils.errorDisplayPreventedWhenHalted = true;\n    }\n\n    return errorInputs.length === 0 && !$.formUtils.haltValidation;\n  };\n\n  /**\n   * Plugin for displaying input length restriction\n   */\n  $.fn.restrictLength = function (maxLengthElement) {\n    new $.formUtils.lengthRestriction(this, maxLengthElement);\n    return this;\n  };\n\n  /**\n   * Add suggestion dropdown to inputs having data-suggestions with a comma\n   * separated string with suggestions\n   * @param {Array} [settings]\n   * @returns {jQuery}\n   */\n  $.fn.addSuggestions = function (settings) {\n    var sugs = false;\n    this.find('input').each(function () {\n      var $field = $(this);\n\n      sugs = $.split($field.attr('data-suggestions'));\n\n      if (sugs.length > 0 && !$field.hasClass('has-suggestions')) {\n        $.formUtils.suggest($field, sugs, settings);\n        $field.addClass('has-suggestions');\n      }\n    });\n    return this;\n  };\n\n\n})(jQuery, window);\n\n/**\n * Utility methods used for handling loading of modules (attached to $.formUtils)\n */\n(function($) {\n\n  'use strict';\n\n  $.formUtils = $.extend($.formUtils || {}, {\n\n    /**\n     * @var {Boolean}\n     */\n    isLoadingModules: false,\n\n    /**\n     * @var {Object}\n     */\n    loadedModules: {},\n\n    /**\n     * @param {String} name\n     */\n    registerLoadedModule: function (name) {\n      this.loadedModules[$.trim(name).toLowerCase()] = true;\n    },\n\n    /**\n     * @param {String} name\n     * @return {Boolean}\n     */\n    hasLoadedModule: function (name) {\n      return $.trim(name).toLowerCase() in this.loadedModules;\n    },\n\n    /**\n     * @example\n     *  $.formUtils.loadModules('date, security.dev');\n     *\n     * Will load the scripts date.js and security.dev.js from the\n     * directory where this script resides. If you want to load\n     * the modules from another directory you can use the\n     * path argument.\n     *\n     * The script will be cached by the browser unless the module\n     * name ends with .dev\n     *\n     * @param {String} modules - Comma separated string with module file names (no directory nor file extension)\n     * @param {String} [path] - Path where the module files are located if their not in the same directory as the core modules\n     * @param {function} [callback] - Callback invoked when all modules are loaded\n     */\n    loadModules: function (modules, path, callback) {\n\n      if ($.formUtils.isLoadingModules) {\n        setTimeout(function () {\n          $.formUtils.loadModules(modules, path, callback);\n        }, 100);\n        return;\n      }\n\n      var loadModuleScripts = function (modules, path) {\n\n          var moduleList = $.split(modules),\n            numModules = moduleList.length,\n            moduleLoadedCallback = function () {\n              numModules--;\n              if (numModules === 0) {\n                $.formUtils.isLoadingModules = false;\n                if (typeof callback === 'function') {\n                    callback();\n                }\n              }\n            };\n\n          if (numModules > 0) {\n            $.formUtils.isLoadingModules = true;\n          }\n\n          var cacheSuffix = '?_=' + ( new Date().getTime() ),\n            appendToElement = document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0];\n\n          $.each(moduleList, function (i, modName) {\n            modName = $.trim(modName);\n            if (modName.length === 0 || $.formUtils.hasLoadedModule(modName)) {\n              moduleLoadedCallback();\n            } else {\n              var scriptUrl = path + modName + (modName.slice(-3) === '.js' ? '' : '.js'),\n                script = document.createElement('SCRIPT');\n\n              if (typeof define === 'function' && define.amd) {\n                require([scriptUrl + ( scriptUrl.slice(-7) === '.dev.js' ? cacheSuffix : '' )], moduleLoadedCallback);\n              } else {\n                // Load the script\n                script.type = 'text/javascript';\n                script.onload = moduleLoadedCallback;\n                script.src = scriptUrl + ( scriptUrl.slice(-7) === '.dev.js' ? cacheSuffix : '' );\n                script.onerror = function() {\n                  $.formUtils.warn('Unable to load form validation module '+scriptUrl, true);\n                  moduleLoadedCallback();\n                };\n                script.onreadystatechange = function () {\n                  // IE 7 fix\n                  if (this.readyState === 'complete' || this.readyState === 'loaded') {\n                    moduleLoadedCallback();\n                    // Handle memory leak in IE\n                    this.onload = null;\n                    this.onreadystatechange = null;\n                  }\n                };\n                appendToElement.appendChild(script);\n              }\n            }\n          });\n        };\n\n      if (path) {\n        loadModuleScripts(modules, path);\n      } else {\n        var findScriptPathAndLoadModules = function () {\n          var foundPath = false;\n          $('script[src*=\"form-validator\"]').each(function () {\n            var isScriptFromPluginNodeModulesDirectory = this.src.split('form-validator')[1].split('node_modules').length > 1;\n            if (!isScriptFromPluginNodeModulesDirectory) {\n              foundPath = this.src.substr(0, this.src.lastIndexOf('/')) + '/';\n              if (foundPath === '/') {\n                foundPath = '';\n              }\n              return false;\n            }\n          });\n\n          if (foundPath !== false) {\n            loadModuleScripts(modules, foundPath);\n            return true;\n          }\n          return false;\n        };\n\n        if (!findScriptPathAndLoadModules()) {\n          $(function () {\n            var hasLoadedModuleScripts = findScriptPathAndLoadModules();\n            if (!hasLoadedModuleScripts) {\n              // The modules may have been inserted via a minified script\n              if (typeof callback === 'function') {\n                callback();\n              }\n            }\n          });\n        }\n      }\n    }\n\n  });\n\n})(jQuery);\n\n/**\n * Setup function for the plugin\n */\n(function ($) {\n\n  'use strict';\n\n\n  /**\n   * A bit smarter split function\n   * delimiter can be space, comma, dash or pipe\n   * @param {String} val\n   * @param {Function|String} [callback]\n   * @param {Boolean} [allowSpaceAsDelimiter]\n   * @returns {Array|void}\n   */\n  $.split = function (val, callback, allowSpaceAsDelimiter) {\n    // default to true\n    allowSpaceAsDelimiter = allowSpaceAsDelimiter === undefined || allowSpaceAsDelimiter === true;\n    var pattern = '[,|'+(allowSpaceAsDelimiter ? '\\\\s':'')+'-]\\\\s*',\n      regex = new RegExp(pattern, 'g');\n    if (typeof callback !== 'function') {\n      // return array\n      if (!val) {\n        return [];\n      }\n      var values = [];\n      $.each(val.split(callback ? callback : regex),\n        function (i, str) {\n          str = $.trim(str);\n          if (str.length) {\n            values.push(str);\n          }\n        }\n      );\n      return values;\n    } else if (val) {\n      // exec callback func on each\n      $.each(val.split(regex),\n        function (i, str) {\n          str = $.trim(str);\n          if (str.length) {\n            return callback(str, i);\n          }\n        }\n      );\n    }\n  };\n\n  /**\n   * Short hand function that makes the validation setup require less code\n   * @param conf\n   */\n  $.validate = function (conf) {\n\n    var defaultConf = $.extend($.formUtils.defaultConfig(), {\n      form: 'form',\n      validateOnEvent: false,\n      validateOnBlur: true,\n      validateCheckboxRadioOnClick: true,\n      showHelpOnFocus: true,\n      addSuggestions: true,\n      modules: '',\n      onModulesLoaded: null,\n      language: false,\n      onSuccess: false,\n      onError: false,\n      onElementValidate: false\n    });\n\n    conf = $.extend(defaultConf, conf || {});\n\n    $(window).trigger('formValidationPluginInit', [conf]);\n\n    if( conf.lang && conf.lang !== 'en' ) {\n      var langModule = 'lang/'+conf.lang+'.js';\n      conf.modules += conf.modules.length ? ','+langModule : langModule;\n    }\n\n    // Add validation to forms\n    $(conf.form).each(function (i, form) {\n\n      // Make a reference to the config for this form\n      form.validationConfig = conf;\n\n      // Trigger jQuery event that we're about to setup validation\n      var $form = $(form);\n      $form.trigger('formValidationSetup', [$form, conf]);\n\n      // Remove classes and event handlers that might have been\n      // added by a previous call to $.validate\n      $form.find('.has-help-txt')\n          .unbind('focus.validation')\n          .unbind('blur.validation');\n\n      $form\n        .removeClass('has-validation-callback')\n        .unbind('submit.validation')\n        .unbind('reset.validation')\n        .find('input[data-validation],textarea[data-validation]')\n          .unbind('blur.validation');\n\n      // Validate when submitted\n      $form.bind('submit.validation', function (evt) {\n\n        var $form = $(this),\n          stop = function() {\n            evt.stopImmediatePropagation();\n            return false;\n          };\n\n        if ($.formUtils.haltValidation) {\n          // pressing several times on submit button while validation is halted\n          return stop();\n        }\n\n        if ($.formUtils.isLoadingModules) {\n          setTimeout(function () {\n            $form.trigger('submit.validation');\n          }, 200);\n          return stop();\n        }\n\n        var valid = $form.isValid(conf.language, conf);\n        if ($.formUtils.haltValidation) {\n          // Validation got halted by one of the validators\n          return stop();\n        } else {\n          if (valid && typeof conf.onSuccess === 'function') {\n            var callbackResponse = conf.onSuccess($form);\n            if (callbackResponse === false) {\n              return stop();\n            }\n          } else if (!valid && typeof conf.onError === 'function') {\n            conf.onError($form);\n            return stop();\n          } else {\n            return valid ? true : stop();\n          }\n        }\n      })\n      .bind('reset.validation', function () {\n        $.formUtils.dialogs.removeAllMessagesAndStyling($form, conf);\n      })\n      .addClass('has-validation-callback');\n\n      if (conf.showHelpOnFocus) {\n        $form.showHelpOnFocus();\n      }\n      if (conf.addSuggestions) {\n        $form.addSuggestions();\n      }\n      if (conf.validateOnBlur) {\n        $form.validateOnBlur(conf.language, conf);\n        $form.bind('html5ValidationAttrsFound', function () {\n          $form.validateOnBlur(conf.language, conf);\n        });\n      }\n      if (conf.validateOnEvent) {\n        $form.validateOnEvent(conf.language, conf);\n      }\n    });\n\n    if (conf.modules !== '') {\n      $.formUtils.loadModules(conf.modules, null, function() {\n        if (typeof conf.onModulesLoaded === 'function') {\n          conf.onModulesLoaded();\n        }\n        var $form = typeof conf.form === 'string' ? $(conf.form) : conf.form;\n        $.formUtils.$win.trigger('validatorsLoaded', [$form, conf]);\n      });\n    }\n  };\n\n})(jQuery);\n\n/**\n * Utility methods and properties attached to $.formUtils\n */\n(function($, window) {\n\n  'use strict';\n\n  var $win = $(window);\n\n  $.formUtils = $.extend($.formUtils || {}, {\n\n    $win: $win,\n\n    /**\n     * Default config for $(...).isValid();\n     */\n    defaultConfig: function () {\n      return {\n        ignore: [], // Names of inputs not to be validated even though `validationRuleAttribute` containing the validation rules tells us to\n        errorElementClass: 'error', // Class that will be put on elements which value is invalid\n        successElementClass: 'valid', // Class that will be put on elements that has been validated with success\n        borderColorOnError: '#b94a48', // Border color of elements which value is invalid, empty string to not change border color\n        errorMessageClass: 'form-error', // class name of div containing error messages when validation fails\n        validationRuleAttribute: 'data-validation', // name of the attribute holding the validation rules\n        validationErrorMsgAttribute: 'data-validation-error-msg', // define custom err msg inline with element\n        errorMessagePosition: 'inline', // Can be either \"top\" or \"inline\"\n        errorMessageTemplate: {\n          container: '<div class=\"{errorMessageClass} alert alert-danger\">{messages}</div>',\n          messages: '<strong>{errorTitle}</strong><ul>{fields}</ul>',\n          field: '<li>{msg}</li>'\n        },\n        scrollToTopOnError: true,\n        dateFormat: 'yyyy-mm-dd',\n        addValidClassOnAll: false, // whether or not to apply class=\"valid\" even if the input wasn't validated\n        decimalSeparator: '.',\n        inputParentClassOnError: 'has-error', // twitter-bootstrap default class name\n        inputParentClassOnSuccess: 'has-success', // twitter-bootstrap default class name\n        validateHiddenInputs: false, // whether or not hidden inputs should be validated\n        inlineErrorMessageCallback: false,\n        submitErrorMessageCallback: false\n      };\n    },\n\n    /**\n     * Available validators\n     */\n    validators: {},\n\n    /**\n     * Events triggered by form validator\n     */\n    _events: {load: [], valid: [], invalid: []},\n\n    /**\n     * Setting this property to true during validation will\n     * stop further validation from taking place and form will\n     * not be sent\n     */\n    haltValidation: false,\n\n    /**\n     * Function for adding a validator\n     * @see $.formUtils.addAsyncValidator (async.js)\n     * @param {Object} validator\n     */\n    addValidator: function (validator) {\n      // prefix with \"validate_\" for backward compatibility reasons\n      var name = validator.name.indexOf('validate_') === 0 ? validator.name : 'validate_' + validator.name;\n      if (validator.validateOnKeyUp === undefined) {\n        validator.validateOnKeyUp = true;\n      }\n      this.validators[name] = validator;\n    },\n\n    /**\n     * Warn user via the console if available\n     */\n    warn: function(msg, fallbackOnAlert) {\n      if( 'console' in window ) {\n        if( typeof window.console.warn === 'function' ) {\n          window.console.warn(msg);\n        } else if( typeof window.console.log === 'function' ) {\n          window.console.log(msg);\n        }\n      } else if (fallbackOnAlert) {\n        // This is for some old IE version...\n        alert(msg);\n      }\n    },\n\n    /**\n     * Same as input $.fn.val() but also supporting input of typ radio or checkbox\n     * @example\n     *\n     *  $.formUtils.getValue('.myRadioButtons', $('#some-form'));\n     *  $.formUtils.getValue($('#some-form').find('.check-boxes'));\n     *\n     * @param query\n     * @param $parent\n     * @returns {String|Boolean}\n     */\n    getValue: function(query, $parent) {\n      var $inputs = $parent ? $parent.find(query) : query;\n      if ($inputs.length > 0 ) {\n        var type = $inputs.eq(0).attr('type');\n        if (type === 'radio' || type === 'checkbox') {\n          return $inputs.filter(':checked').val() || '';\n        } else {\n          return $inputs.val() || '';\n        }\n      }\n      return false;\n    },\n\n    /**\n     * Validate the value of given element according to the validation rules\n     * found in the attribute data-validation. Will return an object representing\n     * a validation result, having the props shouldChangeDisplay, isValid and errorMsg\n     * @param {jQuery} $elem\n     * @param {Object} language ($.formUtils.LANG)\n     * @param {Object} conf\n     * @param {jQuery} $form\n     * @param {String} [eventContext]\n     * @return {Object}\n     */\n    validateInput: function ($elem, language, conf, $form, eventContext) {\n\n      conf = conf || $.formUtils.defaultConfig();\n      language = language || $.formUtils.LANG;\n\n      if (!$form.length) {\n        $form = $elem.parent();\n      }\n\n      var value = this.getValue($elem);\n\n      $elem\n        .valAttr('skipped', false)\n        .one('beforeValidation', function() {\n          // Skip input because its hidden or disabled\n          // Doing this in a callback makes it possible for others to prevent the default\n          // behaviour by binding to the same event and call evt.stopImmediatePropagation()\n          if ($elem.attr('disabled') || (!$elem.is(':visible') && !conf.validateHiddenInputs)) {\n            $elem.valAttr('skipped', 1);\n          }\n        })\n        .trigger('beforeValidation', [value, language, conf]);\n\n      var inputIsOptional = $elem.valAttr('optional') === 'true',\n          skipBecauseItsEmpty = !value && inputIsOptional,\n          validationRules = $elem.attr(conf.validationRuleAttribute),\n          isValid = true,\n          errorMsg = '',\n          result = {isValid: true, shouldChangeDisplay:true, errorMsg:''};\n\n      // For input type=\"number\", browsers attempt to parse the entered value into a number.\n      // If the input is not numeric, browsers handle the situation differently:\n      // Chrome 48 simply disallows non-numeric input; FF 44 clears out the input box on blur;\n      // Safari 5 parses the entered string to find a leading number.\n      // If the input fails browser validation, the browser sets the input value equal to an empty string.\n      // Therefore, we cannot distinguish (apart from hacks) between an empty input type=\"text\" and one with a\n      // value that can't be parsed by the browser.\n\n      if (!validationRules || skipBecauseItsEmpty || $elem.valAttr('skipped')) {\n        result.shouldChangeDisplay = conf.addValidClassOnAll;\n        return result;\n      }\n\n      // Filter out specified characters\n      var ignore = $elem.valAttr('ignore');\n      if (ignore) {\n        $.each(ignore.split(''), function(i, character) {\n          value = value.replace(new RegExp('\\\\'+character, 'g'), '');\n        });\n      }\n\n      $.split(validationRules, function (rule) {\n\n        if (rule.indexOf('validate_') !== 0) {\n          rule = 'validate_' + rule;\n        }\n\n        var validator = $.formUtils.validators[rule];\n\n        if (validator) {\n\n          // special change of element for checkbox_group rule\n          if (rule === 'validate_checkbox_group') {\n            // set element to first in group, so error msg attr doesn't need to be set on all elements in group\n            $elem = $form.find('[name=\"' + $elem.attr('name') + '\"]:eq(0)');\n          }\n\n          if (eventContext !== 'keyup' || validator.validateOnKeyUp) {\n            // A validator can prevent itself from getting triggered on keyup\n            isValid = validator.validatorFunction(value, $elem, conf, language, $form, eventContext);\n          }\n\n          if (!isValid) {\n            if (conf.validateOnBlur) {\n              $elem.validateOnKeyUp(language, conf);\n            }\n            errorMsg = $.formUtils.dialogs.resolveErrorMessage($elem, validator, rule, conf, language);\n            return false; // break iteration\n          }\n\n        } else {\n\n          // todo: Add some validator lookup function and tell immediately which module is missing\n          throw new Error('Using undefined validator \"' + rule +\n            '\". Maybe you have forgotten to load the module that \"' + rule +'\" belongs to?');\n\n        }\n\n      });\n\n\n      if (isValid === false) {\n        $elem.trigger('validation', false);\n        result.errorMsg = errorMsg;\n        result.isValid = false;\n        result.shouldChangeDisplay = true;\n      } else if (isValid === null) {\n        // A validatorFunction returning null means that it's not able to validate\n        // the input at this time. Most probably some async stuff need to gets finished\n        // first and then the validator will re-trigger the validation.\n        result.shouldChangeDisplay = false;\n      } else {\n        $elem.trigger('validation', true);\n        result.shouldChangeDisplay = true;\n      }\n\n      // Run element validation callback\n      if (typeof conf.onElementValidate === 'function' && errorMsg !== null) {\n        conf.onElementValidate(result.isValid, $elem, $form, errorMsg);\n      }\n\n      $elem.trigger('afterValidation', [result, eventContext]);\n\n      return result;\n    },\n\n    /**\n     * Is it a correct date according to given dateFormat. Will return false if not, otherwise\n     * an array 0=>year 1=>month 2=>day\n     *\n     * @param {String} val\n     * @param {String} dateFormat\n     * @param {Boolean} [addMissingLeadingZeros]\n     * @return {Array}|{Boolean}\n     */\n    parseDate: function (val, dateFormat, addMissingLeadingZeros) {\n      var divider = dateFormat.replace(/[a-zA-Z]/gi, '').substring(0, 1),\n        regexp = '^',\n        formatParts = dateFormat.split(divider || null),\n        matches, day, month, year;\n\n      $.each(formatParts, function (i, part) {\n        regexp += (i > 0 ? '\\\\' + divider : '') + '(\\\\d{' + part.length + '})';\n      });\n\n      regexp += '$';\n\n      if (addMissingLeadingZeros) {\n        var newValueParts = [];\n        $.each(val.split(divider), function(i, part) {\n          if(part.length === 1) {\n            part = '0'+part;\n          }\n          newValueParts.push(part);\n        });\n        val = newValueParts.join(divider);\n      }\n\n      matches = val.match(new RegExp(regexp));\n      if (matches === null) {\n        return false;\n      }\n\n      var findDateUnit = function (unit, formatParts, matches) {\n        for (var i = 0; i < formatParts.length; i++) {\n          if (formatParts[i].substring(0, 1) === unit) {\n            return $.formUtils.parseDateInt(matches[i + 1]);\n          }\n        }\n        return -1;\n      };\n\n      month = findDateUnit('m', formatParts, matches);\n      day = findDateUnit('d', formatParts, matches);\n      year = findDateUnit('y', formatParts, matches);\n\n      if ((month === 2 && day > 28 && (year % 4 !== 0 || year % 100 === 0 && year % 400 !== 0)) ||\n        (month === 2 && day > 29 && (year % 4 === 0 || year % 100 !== 0 && year % 400 === 0)) ||\n        month > 12 || month === 0) {\n        return false;\n      }\n      if ((this.isShortMonth(month) && day > 30) || (!this.isShortMonth(month) && day > 31) || day === 0) {\n        return false;\n      }\n\n      return [year, month, day];\n    },\n\n    /**\n     * skum fix. är talet 05 eller lägre ger parseInt rätt int annars får man 0 när man kör parseInt?\n     *\n     * @param {String} val\n     * @return {Number}\n     */\n    parseDateInt: function (val) {\n      if (val.indexOf('0') === 0) {\n        val = val.replace('0', '');\n      }\n      return parseInt(val, 10);\n    },\n\n    /**\n     * Has month only 30 days?\n     *\n     * @param {Number} m\n     * @return {Boolean}\n     */\n    isShortMonth: function (m) {\n      return (m % 2 === 0 && m < 7) || (m % 2 !== 0 && m > 7);\n    },\n\n    /**\n     * Restrict input length\n     *\n     * @param {jQuery} $inputElement Jquery Html object\n     * @param {jQuery} $maxLengthElement jQuery Html Object\n     * @return void\n     */\n    lengthRestriction: function ($inputElement, $maxLengthElement) {\n      // read maxChars from counter display initial text value\n      var maxChars = parseInt($maxLengthElement.text(), 10),\n        charsLeft = 0,\n\n      // internal function does the counting and sets display value\n        countCharacters = function () {\n          var numChars = $inputElement.val().length;\n          if (numChars > maxChars) {\n            // get current scroll bar position\n            var currScrollTopPos = $inputElement.scrollTop();\n            // trim value to max length\n            $inputElement.val($inputElement.val().substring(0, maxChars));\n            $inputElement.scrollTop(currScrollTopPos);\n          }\n          charsLeft = maxChars - numChars;\n          if (charsLeft < 0) {\n            charsLeft = 0;\n          }\n\n          // set counter text\n          $maxLengthElement.text(charsLeft);\n        };\n\n      // bind events to this element\n      // setTimeout is needed, cut or paste fires before val is available\n      $($inputElement).bind('keydown keyup keypress focus blur', countCharacters)\n        .bind('cut paste', function () {\n          setTimeout(countCharacters, 100);\n        });\n\n      // count chars on pageload, if there are prefilled input-values\n      $(document).bind('ready', countCharacters);\n    },\n\n    /**\n     * Test numeric against allowed range\n     *\n     * @param $value int\n     * @param $rangeAllowed str; (1-2, min1, max2, 10)\n     * @return array\n     */\n    numericRangeCheck: function (value, rangeAllowed) {\n      // split by dash\n      var range = $.split(rangeAllowed),\n      // min or max\n        minmax = parseInt(rangeAllowed.substr(3), 10);\n\n      if( range.length === 1 && rangeAllowed.indexOf('min') === -1 && rangeAllowed.indexOf('max') === -1 ) {\n        range = [rangeAllowed, rangeAllowed]; // only a number, checking agains an exact number of characters\n      }\n\n      // range ?\n      if (range.length === 2 && (value < parseInt(range[0], 10) || value > parseInt(range[1], 10) )) {\n        return [ 'out', range[0], range[1] ];\n      } // value is out of range\n      else if (rangeAllowed.indexOf('min') === 0 && (value < minmax )) // min\n      {\n        return ['min', minmax];\n      } // value is below min\n      else if (rangeAllowed.indexOf('max') === 0 && (value > minmax )) // max\n      {\n        return ['max', minmax];\n      } // value is above max\n      // since no other returns executed, value is in allowed range\n      return [ 'ok' ];\n    },\n\n\n    _numSuggestionElements: 0,\n    _selectedSuggestion: null,\n    _previousTypedVal: null,\n\n    /**\n     * Utility function that can be used to create plugins that gives\n     * suggestions when inputs is typed into\n     * @param {jQuery} $elem\n     * @param {Array} suggestions\n     * @param {Object} settings - Optional\n     * @return {jQuery}\n     */\n    suggest: function ($elem, suggestions, settings) {\n      var conf = {\n          css: {\n            maxHeight: '150px',\n            background: '#FFF',\n            lineHeight: '150%',\n            textDecoration: 'underline',\n            overflowX: 'hidden',\n            overflowY: 'auto',\n            border: '#CCC solid 1px',\n            borderTop: 'none',\n            cursor: 'pointer'\n          },\n          activeSuggestionCSS: {\n            background: '#E9E9E9'\n          }\n        },\n        setSuggsetionPosition = function ($suggestionContainer, $input) {\n          var offset = $input.offset();\n          $suggestionContainer.css({\n            width: $input.outerWidth(),\n            left: offset.left + 'px',\n            top: (offset.top + $input.outerHeight()) + 'px'\n          });\n        };\n\n      if (settings) {\n        $.extend(conf, settings);\n      }\n\n      conf.css.position = 'absolute';\n      conf.css['z-index'] = 9999;\n      $elem.attr('autocomplete', 'off');\n\n      if (this._numSuggestionElements === 0) {\n        // Re-position suggestion container if window size changes\n        $win.bind('resize', function () {\n          $('.jquery-form-suggestions').each(function () {\n            var $container = $(this),\n              suggestID = $container.attr('data-suggest-container');\n            setSuggsetionPosition($container, $('.suggestions-' + suggestID).eq(0));\n          });\n        });\n      }\n\n      this._numSuggestionElements++;\n\n      var onSelectSuggestion = function ($el) {\n        var suggestionId = $el.valAttr('suggestion-nr');\n        $.formUtils._selectedSuggestion = null;\n        $.formUtils._previousTypedVal = null;\n        $('.jquery-form-suggestion-' + suggestionId).fadeOut('fast');\n      };\n\n      $elem\n        .data('suggestions', suggestions)\n        .valAttr('suggestion-nr', this._numSuggestionElements)\n        .unbind('focus.suggest')\n        .bind('focus.suggest', function () {\n          $(this).trigger('keyup');\n          $.formUtils._selectedSuggestion = null;\n        })\n        .unbind('keyup.suggest')\n        .bind('keyup.suggest', function () {\n          var $input = $(this),\n            foundSuggestions = [],\n            val = $.trim($input.val()).toLocaleLowerCase();\n\n          if (val === $.formUtils._previousTypedVal) {\n            return;\n          }\n          else {\n            $.formUtils._previousTypedVal = val;\n          }\n\n          var hasTypedSuggestion = false,\n            suggestionId = $input.valAttr('suggestion-nr'),\n            $suggestionContainer = $('.jquery-form-suggestion-' + suggestionId);\n\n          $suggestionContainer.scrollTop(0);\n\n          // Find the right suggestions\n          if (val !== '') {\n            var findPartial = val.length > 2;\n            $.each($input.data('suggestions'), function (i, suggestion) {\n              var lowerCaseVal = suggestion.toLocaleLowerCase();\n              if (lowerCaseVal === val) {\n                foundSuggestions.push('<strong>' + suggestion + '</strong>');\n                hasTypedSuggestion = true;\n                return false;\n              } else if (lowerCaseVal.indexOf(val) === 0 || (findPartial && lowerCaseVal.indexOf(val) > -1)) {\n                foundSuggestions.push(suggestion.replace(new RegExp(val, 'gi'), '<strong>$&</strong>'));\n              }\n            });\n          }\n\n          // Hide suggestion container\n          if (hasTypedSuggestion || (foundSuggestions.length === 0 && $suggestionContainer.length > 0)) {\n            $suggestionContainer.hide();\n          }\n\n          // Create suggestion container if not already exists\n          else if (foundSuggestions.length > 0 && $suggestionContainer.length === 0) {\n            $suggestionContainer = $('<div></div>').css(conf.css).appendTo('body');\n            $elem.addClass('suggestions-' + suggestionId);\n            $suggestionContainer\n              .attr('data-suggest-container', suggestionId)\n              .addClass('jquery-form-suggestions')\n              .addClass('jquery-form-suggestion-' + suggestionId);\n          }\n\n          // Show hidden container\n          else if (foundSuggestions.length > 0 && !$suggestionContainer.is(':visible')) {\n            $suggestionContainer.show();\n          }\n\n          // add suggestions\n          if (foundSuggestions.length > 0 && val.length !== foundSuggestions[0].length) {\n\n            // put container in place every time, just in case\n            setSuggsetionPosition($suggestionContainer, $input);\n\n            // Add suggestions HTML to container\n            $suggestionContainer.html('');\n            $.each(foundSuggestions, function (i, text) {\n              $('<div></div>')\n                .append(text)\n                .css({\n                  overflow: 'hidden',\n                  textOverflow: 'ellipsis',\n                  whiteSpace: 'nowrap',\n                  padding: '5px'\n                })\n                .addClass('form-suggest-element')\n                .appendTo($suggestionContainer)\n                .click(function () {\n                  $input.focus();\n                  $input.val($(this).text());\n                  $input.trigger('change');\n                  onSelectSuggestion($input);\n                });\n            });\n          }\n        })\n        .unbind('keydown.validation')\n        .bind('keydown.validation', function (e) {\n          var code = (e.keyCode ? e.keyCode : e.which),\n            suggestionId,\n            $suggestionContainer,\n            $input = $(this);\n\n          if (code === 13 && $.formUtils._selectedSuggestion !== null) {\n            suggestionId = $input.valAttr('suggestion-nr');\n            $suggestionContainer = $('.jquery-form-suggestion-' + suggestionId);\n            if ($suggestionContainer.length > 0) {\n              var newText = $suggestionContainer.find('div').eq($.formUtils._selectedSuggestion).text();\n              $input.val(newText);\n              $input.trigger('change');\n              onSelectSuggestion($input);\n              e.preventDefault();\n            }\n          }\n          else {\n            suggestionId = $input.valAttr('suggestion-nr');\n            $suggestionContainer = $('.jquery-form-suggestion-' + suggestionId);\n            var $suggestions = $suggestionContainer.children();\n            if ($suggestions.length > 0 && $.inArray(code, [38, 40]) > -1) {\n              if (code === 38) { // key up\n                if ($.formUtils._selectedSuggestion === null) {\n                  $.formUtils._selectedSuggestion = $suggestions.length - 1;\n                }\n                else{\n                  $.formUtils._selectedSuggestion--;\n                }\n                if ($.formUtils._selectedSuggestion < 0) {\n                  $.formUtils._selectedSuggestion = $suggestions.length - 1;\n                }\n              }\n              else if (code === 40) { // key down\n                if ($.formUtils._selectedSuggestion === null) {\n                  $.formUtils._selectedSuggestion = 0;\n                }\n                else {\n                  $.formUtils._selectedSuggestion++;\n                }\n                if ($.formUtils._selectedSuggestion > ($suggestions.length - 1)) {\n                  $.formUtils._selectedSuggestion = 0;\n                }\n              }\n\n              // Scroll in suggestion window\n              var containerInnerHeight = $suggestionContainer.innerHeight(),\n                containerScrollTop = $suggestionContainer.scrollTop(),\n                suggestionHeight = $suggestionContainer.children().eq(0).outerHeight(),\n                activeSuggestionPosY = suggestionHeight * ($.formUtils._selectedSuggestion);\n\n              if (activeSuggestionPosY < containerScrollTop || activeSuggestionPosY > (containerScrollTop + containerInnerHeight)) {\n                $suggestionContainer.scrollTop(activeSuggestionPosY);\n              }\n\n              $suggestions\n                .removeClass('active-suggestion')\n                .css('background', 'none')\n                .eq($.formUtils._selectedSuggestion)\n                .addClass('active-suggestion')\n                .css(conf.activeSuggestionCSS);\n\n              e.preventDefault();\n              return false;\n            }\n          }\n        })\n        .unbind('blur.suggest')\n        .bind('blur.suggest', function () {\n          onSelectSuggestion($(this));\n        });\n\n      return $elem;\n    },\n\n    /**\n     * Error dialogs\n     *\n     * @var {Object}\n     */\n    LANG: {\n      errorTitle: 'Form submission failed!',\n      requiredField: 'This is a required field',\n      requiredFields: 'You have not answered all required fields',\n      badTime: 'You have not given a correct time',\n      badEmail: 'You have not given a correct e-mail address',\n      badTelephone: 'You have not given a correct phone number',\n      badSecurityAnswer: 'You have not given a correct answer to the security question',\n      badDate: 'You have not given a correct date',\n      lengthBadStart: 'The input value must be between ',\n      lengthBadEnd: ' characters',\n      lengthTooLongStart: 'The input value is longer than ',\n      lengthTooShortStart: 'The input value is shorter than ',\n      notConfirmed: 'Input values could not be confirmed',\n      badDomain: 'Incorrect domain value',\n      badUrl: 'The input value is not a correct URL',\n      badCustomVal: 'The input value is incorrect',\n      andSpaces: ' and spaces ',\n      badInt: 'The input value was not a correct number',\n      badSecurityNumber: 'Your social security number was incorrect',\n      badUKVatAnswer: 'Incorrect UK VAT Number',\n      badUKNin: 'Incorrect UK NIN',\n      badUKUtr: 'Incorrect UK UTR Number',\n      badStrength: 'The password isn\\'t strong enough',\n      badNumberOfSelectedOptionsStart: 'You have to choose at least ',\n      badNumberOfSelectedOptionsEnd: ' answers',\n      badAlphaNumeric: 'The input value can only contain alphanumeric characters ',\n      badAlphaNumericExtra: ' and ',\n      wrongFileSize: 'The file you are trying to upload is too large (max %s)',\n      wrongFileType: 'Only files of type %s is allowed',\n      groupCheckedRangeStart: 'Please choose between ',\n      groupCheckedTooFewStart: 'Please choose at least ',\n      groupCheckedTooManyStart: 'Please choose a maximum of ',\n      groupCheckedEnd: ' item(s)',\n      badCreditCard: 'The credit card number is not correct',\n      badCVV: 'The CVV number was not correct',\n      wrongFileDim : 'Incorrect image dimensions,',\n      imageTooTall : 'the image can not be taller than',\n      imageTooWide : 'the image can not be wider than',\n      imageTooSmall : 'the image was too small',\n      min : 'min',\n      max : 'max',\n      imageRatioNotAccepted : 'Image ratio is not be accepted',\n      badBrazilTelephoneAnswer: 'The phone number entered is invalid',\n      badBrazilCEPAnswer: 'The CEP entered is invalid',\n      badBrazilCPFAnswer: 'The CPF entered is invalid',\n      badPlPesel: 'The PESEL entered is invalid',\n      badPlNip: 'The NIP entered is invalid',\n      badPlRegon: 'The REGON entered is invalid',\n      badreCaptcha: 'Please confirm that you are not a bot',\n      passwordComplexityStart: 'Password must contain at least ',\n      passwordComplexitySeparator: ', ',\n      passwordComplexityUppercaseInfo: ' uppercase letter(s)',\n      passwordComplexityLowercaseInfo: ' lowercase letter(s)',\n      passwordComplexitySpecialCharsInfo: ' special character(s)',\n      passwordComplexityNumericCharsInfo: ' numeric character(s)',\n      passwordComplexityEnd: '.'\n    }\n  });\n\n})(jQuery, window);\n\n/**\n * File declaring all default validators.\n */\n(function($) {\n\n  /*\n   * Validate email\n   */\n  $.formUtils.addValidator({\n    name: 'email',\n    validatorFunction: function (email) {\n\n      var emailParts = email.toLowerCase().split('@'),\n        localPart = emailParts[0],\n        domain = emailParts[1];\n\n      if (localPart && domain) {\n\n        if( localPart.indexOf('\"') === 0 ) {\n          var len = localPart.length;\n          localPart = localPart.replace(/\\\"/g, '');\n          if( localPart.length !== (len-2) ) {\n            return false; // It was not allowed to have more than two apostrophes\n          }\n        }\n\n        return $.formUtils.validators.validate_domain.validatorFunction(emailParts[1]) &&\n          localPart.indexOf('.') !== 0 &&\n          localPart.substring(localPart.length-1, localPart.length) !== '.' &&\n          localPart.indexOf('..') === -1 &&\n          !(/[^\\w\\+\\.\\-\\#\\-\\_\\~\\!\\$\\&\\'\\(\\)\\*\\+\\,\\;\\=\\:]/.test(localPart));\n      }\n\n      return false;\n    },\n    errorMessage: '',\n    errorMessageKey: 'badEmail'\n  });\n\n  /*\n   * Validate domain name\n   */\n  $.formUtils.addValidator({\n    name: 'domain',\n    validatorFunction: function (val) {\n      return val.length > 0 &&\n        val.length <= 253 && // Including sub domains\n        !(/[^a-zA-Z0-9]/.test(val.slice(-2))) && !(/[^a-zA-Z0-9]/.test(val.substr(0, 1))) && !(/[^a-zA-Z0-9\\.\\-]/.test(val)) &&\n        val.split('..').length === 1 &&\n        val.split('.').length > 1;\n    },\n    errorMessage: '',\n    errorMessageKey: 'badDomain'\n  });\n\n  /*\n   * Validate required\n   */\n  $.formUtils.addValidator({\n    name: 'required',\n    validatorFunction: function (val, $el, config, language, $form) {\n      switch ($el.attr('type')) {\n        case 'checkbox':\n          return $el.is(':checked');\n        case 'radio':\n          return $form.find('input[name=\"' + $el.attr('name') + '\"]').filter(':checked').length > 0;\n        default:\n          return $.trim(val) !== '';\n      }\n    },\n    errorMessage: '',\n    errorMessageKey: function(config) {\n      if (config.errorMessagePosition === 'top' || typeof config.errorMessagePosition === 'function') {\n        return 'requiredFields';\n      }\n      else {\n        return 'requiredField';\n      }\n    }\n  });\n\n  /*\n   * Validate length range\n   */\n  $.formUtils.addValidator({\n    name: 'length',\n    validatorFunction: function (val, $el, conf, lang) {\n      var lengthAllowed = $el.valAttr('length'),\n        type = $el.attr('type');\n\n      if (lengthAllowed === undefined) {\n        alert('Please add attribute \"data-validation-length\" to ' + $el[0].nodeName + ' named ' + $el.attr('name'));\n        return true;\n      }\n\n      // check if length is above min, below max or within range.\n      var len = type === 'file' && $el.get(0).files !== undefined ? $el.get(0).files.length : val.length,\n        lengthCheckResults = $.formUtils.numericRangeCheck(len, lengthAllowed),\n        checkResult;\n\n      switch (lengthCheckResults[0]) {   // outside of allowed range\n        case 'out':\n          this.errorMessage = lang.lengthBadStart + lengthAllowed + lang.lengthBadEnd;\n          checkResult = false;\n          break;\n        // too short\n        case 'min':\n          this.errorMessage = lang.lengthTooShortStart + lengthCheckResults[1] + lang.lengthBadEnd;\n          checkResult = false;\n          break;\n        // too long\n        case 'max':\n          this.errorMessage = lang.lengthTooLongStart + lengthCheckResults[1] + lang.lengthBadEnd;\n          checkResult = false;\n          break;\n        // ok\n        default:\n          checkResult = true;\n      }\n\n      return checkResult;\n    },\n    errorMessage: '',\n    errorMessageKey: ''\n  });\n\n  /*\n   * Validate url\n   */\n  $.formUtils.addValidator({\n    name: 'url',\n    validatorFunction: function (url) {\n      // written by Scott Gonzalez: http://projects.scottsplayground.com/iri/\n      // - Victor Jonsson added support for arrays in the url ?arg[]=sdfsdf\n      // - General improvements made by Stéphane Moureau <https://github.com/TraderStf>\n\n      var urlFilter = /^(https?|ftp):\\/\\/((((\\w|-|\\.|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:)*@)?(((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])(\\w|-|\\.|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])(\\w|-|\\.|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?)(:\\d*)?)(\\/(((\\w|-|\\.|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)+(\\/((\\w|-|\\.|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)*)*)?)?(\\?((([a-z]|\\d|\\[|\\]|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)|[\\uE000-\\uF8FF]|\\/|\\?)*)?(\\#(((\\w|-|\\.|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)|\\/|\\?)*)?$/i;\n      if (urlFilter.test(url)) {\n        var domain = url.split('://')[1],\n          domainSlashPos = domain.indexOf('/');\n\n        if (domainSlashPos > -1) {\n          domain = domain.substr(0, domainSlashPos);\n        }\n\n        return $.formUtils.validators.validate_domain.validatorFunction(domain); // todo: add support for IP-addresses\n      }\n      return false;\n    },\n    errorMessage: '',\n    errorMessageKey: 'badUrl'\n  });\n\n  /*\n   * Validate number (floating or integer)\n   */\n  $.formUtils.addValidator({\n    name: 'number',\n    validatorFunction: function (val, $el, conf) {\n      if (val !== '') {\n        var allowing = $el.valAttr('allowing') || '',\n          decimalSeparator = $el.valAttr('decimal-separator') || conf.decimalSeparator,\n          allowsRange = false,\n          begin, end,\n          steps = $el.valAttr('step') || '',\n          allowsSteps = false,\n          sanitize = $el.attr('data-sanitize') || '',\n          isFormattedWithNumeral = sanitize.match(/(^|[\\s])numberFormat([\\s]|$)/i);\n\n        if (isFormattedWithNumeral) {\n          if (!window.numeral) {\n            throw new ReferenceError('The data-sanitize value numberFormat cannot be used without the numeral' +\n              ' library. Please see Data Validation in http://www.formvalidator.net for more information.');\n          }\n          //Unformat input first, then convert back to String\n          if (val.length) {\n            val = String(numeral().unformat(val));\n          }\n        }\n\n        if (allowing.indexOf('number') === -1) {\n          allowing += ',number';\n        }\n\n        if (allowing.indexOf('negative') === -1 && val.indexOf('-') === 0) {\n          return false;\n        }\n\n        if (allowing.indexOf('range') > -1) {\n          begin = parseFloat(allowing.substring(allowing.indexOf('[') + 1, allowing.indexOf(';')));\n          end = parseFloat(allowing.substring(allowing.indexOf(';') + 1, allowing.indexOf(']')));\n          allowsRange = true;\n        }\n\n        if (steps !== '') {\n          allowsSteps = true;\n        }\n\n        if (decimalSeparator === ',') {\n          if (val.indexOf('.') > -1) {\n            return false;\n          }\n          // Fix for checking range with floats using ,\n          val = val.replace(',', '.');\n        }\n        if (val.replace(/[0-9-]/g, '') === '' && (!allowsRange || (val >= begin && val <= end)) && (!allowsSteps || (val % steps === 0))) {\n          return true;\n        }\n\n        if (allowing.indexOf('float') > -1 && val.match(new RegExp('^([0-9-]+)\\\\.([0-9]+)$')) !== null && (!allowsRange || (val >= begin && val <= end)) && (!allowsSteps || (val % steps === 0))) {\n          return true;\n        }\n      }\n      return false;\n    },\n    errorMessage: '',\n    errorMessageKey: 'badInt'\n  });\n\n  /*\n   * Validate alpha numeric\n   */\n  $.formUtils.addValidator({\n    name: 'alphanumeric',\n    validatorFunction: function (val, $el, conf, language) {\n      var patternStart = '^([a-zA-Z0-9',\n        patternEnd = ']+)$',\n        additionalChars = $el.valAttr('allowing'),\n        pattern = '',\n        hasSpaces = false;\n\n      if (additionalChars) {\n        pattern = patternStart + additionalChars + patternEnd;\n        var extra = additionalChars.replace(/\\\\/g, '');\n        if (extra.indexOf(' ') > -1) {\n          hasSpaces = true;\n          extra = extra.replace(' ', '');\n          extra += language.andSpaces || $.formUtils.LANG.andSpaces;\n        }\n\n        if(language.badAlphaNumericAndExtraAndSpaces && language.badAlphaNumericAndExtra) {\n          if(hasSpaces) {\n            this.errorMessage = language.badAlphaNumericAndExtraAndSpaces + extra; \n          } else {\n            this.errorMessage = language.badAlphaNumericAndExtra + extra + language.badAlphaNumericExtra; \n          }\n        } else {\n          this.errorMessage = language.badAlphaNumeric + language.badAlphaNumericExtra + extra;\n        }\n      } else {\n        pattern = patternStart + patternEnd;\n        this.errorMessage = language.badAlphaNumeric;\n      }\n\n      return new RegExp(pattern).test(val);\n    },\n    errorMessage: '',\n    errorMessageKey: ''\n  });\n\n  /*\n   * Validate against regexp\n   */\n  $.formUtils.addValidator({\n    name: 'custom',\n    validatorFunction: function (val, $el) {\n      var regexp = new RegExp($el.valAttr('regexp'));\n      return regexp.test(val);\n    },\n    errorMessage: '',\n    errorMessageKey: 'badCustomVal'\n  });\n\n  /*\n   * Validate date\n   */\n  $.formUtils.addValidator({\n    name: 'date',\n    validatorFunction: function (date, $el, conf) {\n      var dateFormat = $el.valAttr('format') || conf.dateFormat || 'yyyy-mm-dd',\n        addMissingLeadingZeros = $el.valAttr('require-leading-zero') === 'false';\n      return $.formUtils.parseDate(date, dateFormat, addMissingLeadingZeros) !== false;\n    },\n    errorMessage: '',\n    errorMessageKey: 'badDate'\n  });\n\n\n  /*\n   * Validate group of checkboxes, validate qty required is checked\n   * written by Steve Wasiura : http://stevewasiura.waztech.com\n   * element attrs\n   *    data-validation=\"checkbox_group\"\n   *    data-validation-qty=\"1-2\"  // min 1 max 2\n   *    data-validation-error-msg=\"chose min 1, max of 2 checkboxes\"\n   */\n  $.formUtils.addValidator({\n    name: 'checkbox_group',\n    validatorFunction: function (val, $el, conf, lang, $form) {\n      // preset return var\n      var isValid = true,\n      // get name of element. since it is a checkbox group, all checkboxes will have same name\n        elname = $el.attr('name'),\n      // get checkboxes and count the checked ones\n        $checkBoxes = $('input[type=checkbox][name^=\"' + elname + '\"]', $form),\n        checkedCount = $checkBoxes.filter(':checked').length,\n      // get el attr that specs qty required / allowed\n        qtyAllowed = $el.valAttr('qty');\n\n      if (qtyAllowed === undefined) {\n        var elementType = $el.get(0).nodeName;\n        alert('Attribute \"data-validation-qty\" is missing from ' + elementType + ' named ' + $el.attr('name'));\n      }\n\n      // call Utility function to check if count is above min, below max, within range etc.\n      var qtyCheckResults = $.formUtils.numericRangeCheck(checkedCount, qtyAllowed);\n\n      // results will be array, [0]=result str, [1]=qty int\n      switch (qtyCheckResults[0]) {\n        // outside allowed range\n        case 'out':\n          this.errorMessage = lang.groupCheckedRangeStart + qtyAllowed + lang.groupCheckedEnd;\n          isValid = false;\n          break;\n        // below min qty\n        case 'min':\n          this.errorMessage = lang.groupCheckedTooFewStart + qtyCheckResults[1] + (lang.groupCheckedTooFewEnd || lang.groupCheckedEnd);\n          isValid = false;\n          break;\n        // above max qty\n        case 'max':\n          this.errorMessage = lang.groupCheckedTooManyStart + qtyCheckResults[1] + (lang.groupCheckedTooManyEnd || lang.groupCheckedEnd);\n          isValid = false;\n          break;\n        // ok\n        default:\n          isValid = true;\n      }\n\n      if( !isValid ) {\n        var _triggerOnBlur = function() {\n          $checkBoxes.unbind('click', _triggerOnBlur);\n          $checkBoxes.filter('*[data-validation]').validateInputOnBlur(lang, conf, false, 'blur');\n        };\n        $checkBoxes.bind('click', _triggerOnBlur);\n      }\n\n      return isValid;\n    }\n    //   errorMessage : '', // set above in switch statement\n    //   errorMessageKey: '' // not used\n  });\n\n})(jQuery);\n\n\n}));\n"]}