From 6cf8f4c8ca693f196038c5b8910e9c2aefc79ba4 Mon Sep 17 00:00:00 2001 From: Corne Oppelaar Date: Tue, 5 Apr 2016 02:19:21 +0200 Subject: [PATCH] [wip] --- bin/clean-all | 7 + bin/create-ca | 16 ++ bin/create-crl | 4 + bin/create-csr | 7 + bin/create-invite.php | 14 +- bin/dev-server | 4 + bin/revoke-cert | 3 + bin/setup | 15 ++ bin/sign-client-csr | 6 + bin/sign-server-csr | 6 + config/app.yml | 3 +- config/routes.yml | 4 +- config/schema.xml | 19 +- etc/openssl.conf | 44 ++++ etc/openssl.conf.twig | 45 ++++ public/js/FileSaver.min.js | 2 + public/js/jszip.min.js | 14 ++ public/js/main.js | 27 ++- src/Handler/Main.php | 21 ++ src/Handler/Panel/Certificates/Download.php | 37 ++++ .../Panel/Certificates/_New/Action.php | 85 +++++++ src/Handler/Session.php | 27 +++ src/Model/Base/Certificate.php | 208 +++++++++++++++--- src/Model/Base/CertificateQuery.php | 124 +++++++++-- src/Model/Base/User.php | 54 ++--- src/Model/Base/UserQuery.php | 38 ++-- src/Model/Map/CertificateTableMap.php | 52 +++-- src/Model/Map/UserTableMap.php | 28 +-- src/Service/CA.php | 73 ++++++ views/base.html.twig | 2 +- views/panel.html.twig | 7 +- views/panel/certificates/new.html.twig | 36 +-- 32 files changed, 862 insertions(+), 170 deletions(-) create mode 100755 bin/clean-all create mode 100755 bin/create-ca create mode 100755 bin/create-crl create mode 100755 bin/create-csr create mode 100755 bin/dev-server create mode 100755 bin/revoke-cert create mode 100755 bin/setup create mode 100755 bin/sign-client-csr create mode 100755 bin/sign-server-csr create mode 100644 etc/openssl.conf create mode 100644 etc/openssl.conf.twig create mode 100644 public/js/FileSaver.min.js create mode 100644 public/js/jszip.min.js create mode 100644 src/Handler/Panel/Certificates/Download.php create mode 100644 src/Handler/Panel/Certificates/_New/Action.php create mode 100644 src/Service/CA.php diff --git a/bin/clean-all b/bin/clean-all new file mode 100755 index 0000000..4bb6a7b --- /dev/null +++ b/bin/clean-all @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +BINDIR=$(dirname $(realpath $0)); +BASEDIR=$(realpath "$BINDIR/../"); +cd $BASEDIR; +rm -rf ./storage/ca/*; +mkdir ./storage/ca/certs; +touch ./storage/ca/{,certs/}.gitkeep; diff --git a/bin/create-ca b/bin/create-ca new file mode 100755 index 0000000..aeb10bc --- /dev/null +++ b/bin/create-ca @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +BASEDIR=$(realpath $(dirname $0)); +KEYDIR=$(realpath "$BASEDIR/../storage/ca/"); + +if [ -f $KEYDIR/ca.key ]; then + echo "CA key already exists. not overwriting it." + exit 1; +fi + +CN="ob.ae-cn"; + +if [ ! -z "$1" ]; then + CN=$1; +fi; + +openssl req -days 3650 -nodes -new -x509 -keyout $KEYDIR/ca.key -out $KEYDIR/ca.crt -subj "/CN=$CN" -extensions ca_ext -config "$BASEDIR/../etc/openssl.conf"; diff --git a/bin/create-crl b/bin/create-crl new file mode 100755 index 0000000..34997ab --- /dev/null +++ b/bin/create-crl @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +DIR=$(dirname $(realpath $0)); +openssl ca -config "$DIR/../etc/openssl.conf" -gencrl -keyfile "$DIR/../storage/ca/ca.key" -cert "$DIR/../storage/ca/ca.crt" -out "$DIR/../storage/ca/crl.pem"; +openssl crl -inform PEM -in "$DIR/../storage/ca/crl.pem" -outform DER -out "$DIR/../storage/ca/crl.der"; diff --git a/bin/create-csr b/bin/create-csr new file mode 100755 index 0000000..c1a342c --- /dev/null +++ b/bin/create-csr @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +if [ -z "$3" ]; then + echo "Usage: $0 [commonname] [csr path] [key path]"; + exit 1; +fi + +openssl req -sha256 -keyout $3 -nodes -newkey rsa:2048 -out $2 -subj "/CN=$1" diff --git a/bin/create-invite.php b/bin/create-invite.php index 81be1c3..b93811b 100644 --- a/bin/create-invite.php +++ b/bin/create-invite.php @@ -1,14 +1,12 @@ +#!/usr/bin/env php boot($baseDir); -$newInvite = new \Eater\Glim\Model\Invite(); -$newInvite->setInvite(md5(rand(0, PHP_INT_MAX))); -$newInvite->save(); +$config = new Config(); +$controller = new Controller($config); -echo $newInvite->getInvite() . "\n"; \ No newline at end of file +echo $controller->createInvite() . "\n"; diff --git a/bin/dev-server b/bin/dev-server new file mode 100755 index 0000000..93ae251 --- /dev/null +++ b/bin/dev-server @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +DIR=$(dirname $0); +cd $DIR/../public; +php -S 0:8888; diff --git a/bin/revoke-cert b/bin/revoke-cert new file mode 100755 index 0000000..f432157 --- /dev/null +++ b/bin/revoke-cert @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +DIR=$(dirname $(realpath $0)); +openssl ca -config "$DIR/../etc/openssl.conf" -revoke "$1"; diff --git a/bin/setup b/bin/setup new file mode 100755 index 0000000..a48d0d7 --- /dev/null +++ b/bin/setup @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +BASEDIR="$(dirname $(realpath $0))/../"; +cd $BASEDIR; +STORAGE=$(realpath "$BASEDIR/storage/ca"); + +mkdir -p $STORAGE; +mkdir -p $STORAGE/certs; + +echo 01 > $STORAGE/serial; +echo 01 > $STORAGE/crl_serial; +touch $STORAGE/database; +touch $STORAGE/database.attr; + +$BASEDIR/bin/create-ca $1; +$BASEDIR/bin/create-crl; diff --git a/bin/sign-client-csr b/bin/sign-client-csr new file mode 100755 index 0000000..a95328d --- /dev/null +++ b/bin/sign-client-csr @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +DIR=$(dirname $(realpath $0)); +CSR=$(realpath $1); +CRT=$(realpath $2); +cd $DIR/../; +openssl ca -in $CSR -out $CRT -config $DIR/../etc/openssl.conf -md sha256 -days 3650 -extensions client_ext -batch -notext; diff --git a/bin/sign-server-csr b/bin/sign-server-csr new file mode 100755 index 0000000..3961ad9 --- /dev/null +++ b/bin/sign-server-csr @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +DIR=$(dirname $(realpath $0)); +CSR=$(realpath $1); +CRT=$(realpath $2); +cd $DIR/../; +openssl ca -in $CSR -out $CRT -config $DIR/../etc/openssl.conf -md sha256 -days 3650 -extensions server_ext; \ No newline at end of file diff --git a/config/app.yml b/config/app.yml index 9831de1..d219fc1 100644 --- a/config/app.yml +++ b/config/app.yml @@ -11,4 +11,5 @@ core: user: Eater\Glim\Service\User session: Eater\Glim\Service\Session twig: Eater\Glim\Service\Twig - twig-vars: Eater\Glim\Service\TwigVars \ No newline at end of file + twig-vars: Eater\Glim\Service\TwigVars + ca: Eater\Glim\Service\CA \ No newline at end of file diff --git a/config/routes.yml b/config/routes.yml index d47c5b8..0b0efb1 100644 --- a/config/routes.yml +++ b/config/routes.yml @@ -12,4 +12,6 @@ routes: get: Panel /certificates: /new: - get: Panel\Certificates\_New\Show \ No newline at end of file + get: Panel\Certificates\_New\Show + post: Panel\Certificates\_New\Action + /download/{name}: Panel\Certificates\Download \ No newline at end of file diff --git a/config/schema.xml b/config/schema.xml index a74e792..f83df77 100644 --- a/config/schema.xml +++ b/config/schema.xml @@ -5,7 +5,7 @@ > - + @@ -17,17 +17,28 @@
- + + + - + + + + + + + + + + - +
diff --git a/etc/openssl.conf b/etc/openssl.conf new file mode 100644 index 0000000..4d8191d --- /dev/null +++ b/etc/openssl.conf @@ -0,0 +1,44 @@ +distinguished_name = req_distinguished_name +[ca] +default_ca=ca_default +[req_distinguished_name] +[v3_req] +[v3_ca] +[ca_default] +crl_extensions=crl_ext +private_key=storage/ca/ca.key +certificate=storage/ca/ca.crt +new_certs_dir=storage/ca/certs/ +database=storage/ca/database +default_md=sha256 +policy=policy_only_commonname +serial=storage/ca/serial +crlnumber=storage/ca/crl_serial +default_crl_days=1 +[policy_only_commonname] +countryName = optional +stateOrProvinceName = optional +localityName = optional +organizationName = optional +organizationalUnitName = optional +commonName = supplied +emailAddress = optional +[req] +x509_extensions = client_ext +[server_ext] +basicConstraints = CA:FALSE +subjectKeyIdentifier=hash +authorityKeyIdentifier = keyid,issuer:always +extendedKeyUsage = serverAuth +keyUsage = digitalSignature,keyEncipherment +crlDistributionPoints = URI:http://0b.ae/crl +[client_ext] +subjectKeyIdentifier=hash +basicConstraints = CA:FALSE +crlDistributionPoints = URI:http://localhost:8888/crl +[ca_ext] +basicConstraints = CA:TRUE +subjectKeyIdentifier=hash +crlDistributionPoints = URI:http://localhost:8888/crl +[crl_ext] +authorityKeyIdentifier=keyid:always diff --git a/etc/openssl.conf.twig b/etc/openssl.conf.twig new file mode 100644 index 0000000..8b7117e --- /dev/null +++ b/etc/openssl.conf.twig @@ -0,0 +1,45 @@ +distinguished_name = req_distinguished_name +[ca] +default_ca=ca_default +[req_distinguished_name] +[v3_req] +[v3_ca] +[ca_default] +crl_extensions=crl_ext +unique_subject=no +private_key=storage/ca.key +certificate=storage/ca.crt +new_certs_dir=storage/certs/ +database=storage/database +default_md=sha256 +policy=policy_only_commonname +serial=storage/serial +crlnumber=storage/crl_serial +default_crl_days=1 +[policy_only_commonname] +countryName = optional +stateOrProvinceName = optional +localityName = optional +organizationName = optional +organizationalUnitName = optional +commonName = supplied +emailAddress = optional +[req] +x509_extensions = client_ext +[server_ext] +basicConstraints = CA:FALSE +subjectKeyIdentifier=hash +authorityKeyIdentifier = keyid,issuer:always +extendedKeyUsage = serverAuth +keyUsage = digitalSignature,keyEncipherment +crlDistributionPoints = URI:http://{{ hostname }}/crl +[client_ext] +subjectKeyIdentifier=hash +basicConstraints = CA:FALSE +crlDistributionPoints = URI:http://{{ hostname }}/crl +[ca_ext] +basicConstraints = CA:TRUE +subjectKeyIdentifier=hash +crlDistributionPoints = URI:http://{{ hostname }}/crl +[crl_ext] +authorityKeyIdentifier=keyid:always diff --git a/public/js/FileSaver.min.js b/public/js/FileSaver.min.js new file mode 100644 index 0000000..6268ec9 --- /dev/null +++ b/public/js/FileSaver.min.js @@ -0,0 +1,2 @@ +/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */ +var saveAs=saveAs||function(e){"use strict";if("undefined"==typeof navigator||!/MSIE [1-9]\./.test(navigator.userAgent)){var t=e.document,n=function(){return e.URL||e.webkitURL||e},o=t.createElementNS("http://www.w3.org/1999/xhtml","a"),r="download"in o,i=function(e){var t=new MouseEvent("click");e.dispatchEvent(t)},a=/Version\/[\d\.]+.*Safari/.test(navigator.userAgent),c=e.webkitRequestFileSystem,f=e.requestFileSystem||c||e.mozRequestFileSystem,u=function(t){(e.setImmediate||e.setTimeout)(function(){throw t},0)},d="application/octet-stream",s=0,l=4e4,v=function(e){var t=function(){"string"==typeof e?n().revokeObjectURL(e):e.remove()};setTimeout(t,l)},p=function(e,t,n){t=[].concat(t);for(var o=t.length;o--;){var r=e["on"+t[o]];if("function"==typeof r)try{r.call(e,n||e)}catch(i){u(i)}}},w=function(e){return/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(e.type)?new Blob(["\ufeff",e],{type:e.type}):e},y=function(t,u,l){l||(t=w(t));var y,m,S,h=this,R=t.type,O=!1,g=function(){p(h,"writestart progress write writeend".split(" "))},b=function(){if(m&&a&&"undefined"!=typeof FileReader){var o=new FileReader;return o.onloadend=function(){var e=o.result;m.location.href="data:attachment/file"+e.slice(e.search(/[,;]/)),h.readyState=h.DONE,g()},o.readAsDataURL(t),void(h.readyState=h.INIT)}if((O||!y)&&(y=n().createObjectURL(t)),m)m.location.href=y;else{var r=e.open(y,"_blank");void 0===r&&a&&(e.location.href=y)}h.readyState=h.DONE,g(),v(y)},E=function(e){return function(){return h.readyState!==h.DONE?e.apply(this,arguments):void 0}},N={create:!0,exclusive:!1};return h.readyState=h.INIT,u||(u="download"),r?(y=n().createObjectURL(t),void setTimeout(function(){o.href=y,o.download=u,i(o),g(),v(y),h.readyState=h.DONE})):(e.chrome&&R&&R!==d&&(S=t.slice||t.webkitSlice,t=S.call(t,0,t.size,d),O=!0),c&&"download"!==u&&(u+=".download"),(R===d||c)&&(m=e),f?(s+=t.size,void f(e.TEMPORARY,s,E(function(e){e.root.getDirectory("saved",N,E(function(e){var n=function(){e.getFile(u,N,E(function(e){e.createWriter(E(function(n){n.onwriteend=function(t){m.location.href=e.toURL(),h.readyState=h.DONE,p(h,"writeend",t),v(e)},n.onerror=function(){var e=n.error;e.code!==e.ABORT_ERR&&b()},"writestart progress write abort".split(" ").forEach(function(e){n["on"+e]=h["on"+e]}),n.write(t),h.abort=function(){n.abort(),h.readyState=h.DONE},h.readyState=h.WRITING}),b)}),b)};e.getFile(u,{create:!1},E(function(e){e.remove(),n()}),E(function(e){e.code===e.NOT_FOUND_ERR?n():b()}))}),b)}),b)):void b())},m=y.prototype,S=function(e,t,n){return new y(e,t,n)};return"undefined"!=typeof navigator&&navigator.msSaveOrOpenBlob?function(e,t,n){return n||(e=w(e)),navigator.msSaveOrOpenBlob(e,t||"download")}:(m.abort=function(){var e=this;e.readyState=e.DONE,p(e,"abort")},m.readyState=m.INIT=0,m.WRITING=1,m.DONE=2,m.error=m.onwritestart=m.onprogress=m.onwrite=m.onabort=m.onerror=m.onwriteend=null,S)}}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||this.content);"undefined"!=typeof module&&module.exports?module.exports.saveAs=saveAs:"undefined"!=typeof define&&null!==define&&null!==define.amd&&define([],function(){return saveAs}); \ No newline at end of file diff --git a/public/js/jszip.min.js b/public/js/jszip.min.js new file mode 100644 index 0000000..3b36cd8 --- /dev/null +++ b/public/js/jszip.min.js @@ -0,0 +1,14 @@ +/*! + +JSZip - A Javascript class for generating and reading zip files + + +(c) 2009-2014 Stuart Knightley +Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip/master/LICENSE.markdown. + +JSZip uses the library pako released under the MIT license : +https://github.com/nodeca/pako/blob/master/LICENSE +*/ +!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,b.JSZip=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g=0;--f)if(this.data[f]===b&&this.data[f+1]===c&&this.data[f+2]===d&&this.data[f+3]===e)return f-this.zero;return-1},d.prototype.readData=function(a){if(this.checkOffset(a),0===a)return[];var b=this.data.slice(this.zero+this.index,this.zero+this.index+a);return this.index+=a,b},b.exports=d},{"./dataReader":6}],2:[function(a,b,c){"use strict";var d="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";c.encode=function(a,b){for(var c,e,f,g,h,i,j,k="",l=0;l>2,h=(3&c)<<4|e>>4,i=(15&e)<<2|f>>6,j=63&f,isNaN(e)?i=j=64:isNaN(f)&&(j=64),k=k+d.charAt(g)+d.charAt(h)+d.charAt(i)+d.charAt(j);return k},c.decode=function(a,b){var c,e,f,g,h,i,j,k="",l=0;for(a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");l>4,e=(15&h)<<4|i>>2,f=(3&i)<<6|j,k+=String.fromCharCode(c),64!=i&&(k+=String.fromCharCode(e)),64!=j&&(k+=String.fromCharCode(f));return k}},{}],3:[function(a,b,c){"use strict";function d(){this.compressedSize=0,this.uncompressedSize=0,this.crc32=0,this.compressionMethod=null,this.compressedContent=null}d.prototype={getContent:function(){return null},getCompressedContent:function(){return null}},b.exports=d},{}],4:[function(a,b,c){"use strict";c.STORE={magic:"\x00\x00",compress:function(a,b){return a},uncompress:function(a){return a},compressInputType:null,uncompressInputType:null},c.DEFLATE=a("./flate")},{"./flate":9}],5:[function(a,b,c){"use strict";var d=a("./utils"),e=[0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918e3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117];b.exports=function(a,b){if("undefined"==typeof a||!a.length)return 0;var c="string"!==d.getTypeOf(a);"undefined"==typeof b&&(b=0);var f=0,g=0,h=0;b=-1^b;for(var i=0,j=a.length;j>i;i++)h=c?a[i]:a.charCodeAt(i),g=255&(b^h),f=e[g],b=b>>>8^f;return-1^b}},{"./utils":22}],6:[function(a,b,c){"use strict";function d(a){this.data=null,this.length=0,this.index=0,this.zero=0}var e=a("./utils");d.prototype={checkOffset:function(a){this.checkIndex(this.index+a)},checkIndex:function(a){if(this.lengtha)throw new Error("End of data reached (data length = "+this.length+", asked index = "+a+"). Corrupted zip ?")},setIndex:function(a){this.checkIndex(a),this.index=a},skip:function(a){this.setIndex(this.index+a)},byteAt:function(a){},readInt:function(a){var b,c=0;for(this.checkOffset(a),b=this.index+a-1;b>=this.index;b--)c=(c<<8)+this.byteAt(b);return this.index+=a,c},readString:function(a){return e.transformTo("string",this.readData(a))},readData:function(a){},lastIndexOfSignature:function(a){},readDate:function(){var a=this.readInt(4);return new Date((a>>25&127)+1980,(a>>21&15)-1,a>>16&31,a>>11&31,a>>5&63,(31&a)<<1)}},b.exports=d},{"./utils":22}],7:[function(a,b,c){"use strict";c.base64=!1,c.binary=!1,c.dir=!1,c.createFolders=!1,c.date=null,c.compression=null,c.compressionOptions=null,c.comment=null,c.unixPermissions=null,c.dosPermissions=null},{}],8:[function(a,b,c){"use strict";var d=a("./utils");c.string2binary=function(a){return d.string2binary(a)},c.string2Uint8Array=function(a){return d.transformTo("uint8array",a)},c.uint8Array2String=function(a){return d.transformTo("string",a)},c.string2Blob=function(a){var b=d.transformTo("arraybuffer",a);return d.arrayBuffer2Blob(b)},c.arrayBuffer2Blob=function(a){return d.arrayBuffer2Blob(a)},c.transformTo=function(a,b){return d.transformTo(a,b)},c.getTypeOf=function(a){return d.getTypeOf(a)},c.checkSupport=function(a){return d.checkSupport(a)},c.MAX_VALUE_16BITS=d.MAX_VALUE_16BITS,c.MAX_VALUE_32BITS=d.MAX_VALUE_32BITS,c.pretty=function(a){return d.pretty(a)},c.findCompression=function(a){return d.findCompression(a)},c.isRegExp=function(a){return d.isRegExp(a)}},{"./utils":22}],9:[function(a,b,c){"use strict";var d="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Uint32Array,e=a("pako");c.uncompressInputType=d?"uint8array":"array",c.compressInputType=d?"uint8array":"array",c.magic="\b\x00",c.compress=function(a,b){return e.deflateRaw(a,{level:b.level||-1})},c.uncompress=function(a){return e.inflateRaw(a)}},{pako:25}],10:[function(a,b,c){"use strict";function d(a,b){return this instanceof d?(this.files={},this.comment=null,this.root="",a&&this.load(a,b),void(this.clone=function(){var a=new d;for(var b in this)"function"!=typeof this[b]&&(a[b]=this[b]);return a})):new d(a,b)}var e=a("./base64");d.prototype=a("./object"),d.prototype.load=a("./load"),d.support=a("./support"),d.defaults=a("./defaults"),d.utils=a("./deprecatedPublicUtils"),d.base64={encode:function(a){return e.encode(a)},decode:function(a){return e.decode(a)}},d.compressions=a("./compressions"),b.exports=d},{"./base64":2,"./compressions":4,"./defaults":7,"./deprecatedPublicUtils":8,"./load":11,"./object":14,"./support":18}],11:[function(a,b,c){"use strict";var d=a("./base64"),e=a("./utf8"),f=a("./utils"),g=a("./zipEntries");b.exports=function(a,b){var c,h,i,j;for(b=f.extend(b||{},{base64:!1,checkCRC32:!1,optimizedBinaryString:!1,createFolders:!1,decodeFileName:e.utf8decode}),b.base64&&(a=d.decode(a)),h=new g(a,b),c=h.files,i=0;ic;c++)d+=String.fromCharCode(255&a),a>>>=8;return d},u=function(a){return a=a||{},a.base64!==!0||null!==a.binary&&void 0!==a.binary||(a.binary=!0),a=e.extend(a,h),a.date=a.date||new Date,null!==a.compression&&(a.compression=a.compression.toUpperCase()),a},v=function(a,b,c){var d,f=e.getTypeOf(b);if(c=u(c),"string"==typeof c.unixPermissions&&(c.unixPermissions=parseInt(c.unixPermissions,8)),c.unixPermissions&&16384&c.unixPermissions&&(c.dir=!0),c.dosPermissions&&16&c.dosPermissions&&(c.dir=!0),c.dir&&(a=x(a)),c.createFolders&&(d=w(a))&&y.call(this,d,!0),c.dir||null===b||"undefined"==typeof b)c.base64=!1,c.binary=!1,b=null,f=null;else if("string"===f)c.binary&&!c.base64&&c.optimizedBinaryString!==!0&&(b=e.string2binary(b));else{if(c.base64=!1,c.binary=!0,!(f||b instanceof k))throw new Error("The data of '"+a+"' is in an unsupported format !");"arraybuffer"===f&&(b=e.transformTo("uint8array",b))}var g=new s(a,b,c);return this.files[a]=g,g},w=function(a){"/"==a.slice(-1)&&(a=a.substring(0,a.length-1));var b=a.lastIndexOf("/");return b>0?a.substring(0,b):""},x=function(a){return"/"!=a.slice(-1)&&(a+="/"),a},y=function(a,b){return b="undefined"!=typeof b?b:!1,a=x(a),this.files[a]||v.call(this,a,null,{dir:!0,createFolders:b}),this.files[a]},z=function(a,b,c){var d,g=new k;return a._data instanceof k?(g.uncompressedSize=a._data.uncompressedSize,g.crc32=a._data.crc32,0===g.uncompressedSize||a.dir?(b=j.STORE,g.compressedContent="",g.crc32=0):a._data.compressionMethod===b.magic?g.compressedContent=a._data.getCompressedContent():(d=a._data.getContent(),g.compressedContent=b.compress(e.transformTo(b.compressInputType,d),c))):(d=q(a),d&&0!==d.length&&!a.dir||(b=j.STORE,d=""),g.uncompressedSize=d.length,g.crc32=f(d),g.compressedContent=b.compress(e.transformTo(b.compressInputType,d),c)),g.compressedSize=g.compressedContent.length,g.compressionMethod=b.magic,g},A=function(a,b){var c=a;return a||(c=b?16893:33204),(65535&c)<<16},B=function(a,b){return 63&(a||0)},C=function(a,b,c,d,h,i){var j,k,l,n,o=(c.compressedContent,i!==m.utf8encode),p=e.transformTo("string",i(b.name)),q=e.transformTo("string",m.utf8encode(b.name)),r=b.comment||"",s=e.transformTo("string",i(r)),u=e.transformTo("string",m.utf8encode(r)),v=q.length!==b.name.length,w=u.length!==r.length,x=b.options,y="",z="",C="";l=b._initialMetadata.dir!==b.dir?b.dir:x.dir,n=b._initialMetadata.date!==b.date?b.date:x.date;var D=0,E=0;l&&(D|=16),"UNIX"===h?(E=798,D|=A(b.unixPermissions,l)):(E=20,D|=B(b.dosPermissions,l)),j=n.getHours(),j<<=6,j|=n.getMinutes(),j<<=5,j|=n.getSeconds()/2,k=n.getFullYear()-1980,k<<=4,k|=n.getMonth()+1,k<<=5,k|=n.getDate(),v&&(z=t(1,1)+t(f(p),4)+q,y+="up"+t(z.length,2)+z),w&&(C=t(1,1)+t(this.crc32(s),4)+u,y+="uc"+t(C.length,2)+C);var F="";F+="\n\x00",F+=o||!v&&!w?"\x00\x00":"\x00\b",F+=c.compressionMethod,F+=t(j,2),F+=t(k,2),F+=t(c.crc32,4),F+=t(c.compressedSize,4),F+=t(c.uncompressedSize,4),F+=t(p.length,2),F+=t(y.length,2);var G=g.LOCAL_FILE_HEADER+F+p+y,H=g.CENTRAL_FILE_HEADER+t(E,2)+F+t(s.length,2)+"\x00\x00\x00\x00"+t(D,4)+t(d,4)+p+y+s;return{fileRecord:G,dirRecord:H,compressedObject:c}},D={load:function(a,b){throw new Error("Load method is not defined. Is the file jszip-load.js included ?")},filter:function(a){var b,c,d,f,g=[];for(b in this.files)this.files.hasOwnProperty(b)&&(d=this.files[b],f=new s(d.name,d._data,e.extend(d.options)),c=b.slice(this.root.length,b.length),b.slice(0,this.root.length)===this.root&&a(c,f)&&g.push(f));return g},file:function(a,b,c){if(1===arguments.length){if(e.isRegExp(a)){var d=a;return this.filter(function(a,b){return!b.dir&&d.test(a)})}return this.filter(function(b,c){return!c.dir&&b===a})[0]||null}return a=this.root+a,v.call(this,a,b,c),this},folder:function(a){if(!a)return this;if(e.isRegExp(a))return this.filter(function(b,c){return c.dir&&a.test(b)});var b=this.root+a,c=y.call(this,b),d=this.clone();return d.root=c.name,d},remove:function(a){a=this.root+a;var b=this.files[a];if(b||("/"!=a.slice(-1)&&(a+="/"),b=this.files[a]),b&&!b.dir)delete this.files[a];else for(var c=this.filter(function(b,c){return c.name.slice(0,a.length)===a}),d=0;dh;h++)g[h]=h>=252?6:h>=248?5:h>=240?4:h>=224?3:h>=192?2:1;g[254]=g[254]=1;var i=function(a){var b,c,d,f,g,h=a.length,i=0;for(f=0;h>f;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),i+=128>c?1:2048>c?2:65536>c?3:4;for(b=e.uint8array?new Uint8Array(i):new Array(i),g=0,f=0;i>g;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),128>c?b[g++]=c:2048>c?(b[g++]=192|c>>>6,b[g++]=128|63&c):65536>c?(b[g++]=224|c>>>12,b[g++]=128|c>>>6&63,b[g++]=128|63&c):(b[g++]=240|c>>>18,b[g++]=128|c>>>12&63,b[g++]=128|c>>>6&63,b[g++]=128|63&c);return b},j=function(a,b){var c;for(b=b||a.length,b>a.length&&(b=a.length),c=b-1;c>=0&&128===(192&a[c]);)c--;return 0>c?b:0===c?b:c+g[a[c]]>b?c:b},k=function(a){var b,c,e,f,h=a.length,i=new Array(2*h);for(c=0,b=0;h>b;)if(e=a[b++],128>e)i[c++]=e;else if(f=g[e],f>4)i[c++]=65533,b+=f-1;else{for(e&=2===f?31:3===f?15:7;f>1&&h>b;)e=e<<6|63&a[b++],f--;f>1?i[c++]=65533:65536>e?i[c++]=e:(e-=65536,i[c++]=55296|e>>10&1023,i[c++]=56320|1023&e)}return i.length!==c&&(i.subarray?i=i.subarray(0,c):i.length=c),d.applyFromCharCode(i)};c.utf8encode=function(a){return e.nodebuffer?f(a,"utf-8"):i(a)},c.utf8decode=function(a){if(e.nodebuffer)return d.transformTo("nodebuffer",a).toString("utf-8");a=d.transformTo(e.uint8array?"uint8array":"array",a);for(var b=[],c=0,f=a.length,g=65536;f>c;){var h=j(a,Math.min(c+g,f));e.uint8array?b.push(k(a.subarray(c,h))):b.push(k(a.slice(c,h))),c=h}return b.join("")}},{"./nodeBuffer":12,"./support":18,"./utils":22}],22:[function(a,b,c){"use strict";function d(a){return a}function e(a,b){for(var c=0;cg&&b>1;)try{"array"===f||"nodebuffer"===f?d.push(String.fromCharCode.apply(null,a.slice(g,Math.min(g+b,e)))):d.push(String.fromCharCode.apply(null,a.subarray(g,Math.min(g+b,e)))),g+=b}catch(i){b=Math.floor(b/2)}return d.join("")}function g(a,b){for(var c=0;cb?"0":"")+b.toString(16).toUpperCase();return d},c.findCompression=function(a){for(var b in i)if(i.hasOwnProperty(b)&&i[b].magic===a)return i[b];return null},c.isRegExp=function(a){return"[object RegExp]"===Object.prototype.toString.call(a)},c.extend=function(){var a,b,c={};for(a=0;ae;)a=this.reader.readInt(2),b=this.reader.readInt(4),c=this.reader.readString(b),this.zip64ExtensibleData[a]={id:a,length:b,value:c}},readBlockZip64EndOfCentralLocator:function(){if(this.diskWithZip64CentralDirStart=this.reader.readInt(4),this.relativeOffsetEndOfZip64CentralDir=this.reader.readInt(8),this.disksCount=this.reader.readInt(4),this.disksCount>1)throw new Error("Multi-volumes zip are not supported")},readLocalFiles:function(){var a,b;for(a=0;aa){var b=!this.isSignature(0,j.LOCAL_FILE_HEADER);throw b?new Error("Can't find end of central directory : is this a zip file ? If it is, see http://stuk.github.io/jszip/documentation/howto/read_zip.html"):new Error("Corrupted zip : can't find end of central directory")}this.reader.setIndex(a);var c=a;if(this.checkSignature(j.CENTRAL_DIRECTORY_END),this.readBlockEndOfCentral(),this.diskNumber===i.MAX_VALUE_16BITS||this.diskWithCentralDirStart===i.MAX_VALUE_16BITS||this.centralDirRecordsOnThisDisk===i.MAX_VALUE_16BITS||this.centralDirRecords===i.MAX_VALUE_16BITS||this.centralDirSize===i.MAX_VALUE_32BITS||this.centralDirOffset===i.MAX_VALUE_32BITS){if(this.zip64=!0,a=this.reader.lastIndexOfSignature(j.ZIP64_CENTRAL_DIRECTORY_LOCATOR),0>a)throw new Error("Corrupted zip : can't find the ZIP64 end of central directory locator");if(this.reader.setIndex(a),this.checkSignature(j.ZIP64_CENTRAL_DIRECTORY_LOCATOR),this.readBlockZip64EndOfCentralLocator(),!this.isSignature(this.relativeOffsetEndOfZip64CentralDir,j.ZIP64_CENTRAL_DIRECTORY_END)&&(this.relativeOffsetEndOfZip64CentralDir=this.reader.lastIndexOfSignature(j.ZIP64_CENTRAL_DIRECTORY_END),this.relativeOffsetEndOfZip64CentralDir<0))throw new Error("Corrupted zip : can't find the ZIP64 end of central directory");this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir),this.checkSignature(j.ZIP64_CENTRAL_DIRECTORY_END),this.readBlockZip64EndOfCentral()}var d=this.centralDirOffset+this.centralDirSize;this.zip64&&(d+=20,d+=12+this.zip64EndOfCentralSize);var e=c-d;if(e>0)this.isSignature(c,j.CENTRAL_FILE_HEADER)||(this.reader.zero=e);else if(0>e)throw new Error("Corrupted zip: missing "+Math.abs(e)+" bytes.")},prepareReader:function(a){var b=i.getTypeOf(a);if(i.checkSupport(b),"string"!==b||l.uint8array)if("nodebuffer"===b)this.reader=new f(a);else if(l.uint8array)this.reader=new g(i.transformTo("uint8array",a));else{if(!l.array)throw new Error("Unexpected error: unsupported type '"+b+"'");this.reader=new h(i.transformTo("array",a))}else this.reader=new e(a,this.loadOptions.optimizedBinaryString)},load:function(a){this.prepareReader(a),this.readEndOfCentral(),this.readCentralDir(),this.readLocalFiles()}},b.exports=d},{"./arrayReader":1,"./nodeBufferReader":13,"./object":14,"./signature":15,"./stringReader":16,"./support":18,"./uint8ArrayReader":19,"./utils":22,"./zipEntry":24}],24:[function(a,b,c){"use strict";function d(a,b){this.options=a,this.loadOptions=b}var e=a("./stringReader"),f=a("./utils"),g=a("./compressedObject"),h=a("./object"),i=a("./support"),j=0,k=3;d.prototype={isEncrypted:function(){return 1===(1&this.bitFlag)},useUTF8:function(){return 2048===(2048&this.bitFlag)},prepareCompressedContent:function(a,b,c){return function(){var d=a.index;a.setIndex(b);var e=a.readData(c);return a.setIndex(d),e}},prepareContent:function(a,b,c,d,e){return function(){var a=f.transformTo(d.uncompressInputType,this.getCompressedContent()),b=d.uncompress(a);if(b.length!==e)throw new Error("Bug : uncompressed data size mismatch");return b}},readLocalPart:function(a){var b,c;if(a.skip(22),this.fileNameLength=a.readInt(2),c=a.readInt(2),this.fileName=a.readData(this.fileNameLength),a.skip(c),-1==this.compressedSize||-1==this.uncompressedSize)throw new Error("Bug or corrupted zip : didn't get enough informations from the central directory (compressedSize == -1 || uncompressedSize == -1)");if(b=f.findCompression(this.compressionMethod),null===b)throw new Error("Corrupted zip : compression "+f.pretty(this.compressionMethod)+" unknown (inner file : "+f.transformTo("string",this.fileName)+")");if(this.decompressed=new g,this.decompressed.compressedSize=this.compressedSize,this.decompressed.uncompressedSize=this.uncompressedSize,this.decompressed.crc32=this.crc32,this.decompressed.compressionMethod=this.compressionMethod,this.decompressed.getCompressedContent=this.prepareCompressedContent(a,a.index,this.compressedSize,b),this.decompressed.getContent=this.prepareContent(a,a.index,this.compressedSize,b,this.uncompressedSize),this.loadOptions.checkCRC32&&(this.decompressed=f.transformTo("string",this.decompressed.getContent()), +h.crc32(this.decompressed)!==this.crc32))throw new Error("Corrupted zip : CRC32 mismatch")},readCentralPart:function(a){if(this.versionMadeBy=a.readInt(2),this.versionNeeded=a.readInt(2),this.bitFlag=a.readInt(2),this.compressionMethod=a.readString(2),this.date=a.readDate(),this.crc32=a.readInt(4),this.compressedSize=a.readInt(4),this.uncompressedSize=a.readInt(4),this.fileNameLength=a.readInt(2),this.extraFieldsLength=a.readInt(2),this.fileCommentLength=a.readInt(2),this.diskNumberStart=a.readInt(2),this.internalFileAttributes=a.readInt(2),this.externalFileAttributes=a.readInt(4),this.localHeaderOffset=a.readInt(4),this.isEncrypted())throw new Error("Encrypted zip are not supported");this.fileName=a.readData(this.fileNameLength),this.readExtraFields(a),this.parseZIP64ExtraField(a),this.fileComment=a.readData(this.fileCommentLength)},processAttributes:function(){this.unixPermissions=null,this.dosPermissions=null;var a=this.versionMadeBy>>8;this.dir=!!(16&this.externalFileAttributes),a===j&&(this.dosPermissions=63&this.externalFileAttributes),a===k&&(this.unixPermissions=this.externalFileAttributes>>16&65535),this.dir||"/"!==this.fileNameStr.slice(-1)||(this.dir=!0)},parseZIP64ExtraField:function(a){if(this.extraFields[1]){var b=new e(this.extraFields[1].value);this.uncompressedSize===f.MAX_VALUE_32BITS&&(this.uncompressedSize=b.readInt(8)),this.compressedSize===f.MAX_VALUE_32BITS&&(this.compressedSize=b.readInt(8)),this.localHeaderOffset===f.MAX_VALUE_32BITS&&(this.localHeaderOffset=b.readInt(8)),this.diskNumberStart===f.MAX_VALUE_32BITS&&(this.diskNumberStart=b.readInt(4))}},readExtraFields:function(a){var b,c,d,e=a.index;for(this.extraFields=this.extraFields||{};a.index0?b.windowBits=-b.windowBits:b.gzip&&b.windowBits>0&&b.windowBits<16&&(b.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new l,this.strm.avail_out=0;var c=h.deflateInit2(this.strm,b.level,b.method,b.windowBits,b.memLevel,b.strategy);if(c!==p)throw new Error(k[c]);b.header&&h.deflateSetHeader(this.strm,b.header)}function e(a,b){var c=new d(b);if(c.push(a,!0),c.err)throw c.msg;return c.result}function f(a,b){return b=b||{},b.raw=!0,e(a,b)}function g(a,b){return b=b||{},b.gzip=!0,e(a,b)}var h=a("./zlib/deflate"),i=a("./utils/common"),j=a("./utils/strings"),k=a("./zlib/messages"),l=a("./zlib/zstream"),m=Object.prototype.toString,n=0,o=4,p=0,q=1,r=2,s=-1,t=0,u=8;d.prototype.push=function(a,b){var c,d,e=this.strm,f=this.options.chunkSize;if(this.ended)return!1;d=b===~~b?b:b===!0?o:n,"string"==typeof a?e.input=j.string2buf(a):"[object ArrayBuffer]"===m.call(a)?e.input=new Uint8Array(a):e.input=a,e.next_in=0,e.avail_in=e.input.length;do{if(0===e.avail_out&&(e.output=new i.Buf8(f),e.next_out=0,e.avail_out=f),c=h.deflate(e,d),c!==q&&c!==p)return this.onEnd(c),this.ended=!0,!1;0!==e.avail_out&&(0!==e.avail_in||d!==o&&d!==r)||("string"===this.options.to?this.onData(j.buf2binstring(i.shrinkBuf(e.output,e.next_out))):this.onData(i.shrinkBuf(e.output,e.next_out)))}while((e.avail_in>0||0===e.avail_out)&&c!==q);return d===o?(c=h.deflateEnd(this.strm),this.onEnd(c),this.ended=!0,c===p):d===r?(this.onEnd(p),e.avail_out=0,!0):!0},d.prototype.onData=function(a){this.chunks.push(a)},d.prototype.onEnd=function(a){a===p&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=i.flattenChunks(this.chunks)),this.chunks=[],this.err=a,this.msg=this.strm.msg},c.Deflate=d,c.deflate=e,c.deflateRaw=f,c.gzip=g},{"./utils/common":28,"./utils/strings":29,"./zlib/deflate":33,"./zlib/messages":38,"./zlib/zstream":40}],27:[function(a,b,c){"use strict";function d(a){if(!(this instanceof d))return new d(a);this.options=h.assign({chunkSize:16384,windowBits:0,to:""},a||{});var b=this.options;b.raw&&b.windowBits>=0&&b.windowBits<16&&(b.windowBits=-b.windowBits,0===b.windowBits&&(b.windowBits=-15)),!(b.windowBits>=0&&b.windowBits<16)||a&&a.windowBits||(b.windowBits+=32),b.windowBits>15&&b.windowBits<48&&0===(15&b.windowBits)&&(b.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new l,this.strm.avail_out=0;var c=g.inflateInit2(this.strm,b.windowBits);if(c!==j.Z_OK)throw new Error(k[c]);this.header=new m,g.inflateGetHeader(this.strm,this.header)}function e(a,b){var c=new d(b);if(c.push(a,!0),c.err)throw c.msg;return c.result}function f(a,b){return b=b||{},b.raw=!0,e(a,b)}var g=a("./zlib/inflate"),h=a("./utils/common"),i=a("./utils/strings"),j=a("./zlib/constants"),k=a("./zlib/messages"),l=a("./zlib/zstream"),m=a("./zlib/gzheader"),n=Object.prototype.toString;d.prototype.push=function(a,b){var c,d,e,f,k,l=this.strm,m=this.options.chunkSize,o=!1;if(this.ended)return!1;d=b===~~b?b:b===!0?j.Z_FINISH:j.Z_NO_FLUSH,"string"==typeof a?l.input=i.binstring2buf(a):"[object ArrayBuffer]"===n.call(a)?l.input=new Uint8Array(a):l.input=a,l.next_in=0,l.avail_in=l.input.length;do{if(0===l.avail_out&&(l.output=new h.Buf8(m),l.next_out=0,l.avail_out=m),c=g.inflate(l,j.Z_NO_FLUSH),c===j.Z_BUF_ERROR&&o===!0&&(c=j.Z_OK,o=!1),c!==j.Z_STREAM_END&&c!==j.Z_OK)return this.onEnd(c),this.ended=!0,!1;l.next_out&&(0!==l.avail_out&&c!==j.Z_STREAM_END&&(0!==l.avail_in||d!==j.Z_FINISH&&d!==j.Z_SYNC_FLUSH)||("string"===this.options.to?(e=i.utf8border(l.output,l.next_out),f=l.next_out-e,k=i.buf2string(l.output,e),l.next_out=f,l.avail_out=m-f,f&&h.arraySet(l.output,l.output,e,f,0),this.onData(k)):this.onData(h.shrinkBuf(l.output,l.next_out)))),0===l.avail_in&&0===l.avail_out&&(o=!0)}while((l.avail_in>0||0===l.avail_out)&&c!==j.Z_STREAM_END);return c===j.Z_STREAM_END&&(d=j.Z_FINISH),d===j.Z_FINISH?(c=g.inflateEnd(this.strm),this.onEnd(c),this.ended=!0,c===j.Z_OK):d===j.Z_SYNC_FLUSH?(this.onEnd(j.Z_OK),l.avail_out=0,!0):!0},d.prototype.onData=function(a){this.chunks.push(a)},d.prototype.onEnd=function(a){a===j.Z_OK&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=h.flattenChunks(this.chunks)),this.chunks=[],this.err=a,this.msg=this.strm.msg},c.Inflate=d,c.inflate=e,c.inflateRaw=f,c.ungzip=e},{"./utils/common":28,"./utils/strings":29,"./zlib/constants":31,"./zlib/gzheader":34,"./zlib/inflate":36,"./zlib/messages":38,"./zlib/zstream":40}],28:[function(a,b,c){"use strict";var d="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Int32Array;c.assign=function(a){for(var b=Array.prototype.slice.call(arguments,1);b.length;){var c=b.shift();if(c){if("object"!=typeof c)throw new TypeError(c+"must be non-object");for(var d in c)c.hasOwnProperty(d)&&(a[d]=c[d])}}return a},c.shrinkBuf=function(a,b){return a.length===b?a:a.subarray?a.subarray(0,b):(a.length=b,a)};var e={arraySet:function(a,b,c,d,e){if(b.subarray&&a.subarray)return void a.set(b.subarray(c,c+d),e);for(var f=0;d>f;f++)a[e+f]=b[c+f]},flattenChunks:function(a){var b,c,d,e,f,g;for(d=0,b=0,c=a.length;c>b;b++)d+=a[b].length;for(g=new Uint8Array(d),e=0,b=0,c=a.length;c>b;b++)f=a[b],g.set(f,e),e+=f.length;return g}},f={arraySet:function(a,b,c,d,e){for(var f=0;d>f;f++)a[e+f]=b[c+f]},flattenChunks:function(a){return[].concat.apply([],a)}};c.setTyped=function(a){a?(c.Buf8=Uint8Array,c.Buf16=Uint16Array,c.Buf32=Int32Array,c.assign(c,e)):(c.Buf8=Array,c.Buf16=Array,c.Buf32=Array,c.assign(c,f))},c.setTyped(d)},{}],29:[function(a,b,c){"use strict";function d(a,b){if(65537>b&&(a.subarray&&g||!a.subarray&&f))return String.fromCharCode.apply(null,e.shrinkBuf(a,b));for(var c="",d=0;b>d;d++)c+=String.fromCharCode(a[d]);return c}var e=a("./common"),f=!0,g=!0;try{String.fromCharCode.apply(null,[0])}catch(h){f=!1}try{String.fromCharCode.apply(null,new Uint8Array(1))}catch(h){g=!1}for(var i=new e.Buf8(256),j=0;256>j;j++)i[j]=j>=252?6:j>=248?5:j>=240?4:j>=224?3:j>=192?2:1;i[254]=i[254]=1,c.string2buf=function(a){var b,c,d,f,g,h=a.length,i=0;for(f=0;h>f;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),i+=128>c?1:2048>c?2:65536>c?3:4;for(b=new e.Buf8(i),g=0,f=0;i>g;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),128>c?b[g++]=c:2048>c?(b[g++]=192|c>>>6,b[g++]=128|63&c):65536>c?(b[g++]=224|c>>>12,b[g++]=128|c>>>6&63,b[g++]=128|63&c):(b[g++]=240|c>>>18,b[g++]=128|c>>>12&63,b[g++]=128|c>>>6&63,b[g++]=128|63&c);return b},c.buf2binstring=function(a){return d(a,a.length)},c.binstring2buf=function(a){for(var b=new e.Buf8(a.length),c=0,d=b.length;d>c;c++)b[c]=a.charCodeAt(c);return b},c.buf2string=function(a,b){var c,e,f,g,h=b||a.length,j=new Array(2*h);for(e=0,c=0;h>c;)if(f=a[c++],128>f)j[e++]=f;else if(g=i[f],g>4)j[e++]=65533,c+=g-1;else{for(f&=2===g?31:3===g?15:7;g>1&&h>c;)f=f<<6|63&a[c++],g--;g>1?j[e++]=65533:65536>f?j[e++]=f:(f-=65536,j[e++]=55296|f>>10&1023,j[e++]=56320|1023&f)}return d(j,e)},c.utf8border=function(a,b){var c;for(b=b||a.length,b>a.length&&(b=a.length),c=b-1;c>=0&&128===(192&a[c]);)c--;return 0>c?b:0===c?b:c+i[a[c]]>b?c:b}},{"./common":28}],30:[function(a,b,c){"use strict";function d(a,b,c,d){for(var e=65535&a|0,f=a>>>16&65535|0,g=0;0!==c;){g=c>2e3?2e3:c,c-=g;do e=e+b[d++]|0,f=f+e|0;while(--g);e%=65521,f%=65521}return e|f<<16|0}b.exports=d},{}],31:[function(a,b,c){"use strict";b.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8}},{}],32:[function(a,b,c){"use strict";function d(){for(var a,b=[],c=0;256>c;c++){a=c;for(var d=0;8>d;d++)a=1&a?3988292384^a>>>1:a>>>1;b[c]=a}return b}function e(a,b,c,d){var e=f,g=d+c;a^=-1;for(var h=d;g>h;h++)a=a>>>8^e[255&(a^b[h])];return-1^a}var f=d();b.exports=e},{}],33:[function(a,b,c){"use strict";function d(a,b){return a.msg=H[b],b}function e(a){return(a<<1)-(a>4?9:0)}function f(a){for(var b=a.length;--b>=0;)a[b]=0}function g(a){var b=a.state,c=b.pending;c>a.avail_out&&(c=a.avail_out),0!==c&&(D.arraySet(a.output,b.pending_buf,b.pending_out,c,a.next_out),a.next_out+=c,b.pending_out+=c,a.total_out+=c,a.avail_out-=c,b.pending-=c,0===b.pending&&(b.pending_out=0))}function h(a,b){E._tr_flush_block(a,a.block_start>=0?a.block_start:-1,a.strstart-a.block_start,b),a.block_start=a.strstart,g(a.strm)}function i(a,b){a.pending_buf[a.pending++]=b}function j(a,b){a.pending_buf[a.pending++]=b>>>8&255,a.pending_buf[a.pending++]=255&b}function k(a,b,c,d){var e=a.avail_in;return e>d&&(e=d),0===e?0:(a.avail_in-=e,D.arraySet(b,a.input,a.next_in,e,c),1===a.state.wrap?a.adler=F(a.adler,b,e,c):2===a.state.wrap&&(a.adler=G(a.adler,b,e,c)),a.next_in+=e,a.total_in+=e,e)}function l(a,b){var c,d,e=a.max_chain_length,f=a.strstart,g=a.prev_length,h=a.nice_match,i=a.strstart>a.w_size-ka?a.strstart-(a.w_size-ka):0,j=a.window,k=a.w_mask,l=a.prev,m=a.strstart+ja,n=j[f+g-1],o=j[f+g];a.prev_length>=a.good_match&&(e>>=2),h>a.lookahead&&(h=a.lookahead);do if(c=b,j[c+g]===o&&j[c+g-1]===n&&j[c]===j[f]&&j[++c]===j[f+1]){f+=2,c++;do;while(j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&m>f);if(d=ja-(m-f),f=m-ja,d>g){if(a.match_start=b,g=d,d>=h)break;n=j[f+g-1],o=j[f+g]}}while((b=l[b&k])>i&&0!==--e);return g<=a.lookahead?g:a.lookahead}function m(a){var b,c,d,e,f,g=a.w_size;do{if(e=a.window_size-a.lookahead-a.strstart,a.strstart>=g+(g-ka)){D.arraySet(a.window,a.window,g,g,0),a.match_start-=g,a.strstart-=g,a.block_start-=g,c=a.hash_size,b=c;do d=a.head[--b],a.head[b]=d>=g?d-g:0;while(--c);c=g,b=c;do d=a.prev[--b],a.prev[b]=d>=g?d-g:0;while(--c);e+=g}if(0===a.strm.avail_in)break;if(c=k(a.strm,a.window,a.strstart+a.lookahead,e),a.lookahead+=c,a.lookahead+a.insert>=ia)for(f=a.strstart-a.insert,a.ins_h=a.window[f],a.ins_h=(a.ins_h<a.pending_buf_size-5&&(c=a.pending_buf_size-5);;){if(a.lookahead<=1){if(m(a),0===a.lookahead&&b===I)return ta;if(0===a.lookahead)break}a.strstart+=a.lookahead,a.lookahead=0;var d=a.block_start+c;if((0===a.strstart||a.strstart>=d)&&(a.lookahead=a.strstart-d,a.strstart=d,h(a,!1),0===a.strm.avail_out))return ta;if(a.strstart-a.block_start>=a.w_size-ka&&(h(a,!1),0===a.strm.avail_out))return ta}return a.insert=0,b===L?(h(a,!0),0===a.strm.avail_out?va:wa):a.strstart>a.block_start&&(h(a,!1),0===a.strm.avail_out)?ta:ta}function o(a,b){for(var c,d;;){if(a.lookahead=ia&&(a.ins_h=(a.ins_h<=ia)if(d=E._tr_tally(a,a.strstart-a.match_start,a.match_length-ia),a.lookahead-=a.match_length,a.match_length<=a.max_lazy_match&&a.lookahead>=ia){a.match_length--;do a.strstart++,a.ins_h=(a.ins_h<=ia&&(a.ins_h=(a.ins_h<4096)&&(a.match_length=ia-1)),a.prev_length>=ia&&a.match_length<=a.prev_length){e=a.strstart+a.lookahead-ia,d=E._tr_tally(a,a.strstart-1-a.prev_match,a.prev_length-ia),a.lookahead-=a.prev_length-1,a.prev_length-=2;do++a.strstart<=e&&(a.ins_h=(a.ins_h<=ia&&a.strstart>0&&(e=a.strstart-1,d=g[e],d===g[++e]&&d===g[++e]&&d===g[++e])){f=a.strstart+ja;do;while(d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&f>e);a.match_length=ja-(f-e),a.match_length>a.lookahead&&(a.match_length=a.lookahead)}if(a.match_length>=ia?(c=E._tr_tally(a,1,a.match_length-ia),a.lookahead-=a.match_length,a.strstart+=a.match_length,a.match_length=0):(c=E._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++),c&&(h(a,!1),0===a.strm.avail_out))return ta}return a.insert=0,b===L?(h(a,!0),0===a.strm.avail_out?va:wa):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?ta:ua}function r(a,b){for(var c;;){if(0===a.lookahead&&(m(a),0===a.lookahead)){if(b===I)return ta;break}if(a.match_length=0,c=E._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++,c&&(h(a,!1),0===a.strm.avail_out))return ta}return a.insert=0,b===L?(h(a,!0),0===a.strm.avail_out?va:wa):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?ta:ua}function s(a,b,c,d,e){this.good_length=a,this.max_lazy=b,this.nice_length=c,this.max_chain=d,this.func=e}function t(a){a.window_size=2*a.w_size,f(a.head),a.max_lazy_match=C[a.level].max_lazy,a.good_match=C[a.level].good_length,a.nice_match=C[a.level].nice_length,a.max_chain_length=C[a.level].max_chain,a.strstart=0,a.block_start=0,a.lookahead=0,a.insert=0,a.match_length=a.prev_length=ia-1,a.match_available=0,a.ins_h=0}function u(){this.strm=null,this.status=0,this.pending_buf=null,this.pending_buf_size=0,this.pending_out=0,this.pending=0,this.wrap=0,this.gzhead=null,this.gzindex=0,this.method=Z,this.last_flush=-1,this.w_size=0,this.w_bits=0,this.w_mask=0,this.window=null,this.window_size=0,this.prev=null,this.head=null,this.ins_h=0,this.hash_size=0,this.hash_bits=0,this.hash_mask=0,this.hash_shift=0,this.block_start=0,this.match_length=0,this.prev_match=0,this.match_available=0,this.strstart=0,this.match_start=0,this.lookahead=0,this.prev_length=0,this.max_chain_length=0,this.max_lazy_match=0,this.level=0,this.strategy=0,this.good_match=0,this.nice_match=0,this.dyn_ltree=new D.Buf16(2*ga),this.dyn_dtree=new D.Buf16(2*(2*ea+1)),this.bl_tree=new D.Buf16(2*(2*fa+1)),f(this.dyn_ltree),f(this.dyn_dtree),f(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new D.Buf16(ha+1),this.heap=new D.Buf16(2*da+1),f(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new D.Buf16(2*da+1),f(this.depth),this.l_buf=0,this.lit_bufsize=0,this.last_lit=0,this.d_buf=0,this.opt_len=0,this.static_len=0,this.matches=0,this.insert=0,this.bi_buf=0,this.bi_valid=0}function v(a){var b;return a&&a.state?(a.total_in=a.total_out=0,a.data_type=Y,b=a.state,b.pending=0,b.pending_out=0,b.wrap<0&&(b.wrap=-b.wrap),b.status=b.wrap?ma:ra,a.adler=2===b.wrap?0:1,b.last_flush=I,E._tr_init(b),N):d(a,P)}function w(a){var b=v(a);return b===N&&t(a.state),b}function x(a,b){return a&&a.state?2!==a.state.wrap?P:(a.state.gzhead=b,N):P}function y(a,b,c,e,f,g){if(!a)return P;var h=1;if(b===S&&(b=6),0>e?(h=0,e=-e):e>15&&(h=2,e-=16),1>f||f>$||c!==Z||8>e||e>15||0>b||b>9||0>g||g>W)return d(a,P);8===e&&(e=9);var i=new u;return a.state=i,i.strm=a,i.wrap=h,i.gzhead=null,i.w_bits=e,i.w_size=1<>1,i.l_buf=3*i.lit_bufsize,i.level=b,i.strategy=g,i.method=c,w(a)}function z(a,b){return y(a,b,Z,_,aa,X)}function A(a,b){var c,h,k,l;if(!a||!a.state||b>M||0>b)return a?d(a,P):P;if(h=a.state,!a.output||!a.input&&0!==a.avail_in||h.status===sa&&b!==L)return d(a,0===a.avail_out?R:P);if(h.strm=a,c=h.last_flush,h.last_flush=b,h.status===ma)if(2===h.wrap)a.adler=0,i(h,31),i(h,139),i(h,8),h.gzhead?(i(h,(h.gzhead.text?1:0)+(h.gzhead.hcrc?2:0)+(h.gzhead.extra?4:0)+(h.gzhead.name?8:0)+(h.gzhead.comment?16:0)),i(h,255&h.gzhead.time),i(h,h.gzhead.time>>8&255),i(h,h.gzhead.time>>16&255),i(h,h.gzhead.time>>24&255),i(h,9===h.level?2:h.strategy>=U||h.level<2?4:0),i(h,255&h.gzhead.os),h.gzhead.extra&&h.gzhead.extra.length&&(i(h,255&h.gzhead.extra.length),i(h,h.gzhead.extra.length>>8&255)),h.gzhead.hcrc&&(a.adler=G(a.adler,h.pending_buf,h.pending,0)),h.gzindex=0,h.status=na):(i(h,0),i(h,0),i(h,0),i(h,0),i(h,0),i(h,9===h.level?2:h.strategy>=U||h.level<2?4:0),i(h,xa),h.status=ra);else{var m=Z+(h.w_bits-8<<4)<<8,n=-1;n=h.strategy>=U||h.level<2?0:h.level<6?1:6===h.level?2:3,m|=n<<6,0!==h.strstart&&(m|=la),m+=31-m%31,h.status=ra,j(h,m),0!==h.strstart&&(j(h,a.adler>>>16),j(h,65535&a.adler)),a.adler=1}if(h.status===na)if(h.gzhead.extra){for(k=h.pending;h.gzindex<(65535&h.gzhead.extra.length)&&(h.pending!==h.pending_buf_size||(h.gzhead.hcrc&&h.pending>k&&(a.adler=G(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending!==h.pending_buf_size));)i(h,255&h.gzhead.extra[h.gzindex]),h.gzindex++;h.gzhead.hcrc&&h.pending>k&&(a.adler=G(a.adler,h.pending_buf,h.pending-k,k)),h.gzindex===h.gzhead.extra.length&&(h.gzindex=0,h.status=oa)}else h.status=oa;if(h.status===oa)if(h.gzhead.name){k=h.pending;do{if(h.pending===h.pending_buf_size&&(h.gzhead.hcrc&&h.pending>k&&(a.adler=G(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending===h.pending_buf_size)){l=1;break}l=h.gzindexk&&(a.adler=G(a.adler,h.pending_buf,h.pending-k,k)),0===l&&(h.gzindex=0,h.status=pa)}else h.status=pa;if(h.status===pa)if(h.gzhead.comment){k=h.pending;do{if(h.pending===h.pending_buf_size&&(h.gzhead.hcrc&&h.pending>k&&(a.adler=G(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending===h.pending_buf_size)){l=1;break}l=h.gzindexk&&(a.adler=G(a.adler,h.pending_buf,h.pending-k,k)),0===l&&(h.status=qa)}else h.status=qa;if(h.status===qa&&(h.gzhead.hcrc?(h.pending+2>h.pending_buf_size&&g(a),h.pending+2<=h.pending_buf_size&&(i(h,255&a.adler),i(h,a.adler>>8&255),a.adler=0,h.status=ra)):h.status=ra),0!==h.pending){if(g(a),0===a.avail_out)return h.last_flush=-1,N}else if(0===a.avail_in&&e(b)<=e(c)&&b!==L)return d(a,R);if(h.status===sa&&0!==a.avail_in)return d(a,R);if(0!==a.avail_in||0!==h.lookahead||b!==I&&h.status!==sa){var o=h.strategy===U?r(h,b):h.strategy===V?q(h,b):C[h.level].func(h,b);if(o!==va&&o!==wa||(h.status=sa),o===ta||o===va)return 0===a.avail_out&&(h.last_flush=-1),N;if(o===ua&&(b===J?E._tr_align(h):b!==M&&(E._tr_stored_block(h,0,0,!1),b===K&&(f(h.head),0===h.lookahead&&(h.strstart=0,h.block_start=0,h.insert=0))),g(a),0===a.avail_out))return h.last_flush=-1,N}return b!==L?N:h.wrap<=0?O:(2===h.wrap?(i(h,255&a.adler),i(h,a.adler>>8&255),i(h,a.adler>>16&255),i(h,a.adler>>24&255),i(h,255&a.total_in),i(h,a.total_in>>8&255),i(h,a.total_in>>16&255),i(h,a.total_in>>24&255)):(j(h,a.adler>>>16),j(h,65535&a.adler)),g(a),h.wrap>0&&(h.wrap=-h.wrap),0!==h.pending?N:O)}function B(a){var b;return a&&a.state?(b=a.state.status,b!==ma&&b!==na&&b!==oa&&b!==pa&&b!==qa&&b!==ra&&b!==sa?d(a,P):(a.state=null,b===ra?d(a,Q):N)):P}var C,D=a("../utils/common"),E=a("./trees"),F=a("./adler32"),G=a("./crc32"),H=a("./messages"),I=0,J=1,K=3,L=4,M=5,N=0,O=1,P=-2,Q=-3,R=-5,S=-1,T=1,U=2,V=3,W=4,X=0,Y=2,Z=8,$=9,_=15,aa=8,ba=29,ca=256,da=ca+1+ba,ea=30,fa=19,ga=2*da+1,ha=15,ia=3,ja=258,ka=ja+ia+1,la=32,ma=42,na=69,oa=73,pa=91,qa=103,ra=113,sa=666,ta=1,ua=2,va=3,wa=4,xa=3;C=[new s(0,0,0,0,n),new s(4,4,8,4,o),new s(4,5,16,8,o),new s(4,6,32,32,o),new s(4,4,16,16,p),new s(8,16,32,32,p),new s(8,16,128,128,p),new s(8,32,128,256,p),new s(32,128,258,1024,p),new s(32,258,258,4096,p)],c.deflateInit=z,c.deflateInit2=y,c.deflateReset=w,c.deflateResetKeep=v,c.deflateSetHeader=x,c.deflate=A,c.deflateEnd=B,c.deflateInfo="pako deflate (from Nodeca project)"},{"../utils/common":28,"./adler32":30,"./crc32":32,"./messages":38,"./trees":39}],34:[function(a,b,c){"use strict";function d(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1}b.exports=d},{}],35:[function(a,b,c){"use strict";var d=30,e=12;b.exports=function(a,b){var c,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C;c=a.state,f=a.next_in,B=a.input,g=f+(a.avail_in-5),h=a.next_out,C=a.output,i=h-(b-a.avail_out),j=h+(a.avail_out-257),k=c.dmax,l=c.wsize,m=c.whave,n=c.wnext,o=c.window,p=c.hold,q=c.bits,r=c.lencode,s=c.distcode,t=(1<q&&(p+=B[f++]<>>24,p>>>=w,q-=w,w=v>>>16&255,0===w)C[h++]=65535&v;else{if(!(16&w)){if(0===(64&w)){v=r[(65535&v)+(p&(1<q&&(p+=B[f++]<>>=w,q-=w),15>q&&(p+=B[f++]<>>24,p>>>=w,q-=w,w=v>>>16&255,!(16&w)){if(0===(64&w)){v=s[(65535&v)+(p&(1<q&&(p+=B[f++]<q&&(p+=B[f++]<k){a.msg="invalid distance too far back",c.mode=d;break a}if(p>>>=w,q-=w,w=h-i,y>w){if(w=y-w,w>m&&c.sane){a.msg="invalid distance too far back",c.mode=d;break a}if(z=0,A=o,0===n){if(z+=l-w,x>w){x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}}else if(w>n){if(z+=l+n-w,w-=n,x>w){x-=w;do C[h++]=o[z++];while(--w);if(z=0,x>n){w=n,x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}}}else if(z+=n-w,x>w){x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}for(;x>2;)C[h++]=A[z++],C[h++]=A[z++],C[h++]=A[z++],x-=3;x&&(C[h++]=A[z++],x>1&&(C[h++]=A[z++]))}else{z=h-y;do C[h++]=C[z++],C[h++]=C[z++],C[h++]=C[z++],x-=3;while(x>2);x&&(C[h++]=C[z++],x>1&&(C[h++]=C[z++]))}break}}break}}while(g>f&&j>h);x=q>>3,f-=x,q-=x<<3,p&=(1<f?5+(g-f):5-(f-g),a.avail_out=j>h?257+(j-h):257-(h-j),c.hold=p,c.bits=q}},{}],36:[function(a,b,c){"use strict";function d(a){return(a>>>24&255)+(a>>>8&65280)+((65280&a)<<8)+((255&a)<<24)}function e(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new r.Buf16(320),this.work=new r.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function f(a){var b;return a&&a.state?(b=a.state,a.total_in=a.total_out=b.total=0,a.msg="",b.wrap&&(a.adler=1&b.wrap),b.mode=K,b.last=0,b.havedict=0,b.dmax=32768,b.head=null,b.hold=0,b.bits=0,b.lencode=b.lendyn=new r.Buf32(oa),b.distcode=b.distdyn=new r.Buf32(pa),b.sane=1,b.back=-1,C):F}function g(a){var b;return a&&a.state?(b=a.state,b.wsize=0,b.whave=0,b.wnext=0,f(a)):F}function h(a,b){var c,d;return a&&a.state?(d=a.state,0>b?(c=0,b=-b):(c=(b>>4)+1,48>b&&(b&=15)),b&&(8>b||b>15)?F:(null!==d.window&&d.wbits!==b&&(d.window=null),d.wrap=c,d.wbits=b,g(a))):F}function i(a,b){var c,d;return a?(d=new e,a.state=d,d.window=null,c=h(a,b),c!==C&&(a.state=null),c):F}function j(a){return i(a,ra)}function k(a){if(sa){var b;for(p=new r.Buf32(512),q=new r.Buf32(32),b=0;144>b;)a.lens[b++]=8;for(;256>b;)a.lens[b++]=9;for(;280>b;)a.lens[b++]=7;for(;288>b;)a.lens[b++]=8;for(v(x,a.lens,0,288,p,0,a.work,{bits:9}),b=0;32>b;)a.lens[b++]=5;v(y,a.lens,0,32,q,0,a.work,{bits:5}),sa=!1}a.lencode=p,a.lenbits=9,a.distcode=q,a.distbits=5}function l(a,b,c,d){var e,f=a.state;return null===f.window&&(f.wsize=1<=f.wsize?(r.arraySet(f.window,b,c-f.wsize,f.wsize,0),f.wnext=0,f.whave=f.wsize):(e=f.wsize-f.wnext,e>d&&(e=d),r.arraySet(f.window,b,c-d,e,f.wnext),d-=e,d?(r.arraySet(f.window,b,c-d,d,0),f.wnext=d,f.whave=f.wsize):(f.wnext+=e,f.wnext===f.wsize&&(f.wnext=0),f.whaven;){if(0===i)break a;i--,m+=e[g++]<>>8&255,c.check=t(c.check,Ba,2,0),m=0,n=0,c.mode=L;break}if(c.flags=0,c.head&&(c.head.done=!1),!(1&c.wrap)||(((255&m)<<8)+(m>>8))%31){a.msg="incorrect header check",c.mode=la;break}if((15&m)!==J){a.msg="unknown compression method",c.mode=la;break}if(m>>>=4,n-=4,wa=(15&m)+8,0===c.wbits)c.wbits=wa;else if(wa>c.wbits){a.msg="invalid window size",c.mode=la;break}c.dmax=1<n;){if(0===i)break a;i--,m+=e[g++]<>8&1),512&c.flags&&(Ba[0]=255&m,Ba[1]=m>>>8&255,c.check=t(c.check,Ba,2,0)),m=0,n=0,c.mode=M;case M:for(;32>n;){if(0===i)break a;i--,m+=e[g++]<>>8&255,Ba[2]=m>>>16&255,Ba[3]=m>>>24&255,c.check=t(c.check,Ba,4,0)),m=0,n=0,c.mode=N;case N:for(;16>n;){if(0===i)break a;i--,m+=e[g++]<>8),512&c.flags&&(Ba[0]=255&m,Ba[1]=m>>>8&255,c.check=t(c.check,Ba,2,0)),m=0,n=0,c.mode=O;case O:if(1024&c.flags){for(;16>n;){if(0===i)break a;i--,m+=e[g++]<>>8&255,c.check=t(c.check,Ba,2,0)),m=0,n=0}else c.head&&(c.head.extra=null);c.mode=P;case P:if(1024&c.flags&&(q=c.length,q>i&&(q=i),q&&(c.head&&(wa=c.head.extra_len-c.length,c.head.extra||(c.head.extra=new Array(c.head.extra_len)),r.arraySet(c.head.extra,e,g,q,wa)),512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,c.length-=q),c.length))break a;c.length=0,c.mode=Q;case Q:if(2048&c.flags){if(0===i)break a;q=0;do wa=e[g+q++],c.head&&wa&&c.length<65536&&(c.head.name+=String.fromCharCode(wa));while(wa&&i>q);if(512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,wa)break a}else c.head&&(c.head.name=null);c.length=0,c.mode=R;case R:if(4096&c.flags){if(0===i)break a;q=0;do wa=e[g+q++],c.head&&wa&&c.length<65536&&(c.head.comment+=String.fromCharCode(wa));while(wa&&i>q);if(512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,wa)break a}else c.head&&(c.head.comment=null);c.mode=S;case S:if(512&c.flags){for(;16>n;){ +if(0===i)break a;i--,m+=e[g++]<>9&1,c.head.done=!0),a.adler=c.check=0,c.mode=V;break;case T:for(;32>n;){if(0===i)break a;i--,m+=e[g++]<>>=7&n,n-=7&n,c.mode=ia;break}for(;3>n;){if(0===i)break a;i--,m+=e[g++]<>>=1,n-=1,3&m){case 0:c.mode=X;break;case 1:if(k(c),c.mode=ba,b===B){m>>>=2,n-=2;break a}break;case 2:c.mode=$;break;case 3:a.msg="invalid block type",c.mode=la}m>>>=2,n-=2;break;case X:for(m>>>=7&n,n-=7&n;32>n;){if(0===i)break a;i--,m+=e[g++]<>>16^65535)){a.msg="invalid stored block lengths",c.mode=la;break}if(c.length=65535&m,m=0,n=0,c.mode=Y,b===B)break a;case Y:c.mode=Z;case Z:if(q=c.length){if(q>i&&(q=i),q>j&&(q=j),0===q)break a;r.arraySet(f,e,g,q,h),i-=q,g+=q,j-=q,h+=q,c.length-=q;break}c.mode=V;break;case $:for(;14>n;){if(0===i)break a;i--,m+=e[g++]<>>=5,n-=5,c.ndist=(31&m)+1,m>>>=5,n-=5,c.ncode=(15&m)+4,m>>>=4,n-=4,c.nlen>286||c.ndist>30){a.msg="too many length or distance symbols",c.mode=la;break}c.have=0,c.mode=_;case _:for(;c.haven;){if(0===i)break a;i--,m+=e[g++]<>>=3,n-=3}for(;c.have<19;)c.lens[Ca[c.have++]]=0;if(c.lencode=c.lendyn,c.lenbits=7,ya={bits:c.lenbits},xa=v(w,c.lens,0,19,c.lencode,0,c.work,ya),c.lenbits=ya.bits,xa){a.msg="invalid code lengths set",c.mode=la;break}c.have=0,c.mode=aa;case aa:for(;c.have>>24,ra=Aa>>>16&255,sa=65535&Aa,!(n>=qa);){if(0===i)break a;i--,m+=e[g++]<sa)m>>>=qa,n-=qa,c.lens[c.have++]=sa;else{if(16===sa){for(za=qa+2;za>n;){if(0===i)break a;i--,m+=e[g++]<>>=qa,n-=qa,0===c.have){a.msg="invalid bit length repeat",c.mode=la;break}wa=c.lens[c.have-1],q=3+(3&m),m>>>=2,n-=2}else if(17===sa){for(za=qa+3;za>n;){if(0===i)break a;i--,m+=e[g++]<>>=qa,n-=qa,wa=0,q=3+(7&m),m>>>=3,n-=3}else{for(za=qa+7;za>n;){if(0===i)break a;i--,m+=e[g++]<>>=qa,n-=qa,wa=0,q=11+(127&m),m>>>=7,n-=7}if(c.have+q>c.nlen+c.ndist){a.msg="invalid bit length repeat",c.mode=la;break}for(;q--;)c.lens[c.have++]=wa}}if(c.mode===la)break;if(0===c.lens[256]){a.msg="invalid code -- missing end-of-block",c.mode=la;break}if(c.lenbits=9,ya={bits:c.lenbits},xa=v(x,c.lens,0,c.nlen,c.lencode,0,c.work,ya),c.lenbits=ya.bits,xa){a.msg="invalid literal/lengths set",c.mode=la;break}if(c.distbits=6,c.distcode=c.distdyn,ya={bits:c.distbits},xa=v(y,c.lens,c.nlen,c.ndist,c.distcode,0,c.work,ya),c.distbits=ya.bits,xa){a.msg="invalid distances set",c.mode=la;break}if(c.mode=ba,b===B)break a;case ba:c.mode=ca;case ca:if(i>=6&&j>=258){a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,u(a,p),h=a.next_out,f=a.output,j=a.avail_out,g=a.next_in,e=a.input,i=a.avail_in,m=c.hold,n=c.bits,c.mode===V&&(c.back=-1);break}for(c.back=0;Aa=c.lencode[m&(1<>>24,ra=Aa>>>16&255,sa=65535&Aa,!(n>=qa);){if(0===i)break a;i--,m+=e[g++]<>ta)],qa=Aa>>>24,ra=Aa>>>16&255,sa=65535&Aa,!(n>=ta+qa);){if(0===i)break a;i--,m+=e[g++]<>>=ta,n-=ta,c.back+=ta}if(m>>>=qa,n-=qa,c.back+=qa,c.length=sa,0===ra){c.mode=ha;break}if(32&ra){c.back=-1,c.mode=V;break}if(64&ra){a.msg="invalid literal/length code",c.mode=la;break}c.extra=15&ra,c.mode=da;case da:if(c.extra){for(za=c.extra;za>n;){if(0===i)break a;i--,m+=e[g++]<>>=c.extra,n-=c.extra,c.back+=c.extra}c.was=c.length,c.mode=ea;case ea:for(;Aa=c.distcode[m&(1<>>24,ra=Aa>>>16&255,sa=65535&Aa,!(n>=qa);){if(0===i)break a;i--,m+=e[g++]<>ta)],qa=Aa>>>24,ra=Aa>>>16&255,sa=65535&Aa,!(n>=ta+qa);){if(0===i)break a;i--,m+=e[g++]<>>=ta,n-=ta,c.back+=ta}if(m>>>=qa,n-=qa,c.back+=qa,64&ra){a.msg="invalid distance code",c.mode=la;break}c.offset=sa,c.extra=15&ra,c.mode=fa;case fa:if(c.extra){for(za=c.extra;za>n;){if(0===i)break a;i--,m+=e[g++]<>>=c.extra,n-=c.extra,c.back+=c.extra}if(c.offset>c.dmax){a.msg="invalid distance too far back",c.mode=la;break}c.mode=ga;case ga:if(0===j)break a;if(q=p-j,c.offset>q){if(q=c.offset-q,q>c.whave&&c.sane){a.msg="invalid distance too far back",c.mode=la;break}q>c.wnext?(q-=c.wnext,oa=c.wsize-q):oa=c.wnext-q,q>c.length&&(q=c.length),pa=c.window}else pa=f,oa=h-c.offset,q=c.length;q>j&&(q=j),j-=q,c.length-=q;do f[h++]=pa[oa++];while(--q);0===c.length&&(c.mode=ca);break;case ha:if(0===j)break a;f[h++]=c.length,j--,c.mode=ca;break;case ia:if(c.wrap){for(;32>n;){if(0===i)break a;i--,m|=e[g++]<n;){if(0===i)break a;i--,m+=e[g++]<=D;D++)P[D]=0;for(E=0;o>E;E++)P[b[c+E]]++;for(H=C,G=e;G>=1&&0===P[G];G--);if(H>G&&(H=G),0===G)return p[q++]=20971520,p[q++]=20971520,s.bits=1,0;for(F=1;G>F&&0===P[F];F++);for(F>H&&(H=F),K=1,D=1;e>=D;D++)if(K<<=1,K-=P[D],0>K)return-1;if(K>0&&(a===h||1!==G))return-1;for(Q[1]=0,D=1;e>D;D++)Q[D+1]=Q[D]+P[D];for(E=0;o>E;E++)0!==b[c+E]&&(r[Q[b[c+E]]++]=E);if(a===h?(N=R=r,y=19):a===i?(N=k,O-=257,R=l,S-=257,y=256):(N=m,R=n,y=-1),M=0,E=0,D=F,x=q,I=H,J=0,v=-1,L=1<f||a===j&&L>g)return 1;for(var T=0;;){T++,z=D-J,r[E]y?(A=R[S+r[E]],B=N[O+r[E]]):(A=96,B=0),t=1<>J)+u]=z<<24|A<<16|B|0;while(0!==u);for(t=1<>=1;if(0!==t?(M&=t-1,M+=t):M=0,E++,0===--P[D]){if(D===G)break;D=b[c+r[E]]}if(D>H&&(M&w)!==v){for(0===J&&(J=H),x+=F,I=D-J,K=1<I+J&&(K-=P[I+J],!(0>=K));)I++,K<<=1;if(L+=1<f||a===j&&L>g)return 1;v=M&w,p[v]=H<<24|I<<16|x-q|0}}return 0!==M&&(p[x+M]=D-J<<24|64<<16|0),s.bits=H,0}},{"../utils/common":28}],38:[function(a,b,c){"use strict";b.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}},{}],39:[function(a,b,c){"use strict";function d(a){for(var b=a.length;--b>=0;)a[b]=0}function e(a,b,c,d,e){this.static_tree=a,this.extra_bits=b,this.extra_base=c,this.elems=d,this.max_length=e,this.has_stree=a&&a.length}function f(a,b){this.dyn_tree=a,this.max_code=0,this.stat_desc=b}function g(a){return 256>a?ia[a]:ia[256+(a>>>7)]}function h(a,b){a.pending_buf[a.pending++]=255&b,a.pending_buf[a.pending++]=b>>>8&255}function i(a,b,c){a.bi_valid>X-c?(a.bi_buf|=b<>X-a.bi_valid,a.bi_valid+=c-X):(a.bi_buf|=b<>>=1,c<<=1;while(--b>0);return c>>>1}function l(a){16===a.bi_valid?(h(a,a.bi_buf),a.bi_buf=0,a.bi_valid=0):a.bi_valid>=8&&(a.pending_buf[a.pending++]=255&a.bi_buf,a.bi_buf>>=8,a.bi_valid-=8)}function m(a,b){var c,d,e,f,g,h,i=b.dyn_tree,j=b.max_code,k=b.stat_desc.static_tree,l=b.stat_desc.has_stree,m=b.stat_desc.extra_bits,n=b.stat_desc.extra_base,o=b.stat_desc.max_length,p=0;for(f=0;W>=f;f++)a.bl_count[f]=0;for(i[2*a.heap[a.heap_max]+1]=0,c=a.heap_max+1;V>c;c++)d=a.heap[c],f=i[2*i[2*d+1]+1]+1,f>o&&(f=o,p++),i[2*d+1]=f,d>j||(a.bl_count[f]++,g=0,d>=n&&(g=m[d-n]),h=i[2*d],a.opt_len+=h*(f+g),l&&(a.static_len+=h*(k[2*d+1]+g)));if(0!==p){do{for(f=o-1;0===a.bl_count[f];)f--;a.bl_count[f]--,a.bl_count[f+1]+=2,a.bl_count[o]--,p-=2}while(p>0);for(f=o;0!==f;f--)for(d=a.bl_count[f];0!==d;)e=a.heap[--c],e>j||(i[2*e+1]!==f&&(a.opt_len+=(f-i[2*e+1])*i[2*e],i[2*e+1]=f),d--)}}function n(a,b,c){var d,e,f=new Array(W+1),g=0;for(d=1;W>=d;d++)f[d]=g=g+c[d-1]<<1;for(e=0;b>=e;e++){var h=a[2*e+1];0!==h&&(a[2*e]=k(f[h]++,h))}}function o(){var a,b,c,d,f,g=new Array(W+1);for(c=0,d=0;Q-1>d;d++)for(ka[d]=c,a=0;a<1<d;d++)for(la[d]=f,a=0;a<1<>=7;T>d;d++)for(la[d]=f<<7,a=0;a<1<=b;b++)g[b]=0;for(a=0;143>=a;)ga[2*a+1]=8,a++,g[8]++;for(;255>=a;)ga[2*a+1]=9,a++,g[9]++;for(;279>=a;)ga[2*a+1]=7,a++,g[7]++;for(;287>=a;)ga[2*a+1]=8,a++,g[8]++;for(n(ga,S+1,g),a=0;T>a;a++)ha[2*a+1]=5,ha[2*a]=k(a,5);ma=new e(ga,ba,R+1,S,W),na=new e(ha,ca,0,T,W),oa=new e(new Array(0),da,0,U,Y)}function p(a){var b;for(b=0;S>b;b++)a.dyn_ltree[2*b]=0;for(b=0;T>b;b++)a.dyn_dtree[2*b]=0;for(b=0;U>b;b++)a.bl_tree[2*b]=0;a.dyn_ltree[2*Z]=1,a.opt_len=a.static_len=0,a.last_lit=a.matches=0}function q(a){a.bi_valid>8?h(a,a.bi_buf):a.bi_valid>0&&(a.pending_buf[a.pending++]=a.bi_buf),a.bi_buf=0,a.bi_valid=0}function r(a,b,c,d){q(a),d&&(h(a,c),h(a,~c)),G.arraySet(a.pending_buf,a.window,b,c,a.pending),a.pending+=c}function s(a,b,c,d){var e=2*b,f=2*c;return a[e]c;c++)0!==f[2*c]?(a.heap[++a.heap_len]=j=c,a.depth[c]=0):f[2*c+1]=0;for(;a.heap_len<2;)e=a.heap[++a.heap_len]=2>j?++j:0,f[2*e]=1,a.depth[e]=0,a.opt_len--,h&&(a.static_len-=g[2*e+1]);for(b.max_code=j,c=a.heap_len>>1;c>=1;c--)t(a,f,c);e=i;do c=a.heap[1],a.heap[1]=a.heap[a.heap_len--],t(a,f,1),d=a.heap[1],a.heap[--a.heap_max]=c,a.heap[--a.heap_max]=d,f[2*e]=f[2*c]+f[2*d],a.depth[e]=(a.depth[c]>=a.depth[d]?a.depth[c]:a.depth[d])+1,f[2*c+1]=f[2*d+1]=e,a.heap[1]=e++,t(a,f,1);while(a.heap_len>=2);a.heap[--a.heap_max]=a.heap[1],m(a,b),n(f,j,a.bl_count)}function w(a,b,c){var d,e,f=-1,g=b[1],h=0,i=7,j=4;for(0===g&&(i=138,j=3),b[2*(c+1)+1]=65535,d=0;c>=d;d++)e=g,g=b[2*(d+1)+1],++hh?a.bl_tree[2*e]+=h:0!==e?(e!==f&&a.bl_tree[2*e]++,a.bl_tree[2*$]++):10>=h?a.bl_tree[2*_]++:a.bl_tree[2*aa]++,h=0,f=e,0===g?(i=138,j=3):e===g?(i=6,j=3):(i=7,j=4))}function x(a,b,c){var d,e,f=-1,g=b[1],h=0,k=7,l=4;for(0===g&&(k=138,l=3),d=0;c>=d;d++)if(e=g,g=b[2*(d+1)+1],!(++hh){do j(a,e,a.bl_tree);while(0!==--h)}else 0!==e?(e!==f&&(j(a,e,a.bl_tree),h--),j(a,$,a.bl_tree),i(a,h-3,2)):10>=h?(j(a,_,a.bl_tree),i(a,h-3,3)):(j(a,aa,a.bl_tree),i(a,h-11,7));h=0,f=e,0===g?(k=138,l=3):e===g?(k=6,l=3):(k=7,l=4)}}function y(a){var b;for(w(a,a.dyn_ltree,a.l_desc.max_code),w(a,a.dyn_dtree,a.d_desc.max_code),v(a,a.bl_desc),b=U-1;b>=3&&0===a.bl_tree[2*ea[b]+1];b--);return a.opt_len+=3*(b+1)+5+5+4,b}function z(a,b,c,d){var e;for(i(a,b-257,5),i(a,c-1,5),i(a,d-4,4),e=0;d>e;e++)i(a,a.bl_tree[2*ea[e]+1],3);x(a,a.dyn_ltree,b-1),x(a,a.dyn_dtree,c-1)}function A(a){var b,c=4093624447;for(b=0;31>=b;b++,c>>>=1)if(1&c&&0!==a.dyn_ltree[2*b])return I;if(0!==a.dyn_ltree[18]||0!==a.dyn_ltree[20]||0!==a.dyn_ltree[26])return J;for(b=32;R>b;b++)if(0!==a.dyn_ltree[2*b])return J;return I}function B(a){pa||(o(),pa=!0),a.l_desc=new f(a.dyn_ltree,ma),a.d_desc=new f(a.dyn_dtree,na),a.bl_desc=new f(a.bl_tree,oa),a.bi_buf=0,a.bi_valid=0,p(a)}function C(a,b,c,d){i(a,(L<<1)+(d?1:0),3),r(a,b,c,!0)}function D(a){i(a,M<<1,3),j(a,Z,ga),l(a)}function E(a,b,c,d){var e,f,g=0;a.level>0?(a.strm.data_type===K&&(a.strm.data_type=A(a)),v(a,a.l_desc),v(a,a.d_desc),g=y(a),e=a.opt_len+3+7>>>3,f=a.static_len+3+7>>>3,e>=f&&(e=f)):e=f=c+5,e>=c+4&&-1!==b?C(a,b,c,d):a.strategy===H||f===e?(i(a,(M<<1)+(d?1:0),3),u(a,ga,ha)):(i(a,(N<<1)+(d?1:0),3),z(a,a.l_desc.max_code+1,a.d_desc.max_code+1,g+1),u(a,a.dyn_ltree,a.dyn_dtree)),p(a),d&&q(a)}function F(a,b,c){return a.pending_buf[a.d_buf+2*a.last_lit]=b>>>8&255,a.pending_buf[a.d_buf+2*a.last_lit+1]=255&b,a.pending_buf[a.l_buf+a.last_lit]=255&c,a.last_lit++,0===b?a.dyn_ltree[2*c]++:(a.matches++,b--,a.dyn_ltree[2*(ja[c]+R+1)]++,a.dyn_dtree[2*g(b)]++),a.last_lit===a.lit_bufsize-1}var G=a("../utils/common"),H=4,I=0,J=1,K=2,L=0,M=1,N=2,O=3,P=258,Q=29,R=256,S=R+1+Q,T=30,U=19,V=2*S+1,W=15,X=16,Y=7,Z=256,$=16,_=17,aa=18,ba=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],ca=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],da=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],ea=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],fa=512,ga=new Array(2*(S+2));d(ga);var ha=new Array(2*T);d(ha);var ia=new Array(fa);d(ia);var ja=new Array(P-O+1);d(ja);var ka=new Array(Q);d(ka);var la=new Array(T);d(la);var ma,na,oa,pa=!1;c._tr_init=B,c._tr_stored_block=C,c._tr_flush_block=E,c._tr_tally=F,c._tr_align=D},{"../utils/common":28}],40:[function(a,b,c){"use strict";function d(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}b.exports=d},{}]},{},[10])(10)}); \ No newline at end of file diff --git a/public/js/main.js b/public/js/main.js index 7f5f239..b23b07a 100644 --- a/public/js/main.js +++ b/public/js/main.js @@ -1,20 +1,39 @@ $(function () { + var error = $(''); + $('.magic-csr').click(function () { + var name = $('#name').val(); + var user = $('.user').text(); + var keys = forge.pki.rsa.generateKeyPair(1024); var csr = forge.pki.createCertificationRequest(); + var commonName = name + '.' + user; + csr.publicKey = keys.publicKey; csr.setSubject([{ name: 'commonName', - value: 'eater-' + +Date.now() + value: commonName }]); csr.sign(keys.privateKey); var pem = forge.pki.certificationRequestToPem(csr); $.post('/panel/certificates/new', { - csr: pem + csr: pem, + name: name }, function (data) { - var config = data.config; - config = config.replace('', forge.pki.privateKeyToPem(keys.privateKey)); + if (data.success) { + var zip = new JSZip(); + zip.file(commonName + '.key', pem); + + for(var file in data.zip) { + zip.file(file, data.zip[file]); + } + var content = zip.generate({type:"blob"}); + saveAs(content, commonName + '-vpn.zip'); + location.href = '/panel'; + } else { + $('h2').after(error.text(data.error)); + } }); }); }); diff --git a/src/Handler/Main.php b/src/Handler/Main.php index 2564f28..3fa2c41 100644 --- a/src/Handler/Main.php +++ b/src/Handler/Main.php @@ -136,4 +136,25 @@ abstract class Main implements ContainerInterface $response = $this->getResponse(); return $response->withRedirect($url); } + + /** + * @param array $array + * @return Response + */ + public function json($array) + { + return $this->getResponse() + ->withHeader('Content-Type', 'application/json') + ->write(json_encode($array)); + + } + + /** + * @param string $name + * @return string + */ + public function attr($name) + { + return $this->getRequest()->getAttribute($name); + } } \ No newline at end of file diff --git a/src/Handler/Panel/Certificates/Download.php b/src/Handler/Panel/Certificates/Download.php new file mode 100644 index 0000000..733c074 --- /dev/null +++ b/src/Handler/Panel/Certificates/Download.php @@ -0,0 +1,37 @@ +attr('name'); + + $cert = CertificateQuery::create() + ->filterByName($name) + ->filterByUser($this->getUser()) + ->findOne(); + + if ($cert === null) { + return $this->getResponse()->withStatus(404)->write("Couldn't find your Certificate with the name '{$name}'"); + } + + return $this->getResponse() + ->withHeader('Content-Type', 'plain/text') + ->withHeader('Content-Disposition', 'attachment; filename="' . $name . '.' . $this->getUser()->getUsername() .'.crt"') + ->write($cert->getCertificate()); + } +} \ No newline at end of file diff --git a/src/Handler/Panel/Certificates/_New/Action.php b/src/Handler/Panel/Certificates/_New/Action.php new file mode 100644 index 0000000..fa59bfe --- /dev/null +++ b/src/Handler/Panel/Certificates/_New/Action.php @@ -0,0 +1,85 @@ +getUser(); + $core = $this->getCore(); + /** @var CA $ca */ + $ca = $this->get('ca'); + + $name = $this->post('name'); + $csr = $this->post('csr'); + + $amount = CertificateQuery::create() + ->filterByName($name) + ->filterByUser($user) + ->count(); + if ($amount > 0) { + return $this->json([ + "error" => "You already have an Certificate with the name '$name'", + "success" => false + ]); + } + + try { + $commonName = $ca->getCommonNameFromCsr($csr); + }catch (\Exception $e) { + return $this->json([ + "error" => $e->getMessage(), + "success" => false + ]); + } + + $designatedCommonName = $name . '.' . $user->getUsername(); + + if ($commonName !== $name . '.' . $user->getUsername()) { + return $this->json([ + "error" => "CommonName of CSR isn't '$designatedCommonName'", + "success" => false + ]); + } + + $crt = $ca->signClientCsr($csr); + + $details = openssl_x509_parse($crt); + + $certificate = new Certificate(); + $certificate->setName($name); + $certificate->setCertificate($crt); + $certificate->setExpiresOn(new \DateTime('@' . $details['validTo_time_t'])); + $certificate->setSerial($details['serialNumber']); + + $user->addCertificate($certificate); + $user->save(); + + return $this->json([ + "success" => true, + "zip" => [ + "ca.crt" => file_get_contents($core->getBaseDir() . '/storage/ca/ca.crt'), + $designatedCommonName . '.crt' => $crt + ] + ]); + } +} \ No newline at end of file diff --git a/src/Handler/Session.php b/src/Handler/Session.php index 284a10c..6983605 100644 --- a/src/Handler/Session.php +++ b/src/Handler/Session.php @@ -14,7 +14,32 @@ use Eater\Glim\Service\TwigVars; class Session extends Main { + /** + * @var bool + */ protected $shouldHaveUser = false; + + /** + * @var User + */ + protected $user; + + /** + * @return User + */ + public function getUser() + { + return $this->user; + } + + /** + * @param User $user + */ + public function setUser($user) + { + $this->user = $user; + } + public function beforeHandle() { @@ -28,6 +53,8 @@ class Session extends Main $user = $segment->get('user'); $twigVar->def('user', $user); + $this->setUser($user); + if ($user === null && $this->shouldHaveUser) { return $this->redirect('/login'); } diff --git a/src/Model/Base/Certificate.php b/src/Model/Base/Certificate.php index 33b501b..e349597 100644 --- a/src/Model/Base/Certificate.php +++ b/src/Model/Base/Certificate.php @@ -2,6 +2,7 @@ namespace Eater\Glim\Model\Base; +use \DateTime; use \Exception; use \PDO; use Eater\Glim\Model\CertificateQuery as ChildCertificateQuery; @@ -19,6 +20,7 @@ use Propel\Runtime\Exception\LogicException; use Propel\Runtime\Exception\PropelException; use Propel\Runtime\Map\TableMap; use Propel\Runtime\Parser\AbstractParser; +use Propel\Runtime\Util\PropelDateTime; /** * Base class that represents a row from the 'Certificate' table. @@ -68,10 +70,10 @@ abstract class Certificate implements ActiveRecordInterface protected $id; /** - * The value for the userid field. + * The value for the user_id field. * @var int */ - protected $userid; + protected $user_id; /** * The value for the name field. @@ -85,6 +87,12 @@ abstract class Certificate implements ActiveRecordInterface */ protected $certificate; + /** + * The value for the expires_on field. + * @var \DateTime + */ + protected $expires_on; + /** * The value for the revoked field. * Note: this column has a database default value of: false @@ -92,6 +100,12 @@ abstract class Certificate implements ActiveRecordInterface */ protected $revoked; + /** + * The value for the serial field. + * @var string + */ + protected $serial; + /** * @var ChildUser */ @@ -346,13 +360,13 @@ abstract class Certificate implements ActiveRecordInterface } /** - * Get the [userid] column value. + * Get the [user_id] column value. * * @return int */ - public function getUserid() + public function getUserId() { - return $this->userid; + return $this->user_id; } /** @@ -375,6 +389,26 @@ abstract class Certificate implements ActiveRecordInterface return $this->certificate; } + /** + * Get the [optionally formatted] temporal [expires_on] column value. + * + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the raw DateTime object will be returned. + * + * @return string|DateTime Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL + * + * @throws PropelException - if unable to parse/validate the date/time value. + */ + public function getExpiresOn($format = NULL) + { + if ($format === null) { + return $this->expires_on; + } else { + return $this->expires_on instanceof \DateTime ? $this->expires_on->format($format) : null; + } + } + /** * Get the [revoked] column value. * @@ -395,6 +429,16 @@ abstract class Certificate implements ActiveRecordInterface return $this->getRevoked(); } + /** + * Get the [serial] column value. + * + * @return string + */ + public function getSerial() + { + return $this->serial; + } + /** * Set the value of [id] column. * @@ -416,20 +460,20 @@ abstract class Certificate implements ActiveRecordInterface } // setId() /** - * Set the value of [userid] column. + * Set the value of [user_id] column. * * @param int $v new value * @return $this|\Eater\Glim\Model\Certificate The current object (for fluent API support) */ - public function setUserid($v) + public function setUserId($v) { if ($v !== null) { $v = (int) $v; } - if ($this->userid !== $v) { - $this->userid = $v; - $this->modifiedColumns[CertificateTableMap::COL_USERID] = true; + if ($this->user_id !== $v) { + $this->user_id = $v; + $this->modifiedColumns[CertificateTableMap::COL_USER_ID] = true; } if ($this->aUser !== null && $this->aUser->getId() !== $v) { @@ -437,7 +481,7 @@ abstract class Certificate implements ActiveRecordInterface } return $this; - } // setUserid() + } // setUserId() /** * Set the value of [name] column. @@ -479,6 +523,26 @@ abstract class Certificate implements ActiveRecordInterface return $this; } // setCertificate() + /** + * Sets the value of [expires_on] column to a normalized version of the date/time value specified. + * + * @param mixed $v string, integer (timestamp), or \DateTime value. + * Empty strings are treated as NULL. + * @return $this|\Eater\Glim\Model\Certificate The current object (for fluent API support) + */ + public function setExpiresOn($v) + { + $dt = PropelDateTime::newInstance($v, null, 'DateTime'); + if ($this->expires_on !== null || $dt !== null) { + if ($this->expires_on === null || $dt === null || $dt->format("Y-m-d H:i:s") !== $this->expires_on->format("Y-m-d H:i:s")) { + $this->expires_on = $dt === null ? null : clone $dt; + $this->modifiedColumns[CertificateTableMap::COL_EXPIRES_ON] = true; + } + } // if either are not null + + return $this; + } // setExpiresOn() + /** * Sets the value of the [revoked] column. * Non-boolean arguments are converted using the following rules: @@ -507,6 +571,26 @@ abstract class Certificate implements ActiveRecordInterface return $this; } // setRevoked() + /** + * Set the value of [serial] column. + * + * @param string $v new value + * @return $this|\Eater\Glim\Model\Certificate The current object (for fluent API support) + */ + public function setSerial($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->serial !== $v) { + $this->serial = $v; + $this->modifiedColumns[CertificateTableMap::COL_SERIAL] = true; + } + + return $this; + } // setSerial() + /** * Indicates whether the columns in this object are only set to default values. * @@ -550,8 +634,8 @@ abstract class Certificate implements ActiveRecordInterface $col = $row[TableMap::TYPE_NUM == $indexType ? 0 + $startcol : CertificateTableMap::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)]; $this->id = (null !== $col) ? (int) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 1 + $startcol : CertificateTableMap::translateFieldName('Userid', TableMap::TYPE_PHPNAME, $indexType)]; - $this->userid = (null !== $col) ? (int) $col : null; + $col = $row[TableMap::TYPE_NUM == $indexType ? 1 + $startcol : CertificateTableMap::translateFieldName('UserId', TableMap::TYPE_PHPNAME, $indexType)]; + $this->user_id = (null !== $col) ? (int) $col : null; $col = $row[TableMap::TYPE_NUM == $indexType ? 2 + $startcol : CertificateTableMap::translateFieldName('Name', TableMap::TYPE_PHPNAME, $indexType)]; $this->name = (null !== $col) ? (string) $col : null; @@ -559,8 +643,14 @@ abstract class Certificate implements ActiveRecordInterface $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : CertificateTableMap::translateFieldName('Certificate', TableMap::TYPE_PHPNAME, $indexType)]; $this->certificate = (null !== $col) ? (string) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : CertificateTableMap::translateFieldName('Revoked', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : CertificateTableMap::translateFieldName('ExpiresOn', TableMap::TYPE_PHPNAME, $indexType)]; + $this->expires_on = (null !== $col) ? PropelDateTime::newInstance($col, null, 'DateTime') : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : CertificateTableMap::translateFieldName('Revoked', TableMap::TYPE_PHPNAME, $indexType)]; $this->revoked = (null !== $col) ? (boolean) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 6 + $startcol : CertificateTableMap::translateFieldName('Serial', TableMap::TYPE_PHPNAME, $indexType)]; + $this->serial = (null !== $col) ? (string) $col : null; $this->resetModified(); $this->setNew(false); @@ -569,7 +659,7 @@ abstract class Certificate implements ActiveRecordInterface $this->ensureConsistency(); } - return $startcol + 5; // 5 = CertificateTableMap::NUM_HYDRATE_COLUMNS. + return $startcol + 7; // 7 = CertificateTableMap::NUM_HYDRATE_COLUMNS. } catch (Exception $e) { throw new PropelException(sprintf('Error populating %s object', '\\Eater\\Glim\\Model\\Certificate'), 0, $e); @@ -591,7 +681,7 @@ abstract class Certificate implements ActiveRecordInterface */ public function ensureConsistency() { - if ($this->aUser !== null && $this->userid !== $this->aUser->getId()) { + if ($this->aUser !== null && $this->user_id !== $this->aUser->getId()) { $this->aUser = null; } } // ensureConsistency @@ -785,8 +875,8 @@ abstract class Certificate implements ActiveRecordInterface if ($this->isColumnModified(CertificateTableMap::COL_ID)) { $modifiedColumns[':p' . $index++] = 'id'; } - if ($this->isColumnModified(CertificateTableMap::COL_USERID)) { - $modifiedColumns[':p' . $index++] = 'userId'; + if ($this->isColumnModified(CertificateTableMap::COL_USER_ID)) { + $modifiedColumns[':p' . $index++] = 'user_id'; } if ($this->isColumnModified(CertificateTableMap::COL_NAME)) { $modifiedColumns[':p' . $index++] = 'name'; @@ -794,9 +884,15 @@ abstract class Certificate implements ActiveRecordInterface if ($this->isColumnModified(CertificateTableMap::COL_CERTIFICATE)) { $modifiedColumns[':p' . $index++] = 'certificate'; } + if ($this->isColumnModified(CertificateTableMap::COL_EXPIRES_ON)) { + $modifiedColumns[':p' . $index++] = 'expires_on'; + } if ($this->isColumnModified(CertificateTableMap::COL_REVOKED)) { $modifiedColumns[':p' . $index++] = 'revoked'; } + if ($this->isColumnModified(CertificateTableMap::COL_SERIAL)) { + $modifiedColumns[':p' . $index++] = 'serial'; + } $sql = sprintf( 'INSERT INTO Certificate (%s) VALUES (%s)', @@ -811,8 +907,8 @@ abstract class Certificate implements ActiveRecordInterface case 'id': $stmt->bindValue($identifier, $this->id, PDO::PARAM_INT); break; - case 'userId': - $stmt->bindValue($identifier, $this->userid, PDO::PARAM_INT); + case 'user_id': + $stmt->bindValue($identifier, $this->user_id, PDO::PARAM_INT); break; case 'name': $stmt->bindValue($identifier, $this->name, PDO::PARAM_STR); @@ -820,9 +916,15 @@ abstract class Certificate implements ActiveRecordInterface case 'certificate': $stmt->bindValue($identifier, $this->certificate, PDO::PARAM_STR); break; + case 'expires_on': + $stmt->bindValue($identifier, $this->expires_on ? $this->expires_on->format("Y-m-d H:i:s") : null, PDO::PARAM_STR); + break; case 'revoked': $stmt->bindValue($identifier, $this->revoked, PDO::PARAM_BOOL); break; + case 'serial': + $stmt->bindValue($identifier, $this->serial, PDO::PARAM_STR); + break; } } $stmt->execute(); @@ -889,7 +991,7 @@ abstract class Certificate implements ActiveRecordInterface return $this->getId(); break; case 1: - return $this->getUserid(); + return $this->getUserId(); break; case 2: return $this->getName(); @@ -898,8 +1000,14 @@ abstract class Certificate implements ActiveRecordInterface return $this->getCertificate(); break; case 4: + return $this->getExpiresOn(); + break; + case 5: return $this->getRevoked(); break; + case 6: + return $this->getSerial(); + break; default: return null; break; @@ -931,11 +1039,21 @@ abstract class Certificate implements ActiveRecordInterface $keys = CertificateTableMap::getFieldNames($keyType); $result = array( $keys[0] => $this->getId(), - $keys[1] => $this->getUserid(), + $keys[1] => $this->getUserId(), $keys[2] => $this->getName(), $keys[3] => $this->getCertificate(), - $keys[4] => $this->getRevoked(), + $keys[4] => $this->getExpiresOn(), + $keys[5] => $this->getRevoked(), + $keys[6] => $this->getSerial(), ); + + $utc = new \DateTimeZone('utc'); + if ($result[$keys[4]] instanceof \DateTime) { + // When changing timezone we don't want to change existing instances + $dateTime = clone $result[$keys[4]]; + $result[$keys[4]] = $dateTime->setTimezone($utc)->format('Y-m-d\TH:i:s\Z'); + } + $virtualColumns = $this->virtualColumns; foreach ($virtualColumns as $key => $virtualColumn) { $result[$key] = $virtualColumn; @@ -995,7 +1113,7 @@ abstract class Certificate implements ActiveRecordInterface $this->setId($value); break; case 1: - $this->setUserid($value); + $this->setUserId($value); break; case 2: $this->setName($value); @@ -1004,8 +1122,14 @@ abstract class Certificate implements ActiveRecordInterface $this->setCertificate($value); break; case 4: + $this->setExpiresOn($value); + break; + case 5: $this->setRevoked($value); break; + case 6: + $this->setSerial($value); + break; } // switch() return $this; @@ -1036,7 +1160,7 @@ abstract class Certificate implements ActiveRecordInterface $this->setId($arr[$keys[0]]); } if (array_key_exists($keys[1], $arr)) { - $this->setUserid($arr[$keys[1]]); + $this->setUserId($arr[$keys[1]]); } if (array_key_exists($keys[2], $arr)) { $this->setName($arr[$keys[2]]); @@ -1045,7 +1169,13 @@ abstract class Certificate implements ActiveRecordInterface $this->setCertificate($arr[$keys[3]]); } if (array_key_exists($keys[4], $arr)) { - $this->setRevoked($arr[$keys[4]]); + $this->setExpiresOn($arr[$keys[4]]); + } + if (array_key_exists($keys[5], $arr)) { + $this->setRevoked($arr[$keys[5]]); + } + if (array_key_exists($keys[6], $arr)) { + $this->setSerial($arr[$keys[6]]); } } @@ -1091,8 +1221,8 @@ abstract class Certificate implements ActiveRecordInterface if ($this->isColumnModified(CertificateTableMap::COL_ID)) { $criteria->add(CertificateTableMap::COL_ID, $this->id); } - if ($this->isColumnModified(CertificateTableMap::COL_USERID)) { - $criteria->add(CertificateTableMap::COL_USERID, $this->userid); + if ($this->isColumnModified(CertificateTableMap::COL_USER_ID)) { + $criteria->add(CertificateTableMap::COL_USER_ID, $this->user_id); } if ($this->isColumnModified(CertificateTableMap::COL_NAME)) { $criteria->add(CertificateTableMap::COL_NAME, $this->name); @@ -1100,9 +1230,15 @@ abstract class Certificate implements ActiveRecordInterface if ($this->isColumnModified(CertificateTableMap::COL_CERTIFICATE)) { $criteria->add(CertificateTableMap::COL_CERTIFICATE, $this->certificate); } + if ($this->isColumnModified(CertificateTableMap::COL_EXPIRES_ON)) { + $criteria->add(CertificateTableMap::COL_EXPIRES_ON, $this->expires_on); + } if ($this->isColumnModified(CertificateTableMap::COL_REVOKED)) { $criteria->add(CertificateTableMap::COL_REVOKED, $this->revoked); } + if ($this->isColumnModified(CertificateTableMap::COL_SERIAL)) { + $criteria->add(CertificateTableMap::COL_SERIAL, $this->serial); + } return $criteria; } @@ -1189,10 +1325,12 @@ abstract class Certificate implements ActiveRecordInterface */ public function copyInto($copyObj, $deepCopy = false, $makeNew = true) { - $copyObj->setUserid($this->getUserid()); + $copyObj->setUserId($this->getUserId()); $copyObj->setName($this->getName()); $copyObj->setCertificate($this->getCertificate()); + $copyObj->setExpiresOn($this->getExpiresOn()); $copyObj->setRevoked($this->getRevoked()); + $copyObj->setSerial($this->getSerial()); if ($makeNew) { $copyObj->setNew(true); $copyObj->setId(NULL); // this is a auto-increment column, so set to default value @@ -1231,9 +1369,9 @@ abstract class Certificate implements ActiveRecordInterface public function setUser(ChildUser $v = null) { if ($v === null) { - $this->setUserid(NULL); + $this->setUserId(NULL); } else { - $this->setUserid($v->getId()); + $this->setUserId($v->getId()); } $this->aUser = $v; @@ -1258,8 +1396,8 @@ abstract class Certificate implements ActiveRecordInterface */ public function getUser(ConnectionInterface $con = null) { - if ($this->aUser === null && ($this->userid !== null)) { - $this->aUser = ChildUserQuery::create()->findPk($this->userid, $con); + if ($this->aUser === null && ($this->user_id !== null)) { + $this->aUser = ChildUserQuery::create()->findPk($this->user_id, $con); /* The following can be used additionally to guarantee the related object contains a reference to this object. This level of coupling may, however, be @@ -1283,10 +1421,12 @@ abstract class Certificate implements ActiveRecordInterface $this->aUser->removeCertificate($this); } $this->id = null; - $this->userid = null; + $this->user_id = null; $this->name = null; $this->certificate = null; + $this->expires_on = null; $this->revoked = null; + $this->serial = null; $this->alreadyInSave = false; $this->clearAllReferences(); $this->applyDefaultValues(); diff --git a/src/Model/Base/CertificateQuery.php b/src/Model/Base/CertificateQuery.php index 205d7b2..d5252d4 100644 --- a/src/Model/Base/CertificateQuery.php +++ b/src/Model/Base/CertificateQuery.php @@ -21,16 +21,20 @@ use Propel\Runtime\Exception\PropelException; * * * @method ChildCertificateQuery orderById($order = Criteria::ASC) Order by the id column - * @method ChildCertificateQuery orderByUserid($order = Criteria::ASC) Order by the userId column + * @method ChildCertificateQuery orderByUserId($order = Criteria::ASC) Order by the user_id column * @method ChildCertificateQuery orderByName($order = Criteria::ASC) Order by the name column * @method ChildCertificateQuery orderByCertificate($order = Criteria::ASC) Order by the certificate column + * @method ChildCertificateQuery orderByExpiresOn($order = Criteria::ASC) Order by the expires_on column * @method ChildCertificateQuery orderByRevoked($order = Criteria::ASC) Order by the revoked column + * @method ChildCertificateQuery orderBySerial($order = Criteria::ASC) Order by the serial column * * @method ChildCertificateQuery groupById() Group by the id column - * @method ChildCertificateQuery groupByUserid() Group by the userId column + * @method ChildCertificateQuery groupByUserId() Group by the user_id column * @method ChildCertificateQuery groupByName() Group by the name column * @method ChildCertificateQuery groupByCertificate() Group by the certificate column + * @method ChildCertificateQuery groupByExpiresOn() Group by the expires_on column * @method ChildCertificateQuery groupByRevoked() Group by the revoked column + * @method ChildCertificateQuery groupBySerial() Group by the serial column * * @method ChildCertificateQuery leftJoin($relation) Adds a LEFT JOIN clause to the query * @method ChildCertificateQuery rightJoin($relation) Adds a RIGHT JOIN clause to the query @@ -46,26 +50,32 @@ use Propel\Runtime\Exception\PropelException; * @method ChildCertificate findOneOrCreate(ConnectionInterface $con = null) Return the first ChildCertificate matching the query, or a new ChildCertificate object populated from the query conditions when no match is found * * @method ChildCertificate findOneById(int $id) Return the first ChildCertificate filtered by the id column - * @method ChildCertificate findOneByUserid(int $userId) Return the first ChildCertificate filtered by the userId column + * @method ChildCertificate findOneByUserId(int $user_id) Return the first ChildCertificate filtered by the user_id column * @method ChildCertificate findOneByName(string $name) Return the first ChildCertificate filtered by the name column * @method ChildCertificate findOneByCertificate(string $certificate) Return the first ChildCertificate filtered by the certificate column - * @method ChildCertificate findOneByRevoked(boolean $revoked) Return the first ChildCertificate filtered by the revoked column * + * @method ChildCertificate findOneByExpiresOn(string $expires_on) Return the first ChildCertificate filtered by the expires_on column + * @method ChildCertificate findOneByRevoked(boolean $revoked) Return the first ChildCertificate filtered by the revoked column + * @method ChildCertificate findOneBySerial(string $serial) Return the first ChildCertificate filtered by the serial column * * @method ChildCertificate requirePk($key, ConnectionInterface $con = null) Return the ChildCertificate by primary key and throws \Propel\Runtime\Exception\EntityNotFoundException when not found * @method ChildCertificate requireOne(ConnectionInterface $con = null) Return the first ChildCertificate matching the query and throws \Propel\Runtime\Exception\EntityNotFoundException when not found * * @method ChildCertificate requireOneById(int $id) Return the first ChildCertificate filtered by the id column and throws \Propel\Runtime\Exception\EntityNotFoundException when not found - * @method ChildCertificate requireOneByUserid(int $userId) Return the first ChildCertificate filtered by the userId column and throws \Propel\Runtime\Exception\EntityNotFoundException when not found + * @method ChildCertificate requireOneByUserId(int $user_id) Return the first ChildCertificate filtered by the user_id column and throws \Propel\Runtime\Exception\EntityNotFoundException when not found * @method ChildCertificate requireOneByName(string $name) Return the first ChildCertificate filtered by the name column and throws \Propel\Runtime\Exception\EntityNotFoundException when not found * @method ChildCertificate requireOneByCertificate(string $certificate) Return the first ChildCertificate filtered by the certificate column and throws \Propel\Runtime\Exception\EntityNotFoundException when not found + * @method ChildCertificate requireOneByExpiresOn(string $expires_on) Return the first ChildCertificate filtered by the expires_on column and throws \Propel\Runtime\Exception\EntityNotFoundException when not found * @method ChildCertificate requireOneByRevoked(boolean $revoked) Return the first ChildCertificate filtered by the revoked column and throws \Propel\Runtime\Exception\EntityNotFoundException when not found + * @method ChildCertificate requireOneBySerial(string $serial) Return the first ChildCertificate filtered by the serial column and throws \Propel\Runtime\Exception\EntityNotFoundException when not found * * @method ChildCertificate[]|ObjectCollection find(ConnectionInterface $con = null) Return ChildCertificate objects based on current ModelCriteria * @method ChildCertificate[]|ObjectCollection findById(int $id) Return ChildCertificate objects filtered by the id column - * @method ChildCertificate[]|ObjectCollection findByUserid(int $userId) Return ChildCertificate objects filtered by the userId column + * @method ChildCertificate[]|ObjectCollection findByUserId(int $user_id) Return ChildCertificate objects filtered by the user_id column * @method ChildCertificate[]|ObjectCollection findByName(string $name) Return ChildCertificate objects filtered by the name column * @method ChildCertificate[]|ObjectCollection findByCertificate(string $certificate) Return ChildCertificate objects filtered by the certificate column + * @method ChildCertificate[]|ObjectCollection findByExpiresOn(string $expires_on) Return ChildCertificate objects filtered by the expires_on column * @method ChildCertificate[]|ObjectCollection findByRevoked(boolean $revoked) Return ChildCertificate objects filtered by the revoked column + * @method ChildCertificate[]|ObjectCollection findBySerial(string $serial) Return ChildCertificate objects filtered by the serial column * @method ChildCertificate[]|\Propel\Runtime\Util\PropelModelPager paginate($page = 1, $maxPerPage = 10, ConnectionInterface $con = null) Issue a SELECT query based on the current ModelCriteria and uses a page and a maximum number of results per page to compute an offset and a limit * */ @@ -158,7 +168,7 @@ abstract class CertificateQuery extends ModelCriteria */ protected function findPkSimple($key, ConnectionInterface $con) { - $sql = 'SELECT id, userId, name, certificate, revoked FROM Certificate WHERE id = :p0'; + $sql = 'SELECT id, user_id, name, certificate, expires_on, revoked, serial FROM Certificate WHERE id = :p0'; try { $stmt = $con->prepare($sql); $stmt->bindValue(':p0', $key, PDO::PARAM_INT); @@ -290,18 +300,18 @@ abstract class CertificateQuery extends ModelCriteria } /** - * Filter the query on the userId column + * Filter the query on the user_id column * * Example usage: * - * $query->filterByUserid(1234); // WHERE userId = 1234 - * $query->filterByUserid(array(12, 34)); // WHERE userId IN (12, 34) - * $query->filterByUserid(array('min' => 12)); // WHERE userId > 12 + * $query->filterByUserId(1234); // WHERE user_id = 1234 + * $query->filterByUserId(array(12, 34)); // WHERE user_id IN (12, 34) + * $query->filterByUserId(array('min' => 12)); // WHERE user_id > 12 * * * @see filterByUser() * - * @param mixed $userid The value to use as filter. + * @param mixed $userId The value to use as filter. * Use scalar values for equality. * Use array values for in_array() equivalent. * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. @@ -309,16 +319,16 @@ abstract class CertificateQuery extends ModelCriteria * * @return $this|ChildCertificateQuery The current query, for fluid interface */ - public function filterByUserid($userid = null, $comparison = null) + public function filterByUserId($userId = null, $comparison = null) { - if (is_array($userid)) { + if (is_array($userId)) { $useMinMax = false; - if (isset($userid['min'])) { - $this->addUsingAlias(CertificateTableMap::COL_USERID, $userid['min'], Criteria::GREATER_EQUAL); + if (isset($userId['min'])) { + $this->addUsingAlias(CertificateTableMap::COL_USER_ID, $userId['min'], Criteria::GREATER_EQUAL); $useMinMax = true; } - if (isset($userid['max'])) { - $this->addUsingAlias(CertificateTableMap::COL_USERID, $userid['max'], Criteria::LESS_EQUAL); + if (isset($userId['max'])) { + $this->addUsingAlias(CertificateTableMap::COL_USER_ID, $userId['max'], Criteria::LESS_EQUAL); $useMinMax = true; } if ($useMinMax) { @@ -329,7 +339,7 @@ abstract class CertificateQuery extends ModelCriteria } } - return $this->addUsingAlias(CertificateTableMap::COL_USERID, $userid, $comparison); + return $this->addUsingAlias(CertificateTableMap::COL_USER_ID, $userId, $comparison); } /** @@ -390,6 +400,49 @@ abstract class CertificateQuery extends ModelCriteria return $this->addUsingAlias(CertificateTableMap::COL_CERTIFICATE, $certificate, $comparison); } + /** + * Filter the query on the expires_on column + * + * Example usage: + * + * $query->filterByExpiresOn('2011-03-14'); // WHERE expires_on = '2011-03-14' + * $query->filterByExpiresOn('now'); // WHERE expires_on = '2011-03-14' + * $query->filterByExpiresOn(array('max' => 'yesterday')); // WHERE expires_on > '2011-03-13' + * + * + * @param mixed $expiresOn The value to use as filter. + * Values can be integers (unix timestamps), DateTime objects, or strings. + * Empty strings are treated as NULL. + * Use scalar values for equality. + * Use array values for in_array() equivalent. + * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return $this|ChildCertificateQuery The current query, for fluid interface + */ + public function filterByExpiresOn($expiresOn = null, $comparison = null) + { + if (is_array($expiresOn)) { + $useMinMax = false; + if (isset($expiresOn['min'])) { + $this->addUsingAlias(CertificateTableMap::COL_EXPIRES_ON, $expiresOn['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($expiresOn['max'])) { + $this->addUsingAlias(CertificateTableMap::COL_EXPIRES_ON, $expiresOn['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(CertificateTableMap::COL_EXPIRES_ON, $expiresOn, $comparison); + } + /** * Filter the query on the revoked column * @@ -417,6 +470,35 @@ abstract class CertificateQuery extends ModelCriteria return $this->addUsingAlias(CertificateTableMap::COL_REVOKED, $revoked, $comparison); } + /** + * Filter the query on the serial column + * + * Example usage: + * + * $query->filterBySerial('fooValue'); // WHERE serial = 'fooValue' + * $query->filterBySerial('%fooValue%'); // WHERE serial LIKE '%fooValue%' + * + * + * @param string $serial The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return $this|ChildCertificateQuery The current query, for fluid interface + */ + public function filterBySerial($serial = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($serial)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $serial)) { + $serial = str_replace('*', '%', $serial); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(CertificateTableMap::COL_SERIAL, $serial, $comparison); + } + /** * Filter the query by a related \Eater\Glim\Model\User object * @@ -431,14 +513,14 @@ abstract class CertificateQuery extends ModelCriteria { if ($user instanceof \Eater\Glim\Model\User) { return $this - ->addUsingAlias(CertificateTableMap::COL_USERID, $user->getId(), $comparison); + ->addUsingAlias(CertificateTableMap::COL_USER_ID, $user->getId(), $comparison); } elseif ($user instanceof ObjectCollection) { if (null === $comparison) { $comparison = Criteria::IN; } return $this - ->addUsingAlias(CertificateTableMap::COL_USERID, $user->toKeyValue('PrimaryKey', 'Id'), $comparison); + ->addUsingAlias(CertificateTableMap::COL_USER_ID, $user->toKeyValue('PrimaryKey', 'Id'), $comparison); } else { throw new PropelException('filterByUser() only accepts arguments of type \Eater\Glim\Model\User or Collection'); } diff --git a/src/Model/Base/User.php b/src/Model/Base/User.php index e0b99aa..83a33a9 100644 --- a/src/Model/Base/User.php +++ b/src/Model/Base/User.php @@ -70,11 +70,11 @@ abstract class User implements ActiveRecordInterface protected $id; /** - * The value for the maxkeys field. + * The value for the max_keys field. * Note: this column has a database default value of: 5 * @var int */ - protected $maxkeys; + protected $max_keys; /** * The value for the username field. @@ -123,7 +123,7 @@ abstract class User implements ActiveRecordInterface */ public function applyDefaultValues() { - $this->maxkeys = 5; + $this->max_keys = 5; $this->superuser = false; } @@ -357,13 +357,13 @@ abstract class User implements ActiveRecordInterface } /** - * Get the [maxkeys] column value. + * Get the [max_keys] column value. * * @return int */ - public function getMaxkeys() + public function getMaxKeys() { - return $this->maxkeys; + return $this->max_keys; } /** @@ -427,24 +427,24 @@ abstract class User implements ActiveRecordInterface } // setId() /** - * Set the value of [maxkeys] column. + * Set the value of [max_keys] column. * * @param int $v new value * @return $this|\Eater\Glim\Model\User The current object (for fluent API support) */ - public function setMaxkeys($v) + public function setMaxKeys($v) { if ($v !== null) { $v = (int) $v; } - if ($this->maxkeys !== $v) { - $this->maxkeys = $v; - $this->modifiedColumns[UserTableMap::COL_MAXKEYS] = true; + if ($this->max_keys !== $v) { + $this->max_keys = $v; + $this->modifiedColumns[UserTableMap::COL_MAX_KEYS] = true; } return $this; - } // setMaxkeys() + } // setMaxKeys() /** * Set the value of [username] column. @@ -524,7 +524,7 @@ abstract class User implements ActiveRecordInterface */ public function hasOnlyDefaultValues() { - if ($this->maxkeys !== 5) { + if ($this->max_keys !== 5) { return false; } @@ -561,8 +561,8 @@ abstract class User implements ActiveRecordInterface $col = $row[TableMap::TYPE_NUM == $indexType ? 0 + $startcol : UserTableMap::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)]; $this->id = (null !== $col) ? (int) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 1 + $startcol : UserTableMap::translateFieldName('Maxkeys', TableMap::TYPE_PHPNAME, $indexType)]; - $this->maxkeys = (null !== $col) ? (int) $col : null; + $col = $row[TableMap::TYPE_NUM == $indexType ? 1 + $startcol : UserTableMap::translateFieldName('MaxKeys', TableMap::TYPE_PHPNAME, $indexType)]; + $this->max_keys = (null !== $col) ? (int) $col : null; $col = $row[TableMap::TYPE_NUM == $indexType ? 2 + $startcol : UserTableMap::translateFieldName('Username', TableMap::TYPE_PHPNAME, $indexType)]; $this->username = (null !== $col) ? (string) $col : null; @@ -800,8 +800,8 @@ abstract class User implements ActiveRecordInterface if ($this->isColumnModified(UserTableMap::COL_ID)) { $modifiedColumns[':p' . $index++] = 'id'; } - if ($this->isColumnModified(UserTableMap::COL_MAXKEYS)) { - $modifiedColumns[':p' . $index++] = 'maxKeys'; + if ($this->isColumnModified(UserTableMap::COL_MAX_KEYS)) { + $modifiedColumns[':p' . $index++] = 'max_keys'; } if ($this->isColumnModified(UserTableMap::COL_USERNAME)) { $modifiedColumns[':p' . $index++] = 'username'; @@ -826,8 +826,8 @@ abstract class User implements ActiveRecordInterface case 'id': $stmt->bindValue($identifier, $this->id, PDO::PARAM_INT); break; - case 'maxKeys': - $stmt->bindValue($identifier, $this->maxkeys, PDO::PARAM_INT); + case 'max_keys': + $stmt->bindValue($identifier, $this->max_keys, PDO::PARAM_INT); break; case 'username': $stmt->bindValue($identifier, $this->username, PDO::PARAM_STR); @@ -904,7 +904,7 @@ abstract class User implements ActiveRecordInterface return $this->getId(); break; case 1: - return $this->getMaxkeys(); + return $this->getMaxKeys(); break; case 2: return $this->getUsername(); @@ -946,7 +946,7 @@ abstract class User implements ActiveRecordInterface $keys = UserTableMap::getFieldNames($keyType); $result = array( $keys[0] => $this->getId(), - $keys[1] => $this->getMaxkeys(), + $keys[1] => $this->getMaxKeys(), $keys[2] => $this->getUsername(), $keys[3] => $this->getPassword(), $keys[4] => $this->getSuperuser(), @@ -1010,7 +1010,7 @@ abstract class User implements ActiveRecordInterface $this->setId($value); break; case 1: - $this->setMaxkeys($value); + $this->setMaxKeys($value); break; case 2: $this->setUsername($value); @@ -1051,7 +1051,7 @@ abstract class User implements ActiveRecordInterface $this->setId($arr[$keys[0]]); } if (array_key_exists($keys[1], $arr)) { - $this->setMaxkeys($arr[$keys[1]]); + $this->setMaxKeys($arr[$keys[1]]); } if (array_key_exists($keys[2], $arr)) { $this->setUsername($arr[$keys[2]]); @@ -1106,8 +1106,8 @@ abstract class User implements ActiveRecordInterface if ($this->isColumnModified(UserTableMap::COL_ID)) { $criteria->add(UserTableMap::COL_ID, $this->id); } - if ($this->isColumnModified(UserTableMap::COL_MAXKEYS)) { - $criteria->add(UserTableMap::COL_MAXKEYS, $this->maxkeys); + if ($this->isColumnModified(UserTableMap::COL_MAX_KEYS)) { + $criteria->add(UserTableMap::COL_MAX_KEYS, $this->max_keys); } if ($this->isColumnModified(UserTableMap::COL_USERNAME)) { $criteria->add(UserTableMap::COL_USERNAME, $this->username); @@ -1204,7 +1204,7 @@ abstract class User implements ActiveRecordInterface */ public function copyInto($copyObj, $deepCopy = false, $makeNew = true) { - $copyObj->setMaxkeys($this->getMaxkeys()); + $copyObj->setMaxKeys($this->getMaxKeys()); $copyObj->setUsername($this->getUsername()); $copyObj->setPassword($this->getPassword()); $copyObj->setSuperuser($this->getSuperuser()); @@ -1492,7 +1492,7 @@ abstract class User implements ActiveRecordInterface public function clear() { $this->id = null; - $this->maxkeys = null; + $this->max_keys = null; $this->username = null; $this->password = null; $this->superuser = null; diff --git a/src/Model/Base/UserQuery.php b/src/Model/Base/UserQuery.php index 24af5b5..43fb663 100644 --- a/src/Model/Base/UserQuery.php +++ b/src/Model/Base/UserQuery.php @@ -21,13 +21,13 @@ use Propel\Runtime\Exception\PropelException; * * * @method ChildUserQuery orderById($order = Criteria::ASC) Order by the id column - * @method ChildUserQuery orderByMaxkeys($order = Criteria::ASC) Order by the maxKeys column + * @method ChildUserQuery orderByMaxKeys($order = Criteria::ASC) Order by the max_keys column * @method ChildUserQuery orderByUsername($order = Criteria::ASC) Order by the username column * @method ChildUserQuery orderByPassword($order = Criteria::ASC) Order by the password column * @method ChildUserQuery orderBySuperuser($order = Criteria::ASC) Order by the superuser column * * @method ChildUserQuery groupById() Group by the id column - * @method ChildUserQuery groupByMaxkeys() Group by the maxKeys column + * @method ChildUserQuery groupByMaxKeys() Group by the max_keys column * @method ChildUserQuery groupByUsername() Group by the username column * @method ChildUserQuery groupByPassword() Group by the password column * @method ChildUserQuery groupBySuperuser() Group by the superuser column @@ -46,7 +46,7 @@ use Propel\Runtime\Exception\PropelException; * @method ChildUser findOneOrCreate(ConnectionInterface $con = null) Return the first ChildUser matching the query, or a new ChildUser object populated from the query conditions when no match is found * * @method ChildUser findOneById(int $id) Return the first ChildUser filtered by the id column - * @method ChildUser findOneByMaxkeys(int $maxKeys) Return the first ChildUser filtered by the maxKeys column + * @method ChildUser findOneByMaxKeys(int $max_keys) Return the first ChildUser filtered by the max_keys column * @method ChildUser findOneByUsername(string $username) Return the first ChildUser filtered by the username column * @method ChildUser findOneByPassword(string $password) Return the first ChildUser filtered by the password column * @method ChildUser findOneBySuperuser(boolean $superuser) Return the first ChildUser filtered by the superuser column * @@ -55,14 +55,14 @@ use Propel\Runtime\Exception\PropelException; * @method ChildUser requireOne(ConnectionInterface $con = null) Return the first ChildUser matching the query and throws \Propel\Runtime\Exception\EntityNotFoundException when not found * * @method ChildUser requireOneById(int $id) Return the first ChildUser filtered by the id column and throws \Propel\Runtime\Exception\EntityNotFoundException when not found - * @method ChildUser requireOneByMaxkeys(int $maxKeys) Return the first ChildUser filtered by the maxKeys column and throws \Propel\Runtime\Exception\EntityNotFoundException when not found + * @method ChildUser requireOneByMaxKeys(int $max_keys) Return the first ChildUser filtered by the max_keys column and throws \Propel\Runtime\Exception\EntityNotFoundException when not found * @method ChildUser requireOneByUsername(string $username) Return the first ChildUser filtered by the username column and throws \Propel\Runtime\Exception\EntityNotFoundException when not found * @method ChildUser requireOneByPassword(string $password) Return the first ChildUser filtered by the password column and throws \Propel\Runtime\Exception\EntityNotFoundException when not found * @method ChildUser requireOneBySuperuser(boolean $superuser) Return the first ChildUser filtered by the superuser column and throws \Propel\Runtime\Exception\EntityNotFoundException when not found * * @method ChildUser[]|ObjectCollection find(ConnectionInterface $con = null) Return ChildUser objects based on current ModelCriteria * @method ChildUser[]|ObjectCollection findById(int $id) Return ChildUser objects filtered by the id column - * @method ChildUser[]|ObjectCollection findByMaxkeys(int $maxKeys) Return ChildUser objects filtered by the maxKeys column + * @method ChildUser[]|ObjectCollection findByMaxKeys(int $max_keys) Return ChildUser objects filtered by the max_keys column * @method ChildUser[]|ObjectCollection findByUsername(string $username) Return ChildUser objects filtered by the username column * @method ChildUser[]|ObjectCollection findByPassword(string $password) Return ChildUser objects filtered by the password column * @method ChildUser[]|ObjectCollection findBySuperuser(boolean $superuser) Return ChildUser objects filtered by the superuser column @@ -158,7 +158,7 @@ abstract class UserQuery extends ModelCriteria */ protected function findPkSimple($key, ConnectionInterface $con) { - $sql = 'SELECT id, maxKeys, username, password, superuser FROM User WHERE id = :p0'; + $sql = 'SELECT id, max_keys, username, password, superuser FROM User WHERE id = :p0'; try { $stmt = $con->prepare($sql); $stmt->bindValue(':p0', $key, PDO::PARAM_INT); @@ -290,16 +290,16 @@ abstract class UserQuery extends ModelCriteria } /** - * Filter the query on the maxKeys column + * Filter the query on the max_keys column * * Example usage: * - * $query->filterByMaxkeys(1234); // WHERE maxKeys = 1234 - * $query->filterByMaxkeys(array(12, 34)); // WHERE maxKeys IN (12, 34) - * $query->filterByMaxkeys(array('min' => 12)); // WHERE maxKeys > 12 + * $query->filterByMaxKeys(1234); // WHERE max_keys = 1234 + * $query->filterByMaxKeys(array(12, 34)); // WHERE max_keys IN (12, 34) + * $query->filterByMaxKeys(array('min' => 12)); // WHERE max_keys > 12 * * - * @param mixed $maxkeys The value to use as filter. + * @param mixed $maxKeys The value to use as filter. * Use scalar values for equality. * Use array values for in_array() equivalent. * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. @@ -307,16 +307,16 @@ abstract class UserQuery extends ModelCriteria * * @return $this|ChildUserQuery The current query, for fluid interface */ - public function filterByMaxkeys($maxkeys = null, $comparison = null) + public function filterByMaxKeys($maxKeys = null, $comparison = null) { - if (is_array($maxkeys)) { + if (is_array($maxKeys)) { $useMinMax = false; - if (isset($maxkeys['min'])) { - $this->addUsingAlias(UserTableMap::COL_MAXKEYS, $maxkeys['min'], Criteria::GREATER_EQUAL); + if (isset($maxKeys['min'])) { + $this->addUsingAlias(UserTableMap::COL_MAX_KEYS, $maxKeys['min'], Criteria::GREATER_EQUAL); $useMinMax = true; } - if (isset($maxkeys['max'])) { - $this->addUsingAlias(UserTableMap::COL_MAXKEYS, $maxkeys['max'], Criteria::LESS_EQUAL); + if (isset($maxKeys['max'])) { + $this->addUsingAlias(UserTableMap::COL_MAX_KEYS, $maxKeys['max'], Criteria::LESS_EQUAL); $useMinMax = true; } if ($useMinMax) { @@ -327,7 +327,7 @@ abstract class UserQuery extends ModelCriteria } } - return $this->addUsingAlias(UserTableMap::COL_MAXKEYS, $maxkeys, $comparison); + return $this->addUsingAlias(UserTableMap::COL_MAX_KEYS, $maxKeys, $comparison); } /** @@ -427,7 +427,7 @@ abstract class UserQuery extends ModelCriteria { if ($certificate instanceof \Eater\Glim\Model\Certificate) { return $this - ->addUsingAlias(UserTableMap::COL_ID, $certificate->getUserid(), $comparison); + ->addUsingAlias(UserTableMap::COL_ID, $certificate->getUserId(), $comparison); } elseif ($certificate instanceof ObjectCollection) { return $this ->useCertificateQuery() diff --git a/src/Model/Map/CertificateTableMap.php b/src/Model/Map/CertificateTableMap.php index fc47354..aba639b 100644 --- a/src/Model/Map/CertificateTableMap.php +++ b/src/Model/Map/CertificateTableMap.php @@ -59,7 +59,7 @@ class CertificateTableMap extends TableMap /** * The total number of columns */ - const NUM_COLUMNS = 5; + const NUM_COLUMNS = 7; /** * The number of lazy-loaded columns @@ -69,7 +69,7 @@ class CertificateTableMap extends TableMap /** * The number of columns to hydrate (NUM_COLUMNS - NUM_LAZY_LOAD_COLUMNS) */ - const NUM_HYDRATE_COLUMNS = 5; + const NUM_HYDRATE_COLUMNS = 7; /** * the column name for the id field @@ -77,9 +77,9 @@ class CertificateTableMap extends TableMap const COL_ID = 'Certificate.id'; /** - * the column name for the userId field + * the column name for the user_id field */ - const COL_USERID = 'Certificate.userId'; + const COL_USER_ID = 'Certificate.user_id'; /** * the column name for the name field @@ -91,11 +91,21 @@ class CertificateTableMap extends TableMap */ const COL_CERTIFICATE = 'Certificate.certificate'; + /** + * the column name for the expires_on field + */ + const COL_EXPIRES_ON = 'Certificate.expires_on'; + /** * the column name for the revoked field */ const COL_REVOKED = 'Certificate.revoked'; + /** + * the column name for the serial field + */ + const COL_SERIAL = 'Certificate.serial'; + /** * The default string format for model objects of the related table */ @@ -108,11 +118,11 @@ class CertificateTableMap extends TableMap * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' */ protected static $fieldNames = array ( - self::TYPE_PHPNAME => array('Id', 'Userid', 'Name', 'Certificate', 'Revoked', ), - self::TYPE_CAMELNAME => array('id', 'userid', 'name', 'certificate', 'revoked', ), - self::TYPE_COLNAME => array(CertificateTableMap::COL_ID, CertificateTableMap::COL_USERID, CertificateTableMap::COL_NAME, CertificateTableMap::COL_CERTIFICATE, CertificateTableMap::COL_REVOKED, ), - self::TYPE_FIELDNAME => array('id', 'userId', 'name', 'certificate', 'revoked', ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, ) + self::TYPE_PHPNAME => array('Id', 'UserId', 'Name', 'Certificate', 'ExpiresOn', 'Revoked', 'Serial', ), + self::TYPE_CAMELNAME => array('id', 'userId', 'name', 'certificate', 'expiresOn', 'revoked', 'serial', ), + self::TYPE_COLNAME => array(CertificateTableMap::COL_ID, CertificateTableMap::COL_USER_ID, CertificateTableMap::COL_NAME, CertificateTableMap::COL_CERTIFICATE, CertificateTableMap::COL_EXPIRES_ON, CertificateTableMap::COL_REVOKED, CertificateTableMap::COL_SERIAL, ), + self::TYPE_FIELDNAME => array('id', 'user_id', 'name', 'certificate', 'expires_on', 'revoked', 'serial', ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, ) ); /** @@ -122,11 +132,11 @@ class CertificateTableMap extends TableMap * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 */ protected static $fieldKeys = array ( - self::TYPE_PHPNAME => array('Id' => 0, 'Userid' => 1, 'Name' => 2, 'Certificate' => 3, 'Revoked' => 4, ), - self::TYPE_CAMELNAME => array('id' => 0, 'userid' => 1, 'name' => 2, 'certificate' => 3, 'revoked' => 4, ), - self::TYPE_COLNAME => array(CertificateTableMap::COL_ID => 0, CertificateTableMap::COL_USERID => 1, CertificateTableMap::COL_NAME => 2, CertificateTableMap::COL_CERTIFICATE => 3, CertificateTableMap::COL_REVOKED => 4, ), - self::TYPE_FIELDNAME => array('id' => 0, 'userId' => 1, 'name' => 2, 'certificate' => 3, 'revoked' => 4, ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, ) + self::TYPE_PHPNAME => array('Id' => 0, 'UserId' => 1, 'Name' => 2, 'Certificate' => 3, 'ExpiresOn' => 4, 'Revoked' => 5, 'Serial' => 6, ), + self::TYPE_CAMELNAME => array('id' => 0, 'userId' => 1, 'name' => 2, 'certificate' => 3, 'expiresOn' => 4, 'revoked' => 5, 'serial' => 6, ), + self::TYPE_COLNAME => array(CertificateTableMap::COL_ID => 0, CertificateTableMap::COL_USER_ID => 1, CertificateTableMap::COL_NAME => 2, CertificateTableMap::COL_CERTIFICATE => 3, CertificateTableMap::COL_EXPIRES_ON => 4, CertificateTableMap::COL_REVOKED => 5, CertificateTableMap::COL_SERIAL => 6, ), + self::TYPE_FIELDNAME => array('id' => 0, 'user_id' => 1, 'name' => 2, 'certificate' => 3, 'expires_on' => 4, 'revoked' => 5, 'serial' => 6, ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, ) ); /** @@ -147,10 +157,12 @@ class CertificateTableMap extends TableMap $this->setUseIdGenerator(true); // columns $this->addPrimaryKey('id', 'Id', 'INTEGER', true, null, null); - $this->addForeignKey('userId', 'Userid', 'INTEGER', 'User', 'id', false, null, null); + $this->addForeignKey('user_id', 'UserId', 'INTEGER', 'User', 'id', false, null, null); $this->addColumn('name', 'Name', 'VARCHAR', false, 64, null); $this->addColumn('certificate', 'Certificate', 'LONGVARCHAR', false, null, null); + $this->addColumn('expires_on', 'ExpiresOn', 'TIMESTAMP', false, null, null); $this->addColumn('revoked', 'Revoked', 'BOOLEAN', false, null, false); + $this->addColumn('serial', 'Serial', 'VARCHAR', false, 64, null); } // initialize() /** @@ -161,7 +173,7 @@ class CertificateTableMap extends TableMap $this->addRelation('User', '\\Eater\\Glim\\Model\\User', RelationMap::MANY_TO_ONE, array ( 0 => array ( - 0 => ':userId', + 0 => ':user_id', 1 => ':id', ), ), null, null, null, false); @@ -309,16 +321,20 @@ class CertificateTableMap extends TableMap { if (null === $alias) { $criteria->addSelectColumn(CertificateTableMap::COL_ID); - $criteria->addSelectColumn(CertificateTableMap::COL_USERID); + $criteria->addSelectColumn(CertificateTableMap::COL_USER_ID); $criteria->addSelectColumn(CertificateTableMap::COL_NAME); $criteria->addSelectColumn(CertificateTableMap::COL_CERTIFICATE); + $criteria->addSelectColumn(CertificateTableMap::COL_EXPIRES_ON); $criteria->addSelectColumn(CertificateTableMap::COL_REVOKED); + $criteria->addSelectColumn(CertificateTableMap::COL_SERIAL); } else { $criteria->addSelectColumn($alias . '.id'); - $criteria->addSelectColumn($alias . '.userId'); + $criteria->addSelectColumn($alias . '.user_id'); $criteria->addSelectColumn($alias . '.name'); $criteria->addSelectColumn($alias . '.certificate'); + $criteria->addSelectColumn($alias . '.expires_on'); $criteria->addSelectColumn($alias . '.revoked'); + $criteria->addSelectColumn($alias . '.serial'); } } diff --git a/src/Model/Map/UserTableMap.php b/src/Model/Map/UserTableMap.php index 99f1710..c70cf22 100644 --- a/src/Model/Map/UserTableMap.php +++ b/src/Model/Map/UserTableMap.php @@ -77,9 +77,9 @@ class UserTableMap extends TableMap const COL_ID = 'User.id'; /** - * the column name for the maxKeys field + * the column name for the max_keys field */ - const COL_MAXKEYS = 'User.maxKeys'; + const COL_MAX_KEYS = 'User.max_keys'; /** * the column name for the username field @@ -108,10 +108,10 @@ class UserTableMap extends TableMap * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' */ protected static $fieldNames = array ( - self::TYPE_PHPNAME => array('Id', 'Maxkeys', 'Username', 'Password', 'Superuser', ), - self::TYPE_CAMELNAME => array('id', 'maxkeys', 'username', 'password', 'superuser', ), - self::TYPE_COLNAME => array(UserTableMap::COL_ID, UserTableMap::COL_MAXKEYS, UserTableMap::COL_USERNAME, UserTableMap::COL_PASSWORD, UserTableMap::COL_SUPERUSER, ), - self::TYPE_FIELDNAME => array('id', 'maxKeys', 'username', 'password', 'superuser', ), + self::TYPE_PHPNAME => array('Id', 'MaxKeys', 'Username', 'Password', 'Superuser', ), + self::TYPE_CAMELNAME => array('id', 'maxKeys', 'username', 'password', 'superuser', ), + self::TYPE_COLNAME => array(UserTableMap::COL_ID, UserTableMap::COL_MAX_KEYS, UserTableMap::COL_USERNAME, UserTableMap::COL_PASSWORD, UserTableMap::COL_SUPERUSER, ), + self::TYPE_FIELDNAME => array('id', 'max_keys', 'username', 'password', 'superuser', ), self::TYPE_NUM => array(0, 1, 2, 3, 4, ) ); @@ -122,10 +122,10 @@ class UserTableMap extends TableMap * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 */ protected static $fieldKeys = array ( - self::TYPE_PHPNAME => array('Id' => 0, 'Maxkeys' => 1, 'Username' => 2, 'Password' => 3, 'Superuser' => 4, ), - self::TYPE_CAMELNAME => array('id' => 0, 'maxkeys' => 1, 'username' => 2, 'password' => 3, 'superuser' => 4, ), - self::TYPE_COLNAME => array(UserTableMap::COL_ID => 0, UserTableMap::COL_MAXKEYS => 1, UserTableMap::COL_USERNAME => 2, UserTableMap::COL_PASSWORD => 3, UserTableMap::COL_SUPERUSER => 4, ), - self::TYPE_FIELDNAME => array('id' => 0, 'maxKeys' => 1, 'username' => 2, 'password' => 3, 'superuser' => 4, ), + self::TYPE_PHPNAME => array('Id' => 0, 'MaxKeys' => 1, 'Username' => 2, 'Password' => 3, 'Superuser' => 4, ), + self::TYPE_CAMELNAME => array('id' => 0, 'maxKeys' => 1, 'username' => 2, 'password' => 3, 'superuser' => 4, ), + self::TYPE_COLNAME => array(UserTableMap::COL_ID => 0, UserTableMap::COL_MAX_KEYS => 1, UserTableMap::COL_USERNAME => 2, UserTableMap::COL_PASSWORD => 3, UserTableMap::COL_SUPERUSER => 4, ), + self::TYPE_FIELDNAME => array('id' => 0, 'max_keys' => 1, 'username' => 2, 'password' => 3, 'superuser' => 4, ), self::TYPE_NUM => array(0, 1, 2, 3, 4, ) ); @@ -147,7 +147,7 @@ class UserTableMap extends TableMap $this->setUseIdGenerator(true); // columns $this->addPrimaryKey('id', 'Id', 'INTEGER', true, null, null); - $this->addColumn('maxKeys', 'Maxkeys', 'INTEGER', false, null, 5); + $this->addColumn('max_keys', 'MaxKeys', 'INTEGER', false, null, 5); $this->addColumn('username', 'Username', 'VARCHAR', false, 64, null); $this->addColumn('password', 'Password', 'VARCHAR', false, 64, null); $this->addColumn('superuser', 'Superuser', 'BOOLEAN', false, null, false); @@ -161,7 +161,7 @@ class UserTableMap extends TableMap $this->addRelation('Certificate', '\\Eater\\Glim\\Model\\Certificate', RelationMap::ONE_TO_MANY, array ( 0 => array ( - 0 => ':userId', + 0 => ':user_id', 1 => ':id', ), ), null, null, 'Certificates', false); @@ -309,13 +309,13 @@ class UserTableMap extends TableMap { if (null === $alias) { $criteria->addSelectColumn(UserTableMap::COL_ID); - $criteria->addSelectColumn(UserTableMap::COL_MAXKEYS); + $criteria->addSelectColumn(UserTableMap::COL_MAX_KEYS); $criteria->addSelectColumn(UserTableMap::COL_USERNAME); $criteria->addSelectColumn(UserTableMap::COL_PASSWORD); $criteria->addSelectColumn(UserTableMap::COL_SUPERUSER); } else { $criteria->addSelectColumn($alias . '.id'); - $criteria->addSelectColumn($alias . '.maxKeys'); + $criteria->addSelectColumn($alias . '.max_keys'); $criteria->addSelectColumn($alias . '.username'); $criteria->addSelectColumn($alias . '.password'); $criteria->addSelectColumn($alias . '.superuser'); diff --git a/src/Service/CA.php b/src/Service/CA.php new file mode 100644 index 0000000..41e35fe --- /dev/null +++ b/src/Service/CA.php @@ -0,0 +1,73 @@ +get('core'); + + $csrPath = tempnam(sys_get_temp_dir(), '0.'); + $crtPath = tempnam(sys_get_temp_dir(), '0.'); + + file_put_contents($csrPath, $csr); + + exec(escapeshellcmd($core->getBaseDir() . '/bin/sign-client-csr') . ' ' . escapeshellarg($csrPath) . ' ' . escapeshellarg($crtPath) . ' 2>&1', $output, $exitCode); + + if ($exitCode !== 0) { + throw new \Exception("Failed signing CSR: " . implode("\n", $output)); + } + + $crt = file_get_contents($crtPath); + + unlink($crtPath); + unlink($csrPath); + + return $crt; + } + + /** + * @param string $csr + * @throws \Exception + */ + public function getCommonNameFromCsr($csr) + { + $subject = openssl_csr_get_subject($csr); + + if ($subject === false) { + throw new \Exception("Failed to read CSR: " . $this->getOpenSslError()); + } + + return $subject["CN"]; + } + +} \ No newline at end of file diff --git a/views/base.html.twig b/views/base.html.twig index 5971daf..19fa952 100644 --- a/views/base.html.twig +++ b/views/base.html.twig @@ -19,7 +19,7 @@
{% if user %} - {{ user.username }} + {{ user.username }} Logout {% else %} Login diff --git a/views/panel.html.twig b/views/panel.html.twig index 0e43703..329939a 100644 --- a/views/panel.html.twig +++ b/views/panel.html.twig @@ -25,10 +25,13 @@ {{ certificate.getName() }} - {{ certificate.getExpiriationDate() }} + {{ certificate.getExpiresOn().format('Y-m-d H:i:s') }} - +
+ + Download certificate +
{% else %} diff --git a/views/panel/certificates/new.html.twig b/views/panel/certificates/new.html.twig index 769f0bc..65cbbb8 100644 --- a/views/panel/certificates/new.html.twig +++ b/views/panel/certificates/new.html.twig @@ -3,28 +3,32 @@ {% block head %} {{ parent() }} + + -{% endblock %} +{% endblock %} {% block content %} -
-

New Certificate

-
-
-
- - -
-
{% endblock %} \ No newline at end of file