/*Downloaded from https://www.codeseek.co/hspindler/angularjs-ngmask-sample-NRmQrd */
.input-help {
display: none;
position: absolute;
z-index: 100;
top: -6px;
left: 160px;
width: 200px;
padding: 10px;
background: #fefefe;
font-size: .875em;
border-radius: 5px;
box-shadow: 0 1px 3px #aaa;
border: 1px solid #ddd;
opacity: 0.9;
}
.input-help::before {
content: "\25C0";
position: absolute;
top: 10px;
left: -12px;
font-size: 16px;
line-height: 16px;
color: #ddd;
text-shadow: none;
}
.input-help h4 {
margin: 0;
padding: 0;
font-weight: normal;
font-size: 1.1em;
}
/* Always hide the input help when it's pristine */
input.ng-pristine + .input-help {
display: none;
}
/* Hide the invalid box while the input has focus */
.ng-invalid:focus + .input-help {
display: none;
}
/* Show a blue border while an input has focus, make sure it overrides everything else */
/* Overriding Twitter Bootstrap cuz I don't agree we need to alarm the user while they're typing */
input:focus {
color: black !important;
border-color: rgba(82, 168, 236, 0.8) !important;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6) !important;
-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6) !important;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6) !important;
}
/* Show green border when stuff has been typed in, and its valid */
.ng-dirty.ng-valid {
border-color: #3a7d34;
}
/* Show red border when stuff has been typed in, but its invalid */
.ng-dirty.ng-invalid {
border-color: #ec3f41;
}
/* Show the help box once it has focus */
.immediate-help:focus + .input-help {
display: block;
}
/* Immediate help should be red when pristine */
.immediate-help.ng-pristine:focus + .input-help {
border-color: #ec3f41;
}
.immediate-help.ng-pristine:focus + .input-help::before {
color: #ec3f41;
}
/* Help hould be green when input is valid */
.ng-valid + .input-help {
border-color: #3a7d34;
}
.ng-valid + .input-help::before {
color: #3a7d34;
}
/* Help should show and be red when invalid */
.ng-invalid + .input-help {
display: block;
border-color: #ec3f41;
}
.ng-invalid + .input-help::before {
color: #ec3f41;
}
/* Style input help requirement bullets */
.input-help ul {
list-style: none;
margin: 10px 0 0 0;
}
/* Default each bullet to be invalid with a red cross and text */
.input-help li {
padding-left: 22px;
line-height: 24px;
color: #ec3f41;
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAA1CAYAAABIkmvkAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAJwAAACcBKgmRTwAAABZ0RVh0Q3JlYXRpb24gVGltZQAxMC8wOS8xMlhq+BkAAAAcdEVYdFNvZnR3YXJlAEFkb2JlIEZpcmV3b3JrcyBDUzVxteM2AAAEA0lEQVRIie2WW2jbVRzHv//zT5rkn0ub61zaNdEiPqTC9EFRhtgJk63qg3Wr0806pswNiYgDUXxwyryCEB8UBevtaSCCDHQoboKyoVvVzfRmL2napU0mrdbl8s//dy4+dM1M28n64FsPnIdz+XzO75zfOXA0pRRWU7o/uS9FxOc+3/vlIQBgq4F3fHxvKuIPJ9cFwi9uTXU8BwDa1Uaw/aN7UusCkWRbPI5yxcTI2Bgy49kXrkrwwIedqYg/nGyLXwsJiYHBYWTGs7Cq5Kpt4cA3PXft+2rX40vhrt7OVLgplIzHYuBKoH9gCKMjGVE1LdfJl86YDAAOfN2ziZP4NODyv9/z2fanFuH7P9iWCjcFk/FYK4QSGLgEk0WeUy/3mQCgPXFs9xbBRW883NrssDvQN3hWcOLPEPGWiD94MBaPQymBoaERjI9mBSfu+fHwL+biItpjR3e6JFfloDeAaGQ9SpUycvlp6ExHJBKGYsDvgyMYH81KTsL90yuX4VoWdh3pMqSQpWBjAC3RZkgpYEkCFDA8NIqJ0UlFxI3Tr/5aB9elsau305BcloKBAFpjLeBSYGRwDBNjk4oTN06/dnYZXCcAgK1vbzYkl6VwOATihOzYlOLEjTOvn1sRXiYAgDsP32YIKUuWaXFOwtP3xrnqleAVBQBwy/M3GZy4+PnN3/4TvqJgNWVVj2lNsCZYE6wJ1gRrgv9dYAMAHHw2Bl2fUEpBVavtLPVW/78nVR/Zk4CupzVHA6zChSOK0yHv0S8GFyK4BMPhAJxOgLE03/9kYhE2dz+agKaldY8bDaEQ7D5ft7Roy+UIlCooy5LQdaZ5vVBEgGmmrT172yVxaIylmdcDm9cHc2oK1Zm8kETvLAo0pRRk8mmnEqKouVw68zVCzP8F/uccFHHoXi/sjT6Y53Mw83mhOHn8J7416wQAwPftd0ouiswwdJu/CRASkBKQAmYuBzNfWIC/O173W6llwfbeu6Yi8tDsrAQJYGICyGQAIWDO5KUkaxlcJwAASdSmaWAQHCACOAc4h6YzJi1qWymNNUHlwYcT0JDWXQbACYhGgeh6gHM4Ghuh2/R0YePNiaUCTSmFcvdDCY1paZvhht3nQ2VmGmahICSR5vQHmDt6DcozeZSnp2FdLLZHhwdq94SVd+xMaJqWtrkM2L1uVHILpy0t8igidymXExfHMzBCQbhCIdga7Onz8etqkdgkUYTZbYCSqORmULlQEIq4J3jyexMA8jdu9BRzuaKyLN3udkNjDEqICID+2hbm797Wwez24/T3vJTE3aFTP9Sd9vT1NziVEMUGr1c35+Y2b5jKnqgNKqWglMLspjs6/rj1dudie2mdao07J5s3dCzt/werJTyI1yYqpQAAAABJRU5ErkJggg==) no-repeat 2px -34px;
}
/* Set to green check and text when valid */
.input-help li.valid {
color: #3a7d34;
background-position: 2px 6px;
}
/* Set submit button */
form .btn,
form.ng-valid .btn[disabled] {
display: none;
}
form.ng-invalid .btn[disabled],
form.ng-valid .btn {
display: inline-block;
}
body {
padding: 20px 0;
}
input {
width: 166px
}
.form-horizontal .control-label {
width: 100px;
}
.form-horizontal .controls {
position: relative;
margin-left: 120px;
}
/*Downloaded from https://www.codeseek.co/hspindler/angularjs-ngmask-sample-NRmQrd */
var app = angular.module('form-example', ['ngMask']);
app.directive('passwordValidate', function() {
return {
require: 'ngModel',
link: function(scope, elm, attrs, ctrl) {
ctrl.$parsers.unshift(function(viewValue) {
scope.pwdValidLength = (viewValue && viewValue.length >= 8 ? 'valid' : undefined);
scope.pwdHasLetter = (viewValue && /[A-z]/.test(viewValue)) ? 'valid' : undefined;
scope.pwdHasNumber = (viewValue && /\d/.test(viewValue)) ? 'valid' : undefined;
if (scope.pwdValidLength && scope.pwdHasLetter && scope.pwdHasNumber) {
ctrl.$setValidity('pwd', true);
//elm.$setValidity('pwd', true); //<-- I WANT THIS TO WORK! (or something like it)
return viewValue;
} else {
ctrl.$setValidity('pwd', false);
//elm.$setValidity('pwd', false); //<-- I WANT THIS TO WORK! (or something like it)
return undefined;
}
});
}
};
});
(function() {
'use strict';
angular.module('ngMask', []);
})();
(function() {
'use strict';
angular.module('ngMask')
.directive('mask', ['$log', '$timeout', 'MaskService', function($log, $timeout, MaskService) {
return {
restrict: 'A',
require: 'ngModel',
compile: function($element, $attrs) {
if (!$attrs.mask || !$attrs.ngModel) {
$log.info('Mask and ng-model attributes are required!');
return;
}
var maskService = MaskService.create();
var timeout;
var promise;
function setSelectionRange(selectionStart) {
if (typeof selectionStart !== 'number') {
return;
}
// using $timeout:
// it should run after the DOM has been manipulated by Angular
// and after the browser renders (which may cause flicker in some cases)
$timeout.cancel(timeout);
timeout = $timeout(function() {
var selectionEnd = selectionStart + 1;
var input = $element[0];
if (input.setSelectionRange) {
input.focus();
input.setSelectionRange(selectionStart, selectionEnd);
} else if (input.createTextRange) {
var range = input.createTextRange();
range.collapse(true);
range.moveEnd('character', selectionEnd);
range.moveStart('character', selectionStart);
range.select();
}
});
}
return {
pre: function($scope, $element, $attrs, controller) {
promise = maskService.generateRegex({
mask: $attrs.mask,
// repeat mask expression n times
repeat: ($attrs.repeat || $attrs.maskRepeat),
// clean model value - without divisors
clean: (($attrs.clean || $attrs.maskClean) === 'true'),
// limit length based on mask length
limit: (($attrs.limit || $attrs.maskLimit || 'true') === 'true'),
// how to act with a wrong value
restrict: ($attrs.restrict || $attrs.maskRestrict || 'select'), //select, reject, accept
// set validity mask
validate: (($attrs.validate || $attrs.maskValidate || 'true') === 'true'),
// default model value
model: $attrs.ngModel,
// default input value
value: $attrs.ngValue
});
},
post: function($scope, $element, $attrs, controller) {
var timeout;
var options = maskService.getOptions();
function parseViewValue(value) {
var untouchedValue = value;
options = maskService.getOptions();
// set default value equal 0
value = value || '';
// get view value object
var viewValue = maskService.getViewValue(value);
// get mask without question marks
var maskWithoutOptionals = options['maskWithoutOptionals'] || '';
// get view values capped
// used on view
var viewValueWithDivisors = viewValue.withDivisors(true);
// used on model
var viewValueWithoutDivisors = viewValue.withoutDivisors(true);
try {
// get current regex
var regex = maskService.getRegex(viewValueWithDivisors.length - 1);
var fullRegex = maskService.getRegex(maskWithoutOptionals.length - 1);
// current position is valid
var validCurrentPosition = regex.test(viewValueWithDivisors) || fullRegex.test(viewValueWithDivisors);
// difference means for select option
var diffValueAndViewValueLengthIsOne = (value.length - viewValueWithDivisors.length) === 1;
var diffMaskAndViewValueIsGreaterThanZero = (maskWithoutOptionals.length - viewValueWithDivisors.length) > 0;
if (options.restrict !== 'accept') {
if (options.restrict === 'select' && (!validCurrentPosition || diffValueAndViewValueLengthIsOne)) {
var lastCharInputed = value[(value.length - 1)];
var lastCharGenerated = viewValueWithDivisors[(viewValueWithDivisors.length - 1)];
if ((lastCharInputed !== lastCharGenerated) && diffMaskAndViewValueIsGreaterThanZero) {
viewValueWithDivisors = viewValueWithDivisors + lastCharInputed;
}
var wrongPosition = maskService.getFirstWrongPosition(viewValueWithDivisors);
if (angular.isDefined(wrongPosition)) {
setSelectionRange(wrongPosition);
}
} else if (options.restrict === 'reject' && !validCurrentPosition) {
viewValue = maskService.removeWrongPositions(viewValueWithDivisors);
viewValueWithDivisors = viewValue.withDivisors(true);
viewValueWithoutDivisors = viewValue.withoutDivisors(true);
// setSelectionRange(viewValueWithDivisors.length);
}
}
if (!options.limit) {
viewValueWithDivisors = viewValue.withDivisors(false);
viewValueWithoutDivisors = viewValue.withoutDivisors(false);
}
// Set validity
if (options.validate && controller.$dirty) {
if (fullRegex.test(viewValueWithDivisors) || controller.$isEmpty(untouchedValue)) {
controller.$setValidity('mask', true);
} else {
controller.$setValidity('mask', false);
}
}
// Update view and model values
if (value !== viewValueWithDivisors) {
controller.$setViewValue(angular.copy(viewValueWithDivisors), 'input');
controller.$render();
}
} catch (e) {
$log.error('[mask - parseViewValue]');
throw e;
}
// Update model, can be different of view value
if (options.clean) {
return viewValueWithoutDivisors;
} else {
return viewValueWithDivisors;
}
}
var callParseViewValue = function() {
parseViewValue();
controller.$parsers.push(parseViewValue);
// $evalAsync from a directive
// it should run after the DOM has been manipulated by Angular
// but before the browser renders
if (options.value) {
$scope.$evalAsync(function($scope) {
controller.$setViewValue(angular.copy(options.value), 'input');
controller.$render();
});
}
}
$element.on('click input paste keyup', function() {
timeout = $timeout(function() {
// Manual debounce to prevent multiple execution
$timeout.cancel(timeout);
parseViewValue($element.val());
$scope.$apply();
}, 100);
});
// Register the watch to observe remote loading or promised data
// Deregister calling returned function
var watcher = $scope.$watch($attrs.ngModel, function(newValue, oldValue) {
if (angular.isDefined(newValue)) {
parseViewValue(newValue);
watcher();
}
});
$scope.$watch(function() {
return [$attrs.mask];
}, function() {
promise = maskService.generateRegex({
mask: $attrs.mask,
// repeat mask expression n times
repeat: ($attrs.repeat || $attrs.maskRepeat),
// clean model value - without divisors
clean: (($attrs.clean || $attrs.maskClean) === 'true'),
// limit length based on mask length
limit: (($attrs.limit || $attrs.maskLimit || 'true') === 'true'),
// how to act with a wrong value
restrict: ($attrs.restrict || $attrs.maskRestrict || 'select'), //select, reject, accept
// set validity mask
validate: (($attrs.validate || $attrs.maskValidate || 'true') === 'true'),
// default model value
model: $attrs.ngModel,
// default input value
value: $attrs.ngValue
}).then(function() {
$element.triggerHandler('click');
});
promise.then(callParseViewValue);
}, true);
promise.then(callParseViewValue);
}
}
}
}
}]);
})();
(function() {
'use strict';
angular.module('ngMask')
.factory('MaskService', ['$q', 'OptionalService', 'UtilService', function($q, OptionalService, UtilService) {
function create() {
var options;
var maskWithoutOptionals;
var maskWithoutOptionalsLength = 0;
var maskWithoutOptionalsAndDivisorsLength = 0;
var optionalIndexes = [];
var optionalDivisors = {};
var optionalDivisorsCombinations = [];
var divisors = [];
var divisorElements = {};
var regex = [];
var patterns = {
'9': /[0-9]/,
'8': /[0-8]/,
'7': /[0-7]/,
'6': /[0-6]/,
'5': /[0-5]/,
'4': /[0-4]/,
'3': /[0-3]/,
'2': /[0-2]/,
'1': /[0-1]/,
'0': /[0]/,
'*': /./,
'w': /\w/,
'W': /\W/,
'd': /\d/,
'D': /\D/,
's': /\s/,
'S': /\S/,
'b': /\b/,
'A': /[A-Z]/,
'a': /[a-z]/,
'Z': /[A-ZÇÀÁÂÃÈÉÊẼÌÍÎĨÒÓÔÕÙÚÛŨ]/,
'z': /[a-zçáàãâéèêẽíìĩîóòôõúùũüû]/,
'@': /[a-zA-Z]/,
'#': /[a-zA-ZçáàãâéèêẽíìĩîóòôõúùũüûÇÀÁÂÃÈÉÊẼÌÍÎĨÒÓÔÕÙÚÛŨ]/,
'%': /[0-9a-zA-ZçáàãâéèêẽíìĩîóòôõúùũüûÇÀÁÂÃÈÉÊẼÌÍÎĨÒÓÔÕÙÚÛŨ]/
};
// REGEX
function generateIntermetiateElementRegex(i, forceOptional) {
var charRegex;
try {
var element = maskWithoutOptionals[i];
var elementRegex = patterns[element];
var hasOptional = isOptional(i);
if (elementRegex) {
charRegex = '(' + elementRegex.source + ')';
} else { // is a divisor
if (!isDivisor(i)) {
divisors.push(i);
divisorElements[i] = element;
}
charRegex = '(' + '\\' + element + ')';
}
} catch (e) {
throw e;
}
if (hasOptional || forceOptional) {
charRegex += '?';
}
return new RegExp(charRegex);
}
function generateIntermetiateRegex(i, forceOptional) {
var elementRegex
var elementOptionalRegex;
try {
var intermetiateElementRegex = generateIntermetiateElementRegex(i, forceOptional);
elementRegex = intermetiateElementRegex;
var hasOptional = isOptional(i);
var currentRegex = intermetiateElementRegex.source;
if (hasOptional && ((i + 1) < maskWithoutOptionalsLength)) {
var intermetiateRegex = generateIntermetiateRegex((i + 1), true).elementOptionalRegex();
currentRegex += intermetiateRegex.source;
}
elementOptionalRegex = new RegExp(currentRegex);
} catch (e) {
throw e;
}
return {
elementRegex: function() {
return elementRegex;
},
elementOptionalRegex: function() {
// from element regex, gets the flow of regex until first not optional
return elementOptionalRegex;
}
};
}
function generateRegex(opts) {
var deferred = $q.defer();
maskWithoutOptionals = null;
maskWithoutOptionalsLength = 0;
maskWithoutOptionalsAndDivisorsLength = 0;
optionalIndexes = [];
optionalDivisors = {};
optionalDivisorsCombinations = [];
divisors = [];
divisorElements = {};
regex = [];
options = opts;
try {
var mask = opts['mask'];
var repeat = opts['repeat'];
if (!mask)
return;
if (repeat) {
mask = Array((parseInt(repeat) + 1)).join(mask);
}
optionalIndexes = OptionalService.getOptionals(mask).fromMaskWithoutOptionals();
options['maskWithoutOptionals'] = maskWithoutOptionals = OptionalService.removeOptionals(mask);
maskWithoutOptionalsLength = maskWithoutOptionals.length;
var cumulativeRegex;
for (var i = 0; i < maskWithoutOptionalsLength; i++) {
var charRegex = generateIntermetiateRegex(i);
var elementRegex = charRegex.elementRegex();
var elementOptionalRegex = charRegex.elementOptionalRegex();
var newRegex = cumulativeRegex ? cumulativeRegex.source + elementOptionalRegex.source : elementOptionalRegex.source;
newRegex = new RegExp(newRegex);
cumulativeRegex = cumulativeRegex ? cumulativeRegex.source + elementRegex.source : elementRegex.source;
cumulativeRegex = new RegExp(cumulativeRegex);
regex.push(newRegex);
}
generateOptionalDivisors();
maskWithoutOptionalsAndDivisorsLength = removeDivisors(maskWithoutOptionals).length;
deferred.resolve({
options: options,
divisors: divisors,
divisorElements: divisorElements,
optionalIndexes: optionalIndexes,
optionalDivisors: optionalDivisors,
optionalDivisorsCombinations: optionalDivisorsCombinations
});
} catch (e) {
deferred.reject(e);
throw e;
}
return deferred.promise;
}
function getRegex(index) {
var currentRegex;
try {
currentRegex = regex[index] ? regex[index].source : '';
} catch (e) {
throw e;
}
return (new RegExp('^' + currentRegex + '$'));
}
// DIVISOR
function isOptional(currentPos) {
return UtilService.inArray(currentPos, optionalIndexes);
}
function isDivisor(currentPos) {
return UtilService.inArray(currentPos, divisors);
}
function generateOptionalDivisors() {
function sortNumber(a, b) {
return a - b;
}
var sortedDivisors = divisors.sort(sortNumber);
var sortedOptionals = optionalIndexes.sort(sortNumber);
for (var i = 0; i < sortedDivisors.length; i++) {
var divisor = sortedDivisors[i];
for (var j = 1; j <= sortedOptionals.length; j++) {
var optional = sortedOptionals[(j - 1)];
if (optional >= divisor) {
break;
}
if (optionalDivisors[divisor]) {
optionalDivisors[divisor] = optionalDivisors[divisor].concat(divisor - j);
} else {
optionalDivisors[divisor] = [(divisor - j)];
}
// get the original divisor for alternative divisor
divisorElements[(divisor - j)] = divisorElements[divisor];
}
}
}
function removeDivisors(value) {
value = value.toString();
try {
if (divisors.length > 0 && value) {
var keys = Object.keys(divisorElements);
var elments = [];
for (var i = keys.length - 1; i >= 0; i--) {
var divisor = divisorElements[keys[i]];
if (divisor) {
elments.push(divisor);
}
}
elments = UtilService.uniqueArray(elments);
// remove if it is not pattern
var regex = new RegExp(('[' + '\\' + elments.join('\\') + ']'), 'g');
return value.replace(regex, '');
} else {
return value;
}
} catch (e) {
throw e;
}
}
function insertDivisors(array, combination) {
function insert(array, output) {
var out = output;
for (var i = 0; i < array.length; i++) {
var divisor = array[i];
if (divisor < out.length) {
out.splice(divisor, 0, divisorElements[divisor]);
}
}
return out;
}
var output = array;
var divs = divisors.filter(function(it) {
var optionalDivisorsKeys = Object.keys(optionalDivisors).map(function(it) {
return parseInt(it);
});
return !UtilService.inArray(it, combination) && !UtilService.inArray(it, optionalDivisorsKeys);
});
if (!angular.isArray(array) || !angular.isArray(combination)) {
return output;
}
// insert not optional divisors
output = insert(divs, output);
// insert optional divisors
output = insert(combination, output);
return output;
}
function tryDivisorConfiguration(value) {
var output = value.split('');
var defaultDivisors = true;
// has optional?
if (optionalIndexes.length > 0) {
var lazyArguments = [];
var optionalDivisorsKeys = Object.keys(optionalDivisors);
// get all optional divisors as array of arrays [[], [], []...]
for (var i = 0; i < optionalDivisorsKeys.length; i++) {
var val = optionalDivisors[optionalDivisorsKeys[i]];
lazyArguments.push(val);
}
// generate all possible configurations
if (optionalDivisorsCombinations.length === 0) {
UtilService.lazyProduct(lazyArguments, function() {
// convert arguments to array
optionalDivisorsCombinations.push(Array.prototype.slice.call(arguments));
});
}
for (var i = optionalDivisorsCombinations.length - 1; i >= 0; i--) {
var outputClone = angular.copy(output);
outputClone = insertDivisors(outputClone, optionalDivisorsCombinations[i]);
// try validation
var viewValueWithDivisors = outputClone.join('');
var regex = getRegex(maskWithoutOptionals.length - 1);
if (regex.test(viewValueWithDivisors)) {
defaultDivisors = false;
output = outputClone;
break;
}
}
}
if (defaultDivisors) {
output = insertDivisors(output, divisors);
}
return output.join('');
}
// MASK
function getOptions() {
return options;
}
function getViewValue(value) {
try {
var outputWithoutDivisors = removeDivisors(value);
var output = tryDivisorConfiguration(outputWithoutDivisors);
return {
withDivisors: function(capped) {
if (capped) {
return output.substr(0, maskWithoutOptionalsLength);
} else {
return output;
}
},
withoutDivisors: function(capped) {
if (capped) {
return outputWithoutDivisors.substr(0, maskWithoutOptionalsAndDivisorsLength);
} else {
return outputWithoutDivisors;
}
}
};
} catch (e) {
throw e;
}
}
// SELECTOR
function getWrongPositions(viewValueWithDivisors, onlyFirst) {
var pos = [];
if (!viewValueWithDivisors) {
return 0;
}
for (var i = 0; i < viewValueWithDivisors.length; i++) {
var pattern = getRegex(i);
var value = viewValueWithDivisors.substr(0, (i + 1));
if (pattern && !pattern.test(value)) {
pos.push(i);
if (onlyFirst) {
break;
}
}
}
return pos;
}
function getFirstWrongPosition(viewValueWithDivisors) {
return getWrongPositions(viewValueWithDivisors, true)[0];
}
function removeWrongPositions(viewValueWithDivisors) {
var wrongPositions = getWrongPositions(viewValueWithDivisors, false);
var newViewValue = viewValueWithDivisors;
for (var i = 0; i < wrongPositions.length; i++) {
var wrongPosition = wrongPositions[i];
var viewValueArray = viewValueWithDivisors.split('');
viewValueArray.splice(wrongPosition, 1);
newViewValue = viewValueArray.join('');
}
return getViewValue(newViewValue);
}
return {
getViewValue: getViewValue,
generateRegex: generateRegex,
getRegex: getRegex,
getOptions: getOptions,
removeDivisors: removeDivisors,
getFirstWrongPosition: getFirstWrongPosition,
removeWrongPositions: removeWrongPositions
}
}
return {
create: create
}
}]);
})();
(function() {
'use strict';
angular.module('ngMask')
.factory('OptionalService', [function() {
function getOptionalsIndexes(mask) {
var indexes = [];
try {
var regexp = /\?/g;
var match = [];
while ((match = regexp.exec(mask)) != null) {
// Save the optional char
indexes.push((match.index - 1));
}
} catch (e) {
throw e;
}
return {
fromMask: function() {
return indexes;
},
fromMaskWithoutOptionals: function() {
return getOptionalsRelativeMaskWithoutOptionals(indexes);
}
};
}
function getOptionalsRelativeMaskWithoutOptionals(optionals) {
var indexes = [];
for (var i = 0; i < optionals.length; i++) {
indexes.push(optionals[i] - i);
}
return indexes;
}
function removeOptionals(mask) {
var newMask;
try {
newMask = mask.replace(/\?/g, '');
} catch (e) {
throw e;
}
return newMask;
}
return {
removeOptionals: removeOptionals,
getOptionals: getOptionalsIndexes
}
}]);
})();
(function() {
'use strict';
angular.module('ngMask')
.factory('UtilService', [function() {
// sets: an array of arrays
// f: your callback function
// context: [optional] the `this` to use for your callback
// http://phrogz.net/lazy-cartesian-product
function lazyProduct(sets, f, context) {
if (!context) {
context = this;
}
var p = [];
var max = sets.length - 1;
var lens = [];
for (var i = sets.length; i--;) {
lens[i] = sets[i].length;
}
function dive(d) {
var a = sets[d];
var len = lens[d];
if (d === max) {
for (var i = 0; i < len; ++i) {
p[d] = a[i];
f.apply(context, p);
}
} else {
for (var i = 0; i < len; ++i) {
p[d] = a[i];
dive(d + 1);
}
}
p.pop();
}
dive(0);
}
function inArray(i, array) {
var output;
try {
output = array.indexOf(i) > -1;
} catch (e) {
throw e;
}
return output;
}
function uniqueArray(array) {
var u = {};
var a = [];
for (var i = 0, l = array.length; i < l; ++i) {
if (u.hasOwnProperty(array[i])) {
continue;
}
a.push(array[i]);
u[array[i]] = 1;
}
return a;
}
return {
lazyProduct: lazyProduct,
inArray: inArray,
uniqueArray: uniqueArray
}
}]);
})();