/*!
* docker-registry-ui
* Copyright (C) 2016-2019 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
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
function Http(){this.oReq=new XMLHttpRequest,this.oReq.hasHeader=Http.hasHeader,this.oReq.getErrorMessage=Http.getErrorMessage,this._events={},this._headers={}}Http.prototype.addEventListener=function(t,e){this._events[t]=e;const r=this;switch(t){case"loadend":r.oReq.addEventListener("loadend",function(){if(401==this.status){const t=new XMLHttpRequest;for(key in t.open(r._method,r._url),r._events)t.addEventListener(key,r._events[key]);for(key in r._headers)t.setRequestHeader(key,r._headers[key]);t.withCredentials=!0,t.hasHeader=Http.hasHeader,t.getErrorMessage=Http.getErrorMessage,t.send()}else e.bind(this)()});break;case"load":r.oReq.addEventListener("load",function(){401!==this.status&&e.bind(this)()});break;default:r.oReq.addEventListener(t,function(){e.bind(this)()})}},Http.prototype.setRequestHeader=function(t,e){this.oReq.setRequestHeader(t,e),this._headers[t]=e},Http.prototype.open=function(t,e){this._method=t,this._url=e,this.oReq.open(t,e)},Http.prototype.send=function(){this.oReq.send()},Http.hasHeader=function(t){return this.getAllResponseHeaders().split("\n").some(function(e){return new RegExp("^"+t+":","i").test(e)})},Http.getErrorMessage=function(){return registryUI.url()&®istryUI.url().match("^http://")&&"https:"===window.location.protocol?"Mixed Content: The page at `"+window.location.origin+"` was loaded over HTTPS, but requested an insecure server endpoint `"+registryUI.url()+"`. This request has been blocked; the content must be served over HTTPS.":registryUI.url()?this.withCredentials&&!this.hasHeader("Access-Control-Allow-Credentials")?"The `Access-Control-Allow-Credentials` header in the response is missing and must be set to `true` when the request's credentials mode is on. Origin `"+registryUI.url()+"` is therefore not allowed access.":"An error occured: Check your connection and your registry must have `Access-Control-Allow-Origin` header set to `"+window.location.origin+"`":"Incorrect server endpoint."};var registryUI={url:function(){var t="${URL}";return t||((t=window.location.origin+window.location.pathname).endsWith("/")?t.substr(0,t.length-1):t)},name:function(){return"${REGISTRY_TITLE}"},pullUrl:"${PULL_URL}",isImageRemoveActivated:!0,catalog:{},taglist:{},taghistory:{}};window.addEventListener("DOMContentLoaded",function(){riot.mount("*")}),riot.tag2("app",'
',"","",function(t){registryUI.catalog.instance=this,registryUI.catalog.display=function(){registryUI.catalog.repositories=[];const 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(),registryUI.catalog.length=registryUI.catalog.repositories.length,registryUI.catalog.repositories=registryUI.catalog.repositories.reduce(function(t,e){const r=e.indexOf("/");if(r>0){const i=e.substring(0,r)+"/";return 0!=t.length&&t[t.length-1].repo==i||t.push({repo:i,images:[]}),t[t.length-1].images.push(e),t}return t.push(e),t},[])):404==this.status?registryUI.snackbar("Server not found",!0):registryUI.snackbar(this.responseText)}),t.addEventListener("error",function(){registryUI.snackbar(this.getErrorMessage(),!0),registryUI.catalog.repositories=[]}),t.addEventListener("loadend",function(){registryUI.catalog.loadend=!0,registryUI.catalog.instance.update()}),t.open("GET",registryUI.url()+"/v2/_catalog?n=100000"),t.send()},registryUI.catalog.display()}),riot.tag2("copy-to-clipboard",' content_copy',"","",function(t){this.dockerCmd="docker pull "+registryUI.cleanName()+"/"+t.image.name+":"+t.image.tag,this.copy=function(){const t=this.refs.input;t.style.display="block",t.select(),document.execCommand("copy"),t.style.display="none",registryUI.snackbar("`"+this.dockerCmd+"` has been copied to clipboard.")}}),riot.tag2("image-date",'
',"","",function(t){const e=this;t.image.on("sha256",function(t){e.sha256=t.substring(0,19),e.update()}),t.image.trigger("get-sha256")}),riot.tag2("remove-image",'delete',"","",function(t){const e=this;this.on("update",function(){!this.opts.multiDelete&&this.tags["material-checkbox"].checked&&this.tags["material-checkbox"].toggle()}),this.on("mount",function(){this.delete=this.tags["material-button"].root.onclick=function(t){const r=e.opts.image.name,i=e.opts.image.tag,s=new Http;s.addEventListener("loadend",function(){if(registryUI.taglist.go(r),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.");const e=this.getResponseHeader("Docker-Content-Digest"),s=new Http;s.addEventListener("loadend",function(){200==this.status||202==this.status?(registryUI.taglist.display(),registryUI.snackbar("Deleting "+r+":"+i+" image. Run `registry garbage-collect config.yml` on your registry")):404==this.status?t||registryUI.errorSnackbar("Digest not found"):registryUI.snackbar(this.responseText)}),s.open("DELETE",registryUI.url()+"/v2/"+r+"/manifests/"+e),s.setRequestHeader("Accept","application/vnd.docker.distribution.manifest.v2+json"),s.addEventListener("error",function(){registryUI.errorSnackbar("An error occurred when deleting image. Check if your server accept DELETE methods Access-Control-Allow-Methods: ['DELETE'].")}),s.send()}else 404==this.status?registryUI.errorSnackbar("Manifest for "+r+":"+i+" not found"):registryUI.snackbar(this.responseText)}),s.open("HEAD",registryUI.url()+"/v2/"+r+"/manifests/"+i),s.setRequestHeader("Accept","application/vnd.docker.distribution.manifest.v2+json"),s.send()},this.tags["material-checkbox"].on("toggle",function(){registryUI.taglist.instance.trigger("toggle-remove-image",this.checked)})})}),riot.tag2("tag-history-button",'history',"","",function(t){this.on("mount",function(){const t=this;this.refs.button.root.onclick=function(){registryUI.taghistory._image=t.opts.image,registryUI.taghistory.go(t.opts.image.name,t.opts.image.tag)}}),this.update()}),riot.tag2("tag-history-element",'