Codebase list python-xstatic-tv4 / 253cc21
Initial commit Rob Cresswell 7 years ago
13 changed file(s) with 1854 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 *.pyc
1 *.sw?
2 *.sqlite3
3 .DS_STORE
4 *.egg-info
5 .venv
6 .tox
7 build
8 dist
0 [gerrit]
1 host=review.openstack.org
2 port=29418
3 project=openstack/xstatic-tv4.git
0 The MIT License
1
2 Copyright (c) 2010-2014 Google, Inc. http://angularjs.org
3
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
10
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 THE SOFTWARE.
21
0 include README.txt
1 recursive-include xstatic/pkg/tv4 *
2
3 global-exclude *.pyc
4 global-exclude *.pyo
5 global-exclude *.orig
6 global-exclude *.rej
7
0 XStatic-Angular
1 ---------------
2
3 Angular JavaScript library packaged for setuptools (easy_install) / pip.
4
5 This package is intended to be used by **any** project that needs these files.
6
7 It intentionally does **not** provide any extra code except some metadata
8 **nor** has any extra requirements. You MAY use some minimal support code from
9 the XStatic base package, if you like.
10
11 You can find more info about the xstatic packaging way in the package `XStatic`.
12
0 from xstatic.pkg import tv4 as xs
1
2 # The README.txt file should be written in reST so that PyPI can use
3 # it to generate your project's PyPI page.
4 long_description = open('README.txt').read()
5
6 from setuptools import setup, find_packages
7
8 setup(
9 name=xs.PACKAGE_NAME,
10 version=xs.PACKAGE_VERSION,
11 description=xs.DESCRIPTION,
12 long_description=long_description,
13 classifiers=xs.CLASSIFIERS,
14 keywords=xs.KEYWORDS,
15 maintainer=xs.MAINTAINER,
16 maintainer_email=xs.MAINTAINER_EMAIL,
17 license=xs.LICENSE,
18 url=xs.HOMEPAGE,
19 platforms=xs.PLATFORMS,
20 packages=find_packages(),
21 namespace_packages=['xstatic', 'xstatic.pkg', ],
22 include_package_data=True,
23 zip_safe=False,
24 install_requires=[], # nothing! :)
25 # if you like, you MAY use the 'XStatic' package.
26 )
0 [tox]
1 minversion = 1.6
2 skipsdist = True
3 envlist = py27,py33,py34
4
5 [testenv:venv]
6 commands = {posargs}
7
0 __import__('pkg_resources').declare_namespace(__name__)
0 __import__('pkg_resources').declare_namespace(__name__)
0 """
1 XStatic resource package
2
3 See package 'XStatic' for documentation and basic tools.
4 """
5
6 DISPLAY_NAME = 'tv4' # official name, upper/lowercase allowed, no spaces
7 PACKAGE_NAME = 'XStatic-%s' % DISPLAY_NAME # name used for PyPi
8
9 NAME = __name__.split('.')[-1] # package name (e.g. 'foo' or 'foo_bar')
10 # please use a all-lowercase valid python
11 # package name
12
13 VERSION = '1.2.7' # version of the packaged files, please use the upstream
14 # version number
15 BUILD = '0' # our package build number, so we can release new builds
16 # with fixes for xstatic stuff.
17 PACKAGE_VERSION = VERSION + '.' + BUILD # version used for PyPi
18
19 DESCRIPTION = "%s %s (XStatic packaging standard)" % (DISPLAY_NAME, VERSION)
20
21 PLATFORMS = 'any'
22 CLASSIFIERS = []
23 KEYWORDS = '%s xstatic' % NAME
24
25 # XStatic-* package maintainer:
26 MAINTAINER = 'Rob Cresswell'
27 MAINTAINER_EMAIL = 'robert.cresswell@outlook.com'
28
29 # this refers to the project homepage of the stuff we packaged:
30 HOMEPAGE = 'http://geraintluff.github.com/tv4/'
31
32 # this refers to all files:
33 LICENSE = 'https://github.com/geraintluff/tv4/blob/master/LICENSE.txt'
34
35 from os.path import join, dirname
36 BASE_DIR = join(dirname(__file__), 'data')
37 # linux package maintainers just can point to their file locations like this:
38 #BASE_DIR = '/usr/share/javascript/angular-schema-form'
39
40 LOCATIONS = {
41 # CDN locations (if no public CDN exists, use an empty dict)
42 # if value is a string, it is a base location, just append relative
43 # path/filename. if value is a dict, do another lookup using the
44 # relative path/filename you want.
45 # your relative path/filenames should usually be without version
46 # information, because either the base dir/url is exactly for this
47 # version or the mapping will care for accessing this version.
48 }
0 // Provides support for asynchronous validation (fetching schemas) using jQuery
1 // Callback is optional third argument to tv4.validate() - if not present, synchronous operation
2 // callback(result, error);
3 if (typeof (tv4.asyncValidate) === 'undefined') {
4 tv4.syncValidate = tv4.validate;
5 tv4.validate = function (data, schema, callback, checkRecursive, banUnknownProperties) {
6 if (typeof (callback) === 'undefined') {
7 return this.syncValidate(data, schema, checkRecursive, banUnknownProperties);
8 } else {
9 return this.asyncValidate(data, schema, callback, checkRecursive, banUnknownProperties);
10 }
11 };
12 tv4.asyncValidate = function (data, schema, callback, checkRecursive, banUnknownProperties) {
13 var $ = jQuery;
14 var result = tv4.validate(data, schema, checkRecursive, banUnknownProperties);
15 if (!tv4.missing.length) {
16 callback(result, tv4.error);
17 } else {
18 // Make a request for each missing schema
19 var missingSchemas = $.map(tv4.missing, function (schemaUri) {
20 return $.getJSON(schemaUri).success(function (fetchedSchema) {
21 tv4.addSchema(schemaUri, fetchedSchema);
22 }).error(function () {
23 // If there's an error, just use an empty schema
24 tv4.addSchema(schemaUri, {});
25 });
26 });
27 // When all requests done, try again
28 $.when.apply($, missingSchemas).done(function () {
29 var result = tv4.asyncValidate(data, schema, callback, checkRecursive, banUnknownProperties);
30 });
31 }
32 };
33 }
0 /*
1 Author: Geraint Luff and others
2 Year: 2013
3
4 This code is released into the "public domain" by its author(s). Anybody may use, alter and distribute the code without restriction. The author makes no guarantees, and takes no liability of any kind for use of this code.
5
6 If you find a bug or make an improvement, it would be courteous to let the author know, but it is not compulsory.
7 */
8 (function (global, factory) {
9 if (typeof define === 'function' && define.amd) {
10 // AMD. Register as an anonymous module.
11 define([], factory);
12 } else if (typeof module !== 'undefined' && module.exports){
13 // CommonJS. Define export.
14 module.exports = factory();
15 } else {
16 // Browser globals
17 global.tv4 = factory();
18 }
19 }(this, function () {
20
21 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FGlobal_Objects%2FObject%2Fkeys
22 if (!Object.keys) {
23 Object.keys = (function () {
24 var hasOwnProperty = Object.prototype.hasOwnProperty,
25 hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),
26 dontEnums = [
27 'toString',
28 'toLocaleString',
29 'valueOf',
30 'hasOwnProperty',
31 'isPrototypeOf',
32 'propertyIsEnumerable',
33 'constructor'
34 ],
35 dontEnumsLength = dontEnums.length;
36
37 return function (obj) {
38 if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) {
39 throw new TypeError('Object.keys called on non-object');
40 }
41
42 var result = [];
43
44 for (var prop in obj) {
45 if (hasOwnProperty.call(obj, prop)) {
46 result.push(prop);
47 }
48 }
49
50 if (hasDontEnumBug) {
51 for (var i=0; i < dontEnumsLength; i++) {
52 if (hasOwnProperty.call(obj, dontEnums[i])) {
53 result.push(dontEnums[i]);
54 }
55 }
56 }
57 return result;
58 };
59 })();
60 }
61 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create
62 if (!Object.create) {
63 Object.create = (function(){
64 function F(){}
65
66 return function(o){
67 if (arguments.length !== 1) {
68 throw new Error('Object.create implementation only accepts one parameter.');
69 }
70 F.prototype = o;
71 return new F();
72 };
73 })();
74 }
75 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FGlobal_Objects%2FArray%2FisArray
76 if(!Array.isArray) {
77 Array.isArray = function (vArg) {
78 return Object.prototype.toString.call(vArg) === "[object Array]";
79 };
80 }
81 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FGlobal_Objects%2FArray%2FindexOf
82 if (!Array.prototype.indexOf) {
83 Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
84 if (this === null) {
85 throw new TypeError();
86 }
87 var t = Object(this);
88 var len = t.length >>> 0;
89
90 if (len === 0) {
91 return -1;
92 }
93 var n = 0;
94 if (arguments.length > 1) {
95 n = Number(arguments[1]);
96 if (n !== n) { // shortcut for verifying if it's NaN
97 n = 0;
98 } else if (n !== 0 && n !== Infinity && n !== -Infinity) {
99 n = (n > 0 || -1) * Math.floor(Math.abs(n));
100 }
101 }
102 if (n >= len) {
103 return -1;
104 }
105 var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
106 for (; k < len; k++) {
107 if (k in t && t[k] === searchElement) {
108 return k;
109 }
110 }
111 return -1;
112 };
113 }
114
115 // Grungey Object.isFrozen hack
116 if (!Object.isFrozen) {
117 Object.isFrozen = function (obj) {
118 var key = "tv4_test_frozen_key";
119 while (obj.hasOwnProperty(key)) {
120 key += Math.random();
121 }
122 try {
123 obj[key] = true;
124 delete obj[key];
125 return false;
126 } catch (e) {
127 return true;
128 }
129 };
130 }
131 // Based on: https://github.com/geraintluff/uri-templates, but with all the de-substitution stuff removed
132
133 var uriTemplateGlobalModifiers = {
134 "+": true,
135 "#": true,
136 ".": true,
137 "/": true,
138 ";": true,
139 "?": true,
140 "&": true
141 };
142 var uriTemplateSuffices = {
143 "*": true
144 };
145
146 function notReallyPercentEncode(string) {
147 return encodeURI(string).replace(/%25[0-9][0-9]/g, function (doubleEncoded) {
148 return "%" + doubleEncoded.substring(3);
149 });
150 }
151
152 function uriTemplateSubstitution(spec) {
153 var modifier = "";
154 if (uriTemplateGlobalModifiers[spec.charAt(0)]) {
155 modifier = spec.charAt(0);
156 spec = spec.substring(1);
157 }
158 var separator = "";
159 var prefix = "";
160 var shouldEscape = true;
161 var showVariables = false;
162 var trimEmptyString = false;
163 if (modifier === '+') {
164 shouldEscape = false;
165 } else if (modifier === ".") {
166 prefix = ".";
167 separator = ".";
168 } else if (modifier === "/") {
169 prefix = "/";
170 separator = "/";
171 } else if (modifier === '#') {
172 prefix = "#";
173 shouldEscape = false;
174 } else if (modifier === ';') {
175 prefix = ";";
176 separator = ";";
177 showVariables = true;
178 trimEmptyString = true;
179 } else if (modifier === '?') {
180 prefix = "?";
181 separator = "&";
182 showVariables = true;
183 } else if (modifier === '&') {
184 prefix = "&";
185 separator = "&";
186 showVariables = true;
187 }
188
189 var varNames = [];
190 var varList = spec.split(",");
191 var varSpecs = [];
192 var varSpecMap = {};
193 for (var i = 0; i < varList.length; i++) {
194 var varName = varList[i];
195 var truncate = null;
196 if (varName.indexOf(":") !== -1) {
197 var parts = varName.split(":");
198 varName = parts[0];
199 truncate = parseInt(parts[1], 10);
200 }
201 var suffices = {};
202 while (uriTemplateSuffices[varName.charAt(varName.length - 1)]) {
203 suffices[varName.charAt(varName.length - 1)] = true;
204 varName = varName.substring(0, varName.length - 1);
205 }
206 var varSpec = {
207 truncate: truncate,
208 name: varName,
209 suffices: suffices
210 };
211 varSpecs.push(varSpec);
212 varSpecMap[varName] = varSpec;
213 varNames.push(varName);
214 }
215 var subFunction = function (valueFunction) {
216 var result = "";
217 var startIndex = 0;
218 for (var i = 0; i < varSpecs.length; i++) {
219 var varSpec = varSpecs[i];
220 var value = valueFunction(varSpec.name);
221 if (value === null || value === undefined || (Array.isArray(value) && value.length === 0) || (typeof value === 'object' && Object.keys(value).length === 0)) {
222 startIndex++;
223 continue;
224 }
225 if (i === startIndex) {
226 result += prefix;
227 } else {
228 result += (separator || ",");
229 }
230 if (Array.isArray(value)) {
231 if (showVariables) {
232 result += varSpec.name + "=";
233 }
234 for (var j = 0; j < value.length; j++) {
235 if (j > 0) {
236 result += varSpec.suffices['*'] ? (separator || ",") : ",";
237 if (varSpec.suffices['*'] && showVariables) {
238 result += varSpec.name + "=";
239 }
240 }
241 result += shouldEscape ? encodeURIComponent(value[j]).replace(/!/g, "%21") : notReallyPercentEncode(value[j]);
242 }
243 } else if (typeof value === "object") {
244 if (showVariables && !varSpec.suffices['*']) {
245 result += varSpec.name + "=";
246 }
247 var first = true;
248 for (var key in value) {
249 if (!first) {
250 result += varSpec.suffices['*'] ? (separator || ",") : ",";
251 }
252 first = false;
253 result += shouldEscape ? encodeURIComponent(key).replace(/!/g, "%21") : notReallyPercentEncode(key);
254 result += varSpec.suffices['*'] ? '=' : ",";
255 result += shouldEscape ? encodeURIComponent(value[key]).replace(/!/g, "%21") : notReallyPercentEncode(value[key]);
256 }
257 } else {
258 if (showVariables) {
259 result += varSpec.name;
260 if (!trimEmptyString || value !== "") {
261 result += "=";
262 }
263 }
264 if (varSpec.truncate != null) {
265 value = value.substring(0, varSpec.truncate);
266 }
267 result += shouldEscape ? encodeURIComponent(value).replace(/!/g, "%21"): notReallyPercentEncode(value);
268 }
269 }
270 return result;
271 };
272 subFunction.varNames = varNames;
273 return {
274 prefix: prefix,
275 substitution: subFunction
276 };
277 }
278
279 function UriTemplate(template) {
280 if (!(this instanceof UriTemplate)) {
281 return new UriTemplate(template);
282 }
283 var parts = template.split("{");
284 var textParts = [parts.shift()];
285 var prefixes = [];
286 var substitutions = [];
287 var varNames = [];
288 while (parts.length > 0) {
289 var part = parts.shift();
290 var spec = part.split("}")[0];
291 var remainder = part.substring(spec.length + 1);
292 var funcs = uriTemplateSubstitution(spec);
293 substitutions.push(funcs.substitution);
294 prefixes.push(funcs.prefix);
295 textParts.push(remainder);
296 varNames = varNames.concat(funcs.substitution.varNames);
297 }
298 this.fill = function (valueFunction) {
299 var result = textParts[0];
300 for (var i = 0; i < substitutions.length; i++) {
301 var substitution = substitutions[i];
302 result += substitution(valueFunction);
303 result += textParts[i + 1];
304 }
305 return result;
306 };
307 this.varNames = varNames;
308 this.template = template;
309 }
310 UriTemplate.prototype = {
311 toString: function () {
312 return this.template;
313 },
314 fillFromObject: function (obj) {
315 return this.fill(function (varName) {
316 return obj[varName];
317 });
318 }
319 };
320 var ValidatorContext = function ValidatorContext(parent, collectMultiple, errorReporter, checkRecursive, trackUnknownProperties) {
321 this.missing = [];
322 this.missingMap = {};
323 this.formatValidators = parent ? Object.create(parent.formatValidators) : {};
324 this.schemas = parent ? Object.create(parent.schemas) : {};
325 this.collectMultiple = collectMultiple;
326 this.errors = [];
327 this.handleError = collectMultiple ? this.collectError : this.returnError;
328 if (checkRecursive) {
329 this.checkRecursive = true;
330 this.scanned = [];
331 this.scannedFrozen = [];
332 this.scannedFrozenSchemas = [];
333 this.scannedFrozenValidationErrors = [];
334 this.validatedSchemasKey = 'tv4_validation_id';
335 this.validationErrorsKey = 'tv4_validation_errors_id';
336 }
337 if (trackUnknownProperties) {
338 this.trackUnknownProperties = true;
339 this.knownPropertyPaths = {};
340 this.unknownPropertyPaths = {};
341 }
342 this.errorReporter = errorReporter || defaultErrorReporter('en');
343 if (typeof this.errorReporter === 'string') {
344 throw new Error('debug');
345 }
346 this.definedKeywords = {};
347 if (parent) {
348 for (var key in parent.definedKeywords) {
349 this.definedKeywords[key] = parent.definedKeywords[key].slice(0);
350 }
351 }
352 };
353 ValidatorContext.prototype.defineKeyword = function (keyword, keywordFunction) {
354 this.definedKeywords[keyword] = this.definedKeywords[keyword] || [];
355 this.definedKeywords[keyword].push(keywordFunction);
356 };
357 ValidatorContext.prototype.createError = function (code, messageParams, dataPath, schemaPath, subErrors, data, schema) {
358 var error = new ValidationError(code, messageParams, dataPath, schemaPath, subErrors);
359 error.message = this.errorReporter(error, data, schema);
360 return error;
361 };
362 ValidatorContext.prototype.returnError = function (error) {
363 return error;
364 };
365 ValidatorContext.prototype.collectError = function (error) {
366 if (error) {
367 this.errors.push(error);
368 }
369 return null;
370 };
371 ValidatorContext.prototype.prefixErrors = function (startIndex, dataPath, schemaPath) {
372 for (var i = startIndex; i < this.errors.length; i++) {
373 this.errors[i] = this.errors[i].prefixWith(dataPath, schemaPath);
374 }
375 return this;
376 };
377 ValidatorContext.prototype.banUnknownProperties = function (data, schema) {
378 for (var unknownPath in this.unknownPropertyPaths) {
379 var error = this.createError(ErrorCodes.UNKNOWN_PROPERTY, {path: unknownPath}, unknownPath, "", null, data, schema);
380 var result = this.handleError(error);
381 if (result) {
382 return result;
383 }
384 }
385 return null;
386 };
387
388 ValidatorContext.prototype.addFormat = function (format, validator) {
389 if (typeof format === 'object') {
390 for (var key in format) {
391 this.addFormat(key, format[key]);
392 }
393 return this;
394 }
395 this.formatValidators[format] = validator;
396 };
397 ValidatorContext.prototype.resolveRefs = function (schema, urlHistory) {
398 if (schema['$ref'] !== undefined) {
399 urlHistory = urlHistory || {};
400 if (urlHistory[schema['$ref']]) {
401 return this.createError(ErrorCodes.CIRCULAR_REFERENCE, {urls: Object.keys(urlHistory).join(', ')}, '', '', null, undefined, schema);
402 }
403 urlHistory[schema['$ref']] = true;
404 schema = this.getSchema(schema['$ref'], urlHistory);
405 }
406 return schema;
407 };
408 ValidatorContext.prototype.getSchema = function (url, urlHistory) {
409 var schema;
410 if (this.schemas[url] !== undefined) {
411 schema = this.schemas[url];
412 return this.resolveRefs(schema, urlHistory);
413 }
414 var baseUrl = url;
415 var fragment = "";
416 if (url.indexOf('#') !== -1) {
417 fragment = url.substring(url.indexOf("#") + 1);
418 baseUrl = url.substring(0, url.indexOf("#"));
419 }
420 if (typeof this.schemas[baseUrl] === 'object') {
421 schema = this.schemas[baseUrl];
422 var pointerPath = decodeURIComponent(fragment);
423 if (pointerPath === "") {
424 return this.resolveRefs(schema, urlHistory);
425 } else if (pointerPath.charAt(0) !== "/") {
426 return undefined;
427 }
428 var parts = pointerPath.split("/").slice(1);
429 for (var i = 0; i < parts.length; i++) {
430 var component = parts[i].replace(/~1/g, "/").replace(/~0/g, "~");
431 if (schema[component] === undefined) {
432 schema = undefined;
433 break;
434 }
435 schema = schema[component];
436 }
437 if (schema !== undefined) {
438 return this.resolveRefs(schema, urlHistory);
439 }
440 }
441 if (this.missing[baseUrl] === undefined) {
442 this.missing.push(baseUrl);
443 this.missing[baseUrl] = baseUrl;
444 this.missingMap[baseUrl] = baseUrl;
445 }
446 };
447 ValidatorContext.prototype.searchSchemas = function (schema, url) {
448 if (Array.isArray(schema)) {
449 for (var i = 0; i < schema.length; i++) {
450 this.searchSchemas(schema[i], url);
451 }
452 } else if (schema && typeof schema === "object") {
453 if (typeof schema.id === "string") {
454 if (isTrustedUrl(url, schema.id)) {
455 if (this.schemas[schema.id] === undefined) {
456 this.schemas[schema.id] = schema;
457 }
458 }
459 }
460 for (var key in schema) {
461 if (key !== "enum") {
462 if (typeof schema[key] === "object") {
463 this.searchSchemas(schema[key], url);
464 } else if (key === "$ref") {
465 var uri = getDocumentUri(schema[key]);
466 if (uri && this.schemas[uri] === undefined && this.missingMap[uri] === undefined) {
467 this.missingMap[uri] = uri;
468 }
469 }
470 }
471 }
472 }
473 };
474 ValidatorContext.prototype.addSchema = function (url, schema) {
475 //overload
476 if (typeof url !== 'string' || typeof schema === 'undefined') {
477 if (typeof url === 'object' && typeof url.id === 'string') {
478 schema = url;
479 url = schema.id;
480 }
481 else {
482 return;
483 }
484 }
485 if (url === getDocumentUri(url) + "#") {
486 // Remove empty fragment
487 url = getDocumentUri(url);
488 }
489 this.schemas[url] = schema;
490 delete this.missingMap[url];
491 normSchema(schema, url);
492 this.searchSchemas(schema, url);
493 };
494
495 ValidatorContext.prototype.getSchemaMap = function () {
496 var map = {};
497 for (var key in this.schemas) {
498 map[key] = this.schemas[key];
499 }
500 return map;
501 };
502
503 ValidatorContext.prototype.getSchemaUris = function (filterRegExp) {
504 var list = [];
505 for (var key in this.schemas) {
506 if (!filterRegExp || filterRegExp.test(key)) {
507 list.push(key);
508 }
509 }
510 return list;
511 };
512
513 ValidatorContext.prototype.getMissingUris = function (filterRegExp) {
514 var list = [];
515 for (var key in this.missingMap) {
516 if (!filterRegExp || filterRegExp.test(key)) {
517 list.push(key);
518 }
519 }
520 return list;
521 };
522
523 ValidatorContext.prototype.dropSchemas = function () {
524 this.schemas = {};
525 this.reset();
526 };
527 ValidatorContext.prototype.reset = function () {
528 this.missing = [];
529 this.missingMap = {};
530 this.errors = [];
531 };
532
533 ValidatorContext.prototype.validateAll = function (data, schema, dataPathParts, schemaPathParts, dataPointerPath) {
534 var topLevel;
535 schema = this.resolveRefs(schema);
536 if (!schema) {
537 return null;
538 } else if (schema instanceof ValidationError) {
539 this.errors.push(schema);
540 return schema;
541 }
542
543 var startErrorCount = this.errors.length;
544 var frozenIndex, scannedFrozenSchemaIndex = null, scannedSchemasIndex = null;
545 if (this.checkRecursive && data && typeof data === 'object') {
546 topLevel = !this.scanned.length;
547 if (data[this.validatedSchemasKey]) {
548 var schemaIndex = data[this.validatedSchemasKey].indexOf(schema);
549 if (schemaIndex !== -1) {
550 this.errors = this.errors.concat(data[this.validationErrorsKey][schemaIndex]);
551 return null;
552 }
553 }
554 if (Object.isFrozen(data)) {
555 frozenIndex = this.scannedFrozen.indexOf(data);
556 if (frozenIndex !== -1) {
557 var frozenSchemaIndex = this.scannedFrozenSchemas[frozenIndex].indexOf(schema);
558 if (frozenSchemaIndex !== -1) {
559 this.errors = this.errors.concat(this.scannedFrozenValidationErrors[frozenIndex][frozenSchemaIndex]);
560 return null;
561 }
562 }
563 }
564 this.scanned.push(data);
565 if (Object.isFrozen(data)) {
566 if (frozenIndex === -1) {
567 frozenIndex = this.scannedFrozen.length;
568 this.scannedFrozen.push(data);
569 this.scannedFrozenSchemas.push([]);
570 }
571 scannedFrozenSchemaIndex = this.scannedFrozenSchemas[frozenIndex].length;
572 this.scannedFrozenSchemas[frozenIndex][scannedFrozenSchemaIndex] = schema;
573 this.scannedFrozenValidationErrors[frozenIndex][scannedFrozenSchemaIndex] = [];
574 } else {
575 if (!data[this.validatedSchemasKey]) {
576 try {
577 Object.defineProperty(data, this.validatedSchemasKey, {
578 value: [],
579 configurable: true
580 });
581 Object.defineProperty(data, this.validationErrorsKey, {
582 value: [],
583 configurable: true
584 });
585 } catch (e) {
586 //IE 7/8 workaround
587 data[this.validatedSchemasKey] = [];
588 data[this.validationErrorsKey] = [];
589 }
590 }
591 scannedSchemasIndex = data[this.validatedSchemasKey].length;
592 data[this.validatedSchemasKey][scannedSchemasIndex] = schema;
593 data[this.validationErrorsKey][scannedSchemasIndex] = [];
594 }
595 }
596
597 var errorCount = this.errors.length;
598 var error = this.validateBasic(data, schema, dataPointerPath)
599 || this.validateNumeric(data, schema, dataPointerPath)
600 || this.validateString(data, schema, dataPointerPath)
601 || this.validateArray(data, schema, dataPointerPath)
602 || this.validateObject(data, schema, dataPointerPath)
603 || this.validateCombinations(data, schema, dataPointerPath)
604 || this.validateHypermedia(data, schema, dataPointerPath)
605 || this.validateFormat(data, schema, dataPointerPath)
606 || this.validateDefinedKeywords(data, schema, dataPointerPath)
607 || null;
608
609 if (topLevel) {
610 while (this.scanned.length) {
611 var item = this.scanned.pop();
612 delete item[this.validatedSchemasKey];
613 }
614 this.scannedFrozen = [];
615 this.scannedFrozenSchemas = [];
616 }
617
618 if (error || errorCount !== this.errors.length) {
619 while ((dataPathParts && dataPathParts.length) || (schemaPathParts && schemaPathParts.length)) {
620 var dataPart = (dataPathParts && dataPathParts.length) ? "" + dataPathParts.pop() : null;
621 var schemaPart = (schemaPathParts && schemaPathParts.length) ? "" + schemaPathParts.pop() : null;
622 if (error) {
623 error = error.prefixWith(dataPart, schemaPart);
624 }
625 this.prefixErrors(errorCount, dataPart, schemaPart);
626 }
627 }
628
629 if (scannedFrozenSchemaIndex !== null) {
630 this.scannedFrozenValidationErrors[frozenIndex][scannedFrozenSchemaIndex] = this.errors.slice(startErrorCount);
631 } else if (scannedSchemasIndex !== null) {
632 data[this.validationErrorsKey][scannedSchemasIndex] = this.errors.slice(startErrorCount);
633 }
634
635 return this.handleError(error);
636 };
637 ValidatorContext.prototype.validateFormat = function (data, schema) {
638 if (typeof schema.format !== 'string' || !this.formatValidators[schema.format]) {
639 return null;
640 }
641 var errorMessage = this.formatValidators[schema.format].call(null, data, schema);
642 if (typeof errorMessage === 'string' || typeof errorMessage === 'number') {
643 return this.createError(ErrorCodes.FORMAT_CUSTOM, {message: errorMessage}, '', '/format', null, data, schema);
644 } else if (errorMessage && typeof errorMessage === 'object') {
645 return this.createError(ErrorCodes.FORMAT_CUSTOM, {message: errorMessage.message || "?"}, errorMessage.dataPath || '', errorMessage.schemaPath || "/format", null, data, schema);
646 }
647 return null;
648 };
649 ValidatorContext.prototype.validateDefinedKeywords = function (data, schema, dataPointerPath) {
650 for (var key in this.definedKeywords) {
651 if (typeof schema[key] === 'undefined') {
652 continue;
653 }
654 var validationFunctions = this.definedKeywords[key];
655 for (var i = 0; i < validationFunctions.length; i++) {
656 var func = validationFunctions[i];
657 var result = func(data, schema[key], schema, dataPointerPath);
658 if (typeof result === 'string' || typeof result === 'number') {
659 return this.createError(ErrorCodes.KEYWORD_CUSTOM, {key: key, message: result}, '', '', null, data, schema).prefixWith(null, key);
660 } else if (result && typeof result === 'object') {
661 var code = result.code;
662 if (typeof code === 'string') {
663 if (!ErrorCodes[code]) {
664 throw new Error('Undefined error code (use defineError): ' + code);
665 }
666 code = ErrorCodes[code];
667 } else if (typeof code !== 'number') {
668 code = ErrorCodes.KEYWORD_CUSTOM;
669 }
670 var messageParams = (typeof result.message === 'object') ? result.message : {key: key, message: result.message || "?"};
671 var schemaPath = result.schemaPath || ("/" + key.replace(/~/g, '~0').replace(/\//g, '~1'));
672 return this.createError(code, messageParams, result.dataPath || null, schemaPath, null, data, schema);
673 }
674 }
675 }
676 return null;
677 };
678
679 function recursiveCompare(A, B) {
680 if (A === B) {
681 return true;
682 }
683 if (A && B && typeof A === "object" && typeof B === "object") {
684 if (Array.isArray(A) !== Array.isArray(B)) {
685 return false;
686 } else if (Array.isArray(A)) {
687 if (A.length !== B.length) {
688 return false;
689 }
690 for (var i = 0; i < A.length; i++) {
691 if (!recursiveCompare(A[i], B[i])) {
692 return false;
693 }
694 }
695 } else {
696 var key;
697 for (key in A) {
698 if (B[key] === undefined && A[key] !== undefined) {
699 return false;
700 }
701 }
702 for (key in B) {
703 if (A[key] === undefined && B[key] !== undefined) {
704 return false;
705 }
706 }
707 for (key in A) {
708 if (!recursiveCompare(A[key], B[key])) {
709 return false;
710 }
711 }
712 }
713 return true;
714 }
715 return false;
716 }
717
718 ValidatorContext.prototype.validateBasic = function validateBasic(data, schema, dataPointerPath) {
719 var error;
720 if (error = this.validateType(data, schema, dataPointerPath)) {
721 return error.prefixWith(null, "type");
722 }
723 if (error = this.validateEnum(data, schema, dataPointerPath)) {
724 return error.prefixWith(null, "type");
725 }
726 return null;
727 };
728
729 ValidatorContext.prototype.validateType = function validateType(data, schema) {
730 if (schema.type === undefined) {
731 return null;
732 }
733 var dataType = typeof data;
734 if (data === null) {
735 dataType = "null";
736 } else if (Array.isArray(data)) {
737 dataType = "array";
738 }
739 var allowedTypes = schema.type;
740 if (!Array.isArray(allowedTypes)) {
741 allowedTypes = [allowedTypes];
742 }
743
744 for (var i = 0; i < allowedTypes.length; i++) {
745 var type = allowedTypes[i];
746 if (type === dataType || (type === "integer" && dataType === "number" && (data % 1 === 0))) {
747 return null;
748 }
749 }
750 return this.createError(ErrorCodes.INVALID_TYPE, {type: dataType, expected: allowedTypes.join("/")}, '', '', null, data, schema);
751 };
752
753 ValidatorContext.prototype.validateEnum = function validateEnum(data, schema) {
754 if (schema["enum"] === undefined) {
755 return null;
756 }
757 for (var i = 0; i < schema["enum"].length; i++) {
758 var enumVal = schema["enum"][i];
759 if (recursiveCompare(data, enumVal)) {
760 return null;
761 }
762 }
763 return this.createError(ErrorCodes.ENUM_MISMATCH, {value: (typeof JSON !== 'undefined') ? JSON.stringify(data) : data}, '', '', null, data, schema);
764 };
765
766 ValidatorContext.prototype.validateNumeric = function validateNumeric(data, schema, dataPointerPath) {
767 return this.validateMultipleOf(data, schema, dataPointerPath)
768 || this.validateMinMax(data, schema, dataPointerPath)
769 || this.validateNaN(data, schema, dataPointerPath)
770 || null;
771 };
772
773 var CLOSE_ENOUGH_LOW = Math.pow(2, -51);
774 var CLOSE_ENOUGH_HIGH = 1 - CLOSE_ENOUGH_LOW;
775 ValidatorContext.prototype.validateMultipleOf = function validateMultipleOf(data, schema) {
776 var multipleOf = schema.multipleOf || schema.divisibleBy;
777 if (multipleOf === undefined) {
778 return null;
779 }
780 if (typeof data === "number") {
781 var remainder = (data/multipleOf)%1;
782 if (remainder >= CLOSE_ENOUGH_LOW && remainder < CLOSE_ENOUGH_HIGH) {
783 return this.createError(ErrorCodes.NUMBER_MULTIPLE_OF, {value: data, multipleOf: multipleOf}, '', '', null, data, schema);
784 }
785 }
786 return null;
787 };
788
789 ValidatorContext.prototype.validateMinMax = function validateMinMax(data, schema) {
790 if (typeof data !== "number") {
791 return null;
792 }
793 if (schema.minimum !== undefined) {
794 if (data < schema.minimum) {
795 return this.createError(ErrorCodes.NUMBER_MINIMUM, {value: data, minimum: schema.minimum}, '', '/minimum', null, data, schema);
796 }
797 if (schema.exclusiveMinimum && data === schema.minimum) {
798 return this.createError(ErrorCodes.NUMBER_MINIMUM_EXCLUSIVE, {value: data, minimum: schema.minimum}, '', '/exclusiveMinimum', null, data, schema);
799 }
800 }
801 if (schema.maximum !== undefined) {
802 if (data > schema.maximum) {
803 return this.createError(ErrorCodes.NUMBER_MAXIMUM, {value: data, maximum: schema.maximum}, '', '/maximum', null, data, schema);
804 }
805 if (schema.exclusiveMaximum && data === schema.maximum) {
806 return this.createError(ErrorCodes.NUMBER_MAXIMUM_EXCLUSIVE, {value: data, maximum: schema.maximum}, '', '/exclusiveMaximum', null, data, schema);
807 }
808 }
809 return null;
810 };
811
812 ValidatorContext.prototype.validateNaN = function validateNaN(data, schema) {
813 if (typeof data !== "number") {
814 return null;
815 }
816 if (isNaN(data) === true || data === Infinity || data === -Infinity) {
817 return this.createError(ErrorCodes.NUMBER_NOT_A_NUMBER, {value: data}, '', '/type', null, data, schema);
818 }
819 return null;
820 };
821
822 ValidatorContext.prototype.validateString = function validateString(data, schema, dataPointerPath) {
823 return this.validateStringLength(data, schema, dataPointerPath)
824 || this.validateStringPattern(data, schema, dataPointerPath)
825 || null;
826 };
827
828 ValidatorContext.prototype.validateStringLength = function validateStringLength(data, schema) {
829 if (typeof data !== "string") {
830 return null;
831 }
832 if (schema.minLength !== undefined) {
833 if (data.length < schema.minLength) {
834 return this.createError(ErrorCodes.STRING_LENGTH_SHORT, {length: data.length, minimum: schema.minLength}, '', '/minLength', null, data, schema);
835 }
836 }
837 if (schema.maxLength !== undefined) {
838 if (data.length > schema.maxLength) {
839 return this.createError(ErrorCodes.STRING_LENGTH_LONG, {length: data.length, maximum: schema.maxLength}, '', '/maxLength', null, data, schema);
840 }
841 }
842 return null;
843 };
844
845 ValidatorContext.prototype.validateStringPattern = function validateStringPattern(data, schema) {
846 if (typeof data !== "string" || (typeof schema.pattern !== "string" && !(schema.pattern instanceof RegExp))) {
847 return null;
848 }
849 var regexp;
850 if (schema.pattern instanceof RegExp) {
851 regexp = schema.pattern;
852 }
853 else {
854 var body, flags = '';
855 // Check for regular expression literals
856 // @see http://www.ecma-international.org/ecma-262/5.1/#sec-7.8.5
857 var literal = schema.pattern.match(/^\/(.+)\/([img]*)$/);
858 if (literal) {
859 body = literal[1];
860 flags = literal[2];
861 }
862 else {
863 body = schema.pattern;
864 }
865 regexp = new RegExp(body, flags);
866 }
867 if (!regexp.test(data)) {
868 return this.createError(ErrorCodes.STRING_PATTERN, {pattern: schema.pattern}, '', '/pattern', null, data, schema);
869 }
870 return null;
871 };
872
873 ValidatorContext.prototype.validateArray = function validateArray(data, schema, dataPointerPath) {
874 if (!Array.isArray(data)) {
875 return null;
876 }
877 return this.validateArrayLength(data, schema, dataPointerPath)
878 || this.validateArrayUniqueItems(data, schema, dataPointerPath)
879 || this.validateArrayItems(data, schema, dataPointerPath)
880 || null;
881 };
882
883 ValidatorContext.prototype.validateArrayLength = function validateArrayLength(data, schema) {
884 var error;
885 if (schema.minItems !== undefined) {
886 if (data.length < schema.minItems) {
887 error = this.createError(ErrorCodes.ARRAY_LENGTH_SHORT, {length: data.length, minimum: schema.minItems}, '', '/minItems', null, data, schema);
888 if (this.handleError(error)) {
889 return error;
890 }
891 }
892 }
893 if (schema.maxItems !== undefined) {
894 if (data.length > schema.maxItems) {
895 error = this.createError(ErrorCodes.ARRAY_LENGTH_LONG, {length: data.length, maximum: schema.maxItems}, '', '/maxItems', null, data, schema);
896 if (this.handleError(error)) {
897 return error;
898 }
899 }
900 }
901 return null;
902 };
903
904 ValidatorContext.prototype.validateArrayUniqueItems = function validateArrayUniqueItems(data, schema) {
905 if (schema.uniqueItems) {
906 for (var i = 0; i < data.length; i++) {
907 for (var j = i + 1; j < data.length; j++) {
908 if (recursiveCompare(data[i], data[j])) {
909 var error = this.createError(ErrorCodes.ARRAY_UNIQUE, {match1: i, match2: j}, '', '/uniqueItems', null, data, schema);
910 if (this.handleError(error)) {
911 return error;
912 }
913 }
914 }
915 }
916 }
917 return null;
918 };
919
920 ValidatorContext.prototype.validateArrayItems = function validateArrayItems(data, schema, dataPointerPath) {
921 if (schema.items === undefined) {
922 return null;
923 }
924 var error, i;
925 if (Array.isArray(schema.items)) {
926 for (i = 0; i < data.length; i++) {
927 if (i < schema.items.length) {
928 if (error = this.validateAll(data[i], schema.items[i], [i], ["items", i], dataPointerPath + "/" + i)) {
929 return error;
930 }
931 } else if (schema.additionalItems !== undefined) {
932 if (typeof schema.additionalItems === "boolean") {
933 if (!schema.additionalItems) {
934 error = (this.createError(ErrorCodes.ARRAY_ADDITIONAL_ITEMS, {}, '/' + i, '/additionalItems', null, data, schema));
935 if (this.handleError(error)) {
936 return error;
937 }
938 }
939 } else if (error = this.validateAll(data[i], schema.additionalItems, [i], ["additionalItems"], dataPointerPath + "/" + i)) {
940 return error;
941 }
942 }
943 }
944 } else {
945 for (i = 0; i < data.length; i++) {
946 if (error = this.validateAll(data[i], schema.items, [i], ["items"], dataPointerPath + "/" + i)) {
947 return error;
948 }
949 }
950 }
951 return null;
952 };
953
954 ValidatorContext.prototype.validateObject = function validateObject(data, schema, dataPointerPath) {
955 if (typeof data !== "object" || data === null || Array.isArray(data)) {
956 return null;
957 }
958 return this.validateObjectMinMaxProperties(data, schema, dataPointerPath)
959 || this.validateObjectRequiredProperties(data, schema, dataPointerPath)
960 || this.validateObjectProperties(data, schema, dataPointerPath)
961 || this.validateObjectDependencies(data, schema, dataPointerPath)
962 || null;
963 };
964
965 ValidatorContext.prototype.validateObjectMinMaxProperties = function validateObjectMinMaxProperties(data, schema) {
966 var keys = Object.keys(data);
967 var error;
968 if (schema.minProperties !== undefined) {
969 if (keys.length < schema.minProperties) {
970 error = this.createError(ErrorCodes.OBJECT_PROPERTIES_MINIMUM, {propertyCount: keys.length, minimum: schema.minProperties}, '', '/minProperties', null, data, schema);
971 if (this.handleError(error)) {
972 return error;
973 }
974 }
975 }
976 if (schema.maxProperties !== undefined) {
977 if (keys.length > schema.maxProperties) {
978 error = this.createError(ErrorCodes.OBJECT_PROPERTIES_MAXIMUM, {propertyCount: keys.length, maximum: schema.maxProperties}, '', '/maxProperties', null, data, schema);
979 if (this.handleError(error)) {
980 return error;
981 }
982 }
983 }
984 return null;
985 };
986
987 ValidatorContext.prototype.validateObjectRequiredProperties = function validateObjectRequiredProperties(data, schema) {
988 if (schema.required !== undefined) {
989 for (var i = 0; i < schema.required.length; i++) {
990 var key = schema.required[i];
991 if (data[key] === undefined) {
992 var error = this.createError(ErrorCodes.OBJECT_REQUIRED, {key: key}, '', '/required/' + i, null, data, schema);
993 if (this.handleError(error)) {
994 return error;
995 }
996 }
997 }
998 }
999 return null;
1000 };
1001
1002 ValidatorContext.prototype.validateObjectProperties = function validateObjectProperties(data, schema, dataPointerPath) {
1003 var error;
1004 for (var key in data) {
1005 var keyPointerPath = dataPointerPath + "/" + key.replace(/~/g, '~0').replace(/\//g, '~1');
1006 var foundMatch = false;
1007 if (schema.properties !== undefined && schema.properties[key] !== undefined) {
1008 foundMatch = true;
1009 if (error = this.validateAll(data[key], schema.properties[key], [key], ["properties", key], keyPointerPath)) {
1010 return error;
1011 }
1012 }
1013 if (schema.patternProperties !== undefined) {
1014 for (var patternKey in schema.patternProperties) {
1015 var regexp = new RegExp(patternKey);
1016 if (regexp.test(key)) {
1017 foundMatch = true;
1018 if (error = this.validateAll(data[key], schema.patternProperties[patternKey], [key], ["patternProperties", patternKey], keyPointerPath)) {
1019 return error;
1020 }
1021 }
1022 }
1023 }
1024 if (!foundMatch) {
1025 if (schema.additionalProperties !== undefined) {
1026 if (this.trackUnknownProperties) {
1027 this.knownPropertyPaths[keyPointerPath] = true;
1028 delete this.unknownPropertyPaths[keyPointerPath];
1029 }
1030 if (typeof schema.additionalProperties === "boolean") {
1031 if (!schema.additionalProperties) {
1032 error = this.createError(ErrorCodes.OBJECT_ADDITIONAL_PROPERTIES, {key: key}, '', '/additionalProperties', null, data, schema).prefixWith(key, null);
1033 if (this.handleError(error)) {
1034 return error;
1035 }
1036 }
1037 } else {
1038 if (error = this.validateAll(data[key], schema.additionalProperties, [key], ["additionalProperties"], keyPointerPath)) {
1039 return error;
1040 }
1041 }
1042 } else if (this.trackUnknownProperties && !this.knownPropertyPaths[keyPointerPath]) {
1043 this.unknownPropertyPaths[keyPointerPath] = true;
1044 }
1045 } else if (this.trackUnknownProperties) {
1046 this.knownPropertyPaths[keyPointerPath] = true;
1047 delete this.unknownPropertyPaths[keyPointerPath];
1048 }
1049 }
1050 return null;
1051 };
1052
1053 ValidatorContext.prototype.validateObjectDependencies = function validateObjectDependencies(data, schema, dataPointerPath) {
1054 var error;
1055 if (schema.dependencies !== undefined) {
1056 for (var depKey in schema.dependencies) {
1057 if (data[depKey] !== undefined) {
1058 var dep = schema.dependencies[depKey];
1059 if (typeof dep === "string") {
1060 if (data[dep] === undefined) {
1061 error = this.createError(ErrorCodes.OBJECT_DEPENDENCY_KEY, {key: depKey, missing: dep}, '', '', null, data, schema).prefixWith(null, depKey).prefixWith(null, "dependencies");
1062 if (this.handleError(error)) {
1063 return error;
1064 }
1065 }
1066 } else if (Array.isArray(dep)) {
1067 for (var i = 0; i < dep.length; i++) {
1068 var requiredKey = dep[i];
1069 if (data[requiredKey] === undefined) {
1070 error = this.createError(ErrorCodes.OBJECT_DEPENDENCY_KEY, {key: depKey, missing: requiredKey}, '', '/' + i, null, data, schema).prefixWith(null, depKey).prefixWith(null, "dependencies");
1071 if (this.handleError(error)) {
1072 return error;
1073 }
1074 }
1075 }
1076 } else {
1077 if (error = this.validateAll(data, dep, [], ["dependencies", depKey], dataPointerPath)) {
1078 return error;
1079 }
1080 }
1081 }
1082 }
1083 }
1084 return null;
1085 };
1086
1087 ValidatorContext.prototype.validateCombinations = function validateCombinations(data, schema, dataPointerPath) {
1088 return this.validateAllOf(data, schema, dataPointerPath)
1089 || this.validateAnyOf(data, schema, dataPointerPath)
1090 || this.validateOneOf(data, schema, dataPointerPath)
1091 || this.validateNot(data, schema, dataPointerPath)
1092 || null;
1093 };
1094
1095 ValidatorContext.prototype.validateAllOf = function validateAllOf(data, schema, dataPointerPath) {
1096 if (schema.allOf === undefined) {
1097 return null;
1098 }
1099 var error;
1100 for (var i = 0; i < schema.allOf.length; i++) {
1101 var subSchema = schema.allOf[i];
1102 if (error = this.validateAll(data, subSchema, [], ["allOf", i], dataPointerPath)) {
1103 return error;
1104 }
1105 }
1106 return null;
1107 };
1108
1109 ValidatorContext.prototype.validateAnyOf = function validateAnyOf(data, schema, dataPointerPath) {
1110 if (schema.anyOf === undefined) {
1111 return null;
1112 }
1113 var errors = [];
1114 var startErrorCount = this.errors.length;
1115 var oldUnknownPropertyPaths, oldKnownPropertyPaths;
1116 if (this.trackUnknownProperties) {
1117 oldUnknownPropertyPaths = this.unknownPropertyPaths;
1118 oldKnownPropertyPaths = this.knownPropertyPaths;
1119 }
1120 var errorAtEnd = true;
1121 for (var i = 0; i < schema.anyOf.length; i++) {
1122 if (this.trackUnknownProperties) {
1123 this.unknownPropertyPaths = {};
1124 this.knownPropertyPaths = {};
1125 }
1126 var subSchema = schema.anyOf[i];
1127
1128 var errorCount = this.errors.length;
1129 var error = this.validateAll(data, subSchema, [], ["anyOf", i], dataPointerPath);
1130
1131 if (error === null && errorCount === this.errors.length) {
1132 this.errors = this.errors.slice(0, startErrorCount);
1133
1134 if (this.trackUnknownProperties) {
1135 for (var knownKey in this.knownPropertyPaths) {
1136 oldKnownPropertyPaths[knownKey] = true;
1137 delete oldUnknownPropertyPaths[knownKey];
1138 }
1139 for (var unknownKey in this.unknownPropertyPaths) {
1140 if (!oldKnownPropertyPaths[unknownKey]) {
1141 oldUnknownPropertyPaths[unknownKey] = true;
1142 }
1143 }
1144 // We need to continue looping so we catch all the property definitions, but we don't want to return an error
1145 errorAtEnd = false;
1146 continue;
1147 }
1148
1149 return null;
1150 }
1151 if (error) {
1152 errors.push(error.prefixWith(null, "" + i).prefixWith(null, "anyOf"));
1153 }
1154 }
1155 if (this.trackUnknownProperties) {
1156 this.unknownPropertyPaths = oldUnknownPropertyPaths;
1157 this.knownPropertyPaths = oldKnownPropertyPaths;
1158 }
1159 if (errorAtEnd) {
1160 errors = errors.concat(this.errors.slice(startErrorCount));
1161 this.errors = this.errors.slice(0, startErrorCount);
1162 return this.createError(ErrorCodes.ANY_OF_MISSING, {}, "", "/anyOf", errors, data, schema);
1163 }
1164 };
1165
1166 ValidatorContext.prototype.validateOneOf = function validateOneOf(data, schema, dataPointerPath) {
1167 if (schema.oneOf === undefined) {
1168 return null;
1169 }
1170 var validIndex = null;
1171 var errors = [];
1172 var startErrorCount = this.errors.length;
1173 var oldUnknownPropertyPaths, oldKnownPropertyPaths;
1174 if (this.trackUnknownProperties) {
1175 oldUnknownPropertyPaths = this.unknownPropertyPaths;
1176 oldKnownPropertyPaths = this.knownPropertyPaths;
1177 }
1178 for (var i = 0; i < schema.oneOf.length; i++) {
1179 if (this.trackUnknownProperties) {
1180 this.unknownPropertyPaths = {};
1181 this.knownPropertyPaths = {};
1182 }
1183 var subSchema = schema.oneOf[i];
1184
1185 var errorCount = this.errors.length;
1186 var error = this.validateAll(data, subSchema, [], ["oneOf", i], dataPointerPath);
1187
1188 if (error === null && errorCount === this.errors.length) {
1189 if (validIndex === null) {
1190 validIndex = i;
1191 } else {
1192 this.errors = this.errors.slice(0, startErrorCount);
1193 return this.createError(ErrorCodes.ONE_OF_MULTIPLE, {index1: validIndex, index2: i}, "", "/oneOf", null, data, schema);
1194 }
1195 if (this.trackUnknownProperties) {
1196 for (var knownKey in this.knownPropertyPaths) {
1197 oldKnownPropertyPaths[knownKey] = true;
1198 delete oldUnknownPropertyPaths[knownKey];
1199 }
1200 for (var unknownKey in this.unknownPropertyPaths) {
1201 if (!oldKnownPropertyPaths[unknownKey]) {
1202 oldUnknownPropertyPaths[unknownKey] = true;
1203 }
1204 }
1205 }
1206 } else if (error) {
1207 errors.push(error);
1208 }
1209 }
1210 if (this.trackUnknownProperties) {
1211 this.unknownPropertyPaths = oldUnknownPropertyPaths;
1212 this.knownPropertyPaths = oldKnownPropertyPaths;
1213 }
1214 if (validIndex === null) {
1215 errors = errors.concat(this.errors.slice(startErrorCount));
1216 this.errors = this.errors.slice(0, startErrorCount);
1217 return this.createError(ErrorCodes.ONE_OF_MISSING, {}, "", "/oneOf", errors, data, schema);
1218 } else {
1219 this.errors = this.errors.slice(0, startErrorCount);
1220 }
1221 return null;
1222 };
1223
1224 ValidatorContext.prototype.validateNot = function validateNot(data, schema, dataPointerPath) {
1225 if (schema.not === undefined) {
1226 return null;
1227 }
1228 var oldErrorCount = this.errors.length;
1229 var oldUnknownPropertyPaths, oldKnownPropertyPaths;
1230 if (this.trackUnknownProperties) {
1231 oldUnknownPropertyPaths = this.unknownPropertyPaths;
1232 oldKnownPropertyPaths = this.knownPropertyPaths;
1233 this.unknownPropertyPaths = {};
1234 this.knownPropertyPaths = {};
1235 }
1236 var error = this.validateAll(data, schema.not, null, null, dataPointerPath);
1237 var notErrors = this.errors.slice(oldErrorCount);
1238 this.errors = this.errors.slice(0, oldErrorCount);
1239 if (this.trackUnknownProperties) {
1240 this.unknownPropertyPaths = oldUnknownPropertyPaths;
1241 this.knownPropertyPaths = oldKnownPropertyPaths;
1242 }
1243 if (error === null && notErrors.length === 0) {
1244 return this.createError(ErrorCodes.NOT_PASSED, {}, "", "/not", null, data, schema);
1245 }
1246 return null;
1247 };
1248
1249 ValidatorContext.prototype.validateHypermedia = function validateCombinations(data, schema, dataPointerPath) {
1250 if (!schema.links) {
1251 return null;
1252 }
1253 var error;
1254 for (var i = 0; i < schema.links.length; i++) {
1255 var ldo = schema.links[i];
1256 if (ldo.rel === "describedby") {
1257 var template = new UriTemplate(ldo.href);
1258 var allPresent = true;
1259 for (var j = 0; j < template.varNames.length; j++) {
1260 if (!(template.varNames[j] in data)) {
1261 allPresent = false;
1262 break;
1263 }
1264 }
1265 if (allPresent) {
1266 var schemaUrl = template.fillFromObject(data);
1267 var subSchema = {"$ref": schemaUrl};
1268 if (error = this.validateAll(data, subSchema, [], ["links", i], dataPointerPath)) {
1269 return error;
1270 }
1271 }
1272 }
1273 }
1274 };
1275
1276 // parseURI() and resolveUrl() are from https://gist.github.com/1088850
1277 // - released as public domain by author ("Yaffle") - see comments on gist
1278
1279 function parseURI(url) {
1280 var m = String(url).replace(/^\s+|\s+$/g, '').match(/^([^:\/?#]+:)?(\/\/(?:[^:@]*(?::[^:@]*)?@)?(([^:\/?#]*)(?::(\d*))?))?([^?#]*)(\?[^#]*)?(#[\s\S]*)?/);
1281 // authority = '//' + user + ':' + pass '@' + hostname + ':' port
1282 return (m ? {
1283 href : m[0] || '',
1284 protocol : m[1] || '',
1285 authority: m[2] || '',
1286 host : m[3] || '',
1287 hostname : m[4] || '',
1288 port : m[5] || '',
1289 pathname : m[6] || '',
1290 search : m[7] || '',
1291 hash : m[8] || ''
1292 } : null);
1293 }
1294
1295 function resolveUrl(base, href) {// RFC 3986
1296
1297 function removeDotSegments(input) {
1298 var output = [];
1299 input.replace(/^(\.\.?(\/|$))+/, '')
1300 .replace(/\/(\.(\/|$))+/g, '/')
1301 .replace(/\/\.\.$/, '/../')
1302 .replace(/\/?[^\/]*/g, function (p) {
1303 if (p === '/..') {
1304 output.pop();
1305 } else {
1306 output.push(p);
1307 }
1308 });
1309 return output.join('').replace(/^\//, input.charAt(0) === '/' ? '/' : '');
1310 }
1311
1312 href = parseURI(href || '');
1313 base = parseURI(base || '');
1314
1315 return !href || !base ? null : (href.protocol || base.protocol) +
1316 (href.protocol || href.authority ? href.authority : base.authority) +
1317 removeDotSegments(href.protocol || href.authority || href.pathname.charAt(0) === '/' ? href.pathname : (href.pathname ? ((base.authority && !base.pathname ? '/' : '') + base.pathname.slice(0, base.pathname.lastIndexOf('/') + 1) + href.pathname) : base.pathname)) +
1318 (href.protocol || href.authority || href.pathname ? href.search : (href.search || base.search)) +
1319 href.hash;
1320 }
1321
1322 function getDocumentUri(uri) {
1323 return uri.split('#')[0];
1324 }
1325 function normSchema(schema, baseUri) {
1326 if (schema && typeof schema === "object") {
1327 if (baseUri === undefined) {
1328 baseUri = schema.id;
1329 } else if (typeof schema.id === "string") {
1330 baseUri = resolveUrl(baseUri, schema.id);
1331 schema.id = baseUri;
1332 }
1333 if (Array.isArray(schema)) {
1334 for (var i = 0; i < schema.length; i++) {
1335 normSchema(schema[i], baseUri);
1336 }
1337 } else {
1338 if (typeof schema['$ref'] === "string") {
1339 schema['$ref'] = resolveUrl(baseUri, schema['$ref']);
1340 }
1341 for (var key in schema) {
1342 if (key !== "enum") {
1343 normSchema(schema[key], baseUri);
1344 }
1345 }
1346 }
1347 }
1348 }
1349
1350 function defaultErrorReporter(language) {
1351 language = language || 'en';
1352
1353 var errorMessages = languages[language];
1354
1355 return function (error) {
1356 var messageTemplate = errorMessages[error.code] || ErrorMessagesDefault[error.code];
1357 if (typeof messageTemplate !== 'string') {
1358 return "Unknown error code " + error.code + ": " + JSON.stringify(error.messageParams);
1359 }
1360 var messageParams = error.params;
1361 // Adapted from Crockford's supplant()
1362 return messageTemplate.replace(/\{([^{}]*)\}/g, function (whole, varName) {
1363 var subValue = messageParams[varName];
1364 return typeof subValue === 'string' || typeof subValue === 'number' ? subValue : whole;
1365 });
1366 };
1367 }
1368
1369 var ErrorCodes = {
1370 INVALID_TYPE: 0,
1371 ENUM_MISMATCH: 1,
1372 ANY_OF_MISSING: 10,
1373 ONE_OF_MISSING: 11,
1374 ONE_OF_MULTIPLE: 12,
1375 NOT_PASSED: 13,
1376 // Numeric errors
1377 NUMBER_MULTIPLE_OF: 100,
1378 NUMBER_MINIMUM: 101,
1379 NUMBER_MINIMUM_EXCLUSIVE: 102,
1380 NUMBER_MAXIMUM: 103,
1381 NUMBER_MAXIMUM_EXCLUSIVE: 104,
1382 NUMBER_NOT_A_NUMBER: 105,
1383 // String errors
1384 STRING_LENGTH_SHORT: 200,
1385 STRING_LENGTH_LONG: 201,
1386 STRING_PATTERN: 202,
1387 // Object errors
1388 OBJECT_PROPERTIES_MINIMUM: 300,
1389 OBJECT_PROPERTIES_MAXIMUM: 301,
1390 OBJECT_REQUIRED: 302,
1391 OBJECT_ADDITIONAL_PROPERTIES: 303,
1392 OBJECT_DEPENDENCY_KEY: 304,
1393 // Array errors
1394 ARRAY_LENGTH_SHORT: 400,
1395 ARRAY_LENGTH_LONG: 401,
1396 ARRAY_UNIQUE: 402,
1397 ARRAY_ADDITIONAL_ITEMS: 403,
1398 // Custom/user-defined errors
1399 FORMAT_CUSTOM: 500,
1400 KEYWORD_CUSTOM: 501,
1401 // Schema structure
1402 CIRCULAR_REFERENCE: 600,
1403 // Non-standard validation options
1404 UNKNOWN_PROPERTY: 1000
1405 };
1406 var ErrorCodeLookup = {};
1407 for (var key in ErrorCodes) {
1408 ErrorCodeLookup[ErrorCodes[key]] = key;
1409 }
1410 var ErrorMessagesDefault = {
1411 INVALID_TYPE: "Invalid type: {type} (expected {expected})",
1412 ENUM_MISMATCH: "No enum match for: {value}",
1413 ANY_OF_MISSING: "Data does not match any schemas from \"anyOf\"",
1414 ONE_OF_MISSING: "Data does not match any schemas from \"oneOf\"",
1415 ONE_OF_MULTIPLE: "Data is valid against more than one schema from \"oneOf\": indices {index1} and {index2}",
1416 NOT_PASSED: "Data matches schema from \"not\"",
1417 // Numeric errors
1418 NUMBER_MULTIPLE_OF: "Value {value} is not a multiple of {multipleOf}",
1419 NUMBER_MINIMUM: "Value {value} is less than minimum {minimum}",
1420 NUMBER_MINIMUM_EXCLUSIVE: "Value {value} is equal to exclusive minimum {minimum}",
1421 NUMBER_MAXIMUM: "Value {value} is greater than maximum {maximum}",
1422 NUMBER_MAXIMUM_EXCLUSIVE: "Value {value} is equal to exclusive maximum {maximum}",
1423 NUMBER_NOT_A_NUMBER: "Value {value} is not a valid number",
1424 // String errors
1425 STRING_LENGTH_SHORT: "String is too short ({length} chars), minimum {minimum}",
1426 STRING_LENGTH_LONG: "String is too long ({length} chars), maximum {maximum}",
1427 STRING_PATTERN: "String does not match pattern: {pattern}",
1428 // Object errors
1429 OBJECT_PROPERTIES_MINIMUM: "Too few properties defined ({propertyCount}), minimum {minimum}",
1430 OBJECT_PROPERTIES_MAXIMUM: "Too many properties defined ({propertyCount}), maximum {maximum}",
1431 OBJECT_REQUIRED: "Missing required property: {key}",
1432 OBJECT_ADDITIONAL_PROPERTIES: "Additional properties not allowed",
1433 OBJECT_DEPENDENCY_KEY: "Dependency failed - key must exist: {missing} (due to key: {key})",
1434 // Array errors
1435 ARRAY_LENGTH_SHORT: "Array is too short ({length}), minimum {minimum}",
1436 ARRAY_LENGTH_LONG: "Array is too long ({length}), maximum {maximum}",
1437 ARRAY_UNIQUE: "Array items are not unique (indices {match1} and {match2})",
1438 ARRAY_ADDITIONAL_ITEMS: "Additional items not allowed",
1439 // Format errors
1440 FORMAT_CUSTOM: "Format validation failed ({message})",
1441 KEYWORD_CUSTOM: "Keyword failed: {key} ({message})",
1442 // Schema structure
1443 CIRCULAR_REFERENCE: "Circular $refs: {urls}",
1444 // Non-standard validation options
1445 UNKNOWN_PROPERTY: "Unknown property (not in schema)"
1446 };
1447
1448 function ValidationError(code, params, dataPath, schemaPath, subErrors) {
1449 Error.call(this);
1450 if (code === undefined) {
1451 throw new Error ("No error code supplied: " + schemaPath);
1452 }
1453 this.message = '';
1454 this.params = params;
1455 this.code = code;
1456 this.dataPath = dataPath || "";
1457 this.schemaPath = schemaPath || "";
1458 this.subErrors = subErrors || null;
1459
1460 var err = new Error(this.message);
1461 this.stack = err.stack || err.stacktrace;
1462 if (!this.stack) {
1463 try {
1464 throw err;
1465 }
1466 catch(err) {
1467 this.stack = err.stack || err.stacktrace;
1468 }
1469 }
1470 }
1471 ValidationError.prototype = Object.create(Error.prototype);
1472 ValidationError.prototype.constructor = ValidationError;
1473 ValidationError.prototype.name = 'ValidationError';
1474
1475 ValidationError.prototype.prefixWith = function (dataPrefix, schemaPrefix) {
1476 if (dataPrefix !== null) {
1477 dataPrefix = dataPrefix.replace(/~/g, "~0").replace(/\//g, "~1");
1478 this.dataPath = "/" + dataPrefix + this.dataPath;
1479 }
1480 if (schemaPrefix !== null) {
1481 schemaPrefix = schemaPrefix.replace(/~/g, "~0").replace(/\//g, "~1");
1482 this.schemaPath = "/" + schemaPrefix + this.schemaPath;
1483 }
1484 if (this.subErrors !== null) {
1485 for (var i = 0; i < this.subErrors.length; i++) {
1486 this.subErrors[i].prefixWith(dataPrefix, schemaPrefix);
1487 }
1488 }
1489 return this;
1490 };
1491
1492 function isTrustedUrl(baseUrl, testUrl) {
1493 if(testUrl.substring(0, baseUrl.length) === baseUrl){
1494 var remainder = testUrl.substring(baseUrl.length);
1495 if ((testUrl.length > 0 && testUrl.charAt(baseUrl.length - 1) === "/")
1496 || remainder.charAt(0) === "#"
1497 || remainder.charAt(0) === "?") {
1498 return true;
1499 }
1500 }
1501 return false;
1502 }
1503
1504 var languages = {};
1505 function createApi(language) {
1506 var globalContext = new ValidatorContext();
1507 var currentLanguage;
1508 var customErrorReporter;
1509 var api = {
1510 setErrorReporter: function (reporter) {
1511 if (typeof reporter === 'string') {
1512 return this.language(reporter);
1513 }
1514 customErrorReporter = reporter;
1515 return true;
1516 },
1517 addFormat: function () {
1518 globalContext.addFormat.apply(globalContext, arguments);
1519 },
1520 language: function (code) {
1521 if (!code) {
1522 return currentLanguage;
1523 }
1524 if (!languages[code]) {
1525 code = code.split('-')[0]; // fall back to base language
1526 }
1527 if (languages[code]) {
1528 currentLanguage = code;
1529 return code; // so you can tell if fall-back has happened
1530 }
1531 return false;
1532 },
1533 addLanguage: function (code, messageMap) {
1534 var key;
1535 for (key in ErrorCodes) {
1536 if (messageMap[key] && !messageMap[ErrorCodes[key]]) {
1537 messageMap[ErrorCodes[key]] = messageMap[key];
1538 }
1539 }
1540 var rootCode = code.split('-')[0];
1541 if (!languages[rootCode]) { // use for base language if not yet defined
1542 languages[code] = messageMap;
1543 languages[rootCode] = messageMap;
1544 } else {
1545 languages[code] = Object.create(languages[rootCode]);
1546 for (key in messageMap) {
1547 if (typeof languages[rootCode][key] === 'undefined') {
1548 languages[rootCode][key] = messageMap[key];
1549 }
1550 languages[code][key] = messageMap[key];
1551 }
1552 }
1553 return this;
1554 },
1555 freshApi: function (language) {
1556 var result = createApi();
1557 if (language) {
1558 result.language(language);
1559 }
1560 return result;
1561 },
1562 validate: function (data, schema, checkRecursive, banUnknownProperties) {
1563 var def = defaultErrorReporter(currentLanguage);
1564 var errorReporter = customErrorReporter ? function (error, data, schema) {
1565 return customErrorReporter(error, data, schema) || def(error, data, schema);
1566 } : def;
1567 var context = new ValidatorContext(globalContext, false, errorReporter, checkRecursive, banUnknownProperties);
1568 if (typeof schema === "string") {
1569 schema = {"$ref": schema};
1570 }
1571 context.addSchema("", schema);
1572 var error = context.validateAll(data, schema, null, null, "");
1573 if (!error && banUnknownProperties) {
1574 error = context.banUnknownProperties(data, schema);
1575 }
1576 this.error = error;
1577 this.missing = context.missing;
1578 this.valid = (error === null);
1579 return this.valid;
1580 },
1581 validateResult: function () {
1582 var result = {};
1583 this.validate.apply(result, arguments);
1584 return result;
1585 },
1586 validateMultiple: function (data, schema, checkRecursive, banUnknownProperties) {
1587 var def = defaultErrorReporter(currentLanguage);
1588 var errorReporter = customErrorReporter ? function (error, data, schema) {
1589 return customErrorReporter(error, data, schema) || def(error, data, schema);
1590 } : def;
1591 var context = new ValidatorContext(globalContext, true, errorReporter, checkRecursive, banUnknownProperties);
1592 if (typeof schema === "string") {
1593 schema = {"$ref": schema};
1594 }
1595 context.addSchema("", schema);
1596 context.validateAll(data, schema, null, null, "");
1597 if (banUnknownProperties) {
1598 context.banUnknownProperties(data, schema);
1599 }
1600 var result = {};
1601 result.errors = context.errors;
1602 result.missing = context.missing;
1603 result.valid = (result.errors.length === 0);
1604 return result;
1605 },
1606 addSchema: function () {
1607 return globalContext.addSchema.apply(globalContext, arguments);
1608 },
1609 getSchema: function () {
1610 return globalContext.getSchema.apply(globalContext, arguments);
1611 },
1612 getSchemaMap: function () {
1613 return globalContext.getSchemaMap.apply(globalContext, arguments);
1614 },
1615 getSchemaUris: function () {
1616 return globalContext.getSchemaUris.apply(globalContext, arguments);
1617 },
1618 getMissingUris: function () {
1619 return globalContext.getMissingUris.apply(globalContext, arguments);
1620 },
1621 dropSchemas: function () {
1622 globalContext.dropSchemas.apply(globalContext, arguments);
1623 },
1624 defineKeyword: function () {
1625 globalContext.defineKeyword.apply(globalContext, arguments);
1626 },
1627 defineError: function (codeName, codeNumber, defaultMessage) {
1628 if (typeof codeName !== 'string' || !/^[A-Z]+(_[A-Z]+)*$/.test(codeName)) {
1629 throw new Error('Code name must be a string in UPPER_CASE_WITH_UNDERSCORES');
1630 }
1631 if (typeof codeNumber !== 'number' || codeNumber%1 !== 0 || codeNumber < 10000) {
1632 throw new Error('Code number must be an integer > 10000');
1633 }
1634 if (typeof ErrorCodes[codeName] !== 'undefined') {
1635 throw new Error('Error already defined: ' + codeName + ' as ' + ErrorCodes[codeName]);
1636 }
1637 if (typeof ErrorCodeLookup[codeNumber] !== 'undefined') {
1638 throw new Error('Error code already used: ' + ErrorCodeLookup[codeNumber] + ' as ' + codeNumber);
1639 }
1640 ErrorCodes[codeName] = codeNumber;
1641 ErrorCodeLookup[codeNumber] = codeName;
1642 ErrorMessagesDefault[codeName] = ErrorMessagesDefault[codeNumber] = defaultMessage;
1643 for (var langCode in languages) {
1644 var language = languages[langCode];
1645 if (language[codeName]) {
1646 language[codeNumber] = language[codeNumber] || language[codeName];
1647 }
1648 }
1649 },
1650 reset: function () {
1651 globalContext.reset();
1652 this.error = null;
1653 this.missing = [];
1654 this.valid = true;
1655 },
1656 missing: [],
1657 error: null,
1658 valid: true,
1659 normSchema: normSchema,
1660 resolveUrl: resolveUrl,
1661 getDocumentUri: getDocumentUri,
1662 errorCodes: ErrorCodes
1663 };
1664 api.language(language || 'en');
1665 return api;
1666 }
1667
1668 var tv4 = createApi();
1669 tv4.addLanguage('en-gb', ErrorMessagesDefault);
1670
1671 //legacy property
1672 tv4.tv4 = tv4;
1673
1674 return tv4; // used by _header.js to globalise.
1675
1676 }));
0 !function(a,b){"function"==typeof define&&define.amd?define([],b):"undefined"!=typeof module&&module.exports?module.exports=b():a.tv4=b()}(this,function(){function a(a){return encodeURI(a).replace(/%25[0-9][0-9]/g,function(a){return"%"+a.substring(3)})}function b(b){var c="";m[b.charAt(0)]&&(c=b.charAt(0),b=b.substring(1));var d="",e="",f=!0,g=!1,h=!1;"+"===c?f=!1:"."===c?(e=".",d="."):"/"===c?(e="/",d="/"):"#"===c?(e="#",f=!1):";"===c?(e=";",d=";",g=!0,h=!0):"?"===c?(e="?",d="&",g=!0):"&"===c&&(e="&",d="&",g=!0);for(var i=[],j=b.split(","),k=[],l={},o=0;o<j.length;o++){var p=j[o],q=null;if(-1!==p.indexOf(":")){var r=p.split(":");p=r[0],q=parseInt(r[1],10)}for(var s={};n[p.charAt(p.length-1)];)s[p.charAt(p.length-1)]=!0,p=p.substring(0,p.length-1);var t={truncate:q,name:p,suffices:s};k.push(t),l[p]=t,i.push(p)}var u=function(b){for(var c="",i=0,j=0;j<k.length;j++){var l=k[j],m=b(l.name);if(null===m||void 0===m||Array.isArray(m)&&0===m.length||"object"==typeof m&&0===Object.keys(m).length)i++;else if(c+=j===i?e:d||",",Array.isArray(m)){g&&(c+=l.name+"=");for(var n=0;n<m.length;n++)n>0&&(c+=l.suffices["*"]?d||",":",",l.suffices["*"]&&g&&(c+=l.name+"=")),c+=f?encodeURIComponent(m[n]).replace(/!/g,"%21"):a(m[n])}else if("object"==typeof m){g&&!l.suffices["*"]&&(c+=l.name+"=");var o=!0;for(var p in m)o||(c+=l.suffices["*"]?d||",":","),o=!1,c+=f?encodeURIComponent(p).replace(/!/g,"%21"):a(p),c+=l.suffices["*"]?"=":",",c+=f?encodeURIComponent(m[p]).replace(/!/g,"%21"):a(m[p])}else g&&(c+=l.name,h&&""===m||(c+="=")),null!=l.truncate&&(m=m.substring(0,l.truncate)),c+=f?encodeURIComponent(m).replace(/!/g,"%21"):a(m)}return c};return u.varNames=i,{prefix:e,substitution:u}}function c(a){if(!(this instanceof c))return new c(a);for(var d=a.split("{"),e=[d.shift()],f=[],g=[],h=[];d.length>0;){var i=d.shift(),j=i.split("}")[0],k=i.substring(j.length+1),l=b(j);g.push(l.substitution),f.push(l.prefix),e.push(k),h=h.concat(l.substitution.varNames)}this.fill=function(a){for(var b=e[0],c=0;c<g.length;c++){var d=g[c];b+=d(a),b+=e[c+1]}return b},this.varNames=h,this.template=a}function d(a,b){if(a===b)return!0;if(a&&b&&"object"==typeof a&&"object"==typeof b){if(Array.isArray(a)!==Array.isArray(b))return!1;if(Array.isArray(a)){if(a.length!==b.length)return!1;for(var c=0;c<a.length;c++)if(!d(a[c],b[c]))return!1}else{var e;for(e in a)if(void 0===b[e]&&void 0!==a[e])return!1;for(e in b)if(void 0===a[e]&&void 0!==b[e])return!1;for(e in a)if(!d(a[e],b[e]))return!1}return!0}return!1}function e(a){var b=String(a).replace(/^\s+|\s+$/g,"").match(/^([^:\/?#]+:)?(\/\/(?:[^:@]*(?::[^:@]*)?@)?(([^:\/?#]*)(?::(\d*))?))?([^?#]*)(\?[^#]*)?(#[\s\S]*)?/);return b?{href:b[0]||"",protocol:b[1]||"",authority:b[2]||"",host:b[3]||"",hostname:b[4]||"",port:b[5]||"",pathname:b[6]||"",search:b[7]||"",hash:b[8]||""}:null}function f(a,b){function c(a){var b=[];return a.replace(/^(\.\.?(\/|$))+/,"").replace(/\/(\.(\/|$))+/g,"/").replace(/\/\.\.$/,"/../").replace(/\/?[^\/]*/g,function(a){"/.."===a?b.pop():b.push(a)}),b.join("").replace(/^\//,"/"===a.charAt(0)?"/":"")}return b=e(b||""),a=e(a||""),b&&a?(b.protocol||a.protocol)+(b.protocol||b.authority?b.authority:a.authority)+c(b.protocol||b.authority||"/"===b.pathname.charAt(0)?b.pathname:b.pathname?(a.authority&&!a.pathname?"/":"")+a.pathname.slice(0,a.pathname.lastIndexOf("/")+1)+b.pathname:a.pathname)+(b.protocol||b.authority||b.pathname?b.search:b.search||a.search)+b.hash:null}function g(a){return a.split("#")[0]}function h(a,b){if(a&&"object"==typeof a)if(void 0===b?b=a.id:"string"==typeof a.id&&(b=f(b,a.id),a.id=b),Array.isArray(a))for(var c=0;c<a.length;c++)h(a[c],b);else{"string"==typeof a.$ref&&(a.$ref=f(b,a.$ref));for(var d in a)"enum"!==d&&h(a[d],b)}}function i(a){a=a||"en";var b=v[a];return function(a){var c=b[a.code]||u[a.code];if("string"!=typeof c)return"Unknown error code "+a.code+": "+JSON.stringify(a.messageParams);var d=a.params;return c.replace(/\{([^{}]*)\}/g,function(a,b){var c=d[b];return"string"==typeof c||"number"==typeof c?c:a})}}function j(a,b,c,d,e){if(Error.call(this),void 0===a)throw new Error("No error code supplied: "+d);this.message="",this.params=b,this.code=a,this.dataPath=c||"",this.schemaPath=d||"",this.subErrors=e||null;var f=new Error(this.message);if(this.stack=f.stack||f.stacktrace,!this.stack)try{throw f}catch(f){this.stack=f.stack||f.stacktrace}}function k(a,b){if(b.substring(0,a.length)===a){var c=b.substring(a.length);if(b.length>0&&"/"===b.charAt(a.length-1)||"#"===c.charAt(0)||"?"===c.charAt(0))return!0}return!1}function l(a){var b,c,d=new o,e={setErrorReporter:function(a){return"string"==typeof a?this.language(a):(c=a,!0)},addFormat:function(){d.addFormat.apply(d,arguments)},language:function(a){return a?(v[a]||(a=a.split("-")[0]),v[a]?(b=a,a):!1):b},addLanguage:function(a,b){var c;for(c in r)b[c]&&!b[r[c]]&&(b[r[c]]=b[c]);var d=a.split("-")[0];if(v[d]){v[a]=Object.create(v[d]);for(c in b)"undefined"==typeof v[d][c]&&(v[d][c]=b[c]),v[a][c]=b[c]}else v[a]=b,v[d]=b;return this},freshApi:function(a){var b=l();return a&&b.language(a),b},validate:function(a,e,f,g){var h=i(b),j=c?function(a,b,d){return c(a,b,d)||h(a,b,d)}:h,k=new o(d,!1,j,f,g);"string"==typeof e&&(e={$ref:e}),k.addSchema("",e);var l=k.validateAll(a,e,null,null,"");return!l&&g&&(l=k.banUnknownProperties(a,e)),this.error=l,this.missing=k.missing,this.valid=null===l,this.valid},validateResult:function(){var a={};return this.validate.apply(a,arguments),a},validateMultiple:function(a,e,f,g){var h=i(b),j=c?function(a,b,d){return c(a,b,d)||h(a,b,d)}:h,k=new o(d,!0,j,f,g);"string"==typeof e&&(e={$ref:e}),k.addSchema("",e),k.validateAll(a,e,null,null,""),g&&k.banUnknownProperties(a,e);var l={};return l.errors=k.errors,l.missing=k.missing,l.valid=0===l.errors.length,l},addSchema:function(){return d.addSchema.apply(d,arguments)},getSchema:function(){return d.getSchema.apply(d,arguments)},getSchemaMap:function(){return d.getSchemaMap.apply(d,arguments)},getSchemaUris:function(){return d.getSchemaUris.apply(d,arguments)},getMissingUris:function(){return d.getMissingUris.apply(d,arguments)},dropSchemas:function(){d.dropSchemas.apply(d,arguments)},defineKeyword:function(){d.defineKeyword.apply(d,arguments)},defineError:function(a,b,c){if("string"!=typeof a||!/^[A-Z]+(_[A-Z]+)*$/.test(a))throw new Error("Code name must be a string in UPPER_CASE_WITH_UNDERSCORES");if("number"!=typeof b||b%1!==0||1e4>b)throw new Error("Code number must be an integer > 10000");if("undefined"!=typeof r[a])throw new Error("Error already defined: "+a+" as "+r[a]);if("undefined"!=typeof s[b])throw new Error("Error code already used: "+s[b]+" as "+b);r[a]=b,s[b]=a,u[a]=u[b]=c;for(var d in v){var e=v[d];e[a]&&(e[b]=e[b]||e[a])}},reset:function(){d.reset(),this.error=null,this.missing=[],this.valid=!0},missing:[],error:null,valid:!0,normSchema:h,resolveUrl:f,getDocumentUri:g,errorCodes:r};return e.language(a||"en"),e}Object.keys||(Object.keys=function(){var a=Object.prototype.hasOwnProperty,b=!{toString:null}.propertyIsEnumerable("toString"),c=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],d=c.length;return function(e){if("object"!=typeof e&&"function"!=typeof e||null===e)throw new TypeError("Object.keys called on non-object");var f=[];for(var g in e)a.call(e,g)&&f.push(g);if(b)for(var h=0;d>h;h++)a.call(e,c[h])&&f.push(c[h]);return f}}()),Object.create||(Object.create=function(){function a(){}return function(b){if(1!==arguments.length)throw new Error("Object.create implementation only accepts one parameter.");return a.prototype=b,new a}}()),Array.isArray||(Array.isArray=function(a){return"[object Array]"===Object.prototype.toString.call(a)}),Array.prototype.indexOf||(Array.prototype.indexOf=function(a){if(null===this)throw new TypeError;var b=Object(this),c=b.length>>>0;if(0===c)return-1;var d=0;if(arguments.length>1&&(d=Number(arguments[1]),d!==d?d=0:0!==d&&d!==1/0&&d!==-(1/0)&&(d=(d>0||-1)*Math.floor(Math.abs(d)))),d>=c)return-1;for(var e=d>=0?d:Math.max(c-Math.abs(d),0);c>e;e++)if(e in b&&b[e]===a)return e;return-1}),Object.isFrozen||(Object.isFrozen=function(a){for(var b="tv4_test_frozen_key";a.hasOwnProperty(b);)b+=Math.random();try{return a[b]=!0,delete a[b],!1}catch(c){return!0}});var m={"+":!0,"#":!0,".":!0,"/":!0,";":!0,"?":!0,"&":!0},n={"*":!0};c.prototype={toString:function(){return this.template},fillFromObject:function(a){return this.fill(function(b){return a[b]})}};var o=function(a,b,c,d,e){if(this.missing=[],this.missingMap={},this.formatValidators=a?Object.create(a.formatValidators):{},this.schemas=a?Object.create(a.schemas):{},this.collectMultiple=b,this.errors=[],this.handleError=b?this.collectError:this.returnError,d&&(this.checkRecursive=!0,this.scanned=[],this.scannedFrozen=[],this.scannedFrozenSchemas=[],this.scannedFrozenValidationErrors=[],this.validatedSchemasKey="tv4_validation_id",this.validationErrorsKey="tv4_validation_errors_id"),e&&(this.trackUnknownProperties=!0,this.knownPropertyPaths={},this.unknownPropertyPaths={}),this.errorReporter=c||i("en"),"string"==typeof this.errorReporter)throw new Error("debug");if(this.definedKeywords={},a)for(var f in a.definedKeywords)this.definedKeywords[f]=a.definedKeywords[f].slice(0)};o.prototype.defineKeyword=function(a,b){this.definedKeywords[a]=this.definedKeywords[a]||[],this.definedKeywords[a].push(b)},o.prototype.createError=function(a,b,c,d,e,f,g){var h=new j(a,b,c,d,e);return h.message=this.errorReporter(h,f,g),h},o.prototype.returnError=function(a){return a},o.prototype.collectError=function(a){return a&&this.errors.push(a),null},o.prototype.prefixErrors=function(a,b,c){for(var d=a;d<this.errors.length;d++)this.errors[d]=this.errors[d].prefixWith(b,c);return this},o.prototype.banUnknownProperties=function(a,b){for(var c in this.unknownPropertyPaths){var d=this.createError(r.UNKNOWN_PROPERTY,{path:c},c,"",null,a,b),e=this.handleError(d);if(e)return e}return null},o.prototype.addFormat=function(a,b){if("object"==typeof a){for(var c in a)this.addFormat(c,a[c]);return this}this.formatValidators[a]=b},o.prototype.resolveRefs=function(a,b){if(void 0!==a.$ref){if(b=b||{},b[a.$ref])return this.createError(r.CIRCULAR_REFERENCE,{urls:Object.keys(b).join(", ")},"","",null,void 0,a);b[a.$ref]=!0,a=this.getSchema(a.$ref,b)}return a},o.prototype.getSchema=function(a,b){var c;if(void 0!==this.schemas[a])return c=this.schemas[a],this.resolveRefs(c,b);var d=a,e="";if(-1!==a.indexOf("#")&&(e=a.substring(a.indexOf("#")+1),d=a.substring(0,a.indexOf("#"))),"object"==typeof this.schemas[d]){c=this.schemas[d];var f=decodeURIComponent(e);if(""===f)return this.resolveRefs(c,b);if("/"!==f.charAt(0))return void 0;for(var g=f.split("/").slice(1),h=0;h<g.length;h++){var i=g[h].replace(/~1/g,"/").replace(/~0/g,"~");if(void 0===c[i]){c=void 0;break}c=c[i]}if(void 0!==c)return this.resolveRefs(c,b)}void 0===this.missing[d]&&(this.missing.push(d),this.missing[d]=d,this.missingMap[d]=d)},o.prototype.searchSchemas=function(a,b){if(Array.isArray(a))for(var c=0;c<a.length;c++)this.searchSchemas(a[c],b);else if(a&&"object"==typeof a){"string"==typeof a.id&&k(b,a.id)&&void 0===this.schemas[a.id]&&(this.schemas[a.id]=a);for(var d in a)if("enum"!==d)if("object"==typeof a[d])this.searchSchemas(a[d],b);else if("$ref"===d){var e=g(a[d]);e&&void 0===this.schemas[e]&&void 0===this.missingMap[e]&&(this.missingMap[e]=e)}}},o.prototype.addSchema=function(a,b){if("string"!=typeof a||"undefined"==typeof b){if("object"!=typeof a||"string"!=typeof a.id)return;b=a,a=b.id}a===g(a)+"#"&&(a=g(a)),this.schemas[a]=b,delete this.missingMap[a],h(b,a),this.searchSchemas(b,a)},o.prototype.getSchemaMap=function(){var a={};for(var b in this.schemas)a[b]=this.schemas[b];return a},o.prototype.getSchemaUris=function(a){var b=[];for(var c in this.schemas)(!a||a.test(c))&&b.push(c);return b},o.prototype.getMissingUris=function(a){var b=[];for(var c in this.missingMap)(!a||a.test(c))&&b.push(c);return b},o.prototype.dropSchemas=function(){this.schemas={},this.reset()},o.prototype.reset=function(){this.missing=[],this.missingMap={},this.errors=[]},o.prototype.validateAll=function(a,b,c,d,e){var f;if(b=this.resolveRefs(b),!b)return null;if(b instanceof j)return this.errors.push(b),b;var g,h=this.errors.length,i=null,k=null;if(this.checkRecursive&&a&&"object"==typeof a){if(f=!this.scanned.length,a[this.validatedSchemasKey]){var l=a[this.validatedSchemasKey].indexOf(b);if(-1!==l)return this.errors=this.errors.concat(a[this.validationErrorsKey][l]),null}if(Object.isFrozen(a)&&(g=this.scannedFrozen.indexOf(a),-1!==g)){var m=this.scannedFrozenSchemas[g].indexOf(b);if(-1!==m)return this.errors=this.errors.concat(this.scannedFrozenValidationErrors[g][m]),null}if(this.scanned.push(a),Object.isFrozen(a))-1===g&&(g=this.scannedFrozen.length,this.scannedFrozen.push(a),this.scannedFrozenSchemas.push([])),i=this.scannedFrozenSchemas[g].length,this.scannedFrozenSchemas[g][i]=b,this.scannedFrozenValidationErrors[g][i]=[];else{if(!a[this.validatedSchemasKey])try{Object.defineProperty(a,this.validatedSchemasKey,{value:[],configurable:!0}),Object.defineProperty(a,this.validationErrorsKey,{value:[],configurable:!0})}catch(n){a[this.validatedSchemasKey]=[],a[this.validationErrorsKey]=[]}k=a[this.validatedSchemasKey].length,a[this.validatedSchemasKey][k]=b,a[this.validationErrorsKey][k]=[]}}var o=this.errors.length,p=this.validateBasic(a,b,e)||this.validateNumeric(a,b,e)||this.validateString(a,b,e)||this.validateArray(a,b,e)||this.validateObject(a,b,e)||this.validateCombinations(a,b,e)||this.validateHypermedia(a,b,e)||this.validateFormat(a,b,e)||this.validateDefinedKeywords(a,b,e)||null;if(f){for(;this.scanned.length;){var q=this.scanned.pop();delete q[this.validatedSchemasKey]}this.scannedFrozen=[],this.scannedFrozenSchemas=[]}if(p||o!==this.errors.length)for(;c&&c.length||d&&d.length;){var r=c&&c.length?""+c.pop():null,s=d&&d.length?""+d.pop():null;p&&(p=p.prefixWith(r,s)),this.prefixErrors(o,r,s)}return null!==i?this.scannedFrozenValidationErrors[g][i]=this.errors.slice(h):null!==k&&(a[this.validationErrorsKey][k]=this.errors.slice(h)),this.handleError(p)},o.prototype.validateFormat=function(a,b){if("string"!=typeof b.format||!this.formatValidators[b.format])return null;var c=this.formatValidators[b.format].call(null,a,b);return"string"==typeof c||"number"==typeof c?this.createError(r.FORMAT_CUSTOM,{message:c},"","/format",null,a,b):c&&"object"==typeof c?this.createError(r.FORMAT_CUSTOM,{message:c.message||"?"},c.dataPath||"",c.schemaPath||"/format",null,a,b):null},o.prototype.validateDefinedKeywords=function(a,b,c){for(var d in this.definedKeywords)if("undefined"!=typeof b[d])for(var e=this.definedKeywords[d],f=0;f<e.length;f++){var g=e[f],h=g(a,b[d],b,c);if("string"==typeof h||"number"==typeof h)return this.createError(r.KEYWORD_CUSTOM,{key:d,message:h},"","",null,a,b).prefixWith(null,d);if(h&&"object"==typeof h){var i=h.code;if("string"==typeof i){if(!r[i])throw new Error("Undefined error code (use defineError): "+i);i=r[i]}else"number"!=typeof i&&(i=r.KEYWORD_CUSTOM);var j="object"==typeof h.message?h.message:{key:d,message:h.message||"?"},k=h.schemaPath||"/"+d.replace(/~/g,"~0").replace(/\//g,"~1");return this.createError(i,j,h.dataPath||null,k,null,a,b)}}return null},o.prototype.validateBasic=function(a,b,c){var d;return(d=this.validateType(a,b,c))?d.prefixWith(null,"type"):(d=this.validateEnum(a,b,c))?d.prefixWith(null,"type"):null},o.prototype.validateType=function(a,b){if(void 0===b.type)return null;var c=typeof a;null===a?c="null":Array.isArray(a)&&(c="array");var d=b.type;Array.isArray(d)||(d=[d]);for(var e=0;e<d.length;e++){var f=d[e];if(f===c||"integer"===f&&"number"===c&&a%1===0)return null}return this.createError(r.INVALID_TYPE,{type:c,expected:d.join("/")},"","",null,a,b)},o.prototype.validateEnum=function(a,b){if(void 0===b["enum"])return null;for(var c=0;c<b["enum"].length;c++){var e=b["enum"][c];if(d(a,e))return null}return this.createError(r.ENUM_MISMATCH,{value:"undefined"!=typeof JSON?JSON.stringify(a):a},"","",null,a,b)},o.prototype.validateNumeric=function(a,b,c){return this.validateMultipleOf(a,b,c)||this.validateMinMax(a,b,c)||this.validateNaN(a,b,c)||null};var p=Math.pow(2,-51),q=1-p;o.prototype.validateMultipleOf=function(a,b){var c=b.multipleOf||b.divisibleBy;if(void 0===c)return null;if("number"==typeof a){var d=a/c%1;if(d>=p&&q>d)return this.createError(r.NUMBER_MULTIPLE_OF,{value:a,multipleOf:c},"","",null,a,b)}return null},o.prototype.validateMinMax=function(a,b){if("number"!=typeof a)return null;if(void 0!==b.minimum){if(a<b.minimum)return this.createError(r.NUMBER_MINIMUM,{value:a,minimum:b.minimum},"","/minimum",null,a,b);if(b.exclusiveMinimum&&a===b.minimum)return this.createError(r.NUMBER_MINIMUM_EXCLUSIVE,{value:a,minimum:b.minimum},"","/exclusiveMinimum",null,a,b)}if(void 0!==b.maximum){if(a>b.maximum)return this.createError(r.NUMBER_MAXIMUM,{value:a,maximum:b.maximum},"","/maximum",null,a,b);if(b.exclusiveMaximum&&a===b.maximum)return this.createError(r.NUMBER_MAXIMUM_EXCLUSIVE,{value:a,maximum:b.maximum},"","/exclusiveMaximum",null,a,b)}return null},o.prototype.validateNaN=function(a,b){return"number"!=typeof a?null:isNaN(a)===!0||a===1/0||a===-(1/0)?this.createError(r.NUMBER_NOT_A_NUMBER,{value:a},"","/type",null,a,b):null},o.prototype.validateString=function(a,b,c){return this.validateStringLength(a,b,c)||this.validateStringPattern(a,b,c)||null},o.prototype.validateStringLength=function(a,b){return"string"!=typeof a?null:void 0!==b.minLength&&a.length<b.minLength?this.createError(r.STRING_LENGTH_SHORT,{length:a.length,minimum:b.minLength},"","/minLength",null,a,b):void 0!==b.maxLength&&a.length>b.maxLength?this.createError(r.STRING_LENGTH_LONG,{length:a.length,maximum:b.maxLength},"","/maxLength",null,a,b):null},o.prototype.validateStringPattern=function(a,b){if("string"!=typeof a||"string"!=typeof b.pattern&&!(b.pattern instanceof RegExp))return null;var c;if(b.pattern instanceof RegExp)c=b.pattern;else{var d,e="",f=b.pattern.match(/^\/(.+)\/([img]*)$/);f?(d=f[1],e=f[2]):d=b.pattern,c=new RegExp(d,e)}return c.test(a)?null:this.createError(r.STRING_PATTERN,{pattern:b.pattern},"","/pattern",null,a,b)},o.prototype.validateArray=function(a,b,c){return Array.isArray(a)?this.validateArrayLength(a,b,c)||this.validateArrayUniqueItems(a,b,c)||this.validateArrayItems(a,b,c)||null:null},o.prototype.validateArrayLength=function(a,b){var c;return void 0!==b.minItems&&a.length<b.minItems&&(c=this.createError(r.ARRAY_LENGTH_SHORT,{length:a.length,minimum:b.minItems},"","/minItems",null,a,b),this.handleError(c))?c:void 0!==b.maxItems&&a.length>b.maxItems&&(c=this.createError(r.ARRAY_LENGTH_LONG,{length:a.length,maximum:b.maxItems},"","/maxItems",null,a,b),this.handleError(c))?c:null},o.prototype.validateArrayUniqueItems=function(a,b){if(b.uniqueItems)for(var c=0;c<a.length;c++)for(var e=c+1;e<a.length;e++)if(d(a[c],a[e])){var f=this.createError(r.ARRAY_UNIQUE,{match1:c,match2:e},"","/uniqueItems",null,a,b);if(this.handleError(f))return f}return null},o.prototype.validateArrayItems=function(a,b,c){if(void 0===b.items)return null;var d,e;if(Array.isArray(b.items)){for(e=0;e<a.length;e++)if(e<b.items.length){if(d=this.validateAll(a[e],b.items[e],[e],["items",e],c+"/"+e))return d}else if(void 0!==b.additionalItems)if("boolean"==typeof b.additionalItems){if(!b.additionalItems&&(d=this.createError(r.ARRAY_ADDITIONAL_ITEMS,{},"/"+e,"/additionalItems",null,a,b),this.handleError(d)))return d}else if(d=this.validateAll(a[e],b.additionalItems,[e],["additionalItems"],c+"/"+e))return d}else for(e=0;e<a.length;e++)if(d=this.validateAll(a[e],b.items,[e],["items"],c+"/"+e))return d;return null},o.prototype.validateObject=function(a,b,c){return"object"!=typeof a||null===a||Array.isArray(a)?null:this.validateObjectMinMaxProperties(a,b,c)||this.validateObjectRequiredProperties(a,b,c)||this.validateObjectProperties(a,b,c)||this.validateObjectDependencies(a,b,c)||null},o.prototype.validateObjectMinMaxProperties=function(a,b){var c,d=Object.keys(a);return void 0!==b.minProperties&&d.length<b.minProperties&&(c=this.createError(r.OBJECT_PROPERTIES_MINIMUM,{propertyCount:d.length,minimum:b.minProperties},"","/minProperties",null,a,b),this.handleError(c))?c:void 0!==b.maxProperties&&d.length>b.maxProperties&&(c=this.createError(r.OBJECT_PROPERTIES_MAXIMUM,{propertyCount:d.length,maximum:b.maxProperties},"","/maxProperties",null,a,b),this.handleError(c))?c:null},o.prototype.validateObjectRequiredProperties=function(a,b){if(void 0!==b.required)for(var c=0;c<b.required.length;c++){var d=b.required[c];if(void 0===a[d]){var e=this.createError(r.OBJECT_REQUIRED,{key:d},"","/required/"+c,null,a,b);if(this.handleError(e))return e}}return null},o.prototype.validateObjectProperties=function(a,b,c){var d;for(var e in a){var f=c+"/"+e.replace(/~/g,"~0").replace(/\//g,"~1"),g=!1;if(void 0!==b.properties&&void 0!==b.properties[e]&&(g=!0,d=this.validateAll(a[e],b.properties[e],[e],["properties",e],f)))return d;if(void 0!==b.patternProperties)for(var h in b.patternProperties){var i=new RegExp(h);if(i.test(e)&&(g=!0,d=this.validateAll(a[e],b.patternProperties[h],[e],["patternProperties",h],f)))return d}if(g)this.trackUnknownProperties&&(this.knownPropertyPaths[f]=!0,delete this.unknownPropertyPaths[f]);else if(void 0!==b.additionalProperties){if(this.trackUnknownProperties&&(this.knownPropertyPaths[f]=!0,delete this.unknownPropertyPaths[f]),"boolean"==typeof b.additionalProperties){if(!b.additionalProperties&&(d=this.createError(r.OBJECT_ADDITIONAL_PROPERTIES,{key:e},"","/additionalProperties",null,a,b).prefixWith(e,null),this.handleError(d)))return d}else if(d=this.validateAll(a[e],b.additionalProperties,[e],["additionalProperties"],f))return d}else this.trackUnknownProperties&&!this.knownPropertyPaths[f]&&(this.unknownPropertyPaths[f]=!0)}return null},o.prototype.validateObjectDependencies=function(a,b,c){var d;if(void 0!==b.dependencies)for(var e in b.dependencies)if(void 0!==a[e]){var f=b.dependencies[e];if("string"==typeof f){if(void 0===a[f]&&(d=this.createError(r.OBJECT_DEPENDENCY_KEY,{key:e,missing:f},"","",null,a,b).prefixWith(null,e).prefixWith(null,"dependencies"),this.handleError(d)))return d}else if(Array.isArray(f))for(var g=0;g<f.length;g++){var h=f[g];if(void 0===a[h]&&(d=this.createError(r.OBJECT_DEPENDENCY_KEY,{key:e,missing:h},"","/"+g,null,a,b).prefixWith(null,e).prefixWith(null,"dependencies"),this.handleError(d)))return d}else if(d=this.validateAll(a,f,[],["dependencies",e],c))return d}return null},o.prototype.validateCombinations=function(a,b,c){return this.validateAllOf(a,b,c)||this.validateAnyOf(a,b,c)||this.validateOneOf(a,b,c)||this.validateNot(a,b,c)||null},o.prototype.validateAllOf=function(a,b,c){if(void 0===b.allOf)return null;for(var d,e=0;e<b.allOf.length;e++){var f=b.allOf[e];if(d=this.validateAll(a,f,[],["allOf",e],c))return d}return null},o.prototype.validateAnyOf=function(a,b,c){if(void 0===b.anyOf)return null;var d,e,f=[],g=this.errors.length;this.trackUnknownProperties&&(d=this.unknownPropertyPaths,e=this.knownPropertyPaths);for(var h=!0,i=0;i<b.anyOf.length;i++){this.trackUnknownProperties&&(this.unknownPropertyPaths={},this.knownPropertyPaths={});var j=b.anyOf[i],k=this.errors.length,l=this.validateAll(a,j,[],["anyOf",i],c);if(null===l&&k===this.errors.length){if(this.errors=this.errors.slice(0,g),this.trackUnknownProperties){for(var m in this.knownPropertyPaths)e[m]=!0,delete d[m];for(var n in this.unknownPropertyPaths)e[n]||(d[n]=!0);h=!1;continue}return null}l&&f.push(l.prefixWith(null,""+i).prefixWith(null,"anyOf"))}return this.trackUnknownProperties&&(this.unknownPropertyPaths=d,this.knownPropertyPaths=e),h?(f=f.concat(this.errors.slice(g)),this.errors=this.errors.slice(0,g),this.createError(r.ANY_OF_MISSING,{},"","/anyOf",f,a,b)):void 0},o.prototype.validateOneOf=function(a,b,c){if(void 0===b.oneOf)return null;var d,e,f=null,g=[],h=this.errors.length;this.trackUnknownProperties&&(d=this.unknownPropertyPaths,e=this.knownPropertyPaths);for(var i=0;i<b.oneOf.length;i++){this.trackUnknownProperties&&(this.unknownPropertyPaths={},this.knownPropertyPaths={});var j=b.oneOf[i],k=this.errors.length,l=this.validateAll(a,j,[],["oneOf",i],c);if(null===l&&k===this.errors.length){if(null!==f)return this.errors=this.errors.slice(0,h),this.createError(r.ONE_OF_MULTIPLE,{index1:f,index2:i},"","/oneOf",null,a,b);if(f=i,this.trackUnknownProperties){for(var m in this.knownPropertyPaths)e[m]=!0,delete d[m];for(var n in this.unknownPropertyPaths)e[n]||(d[n]=!0)}}else l&&g.push(l)}return this.trackUnknownProperties&&(this.unknownPropertyPaths=d,this.knownPropertyPaths=e),null===f?(g=g.concat(this.errors.slice(h)),this.errors=this.errors.slice(0,h),this.createError(r.ONE_OF_MISSING,{},"","/oneOf",g,a,b)):(this.errors=this.errors.slice(0,h),null)},o.prototype.validateNot=function(a,b,c){if(void 0===b.not)return null;var d,e,f=this.errors.length;this.trackUnknownProperties&&(d=this.unknownPropertyPaths,e=this.knownPropertyPaths,this.unknownPropertyPaths={},this.knownPropertyPaths={});var g=this.validateAll(a,b.not,null,null,c),h=this.errors.slice(f);return this.errors=this.errors.slice(0,f),this.trackUnknownProperties&&(this.unknownPropertyPaths=d,this.knownPropertyPaths=e),null===g&&0===h.length?this.createError(r.NOT_PASSED,{},"","/not",null,a,b):null},o.prototype.validateHypermedia=function(a,b,d){if(!b.links)return null;for(var e,f=0;f<b.links.length;f++){var g=b.links[f];if("describedby"===g.rel){for(var h=new c(g.href),i=!0,j=0;j<h.varNames.length;j++)if(!(h.varNames[j]in a)){i=!1;break}if(i){var k=h.fillFromObject(a),l={$ref:k};if(e=this.validateAll(a,l,[],["links",f],d))return e}}}};var r={INVALID_TYPE:0,ENUM_MISMATCH:1,ANY_OF_MISSING:10,ONE_OF_MISSING:11,ONE_OF_MULTIPLE:12,NOT_PASSED:13,NUMBER_MULTIPLE_OF:100,NUMBER_MINIMUM:101,NUMBER_MINIMUM_EXCLUSIVE:102,NUMBER_MAXIMUM:103,NUMBER_MAXIMUM_EXCLUSIVE:104,NUMBER_NOT_A_NUMBER:105,STRING_LENGTH_SHORT:200,STRING_LENGTH_LONG:201,STRING_PATTERN:202,OBJECT_PROPERTIES_MINIMUM:300,OBJECT_PROPERTIES_MAXIMUM:301,OBJECT_REQUIRED:302,OBJECT_ADDITIONAL_PROPERTIES:303,OBJECT_DEPENDENCY_KEY:304,ARRAY_LENGTH_SHORT:400,ARRAY_LENGTH_LONG:401,ARRAY_UNIQUE:402,ARRAY_ADDITIONAL_ITEMS:403,FORMAT_CUSTOM:500,KEYWORD_CUSTOM:501,CIRCULAR_REFERENCE:600,UNKNOWN_PROPERTY:1e3},s={};for(var t in r)s[r[t]]=t;var u={INVALID_TYPE:"Invalid type: {type} (expected {expected})",ENUM_MISMATCH:"No enum match for: {value}",ANY_OF_MISSING:'Data does not match any schemas from "anyOf"',ONE_OF_MISSING:'Data does not match any schemas from "oneOf"',ONE_OF_MULTIPLE:'Data is valid against more than one schema from "oneOf": indices {index1} and {index2}',NOT_PASSED:'Data matches schema from "not"',NUMBER_MULTIPLE_OF:"Value {value} is not a multiple of {multipleOf}",NUMBER_MINIMUM:"Value {value} is less than minimum {minimum}",NUMBER_MINIMUM_EXCLUSIVE:"Value {value} is equal to exclusive minimum {minimum}",NUMBER_MAXIMUM:"Value {value} is greater than maximum {maximum}",NUMBER_MAXIMUM_EXCLUSIVE:"Value {value} is equal to exclusive maximum {maximum}",NUMBER_NOT_A_NUMBER:"Value {value} is not a valid number",STRING_LENGTH_SHORT:"String is too short ({length} chars), minimum {minimum}",STRING_LENGTH_LONG:"String is too long ({length} chars), maximum {maximum}",STRING_PATTERN:"String does not match pattern: {pattern}",OBJECT_PROPERTIES_MINIMUM:"Too few properties defined ({propertyCount}), minimum {minimum}",OBJECT_PROPERTIES_MAXIMUM:"Too many properties defined ({propertyCount}), maximum {maximum}",OBJECT_REQUIRED:"Missing required property: {key}",OBJECT_ADDITIONAL_PROPERTIES:"Additional properties not allowed",OBJECT_DEPENDENCY_KEY:"Dependency failed - key must exist: {missing} (due to key: {key})",ARRAY_LENGTH_SHORT:"Array is too short ({length}), minimum {minimum}",ARRAY_LENGTH_LONG:"Array is too long ({length}), maximum {maximum}",ARRAY_UNIQUE:"Array items are not unique (indices {match1} and {match2})",ARRAY_ADDITIONAL_ITEMS:"Additional items not allowed",FORMAT_CUSTOM:"Format validation failed ({message})",KEYWORD_CUSTOM:"Keyword failed: {key} ({message})",CIRCULAR_REFERENCE:"Circular $refs: {urls}",UNKNOWN_PROPERTY:"Unknown property (not in schema)"};j.prototype=Object.create(Error.prototype),j.prototype.constructor=j,j.prototype.name="ValidationError",j.prototype.prefixWith=function(a,b){if(null!==a&&(a=a.replace(/~/g,"~0").replace(/\//g,"~1"),this.dataPath="/"+a+this.dataPath),null!==b&&(b=b.replace(/~/g,"~0").replace(/\//g,"~1"),this.schemaPath="/"+b+this.schemaPath),null!==this.subErrors)for(var c=0;c<this.subErrors.length;c++)this.subErrors[c].prefixWith(a,b);return this};var v={},w=l();return w.addLanguage("en-gb",u),w.tv4=w,w});