init

Massimo Melina committed Dec 8, 2021 at 00:17 UTC 054e7d9b05d94a27c75233526cfe0850af2ed5a8
9 files changed +1323
.gitignore new
+2
@@ -0,0 +1,2 @@
1 +node_modules
2 +.idea
\ No newline at end of file
frontend/index.html new
+33
@@ -0,0 +1,33 @@
1 +<!DOCTYPE html>
2 +<html>
3 +<head>
4 + <meta charset="UTF-8" />
5 + <title>HFS 3 front end</title>
6 + <meta name="viewport" content="width=device-width, initial-scale=1">
7 + <link rel="stylesheet" type="text/css" href="/~/frontend/main.css" />
8 +
9 + <!--[if lt IE 9 ]> <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]-->
10 + <script src='/socket.io/socket.io.js'></script>
11 + <script src='/~/jquery-1.11.3.js'></script>
12 + <script src='/~/frontend/main.js'></script>
13 + </head>
14 +<body>
15 +<div id="control-tiles">
16 + <div id='folder'></div>
17 + <div id='folder-info'></div>
18 + <div>
19 + <label>View mode</label>
20 + <select id='mode'><option>tiles<option>list</select>
21 + </div>
22 + <div>
23 + <label>Order</label>
24 + <select id='order'><option value=''>none<option value='label' selected>name<option>type<option>size</select>
25 + </div>
26 + <div>
27 + <label>Pagination</label>
28 + <select id='pagination'><option value=''>none<option>50<option selected>200<option>500</select>
29 + </div>
30 +</div>
31 +<ul id='items'></ul>
32 +</body>
33 +</html>
frontend/main.css new
+54
@@ -0,0 +1,54 @@
1 +body { font:10pt verdana, arial, sans-serif; }
2 +a img { border:0; } /* conform IE */
3 +
4 +#items { list-style:none; padding:0; margin-top:1em; }
5 +#control-tiles { display: inline; }
6 +#control-tiles > div {
7 + display:inline-block;
8 + border-left: 5px solid #bbb;
9 + background-color: #eee;
10 + padding: 0.3em 1em;
11 + margin: 0.1em 0;
12 + color: #777;
13 + line-height: 2em;
14 +}
15 +#folder { font-size:1.6em; font-weight:bold; word-break:break-all; display:block !important; padding-left:0.5em !important; }
16 +#folder img { height:1em; padding: 0 0.1em; }
17 +#folder a { text-decoration:none; }
18 +#folder a:hover { text-decoration:underline; }
19 +
20 +#num-items { min-width:3em; display: inline-block; font-weight:bold; }
21 +
22 +.full-label { position:absolute; padding-right:1em; text-align:left; background-color:#eee; }
23 +
24 +/* tiles */
25 +[mode=tiles] #items li { display:inline-block; } /* without this, the LI has height:0 */
26 +[mode=tiles] #items li.forced-br { display:block; } /* used for easeing the CPU */
27 +[mode=tiles] .item-link { float:left; overflow:hidden; width:8.2em; height:9.1em; /* this 0.1 more ensure the content doesn't go over for very little causing necessary effects */
28 + text-align:center; text-decoration:none;
29 + margin:1px; /* reserve space for the border on hover */
30 +}
31 +[mode=tiles].hover .item-link:hover {
32 + background:#ddd;
33 + border:1px solid #bbb; margin:0; /* replace margin with border */
34 +}
35 +[mode=tiles].hover .item-link:hover + .item-details { display:block; float:left; }
36 +
37 +[mode=tiles] .item-label { display:block; padding:0 0.5em; margin:3px; word-wrap:break-word; }
38 +[mode=tiles] .item-details { display:none; }
39 +[mode=tiles] .item-details-wrapper { position:absolute; background:#ffe; border:1px solid #eec; padding:0.2em 0.4em; }
40 +[mode=tiles] .full-label { max-width:17em; border:1px solid #bbb; padding:0.2em 0.5em; }
41 +
42 +/* list */
43 +[mode=list] li { border-bottom:1px solid #eee; height:1.5em; }
44 +[mode=list] li:nth-of-type(odd) { background:#eee; } /* stripes */
45 +[mode=list] .item-link { clear:left; float:left; text-decoration:none;
46 + width:80%; max-width:30em; height:1.5em; overflow:hidden;
47 + margin-right:1em; /* leave some space to breathe */
48 + white-space:nowrap; /* show as much as you can, even half-words, otherwise it will wrap under */
49 +}
50 +[mode=list] .full-label { white-space:normal; } /* re-enable wrapping */
51 +[mode=list] .item-link img { height:1.5em; vertical-align:middle; float:left; }
52 +[mode=list] .item-label { margin-left:0.5em; margin-right:1em; }
53 +[mode=list] .item-type { display:none; }
54 +[mode=list] .item-size { display:inline; min-width:7em; }
frontend/main.js new
+216
@@ -0,0 +1,216 @@
1 +/**
2 + * @author Massimo Melina <a@rejetto.com>
3 + */
4 +
5 +function loadJS(libs) {
6 + libs = libs.split(',');
7 + for (var i=libs.length; i--;) {
8 + document.write("<script src='/~/"+libs[i]+".js'></script>");
9 + }
10 +}
11 +
12 +loadJS('extending,cs-shared,misc');
13 +
14 +
15 +var socket, currentFolder, listFromServer, currentMode, foldersBefore=1, currentPage= 0;
16 +
17 +// this object will hold all the customizable stuff, that is added in file "tpl.js"
18 +var TPL = function(event) {
19 + var fun = TPL[currentMode+'_'+event] || TPL[event];
20 + if (!fun) return;
21 + var newArgs = [];
22 + for (var i=1,a=arguments,l=a.length; i<l; ++i)
23 + newArgs.push(a[i]);
24 + fun.apply(this, newArgs);
25 +};
26 +
27 +loadJS('frontend/tpl,frontend/vfs');
28 +
29 +// understand the requested folder from the URL
30 +function getURLfolder() {
31 + var sub = location.hash.substr(1);
32 + return sub.startsWith('/') ? sub : location.pathname+sub;
33 +} // getURLfolder
34 +
35 +$(function onJQ(){ // dom ready
36 +
37 + (function speedSetup() {
38 +
39 + function chooseSpeed(q, map, def){
40 + for (var k in map) {
41 + if (q <= k) return map[k];
42 + }
43 + return def;
44 + } // chooseSpeed
45 +
46 + $('#pagination').val( chooseSpeed(benchmark(), {
47 + 5: 500,
48 + 50: 200
49 + }, 50) );
50 + })();
51 +
52 + socket = io.connect(window.location.origin);
53 +
54 + socket.on('connect', function onIO(){ // socket ready
55 + log('connected');
56 +
57 + var saved = JSON.parse(getCookie('settings')) || {};
58 + ['Order','Mode','Pagination'].forEach(function(v){
59 + var lc = v.low();
60 + var update = window['update'+v];
61 + update(saved[lc]); // try to restore last options
62 + // change things at user will
63 + $('#'+lc).change(function(){
64 + update();
65 + redrawItems();
66 + });
67 + });
68 +
69 + loadFolder(getURLfolder(), function onFolder(){ // folder ready
70 +
71 + /* support for the BACK button: when the user clicks the BACK button, the address bar changes going out of
72 + sync with the view. We fix it ASAP. I don't know an event for the address bar, so i'm polling. */
73 + repeat(300, function(){
74 + var shouldBe = getURLfolder();
75 + if (currentFolder != shouldBe) {
76 + loadFolder(shouldBe);
77 + }
78 + });
79 +
80 + }); // don't redraw
81 + });//socket connect
82 +
83 + socket.on('vfs.changed', function(data){
84 + log('vfs.changed',data);
85 + // it would be nicer to update only the changed item, but for now easily reload the whole dir
86 + var folder = data.uri.endsWith('/') ? data.uri : dirname(data.uri);
87 + if (folder === currentFolder) {
88 + loadFolder();
89 + }
90 + });
91 +
92 +});
93 +
94 +// ask the server for the items list of the specified folder, then sort and display
95 +function loadFolder(path /** optional */, cb /** optional */) {
96 + if (path) currentFolder = path;
97 + // breadcrumbs
98 + $('#folder').html(
99 + '<a href="/#"><img src="'+getPicURI('home')+'"/></a>'+
100 + // build pairs text/link
101 + decodeURI(currentFolder).split('/').filter('A').map('["/"+A, "/#"+C.slice(0,B+1).join("/")+"/"]')
102 + // then to html
103 + .map('$("<a>").text(A[0]).attr({href:A[1]})[0].outerHTML').join('')
104 + );
105 +
106 + socket.emit('get list', { path:currentFolder }, function onGetList(reply){
107 + if (showError(reply)) return;
108 + listFromServer = reply; // hold it in a global variable, to not loose it
109 + convertList(reply);
110 + $('#folder-info').html("Items: <span id='num-items'>{0}</span>".x(reply.items.length));
111 + sortItems();
112 + redrawItems();
113 + if (typeof cb == 'function') {
114 + cb();
115 + }
116 + });
117 +} // loadFolder
118 +
119 +function showError(reply) {
120 + if (reply.ok) return false;
121 + if (reply.error) alert('Error: '+reply.error);
122 + return true;
123 +} // showError
124 +
125 +// convert file list format: expands some field-names
126 +function convertList(serverReply) {
127 + if (!serverReply) return;
128 + var a = serverReply.items;
129 + if (!a) return;
130 + for (var i=a.length; i--;) {
131 + var o = a[i]._remapKeys({ n:'label', t:'type', s:'size'});
132 + switch (o.type) {
133 + case undefined: // no type is default type: file
134 + o.type = 'file'; // now continue with the case 'file'
135 + case 'file': // for files, calculate specific type
136 + var t = nameToType(o.label);
137 + if (t) o.type = t;
138 + break;
139 + case 'link':
140 + o.url = o.resource;
141 + break;
142 + }
143 + o.url = o.url || escapeLink(currentFolder+o.label)+(o.type == 'folder' ? '/' : '');
144 + }
145 +} // convertList
146 +
147 +function escapeLink(s) {
148 + //return encodeURI(s)
149 + return s.replace('"','&quot;').replace("'", '&#39;').replace('%','%25')
150 +}
151 +
152 +function updateSettingsCookie(settings) {
153 + var v = getCookie('settings');
154 + try { v = JSON.parse(v) }
155 + catch(e) {}
156 + if (!v || typeof v != 'object') v = {};
157 + v._expand(settings);
158 + setCookie('settings', JSON.stringify(v));
159 +} // updateSettingsCookie
160 +
161 +function updateMode(v){
162 + // if no value is passed, then read it from the DOM, otherwise write it in the DOM
163 + if (!v || !v.length) v = $('#mode').val();
164 + else $('#mode').val(v);
165 +
166 + currentMode = v; // global
167 + updateSettingsCookie({ mode: v }); // remember
168 + $('html').attr('mode', v);
169 +} // updateMode
170 +
171 +function updatePagination(v){
172 + // if no value is passed, then read it from the DOM, otherwise write it in the DOM
173 + if (!v || !v.length) v = $('#pagination').val();
174 + else $('#pagination').val(v);
175 +
176 + currentPagination = v; // global
177 + updateSettingsCookie({ pagination: v }); // remember
178 + redrawItems();
179 +} // updatePagination
180 +
181 +function updateOrder(v) {
182 + // if no value is passed, then read it from the DOM, otherwise write it in the DOM
183 + if (!v || !v.length) v = $('#order').val();
184 + else $('#order').val(v);
185 +
186 + currentOrder = v; // global
187 + updateSettingsCookie({ order: v }); // remember
188 + if (v) {
189 + $('#order option[value=""]').remove(); // after we have sorted the items there's no way to return to the original order, so let's hide this option
190 + }
191 + sortItems();
192 +} // updateOrder
193 +
194 +function sortItems() {
195 + if (!currentOrder || !listFromServer) return; // no job
196 +
197 + listFromServer.items.sort(function cb(a,b,field){
198 + field = field || currentOrder;
199 + if (field != 'type' && foldersBefore) { // if field is 'type', then the folders are always put at the top
200 + var res = -cmp(a['type'] == 'folder', b['type'] == 'folder');
201 + if (res) return res;
202 + }
203 + var va = a[field];
204 + var vb = b[field];
205 + switch (field) {
206 + case 'label':
207 + va=va.low(), vb=vb.low();
208 + break;
209 + case 'type':
210 + if (va == 'folder') va=''; // trick to get folders at the top
211 + if (vb == 'folder') vb='';
212 + break;
213 + }
214 + return cmp(va,vb) || (field=='label' ? 0 : cb(a,b,'label'));
215 + });
216 +} // sortItems
frontend/tpl.js new
+17
@@ -0,0 +1,17 @@
1 +assert(TPL, 'tpl');
2 +
3 +TPL.item =
4 + "<a href=\"{url}\" class='item-link'><img src='{icon-file}' class='item-icon' /><span class='item-label'>{label}</span></a>"
5 + +"<div class='item-details'><div class='item-details-wrapper'>"
6 + +"<div class='item-type'>{type}</div>"
7 + +"<div class='item-size'>{size}</div>"
8 + +"</div></div>";
9 +
10 +TPL.list_onObjectItem = function(item) {
11 + item.size = item.size ? formatBytes(item.size) : 'folder';
12 +};
13 +
14 +TPL.tiles_onObjectItem = function(item) {
15 + item.type = 'Type: '+item.type;
16 + item.size = item.size ? 'Size: '+formatBytes(item.size) : '';
17 +};
frontend/vfs.js new
+118
@@ -0,0 +1,118 @@
1 +$(function(){
2 + $('#items').on({
3 + mouseenter: function(){
4 + if (!$(this).isOverflowed()) return; // is our label clipped?
5 + var lbl = $(this).find('.item-label');
6 + // make some changes so it's hopefully fully visible. We actually just mark it, leaving the real work to your css rules.
7 + lbl.addClass('full-label');
8 + },
9 + mouseleave: function(){
10 + // undo changes made few lines above
11 + var lbl = $(this).find('.full-label');
12 + lbl.removeClass('full-label');
13 + if (lbl.data('remove bg')) {
14 + lbl.css('background-color','');
15 + lbl.removeData('remove bg',null);
16 + }
17 + },
18 + click: itemClickHandler
19 + }, '.item-link');
20 +
21 + /* display:float used by 'tiles' is CPU expensive when we get many items (500+ on a core2duo@2.1).
22 + * To ease this task we periodically set fixed line breaks.
23 + */
24 + var last;
25 + repeat(100, function(){
26 + if (currentMode !== 'tiles') {
27 + last = null;
28 + return;
29 + }
30 + var d = $('#items');
31 + var x = d.children(':first').width();
32 + if (!x) return; // no items
33 + var n = Math.floor((d.width() - 5) / x); // leave a small margin, otherwise the browser decides it is not truly fitting, and you get an undesired wrapping
34 + if ($.support.hover) n--; // we leave some space for popup properties
35 + if (n === last) return;
36 + last = n;
37 + d.children('.forced-br').removeClass('forced-br'); // clean
38 + d.children(':nth-child({0}n+1):not(:first)'.x(n)).addClass('forced-br'); // set new br
39 + });
40 +
41 +
42 +});
43 +
44 +// rebuild the DOM of items
45 +function redrawItems() {
46 + var x = $('#items').empty();
47 +
48 + if (!listFromServer) return;
49 +
50 + // add a link to the parent folder
51 + var cf = currentFolder; // shortcut
52 + if (cf > '/') {
53 + addItem({
54 + label: '&uarr;&uarr;',
55 + url: dirname(cf).includeTrailing('/'),
56 + type: 'folder',
57 + icon: 'folder'
58 + });
59 + }
60 +
61 + var n = listFromServer.items.length;
62 + var pages = Math.max(1, Math.ceil(n/currentPagination));
63 + if (currentPage >= pages) currentPage = pages-1;
64 + var overflow = (currentPagination && currentPagination < n);
65 + var ofs = overflow ? currentPage*currentPagination : 0;
66 + var max = currentPagination ? Math.min(currentPagination, n-ofs) : n;
67 +
68 + $('#paginator').remove();
69 + if (overflow) { // draw a paginator
70 + var d = $("<div id='paginator'>").insertBefore('#items');
71 + d.append("Pages ");
72 + for (var i=0; i<pages; i++) {
73 + $("<button>").text(i+1)
74 + .attr({page:i, disabled:i===currentPage}) // highlight current page (by disabling the button)
75 + .appendTo(d)
76 + .click(function(){
77 + currentPage = +$(this).attr('page');if (it.jquery)
78 + redrawItems();
79 + })
80 + }
81 + }
82 +
83 + for (var a=listFromServer.items, i=0; i<max; ++i) {
84 + var o = a[ofs+i]._clone(); // The item will be manipulated (also inside addItem), and we don't want to make this changes persistent over view modes
85 + o.icon = o.type;
86 + addItem(o);
87 + }
88 +} // redrawItems
89 +
90 +// build the DOM for the single item, applying possible filtering functions
91 +function addItem(it) {
92 + it._expand({'icon-file':getIconURI(it.icon)}); // make this additions before the hook, so it can change these too
93 + TPL('onObjectItem', it); // custom treatment, especially mode-based
94 + $('<li>').append(TPL.item.format(it))
95 + .appendTo('#items');
96 +} // addItem
97 +
98 +// called when an item is clicked
99 +function itemClickHandler(ev) {
100 + var x = $(this);
101 + var h = x.attr('href');
102 + if (h.substr(-1) == '/') {
103 + if (location.pathname != '/') { // reloads the page to have a neater URL
104 + location = '/#'+h.substr(1);
105 + return false;
106 + }
107 +
108 + location.hash = (h.startsWith(location.pathname)) ? h.substr(location.pathname.length) : h;
109 + var loader = $("<img src='/~/pics/loader.gif'>").css(x.find('.item-icon').offset()._expand({position:'absolute'})).appendTo('body');
110 + loadFolder(h, function(){ loader.remove() });
111 + return false;
112 + }
113 + if (!x.attr('target')) {
114 + x.attr('target', 'preview'); // open the file in a new window so the app doesn't stop
115 + }
116 + return true;
117 +} // itemClickHandler
118 +
package-lock.json new
+855
@@ -0,0 +1,855 @@
1 +{
2 + "name": "hfs4",
3 + "lockfileVersion": 2,
4 + "requires": true,
5 + "packages": {
6 + "": {
7 + "dependencies": {
8 + "koa": "^2.13.4",
9 + "koa-static": "^5.0.0"
10 + }
11 + },
12 + "node_modules/accepts": {
13 + "version": "1.3.7",
14 + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
15 + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
16 + "dependencies": {
17 + "mime-types": "~2.1.24",
18 + "negotiator": "0.6.2"
19 + },
20 + "engines": {
21 + "node": ">= 0.6"
22 + }
23 + },
24 + "node_modules/cache-content-type": {
25 + "version": "1.0.1",
26 + "resolved": "https://registry.npmjs.org/cache-content-type/-/cache-content-type-1.0.1.tgz",
27 + "integrity": "sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA==",
28 + "dependencies": {
29 + "mime-types": "^2.1.18",
30 + "ylru": "^1.2.0"
31 + },
32 + "engines": {
33 + "node": ">= 6.0.0"
34 + }
35 + },
36 + "node_modules/co": {
37 + "version": "4.6.0",
38 + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
39 + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
40 + "engines": {
41 + "iojs": ">= 1.0.0",
42 + "node": ">= 0.12.0"
43 + }
44 + },
45 + "node_modules/content-disposition": {
46 + "version": "0.5.3",
47 + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
48 + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
49 + "dependencies": {
50 + "safe-buffer": "5.1.2"
51 + },
52 + "engines": {
53 + "node": ">= 0.6"
54 + }
55 + },
56 + "node_modules/content-type": {
57 + "version": "1.0.4",
58 + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
59 + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
60 + "engines": {
61 + "node": ">= 0.6"
62 + }
63 + },
64 + "node_modules/cookies": {
65 + "version": "0.8.0",
66 + "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.8.0.tgz",
67 + "integrity": "sha512-8aPsApQfebXnuI+537McwYsDtjVxGm8gTIzQI3FDW6t5t/DAhERxtnbEPN/8RX+uZthoz4eCOgloXaE5cYyNow==",
68 + "dependencies": {
69 + "depd": "~2.0.0",
70 + "keygrip": "~1.1.0"
71 + },
72 + "engines": {
73 + "node": ">= 0.8"
74 + }
75 + },
76 + "node_modules/debug": {
77 + "version": "4.3.3",
78 + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
79 + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
80 + "dependencies": {
81 + "ms": "2.1.2"
82 + },
83 + "engines": {
84 + "node": ">=6.0"
85 + },
86 + "peerDependenciesMeta": {
87 + "supports-color": {
88 + "optional": true
89 + }
90 + }
91 + },
92 + "node_modules/deep-equal": {
93 + "version": "1.0.1",
94 + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz",
95 + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU="
96 + },
97 + "node_modules/delegates": {
98 + "version": "1.0.0",
99 + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
100 + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
101 + },
102 + "node_modules/depd": {
103 + "version": "2.0.0",
104 + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
105 + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
106 + "engines": {
107 + "node": ">= 0.8"
108 + }
109 + },
110 + "node_modules/destroy": {
111 + "version": "1.0.4",
112 + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
113 + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
114 + },
115 + "node_modules/ee-first": {
116 + "version": "1.1.1",
117 + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
118 + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
119 + },
120 + "node_modules/encodeurl": {
121 + "version": "1.0.2",
122 + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
123 + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
124 + "engines": {
125 + "node": ">= 0.8"
126 + }
127 + },
128 + "node_modules/escape-html": {
129 + "version": "1.0.3",
130 + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
131 + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
132 + },
133 + "node_modules/fresh": {
134 + "version": "0.5.2",
135 + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
136 + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
137 + "engines": {
138 + "node": ">= 0.6"
139 + }
140 + },
141 + "node_modules/has-symbols": {
142 + "version": "1.0.2",
143 + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
144 + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==",
145 + "engines": {
146 + "node": ">= 0.4"
147 + },
148 + "funding": {
149 + "url": "https://github.com/sponsors/ljharb"
150 + }
151 + },
152 + "node_modules/has-tostringtag": {
153 + "version": "1.0.0",
154 + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
155 + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
156 + "dependencies": {
157 + "has-symbols": "^1.0.2"
158 + },
159 + "engines": {
160 + "node": ">= 0.4"
161 + },
162 + "funding": {
163 + "url": "https://github.com/sponsors/ljharb"
164 + }
165 + },
166 + "node_modules/http-assert": {
167 + "version": "1.5.0",
168 + "resolved": "https://registry.npmjs.org/http-assert/-/http-assert-1.5.0.tgz",
169 + "integrity": "sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w==",
170 + "dependencies": {
171 + "deep-equal": "~1.0.1",
172 + "http-errors": "~1.8.0"
173 + },
174 + "engines": {
175 + "node": ">= 0.8"
176 + }
177 + },
178 + "node_modules/http-errors": {
179 + "version": "1.8.1",
180 + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz",
181 + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==",
182 + "dependencies": {
183 + "depd": "~1.1.2",
184 + "inherits": "2.0.4",
185 + "setprototypeof": "1.2.0",
186 + "statuses": ">= 1.5.0 < 2",
187 + "toidentifier": "1.0.1"
188 + },
189 + "engines": {
190 + "node": ">= 0.6"
191 + }
192 + },
193 + "node_modules/http-errors/node_modules/depd": {
194 + "version": "1.1.2",
195 + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
196 + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
197 + "engines": {
198 + "node": ">= 0.6"
199 + }
200 + },
201 + "node_modules/inherits": {
202 + "version": "2.0.4",
203 + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
204 + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
205 + },
206 + "node_modules/is-generator-function": {
207 + "version": "1.0.10",
208 + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz",
209 + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==",
210 + "dependencies": {
211 + "has-tostringtag": "^1.0.0"
212 + },
213 + "engines": {
214 + "node": ">= 0.4"
215 + },
216 + "funding": {
217 + "url": "https://github.com/sponsors/ljharb"
218 + }
219 + },
220 + "node_modules/keygrip": {
221 + "version": "1.1.0",
222 + "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz",
223 + "integrity": "sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==",
224 + "dependencies": {
225 + "tsscmp": "1.0.6"
226 + },
227 + "engines": {
228 + "node": ">= 0.6"
229 + }
230 + },
231 + "node_modules/koa": {
232 + "version": "2.13.4",
233 + "resolved": "https://registry.npmjs.org/koa/-/koa-2.13.4.tgz",
234 + "integrity": "sha512-43zkIKubNbnrULWlHdN5h1g3SEKXOEzoAlRsHOTFpnlDu8JlAOZSMJBLULusuXRequboiwJcj5vtYXKB3k7+2g==",
235 + "dependencies": {
236 + "accepts": "^1.3.5",
237 + "cache-content-type": "^1.0.0",
238 + "content-disposition": "~0.5.2",
239 + "content-type": "^1.0.4",
240 + "cookies": "~0.8.0",
241 + "debug": "^4.3.2",
242 + "delegates": "^1.0.0",
243 + "depd": "^2.0.0",
244 + "destroy": "^1.0.4",
245 + "encodeurl": "^1.0.2",
246 + "escape-html": "^1.0.3",
247 + "fresh": "~0.5.2",
248 + "http-assert": "^1.3.0",
249 + "http-errors": "^1.6.3",
250 + "is-generator-function": "^1.0.7",
251 + "koa-compose": "^4.1.0",
252 + "koa-convert": "^2.0.0",
253 + "on-finished": "^2.3.0",
254 + "only": "~0.0.2",
255 + "parseurl": "^1.3.2",
256 + "statuses": "^1.5.0",
257 + "type-is": "^1.6.16",
258 + "vary": "^1.1.2"
259 + },
260 + "engines": {
261 + "node": "^4.8.4 || ^6.10.1 || ^7.10.1 || >= 8.1.4"
262 + }
263 + },
264 + "node_modules/koa-compose": {
265 + "version": "4.1.0",
266 + "resolved": "https://registry.npmjs.org/koa-compose/-/koa-compose-4.1.0.tgz",
267 + "integrity": "sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw=="
268 + },
269 + "node_modules/koa-convert": {
270 + "version": "2.0.0",
271 + "resolved": "https://registry.npmjs.org/koa-convert/-/koa-convert-2.0.0.tgz",
272 + "integrity": "sha512-asOvN6bFlSnxewce2e/DK3p4tltyfC4VM7ZwuTuepI7dEQVcvpyFuBcEARu1+Hxg8DIwytce2n7jrZtRlPrARA==",
273 + "dependencies": {
274 + "co": "^4.6.0",
275 + "koa-compose": "^4.1.0"
276 + },
277 + "engines": {
278 + "node": ">= 10"
279 + }
280 + },
281 + "node_modules/koa-send": {
282 + "version": "5.0.1",
283 + "resolved": "https://registry.npmjs.org/koa-send/-/koa-send-5.0.1.tgz",
284 + "integrity": "sha512-tmcyQ/wXXuxpDxyNXv5yNNkdAMdFRqwtegBXUaowiQzUKqJehttS0x2j0eOZDQAyloAth5w6wwBImnFzkUz3pQ==",
285 + "dependencies": {
286 + "debug": "^4.1.1",
287 + "http-errors": "^1.7.3",
288 + "resolve-path": "^1.4.0"
289 + },
290 + "engines": {
291 + "node": ">= 8"
292 + }
293 + },
294 + "node_modules/koa-static": {
295 + "version": "5.0.0",
296 + "resolved": "https://registry.npmjs.org/koa-static/-/koa-static-5.0.0.tgz",
297 + "integrity": "sha512-UqyYyH5YEXaJrf9S8E23GoJFQZXkBVJ9zYYMPGz919MSX1KuvAcycIuS0ci150HCoPf4XQVhQ84Qf8xRPWxFaQ==",
298 + "dependencies": {
299 + "debug": "^3.1.0",
300 + "koa-send": "^5.0.0"
301 + },
302 + "engines": {
303 + "node": ">= 7.6.0"
304 + }
305 + },
306 + "node_modules/koa-static/node_modules/debug": {
307 + "version": "3.2.7",
308 + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
309 + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
310 + "dependencies": {
311 + "ms": "^2.1.1"
312 + }
313 + },
314 + "node_modules/media-typer": {
315 + "version": "0.3.0",
316 + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
317 + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
318 + "engines": {
319 + "node": ">= 0.6"
320 + }
321 + },
322 + "node_modules/mime-db": {
323 + "version": "1.51.0",
324 + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz",
325 + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==",
326 + "engines": {
327 + "node": ">= 0.6"
328 + }
329 + },
330 + "node_modules/mime-types": {
331 + "version": "2.1.34",
332 + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz",
333 + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==",
334 + "dependencies": {
335 + "mime-db": "1.51.0"
336 + },
337 + "engines": {
338 + "node": ">= 0.6"
339 + }
340 + },
341 + "node_modules/ms": {
342 + "version": "2.1.2",
343 + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
344 + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
345 + },
346 + "node_modules/negotiator": {
347 + "version": "0.6.2",
348 + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
349 + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==",
350 + "engines": {
351 + "node": ">= 0.6"
352 + }
353 + },
354 + "node_modules/on-finished": {
355 + "version": "2.3.0",
356 + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
357 + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
358 + "dependencies": {
359 + "ee-first": "1.1.1"
360 + },
361 + "engines": {
362 + "node": ">= 0.8"
363 + }
364 + },
365 + "node_modules/only": {
366 + "version": "0.0.2",
367 + "resolved": "https://registry.npmjs.org/only/-/only-0.0.2.tgz",
368 + "integrity": "sha1-Kv3oTQPlC5qO3EROMGEKcCle37Q="
369 + },
370 + "node_modules/parseurl": {
371 + "version": "1.3.3",
372 + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
373 + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
374 + "engines": {
375 + "node": ">= 0.8"
376 + }
377 + },
378 + "node_modules/path-is-absolute": {
379 + "version": "1.0.1",
380 + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
381 + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
382 + "engines": {
383 + "node": ">=0.10.0"
384 + }
385 + },
386 + "node_modules/resolve-path": {
387 + "version": "1.4.0",
388 + "resolved": "https://registry.npmjs.org/resolve-path/-/resolve-path-1.4.0.tgz",
389 + "integrity": "sha1-xL2p9e+y/OZSR4c6s2u02DT+Fvc=",
390 + "dependencies": {
391 + "http-errors": "~1.6.2",
392 + "path-is-absolute": "1.0.1"
393 + },
394 + "engines": {
395 + "node": ">= 0.8"
396 + }
397 + },
398 + "node_modules/resolve-path/node_modules/depd": {
399 + "version": "1.1.2",
400 + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
401 + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
402 + "engines": {
403 + "node": ">= 0.6"
404 + }
405 + },
406 + "node_modules/resolve-path/node_modules/http-errors": {
407 + "version": "1.6.3",
408 + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
409 + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
410 + "dependencies": {
411 + "depd": "~1.1.2",
412 + "inherits": "2.0.3",
413 + "setprototypeof": "1.1.0",
414 + "statuses": ">= 1.4.0 < 2"
415 + },
416 + "engines": {
417 + "node": ">= 0.6"
418 + }
419 + },
420 + "node_modules/resolve-path/node_modules/inherits": {
421 + "version": "2.0.3",
422 + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
423 + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
424 + },
425 + "node_modules/resolve-path/node_modules/setprototypeof": {
426 + "version": "1.1.0",
427 + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
428 + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ=="
429 + },
430 + "node_modules/safe-buffer": {
431 + "version": "5.1.2",
432 + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
433 + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
434 + },
435 + "node_modules/setprototypeof": {
436 + "version": "1.2.0",
437 + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
438 + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
439 + },
440 + "node_modules/statuses": {
441 + "version": "1.5.0",
442 + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
443 + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
444 + "engines": {
445 + "node": ">= 0.6"
446 + }
447 + },
448 + "node_modules/toidentifier": {
449 + "version": "1.0.1",
450 + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
451 + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
452 + "engines": {
453 + "node": ">=0.6"
454 + }
455 + },
456 + "node_modules/tsscmp": {
457 + "version": "1.0.6",
458 + "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz",
459 + "integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==",
460 + "engines": {
461 + "node": ">=0.6.x"
462 + }
463 + },
464 + "node_modules/type-is": {
465 + "version": "1.6.18",
466 + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
467 + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
468 + "dependencies": {
469 + "media-typer": "0.3.0",
470 + "mime-types": "~2.1.24"
471 + },
472 + "engines": {
473 + "node": ">= 0.6"
474 + }
475 + },
476 + "node_modules/vary": {
477 + "version": "1.1.2",
478 + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
479 + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
480 + "engines": {
481 + "node": ">= 0.8"
482 + }
483 + },
484 + "node_modules/ylru": {
485 + "version": "1.2.1",
486 + "resolved": "https://registry.npmjs.org/ylru/-/ylru-1.2.1.tgz",
487 + "integrity": "sha512-faQrqNMzcPCHGVC2aaOINk13K+aaBDUPjGWl0teOXywElLjyVAB6Oe2jj62jHYtwsU49jXhScYbvPENK+6zAvQ==",
488 + "engines": {
489 + "node": ">= 4.0.0"
490 + }
491 + }
492 + },
493 + "dependencies": {
494 + "accepts": {
495 + "version": "1.3.7",
496 + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
497 + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
498 + "requires": {
499 + "mime-types": "~2.1.24",
500 + "negotiator": "0.6.2"
501 + }
502 + },
503 + "cache-content-type": {
504 + "version": "1.0.1",
505 + "resolved": "https://registry.npmjs.org/cache-content-type/-/cache-content-type-1.0.1.tgz",
506 + "integrity": "sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA==",
507 + "requires": {
508 + "mime-types": "^2.1.18",
509 + "ylru": "^1.2.0"
510 + }
511 + },
512 + "co": {
513 + "version": "4.6.0",
514 + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
515 + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ="
516 + },
517 + "content-disposition": {
518 + "version": "0.5.3",
519 + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
520 + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
521 + "requires": {
522 + "safe-buffer": "5.1.2"
523 + }
524 + },
525 + "content-type": {
526 + "version": "1.0.4",
527 + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
528 + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
529 + },
530 + "cookies": {
531 + "version": "0.8.0",
532 + "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.8.0.tgz",
533 + "integrity": "sha512-8aPsApQfebXnuI+537McwYsDtjVxGm8gTIzQI3FDW6t5t/DAhERxtnbEPN/8RX+uZthoz4eCOgloXaE5cYyNow==",
534 + "requires": {
535 + "depd": "~2.0.0",
536 + "keygrip": "~1.1.0"
537 + }
538 + },
539 + "debug": {
540 + "version": "4.3.3",
541 + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
542 + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
543 + "requires": {
544 + "ms": "2.1.2"
545 + }
546 + },
547 + "deep-equal": {
548 + "version": "1.0.1",
549 + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz",
550 + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU="
551 + },
552 + "delegates": {
553 + "version": "1.0.0",
554 + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
555 + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
556 + },
557 + "depd": {
558 + "version": "2.0.0",
559 + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
560 + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="
561 + },
562 + "destroy": {
563 + "version": "1.0.4",
564 + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
565 + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
566 + },
567 + "ee-first": {
568 + "version": "1.1.1",
569 + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
570 + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
571 + },
572 + "encodeurl": {
573 + "version": "1.0.2",
574 + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
575 + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
576 + },
577 + "escape-html": {
578 + "version": "1.0.3",
579 + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
580 + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
581 + },
582 + "fresh": {
583 + "version": "0.5.2",
584 + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
585 + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
586 + },
587 + "has-symbols": {
588 + "version": "1.0.2",
589 + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
590 + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw=="
591 + },
592 + "has-tostringtag": {
593 + "version": "1.0.0",
594 + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
595 + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
596 + "requires": {
597 + "has-symbols": "^1.0.2"
598 + }
599 + },
600 + "http-assert": {
601 + "version": "1.5.0",
602 + "resolved": "https://registry.npmjs.org/http-assert/-/http-assert-1.5.0.tgz",
603 + "integrity": "sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w==",
604 + "requires": {
605 + "deep-equal": "~1.0.1",
606 + "http-errors": "~1.8.0"
607 + }
608 + },
609 + "http-errors": {
610 + "version": "1.8.1",
611 + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz",
612 + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==",
613 + "requires": {
614 + "depd": "~1.1.2",
615 + "inherits": "2.0.4",
616 + "setprototypeof": "1.2.0",
617 + "statuses": ">= 1.5.0 < 2",
618 + "toidentifier": "1.0.1"
619 + },
620 + "dependencies": {
621 + "depd": {
622 + "version": "1.1.2",
623 + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
624 + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
625 + }
626 + }
627 + },
628 + "inherits": {
629 + "version": "2.0.4",
630 + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
631 + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
632 + },
633 + "is-generator-function": {
634 + "version": "1.0.10",
635 + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz",
636 + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==",
637 + "requires": {
638 + "has-tostringtag": "^1.0.0"
639 + }
640 + },
641 + "keygrip": {
642 + "version": "1.1.0",
643 + "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz",
644 + "integrity": "sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==",
645 + "requires": {
646 + "tsscmp": "1.0.6"
647 + }
648 + },
649 + "koa": {
650 + "version": "2.13.4",
651 + "resolved": "https://registry.npmjs.org/koa/-/koa-2.13.4.tgz",
652 + "integrity": "sha512-43zkIKubNbnrULWlHdN5h1g3SEKXOEzoAlRsHOTFpnlDu8JlAOZSMJBLULusuXRequboiwJcj5vtYXKB3k7+2g==",
653 + "requires": {
654 + "accepts": "^1.3.5",
655 + "cache-content-type": "^1.0.0",
656 + "content-disposition": "~0.5.2",
657 + "content-type": "^1.0.4",
658 + "cookies": "~0.8.0",
659 + "debug": "^4.3.2",
660 + "delegates": "^1.0.0",
661 + "depd": "^2.0.0",
662 + "destroy": "^1.0.4",
663 + "encodeurl": "^1.0.2",
664 + "escape-html": "^1.0.3",
665 + "fresh": "~0.5.2",
666 + "http-assert": "^1.3.0",
667 + "http-errors": "^1.6.3",
668 + "is-generator-function": "^1.0.7",
669 + "koa-compose": "^4.1.0",
670 + "koa-convert": "^2.0.0",
671 + "on-finished": "^2.3.0",
672 + "only": "~0.0.2",
673 + "parseurl": "^1.3.2",
674 + "statuses": "^1.5.0",
675 + "type-is": "^1.6.16",
676 + "vary": "^1.1.2"
677 + }
678 + },
679 + "koa-compose": {
680 + "version": "4.1.0",
681 + "resolved": "https://registry.npmjs.org/koa-compose/-/koa-compose-4.1.0.tgz",
682 + "integrity": "sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw=="
683 + },
684 + "koa-convert": {
685 + "version": "2.0.0",
686 + "resolved": "https://registry.npmjs.org/koa-convert/-/koa-convert-2.0.0.tgz",
687 + "integrity": "sha512-asOvN6bFlSnxewce2e/DK3p4tltyfC4VM7ZwuTuepI7dEQVcvpyFuBcEARu1+Hxg8DIwytce2n7jrZtRlPrARA==",
688 + "requires": {
689 + "co": "^4.6.0",
690 + "koa-compose": "^4.1.0"
691 + }
692 + },
693 + "koa-send": {
694 + "version": "5.0.1",
695 + "resolved": "https://registry.npmjs.org/koa-send/-/koa-send-5.0.1.tgz",
696 + "integrity": "sha512-tmcyQ/wXXuxpDxyNXv5yNNkdAMdFRqwtegBXUaowiQzUKqJehttS0x2j0eOZDQAyloAth5w6wwBImnFzkUz3pQ==",
697 + "requires": {
698 + "debug": "^4.1.1",
699 + "http-errors": "^1.7.3",
700 + "resolve-path": "^1.4.0"
701 + }
702 + },
703 + "koa-static": {
704 + "version": "5.0.0",
705 + "resolved": "https://registry.npmjs.org/koa-static/-/koa-static-5.0.0.tgz",
706 + "integrity": "sha512-UqyYyH5YEXaJrf9S8E23GoJFQZXkBVJ9zYYMPGz919MSX1KuvAcycIuS0ci150HCoPf4XQVhQ84Qf8xRPWxFaQ==",
707 + "requires": {
708 + "debug": "^3.1.0",
709 + "koa-send": "^5.0.0"
710 + },
711 + "dependencies": {
712 + "debug": {
713 + "version": "3.2.7",
714 + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
715 + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
716 + "requires": {
717 + "ms": "^2.1.1"
718 + }
719 + }
720 + }
721 + },
722 + "media-typer": {
723 + "version": "0.3.0",
724 + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
725 + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
726 + },
727 + "mime-db": {
728 + "version": "1.51.0",
729 + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz",
730 + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g=="
731 + },
732 + "mime-types": {
733 + "version": "2.1.34",
734 + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz",
735 + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==",
736 + "requires": {
737 + "mime-db": "1.51.0"
738 + }
739 + },
740 + "ms": {
741 + "version": "2.1.2",
742 + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
743 + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
744 + },
745 + "negotiator": {
746 + "version": "0.6.2",
747 + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
748 + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
749 + },
750 + "on-finished": {
751 + "version": "2.3.0",
752 + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
753 + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
754 + "requires": {
755 + "ee-first": "1.1.1"
756 + }
757 + },
758 + "only": {
759 + "version": "0.0.2",
760 + "resolved": "https://registry.npmjs.org/only/-/only-0.0.2.tgz",
761 + "integrity": "sha1-Kv3oTQPlC5qO3EROMGEKcCle37Q="
762 + },
763 + "parseurl": {
764 + "version": "1.3.3",
765 + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
766 + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
767 + },
768 + "path-is-absolute": {
769 + "version": "1.0.1",
770 + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
771 + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
772 + },
773 + "resolve-path": {
774 + "version": "1.4.0",
775 + "resolved": "https://registry.npmjs.org/resolve-path/-/resolve-path-1.4.0.tgz",
776 + "integrity": "sha1-xL2p9e+y/OZSR4c6s2u02DT+Fvc=",
777 + "requires": {
778 + "http-errors": "~1.6.2",
779 + "path-is-absolute": "1.0.1"
780 + },
781 + "dependencies": {
782 + "depd": {
783 + "version": "1.1.2",
784 + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
785 + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
786 + },
787 + "http-errors": {
788 + "version": "1.6.3",
789 + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
790 + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
791 + "requires": {
792 + "depd": "~1.1.2",
793 + "inherits": "2.0.3",
794 + "setprototypeof": "1.1.0",
795 + "statuses": ">= 1.4.0 < 2"
796 + }
797 + },
798 + "inherits": {
799 + "version": "2.0.3",
800 + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
801 + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
802 + },
803 + "setprototypeof": {
804 + "version": "1.1.0",
805 + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
806 + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ=="
807 + }
808 + }
809 + },
810 + "safe-buffer": {
811 + "version": "5.1.2",
812 + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
813 + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
814 + },
815 + "setprototypeof": {
816 + "version": "1.2.0",
817 + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
818 + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
819 + },
820 + "statuses": {
821 + "version": "1.5.0",
822 + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
823 + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
824 + },
825 + "toidentifier": {
826 + "version": "1.0.1",
827 + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
828 + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="
829 + },
830 + "tsscmp": {
831 + "version": "1.0.6",
832 + "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz",
833 + "integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA=="
834 + },
835 + "type-is": {
836 + "version": "1.6.18",
837 + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
838 + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
839 + "requires": {
840 + "media-typer": "0.3.0",
841 + "mime-types": "~2.1.24"
842 + }
843 + },
844 + "vary": {
845 + "version": "1.1.2",
846 + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
847 + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
848 + },
849 + "ylru": {
850 + "version": "1.2.1",
851 + "resolved": "https://registry.npmjs.org/ylru/-/ylru-1.2.1.tgz",
852 + "integrity": "sha512-faQrqNMzcPCHGVC2aaOINk13K+aaBDUPjGWl0teOXywElLjyVAB6Oe2jj62jHYtwsU49jXhScYbvPENK+6zAvQ=="
853 + }
854 + }
855 +}
package.json new
+9
@@ -0,0 +1,9 @@
1 +{
2 + "scripts": {
3 + "start": "node src"
4 + },
5 + "dependencies": {
6 + "koa": "^2.13.4",
7 + "koa-static": "^5.0.0"
8 + }
9 +}
src/index.js new
+19
@@ -0,0 +1,19 @@
1 +const Koa = require('koa')
2 +const serve = require('koa-static')
3 +const srv = new Koa()
4 +
5 +const frontend = serve('frontend')
6 +srv.use((ctx,next) => {
7 + const rq = ctx.request
8 + if (rq.method === 'GET' && rq.originalUrl === '/c') {
9 + ctx.body = 'ciao'
10 + }
11 + else
12 + return frontend(ctx,next)
13 +})
14 +srv.listen(3000)
15 +console.log('running')
16 +/*
17 +body
18 +set(k,v)
19 +* */
\ No newline at end of file