├── .scrutinizer.yml
├── examples
├── list-files.html
├── list-files - with page.html
├── get-info - example 1.html
├── list-files - in directory.html
├── list-files - with page and results per page.html
├── get-info - example 2.html
├── destroy-files.html
└── schedule-files.html
├── sandcage.min.js
├── README.md
├── json2.min.js
├── sandcage.coffee
├── sandcage.js
├── LICENSE
└── json2.js
/.scrutinizer.yml:
--------------------------------------------------------------------------------
1 | filter:
2 | excluded_paths: ["examples/*", "json2*", "*.min.js", "*.coffee"]
3 | checks:
4 | javascript: true
5 | build: true
--------------------------------------------------------------------------------
/examples/list-files.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | If you have opened this page in a browser, open the console and reload the page for the output.
10 | For the documentation of the List Files service, click Here
11 |
18 |
19 |
--------------------------------------------------------------------------------
/examples/list-files - with page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | If you have opened this page in a browser, open the console and reload the page for the output.
10 | For the documentation of the List Files service, click Here
11 |
20 |
21 |
--------------------------------------------------------------------------------
/examples/get-info - example 1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | If you have opened this page in a browser, open the console and reload the page for the output.
10 | For the documentation of the Get Info service, click Here
11 |
20 |
21 |
--------------------------------------------------------------------------------
/examples/list-files - in directory.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | If you have opened this page in a browser, open the console and reload the page for the output.
10 | For the documentation of the List Files service, click Here
11 |
20 |
21 |
--------------------------------------------------------------------------------
/examples/list-files - with page and results per page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | If you have opened this page in a browser, open the console and reload the page for the output.
10 | For the documentation of the List Files service, click Here
11 |
21 |
22 |
--------------------------------------------------------------------------------
/examples/get-info - example 2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | If you have opened this page in a browser, open the console and reload the page for the output.
10 | For the documentation of the Get Info service, click Here
11 |
23 |
24 |
--------------------------------------------------------------------------------
/examples/destroy-files.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | If you have opened this page in a browser, open the console and reload the page for the output.
10 | For the documentation of the Destroy Files service, click Here
11 |
24 |
25 |
--------------------------------------------------------------------------------
/sandcage.min.js:
--------------------------------------------------------------------------------
1 | var SandCage;SandCage=function(){function e(e){return this.apikey=e,this.apikey?(t=this,("undefined"==typeof JSON||null===JSON)&&this.loadScript("json2.min.js"),this):{status:"error",name:"MissingKey",message:"Provide your SandCage API Key."}}var t={},n="0.2",r="https://api.sandcage.com/"+n+"/";return e.call=function(e,n,r,a){var s,i;if(null==n||n==={})return!1;i={key:t.apikey};for(s in n)i[s]=n[s];return this.ajaxCall(e,i,r,a)},e.ajaxCall=function(e,t,n,a){var s;return n||(t.callback_url=n),t=JSON.stringify(t),s=new XMLHttpRequest,s.open("POST",""+r+e,!1),s.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),s.onreadystatechange=function(){var e;return 4!==s.readyState?!1:(e=JSON.parse(s.responseText),null==e&&(e={status:"error",name:"GenericError",message:"An error occurred."}),a?a(e):!1)},s.send(t)},e.loadScript=function(e){var t;t=new XMLHttpRequest,t.open("GET",e,!1),t.onreadystatechange=function(){var n;4===t.readyState&&200===t.status&&(n=document.createElement("script"),n.setAttribute("type","text/javascript"),n.setAttribute("charset","UTF-8"),n.setAttribute("src",e),document.head.appendChild(n))},t.send(null)},e.getInfo=function(e,t){return null==t?!1:this.call("get-info",e,"",t)},e.listFiles=function(e,t){return null==t?!1:this.call("list-files",e,"",t)},e.scheduleFiles=function(e,t,n){return this.call("schedule-tasks",e,t,n)},e.destroyFiles=function(e,t,n){return this.call("destroy-files",e,t,n)},e}();
--------------------------------------------------------------------------------
/examples/schedule-files.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | If you have opened this page in a browser, open the console and reload the page for the output.
10 | For the documentation of the Schedule Tasks service, click Here
11 |
59 |
60 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | [](https://scrutinizer-ci.com/g/sandcage/sandcage-api-js/?branch=master)
4 | [](https://scrutinizer-ci.com/g/sandcage/sandcage-api-js/build-status/master)
5 |
6 | sandcage-api-js is a JavaScript library for interfacing with SandCage's API. The API documentation can be found at https://www.sandcage.com/docs/0.2/
7 |
8 |
9 | ### Table of Contents
10 | * [Requirements](https://github.com/sandcage/sandcage-api-js/blob/master/README.md#requirements)
11 | * [Usage](https://github.com/sandcage/sandcage-api-js/blob/master/README.md#usage)
12 | * [Examples](https://github.com/sandcage/sandcage-api-js/tree/master/examples)
13 | * [Contributing](https://github.com/sandcage/sandcage-api-js/blob/master/README.md#contribute)
14 | * [Contact Us](https://www.sandcage.com/contact)
15 |
16 |
17 |
18 | ## Requirements
19 |
20 | * A SandCage account, in order to get your SandCage API Key. Once logged into SandCage get your API Key at https://www.sandcage.com/panel/api_key
21 |
22 |
23 |
24 | ## Usage
25 |
26 | ```javascript
27 | var sandcage = SandCage('[YOUR SANDCAGE API KEY]');
28 | sandcage.SandCage.listFiles({}, function(resp) {
29 | console.log(resp);
30 | })
31 | ```
32 |
33 |
34 |
35 | ## Contributing
36 |
37 | We are open to suggestions and code revisions, however there are some rules and limitations that you might want to consider first.
38 |
39 | * Code that you contribute will automatically be licensed under the [Apache License Version 2.0](https://github.com/sandcage/sandcage-api-js/blob/master/LICENSE).
40 | * Third party code will be reviewed, tested and possibly modified before being released.
41 |
42 | These basic rules help ensure that this code remains Open Source and compatible with Apache 2.0 license. All contributions will be added to the changelog and appear in every release.
--------------------------------------------------------------------------------
/json2.min.js:
--------------------------------------------------------------------------------
1 | "object"!=typeof JSON&&(JSON={}),function(){"use strict";function f(t){return 10>t?"0"+t:t}function this_value(){return this.valueOf()}function quote(t){return rx_escapable.lastIndex=0,rx_escapable.test(t)?'"'+t.replace(rx_escapable,function(t){var e=meta[t];return"string"==typeof e?e:"\\u"+("0000"+t.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+t+'"'}function str(t,e){var r,n,o,u,f,a=gap,i=e[t];switch(i&&"object"==typeof i&&"function"==typeof i.toJSON&&(i=i.toJSON(t)),"function"==typeof rep&&(i=rep.call(e,t,i)),typeof i){case"string":return quote(i);case"number":return isFinite(i)?String(i):"null";case"boolean":case"null":return String(i);case"object":if(!i)return"null";if(gap+=indent,f=[],"[object Array]"===Object.prototype.toString.apply(i)){for(u=i.length,r=0;u>r;r+=1)f[r]=str(r,i)||"null";return o=0===f.length?"[]":gap?"[\n"+gap+f.join(",\n"+gap)+"\n"+a+"]":"["+f.join(",")+"]",gap=a,o}if(rep&&"object"==typeof rep)for(u=rep.length,r=0;u>r;r+=1)"string"==typeof rep[r]&&(n=rep[r],o=str(n,i),o&&f.push(quote(n)+(gap?": ":":")+o));else for(n in i)Object.prototype.hasOwnProperty.call(i,n)&&(o=str(n,i),o&&f.push(quote(n)+(gap?": ":":")+o));return o=0===f.length?"{}":gap?"{\n"+gap+f.join(",\n"+gap)+"\n"+a+"}":"{"+f.join(",")+"}",gap=a,o}}var rx_one=/^[\],:{}\s]*$/,rx_two=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,rx_three=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,rx_four=/(?:^|:|,)(?:\s*\[)+/g,rx_escapable=/[\\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,rx_dangerous=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;"function"!=typeof Date.prototype.toJSON&&(Date.prototype.toJSON=function(){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null},Boolean.prototype.toJSON=this_value,Number.prototype.toJSON=this_value,String.prototype.toJSON=this_value);var gap,indent,meta,rep;"function"!=typeof JSON.stringify&&(meta={"\b":"\\b"," ":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},JSON.stringify=function(t,e,r){var n;if(gap="",indent="","number"==typeof r)for(n=0;r>n;n+=1)indent+=" ";else"string"==typeof r&&(indent=r);if(rep=e,e&&"function"!=typeof e&&("object"!=typeof e||"number"!=typeof e.length))throw new Error("JSON.stringify");return str("",{"":t})}),"function"!=typeof JSON.parse&&(JSON.parse=function(text,reviver){function walk(t,e){var r,n,o=t[e];if(o&&"object"==typeof o)for(r in o)Object.prototype.hasOwnProperty.call(o,r)&&(n=walk(o,r),void 0!==n?o[r]=n:delete o[r]);return reviver.call(t,e,o)}var j;if(text=String(text),rx_dangerous.lastIndex=0,rx_dangerous.test(text)&&(text=text.replace(rx_dangerous,function(t){return"\\u"+("0000"+t.charCodeAt(0).toString(16)).slice(-4)})),rx_one.test(text.replace(rx_two,"@").replace(rx_three,"]").replace(rx_four,"")))return j=eval("("+text+")"),"function"==typeof reviver?walk({"":j},""):j;throw new SyntaxError("JSON.parse")})}();
--------------------------------------------------------------------------------
/sandcage.coffee:
--------------------------------------------------------------------------------
1 |
2 | class SandCage
3 | SANDCAGE_API={}
4 | API_VERSION = "0.2"
5 | ENDPOINT_BASE = "https://api.sandcage.com/#{API_VERSION}/"
6 |
7 | constructor: (@apikey) ->
8 | if not @apikey
9 | return {status: 'error', name: 'MissingKey', message: 'Provide your SandCage API Key.'}
10 | SANDCAGE_API = @
11 |
12 | if not JSON? then @loadScript('json2.min.js')
13 | return @
14 |
15 | @call: (service_endpoint, params, callback_endpoint, onresult) ->
16 | if not params? or params is {} then return false
17 | payload = key: SANDCAGE_API.apikey
18 | for key of params
19 | payload[key] = params[key]
20 | @ajaxCall(service_endpoint, payload, callback_endpoint, onresult)
21 |
22 | @ajaxCall: (service_endpoint, payload, callback_endpoint, onresult) ->
23 | ###
24 | global: XMLHttpRequest
25 | ###
26 | if not callback_endpoint then payload.callback_url = callback_endpoint
27 | payload = JSON.stringify(payload)
28 | req = new XMLHttpRequest()
29 | req.open('POST', "#{ENDPOINT_BASE}#{service_endpoint}", false)
30 | req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
31 | req.onreadystatechange = () ->
32 | if req.readyState isnt 4 then return false
33 | res = JSON.parse(req.responseText)
34 | res ?= {status: 'error', name: 'GenericError', message: 'An error occurred.'}
35 | if onresult
36 | onresult(res)
37 | else
38 | return false
39 |
40 | req.send(payload)
41 |
42 | @loadScript = (url) ->
43 | ###
44 | global: XMLHttpRequest
45 | ###
46 | req = new XMLHttpRequest()
47 | req.open 'GET', url, false
48 | req.onreadystatechange = ->
49 | if req.readyState is 4
50 | if req.status is 200
51 | scriptNode = document.createElement('script')
52 | scriptNode.setAttribute 'type', 'text/javascript'
53 | scriptNode.setAttribute 'charset', 'UTF-8'
54 | scriptNode.setAttribute 'src', url
55 | document.head.appendChild scriptNode
56 | return
57 |
58 | req.send null
59 | return
60 |
61 | ###
62 | The "get-info" service
63 | @param {Object} params the hash of the parameters to pass to the request
64 | @param {Function} onresult an optional callback to execute when the API call is made
65 | ###
66 | @getInfo: (params, onresult) ->
67 | if not onresult? then return false
68 | @call('get-info', params, '', onresult)
69 |
70 | ###
71 | The "list-files" service
72 | @param {Object} params the hash of the parameters to pass to the request
73 | @param {Function} onresult an optional callback to execute when the API call is made
74 | ###
75 | @listFiles: (params, onresult) ->
76 | if not onresult? then return false
77 | @call('list-files', params, '', onresult)
78 |
79 | ###
80 | The "schedule-tasks" service
81 | @param {Object} params the hash of the parameters to pass to the request
82 | @param {String} callback_endpoint an optional callback endpoint, to which a request will be sent whenever there is an update for any of the tasks included in this request. See https://www.sandcage.com/docs/0.2/schedule_tasks#callbacks for an example
83 | @param {Function} onresult an optional callback to execute when the API call is made
84 | ###
85 | @scheduleFiles: (params, callback_endpoint, onresult) ->
86 | @call('schedule-tasks', params, callback_endpoint, onresult)
87 |
88 | ###
89 | The "destroy-files" service
90 | @param {Object} params the hash of the parameters to pass to the request
91 | @param {String} callback_endpoint an optional callback endpoint, to which a request will be sent whenever there is an update for any of the tasks included in this request. See https://www.sandcage.com/docs/0.2/destroy_files#callbacks for an example
92 | @param {Function} onresult an optional callback to execute when the API call is made
93 | ###
94 | @destroyFiles: (params, callback_endpoint, onresult) ->
95 | @call('destroy-files', params, callback_endpoint, onresult)
96 |
97 |
--------------------------------------------------------------------------------
/sandcage.js:
--------------------------------------------------------------------------------
1 | var SandCage;
2 |
3 | SandCage = (function() {
4 | var SANDCAGE_API = {};
5 | var API_VERSION = "0.2";
6 | var ENDPOINT_BASE = "https://api.sandcage.com/" + API_VERSION + "/";
7 |
8 | function SandCage(apikey) {
9 | this.apikey = apikey;
10 | if (!this.apikey) {
11 | return {status: 'error', name: 'MissingKey', message: 'Provide your SandCage API Key.'};
12 | }
13 | SANDCAGE_API = this;
14 | if (typeof JSON === "undefined" || JSON === null) {
15 | this.loadScript('json2.min.js');
16 | }
17 | return this;
18 | }
19 |
20 | SandCage.call = function(service_endpoint, params, callback_endpoint, onresult) {
21 | var key, payload;
22 | if ((params == null) || params === {}) {
23 | return false;
24 | }
25 | payload = {
26 | key: SANDCAGE_API.apikey
27 | };
28 | for (key in params) {
29 | payload[key] = params[key];
30 | }
31 | return this.ajaxCall(service_endpoint, payload, callback_endpoint, onresult);
32 | };
33 |
34 | SandCage.ajaxCall = function(service_endpoint, payload, callback_endpoint, onresult) {
35 | /*
36 | global: XMLHttpRequest
37 | */
38 | var req;
39 | if (!callback_endpoint) {
40 | payload.callback_url = callback_endpoint;
41 | }
42 | payload = JSON.stringify(payload);
43 | req = new XMLHttpRequest();
44 | req.open('POST', "" + ENDPOINT_BASE + service_endpoint, false);
45 | req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
46 | req.onreadystatechange = function() {
47 | var res;
48 | if (req.readyState !== 4) {
49 | return false;
50 | }
51 | res = JSON.parse(req.responseText);
52 | if (res == null) {
53 | res = {status: 'error', name: 'GenericError', message: 'An error occurred.'};
54 | }
55 | if (onresult) {
56 | return onresult(res);
57 | } else {
58 | return false;
59 | }
60 | };
61 | return req.send(payload);
62 | };
63 |
64 | SandCage.loadScript = function(url) {
65 | /*
66 | global: XMLHttpRequest
67 | */
68 | var req;
69 | req = new XMLHttpRequest();
70 | req.open('GET', url, false);
71 | req.onreadystatechange = function() {
72 | var scriptNode;
73 | if (req.readyState === 4) {
74 | if (req.status === 200) {
75 | scriptNode = document.createElement('script');
76 | scriptNode.setAttribute('type', 'text/javascript');
77 | scriptNode.setAttribute('charset', 'UTF-8');
78 | scriptNode.setAttribute('src', url);
79 | document.head.appendChild(scriptNode);
80 | }
81 | }
82 | };
83 | req.send(null);
84 | };
85 |
86 | /*
87 | The "get-info" service
88 | @param {Object} params the hash of the parameters to pass to the request
89 | @param {Function} onresult an optional callback to execute when the API call is made
90 | */
91 | SandCage.getInfo = function(params, onresult) {
92 | if (onresult == null) {
93 | return false;
94 | }
95 | return this.call('get-info', params, '', onresult);
96 | };
97 |
98 | /*
99 | The "list-files" service
100 | @param {Object} params the hash of the parameters to pass to the request
101 | @param {Function} onresult an optional callback to execute when the API call is made
102 | */
103 | SandCage.listFiles = function(params, onresult) {
104 | if (onresult == null) {
105 | return false;
106 | }
107 | return this.call('list-files', params, '', onresult);
108 | };
109 |
110 | /*
111 | The "schedule-tasks" service
112 | @param {Object} params the hash of the parameters to pass to the request
113 | @param {String} callback_endpoint an optional callback endpoint, to which a request will be sent whenever there is an update for any of the tasks included in this request. See https://www.sandcage.com/docs/0.2/schedule_tasks#callbacks for an example
114 | @param {Function} onresult an optional callback to execute when the API call is made
115 | */
116 | SandCage.scheduleFiles = function(params, callback_endpoint, onresult) {
117 | return this.call('schedule-tasks', params, callback_endpoint, onresult);
118 | };
119 |
120 | /*
121 | The "destroy-files" service
122 | @param {Object} params the hash of the parameters to pass to the request
123 | @param {String} callback_endpoint an optional callback endpoint, to which a request will be sent whenever there is an update for any of the tasks included in this request. See https://www.sandcage.com/docs/0.2/destroy_files#callbacks for an example
124 | @param {Function} onresult an optional callback to execute when the API call is made
125 | */
126 | SandCage.destroyFiles = function(params, callback_endpoint, onresult) {
127 | return this.call('destroy-files', params, callback_endpoint, onresult);
128 | };
129 |
130 | return SandCage;
131 | })();
132 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/json2.js:
--------------------------------------------------------------------------------
1 | // json2.js
2 | // 2016-05-01
3 | // Public Domain.
4 | // NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
5 | // See http://www.JSON.org/js.html
6 | // This code should be minified before deployment.
7 | // See http://javascript.crockford.com/jsmin.html
8 |
9 | // USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
10 | // NOT CONTROL.
11 |
12 | // This file creates a global JSON object containing two methods: stringify
13 | // and parse. This file is provides the ES5 JSON capability to ES3 systems.
14 | // If a project might run on IE8 or earlier, then this file should be included.
15 | // This file does nothing on ES5 systems.
16 |
17 | // JSON.stringify(value, replacer, space)
18 | // value any JavaScript value, usually an object or array.
19 | // replacer an optional parameter that determines how object
20 | // values are stringified for objects. It can be a
21 | // function or an array of strings.
22 | // space an optional parameter that specifies the indentation
23 | // of nested structures. If it is omitted, the text will
24 | // be packed without extra whitespace. If it is a number,
25 | // it will specify the number of spaces to indent at each
26 | // level. If it is a string (such as "\t" or " "),
27 | // it contains the characters used to indent at each level.
28 | // This method produces a JSON text from a JavaScript value.
29 | // When an object value is found, if the object contains a toJSON
30 | // method, its toJSON method will be called and the result will be
31 | // stringified. A toJSON method does not serialize: it returns the
32 | // value represented by the name/value pair that should be serialized,
33 | // or undefined if nothing should be serialized. The toJSON method
34 | // will be passed the key associated with the value, and this will be
35 | // bound to the value.
36 |
37 | // For example, this would serialize Dates as ISO strings.
38 |
39 | // Date.prototype.toJSON = function (key) {
40 | // function f(n) {
41 | // // Format integers to have at least two digits.
42 | // return (n < 10)
43 | // ? "0" + n
44 | // : n;
45 | // }
46 | // return this.getUTCFullYear() + "-" +
47 | // f(this.getUTCMonth() + 1) + "-" +
48 | // f(this.getUTCDate()) + "T" +
49 | // f(this.getUTCHours()) + ":" +
50 | // f(this.getUTCMinutes()) + ":" +
51 | // f(this.getUTCSeconds()) + "Z";
52 | // };
53 |
54 | // You can provide an optional replacer method. It will be passed the
55 | // key and value of each member, with this bound to the containing
56 | // object. The value that is returned from your method will be
57 | // serialized. If your method returns undefined, then the member will
58 | // be excluded from the serialization.
59 |
60 | // If the replacer parameter is an array of strings, then it will be
61 | // used to select the members to be serialized. It filters the results
62 | // such that only members with keys listed in the replacer array are
63 | // stringified.
64 |
65 | // Values that do not have JSON representations, such as undefined or
66 | // functions, will not be serialized. Such values in objects will be
67 | // dropped; in arrays they will be replaced with null. You can use
68 | // a replacer function to replace those with JSON values.
69 |
70 | // JSON.stringify(undefined) returns undefined.
71 |
72 | // The optional space parameter produces a stringification of the
73 | // value that is filled with line breaks and indentation to make it
74 | // easier to read.
75 |
76 | // If the space parameter is a non-empty string, then that string will
77 | // be used for indentation. If the space parameter is a number, then
78 | // the indentation will be that many spaces.
79 |
80 | // Example:
81 |
82 | // text = JSON.stringify(["e", {pluribus: "unum"}]);
83 | // // text is '["e",{"pluribus":"unum"}]'
84 |
85 | // text = JSON.stringify(["e", {pluribus: "unum"}], null, "\t");
86 | // // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
87 |
88 | // text = JSON.stringify([new Date()], function (key, value) {
89 | // return this[key] instanceof Date
90 | // ? "Date(" + this[key] + ")"
91 | // : value;
92 | // });
93 | // // text is '["Date(---current time---)"]'
94 |
95 | // JSON.parse(text, reviver)
96 | // This method parses a JSON text to produce an object or array.
97 | // It can throw a SyntaxError exception.
98 |
99 | // The optional reviver parameter is a function that can filter and
100 | // transform the results. It receives each of the keys and values,
101 | // and its return value is used instead of the original value.
102 | // If it returns what it received, then the structure is not modified.
103 | // If it returns undefined then the member is deleted.
104 |
105 | // Example:
106 |
107 | // // Parse the text. Values that look like ISO date strings will
108 | // // be converted to Date objects.
109 |
110 | // myData = JSON.parse(text, function (key, value) {
111 | // var a;
112 | // if (typeof value === "string") {
113 | // a =
114 | // /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
115 | // if (a) {
116 | // return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
117 | // +a[5], +a[6]));
118 | // }
119 | // }
120 | // return value;
121 | // });
122 |
123 | // myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
124 | // var d;
125 | // if (typeof value === "string" &&
126 | // value.slice(0, 5) === "Date(" &&
127 | // value.slice(-1) === ")") {
128 | // d = new Date(value.slice(5, -1));
129 | // if (d) {
130 | // return d;
131 | // }
132 | // }
133 | // return value;
134 | // });
135 |
136 | // This is a reference implementation. You are free to copy, modify, or
137 | // redistribute.
138 |
139 | /*jslint
140 | eval, for, this
141 | */
142 |
143 | /*property
144 | JSON, apply, call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
145 | getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
146 | lastIndex, length, parse, prototype, push, replace, slice, stringify,
147 | test, toJSON, toString, valueOf
148 | */
149 |
150 |
151 | // Create a JSON object only if one does not already exist. We create the
152 | // methods in a closure to avoid creating global variables.
153 |
154 | if (typeof JSON !== "object") {
155 | JSON = {};
156 | }
157 |
158 | (function () {
159 | "use strict";
160 |
161 | var rx_one = /^[\],:{}\s]*$/;
162 | var rx_two = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g;
163 | var rx_three = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
164 | var rx_four = /(?:^|:|,)(?:\s*\[)+/g;
165 | var rx_escapable = /[\\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
166 | var rx_dangerous = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
167 |
168 | function f(n) {
169 | // Format integers to have at least two digits.
170 | return n < 10
171 | ? "0" + n
172 | : n;
173 | }
174 |
175 | function this_value() {
176 | return this.valueOf();
177 | }
178 |
179 | if (typeof Date.prototype.toJSON !== "function") {
180 |
181 | Date.prototype.toJSON = function () {
182 |
183 | return isFinite(this.valueOf())
184 | ? this.getUTCFullYear() + "-" +
185 | f(this.getUTCMonth() + 1) + "-" +
186 | f(this.getUTCDate()) + "T" +
187 | f(this.getUTCHours()) + ":" +
188 | f(this.getUTCMinutes()) + ":" +
189 | f(this.getUTCSeconds()) + "Z"
190 | : null;
191 | };
192 |
193 | Boolean.prototype.toJSON = this_value;
194 | Number.prototype.toJSON = this_value;
195 | String.prototype.toJSON = this_value;
196 | }
197 |
198 | var gap;
199 | var indent;
200 | var meta;
201 | var rep;
202 |
203 |
204 | function quote(string) {
205 |
206 | // If the string contains no control characters, no quote characters, and no
207 | // backslash characters, then we can safely slap some quotes around it.
208 | // Otherwise we must also replace the offending characters with safe escape
209 | // sequences.
210 |
211 | rx_escapable.lastIndex = 0;
212 | return rx_escapable.test(string)
213 | ? "\"" + string.replace(rx_escapable, function (a) {
214 | var c = meta[a];
215 | return typeof c === "string"
216 | ? c
217 | : "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice(-4);
218 | }) + "\""
219 | : "\"" + string + "\"";
220 | }
221 |
222 |
223 | function str(key, holder) {
224 |
225 | // Produce a string from holder[key].
226 |
227 | var i; // The loop counter.
228 | var k; // The member key.
229 | var v; // The member value.
230 | var length;
231 | var mind = gap;
232 | var partial;
233 | var value = holder[key];
234 |
235 | // If the value has a toJSON method, call it to obtain a replacement value.
236 |
237 | if (value && typeof value === "object" &&
238 | typeof value.toJSON === "function") {
239 | value = value.toJSON(key);
240 | }
241 |
242 | // If we were called with a replacer function, then call the replacer to
243 | // obtain a replacement value.
244 |
245 | if (typeof rep === "function") {
246 | value = rep.call(holder, key, value);
247 | }
248 |
249 | // What happens next depends on the value's type.
250 |
251 | switch (typeof value) {
252 | case "string":
253 | return quote(value);
254 |
255 | case "number":
256 |
257 | // JSON numbers must be finite. Encode non-finite numbers as null.
258 |
259 | return isFinite(value)
260 | ? String(value)
261 | : "null";
262 |
263 | case "boolean":
264 | case "null":
265 |
266 | // If the value is a boolean or null, convert it to a string. Note:
267 | // typeof null does not produce "null". The case is included here in
268 | // the remote chance that this gets fixed someday.
269 |
270 | return String(value);
271 |
272 | // If the type is "object", we might be dealing with an object or an array or
273 | // null.
274 |
275 | case "object":
276 |
277 | // Due to a specification blunder in ECMAScript, typeof null is "object",
278 | // so watch out for that case.
279 |
280 | if (!value) {
281 | return "null";
282 | }
283 |
284 | // Make an array to hold the partial results of stringifying this object value.
285 |
286 | gap += indent;
287 | partial = [];
288 |
289 | // Is the value an array?
290 |
291 | if (Object.prototype.toString.apply(value) === "[object Array]") {
292 |
293 | // The value is an array. Stringify every element. Use null as a placeholder
294 | // for non-JSON values.
295 |
296 | length = value.length;
297 | for (i = 0; i < length; i += 1) {
298 | partial[i] = str(i, value) || "null";
299 | }
300 |
301 | // Join all of the elements together, separated with commas, and wrap them in
302 | // brackets.
303 |
304 | v = partial.length === 0
305 | ? "[]"
306 | : gap
307 | ? "[\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "]"
308 | : "[" + partial.join(",") + "]";
309 | gap = mind;
310 | return v;
311 | }
312 |
313 | // If the replacer is an array, use it to select the members to be stringified.
314 |
315 | if (rep && typeof rep === "object") {
316 | length = rep.length;
317 | for (i = 0; i < length; i += 1) {
318 | if (typeof rep[i] === "string") {
319 | k = rep[i];
320 | v = str(k, value);
321 | if (v) {
322 | partial.push(quote(k) + (
323 | gap
324 | ? ": "
325 | : ":"
326 | ) + v);
327 | }
328 | }
329 | }
330 | } else {
331 |
332 | // Otherwise, iterate through all of the keys in the object.
333 |
334 | for (k in value) {
335 | if (Object.prototype.hasOwnProperty.call(value, k)) {
336 | v = str(k, value);
337 | if (v) {
338 | partial.push(quote(k) + (
339 | gap
340 | ? ": "
341 | : ":"
342 | ) + v);
343 | }
344 | }
345 | }
346 | }
347 |
348 | // Join all of the member texts together, separated with commas,
349 | // and wrap them in braces.
350 |
351 | v = partial.length === 0
352 | ? "{}"
353 | : gap
354 | ? "{\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "}"
355 | : "{" + partial.join(",") + "}";
356 | gap = mind;
357 | return v;
358 | }
359 | }
360 |
361 | // If the JSON object does not yet have a stringify method, give it one.
362 |
363 | if (typeof JSON.stringify !== "function") {
364 | meta = { // table of character substitutions
365 | "\b": "\\b",
366 | "\t": "\\t",
367 | "\n": "\\n",
368 | "\f": "\\f",
369 | "\r": "\\r",
370 | "\"": "\\\"",
371 | "\\": "\\\\"
372 | };
373 | JSON.stringify = function (value, replacer, space) {
374 |
375 | // The stringify method takes a value and an optional replacer, and an optional
376 | // space parameter, and returns a JSON text. The replacer can be a function
377 | // that can replace values, or an array of strings that will select the keys.
378 | // A default replacer method can be provided. Use of the space parameter can
379 | // produce text that is more easily readable.
380 |
381 | var i;
382 | gap = "";
383 | indent = "";
384 |
385 | // If the space parameter is a number, make an indent string containing that
386 | // many spaces.
387 |
388 | if (typeof space === "number") {
389 | for (i = 0; i < space; i += 1) {
390 | indent += " ";
391 | }
392 |
393 | // If the space parameter is a string, it will be used as the indent string.
394 |
395 | } else if (typeof space === "string") {
396 | indent = space;
397 | }
398 |
399 | // If there is a replacer, it must be a function or an array.
400 | // Otherwise, throw an error.
401 |
402 | rep = replacer;
403 | if (replacer && typeof replacer !== "function" &&
404 | (typeof replacer !== "object" ||
405 | typeof replacer.length !== "number")) {
406 | throw new Error("JSON.stringify");
407 | }
408 |
409 | // Make a fake root object containing our value under the key of "".
410 | // Return the result of stringifying the value.
411 |
412 | return str("", {"": value});
413 | };
414 | }
415 |
416 |
417 | // If the JSON object does not yet have a parse method, give it one.
418 |
419 | if (typeof JSON.parse !== "function") {
420 | JSON.parse = function (text, reviver) {
421 |
422 | // The parse method takes a text and an optional reviver function, and returns
423 | // a JavaScript value if the text is a valid JSON text.
424 |
425 | var j;
426 |
427 | function walk(holder, key) {
428 |
429 | // The walk method is used to recursively walk the resulting structure so
430 | // that modifications can be made.
431 |
432 | var k;
433 | var v;
434 | var value = holder[key];
435 | if (value && typeof value === "object") {
436 | for (k in value) {
437 | if (Object.prototype.hasOwnProperty.call(value, k)) {
438 | v = walk(value, k);
439 | if (v !== undefined) {
440 | value[k] = v;
441 | } else {
442 | delete value[k];
443 | }
444 | }
445 | }
446 | }
447 | return reviver.call(holder, key, value);
448 | }
449 |
450 |
451 | // Parsing happens in four stages. In the first stage, we replace certain
452 | // Unicode characters with escape sequences. JavaScript handles many characters
453 | // incorrectly, either silently deleting them, or treating them as line endings.
454 |
455 | text = String(text);
456 | rx_dangerous.lastIndex = 0;
457 | if (rx_dangerous.test(text)) {
458 | text = text.replace(rx_dangerous, function (a) {
459 | return "\\u" +
460 | ("0000" + a.charCodeAt(0).toString(16)).slice(-4);
461 | });
462 | }
463 |
464 | // In the second stage, we run the text against regular expressions that look
465 | // for non-JSON patterns. We are especially concerned with "()" and "new"
466 | // because they can cause invocation, and "=" because it can cause mutation.
467 | // But just to be safe, we want to reject all unexpected forms.
468 |
469 | // We split the second stage into 4 regexp operations in order to work around
470 | // crippling inefficiencies in IE's and Safari's regexp engines. First we
471 | // replace the JSON backslash pairs with "@" (a non-JSON character). Second, we
472 | // replace all simple value tokens with "]" characters. Third, we delete all
473 | // open brackets that follow a colon or comma or that begin the text. Finally,
474 | // we look to see that the remaining characters are only whitespace or "]" or
475 | // "," or ":" or "{" or "}". If that is so, then the text is safe for eval.
476 |
477 | if (
478 | rx_one.test(
479 | text
480 | .replace(rx_two, "@")
481 | .replace(rx_three, "]")
482 | .replace(rx_four, "")
483 | )
484 | ) {
485 |
486 | // In the third stage we use the eval function to compile the text into a
487 | // JavaScript structure. The "{" operator is subject to a syntactic ambiguity
488 | // in JavaScript: it can begin a block or an object literal. We wrap the text
489 | // in parens to eliminate the ambiguity.
490 |
491 | j = eval("(" + text + ")");
492 |
493 | // In the optional fourth stage, we recursively walk the new structure, passing
494 | // each name/value pair to a reviver function for possible transformation.
495 |
496 | return (typeof reviver === "function")
497 | ? walk({"": j}, "")
498 | : j;
499 | }
500 |
501 | // If the text is not JSON parseable, then a SyntaxError is thrown.
502 |
503 | throw new SyntaxError("JSON.parse");
504 | };
505 | }
506 | }());
507 |
--------------------------------------------------------------------------------