add license file for CII Badge application
[msb/apigateway.git] / apiroute / apiroute-service / src / main / resources / api-doc / lib / swagger-client.js
1 /**
2  * swagger-client - swagger.js is a javascript client for use with swaggering APIs.
3  * @version v2.1.9-M1
4  * @link http://swagger.io
5  * @license apache 2.0
6  */
7 (function(){
8 var ArrayModel = function(definition) {
9   this.name = "arrayModel";
10   this.definition = definition || {};
11   this.properties = [];
12   
13   var requiredFields = definition.enum || [];
14   var innerType = definition.items;
15   if(innerType) {
16     if(innerType.type) {
17       this.type = typeFromJsonSchema(innerType.type, innerType.format);
18     }
19     else {
20       this.ref = innerType.$ref;
21     }
22   }
23   return this;
24 };
25
26 ArrayModel.prototype.createJSONSample = function(modelsToIgnore) {
27   var result;
28   modelsToIgnore = (modelsToIgnore||{});
29   if(this.type) {
30     result = this.type;
31   }
32   else if (this.ref) {
33     var name = simpleRef(this.ref);
34     if(typeof modelsToIgnore[name] === 'undefined') {
35       modelsToIgnore[name] = this;
36       result = models[name].createJSONSample(modelsToIgnore);
37     }
38     else {
39       return name;
40     }
41   }
42   return [ result ];
43 };
44
45 ArrayModel.prototype.getSampleValue = function(modelsToIgnore) {
46   var result;
47   modelsToIgnore = (modelsToIgnore || {});
48   if(this.type) {
49     result = type;
50   }
51   else if (this.ref) {
52     var name = simpleRef(this.ref);
53     result = models[name].getSampleValue(modelsToIgnore);
54   }
55   return [ result ];
56 };
57
58 ArrayModel.prototype.getMockSignature = function(modelsToIgnore) {
59   var propertiesStr = [];
60   var i, prop;
61   for (i = 0; i < this.properties.length; i++) {
62     prop = this.properties[i];
63     propertiesStr.push(prop.toString());
64   }
65
66   var strong = '<span class="strong">';
67   var stronger = '<span class="stronger">';
68   var strongClose = '</span>';
69   var classOpen = strong + 'array' + ' {' + strongClose;
70   var classClose = strong + '}' + strongClose;
71   var returnVal = classOpen + '<div>' + propertiesStr.join(',</div><div>') + '</div>' + classClose;
72
73   if (!modelsToIgnore)
74     modelsToIgnore = {};
75   modelsToIgnore[this.name] = this;
76   for (i = 0; i < this.properties.length; i++) {
77     prop = this.properties[i];
78     var ref = prop.$ref;
79     var model = models[ref];
80     if (model && typeof modelsToIgnore[ref] === 'undefined') {
81       returnVal = returnVal + ('<br>' + model.getMockSignature(modelsToIgnore));
82     }
83   }
84   return returnVal;
85 };
86
87
88 /**
89  * SwaggerAuthorizations applys the correct authorization to an operation being executed
90  */
91 var SwaggerAuthorizations = function() {
92   this.authz = {};
93 };
94
95 SwaggerAuthorizations.prototype.add = function(name, auth) {
96   this.authz[name] = auth;
97   return auth;
98 };
99
100 SwaggerAuthorizations.prototype.remove = function(name) {
101   return delete this.authz[name];
102 };
103
104 SwaggerAuthorizations.prototype.apply = function (obj, authorizations) {
105   var status = null;
106   var key, name, value, result;
107
108   // if the "authorizations" key is undefined, or has an empty array, add all keys
109   if (typeof authorizations === 'undefined' || Object.keys(authorizations).length === 0) {
110     for (key in this.authz) {
111       value = this.authz[key];
112       result = value.apply(obj, authorizations);
113       if (result === true)
114         status = true;
115     }
116   }
117   else {
118     // 2.0 support
119     if (Array.isArray(authorizations)) {
120
121       for (var i = 0; i < authorizations.length; i++) {
122         var auth = authorizations[i];
123         for (name in auth) {
124           for (key in this.authz) {
125             if (key == name) {
126               value = this.authz[key];
127               result = value.apply(obj, authorizations);
128               if (result === true)
129                 status = true;
130             }
131           }
132         }
133       }
134     }
135     else {
136       // 1.2 support
137       for (name in authorizations) {
138         for (key in this.authz) {
139           if (key == name) {
140             value = this.authz[key];
141             result = value.apply(obj, authorizations);
142             if (result === true)
143               status = true;
144           }
145         }
146       }
147     }
148   }
149
150   return status;
151 };
152
153 /**
154  * ApiKeyAuthorization allows a query param or header to be injected
155  */
156 var ApiKeyAuthorization = function(name, value, type) {
157   this.name = name;
158   this.value = value;
159   this.type = type;
160 };
161
162 ApiKeyAuthorization.prototype.apply = function(obj, authorizations) {
163   if (this.type === "query") {
164     if (obj.url.indexOf('?') > 0)
165       obj.url = obj.url + "&" + this.name + "=" + this.value;
166     else
167       obj.url = obj.url + "?" + this.name + "=" + this.value;
168     return true;
169   } else if (this.type === "header") {
170     obj.headers[this.name] = this.value;
171     return true;
172   }
173 };
174
175 var CookieAuthorization = function(cookie) {
176   this.cookie = cookie;
177 };
178
179 CookieAuthorization.prototype.apply = function(obj, authorizations) {
180   obj.cookieJar = obj.cookieJar || CookieJar();
181   obj.cookieJar.setCookie(this.cookie);
182   return true;
183 };
184
185 /**
186  * Password Authorization is a basic auth implementation
187  */
188 var PasswordAuthorization = function(name, username, password) {
189   this.name = name;
190   this.username = username;
191   this.password = password;
192   this._btoa = null;
193   if (typeof window !== 'undefined')
194     this._btoa = btoa;
195   else
196     this._btoa = require("btoa");
197 };
198
199 PasswordAuthorization.prototype.apply = function(obj, authorizations) {
200   var base64encoder = this._btoa;
201   obj.headers.Authorization = "Basic " + base64encoder(this.username + ":" + this.password);
202   return true;
203 };
204 var __bind = function(fn, me){
205   return function(){
206     return fn.apply(me, arguments);
207   };
208 };
209
210 fail = function(message) {
211   log(message);
212 };
213
214 log = function(){
215   log.history = log.history || [];
216   log.history.push(arguments);
217   if(this.console){
218     console.log( Array.prototype.slice.call(arguments)[0] );
219   }
220 };
221
222 if (!Array.prototype.indexOf) {
223   Array.prototype.indexOf = function(obj, start) {
224     for (var i = (start || 0), j = this.length; i < j; i++) {
225       if (this[i] === obj) { return i; }
226     }
227     return -1;
228   };
229 }
230
231 /**
232  * allows override of the default value based on the parameter being
233  * supplied
234  **/
235 var applyParameterMacro = function (operation, parameter) {
236   var e = (typeof window !== 'undefined' ? window : exports);
237   if(e.parameterMacro)
238     return e.parameterMacro(operation, parameter);
239   else
240     return parameter.defaultValue;
241 };
242
243 /**
244  * allows overriding the default value of an model property
245  **/
246 var applyModelPropertyMacro = function (model, property) {
247   var e = (typeof window !== 'undefined' ? window : exports);
248   if(e.modelPropertyMacro)
249     return e.modelPropertyMacro(model, property);
250   else
251     return property.defaultValue;
252 };
253
254 /**
255  * PrimitiveModel
256  **/
257 var PrimitiveModel = function(definition) {
258   this.name = "name";
259   this.definition = definition || {};
260   this.properties = [];
261
262   var requiredFields = definition.enum || [];
263   this.type = typeFromJsonSchema(definition.type, definition.format);
264 };
265
266 PrimitiveModel.prototype.createJSONSample = function(modelsToIgnore) {
267   var result = this.type;
268   return result;
269 };
270
271 PrimitiveModel.prototype.getSampleValue = function() {
272   var result = this.type;
273   return null;
274 };
275
276 PrimitiveModel.prototype.getMockSignature = function(modelsToIgnore) {
277   var propertiesStr = [];
278   var i, prop;
279   for (i = 0; i < this.properties.length; i++) {
280     prop = this.properties[i];
281     propertiesStr.push(prop.toString());
282   }
283
284   var strong = '<span class="strong">';
285   var stronger = '<span class="stronger">';
286   var strongClose = '</span>';
287   var classOpen = strong + this.name + ' {' + strongClose;
288   var classClose = strong + '}' + strongClose;
289   var returnVal = classOpen + '<div>' + propertiesStr.join(',</div><div>') + '</div>' + classClose;
290
291   if (!modelsToIgnore)
292     modelsToIgnore = {};
293   modelsToIgnore[this.name] = this;
294   for (i = 0; i < this.properties.length; i++) {
295     prop = this.properties[i];
296     var ref = prop.$ref;
297     var model = models[ref];
298     if (model && typeof modelsToIgnore[ref] === 'undefined') {
299       returnVal = returnVal + ('<br>' + model.getMockSignature(modelsToIgnore));
300     }
301   }
302   return returnVal;
303 };
304 /** 
305  * Resolves a spec's remote references
306  */
307 var Resolver = function (){};
308
309 Resolver.prototype.resolve = function(spec, callback, scope) {
310   this.scope = (scope || this);
311   var host, name, path, property, propertyName, type;
312   var processedCalls = 0, resolvedRefs = {}, unresolvedRefs = {};
313
314   // store objects for dereferencing
315   var resolutionTable = {};
316
317   // models
318   for(name in spec.definitions) {
319     var model = spec.definitions[name];
320     for(propertyName in model.properties) {
321       property = model.properties[propertyName];
322       this.resolveTo(property, resolutionTable);
323     }
324   }
325   // operations
326   for(name in spec.paths) {
327     var method, operation, responseCode;
328     path = spec.paths[name];
329     for(method in path) {
330       operation = path[method];
331       var i, parameters = operation.parameters;
332       for(i in parameters) {
333         var parameter = parameters[i];
334         if(parameter.in === 'body' && parameter.schema) {
335           this.resolveTo(parameter.schema, resolutionTable);
336         }
337         if(parameter.$ref) {
338           this.resolveInline(spec, parameter, resolutionTable, unresolvedRefs);
339         }
340       }
341       for(responseCode in operation.responses) {
342         var response = operation.responses[responseCode];
343         if(response.schema) {
344           this.resolveTo(response.schema, resolutionTable);
345         }
346       }
347     }
348   }
349   // get hosts
350   var opts = {}, expectedCalls = 0;
351   for(name in resolutionTable) {
352     var parts = name.split('#');
353     if(parts.length == 2) {
354       host = parts[0]; path = parts[1];
355       if(!Array.isArray(opts[host])) {
356         opts[host] = [];
357         expectedCalls += 1;
358       }
359       opts[host].push(path);
360     }
361   }
362
363   for(name in opts) {
364     var self = this, opt = opts[name];
365     host = name;
366
367     var obj = {
368       useJQuery: false,  // TODO
369       url: host,
370       method: "get",
371       headers: {
372         accept: this.scope.swaggerRequestHeaders || 'application/json'
373       },
374       on: {
375         error: function(response) {
376           processedCalls += 1;
377           var i;
378           for(i = 0; i < opt.length; i++) {
379             // fail all of these
380             var resolved = host + '#' + opt[i];
381             unresolvedRefs[resolved] = null;
382           }
383           if(processedCalls === expectedCalls)
384             self.finish(spec, resolutionTable, resolvedRefs, unresolvedRefs, callback);
385         },
386         response: function(response) {
387           var i, j, swagger = response.obj;
388           processedCalls += 1;
389           for(i = 0; i < opt.length; i++) {
390             var location = swagger, path = opt[i], parts = path.split('/');
391             for(j = 0; j < parts.length; j++) {
392               var segment = parts[j];
393               if(typeof location === 'undefined')
394                 break;
395               if(segment.length > 0)
396                 location = location[segment];
397             }
398             var resolved = host + '#' + path, resolvedName = parts[j-1];
399             if(typeof location !== 'undefined') {
400               resolvedRefs[resolved] = {
401                 name: resolvedName,
402                 obj: location
403               };
404             }
405             else unresolvedRefs[resolved] = null;
406           }
407           if(processedCalls === expectedCalls)
408             self.finish(spec, resolutionTable, resolvedRefs, unresolvedRefs, callback);
409         }
410       }
411     };
412     authorizations.apply(obj);
413     new SwaggerHttp().execute(obj);
414   }
415   if(Object.keys(opts).length === 0)
416     callback.call(this.scope, spec, unresolvedRefs);
417 };
418
419 Resolver.prototype.finish = function(spec, resolutionTable, resolvedRefs, unresolvedRefs, callback) {
420   // walk resolution table and replace with resolved refs
421   var ref;
422   for(ref in resolutionTable) {
423     var i, locations = resolutionTable[ref];
424     for(i = 0; i < locations.length; i++) {
425       var resolvedTo = resolvedRefs[locations[i].obj.$ref];
426       if(resolvedTo) {
427         if(!spec.definitions)
428           spec.definitions = {};
429         if(locations[i].resolveAs === '$ref') {
430           spec.definitions[resolvedTo.name] = resolvedTo.obj;
431           locations[i].obj.$ref = '#/definitions/' + resolvedTo.name;
432         }
433         else if (locations[i].resolveAs === 'inline') {
434           var key;
435           var targetObj = locations[i].obj;
436           delete targetObj.$ref;
437           for(key in resolvedTo.obj) {
438             targetObj[key] = resolvedTo.obj[key];
439           }
440         }
441       }
442     }
443   }
444   callback.call(this.scope, spec, unresolvedRefs);
445 };
446
447 /**
448  * immediately in-lines local refs, queues remote refs
449  * for inline resolution
450  */
451 Resolver.prototype.resolveInline = function (spec, property, objs, unresolvedRefs) {
452   var ref = property.$ref;
453   if(ref) {
454     if(ref.indexOf('http') === 0) {
455       if(Array.isArray(objs[ref])) {
456         objs[ref].push({obj: property, resolveAs: 'inline'});
457       }
458       else {
459         objs[ref] = [{obj: property, resolveAs: 'inline'}];
460       }
461     }
462     else if (ref.indexOf('#') === 0) {
463       // local resolve
464       var shortenedRef = ref.substring(1);
465       var i, parts = shortenedRef.split('/'), location = spec;
466       for(i = 0; i < parts.length; i++) {
467         var part = parts[i];
468         if(part.length > 0) {
469           location = location[part];
470         }
471       }
472       if(location) {
473         delete property.$ref;
474         var key;
475         for(key in location) {
476           property[key] = location[key];
477         }
478       }
479       else unresolvedRefs[ref] = null;
480     }
481   }
482   else if(property.type === 'array') {
483     this.resolveTo(property.items, objs);
484   }
485 };
486
487 Resolver.prototype.resolveTo = function (property, objs) {
488   var ref = property.$ref;
489   if(ref) {
490     if(ref.indexOf('http') === 0) {
491       if(Array.isArray(objs[ref])) {
492         objs[ref].push({obj: property, resolveAs: '$ref'});
493       }
494       else {
495         objs[ref] = [{obj: property, resolveAs: '$ref'}];
496       }
497     }
498   }
499   else if(property.type === 'array') {
500     var items = property.items;
501     this.resolveTo(items, objs);
502   }
503 };
504 var addModel = function(name, model) {
505   models[name] = model;
506 };
507
508 var SwaggerClient = function(url, options) {
509   this.isBuilt = false;
510   this.url = null;
511   this.debug = false;
512   this.basePath = null;
513   this.modelsArray = [];
514   this.authorizations = null;
515   this.authorizationScheme = null;
516   this.isValid = false;
517   this.info = null;
518   this.useJQuery = false;
519   this.resourceCount = 0;
520
521   if(typeof url !== 'undefined')
522     return this.initialize(url, options);
523 };
524
525 SwaggerClient.prototype.initialize = function (url, options) {
526   this.models = models = {};
527
528   options = (options||{});
529
530   if(typeof url === 'string')
531     this.url = url;
532   else if(typeof url === 'object') {
533     options = url;
534     this.url = options.url;
535   }
536   this.swaggerRequstHeaders = options.swaggerRequstHeaders || 'application/json;charset=utf-8,*/*';
537   this.defaultSuccessCallback = options.defaultSuccessCallback || null;
538   this.defaultErrorCallback = options.defaultErrorCallback || null;
539
540   if (typeof options.success === 'function')
541     this.success = options.success;
542
543   if (options.useJQuery)
544     this.useJQuery = options.useJQuery;
545
546   if (options.authorizations) {
547     this.clientAuthorizations = options.authorizations;
548   } else {
549     this.clientAuthorizations = authorizations;
550   }
551
552   this.supportedSubmitMethods = options.supportedSubmitMethods || [];
553   this.failure = options.failure || function() {};
554   this.progress = options.progress || function() {};
555   this.spec = options.spec;
556   this.options = options;
557
558   if (typeof options.success === 'function') {
559     this.ready = true;
560     this.build();
561   }
562 };
563
564 SwaggerClient.prototype.build = function(mock) {
565   if (this.isBuilt) return this;
566   var self = this;
567   this.progress('fetching resource list: ' + this.url);
568   var obj = {
569     useJQuery: this.useJQuery,
570     url: this.url,
571     method: "get",
572     headers: {
573       accept: this.swaggerRequstHeaders
574     },
575     on: {
576       error: function(response) {
577         if (self.url.substring(0, 4) !== 'http')
578           return self.fail('Please specify the protocol for ' + self.url);
579         else if (response.status === 0)
580           return self.fail('Can\'t read from server.  It may not have the appropriate access-control-origin settings.');
581         else if (response.status === 404)
582           return self.fail('Can\'t read swagger JSON from ' + self.url);
583         else
584           return self.fail(response.status + ' : ' + response.statusText + ' ' + self.url);
585       },
586       response: function(resp) {
587         var responseObj = resp.obj || JSON.parse(resp.data);
588         self.swaggerVersion = responseObj.swaggerVersion;
589
590         if(responseObj.swagger && parseInt(responseObj.swagger) === 2) {
591           self.swaggerVersion = responseObj.swagger;
592           new Resolver().resolve(responseObj, self.buildFromSpec, self);
593           self.isValid = true;
594         }
595         else {
596           if (self.swaggerVersion === '1.2') {
597             return self.buildFrom1_2Spec(responseObj);
598           } else {
599             return self.buildFrom1_1Spec(responseObj);
600           }
601         }
602       }
603     }
604   };
605   if(this.spec) {
606     setTimeout(function() {
607       new Resolver().resolve(self.spec, self.buildFromSpec, self);
608    }, 10);
609   }
610   else {
611     authorizations.apply(obj);
612     if(mock)
613       return obj;
614     new SwaggerHttp().execute(obj);
615   }
616   return this;
617 };
618
619 SwaggerClient.prototype.buildFromSpec = function(response) {
620   if(this.isBuilt) return this;
621
622   this.info = response.info || {};
623   this.title = response.title || '';
624   this.host = response.host || '';
625   this.schemes = response.schemes || [];
626   this.basePath = response.basePath || '';
627   this.apis = {};
628   this.apisArray = [];
629   this.consumes = response.consumes;
630   this.produces = response.produces;
631   this.securityDefinitions = response.securityDefinitions;
632
633   // legacy support
634   this.authSchemes = response.securityDefinitions;
635
636   var definedTags = {};
637   if(Array.isArray(response.tags)) {
638     definedTags = {};
639     for(k = 0; k < response.tags.length; k++) {
640       var t = response.tags[k];
641       definedTags[t.name] = t;
642     }
643   }
644
645   var location;
646   if(typeof this.url === 'string') {
647     location = this.parseUri(this.url);
648   }
649
650   if(typeof this.schemes === 'undefined' || this.schemes.length === 0) {
651     this.scheme = location.scheme || 'http';
652   }
653   else {
654     this.scheme = this.schemes[0];
655   }
656
657   if(typeof this.host === 'undefined' || this.host === '') {
658     this.host = location.host;
659     if (location.port) {
660       this.host = this.host + ':' + location.port;
661     }
662   }
663
664   this.definitions = response.definitions;
665   var key;
666   for(key in this.definitions) {
667     var model = new Model(key, this.definitions[key]);
668     if(model) {
669       models[key] = model;
670     }
671   }
672
673   // get paths, create functions for each operationId
674   var path;
675   var operations = [];
676   for(path in response.paths) {
677     if(typeof response.paths[path] === 'object') {
678       var httpMethod;
679       for(httpMethod in response.paths[path]) {
680         if(['delete', 'get', 'head', 'options', 'patch', 'post', 'put'].indexOf(httpMethod) === -1) {
681           continue;
682         }
683         var operation = response.paths[path][httpMethod];
684         var tags = operation.tags;
685         if(typeof tags === 'undefined') {
686           operation.tags = [ 'default' ];
687           tags = operation.tags;
688         }
689         var operationId = this.idFromOp(path, httpMethod, operation);
690         var operationObject = new Operation (
691           this,
692           operation.scheme,
693           operationId,
694           httpMethod,
695           path,
696           operation,
697           this.definitions
698         );
699         // bind this operation's execute command to the api
700         if(tags.length > 0) {
701           var i;
702           for(i = 0; i < tags.length; i++) {
703             var tag = this.tagFromLabel(tags[i]);
704             var operationGroup = this[tag];
705             if(typeof this.apis[tag] === 'undefined')
706               this.apis[tag] = {};
707             if(typeof operationGroup === 'undefined') {
708               this[tag] = [];
709               operationGroup = this[tag];
710               operationGroup.operations = {};
711               operationGroup.label = tag;
712               operationGroup.apis = [];
713               var tagObject = definedTags[tag];
714               if(typeof tagObject === 'object') {
715                 operationGroup.description = tagObject.description;
716                 operationGroup.externalDocs = tagObject.externalDocs;
717               }
718               this[tag].help = this.help.bind(operationGroup);
719               this.apisArray.push(new OperationGroup(tag, operationGroup.description, operationGroup.externalDocs, operationObject));
720             }
721             if(typeof this.apis[tag].help !== 'function')
722               this.apis[tag].help = this.help.bind(operationGroup);
723             // bind to the apis object
724             this.apis[tag][operationId] = operationObject.execute.bind(operationObject);
725             this.apis[tag][operationId].help = operationObject.help.bind(operationObject);
726             this.apis[tag][operationId].asCurl = operationObject.asCurl.bind(operationObject);
727             operationGroup[operationId] = operationObject.execute.bind(operationObject);
728             operationGroup[operationId].help = operationObject.help.bind(operationObject);
729             operationGroup[operationId].asCurl = operationObject.asCurl.bind(operationObject);
730
731             operationGroup.apis.push(operationObject);
732             operationGroup.operations[operationId] = operationObject;
733
734             // legacy UI feature
735             var j;
736             var api;
737             for(j = 0; j < this.apisArray.length; j++) {
738               if(this.apisArray[j].tag === tag) {
739                 api = this.apisArray[j];
740               }
741             }
742             if(api) {
743               api.operationsArray.push(operationObject);
744             }
745           }
746         }
747         else {
748           log('no group to bind to');
749         }
750       }
751     }
752   }
753   this.isBuilt = true;
754   if (this.success) {
755     this.isValid = true;
756     this.isBuilt = true;
757     this.success();
758   }
759   return this;
760 };
761
762 SwaggerClient.prototype.parseUri = function(uri) {
763   var urlParseRE = /^(((([^:\/#\?]+:)?(?:(\/\/)((?:(([^:@\/#\?]+)(?:\:([^:@\/#\?]+))?)@)?(([^:\/#\?\]\[]+|\[[^\/\]@#?]+\])(?:\:([0-9]+))?))?)?)?((\/?(?:[^\/\?#]+\/+)*)([^\?#]*)))?(\?[^#]+)?)(#.*)?/;
764   var parts = urlParseRE.exec(uri);
765   return {
766     scheme: parts[4].replace(':',''),
767     host: parts[11],
768     port: parts[12],
769     path: parts[15]
770   };
771 };
772
773 SwaggerClient.prototype.help = function(dontPrint) {
774   var i;
775   var output = 'operations for the "' + this.label + '" tag';
776   for(i = 0; i < this.apis.length; i++) {
777     var api = this.apis[i];
778     output += '\n  * ' + api.nickname + ': ' + api.operation.summary;
779   }
780   if(dontPrint)
781     return output;
782   else {
783     log(output);
784     return output;
785   }
786 };
787
788 SwaggerClient.prototype.tagFromLabel = function(label) {
789   return label;
790 };
791
792 SwaggerClient.prototype.idFromOp = function(path, httpMethod, op) {
793   var opId = op.operationId || (path.substring(1) + '_' + httpMethod);
794   return opId.replace(/[\.,-\/#!$%\^&\*;:{}=\-_`~()\+\s]/g,'_');
795 };
796
797 SwaggerClient.prototype.fail = function(message) {
798   this.failure(message);
799   throw message;
800 };
801
802 var OperationGroup = function(tag, description, externalDocs, operation) {
803   this.tag = tag;
804   this.path = tag;
805   this.description = description;
806   this.externalDocs = externalDocs;
807   this.name = tag;
808   this.operation = operation;
809   this.operationsArray = [];
810 };
811
812 var Operation = function(parent, scheme, operationId, httpMethod, path, args, definitions) {
813   var errors = [];
814   parent = parent||{};
815   args = args||{};
816
817   this.operations = {};
818   this.operation = args;
819   this.deprecated = args.deprecated;
820   this.consumes = args.consumes;
821   this.produces = args.produces;
822   this.parent = parent;
823   this.host = parent.host || 'localhost';
824   this.schemes = parent.schemes;
825   this.scheme = scheme || parent.scheme || 'http';
826   // this.basePath = window.location.pathname.split("/api-doc")[0]+parent.basePath || '/';
827    // var url = window.location.search.match(/\?url=(.*)\/.*.json.*$/); 
828    var url;
829   if (window.location.search && window.location.search.length > 1) {
830         url = window.location.search.split("&api=")[1];
831
832
833         // //本地json;
834         // if(url.lastIndexOf("runtime")>0){
835         //   var realUrl = window.location.search.match(/\&api=(.*)$/); 
836         //   url=realUrl[1];
837         // }
838
839
840       } else {
841         url = "/api/microservices/v1";
842       }
843
844
845
846   this.basePath=url;
847   
848   this.nickname = (operationId||errors.push('Operations must have a nickname.'));
849   this.method = (httpMethod||errors.push('Operation ' + operationId + ' is missing method.'));
850   this.path = (path||errors.push('Operation ' + this.nickname + ' is missing path.'));
851   this.parameters = args !== null ? (args.parameters||[]) : {};
852   this.summary = args.summary || '';
853   this.responses = (args.responses||{});
854   this.type = null;
855   this.security = args.security;
856   this.authorizations = args.security;
857   this.description = args.description;
858   this.useJQuery = parent.useJQuery;
859
860   if(typeof this.deprecated === 'string') {
861     switch(this.deprecated.toLowerCase()) {
862       case 'true': case 'yes': case '1': {
863         this.deprecated = true;
864         break;
865       }
866       case 'false': case 'no': case '0': case null: {
867         this.deprecated = false;
868         break;
869       }
870       default: this.deprecated = Boolean(this.deprecated);
871     }
872   }
873
874   var i, model;
875
876   if(definitions) {
877     // add to global models
878     var key;
879     for(key in this.definitions) {
880       model = new Model(key, definitions[key]);
881       if(model) {
882         models[key] = model;
883       }
884     }
885   }
886   for(i = 0; i < this.parameters.length; i++) {
887     var param = this.parameters[i];
888     if(param.type === 'array') {
889       param.isList = true;
890       param.allowMultiple = true;
891     }
892     var innerType = this.getType(param);
893     if(innerType && innerType.toString().toLowerCase() === 'boolean') {
894       param.allowableValues = {};
895       param.isList = true;
896       param['enum'] = ["true", "false"];
897     }
898     if(typeof param['enum'] !== 'undefined') {
899       var id;
900       param.allowableValues = {};
901       param.allowableValues.values = [];
902       param.allowableValues.descriptiveValues = [];
903       for(id = 0; id < param['enum'].length; id++) {
904         var value = param['enum'][id];
905         var isDefault = (value === param.default) ? true : false;
906         param.allowableValues.values.push(value);
907         param.allowableValues.descriptiveValues.push({value : value, isDefault: isDefault});
908       }
909     }
910     if(param.type === 'array') {
911       innerType = [innerType];
912       if(typeof param.allowableValues === 'undefined') {
913         // can't show as a list if no values to select from
914         delete param.isList;
915         delete param.allowMultiple;
916       }
917     }
918     param.signature = this.getModelSignature(innerType, models).toString();
919     param.sampleJSON = this.getModelSampleJSON(innerType, models);
920     param.responseClassSignature = param.signature;
921   }
922
923   var defaultResponseCode, response, responses = this.responses;
924
925   if(responses['200']) {
926     response = responses['200'];
927     defaultResponseCode = '200';
928   }
929   else if(responses['201']) {
930     response = responses['201'];
931     defaultResponseCode = '201';
932   }
933   else if(responses['202']) {
934     response = responses['202'];
935     defaultResponseCode = '202';
936   }
937   else if(responses['203']) {
938     response = responses['203'];
939     defaultResponseCode = '203';
940   }
941   else if(responses['204']) {
942     response = responses['204'];
943     defaultResponseCode = '204';
944   }
945   else if(responses['205']) {
946     response = responses['205'];
947     defaultResponseCode = '205';
948   }
949   else if(responses['206']) {
950     response = responses['206'];
951     defaultResponseCode = '206';
952   }
953   else if(responses['default']) {
954     response = responses['default'];
955     defaultResponseCode = 'default';
956   }
957
958   if(response && response.schema) {
959     var resolvedModel = this.resolveModel(response.schema, definitions);
960     delete responses[defaultResponseCode];
961     if(resolvedModel) {
962       this.successResponse = {};
963       this.successResponse[defaultResponseCode] = resolvedModel;
964     }
965     else {
966       this.successResponse = {};
967       this.successResponse[defaultResponseCode] = response.schema.type;
968     }
969     this.type = response;
970   }
971
972   if (errors.length > 0) {
973     if(this.resource && this.resource.api && this.resource.api.fail)
974       this.resource.api.fail(errors);
975   }
976
977   return this;
978 };
979
980 OperationGroup.prototype.sort = function(sorter) {
981
982 };
983
984 Operation.prototype.getType = function (param) {
985   var type = param.type;
986   var format = param.format;
987   var isArray = false;
988   var str;
989   if(type === 'integer' && format === 'int32')
990     str = 'integer';
991   else if(type === 'integer' && format === 'int64')
992     str = 'long';
993   else if(type === 'integer')
994     str = 'integer';
995   else if(type === 'string') {
996     if(format === 'date-time')
997       str = 'date-time';
998     else if(format === 'date')
999       str = 'date';
1000     else
1001       str = 'string';
1002   }
1003   else if(type === 'number' && format === 'float')
1004     str = 'float';
1005   else if(type === 'number' && format === 'double')
1006     str = 'double';
1007   else if(type === 'number')
1008     str = 'double';
1009   else if(type === 'boolean')
1010     str = 'boolean';
1011   else if(type === 'array') {
1012     isArray = true;
1013     if(param.items)
1014       str = this.getType(param.items);
1015   }
1016   if(param.$ref)
1017     str = param.$ref;
1018
1019   var schema = param.schema;
1020   if(schema) {
1021     var ref = schema.$ref;
1022     if(ref) {
1023       ref = simpleRef(ref);
1024       if(isArray)
1025         return [ ref ];
1026       else
1027         return ref;
1028     }
1029     else
1030       return this.getType(schema);
1031   }
1032   if(isArray)
1033     return [ str ];
1034   else
1035     return str;
1036 };
1037
1038 Operation.prototype.resolveModel = function (schema, definitions) {
1039   if(typeof schema.$ref !== 'undefined') {
1040     var ref = schema.$ref;
1041     if(ref.indexOf('#/definitions/') === 0)
1042       ref = ref.substring('#/definitions/'.length);
1043     if(definitions[ref]) {
1044       return new Model(ref, definitions[ref]);
1045     }
1046   }
1047   if(schema.type === 'array')
1048     return new ArrayModel(schema);
1049   else
1050     return null;
1051 };
1052
1053 Operation.prototype.help = function(dontPrint) {
1054   var out = this.nickname + ': ' + this.summary + '\n';
1055   for(var i = 0; i < this.parameters.length; i++) {
1056     var param = this.parameters[i];
1057     var typeInfo = param.signature;
1058     out += '\n  * ' + param.name + ' (' + typeInfo + '): ' + param.description;
1059   }
1060   if(typeof dontPrint === 'undefined')
1061     log(out);
1062   return out;
1063 };
1064
1065 Operation.prototype.getModelSignature = function(type, definitions) {
1066   var isPrimitive, listType;
1067
1068   if(type instanceof Array) {
1069     listType = true;
1070     type = type[0];
1071   }
1072   else if(typeof type === 'undefined')
1073     type = 'undefined';
1074
1075   if(type === 'string')
1076     isPrimitive = true;
1077   else
1078     isPrimitive = (listType && definitions[listType]) || (definitions[type]) ? false : true;
1079   if (isPrimitive) {
1080     if(listType)
1081       return 'Array[' + type + ']';
1082     else
1083       return type.toString();
1084   } else {
1085     if (listType)
1086       return 'Array[' + definitions[type].getMockSignature() + ']';
1087     else
1088       return definitions[type].getMockSignature();
1089   }
1090 };
1091
1092 Operation.prototype.supportHeaderParams = function () {
1093   return true;
1094 };
1095
1096 Operation.prototype.supportedSubmitMethods = function () {
1097   return this.parent.supportedSubmitMethods;
1098 };
1099
1100 Operation.prototype.getHeaderParams = function (args) {
1101   var headers = this.setContentTypes(args, {});
1102   for(var i = 0; i < this.parameters.length; i++) {
1103     var param = this.parameters[i];
1104     if(typeof args[param.name] !== 'undefined') {
1105       if (param.in === 'header') {
1106         var value = args[param.name];
1107         if(Array.isArray(value))
1108           value = value.toString();
1109         headers[param.name] = value;
1110       }
1111     }
1112   }
1113   return headers;
1114 };
1115
1116 Operation.prototype.urlify = function (args) {
1117   var formParams = {};
1118   var requestUrl = this.path;
1119
1120   // grab params from the args, build the querystring along the way
1121   var querystring = '';
1122   for(var i = 0; i < this.parameters.length; i++) {
1123     var param = this.parameters[i];
1124     if(typeof args[param.name] !== 'undefined') {
1125       if(param.in === 'path') {
1126         var reg = new RegExp('\{' + param.name + '\}', 'gi');
1127         var value = args[param.name];
1128         if(Array.isArray(value))
1129           value = this.encodePathCollection(param.collectionFormat, param.name, value);
1130         else
1131           value = this.encodePathParam(value);
1132         requestUrl = requestUrl.replace(reg, value);
1133       }
1134       else if (param.in === 'query' && typeof args[param.name] !== 'undefined') {
1135         if(querystring === '')
1136           querystring += '?';
1137         else
1138           querystring += '&';
1139         if(typeof param.collectionFormat !== 'undefined') {
1140           var qp = args[param.name];
1141           if(Array.isArray(qp))
1142             querystring += this.encodeQueryCollection(param.collectionFormat, param.name, qp);
1143           else
1144             querystring += this.encodeQueryParam(param.name) + '=' + this.encodeQueryParam(args[param.name]);
1145         }
1146         else
1147           querystring += this.encodeQueryParam(param.name) + '=' + this.encodeQueryParam(args[param.name]);
1148       }
1149       else if (param.in === 'formData')
1150         formParams[param.name] = args[param.name];
1151     }
1152   }
1153   var url = this.scheme + '://' + this.host;
1154
1155   if(this.basePath !== '/')
1156     url += this.basePath;
1157
1158   return url + requestUrl + querystring;
1159 };
1160
1161 Operation.prototype.getMissingParams = function(args) {
1162   var missingParams = [];
1163   // check required params, track the ones that are missing
1164   var i;
1165   for(i = 0; i < this.parameters.length; i++) {
1166     var param = this.parameters[i];
1167     if(param.required === true) {
1168       if(typeof args[param.name] === 'undefined')
1169         missingParams = param.name;
1170     }
1171   }
1172   return missingParams;
1173 };
1174
1175 Operation.prototype.getBody = function(headers, args, opts) {
1176   var formParams = {}, body, key;
1177
1178   for(var i = 0; i < this.parameters.length; i++) {
1179     var param = this.parameters[i];
1180     if(typeof args[param.name] !== 'undefined') {
1181       if (param.in === 'body') {
1182         body = args[param.name];
1183       } else if(param.in === 'formData') {
1184         formParams[param.name] = args[param.name];
1185       }
1186     }
1187   }
1188
1189   // handle form params
1190   if(headers['Content-Type'] === 'application/x-www-form-urlencoded') {
1191     var encoded = "";
1192     for(key in formParams) {
1193       value = formParams[key];
1194       if(typeof value !== 'undefined'){
1195         if(encoded !== "")
1196           encoded += "&";
1197         encoded += encodeURIComponent(key) + '=' + encodeURIComponent(value);
1198       }
1199     }
1200     body = encoded;
1201   }
1202   else if (headers['Content-Type'] && headers['Content-Type'].indexOf('multipart/form-data') >= 0) {
1203     if(opts.useJQuery) {
1204       var bodyParam = new FormData();
1205       bodyParam.type = 'formData';
1206       for (key in formParams) {
1207         value = args[key];
1208         if (typeof value !== 'undefined') {
1209           // required for jquery file upload
1210           if(value.type === 'file' && value.value) {
1211             delete headers['Content-Type'];
1212             bodyParam.append(key, value.value);
1213           }
1214           else
1215             bodyParam.append(key, value);
1216         }
1217       }
1218       body = bodyParam;
1219     }
1220   }
1221
1222   return body;
1223 };
1224
1225 /**
1226  * gets sample response for a single operation
1227  **/
1228 Operation.prototype.getModelSampleJSON = function(type, models) {
1229   var isPrimitive, listType, sampleJson;
1230
1231   listType = (type instanceof Array);
1232   isPrimitive = models[type] ? false : true;
1233   sampleJson = isPrimitive ? void 0 : models[type].createJSONSample();
1234   if (sampleJson) {
1235     sampleJson = listType ? [sampleJson] : sampleJson;
1236     if(typeof sampleJson == 'string')
1237       return sampleJson;
1238     else if(typeof sampleJson === 'object') {
1239       var t = sampleJson;
1240       if(sampleJson instanceof Array && sampleJson.length > 0) {
1241         t = sampleJson[0];
1242       }
1243       if(t.nodeName) {
1244         var xmlString = new XMLSerializer().serializeToString(t);
1245         return this.formatXml(xmlString);
1246       }
1247       else
1248         return JSON.stringify(sampleJson, null, 2);
1249     }
1250     else
1251       return sampleJson;
1252   }
1253 };
1254
1255 /**
1256  * legacy binding
1257  **/
1258 Operation.prototype["do"] = function(args, opts, callback, error, parent) {
1259   return this.execute(args, opts, callback, error, parent);
1260 };
1261
1262
1263 /**
1264  * executes an operation
1265  **/
1266 Operation.prototype.execute = function(arg1, arg2, arg3, arg4, parent) {
1267   var args = arg1 || {};
1268   var opts = {}, success, error;
1269   if(typeof arg2 === 'object') {
1270     opts = arg2;
1271     success = arg3;
1272     error = arg4;
1273   }
1274
1275   if(typeof arg2 === 'function') {
1276     success = arg2;
1277     error = arg3;
1278   }
1279
1280   success = (success||log);
1281   error = (error||log);
1282
1283   if(opts.useJQuery)
1284     this.useJQuery = opts.useJQuery;
1285
1286   var missingParams = this.getMissingParams(args);
1287   if(missingParams.length > 0) {
1288     var message = 'missing required params: ' + missingParams;
1289     fail(message);
1290     return;
1291   }
1292   var allHeaders = this.getHeaderParams(args);
1293   var contentTypeHeaders = this.setContentTypes(args, opts);
1294
1295   var headers = {}, attrname;
1296   for (attrname in allHeaders) { headers[attrname] = allHeaders[attrname]; }
1297   for (attrname in contentTypeHeaders) { headers[attrname] = contentTypeHeaders[attrname]; }
1298
1299   var body = this.getBody(headers, args, opts);
1300   var url = this.urlify(args);
1301
1302   var obj = {
1303     url: url,
1304     method: this.method.toUpperCase(),
1305     body: body,
1306     useJQuery: this.useJQuery,
1307     headers: headers,
1308     on: {
1309       response: function(response) {
1310         return success(response, parent);
1311       },
1312       error: function(response) {
1313         return error(response, parent);
1314       }
1315     }
1316   };
1317   var status = authorizations.apply(obj, this.operation.security);
1318   if(opts.mock === true)
1319     return obj;
1320   else
1321     new SwaggerHttp().execute(obj, opts);
1322 };
1323
1324 Operation.prototype.setContentTypes = function(args, opts) {
1325   // default type
1326   var accepts = 'application/json';
1327   var consumes = args.parameterContentType || 'application/json';
1328   var allDefinedParams = this.parameters;
1329   var definedFormParams = [];
1330   var definedFileParams = [];
1331   var body;
1332   var headers = {};
1333
1334   // get params from the operation and set them in definedFileParams, definedFormParams, headers
1335   var i;
1336   for(i = 0; i < allDefinedParams.length; i++) {
1337     var param = allDefinedParams[i];
1338     if(param.in === 'formData') {
1339       if(param.type === 'file')
1340         definedFileParams.push(param);
1341       else
1342         definedFormParams.push(param);
1343     }
1344     else if(param.in === 'header' && opts) {
1345       var key = param.name;
1346       var headerValue = opts[param.name];
1347       if(typeof opts[param.name] !== 'undefined')
1348         headers[key] = headerValue;
1349     }
1350     else if(param.in === 'body' && typeof args[param.name] !== 'undefined') {
1351       body = args[param.name];
1352     }
1353   }
1354
1355   // if there's a body, need to set the consumes header via requestContentType
1356   if (body && (this.method === 'post' || this.method === 'put' || this.method === 'patch' || this.method === 'delete')) {
1357     if (opts.requestContentType)
1358       consumes = opts.requestContentType;
1359   } else {
1360     // if any form params, content type must be set
1361     if(definedFormParams.length > 0) {
1362       if(opts.requestContentType)           // override if set
1363         consumes = opts.requestContentType;
1364       else if(definedFileParams.length > 0) // if a file, must be multipart/form-data
1365         consumes = 'multipart/form-data';
1366       else                                  // default to x-www-from-urlencoded
1367         consumes = 'application/x-www-form-urlencoded';
1368     }
1369     else if (this.type == 'DELETE')
1370       body = '{}';
1371     else if (this.type != 'DELETE')
1372       consumes = null;
1373   }
1374
1375   if (consumes && this.consumes) {
1376     if (this.consumes.indexOf(consumes) === -1) {
1377       log('server doesn\'t consume ' + consumes + ', try ' + JSON.stringify(this.consumes));
1378     }
1379   }
1380
1381   if (opts.responseContentType) {
1382     accepts = opts.responseContentType;
1383   } else {
1384     accepts = 'application/json';
1385   }
1386   if (accepts && this.produces) {
1387     if (this.produces.indexOf(accepts) === -1) {
1388       log('server can\'t produce ' + accepts);
1389     }
1390   }
1391
1392   if ((consumes && body !== '') || (consumes === 'application/x-www-form-urlencoded'))
1393     headers['Content-Type'] = consumes;
1394   if (accepts)
1395     headers.Accept = accepts;
1396   return headers;
1397 };
1398
1399 Operation.prototype.asCurl = function (args) {
1400   var obj = this.execute(args, {mock: true});
1401   authorizations.apply(obj);
1402   var results = [];
1403   results.push('-X ' + this.method.toUpperCase());
1404   if (obj.headers) {
1405     var key;
1406     for (key in obj.headers)
1407       results.push('--header "' + key + ': ' + obj.headers[key] + '"');
1408   }
1409   if(obj.body) {
1410     var body;
1411     if(typeof obj.body === 'object')
1412       body = JSON.stringify(obj.body);
1413     else
1414       body = obj.body;
1415     results.push('-d "' + body.replace(/"/g, '\\"') + '"');
1416   }
1417   return 'curl ' + (results.join(' ')) + ' "' + obj.url + '"';
1418 };
1419
1420 Operation.prototype.encodePathCollection = function(type, name, value) {
1421   var encoded = '';
1422   var i;
1423   var separator = '';
1424   if(type === 'ssv')
1425     separator = '%20';
1426   else if(type === 'tsv')
1427     separator = '\\t';
1428   else if(type === 'pipes')
1429     separator = '|';
1430   else
1431     separator = ',';
1432
1433   for(i = 0; i < value.length; i++) {
1434     if(i === 0)
1435       encoded = this.encodeQueryParam(value[i]);
1436     else
1437       encoded += separator + this.encodeQueryParam(value[i]);
1438   }
1439   return encoded;
1440 };
1441
1442 Operation.prototype.encodeQueryCollection = function(type, name, value) {
1443   var encoded = '';
1444   var i;
1445   if(type === 'default' || type === 'multi') {
1446     for(i = 0; i < value.length; i++) {
1447       if(i > 0) encoded += '&';
1448       encoded += this.encodeQueryParam(name) + '=' + this.encodeQueryParam(value[i]);
1449     }
1450   }
1451   else {
1452     var separator = '';
1453     if(type === 'csv')
1454       separator = ',';
1455     else if(type === 'ssv')
1456       separator = '%20';
1457     else if(type === 'tsv')
1458       separator = '\\t';
1459     else if(type === 'pipes')
1460       separator = '|';
1461     else if(type === 'brackets') {
1462       for(i = 0; i < value.length; i++) {
1463         if(i !== 0)
1464           encoded += '&';
1465         encoded += this.encodeQueryParam(name) + '[]=' + this.encodeQueryParam(value[i]);
1466       }
1467     }
1468     if(separator !== '') {
1469       for(i = 0; i < value.length; i++) {
1470         if(i === 0)
1471           encoded = this.encodeQueryParam(name) + '=' + this.encodeQueryParam(value[i]);
1472         else
1473           encoded += separator + this.encodeQueryParam(value[i]);
1474       }
1475     }
1476   }
1477   return encoded;
1478 };
1479
1480 Operation.prototype.encodeQueryParam = function(arg) {
1481   return encodeURIComponent(arg);
1482 };
1483
1484 /**
1485  * TODO revisit, might not want to leave '/'
1486  **/
1487 Operation.prototype.encodePathParam = function(pathParam) {
1488   var encParts, part, parts, i, len;
1489   pathParam = pathParam.toString();
1490   if (pathParam.indexOf('/') === -1) {
1491     return encodeURIComponent(pathParam);
1492   } else {
1493     parts = pathParam.split('/');
1494     encParts = [];
1495     for (i = 0, len = parts.length; i < len; i++) {
1496       encParts.push(encodeURIComponent(parts[i]));
1497     }
1498     return encParts.join('/');
1499   }
1500 };
1501
1502 var Model = function(name, definition) {
1503   this.name = name;
1504   this.definition = definition || {};
1505   this.properties = [];
1506   var requiredFields = definition.required || [];
1507   if(definition.type === 'array') {
1508     var out = new ArrayModel(definition);
1509     return out;
1510   }
1511   var key;
1512   var props = definition.properties;
1513   if(props) {
1514     for(key in props) {
1515       var required = false;
1516       var property = props[key];
1517       if(requiredFields.indexOf(key) >= 0)
1518         required = true;
1519       this.properties.push(new Property(key, property, required));
1520     }
1521   }
1522 };
1523
1524 Model.prototype.createJSONSample = function(modelsToIgnore) {
1525   var i, result = {}, representations = {};
1526   modelsToIgnore = (modelsToIgnore||{});
1527   modelsToIgnore[this.name] = this;
1528   for (i = 0; i < this.properties.length; i++) {
1529     prop = this.properties[i];
1530     var sample = prop.getSampleValue(modelsToIgnore, representations);
1531     result[prop.name] = sample;
1532   }
1533   delete modelsToIgnore[this.name];
1534   return result;
1535 };
1536
1537 Model.prototype.getSampleValue = function(modelsToIgnore) {
1538   var i, obj = {}, representations = {};
1539   for(i = 0; i < this.properties.length; i++ ) {
1540     var property = this.properties[i];
1541     obj[property.name] = property.sampleValue(false, modelsToIgnore, representations);
1542   }
1543   return obj;
1544 };
1545
1546 Model.prototype.getMockSignature = function(modelsToIgnore) {
1547   var i, prop, propertiesStr = [];
1548   for (i = 0; i < this.properties.length; i++) {
1549     prop = this.properties[i];
1550     propertiesStr.push(prop.toString());
1551   }
1552   var strong = '<span class="strong">';
1553   var stronger = '<span class="stronger">';
1554   var strongClose = '</span>';
1555   var classOpen = strong + this.name + ' {' + strongClose;
1556   var classClose = strong + '}' + strongClose;
1557   var returnVal = classOpen + '<div>' + propertiesStr.join(',</div><div>') + '</div>' + classClose;
1558   if (!modelsToIgnore)
1559     modelsToIgnore = {};
1560
1561   modelsToIgnore[this.name] = this;
1562   for (i = 0; i < this.properties.length; i++) {
1563     prop = this.properties[i];
1564     var ref = prop.$ref;
1565     var model = models[ref];
1566     if (model && typeof modelsToIgnore[model.name] === 'undefined') {
1567       returnVal = returnVal + ('<br>' + model.getMockSignature(modelsToIgnore));
1568     }
1569   }
1570   return returnVal;
1571 };
1572
1573 var Property = function(name, obj, required) {
1574   this.schema = obj;
1575   this.required = required;
1576   if(obj.$ref)
1577     this.$ref = simpleRef(obj.$ref);
1578   else if (obj.type === 'array' && obj.items) {
1579     if(obj.items.$ref)
1580       this.$ref = simpleRef(obj.items.$ref);
1581     else
1582       obj = obj.items;
1583   }
1584   this.name = name;
1585   this.description = obj.description;
1586   this.obj = obj;
1587   this.optional = true;
1588   this.optional = !required;
1589   this.default = obj.default || null;
1590   this.example = obj.example !== undefined ? obj.example : null;
1591   this.collectionFormat = obj.collectionFormat || null;
1592   this.maximum = obj.maximum || null;
1593   this.exclusiveMaximum = obj.exclusiveMaximum || null;
1594   this.minimum = obj.minimum || null;
1595   this.exclusiveMinimum = obj.exclusiveMinimum || null;
1596   this.maxLength = obj.maxLength || null;
1597   this.minLength = obj.minLength || null;
1598   this.pattern = obj.pattern || null;
1599   this.maxItems = obj.maxItems || null;
1600   this.minItems = obj.minItems || null;
1601   this.uniqueItems = obj.uniqueItems || null;
1602   this['enum'] = obj['enum'] || null;
1603   this.multipleOf = obj.multipleOf || null;
1604 };
1605
1606 Property.prototype.getSampleValue = function (modelsToIgnore, representations) {
1607   return this.sampleValue(false, modelsToIgnore, representations);
1608 };
1609
1610 Property.prototype.isArray = function () {
1611   var schema = this.schema;
1612   if(schema.type === 'array')
1613     return true;
1614   else
1615     return false;
1616 };
1617
1618 Property.prototype.sampleValue = function(isArray, ignoredModels, representations) {
1619   isArray = (isArray || this.isArray());
1620   ignoredModels = (ignoredModels || {});
1621   // representations = (representations || {});
1622
1623   var type = getStringSignature(this.obj, true);
1624   var output;
1625
1626   if(this.$ref) {
1627     var refModelName = simpleRef(this.$ref);
1628     var refModel = models[refModelName];
1629     if(typeof representations[type] !== 'undefined') {
1630       return representations[type];
1631     }
1632     else
1633
1634     if(refModel && typeof ignoredModels[type] === 'undefined') {
1635       ignoredModels[type] = this;
1636       output = refModel.getSampleValue(ignoredModels, representations);
1637       representations[type] = output;
1638     }
1639     else {
1640       output = (representations[type] || refModelName);
1641     }
1642   }
1643   else if(this.example)
1644     output = this.example;
1645   else if(this.default)
1646     output = this.default;
1647   else if(type === 'date-time')
1648     output = new Date().toISOString();
1649   else if(type === 'date')
1650     output = new Date().toISOString().split("T")[0];
1651   else if(type === 'string')
1652     output = 'string';
1653   else if(type === 'integer')
1654     output = 0;
1655   else if(type === 'long')
1656     output = 0;
1657   else if(type === 'float')
1658     output = 0.0;
1659   else if(type === 'double')
1660     output = 0.0;
1661   else if(type === 'boolean')
1662     output = true;
1663   else
1664     output = {};
1665   ignoredModels[type] = output;
1666   if(isArray)
1667     return [output];
1668   else
1669     return output;
1670 };
1671
1672 getStringSignature = function(obj, baseComponent) {
1673   var str = '';
1674   if(typeof obj.$ref !== 'undefined')
1675     str += simpleRef(obj.$ref);
1676   else if(typeof obj.type === 'undefined')
1677     str += 'object';
1678   else if(obj.type === 'array') {
1679     if(baseComponent)
1680       str += getStringSignature((obj.items || obj.$ref || {}));
1681     else {
1682       str += 'Array[';
1683       str += getStringSignature((obj.items || obj.$ref || {}));
1684       str += ']';
1685     }
1686   }
1687   else if(obj.type === 'integer' && obj.format === 'int32')
1688     str += 'integer';
1689   else if(obj.type === 'integer' && obj.format === 'int64')
1690     str += 'long';
1691   else if(obj.type === 'integer' && typeof obj.format === 'undefined')
1692     str += 'long';
1693   else if(obj.type === 'string' && obj.format === 'date-time')
1694     str += 'date-time';
1695   else if(obj.type === 'string' && obj.format === 'date')
1696     str += 'date';
1697   else if(obj.type === 'string' && typeof obj.format === 'undefined')
1698     str += 'string';
1699   else if(obj.type === 'number' && obj.format === 'float')
1700     str += 'float';
1701   else if(obj.type === 'number' && obj.format === 'double')
1702     str += 'double';
1703   else if(obj.type === 'number' && typeof obj.format === 'undefined')
1704     str += 'double';
1705   else if(obj.type === 'boolean')
1706     str += 'boolean';
1707   else if(obj.$ref)
1708     str += simpleRef(obj.$ref);
1709   else
1710     str += obj.type;
1711   return str;
1712 };
1713
1714 simpleRef = function(name) {
1715   if(typeof name === 'undefined')
1716     return null;
1717   if(name.indexOf("#/definitions/") === 0)
1718     return name.substring('#/definitions/'.length);
1719   else
1720     return name;
1721 };
1722
1723 Property.prototype.toString = function() {
1724   var str = getStringSignature(this.obj);
1725   if(str !== '') {
1726     str = '<span class="propName ' + this.required + '">' + this.name + '</span> (<span class="propType">' + str + '</span>';
1727     if(!this.required)
1728       str += ', <span class="propOptKey">optional</span>';
1729     str += ')';
1730   }
1731   else
1732     str = this.name + ' (' + JSON.stringify(this.obj) + ')';
1733
1734   if(typeof this.description !== 'undefined')
1735     str += ': ' + this.description;
1736
1737   if (this['enum']) {
1738     str += ' = <span class="propVals">[\'' + this['enum'].join('\' or \'') + '\']</span>';
1739   }
1740   if (this.descr) {
1741     str += ': <span class="propDesc">' + this.descr + '</span>';
1742   }
1743
1744
1745   var options = ''; 
1746   var isArray = this.schema.type === 'array';
1747   var type;
1748
1749   if(isArray) {
1750     if(this.schema.items)
1751       type = this.schema.items.type;
1752     else
1753       type = '';
1754   }
1755   else {
1756     type = this.schema.type;
1757   }
1758
1759   if (this.default)
1760     options += optionHtml('Default', this.default);
1761
1762   switch (type) {
1763     case 'string':
1764       if (this.minLength)
1765         options += optionHtml('Min. Length', this.minLength);
1766       if (this.maxLength)
1767         options += optionHtml('Max. Length', this.maxLength);
1768       if (this.pattern)
1769         options += optionHtml('Reg. Exp.', this.pattern);
1770       break;
1771     case 'integer':
1772     case 'number':
1773       if (this.minimum)
1774         options += optionHtml('Min. Value', this.minimum);
1775       if (this.exclusiveMinimum)
1776         options += optionHtml('Exclusive Min.', "true");
1777       if (this.maximum)
1778         options += optionHtml('Max. Value', this.maximum);
1779       if (this.exclusiveMaximum)
1780         options += optionHtml('Exclusive Max.', "true");
1781       if (this.multipleOf)
1782         options += optionHtml('Multiple Of', this.multipleOf);
1783       break;
1784   }
1785
1786   if (isArray) {
1787     if (this.minItems)
1788       options += optionHtml('Min. Items', this.minItems);
1789     if (this.maxItems)
1790       options += optionHtml('Max. Items', this.maxItems);
1791     if (this.uniqueItems)
1792       options += optionHtml('Unique Items', "true");
1793     if (this.collectionFormat)
1794       options += optionHtml('Coll. Format', this.collectionFormat);
1795   }
1796
1797   if (this['enum']) {
1798     var enumString;
1799
1800     if (type === 'number' || type === 'integer')
1801       enumString = this['enum'].join(', ');
1802     else {
1803       enumString = '"' + this['enum'].join('", "') + '"';
1804     }
1805
1806     options += optionHtml('Enum', enumString);
1807   }     
1808
1809   if (options.length > 0)
1810     str = '<span class="propWrap">' + str + '<table class="optionsWrapper"><tr><th colspan="2">' + this.name + '</th></tr>' + options + '</table></span>';
1811   
1812   return str;
1813 };
1814
1815 optionHtml = function(label, value) {
1816   return '<tr><td class="optionName">' + label + ':</td><td>' + value + '</td></tr>';
1817 };
1818
1819 typeFromJsonSchema = function(type, format) {
1820   var str;
1821   if(type === 'integer' && format === 'int32')
1822     str = 'integer';
1823   else if(type === 'integer' && format === 'int64')
1824     str = 'long';
1825   else if(type === 'integer' && typeof format === 'undefined')
1826     str = 'long';
1827   else if(type === 'string' && format === 'date-time')
1828     str = 'date-time';
1829   else if(type === 'string' && format === 'date')
1830     str = 'date';
1831   else if(type === 'number' && format === 'float')
1832     str = 'float';
1833   else if(type === 'number' && format === 'double')
1834     str = 'double';
1835   else if(type === 'number' && typeof format === 'undefined')
1836     str = 'double';
1837   else if(type === 'boolean')
1838     str = 'boolean';
1839   else if(type === 'string')
1840     str = 'string';
1841
1842   return str;
1843 };
1844
1845 var sampleModels = {};
1846 var cookies = {};
1847 var models = {};
1848
1849 SwaggerClient.prototype.buildFrom1_2Spec = function (response) {
1850   if (response.apiVersion !== null) {
1851     this.apiVersion = response.apiVersion;
1852   }
1853   this.apis = {};
1854   this.apisArray = [];
1855   this.consumes = response.consumes;
1856   this.produces = response.produces;
1857   this.authSchemes = response.authorizations;
1858   this.info = this.convertInfo(response.info);
1859
1860   var isApi = false, i, res;
1861   for (i = 0; i < response.apis.length; i++) {
1862     var api = response.apis[i];
1863     if (api.operations) {
1864       var j;
1865       for (j = 0; j < api.operations.length; j++) {
1866         operation = api.operations[j];
1867         isApi = true;
1868       }
1869     }
1870   }
1871   if (response.basePath)
1872     this.basePath = response.basePath;
1873   else if (this.url.indexOf('?') > 0)
1874     this.basePath = this.url.substring(0, this.url.lastIndexOf('?'));
1875   else
1876     this.basePath = this.url;
1877
1878   if (isApi) {
1879     var newName = response.resourcePath.replace(/\//g, '');
1880     this.resourcePath = response.resourcePath;
1881     res = new SwaggerResource(response, this);
1882     this.apis[newName] = res;
1883     this.apisArray.push(res);
1884     this.finish();
1885   } else {
1886     var k;
1887     this.expectedResourceCount = response.apis.length;
1888     for (k = 0; k < response.apis.length; k++) {
1889       var resource = response.apis[k];
1890       res = new SwaggerResource(resource, this);
1891       this.apis[res.name] = res;
1892       this.apisArray.push(res);
1893     }
1894   }
1895   this.isValid = true;
1896   return this;
1897 };
1898
1899 SwaggerClient.prototype.finish = function() {
1900   if (typeof this.success === 'function') {
1901     this.isValid = true;
1902     this.ready = true;
1903     this.isBuilt = true;
1904     this.selfReflect();
1905     this.success();
1906   }  
1907 };
1908
1909 SwaggerClient.prototype.buildFrom1_1Spec = function (response) {
1910   log('This API is using a deprecated version of Swagger!  Please see http://github.com/wordnik/swagger-core/wiki for more info');
1911   if (response.apiVersion !== null)
1912     this.apiVersion = response.apiVersion;
1913   this.apis = {};
1914   this.apisArray = [];
1915   this.produces = response.produces;
1916   this.info = this.convertInfo(response.info);
1917   var isApi = false, res;
1918   for (var i = 0; i < response.apis.length; i++) {
1919     var api = response.apis[i];
1920     if (api.operations) {
1921       for (var j = 0; j < api.operations.length; j++) {
1922         operation = api.operations[j];
1923         isApi = true;
1924       }
1925     }
1926   }
1927   if (response.basePath) {
1928     this.basePath = response.basePath;
1929   } else if (this.url.indexOf('?') > 0) {
1930     this.basePath = this.url.substring(0, this.url.lastIndexOf('?'));
1931   } else {
1932     this.basePath = this.url;
1933   }
1934   if (isApi) {
1935     var newName = response.resourcePath.replace(/\//g, '');
1936     this.resourcePath = response.resourcePath;
1937     res = new SwaggerResource(response, this);
1938     this.apis[newName] = res;
1939     this.apisArray.push(res);
1940     this.finish();
1941   } else {
1942     this.expectedResourceCount = response.apis.length;
1943     for (k = 0; k < response.apis.length; k++) {
1944       resource = response.apis[k];
1945       res = new SwaggerResource(resource, this);
1946       this.apis[res.name] = res;
1947       this.apisArray.push(res);
1948     }
1949   }
1950   this.isValid = true;
1951   return this;
1952 };
1953
1954 SwaggerClient.prototype.convertInfo = function (resp) {
1955   if(typeof resp == 'object') {
1956     var info = {};
1957
1958     info.title = resp.title;
1959     info.description = resp.description;
1960     info.termsOfService = resp.termsOfServiceUrl;
1961     info.contact = {};
1962     info.contact.name = resp.contact;
1963     info.license = {};
1964     info.license.name = resp.license;
1965     info.license.url = resp.licenseUrl;
1966
1967     return info;
1968   }
1969 };
1970
1971 SwaggerClient.prototype.selfReflect = function () {
1972   var resource, tag, ref;
1973   if (this.apis === null) {
1974     return false;
1975   }
1976   ref = this.apis;
1977   for (tag in ref) {
1978     api = ref[tag];
1979     if (api.ready === null) {
1980       return false;
1981     }
1982     this[tag] = api;
1983     this[tag].help = __bind(api.help, api);
1984   }
1985   this.setConsolidatedModels();
1986   this.ready = true;
1987 };
1988
1989 SwaggerClient.prototype.setConsolidatedModels = function () {
1990   var model, modelName, resource, resource_name, i, apis, models, results;
1991   this.models = {};
1992   apis = this.apis;
1993   for (resource_name in apis) {
1994     resource = apis[resource_name];
1995     for (modelName in resource.models) {
1996       if (typeof this.models[modelName] === 'undefined') {
1997         this.models[modelName] = resource.models[modelName];
1998         this.modelsArray.push(resource.models[modelName]);
1999       }
2000     }
2001   }
2002   models = this.modelsArray;
2003   results = [];
2004   for (i = 0; i < models.length; i++) {
2005     model = models[i];
2006     results.push(model.setReferencedModels(this.models));
2007   }
2008   return results;
2009 };
2010
2011 var SwaggerResource = function (resourceObj, api) {
2012   var _this = this;
2013   this.api = api;
2014   this.swaggerRequstHeaders = api.swaggerRequstHeaders;
2015   this.path = (typeof this.api.resourcePath === 'string') ? this.api.resourcePath : resourceObj.path;
2016   this.description = resourceObj.description;
2017   this.authorizations = (resourceObj.authorizations || {});
2018
2019   var parts = this.path.split('/');
2020   this.name = parts[parts.length - 1].replace('.{format}', '');
2021   this.basePath = this.api.basePath;
2022   this.operations = {};
2023   this.operationsArray = [];
2024   this.modelsArray = [];
2025   this.models = api.models || {};
2026   this.rawModels = {};
2027   this.useJQuery = (typeof api.useJQuery !== 'undefined') ? api.useJQuery : null;
2028
2029   if ((resourceObj.apis) && this.api.resourcePath) {
2030     this.addApiDeclaration(resourceObj);
2031   } else {
2032     if (typeof this.path === 'undefined') {
2033       this.api.fail('SwaggerResources must have a path.');
2034     }
2035     if (this.path.substring(0, 4) === 'http') {
2036       this.url = this.path.replace('{format}', 'json');
2037     } else {
2038       this.url = this.api.basePath + this.path.replace('{format}', 'json');
2039     }
2040     this.api.progress('fetching resource ' + this.name + ': ' + this.url);
2041     var obj = {
2042       url: this.url,
2043       method: 'GET',
2044       useJQuery: this.useJQuery,
2045       headers: {
2046         accept: this.swaggerRequstHeaders
2047       },
2048       on: {
2049         response: function (resp) {
2050           var responseObj = resp.obj || JSON.parse(resp.data);
2051           _this.api.resourceCount += 1;
2052           return _this.addApiDeclaration(responseObj);
2053         },
2054         error: function (response) {
2055           _this.api.resourceCount += 1;
2056           return _this.api.fail('Unable to read api \'' +
2057           _this.name + '\' from path ' + _this.url + ' (server returned ' + response.statusText + ')');
2058         }
2059       }
2060     };
2061     var e = typeof window !== 'undefined' ? window : exports;
2062     e.authorizations.apply(obj);
2063     new SwaggerHttp().execute(obj);
2064   }
2065 };
2066
2067 SwaggerResource.prototype.help = function (dontPrint) {
2068   var i;
2069   var output = 'operations for the "' + this.name + '" tag';
2070   for(i = 0; i < this.operationsArray.length; i++) {
2071     var api = this.operationsArray[i];
2072     output += '\n  * ' + api.nickname + ': ' + api.description;
2073   }
2074   if(dontPrint)
2075     return output;
2076   else {
2077     log(output);
2078     return output;
2079   }
2080 };
2081
2082 SwaggerResource.prototype.getAbsoluteBasePath = function (relativeBasePath) {
2083   var pos, url;
2084   url = this.api.basePath;
2085   pos = url.lastIndexOf(relativeBasePath);
2086   var parts = url.split('/');
2087   var rootUrl = parts[0] + '//' + parts[2];
2088
2089   if (relativeBasePath.indexOf('http') === 0)
2090     return relativeBasePath;
2091   if (relativeBasePath === '/')
2092     return rootUrl;
2093   if (relativeBasePath.substring(0, 1) == '/') {
2094     // use root + relative
2095     return rootUrl + relativeBasePath;
2096   }
2097   else {
2098     pos = this.basePath.lastIndexOf('/');
2099     var base = this.basePath.substring(0, pos);
2100     if (base.substring(base.length - 1) == '/')
2101       return base + relativeBasePath;
2102     else
2103       return base + '/' + relativeBasePath;
2104   }
2105 };
2106
2107 SwaggerResource.prototype.addApiDeclaration = function (response) {
2108   if (typeof response.produces === 'string')
2109     this.produces = response.produces;
2110   if (typeof response.consumes === 'string')
2111     this.consumes = response.consumes;
2112   if ((typeof response.basePath === 'string') && response.basePath.replace(/\s/g, '').length > 0)
2113     this.basePath = response.basePath.indexOf('http') === -1 ? this.getAbsoluteBasePath(response.basePath) : response.basePath;
2114   this.resourcePath = response.resourcePath;
2115   this.addModels(response.models);
2116   if (response.apis) {
2117     for (var i = 0 ; i < response.apis.length; i++) {
2118       var endpoint = response.apis[i];
2119       this.addOperations(endpoint.path, endpoint.operations, response.consumes, response.produces);
2120     }
2121   }
2122   this.api[this.name] = this;
2123   this.ready = true;
2124   if(this.api.resourceCount === this.api.expectedResourceCount)
2125     this.api.finish();
2126   return this;
2127 };
2128
2129 SwaggerResource.prototype.addModels = function (models) {
2130   if (typeof models === 'object') {
2131     var modelName;
2132     for (modelName in models) {
2133       if (typeof this.models[modelName] === 'undefined') {
2134         var swaggerModel = new SwaggerModel(modelName, models[modelName]);
2135         this.modelsArray.push(swaggerModel);
2136         this.models[modelName] = swaggerModel;
2137         this.rawModels[modelName] = models[modelName];
2138       }
2139     }
2140     var output = [];
2141     for (var i = 0; i < this.modelsArray.length; i++) {
2142       var model = this.modelsArray[i];
2143       output.push(model.setReferencedModels(this.models));
2144     }
2145     return output;
2146   }
2147 };
2148
2149 SwaggerResource.prototype.addOperations = function (resource_path, ops, consumes, produces) {
2150   if (ops) {
2151     var output = [];
2152     for (var i = 0; i < ops.length; i++) {
2153       var o = ops[i];
2154       consumes = this.consumes;
2155       produces = this.produces;
2156       if (typeof o.consumes !== 'undefined')
2157         consumes = o.consumes;
2158       else
2159         consumes = this.consumes;
2160
2161       if (typeof o.produces !== 'undefined')
2162         produces = o.produces;
2163       else
2164         produces = this.produces;
2165       var type = (o.type || o.responseClass);
2166
2167       if (type === 'array') {
2168         ref = null;
2169         if (o.items)
2170           ref = o.items.type || o.items.$ref;
2171         type = 'array[' + ref + ']';
2172       }
2173       var responseMessages = o.responseMessages;
2174       var method = o.method;
2175       if (o.httpMethod) {
2176         method = o.httpMethod;
2177       }
2178       if (o.supportedContentTypes) {
2179         consumes = o.supportedContentTypes;
2180       }
2181       if (o.errorResponses) {
2182         responseMessages = o.errorResponses;
2183         for (var j = 0; j < responseMessages.length; j++) {
2184           r = responseMessages[j];
2185           r.message = r.reason;
2186           r.reason = null;
2187         }
2188       }
2189       o.nickname = this.sanitize(o.nickname);
2190       var op = new SwaggerOperation(o.nickname,
2191           resource_path,
2192           method,
2193           o.parameters,
2194           o.summary,
2195           o.notes,
2196           type,
2197           responseMessages, 
2198           this, 
2199           consumes, 
2200           produces, 
2201           o.authorizations, 
2202           o.deprecated);
2203
2204       this.operations[op.nickname] = op;
2205       output.push(this.operationsArray.push(op));
2206     }
2207     return output;
2208   }
2209 };
2210
2211 SwaggerResource.prototype.sanitize = function (nickname) {
2212   var op;
2213   op = nickname.replace(/[\s!@#$%^&*()_+=\[{\]};:<>|.\/?,\\'""-]/g, '_');
2214   op = op.replace(/((_){2,})/g, '_');
2215   op = op.replace(/^(_)*/g, '');
2216   op = op.replace(/([_])*$/g, '');
2217   return op;
2218 };
2219
2220 var SwaggerModel = function (modelName, obj) {
2221   this.name = typeof obj.id !== 'undefined' ? obj.id : modelName;
2222   this.properties = [];
2223   var propertyName;
2224   for (propertyName in obj.properties) {
2225     if (obj.required) {
2226       var value;
2227       for (value in obj.required) {
2228         if (propertyName === obj.required[value]) {
2229           obj.properties[propertyName].required = true;
2230         }
2231       }
2232     }
2233     var prop = new SwaggerModelProperty(propertyName, obj.properties[propertyName], this);
2234     this.properties.push(prop);
2235   }
2236 };
2237
2238 SwaggerModel.prototype.setReferencedModels = function (allModels) {
2239   var results = [];
2240   for (var i = 0; i < this.properties.length; i++) {
2241     var property = this.properties[i];
2242     var type = property.type || property.dataType;
2243     if (allModels[type])
2244       results.push(property.refModel = allModels[type]);
2245     else if ((property.refDataType) && (allModels[property.refDataType]))
2246       results.push(property.refModel = allModels[property.refDataType]);
2247     else
2248       results.push(void 0);
2249   }
2250   return results;
2251 };
2252
2253 SwaggerModel.prototype.getMockSignature = function (modelsToIgnore) {
2254   var i, prop, propertiesStr = [];
2255   for (i = 0; i < this.properties.length; i++) {
2256     prop = this.properties[i];
2257     propertiesStr.push(prop.toString());
2258   }
2259
2260   var strong = '<span class="strong">';
2261   var strongClose = '</span>';
2262   var classOpen = strong + this.name + ' {' + strongClose;
2263   var classClose = strong + '}' + strongClose;
2264   var returnVal = classOpen + '<div>' + propertiesStr.join(',</div><div>') + '</div>' + classClose;
2265   if (!modelsToIgnore)
2266     modelsToIgnore = [];
2267   modelsToIgnore.push(this.name);
2268
2269   for (i = 0; i < this.properties.length; i++) {
2270     prop = this.properties[i];
2271     if ((prop.refModel) && modelsToIgnore.indexOf(prop.refModel.name) === -1) {
2272       returnVal = returnVal + ('<br>' + prop.refModel.getMockSignature(modelsToIgnore));
2273     }
2274   }
2275   return returnVal;
2276 };
2277
2278 SwaggerModel.prototype.createJSONSample = function (modelsToIgnore) {
2279   if (sampleModels[this.name]) {
2280     return sampleModels[this.name];
2281   }
2282   else {
2283     var result = {};
2284     modelsToIgnore = (modelsToIgnore || []);
2285     modelsToIgnore.push(this.name);
2286     for (var i = 0; i < this.properties.length; i++) {
2287       var prop = this.properties[i];
2288       result[prop.name] = prop.getSampleValue(modelsToIgnore);
2289     }
2290     modelsToIgnore.pop(this.name);
2291     return result;
2292   }
2293 };
2294
2295 var SwaggerModelProperty = function (name, obj, model) {
2296   this.name = name;
2297   this.dataType = obj.type || obj.dataType || obj.$ref;
2298   this.isCollection = this.dataType && (this.dataType.toLowerCase() === 'array' || this.dataType.toLowerCase() === 'list' || this.dataType.toLowerCase() === 'set');
2299   this.descr = obj.description;
2300   this.required = obj.required;
2301   this.defaultValue = applyModelPropertyMacro(obj, model);
2302   if (obj.items) {
2303     if (obj.items.type) {
2304       this.refDataType = obj.items.type;
2305     }
2306     if (obj.items.$ref) {
2307       this.refDataType = obj.items.$ref;
2308     }
2309   }
2310   this.dataTypeWithRef = this.refDataType ? (this.dataType + '[' + this.refDataType + ']') : this.dataType;
2311   if (obj.allowableValues) {
2312     this.valueType = obj.allowableValues.valueType;
2313     this.values = obj.allowableValues.values;
2314     if (this.values) {
2315       this.valuesString = '\'' + this.values.join('\' or \'') + '\'';
2316     }
2317   }
2318   if (obj['enum']) {
2319     this.valueType = 'string';
2320     this.values = obj['enum'];
2321     if (this.values) {
2322       this.valueString = '\'' + this.values.join('\' or \'') + '\'';
2323     }
2324   }
2325 };
2326
2327 SwaggerModelProperty.prototype.getSampleValue = function (modelsToIgnore) {
2328   var result;
2329   if ((this.refModel) && (modelsToIgnore.indexOf(this.refModel.name) === -1)) {
2330     result = this.refModel.createJSONSample(modelsToIgnore);
2331   } else {
2332     if (this.isCollection) {
2333       result = this.toSampleValue(this.refDataType);
2334     } else {
2335       result = this.toSampleValue(this.dataType);
2336     }
2337   }
2338   if (this.isCollection) {
2339     return [result];
2340   } else {
2341     return result;
2342   }
2343 };
2344
2345 SwaggerModelProperty.prototype.toSampleValue = function (value) {
2346   var result;
2347   if ((typeof this.defaultValue !== 'undefined') && this.defaultValue) {
2348     result = this.defaultValue;
2349   } else if (value === 'integer') {
2350     result = 0;
2351   } else if (value === 'boolean') {
2352     result = false;
2353   } else if (value === 'double' || value === 'number') {
2354     result = 0.0;
2355   } else if (value === 'string') {
2356     result = '';
2357   } else {
2358     result = value;
2359   }
2360   return result;
2361 };
2362
2363 SwaggerModelProperty.prototype.toString = function () {
2364   var req = this.required ? 'propReq' : 'propOpt';
2365   var str = '<span class="propName ' + req + '">' + this.name + '</span> (<span class="propType">' + this.dataTypeWithRef + '</span>';
2366   if (!this.required) {
2367     str += ', <span class="propOptKey">optional</span>';
2368   }
2369   str += ')';
2370   if (this.values) {
2371     str += ' = <span class="propVals">[\'' + this.values.join('\' or \'') + '\']</span>';
2372   }
2373   if (this.descr) {
2374     str += ': <span class="propDesc">' + this.descr + '</span>';
2375   }
2376   return str;
2377 };
2378
2379 var SwaggerOperation = function (nickname, path, method, parameters, summary, notes, type, responseMessages, resource, consumes, produces, authorizations, deprecated) {
2380   var _this = this;
2381
2382   var errors = [];
2383   this.nickname = (nickname || errors.push('SwaggerOperations must have a nickname.'));
2384   this.path = (path || errors.push('SwaggerOperation ' + nickname + ' is missing path.'));
2385   this.method = (method || errors.push('SwaggerOperation ' + nickname + ' is missing method.'));
2386   this.parameters = parameters ? parameters : [];
2387   this.summary = summary;
2388   this.notes = notes;
2389   this.type = type;
2390   this.responseMessages = (responseMessages || []);
2391   this.resource = (resource || errors.push('Resource is required'));
2392   this.consumes = consumes;
2393   this.produces = produces;
2394   this.authorizations = typeof authorizations !== 'undefined' ? authorizations : resource.authorizations;
2395   this.deprecated = deprecated;
2396   this['do'] = __bind(this['do'], this);
2397
2398
2399   if(typeof this.deprecated === 'string') {
2400     switch(this.deprecated.toLowerCase()) {
2401       case 'true': case 'yes': case '1': {
2402         this.deprecated = true;
2403         break;
2404       }
2405       case 'false': case 'no': case '0': case null: {
2406         this.deprecated = false;
2407         break;
2408       }
2409       default: this.deprecated = Boolean(this.deprecated);
2410     }
2411   }
2412
2413   if (errors.length > 0) {
2414     console.error('SwaggerOperation errors', errors, arguments);
2415     this.resource.api.fail(errors);
2416   }
2417
2418   this.path = this.path.replace('{format}', 'json');
2419   this.method = this.method.toLowerCase();
2420   this.isGetMethod = this.method === 'get';
2421
2422   var i, j, v;
2423   this.resourceName = this.resource.name;
2424   if (typeof this.type !== 'undefined' && this.type === 'void')
2425     this.type = null;
2426   else {
2427     this.responseClassSignature = this.getSignature(this.type, this.resource.models);
2428     this.responseSampleJSON = this.getSampleJSON(this.type, this.resource.models);
2429   }
2430
2431   for (i = 0; i < this.parameters.length; i++) {
2432     var param = this.parameters[i];
2433     // might take this away
2434     param.name = param.name || param.type || param.dataType;
2435     // for 1.1 compatibility
2436     type = param.type || param.dataType;
2437     if (type === 'array') {
2438       type = 'array[' + (param.items.$ref ? param.items.$ref : param.items.type) + ']';
2439     }
2440     param.type = type;
2441
2442     if (type && type.toLowerCase() === 'boolean') {
2443       param.allowableValues = {};
2444       param.allowableValues.values = ['true', 'false'];
2445     }
2446     param.signature = this.getSignature(type, this.resource.models);
2447     param.sampleJSON = this.getSampleJSON(type, this.resource.models);
2448
2449     var enumValue = param['enum'];
2450     if (typeof enumValue !== 'undefined') {
2451       param.isList = true;
2452       param.allowableValues = {};
2453       param.allowableValues.descriptiveValues = [];
2454
2455       for (j = 0; j < enumValue.length; j++) {
2456         v = enumValue[j];
2457         if (param.defaultValue) {
2458           param.allowableValues.descriptiveValues.push({
2459             value: String(v),
2460             isDefault: (v === param.defaultValue)
2461           });
2462         }
2463         else {
2464           param.allowableValues.descriptiveValues.push({
2465             value: String(v),
2466             isDefault: false
2467           });
2468         }
2469       }
2470     }
2471     else if (param.allowableValues) {
2472       if (param.allowableValues.valueType === 'RANGE')
2473         param.isRange = true;
2474       else
2475         param.isList = true;
2476       if (param.allowableValues) {
2477         param.allowableValues.descriptiveValues = [];
2478         if (param.allowableValues.values) {
2479           for (j = 0; j < param.allowableValues.values.length; j++) {
2480             v = param.allowableValues.values[j];
2481             if (param.defaultValue !== null) {
2482               param.allowableValues.descriptiveValues.push({
2483                 value: String(v),
2484                 isDefault: (v === param.defaultValue)
2485               });
2486             }
2487             else {
2488               param.allowableValues.descriptiveValues.push({
2489                 value: String(v),
2490                 isDefault: false
2491               });
2492             }
2493           }
2494         }
2495       }
2496     }
2497     param.defaultValue = applyParameterMacro(this, param);
2498   }
2499   var defaultSuccessCallback = this.resource.api.defaultSuccessCallback || null;
2500   var defaultErrorCallback = this.resource.api.defaultErrorCallback || null;
2501
2502   this.resource[this.nickname] = function (args, opts, callback, error) {
2503     var arg1, arg2, arg3, arg4;
2504     if(typeof args === 'function') {  // right shift 3
2505       arg1 = {}; arg2 = {}; arg3 = args; arg4 = opts;
2506     }
2507     else if(typeof args === 'object' && typeof opts === 'function') { // right shift 2
2508       arg1 = args; arg2 = {}; arg3 = opts; arg4 = callback;
2509     }
2510     else {
2511       arg1 = args; arg2 = opts; arg3 = callback; arg4 = error;
2512     }
2513     return _this['do'](arg1 || {}, arg2 || {}, arg3 || defaultSuccessCallback, arg4 || defaultErrorCallback);
2514   };
2515
2516   this.resource[this.nickname].help = function (dontPrint) {
2517     return _this.help(dontPrint);
2518   };
2519   this.resource[this.nickname].asCurl = function (args) {
2520     return _this.asCurl(args);
2521   };
2522 };
2523
2524 SwaggerOperation.prototype.isListType = function (type) {
2525   if (type && type.indexOf('[') >= 0) {
2526     return type.substring(type.indexOf('[') + 1, type.indexOf(']'));
2527   } else {
2528     return void 0;
2529   }
2530 };
2531
2532 SwaggerOperation.prototype.getSignature = function (type, models) {
2533   var isPrimitive, listType;
2534   listType = this.isListType(type);
2535   isPrimitive = ((typeof listType !== 'undefined') && models[listType]) || (typeof models[type] !== 'undefined') ? false : true;
2536   if (isPrimitive) {
2537     return type;
2538   } else {
2539     if (typeof listType !== 'undefined') {
2540       return models[listType].getMockSignature();
2541     } else {
2542       return models[type].getMockSignature();
2543     }
2544   }
2545 };
2546
2547 SwaggerOperation.prototype.getSampleJSON = function (type, models) {
2548   var isPrimitive, listType, val;
2549   listType = this.isListType(type);
2550   isPrimitive = ((typeof listType !== 'undefined') && models[listType]) || (typeof models[type] !== 'undefined') ? false : true;
2551   val = isPrimitive ? void 0 : (listType ? models[listType].createJSONSample() : models[type].createJSONSample());
2552   if (val) {
2553     val = listType ? [val] : val;
2554     if (typeof val == 'string')
2555       return val;
2556     else if (typeof val === 'object') {
2557       var t = val;
2558       if (val instanceof Array && val.length > 0) {
2559         t = val[0];
2560       }
2561       if (t.nodeName) {
2562         var xmlString = new XMLSerializer().serializeToString(t);
2563         return this.formatXml(xmlString);
2564       }
2565       else
2566         return JSON.stringify(val, null, 2);
2567     }
2568     else
2569       return val;
2570   }
2571 };
2572
2573 SwaggerOperation.prototype['do'] = function (args, opts, callback, error) {
2574   var key, param, params, possibleParams = [], req, value;
2575
2576   if (typeof error !== 'function') {
2577     error = function (xhr, textStatus, error) {
2578       return log(xhr, textStatus, error);
2579     };
2580   }
2581
2582   if (typeof callback !== 'function') {
2583     callback = function (response) {
2584       var content;
2585       content = null;
2586       if (response !== null) {
2587         content = response.data;
2588       } else {
2589         content = 'no data';
2590       }
2591       return log('default callback: ' + content);
2592     };
2593   }
2594
2595   params = {};
2596   params.headers = [];
2597   if (args.headers) {
2598     params.headers = args.headers;
2599     delete args.headers;
2600   }
2601   // allow override from the opts
2602   if(opts && opts.responseContentType) {
2603     params.headers['Content-Type'] = opts.responseContentType;
2604   }
2605   if(opts && opts.requestContentType) {
2606     params.headers.Accept = opts.requestContentType;
2607   }
2608
2609   for (var i = 0; i < this.parameters.length; i++) {
2610     param = this.parameters[i];
2611     if (param.paramType === 'header') {
2612       if (typeof args[param.name] !== 'undefined')
2613         params.headers[param.name] = args[param.name];
2614     }
2615     else if (param.paramType === 'form' || param.paramType.toLowerCase() === 'file')
2616       possibleParams.push(param);
2617     else if (param.paramType === 'body' && param.name !== 'body' && typeof args[param.name] !== 'undefined') {
2618       if (args.body) {
2619         throw new Error('Saw two body params in an API listing; expecting a max of one.');
2620       }
2621       args.body = args[param.name];
2622     }
2623   }
2624
2625   if (typeof args.body !== 'undefined') {
2626     params.body = args.body;
2627     delete args.body;
2628   }
2629
2630   if (possibleParams) {
2631     for (key in possibleParams) {
2632       value = possibleParams[key];
2633       if (args[value.name]) {
2634         params[value.name] = args[value.name];
2635       }
2636     }
2637   }
2638
2639   req = new SwaggerRequest(this.method, this.urlify(args), params, opts, callback, error, this);
2640   if (opts.mock) {
2641     return req;
2642   } else {
2643     return true;
2644   }
2645 };
2646
2647 SwaggerOperation.prototype.pathJson = function () {
2648   return this.path.replace('{format}', 'json');
2649 };
2650
2651 SwaggerOperation.prototype.pathXml = function () {
2652   return this.path.replace('{format}', 'xml');
2653 };
2654
2655 SwaggerOperation.prototype.encodePathParam = function (pathParam) {
2656   var encParts, part, parts, _i, _len;
2657   pathParam = pathParam.toString();
2658   if (pathParam.indexOf('/') === -1) {
2659     return encodeURIComponent(pathParam);
2660   } else {
2661     parts = pathParam.split('/');
2662     encParts = [];
2663     for (_i = 0, _len = parts.length; _i < _len; _i++) {
2664       part = parts[_i];
2665       encParts.push(encodeURIComponent(part));
2666     }
2667     return encParts.join('/');
2668   }
2669 };
2670
2671 SwaggerOperation.prototype.urlify = function (args) {
2672   var i, j, param, url;
2673   // ensure no double slashing...
2674   if(this.resource.basePath.length > 1 && this.resource.basePath.slice(-1) === '/' && this.pathJson().charAt(0) === '/')
2675     url = this.resource.basePath + this.pathJson().substring(1);
2676   else
2677     url = this.resource.basePath + this.pathJson();
2678   var params = this.parameters;
2679   for (i = 0; i < params.length; i++) {
2680     param = params[i];
2681     if (param.paramType === 'path') {
2682       if (typeof args[param.name] !== 'undefined') {
2683         // apply path params and remove from args
2684         var reg = new RegExp('\\{\\s*?' + param.name + '[^\\{\\}\\/]*(?:\\{.*?\\}[^\\{\\}\\/]*)*\\}(?=(\\/?|$))', 'gi');
2685         url = url.replace(reg, this.encodePathParam(args[param.name]));
2686         delete args[param.name];
2687       }
2688       else
2689         throw '' + param.name + ' is a required path param.';
2690     }
2691   }
2692
2693   var queryParams = '';
2694   for (i = 0; i < params.length; i++) {
2695     param = params[i];
2696     if(param.paramType === 'query') {
2697       if (queryParams !== '')
2698         queryParams += '&';    
2699       if (Array.isArray(param)) {
2700         var output = '';   
2701         for(j = 0; j < param.length; j++) {    
2702           if(j > 0)    
2703             output += ',';   
2704           output += encodeURIComponent(param[j]);    
2705         }    
2706         queryParams += encodeURIComponent(param.name) + '=' + output;    
2707       }
2708       else {
2709         if (typeof args[param.name] !== 'undefined') {
2710           queryParams += encodeURIComponent(param.name) + '=' + encodeURIComponent(args[param.name]);
2711         } else {
2712           if (param.required)
2713             throw '' + param.name + ' is a required query param.';
2714         }
2715       }
2716     }
2717   }
2718   if ((queryParams) && queryParams.length > 0)
2719     url += '?' + queryParams;
2720   return url;
2721 };
2722
2723 SwaggerOperation.prototype.supportHeaderParams = function () {
2724   return this.resource.api.supportHeaderParams;
2725 };
2726
2727 SwaggerOperation.prototype.supportedSubmitMethods = function () {
2728   return this.resource.api.supportedSubmitMethods;
2729 };
2730
2731 SwaggerOperation.prototype.getQueryParams = function (args) {
2732   return this.getMatchingParams(['query'], args);
2733 };
2734
2735 SwaggerOperation.prototype.getHeaderParams = function (args) {
2736   return this.getMatchingParams(['header'], args);
2737 };
2738
2739 SwaggerOperation.prototype.getMatchingParams = function (paramTypes, args) {
2740   var matchingParams = {};
2741   var params = this.parameters;
2742   for (var i = 0; i < params.length; i++) {
2743     param = params[i];
2744     if (args && args[param.name])
2745       matchingParams[param.name] = args[param.name];
2746   }
2747   var headers = this.resource.api.headers;
2748   var name;
2749   for (name in headers) {
2750     var value = headers[name];
2751     matchingParams[name] = value;
2752   }
2753   return matchingParams;
2754 };
2755
2756 SwaggerOperation.prototype.help = function (dontPrint) {
2757   var msg = this.nickname + ': ' + this.summary;
2758   var params = this.parameters;
2759   for (var i = 0; i < params.length; i++) {
2760     var param = params[i];
2761     msg += '\n* ' + param.name + (param.required ? ' (required)' : '') + " - " + param.description;
2762   }
2763   if(dontPrint)
2764     return msg;
2765   else {
2766     console.log(msg);
2767     return msg;
2768   }
2769 };
2770
2771 SwaggerOperation.prototype.asCurl = function (args) {
2772   var results = [];
2773   var i;
2774
2775   var headers = SwaggerRequest.prototype.setHeaders(args, {}, this);    
2776   for(i = 0; i < this.parameters.length; i++) {
2777     var param = this.parameters[i];
2778     if(param.paramType && param.paramType === 'header' && args[param.name]) {
2779       headers[param.name] = args[param.name];
2780     }
2781   }
2782
2783   var key;
2784   for (key in headers) {
2785     results.push('--header "' + key + ': ' + headers[key] + '"');
2786   }
2787   return 'curl ' + (results.join(' ')) + ' ' + this.urlify(args);
2788 };
2789
2790 SwaggerOperation.prototype.formatXml = function (xml) {
2791   var contexp, formatted, indent, lastType, lines, ln, pad, reg, transitions, wsexp, _fn, _i, _len;
2792   reg = /(>)(<)(\/*)/g;
2793   wsexp = /[ ]*(.*)[ ]+\n/g;
2794   contexp = /(<.+>)(.+\n)/g;
2795   xml = xml.replace(reg, '$1\n$2$3').replace(wsexp, '$1\n').replace(contexp, '$1\n$2');
2796   pad = 0;
2797   formatted = '';
2798   lines = xml.split('\n');
2799   indent = 0;
2800   lastType = 'other';
2801   transitions = {
2802     'single->single': 0,
2803     'single->closing': -1,
2804     'single->opening': 0,
2805     'single->other': 0,
2806     'closing->single': 0,
2807     'closing->closing': -1,
2808     'closing->opening': 0,
2809     'closing->other': 0,
2810     'opening->single': 1,
2811     'opening->closing': 0,
2812     'opening->opening': 1,
2813     'opening->other': 1,
2814     'other->single': 0,
2815     'other->closing': -1,
2816     'other->opening': 0,
2817     'other->other': 0
2818   };
2819   _fn = function (ln) {
2820     var fromTo, j, key, padding, type, types, value;
2821     types = {
2822       single: Boolean(ln.match(/<.+\/>/)),
2823       closing: Boolean(ln.match(/<\/.+>/)),
2824       opening: Boolean(ln.match(/<[^!?].*>/))
2825     };
2826     type = ((function () {
2827       var _results;
2828       _results = [];
2829       for (key in types) {
2830         value = types[key];
2831         if (value) {
2832           _results.push(key);
2833         }
2834       }
2835       return _results;
2836     })())[0];
2837     type = type === void 0 ? 'other' : type;
2838     fromTo = lastType + '->' + type;
2839     lastType = type;
2840     padding = '';
2841     indent += transitions[fromTo];
2842     padding = ((function () {
2843       var _j, _ref5, _results;
2844       _results = [];
2845       for (j = _j = 0, _ref5 = indent; 0 <= _ref5 ? _j < _ref5 : _j > _ref5; j = 0 <= _ref5 ? ++_j : --_j) {
2846         _results.push('  ');
2847       }
2848       return _results;
2849     })()).join('');
2850     if (fromTo === 'opening->closing') {
2851       formatted = formatted.substr(0, formatted.length - 1) + ln + '\n';
2852     } else {
2853       formatted += padding + ln + '\n';
2854     }
2855   };
2856   for (_i = 0, _len = lines.length; _i < _len; _i++) {
2857     ln = lines[_i];
2858     _fn(ln);
2859   }
2860   return formatted;
2861 };
2862
2863 var SwaggerRequest = function (type, url, params, opts, successCallback, errorCallback, operation, execution) {
2864   var _this = this;
2865   var errors = [];
2866
2867   this.useJQuery = (typeof operation.resource.useJQuery !== 'undefined' ? operation.resource.useJQuery : null);
2868   this.type = (type || errors.push('SwaggerRequest type is required (get/post/put/delete/patch/options).'));
2869   this.url = (url || errors.push('SwaggerRequest url is required.'));
2870   this.params = params;
2871   this.opts = opts;
2872   this.successCallback = (successCallback || errors.push('SwaggerRequest successCallback is required.'));
2873   this.errorCallback = (errorCallback || errors.push('SwaggerRequest error callback is required.'));
2874   this.operation = (operation || errors.push('SwaggerRequest operation is required.'));
2875   this.execution = execution;
2876   this.headers = (params.headers || {});
2877
2878   if (errors.length > 0) {
2879     throw errors;
2880   }
2881
2882   this.type = this.type.toUpperCase();
2883
2884   // set request, response content type headers
2885   var headers = this.setHeaders(params, opts, this.operation);
2886   var body = params.body;
2887
2888   // encode the body for form submits
2889   if (headers['Content-Type']) {
2890     var key, value, values = {}, i;
2891     var operationParams = this.operation.parameters;
2892     for (i = 0; i < operationParams.length; i++) {
2893       var param = operationParams[i];
2894       if (param.paramType === 'form')
2895         values[param.name] = param;
2896     }
2897
2898     if (headers['Content-Type'].indexOf('application/x-www-form-urlencoded') === 0) {
2899       var encoded = '';
2900       for (key in values) {
2901         value = this.params[key];
2902         if (typeof value !== 'undefined') {
2903           if (encoded !== '')
2904             encoded += '&';
2905           encoded += encodeURIComponent(key) + '=' + encodeURIComponent(value);
2906         }
2907       }
2908       body = encoded;
2909     }
2910     else if (headers['Content-Type'].indexOf('multipart/form-data') === 0) {
2911       // encode the body for form submits
2912       var data = '';
2913       var boundary = '----SwaggerFormBoundary' + Date.now();
2914       for (key in values) {
2915         value = this.params[key];
2916         if (typeof value !== 'undefined') {
2917           data += '--' + boundary + '\n';
2918           data += 'Content-Disposition: form-data; name="' + key + '"';
2919           data += '\n\n';
2920           data += value + '\n';
2921         }
2922       }
2923       data += '--' + boundary + '--\n';
2924       headers['Content-Type'] = 'multipart/form-data; boundary=' + boundary;
2925       body = data;
2926     }
2927   }
2928
2929   var obj;
2930   if (!((this.headers) && (this.headers.mock))) {
2931     obj = {
2932       url: this.url,
2933       method: this.type,
2934       headers: headers,
2935       body: body,
2936       useJQuery: this.useJQuery,
2937       on: {
2938         error: function (response) {
2939           return _this.errorCallback(response, _this.opts.parent);
2940         },
2941         redirect: function (response) {
2942           return _this.successCallback(response, _this.opts.parent);
2943         },
2944         307: function (response) {
2945           return _this.successCallback(response, _this.opts.parent);
2946         },
2947         response: function (response) {
2948           return _this.successCallback(response, _this.opts.parent);
2949         }
2950       }
2951     };
2952
2953     var status = false;
2954     if (this.operation.resource && this.operation.resource.api && this.operation.resource.api.clientAuthorizations) {
2955       // Get the client authorizations from the resource declaration
2956       status = this.operation.resource.api.clientAuthorizations.apply(obj, this.operation.authorizations);
2957     } else {
2958       // Get the client authorization from the default authorization declaration
2959       var e;
2960       if (typeof window !== 'undefined') {
2961         e = window;
2962       } else {
2963         e = exports;
2964       }
2965       status = e.authorizations.apply(obj, this.operation.authorizations);
2966     }
2967
2968     if (!opts.mock) {
2969       if (status !== false) {
2970         new SwaggerHttp().execute(obj);
2971       } else {
2972         obj.canceled = true;
2973       }
2974     } else {
2975       return obj;
2976     }
2977   }
2978   return obj;
2979 };
2980
2981 SwaggerRequest.prototype.setHeaders = function (params, opts, operation) {
2982   // default type
2983   var accepts = opts.responseContentType || 'application/json';
2984   var consumes = opts.requestContentType || 'application/json';
2985
2986   var allDefinedParams = operation.parameters;
2987   var definedFormParams = [];
2988   var definedFileParams = [];
2989   var body = params.body;
2990   var headers = {};
2991
2992   // get params from the operation and set them in definedFileParams, definedFormParams, headers
2993   var i;
2994   for (i = 0; i < allDefinedParams.length; i++) {
2995     var param = allDefinedParams[i];
2996     if (param.paramType === 'form')
2997       definedFormParams.push(param);
2998     else if (param.paramType === 'file')
2999       definedFileParams.push(param);
3000     else if (param.paramType === 'header' && this.params.headers) {
3001       var key = param.name;
3002       var headerValue = this.params.headers[param.name];
3003       if (typeof this.params.headers[param.name] !== 'undefined')
3004         headers[key] = headerValue;
3005     }
3006   }
3007
3008   // if there's a body, need to set the accepts header via requestContentType
3009   if (body && (this.type === 'POST' || this.type === 'PUT' || this.type === 'PATCH' || this.type === 'DELETE')) {
3010     if (this.opts.requestContentType)
3011       consumes = this.opts.requestContentType;
3012   } else {
3013     // if any form params, content type must be set
3014     if (definedFormParams.length > 0) {
3015       if (definedFileParams.length > 0)
3016         consumes = 'multipart/form-data';
3017       else
3018         consumes = 'application/x-www-form-urlencoded';
3019     }
3020     else if (this.type === 'DELETE')
3021       body = '{}';
3022     else if (this.type != 'DELETE')
3023       consumes = null;
3024   }
3025
3026   if (consumes && this.operation.consumes) {
3027     if (this.operation.consumes.indexOf(consumes) === -1) {
3028       log('server doesn\'t consume ' + consumes + ', try ' + JSON.stringify(this.operation.consumes));
3029     }
3030   }
3031
3032   if (this.opts && this.opts.responseContentType) {
3033     accepts = this.opts.responseContentType;
3034   } else {
3035     accepts = 'application/json';
3036   }
3037   if (accepts && operation.produces) {
3038     if (operation.produces.indexOf(accepts) === -1) {
3039       log('server can\'t produce ' + accepts);
3040     }
3041   }
3042
3043   if ((consumes && body !== '') || (consumes === 'application/x-www-form-urlencoded'))
3044     headers['Content-Type'] = consumes;
3045   if (accepts)
3046     headers.Accept = accepts;
3047   return headers;
3048 };
3049
3050 /**
3051  * SwaggerHttp is a wrapper for executing requests
3052  */
3053 var SwaggerHttp = function() {};
3054
3055 SwaggerHttp.prototype.execute = function(obj, opts) {
3056   if(obj && (typeof obj.useJQuery === 'boolean'))
3057     this.useJQuery = obj.useJQuery;
3058   else
3059     this.useJQuery = this.isIE8();
3060
3061   if(obj && typeof obj.body === 'object') {
3062     if(obj.body.type && obj.body.type !== 'formData')
3063       obj.body = JSON.stringify(obj.body);
3064     else {
3065       obj.contentType = false;
3066       obj.processData = false;
3067       // delete obj.cache;
3068       delete obj.headers['Content-Type'];
3069     }
3070   }
3071
3072   if(this.useJQuery)
3073     return new JQueryHttpClient(opts).execute(obj);
3074   else
3075     return new ShredHttpClient(opts).execute(obj);
3076 };
3077
3078 SwaggerHttp.prototype.isIE8 = function() {
3079   var detectedIE = false;
3080   if (typeof navigator !== 'undefined' && navigator.userAgent) {
3081     nav = navigator.userAgent.toLowerCase();
3082     if (nav.indexOf('msie') !== -1) {
3083       var version = parseInt(nav.split('msie')[1]);
3084       if (version <= 8) {
3085         detectedIE = true;
3086       }
3087     }
3088   }
3089   return detectedIE;
3090 };
3091
3092 /*
3093  * JQueryHttpClient lets a browser take advantage of JQuery's cross-browser magic.
3094  * NOTE: when jQuery is available it will export both '$' and 'jQuery' to the global space.
3095  *       Since we are using closures here we need to alias it for internal use.
3096  */
3097 var JQueryHttpClient = function(options) {
3098   "use strict";
3099   if(!jQuery){
3100     var jQuery = window.jQuery;
3101   }
3102 };
3103
3104 JQueryHttpClient.prototype.execute = function(obj) {
3105   var cb = obj.on;
3106   var request = obj;
3107
3108   obj.type = obj.method;
3109   obj.cache = false;
3110   delete obj.useJQuery;
3111
3112   /*
3113   obj.beforeSend = function(xhr) {
3114     var key, results;
3115     if (obj.headers) {
3116       results = [];
3117       for (key in obj.headers) {
3118         if (key.toLowerCase() === "content-type") {
3119           results.push(obj.contentType = obj.headers[key]);
3120         } else if (key.toLowerCase() === "accept") {
3121           results.push(obj.accepts = obj.headers[key]);
3122         } else {
3123           results.push(xhr.setRequestHeader(key, obj.headers[key]));
3124         }
3125       }
3126       return results;
3127     }
3128   };*/
3129
3130   obj.data = obj.body;
3131   delete obj.body;
3132   obj.complete = function(response, textStatus, opts) {
3133     var headers = {},
3134       headerArray = response.getAllResponseHeaders().split("\n");
3135
3136     for(var i = 0; i < headerArray.length; i++) {
3137       var toSplit = headerArray[i].trim();
3138       if(toSplit.length === 0)
3139         continue;
3140       var separator = toSplit.indexOf(":");
3141       if(separator === -1) {
3142         // Name but no value in the header
3143         headers[toSplit] = null;
3144         continue;
3145       }
3146       var name = toSplit.substring(0, separator).trim(),
3147         value = toSplit.substring(separator + 1).trim();
3148       headers[name] = value;
3149     }
3150
3151     var out = {
3152       url: request.url,
3153       method: request.method,
3154       status: response.status,
3155       statusText: response.statusText,
3156       data: response.responseText,
3157       headers: headers
3158     };
3159
3160     var contentType = (headers["content-type"]||headers["Content-Type"]||null);
3161     if(contentType) {
3162       if(contentType.indexOf("application/json") === 0 || contentType.indexOf("+json") > 0) {
3163         try {
3164           out.obj = response.responseJSON || JSON.parse(out.data) || {};
3165         } catch (ex) {
3166           // do not set out.obj
3167           log("unable to parse JSON content");
3168         }
3169       }
3170     }
3171
3172     if(response.status >= 200 && response.status < 300)
3173       cb.response(out);
3174     else if(response.status === 0 || (response.status >= 400 && response.status < 599))
3175       cb.error(out);
3176     else
3177       return cb.response(out);
3178   };
3179
3180   jQuery.support.cors = true;
3181   return jQuery.ajax(obj);
3182 };
3183
3184 /*
3185  * ShredHttpClient is a light-weight, node or browser HTTP client
3186  */
3187 var ShredHttpClient = function(opts) {
3188   this.opts = (opts||{});
3189   this.isInitialized = false;
3190
3191   var identity, toString;
3192
3193   if (typeof window !== 'undefined') {
3194     this.Shred = require("./shred");
3195     this.content = require("./shred/content");
3196   }
3197   else
3198     this.Shred = require("shred");
3199   this.shred = new this.Shred(opts);
3200 };
3201
3202 ShredHttpClient.prototype.initShred = function () {
3203   this.isInitialized = true;
3204   this.registerProcessors(this.shred);
3205 };
3206
3207 ShredHttpClient.prototype.registerProcessors = function(shred) {
3208   var identity = function(x) {
3209     return x;
3210   };
3211   var toString = function(x) {
3212     return x.toString();
3213   };
3214
3215   if (typeof window !== 'undefined') {
3216     this.content.registerProcessor(["application/json; charset=utf-8", "application/json", "json"], {
3217       parser: identity,
3218       stringify: toString
3219     });
3220   } else {
3221     this.Shred.registerProcessor(["application/json; charset=utf-8", "application/json", "json"], {
3222       parser: identity,
3223       stringify: toString
3224     });
3225   }
3226 };
3227
3228 ShredHttpClient.prototype.execute = function(obj) {
3229   if(!this.isInitialized)
3230     this.initShred();
3231
3232   var cb = obj.on, res;
3233   var transform = function(response) {
3234     var out = {
3235       headers: response._headers,
3236       url: response.request.url,
3237       method: response.request.method,
3238       status: response.status,
3239       data: response.content.data
3240     };
3241
3242     var headers = response._headers.normalized || response._headers;
3243     var contentType = (headers["content-type"]||headers["Content-Type"]||null);
3244
3245     if(contentType) {
3246       if(contentType.indexOf("application/json") === 0 || contentType.indexOf("+json") > 0) {
3247         if(response.content.data && response.content.data !== "")
3248           try{
3249             out.obj = JSON.parse(response.content.data);
3250           }
3251           catch (e) {
3252             // unable to parse
3253           }
3254         else
3255           out.obj = {};
3256       }
3257     }
3258     return out;
3259   };
3260
3261   // Transform an error into a usable response-like object
3262   var transformError = function (error) {
3263     var out = {
3264       // Default to a status of 0 - The client will treat this as a generic permissions sort of error
3265       status: 0,
3266       data: error.message || error
3267     };
3268
3269     if (error.code) {
3270       out.obj = error;
3271
3272       if (error.code === 'ENOTFOUND' || error.code === 'ECONNREFUSED') {
3273         // We can tell the client that this should be treated as a missing resource and not as a permissions thing
3274         out.status = 404;
3275       }
3276     }
3277     return out;
3278   };
3279
3280   res = {
3281     error: function (response) {
3282       if (obj)
3283         return cb.error(transform(response));
3284     },
3285     // Catch the Shred error raised when the request errors as it is made (i.e. No Response is coming)
3286     request_error: function (err) {
3287       if (obj)
3288         return cb.error(transformError(err));
3289     },
3290     response: function (response) {
3291       if (obj) {
3292         return cb.response(transform(response));
3293       }
3294     }
3295   };
3296   if (obj) {
3297     obj.on = res;
3298   }
3299   return this.shred.request(obj);
3300 };
3301
3302
3303 var e = (typeof window !== 'undefined' ? window : exports);
3304
3305 e.authorizations = authorizations = new SwaggerAuthorizations();
3306 e.ApiKeyAuthorization = ApiKeyAuthorization;
3307 e.PasswordAuthorization = PasswordAuthorization;
3308 e.CookieAuthorization = CookieAuthorization;
3309 e.SwaggerClient = SwaggerClient;
3310 e.SwaggerApi = SwaggerClient;
3311 e.Operation = Operation;
3312 e.Model = Model;
3313 e.addModel = addModel;
3314 e.Resolver = Resolver;
3315 })();