diff --git a/dist/scripts/script-static.js b/dist/scripts/script-static.js
index 2dd26908..c9553a0a 100644
--- a/dist/scripts/script-static.js
+++ b/dist/scripts/script-static.js
@@ -1,6 +1,6 @@
/*!
* docker-registry-ui
- * Copyright (C) 2016 Jones Magloire @Joxit
+ * Copyright (C) 2016-2018 Jones Magloire @Joxit
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
diff --git a/dist/scripts/script.js b/dist/scripts/script.js
index 705ffd65..48868385 100644
--- a/dist/scripts/script.js
+++ b/dist/scripts/script.js
@@ -1,6 +1,6 @@
/*!
* docker-registry-ui
- * Copyright (C) 2016 Jones Magloire @Joxit
+ * Copyright (C) 2016-2018 Jones Magloire @Joxit
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
diff --git a/dist/scripts/tags-static.js b/dist/scripts/tags-static.js
index da490da2..98ede338 100644
--- a/dist/scripts/tags-static.js
+++ b/dist/scripts/tags-static.js
@@ -1,6 +1,6 @@
/*!
* docker-registry-ui
- * Copyright (C) 2016 Jones Magloire @Joxit
+ * Copyright (C) 2016-2018 Jones Magloire @Joxit
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
@@ -15,4 +15,4 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
-riot.tag2("catalog",'
Repositories of {registryUI.url()}
send {item}
',"","",function(t){registryUI.catalog.instance=this,registryUI.catalog.display=function(){registryUI.catalog.repositories=[];var t=new Http;t.addEventListener("load",function(){registryUI.catalog.repositories=[],200==this.status?(registryUI.catalog.repositories=JSON.parse(this.responseText).repositories||[],registryUI.catalog.repositories.sort()):404==this.status?registryUI.snackbar("Server not found",!0):registryUI.snackbar(this.responseText)}),t.addEventListener("error",function(){registryUI.snackbar("An error occured",!0),registryUI.catalog.repositories=[]}),t.addEventListener("loadend",function(){registryUI.catalog.loadend=!0,registryUI.catalog.instance.update()}),t.open("GET",registryUI.url()+"/v2/_catalog"),t.send()},registryUI.catalog.go=function(t){route("taglist/"+t)},registryUI.catalog.display()}),riot.tag2("app",'
Tags of {registryUI.url() + \'/\' + registryUI.taglist.name}
Repository
Tag
{registryUI.taglist.name}
{item}
',"","",function(t){registryUI.taglist.instance=this,registryUI.taglist.display=function(){if(registryUI.taglist.tags=[],"taglist"==route.routeName){var t=new Http;registryUI.taglist.instance.update(),t.addEventListener("load",function(){registryUI.taglist.tags=[],200==this.status?(registryUI.taglist.tags=JSON.parse(this.responseText).tags||[],registryUI.taglist.tags.sort()):404==this.status?registryUI.snackbar("Server not found",!0):registryUI.snackbar(this.responseText,!0)}),t.addEventListener("error",function(){registryUI.snackbar("An error occured",!0),registryUI.taglist.tags=[]}),t.addEventListener("loadend",function(){registryUI.taglist.loadend=!0,registryUI.taglist.instance.update()}),t.open("GET",registryUI.url()+"/v2/"+registryUI.taglist.name+"/tags/list"),t.send(),registryUI.taglist.asc=!0}},registryUI.taglist.display(),registryUI.taglist.instance.update(),registryUI.taglist.reverse=function(){registryUI.taglist.asc?(registryUI.taglist.tags.reverse(),registryUI.taglist.asc=!1):(registryUI.taglist.tags.sort(),registryUI.taglist.asc=!0),registryUI.taglist.instance.update()},registryUI.taglist.refresh=function(){route(registryUI.taglist.name)}}),riot.tag2("remove-image",'delete',"","",function(t){registryUI.removeImage=registryUI.removeImage||{},registryUI.removeImage.update=this.update,registryUI.removeImage.remove=function(t,e){var r=new Http;r.addEventListener("loadend",function(){if(registryUI.taglist.refresh(),200==this.status){if(!this.hasHeader("Docker-Content-Digest"))return void registryUI.errorSnackbar("You need to add Access-Control-Expose-Headers: ['Docker-Content-Digest'] in your server configuration.");var r=this.getResponseHeader("Docker-Content-Digest"),a=new Http;a.addEventListener("loadend",function(){200==this.status||202==this.status?(registryUI.taglist.refresh(),registryUI.snackbar("Deleting "+t+":"+e+" image. Run `registry garbage-collect config.yml` on your registry")):404==this.status?registryUI.errorSnackbar("Digest not found"):registryUI.snackbar(this.responseText)}),a.open("DELETE",registryUI.url()+"/v2/"+t+"/manifests/"+r),a.setRequestHeader("Accept","application/vnd.docker.distribution.manifest.v2+json"),a.addEventListener("error",function(){registryUI.errorSnackbar("An error occurred when deleting image. Check if your server accept DELETE methods Access-Control-Allow-Methods: ['DELETE'].")}),a.send()}else 404==this.status?registryUI.errorSnackbar("Manifest for "+t+":"+e+" not found"):registryUI.snackbar(this.responseText)}),r.open("HEAD",registryUI.url()+"/v2/"+t+"/manifests/"+e),r.setRequestHeader("Accept","application/vnd.docker.distribution.manifest.v2+json"),r.send()}});
\ No newline at end of file
+riot.tag2("catalog",'
Repositories of {registryUI.url()}
send {item}
',"","",function(t){registryUI.catalog.instance=this,registryUI.catalog.display=function(){registryUI.catalog.repositories=[];var t=new Http;t.addEventListener("load",function(){registryUI.catalog.repositories=[],200==this.status?(registryUI.catalog.repositories=JSON.parse(this.responseText).repositories||[],registryUI.catalog.repositories.sort()):404==this.status?registryUI.snackbar("Server not found",!0):registryUI.snackbar(this.responseText)}),t.addEventListener("error",function(){registryUI.snackbar("An error occured",!0),registryUI.catalog.repositories=[]}),t.addEventListener("loadend",function(){registryUI.catalog.loadend=!0,registryUI.catalog.instance.update()}),t.open("GET",registryUI.url()+"/v2/_catalog"),t.send()},registryUI.catalog.go=function(t){route("taglist/"+t)},registryUI.catalog.display()}),riot.tag2("app",'
Tags of {registryUI.url() + \'/\' + registryUI.taglist.name}
Repository
Size
Tag
{registryUI.taglist.name}
{item}
',"","",function(t){registryUI.taglist.instance=this,registryUI.taglist.display=function(){if(registryUI.taglist.tags=[],"taglist"==route.routeName){var t=new Http;registryUI.taglist.instance.update(),t.addEventListener("load",function(){registryUI.taglist.tags=[],200==this.status?(registryUI.taglist.tags=JSON.parse(this.responseText).tags||[],registryUI.taglist.tags.sort()):404==this.status?registryUI.snackbar("Server not found",!0):registryUI.snackbar(this.responseText,!0)}),t.addEventListener("error",function(){registryUI.snackbar("An error occured",!0),registryUI.taglist.tags=[]}),t.addEventListener("loadend",function(){registryUI.taglist.loadend=!0,registryUI.taglist.instance.update()}),t.open("GET",registryUI.url()+"/v2/"+registryUI.taglist.name+"/tags/list"),t.send(),registryUI.taglist.asc=!0}},registryUI.taglist.display(),registryUI.taglist.instance.update(),registryUI.taglist.reverse=function(){registryUI.taglist.asc?(registryUI.taglist.tags.reverse(),registryUI.taglist.asc=!1):(registryUI.taglist.tags.sort(),registryUI.taglist.asc=!0),registryUI.taglist.instance.update()},registryUI.taglist.refresh=function(){route(registryUI.taglist.name)}}),riot.tag2("remove-image",'delete',"","",function(t){registryUI.removeImage=registryUI.removeImage||{},registryUI.removeImage.update=this.update,registryUI.removeImage.remove=function(t,e){var r=new Http;r.addEventListener("loadend",function(){if(registryUI.taglist.refresh(),200==this.status){if(!this.hasHeader("Docker-Content-Digest"))return void registryUI.errorSnackbar("You need to add Access-Control-Expose-Headers: ['Docker-Content-Digest'] in your server configuration.");var r=this.getResponseHeader("Docker-Content-Digest"),a=new Http;a.addEventListener("loadend",function(){200==this.status||202==this.status?(registryUI.taglist.refresh(),registryUI.snackbar("Deleting "+t+":"+e+" image. Run `registry garbage-collect config.yml` on your registry")):404==this.status?registryUI.errorSnackbar("Digest not found"):registryUI.snackbar(this.responseText)}),a.open("DELETE",registryUI.url()+"/v2/"+t+"/manifests/"+r),a.setRequestHeader("Accept","application/vnd.docker.distribution.manifest.v2+json"),a.addEventListener("error",function(){registryUI.errorSnackbar("An error occurred when deleting image. Check if your server accept DELETE methods Access-Control-Allow-Methods: ['DELETE'].")}),a.send()}else 404==this.status?registryUI.errorSnackbar("Manifest for "+t+":"+e+" not found"):registryUI.snackbar(this.responseText)}),r.open("HEAD",registryUI.url()+"/v2/"+t+"/manifests/"+e),r.setRequestHeader("Accept","application/vnd.docker.distribution.manifest.v2+json"),r.send()}}),riot.tag2("image-size","
{this.bytesToSize(this.size)}
","","",function(t){var e=this;this.bytesToSize=function(t){var e=["Bytes","KB","MB","GB","TB"];if(void 0==t||isNaN(t))return"?";if(0==t)return"0 Byte";var r=parseInt(Math.floor(Math.log(t)/Math.log(1024)));return Math.ceil(t/Math.pow(1024,r))+" "+e[r]};var r=new Http;r.addEventListener("loadend",function(){200==this.status||202==this.status?(e.size=JSON.parse(this.responseText).layers.reduce(function(t,e){return t+e.size},0),e.update()):404==this.status?registryUI.errorSnackbar("Manifest for "+t.name+":"+t.tag+" not found"):registryUI.snackbar(this.responseText)}),r.open("GET",registryUI.url()+"/v2/"+t.name+"/manifests/"+t.tag),r.setRequestHeader("Accept","application/vnd.docker.distribution.manifest.v2+json"),r.send()});
\ No newline at end of file
diff --git a/dist/scripts/tags.js b/dist/scripts/tags.js
index 9936e52e..b9195e41 100644
--- a/dist/scripts/tags.js
+++ b/dist/scripts/tags.js
@@ -1,6 +1,6 @@
/*!
* docker-registry-ui
- * Copyright (C) 2016 Jones Magloire @Joxit
+ * Copyright (C) 2016-2018 Jones Magloire @Joxit
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
@@ -15,4 +15,4 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
-riot.tag2("add",'
',"","",function(e){registryUI.menuTag=registryUI.menuTag||{},registryUI.menuTag.update=this.update,this.one("mount",function(e){var t=this;registryUI.menuTag.close=function(){t.tags["material-dropdown"].close(),t.update()},registryUI.menuTag.isOpen=function(){return t.tags["material-dropdown"].opened},registryUI.menuTag.toggle=function(){t.tags["material-dropdown"].opened?t.tags["material-dropdown"].close():t.tags["material-dropdown"].open(),t.update()}})}),riot.tag2("remove-image",'delete',"","",function(e){registryUI.removeImage=registryUI.removeImage||{},registryUI.removeImage.update=this.update,registryUI.removeImage.remove=function(e,t){var r=new Http;r.addEventListener("loadend",function(){if(registryUI.taglist.refresh(),200==this.status){if(!this.hasHeader("Docker-Content-Digest"))return void registryUI.errorSnackbar("You need to add Access-Control-Expose-Headers: ['Docker-Content-Digest'] in your server configuration.");var r=this.getResponseHeader("Docker-Content-Digest"),a=new Http;a.addEventListener("loadend",function(){200==this.status||202==this.status?(registryUI.taglist.refresh(),registryUI.snackbar("Deleting "+e+":"+t+" image. Run `registry garbage-collect config.yml` on your registry")):404==this.status?registryUI.errorSnackbar("Digest not found"):registryUI.snackbar(this.responseText)}),a.open("DELETE",registryUI.url()+"/v2/"+e+"/manifests/"+r),a.setRequestHeader("Accept","application/vnd.docker.distribution.manifest.v2+json"),a.addEventListener("error",function(){registryUI.errorSnackbar("An error occurred when deleting image. Check if your server accept DELETE methods Access-Control-Allow-Methods: ['DELETE'].")}),a.send()}else 404==this.status?registryUI.errorSnackbar("Manifest for "+e+":"+t+" not found"):registryUI.snackbar(this.responseText)}),r.open("HEAD",registryUI.url()+"/v2/"+e+"/manifests/"+t),r.setRequestHeader("Accept","application/vnd.docker.distribution.manifest.v2+json"),r.send()}}),riot.tag2("remove",'
Tags of {registryUI.url() + \'/\' + registryUI.taglist.name}
Repository
Tag
{registryUI.taglist.name}
{item}
',"","",function(e){registryUI.taglist.instance=this,registryUI.taglist.display=function(){if(registryUI.taglist.tags=[],"taglist"==route.routeName){var e=new Http;registryUI.taglist.instance.update(),e.addEventListener("load",function(){registryUI.taglist.tags=[],200==this.status?(registryUI.taglist.tags=JSON.parse(this.responseText).tags||[],registryUI.taglist.tags.sort()):404==this.status?registryUI.snackbar("Server not found",!0):registryUI.snackbar(this.responseText,!0)}),e.addEventListener("error",function(){registryUI.snackbar("An error occured",!0),registryUI.taglist.tags=[]}),e.addEventListener("loadend",function(){registryUI.taglist.loadend=!0,registryUI.taglist.instance.update()}),e.open("GET",registryUI.url()+"/v2/"+registryUI.taglist.name+"/tags/list"),e.send(),registryUI.taglist.asc=!0}},registryUI.taglist.display(),registryUI.taglist.instance.update(),registryUI.taglist.reverse=function(){registryUI.taglist.asc?(registryUI.taglist.tags.reverse(),registryUI.taglist.asc=!1):(registryUI.taglist.tags.sort(),registryUI.taglist.asc=!0),registryUI.taglist.instance.update()},registryUI.taglist.refresh=function(){route(registryUI.taglist.name)}});
\ No newline at end of file
+riot.tag2("add",'
","","",function(e){var t=this;this.bytesToSize=function(e){var t=["Bytes","KB","MB","GB","TB"];if(void 0==e||isNaN(e))return"?";if(0==e)return"0 Byte";var r=parseInt(Math.floor(Math.log(e)/Math.log(1024)));return Math.ceil(e/Math.pow(1024,r))+" "+t[r]};var r=new Http;r.addEventListener("loadend",function(){200==this.status||202==this.status?(t.size=JSON.parse(this.responseText).layers.reduce(function(e,t){return e+t.size},0),t.update()):404==this.status?registryUI.errorSnackbar("Manifest for "+e.name+":"+e.tag+" not found"):registryUI.snackbar(this.responseText)}),r.open("GET",registryUI.url()+"/v2/"+e.name+"/manifests/"+e.tag),r.setRequestHeader("Accept","application/vnd.docker.distribution.manifest.v2+json"),r.send()}),riot.tag2("menu",'more_vert
Add URL
Change URL
Remove URL
',"","",function(e){registryUI.menuTag=registryUI.menuTag||{},registryUI.menuTag.update=this.update,this.one("mount",function(e){var t=this;registryUI.menuTag.close=function(){t.tags["material-dropdown"].close(),t.update()},registryUI.menuTag.isOpen=function(){return t.tags["material-dropdown"].opened},registryUI.menuTag.toggle=function(){t.tags["material-dropdown"].opened?t.tags["material-dropdown"].close():t.tags["material-dropdown"].open(),t.update()}})}),riot.tag2("remove-image",'delete',"","",function(e){registryUI.removeImage=registryUI.removeImage||{},registryUI.removeImage.update=this.update,registryUI.removeImage.remove=function(e,t){var r=new Http;r.addEventListener("loadend",function(){if(registryUI.taglist.refresh(),200==this.status){if(!this.hasHeader("Docker-Content-Digest"))return void registryUI.errorSnackbar("You need to add Access-Control-Expose-Headers: ['Docker-Content-Digest'] in your server configuration.");var r=this.getResponseHeader("Docker-Content-Digest"),a=new Http;a.addEventListener("loadend",function(){200==this.status||202==this.status?(registryUI.taglist.refresh(),registryUI.snackbar("Deleting "+e+":"+t+" image. Run `registry garbage-collect config.yml` on your registry")):404==this.status?registryUI.errorSnackbar("Digest not found"):registryUI.snackbar(this.responseText)}),a.open("DELETE",registryUI.url()+"/v2/"+e+"/manifests/"+r),a.setRequestHeader("Accept","application/vnd.docker.distribution.manifest.v2+json"),a.addEventListener("error",function(){registryUI.errorSnackbar("An error occurred when deleting image. Check if your server accept DELETE methods Access-Control-Allow-Methods: ['DELETE'].")}),a.send()}else 404==this.status?registryUI.errorSnackbar("Manifest for "+e+":"+t+" not found"):registryUI.snackbar(this.responseText)}),r.open("HEAD",registryUI.url()+"/v2/"+e+"/manifests/"+t),r.setRequestHeader("Accept","application/vnd.docker.distribution.manifest.v2+json"),r.send()}}),riot.tag2("remove",'
',"","",function(opts){var _this=this;if(this.opened=!1,opts.items){try{this.items=eval(opts.items)||[]}catch(t){console.error("Something wrong with your items. For details look at it - "+t)}this.update({items:this.items})}opts.selected&&this.update({selected:opts.selected}),this.select=function(t){return _this.update({selected:t.item.key}),_this.close(),_this.trigger("selectChanged",t.item.key,t.item.item),!0},this.open=function(){_this.update({opened:!0,opening:!0}),_this.opts.extraclose&&document.body.appendChild(_this.refs.overlay),setTimeout(function(){_this.update({opening:!1})},0)},this.close=function(){_this.update({opening:!0}),setTimeout(function(){_this.update({opened:!1})},200)}})},function(t,e,i){"use strict";riot.tag2("material-dropdown",'
',"","",function(t){var e=this;if(this.opts=t,this.required="",this.name=t.ref||"input",this.notSupportedTypes=["date","color","datetime","month","range","time"],-1!=this.notSupportedTypes.indexOf(t.type))throw new Error("Sorry but we do not support "+t.type+" type yet!");this.update({showIcon:!1}),this.on("mount",function(){e.update({value:t.value||"",disabled:t.disabled||!1,required:t.required||!1}),e.n=t.ref||"default-input",e.refs[e.n].addEventListener("focus",e.changeFocus),e.refs[e.n].addEventListener("blur",e.changeFocus)}),this.changeFocus=function(i){if(e.disabled)return!1;e.update({focused:e.refs[e.n]==document.activeElement}),e.trigger("focusChanged",e.focused,i),t.focuschanged&&"function"==typeof t.focuschanged&&t.focuschanged(e.focused)},this.changeValue=function(i){e.update({value:e.refs[e.n].value}),e.trigger("valueChanged",e.refs[e.n].value,i),t.valuechanged&&"function"==typeof t.valuechanged&&t.valuechanged(e.refs[e.n].value)},this.iconClickHandler=function(t){e.opts.iconclicked&&"function"==typeof e.opts.iconclicked&&e.opts.iconclicked.call(e,t),e.trigger("iconclicked",t)},this.on("update",function(t){t&&void 0!=t.value&&e.validationType&&e.isValid(e.validate(t.value))}),this.isValid=function(t){e.update({error:!t})},this.mixin("validate")})},function(t,e,i){"use strict";riot.tag2("material-navbar",'
',"","",function(t){var e=this;this.opts=t,this.disabled=t.disabled||!1,this.on("mount",function(){t.maxRows&&(e.refs.mirror.style.maxHeight=t.maxRows*e.refs[e.n].getBoundingClientRect().height+"px"),e.n=t.ref||"default-textarea",e.value=t.value||"",e.refs.mirror.innerHTML=e.format(e.value),e.refs[e.n].value=e.value,e.refs[e.n].scrollTop=e.refs[e.n].scrollHeight,e.refs[e.n].addEventListener("focus",e.changeFocus),e.refs[e.n].addEventListener("blur",e.changeFocus),e.refs[e.n].addEventListener("input",e.inputHandler),e.update({value:e.value})}),this.changeFocus=function(t){if(e.disabled)return!1;var i=e.refs[e.n]==document.activeElement;e.update({focused:i}),e.trigger("focusChanged",i)},this.inputHandler=function(t){var i=e.refs[e.n].value;e.refs.mirror.innerHTML=e.format(i),e.update({value:i})},this.changeValue=function(i){e.trigger("valueChanged",e.refs[e.n].value,i),t.valuechanged&&"function"==typeof t.valuechanged&&t.valuechanged(e.refs[e.n].value)},this.isValid=function(t){e.update({error:!t})},this.format=function(t){return t.replace(/\n/g," ")},this.on("update",function(t){t&&void 0!=t.value&&e.validationType&&e.isValid(e.validate(t.value))}),this.mixin("validate")})},function(t,e,i){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function o(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function a(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}var s=i(0),r=function(t){return t&&t.__esModule?t:{default:t}}(s);riot.tag2("material-waves",'',"","",function(t){var e=this,i=function(t){function e(i,a,s){n(this,e);var r=o(this,t.call(this));return i||console.error("You should set container to the wave!"),r.container=i,r.maxOpacity=a.opacity||.6,r.duration=a.duration||750,r.color=a.color||"#fff",r.center=a.center||!1,r.event=s,r.containerBound=r.receiveBound(),r.maxScale=r.containerBound.size/100*10,r.created=Date.now(),r.start={},r.createNode(),r.waveIn(),r}return a(e,t),e.prototype.createNode=function(){this.wave=document.createElement("div"),this.wave.classList.add("wave"),this.container.appendChild(this.wave)},e.prototype.waveIn=function(){var t=this;this.center&&!this.event&&console.error("Setup at least mouse event... Or just set center attribute"),this.start.x=this.center?this.containerBound.height/2:this.event.pageY-this.containerBound.offsetTop,this.start.y=this.center?this.containerBound.width/2:this.event.pageX-this.containerBound.offsetLeft;var e=-1!==window.navigator.userAgent.indexOf("Trident");setTimeout(function(){return t.setStyles(t.maxOpacity)},e?50:0)},e.prototype.waveOut=function(t){var e=this,i=Date.now()-this.created,n=Math.round(this.duration/2)-i,o=n>0?n:0;setTimeout(function(){e.setStyles(0),setTimeout(function(){e.wave.parentNode===e.container&&(e.container.removeChild(e.wave),t())},e.duration)},o)},e.prototype.setStyles=function(t){this.wave.setAttribute("style",this.convertStyle({top:this.start.x+"px",left:this.start.y+"px",transform:"scale("+this.maxScale+")","transition-duration":this.duration+"ms","transition-timing-function":"cubic-bezier(0.250, 0.460, 0.450, 0.940)",background:this.color,opacity:t}))},e.prototype.convertStyle=function(t){var e="";return Object.keys(t).forEach(function(i){t.hasOwnProperty(i)&&(e+=i+":"+t[i]+";")}),e},e}(r.default);this._waves=[],this._events=[],this.on("launch",function(n){var o=new i(e.refs.waves,t,n);e._waves.push(o),e.trigger("wavestart",o),e.parent&&e.parent.opts&&e.parent.opts.wavestart&&e.parent.opts.wavestart(o),e._events.length||(e._events.push(n.target.addEventListener("mouseup",function(){return e.trigger("hold")})),e._events.push(n.target.addEventListener("mouseleave",function(){return e.trigger("hold")})))}),this.on("hold",function(){e._waves[e._waves.length-1]&&e._waves[e._waves.length-1].waveOut(e.waveOut),e._waves[e._waves.length-1]&&e._waves.slice(e._waves.length-1,1)}),this.waveOut=function(){e.trigger("waveend"),e.parent&&e.parent.opts&&e.parent.opts.waveend&&e.parent.opts.waveend()}})},function(t,e,i){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(e,"__esModule",{value:!0});var o=function(){function t(){n(this,t)}return t.prototype.filter=function(t,e){return this[t].filter(function(t){var i=!1;return Object.keys(e).forEach(function(n){var o=e[n],a=new RegExp(""+o,"i");i=a.test(t[n])}),i})},t.prototype.find=function(t,e){var i={},n=0;return t.forEach(function(t){Object.keys(e).forEach(function(o){var a=e[o];t[o]==a&&(i.e=t,i.k=n)}),n++}),i},t}();e.default=o,riot.mixin("collection",o)},function(t,e,i){"use strict";var n={init:function(){var t=this;this.on("mount",function(){[].forEach.call(t.root.querySelectorAll("content"),function(e){var i=e.getAttribute("select");[].forEach.call(t.root.querySelectorAll(i),function(t){e.parentNode.insertBefore(t,e.nextSibling)}),e.parentNode.removeChild(e)})})}};riot.mixin("content",n)},function(t,e,i){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(e,"__esModule",{value:!0});var o=function(){function t(){n(this,t)}return t.prototype.init=function(){var t=this;this.on("update",function(e){e&&t.dynamicAttributes&&t.dynamicAttributes.forEach(function(i){void 0!=e[i]&&t.root.setAttribute(i,e[i])})})},t}();e.default=o,riot.mixin("dynamicAttributes",o)},function(t,e,i){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(e,"__esModule",{value:!0});var o=function(){function t(){n(this,t)}return t.prototype.findTag=function(t,e){var i=null;return t.forEach(function(t){t.root.getAttribute("name").toLowerCase()!=e.toLowerCase()&&t.root.tagName.toLowerCase()!=e.toLowerCase()&&t.root.getAttribute("ref").toLowerCase()!=e.toLowerCase()||(i=t)}),i},t.prototype.turnHyphensOptsToCamelCase=function(t){for(var e in t)if(/-/.test(e)){var i=e.replace(/-([a-z])/g,function(t){return t[1].toUpperCase()});t[i]=t[e],delete t[e]}},t}();e.default=o,riot.findTag=o.findTag,riot.mixin("helpers",o)},function(module,exports,__webpack_require__){"use strict";function _classCallCheck(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(exports,"__esModule",{value:!0});var _createClass=function(){function t(t,e){for(var i=0;i
+
diff --git a/src/tags/image-size.tag b/src/tags/image-size.tag
new file mode 100644
index 00000000..113661c7
--- /dev/null
+++ b/src/tags/image-size.tag
@@ -0,0 +1,48 @@
+
+
+
{ this.bytesToSize(this.size) }
+
+
\ No newline at end of file
diff --git a/src/tags/taglist.tag b/src/tags/taglist.tag
index 8b981e42..eceb7118 100644
--- a/src/tags/taglist.tag
+++ b/src/tags/taglist.tag
@@ -30,6 +30,7 @@