├── config ├── .gitkeep ├── local │ └── swaggervel.php └── swagger.php ├── tests └── .gitkeep ├── resources └── views │ ├── .gitkeep │ └── index.blade.php ├── public ├── images │ ├── favicon.ico │ ├── throbber.gif │ ├── logo_small.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── pet_store_api.png │ ├── wordnik_api.png │ └── explorer_icons.png ├── fonts │ ├── droid-sans-v6-latin-700.eot │ ├── droid-sans-v6-latin-700.ttf │ ├── droid-sans-v6-latin-700.woff │ ├── droid-sans-v6-latin-700.woff2 │ ├── droid-sans-v6-latin-regular.eot │ ├── droid-sans-v6-latin-regular.ttf │ ├── droid-sans-v6-latin-regular.woff │ └── droid-sans-v6-latin-regular.woff2 ├── lib │ ├── jquery.slideto.min.js │ ├── jquery.wiggle.min.js │ ├── jquery.ba-bbq.min.js │ ├── highlight.7.3.pack.js │ ├── swagger-oauth.js │ ├── underscore-min.js │ ├── backbone-min.js │ ├── underscore-min.map │ ├── marked.js │ └── handlebars-2.0.0.js ├── o2c.html ├── lang │ ├── translator.js │ ├── zh-CN.js │ └── en.js └── css │ ├── typography.css │ ├── reset.css │ └── style.css ├── .travis.yml ├── .gitattributes ├── phpunit.xml ├── composer.json ├── .gitignore ├── README.md └── src ├── SwaggervelServiceProvider.php └── routes.php /config/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/views/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/helei112g/laravel-swagger/HEAD/public/images/favicon.ico -------------------------------------------------------------------------------- /public/images/throbber.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/helei112g/laravel-swagger/HEAD/public/images/throbber.gif -------------------------------------------------------------------------------- /public/images/logo_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/helei112g/laravel-swagger/HEAD/public/images/logo_small.png -------------------------------------------------------------------------------- /public/images/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/helei112g/laravel-swagger/HEAD/public/images/favicon-16x16.png -------------------------------------------------------------------------------- /public/images/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/helei112g/laravel-swagger/HEAD/public/images/favicon-32x32.png -------------------------------------------------------------------------------- /public/images/pet_store_api.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/helei112g/laravel-swagger/HEAD/public/images/pet_store_api.png -------------------------------------------------------------------------------- /public/images/wordnik_api.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/helei112g/laravel-swagger/HEAD/public/images/wordnik_api.png -------------------------------------------------------------------------------- /config/local/swaggervel.php: -------------------------------------------------------------------------------- 1 | 2 | var qp = null; 3 | if(window.location.hash) { 4 | qp = location.hash.substring(1); 5 | } 6 | else { 7 | qp = location.search.substring(1); 8 | } 9 | qp = qp ? JSON.parse('{"' + qp.replace(/&/g, '","').replace(/=/g,'":"') + '"}', 10 | function(key, value) { 11 | return key===""?value:decodeURIComponent(value) } 12 | ):{} 13 | 14 | if (window.opener.swaggerUi.tokenUrl) 15 | window.opener.processOAuthCode(qp); 16 | else 17 | window.opener.onOAuthComplete(qp); 18 | 19 | window.close(); 20 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 15 | ./tests/ 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "riverslei/laravel-swagger", 3 | "description": "在laravel5中使用swagger自动生成api接口文档", 4 | "keywords": ["laravel", "swagger", "laravel swagger", "laravel5", "swagger-php", "documentation", "api"], 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "helei112g", 9 | "email": "helei5200@126.com" 10 | } 11 | ], 12 | "require": { 13 | "php": ">=5.5.9", 14 | "zircote/swagger-php": "~1.0" 15 | }, 16 | "autoload": { 17 | "psr-4": { 18 | "Riverslei\\Swaggervel\\": "src/" 19 | } 20 | }, 21 | "minimum-stability": "stable" 22 | } 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear on external disk 35 | .Spotlight-V100 36 | .Trashes 37 | 38 | # Directories potentially created on remote AFP share 39 | .AppleDB 40 | .AppleDesktop 41 | Network Trash Folder 42 | Temporary Items 43 | .apdisk 44 | -------------------------------------------------------------------------------- /public/lib/jquery.wiggle.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | jQuery Wiggle 3 | Author: WonderGroup, Jordan Thomas 4 | URL: http://labs.wondergroup.com/demos/mini-ui/index.html 5 | License: MIT (http://en.wikipedia.org/wiki/MIT_License) 6 | */ 7 | jQuery.fn.wiggle=function(o){var d={speed:50,wiggles:3,travel:5,callback:null};var o=jQuery.extend(d,o);return this.each(function(){var cache=this;var wrap=jQuery(this).wrap('
').css("position","relative");var calls=0;for(i=1;i<=o.wiggles;i++){jQuery(this).animate({left:"-="+o.travel},o.speed).animate({left:"+="+o.travel*2},o.speed*2).animate({left:"-="+o.travel},o.speed,function(){calls++;if(jQuery(cache).parent().hasClass('wiggle-wrap')){jQuery(cache).parent().replaceWith(cache);} 8 | if(calls==o.wiggles&&jQuery.isFunction(o.callback)){o.callback();}});}});}; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 说明 2 | 该项目,主要用于解决API文档生成的问题。 3 | 项目基于laravel5+swagger-php构成。[项目源地址](https://github.com/slampenny/Swaggervel) 4 | 5 | # 改进日志 6 | * V1.1.1 修改了依赖swagger-php包版本问题(swagger-php v2上的版本使用了PSR-4标准) 7 | * 2015年7月1日 [v1.1.0] 修改路由 8 | * 修改了项目文件结构 9 | * 将swagger前端部分版本提升到V2.1版本,使用swagger前端[项目地址](https://github.com/helei112g/swagger-ui) 10 | * 将项目改进为PSR-4自动加载,抛弃之前的PSR-0 11 | 12 | # 安装 13 | 建议采用 `composer` 进行安装, 14 | 1. 在项目的composer.json中配置 `"riverslei/laravel-swagger": "~1.0"` 15 | 2. 运行 `composer update` 16 | 3. 安装完成后,配置 `config/app.php` 中的服务提供者 `Riverslei\Swaggervel\SwaggervelServiceProvider::class` 17 | 4. 以上配置完成后,运行 `php artisan vendor:publish` ,生成相关的配置文件以及资源文件。 18 | 19 | *通过以上配置,已经完成了所有的安装工作,现在开始运行* 20 | 21 | # 运行 22 | 查看api-doc的路由,使用一下命令 23 | ```artisan 24 | php artisan route:list 25 | ``` 26 | 根据路由信息,访问:baseUrl+api-docs,如果看到swagger的首页,说明已经成功 27 | 28 | # 补充 29 | 安装该lib后,不需要再运行命令生成相关的json文件,一切在你运行url访问你项目swagger文档首页时,它会自动扫描相关的Model及Controller 30 | ,一切就是这么美妙,以后再也不需要劳心费神的写api接口文档了。 31 | 32 | 这里给出swagger-php注解的书写规则文档:[官方文档](http://zircote.com/swagger-php/annotations.html) 33 | -------------------------------------------------------------------------------- /public/lang/translator.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Translator for documentation pages. 5 | * 6 | * To enable translation you should include one of language-files in your index.html 7 | * after . 8 | * For example - 9 | * 10 | * If you wish to translate some new texsts you should do two things: 11 | * 1. Add a new phrase pair ("New Phrase": "New Translation") into your language file (for example lang/ru.js). It will be great if you add it in other language files too. 12 | * 2. Mark that text it templates this way New Phrase or . 13 | * The main thing here is attribute data-sw-translate. Only inner html, title-attribute and value-attribute are going to translate. 14 | * 15 | */ 16 | window.SwaggerTranslator = { 17 | _words:[], 18 | 19 | translate: function() { 20 | var $this = this; 21 | $('[data-sw-translate]').each(function(){ 22 | $(this).html($this._tryTranslate($(this).html())); 23 | $(this).val($this._tryTranslate($(this).val())); 24 | $(this).attr('title', $this._tryTranslate($(this).attr('title'))); 25 | }); 26 | }, 27 | 28 | _tryTranslate: function(word){ 29 | return this._words[$.trim(word)] !== undefined ? this._words[$.trim(word)] : word; 30 | }, 31 | 32 | learn: function(wordsMap){ 33 | this._words = wordsMap; 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /src/SwaggervelServiceProvider.php: -------------------------------------------------------------------------------- 1 | publishes([ 25 | __DIR__.'/../config/swagger.php' => config_path('swagger.php'), 26 | ]); 27 | 28 | $this->publishes([ 29 | __DIR__.'/../public' => public_path('vendor/swagger'), 30 | ], 'public'); 31 | 32 | 33 | $this->loadViewsFrom(__DIR__.'/../resources/views', 'swagger'); 34 | 35 | $this->publishes([ 36 | __DIR__.'/../resources/views' => base_path('resources/views/vendor/swagger'), 37 | ]); 38 | 39 | require_once __DIR__ .'/routes.php'; 40 | } 41 | /** 42 | * Register the service provider. 43 | * 44 | * @return void 45 | */ 46 | public function register() 47 | { 48 | $this->mergeConfigFrom( 49 | __DIR__.'/../config/swagger.php', 'swagger' 50 | ); 51 | } 52 | 53 | /** 54 | * Get the services provided by the provider. 55 | * 56 | * @return array 57 | */ 58 | public function provides() 59 | { 60 | 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /public/css/typography.css: -------------------------------------------------------------------------------- 1 | /* droid-sans-regular - latin */ 2 | @font-face { 3 | font-family: 'Droid Sans'; 4 | font-style: normal; 5 | font-weight: 400; 6 | src: url('../fonts/droid-sans-v6-latin-regular.eot'); /* IE9 Compat Modes */ 7 | src: local('Droid Sans'), local('DroidSans'), 8 | url('../fonts/droid-sans-v6-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ 9 | url('../fonts/droid-sans-v6-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */ 10 | url('../fonts/droid-sans-v6-latin-regular.woff') format('woff'), /* Modern Browsers */ 11 | url('../fonts/droid-sans-v6-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */ 12 | url('../fonts/droid-sans-v6-latin-regular.svg#DroidSans') format('svg'); /* Legacy iOS */ 13 | } 14 | /* droid-sans-700 - latin */ 15 | @font-face { 16 | font-family: 'Droid Sans'; 17 | font-style: normal; 18 | font-weight: 700; 19 | src: url('../fonts/droid-sans-v6-latin-700.eot'); /* IE9 Compat Modes */ 20 | src: local('Droid Sans Bold'), local('DroidSans-Bold'), 21 | url('../fonts/droid-sans-v6-latin-700.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ 22 | url('../fonts/droid-sans-v6-latin-700.woff2') format('woff2'), /* Super Modern Browsers */ 23 | url('../fonts/droid-sans-v6-latin-700.woff') format('woff'), /* Modern Browsers */ 24 | url('../fonts/droid-sans-v6-latin-700.ttf') format('truetype'), /* Safari, Android, iOS */ 25 | url('../fonts/droid-sans-v6-latin-700.svg#DroidSans') format('svg'); /* Legacy iOS */ 26 | } 27 | -------------------------------------------------------------------------------- /public/css/reset.css: -------------------------------------------------------------------------------- 1 | /* http://meyerweb.com/eric/tools/css/reset/ v2.0 | 20110126 */ 2 | html, 3 | body, 4 | div, 5 | span, 6 | applet, 7 | object, 8 | iframe, 9 | h1, 10 | h2, 11 | h3, 12 | h4, 13 | h5, 14 | h6, 15 | p, 16 | blockquote, 17 | pre, 18 | a, 19 | abbr, 20 | acronym, 21 | address, 22 | big, 23 | cite, 24 | code, 25 | del, 26 | dfn, 27 | em, 28 | img, 29 | ins, 30 | kbd, 31 | q, 32 | s, 33 | samp, 34 | small, 35 | strike, 36 | strong, 37 | sub, 38 | sup, 39 | tt, 40 | var, 41 | b, 42 | u, 43 | i, 44 | center, 45 | dl, 46 | dt, 47 | dd, 48 | ol, 49 | ul, 50 | li, 51 | fieldset, 52 | form, 53 | label, 54 | legend, 55 | table, 56 | caption, 57 | tbody, 58 | tfoot, 59 | thead, 60 | tr, 61 | th, 62 | td, 63 | article, 64 | aside, 65 | canvas, 66 | details, 67 | embed, 68 | figure, 69 | figcaption, 70 | footer, 71 | header, 72 | hgroup, 73 | menu, 74 | nav, 75 | output, 76 | ruby, 77 | section, 78 | summary, 79 | time, 80 | mark, 81 | audio, 82 | video { 83 | margin: 0; 84 | padding: 0; 85 | border: 0; 86 | font-size: 100%; 87 | font: inherit; 88 | vertical-align: baseline; 89 | } 90 | /* HTML5 display-role reset for older browsers */ 91 | article, 92 | aside, 93 | details, 94 | figcaption, 95 | figure, 96 | footer, 97 | header, 98 | hgroup, 99 | menu, 100 | nav, 101 | section { 102 | display: block; 103 | } 104 | body { 105 | line-height: 1; 106 | } 107 | ol, 108 | ul { 109 | list-style: none; 110 | } 111 | blockquote, 112 | q { 113 | quotes: none; 114 | } 115 | blockquote:before, 116 | blockquote:after, 117 | q:before, 118 | q:after { 119 | content: ''; 120 | content: none; 121 | } 122 | table { 123 | border-collapse: collapse; 124 | border-spacing: 0; 125 | } 126 | -------------------------------------------------------------------------------- /public/lang/zh-CN.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* 中文版本。 */ 4 | window.SwaggerTranslator.learn({ 5 | "Warning: Deprecated":"Warning: Deprecated", 6 | "Implementation Notes":"注意事项", 7 | "Response Class":"Response Class", 8 | "Status":"Status1", 9 | "Parameters":"请求参数", 10 | "Parameter":"参数", 11 | "Value":"值", 12 | "Description":"说明信息", 13 | "Parameter Type":"参数类型", 14 | "Data Type":"数据类型", 15 | "Response Messages":"响应信息", 16 | "HTTP Status Code":"返回码", 17 | "Reason":"原因", 18 | "Response Model":"响应 Model", 19 | "Request URL":"Request URL", 20 | "Response Body":"Response Body", 21 | "Response Code":"Response Code", 22 | "Response Headers":"Response Headers", 23 | "Headers":"头", 24 | "Hide Response":"隐藏响应", 25 | "Try it out!":"测试", 26 | "Show/Hide":"展开/收起", 27 | "List Operations":"查看列表", 28 | "Expand Operations":"展开所有", 29 | "Raw":"Raw", 30 | "can't parse JSON. Raw result":"can't parse JSON. Raw result", 31 | "Model Schema":"Model Schema", 32 | "Model":"Model", 33 | "apply":"apply", 34 | "Username":"Username", 35 | "Password":"Password", 36 | "Terms of service":"Terms of service", 37 | "Created by":"Created by", 38 | "See more at":"See more at", 39 | "Contact the developer":"联系开发者", 40 | "api version":"api version", 41 | "Response Content Type":"Response Content Type", 42 | "fetching resource":"fetching resource", 43 | "fetching resource list":"fetching resource list", 44 | "Explore":"Explore", 45 | "Show Swagger Petstore Example Apis":"Show Swagger Petstore Example Apis", 46 | "Can't read from server. It may not have the appropriate access-control-origin settings.":"Can't read from server. It may not have the appropriate access-control-origin settings.", 47 | "Please specify the protocol for":"Please specify the protocol for", 48 | "Can't read swagger JSON from":"Can't read swagger JSON from", 49 | "Finished Loading Resource Information. Rendering Swagger UI":"Finished Loading Resource Information. Rendering Swagger UI", 50 | "Unable to read api":"Unable to read api", 51 | "from path":"from path", 52 | "server returned":"server returned", 53 | "Parameter content type:":"参数类型:" 54 | }); 55 | -------------------------------------------------------------------------------- /public/lang/en.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* jshint quotmark: double */ 4 | window.SwaggerTranslator.learn({ 5 | "Warning: Deprecated":"Warning: Deprecated", 6 | "Implementation Notes":"Implementation Notes", 7 | "Response Class":"Response Class", 8 | "Status":"Status", 9 | "Parameters":"Parameters", 10 | "Parameter":"Parameter", 11 | "Value":"Value", 12 | "Description":"Description", 13 | "Parameter Type":"Parameter Type", 14 | "Data Type":"Data Type", 15 | "Response Messages":"Response Messages", 16 | "HTTP Status Code":"HTTP Status Code", 17 | "Reason":"Reason", 18 | "Response Model":"Response Model", 19 | "Request URL":"Request URL", 20 | "Response Body":"Response Body", 21 | "Response Code":"Response Code", 22 | "Response Headers":"Response Headers", 23 | "Hide Response":"Hide Response", 24 | "Try it out!":"Try it out!", 25 | "Show/Hide":"Show/Hide", 26 | "List Operations":"List Operations", 27 | "Expand Operations":"Expand Operations", 28 | "Raw":"Raw", 29 | "can't parse JSON. Raw result":"can't parse JSON. Raw result", 30 | "Model Schema":"Model Schema", 31 | "Model":"Model", 32 | "apply":"apply", 33 | "Username":"Username", 34 | "Password":"Password", 35 | "Terms of service":"Terms of service", 36 | "Created by":"Created by", 37 | "See more at":"See more at", 38 | "Contact the developer":"Contact the developer", 39 | "api version":"api version", 40 | "Response Content Type":"Response Content Type", 41 | "fetching resource":"fetching resource", 42 | "fetching resource list":"fetching resource list", 43 | "Explore":"Explore", 44 | "Show Swagger Petstore Example Apis":"Show Swagger Petstore Example Apis", 45 | "Can't read from server. It may not have the appropriate access-control-origin settings.":"Can't read from server. It may not have the appropriate access-control-origin settings.", 46 | "Please specify the protocol for":"Please specify the protocol for", 47 | "Can't read swagger JSON from":"Can't read swagger JSON from", 48 | "Finished Loading Resource Information. Rendering Swagger UI":"Finished Loading Resource Information. Rendering Swagger UI", 49 | "Unable to read api":"Unable to read api", 50 | "from path":"from path", 51 | "server returned":"server returned" 52 | }); 53 | -------------------------------------------------------------------------------- /config/swagger.php: -------------------------------------------------------------------------------- 1 | storage_path() . '/docs', 16 | 17 | /* 18 | |-------------------------------------------------------------------------- 19 | | Relative path to access parsed swagger annotations. 20 | |-------------------------------------------------------------------------- 21 | */ 22 | 'doc-route' => 'docs', 23 | 24 | /* 25 | |-------------------------------------------------------------------------- 26 | | Absolute path to directory containing the swagger annotations are stored. 27 | |-------------------------------------------------------------------------- 28 | */ 29 | "app-dir" => "app", 30 | 31 | /* 32 | |-------------------------------------------------------------------------- 33 | | Absolute path to directories that you would like to exclude from swagger generation 34 | |-------------------------------------------------------------------------- 35 | */ 36 | "excludes" => array( 37 | storage_path(), 38 | base_path()."/tests", 39 | base_path()."/resources/views", 40 | base_path()."/config" 41 | ), 42 | 43 | /* 44 | |-------------------------------------------------------------------------- 45 | | Turn this off to remove swagger generation on production 46 | |-------------------------------------------------------------------------- 47 | */ 48 | "generateAlways" => true, 49 | 50 | "api-key" => "auth_token", 51 | 52 | /* 53 | |-------------------------------------------------------------------------- 54 | | Edit to set the api's version number 55 | |-------------------------------------------------------------------------- 56 | */ 57 | "default-api-version" => "", 58 | 59 | /* 60 | |-------------------------------------------------------------------------- 61 | | Edit to set the swagger version number 62 | |-------------------------------------------------------------------------- 63 | */ 64 | "default-swagger-version" => "1.2", 65 | 66 | /* 67 | |-------------------------------------------------------------------------- 68 | | Edit to set the api's base path 69 | |-------------------------------------------------------------------------- 70 | */ 71 | "default-base-path" => "", 72 | 73 | /* 74 | |-------------------------------------------------------------------------- 75 | | Edit to trust the proxy's ip address - needed for AWS Load Balancer 76 | |-------------------------------------------------------------------------- 77 | */ 78 | "behind-reverse-proxy" => false, 79 | /* 80 | |-------------------------------------------------------------------------- 81 | | Uncomment to add response headers when swagger is generated 82 | |-------------------------------------------------------------------------- 83 | */ 84 | /*"viewHeaders" => array( 85 | 'Content-Type' => 'text/plain' 86 | ),*/ 87 | 88 | /* 89 | |-------------------------------------------------------------------------- 90 | | Uncomment to add request headers when swagger performs requests 91 | |-------------------------------------------------------------------------- 92 | */ 93 | /*"requestHeaders" => array( 94 | 'TestMe' => 'testValue' 95 | ),*/ 96 | ); 97 | -------------------------------------------------------------------------------- /public/lib/jquery.ba-bbq.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery BBQ: Back Button & Query Library - v1.2.1 - 2/17/2010 3 | * http://benalman.com/projects/jquery-bbq-plugin/ 4 | * 5 | * Copyright (c) 2010 "Cowboy" Ben Alman 6 | * Dual licensed under the MIT and GPL licenses. 7 | * http://benalman.com/about/license/ 8 | */ 9 | (function($,p){var i,m=Array.prototype.slice,r=decodeURIComponent,a=$.param,c,l,v,b=$.bbq=$.bbq||{},q,u,j,e=$.event.special,d="hashchange",A="querystring",D="fragment",y="elemUrlAttr",g="location",k="href",t="src",x=/^.*\?|#.*$/g,w=/^.*\#/,h,C={};function E(F){return typeof F==="string"}function B(G){var F=m.call(arguments,1);return function(){return G.apply(this,F.concat(m.call(arguments)))}}function n(F){return F.replace(/^[^#]*#?(.*)$/,"$1")}function o(F){return F.replace(/(?:^[^?#]*\?([^#]*).*$)?.*/,"$1")}function f(H,M,F,I,G){var O,L,K,N,J;if(I!==i){K=F.match(H?/^([^#]*)\#?(.*)$/:/^([^#?]*)\??([^#]*)(#?.*)/);J=K[3]||"";if(G===2&&E(I)){L=I.replace(H?w:x,"")}else{N=l(K[2]);I=E(I)?l[H?D:A](I):I;L=G===2?I:G===1?$.extend({},I,N):$.extend({},N,I);L=a(L);if(H){L=L.replace(h,r)}}O=K[1]+(H?"#":L||!K[1]?"?":"")+L+J}else{O=M(F!==i?F:p[g][k])}return O}a[A]=B(f,0,o);a[D]=c=B(f,1,n);c.noEscape=function(G){G=G||"";var F=$.map(G.split(""),encodeURIComponent);h=new RegExp(F.join("|"),"g")};c.noEscape(",/");$.deparam=l=function(I,F){var H={},G={"true":!0,"false":!1,"null":null};$.each(I.replace(/\+/g," ").split("&"),function(L,Q){var K=Q.split("="),P=r(K[0]),J,O=H,M=0,R=P.split("]["),N=R.length-1;if(/\[/.test(R[0])&&/\]$/.test(R[N])){R[N]=R[N].replace(/\]$/,"");R=R.shift().split("[").concat(R);N=R.length-1}else{N=0}if(K.length===2){J=r(K[1]);if(F){J=J&&!isNaN(J)?+J:J==="undefined"?i:G[J]!==i?G[J]:J}if(N){for(;M<=N;M++){P=R[M]===""?O.length:R[M];O=O[P]=M').hide().insertAfter("body")[0].contentWindow;q=function(){return a(n.document[c][l])};o=function(u,s){if(u!==s){var t=n.document;t.open().close();t[c].hash="#"+u}};o(a())}}m.start=function(){if(r){return}var t=a();o||p();(function s(){var v=a(),u=q(t);if(v!==t){o(t=v,u);$(i).trigger(d)}else{if(u!==t){i[c][l]=i[c][l].replace(/#.*/,"")+"#"+u}}r=setTimeout(s,$[d+"Delay"])})()};m.stop=function(){if(!n){r&&clearTimeout(r);r=0}};return m})()})(jQuery,this); -------------------------------------------------------------------------------- /src/routes.php: -------------------------------------------------------------------------------- 1 | 'application/json' 18 | )); 19 | }); 20 | 21 | Route::get('api-docs', function() { 22 | if (Config::get('swagger.generateAlways')) { 23 | $appDir = base_path()."/".Config::get('swagger.app-dir'); 24 | $docDir = Config::get('swagger.doc-dir'); 25 | 26 | if (!File::exists($docDir) || is_writable($docDir)) { 27 | // delete all existing documentation 28 | if (File::exists($docDir)) { 29 | File::deleteDirectory($docDir); 30 | } 31 | 32 | File::makeDirectory($docDir); 33 | 34 | $defaultBasePath = Config::get('swagger.default-base-path'); 35 | $defaultApiVersion = Config::get('swagger.default-api-version'); 36 | $defaultSwaggerVersion = Config::get('swagger.default-swagger-version'); 37 | $excludeDirs = Config::get('swagger.excludes'); 38 | 39 | $swagger = new Swagger($appDir, $excludeDirs); 40 | 41 | $resourceList = $swagger->getResourceList(array( 42 | 'output' => 'array', 43 | 'apiVersion' => $defaultApiVersion, 44 | 'swaggerVersion' => $defaultSwaggerVersion, 45 | )); 46 | $resourceOptions = array( 47 | 'output' => 'json', 48 | 'defaultSwaggerVersion' => $resourceList['swaggerVersion'], 49 | 'defaultBasePath' => $defaultBasePath 50 | ); 51 | 52 | $output = array(); 53 | foreach ($swagger->getResourceNames() as $resourceName) { 54 | $json = $swagger->getResource($resourceName, $resourceOptions); 55 | $resourceName = str_replace(DIRECTORY_SEPARATOR, '-', ltrim($resourceName, DIRECTORY_SEPARATOR)); 56 | $output[$resourceName] = $json; 57 | } 58 | 59 | $filename = $docDir . '/api-docs.json'; 60 | file_put_contents($filename, Swagger::jsonEncode($resourceList, true)); 61 | 62 | foreach ($output as $name => $json) { 63 | $name = str_replace(DIRECTORY_SEPARATOR, '-', ltrim($name, DIRECTORY_SEPARATOR)); 64 | $filename = $docDir . '/'.$name . '.json'; 65 | file_put_contents($filename, $json); 66 | } 67 | } 68 | } 69 | 70 | if (Config::get('swagger.behind-reverse-proxy')) { 71 | $proxy = Request::server('REMOTE_ADDR'); 72 | Request::setTrustedProxies(array($proxy)); 73 | } 74 | 75 | Blade::setEscapedContentTags('{{{', '}}}'); 76 | Blade::setContentTags('{{', '}}'); 77 | 78 | //need the / at the end to avoid CORS errors on Homestead systems. 79 | $response = response()->view('swagger::index', array( 80 | 'secure' => Request::secure(), 81 | 'urlToDocs' => url(Config::get('swagger.doc-route')), 82 | 'requestHeaders' => Config::get('swagger.requestHeaders') ) 83 | ); 84 | 85 | //need the / at the end to avoid CORS errors on Homestead systems. 86 | /*$response = Response::make( 87 | View::make('swaggervel::index', array( 88 | 'secure' => Request::secure(), 89 | 'urlToDocs' => url(Config::get('swaggervel.doc-route')), 90 | 'requestHeaders' => Config::get('swaggervel.requestHeaders') ) 91 | ), 92 | 200 93 | );*/ 94 | 95 | if (Config::has('swagger.viewHeaders')) { 96 | foreach (Config::get('swagger.viewHeaders') as $key => $value) { 97 | $response->header($key, $value); 98 | } 99 | } 100 | 101 | return $response; 102 | }); 103 | -------------------------------------------------------------------------------- /resources/views/index.blade.php: -------------------------------------------------------------------------------- 1 | 8 | 9 | 10 | 11 | HeLei API DOC 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | {{-- {{ HTML::script('packages/jlapp/swaggervel/lib/swagger-oauth.js' , array(), $secure); !!}--}} 37 | 38 | 100 | 101 | 102 | 103 | 113 | 114 |
 
115 |
116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /public/css/style.css: -------------------------------------------------------------------------------- 1 | .swagger-section #header a#logo { 2 | font-size: 1.5em; 3 | font-weight: bold; 4 | text-decoration: none; 5 | background: transparent url(../images/logo.png) no-repeat left center; 6 | padding: 20px 0 20px 40px; 7 | } 8 | #text-head { 9 | font-size: 80px; 10 | font-family: 'Roboto', sans-serif; 11 | color: #ffffff; 12 | float: right; 13 | margin-right: 20%; 14 | } 15 | .navbar-fixed-top .navbar-nav { 16 | height: auto; 17 | } 18 | .navbar-fixed-top .navbar-brand { 19 | height: auto; 20 | } 21 | .navbar-header { 22 | height: auto; 23 | } 24 | .navbar-inverse { 25 | background-color: #000; 26 | border-color: #000; 27 | } 28 | #navbar-brand { 29 | margin-left: 20%; 30 | } 31 | .navtext { 32 | font-size: 10px; 33 | } 34 | .h1, 35 | h1 { 36 | font-size: 60px; 37 | } 38 | .navbar-default .navbar-header .navbar-brand { 39 | color: #a2dfee; 40 | } 41 | /* tag titles */ 42 | .swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a { 43 | color: #393939; 44 | font-family: 'Arvo', serif; 45 | font-size: 1.5em; 46 | } 47 | .swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a:hover { 48 | color: black; 49 | } 50 | .swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 { 51 | color: #525252; 52 | padding-left: 0px; 53 | display: block; 54 | clear: none; 55 | float: left; 56 | font-family: 'Arvo', serif; 57 | font-weight: bold; 58 | } 59 | .navbar-default .navbar-collapse, 60 | .navbar-default .navbar-form { 61 | border-color: #0A0A0A; 62 | } 63 | .container1 { 64 | width: 1500px; 65 | margin: auto; 66 | margin-top: 0; 67 | background-image: url('../images/shield.png'); 68 | background-repeat: no-repeat; 69 | background-position: -40px -20px; 70 | margin-bottom: 210px; 71 | } 72 | .container-inner { 73 | width: 1200px; 74 | margin: auto; 75 | background-color: rgba(223, 227, 228, 0.75); 76 | padding-bottom: 40px; 77 | padding-top: 40px; 78 | border-radius: 15px; 79 | } 80 | .header-content { 81 | padding: 0; 82 | width: 1000px; 83 | } 84 | .title1 { 85 | font-size: 80px; 86 | font-family: 'Vollkorn', serif; 87 | color: #404040; 88 | text-align: center; 89 | padding-top: 40px; 90 | padding-bottom: 100px; 91 | } 92 | #icon { 93 | margin-top: -18px; 94 | } 95 | .subtext { 96 | font-size: 25px; 97 | font-style: italic; 98 | color: #08b; 99 | text-align: right; 100 | padding-right: 250px; 101 | } 102 | .bg-primary { 103 | background-color: #00468b; 104 | } 105 | .navbar-default .nav > li > a, 106 | .navbar-default .nav > li > a:focus { 107 | color: #08b; 108 | } 109 | .navbar-default .nav > li > a, 110 | .navbar-default .nav > li > a:hover { 111 | color: #08b; 112 | } 113 | .navbar-default .nav > li > a, 114 | .navbar-default .nav > li > a:focus:hover { 115 | color: #08b; 116 | } 117 | .text-faded { 118 | font-size: 25px; 119 | font-family: 'Vollkorn', serif; 120 | } 121 | .section-heading { 122 | font-family: 'Vollkorn', serif; 123 | font-size: 45px; 124 | padding-bottom: 10px; 125 | } 126 | hr { 127 | border-color: #00468b; 128 | padding-bottom: 10px; 129 | } 130 | .description { 131 | margin-top: 20px; 132 | padding-bottom: 200px; 133 | } 134 | .description li { 135 | font-family: 'Vollkorn', serif; 136 | font-size: 25px; 137 | color: #525252; 138 | margin-left: 28%; 139 | padding-top: 5px; 140 | } 141 | .gap { 142 | margin-top: 200px; 143 | } 144 | .troubleshootingtext { 145 | color: rgba(255, 255, 255, 0.7); 146 | padding-left: 30%; 147 | } 148 | .troubleshootingtext li { 149 | list-style-type: circle; 150 | font-size: 25px; 151 | padding-bottom: 5px; 152 | } 153 | .overlay { 154 | position: absolute; 155 | top: 0; 156 | left: 0; 157 | width: 100%; 158 | height: 100%; 159 | z-index: 1000; 160 | } 161 | .block.response_body.json:hover { 162 | cursor: pointer; 163 | } 164 | .backdrop { 165 | color: blue; 166 | } 167 | #myModal { 168 | height: 100%; 169 | } 170 | .modal-backdrop { 171 | bottom: 0; 172 | position: fixed; 173 | } 174 | .curl { 175 | padding: 10px; 176 | font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; 177 | font-size: 0.9em; 178 | max-height: 400px; 179 | margin-top: 5px; 180 | overflow-y: auto; 181 | background-color: #fcf6db; 182 | border: 1px solid #e5e0c6; 183 | border-radius: 4px; 184 | } 185 | .curl_title { 186 | font-size: 1.1em; 187 | margin: 0; 188 | padding: 15px 0 5px; 189 | font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif; 190 | font-weight: 500; 191 | line-height: 1.1; 192 | } 193 | .footer { 194 | display: none; 195 | } 196 | .swagger-section .swagger-ui-wrap h2 { 197 | padding: 0; 198 | } 199 | h2 { 200 | margin: 0; 201 | margin-bottom: 5px; 202 | } 203 | .markdown p { 204 | font-size: 15px; 205 | font-family: 'Arvo', serif; 206 | } 207 | .swagger-section .swagger-ui-wrap .code { 208 | font-size: 15px; 209 | font-family: 'Arvo', serif; 210 | } 211 | .swagger-section .swagger-ui-wrap b { 212 | font-family: 'Arvo', serif; 213 | } 214 | #signin:hover { 215 | cursor: pointer; 216 | } 217 | .dropdown-menu { 218 | padding: 15px; 219 | } 220 | .navbar-right .dropdown-menu { 221 | left: 0; 222 | right: auto; 223 | } 224 | #signinbutton { 225 | width: 100%; 226 | height: 32px; 227 | font-size: 13px; 228 | font-weight: bold; 229 | color: #08b; 230 | } 231 | .navbar-default .nav > li .details { 232 | color: #000000; 233 | text-transform: none; 234 | font-size: 15px; 235 | font-weight: normal; 236 | font-family: 'Open Sans', sans-serif; 237 | font-style: italic; 238 | line-height: 20px; 239 | top: -2px; 240 | } 241 | .navbar-default .nav > li .details:hover { 242 | color: black; 243 | } 244 | #signout { 245 | width: 100%; 246 | height: 32px; 247 | font-size: 13px; 248 | font-weight: bold; 249 | color: #08b; 250 | } 251 | -------------------------------------------------------------------------------- /public/lib/highlight.7.3.pack.js: -------------------------------------------------------------------------------- 1 | var hljs=new function(){function l(o){return o.replace(/&/gm,"&").replace(//gm,">")}function b(p){for(var o=p.firstChild;o;o=o.nextSibling){if(o.nodeName=="CODE"){return o}if(!(o.nodeType==3&&o.nodeValue.match(/\s+/))){break}}}function h(p,o){return Array.prototype.map.call(p.childNodes,function(q){if(q.nodeType==3){return o?q.nodeValue.replace(/\n/g,""):q.nodeValue}if(q.nodeName=="BR"){return"\n"}return h(q,o)}).join("")}function a(q){var p=(q.className+" "+q.parentNode.className).split(/\s+/);p=p.map(function(r){return r.replace(/^language-/,"")});for(var o=0;o"}while(x.length||v.length){var u=t().splice(0,1)[0];y+=l(w.substr(p,u.offset-p));p=u.offset;if(u.event=="start"){y+=s(u.node);r.push(u.node)}else{if(u.event=="stop"){var o,q=r.length;do{q--;o=r[q];y+=("")}while(o!=u.node);r.splice(q,1);while(q'+L[0]+""}else{r+=L[0]}N=A.lR.lastIndex;L=A.lR.exec(K)}return r+K.substr(N)}function z(){if(A.sL&&!e[A.sL]){return l(w)}var r=A.sL?d(A.sL,w):g(w);if(A.r>0){v+=r.keyword_count;B+=r.r}return''+r.value+""}function J(){return A.sL!==undefined?z():G()}function I(L,r){var K=L.cN?'':"";if(L.rB){x+=K;w=""}else{if(L.eB){x+=l(r)+K;w=""}else{x+=K;w=r}}A=Object.create(L,{parent:{value:A}});B+=L.r}function C(K,r){w+=K;if(r===undefined){x+=J();return 0}var L=o(r,A);if(L){x+=J();I(L,r);return L.rB?0:r.length}var M=s(A,r);if(M){if(!(M.rE||M.eE)){w+=r}x+=J();do{if(A.cN){x+=""}A=A.parent}while(A!=M.parent);if(M.eE){x+=l(r)}w="";if(M.starts){I(M.starts,"")}return M.rE?0:r.length}if(t(r,A)){throw"Illegal"}w+=r;return r.length||1}var F=e[D];f(F);var A=F;var w="";var B=0;var v=0;var x="";try{var u,q,p=0;while(true){A.t.lastIndex=p;u=A.t.exec(E);if(!u){break}q=C(E.substr(p,u.index-p),u[0]);p=u.index+q}C(E.substr(p));return{r:B,keyword_count:v,value:x,language:D}}catch(H){if(H=="Illegal"){return{r:0,keyword_count:0,value:l(E)}}else{throw H}}}function g(s){var o={keyword_count:0,r:0,value:l(s)};var q=o;for(var p in e){if(!e.hasOwnProperty(p)){continue}var r=d(p,s);r.language=p;if(r.keyword_count+r.r>q.keyword_count+q.r){q=r}if(r.keyword_count+r.r>o.keyword_count+o.r){q=o;o=r}}if(q.language){o.second_best=q}return o}function i(q,p,o){if(p){q=q.replace(/^((<[^>]+>|\t)+)/gm,function(r,v,u,t){return v.replace(/\t/g,p)})}if(o){q=q.replace(/\n/g,"
")}return q}function m(r,u,p){var v=h(r,p);var t=a(r);if(t=="no-highlight"){return}var w=t?d(t,v):g(v);t=w.language;var o=c(r);if(o.length){var q=document.createElement("pre");q.innerHTML=w.value;w.value=j(o,c(q),v)}w.value=i(w.value,u,p);var s=r.className;if(!s.match("(\\s|^)(language-)?"+t+"(\\s|$)")){s=s?(s+" "+t):t}r.innerHTML=w.value;r.className=s;r.result={language:t,kw:w.keyword_count,re:w.r};if(w.second_best){r.second_best={language:w.second_best.language,kw:w.second_best.keyword_count,re:w.second_best.r}}}function n(){if(n.called){return}n.called=true;Array.prototype.map.call(document.getElementsByTagName("pre"),b).filter(Boolean).forEach(function(o){m(o,hljs.tabReplace)})}function k(){window.addEventListener("DOMContentLoaded",n,false);window.addEventListener("load",n,false)}var e={};this.LANGUAGES=e;this.highlight=d;this.highlightAuto=g;this.fixMarkup=i;this.highlightBlock=m;this.initHighlighting=n;this.initHighlightingOnLoad=k;this.IR="[a-zA-Z][a-zA-Z0-9_]*";this.UIR="[a-zA-Z_][a-zA-Z0-9_]*";this.NR="\\b\\d+(\\.\\d+)?";this.CNR="(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)";this.BNR="\\b(0b[01]+)";this.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|\\.|-|-=|/|/=|:|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~";this.BE={b:"\\\\[\\s\\S]",r:0};this.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[this.BE],r:0};this.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[this.BE],r:0};this.CLCM={cN:"comment",b:"//",e:"$"};this.CBLCLM={cN:"comment",b:"/\\*",e:"\\*/"};this.HCM={cN:"comment",b:"#",e:"$"};this.NM={cN:"number",b:this.NR,r:0};this.CNM={cN:"number",b:this.CNR,r:0};this.BNM={cN:"number",b:this.BNR,r:0};this.inherit=function(q,r){var o={};for(var p in q){o[p]=q[p]}if(r){for(var p in r){o[p]=r[p]}}return o}}();hljs.LANGUAGES.xml=function(a){var c="[A-Za-z0-9\\._:-]+";var b={eW:true,c:[{cN:"attribute",b:c,r:0},{b:'="',rB:true,e:'"',c:[{cN:"value",b:'"',eW:true}]},{b:"='",rB:true,e:"'",c:[{cN:"value",b:"'",eW:true}]},{b:"=",c:[{cN:"value",b:"[^\\s/>]+"}]}]};return{cI:true,c:[{cN:"pi",b:"<\\?",e:"\\?>",r:10},{cN:"doctype",b:"",r:10,c:[{b:"\\[",e:"\\]"}]},{cN:"comment",b:"",r:10},{cN:"cdata",b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"tag",b:"|$)",e:">",k:{title:"style"},c:[b],starts:{e:"",rE:true,sL:"css"}},{cN:"tag",b:"|$)",e:">",k:{title:"script"},c:[b],starts:{e:"<\/script>",rE:true,sL:"javascript"}},{b:"<%",e:"%>",sL:"vbscript"},{cN:"tag",b:"",c:[{cN:"title",b:"[^ />]+"},b]}]}}(hljs);hljs.LANGUAGES.json=function(a){var e={literal:"true false null"};var d=[a.QSM,a.CNM];var c={cN:"value",e:",",eW:true,eE:true,c:d,k:e};var b={b:"{",e:"}",c:[{cN:"attribute",b:'\\s*"',e:'"\\s*:\\s*',eB:true,eE:true,c:[a.BE],i:"\\n",starts:c}],i:"\\S"};var f={b:"\\[",e:"\\]",c:[a.inherit(c,{cN:null})],i:"\\S"};d.splice(d.length,0,b,f);return{c:d,k:e,i:"\\S"}}(hljs); -------------------------------------------------------------------------------- /public/lib/swagger-oauth.js: -------------------------------------------------------------------------------- 1 | var appName; 2 | var popupMask; 3 | var popupDialog; 4 | var clientId; 5 | var realm; 6 | var oauth2KeyName; 7 | var redirect_uri; 8 | 9 | function handleLogin() { 10 | var scopes = []; 11 | 12 | var auths = window.swaggerUi.api.authSchemes || window.swaggerUi.api.securityDefinitions; 13 | if(auths) { 14 | var key; 15 | var defs = auths; 16 | for(key in defs) { 17 | var auth = defs[key]; 18 | if(auth.type === 'oauth2' && auth.scopes) { 19 | oauth2KeyName = key; 20 | var scope; 21 | if(Array.isArray(auth.scopes)) { 22 | // 1.2 support 23 | var i; 24 | for(i = 0; i < auth.scopes.length; i++) { 25 | scopes.push(auth.scopes[i]); 26 | } 27 | } 28 | else { 29 | // 2.0 support 30 | for(scope in auth.scopes) { 31 | scopes.push({scope: scope, description: auth.scopes[scope]}); 32 | } 33 | } 34 | } 35 | } 36 | } 37 | 38 | if(window.swaggerUi.api 39 | && window.swaggerUi.api.info) { 40 | appName = window.swaggerUi.api.info.title; 41 | } 42 | 43 | popupDialog = $( 44 | [ 45 | '
', 46 | '
Select OAuth2.0 Scopes
', 47 | '
', 48 | '

Scopes are used to grant an application different levels of access to data on behalf of the end user. Each API may declare one or more scopes.', 49 | 'Learn how to use', 50 | '

', 51 | '

' + appName + ' API requires the following scopes. Select which ones you want to grant to Swagger UI.

', 52 | '
    ', 53 | '
', 54 | '

', 55 | '
', 56 | '
', 57 | '
'].join('')); 58 | $(document.body).append(popupDialog); 59 | 60 | popup = popupDialog.find('ul.api-popup-scopes').empty(); 61 | for (i = 0; i < scopes.length; i ++) { 62 | scope = scopes[i]; 63 | str = '
  • ' + '
  • '; 68 | popup.append(str); 69 | } 70 | 71 | var $win = $(window), 72 | dw = $win.width(), 73 | dh = $win.height(), 74 | st = $win.scrollTop(), 75 | dlgWd = popupDialog.outerWidth(), 76 | dlgHt = popupDialog.outerHeight(), 77 | top = (dh -dlgHt)/2 + st, 78 | left = (dw - dlgWd)/2; 79 | 80 | popupDialog.css({ 81 | top: (top < 0? 0 : top) + 'px', 82 | left: (left < 0? 0 : left) + 'px' 83 | }); 84 | 85 | popupDialog.find('button.api-popup-cancel').click(function() { 86 | popupMask.hide(); 87 | popupDialog.hide(); 88 | popupDialog.empty(); 89 | popupDialog = []; 90 | }); 91 | 92 | $('button.api-popup-authbtn').unbind(); 93 | popupDialog.find('button.api-popup-authbtn').click(function() { 94 | popupMask.hide(); 95 | popupDialog.hide(); 96 | 97 | var authSchemes = window.swaggerUi.api.authSchemes; 98 | var host = window.location; 99 | var pathname = location.pathname.substring(0, location.pathname.lastIndexOf("/")); 100 | var defaultRedirectUrl = host.protocol + '//' + host.host + pathname + '/o2c.html'; 101 | var redirectUrl = window.oAuthRedirectUrl || defaultRedirectUrl; 102 | var url = null; 103 | 104 | for (var key in authSchemes) { 105 | if (authSchemes.hasOwnProperty(key)) { 106 | var flow = authSchemes[key].flow; 107 | 108 | if(authSchemes[key].type === 'oauth2' && flow && (flow === 'implicit' || flow === 'accessCode')) { 109 | var dets = authSchemes[key]; 110 | url = dets.authorizationUrl + '?response_type=' + (flow === 'implicit' ? 'token' : 'code'); 111 | window.swaggerUi.tokenName = dets.tokenName || 'access_token'; 112 | window.swaggerUi.tokenUrl = (flow === 'accessCode' ? dets.tokenUrl : null); 113 | } 114 | else if(authSchemes[key].grantTypes) { 115 | // 1.2 support 116 | var o = authSchemes[key].grantTypes; 117 | for(var t in o) { 118 | if(o.hasOwnProperty(t) && t === 'implicit') { 119 | var dets = o[t]; 120 | var ep = dets.loginEndpoint.url; 121 | url = dets.loginEndpoint.url + '?response_type=token'; 122 | window.swaggerUi.tokenName = dets.tokenName; 123 | } 124 | else if (o.hasOwnProperty(t) && t === 'accessCode') { 125 | var dets = o[t]; 126 | var ep = dets.tokenRequestEndpoint.url; 127 | url = dets.tokenRequestEndpoint.url + '?response_type=code'; 128 | window.swaggerUi.tokenName = dets.tokenName; 129 | } 130 | } 131 | } 132 | } 133 | } 134 | var scopes = [] 135 | var o = $('.api-popup-scopes').find('input:checked'); 136 | 137 | for(k =0; k < o.length; k++) { 138 | var scope = $(o[k]).attr('scope'); 139 | 140 | if (scopes.indexOf(scope) === -1) 141 | scopes.push(scope); 142 | } 143 | 144 | // Implicit auth recommends a state parameter. 145 | var state = Math.random (); 146 | 147 | window.enabledScopes=scopes; 148 | 149 | redirect_uri = redirectUrl; 150 | 151 | url += '&redirect_uri=' + encodeURIComponent(redirectUrl); 152 | url += '&realm=' + encodeURIComponent(realm); 153 | url += '&client_id=' + encodeURIComponent(clientId); 154 | url += '&scope=' + encodeURIComponent(scopes.join(' ')); 155 | url += '&state=' + encodeURIComponent(state); 156 | 157 | window.open(url); 158 | }); 159 | 160 | popupMask.show(); 161 | popupDialog.show(); 162 | return; 163 | } 164 | 165 | 166 | function handleLogout() { 167 | for(key in window.authorizations.authz){ 168 | window.authorizations.remove(key) 169 | } 170 | window.enabledScopes = null; 171 | $('.api-ic.ic-on').addClass('ic-off'); 172 | $('.api-ic.ic-on').removeClass('ic-on'); 173 | 174 | // set the info box 175 | $('.api-ic.ic-warning').addClass('ic-error'); 176 | $('.api-ic.ic-warning').removeClass('ic-warning'); 177 | } 178 | 179 | function initOAuth(opts) { 180 | var o = (opts||{}); 181 | var errors = []; 182 | 183 | appName = (o.appName||errors.push('missing appName')); 184 | popupMask = (o.popupMask||$('#api-common-mask')); 185 | popupDialog = (o.popupDialog||$('.api-popup-dialog')); 186 | clientId = (o.clientId||errors.push('missing client id')); 187 | realm = (o.realm||errors.push('missing realm')); 188 | 189 | if(errors.length > 0){ 190 | log('auth unable initialize oauth: ' + errors); 191 | return; 192 | } 193 | 194 | $('pre code').each(function(i, e) {hljs.highlightBlock(e)}); 195 | $('.api-ic').unbind(); 196 | $('.api-ic').click(function(s) { 197 | if($(s.target).hasClass('ic-off')) 198 | handleLogin(); 199 | else { 200 | handleLogout(); 201 | } 202 | false; 203 | }); 204 | } 205 | 206 | window.processOAuthCode = function processOAuthCode(data) { 207 | var params = { 208 | 'client_id': clientId, 209 | 'code': data.code, 210 | 'grant_type': 'authorization_code', 211 | 'redirect_uri': redirect_uri 212 | } 213 | $.ajax( 214 | { 215 | url : window.swaggerUi.tokenUrl, 216 | type: "POST", 217 | data: params, 218 | success:function(data, textStatus, jqXHR) 219 | { 220 | onOAuthComplete(data); 221 | }, 222 | error: function(jqXHR, textStatus, errorThrown) 223 | { 224 | onOAuthComplete(""); 225 | } 226 | }); 227 | } 228 | 229 | window.onOAuthComplete = function onOAuthComplete(token) { 230 | if(token) { 231 | if(token.error) { 232 | var checkbox = $('input[type=checkbox],.secured') 233 | checkbox.each(function(pos){ 234 | checkbox[pos].checked = false; 235 | }); 236 | alert(token.error); 237 | } 238 | else { 239 | var b = token[window.swaggerUi.tokenName]; 240 | if(b){ 241 | // if all roles are satisfied 242 | var o = null; 243 | $.each($('.auth #api_information_panel'), function(k, v) { 244 | var children = v; 245 | if(children && children.childNodes) { 246 | var requiredScopes = []; 247 | $.each((children.childNodes), function (k1, v1){ 248 | var inner = v1.innerHTML; 249 | if(inner) 250 | requiredScopes.push(inner); 251 | }); 252 | var diff = []; 253 | for(var i=0; i < requiredScopes.length; i++) { 254 | var s = requiredScopes[i]; 255 | if(window.enabledScopes && window.enabledScopes.indexOf(s) == -1) { 256 | diff.push(s); 257 | } 258 | } 259 | if(diff.length > 0){ 260 | o = v.parentNode; 261 | $(o.parentNode).find('.api-ic.ic-on').addClass('ic-off'); 262 | $(o.parentNode).find('.api-ic.ic-on').removeClass('ic-on'); 263 | 264 | // sorry, not all scopes are satisfied 265 | $(o).find('.api-ic').addClass('ic-warning'); 266 | $(o).find('.api-ic').removeClass('ic-error'); 267 | } 268 | else { 269 | o = v.parentNode; 270 | $(o.parentNode).find('.api-ic.ic-off').addClass('ic-on'); 271 | $(o.parentNode).find('.api-ic.ic-off').removeClass('ic-off'); 272 | 273 | // all scopes are satisfied 274 | $(o).find('.api-ic').addClass('ic-info'); 275 | $(o).find('.api-ic').removeClass('ic-warning'); 276 | $(o).find('.api-ic').removeClass('ic-error'); 277 | } 278 | } 279 | }); 280 | window.swaggerUi.api.clientAuthorizations.add(oauth2KeyName, new SwaggerClient.ApiKeyAuthorization('Authorization', 'Bearer ' + b, 'header')); 281 | } 282 | } 283 | } 284 | } 285 | -------------------------------------------------------------------------------- /public/lib/underscore-min.js: -------------------------------------------------------------------------------- 1 | // Underscore.js 1.7.0 2 | // http://underscorejs.org 3 | // (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors 4 | // Underscore may be freely distributed under the MIT license. 5 | (function(){var n=this,t=n._,r=Array.prototype,e=Object.prototype,u=Function.prototype,i=r.push,a=r.slice,o=r.concat,l=e.toString,c=e.hasOwnProperty,f=Array.isArray,s=Object.keys,p=u.bind,h=function(n){return n instanceof h?n:this instanceof h?void(this._wrapped=n):new h(n)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=h),exports._=h):n._=h,h.VERSION="1.7.0";var g=function(n,t,r){if(t===void 0)return n;switch(null==r?3:r){case 1:return function(r){return n.call(t,r)};case 2:return function(r,e){return n.call(t,r,e)};case 3:return function(r,e,u){return n.call(t,r,e,u)};case 4:return function(r,e,u,i){return n.call(t,r,e,u,i)}}return function(){return n.apply(t,arguments)}};h.iteratee=function(n,t,r){return null==n?h.identity:h.isFunction(n)?g(n,t,r):h.isObject(n)?h.matches(n):h.property(n)},h.each=h.forEach=function(n,t,r){if(null==n)return n;t=g(t,r);var e,u=n.length;if(u===+u)for(e=0;u>e;e++)t(n[e],e,n);else{var i=h.keys(n);for(e=0,u=i.length;u>e;e++)t(n[i[e]],i[e],n)}return n},h.map=h.collect=function(n,t,r){if(null==n)return[];t=h.iteratee(t,r);for(var e,u=n.length!==+n.length&&h.keys(n),i=(u||n).length,a=Array(i),o=0;i>o;o++)e=u?u[o]:o,a[o]=t(n[e],e,n);return a};var v="Reduce of empty array with no initial value";h.reduce=h.foldl=h.inject=function(n,t,r,e){null==n&&(n=[]),t=g(t,e,4);var u,i=n.length!==+n.length&&h.keys(n),a=(i||n).length,o=0;if(arguments.length<3){if(!a)throw new TypeError(v);r=n[i?i[o++]:o++]}for(;a>o;o++)u=i?i[o]:o,r=t(r,n[u],u,n);return r},h.reduceRight=h.foldr=function(n,t,r,e){null==n&&(n=[]),t=g(t,e,4);var u,i=n.length!==+n.length&&h.keys(n),a=(i||n).length;if(arguments.length<3){if(!a)throw new TypeError(v);r=n[i?i[--a]:--a]}for(;a--;)u=i?i[a]:a,r=t(r,n[u],u,n);return r},h.find=h.detect=function(n,t,r){var e;return t=h.iteratee(t,r),h.some(n,function(n,r,u){return t(n,r,u)?(e=n,!0):void 0}),e},h.filter=h.select=function(n,t,r){var e=[];return null==n?e:(t=h.iteratee(t,r),h.each(n,function(n,r,u){t(n,r,u)&&e.push(n)}),e)},h.reject=function(n,t,r){return h.filter(n,h.negate(h.iteratee(t)),r)},h.every=h.all=function(n,t,r){if(null==n)return!0;t=h.iteratee(t,r);var e,u,i=n.length!==+n.length&&h.keys(n),a=(i||n).length;for(e=0;a>e;e++)if(u=i?i[e]:e,!t(n[u],u,n))return!1;return!0},h.some=h.any=function(n,t,r){if(null==n)return!1;t=h.iteratee(t,r);var e,u,i=n.length!==+n.length&&h.keys(n),a=(i||n).length;for(e=0;a>e;e++)if(u=i?i[e]:e,t(n[u],u,n))return!0;return!1},h.contains=h.include=function(n,t){return null==n?!1:(n.length!==+n.length&&(n=h.values(n)),h.indexOf(n,t)>=0)},h.invoke=function(n,t){var r=a.call(arguments,2),e=h.isFunction(t);return h.map(n,function(n){return(e?t:n[t]).apply(n,r)})},h.pluck=function(n,t){return h.map(n,h.property(t))},h.where=function(n,t){return h.filter(n,h.matches(t))},h.findWhere=function(n,t){return h.find(n,h.matches(t))},h.max=function(n,t,r){var e,u,i=-1/0,a=-1/0;if(null==t&&null!=n){n=n.length===+n.length?n:h.values(n);for(var o=0,l=n.length;l>o;o++)e=n[o],e>i&&(i=e)}else t=h.iteratee(t,r),h.each(n,function(n,r,e){u=t(n,r,e),(u>a||u===-1/0&&i===-1/0)&&(i=n,a=u)});return i},h.min=function(n,t,r){var e,u,i=1/0,a=1/0;if(null==t&&null!=n){n=n.length===+n.length?n:h.values(n);for(var o=0,l=n.length;l>o;o++)e=n[o],i>e&&(i=e)}else t=h.iteratee(t,r),h.each(n,function(n,r,e){u=t(n,r,e),(a>u||1/0===u&&1/0===i)&&(i=n,a=u)});return i},h.shuffle=function(n){for(var t,r=n&&n.length===+n.length?n:h.values(n),e=r.length,u=Array(e),i=0;e>i;i++)t=h.random(0,i),t!==i&&(u[i]=u[t]),u[t]=r[i];return u},h.sample=function(n,t,r){return null==t||r?(n.length!==+n.length&&(n=h.values(n)),n[h.random(n.length-1)]):h.shuffle(n).slice(0,Math.max(0,t))},h.sortBy=function(n,t,r){return t=h.iteratee(t,r),h.pluck(h.map(n,function(n,r,e){return{value:n,index:r,criteria:t(n,r,e)}}).sort(function(n,t){var r=n.criteria,e=t.criteria;if(r!==e){if(r>e||r===void 0)return 1;if(e>r||e===void 0)return-1}return n.index-t.index}),"value")};var m=function(n){return function(t,r,e){var u={};return r=h.iteratee(r,e),h.each(t,function(e,i){var a=r(e,i,t);n(u,e,a)}),u}};h.groupBy=m(function(n,t,r){h.has(n,r)?n[r].push(t):n[r]=[t]}),h.indexBy=m(function(n,t,r){n[r]=t}),h.countBy=m(function(n,t,r){h.has(n,r)?n[r]++:n[r]=1}),h.sortedIndex=function(n,t,r,e){r=h.iteratee(r,e,1);for(var u=r(t),i=0,a=n.length;a>i;){var o=i+a>>>1;r(n[o])t?[]:a.call(n,0,t)},h.initial=function(n,t,r){return a.call(n,0,Math.max(0,n.length-(null==t||r?1:t)))},h.last=function(n,t,r){return null==n?void 0:null==t||r?n[n.length-1]:a.call(n,Math.max(n.length-t,0))},h.rest=h.tail=h.drop=function(n,t,r){return a.call(n,null==t||r?1:t)},h.compact=function(n){return h.filter(n,h.identity)};var y=function(n,t,r,e){if(t&&h.every(n,h.isArray))return o.apply(e,n);for(var u=0,a=n.length;a>u;u++){var l=n[u];h.isArray(l)||h.isArguments(l)?t?i.apply(e,l):y(l,t,r,e):r||e.push(l)}return e};h.flatten=function(n,t){return y(n,t,!1,[])},h.without=function(n){return h.difference(n,a.call(arguments,1))},h.uniq=h.unique=function(n,t,r,e){if(null==n)return[];h.isBoolean(t)||(e=r,r=t,t=!1),null!=r&&(r=h.iteratee(r,e));for(var u=[],i=[],a=0,o=n.length;o>a;a++){var l=n[a];if(t)a&&i===l||u.push(l),i=l;else if(r){var c=r(l,a,n);h.indexOf(i,c)<0&&(i.push(c),u.push(l))}else h.indexOf(u,l)<0&&u.push(l)}return u},h.union=function(){return h.uniq(y(arguments,!0,!0,[]))},h.intersection=function(n){if(null==n)return[];for(var t=[],r=arguments.length,e=0,u=n.length;u>e;e++){var i=n[e];if(!h.contains(t,i)){for(var a=1;r>a&&h.contains(arguments[a],i);a++);a===r&&t.push(i)}}return t},h.difference=function(n){var t=y(a.call(arguments,1),!0,!0,[]);return h.filter(n,function(n){return!h.contains(t,n)})},h.zip=function(n){if(null==n)return[];for(var t=h.max(arguments,"length").length,r=Array(t),e=0;t>e;e++)r[e]=h.pluck(arguments,e);return r},h.object=function(n,t){if(null==n)return{};for(var r={},e=0,u=n.length;u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},h.indexOf=function(n,t,r){if(null==n)return-1;var e=0,u=n.length;if(r){if("number"!=typeof r)return e=h.sortedIndex(n,t),n[e]===t?e:-1;e=0>r?Math.max(0,u+r):r}for(;u>e;e++)if(n[e]===t)return e;return-1},h.lastIndexOf=function(n,t,r){if(null==n)return-1;var e=n.length;for("number"==typeof r&&(e=0>r?e+r+1:Math.min(e,r+1));--e>=0;)if(n[e]===t)return e;return-1},h.range=function(n,t,r){arguments.length<=1&&(t=n||0,n=0),r=r||1;for(var e=Math.max(Math.ceil((t-n)/r),0),u=Array(e),i=0;e>i;i++,n+=r)u[i]=n;return u};var d=function(){};h.bind=function(n,t){var r,e;if(p&&n.bind===p)return p.apply(n,a.call(arguments,1));if(!h.isFunction(n))throw new TypeError("Bind must be called on a function");return r=a.call(arguments,2),e=function(){if(!(this instanceof e))return n.apply(t,r.concat(a.call(arguments)));d.prototype=n.prototype;var u=new d;d.prototype=null;var i=n.apply(u,r.concat(a.call(arguments)));return h.isObject(i)?i:u}},h.partial=function(n){var t=a.call(arguments,1);return function(){for(var r=0,e=t.slice(),u=0,i=e.length;i>u;u++)e[u]===h&&(e[u]=arguments[r++]);for(;r=e)throw new Error("bindAll must be passed function names");for(t=1;e>t;t++)r=arguments[t],n[r]=h.bind(n[r],n);return n},h.memoize=function(n,t){var r=function(e){var u=r.cache,i=t?t.apply(this,arguments):e;return h.has(u,i)||(u[i]=n.apply(this,arguments)),u[i]};return r.cache={},r},h.delay=function(n,t){var r=a.call(arguments,2);return setTimeout(function(){return n.apply(null,r)},t)},h.defer=function(n){return h.delay.apply(h,[n,1].concat(a.call(arguments,1)))},h.throttle=function(n,t,r){var e,u,i,a=null,o=0;r||(r={});var l=function(){o=r.leading===!1?0:h.now(),a=null,i=n.apply(e,u),a||(e=u=null)};return function(){var c=h.now();o||r.leading!==!1||(o=c);var f=t-(c-o);return e=this,u=arguments,0>=f||f>t?(clearTimeout(a),a=null,o=c,i=n.apply(e,u),a||(e=u=null)):a||r.trailing===!1||(a=setTimeout(l,f)),i}},h.debounce=function(n,t,r){var e,u,i,a,o,l=function(){var c=h.now()-a;t>c&&c>0?e=setTimeout(l,t-c):(e=null,r||(o=n.apply(i,u),e||(i=u=null)))};return function(){i=this,u=arguments,a=h.now();var c=r&&!e;return e||(e=setTimeout(l,t)),c&&(o=n.apply(i,u),i=u=null),o}},h.wrap=function(n,t){return h.partial(t,n)},h.negate=function(n){return function(){return!n.apply(this,arguments)}},h.compose=function(){var n=arguments,t=n.length-1;return function(){for(var r=t,e=n[t].apply(this,arguments);r--;)e=n[r].call(this,e);return e}},h.after=function(n,t){return function(){return--n<1?t.apply(this,arguments):void 0}},h.before=function(n,t){var r;return function(){return--n>0?r=t.apply(this,arguments):t=null,r}},h.once=h.partial(h.before,2),h.keys=function(n){if(!h.isObject(n))return[];if(s)return s(n);var t=[];for(var r in n)h.has(n,r)&&t.push(r);return t},h.values=function(n){for(var t=h.keys(n),r=t.length,e=Array(r),u=0;r>u;u++)e[u]=n[t[u]];return e},h.pairs=function(n){for(var t=h.keys(n),r=t.length,e=Array(r),u=0;r>u;u++)e[u]=[t[u],n[t[u]]];return e},h.invert=function(n){for(var t={},r=h.keys(n),e=0,u=r.length;u>e;e++)t[n[r[e]]]=r[e];return t},h.functions=h.methods=function(n){var t=[];for(var r in n)h.isFunction(n[r])&&t.push(r);return t.sort()},h.extend=function(n){if(!h.isObject(n))return n;for(var t,r,e=1,u=arguments.length;u>e;e++){t=arguments[e];for(r in t)c.call(t,r)&&(n[r]=t[r])}return n},h.pick=function(n,t,r){var e,u={};if(null==n)return u;if(h.isFunction(t)){t=g(t,r);for(e in n){var i=n[e];t(i,e,n)&&(u[e]=i)}}else{var l=o.apply([],a.call(arguments,1));n=new Object(n);for(var c=0,f=l.length;f>c;c++)e=l[c],e in n&&(u[e]=n[e])}return u},h.omit=function(n,t,r){if(h.isFunction(t))t=h.negate(t);else{var e=h.map(o.apply([],a.call(arguments,1)),String);t=function(n,t){return!h.contains(e,t)}}return h.pick(n,t,r)},h.defaults=function(n){if(!h.isObject(n))return n;for(var t=1,r=arguments.length;r>t;t++){var e=arguments[t];for(var u in e)n[u]===void 0&&(n[u]=e[u])}return n},h.clone=function(n){return h.isObject(n)?h.isArray(n)?n.slice():h.extend({},n):n},h.tap=function(n,t){return t(n),n};var b=function(n,t,r,e){if(n===t)return 0!==n||1/n===1/t;if(null==n||null==t)return n===t;n instanceof h&&(n=n._wrapped),t instanceof h&&(t=t._wrapped);var u=l.call(n);if(u!==l.call(t))return!1;switch(u){case"[object RegExp]":case"[object String]":return""+n==""+t;case"[object Number]":return+n!==+n?+t!==+t:0===+n?1/+n===1/t:+n===+t;case"[object Date]":case"[object Boolean]":return+n===+t}if("object"!=typeof n||"object"!=typeof t)return!1;for(var i=r.length;i--;)if(r[i]===n)return e[i]===t;var a=n.constructor,o=t.constructor;if(a!==o&&"constructor"in n&&"constructor"in t&&!(h.isFunction(a)&&a instanceof a&&h.isFunction(o)&&o instanceof o))return!1;r.push(n),e.push(t);var c,f;if("[object Array]"===u){if(c=n.length,f=c===t.length)for(;c--&&(f=b(n[c],t[c],r,e)););}else{var s,p=h.keys(n);if(c=p.length,f=h.keys(t).length===c)for(;c--&&(s=p[c],f=h.has(t,s)&&b(n[s],t[s],r,e)););}return r.pop(),e.pop(),f};h.isEqual=function(n,t){return b(n,t,[],[])},h.isEmpty=function(n){if(null==n)return!0;if(h.isArray(n)||h.isString(n)||h.isArguments(n))return 0===n.length;for(var t in n)if(h.has(n,t))return!1;return!0},h.isElement=function(n){return!(!n||1!==n.nodeType)},h.isArray=f||function(n){return"[object Array]"===l.call(n)},h.isObject=function(n){var t=typeof n;return"function"===t||"object"===t&&!!n},h.each(["Arguments","Function","String","Number","Date","RegExp"],function(n){h["is"+n]=function(t){return l.call(t)==="[object "+n+"]"}}),h.isArguments(arguments)||(h.isArguments=function(n){return h.has(n,"callee")}),"function"!=typeof/./&&(h.isFunction=function(n){return"function"==typeof n||!1}),h.isFinite=function(n){return isFinite(n)&&!isNaN(parseFloat(n))},h.isNaN=function(n){return h.isNumber(n)&&n!==+n},h.isBoolean=function(n){return n===!0||n===!1||"[object Boolean]"===l.call(n)},h.isNull=function(n){return null===n},h.isUndefined=function(n){return n===void 0},h.has=function(n,t){return null!=n&&c.call(n,t)},h.noConflict=function(){return n._=t,this},h.identity=function(n){return n},h.constant=function(n){return function(){return n}},h.noop=function(){},h.property=function(n){return function(t){return t[n]}},h.matches=function(n){var t=h.pairs(n),r=t.length;return function(n){if(null==n)return!r;n=new Object(n);for(var e=0;r>e;e++){var u=t[e],i=u[0];if(u[1]!==n[i]||!(i in n))return!1}return!0}},h.times=function(n,t,r){var e=Array(Math.max(0,n));t=g(t,r,1);for(var u=0;n>u;u++)e[u]=t(u);return e},h.random=function(n,t){return null==t&&(t=n,n=0),n+Math.floor(Math.random()*(t-n+1))},h.now=Date.now||function(){return(new Date).getTime()};var _={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},w=h.invert(_),j=function(n){var t=function(t){return n[t]},r="(?:"+h.keys(n).join("|")+")",e=RegExp(r),u=RegExp(r,"g");return function(n){return n=null==n?"":""+n,e.test(n)?n.replace(u,t):n}};h.escape=j(_),h.unescape=j(w),h.result=function(n,t){if(null==n)return void 0;var r=n[t];return h.isFunction(r)?n[t]():r};var x=0;h.uniqueId=function(n){var t=++x+"";return n?n+t:t},h.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var A=/(.)^/,k={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},O=/\\|'|\r|\n|\u2028|\u2029/g,F=function(n){return"\\"+k[n]};h.template=function(n,t,r){!t&&r&&(t=r),t=h.defaults({},t,h.templateSettings);var e=RegExp([(t.escape||A).source,(t.interpolate||A).source,(t.evaluate||A).source].join("|")+"|$","g"),u=0,i="__p+='";n.replace(e,function(t,r,e,a,o){return i+=n.slice(u,o).replace(O,F),u=o+t.length,r?i+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'":e?i+="'+\n((__t=("+e+"))==null?'':__t)+\n'":a&&(i+="';\n"+a+"\n__p+='"),t}),i+="';\n",t.variable||(i="with(obj||{}){\n"+i+"}\n"),i="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+i+"return __p;\n";try{var a=new Function(t.variable||"obj","_",i)}catch(o){throw o.source=i,o}var l=function(n){return a.call(this,n,h)},c=t.variable||"obj";return l.source="function("+c+"){\n"+i+"}",l},h.chain=function(n){var t=h(n);return t._chain=!0,t};var E=function(n){return this._chain?h(n).chain():n};h.mixin=function(n){h.each(h.functions(n),function(t){var r=h[t]=n[t];h.prototype[t]=function(){var n=[this._wrapped];return i.apply(n,arguments),E.call(this,r.apply(h,n))}})},h.mixin(h),h.each(["pop","push","reverse","shift","sort","splice","unshift"],function(n){var t=r[n];h.prototype[n]=function(){var r=this._wrapped;return t.apply(r,arguments),"shift"!==n&&"splice"!==n||0!==r.length||delete r[0],E.call(this,r)}}),h.each(["concat","join","slice"],function(n){var t=r[n];h.prototype[n]=function(){return E.call(this,t.apply(this._wrapped,arguments))}}),h.prototype.value=function(){return this._wrapped},"function"==typeof define&&define.amd&&define("underscore",[],function(){return h})}).call(this); 6 | //# sourceMappingURL=underscore-min.map -------------------------------------------------------------------------------- /public/lib/backbone-min.js: -------------------------------------------------------------------------------- 1 | // Backbone.js 1.1.2 2 | 3 | (function(t,e){if(typeof define==="function"&&define.amd){define(["underscore","jquery","exports"],function(i,r,s){t.Backbone=e(t,s,i,r)})}else if(typeof exports!=="undefined"){var i=require("underscore");e(t,exports,i)}else{t.Backbone=e(t,{},t._,t.jQuery||t.Zepto||t.ender||t.$)}})(this,function(t,e,i,r){var s=t.Backbone;var n=[];var a=n.push;var o=n.slice;var h=n.splice;e.VERSION="1.1.2";e.$=r;e.noConflict=function(){t.Backbone=s;return this};e.emulateHTTP=false;e.emulateJSON=false;var u=e.Events={on:function(t,e,i){if(!c(this,"on",t,[e,i])||!e)return this;this._events||(this._events={});var r=this._events[t]||(this._events[t]=[]);r.push({callback:e,context:i,ctx:i||this});return this},once:function(t,e,r){if(!c(this,"once",t,[e,r])||!e)return this;var s=this;var n=i.once(function(){s.off(t,n);e.apply(this,arguments)});n._callback=e;return this.on(t,n,r)},off:function(t,e,r){var s,n,a,o,h,u,l,f;if(!this._events||!c(this,"off",t,[e,r]))return this;if(!t&&!e&&!r){this._events=void 0;return this}o=t?[t]:i.keys(this._events);for(h=0,u=o.length;h").attr(t);this.setElement(r,false)}else{this.setElement(i.result(this,"el"),false)}}});e.sync=function(t,r,s){var n=T[t];i.defaults(s||(s={}),{emulateHTTP:e.emulateHTTP,emulateJSON:e.emulateJSON});var a={type:n,dataType:"json"};if(!s.url){a.url=i.result(r,"url")||M()}if(s.data==null&&r&&(t==="create"||t==="update"||t==="patch")){a.contentType="application/json";a.data=JSON.stringify(s.attrs||r.toJSON(s))}if(s.emulateJSON){a.contentType="application/x-www-form-urlencoded";a.data=a.data?{model:a.data}:{}}if(s.emulateHTTP&&(n==="PUT"||n==="DELETE"||n==="PATCH")){a.type="POST";if(s.emulateJSON)a.data._method=n;var o=s.beforeSend;s.beforeSend=function(t){t.setRequestHeader("X-HTTP-Method-Override",n);if(o)return o.apply(this,arguments)}}if(a.type!=="GET"&&!s.emulateJSON){a.processData=false}if(a.type==="PATCH"&&k){a.xhr=function(){return new ActiveXObject("Microsoft.XMLHTTP")}}var h=s.xhr=e.ajax(i.extend(a,s));r.trigger("request",r,h,s);return h};var k=typeof window!=="undefined"&&!!window.ActiveXObject&&!(window.XMLHttpRequest&&(new XMLHttpRequest).dispatchEvent);var T={create:"POST",update:"PUT",patch:"PATCH","delete":"DELETE",read:"GET"};e.ajax=function(){return e.$.ajax.apply(e.$,arguments)};var $=e.Router=function(t){t||(t={});if(t.routes)this.routes=t.routes;this._bindRoutes();this.initialize.apply(this,arguments)};var S=/\((.*?)\)/g;var H=/(\(\?)?:\w+/g;var A=/\*\w+/g;var I=/[\-{}\[\]+?.,\\\^$|#\s]/g;i.extend($.prototype,u,{initialize:function(){},route:function(t,r,s){if(!i.isRegExp(t))t=this._routeToRegExp(t);if(i.isFunction(r)){s=r;r=""}if(!s)s=this[r];var n=this;e.history.route(t,function(i){var a=n._extractParameters(t,i);n.execute(s,a);n.trigger.apply(n,["route:"+r].concat(a));n.trigger("route",r,a);e.history.trigger("route",n,r,a)});return this},execute:function(t,e){if(t)t.apply(this,e)},navigate:function(t,i){e.history.navigate(t,i);return this},_bindRoutes:function(){if(!this.routes)return;this.routes=i.result(this,"routes");var t,e=i.keys(this.routes);while((t=e.pop())!=null){this.route(t,this.routes[t])}},_routeToRegExp:function(t){t=t.replace(I,"\\$&").replace(S,"(?:$1)?").replace(H,function(t,e){return e?t:"([^/?]+)"}).replace(A,"([^?]*?)");return new RegExp("^"+t+"(?:\\?([\\s\\S]*))?$")},_extractParameters:function(t,e){var r=t.exec(e).slice(1);return i.map(r,function(t,e){if(e===r.length-1)return t||null;return t?decodeURIComponent(t):null})}});var N=e.History=function(){this.handlers=[];i.bindAll(this,"checkUrl");if(typeof window!=="undefined"){this.location=window.location;this.history=window.history}};var R=/^[#\/]|\s+$/g;var O=/^\/+|\/+$/g;var P=/msie [\w.]+/;var C=/\/$/;var j=/#.*$/;N.started=false;i.extend(N.prototype,u,{interval:50,atRoot:function(){return this.location.pathname.replace(/[^\/]$/,"$&/")===this.root},getHash:function(t){var e=(t||this).location.href.match(/#(.*)$/);return e?e[1]:""},getFragment:function(t,e){if(t==null){if(this._hasPushState||!this._wantsHashChange||e){t=decodeURI(this.location.pathname+this.location.search);var i=this.root.replace(C,"");if(!t.indexOf(i))t=t.slice(i.length)}else{t=this.getHash()}}return t.replace(R,"")},start:function(t){if(N.started)throw new Error("Backbone.history has already been started");N.started=true;this.options=i.extend({root:"/"},this.options,t);this.root=this.options.root;this._wantsHashChange=this.options.hashChange!==false;this._wantsPushState=!!this.options.pushState;this._hasPushState=!!(this.options.pushState&&this.history&&this.history.pushState);var r=this.getFragment();var s=document.documentMode;var n=P.exec(navigator.userAgent.toLowerCase())&&(!s||s<=7);this.root=("/"+this.root+"/").replace(O,"/");if(n&&this._wantsHashChange){var a=e.$('