>>=y,p-=y),p<15&&(c+=z[i++]<>>=y=v>>>24,p-=y,!(16&(y=v>>>16&255))){if(0==(64&y)){v=_[(65535&v)+(c&(1<>>=y,p-=y,(y=s-a)>3,c&=(1<<(p-=w<<3))-1,t.next_in=i,t.next_out=s,t.avail_in=i>>24&255)+(t>>>8&65280)+((65280&t)<<8)+((255&t)<<24)}function s(){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 I.Buf16(320),this.work=new I.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function a(t){var e;return t&&t.state?(e=t.state,t.total_in=t.total_out=e.total=0,t.msg="",e.wrap&&(t.adler=1&e.wrap),e.mode=P,e.last=0,e.havedict=0,e.dmax=32768,e.head=null,e.hold=0,e.bits=0,e.lencode=e.lendyn=new I.Buf32(i),e.distcode=e.distdyn=new I.Buf32(n),e.sane=1,e.back=-1,N):U}function o(t){var e;return t&&t.state?((e=t.state).wsize=0,e.whave=0,e.wnext=0,a(t)):U}function h(t,e){var r,i;return t&&t.state?(i=t.state,e<0?(r=0,e=-e):(r=1+(e>>4),e<48&&(e&=15)),e&&(e<8||15=s.wsize?(I.arraySet(s.window,e,r-s.wsize,s.wsize,0),s.wnext=0,s.whave=s.wsize):(i<(n=s.wsize-s.wnext)&&(n=i),I.arraySet(s.window,e,r-i,n,s.wnext),(i-=n)?(I.arraySet(s.window,e,r-i,i,0),s.wnext=i,s.whave=s.wsize):(s.wnext+=n,s.wnext===s.wsize&&(s.wnext=0),s.whave>>8&255,r.check=B(r.check,E,2,0),l=u=0,r.mode=2;break}if(r.flags=0,r.head&&(r.head.done=!1),!(1&r.wrap)||(((255&u)<<8)+(u>>8))%31){t.msg="incorrect header check",r.mode=30;break}if(8!=(15&u)){t.msg="unknown compression method",r.mode=30;break}if(l-=4,k=8+(15&(u>>>=4)),0===r.wbits)r.wbits=k;else if(k>r.wbits){t.msg="invalid window size",r.mode=30;break}r.dmax=1<>8&1),512&r.flags&&(E[0]=255&u,E[1]=u>>>8&255,r.check=B(r.check,E,2,0)),l=u=0,r.mode=3;case 3:for(;l<32;){if(0===o)break t;o--,u+=i[s++]<>>8&255,E[2]=u>>>16&255,E[3]=u>>>24&255,r.check=B(r.check,E,4,0)),l=u=0,r.mode=4;case 4:for(;l<16;){if(0===o)break t;o--,u+=i[s++]<>8),512&r.flags&&(E[0]=255&u,E[1]=u>>>8&255,r.check=B(r.check,E,2,0)),l=u=0,r.mode=5;case 5:if(1024&r.flags){for(;l<16;){if(0===o)break t;o--,u+=i[s++]<>>8&255,r.check=B(r.check,E,2,0)),l=u=0}else r.head&&(r.head.extra=null);r.mode=6;case 6:if(1024&r.flags&&(o<(c=r.length)&&(c=o),c&&(r.head&&(k=r.head.extra_len-r.length,r.head.extra||(r.head.extra=new Array(r.head.extra_len)),I.arraySet(r.head.extra,i,s,c,k)),512&r.flags&&(r.check=B(r.check,i,c,s)),o-=c,s+=c,r.length-=c),r.length))break t;r.length=0,r.mode=7;case 7:if(2048&r.flags){if(0===o)break t;for(c=0;k=i[s+c++],r.head&&k&&r.length<65536&&(r.head.name+=String.fromCharCode(k)),k&&c>9&1,r.head.done=!0),t.adler=r.check=0,r.mode=12;break;case 10:for(;l<32;){if(0===o)break t;o--,u+=i[s++]<>>=7&l,l-=7&l,r.mode=27;break}for(;l<3;){if(0===o)break t;o--,u+=i[s++]<>>=1)){case 0:r.mode=14;break;case 1:if(j(r),r.mode=20,6!==e)break;u>>>=2,l-=2;break t;case 2:r.mode=17;break;case 3:t.msg="invalid block type",r.mode=30}u>>>=2,l-=2;break;case 14:for(u>>>=7&l,l-=7&l;l<32;){if(0===o)break t;o--,u+=i[s++]<>>16^65535)){t.msg="invalid stored block lengths",r.mode=30;break}if(r.length=65535&u,l=u=0,r.mode=15,6===e)break t;case 15:r.mode=16;case 16:if(c=r.length){if(o>>=5,l-=5,r.ndist=1+(31&u),u>>>=5,l-=5,r.ncode=4+(15&u),u>>>=4,l-=4,286>>=3,l-=3}for(;r.have<19;)r.lens[A[r.have++]]=0;if(r.lencode=r.lendyn,r.lenbits=7,S={bits:r.lenbits},x=T(0,r.lens,0,19,r.lencode,0,r.work,S),r.lenbits=S.bits,x){t.msg="invalid code lengths set",r.mode=30;break}r.have=0,r.mode=19;case 19:for(;r.have>>16&255,b=65535&C,!((_=C>>>24)<=l);){if(0===o)break t;o--,u+=i[s++]<>>=_,l-=_,r.lens[r.have++]=b;else{if(16===b){for(z=_+2;l>>=_,l-=_,0===r.have){t.msg="invalid bit length repeat",r.mode=30;break}k=r.lens[r.have-1],c=3+(3&u),u>>>=2,l-=2}else if(17===b){for(z=_+3;l>>=_)),u>>>=3,l-=3}else{for(z=_+7;l>>=_)),u>>>=7,l-=7}if(r.have+c>r.nlen+r.ndist){t.msg="invalid bit length repeat",r.mode=30;break}for(;c--;)r.lens[r.have++]=k}}if(30===r.mode)break;if(0===r.lens[256]){t.msg="invalid code -- missing end-of-block",r.mode=30;break}if(r.lenbits=9,S={bits:r.lenbits},x=T(D,r.lens,0,r.nlen,r.lencode,0,r.work,S),r.lenbits=S.bits,x){t.msg="invalid literal/lengths set",r.mode=30;break}if(r.distbits=6,r.distcode=r.distdyn,S={bits:r.distbits},x=T(F,r.lens,r.nlen,r.ndist,r.distcode,0,r.work,S),r.distbits=S.bits,x){t.msg="invalid distances set",r.mode=30;break}if(r.mode=20,6===e)break t;case 20:r.mode=21;case 21:if(6<=o&&258<=h){t.next_out=a,t.avail_out=h,t.next_in=s,t.avail_in=o,r.hold=u,r.bits=l,R(t,d),a=t.next_out,n=t.output,h=t.avail_out,s=t.next_in,i=t.input,o=t.avail_in,u=r.hold,l=r.bits,12===r.mode&&(r.back=-1);break}for(r.back=0;g=(C=r.lencode[u&(1<>>16&255,b=65535&C,!((_=C>>>24)<=l);){if(0===o)break t;o--,u+=i[s++]<>v)])>>>16&255,b=65535&C,!(v+(_=C>>>24)<=l);){if(0===o)break t;o--,u+=i[s++]<>>=v,l-=v,r.back+=v}if(u>>>=_,l-=_,r.back+=_,r.length=b,0===g){r.mode=26;break}if(32&g){r.back=-1,r.mode=12;break}if(64&g){t.msg="invalid literal/length code",r.mode=30;break}r.extra=15&g,r.mode=22;case 22:if(r.extra){for(z=r.extra;l>>=r.extra,l-=r.extra,r.back+=r.extra}r.was=r.length,r.mode=23;case 23:for(;g=(C=r.distcode[u&(1<>>16&255,b=65535&C,!((_=C>>>24)<=l);){if(0===o)break t;o--,u+=i[s++]<>v)])>>>16&255,b=65535&C,!(v+(_=C>>>24)<=l);){if(0===o)break t;o--,u+=i[s++]<>>=v,l-=v,r.back+=v}if(u>>>=_,l-=_,r.back+=_,64&g){t.msg="invalid distance code",r.mode=30;break}r.offset=b,r.extra=15&g,r.mode=24;case 24:if(r.extra){for(z=r.extra;l>>=r.extra,l-=r.extra,r.back+=r.extra}if(r.offset>r.dmax){t.msg="invalid distance too far back",r.mode=30;break}r.mode=25;case 25:if(0===h)break t;if(c=d-h,r.offset>c){if((c=r.offset-c)>r.whave&&r.sane){t.msg="invalid distance too far back",r.mode=30;break}p=c>r.wnext?(c-=r.wnext,r.wsize-c):r.wnext-c,c>r.length&&(c=r.length),m=r.window}else m=n,p=a-r.offset,c=r.length;for(hc?(m=R[T+a[v]],A[I+a[v]]):(m=96,0),h=1<>S)+(u-=h)]=p<<24|m<<16|_|0,0!==u;);for(h=1<>=1;if(0!==h?(E&=h-1,E+=h):E=0,v++,0==--O[b]){if(b===w)break;b=e[r+a[v]]}if(k>>7)]}function x(t,e){t.pending_buf[t.pending++]=255&e,t.pending_buf[t.pending++]=e>>>8&255}function S(t,e,r){t.bi_valid>n-r?(t.bi_buf|=e<>n-t.bi_valid,t.bi_valid+=r-n):(t.bi_buf|=e<>>=1,r<<=1,0<--e;);return r>>>1}function E(t,e,r){var i,n,s=new Array(_+1),a=0;for(i=1;i<=_;i++)s[i]=a=a+r[i-1]<<1;for(n=0;n<=e;n++){var o=t[2*n+1];0!==o&&(t[2*n]=C(s[o]++,o))}}function A(t){var e;for(e=0;e<286;e++)t.dyn_ltree[2*e]=0;for(e=0;e<30;e++)t.dyn_dtree[2*e]=0;for(e=0;e<19;e++)t.bl_tree[2*e]=0;t.dyn_ltree[512]=1,t.opt_len=t.static_len=0,t.last_lit=t.matches=0}function I(t){8>1;1<=r;r--)B(t,s,r);for(n=h;r=t.heap[1],t.heap[1]=t.heap[t.heap_len--],B(t,s,1),i=t.heap[1],t.heap[--t.heap_max]=r,t.heap[--t.heap_max]=i,s[2*n]=s[2*r]+s[2*i],t.depth[n]=(t.depth[r]>=t.depth[i]?t.depth[r]:t.depth[i])+1,s[2*r+1]=s[2*i+1]=n,t.heap[1]=n++,B(t,s,1),2<=t.heap_len;);t.heap[--t.heap_max]=t.heap[1],function(t,e){var r,i,n,s,a,o,h=e.dyn_tree,u=e.max_code,l=e.stat_desc.static_tree,f=e.stat_desc.has_stree,d=e.stat_desc.extra_bits,c=e.stat_desc.extra_base,p=e.stat_desc.max_length,m=0;for(s=0;s<=_;s++)t.bl_count[s]=0;for(h[2*t.heap[t.heap_max]+1]=0,r=t.heap_max+1;r<573;r++)p<(s=h[2*h[2*(i=t.heap[r])+1]+1]+1)&&(s=p,m++),h[2*i+1]=s,u>=7;i<30;i++)for(y[i]=n<<7,t=0;t<1<>>=1)if(1&r&&0!==t.dyn_ltree[2*e])return 0;if(0!==t.dyn_ltree[18]||0!==t.dyn_ltree[20]||0!==t.dyn_ltree[26])return 1;for(e=32;e<256;e++)if(0!==t.dyn_ltree[2*e])return 1;return 0}(t)),T(t,t.l_desc),T(t,t.d_desc),a=function(t){var e;for(D(t,t.dyn_ltree,t.l_desc.max_code),D(t,t.dyn_dtree,t.d_desc.max_code),T(t,t.bl_desc),e=18;3<=e&&0===t.bl_tree[2*l[e]+1];e--);return t.opt_len+=3*(e+1)+5+5+4,e}(t),n=t.opt_len+3+7>>>3,(s=t.static_len+3+7>>>3)<=n&&(n=s)):n=s=r+5,r+4<=n&&-1!==e?U(t,e,r,i):4===t.strategy||s===n?(S(t,2+(i?1:0),3),R(t,f,d)):(S(t,4+(i?1:0),3),function(t,e,r,i){var n;for(S(t,e-257,5),S(t,r-1,5),S(t,i-4,4),n=0;n>>8&255,t.pending_buf[t.d_buf+2*t.last_lit+1]=255&e,t.pending_buf[t.l_buf+t.last_lit]=255&r,t.last_lit++,0===e?t.dyn_ltree[2*r]++:(t.matches++,e--,t.dyn_ltree[2*(p[r]+256+1)]++,t.dyn_dtree[2*k(e)]++),t.last_lit===t.lit_bufsize-1},r._tr_align=function(t){var e;S(t,2,3),z(t,256,f),16===(e=t).bi_valid?(x(e,e.bi_buf),e.bi_buf=0,e.bi_valid=0):8<=e.bi_valid&&(e.pending_buf[e.pending++]=255&e.bi_buf,e.bi_buf>>=8,e.bi_valid-=8)}},{"../utils/common":41}],53:[function(t,e,r){"use strict";e.exports=function(){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}},{}],54:[function(t,e,r){"use strict";e.exports="function"==typeof setImmediate?setImmediate:function(){var t=[].slice.apply(arguments);t.splice(1,0,0),setTimeout.apply(null,t)}},{}]},{},[10])(10)})}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}]},{},[1])(1)});
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{}]},{},[1])(1)
+});
\ No newline at end of file
diff --git a/docs/jquery/jszip/dist/jszip.min.js b/docs/jquery/jszip/dist/jszip.min.js
new file mode 100644
index 0000000000..c6ae9ad829
--- /dev/null
+++ b/docs/jquery/jszip/dist/jszip.min.js
@@ -0,0 +1,13 @@
+/*!
+
+JSZip v3.7.1 - A JavaScript class for generating and reading zip files
+
+
+(c) 2009-2016 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(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).JSZip=e()}}(function(){return function s(a,o,h){function u(r,e){if(!o[r]){if(!a[r]){var t="function"==typeof require&&require;if(!e&&t)return t(r,!0);if(l)return l(r,!0);var n=new Error("Cannot find module '"+r+"'");throw n.code="MODULE_NOT_FOUND",n}var i=o[r]={exports:{}};a[r][0].call(i.exports,function(e){var t=a[r][1][e];return u(t||e)},i,i.exports,s,a,o,h)}return o[r].exports}for(var l="function"==typeof require&&require,e=0;e>2,s=(3&t)<<4|r>>4,a=1>6:64,o=2>4,r=(15&i)<<4|(s=p.indexOf(e.charAt(o++)))>>2,n=(3&s)<<6|(a=p.indexOf(e.charAt(o++))),u[h++]=t,64!==s&&(u[h++]=r),64!==a&&(u[h++]=n);return u}},{"./support":30,"./utils":32}],2:[function(e,t,r){"use strict";var n=e("./external"),i=e("./stream/DataWorker"),s=e("./stream/Crc32Probe"),a=e("./stream/DataLengthProbe");function o(e,t,r,n,i){this.compressedSize=e,this.uncompressedSize=t,this.crc32=r,this.compression=n,this.compressedContent=i}o.prototype={getContentWorker:function(){var e=new i(n.Promise.resolve(this.compressedContent)).pipe(this.compression.uncompressWorker()).pipe(new a("data_length")),t=this;return e.on("end",function(){if(this.streamInfo.data_length!==t.uncompressedSize)throw new Error("Bug : uncompressed data size mismatch")}),e},getCompressedWorker:function(){return new i(n.Promise.resolve(this.compressedContent)).withStreamInfo("compressedSize",this.compressedSize).withStreamInfo("uncompressedSize",this.uncompressedSize).withStreamInfo("crc32",this.crc32).withStreamInfo("compression",this.compression)}},o.createWorkerFrom=function(e,t,r){return e.pipe(new s).pipe(new a("uncompressedSize")).pipe(t.compressWorker(r)).pipe(new a("compressedSize")).withStreamInfo("compression",t)},t.exports=o},{"./external":6,"./stream/Crc32Probe":25,"./stream/DataLengthProbe":26,"./stream/DataWorker":27}],3:[function(e,t,r){"use strict";var n=e("./stream/GenericWorker");r.STORE={magic:"\0\0",compressWorker:function(e){return new n("STORE compression")},uncompressWorker:function(){return new n("STORE decompression")}},r.DEFLATE=e("./flate")},{"./flate":7,"./stream/GenericWorker":28}],4:[function(e,t,r){"use strict";var n=e("./utils"),a=function(){for(var e,t=[],r=0;r<256;r++){e=r;for(var n=0;n<8;n++)e=1&e?3988292384^e>>>1:e>>>1;t[r]=e}return t}();t.exports=function(e,t){return void 0!==e&&e.length?"string"!==n.getTypeOf(e)?function(e,t,r){var n=a,i=0+r;e^=-1;for(var s=0;s>>8^n[255&(e^t[s])];return-1^e}(0|t,e,e.length):function(e,t,r){var n=a,i=0+r;e^=-1;for(var s=0;s>>8^n[255&(e^t.charCodeAt(s))];return-1^e}(0|t,e,e.length):0}},{"./utils":32}],5:[function(e,t,r){"use strict";r.base64=!1,r.binary=!1,r.dir=!1,r.createFolders=!0,r.date=null,r.compression=null,r.compressionOptions=null,r.comment=null,r.unixPermissions=null,r.dosPermissions=null},{}],6:[function(e,t,r){"use strict";var n;n="undefined"!=typeof Promise?Promise:e("lie"),t.exports={Promise:n}},{lie:37}],7:[function(e,t,r){"use strict";var n="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Uint32Array,i=e("pako"),s=e("./utils"),a=e("./stream/GenericWorker"),o=n?"uint8array":"array";function h(e,t){a.call(this,"FlateWorker/"+e),this._pako=null,this._pakoAction=e,this._pakoOptions=t,this.meta={}}r.magic="\b\0",s.inherits(h,a),h.prototype.processChunk=function(e){this.meta=e.meta,null===this._pako&&this._createPako(),this._pako.push(s.transformTo(o,e.data),!1)},h.prototype.flush=function(){a.prototype.flush.call(this),null===this._pako&&this._createPako(),this._pako.push([],!0)},h.prototype.cleanUp=function(){a.prototype.cleanUp.call(this),this._pako=null},h.prototype._createPako=function(){this._pako=new i[this._pakoAction]({raw:!0,level:this._pakoOptions.level||-1});var t=this;this._pako.onData=function(e){t.push({data:e,meta:t.meta})}},r.compressWorker=function(e){return new h("Deflate",e)},r.uncompressWorker=function(){return new h("Inflate",{})}},{"./stream/GenericWorker":28,"./utils":32,pako:38}],8:[function(e,t,r){"use strict";function I(e,t){var r,n="";for(r=0;r>>=8;return n}function i(e,t,r,n,i,s){var a,o,h=e.file,u=e.compression,l=s!==B.utf8encode,f=O.transformTo("string",s(h.name)),d=O.transformTo("string",B.utf8encode(h.name)),c=h.comment,p=O.transformTo("string",s(c)),m=O.transformTo("string",B.utf8encode(c)),_=d.length!==h.name.length,g=m.length!==c.length,b="",v="",y="",w=h.dir,k=h.date,x={crc32:0,compressedSize:0,uncompressedSize:0};t&&!r||(x.crc32=e.crc32,x.compressedSize=e.compressedSize,x.uncompressedSize=e.uncompressedSize);var S=0;t&&(S|=8),l||!_&&!g||(S|=2048);var z,C=0,E=0;w&&(C|=16),"UNIX"===i?(E=798,C|=((z=h.unixPermissions)||(z=w?16893:33204),(65535&z)<<16)):(E=20,C|=63&(h.dosPermissions||0)),a=k.getUTCHours(),a<<=6,a|=k.getUTCMinutes(),a<<=5,a|=k.getUTCSeconds()/2,o=k.getUTCFullYear()-1980,o<<=4,o|=k.getUTCMonth()+1,o<<=5,o|=k.getUTCDate(),_&&(b+="up"+I((v=I(1,1)+I(R(f),4)+d).length,2)+v),g&&(b+="uc"+I((y=I(1,1)+I(R(p),4)+m).length,2)+y);var A="";return A+="\n\0",A+=I(S,2),A+=u.magic,A+=I(a,2),A+=I(o,2),A+=I(x.crc32,4),A+=I(x.compressedSize,4),A+=I(x.uncompressedSize,4),A+=I(f.length,2),A+=I(b.length,2),{fileRecord:T.LOCAL_FILE_HEADER+A+f+b,dirRecord:T.CENTRAL_FILE_HEADER+I(E,2)+A+I(p.length,2)+"\0\0\0\0"+I(C,4)+I(n,4)+f+b+p}}var O=e("../utils"),s=e("../stream/GenericWorker"),B=e("../utf8"),R=e("../crc32"),T=e("../signature");function n(e,t,r,n){s.call(this,"ZipFileWorker"),this.bytesWritten=0,this.zipComment=t,this.zipPlatform=r,this.encodeFileName=n,this.streamFiles=e,this.accumulate=!1,this.contentBuffer=[],this.dirRecords=[],this.currentSourceOffset=0,this.entriesCount=0,this.currentFile=null,this._sources=[]}O.inherits(n,s),n.prototype.push=function(e){var t=e.meta.percent||0,r=this.entriesCount,n=this._sources.length;this.accumulate?this.contentBuffer.push(e):(this.bytesWritten+=e.data.length,s.prototype.push.call(this,{data:e.data,meta:{currentFile:this.currentFile,percent:r?(t+100*(r-n-1))/r:100}}))},n.prototype.openedSource=function(e){this.currentSourceOffset=this.bytesWritten,this.currentFile=e.file.name;var t=this.streamFiles&&!e.file.dir;if(t){var r=i(e,t,!1,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);this.push({data:r.fileRecord,meta:{percent:0}})}else this.accumulate=!0},n.prototype.closedSource=function(e){this.accumulate=!1;var t,r=this.streamFiles&&!e.file.dir,n=i(e,r,!0,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);if(this.dirRecords.push(n.dirRecord),r)this.push({data:(t=e,T.DATA_DESCRIPTOR+I(t.crc32,4)+I(t.compressedSize,4)+I(t.uncompressedSize,4)),meta:{percent:100}});else for(this.push({data:n.fileRecord,meta:{percent:0}});this.contentBuffer.length;)this.push(this.contentBuffer.shift());this.currentFile=null},n.prototype.flush=function(){for(var e=this.bytesWritten,t=0;t=this.index;t--)r=(r<<8)+this.byteAt(t);return this.index+=e,r},readString:function(e){return n.transformTo("string",this.readData(e))},readData:function(e){},lastIndexOfSignature:function(e){},readAndCheckSignature:function(e){},readDate:function(){var e=this.readInt(4);return new Date(Date.UTC(1980+(e>>25&127),(e>>21&15)-1,e>>16&31,e>>11&31,e>>5&63,(31&e)<<1))}},t.exports=i},{"../utils":32}],19:[function(e,t,r){"use strict";var n=e("./Uint8ArrayReader");function i(e){n.call(this,e)}e("../utils").inherits(i,n),i.prototype.readData=function(e){this.checkOffset(e);var t=this.data.slice(this.zero+this.index,this.zero+this.index+e);return this.index+=e,t},t.exports=i},{"../utils":32,"./Uint8ArrayReader":21}],20:[function(e,t,r){"use strict";var n=e("./DataReader");function i(e){n.call(this,e)}e("../utils").inherits(i,n),i.prototype.byteAt=function(e){return this.data.charCodeAt(this.zero+e)},i.prototype.lastIndexOfSignature=function(e){return this.data.lastIndexOf(e)-this.zero},i.prototype.readAndCheckSignature=function(e){return e===this.readData(4)},i.prototype.readData=function(e){this.checkOffset(e);var t=this.data.slice(this.zero+this.index,this.zero+this.index+e);return this.index+=e,t},t.exports=i},{"../utils":32,"./DataReader":18}],21:[function(e,t,r){"use strict";var n=e("./ArrayReader");function i(e){n.call(this,e)}e("../utils").inherits(i,n),i.prototype.readData=function(e){if(this.checkOffset(e),0===e)return new Uint8Array(0);var t=this.data.subarray(this.zero+this.index,this.zero+this.index+e);return this.index+=e,t},t.exports=i},{"../utils":32,"./ArrayReader":17}],22:[function(e,t,r){"use strict";var n=e("../utils"),i=e("../support"),s=e("./ArrayReader"),a=e("./StringReader"),o=e("./NodeBufferReader"),h=e("./Uint8ArrayReader");t.exports=function(e){var t=n.getTypeOf(e);return n.checkSupport(t),"string"!==t||i.uint8array?"nodebuffer"===t?new o(e):i.uint8array?new h(n.transformTo("uint8array",e)):new s(n.transformTo("array",e)):new a(e)}},{"../support":30,"../utils":32,"./ArrayReader":17,"./NodeBufferReader":19,"./StringReader":20,"./Uint8ArrayReader":21}],23:[function(e,t,r){"use strict";r.LOCAL_FILE_HEADER="PK",r.CENTRAL_FILE_HEADER="PK",r.CENTRAL_DIRECTORY_END="PK",r.ZIP64_CENTRAL_DIRECTORY_LOCATOR="PK",r.ZIP64_CENTRAL_DIRECTORY_END="PK",r.DATA_DESCRIPTOR="PK\b"},{}],24:[function(e,t,r){"use strict";var n=e("./GenericWorker"),i=e("../utils");function s(e){n.call(this,"ConvertWorker to "+e),this.destType=e}i.inherits(s,n),s.prototype.processChunk=function(e){this.push({data:i.transformTo(this.destType,e.data),meta:e.meta})},t.exports=s},{"../utils":32,"./GenericWorker":28}],25:[function(e,t,r){"use strict";var n=e("./GenericWorker"),i=e("../crc32");function s(){n.call(this,"Crc32Probe"),this.withStreamInfo("crc32",0)}e("../utils").inherits(s,n),s.prototype.processChunk=function(e){this.streamInfo.crc32=i(e.data,this.streamInfo.crc32||0),this.push(e)},t.exports=s},{"../crc32":4,"../utils":32,"./GenericWorker":28}],26:[function(e,t,r){"use strict";var n=e("../utils"),i=e("./GenericWorker");function s(e){i.call(this,"DataLengthProbe for "+e),this.propName=e,this.withStreamInfo(e,0)}n.inherits(s,i),s.prototype.processChunk=function(e){if(e){var t=this.streamInfo[this.propName]||0;this.streamInfo[this.propName]=t+e.data.length}i.prototype.processChunk.call(this,e)},t.exports=s},{"../utils":32,"./GenericWorker":28}],27:[function(e,t,r){"use strict";var n=e("../utils"),i=e("./GenericWorker");function s(e){i.call(this,"DataWorker");var t=this;this.dataIsReady=!1,this.index=0,this.max=0,this.data=null,this.type="",this._tickScheduled=!1,e.then(function(e){t.dataIsReady=!0,t.data=e,t.max=e&&e.length||0,t.type=n.getTypeOf(e),t.isPaused||t._tickAndRepeat()},function(e){t.error(e)})}n.inherits(s,i),s.prototype.cleanUp=function(){i.prototype.cleanUp.call(this),this.data=null},s.prototype.resume=function(){return!!i.prototype.resume.call(this)&&(!this._tickScheduled&&this.dataIsReady&&(this._tickScheduled=!0,n.delay(this._tickAndRepeat,[],this)),!0)},s.prototype._tickAndRepeat=function(){this._tickScheduled=!1,this.isPaused||this.isFinished||(this._tick(),this.isFinished||(n.delay(this._tickAndRepeat,[],this),this._tickScheduled=!0))},s.prototype._tick=function(){if(this.isPaused||this.isFinished)return!1;var e=null,t=Math.min(this.max,this.index+16384);if(this.index>=this.max)return this.end();switch(this.type){case"string":e=this.data.substring(this.index,t);break;case"uint8array":e=this.data.subarray(this.index,t);break;case"array":case"nodebuffer":e=this.data.slice(this.index,t)}return this.index=t,this.push({data:e,meta:{percent:this.max?this.index/this.max*100:0}})},t.exports=s},{"../utils":32,"./GenericWorker":28}],28:[function(e,t,r){"use strict";function n(e){this.name=e||"default",this.streamInfo={},this.generatedError=null,this.extraStreamInfo={},this.isPaused=!0,this.isFinished=!1,this.isLocked=!1,this._listeners={data:[],end:[],error:[]},this.previous=null}n.prototype={push:function(e){this.emit("data",e)},end:function(){if(this.isFinished)return!1;this.flush();try{this.emit("end"),this.cleanUp(),this.isFinished=!0}catch(e){this.emit("error",e)}return!0},error:function(e){return!this.isFinished&&(this.isPaused?this.generatedError=e:(this.isFinished=!0,this.emit("error",e),this.previous&&this.previous.error(e),this.cleanUp()),!0)},on:function(e,t){return this._listeners[e].push(t),this},cleanUp:function(){this.streamInfo=this.generatedError=this.extraStreamInfo=null,this._listeners=[]},emit:function(e,t){if(this._listeners[e])for(var r=0;r "+e:e}},t.exports=n},{}],29:[function(e,t,r){"use strict";var u=e("../utils"),i=e("./ConvertWorker"),s=e("./GenericWorker"),l=e("../base64"),n=e("../support"),a=e("../external"),o=null;if(n.nodestream)try{o=e("../nodejs/NodejsStreamOutputAdapter")}catch(e){}function h(e,t,r){var n=t;switch(t){case"blob":case"arraybuffer":n="uint8array";break;case"base64":n="string"}try{this._internalType=n,this._outputType=t,this._mimeType=r,u.checkSupport(n),this._worker=e.pipe(new i(n)),e.lock()}catch(e){this._worker=new s("error"),this._worker.error(e)}}h.prototype={accumulate:function(e){return o=this,h=e,new a.Promise(function(t,r){var n=[],i=o._internalType,s=o._outputType,a=o._mimeType;o.on("data",function(e,t){n.push(e),h&&h(t)}).on("error",function(e){n=[],r(e)}).on("end",function(){try{var e=function(e,t,r){switch(e){case"blob":return u.newBlob(u.transformTo("arraybuffer",t),r);case"base64":return l.encode(t);default:return u.transformTo(e,t)}}(s,function(e,t){var r,n=0,i=null,s=0;for(r=0;r>>6:(r<65536?t[s++]=224|r>>>12:(t[s++]=240|r>>>18,t[s++]=128|r>>>12&63),t[s++]=128|r>>>6&63),t[s++]=128|63&r);return t}(e)},s.utf8decode=function(e){return h.nodebuffer?o.transformTo("nodebuffer",e).toString("utf-8"):function(e){var t,r,n,i,s=e.length,a=new Array(2*s);for(t=r=0;t>10&1023,a[r++]=56320|1023&n)}return a.length!==r&&(a.subarray?a=a.subarray(0,r):a.length=r),o.applyFromCharCode(a)}(e=o.transformTo(h.uint8array?"uint8array":"array",e))},o.inherits(a,n),a.prototype.processChunk=function(e){var t=o.transformTo(h.uint8array?"uint8array":"array",e.data);if(this.leftOver&&this.leftOver.length){if(h.uint8array){var r=t;(t=new Uint8Array(r.length+this.leftOver.length)).set(this.leftOver,0),t.set(r,this.leftOver.length)}else t=this.leftOver.concat(t);this.leftOver=null}var n=function(e,t){var r;for((t=t||e.length)>e.length&&(t=e.length),r=t-1;0<=r&&128==(192&e[r]);)r--;return r<0?t:0===r?t:r+u[e[r]]>t?r:t}(t),i=t;n!==t.length&&(h.uint8array?(i=t.subarray(0,n),this.leftOver=t.subarray(n,t.length)):(i=t.slice(0,n),this.leftOver=t.slice(n,t.length))),this.push({data:s.utf8decode(i),meta:e.meta})},a.prototype.flush=function(){this.leftOver&&this.leftOver.length&&(this.push({data:s.utf8decode(this.leftOver),meta:{}}),this.leftOver=null)},s.Utf8DecodeWorker=a,o.inherits(l,n),l.prototype.processChunk=function(e){this.push({data:s.utf8encode(e.data),meta:e.meta})},s.Utf8EncodeWorker=l},{"./nodejsUtils":14,"./stream/GenericWorker":28,"./support":30,"./utils":32}],32:[function(e,t,o){"use strict";var h=e("./support"),u=e("./base64"),r=e("./nodejsUtils"),n=e("set-immediate-shim"),l=e("./external");function i(e){return e}function f(e,t){for(var r=0;r>8;this.dir=!!(16&this.externalFileAttributes),0==e&&(this.dosPermissions=63&this.externalFileAttributes),3==e&&(this.unixPermissions=this.externalFileAttributes>>16&65535),this.dir||"/"!==this.fileNameStr.slice(-1)||(this.dir=!0)},parseZIP64ExtraField:function(e){if(this.extraFields[1]){var t=n(this.extraFields[1].value);this.uncompressedSize===s.MAX_VALUE_32BITS&&(this.uncompressedSize=t.readInt(8)),this.compressedSize===s.MAX_VALUE_32BITS&&(this.compressedSize=t.readInt(8)),this.localHeaderOffset===s.MAX_VALUE_32BITS&&(this.localHeaderOffset=t.readInt(8)),this.diskNumberStart===s.MAX_VALUE_32BITS&&(this.diskNumberStart=t.readInt(4))}},readExtraFields:function(e){var t,r,n,i=e.index+this.extraFieldsLength;for(this.extraFields||(this.extraFields={});e.index+4>>6:(r<65536?t[s++]=224|r>>>12:(t[s++]=240|r>>>18,t[s++]=128|r>>>12&63),t[s++]=128|r>>>6&63),t[s++]=128|63&r);return t},r.buf2binstring=function(e){return l(e,e.length)},r.binstring2buf=function(e){for(var t=new h.Buf8(e.length),r=0,n=t.length;r>10&1023,o[n++]=56320|1023&i)}return l(o,n)},r.utf8border=function(e,t){var r;for((t=t||e.length)>e.length&&(t=e.length),r=t-1;0<=r&&128==(192&e[r]);)r--;return r<0?t:0===r?t:r+u[e[r]]>t?r:t}},{"./common":41}],43:[function(e,t,r){"use strict";t.exports=function(e,t,r,n){for(var i=65535&e|0,s=e>>>16&65535|0,a=0;0!==r;){for(r-=a=2e3>>1:e>>>1;t[r]=e}return t}();t.exports=function(e,t,r,n){var i=o,s=n+r;e^=-1;for(var a=n;a>>8^i[255&(e^t[a])];return-1^e}},{}],46:[function(e,t,r){"use strict";var h,d=e("../utils/common"),u=e("./trees"),c=e("./adler32"),p=e("./crc32"),n=e("./messages"),l=0,f=0,m=-2,i=2,_=8,s=286,a=30,o=19,g=2*s+1,b=15,v=3,y=258,w=y+v+1,k=42,x=113;function S(e,t){return e.msg=n[t],t}function z(e){return(e<<1)-(4e.avail_out&&(r=e.avail_out),0!==r&&(d.arraySet(e.output,t.pending_buf,t.pending_out,r,e.next_out),e.next_out+=r,t.pending_out+=r,e.total_out+=r,e.avail_out-=r,t.pending-=r,0===t.pending&&(t.pending_out=0))}function A(e,t){u._tr_flush_block(e,0<=e.block_start?e.block_start:-1,e.strstart-e.block_start,t),e.block_start=e.strstart,E(e.strm)}function I(e,t){e.pending_buf[e.pending++]=t}function O(e,t){e.pending_buf[e.pending++]=t>>>8&255,e.pending_buf[e.pending++]=255&t}function B(e,t){var r,n,i=e.max_chain_length,s=e.strstart,a=e.prev_length,o=e.nice_match,h=e.strstart>e.w_size-w?e.strstart-(e.w_size-w):0,u=e.window,l=e.w_mask,f=e.prev,d=e.strstart+y,c=u[s+a-1],p=u[s+a];e.prev_length>=e.good_match&&(i>>=2),o>e.lookahead&&(o=e.lookahead);do{if(u[(r=t)+a]===p&&u[r+a-1]===c&&u[r]===u[s]&&u[++r]===u[s+1]){s+=2,r++;do{}while(u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&sh&&0!=--i);return a<=e.lookahead?a:e.lookahead}function R(e){var t,r,n,i,s,a,o,h,u,l,f=e.w_size;do{if(i=e.window_size-e.lookahead-e.strstart,e.strstart>=f+(f-w)){for(d.arraySet(e.window,e.window,f,f,0),e.match_start-=f,e.strstart-=f,e.block_start-=f,t=r=e.hash_size;n=e.head[--t],e.head[t]=f<=n?n-f:0,--r;);for(t=r=f;n=e.prev[--t],e.prev[t]=f<=n?n-f:0,--r;);i+=f}if(0===e.strm.avail_in)break;if(a=e.strm,o=e.window,h=e.strstart+e.lookahead,l=void 0,(u=i)<(l=a.avail_in)&&(l=u),r=0===l?0:(a.avail_in-=l,d.arraySet(o,a.input,a.next_in,l,h),1===a.state.wrap?a.adler=c(a.adler,o,l,h):2===a.state.wrap&&(a.adler=p(a.adler,o,l,h)),a.next_in+=l,a.total_in+=l,l),e.lookahead+=r,e.lookahead+e.insert>=v)for(s=e.strstart-e.insert,e.ins_h=e.window[s],e.ins_h=(e.ins_h<=v&&(e.ins_h=(e.ins_h<=v)if(n=u._tr_tally(e,e.strstart-e.match_start,e.match_length-v),e.lookahead-=e.match_length,e.match_length<=e.max_lazy_match&&e.lookahead>=v){for(e.match_length--;e.strstart++,e.ins_h=(e.ins_h<=v&&(e.ins_h=(e.ins_h<=v&&e.match_length<=e.prev_length){for(i=e.strstart+e.lookahead-v,n=u._tr_tally(e,e.strstart-1-e.prev_match,e.prev_length-v),e.lookahead-=e.prev_length-1,e.prev_length-=2;++e.strstart<=i&&(e.ins_h=(e.ins_h<e.pending_buf_size-5&&(r=e.pending_buf_size-5);;){if(e.lookahead<=1){if(R(e),0===e.lookahead&&t===l)return 1;if(0===e.lookahead)break}e.strstart+=e.lookahead,e.lookahead=0;var n=e.block_start+r;if((0===e.strstart||e.strstart>=n)&&(e.lookahead=e.strstart-n,e.strstart=n,A(e,!1),0===e.strm.avail_out))return 1;if(e.strstart-e.block_start>=e.w_size-w&&(A(e,!1),0===e.strm.avail_out))return 1}return e.insert=0,4===t?(A(e,!0),0===e.strm.avail_out?3:4):(e.strstart>e.block_start&&(A(e,!1),e.strm.avail_out),1)}),new F(4,4,8,4,T),new F(4,5,16,8,T),new F(4,6,32,32,T),new F(4,4,16,16,D),new F(8,16,32,32,D),new F(8,16,128,128,D),new F(8,32,128,256,D),new F(32,128,258,1024,D),new F(32,258,258,4096,D)],r.deflateInit=function(e,t){return L(e,t,_,15,8,0)},r.deflateInit2=L,r.deflateReset=P,r.deflateResetKeep=U,r.deflateSetHeader=function(e,t){return e&&e.state?2!==e.state.wrap?m:(e.state.gzhead=t,f):m},r.deflate=function(e,t){var r,n,i,s;if(!e||!e.state||5>8&255),I(n,n.gzhead.time>>16&255),I(n,n.gzhead.time>>24&255),I(n,9===n.level?2:2<=n.strategy||n.level<2?4:0),I(n,255&n.gzhead.os),n.gzhead.extra&&n.gzhead.extra.length&&(I(n,255&n.gzhead.extra.length),I(n,n.gzhead.extra.length>>8&255)),n.gzhead.hcrc&&(e.adler=p(e.adler,n.pending_buf,n.pending,0)),n.gzindex=0,n.status=69):(I(n,0),I(n,0),I(n,0),I(n,0),I(n,0),I(n,9===n.level?2:2<=n.strategy||n.level<2?4:0),I(n,3),n.status=x);else{var a=_+(n.w_bits-8<<4)<<8;a|=(2<=n.strategy||n.level<2?0:n.level<6?1:6===n.level?2:3)<<6,0!==n.strstart&&(a|=32),a+=31-a%31,n.status=x,O(n,a),0!==n.strstart&&(O(n,e.adler>>>16),O(n,65535&e.adler)),e.adler=1}if(69===n.status)if(n.gzhead.extra){for(i=n.pending;n.gzindex<(65535&n.gzhead.extra.length)&&(n.pending!==n.pending_buf_size||(n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),E(e),i=n.pending,n.pending!==n.pending_buf_size));)I(n,255&n.gzhead.extra[n.gzindex]),n.gzindex++;n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),n.gzindex===n.gzhead.extra.length&&(n.gzindex=0,n.status=73)}else n.status=73;if(73===n.status)if(n.gzhead.name){i=n.pending;do{if(n.pending===n.pending_buf_size&&(n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),E(e),i=n.pending,n.pending===n.pending_buf_size)){s=1;break}s=n.gzindexi&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),0===s&&(n.gzindex=0,n.status=91)}else n.status=91;if(91===n.status)if(n.gzhead.comment){i=n.pending;do{if(n.pending===n.pending_buf_size&&(n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),E(e),i=n.pending,n.pending===n.pending_buf_size)){s=1;break}s=n.gzindexi&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),0===s&&(n.status=103)}else n.status=103;if(103===n.status&&(n.gzhead.hcrc?(n.pending+2>n.pending_buf_size&&E(e),n.pending+2<=n.pending_buf_size&&(I(n,255&e.adler),I(n,e.adler>>8&255),e.adler=0,n.status=x)):n.status=x),0!==n.pending){if(E(e),0===e.avail_out)return n.last_flush=-1,f}else if(0===e.avail_in&&z(t)<=z(r)&&4!==t)return S(e,-5);if(666===n.status&&0!==e.avail_in)return S(e,-5);if(0!==e.avail_in||0!==n.lookahead||t!==l&&666!==n.status){var o=2===n.strategy?function(e,t){for(var r;;){if(0===e.lookahead&&(R(e),0===e.lookahead)){if(t===l)return 1;break}if(e.match_length=0,r=u._tr_tally(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++,r&&(A(e,!1),0===e.strm.avail_out))return 1}return e.insert=0,4===t?(A(e,!0),0===e.strm.avail_out?3:4):e.last_lit&&(A(e,!1),0===e.strm.avail_out)?1:2}(n,t):3===n.strategy?function(e,t){for(var r,n,i,s,a=e.window;;){if(e.lookahead<=y){if(R(e),e.lookahead<=y&&t===l)return 1;if(0===e.lookahead)break}if(e.match_length=0,e.lookahead>=v&&0e.lookahead&&(e.match_length=e.lookahead)}if(e.match_length>=v?(r=u._tr_tally(e,1,e.match_length-v),e.lookahead-=e.match_length,e.strstart+=e.match_length,e.match_length=0):(r=u._tr_tally(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++),r&&(A(e,!1),0===e.strm.avail_out))return 1}return e.insert=0,4===t?(A(e,!0),0===e.strm.avail_out?3:4):e.last_lit&&(A(e,!1),0===e.strm.avail_out)?1:2}(n,t):h[n.level].func(n,t);if(3!==o&&4!==o||(n.status=666),1===o||3===o)return 0===e.avail_out&&(n.last_flush=-1),f;if(2===o&&(1===t?u._tr_align(n):5!==t&&(u._tr_stored_block(n,0,0,!1),3===t&&(C(n.head),0===n.lookahead&&(n.strstart=0,n.block_start=0,n.insert=0))),E(e),0===e.avail_out))return n.last_flush=-1,f}return 4!==t?f:n.wrap<=0?1:(2===n.wrap?(I(n,255&e.adler),I(n,e.adler>>8&255),I(n,e.adler>>16&255),I(n,e.adler>>24&255),I(n,255&e.total_in),I(n,e.total_in>>8&255),I(n,e.total_in>>16&255),I(n,e.total_in>>24&255)):(O(n,e.adler>>>16),O(n,65535&e.adler)),E(e),0=r.w_size&&(0===s&&(C(r.head),r.strstart=0,r.block_start=0,r.insert=0),u=new d.Buf8(r.w_size),d.arraySet(u,t,l-r.w_size,r.w_size,0),t=u,l=r.w_size),a=e.avail_in,o=e.next_in,h=e.input,e.avail_in=l,e.next_in=0,e.input=t,R(r);r.lookahead>=v;){for(n=r.strstart,i=r.lookahead-(v-1);r.ins_h=(r.ins_h<>>=y=v>>>24,p-=y,0==(y=v>>>16&255))C[s++]=65535&v;else{if(!(16&y)){if(0==(64&y)){v=m[(65535&v)+(c&(1<>>=y,p-=y),p<15&&(c+=z[n++]<>>=y=v>>>24,p-=y,!(16&(y=v>>>16&255))){if(0==(64&y)){v=_[(65535&v)+(c&(1<>>=y,p-=y,(y=s-a)>3,c&=(1<<(p-=w<<3))-1,e.next_in=n,e.next_out=s,e.avail_in=n>>24&255)+(e>>>8&65280)+((65280&e)<<8)+((255&e)<<24)}function s(){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 I.Buf16(320),this.work=new I.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function a(e){var t;return e&&e.state?(t=e.state,e.total_in=e.total_out=t.total=0,e.msg="",t.wrap&&(e.adler=1&t.wrap),t.mode=P,t.last=0,t.havedict=0,t.dmax=32768,t.head=null,t.hold=0,t.bits=0,t.lencode=t.lendyn=new I.Buf32(n),t.distcode=t.distdyn=new I.Buf32(i),t.sane=1,t.back=-1,N):U}function o(e){var t;return e&&e.state?((t=e.state).wsize=0,t.whave=0,t.wnext=0,a(e)):U}function h(e,t){var r,n;return e&&e.state?(n=e.state,t<0?(r=0,t=-t):(r=1+(t>>4),t<48&&(t&=15)),t&&(t<8||15=s.wsize?(I.arraySet(s.window,t,r-s.wsize,s.wsize,0),s.wnext=0,s.whave=s.wsize):(n<(i=s.wsize-s.wnext)&&(i=n),I.arraySet(s.window,t,r-n,i,s.wnext),(n-=i)?(I.arraySet(s.window,t,r-n,n,0),s.wnext=n,s.whave=s.wsize):(s.wnext+=i,s.wnext===s.wsize&&(s.wnext=0),s.whave>>8&255,r.check=B(r.check,E,2,0),l=u=0,r.mode=2;break}if(r.flags=0,r.head&&(r.head.done=!1),!(1&r.wrap)||(((255&u)<<8)+(u>>8))%31){e.msg="incorrect header check",r.mode=30;break}if(8!=(15&u)){e.msg="unknown compression method",r.mode=30;break}if(l-=4,k=8+(15&(u>>>=4)),0===r.wbits)r.wbits=k;else if(k>r.wbits){e.msg="invalid window size",r.mode=30;break}r.dmax=1<>8&1),512&r.flags&&(E[0]=255&u,E[1]=u>>>8&255,r.check=B(r.check,E,2,0)),l=u=0,r.mode=3;case 3:for(;l<32;){if(0===o)break e;o--,u+=n[s++]<>>8&255,E[2]=u>>>16&255,E[3]=u>>>24&255,r.check=B(r.check,E,4,0)),l=u=0,r.mode=4;case 4:for(;l<16;){if(0===o)break e;o--,u+=n[s++]<>8),512&r.flags&&(E[0]=255&u,E[1]=u>>>8&255,r.check=B(r.check,E,2,0)),l=u=0,r.mode=5;case 5:if(1024&r.flags){for(;l<16;){if(0===o)break e;o--,u+=n[s++]<>>8&255,r.check=B(r.check,E,2,0)),l=u=0}else r.head&&(r.head.extra=null);r.mode=6;case 6:if(1024&r.flags&&(o<(c=r.length)&&(c=o),c&&(r.head&&(k=r.head.extra_len-r.length,r.head.extra||(r.head.extra=new Array(r.head.extra_len)),I.arraySet(r.head.extra,n,s,c,k)),512&r.flags&&(r.check=B(r.check,n,c,s)),o-=c,s+=c,r.length-=c),r.length))break e;r.length=0,r.mode=7;case 7:if(2048&r.flags){if(0===o)break e;for(c=0;k=n[s+c++],r.head&&k&&r.length<65536&&(r.head.name+=String.fromCharCode(k)),k&&c>9&1,r.head.done=!0),e.adler=r.check=0,r.mode=12;break;case 10:for(;l<32;){if(0===o)break e;o--,u+=n[s++]<>>=7&l,l-=7&l,r.mode=27;break}for(;l<3;){if(0===o)break e;o--,u+=n[s++]<>>=1)){case 0:r.mode=14;break;case 1:if(j(r),r.mode=20,6!==t)break;u>>>=2,l-=2;break e;case 2:r.mode=17;break;case 3:e.msg="invalid block type",r.mode=30}u>>>=2,l-=2;break;case 14:for(u>>>=7&l,l-=7&l;l<32;){if(0===o)break e;o--,u+=n[s++]<>>16^65535)){e.msg="invalid stored block lengths",r.mode=30;break}if(r.length=65535&u,l=u=0,r.mode=15,6===t)break e;case 15:r.mode=16;case 16:if(c=r.length){if(o>>=5,l-=5,r.ndist=1+(31&u),u>>>=5,l-=5,r.ncode=4+(15&u),u>>>=4,l-=4,286>>=3,l-=3}for(;r.have<19;)r.lens[A[r.have++]]=0;if(r.lencode=r.lendyn,r.lenbits=7,S={bits:r.lenbits},x=T(0,r.lens,0,19,r.lencode,0,r.work,S),r.lenbits=S.bits,x){e.msg="invalid code lengths set",r.mode=30;break}r.have=0,r.mode=19;case 19:for(;r.have>>16&255,b=65535&C,!((_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>>=_,l-=_,r.lens[r.have++]=b;else{if(16===b){for(z=_+2;l>>=_,l-=_,0===r.have){e.msg="invalid bit length repeat",r.mode=30;break}k=r.lens[r.have-1],c=3+(3&u),u>>>=2,l-=2}else if(17===b){for(z=_+3;l>>=_)),u>>>=3,l-=3}else{for(z=_+7;l>>=_)),u>>>=7,l-=7}if(r.have+c>r.nlen+r.ndist){e.msg="invalid bit length repeat",r.mode=30;break}for(;c--;)r.lens[r.have++]=k}}if(30===r.mode)break;if(0===r.lens[256]){e.msg="invalid code -- missing end-of-block",r.mode=30;break}if(r.lenbits=9,S={bits:r.lenbits},x=T(D,r.lens,0,r.nlen,r.lencode,0,r.work,S),r.lenbits=S.bits,x){e.msg="invalid literal/lengths set",r.mode=30;break}if(r.distbits=6,r.distcode=r.distdyn,S={bits:r.distbits},x=T(F,r.lens,r.nlen,r.ndist,r.distcode,0,r.work,S),r.distbits=S.bits,x){e.msg="invalid distances set",r.mode=30;break}if(r.mode=20,6===t)break e;case 20:r.mode=21;case 21:if(6<=o&&258<=h){e.next_out=a,e.avail_out=h,e.next_in=s,e.avail_in=o,r.hold=u,r.bits=l,R(e,d),a=e.next_out,i=e.output,h=e.avail_out,s=e.next_in,n=e.input,o=e.avail_in,u=r.hold,l=r.bits,12===r.mode&&(r.back=-1);break}for(r.back=0;g=(C=r.lencode[u&(1<>>16&255,b=65535&C,!((_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>v)])>>>16&255,b=65535&C,!(v+(_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>>=v,l-=v,r.back+=v}if(u>>>=_,l-=_,r.back+=_,r.length=b,0===g){r.mode=26;break}if(32&g){r.back=-1,r.mode=12;break}if(64&g){e.msg="invalid literal/length code",r.mode=30;break}r.extra=15&g,r.mode=22;case 22:if(r.extra){for(z=r.extra;l>>=r.extra,l-=r.extra,r.back+=r.extra}r.was=r.length,r.mode=23;case 23:for(;g=(C=r.distcode[u&(1<>>16&255,b=65535&C,!((_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>v)])>>>16&255,b=65535&C,!(v+(_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>>=v,l-=v,r.back+=v}if(u>>>=_,l-=_,r.back+=_,64&g){e.msg="invalid distance code",r.mode=30;break}r.offset=b,r.extra=15&g,r.mode=24;case 24:if(r.extra){for(z=r.extra;l>>=r.extra,l-=r.extra,r.back+=r.extra}if(r.offset>r.dmax){e.msg="invalid distance too far back",r.mode=30;break}r.mode=25;case 25:if(0===h)break e;if(c=d-h,r.offset>c){if((c=r.offset-c)>r.whave&&r.sane){e.msg="invalid distance too far back",r.mode=30;break}p=c>r.wnext?(c-=r.wnext,r.wsize-c):r.wnext-c,c>r.length&&(c=r.length),m=r.window}else m=i,p=a-r.offset,c=r.length;for(hc?(m=R[T+a[v]],A[I+a[v]]):(m=96,0),h=1<>S)+(u-=h)]=p<<24|m<<16|_|0,0!==u;);for(h=1<>=1;if(0!==h?(E&=h-1,E+=h):E=0,v++,0==--O[b]){if(b===w)break;b=t[r+a[v]]}if(k>>7)]}function x(e,t){e.pending_buf[e.pending++]=255&t,e.pending_buf[e.pending++]=t>>>8&255}function S(e,t,r){e.bi_valid>i-r?(e.bi_buf|=t<>i-e.bi_valid,e.bi_valid+=r-i):(e.bi_buf|=t<>>=1,r<<=1,0<--t;);return r>>>1}function E(e,t,r){var n,i,s=new Array(_+1),a=0;for(n=1;n<=_;n++)s[n]=a=a+r[n-1]<<1;for(i=0;i<=t;i++){var o=e[2*i+1];0!==o&&(e[2*i]=C(s[o]++,o))}}function A(e){var t;for(t=0;t<286;t++)e.dyn_ltree[2*t]=0;for(t=0;t<30;t++)e.dyn_dtree[2*t]=0;for(t=0;t<19;t++)e.bl_tree[2*t]=0;e.dyn_ltree[512]=1,e.opt_len=e.static_len=0,e.last_lit=e.matches=0}function I(e){8>1;1<=r;r--)B(e,s,r);for(i=h;r=e.heap[1],e.heap[1]=e.heap[e.heap_len--],B(e,s,1),n=e.heap[1],e.heap[--e.heap_max]=r,e.heap[--e.heap_max]=n,s[2*i]=s[2*r]+s[2*n],e.depth[i]=(e.depth[r]>=e.depth[n]?e.depth[r]:e.depth[n])+1,s[2*r+1]=s[2*n+1]=i,e.heap[1]=i++,B(e,s,1),2<=e.heap_len;);e.heap[--e.heap_max]=e.heap[1],function(e,t){var r,n,i,s,a,o,h=t.dyn_tree,u=t.max_code,l=t.stat_desc.static_tree,f=t.stat_desc.has_stree,d=t.stat_desc.extra_bits,c=t.stat_desc.extra_base,p=t.stat_desc.max_length,m=0;for(s=0;s<=_;s++)e.bl_count[s]=0;for(h[2*e.heap[e.heap_max]+1]=0,r=e.heap_max+1;r<573;r++)p<(s=h[2*h[2*(n=e.heap[r])+1]+1]+1)&&(s=p,m++),h[2*n+1]=s,u>=7;n<30;n++)for(y[n]=i<<7,e=0;e<1<>>=1)if(1&r&&0!==e.dyn_ltree[2*t])return 0;if(0!==e.dyn_ltree[18]||0!==e.dyn_ltree[20]||0!==e.dyn_ltree[26])return 1;for(t=32;t<256;t++)if(0!==e.dyn_ltree[2*t])return 1;return 0}(e)),T(e,e.l_desc),T(e,e.d_desc),a=function(e){var t;for(D(e,e.dyn_ltree,e.l_desc.max_code),D(e,e.dyn_dtree,e.d_desc.max_code),T(e,e.bl_desc),t=18;3<=t&&0===e.bl_tree[2*l[t]+1];t--);return e.opt_len+=3*(t+1)+5+5+4,t}(e),i=e.opt_len+3+7>>>3,(s=e.static_len+3+7>>>3)<=i&&(i=s)):i=s=r+5,r+4<=i&&-1!==t?U(e,t,r,n):4===e.strategy||s===i?(S(e,2+(n?1:0),3),R(e,f,d)):(S(e,4+(n?1:0),3),function(e,t,r,n){var i;for(S(e,t-257,5),S(e,r-1,5),S(e,n-4,4),i=0;i>>8&255,e.pending_buf[e.d_buf+2*e.last_lit+1]=255&t,e.pending_buf[e.l_buf+e.last_lit]=255&r,e.last_lit++,0===t?e.dyn_ltree[2*r]++:(e.matches++,t--,e.dyn_ltree[2*(p[r]+256+1)]++,e.dyn_dtree[2*k(t)]++),e.last_lit===e.lit_bufsize-1},r._tr_align=function(e){var t;S(e,2,3),z(e,256,f),16===(t=e).bi_valid?(x(t,t.bi_buf),t.bi_buf=0,t.bi_valid=0):8<=t.bi_valid&&(t.pending_buf[t.pending++]=255&t.bi_buf,t.bi_buf>>=8,t.bi_valid-=8)}},{"../utils/common":41}],53:[function(e,t,r){"use strict";t.exports=function(){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}},{}],54:[function(e,t,r){"use strict";t.exports="function"==typeof setImmediate?setImmediate:function(){var e=[].slice.apply(arguments);e.splice(1,0,0),setTimeout.apply(null,e)}},{}]},{},[10])(10)})}).call(this,void 0!==r?r:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}]},{},[1])(1)})}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}]},{},[1])(1)});
\ No newline at end of file
diff --git a/docs/member-search-index.js b/docs/member-search-index.js
new file mode 100644
index 0000000000..c570d318a3
--- /dev/null
+++ b/docs/member-search-index.js
@@ -0,0 +1 @@
+memberSearchIndex = [{"p":"dukechatbot.utility","c":"TaskList","l":"add(String)","url":"add(java.lang.String)"},{"p":"dukechatbot.utility","c":"TaskList","l":"add(Task)","url":"add(dukechatbot.utility.Task)"},{"p":"dukechatbot.utility","c":"Ui","l":"added(Task)","url":"added(dukechatbot.utility.Task)"},{"p":"dukechatbot.utility","c":"Ui","l":"bye()"},{"p":"dukechatbot.utility","c":"Parser","l":"categorise(String)","url":"categorise(java.lang.String)"},{"p":"dukechatbot.utility","c":"Deadline","l":"Deadline(String, String)","url":"%3Cinit%3E(java.lang.String,java.lang.String)"},{"p":"dukechatbot.utility","c":"TaskList","l":"delete(Integer, Ui)","url":"delete(java.lang.Integer,dukechatbot.utility.Ui)"},{"p":"dukechatbot.utility","c":"Task","l":"description"},{"p":"dukechatbot.utility","c":"Deadline","l":"DTF"},{"p":"dukechatbot.utility","c":"Event","l":"DTF"},{"p":"dukechatbot.duke","c":"Duke","l":"Duke(String)","url":"%3Cinit%3E(java.lang.String)"},{"p":"dukechatbot.dukeexception","c":"DukeException","l":"DukeException(String)","url":"%3Cinit%3E(java.lang.String)"},{"p":"dukechatbot.utility","c":"Event","l":"end"},{"p":"dukechatbot.utility","c":"Event","l":"Event(String, String)","url":"%3Cinit%3E(java.lang.String,java.lang.String)"},{"p":"dukechatbot.utility","c":"EventTest","l":"EventTest()","url":"%3Cinit%3E()"},{"p":"dukechatbot.utility","c":"EventTest","l":"eventToStringTest()"},{"p":"dukechatbot.utility","c":"TaskList","l":"find(String, Ui)","url":"find(java.lang.String,dukechatbot.utility.Ui)"},{"p":"dukechatbot.utility","c":"TaskList","l":"getArrayList()"},{"p":"dukechatbot.utility","c":"Task","l":"getStatusIcon()"},{"p":"dukechatbot.utility","c":"Ui","l":"greet()"},{"p":"dukechatbot.utility","c":"Task","l":"isDone"},{"p":"dukechatbot.utility","c":"Ui","l":"listMatch(ArrayList)","url":"listMatch(java.util.ArrayList)"},{"p":"dukechatbot.utility","c":"Ui","l":"listOut(ArrayList)","url":"listOut(java.util.ArrayList)"},{"p":"dukechatbot.utility","c":"Storage","l":"load()"},{"p":"dukechatbot.duke","c":"Duke","l":"main(String[])","url":"main(java.lang.String[])"},{"p":"dukechatbot.utility","c":"TaskList","l":"mark(int, Ui)","url":"mark(int,dukechatbot.utility.Ui)"},{"p":"dukechatbot.utility","c":"Task","l":"markAsDone()"},{"p":"dukechatbot.utility","c":"Task","l":"markAsUndone()"},{"p":"dukechatbot.utility","c":"Ui","l":"marked(Task)","url":"marked(dukechatbot.utility.Task)"},{"p":"dukechatbot.utility","c":"Parser","l":"Parser(TaskList, Ui)","url":"%3Cinit%3E(dukechatbot.utility.TaskList,dukechatbot.utility.Ui)"},{"p":"dukechatbot.utility","c":"Ui","l":"removed(Task, ArrayList)","url":"removed(dukechatbot.utility.Task,java.util.ArrayList)"},{"p":"dukechatbot.duke","c":"Duke","l":"run()"},{"p":"dukechatbot.utility","c":"Storage","l":"save()"},{"p":"dukechatbot.utility","c":"Ui","l":"showDescEmptyError(String)","url":"showDescEmptyError(java.lang.String)"},{"p":"dukechatbot.utility","c":"Ui","l":"showLoadingError()"},{"p":"dukechatbot.utility","c":"Ui","l":"showTimeMissingError()"},{"p":"dukechatbot.utility","c":"Ui","l":"showUnknownCommandError()"},{"p":"dukechatbot.utility","c":"Storage","l":"Storage(String, TaskList, Ui)","url":"%3Cinit%3E(java.lang.String,dukechatbot.utility.TaskList,dukechatbot.utility.Ui)"},{"p":"dukechatbot.utility","c":"Deadline","l":"TAG"},{"p":"dukechatbot.utility","c":"Event","l":"TAG"},{"p":"dukechatbot.utility","c":"Todo","l":"TAG"},{"p":"dukechatbot.utility","c":"Task","l":"Task(String)","url":"%3Cinit%3E(java.lang.String)"},{"p":"dukechatbot.utility","c":"TaskList","l":"TaskList(ArrayList)","url":"%3Cinit%3E(java.util.ArrayList)"},{"p":"dukechatbot.utility","c":"Task","l":"time"},{"p":"dukechatbot.utility","c":"Todo","l":"Todo(String)","url":"%3Cinit%3E(java.lang.String)"},{"p":"dukechatbot.utility","c":"TodoTest","l":"TodoTest()","url":"%3Cinit%3E()"},{"p":"dukechatbot.utility","c":"TodoTest","l":"todoToStringTest()"},{"p":"dukechatbot.utility","c":"Deadline","l":"toString()"},{"p":"dukechatbot.utility","c":"Event","l":"toString()"},{"p":"dukechatbot.utility","c":"Task","l":"toString()"},{"p":"dukechatbot.utility","c":"Todo","l":"toString()"},{"p":"dukechatbot.utility","c":"Ui","l":"Ui(ArrayList)","url":"%3Cinit%3E(java.util.ArrayList)"},{"p":"dukechatbot.utility","c":"TaskList","l":"unmark(int, Ui)","url":"unmark(int,dukechatbot.utility.Ui)"},{"p":"dukechatbot.utility","c":"Ui","l":"unmarked(Task)","url":"unmarked(dukechatbot.utility.Task)"}]
\ No newline at end of file
diff --git a/docs/member-search-index.zip b/docs/member-search-index.zip
new file mode 100644
index 0000000000..70da34ad74
Binary files /dev/null and b/docs/member-search-index.zip differ
diff --git a/docs/package-search-index.js b/docs/package-search-index.js
new file mode 100644
index 0000000000..bd13818576
--- /dev/null
+++ b/docs/package-search-index.js
@@ -0,0 +1 @@
+packageSearchIndex = [{"l":"All Packages","url":"allpackages-index.html"},{"l":"dukechatbot.duke"},{"l":"dukechatbot.dukeexception"},{"l":"dukechatbot.utility"}]
\ No newline at end of file
diff --git a/docs/package-search-index.zip b/docs/package-search-index.zip
new file mode 100644
index 0000000000..33f3a7425c
Binary files /dev/null and b/docs/package-search-index.zip differ
diff --git a/docs/resources/glass.png b/docs/resources/glass.png
new file mode 100644
index 0000000000..a7f591f467
Binary files /dev/null and b/docs/resources/glass.png differ
diff --git a/docs/resources/x.png b/docs/resources/x.png
new file mode 100644
index 0000000000..30548a756e
Binary files /dev/null and b/docs/resources/x.png differ
diff --git a/docs/script.js b/docs/script.js
new file mode 100644
index 0000000000..41215a5ab3
--- /dev/null
+++ b/docs/script.js
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+
+var moduleSearchIndex;
+var packageSearchIndex;
+var typeSearchIndex;
+var memberSearchIndex;
+var tagSearchIndex;
+function loadScripts(doc, tag) {
+ createElem(doc, tag, 'jquery/jszip/dist/jszip.js');
+ createElem(doc, tag, 'jquery/jszip-utils/dist/jszip-utils.js');
+ if (window.navigator.userAgent.indexOf('MSIE ') > 0 || window.navigator.userAgent.indexOf('Trident/') > 0 ||
+ window.navigator.userAgent.indexOf('Edge/') > 0) {
+ createElem(doc, tag, 'jquery/jszip-utils/dist/jszip-utils-ie.js');
+ }
+ createElem(doc, tag, 'search.js');
+
+ $.get(pathtoroot + "module-search-index.zip")
+ .done(function() {
+ JSZipUtils.getBinaryContent(pathtoroot + "module-search-index.zip", function(e, data) {
+ JSZip.loadAsync(data).then(function(zip){
+ zip.file("module-search-index.json").async("text").then(function(content){
+ moduleSearchIndex = JSON.parse(content);
+ });
+ });
+ });
+ });
+ $.get(pathtoroot + "package-search-index.zip")
+ .done(function() {
+ JSZipUtils.getBinaryContent(pathtoroot + "package-search-index.zip", function(e, data) {
+ JSZip.loadAsync(data).then(function(zip){
+ zip.file("package-search-index.json").async("text").then(function(content){
+ packageSearchIndex = JSON.parse(content);
+ });
+ });
+ });
+ });
+ $.get(pathtoroot + "type-search-index.zip")
+ .done(function() {
+ JSZipUtils.getBinaryContent(pathtoroot + "type-search-index.zip", function(e, data) {
+ JSZip.loadAsync(data).then(function(zip){
+ zip.file("type-search-index.json").async("text").then(function(content){
+ typeSearchIndex = JSON.parse(content);
+ });
+ });
+ });
+ });
+ $.get(pathtoroot + "member-search-index.zip")
+ .done(function() {
+ JSZipUtils.getBinaryContent(pathtoroot + "member-search-index.zip", function(e, data) {
+ JSZip.loadAsync(data).then(function(zip){
+ zip.file("member-search-index.json").async("text").then(function(content){
+ memberSearchIndex = JSON.parse(content);
+ });
+ });
+ });
+ });
+ $.get(pathtoroot + "tag-search-index.zip")
+ .done(function() {
+ JSZipUtils.getBinaryContent(pathtoroot + "tag-search-index.zip", function(e, data) {
+ JSZip.loadAsync(data).then(function(zip){
+ zip.file("tag-search-index.json").async("text").then(function(content){
+ tagSearchIndex = JSON.parse(content);
+ });
+ });
+ });
+ });
+ if (!moduleSearchIndex) {
+ createElem(doc, tag, 'module-search-index.js');
+ }
+ if (!packageSearchIndex) {
+ createElem(doc, tag, 'package-search-index.js');
+ }
+ if (!typeSearchIndex) {
+ createElem(doc, tag, 'type-search-index.js');
+ }
+ if (!memberSearchIndex) {
+ createElem(doc, tag, 'member-search-index.js');
+ }
+ if (!tagSearchIndex) {
+ createElem(doc, tag, 'tag-search-index.js');
+ }
+ $(window).resize(function() {
+ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
+ });
+}
+
+function createElem(doc, tag, path) {
+ var script = doc.createElement(tag);
+ var scriptElement = doc.getElementsByTagName(tag)[0];
+ script.src = pathtoroot + path;
+ scriptElement.parentNode.insertBefore(script, scriptElement);
+}
+
+function show(type) {
+ count = 0;
+ for (var key in data) {
+ var row = document.getElementById(key);
+ if ((data[key] & type) !== 0) {
+ row.style.display = '';
+ row.className = (count++ % 2) ? rowColor : altColor;
+ }
+ else
+ row.style.display = 'none';
+ }
+ updateTabs(type);
+}
+
+function updateTabs(type) {
+ for (var value in tabs) {
+ var sNode = document.getElementById(tabs[value][0]);
+ var spanNode = sNode.firstChild;
+ if (value == type) {
+ sNode.className = activeTableTab;
+ spanNode.innerHTML = tabs[value][1];
+ }
+ else {
+ sNode.className = tableTab;
+ spanNode.innerHTML = "" + tabs[value][1] + " ";
+ }
+ }
+}
+
+function updateModuleFrame(pFrame, cFrame) {
+ top.packageFrame.location = pFrame;
+ top.classFrame.location = cFrame;
+}
diff --git a/docs/search.js b/docs/search.js
new file mode 100644
index 0000000000..38160c2fb7
--- /dev/null
+++ b/docs/search.js
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+
+var noResult = {l: "No results found"};
+var catModules = "Modules";
+var catPackages = "Packages";
+var catTypes = "Types";
+var catMembers = "Members";
+var catSearchTags = "SearchTags";
+var highlight = "$& ";
+var camelCaseRegexp = "";
+var secondaryMatcher = "";
+function getHighlightedText(item) {
+ var ccMatcher = new RegExp(camelCaseRegexp);
+ var label = item.replace(ccMatcher, highlight);
+ if (label === item) {
+ label = item.replace(secondaryMatcher, highlight);
+ }
+ return label;
+}
+function getURLPrefix(ui) {
+ var urlPrefix="";
+ if (useModuleDirectories) {
+ var slash = "/";
+ if (ui.item.category === catModules) {
+ return ui.item.l + slash;
+ } else if (ui.item.category === catPackages && ui.item.m) {
+ return ui.item.m + slash;
+ } else if ((ui.item.category === catTypes && ui.item.p) || ui.item.category === catMembers) {
+ $.each(packageSearchIndex, function(index, item) {
+ if (ui.item.p == item.l) {
+ urlPrefix = item.m + slash;
+ }
+ });
+ return urlPrefix;
+ } else {
+ return urlPrefix;
+ }
+ }
+ return urlPrefix;
+}
+var watermark = 'Search';
+$(function() {
+ $("#search").val('');
+ $("#search").prop("disabled", false);
+ $("#reset").prop("disabled", false);
+ $("#search").val(watermark).addClass('watermark');
+ $("#search").blur(function() {
+ if ($(this).val().length == 0) {
+ $(this).val(watermark).addClass('watermark');
+ }
+ });
+ $("#search").on('click keydown', function() {
+ if ($(this).val() == watermark) {
+ $(this).val('').removeClass('watermark');
+ }
+ });
+ $("#reset").click(function() {
+ $("#search").val('');
+ $("#search").focus();
+ });
+ $("#search").focus();
+ $("#search")[0].setSelectionRange(0, 0);
+});
+$.widget("custom.catcomplete", $.ui.autocomplete, {
+ _create: function() {
+ this._super();
+ this.widget().menu("option", "items", "> :not(.ui-autocomplete-category)");
+ },
+ _renderMenu: function(ul, items) {
+ var rMenu = this,
+ currentCategory = "";
+ rMenu.menu.bindings = $();
+ $.each(items, function(index, item) {
+ var li;
+ if (item.l !== noResult.l && item.category !== currentCategory) {
+ ul.append("" + item.category + " ");
+ currentCategory = item.category;
+ }
+ li = rMenu._renderItemData(ul, item);
+ if (item.category) {
+ li.attr("aria-label", item.category + " : " + item.l);
+ li.attr("class", "resultItem");
+ } else {
+ li.attr("aria-label", item.l);
+ li.attr("class", "resultItem");
+ }
+ });
+ },
+ _renderItem: function(ul, item) {
+ var label = "";
+ if (item.category === catModules) {
+ label = getHighlightedText(item.l);
+ } else if (item.category === catPackages) {
+ label = (item.m)
+ ? getHighlightedText(item.m + "/" + item.l)
+ : getHighlightedText(item.l);
+ } else if (item.category === catTypes) {
+ label = (item.p)
+ ? getHighlightedText(item.p + "." + item.l)
+ : getHighlightedText(item.l);
+ } else if (item.category === catMembers) {
+ label = getHighlightedText(item.p + "." + (item.c + "." + item.l));
+ } else if (item.category === catSearchTags) {
+ label = getHighlightedText(item.l);
+ } else {
+ label = item.l;
+ }
+ var li = $(" ").appendTo(ul);
+ var div = $("
").appendTo(li);
+ if (item.category === catSearchTags) {
+ if (item.d) {
+ div.html(label + " (" + item.h + ") "
+ + item.d + " ");
+ } else {
+ div.html(label + " (" + item.h + ") ");
+ }
+ } else {
+ div.html(label);
+ }
+ return li;
+ }
+});
+$(function() {
+ $("#search").catcomplete({
+ minLength: 1,
+ delay: 100,
+ source: function(request, response) {
+ var result = new Array();
+ var presult = new Array();
+ var tresult = new Array();
+ var mresult = new Array();
+ var tgresult = new Array();
+ var secondaryresult = new Array();
+ var displayCount = 0;
+ var exactMatcher = new RegExp("^" + $.ui.autocomplete.escapeRegex(request.term) + "$", "i");
+ camelCaseRegexp = ($.ui.autocomplete.escapeRegex(request.term)).split(/(?=[A-Z])/).join("([a-z0-9_$]*?)");
+ var camelCaseMatcher = new RegExp("^" + camelCaseRegexp);
+ secondaryMatcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
+
+ // Return the nested innermost name from the specified object
+ function nestedName(e) {
+ return e.l.substring(e.l.lastIndexOf(".") + 1);
+ }
+
+ function concatResults(a1, a2) {
+ a1 = a1.concat(a2);
+ a2.length = 0;
+ return a1;
+ }
+
+ if (moduleSearchIndex) {
+ var mdleCount = 0;
+ $.each(moduleSearchIndex, function(index, item) {
+ item.category = catModules;
+ if (exactMatcher.test(item.l)) {
+ result.push(item);
+ mdleCount++;
+ } else if (camelCaseMatcher.test(item.l)) {
+ result.push(item);
+ } else if (secondaryMatcher.test(item.l)) {
+ secondaryresult.push(item);
+ }
+ });
+ displayCount = mdleCount;
+ result = concatResults(result, secondaryresult);
+ }
+ if (packageSearchIndex) {
+ var pCount = 0;
+ var pkg = "";
+ $.each(packageSearchIndex, function(index, item) {
+ item.category = catPackages;
+ pkg = (item.m)
+ ? (item.m + "/" + item.l)
+ : item.l;
+ if (exactMatcher.test(item.l)) {
+ presult.push(item);
+ pCount++;
+ } else if (camelCaseMatcher.test(pkg)) {
+ presult.push(item);
+ } else if (secondaryMatcher.test(pkg)) {
+ secondaryresult.push(item);
+ }
+ });
+ result = result.concat(concatResults(presult, secondaryresult));
+ displayCount = (pCount > displayCount) ? pCount : displayCount;
+ }
+ if (typeSearchIndex) {
+ var tCount = 0;
+ $.each(typeSearchIndex, function(index, item) {
+ item.category = catTypes;
+ var s = nestedName(item);
+ if (exactMatcher.test(s)) {
+ tresult.push(item);
+ tCount++;
+ } else if (camelCaseMatcher.test(s)) {
+ tresult.push(item);
+ } else if (secondaryMatcher.test(item.p + "." + item.l)) {
+ secondaryresult.push(item);
+ }
+ });
+ result = result.concat(concatResults(tresult, secondaryresult));
+ displayCount = (tCount > displayCount) ? tCount : displayCount;
+ }
+ if (memberSearchIndex) {
+ var mCount = 0;
+ $.each(memberSearchIndex, function(index, item) {
+ item.category = catMembers;
+ var s = nestedName(item);
+ if (exactMatcher.test(s)) {
+ mresult.push(item);
+ mCount++;
+ } else if (camelCaseMatcher.test(s)) {
+ mresult.push(item);
+ } else if (secondaryMatcher.test(item.c + "." + item.l)) {
+ secondaryresult.push(item);
+ }
+ });
+ result = result.concat(concatResults(mresult, secondaryresult));
+ displayCount = (mCount > displayCount) ? mCount : displayCount;
+ }
+ if (tagSearchIndex) {
+ var tgCount = 0;
+ $.each(tagSearchIndex, function(index, item) {
+ item.category = catSearchTags;
+ if (exactMatcher.test(item.l)) {
+ tgresult.push(item);
+ tgCount++;
+ } else if (secondaryMatcher.test(item.l)) {
+ secondaryresult.push(item);
+ }
+ });
+ result = result.concat(concatResults(tgresult, secondaryresult));
+ displayCount = (tgCount > displayCount) ? tgCount : displayCount;
+ }
+ displayCount = (displayCount > 500) ? displayCount : 500;
+ var counter = function() {
+ var count = {Modules: 0, Packages: 0, Types: 0, Members: 0, SearchTags: 0};
+ var f = function(item) {
+ count[item.category] += 1;
+ return (count[item.category] <= displayCount);
+ };
+ return f;
+ }();
+ response(result.filter(counter));
+ },
+ response: function(event, ui) {
+ if (!ui.content.length) {
+ ui.content.push(noResult);
+ } else {
+ $("#search").empty();
+ }
+ },
+ autoFocus: true,
+ position: {
+ collision: "flip"
+ },
+ select: function(event, ui) {
+ if (ui.item.l !== noResult.l) {
+ var url = getURLPrefix(ui);
+ if (ui.item.category === catModules) {
+ if (useModuleDirectories) {
+ url += "module-summary.html";
+ } else {
+ url = ui.item.l + "-summary.html";
+ }
+ } else if (ui.item.category === catPackages) {
+ if (ui.item.url) {
+ url = ui.item.url;
+ } else {
+ url += ui.item.l.replace(/\./g, '/') + "/package-summary.html";
+ }
+ } else if (ui.item.category === catTypes) {
+ if (ui.item.url) {
+ url = ui.item.url;
+ } else if (ui.item.p === "") {
+ url += ui.item.l + ".html";
+ } else {
+ url += ui.item.p.replace(/\./g, '/') + "/" + ui.item.l + ".html";
+ }
+ } else if (ui.item.category === catMembers) {
+ if (ui.item.p === "") {
+ url += ui.item.c + ".html" + "#";
+ } else {
+ url += ui.item.p.replace(/\./g, '/') + "/" + ui.item.c + ".html" + "#";
+ }
+ if (ui.item.url) {
+ url += ui.item.url;
+ } else {
+ url += ui.item.l;
+ }
+ } else if (ui.item.category === catSearchTags) {
+ url += ui.item.u;
+ }
+ if (top !== window) {
+ parent.classFrame.location = pathtoroot + url;
+ } else {
+ window.location.href = pathtoroot + url;
+ }
+ $("#search").focus();
+ }
+ }
+ });
+});
diff --git a/docs/stylesheet.css b/docs/stylesheet.css
new file mode 100644
index 0000000000..fa246765cf
--- /dev/null
+++ b/docs/stylesheet.css
@@ -0,0 +1,906 @@
+/*
+ * Javadoc style sheet
+ */
+
+@import url('resources/fonts/dejavu.css');
+
+/*
+ * Styles for individual HTML elements.
+ *
+ * These are styles that are specific to individual HTML elements. Changing them affects the style of a particular
+ * HTML element throughout the page.
+ */
+
+body {
+ background-color:#ffffff;
+ color:#353833;
+ font-family:'DejaVu Sans', Arial, Helvetica, sans-serif;
+ font-size:14px;
+ margin:0;
+ padding:0;
+ height:100%;
+ width:100%;
+}
+iframe {
+ margin:0;
+ padding:0;
+ height:100%;
+ width:100%;
+ overflow-y:scroll;
+ border:none;
+}
+a:link, a:visited {
+ text-decoration:none;
+ color:#4A6782;
+}
+a[href]:hover, a[href]:focus {
+ text-decoration:none;
+ color:#bb7a2a;
+}
+a[name] {
+ color:#353833;
+}
+a[name]:before, a[name]:target, a[id]:before, a[id]:target {
+ content:"";
+ display:inline-block;
+ position:relative;
+ padding-top:129px;
+ margin-top:-129px;
+}
+pre {
+ font-family:'DejaVu Sans Mono', monospace;
+ font-size:14px;
+}
+h1 {
+ font-size:20px;
+}
+h2 {
+ font-size:18px;
+}
+h3 {
+ font-size:16px;
+ font-style:italic;
+}
+h4 {
+ font-size:13px;
+}
+h5 {
+ font-size:12px;
+}
+h6 {
+ font-size:11px;
+}
+ul {
+ list-style-type:disc;
+}
+code, tt {
+ font-family:'DejaVu Sans Mono', monospace;
+ font-size:14px;
+ padding-top:4px;
+ margin-top:8px;
+ line-height:1.4em;
+}
+dt code {
+ font-family:'DejaVu Sans Mono', monospace;
+ font-size:14px;
+ padding-top:4px;
+}
+table tr td dt code {
+ font-family:'DejaVu Sans Mono', monospace;
+ font-size:14px;
+ vertical-align:top;
+ padding-top:4px;
+}
+sup {
+ font-size:8px;
+}
+
+/*
+ * Styles for HTML generated by javadoc.
+ *
+ * These are style classes that are used by the standard doclet to generate HTML documentation.
+ */
+
+/*
+ * Styles for document title and copyright.
+ */
+.clear {
+ clear:both;
+ height:0px;
+ overflow:hidden;
+}
+.aboutLanguage {
+ float:right;
+ padding:0px 21px;
+ font-size:11px;
+ z-index:200;
+ margin-top:-9px;
+}
+.legalCopy {
+ margin-left:.5em;
+}
+.bar a, .bar a:link, .bar a:visited, .bar a:active {
+ color:#FFFFFF;
+ text-decoration:none;
+}
+.bar a:hover, .bar a:focus {
+ color:#bb7a2a;
+}
+.tab {
+ background-color:#0066FF;
+ color:#ffffff;
+ padding:8px;
+ width:5em;
+ font-weight:bold;
+}
+/*
+ * Styles for navigation bar.
+ */
+.bar {
+ background-color:#4D7A97;
+ color:#FFFFFF;
+ padding:.8em .5em .4em .8em;
+ height:auto;/*height:1.8em;*/
+ font-size:11px;
+ margin:0;
+}
+.navPadding {
+ padding-top: 107px;
+}
+.fixedNav {
+ position:fixed;
+ width:100%;
+ z-index:999;
+ background-color:#ffffff;
+}
+.topNav {
+ background-color:#4D7A97;
+ color:#FFFFFF;
+ float:left;
+ padding:0;
+ width:100%;
+ clear:right;
+ height:2.8em;
+ padding-top:10px;
+ overflow:hidden;
+ font-size:12px;
+}
+.bottomNav {
+ margin-top:10px;
+ background-color:#4D7A97;
+ color:#FFFFFF;
+ float:left;
+ padding:0;
+ width:100%;
+ clear:right;
+ height:2.8em;
+ padding-top:10px;
+ overflow:hidden;
+ font-size:12px;
+}
+.subNav {
+ background-color:#dee3e9;
+ float:left;
+ width:100%;
+ overflow:hidden;
+ font-size:12px;
+}
+.subNav div {
+ clear:left;
+ float:left;
+ padding:0 0 5px 6px;
+ text-transform:uppercase;
+}
+ul.navList, ul.subNavList {
+ float:left;
+ margin:0 25px 0 0;
+ padding:0;
+}
+ul.navList li{
+ list-style:none;
+ float:left;
+ padding: 5px 6px;
+ text-transform:uppercase;
+}
+ul.navListSearch {
+ float:right;
+ margin:0 0 0 0;
+ padding:0;
+}
+ul.navListSearch li {
+ list-style:none;
+ float:right;
+ padding: 5px 6px;
+ text-transform:uppercase;
+}
+ul.navListSearch li label {
+ position:relative;
+ right:-16px;
+}
+ul.subNavList li {
+ list-style:none;
+ float:left;
+}
+.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited {
+ color:#FFFFFF;
+ text-decoration:none;
+ text-transform:uppercase;
+}
+.topNav a:hover, .bottomNav a:hover {
+ text-decoration:none;
+ color:#bb7a2a;
+ text-transform:uppercase;
+}
+.navBarCell1Rev {
+ background-color:#F8981D;
+ color:#253441;
+ margin: auto 5px;
+}
+.skipNav {
+ position:absolute;
+ top:auto;
+ left:-9999px;
+ overflow:hidden;
+}
+/*
+ * Styles for page header and footer.
+ */
+.header, .footer {
+ clear:both;
+ margin:0 20px;
+ padding:5px 0 0 0;
+}
+.indexNav {
+ position:relative;
+ font-size:12px;
+ background-color:#dee3e9;
+}
+.indexNav ul {
+ margin-top:0;
+ padding:5px;
+}
+.indexNav ul li {
+ display:inline;
+ list-style-type:none;
+ padding-right:10px;
+ text-transform:uppercase;
+}
+.indexNav h1 {
+ font-size:13px;
+}
+.title {
+ color:#2c4557;
+ margin:10px 0;
+}
+.subTitle {
+ margin:5px 0 0 0;
+}
+.header ul {
+ margin:0 0 15px 0;
+ padding:0;
+}
+.footer ul {
+ margin:20px 0 5px 0;
+}
+.header ul li, .footer ul li {
+ list-style:none;
+ font-size:13px;
+}
+/*
+ * Styles for headings.
+ */
+div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 {
+ background-color:#dee3e9;
+ border:1px solid #d0d9e0;
+ margin:0 0 6px -8px;
+ padding:7px 5px;
+}
+ul.blockList ul.blockList ul.blockList li.blockList h3 {
+ background-color:#dee3e9;
+ border:1px solid #d0d9e0;
+ margin:0 0 6px -8px;
+ padding:7px 5px;
+}
+ul.blockList ul.blockList li.blockList h3 {
+ padding:0;
+ margin:15px 0;
+}
+ul.blockList li.blockList h2 {
+ padding:0px 0 20px 0;
+}
+/*
+ * Styles for page layout containers.
+ */
+.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer,
+.allClassesContainer, .allPackagesContainer {
+ clear:both;
+ padding:10px 20px;
+ position:relative;
+}
+.indexContainer {
+ margin:10px;
+ position:relative;
+ font-size:12px;
+}
+.indexContainer h2 {
+ font-size:13px;
+ padding:0 0 3px 0;
+}
+.indexContainer ul {
+ margin:0;
+ padding:0;
+}
+.indexContainer ul li {
+ list-style:none;
+ padding-top:2px;
+}
+.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt {
+ font-size:12px;
+ font-weight:bold;
+ margin:10px 0 0 0;
+ color:#4E4E4E;
+}
+.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd {
+ margin:5px 0 10px 0px;
+ font-size:14px;
+ font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif;
+}
+.serializedFormContainer dl.nameValue dt {
+ margin-left:1px;
+ font-size:1.1em;
+ display:inline;
+ font-weight:bold;
+}
+.serializedFormContainer dl.nameValue dd {
+ margin:0 0 0 1px;
+ font-size:1.1em;
+ display:inline;
+}
+/*
+ * Styles for lists.
+ */
+li.circle {
+ list-style:circle;
+}
+ul.horizontal li {
+ display:inline;
+ font-size:0.9em;
+}
+ul.inheritance {
+ margin:0;
+ padding:0;
+}
+ul.inheritance li {
+ display:inline;
+ list-style:none;
+}
+ul.inheritance li ul.inheritance {
+ margin-left:15px;
+ padding-left:15px;
+ padding-top:1px;
+}
+ul.blockList, ul.blockListLast {
+ margin:10px 0 10px 0;
+ padding:0;
+}
+ul.blockList li.blockList, ul.blockListLast li.blockList {
+ list-style:none;
+ margin-bottom:15px;
+ line-height:1.4;
+}
+ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList {
+ padding:0px 20px 5px 10px;
+ border:1px solid #ededed;
+ background-color:#f8f8f8;
+}
+ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList {
+ padding:0 0 5px 8px;
+ background-color:#ffffff;
+ border:none;
+}
+ul.blockList ul.blockList ul.blockList ul.blockList li.blockList {
+ margin-left:0;
+ padding-left:0;
+ padding-bottom:15px;
+ border:none;
+}
+ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast {
+ list-style:none;
+ border-bottom:none;
+ padding-bottom:0;
+}
+table tr td dl, table tr td dl dt, table tr td dl dd {
+ margin-top:0;
+ margin-bottom:1px;
+}
+/*
+ * Styles for tables.
+ */
+.overviewSummary, .memberSummary, .typeSummary, .useSummary, .constantsSummary, .deprecatedSummary,
+.requiresSummary, .packagesSummary, .providesSummary, .usesSummary {
+ width:100%;
+ border-spacing:0;
+ border-left:1px solid #EEE;
+ border-right:1px solid #EEE;
+ border-bottom:1px solid #EEE;
+}
+.overviewSummary, .memberSummary, .requiresSummary, .packagesSummary, .providesSummary, .usesSummary {
+ padding:0px;
+}
+.overviewSummary caption, .memberSummary caption, .typeSummary caption,
+.useSummary caption, .constantsSummary caption, .deprecatedSummary caption,
+.requiresSummary caption, .packagesSummary caption, .providesSummary caption, .usesSummary caption {
+ position:relative;
+ text-align:left;
+ background-repeat:no-repeat;
+ color:#253441;
+ font-weight:bold;
+ clear:none;
+ overflow:hidden;
+ padding:0px;
+ padding-top:10px;
+ padding-left:1px;
+ margin:0px;
+ white-space:pre;
+}
+.overviewSummary caption a:link, .memberSummary caption a:link, .typeSummary caption a:link,
+.constantsSummary caption a:link, .deprecatedSummary caption a:link,
+.requiresSummary caption a:link, .packagesSummary caption a:link, .providesSummary caption a:link,
+.usesSummary caption a:link,
+.overviewSummary caption a:hover, .memberSummary caption a:hover, .typeSummary caption a:hover,
+.constantsSummary caption a:hover, .deprecatedSummary caption a:hover,
+.requiresSummary caption a:hover, .packagesSummary caption a:hover, .providesSummary caption a:hover,
+.usesSummary caption a:hover,
+.overviewSummary caption a:active, .memberSummary caption a:active, .typeSummary caption a:active,
+.constantsSummary caption a:active, .deprecatedSummary caption a:active,
+.requiresSummary caption a:active, .packagesSummary caption a:active, .providesSummary caption a:active,
+.usesSummary caption a:active,
+.overviewSummary caption a:visited, .memberSummary caption a:visited, .typeSummary caption a:visited,
+.constantsSummary caption a:visited, .deprecatedSummary caption a:visited,
+.requiresSummary caption a:visited, .packagesSummary caption a:visited, .providesSummary caption a:visited,
+.usesSummary caption a:visited {
+ color:#FFFFFF;
+}
+.useSummary caption a:link, .useSummary caption a:hover, .useSummary caption a:active,
+.useSummary caption a:visited {
+ color:#1f389c;
+}
+.overviewSummary caption span, .memberSummary caption span, .typeSummary caption span,
+.useSummary caption span, .constantsSummary caption span, .deprecatedSummary caption span,
+.requiresSummary caption span, .packagesSummary caption span, .providesSummary caption span,
+.usesSummary caption span {
+ white-space:nowrap;
+ padding-top:5px;
+ padding-left:12px;
+ padding-right:12px;
+ padding-bottom:7px;
+ display:inline-block;
+ float:left;
+ background-color:#F8981D;
+ border: none;
+ height:16px;
+}
+.memberSummary caption span.activeTableTab span, .packagesSummary caption span.activeTableTab span,
+.overviewSummary caption span.activeTableTab span, .typeSummary caption span.activeTableTab span {
+ white-space:nowrap;
+ padding-top:5px;
+ padding-left:12px;
+ padding-right:12px;
+ margin-right:3px;
+ display:inline-block;
+ float:left;
+ background-color:#F8981D;
+ height:16px;
+}
+.memberSummary caption span.tableTab span, .packagesSummary caption span.tableTab span,
+.overviewSummary caption span.tableTab span, .typeSummary caption span.tableTab span {
+ white-space:nowrap;
+ padding-top:5px;
+ padding-left:12px;
+ padding-right:12px;
+ margin-right:3px;
+ display:inline-block;
+ float:left;
+ background-color:#4D7A97;
+ height:16px;
+}
+.memberSummary caption span.tableTab, .memberSummary caption span.activeTableTab,
+.packagesSummary caption span.tableTab, .packagesSummary caption span.activeTableTab,
+.overviewSummary caption span.tableTab, .overviewSummary caption span.activeTableTab,
+.typeSummary caption span.tableTab, .typeSummary caption span.activeTableTab {
+ padding-top:0px;
+ padding-left:0px;
+ padding-right:0px;
+ background-image:none;
+ float:none;
+ display:inline;
+}
+.overviewSummary .tabEnd, .memberSummary .tabEnd, .typeSummary .tabEnd,
+.useSummary .tabEnd, .constantsSummary .tabEnd, .deprecatedSummary .tabEnd,
+.requiresSummary .tabEnd, .packagesSummary .tabEnd, .providesSummary .tabEnd, .usesSummary .tabEnd {
+ display:none;
+ width:5px;
+ position:relative;
+ float:left;
+ background-color:#F8981D;
+}
+.memberSummary .activeTableTab .tabEnd, .packagesSummary .activeTableTab .tabEnd,
+.overviewSummary .activeTableTab .tabEnd, .typeSummary .activeTableTab .tabEnd {
+ display:none;
+ width:5px;
+ margin-right:3px;
+ position:relative;
+ float:left;
+ background-color:#F8981D;
+}
+.memberSummary .tableTab .tabEnd, .packagesSummary .tableTab .tabEnd,
+.overviewSummary .tableTab .tabEnd, .typeSummary .tableTab .tabEnd {
+ display:none;
+ width:5px;
+ margin-right:3px;
+ position:relative;
+ background-color:#4D7A97;
+ float:left;
+}
+.rowColor th, .altColor th {
+ font-weight:normal;
+}
+.overviewSummary td, .memberSummary td, .typeSummary td,
+.useSummary td, .constantsSummary td, .deprecatedSummary td,
+.requiresSummary td, .packagesSummary td, .providesSummary td, .usesSummary td {
+ text-align:left;
+ padding:0px 0px 12px 10px;
+}
+th.colFirst, th.colSecond, th.colLast, th.colConstructorName, th.colDeprecatedItemName, .useSummary th,
+.constantsSummary th, .packagesSummary th, td.colFirst, td.colSecond, td.colLast, .useSummary td,
+.constantsSummary td {
+ vertical-align:top;
+ padding-right:0px;
+ padding-top:8px;
+ padding-bottom:3px;
+}
+th.colFirst, th.colSecond, th.colLast, th.colConstructorName, th.colDeprecatedItemName, .constantsSummary th,
+.packagesSummary th {
+ background:#dee3e9;
+ text-align:left;
+ padding:8px 3px 3px 7px;
+}
+td.colFirst, th.colFirst {
+ font-size:13px;
+}
+td.colSecond, th.colSecond, td.colLast, th.colConstructorName, th.colDeprecatedItemName, th.colLast {
+ font-size:13px;
+}
+.constantsSummary th, .packagesSummary th {
+ font-size:13px;
+}
+.providesSummary th.colFirst, .providesSummary th.colLast, .providesSummary td.colFirst,
+.providesSummary td.colLast {
+ white-space:normal;
+ font-size:13px;
+}
+.overviewSummary td.colFirst, .overviewSummary th.colFirst,
+.requiresSummary td.colFirst, .requiresSummary th.colFirst,
+.packagesSummary td.colFirst, .packagesSummary td.colSecond, .packagesSummary th.colFirst, .packagesSummary th,
+.usesSummary td.colFirst, .usesSummary th.colFirst,
+.providesSummary td.colFirst, .providesSummary th.colFirst,
+.memberSummary td.colFirst, .memberSummary th.colFirst,
+.memberSummary td.colSecond, .memberSummary th.colSecond, .memberSummary th.colConstructorName,
+.typeSummary td.colFirst, .typeSummary th.colFirst {
+ vertical-align:top;
+}
+.packagesSummary th.colLast, .packagesSummary td.colLast {
+ white-space:normal;
+}
+td.colFirst a:link, td.colFirst a:visited,
+td.colSecond a:link, td.colSecond a:visited,
+th.colFirst a:link, th.colFirst a:visited,
+th.colSecond a:link, th.colSecond a:visited,
+th.colConstructorName a:link, th.colConstructorName a:visited,
+th.colDeprecatedItemName a:link, th.colDeprecatedItemName a:visited,
+.constantValuesContainer td a:link, .constantValuesContainer td a:visited,
+.allClassesContainer td a:link, .allClassesContainer td a:visited,
+.allPackagesContainer td a:link, .allPackagesContainer td a:visited {
+ font-weight:bold;
+}
+.tableSubHeadingColor {
+ background-color:#EEEEFF;
+}
+.altColor, .altColor th {
+ background-color:#FFFFFF;
+}
+.rowColor, .rowColor th {
+ background-color:#EEEEEF;
+}
+/*
+ * Styles for contents.
+ */
+.description pre {
+ margin-top:0;
+}
+.deprecatedContent {
+ margin:0;
+ padding:10px 0;
+}
+.docSummary {
+ padding:0;
+}
+ul.blockList ul.blockList ul.blockList li.blockList h3 {
+ font-style:normal;
+}
+div.block {
+ font-size:14px;
+ font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif;
+}
+td.colLast div {
+ padding-top:0px;
+}
+td.colLast a {
+ padding-bottom:3px;
+}
+/*
+ * Styles for formatting effect.
+ */
+.sourceLineNo {
+ color:green;
+ padding:0 30px 0 0;
+}
+h1.hidden {
+ visibility:hidden;
+ overflow:hidden;
+ font-size:10px;
+}
+.block {
+ display:block;
+ margin:3px 10px 2px 0px;
+ color:#474747;
+}
+.deprecatedLabel, .descfrmTypeLabel, .implementationLabel, .memberNameLabel, .memberNameLink,
+.moduleLabelInPackage, .moduleLabelInType, .overrideSpecifyLabel, .packageLabelInType,
+.packageHierarchyLabel, .paramLabel, .returnLabel, .seeLabel, .simpleTagLabel,
+.throwsLabel, .typeNameLabel, .typeNameLink, .searchTagLink {
+ font-weight:bold;
+}
+.deprecationComment, .emphasizedPhrase, .interfaceName {
+ font-style:italic;
+}
+.deprecationBlock {
+ font-size:14px;
+ font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif;
+ border-style:solid;
+ border-width:thin;
+ border-radius:10px;
+ padding:10px;
+ margin-bottom:10px;
+ margin-right:10px;
+ display:inline-block;
+}
+div.block div.deprecationComment, div.block div.block span.emphasizedPhrase,
+div.block div.block span.interfaceName {
+ font-style:normal;
+}
+div.contentContainer ul.blockList li.blockList h2 {
+ padding-bottom:0px;
+}
+/*
+ * Styles for IFRAME.
+ */
+.mainContainer {
+ margin:0 auto;
+ padding:0;
+ height:100%;
+ width:100%;
+ position:fixed;
+ top:0;
+ left:0;
+}
+.leftContainer {
+ height:100%;
+ position:fixed;
+ width:320px;
+}
+.leftTop {
+ position:relative;
+ float:left;
+ width:315px;
+ top:0;
+ left:0;
+ height:30%;
+ border-right:6px solid #ccc;
+ border-bottom:6px solid #ccc;
+}
+.leftBottom {
+ position:relative;
+ float:left;
+ width:315px;
+ bottom:0;
+ left:0;
+ height:70%;
+ border-right:6px solid #ccc;
+ border-top:1px solid #000;
+}
+.rightContainer {
+ position:absolute;
+ left:320px;
+ top:0;
+ bottom:0;
+ height:100%;
+ right:0;
+ border-left:1px solid #000;
+}
+.rightIframe {
+ margin:0;
+ padding:0;
+ height:100%;
+ right:30px;
+ width:100%;
+ overflow:visible;
+ margin-bottom:30px;
+}
+/*
+ * Styles specific to HTML5 elements.
+ */
+main, nav, header, footer, section {
+ display:block;
+}
+/*
+ * Styles for javadoc search.
+ */
+.ui-autocomplete-category {
+ font-weight:bold;
+ font-size:15px;
+ padding:7px 0 7px 3px;
+ background-color:#4D7A97;
+ color:#FFFFFF;
+}
+.resultItem {
+ font-size:13px;
+}
+.ui-autocomplete {
+ max-height:85%;
+ max-width:65%;
+ overflow-y:scroll;
+ overflow-x:scroll;
+ white-space:nowrap;
+ box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23);
+}
+ul.ui-autocomplete {
+ position:fixed;
+ z-index:999999;
+}
+ul.ui-autocomplete li {
+ float:left;
+ clear:both;
+ width:100%;
+}
+.resultHighlight {
+ font-weight:bold;
+}
+#search {
+ background-image:url('resources/glass.png');
+ background-size:13px;
+ background-repeat:no-repeat;
+ background-position:2px 3px;
+ padding-left:20px;
+ position:relative;
+ right:-18px;
+}
+#reset {
+ background-color: rgb(255,255,255);
+ background-image:url('resources/x.png');
+ background-position:center;
+ background-repeat:no-repeat;
+ background-size:12px;
+ border:0 none;
+ width:16px;
+ height:17px;
+ position:relative;
+ left:-4px;
+ top:-4px;
+ font-size:0px;
+}
+.watermark {
+ color:#545454;
+}
+.searchTagDescResult {
+ font-style:italic;
+ font-size:11px;
+}
+.searchTagHolderResult {
+ font-style:italic;
+ font-size:12px;
+}
+.searchTagResult:before, .searchTagResult:target {
+ color:red;
+}
+.moduleGraph span {
+ display:none;
+ position:absolute;
+}
+.moduleGraph:hover span {
+ display:block;
+ margin: -100px 0 0 100px;
+ z-index: 1;
+}
+.methodSignature {
+ white-space:normal;
+}
+
+/*
+ * Styles for user-provided tables.
+ *
+ * borderless:
+ * No borders, vertical margins, styled caption.
+ * This style is provided for use with existing doc comments.
+ * In general, borderless tables should not be used for layout purposes.
+ *
+ * plain:
+ * Plain borders around table and cells, vertical margins, styled caption.
+ * Best for small tables or for complex tables for tables with cells that span
+ * rows and columns, when the "striped" style does not work well.
+ *
+ * striped:
+ * Borders around the table and vertical borders between cells, striped rows,
+ * vertical margins, styled caption.
+ * Best for tables that have a header row, and a body containing a series of simple rows.
+ */
+
+table.borderless,
+table.plain,
+table.striped {
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+table.borderless > caption,
+table.plain > caption,
+table.striped > caption {
+ font-weight: bold;
+ font-size: smaller;
+}
+table.borderless th, table.borderless td,
+table.plain th, table.plain td,
+table.striped th, table.striped td {
+ padding: 2px 5px;
+}
+table.borderless,
+table.borderless > thead > tr > th, table.borderless > tbody > tr > th, table.borderless > tr > th,
+table.borderless > thead > tr > td, table.borderless > tbody > tr > td, table.borderless > tr > td {
+ border: none;
+}
+table.borderless > thead > tr, table.borderless > tbody > tr, table.borderless > tr {
+ background-color: transparent;
+}
+table.plain {
+ border-collapse: collapse;
+ border: 1px solid black;
+}
+table.plain > thead > tr, table.plain > tbody tr, table.plain > tr {
+ background-color: transparent;
+}
+table.plain > thead > tr > th, table.plain > tbody > tr > th, table.plain > tr > th,
+table.plain > thead > tr > td, table.plain > tbody > tr > td, table.plain > tr > td {
+ border: 1px solid black;
+}
+table.striped {
+ border-collapse: collapse;
+ border: 1px solid black;
+}
+table.striped > thead {
+ background-color: #E3E3E3;
+}
+table.striped > thead > tr > th, table.striped > thead > tr > td {
+ border: 1px solid black;
+}
+table.striped > tbody > tr:nth-child(even) {
+ background-color: #EEE
+}
+table.striped > tbody > tr:nth-child(odd) {
+ background-color: #FFF
+}
+table.striped > tbody > tr > th, table.striped > tbody > tr > td {
+ border-left: 1px solid black;
+ border-right: 1px solid black;
+}
+table.striped > tbody > tr > th {
+ font-weight: normal;
+}
diff --git a/docs/type-search-index.js b/docs/type-search-index.js
new file mode 100644
index 0000000000..3ce289294b
--- /dev/null
+++ b/docs/type-search-index.js
@@ -0,0 +1 @@
+typeSearchIndex = [{"l":"All Classes","url":"allclasses-index.html"},{"p":"dukechatbot.utility","l":"Deadline"},{"p":"dukechatbot.duke","l":"Duke"},{"p":"dukechatbot.dukeexception","l":"DukeException"},{"p":"dukechatbot.utility","l":"Event"},{"p":"dukechatbot.utility","l":"EventTest"},{"p":"dukechatbot.utility","l":"Parser"},{"p":"dukechatbot.utility","l":"Storage"},{"p":"dukechatbot.utility","l":"Task"},{"p":"dukechatbot.utility","l":"TaskList"},{"p":"dukechatbot.utility","l":"Todo"},{"p":"dukechatbot.utility","l":"TodoTest"},{"p":"dukechatbot.utility","l":"Ui"}]
\ No newline at end of file
diff --git a/docs/type-search-index.zip b/docs/type-search-index.zip
new file mode 100644
index 0000000000..39bf75c555
Binary files /dev/null and b/docs/type-search-index.zip differ
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000..f3d88b1c2f
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000..b7c8c5dbf5
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.2-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
new file mode 100755
index 0000000000..2fe81a7d95
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,183 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000000..62bd9b9cce
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,103 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java
deleted file mode 100644
index 5d313334cc..0000000000
--- a/src/main/java/Duke.java
+++ /dev/null
@@ -1,10 +0,0 @@
-public class Duke {
- public static void main(String[] args) {
- String logo = " ____ _ \n"
- + "| _ \\ _ _| | _____ \n"
- + "| | | | | | | |/ / _ \\\n"
- + "| |_| | |_| | < __/\n"
- + "|____/ \\__,_|_|\\_\\___|\n";
- System.out.println("Hello from\n" + logo);
- }
-}
diff --git a/src/main/java/META-INF/MANIFEST.MF b/src/main/java/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000..555b31322e
--- /dev/null
+++ b/src/main/java/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: dukechatbot.duke.Duke
+
diff --git a/src/main/java/dukechatbot/duke/DialogBox.java b/src/main/java/dukechatbot/duke/DialogBox.java
new file mode 100644
index 0000000000..7d5774c5fe
--- /dev/null
+++ b/src/main/java/dukechatbot/duke/DialogBox.java
@@ -0,0 +1,86 @@
+package dukechatbot.duke;
+
+import java.io.IOException;
+
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.fxml.FXML;
+import javafx.fxml.FXMLLoader;
+import javafx.geometry.Pos;
+import javafx.scene.Node;
+import javafx.scene.control.Label;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+import javafx.scene.layout.HBox;
+
+/**
+ * The DialogBox class encapsulates the chat box for the interaction between client and
+ * Duke.
+ *
+ * @author A0233290M
+ * @version Week4
+ */
+public class DialogBox extends HBox {
+ /**
+ * Label to encapsulate dialog for clients and Duke.
+ */
+ @FXML
+ private Label dialog;
+ /**
+ * Allows for viewing of respective images used in application.
+ */
+ @FXML
+ private ImageView displayPicture;
+
+ /**
+ * Constructor for DialogBox.
+ *
+ * @param text for the dialog box to display.
+ * @param img the image attached to the text.
+ */
+ private DialogBox(String text, Image img) {
+ try {
+ FXMLLoader loader = new FXMLLoader(MainWindow.class.getResource("/view/DialogBox.fxml"));
+ loader.setController(this);
+ loader.setRoot(this);
+ loader.load();
+ } catch (IOException ioe) {
+ System.out.println(ioe.getMessage());
+ }
+ dialog.setText(text);
+ displayPicture.setImage(img);
+ }
+
+ /**
+ * Flips the horizontal arrangements of the children of DialogBox for
+ * better differentiation between Duke and client dialogs.
+ */
+ private void flip() {
+ ObservableList temp = FXCollections.observableArrayList(this.getChildren());
+ FXCollections.reverse(temp);
+ this.getChildren().setAll(temp);
+ this.setAlignment(Pos.TOP_LEFT);
+ }
+
+ /**
+ * Creates a DialogBox instance for users inputs.
+ * @param input passed by client.
+ * @param img the image attached to the input by client.
+ * @return a DialogBox instance for use to display dialogs.
+ */
+ public static DialogBox getUserDialog(String input, Image img) {
+ return new DialogBox(input, img);
+ }
+
+ /**
+ * Creates a DialogBox instance for Duke responses.
+ * @param output responses passed by client.
+ * @param img the image attached to the responses by Duke.
+ * @return a DialogBox instance for use to display dialogs.
+ */
+ public static DialogBox getDukeDialog(String output, Image img) {
+ DialogBox db = new DialogBox(output, img);
+ db.flip();
+ return db;
+ }
+}
diff --git a/src/main/java/dukechatbot/duke/Duke.java b/src/main/java/dukechatbot/duke/Duke.java
new file mode 100644
index 0000000000..5b64870780
--- /dev/null
+++ b/src/main/java/dukechatbot/duke/Duke.java
@@ -0,0 +1,104 @@
+package dukechatbot.duke;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Scanner;
+
+import dukechatbot.dukeexception.DukeException;
+import dukechatbot.utility.Parser;
+import dukechatbot.utility.Storage;
+import dukechatbot.utility.Task;
+import dukechatbot.utility.TaskList;
+import dukechatbot.utility.Ui;
+
+/**
+ * The Duke program implements an application that allows users
+ * to interactively create a task list for them to keep track of their tasks.
+ *
+ * @author A0233290M
+ * @version Week3
+ *
+ * */
+public class Duke {
+ private Storage storage;
+ private TaskList tasks;
+ private Ui ui;
+ private ArrayList taskArrayList;
+ private Parser parse;
+ private MainWindow gui;
+ /**
+ * Constructs an instance of the Duke class.
+ *
+ */
+ public Duke() {
+ this.gui = new MainWindow();
+ this.taskArrayList = new ArrayList<>();
+ this.ui = new Ui(taskArrayList);
+ try {
+ this.tasks = new TaskList(this.taskArrayList, this.ui);
+ this.storage = new Storage(this.tasks, this.ui);
+ this.parse = new Parser(tasks, ui);
+ } catch (IOException ioe) {
+ System.out.println("--------------------------------------\n");
+ System.out.println(ioe.getMessage());
+ System.out.println("--------------------------------------\n");
+ }
+ }
+
+ /**
+ * Helper method to print out a dotted line.
+ */
+ private static void printLine() {
+ System.out.println("--------------------------------------\n");
+ }
+ /**
+ * Serves as the main entry point to the Duke application.
+ *
+ * @param args inputs from client.
+ */
+ public static void main(String[] args) {
+ try {
+ new Duke().run();
+ } catch (DukeException de) {
+ printLine();
+ System.out.println(de.getMessage());
+ printLine();
+ main(args);
+ } catch (IOException io) {
+ printLine();
+ System.out.println(io.getMessage());
+ printLine();
+ }
+ }
+
+ /**
+ * Serves as the method that calls on utility classes that implements the features
+ * of the Duke Chat bot.
+ *
+ * @throws DukeException If Categorise encounters input issue when reading Duke commands.
+ * @throws IOException If save throws an IOException which will be passed to run to throw.
+ */
+ public void run() throws DukeException, IOException {
+ this.ui.greet();
+ Scanner sc = new Scanner(System.in);
+ String str = sc.nextLine();
+ assert(str != null);
+ String uncap = str.toLowerCase();
+ while (!str.equals("bye")) {
+ this.parse.categorise(str);
+ str = sc.nextLine();
+ }
+ sc.close();
+ Storage.save(this.taskArrayList);
+ ui.bye();
+ }
+
+ public String getResponse(String input) throws IOException {
+ String response = parse.categorise(input);
+ if (response.equals(this.ui.bye())) {
+ System.exit(0);
+ }
+ return response;
+ }
+
+}
diff --git a/src/main/java/dukechatbot/duke/Launcher.java b/src/main/java/dukechatbot/duke/Launcher.java
new file mode 100644
index 0000000000..077e729cc7
--- /dev/null
+++ b/src/main/java/dukechatbot/duke/Launcher.java
@@ -0,0 +1,12 @@
+package dukechatbot.duke;
+
+import javafx.application.Application;
+
+/**
+ * This class serves as a workaround around classpath issues to launch the JavaFx Application.
+ */
+public class Launcher {
+ public static void main(String[] args) {
+ Application.launch(Main.class, args);
+ }
+}
diff --git a/src/main/java/dukechatbot/duke/Main.java b/src/main/java/dukechatbot/duke/Main.java
new file mode 100644
index 0000000000..9e66412b2b
--- /dev/null
+++ b/src/main/java/dukechatbot/duke/Main.java
@@ -0,0 +1,39 @@
+package dukechatbot.duke;
+
+import java.io.IOException;
+
+import javafx.application.Application;
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Scene;
+import javafx.scene.layout.AnchorPane;
+import javafx.stage.Stage;
+
+/**
+ * This class encapsulates the main class to inject JavaFx into the Duke application.
+ *
+ * @author A0233290M
+ * @version Week4
+ */
+public class Main extends Application {
+ /**
+ * The Duke instance to be injected into the program run.
+ */
+ private Duke dk = new Duke();
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void start(Stage stage) {
+ try {
+ FXMLLoader loader = new FXMLLoader(Main.class.getResource("/view/MainWindow.fxml"));
+ AnchorPane ap = loader.load();
+ Scene scene = new Scene(ap);
+ stage.setScene(scene);
+ loader.getController().setDuke(dk);
+ stage.show();
+ } catch (IOException ioe) {
+ System.out.println(ioe.getMessage());
+ }
+ }
+}
diff --git a/src/main/java/dukechatbot/duke/MainWindow.java b/src/main/java/dukechatbot/duke/MainWindow.java
new file mode 100644
index 0000000000..ea34e85faf
--- /dev/null
+++ b/src/main/java/dukechatbot/duke/MainWindow.java
@@ -0,0 +1,83 @@
+package dukechatbot.duke;
+
+import java.io.IOException;
+
+import javafx.fxml.FXML;
+import javafx.scene.control.Button;
+import javafx.scene.control.ScrollPane;
+import javafx.scene.control.TextField;
+import javafx.scene.image.Image;
+import javafx.scene.layout.AnchorPane;
+import javafx.scene.layout.VBox;
+
+/**
+ * The class that acts as the Anchor Pane to the many nodes implementing the application.
+ */
+public class MainWindow extends AnchorPane {
+ /**
+ * Instance of vertically aligned dialog box.
+ */
+ @FXML
+ private VBox dialogContainer;
+ /**
+ * The instance of scroll pane to allow client to scroll.
+ */
+ @FXML
+ private ScrollPane sp;
+ /**
+ * The instance of text field to allow users to input their commands.
+ */
+ @FXML
+ private TextField userInput;
+ /**
+ * The Button instance allows users an alternative way to submit their commands
+ * to Duke.
+ */
+ @FXML
+ private Button enterButton;
+ /**
+ * The image representing the user.
+ */
+ private Image userImg = new Image(getClass().getResourceAsStream("/images/DaUser.png"));
+ /**
+ * The image representing Duke.
+ */
+ private Image dukeImg = new Image(getClass().getResourceAsStream("/images/DaDuke.png"));
+ private Duke duke;
+
+ /**
+ * This allows the caller to set the Duke instance to the current run of the application.
+ * @param dk the Duke instance to be set for the application run.
+ */
+ public void setDuke(Duke dk) {
+ this.duke = dk;
+ }
+
+ /**
+ * This will greet the user upon the initialisation of the JavaFX application.
+ */
+ @FXML
+ public void initialize() {
+ String logo = " ____ _ \n"
+ + "| _ \\ _ _| | _____ \n"
+ + "| | | | | | | |/ / _ \\\n"
+ + "| |_| | |_| | < __/\n"
+ + "|____/ \\__,_|_|\\_\\___|\n";
+ dialogContainer.getChildren().addAll(DialogBox.getDukeDialog("Hello from\n" + logo
+ + "Hello I'm Duke, what can I do for you?", dukeImg));
+ }
+
+ /**
+ * handles user inputs by calling on duke to process the inputs and outputting them as dialogs
+ * @throws IOException when getResponse throws the exception.
+ */
+ @FXML
+ public void handleUserInput() throws IOException {
+ String input = userInput.getText();
+ String dukeResponse = duke.getResponse(input);
+ dialogContainer.getChildren().addAll(
+ DialogBox.getUserDialog(input, userImg), DialogBox.getDukeDialog(dukeResponse, dukeImg)
+ );
+ userInput.clear();
+ }
+}
diff --git a/src/main/java/dukechatbot/dukeexception/DukeException.java b/src/main/java/dukechatbot/dukeexception/DukeException.java
new file mode 100644
index 0000000000..cf2cd05a6f
--- /dev/null
+++ b/src/main/java/dukechatbot/dukeexception/DukeException.java
@@ -0,0 +1,21 @@
+package dukechatbot.dukeexception;
+import java.io.IOException;
+
+/**
+ * The DukeException class implements the exceptions thrown by the Duke application when commands input
+ * are unknown.
+ *
+ * @author A0233290M
+ * @version Week3
+ *
+ */
+public class DukeException extends IOException {
+ /**
+ * Constructs an instance of the DukeException class.
+ *
+ * @param message message to printed when a Duke Exception is thrown.
+ */
+ public DukeException(String message) {
+ super(message);
+ }
+}
diff --git a/src/main/java/dukechatbot/utility/Deadline.java b/src/main/java/dukechatbot/utility/Deadline.java
new file mode 100644
index 0000000000..5ce412d27f
--- /dev/null
+++ b/src/main/java/dukechatbot/utility/Deadline.java
@@ -0,0 +1,41 @@
+package dukechatbot.utility;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+
+/**
+ * The Deadline class implements a subclass of Task that encapsulates the type of tasks that has a specific
+ * deadline.
+ *
+ * @author A0233290M
+ * @version Week3
+ */
+public class Deadline extends Task {
+ /**
+ * Defines the tag associated with this type of Task.
+ */
+ protected static final String TAG = "[D]";
+ /**
+ * Defines the Date time format to read in the commands passed by client for processing.
+ */
+ protected static final DateTimeFormatter DTF = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
+
+ /**
+ * Constructs an instance of the Deadline class with its associated attributes.
+ *
+ * @param descriptor describes the Deadline task that is to be instantiated.
+ * @param due describes the deadline to be associated with the deadline task to be instantiated.
+ */
+ public Deadline(String descriptor, String due) {
+ super(descriptor);
+ this.time = LocalDateTime.parse(due, DTF);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ return TAG + super.toString() + " (by: "
+ + this.time.format(DTF) + ")";
+ }
+}
diff --git a/src/main/java/dukechatbot/utility/Event.java b/src/main/java/dukechatbot/utility/Event.java
new file mode 100644
index 0000000000..2f40594a39
--- /dev/null
+++ b/src/main/java/dukechatbot/utility/Event.java
@@ -0,0 +1,47 @@
+package dukechatbot.utility;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+
+/**
+ * The Event class implements a subclass of Task that encapsulates the type of tasks that has a
+ * duration associated with it.
+ *
+ * @author A0233290M
+ * @version Week3
+ */
+public class Event extends Task {
+ /**
+ * Defines the Tag associated with this type of Task.
+ */
+ protected static final String TAG = "[E]";
+ /**
+ * Defines the Date time format to read in the commands passed by client for processing.
+ */
+ protected static final DateTimeFormatter DTF = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
+ /**
+ * Defines the field that encapsulates the end of the duration of the Event instantiated.
+ */
+ protected LocalDateTime end;
+
+ /**
+ * Constructs an instance of the Event class with its associated attributes.
+ *
+ * @param descriptor describes the Event task that is to be instantiated.
+ * @param duration describes the duration associated with the instance of the Event.
+ */
+ public Event(String descriptor, String duration) {
+ super(descriptor);
+ this.time = LocalDateTime.parse(duration.substring(0,16), DTF);
+ this.end = LocalDateTime.parse(duration.substring(0,10) + " " + duration.substring(17), DTF);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ return TAG + super.toString() + " (at: "
+ + this.time.format(DTF) + " to "
+ + this.end.format(DTF) + ")";
+ }
+}
diff --git a/src/main/java/dukechatbot/utility/Parser.java b/src/main/java/dukechatbot/utility/Parser.java
new file mode 100644
index 0000000000..efdcd2db80
--- /dev/null
+++ b/src/main/java/dukechatbot/utility/Parser.java
@@ -0,0 +1,107 @@
+package dukechatbot.utility;
+import dukechatbot.dukeexception.DukeException;
+
+/**
+ * The Parser class implements the class that will parse input commands passed to the Duke program.
+ *
+ * @author A0233290M
+ * @version Week4
+ */
+public class Parser {
+ /**
+ * Encapsulates the instance of TaskList that will be associated with this instance of the Parser.
+ */
+ private TaskList tasks;
+ /**
+ * Encapsulates the instance of Ui that will be associated
+ */
+ private Ui ui;
+
+ /**
+ * Constructs the instance of Parser with the Task instance and Ui instance associated with it.
+ *
+ * @param tasks the TaskList associated with the instance of Parser.
+ * @param ui the Ui associated with the instance of Parser.
+ */
+ public Parser(TaskList tasks, Ui ui) {
+ this.tasks = tasks;
+ this.ui = ui;
+ }
+
+ /**
+ * Categorises the client's inputs to decide the method to be called by the program next in response to it.
+ *
+ * @return a String response to the command.
+ * @param str The input passed into the method to be processed.
+ * @throws DukeException when the command input is unknown.
+ */
+ public String categorise(String str) throws DukeException {
+ String response = null;
+ String uncap = str.toLowerCase();
+ assert(str.length() > 0);
+ if (str.equals("bye")) {
+ return this.ui.bye();
+ }
+ if (uncap.startsWith("mark")) {
+ int i = Integer.parseInt(String.valueOf(uncap.charAt(5)));
+ response = tasks.mark(i, ui);
+ return response;
+ }
+ if (uncap.startsWith("unmark")) {
+ int i = Integer.parseInt(String.valueOf(uncap.charAt(7)));
+ response = tasks.unmark(i, ui);
+ return response;
+ }
+ if (uncap.startsWith("find")) {
+ response = tasks.find(uncap.substring(5), ui);
+ return response;
+ }
+ if (uncap.startsWith("delete")) {
+ Integer i = Integer.parseInt(String.valueOf(str.charAt(7)));
+ response = tasks.delete(i, ui);
+ return response;
+ }
+ if (uncap.equals("list")) {
+ response = ui.listOut();
+ return response;
+ }
+ String command = uncap.split(" ")[0].trim();
+ Task t = null;
+ int idOfSlash = -1;
+ switch (command) {
+ case "deadline":
+ if (!uncap.contains("/")) {
+ this.ui.showTimeMissingError();
+ }
+ idOfSlash = str.indexOf("/");
+ if (idOfSlash - 9 == 0) {
+ this.ui.showDescEmptyError("Deadline");
+ }
+ if (str.length() < idOfSlash + 4) {
+ this.ui.showTimeMissingError();
+ }
+ t = new Deadline(str.substring(9, idOfSlash), str.substring(idOfSlash + 4));
+ break;
+ case "event":
+ if (!uncap.contains("/")) {
+ this.ui.showTimeMissingError();
+ }
+ idOfSlash = str.indexOf("/");
+ if (idOfSlash - 6 == 0) {
+ this.ui.showDescEmptyError("Event");
+ }
+ t = new Event(str.substring(6, idOfSlash), str.substring(idOfSlash + 4));
+ break;
+ case "todo":
+ if (str.length() < 6) {
+ this.ui.showDescEmptyError("To Do");
+ }
+ t = new Todo(str.substring(5));
+ break;
+ default:
+ this.ui.showUnknownCommandError();
+ }
+ response = this.tasks.add(t);
+ return response;
+ }
+}
diff --git a/src/main/java/dukechatbot/utility/Storage.java b/src/main/java/dukechatbot/utility/Storage.java
new file mode 100644
index 0000000000..dc7cf040df
--- /dev/null
+++ b/src/main/java/dukechatbot/utility/Storage.java
@@ -0,0 +1,84 @@
+package dukechatbot.utility;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+/**
+ * The Storage class encapsulates the operations on the file to be read and written.
+ *
+ * @author A0233290M
+ * @version Week3
+ */
+public class Storage {
+ /**
+ * Defines the file to be associated with this instance of the Storage class.
+ */
+ private static final File FILE = new File("storage.txt");
+ /**
+ * Defines the instance of the BufferedReader to allow the instance of Storage to read from input.
+ */
+ private BufferedReader br;
+ /**
+ * Encapsulates the instance of TaskList associated with the instance of Storage.
+ */
+ private TaskList tasks;
+ /**
+ * The instance of ui to be passed in for use by the class to interact with user.
+ */
+ private Ui ui;
+ /**
+ * Constructs the instance of storage to read and write from and to the file passed in.
+ *
+ * @param tasks the task list to be manipulated by the instance of Storage.
+ * @param ui the ui associated with this current run of the program.
+ * @throws IOException when createNewFile fails to create the file.
+ */
+ public Storage(TaskList tasks, Ui ui) throws IOException {
+
+ if (!FILE.exists()) {
+ FILE.createNewFile();
+ }
+ assert(FILE.exists());
+ this.tasks = tasks;
+ this.ui = ui;
+ this.br = new BufferedReader(new FileReader(FILE));
+ this.load();
+ }
+
+ /**
+ * Loads the content of the file and into the list of tasks stored in the associated txt file.
+ *
+ * @throws IOException if the file fails to be read.
+ */
+ public void load() throws IOException {
+ assert(FILE.exists());
+ if (FILE.canRead()) {
+ String ln = this.br.readLine();
+ while (ln != null) {
+ this.tasks.addFromStorage(ln);
+ ln = br.readLine();
+ }
+ } else {
+ this.ui.showLoadingError();
+ }
+ }
+
+ /**
+ * Saves the tasks of the task list into the associated file to be loaded in the next run of the program.
+ *
+ * @throws IOException when method fails to write into the associated file.
+ */
+ public static void save(ArrayList taskArrayList) throws IOException {
+ assert(FILE.exists());
+ FileWriter fw = new FileWriter(FILE.getAbsolutePath());
+ for (Iterator it = taskArrayList.iterator(); it.hasNext();) {
+ Task curr = it.next();
+ fw.write(curr.toString() + "\r\n");
+ }
+ fw.close();
+ }
+}
diff --git a/src/main/java/dukechatbot/utility/Task.java b/src/main/java/dukechatbot/utility/Task.java
new file mode 100644
index 0000000000..8956643cc5
--- /dev/null
+++ b/src/main/java/dukechatbot/utility/Task.java
@@ -0,0 +1,64 @@
+package dukechatbot.utility;
+import java.time.LocalDateTime;
+
+/**
+ * The Task class implements the parent class of the tasks to be kept in the task list when the program is called.
+ *
+ * @author A0233290M
+ * @version Week3
+ */
+public class Task {
+ /**
+ * The description associated with the instance of Task.
+ */
+ protected String description;
+ /**
+ * The boolean associated with the instance of the class to label whether the task is done or not.
+ */
+ protected boolean isDone;
+ /**
+ * Defines the time attribute associated with the instance of Task.
+ */
+ protected LocalDateTime time;
+
+ /**
+ * Constructs the instance of Task with the associated description. The Task class does not have
+ * an associated time attribute and hence the instance has its time field left to be null.
+ * @param description describes the instance of the Task.
+ */
+ public Task(String description) {
+ this.description = description;
+ this.isDone = false;
+ this.time = null;
+ }
+
+ /**
+ * Answers whether the task is done or not.
+ * @return a string that tells the caller whether the task is done or not.
+ */
+ public String getStatusIcon() {
+ return (isDone ? "X" : " "); // mark done task with X
+ }
+
+ /**
+ * Marks the task done when called.
+ */
+ public void markAsDone() {
+ this.isDone = true;
+ }
+
+ /**
+ * Marks the task as not done when called.
+ */
+ public void markAsUndone() {
+ this.isDone = false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ return "[" + getStatusIcon() + "] " + this.description;
+ }
+}
diff --git a/src/main/java/dukechatbot/utility/TaskList.java b/src/main/java/dukechatbot/utility/TaskList.java
new file mode 100644
index 0000000000..37c08e81ec
--- /dev/null
+++ b/src/main/java/dukechatbot/utility/TaskList.java
@@ -0,0 +1,163 @@
+package dukechatbot.utility;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+/**
+ * The TaskList implements the operations and attributes needed to handle
+ * manipulation of the task list.
+ */
+public class TaskList {
+ /**
+ * Encapsulates the array list associated with the instance of
+ * TaskList
+ */
+ private ArrayList tl;
+ private Ui ui;
+
+ /**
+ * Constructs the instance of Task List with its associated
+ * array list.
+ * @param tl the array list that is associated with the TaskList instance.
+ */
+ public TaskList(ArrayList tl, Ui ui) {
+ this.tl = tl;
+ this.ui = ui;
+ }
+
+ /**
+ * serves as the method to return the array list associated
+ * with the TaskList instance.
+ * @return the array list associated with the TaskList instance.
+ */
+ public ArrayList getArrayList() {
+ return this.tl;
+ }
+
+ /**
+ * Adds task into the array list associated with the TaskList instance
+ * if duplicate is not detected else tells user that the task is a duplicate.
+ * @param t the task to be added into the array list.
+ */
+ public String add(Task t) {
+ if (isDuplicate(t)) {
+ return this.ui.foundDuplicate(t);
+ }
+ this.tl.add(t);
+ return this.ui.added(t);
+ }
+
+ /**
+ * Adds the task read by Storage class into the array list
+ * associated with this instance of TaskList.
+ * @param ln the line read by the Storage class.
+ */
+ public void addFromStorage(String ln) {
+ Task toAdd = createTask(ln);
+ this.tl.add(toAdd);
+ }
+
+ /**
+ * Creates tasks from the lines read from storage for adding into task array list.
+ * @param ln the line read from storage.
+ * @return the task to be added.
+ */
+ private static Task createTask(String ln) {
+ String tag = String.valueOf(ln.charAt(1));
+ String desc = null;
+ int id = -1;
+ boolean isDone = false;
+ Task toAdd = null;
+ if (String.valueOf(ln.charAt(4)).equals("X")) {
+ isDone = true;
+ }
+ if (tag.equals("T")) {
+ toAdd = new Todo(ln.substring(7));
+ } else if (tag.equals("D")) {
+ id = ln.indexOf("(by:");
+ toAdd = new Deadline(ln.substring(7, id - 1), ln.substring(id + 5 , ln.length() - 1));
+ } else if (tag.equals("E")) {
+ id = ln.indexOf("(at:");
+ String timeAttr = ln.substring(id + 5, id + 21)
+ + " " + ln.substring(ln.length() - 6, ln.length() - 1);
+ toAdd = new Event(ln.substring(7, id - 1), timeAttr);
+ } else {
+ toAdd = new Task(ln.substring(6));
+ }
+ if (isDone) {
+ toAdd.markAsDone();
+ }
+ return toAdd;
+ }
+ /**
+ * Deletes the task from the array list associated with this instance of TaskList.
+ * @param id the id passed in to obtain the actual task number to be deleted.
+ * @param ui the instance of Ui to allow
+ * for printing out of the success of delete to user.
+ */
+ public String delete(Integer id, Ui ui) {
+ int actualId = id - 1;
+ Task t = this.tl.remove(actualId);
+ return this.ui.removed(t, this.tl);
+ }
+
+ /**
+ * Marks the task specified as done.
+ * @param id the id passed in to obtain the actual task number to be marked done.
+ * @param ui the instance of Ui to allow for printing out of the success of marking
+ * the task as done to user.
+ */
+ public String mark(int id, Ui ui) {
+ Task t = this.tl.get(id - 1);
+ t.markAsDone();
+ return ui.marked(t);
+ }
+
+ /**
+ * Marks the task as not done.
+ * @param id the id passed in to obtain the actual task number to be marked as not done.
+ * @param ui the instance of Ui to allow
+ * for printing out of the success of marking the task as not done to user.
+ */
+ public String unmark(int id, Ui ui) {
+ Task t = this.tl.get(id - 1);
+ t.markAsUndone();
+ return ui.unmarked(t);
+ }
+
+ /**
+ * Finds the tasks in the array list that contains
+ * the description passed in.
+ * @param desc the keywords that will specify which tasks to be found and shown.
+ * @param ui the instance of Ui to allow
+ * for printing of the tasks that are found.
+ */
+ public String find(String desc, Ui ui) {
+ int count = 1;
+ ArrayList tempList = new ArrayList<>();
+ for (Iterator it = tl.iterator(); it.hasNext();) {
+ Task curr = it.next();
+ if (curr.toString().contains(desc)) {
+ tempList.add(curr);
+ }
+ }
+ return ui.listMatch(tempList);
+ }
+
+ /**
+ * Checks whether the task to be added is a duplicate of an
+ * existing task within the task list.
+ * @param t the task to be added.
+ * @return true when duplicate is detected and false
+ * when there is no duplicates detected.
+ */
+ public boolean isDuplicate(Task t) {
+ Iterator iter = this.tl.iterator();
+ while (iter.hasNext()) {
+ Task curr = iter.next();
+ if (curr.toString().substring(7).equals(t.toString().substring(7))) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/src/main/java/dukechatbot/utility/Todo.java b/src/main/java/dukechatbot/utility/Todo.java
new file mode 100644
index 0000000000..65944fe974
--- /dev/null
+++ b/src/main/java/dukechatbot/utility/Todo.java
@@ -0,0 +1,31 @@
+package dukechatbot.utility;
+
+/**
+ * The Todo class implements the type of tasks that are to be done
+ * but do not have an associated deadline or time component to them.
+ *
+ * @author A0233290M
+ * @version Week3
+ */
+public class Todo extends Task {
+ /**
+ * Defines the Tag associated with this type of tasks.
+ */
+ protected static final String TAG = "[T]";
+
+ /**
+ * Constructs the instance of Todo with the associated description.
+ * @param description describes the instance of Todo that is to be created.
+ */
+ public Todo(String description) {
+ super(description);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ return TAG + super.toString();
+ }
+}
diff --git a/src/main/java/dukechatbot/utility/Ui.java b/src/main/java/dukechatbot/utility/Ui.java
new file mode 100644
index 0000000000..6283abfcd0
--- /dev/null
+++ b/src/main/java/dukechatbot/utility/Ui.java
@@ -0,0 +1,177 @@
+package dukechatbot.utility;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import dukechatbot.dukeexception.DukeException;
+
+
+
+
+/**
+ * The Ui class encapsulates operations that
+ * interact with the client during the running of the program.
+ */
+public class Ui {
+ /**
+ * Defines the array list that is associated with the program run.
+ */
+ private ArrayList taskArrayList;
+
+ /**
+ * Constructs the instance of Ui to be used for the run of the program.
+ * @param taskArrayList the array list to be associated with the program run.
+ */
+ public Ui(ArrayList taskArrayList) {
+ this.taskArrayList = taskArrayList;
+ }
+
+ /**
+ * Prints out logo and greets user upon program run.
+ */
+ public String greet() {
+ String logo = " ____ _ \n"
+ + "| _ \\ _ _| | _____ \n"
+ + "| | | | | | | |/ / _ \\\n"
+ + "| |_| | |_| | < __/\n"
+ + "|____/ \\__,_|_|\\_\\___|\n";
+ return "Hello from\n" + logo
+ + "Hello I'm Duke, what can I do for you?";
+ }
+
+ /**
+ * Says goodbye to the user when the program run is terminated by user.
+ */
+ public String bye() {
+ try {
+ Storage.save(this.taskArrayList);
+ } catch (IOException ioe) {
+ return "Failed to save";
+ }
+ return "\tBye. Hope to see you soon again!";
+ }
+
+ /**
+ * Tells the user that the file has failed to be loaded.
+ * @throws IOException when called to show that the file
+ * has failed to be loaded to the user.
+ */
+ public void showLoadingError() throws IOException {
+ throw new IOException("File Loading Error!");
+ }
+
+ /**
+ * Shows success of adding task into the task list when user tries to add a task.
+ * @param t the task that the user has told Duke to add into their task list.
+ */
+ public String added(Task t) {
+ return "Got it. I've added this task: \n" + t.toString()
+ + "\n\tNow you have " + this.taskArrayList.size() + " task(s) in the list.";
+ }
+ /**
+ * Shows success of marking the task in the task list as done.
+ * @param t the task that the user has told Duke to mark as done.
+ */
+ public String marked(Task t) {
+ return "Nice! I have marked this task as done: \n\t" + t.toString();
+ }
+
+ /**
+ * Shows the success of marking the task as not done
+ * to the user.
+ * @param t the task that the user has told Duke to mark as not done.
+ */
+ public String unmarked(Task t) {
+ return "OK, I've marked this task as not done yet: " + "\n\t" + t.toString();
+ }
+
+ /**
+ * Shows the success of removing the task from the task list.
+ * @param t the task that the user has told Duke to remove.
+ * @param taskArrayList the task list associated that is to show the
+ * number of tasks left in the list.
+ */
+ public String removed(Task t, ArrayList taskArrayList) {
+ String response = ("\tNoted. I've removed this task:")
+ + "\t\t" + t.toString() + ("\tNow you have " + taskArrayList.size() + " task(s) in the list.");
+ return response;
+ }
+
+ /**
+ * Tells user that their input is missing the required
+ * time components of the instance of the classes that needs them.
+ * @throws DukeException when called.
+ */
+ public void showTimeMissingError() throws DukeException {
+ throw new DukeException(
+ "☹ OOPS!!! Associated time for event or deadline cannot be empty.");
+ }
+
+ /**
+ * Tells user when they failed to give a description of the task they wish to add.
+ * @throws DukeException when called.
+ */
+ public void showDescEmptyError(String str) throws DukeException {
+ throw new DukeException(""
+ + "☹ OOPS!!! The description of a " + str
+ + " cannot be empty.");
+ }
+
+ /**
+ * Tells user that the input they gave is unknown to Duke.
+ * @throws DukeException when called.
+ */
+ public void showUnknownCommandError() throws DukeException {
+ throw new DukeException(
+ "☹ OOPS!!! I'm sorry, but I don't know what that means :-(");
+ }
+
+ /**
+ * lists out the tasks in the task list to the user.
+ * @return the list of things in the task list in the defined format.
+ */
+ public String listOut() {
+ if (this.taskArrayList.size() == 0) {
+ return "You have no tasks.";
+ }
+ int count = 1;
+ StringBuilder response = new StringBuilder();
+ response.append(("Here are the tasks in your list: "));
+ for (Iterator it = this.taskArrayList.iterator(); it.hasNext();) {
+ Task curr = it.next();
+ response.append("\n\t").append(count).append(". ").append(curr.toString());
+ count++;
+ }
+ return response.toString();
+ }
+
+ /**
+ * lists out the matching tasks in the task list that meets
+ * the user's find query.
+ * @param taskArrayList containing the tasks store in the task list.
+ */
+ public String listMatch(ArrayList taskArrayList) {
+ if (taskArrayList.size() == 0) {
+ return "You have no tasks.";
+ }
+ int count = 1;
+ StringBuilder response = new StringBuilder();
+ response.append(("\tHere are the matching tasks in your list: "));
+ for (Iterator it = taskArrayList.iterator(); it.hasNext();) {
+ Task curr = it.next();
+ response.append("\t\t").append(count).append(". ").append(curr.toString());
+ count++;
+ }
+ return response.toString();
+ }
+
+ /**
+ * Tells user that user is trying to add a duplicate task.
+ * @param t the task that is a duplicate.
+ * @return the message to tell user the task was a duplicate.
+ */
+ public String foundDuplicate(Task t) {
+ return "Sorry! " + t.toString() + " is a duplicate of an item in the current task list.";
+ }
+
+}
diff --git a/src/main/resources/DaDuke.png b/src/main/resources/DaDuke.png
new file mode 100644
index 0000000000..d893658717
Binary files /dev/null and b/src/main/resources/DaDuke.png differ
diff --git a/src/main/resources/DaUser.png b/src/main/resources/DaUser.png
new file mode 100644
index 0000000000..3c82f45461
Binary files /dev/null and b/src/main/resources/DaUser.png differ
diff --git a/src/main/resources/images/DaDuke.png b/src/main/resources/images/DaDuke.png
new file mode 100644
index 0000000000..d893658717
Binary files /dev/null and b/src/main/resources/images/DaDuke.png differ
diff --git a/src/main/resources/images/DaUser.png b/src/main/resources/images/DaUser.png
new file mode 100644
index 0000000000..3c82f45461
Binary files /dev/null and b/src/main/resources/images/DaUser.png differ
diff --git a/src/main/resources/view/DialogBox.fxml b/src/main/resources/view/DialogBox.fxml
new file mode 100644
index 0000000000..e433809947
--- /dev/null
+++ b/src/main/resources/view/DialogBox.fxml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/view/MainWindow.fxml b/src/main/resources/view/MainWindow.fxml
new file mode 100644
index 0000000000..95451f2410
--- /dev/null
+++ b/src/main/resources/view/MainWindow.fxml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/test/META-INF/MANIFEST.MF b/src/test/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000..555b31322e
--- /dev/null
+++ b/src/test/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: dukechatbot.duke.Duke
+
diff --git a/src/test/java/dukechatbot/utility/EventTest.java b/src/test/java/dukechatbot/utility/EventTest.java
new file mode 100644
index 0000000000..f929677c71
--- /dev/null
+++ b/src/test/java/dukechatbot/utility/EventTest.java
@@ -0,0 +1,22 @@
+package dukechatbot.utility;
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * The EventTest class is a test class to test the correctness of
+ * the Event class.
+ */
+public class EventTest {
+ /**
+ * Tests the toString of the Event class.
+ */
+ @Test
+ public void eventToStringTest() {
+ if ((new Event("project", "2022-08-08 04:30 05:30").toString())
+ .equals("[E][ ] project (at: 2022-08-08 04:30 to 2022-08-08 05:30)")) {
+ assertEquals(1,1);
+ } else {
+ assertEquals(1,0);
+ }
+ }
+}
diff --git a/src/test/java/dukechatbot/utility/TodoTest.java b/src/test/java/dukechatbot/utility/TodoTest.java
new file mode 100644
index 0000000000..9e51a689db
--- /dev/null
+++ b/src/test/java/dukechatbot/utility/TodoTest.java
@@ -0,0 +1,22 @@
+package dukechatbot.utility;
+
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * The TodoTest class implements test cases to determine
+ * the correctness of the Todo class.
+ */
+public class TodoTest {
+ /**
+ * tests the correctness of the toString method of the Todo class.
+ */
+ @Test
+ public void todoToStringTest() {
+ if ((new Todo("read book").toString()).equals("[T][ ] read book")) {
+ assertEquals(1, 1);
+ } else {
+ assertEquals(0, 1);
+ }
+ }
+}
diff --git a/text-ui-test/ACTUAL.TXT b/text-ui-test/ACTUAL.TXT
new file mode 100644
index 0000000000..a72e3d54c2
--- /dev/null
+++ b/text-ui-test/ACTUAL.TXT
@@ -0,0 +1,113 @@
+Hello from
+ ____ _
+| _ \ _ _| | _____
+| | | | | | | |/ / _ \
+| |_| | |_| | < __/
+|____/ \__,_|_|\_\___|
+
+--------------------------------------
+
+ Hello I'm Duke, what can I do for you?
+--------------------------------------
+
+------------------------------
+
+ Got it. I've added this task:
+ [T][ ] read book
+ Now you have 1 task(s) in the list.
+------------------------------
+
+------------------------------
+
+ Got it. I've added this task:
+ [D][ ] return book (by: 6th June)
+ Now you have 2 task(s) in the list.
+------------------------------
+
+------------------------------
+
+ Got it. I've added this task:
+ [E][ ] project meeting (at: Aug 6th 2-4pm)
+ Now you have 3 task(s) in the list.
+------------------------------
+
+------------------------------
+
+ Got it. I've added this task:
+ [T][ ] join sports club
+ Now you have 4 task(s) in the list.
+------------------------------
+
+------------------------------
+
+ Got it. I've added this task:
+ [T][ ] borrow book
+ Now you have 5 task(s) in the list.
+------------------------------
+
+-------------------------------
+
+ Here are the tasks in your list:
+ 1. [T][ ] read book
+ 2. [D][ ] return book (by: 6th June)
+ 3. [E][ ] project meeting (at: Aug 6th 2-4pm)
+ 4. [T][ ] join sports club
+ 5. [T][ ] borrow book
+-------------------------------
+
+-------------------------------
+
+ Nice! I have marked this task as done:
+ [T][X] read book
+-------------------------------
+
+-------------------------------
+
+ Nice! I have marked this task as done:
+ [D][X] return book (by: 6th June)
+-------------------------------
+
+-------------------------------
+
+ Nice! I have marked this task as done:
+ [T][X] join sports club
+-------------------------------
+
+-------------------------------
+
+ Here are the tasks in your list:
+ 1. [T][X] read book
+ 2. [D][X] return book (by: 6th June)
+ 3. [E][ ] project meeting (at: Aug 6th 2-4pm)
+ 4. [T][X] join sports club
+ 5. [T][ ] borrow book
+-------------------------------
+
+------------------------------
+
+ Noted. I've removed this task:
+ [E][ ] project meeting (at: Aug 6th 2-4pm)
+ Now you have 4 task(s) in the list.
+------------------------------
+
+-------------------------------
+
+ Here are the tasks in your list:
+ 1. [T][X] read book
+ 2. [D][X] return book (by: 6th June)
+ 3. [T][X] join sports club
+ 4. [T][ ] borrow book
+-------------------------------
+
+------------------------------
+
+ Got it. I've added this task:
+ [T][ ] project
+ Now you have 5 task(s) in the list.
+------------------------------
+
+------------------------------
+
+ Bye. Hope to see you soon again!
+------------------------------
+
diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT
index 657e74f6e7..d1e329943b 100644
--- a/text-ui-test/EXPECTED.TXT
+++ b/text-ui-test/EXPECTED.TXT
@@ -5,3 +5,108 @@ Hello from
| |_| | |_| | < __/
|____/ \__,_|_|\_\___|
+--------------------------------------
+
+ Hello I'm Duke, what can I do for you?
+--------------------------------------
+
+------------------------------
+
+ Got it. I've added this task:
+ [T][ ] read book
+ Now you have 1 task(s) in the list.
+------------------------------
+
+------------------------------
+
+ Got it. I've added this task:
+ [D][ ] return book (by: 6th June)
+ Now you have 2 task(s) in the list.
+------------------------------
+
+------------------------------
+
+ Got it. I've added this task:
+ [E][ ] project meeting (at: Aug 6th 2-4pm)
+ Now you have 3 task(s) in the list.
+------------------------------
+
+------------------------------
+
+ Got it. I've added this task:
+ [T][ ] join sports club
+ Now you have 4 task(s) in the list.
+------------------------------
+
+------------------------------
+
+ Got it. I've added this task:
+ [T][ ] borrow book
+ Now you have 5 task(s) in the list.
+------------------------------
+
+-------------------------------
+
+ Here are the tasks in your list:
+ 1. [T][ ] read book
+ 2. [D][ ] return book (by: 6th June)
+ 3. [E][ ] project meeting (at: Aug 6th 2-4pm)
+ 4. [T][ ] join sports club
+ 5. [T][ ] borrow book
+-------------------------------
+
+-------------------------------
+
+ Nice! I have marked this task as done:
+ [T][X] read book
+-------------------------------
+
+-------------------------------
+
+ Nice! I have marked this task as done:
+ [D][X] return book (by: 6th June)
+-------------------------------
+
+-------------------------------
+
+ Nice! I have marked this task as done:
+ [T][X] join sports club
+-------------------------------
+
+-------------------------------
+
+ Here are the tasks in your list:
+ 1. [T][X] read book
+ 2. [D][X] return book (by: 6th June)
+ 3. [E][ ] project meeting (at: Aug 6th 2-4pm)
+ 4. [T][X] join sports club
+ 5. [T][ ] borrow book
+-------------------------------
+
+------------------------------
+
+ Noted. I've removed this task:
+ [E][ ] project meeting (at: Aug 6th 2-4pm)
+ Now you have 4 task(s) in the list.
+------------------------------
+
+-------------------------------
+
+ Here are the tasks in your list:
+ 1. [T][X] read book
+ 2. [D][X] return book (by: 6th June)
+ 3. [T][X] join sports club
+ 4. [T][ ] borrow book
+-------------------------------
+
+------------------------------
+
+ Got it. I've added this task:
+ [T][ ] project
+ Now you have 5 task(s) in the list.
+------------------------------
+
+------------------------------
+
+ Bye. Hope to see you soon again!
+------------------------------
diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt
index e69de29bb2..bc754e8ee1 100644
--- a/text-ui-test/input.txt
+++ b/text-ui-test/input.txt
@@ -0,0 +1,14 @@
+todo read book
+deadline return book /by 6th June
+event project meeting /at Aug 6th 2-4pm
+todo join sports club
+todo borrow book
+list
+mark 1
+mark 2
+mark 4
+list
+delete 3
+list
+todo project
+bye
diff --git a/text-ui-test/runtest.sh b/text-ui-test/runtest.sh
old mode 100644
new mode 100755