From d3ef3c16a226bd51b2c16e252cfe715e7e1e6d21 Mon Sep 17 00:00:00 2001 From: jr-k Date: Mon, 15 Jul 2024 23:43:18 +0200 Subject: [PATCH] wip --- data/www/css/compiled/main.css | 2 +- data/www/img/logo3.png | Bin 0 -> 49603 bytes data/www/js/explorer.js | 8 +- data/www/js/global.js | 16 +- data/www/js/lib/jquery-explr-1.4.js | 6 +- data/www/js/lib/qrcode.min.js | 1 + data/www/js/playlist/playlists.js | 74 +-- data/www/scss/base/_context.scss | 2 +- data/www/scss/base/_html.scss | 16 +- data/www/scss/base/_menu.scss | 8 +- data/www/scss/components/_alerts.scss | 35 +- data/www/scss/components/_breadcrumb.scss | 2 +- data/www/scss/components/_buttons.scss | 43 +- data/www/scss/components/_dropdown.scss | 2 +- data/www/scss/components/_empty.scss | 15 + data/www/scss/components/_explorer.scss | 4 +- data/www/scss/components/_modals.scss | 22 +- data/www/scss/components/_panes.scss | 6 +- data/www/scss/components/_pills.scss | 2 +- data/www/scss/components/_switches.scss | 168 ++---- data/www/scss/components/_tiles.scss | 117 ++++ data/www/scss/forms/_forms.scss | 314 +++++----- data/www/scss/layout/_header.scss | 2 +- data/www/scss/main.scss | 3 +- data/www/scss/pages/_content.scss | 4 +- data/www/scss/pages/_playlist.scss | 147 ++++- data/www/scss/utils/_mixins.scss | 23 + lang/en.json | 18 +- lang/es.json | 577 +++++++++--------- lang/fr.json | 578 +++++++++---------- lang/it.json | 577 +++++++++--------- src/Application.py | 5 + src/controller/AuthController.py | 6 +- src/controller/PlayerController.py | 13 +- src/controller/PlaylistController.py | 68 ++- src/controller/SlideController.py | 40 +- src/exceptions/PlaylistSlugAlreadyExist.py | 2 + src/manager/DatabaseManager.py | 10 +- src/manager/NodePlayerGroupManager.py | 3 +- src/manager/PlaylistManager.py | 35 +- src/manager/SlideManager.py | 9 +- src/manager/VariableManager.py | 4 +- src/model/entity/Playlist.py | 2 +- src/model/enum/HookType.py | 5 - src/util/utils.py | 10 + views/base.jinja.html | 7 +- views/fleet/node-players/list.jinja.html | 11 +- views/player/player.jinja.html | 10 +- views/playlist/component/edit.jinja.html | 113 ++++ views/playlist/component/table.jinja.html | 126 ++-- views/playlist/list.jinja.html | 68 ++- views/playlist/modal/edit.jinja.html | 37 -- views/playlist/modal/qrcode.jinja.html | 13 + views/slideshow/slides/list.jinja.html | 85 +-- views/slideshow/slides/modal/add.jinja.html | 51 +- views/slideshow/slides/modal/edit.jinja.html | 34 +- 56 files changed, 1949 insertions(+), 1610 deletions(-) create mode 100644 data/www/img/logo3.png create mode 100644 data/www/js/lib/qrcode.min.js create mode 100644 data/www/scss/components/_tiles.scss create mode 100644 src/exceptions/PlaylistSlugAlreadyExist.py create mode 100644 views/playlist/component/edit.jinja.html delete mode 100644 views/playlist/modal/edit.jinja.html create mode 100644 views/playlist/modal/qrcode.jinja.html diff --git a/data/www/css/compiled/main.css b/data/www/css/compiled/main.css index f768829..d324286 100644 --- a/data/www/css/compiled/main.css +++ b/data/www/css/compiled/main.css @@ -1 +1 @@ -.info{color:#027bff!important}.bg-info{background-color:#027bff!important}.border-info{border-color:#027bff!important}.info-alt{color:#075cb7!important}.bg-info-alt{background-color:#075cb7!important}.border-info-alt{border-color:#075cb7!important}.success{color:#0eef5f!important}.bg-success{background-color:#0eef5f!important}.border-success{border-color:#0eef5f!important}.success-alt{color:#11a948!important}.bg-success-alt{background-color:#11a948!important}.border-success-alt{border-color:#11a948!important}.error{color:#ef0e5d!important}.bg-error{background-color:#ef0e5d!important}.border-error{border-color:#ef0e5d!important}.error-alt{color:#c20941!important}.bg-error-alt{background-color:#c20941!important}.border-error-alt{border-color:#c20941!important}.danger{color:#ef0e5d!important}.bg-danger{background-color:#ef0e5d!important}.border-danger{border-color:#ef0e5d!important}.danger-alt{color:#c20941!important}.bg-danger-alt{background-color:#c20941!important}.border-danger-alt{border-color:#c20941!important}.purple{color:#bc48ff!important}.bg-purple{background-color:#bc48ff!important}.border-purple{border-color:#bc48ff!important}.purple-alt{color:#692fbd!important}.bg-purple-alt{background-color:#692fbd!important}.border-purple-alt{border-color:#692fbd!important}.neutral{color:#464646!important}.bg-neutral{background-color:#464646!important}.border-neutral{border-color:#464646!important}.yellow{color:#e5a123!important}.bg-yellow{background-color:#e5a123!important}.border-yellow{border-color:#e5a123!important}.white{color:#fff!important}.bg-white{background-color:#fff!important}.border-white{border-color:#fff!important}.black{color:#000!important}.bg-black{background-color:#000!important}.border-black{border-color:#000!important}.youtube{color:#fd3c01!important}.bg-youtube{background-color:#fd3c01!important}.border-youtube{border-color:#fd3c01!important}.raspbian{color:#b61240!important}.bg-raspbian{background-color:#b61240!important}.border-raspbian{border-color:#b61240!important}.windows{color:#12a7e3!important}.bg-windows{background-color:#12a7e3!important}.border-windows{border-color:#12a7e3!important}.macos{color:#b3bcc2!important}.bg-macos{background-color:#b3bcc2!important}.border-macos{border-color:#b3bcc2!important}.debian{color:#cf084e!important}.bg-debian{background-color:#cf084e!important}.border-debian{border-color:#cf084e!important}.fedora{color:#52a2da!important}.bg-fedora{background-color:#52a2da!important}.border-fedora{border-color:#52a2da!important}.ubuntu{color:#d64514!important}.bg-ubuntu{background-color:#d64514!important}.border-ubuntu{border-color:#d64514!important}.suse{color:#6fb425!important}.bg-suse{background-color:#6fb425!important}.border-suse{border-color:#6fb425!important}.redhat{color:#c60200!important}.bg-redhat{background-color:#c60200!important}.border-redhat{border-color:#c60200!important}.centos{color:#9b4c88!important}.bg-centos{background-color:#9b4c88!important}.border-centos{border-color:#9b4c88!important}.other{color:#e5a123!important}.bg-other{background-color:#e5a123!important}.border-other{border-color:#e5a123!important}button.btn-info,.btn.btn-info{background:#027bff;box-shadow:0 2px #004a9b}button.btn-info:hover,.btn.btn-info:hover{box-shadow:0 2px 0 1px #004a9b inset}button.btn-info:focus,.btn.btn-info:focus{background:#004a9b}button.btn-info-alt,.btn.btn-info-alt{background:#075cb7;box-shadow:0 2px #032b55}button.btn-info-alt:hover,.btn.btn-info-alt:hover{box-shadow:0 2px 0 1px #032b55 inset}button.btn-info-alt:focus,.btn.btn-info-alt:focus{background:#032b55}button.btn-success,.btn.btn-success{background:#0eef5f;box-shadow:0 2px #088f39}button.btn-success:hover,.btn.btn-success:hover{box-shadow:0 2px 0 1px #088f39 inset}button.btn-success:focus,.btn.btn-success:focus{background:#088f39}button.btn-success-alt,.btn.btn-success-alt{background:#11a948;box-shadow:0 2px #084c21}button.btn-success-alt:hover,.btn.btn-success-alt:hover{box-shadow:0 2px 0 1px #084c21 inset}button.btn-success-alt:focus,.btn.btn-success-alt:focus{background:#084c21}button.btn-error,.btn.btn-error{background:#ef0e5d;box-shadow:0 2px #8f0838}button.btn-error:hover,.btn.btn-error:hover{box-shadow:0 2px 0 1px #8f0838 inset}button.btn-error:focus,.btn.btn-error:focus{background:#8f0838}button.btn-error-alt,.btn.btn-error-alt{background:#c20941;box-shadow:0 2px #610420}button.btn-error-alt:hover,.btn.btn-error-alt:hover{box-shadow:0 2px 0 1px #610420 inset}button.btn-error-alt:focus,.btn.btn-error-alt:focus{background:#610420}button.btn-danger,.btn.btn-danger{background:#ef0e5d;box-shadow:0 2px #8f0838}button.btn-danger:hover,.btn.btn-danger:hover{box-shadow:0 2px 0 1px #8f0838 inset}button.btn-danger:focus,.btn.btn-danger:focus{background:#8f0838}button.btn-danger-alt,.btn.btn-danger-alt{background:#c20941;box-shadow:0 2px #610420}button.btn-danger-alt:hover,.btn.btn-danger-alt:hover{box-shadow:0 2px 0 1px #610420 inset}button.btn-danger-alt:focus,.btn.btn-danger-alt:focus{background:#610420}button.btn-purple,.btn.btn-purple{background:#bc48ff;box-shadow:0 2px #8f00e1}button.btn-purple:hover,.btn.btn-purple:hover{box-shadow:0 2px 0 1px #8f00e1 inset}button.btn-purple:focus,.btn.btn-purple:focus{background:#8f00e1}button.btn-purple-alt,.btn.btn-purple-alt{background:#692fbd;box-shadow:0 2px #3c1b6b}button.btn-purple-alt:hover,.btn.btn-purple-alt:hover{box-shadow:0 2px 0 1px #3c1b6b inset}button.btn-purple-alt:focus,.btn.btn-purple-alt:focus{background:#3c1b6b}button.btn-neutral,.btn.btn-neutral{background:#464646;box-shadow:0 2px #131313}button.btn-neutral:hover,.btn.btn-neutral:hover{box-shadow:0 2px 0 1px #131313 inset}button.btn-yellow,.btn.btn-yellow{background:#e5a123;box-shadow:0 2px #916411}button.btn-yellow:hover,.btn.btn-yellow:hover{box-shadow:0 2px 0 1px #916411 inset}button.btn-yellow:focus,.btn.btn-yellow:focus{background:#916411}button.btn-white,.btn.btn-white{background:#fff;box-shadow:0 2px #ccc}button.btn-white:hover,.btn.btn-white:hover{box-shadow:0 2px 0 1px #ccc inset}button.btn-white:focus,.btn.btn-white:focus{background:#ccc}button.btn-black,.btn.btn-black{background:#000;box-shadow:0 2px #000}button.btn-black:hover,.btn.btn-black:hover{box-shadow:0 2px 0 1px #000 inset}button.btn-black:focus,.btn.btn-black:focus{background:#000}button.btn-youtube,.btn.btn-youtube{background:#fd3c01;box-shadow:0 2px #972401}button.btn-youtube:hover,.btn.btn-youtube:hover{box-shadow:0 2px 0 1px #972401 inset}button.btn-youtube:focus,.btn.btn-youtube:focus{background:#972401}button.btn-raspbian,.btn.btn-raspbian{background:#b61240;box-shadow:0 2px #59091f}button.btn-raspbian:hover,.btn.btn-raspbian:hover{box-shadow:0 2px 0 1px #59091f inset}button.btn-raspbian:focus,.btn.btn-raspbian:focus{background:#59091f}button.btn-windows,.btn.btn-windows{background:#12a7e3;box-shadow:0 2px #0b6184}button.btn-windows:hover,.btn.btn-windows:hover{box-shadow:0 2px 0 1px #0b6184 inset}button.btn-windows:focus,.btn.btn-windows:focus{background:#0b6184}button.btn-macos,.btn.btn-macos{background:#b3bcc2;box-shadow:0 2px #7a8a95}button.btn-macos:hover,.btn.btn-macos:hover{box-shadow:0 2px 0 1px #7a8a95 inset}button.btn-macos:focus,.btn.btn-macos:focus{background:#7a8a95}button.btn-debian,.btn.btn-debian{background:#cf084e;box-shadow:0 2px #6d0429}button.btn-debian:hover,.btn.btn-debian:hover{box-shadow:0 2px 0 1px #6d0429 inset}button.btn-debian:focus,.btn.btn-debian:focus{background:#6d0429}button.btn-fedora,.btn.btn-fedora{background:#52a2da;box-shadow:0 2px #236ea3}button.btn-fedora:hover,.btn.btn-fedora:hover{box-shadow:0 2px 0 1px #236ea3 inset}button.btn-fedora:focus,.btn.btn-fedora:focus{background:#236ea3}button.btn-ubuntu,.btn.btn-ubuntu{background:#d64514;box-shadow:0 2px #79270b}button.btn-ubuntu:hover,.btn.btn-ubuntu:hover{box-shadow:0 2px 0 1px #79270b inset}button.btn-ubuntu:focus,.btn.btn-ubuntu:focus{background:#79270b}button.btn-suse,.btn.btn-suse{background:#6fb425;box-shadow:0 2px #3b5f14}button.btn-suse:hover,.btn.btn-suse:hover{box-shadow:0 2px 0 1px #3b5f14 inset}button.btn-suse:focus,.btn.btn-suse:focus{background:#3b5f14}button.btn-redhat,.btn.btn-redhat{background:#c60200;box-shadow:0 2px #600100}button.btn-redhat:hover,.btn.btn-redhat:hover{box-shadow:0 2px 0 1px #600100 inset}button.btn-redhat:focus,.btn.btn-redhat:focus{background:#600100}button.btn-centos,.btn.btn-centos{background:#9b4c88;box-shadow:0 2px #572a4c}button.btn-centos:hover,.btn.btn-centos:hover{box-shadow:0 2px 0 1px #572a4c inset}button.btn-centos:focus,.btn.btn-centos:focus{background:#572a4c}button.btn-other,.btn.btn-other{background:#e5a123;box-shadow:0 2px #916411}button.btn-other:hover,.btn.btn-other:hover{box-shadow:0 2px 0 1px #916411 inset}button.btn-other:focus,.btn.btn-other:focus{background:#916411}@font-face{font-family:Sixtyfour;src:url(../../webfonts/Sixtyfour-Regular.ttf) format("truetype")}*{font-family:Roboto,Arial,"sans-serif";margin:0;padding:0;box-sizing:border-box}html{background-color:#111}body,html{height:100%;font-family:Arial,sans-serif}.container{display:flex;height:100vh}.horizontal{display:flex;flex-direction:row;justify-content:flex-start;align-items:flex-start;flex:1;align-self:stretch}main{flex:1;display:flex;flex-direction:column}main .main-container{display:flex;flex-direction:column;flex:1;overflow:hidden;align-self:stretch}main .main-container .top-content{display:flex;flex-direction:row;justify-content:flex-start;align-items:center;align-self:stretch;padding:10px 10px 10px 20px;background:transparent;border-bottom:1px solid #222}main .main-container .top-content h1{color:#fff;font-weight:600;font-size:24px}main .main-container .top-content .top-actions{flex:1;display:flex;flex-direction:row;justify-content:flex-end;align-items:center}main .main-container .top-content .top-actions button{margin-left:10px}main .main-container .bottom-content{display:flex;flex-direction:row;align-self:stretch;justify-content:flex-start;align-items:flex-start;flex:1;overflow-y:auto;background:radial-gradient(circle at 0% 53%,rgba(239,14,93,.8) 10%,transparent 45%),radial-gradient(circle at 135% 53%,rgba(2,123,255,.8) 10%,transparent 95%),radial-gradient(circle at 50% 80%,rgba(14,239,95,.8) 40%,transparent 95%)}main .main-container .bottom-content .page-content{flex:2;overflow-y:auto;align-self:stretch;display:flex;flex-direction:column;justify-content:flex-start;align-items:flex-start;background:#000c;padding:5px}main .main-container .bottom-content .page-content .inner{flex:1;display:flex;flex-direction:column;justify-content:flex-start;align-items:flex-start;padding:0 10px 40px;background:#111;align-self:stretch}main .main-container .bottom-content .page-panel{flex:1;overflow-y:auto;align-self:stretch;background:#111;border-top:none}main .main-container .bottom-content .page-panel.left-panel{border-right:1px solid #222;border-left:none}main .main-container .bottom-content .page-panel.left-panel.explr-explorer{flex:.5;overflow-y:auto;padding:0;background:#111;box-shadow:1px 1px .5px .5px inset #0003;max-width:250px}main .main-container .bottom-content .page-panel.right-panel{border-left:1px solid #222;border-right:none}.invisible{visibility:hidden!important}.hidden{display:none!important}.tac{text-align:center!important}.tar{text-align:right!important}a{text-decoration:none}.normal{font-weight:400!important}.bold{font-weight:700!important}.col{display:flex;flex:1;flex-direction:column;align-self:stretch}main .context-bar{padding:10px;position:sticky;top:0;z-index:1000;max-height:80px;border-bottom:1px solid #222;display:flex;flex-direction:row;align-items:center}main .context-bar .context-menu{flex:1}main .context-bar .context-menu .inner{display:flex}main .context-bar .context-menu .inner ul.pills{margin:0}main .context-bar .context-divider{width:1px;height:100%;background:#222;margin-left:20px;margin-right:20px}main .context-bar .context-user{display:flex;margin-right:20px}main .context-bar .context-user .trigger{color:#fff}main .context-bar .context-user .trigger .avatar{width:32px;height:32px;border-radius:4px;background:#027bff;margin-right:10px;display:flex;flex-direction:row;justify-content:center;align-items:center;text-align:center;font-weight:700;font-size:14px;border:1px solid #444}main .context-bar .context-user .trigger i{margin-top:-5px;margin-left:10px}menu{width:300px;background:#111;overflow-y:auto;overflow-x:visible;padding:20px;z-index:2000;display:flex;flex-direction:column;justify-content:flex-start;align-items:flex-start;border-right:1px solid #222;min-width:64px}menu h1.logo{margin:40px 0 0 10px;align-self:stretch;display:flex}menu h1.logo a{text-align:center;text-shadow:0px 0 0 #fff,0px 2px 0 #444,0 0px 0 rgb(14,239,95),-0px 0 0 rgb(2,123,255),0 -0px 0 rgb(239,14,93);text-decoration:none;background:linear-gradient(90deg,#a0a0a0 0,#bebebe 46%,#dcdcdc);-webkit-background-clip:text;color:transparent;flex:1;font-family:Sixtyfour,Work Sans,Arial,"sans-serif";align-self:stretch;padding-right:3px;font-size:20px;text-transform:uppercase;transition:all .55s cubic-bezier(.19,1,.22,1);display:flex;flex-direction:row;justify-content:center;align-items:center;position:relative}menu h1.logo a img{flex-shrink:0;width:30px;margin-right:10px;position:absolute;left:5px;transition:all .55s cubic-bezier(.19,1,.22,1)}menu h1.logo a img.after{opacity:0}menu:hover h1.logo a{text-align:center;text-shadow:3px 0 0 #fff,3px 2px 0 #444,0 3px 0 rgb(14,239,95),-3px 0 0 rgb(2,123,255),0 -3px 0 rgb(239,14,93);text-decoration:none;background:linear-gradient(90deg,#a0a0a0 0,#bebebe 46%,#dcdcdc);-webkit-background-clip:text;color:transparent}menu:hover h1.logo a img.before{opacity:0}menu:hover h1.logo a img.after{animation-duration:.2s;animation-name:logotouch}menu nav{display:flex;align-self:stretch;flex:1}menu nav ul{margin:60px 0 20px;flex:1;align-self:flex-start;display:flex;flex-direction:column;list-style:none}menu nav ul li{align-self:stretch;overflow:hidden;position:relative;transition:all .55s cubic-bezier(.19,1,.22,1);margin:10px 0;border-radius:4px}menu nav ul li a{color:#ffffffe6;font-size:16px;display:flex;flex-direction:row;justify-content:flex-start;align-items:center;align-self:stretch;flex:1;padding-top:5px;padding-bottom:5px;padding-left:10px}menu nav ul li a i{color:#fff;opacity:.2;background:transparent;display:flex;justify-content:center;align-items:center;align-self:stretch;padding:10px;width:40px;border-radius:4px;text-align:center;margin-right:20px}menu nav ul li:after{background:#fff;content:"";height:195px;left:-200px;opacity:.2;position:absolute;top:-50px;transform:rotate(35deg);transition:all .55s cubic-bezier(.19,1,.22,1);width:50px;z-index:-2;cursor:pointer}menu nav ul li.active a{color:#027bff;font-weight:700}menu nav ul li.active a i{opacity:1;background:#ffffffe6;background:#017bff}menu nav ul li:hover{background:#027bff}menu nav ul li:hover:after{z-index:2;left:120%;transition:all .55s cubic-bezier(.19,1,.22,1)}menu nav ul li:hover a{color:#fff;font-weight:700}menu nav ul li:hover a i{color:#fff;opacity:1}menu footer{background:#ffffff03;padding:20px 0;display:flex;flex-direction:row;align-self:stretch;text-align:center;justify-content:center}menu footer p{color:#444}menu footer p.version a{color:#777;font-weight:700}.dropdown{position:relative;display:flex;align-self:stretch}.dropdown.dropdown-show ul.dropdown-menu{display:flex;flex-direction:column}.dropdown .trigger{cursor:pointer;display:flex;flex-direction:row;justify-content:flex-start;align-items:center;align-self:stretch;flex:1}.dropdown ul.dropdown-menu{position:absolute;top:100%;left:0;display:none;background-color:#222;box-shadow:0 8px 16px #0003;z-index:1000;list-style-type:none;margin:0;overflow:hidden;border-radius:4px}.dropdown ul.dropdown-menu li{padding:8px 16px;cursor:pointer;display:flex;flex-direction:row;justify-content:flex-start;align-items:center;transition:all .55s cubic-bezier(.19,1,.22,1)}.dropdown ul.dropdown-menu li.danger:hover{background-color:#ef0e5d}.dropdown ul.dropdown-menu li:hover{background-color:#027bff}.dropdown ul.dropdown-menu li a{padding:8px 16px 8px 8px;color:#fff;display:flex;flex-direction:row;justify-content:flex-start;align-items:center;align-self:stretch}.dropdown ul.dropdown-menu li a i{margin-right:15px}@keyframes logotouch{0%{opacity:0}50%{opacity:1}to{opacity:0;left:27px}}button,.btn{position:relative;padding:10px 13px 8px 10px;font-size:14px;color:#fff;cursor:pointer;border:none;border-radius:4px;background:#027bff;box-shadow:0 2px #004a9b;font-weight:700;letter-spacing:-.5px;margin-top:-2px}button i.icon-left,.btn i.icon-left{margin-right:5px}button:hover,.btn:hover{box-shadow:0 2px 0 1px #004a9b inset;color:#fffc}button:focus,.btn:focus{background:#004a9b;color:#ffffff80;box-shadow:none}button.btn-neutral,.btn.btn-neutral{color:#aaa;background:#464646;box-shadow:0 2px #2d2d2d}button.btn-neutral:hover,.btn.btn-neutral:hover{box-shadow:0 2px 0 1px #222 inset;background:#2d2d2d}button.btn-neutral:focus,.btn.btn-neutral:focus{background:#131313}button.btn-naked,.btn.btn-naked{background:transparent;box-shadow:none}button.btn-naked:hover,.btn.btn-naked:hover{box-shadow:0 2px 0 1px #222 inset;background:#2d2d2d}button.btn-naked:focus,.btn.btn-naked:focus{background:#131313}.alert{padding:20px;align-self:stretch;display:flex;flex-direction:row;justify-content:center;align-items:center;border-radius:4px}.alert-info{color:#027bff;background:#027bff33}.alert-success{color:#0eef5f;background:#0eef5f33}.alert-danger,.alert-error{color:#ef0e5d;background:#ef0e5d33}.alert i{margin-right:13px}ul.explr-tree{height:100%!important}ul.explr-tree li span{color:#555;font-size:13px;padding-left:5px;cursor:pointer}ul.explr-tree li span.explr-plus,ul.explr-tree li span.explr-minus{z-index:1}ul.explr-tree li span.explr-plus:hover,ul.explr-tree li span.explr-minus:hover{color:#aaa}ul.explr-tree li a{color:#fff;padding-right:80px}ul.explr-tree li a:hover{color:#fff}ul.explr-tree li a.active{background:#ffffff1a;border-radius:4px;font-weight:700;text-decoration:underline;margin-left:35px;padding-left:5px;margin-right:10px}.explr-selection-actions{display:none;margin-right:10px;border-right:1px solid #222;padding-right:20px}.explr-selection-actions button{display:none}body.explr-selection-actionable .explr-selection-actions,body.explr-selection-actionable.explr-selection-folder .explr-selection-actions button.explr-selection-folder,body.explr-selection-actionable.explr-selection-entity .explr-selection-actions button.explr-selection-entity{display:flex}ul.explr-dirview{display:flex;flex-direction:row;flex-wrap:wrap}ul.explr-dirview li{display:flex;flex-direction:column;justify-content:flex-start;align-items:center;flex-shrink:0;margin:18px;min-width:90px;min-height:104px;padding-top:5px;border:1px solid transparent;border-radius:4px}ul.explr-dirview li.renaming a span{display:none}ul.explr-dirview li.renaming a form{display:block}ul.explr-dirview li.highlight-drop{border:1px dotted rgba(2,123,255,.4);background:#027bff4d}ul.explr-dirview li.highlight-clicked{border:1px dotted rgba(255,255,255,.2);background:#ffffff1a}ul.explr-dirview li a{color:#bbb;text-decoration:none;flex:1;text-align:center;font-size:12px;display:flex;flex-direction:column;justify-content:flex-start;align-items:center;max-width:84px}ul.explr-dirview li a i{font-size:64px;margin-bottom:12px;border-radius:8px}ul.explr-dirview li a input{width:100%;padding:0 3px}ul.explr-dirview li a input:focus{outline:none}ul.explr-dirview li a:hover{opacity:.8}ul.explr-dirview li a form{display:none}ul.explr-dirview li.new-folder a{color:#027bff}ul.explr-dirview li.new-folder a form{display:block}ul.explr-dirview .ui-draggable-dragging{z-index:20}ul.explr-dirview .ui-draggable-dragging a{opacity:1!important}ul.pills{background:#222;padding:6px 4px 5px;box-shadow:1px 1px .5px .5px inset #0003;border:1px solid #222;border-radius:4px;display:flex;flex-direction:row;justify-content:flex-start;align-items:center;list-style:none;margin:0}ul.pills li.divider{margin:0 20px;width:1px;height:100%;background:#333}ul.pills li:hover a{opacity:.9}ul.pills li a{border-radius:4px;display:flex;flex-direction:row;justify-content:center;align-items:center;color:#fff;overflow:hidden;padding-right:30px;text-align:center;background:#0003;margin-right:5px;transition:all .25s cubic-bezier(.19,1,.22,1)}ul.pills li a span{display:flex;justify-content:center;align-items:center;margin-right:20px;height:42px;background:#0003;width:42px}ul.pills li.active a{color:#333;background:#fff;font-weight:700}ul.pills li:hover a{color:#fff;background:#027bff}ul.pills li:last-child a{margin-right:0}.breadcrumb-container{display:flex;flex-direction:row;justify-content:flex-start;align-items:center;align-self:stretch;border-bottom:1px solid #222;background:transparent;padding:10px}.breadcrumb-container ul.breadcrumb{background:#222;padding:6px 4px 5px;box-shadow:1px 1px .5px .5px inset #0003;border:1px solid #222;border-radius:4px;display:flex;flex-direction:row;justify-content:flex-start;align-items:center;list-style:none;margin:0}.breadcrumb-container ul.breadcrumb li.divider{margin:0 5px}.breadcrumb-container ul.breadcrumb li.divider i{color:#aaa}.breadcrumb-container ul.breadcrumb li span,.breadcrumb-container ul.breadcrumb li a{border-radius:4px;display:flex;flex-direction:row;justify-content:center;align-items:center;color:#fff;text-align:center;padding:0 3px}.breadcrumb-container ul.breadcrumb li span i,.breadcrumb-container ul.breadcrumb li a i{margin-right:5px}.breadcrumb-container ul.breadcrumb li:hover a{color:#fff;background:#027bff}.breadcrumb-container ul.breadcrumb li:last-child a{margin-right:0}.modals{position:fixed;background:#0006;top:0;right:0;bottom:0;left:0;display:flex;flex-direction:column;justify-content:center;align-items:center;z-index:10000}.modals .modals-outer{min-width:464px;display:flex;flex-direction:column;overflow:auto;padding-bottom:2px}.modals .modals-outer .modals-inner{background:#111;border-radius:10px;color:#333;padding:40px;box-shadow:0 2px #222;border:1px solid #222}.modals .modals-outer .modals-inner .modal h2{padding:0;margin:0 0 30px;font-weight:400;color:#999}.modals .modals-outer .modals-inner .modal h3{align-self:stretch;border-bottom:1px solid rgb(153,153,153);padding:15px;margin:0}table.panes{flex:1;display:flex;flex-direction:column;justify-content:flex-start;align-items:flex-start;align-self:stretch}table.panes tbody{display:flex;flex-direction:column;justify-content:flex-start;align-items:flex-start;align-self:stretch;margin:1px 1px 28px;background:#111;border-radius:4px;border:4px solid rgba(255,255,255,.05)}table.panes tbody:hover,table.panes tbody:hover tr.title-item{border-color:#027bff0d}table.panes tbody tr{flex:1;display:flex;flex-direction:row;justify-content:flex-start;align-items:center;align-self:stretch;padding:8px 18px;background:#222}table.panes tbody tr:nth-child(odd){background-color:#111}table.panes tbody tr:nth-child(odd) td.description{color:#ffffffb3}table.panes tbody tr:nth-child(2n){background-color:#141414}table.panes tbody tr td{color:#888;display:flex;flex-direction:row;justify-content:flex-start;align-items:center;flex:1;font-size:14px}table.panes tbody tr td.vertical{display:flex;flex-direction:column;justify-content:flex-start;align-items:flex-start}table.panes tbody tr td.description{align-self:stretch}table.panes tbody tr td.value{flex:0;margin-left:20px;word-break:break-all;flex-basis:auto}table.panes tbody tr td.value i.icon-legend{font-size:10px;margin-right:10px}table.panes tbody tr td.value i.icon-value{padding:2px 2px 1px;border-radius:2px;width:16px;text-align:center}table.panes tbody tr.title-item{border-bottom:1px solid #222}table.panes tbody tr.title-item td{color:#027bffe6;font-size:16px;font-weight:700}table.panes tbody tr.title-item td i{margin-right:10px}table.panes tbody tr.title-item td .more{flex:1;text-align:right;font-size:12px;color:#888;font-weight:400;font-style:italic}table.panes tbody tr.variable-item{cursor:pointer}table.panes tbody tr.variable-item:hover{background-color:#027bff0d}table.panes tbody tr.variable-item:hover td{font-weight:700;color:#fff}table.panes tbody tr.variable-item:hover td i.icon-legend{color:#fff}table.panes tbody tr.variable-item:hover td span,table.panes tbody tr.variable-item:hover td i.icon-value{background-color:#ffffff4d;color:#fff}table.panes tbody tr.variable-item:hover td.description{color:#027bff}span.empty{background:#e5a1234d;color:#e5a123;text-transform:lowercase;border-radius:2px;padding:2px 4px;font-weight:700}.form-holder{min-width:686px;display:flex;flex-direction:column;justify-content:flex-start;align-items:flex-start;align-self:stretch}.form-holder form{max-width:434px}form{display:flex;flex-direction:column;justify-content:flex-start;align-items:flex-start;align-self:stretch}form .alert{padding:8px 15px;font-size:14px;margin:0 0 25px}form .form-group{display:flex;flex-direction:column;justify-content:flex-start;align-items:flex-start;align-self:stretch;width:100%;flex:1;margin-bottom:20px}form .form-group label{flex:1;font-size:12px;display:flex;flex-direction:row;justify-content:flex-start;align-items:center;align-self:stretch;color:#666}form .form-group label.btn-upload{color:#fff;font-size:14px;flex:0;flex-basis:auto;margin-top:5px}form .form-group label.btn-upload input[type=file]{display:none}form .form-group label.btn-upload input[type=text]{margin-bottom:2px;padding-left:0;margin-left:10px}form .form-group label.btn-upload i{margin-left:3px;margin-right:10px}form .form-group .widget{margin-top:10px;align-self:stretch;display:flex;flex-direction:row}form .form-group .widget div{color:#ffffffb3;font-size:14px}form .form-group .widget select,form .form-group .widget input,form .form-group .widget textarea{outline:none;padding:8px 0 5px 8px;border-radius:2px;border:1px solid rgba(255,255,255,.05);flex:1;background:#555;box-shadow:0 2px 1px #444,0 4px 2px #333 inset;color:#ddd;font-size:14px}form .form-group .widget select[disabled],form .form-group .widget input[disabled],form .form-group .widget textarea[disabled]{color:#555;background:none;box-shadow:none;border:none;border-bottom:1px solid #333;border-radius:0}form .form-group.tab-select{border-bottom:1px solid #444;display:flex;flex-direction:row;position:relative;height:48px;padding:48px 0 0;flex:0;flex-basis:auto}form .form-group.tab-select .widget{height:49px;margin-top:0;display:flex;flex-direction:row;justify-content:flex-start;align-items:center;position:absolute;top:0;left:0;border-bottom:2px solid rgb(2,123,255);color:#027bff}form .form-group.tab-select .widget select{border:none;background:none;box-shadow:none;padding:10px 35px 10px 10px;margin:0;color:inherit;appearance:none;-moz-appearance:none;-webkit-appearance:none;text-align:left;font-weight:700;cursor:pointer;border-radius:4px 4px 0 0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:200px;z-index:2}form .form-group.tab-select .widget i{margin-left:10px;margin-right:0}form .form-group.tab-select .widget i.triangle{margin-top:-4px;margin-left:0;position:absolute;right:10px}form .actions{display:flex;flex-direction:row;justify-content:flex-end;align-items:center;align-self:stretch;margin:20px 0 0}form .actions button{margin-left:25px}form .actions.actions-left{justify-content:flex-start}form .actions.actions-left button{margin-left:0;margin-right:25px}.view-content-list main .main-container .content-object-input{margin-bottom:6px}.view-content-edit main .main-container .bottom-content .page-content{flex:1}.view-content-edit main .main-container .bottom-content .page-content .form-holder{margin:20px 20px 20px 10px}.view-content-edit main .main-container .bottom-content .page-panel.right-panel{flex:1;align-self:stretch;display:flex;flex-direction:column;overflow:hidden;justify-content:flex-start;align-items:center;padding:20px}.view-content-edit main .main-container .bottom-content .page-panel.right-panel h3{color:#fff;padding:10px 10px 10px 0;margin-bottom:20px;font-size:16px;align-self:stretch;margin-left:-8px}.view-content-edit main .main-container .bottom-content .page-panel.right-panel h3 span{border-width:1px;border-style:solid;border-radius:4px;padding:4px 10px;margin-left:5px}.view-content-edit main .main-container .bottom-content .page-panel.right-panel h3 i{font-size:16px}.view-content-edit main .main-container .bottom-content .page-panel.right-panel .iframe-wrapper{display:flex;flex-direction:column;width:100%;position:relative;padding-top:56.25%;overflow:hidden;border-radius:4px;outline:4px solid rgba(255,255,255,.1)}.view-content-edit main .main-container .bottom-content .page-panel.right-panel .iframe-wrapper iframe{position:absolute;top:0;left:0;width:100%;height:100%;border:none}.view-logs-list main .main-container .bottom-content .page-content .inner{padding-top:8px;padding-bottom:8px}.view-logs-list main .main-container .bottom-content .page-content .logs{flex:1;display:flex;flex-direction:column;align-self:stretch}.view-logs-list main .main-container .bottom-content .page-content .logs pre{flex:1;background:#000000e6;border:1px solid rgba(70,70,70,.5);border-radius:4px;font-family:monospace;color:#f2f2f2;padding:20px;overflow:auto;align-self:stretch}.view-node-player-edit main .main-container .bottom-content .page-content{flex:1}.view-node-player-edit main .main-container .bottom-content .page-content .form-holder{margin:20px 20px 20px 10px}.view-playlist-edit main .main-container .bottom-content .page-content{flex:1}.view-playlist-edit main .main-container .bottom-content .page-content .form-holder{margin:20px 20px 20px 10px}.view-plugins-list main .main-container .bottom-content .page-content .inner{padding:10px}.view-settings-list main .main-container .bottom-content .page-content .inner{padding:10px}.view-sysinfo-list main .main-container .bottom-content .page-content .inner{padding:10px} +.info{color:#027bff!important}.bg-info{background-color:#027bff!important}.border-info{border-color:#027bff!important}.info-alt{color:#075cb7!important}.bg-info-alt{background-color:#075cb7!important}.border-info-alt{border-color:#075cb7!important}.success{color:#0eef5f!important}.bg-success{background-color:#0eef5f!important}.border-success{border-color:#0eef5f!important}.success-alt{color:#11a948!important}.bg-success-alt{background-color:#11a948!important}.border-success-alt{border-color:#11a948!important}.error{color:#ef0e5d!important}.bg-error{background-color:#ef0e5d!important}.border-error{border-color:#ef0e5d!important}.error-alt{color:#c20941!important}.bg-error-alt{background-color:#c20941!important}.border-error-alt{border-color:#c20941!important}.danger{color:#ef0e5d!important}.bg-danger{background-color:#ef0e5d!important}.border-danger{border-color:#ef0e5d!important}.danger-alt{color:#c20941!important}.bg-danger-alt{background-color:#c20941!important}.border-danger-alt{border-color:#c20941!important}.purple{color:#bc48ff!important}.bg-purple{background-color:#bc48ff!important}.border-purple{border-color:#bc48ff!important}.purple-alt{color:#692fbd!important}.bg-purple-alt{background-color:#692fbd!important}.border-purple-alt{border-color:#692fbd!important}.neutral{color:#464646!important}.bg-neutral{background-color:#464646!important}.border-neutral{border-color:#464646!important}.yellow{color:#e5a123!important}.bg-yellow{background-color:#e5a123!important}.border-yellow{border-color:#e5a123!important}.white{color:#fff!important}.bg-white{background-color:#fff!important}.border-white{border-color:#fff!important}.black{color:#000!important}.bg-black{background-color:#000!important}.border-black{border-color:#000!important}.youtube{color:#fd3c01!important}.bg-youtube{background-color:#fd3c01!important}.border-youtube{border-color:#fd3c01!important}.raspbian{color:#b61240!important}.bg-raspbian{background-color:#b61240!important}.border-raspbian{border-color:#b61240!important}.windows{color:#12a7e3!important}.bg-windows{background-color:#12a7e3!important}.border-windows{border-color:#12a7e3!important}.macos{color:#b3bcc2!important}.bg-macos{background-color:#b3bcc2!important}.border-macos{border-color:#b3bcc2!important}.debian{color:#cf084e!important}.bg-debian{background-color:#cf084e!important}.border-debian{border-color:#cf084e!important}.fedora{color:#52a2da!important}.bg-fedora{background-color:#52a2da!important}.border-fedora{border-color:#52a2da!important}.ubuntu{color:#d64514!important}.bg-ubuntu{background-color:#d64514!important}.border-ubuntu{border-color:#d64514!important}.suse{color:#6fb425!important}.bg-suse{background-color:#6fb425!important}.border-suse{border-color:#6fb425!important}.redhat{color:#c60200!important}.bg-redhat{background-color:#c60200!important}.border-redhat{border-color:#c60200!important}.centos{color:#9b4c88!important}.bg-centos{background-color:#9b4c88!important}.border-centos{border-color:#9b4c88!important}.other{color:#e5a123!important}.bg-other{background-color:#e5a123!important}.border-other{border-color:#e5a123!important}button.btn-info,.btn.btn-info{background:#027bff;box-shadow:0 2px #004a9b}button.btn-info:hover,.btn.btn-info:hover{box-shadow:0 2px 0 1px #004a9b inset}button.btn-info:focus,.btn.btn-info:focus{background:#004a9b}button.btn-wire-info,.btn.btn-wire-info{background:transparent;box-shadow:none;border:2px solid rgb(2,123,255);color:#fffc}button.btn-wire-info i.btn-match,.btn.btn-wire-info i.btn-match{color:#027bff}button.btn-wire-info:hover,.btn.btn-wire-info:hover{background:#027bff0d;border-color:#0063ce;color:#0063ce;box-shadow:none}button.btn-wire-info:focus,.btn.btn-wire-info:focus{border-color:#004a9b;background:transparent}button.btn-info-alt,.btn.btn-info-alt{background:#075cb7;box-shadow:0 2px #032b55}button.btn-info-alt:hover,.btn.btn-info-alt:hover{box-shadow:0 2px 0 1px #032b55 inset}button.btn-info-alt:focus,.btn.btn-info-alt:focus{background:#032b55}button.btn-wire-info-alt,.btn.btn-wire-info-alt{background:transparent;box-shadow:none;border:2px solid rgb(7,92,183);color:#fffc}button.btn-wire-info-alt i.btn-match,.btn.btn-wire-info-alt i.btn-match{color:#075cb7}button.btn-wire-info-alt:hover,.btn.btn-wire-info-alt:hover{background:#075cb70d;border-color:#054386;color:#054386;box-shadow:none}button.btn-wire-info-alt:focus,.btn.btn-wire-info-alt:focus{border-color:#032b55;background:transparent}button.btn-success,.btn.btn-success{background:#0eef5f;box-shadow:0 2px #088f39}button.btn-success:hover,.btn.btn-success:hover{box-shadow:0 2px 0 1px #088f39 inset}button.btn-success:focus,.btn.btn-success:focus{background:#088f39}button.btn-wire-success,.btn.btn-wire-success{background:transparent;box-shadow:none;border:2px solid rgb(14,239,95);color:#fffc}button.btn-wire-success i.btn-match,.btn.btn-wire-success i.btn-match{color:#0eef5f}button.btn-wire-success:hover,.btn.btn-wire-success:hover{background:#0eef5f0d;border-color:#0bbf4c;color:#0bbf4c;box-shadow:none}button.btn-wire-success:focus,.btn.btn-wire-success:focus{border-color:#088f39;background:transparent}button.btn-success-alt,.btn.btn-success-alt{background:#11a948;box-shadow:0 2px #084c21}button.btn-success-alt:hover,.btn.btn-success-alt:hover{box-shadow:0 2px 0 1px #084c21 inset}button.btn-success-alt:focus,.btn.btn-success-alt:focus{background:#084c21}button.btn-wire-success-alt,.btn.btn-wire-success-alt{background:transparent;box-shadow:none;border:2px solid rgb(17,169,72);color:#fffc}button.btn-wire-success-alt i.btn-match,.btn.btn-wire-success-alt i.btn-match{color:#11a948}button.btn-wire-success-alt:hover,.btn.btn-wire-success-alt:hover{background:#11a9480d;border-color:#0c7b34;color:#0c7b34;box-shadow:none}button.btn-wire-success-alt:focus,.btn.btn-wire-success-alt:focus{border-color:#084c21;background:transparent}button.btn-error,.btn.btn-error{background:#ef0e5d;box-shadow:0 2px #8f0838}button.btn-error:hover,.btn.btn-error:hover{box-shadow:0 2px 0 1px #8f0838 inset}button.btn-error:focus,.btn.btn-error:focus{background:#8f0838}button.btn-wire-error,.btn.btn-wire-error{background:transparent;box-shadow:none;border:2px solid rgb(239,14,93);color:#fffc}button.btn-wire-error i.btn-match,.btn.btn-wire-error i.btn-match{color:#ef0e5d}button.btn-wire-error:hover,.btn.btn-wire-error:hover{background:#ef0e5d0d;border-color:#bf0b4a;color:#bf0b4a;box-shadow:none}button.btn-wire-error:focus,.btn.btn-wire-error:focus{border-color:#8f0838;background:transparent}button.btn-error-alt,.btn.btn-error-alt{background:#c20941;box-shadow:0 2px #610420}button.btn-error-alt:hover,.btn.btn-error-alt:hover{box-shadow:0 2px 0 1px #610420 inset}button.btn-error-alt:focus,.btn.btn-error-alt:focus{background:#610420}button.btn-wire-error-alt,.btn.btn-wire-error-alt{background:transparent;box-shadow:none;border:2px solid rgb(194,9,65);color:#fffc}button.btn-wire-error-alt i.btn-match,.btn.btn-wire-error-alt i.btn-match{color:#c20941}button.btn-wire-error-alt:hover,.btn.btn-wire-error-alt:hover{background:#c209410d;border-color:#910731;color:#910731;box-shadow:none}button.btn-wire-error-alt:focus,.btn.btn-wire-error-alt:focus{border-color:#610420;background:transparent}button.btn-danger,.btn.btn-danger{background:#ef0e5d;box-shadow:0 2px #8f0838}button.btn-danger:hover,.btn.btn-danger:hover{box-shadow:0 2px 0 1px #8f0838 inset}button.btn-danger:focus,.btn.btn-danger:focus{background:#8f0838}button.btn-wire-danger,.btn.btn-wire-danger{background:transparent;box-shadow:none;border:2px solid rgb(239,14,93);color:#fffc}button.btn-wire-danger i.btn-match,.btn.btn-wire-danger i.btn-match{color:#ef0e5d}button.btn-wire-danger:hover,.btn.btn-wire-danger:hover{background:#ef0e5d0d;border-color:#bf0b4a;color:#bf0b4a;box-shadow:none}button.btn-wire-danger:focus,.btn.btn-wire-danger:focus{border-color:#8f0838;background:transparent}button.btn-danger-alt,.btn.btn-danger-alt{background:#c20941;box-shadow:0 2px #610420}button.btn-danger-alt:hover,.btn.btn-danger-alt:hover{box-shadow:0 2px 0 1px #610420 inset}button.btn-danger-alt:focus,.btn.btn-danger-alt:focus{background:#610420}button.btn-wire-danger-alt,.btn.btn-wire-danger-alt{background:transparent;box-shadow:none;border:2px solid rgb(194,9,65);color:#fffc}button.btn-wire-danger-alt i.btn-match,.btn.btn-wire-danger-alt i.btn-match{color:#c20941}button.btn-wire-danger-alt:hover,.btn.btn-wire-danger-alt:hover{background:#c209410d;border-color:#910731;color:#910731;box-shadow:none}button.btn-wire-danger-alt:focus,.btn.btn-wire-danger-alt:focus{border-color:#610420;background:transparent}button.btn-purple,.btn.btn-purple{background:#bc48ff;box-shadow:0 2px #8f00e1}button.btn-purple:hover,.btn.btn-purple:hover{box-shadow:0 2px 0 1px #8f00e1 inset}button.btn-purple:focus,.btn.btn-purple:focus{background:#8f00e1}button.btn-wire-purple,.btn.btn-wire-purple{background:transparent;box-shadow:none;border:2px solid rgb(188,72,255);color:#fffc}button.btn-wire-purple i.btn-match,.btn.btn-wire-purple i.btn-match{color:#bc48ff}button.btn-wire-purple:hover,.btn.btn-wire-purple:hover{background:#bc48ff0d;border-color:#a915ff;color:#a915ff;box-shadow:none}button.btn-wire-purple:focus,.btn.btn-wire-purple:focus{border-color:#8f00e1;background:transparent}button.btn-purple-alt,.btn.btn-purple-alt{background:#692fbd;box-shadow:0 2px #3c1b6b}button.btn-purple-alt:hover,.btn.btn-purple-alt:hover{box-shadow:0 2px 0 1px #3c1b6b inset}button.btn-purple-alt:focus,.btn.btn-purple-alt:focus{background:#3c1b6b}button.btn-wire-purple-alt,.btn.btn-wire-purple-alt{background:transparent;box-shadow:none;border:2px solid rgb(105,47,189);color:#fffc}button.btn-wire-purple-alt i.btn-match,.btn.btn-wire-purple-alt i.btn-match{color:#692fbd}button.btn-wire-purple-alt:hover,.btn.btn-wire-purple-alt:hover{background:#692fbd0d;border-color:#522594;color:#522594;box-shadow:none}button.btn-wire-purple-alt:focus,.btn.btn-wire-purple-alt:focus{border-color:#3c1b6b;background:transparent}button.btn-neutral,.btn.btn-neutral{background:#464646;box-shadow:0 2px #131313}button.btn-neutral:hover,.btn.btn-neutral:hover{box-shadow:0 2px 0 1px #131313 inset}button.btn-wire-neutral,.btn.btn-wire-neutral{background:transparent;box-shadow:none;border:2px solid rgb(70,70,70);color:#fffc}button.btn-wire-neutral i.btn-match,.btn.btn-wire-neutral i.btn-match{color:#464646}button.btn-wire-neutral:hover,.btn.btn-wire-neutral:hover{background:#4646460d;border-color:#2d2d2d;color:#2d2d2d;box-shadow:none}button.btn-wire-neutral:focus,.btn.btn-wire-neutral:focus{border-color:#131313;background:transparent}button.btn-yellow,.btn.btn-yellow{background:#e5a123;box-shadow:0 2px #916411}button.btn-yellow:hover,.btn.btn-yellow:hover{box-shadow:0 2px 0 1px #916411 inset}button.btn-yellow:focus,.btn.btn-yellow:focus{background:#916411}button.btn-wire-yellow,.btn.btn-wire-yellow{background:transparent;box-shadow:none;border:2px solid rgb(229,161,35);color:#fffc}button.btn-wire-yellow i.btn-match,.btn.btn-wire-yellow i.btn-match{color:#e5a123}button.btn-wire-yellow:hover,.btn.btn-wire-yellow:hover{background:#e5a1230d;border-color:#be8417;color:#be8417;box-shadow:none}button.btn-wire-yellow:focus,.btn.btn-wire-yellow:focus{border-color:#916411;background:transparent}button.btn-white,.btn.btn-white{background:#fff;box-shadow:0 2px #ccc}button.btn-white:hover,.btn.btn-white:hover{box-shadow:0 2px 0 1px #ccc inset}button.btn-white:focus,.btn.btn-white:focus{background:#ccc}button.btn-wire-white,.btn.btn-wire-white{background:transparent;box-shadow:none;border:2px solid rgb(255,255,255);color:#fffc}button.btn-wire-white i.btn-match,.btn.btn-wire-white i.btn-match{color:#fff}button.btn-wire-white:hover,.btn.btn-wire-white:hover{background:#ffffff0d;border-color:#e6e6e6;color:#e6e6e6;box-shadow:none}button.btn-wire-white:focus,.btn.btn-wire-white:focus{border-color:#ccc;background:transparent}button.btn-black,.btn.btn-black{background:#000;box-shadow:0 2px #000}button.btn-black:hover,.btn.btn-black:hover{box-shadow:0 2px 0 1px #000 inset}button.btn-black:focus,.btn.btn-black:focus{background:#000}button.btn-wire-black,.btn.btn-wire-black{background:transparent;box-shadow:none;border:2px solid rgb(0,0,0);color:#fffc}button.btn-wire-black i.btn-match,.btn.btn-wire-black i.btn-match{color:#000}button.btn-wire-black:hover,.btn.btn-wire-black:hover{background:#0000000d;border-color:#000;color:#000;box-shadow:none}button.btn-wire-black:focus,.btn.btn-wire-black:focus{border-color:#000;background:transparent}button.btn-youtube,.btn.btn-youtube{background:#fd3c01;box-shadow:0 2px #972401}button.btn-youtube:hover,.btn.btn-youtube:hover{box-shadow:0 2px 0 1px #972401 inset}button.btn-youtube:focus,.btn.btn-youtube:focus{background:#972401}button.btn-wire-youtube,.btn.btn-wire-youtube{background:transparent;box-shadow:none;border:2px solid rgb(253,60,1);color:#fffc}button.btn-wire-youtube i.btn-match,.btn.btn-wire-youtube i.btn-match{color:#fd3c01}button.btn-wire-youtube:hover,.btn.btn-wire-youtube:hover{background:#fd3c010d;border-color:#ca3001;color:#ca3001;box-shadow:none}button.btn-wire-youtube:focus,.btn.btn-wire-youtube:focus{border-color:#972401;background:transparent}button.btn-raspbian,.btn.btn-raspbian{background:#b61240;box-shadow:0 2px #59091f}button.btn-raspbian:hover,.btn.btn-raspbian:hover{box-shadow:0 2px 0 1px #59091f inset}button.btn-raspbian:focus,.btn.btn-raspbian:focus{background:#59091f}button.btn-wire-raspbian,.btn.btn-wire-raspbian{background:transparent;box-shadow:none;border:2px solid rgb(182,18,64);color:#fffc}button.btn-wire-raspbian i.btn-match,.btn.btn-wire-raspbian i.btn-match{color:#b61240}button.btn-wire-raspbian:hover,.btn.btn-wire-raspbian:hover{background:#b612400d;border-color:#880d30;color:#880d30;box-shadow:none}button.btn-wire-raspbian:focus,.btn.btn-wire-raspbian:focus{border-color:#59091f;background:transparent}button.btn-windows,.btn.btn-windows{background:#12a7e3;box-shadow:0 2px #0b6184}button.btn-windows:hover,.btn.btn-windows:hover{box-shadow:0 2px 0 1px #0b6184 inset}button.btn-windows:focus,.btn.btn-windows:focus{background:#0b6184}button.btn-wire-windows,.btn.btn-wire-windows{background:transparent;box-shadow:none;border:2px solid rgb(18,167,227);color:#fffc}button.btn-wire-windows i.btn-match,.btn.btn-wire-windows i.btn-match{color:#12a7e3}button.btn-wire-windows:hover,.btn.btn-wire-windows:hover{background:#12a7e30d;border-color:#0e84b4;color:#0e84b4;box-shadow:none}button.btn-wire-windows:focus,.btn.btn-wire-windows:focus{border-color:#0b6184;background:transparent}button.btn-macos,.btn.btn-macos{background:#b3bcc2;box-shadow:0 2px #7a8a95}button.btn-macos:hover,.btn.btn-macos:hover{box-shadow:0 2px 0 1px #7a8a95 inset}button.btn-macos:focus,.btn.btn-macos:focus{background:#7a8a95}button.btn-wire-macos,.btn.btn-wire-macos{background:transparent;box-shadow:none;border:2px solid rgb(179,188,194);color:#fffc}button.btn-wire-macos i.btn-match,.btn.btn-wire-macos i.btn-match{color:#b3bcc2}button.btn-wire-macos:hover,.btn.btn-wire-macos:hover{background:#b3bcc20d;border-color:#97a3ab;color:#97a3ab;box-shadow:none}button.btn-wire-macos:focus,.btn.btn-wire-macos:focus{border-color:#7a8a95;background:transparent}button.btn-debian,.btn.btn-debian{background:#cf084e;box-shadow:0 2px #6d0429}button.btn-debian:hover,.btn.btn-debian:hover{box-shadow:0 2px 0 1px #6d0429 inset}button.btn-debian:focus,.btn.btn-debian:focus{background:#6d0429}button.btn-wire-debian,.btn.btn-wire-debian{background:transparent;box-shadow:none;border:2px solid rgb(207,8,78);color:#fffc}button.btn-wire-debian i.btn-match,.btn.btn-wire-debian i.btn-match{color:#cf084e}button.btn-wire-debian:hover,.btn.btn-wire-debian:hover{background:#cf084e0d;border-color:#9e063b;color:#9e063b;box-shadow:none}button.btn-wire-debian:focus,.btn.btn-wire-debian:focus{border-color:#6d0429;background:transparent}button.btn-fedora,.btn.btn-fedora{background:#52a2da;box-shadow:0 2px #236ea3}button.btn-fedora:hover,.btn.btn-fedora:hover{box-shadow:0 2px 0 1px #236ea3 inset}button.btn-fedora:focus,.btn.btn-fedora:focus{background:#236ea3}button.btn-wire-fedora,.btn.btn-wire-fedora{background:transparent;box-shadow:none;border:2px solid rgb(82,162,218);color:#fffc}button.btn-wire-fedora i.btn-match,.btn.btn-wire-fedora i.btn-match{color:#52a2da}button.btn-wire-fedora:hover,.btn.btn-wire-fedora:hover{background:#52a2da0d;border-color:#2c8bcd;color:#2c8bcd;box-shadow:none}button.btn-wire-fedora:focus,.btn.btn-wire-fedora:focus{border-color:#236ea3;background:transparent}button.btn-ubuntu,.btn.btn-ubuntu{background:#d64514;box-shadow:0 2px #79270b}button.btn-ubuntu:hover,.btn.btn-ubuntu:hover{box-shadow:0 2px 0 1px #79270b inset}button.btn-ubuntu:focus,.btn.btn-ubuntu:focus{background:#79270b}button.btn-wire-ubuntu,.btn.btn-wire-ubuntu{background:transparent;box-shadow:none;border:2px solid rgb(214,69,20);color:#fffc}button.btn-wire-ubuntu i.btn-match,.btn.btn-wire-ubuntu i.btn-match{color:#d64514}button.btn-wire-ubuntu:hover,.btn.btn-wire-ubuntu:hover{background:#d645140d;border-color:#a73610;color:#a73610;box-shadow:none}button.btn-wire-ubuntu:focus,.btn.btn-wire-ubuntu:focus{border-color:#79270b;background:transparent}button.btn-suse,.btn.btn-suse{background:#6fb425;box-shadow:0 2px #3b5f14}button.btn-suse:hover,.btn.btn-suse:hover{box-shadow:0 2px 0 1px #3b5f14 inset}button.btn-suse:focus,.btn.btn-suse:focus{background:#3b5f14}button.btn-wire-suse,.btn.btn-wire-suse{background:transparent;box-shadow:none;border:2px solid rgb(111,180,37);color:#fffc}button.btn-wire-suse i.btn-match,.btn.btn-wire-suse i.btn-match{color:#6fb425}button.btn-wire-suse:hover,.btn.btn-wire-suse:hover{background:#6fb4250d;border-color:#558a1c;color:#558a1c;box-shadow:none}button.btn-wire-suse:focus,.btn.btn-wire-suse:focus{border-color:#3b5f14;background:transparent}button.btn-redhat,.btn.btn-redhat{background:#c60200;box-shadow:0 2px #600100}button.btn-redhat:hover,.btn.btn-redhat:hover{box-shadow:0 2px 0 1px #600100 inset}button.btn-redhat:focus,.btn.btn-redhat:focus{background:#600100}button.btn-wire-redhat,.btn.btn-wire-redhat{background:transparent;box-shadow:none;border:2px solid rgb(198,2,0);color:#fffc}button.btn-wire-redhat i.btn-match,.btn.btn-wire-redhat i.btn-match{color:#c60200}button.btn-wire-redhat:hover,.btn.btn-wire-redhat:hover{background:#c602000d;border-color:#930100;color:#930100;box-shadow:none}button.btn-wire-redhat:focus,.btn.btn-wire-redhat:focus{border-color:#600100;background:transparent}button.btn-centos,.btn.btn-centos{background:#9b4c88;box-shadow:0 2px #572a4c}button.btn-centos:hover,.btn.btn-centos:hover{box-shadow:0 2px 0 1px #572a4c inset}button.btn-centos:focus,.btn.btn-centos:focus{background:#572a4c}button.btn-wire-centos,.btn.btn-wire-centos{background:transparent;box-shadow:none;border:2px solid rgb(155,76,136);color:#fffc}button.btn-wire-centos i.btn-match,.btn.btn-wire-centos i.btn-match{color:#9b4c88}button.btn-wire-centos:hover,.btn.btn-wire-centos:hover{background:#9b4c880d;border-color:#793b6a;color:#793b6a;box-shadow:none}button.btn-wire-centos:focus,.btn.btn-wire-centos:focus{border-color:#572a4c;background:transparent}button.btn-other,.btn.btn-other{background:#e5a123;box-shadow:0 2px #916411}button.btn-other:hover,.btn.btn-other:hover{box-shadow:0 2px 0 1px #916411 inset}button.btn-other:focus,.btn.btn-other:focus{background:#916411}button.btn-wire-other,.btn.btn-wire-other{background:transparent;box-shadow:none;border:2px solid rgb(229,161,35);color:#fffc}button.btn-wire-other i.btn-match,.btn.btn-wire-other i.btn-match{color:#e5a123}button.btn-wire-other:hover,.btn.btn-wire-other:hover{background:#e5a1230d;border-color:#be8417;color:#be8417;box-shadow:none}button.btn-wire-other:focus,.btn.btn-wire-other:focus{border-color:#916411;background:transparent}@font-face{font-family:Sixtyfour;src:url(../../webfonts/Sixtyfour-Regular.ttf) format("truetype")}*{font-family:Roboto,Arial,"sans-serif";margin:0;padding:0;box-sizing:border-box}html{background-color:#111}body,html{height:100%;font-family:Arial,sans-serif}.container{display:flex;height:100vh}.horizontal{display:flex;flex-direction:row;justify-content:flex-start;align-items:flex-start;flex:1;align-self:stretch}.vertical{display:flex;flex-direction:column;justify-content:flex-start;align-items:flex-start;flex:1;align-self:stretch}main{flex:1;display:flex;flex-direction:column}main .main-container{display:flex;flex-direction:column;flex:1;overflow:hidden;align-self:stretch}main .main-container .top-content{display:flex;flex-direction:row;justify-content:flex-start;align-items:center;align-self:stretch;padding:10px 10px 10px 20px;background:transparent;border-bottom:1px solid #222}main .main-container .top-content h1{color:#fff;font-weight:600;font-size:24px}main .main-container .top-content .top-actions{flex:1;display:flex;flex-direction:row;justify-content:flex-end;align-items:center}main .main-container .top-content .top-actions .btn,main .main-container .top-content .top-actions button{margin-left:10px}main .main-container .bottom-content{display:flex;flex-direction:row;align-self:stretch;justify-content:flex-start;align-items:flex-start;flex:1;overflow-y:auto;background:radial-gradient(circle at 0% 53%,rgba(239,14,93,.8) 10%,transparent 45%),radial-gradient(circle at 135% 53%,rgba(2,123,255,.8) 10%,transparent 95%),radial-gradient(circle at 50% 80%,rgba(14,239,95,.8) 40%,transparent 95%)}main .main-container .bottom-content .page-content{flex:2;overflow-y:auto;align-self:stretch;display:flex;flex-direction:column;justify-content:flex-start;align-items:flex-start;background:#000c;padding:5px}main .main-container .bottom-content .page-content .inner{flex:1;display:flex;flex-direction:column;justify-content:flex-start;align-items:flex-start;padding:0 10px 40px;background:#111;align-self:stretch}main .main-container .bottom-content .page-panel{flex:1;overflow-y:auto;align-self:stretch;background:#111;border-top:none}main .main-container .bottom-content .page-panel.left-panel{border-right:1px solid #222;border-left:none}main .main-container .bottom-content .page-panel.left-panel.explr-explorer{flex:.5;overflow-y:auto;padding:0;background:#111;box-shadow:1px 1px .5px .5px inset #0003;max-width:250px}main .main-container .bottom-content .page-panel.right-panel{border-left:1px solid #222;border-right:none}.invisible{visibility:hidden!important}.hidden{display:none!important}.tac{text-align:center!important}.tar{text-align:right!important}a{text-decoration:none}.normal{font-weight:400!important}.bold{font-weight:700!important}.col{display:flex;flex:1;flex-direction:column;align-self:stretch}main .context-bar{padding:10px;position:sticky;top:0;z-index:1000;max-height:80px;border-bottom:1px solid #222;display:flex;flex-direction:row;align-items:center}main .context-bar .context-menu{flex:1}main .context-bar .context-menu .inner{display:flex}main .context-bar .context-menu .inner ul.pills{margin:0}main .context-bar .context-divider{width:1px;height:100%;background:#222;margin-left:20px;margin-right:20px}main .context-bar .context-user{display:flex;margin-right:20px}main .context-bar .context-user .trigger{color:#fff}main .context-bar .context-user .trigger .avatar{width:32px;height:32px;border-radius:4px;background:#027bff;margin-right:10px;display:flex;flex-direction:row;justify-content:center;align-items:center;text-align:center;font-weight:700;font-size:14px;border:1px solid #444}main .context-bar .context-user .trigger i{margin-top:-5px;margin-left:10px}menu{width:300px;background:#111;overflow-y:auto;overflow-x:visible;padding:20px;z-index:2000;display:flex;flex-direction:column;justify-content:flex-start;align-items:flex-start;border-right:1px solid #222;min-width:64px}menu h1.logo{margin:40px 0 0 10px;align-self:stretch;display:flex}menu h1.logo a{text-align:center;text-shadow:0px 0 0 #fff,0px 2px 0 #444,0 0px 0 rgb(14,239,95),-0px 0 0 rgb(2,123,255),0 -0px 0 rgb(239,14,93);text-decoration:none;background:linear-gradient(90deg,#a0a0a0 0,#bebebe 46%,#dcdcdc);-webkit-background-clip:text;color:transparent;flex:1;font-family:Sixtyfour,Work Sans,Arial,"sans-serif";align-self:stretch;padding-right:3px;font-size:20px;text-transform:uppercase;transition:all .55s cubic-bezier(.19,1,.22,1);display:flex;flex-direction:row;justify-content:center;align-items:center;position:relative}menu h1.logo a img{flex-shrink:0;width:30px;margin-right:10px;position:absolute;left:5px;transition:all .55s cubic-bezier(.19,1,.22,1)}menu h1.logo a img.after{opacity:0}menu:hover h1.logo a{text-align:center;text-shadow:3px 0 0 #fff,3px 2px 0 #444,0 3px 0 rgb(14,239,95),-3px 0 0 rgb(2,123,255),0 -3px 0 rgb(239,14,93);text-decoration:none;background:linear-gradient(90deg,#a0a0a0 0,#bebebe 46%,#dcdcdc);-webkit-background-clip:text;color:transparent}menu:hover h1.logo a img.before{opacity:0}menu:hover h1.logo a img.after{animation-duration:.2s;animation-name:logotouch}menu nav{display:flex;align-self:stretch;flex:1}menu nav ul{margin:60px 0 20px;flex:1;align-self:flex-start;display:flex;flex-direction:column;list-style:none}menu nav ul li{align-self:stretch;overflow:hidden;position:relative;transition:all .55s cubic-bezier(.19,1,.22,1);margin:10px 0;border-radius:4px}menu nav ul li a{color:#ffffffe6;font-size:16px;display:flex;flex-direction:row;justify-content:flex-start;align-items:center;align-self:stretch;flex:1;padding-top:5px;padding-bottom:5px;padding-left:10px}menu nav ul li a i{color:#fff;opacity:.2;background:transparent;display:flex;justify-content:center;align-items:center;align-self:stretch;padding:10px;width:40px;border-radius:4px;text-align:center;margin-right:20px}menu nav ul li:after{background:#fff;content:"";height:195px;left:-200px;opacity:.2;position:absolute;top:-50px;transform:rotate(35deg);transition:all .55s cubic-bezier(.19,1,.22,1);width:50px;z-index:-2;cursor:pointer}menu nav ul li.active a{color:#027bff;font-weight:700}menu nav ul li.active a i{opacity:1;background:#ffffffe6;background:#017bff}menu nav ul li:hover{background:#027bff}menu nav ul li:hover:after{z-index:2;left:120%;transition:all .55s cubic-bezier(.19,1,.22,1)}menu nav ul li:hover a{color:#fff;font-weight:700}menu nav ul li:hover a i{color:#fff;opacity:1}menu footer{background:#ffffff03;padding:20px 0;display:flex;flex-direction:row;align-self:stretch;text-align:center;justify-content:center}menu footer p{color:#444}menu footer p.version a{color:#777;font-weight:700}.dropdown{position:relative;display:flex;align-self:stretch}.dropdown.dropdown-show ul.dropdown-menu{display:flex;flex-direction:column}.dropdown .trigger{cursor:pointer;display:flex;flex-direction:row;justify-content:flex-start;align-items:center;align-self:stretch;flex:1}.dropdown ul.dropdown-menu{position:absolute;top:100%;left:0;display:none;background-color:#222;box-shadow:0 8px 16px #0003;z-index:1000;list-style-type:none;margin:0;overflow:hidden;border-radius:4px}.dropdown ul.dropdown-menu li{padding:8px 16px;cursor:pointer;display:flex;flex-direction:row;justify-content:flex-start;align-items:center;transition:all .55s cubic-bezier(.19,1,.22,1)}.dropdown ul.dropdown-menu li.danger:hover{background-color:#ef0e5d}.dropdown ul.dropdown-menu li:hover{background-color:#027bff}.dropdown ul.dropdown-menu li a{padding:8px 16px 8px 8px;color:#fff;display:flex;flex-direction:row;justify-content:flex-start;align-items:center;align-self:stretch}.dropdown ul.dropdown-menu li a i{margin-right:15px}@keyframes logotouch{0%{opacity:0}50%{opacity:1}to{opacity:0;left:27px}}button,.btn{position:relative;padding:10px 10px 8px;font-size:14px;color:#fff;cursor:pointer;border:none;border-radius:4px;background:#027bff;box-shadow:0 2px #004a9b;font-weight:700;letter-spacing:-.5px;margin-top:-2px}button i.icon-left,.btn i.icon-left{margin-right:5px}button:hover,.btn:hover{box-shadow:0 2px 0 1px #004a9b inset;color:#fffc}button:focus,.btn:focus{background:#004a9b;color:#ffffff80;box-shadow:none}button.btn-neutral,.btn.btn-neutral{color:#aaa;background:#464646;box-shadow:0 2px #2d2d2d}button.btn-neutral:hover,.btn.btn-neutral:hover{box-shadow:0 2px 0 1px #222 inset;background:#2d2d2d}button.btn-neutral:focus,.btn.btn-neutral:focus{background:#131313}button .btn-wire-neutral,.btn .btn-wire-neutral{background:transparent;border:2px solid rgb(70,70,70);color:#fffc;box-shadow:none}button .btn-wire-neutral:hover,.btn .btn-wire-neutral:hover{background:#4646460d;border-color:#2d2d2d;color:#2d2d2d;box-shadow:none}button .btn-wire-neutral:focus,.btn .btn-wire-neutral:focus{border-color:#131313;background:transparent}button.btn-naked,.btn.btn-naked{background:transparent;box-shadow:none}button.btn-naked:hover,.btn.btn-naked:hover{box-shadow:0 2px 0 1px #222 inset;background:#2d2d2d}button.btn-naked:focus,.btn.btn-naked:focus{background:#131313}.alert{padding:20px;align-self:stretch;display:flex;flex-direction:row;justify-content:center;align-items:center;border-radius:4px}.alert a{color:inherit;margin-left:4px;margin-right:4px;text-decoration:underline}.alert-info{color:#027bff;background:#027bff33}.alert-success{color:#0eef5f;background:#0eef5f33}.alert-danger,.alert-error{color:#ef0e5d;background:#ef0e5d33}.alert i{margin-right:13px}ul.explr-tree{height:100%!important}ul.explr-tree li span{color:#555;font-size:13px;padding-left:5px;cursor:pointer}ul.explr-tree li span.explr-plus,ul.explr-tree li span.explr-minus{z-index:1}ul.explr-tree li span.explr-plus:hover,ul.explr-tree li span.explr-minus:hover{color:#aaa}ul.explr-tree li a{color:#fff;padding-right:80px}ul.explr-tree li a:hover{color:#fff}ul.explr-tree li a.active{background:#ffffff1a;border-radius:4px;font-weight:700;text-decoration:underline;margin-left:35px;padding-left:5px;margin-right:10px}.explr-selection-actions{display:none;margin-right:10px;border-right:1px solid #222;padding-right:20px}.explr-selection-actions button{display:none}body.explr-selection-actionable .explr-selection-actions,body.explr-selection-actionable.explr-selection-folder .explr-selection-actions button.explr-selection-folder,body.explr-selection-actionable.explr-selection-entity .explr-selection-actions button.explr-selection-entity{display:flex}ul.explr-dirview{display:flex;flex-direction:row;flex-wrap:wrap}ul.explr-dirview li{display:flex;flex-direction:column;justify-content:flex-start;align-items:center;flex-shrink:0;margin:18px;min-width:90px;min-height:104px;padding-top:5px;border:1px solid transparent;border-radius:4px}ul.explr-dirview li.renaming a span{display:none}ul.explr-dirview li.renaming a form{display:block}ul.explr-dirview li.highlight-drop{border:1px dotted rgba(2,123,255,.4);background:#027bff4d}ul.explr-dirview li.highlight-clicked{border:1px dotted rgba(255,255,255,.2);background:#ffffff1a}ul.explr-dirview li a{color:#bbb;text-decoration:none;flex:1;text-align:center;font-size:12px;display:flex;flex-direction:column;justify-content:flex-start;align-items:center;max-width:84px}ul.explr-dirview li a i{font-size:64px;margin-bottom:12px;border-radius:8px}ul.explr-dirview li a input{width:100%;padding:0 3px}ul.explr-dirview li a input:focus{outline:none}ul.explr-dirview li a:hover{opacity:.8}ul.explr-dirview li a form{display:none}ul.explr-dirview li.new-folder a{color:#027bff}ul.explr-dirview li.new-folder a form{display:block}ul.explr-dirview .ui-draggable-dragging{z-index:20}ul.explr-dirview .ui-draggable-dragging a{opacity:1!important}ul.pills{background:#222;padding:6px 4px 5px;box-shadow:1px 1px .5px .5px inset #0003;border:1px solid #222;border-radius:4px;display:flex;flex-direction:row;justify-content:flex-start;align-items:center;list-style:none;margin:0}ul.pills li.divider{margin:0 20px;width:1px;height:100%;background:#333}ul.pills li:hover a{opacity:.9}ul.pills li a{border-radius:4px;display:flex;flex-direction:row;justify-content:center;align-items:center;color:#fff;overflow:hidden;padding-right:30px;text-align:center;background:#0003;margin-right:5px;transition:all .25s cubic-bezier(.19,1,.22,1)}ul.pills li a span{display:flex;justify-content:center;align-items:center;margin-right:20px;height:42px;background:#0003;width:42px}ul.pills li.active a{color:#333;background:#fff;font-weight:700}ul.pills li:hover a{color:#fff;background:#027bff}ul.pills li:last-child a{margin-right:0}.breadcrumb-container{display:flex;flex-direction:row;justify-content:flex-start;align-items:center;align-self:stretch;border-bottom:1px solid #222;background:transparent;padding:10px}.breadcrumb-container ul.breadcrumb{background:#222;padding:6px 4px 5px;box-shadow:1px 1px .5px .5px inset #0003;border:1px solid #222;border-radius:4px;display:flex;flex-direction:row;justify-content:flex-start;align-items:center;list-style:none;margin:0}.breadcrumb-container ul.breadcrumb li.divider{margin:0 5px}.breadcrumb-container ul.breadcrumb li.divider i{color:#aaa}.breadcrumb-container ul.breadcrumb li span,.breadcrumb-container ul.breadcrumb li a{border-radius:4px;display:flex;flex-direction:row;justify-content:center;align-items:center;color:#fff;text-align:center;padding:0 3px}.breadcrumb-container ul.breadcrumb li span i,.breadcrumb-container ul.breadcrumb li a i{margin-right:5px}.breadcrumb-container ul.breadcrumb li:hover a{color:#fff;background:#027bff}.breadcrumb-container ul.breadcrumb li:last-child a{margin-right:0}.modals{position:fixed;background:#0006;top:0;right:0;bottom:0;left:0;display:flex;flex-direction:column;justify-content:center;align-items:center;z-index:10000}.modals .modals-outer{min-width:464px;display:flex;flex-direction:column;overflow:auto;padding-bottom:2px}.modals .modals-outer .modals-inner{background:#111;border-radius:10px;color:#333;padding:40px;box-shadow:0 2px #222;border:1px solid #222}.modals .modals-outer .modals-inner .modal h2{padding:0;margin:0 0 30px;font-weight:400;color:#999}.modals .modals-outer .modals-inner .modal h3{align-self:stretch;margin:0;font-size:14px;display:flex;flex-direction:row;justify-content:flex-start;align-items:center;color:#fff;padding-bottom:10px;text-decoration:none}.modals .modals-outer .modals-inner .modal h3.divide{border-top:1px solid #222;margin-top:20px;padding-top:20px}table.panes{flex:1;display:flex;flex-direction:column;justify-content:flex-start;align-items:flex-start;align-self:stretch}table.panes tbody{display:flex;flex-direction:column;justify-content:flex-start;align-items:flex-start;align-self:stretch;margin:1px 1px 28px;background:#111;border-radius:4px;border:4px solid rgba(255,255,255,.05)}table.panes tbody:hover,table.panes tbody:hover tr.title-item{border-color:#027bff0d}table.panes tbody tr{flex:1;display:flex;flex-direction:row;justify-content:flex-start;align-items:center;align-self:stretch;padding:8px 18px;background:#222}table.panes tbody tr:nth-child(odd){background-color:#111}table.panes tbody tr:nth-child(odd) td.description{color:#ffffffb3}table.panes tbody tr:nth-child(2n){background-color:#141414}table.panes tbody tr td{color:#888;display:flex;flex-direction:row;justify-content:flex-start;align-items:center;flex:1;font-size:14px}table.panes tbody tr td.vertical{display:flex;flex-direction:column;justify-content:flex-start;align-items:flex-start}table.panes tbody tr td.description{align-self:stretch}table.panes tbody tr td.value{flex:0;margin-left:20px;word-break:break-all;flex-basis:auto}table.panes tbody tr td.value i.icon-legend{font-size:10px;margin-right:10px}table.panes tbody tr td.value i.icon-value{padding:2px 2px 1px;border-radius:2px;width:16px;text-align:center}table.panes tbody tr.title-item{border-bottom:1px solid #222}table.panes tbody tr.title-item td{color:#027bffe6;font-size:16px;font-weight:700}table.panes tbody tr.title-item td i{margin-right:10px}table.panes tbody tr.title-item td .more{flex:1;text-align:right;font-size:12px;color:#888;font-weight:400;font-style:italic}table.panes tbody tr.variable-item{cursor:pointer}table.panes tbody tr.variable-item:hover{background-color:#027bff0d}table.panes tbody tr.variable-item:hover td{font-weight:700;color:#fff}table.panes tbody tr.variable-item:hover td i.icon-legend{color:#fff}table.panes tbody tr.variable-item:hover td span,table.panes tbody tr.variable-item:hover td i.icon-value{background-color:#ffffff4d;color:#fff}table.panes tbody tr.variable-item:hover td.description{color:#027bff}.tiles{flex:1;display:flex;flex-direction:row;justify-content:flex-start;align-items:flex-start;align-self:stretch}.tiles .tiles-inner{display:flex;flex:1;flex-direction:column;flex-wrap:nowrap;justify-content:flex-start;align-items:flex-start;align-self:stretch;padding:2px}.tiles .tiles-inner .tile-item{display:flex;flex-direction:row;justify-content:flex-start;align-items:center;background:#222;align-self:stretch;color:#fff;margin:1px;padding:15px}.tiles .tiles-inner .tile-item:hover,.tiles .tiles-inner .tile-item.active{background:#111}.tiles .tiles-inner .tile-item:hover:hover,.tiles .tiles-inner .tile-item.active:hover{opacity:1}.tiles .tiles-inner .tile-item.disabled .tile-header .head-icon i{color:#222}.tiles .tiles-inner .tile-item .tile-header{display:flex;flex-direction:row;justify-content:flex-start;align-items:center;align-self:stretch}.tiles .tiles-inner .tile-item .tile-header .head-icon{flex:1}.tiles .tiles-inner .tile-item .tile-header .head-icon i{font-size:6px;color:#fff;opacity:.8;display:flex}.tiles .tiles-inner .tile-item .tile-header .status-icons{display:flex;flex-direction:row;justify-content:flex-end;align-items:center}.tiles .tiles-inner .tile-item .tile-header .status-icons i{font-size:16px;margin-left:10px}.tiles .tiles-inner .tile-item .tile-body{flex:1;display:flex;flex-direction:row;justify-content:flex-start;align-items:center;font-size:15px;font-weight:400;letter-spacing:.8px;line-height:22px;margin:0 0 0 10px;flex-wrap:nowrap}.tiles .tiles-inner .tile-item .tile-footer{display:flex;flex-direction:row;justify-content:flex-end;align-items:center;margin:0}.tiles .tiles-inner .tile-item .tile-footer .foot-span{opacity:.8;font-size:13px;font-family:Courier New}span.empty{background:#e5a1234d;color:#e5a123;text-transform:lowercase;border-radius:2px;padding:2px 4px;font-weight:700}.inner-empty{display:flex;flex:1;align-self:stretch;justify-content:center;align-items:center}.inner-empty i{font-size:90px;opacity:.3;text-shadow:0 -1px #333,0 0px .5px #444}.toggle{position:relative;display:flex;flex-direction:row;justify-content:flex-start;align-items:center}.toggle input{display:none}.toggle input:checked+label{background:#065e26;border:1px solid rgba(255,255,255,.1);box-shadow:0 2px 2px #222 inset}.toggle input:checked+label:after{content:"";display:block;border-radius:50%;margin-left:21px;width:18px;height:18px;transition:.2s;background:#0eef5f;box-shadow:0 2px #032e12}.toggle label{width:44px;height:26px;border-radius:15px;background:#222;cursor:pointer;border:1px solid rgba(255,255,255,.1);box-shadow:0 2px 2px #111 inset}.toggle label:after{content:"";display:block;border-radius:50%;width:18px;height:18px;margin:3px;background:#777;box-shadow:0 2px #000000e6;transition:.2s}.form-holder{display:flex;flex-direction:column;justify-content:flex-start;align-items:flex-start;align-self:stretch;flex:1}.form-holder form{max-width:434px}form{display:flex;flex-direction:column;justify-content:flex-start;align-items:flex-start;align-self:stretch}form .alert{padding:8px 15px;font-size:14px;margin:0 0 25px}.form-group{display:flex;flex-direction:column;justify-content:flex-start;align-items:flex-start;align-self:stretch;width:100%;flex:1;margin-bottom:20px}.form-group label{flex:1;font-size:12px;display:flex;flex-direction:row;justify-content:flex-start;align-items:center;align-self:stretch;color:#666}.form-group label.btn-upload{color:#fff;font-size:14px;flex:0;flex-basis:auto;margin-top:5px}.form-group label.btn-upload input[type=file]{display:none}.form-group label.btn-upload input[type=text]{margin-bottom:2px;padding-left:0;margin-left:10px}.form-group label.btn-upload i{margin-left:3px;margin-right:10px}.form-group .widget{margin-top:10px;align-self:stretch;display:flex;flex-direction:row}.form-group .widget div{color:#ffffffb3;font-size:14px}.form-group .widget select,.form-group .widget input,.form-group .widget textarea{outline:none;padding:8px 0 5px 8px;border-radius:2px;border:1px solid rgba(255,255,255,.05);flex:1;background:#555;box-shadow:0 2px 1px #444,0 4px 2px #333 inset;color:#ddd;font-size:14px}.form-group .widget select[disabled],.form-group .widget input[disabled],.form-group .widget textarea[disabled]{color:#555;background:none;box-shadow:none;border:none;border-bottom:1px solid #333;border-radius:0}.form-group.tab-select{border-bottom:1px solid #444;display:flex;flex-direction:row;position:relative;height:48px;padding:48px 0 0;flex:0;flex-basis:auto}.form-group.tab-select .widget{height:49px;margin-top:0;display:flex;flex-direction:row;justify-content:flex-start;align-items:center;position:absolute;top:0;left:0;border-bottom:2px solid rgb(2,123,255);color:#027bff}.form-group.tab-select .widget select{border:none;background:none;box-shadow:none;padding:10px 35px 10px 10px;margin:0;color:inherit;appearance:none;-moz-appearance:none;-webkit-appearance:none;text-align:left;font-weight:700;cursor:pointer;border-radius:4px 4px 0 0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:200px;z-index:2}.form-group.tab-select .widget i{margin-left:10px;margin-right:0}.form-group.tab-select .widget i.triangle{margin-top:-4px;margin-left:0;position:absolute;right:10px}.form-group.form-group-horizontal{margin:10px 0 20px;flex-direction:row;justify-content:flex-start;align-items:center}.form-group.form-group-horizontal .widget{margin:0;display:flex;flex-direction:row;justify-content:flex-start;align-items:center}.actions{display:flex;flex-direction:row;justify-content:flex-end;align-items:center;align-self:stretch;margin:20px 0 0}.actions button{margin-left:25px}.actions.actions-left{justify-content:flex-start}.actions.actions-left button{margin-left:0;margin-right:25px}.actions.actions-center{justify-content:center}.actions.actions-center button{margin-left:0;margin-right:0}.view-content-list main .main-container .content-object-input{margin-bottom:6px}.view-content-edit main .main-container .bottom-content .page-content{flex:1}.view-content-edit main .main-container .bottom-content .page-content .form-holder{margin:20px 20px 20px 10px}.view-content-edit main .main-container .bottom-content .page-panel.right-panel{flex:2;align-self:stretch;display:flex;flex-direction:column;overflow:hidden;justify-content:flex-start;align-items:center;padding:20px}.view-content-edit main .main-container .bottom-content .page-panel.right-panel h3{color:#fff;padding:10px 10px 10px 0;margin-bottom:20px;font-size:16px;align-self:stretch;margin-left:-8px}.view-content-edit main .main-container .bottom-content .page-panel.right-panel h3 span{border-width:1px;border-style:solid;border-radius:4px;padding:4px 10px;margin-left:5px}.view-content-edit main .main-container .bottom-content .page-panel.right-panel h3 i{font-size:16px}.view-content-edit main .main-container .bottom-content .page-panel.right-panel .iframe-wrapper{display:flex;flex-direction:column;width:100%;position:relative;padding-top:56.25%;overflow:hidden;border-radius:4px;outline:4px solid rgba(255,255,255,.1)}.view-content-edit main .main-container .bottom-content .page-panel.right-panel .iframe-wrapper iframe{position:absolute;top:0;left:0;width:100%;height:100%;border:none}.view-logs-list main .main-container .bottom-content .page-content .inner{padding-top:8px;padding-bottom:8px}.view-logs-list main .main-container .bottom-content .page-content .logs{flex:1;display:flex;flex-direction:column;align-self:stretch}.view-logs-list main .main-container .bottom-content .page-content .logs pre{flex:1;background:#000000e6;border:1px solid rgba(70,70,70,.5);border-radius:4px;font-family:monospace;color:#f2f2f2;padding:20px;overflow:auto;align-self:stretch}.view-node-player-edit main .main-container .bottom-content .page-content{flex:1}.view-node-player-edit main .main-container .bottom-content .page-content .form-holder{margin:20px 20px 20px 10px}.view-playlist-list main .main-container .modal-playlist-qrcode h2{text-align:center}.view-playlist-list main .main-container .modal-playlist-qrcode .qrcode-pic{text-align:center;display:flex;flex-direction:row;justify-content:center;align-items:center}.view-playlist-list main .main-container .modal-playlist-qrcode .qrcode-pic img{border:4px solid #555;border-radius:4px}.view-playlist-list main .main-container .bottom-content .page-content{flex:1}.view-playlist-list main .main-container .bottom-content .page-content.with-right-panel{flex:.5}.view-playlist-list main .main-container .bottom-content .page-content .inner{padding:0}.view-playlist-list main .main-container .bottom-content .page-content .inner h3{font-size:16px;font-weight:500;color:#ddd;text-decoration:none;margin:0 0 20px}.view-playlist-list main .main-container .bottom-content .page-content .inner .form-holder{margin:20px 10px 20px 20px;border-right:1px solid #222;padding-right:20px;flex:1.3}.view-playlist-list main .main-container .bottom-content .page-content .inner .form-holder form{max-width:initial}.view-playlist-list main .main-container .bottom-content .page-content .inner .form-holder .form-group{flex-grow:0}.view-playlist-list main .main-container .bottom-content .page-content .inner .preview-holder{margin:20px 20px 20px 10px;flex:1}.view-playlist-list main .main-container .bottom-content .page-content .inner .preview-holder .form-group{flex-grow:0;margin-bottom:0}.view-playlist-list main .main-container .bottom-content .page-content .inner .preview-holder .form-group .widget a,.view-playlist-list main .main-container .bottom-content .page-content .inner .preview-holder .form-group .widget .btn{margin-left:10px}.view-playlist-list main .main-container .bottom-content .page-content .inner .preview-holder .form-group .widget input[type=text]{border:none;background:#000;border-radius:4px}.view-playlist-list main .main-container .bottom-content .page-content .inner .preview-holder h4{font-size:14px;display:flex;flex-direction:row;justify-content:flex-start;align-items:center;align-self:stretch;color:#fff;padding-bottom:10px;text-decoration:none}.view-playlist-list main .main-container .bottom-content .page-content .inner .preview-holder h4.divide{border-top:1px solid #222;margin-top:20px;padding-top:20px}.view-playlist-list main .main-container .bottom-content .page-content .inner .preview-holder p{font-size:12px;line-height:18px;display:flex;margin-bottom:5px;flex-direction:row;justify-content:flex-start;align-items:center;align-self:stretch;color:#666}.view-playlist-list main .main-container .bottom-content .page-content .inner .preview-holder .qrcode-pic{margin-top:10px}.view-playlist-list main .main-container .bottom-content .page-content .inner .preview-holder .qrcode-pic img{border:1px dashed #555;padding:5px;border-radius:4px}.view-playlist-list main .main-container .bottom-content .page-content .inner .preview-holder .preview{background:#000;border:1px solid rgba(255,255,255,.3);border-radius:4px;justify-content:center;align-items:center;align-self:stretch;display:flex;margin:10px 0 20px;height:300px}.view-playlist-list main .main-container .bottom-content .page-content .inner .preview-holder .preview iframe{flex:1;align-self:stretch}.view-playlist-list main .main-container .bottom-content .page-content .inner .slides-holder{margin-top:40px;border-top:1px solid #222;align-self:stretch;padding-top:20px}.view-playlist-list main .main-container .bottom-content .page-panel.left-panel{flex:.3;max-width:initial;justify-content:center;align-items:center;display:flex}.view-plugins-list main .main-container .bottom-content .page-content .inner{padding:10px}.view-settings-list main .main-container .bottom-content .page-content .inner{padding:10px}.view-sysinfo-list main .main-container .bottom-content .page-content .inner{padding:10px} diff --git a/data/www/img/logo3.png b/data/www/img/logo3.png new file mode 100644 index 0000000000000000000000000000000000000000..cf6a9f4849f23c88a519d2be14dc5e56d284333f GIT binary patch literal 49603 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

VPqgiIj$(0#k{yUl=lV+AXc}&*o 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 J1&1%*_!p#!qSF8X literal 0 HcmV?d00001 diff --git a/data/www/js/explorer.js b/data/www/js/explorer.js index 33f19a6..9ac40fa 100644 --- a/data/www/js/explorer.js +++ b/data/www/js/explorer.js @@ -105,7 +105,7 @@ jQuery(function ($) { route = $(this).attr('data-entity-route') + '?id=' + $item.attr('data-id'); } - if (confirm(l.common_are_you_sure)) { + if (confirm(l.js_common_are_you_sure)) { document.location.href = route; } }); @@ -134,7 +134,13 @@ jQuery(function ($) { selectEpxlrLink(verticalNeighbors.above.find('.explr-link')); } else if (e.key === "ArrowDown" && verticalNeighbors.below) { selectEpxlrLink(verticalNeighbors.below.find('.explr-link')); + } else if (e.key === "Backspace") { + if ($('.explr-item-delete:visible').length) { + $('.explr-item-delete:visible').click(); + } } + } else if (e.key.indexOf('Arrow') === 0) { + selectEpxlrLink($('.explr-dirview li:visible:eq(0)').find('.explr-link')); } }); diff --git a/data/www/js/global.js b/data/www/js/global.js index 0bb27b9..18832d2 100644 --- a/data/www/js/global.js +++ b/data/www/js/global.js @@ -18,7 +18,7 @@ const hideDropdowns = function () { const explrSidebarOpenFromFolder = function (folderId) { const $leaf = $('.li-explr-folder-' + folderId); let $parent = $leaf; - while($parent.length > 0) { + while ($parent.length > 0) { const $toggler = $parent.find('.explr-toggler:eq(0)'); if ($toggler.hasClass('explr-plus')) { $parent.find('.explr-toggler:eq(0)').trigger('click'); @@ -112,7 +112,7 @@ jQuery(document).ready(function ($) { $('#entity-utrack-updated-at').val(prettyTimestamp(entity.updated_at * 1000)); }); - setTimeout(function() { + setTimeout(function () { $('.alert-timeout').remove(); }, 3000); @@ -122,5 +122,17 @@ jQuery(document).ready(function ($) { $firstInputText.focus(); } } + + $(document).on('click', '.copy-link', function (e) { + e.preventDefault(); + const $input = $('#' + $(this).attr('data-target-id')); + $input.select(); + $input[0].setSelectionRange(0, 99999); + document.execCommand("copy"); + + if (navigator.clipboard) { + navigator.clipboard.writeText($input.val()); + } + }); }); diff --git a/data/www/js/lib/jquery-explr-1.4.js b/data/www/js/lib/jquery-explr-1.4.js index b9efeef..5e7cbbe 100755 --- a/data/www/js/lib/jquery-explr-1.4.js +++ b/data/www/js/lib/jquery-explr-1.4.js @@ -159,10 +159,8 @@ .find('ul') // hide every ul .hide() .end() - .find('.explr-expand') // unless explicitly set to expand - .show() - .siblings('.explr-toggler') - .addClass('explr-minus '+opts.classesMinus); + .find('.explr-toggler') + .addClass('explr-plus '+opts.classesPlus); } else { $tree .find('.explr-collapse') // hide every element set to collapse diff --git a/data/www/js/lib/qrcode.min.js b/data/www/js/lib/qrcode.min.js new file mode 100644 index 0000000..993e88f --- /dev/null +++ b/data/www/js/lib/qrcode.min.js @@ -0,0 +1 @@ +var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this.parsedData=[];for(var b=[],d=0,e=this.data.length;e>d;d++){var f=this.data.charCodeAt(d);f>65536?(b[0]=240|(1835008&f)>>>18,b[1]=128|(258048&f)>>>12,b[2]=128|(4032&f)>>>6,b[3]=128|63&f):f>2048?(b[0]=224|(61440&f)>>>12,b[1]=128|(4032&f)>>>6,b[2]=128|63&f):f>128?(b[0]=192|(1984&f)>>>6,b[1]=128|63&f):b[0]=f,this.parsedData=this.parsedData.concat(b)}this.parsedData.length!=this.data.length&&(this.parsedData.unshift(191),this.parsedData.unshift(187),this.parsedData.unshift(239))}function b(a,b){this.typeNumber=a,this.errorCorrectLevel=b,this.modules=null,this.moduleCount=0,this.dataCache=null,this.dataList=[]}function i(a,b){if(void 0==a.length)throw new Error(a.length+"/"+b);for(var c=0;c=f;f++){var h=0;switch(b){case d.L:h=l[f][0];break;case d.M:h=l[f][1];break;case d.Q:h=l[f][2];break;case d.H:h=l[f][3]}if(h>=e)break;c++}if(c>l.length)throw new Error("Too long data");return c}function s(a){var b=encodeURI(a).toString().replace(/\%[0-9a-fA-F]{2}/g,"a");return b.length+(b.length!=a?3:0)}a.prototype={getLength:function(){return this.parsedData.length},write:function(a){for(var b=0,c=this.parsedData.length;c>b;b++)a.put(this.parsedData[b],8)}},b.prototype={addData:function(b){var c=new a(b);this.dataList.push(c),this.dataCache=null},isDark:function(a,b){if(0>a||this.moduleCount<=a||0>b||this.moduleCount<=b)throw new Error(a+","+b);return this.modules[a][b]},getModuleCount:function(){return this.moduleCount},make:function(){this.makeImpl(!1,this.getBestMaskPattern())},makeImpl:function(a,c){this.moduleCount=4*this.typeNumber+17,this.modules=new Array(this.moduleCount);for(var d=0;d=7&&this.setupTypeNumber(a),null==this.dataCache&&(this.dataCache=b.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,c)},setupPositionProbePattern:function(a,b){for(var c=-1;7>=c;c++)if(!(-1>=a+c||this.moduleCount<=a+c))for(var d=-1;7>=d;d++)-1>=b+d||this.moduleCount<=b+d||(this.modules[a+c][b+d]=c>=0&&6>=c&&(0==d||6==d)||d>=0&&6>=d&&(0==c||6==c)||c>=2&&4>=c&&d>=2&&4>=d?!0:!1)},getBestMaskPattern:function(){for(var a=0,b=0,c=0;8>c;c++){this.makeImpl(!0,c);var d=f.getLostPoint(this);(0==c||a>d)&&(a=d,b=c)}return b},createMovieClip:function(a,b,c){var d=a.createEmptyMovieClip(b,c),e=1;this.make();for(var f=0;f=g;g++)for(var h=-2;2>=h;h++)this.modules[d+g][e+h]=-2==g||2==g||-2==h||2==h||0==g&&0==h?!0:!1}},setupTypeNumber:function(a){for(var b=f.getBCHTypeNumber(this.typeNumber),c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[Math.floor(c/3)][c%3+this.moduleCount-8-3]=d}for(var c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[c%3+this.moduleCount-8-3][Math.floor(c/3)]=d}},setupTypeInfo:function(a,b){for(var c=this.errorCorrectLevel<<3|b,d=f.getBCHTypeInfo(c),e=0;15>e;e++){var g=!a&&1==(1&d>>e);6>e?this.modules[e][8]=g:8>e?this.modules[e+1][8]=g:this.modules[this.moduleCount-15+e][8]=g}for(var e=0;15>e;e++){var g=!a&&1==(1&d>>e);8>e?this.modules[8][this.moduleCount-e-1]=g:9>e?this.modules[8][15-e-1+1]=g:this.modules[8][15-e-1]=g}this.modules[this.moduleCount-8][8]=!a},mapData:function(a,b){for(var c=-1,d=this.moduleCount-1,e=7,g=0,h=this.moduleCount-1;h>0;h-=2)for(6==h&&h--;;){for(var i=0;2>i;i++)if(null==this.modules[d][h-i]){var j=!1;g>>e));var k=f.getMask(b,d,h-i);k&&(j=!j),this.modules[d][h-i]=j,e--,-1==e&&(g++,e=7)}if(d+=c,0>d||this.moduleCount<=d){d-=c,c=-c;break}}}},b.PAD0=236,b.PAD1=17,b.createData=function(a,c,d){for(var e=j.getRSBlocks(a,c),g=new k,h=0;h8*l)throw new Error("code length overflow. ("+g.getLengthInBits()+">"+8*l+")");for(g.getLengthInBits()+4<=8*l&&g.put(0,4);0!=g.getLengthInBits()%8;)g.putBit(!1);for(;;){if(g.getLengthInBits()>=8*l)break;if(g.put(b.PAD0,8),g.getLengthInBits()>=8*l)break;g.put(b.PAD1,8)}return b.createBytes(g,e)},b.createBytes=function(a,b){for(var c=0,d=0,e=0,g=new Array(b.length),h=new Array(b.length),j=0;j=0?p.get(q):0}}for(var r=0,m=0;mm;m++)for(var j=0;jm;m++)for(var j=0;j=0;)b^=f.G15<=0;)b^=f.G18<>>=1;return b},getPatternPosition:function(a){return f.PATTERN_POSITION_TABLE[a-1]},getMask:function(a,b,c){switch(a){case e.PATTERN000:return 0==(b+c)%2;case e.PATTERN001:return 0==b%2;case e.PATTERN010:return 0==c%3;case e.PATTERN011:return 0==(b+c)%3;case e.PATTERN100:return 0==(Math.floor(b/2)+Math.floor(c/3))%2;case e.PATTERN101:return 0==b*c%2+b*c%3;case e.PATTERN110:return 0==(b*c%2+b*c%3)%2;case e.PATTERN111:return 0==(b*c%3+(b+c)%2)%2;default:throw new Error("bad maskPattern:"+a)}},getErrorCorrectPolynomial:function(a){for(var b=new i([1],0),c=0;a>c;c++)b=b.multiply(new i([1,g.gexp(c)],0));return b},getLengthInBits:function(a,b){if(b>=1&&10>b)switch(a){case c.MODE_NUMBER:return 10;case c.MODE_ALPHA_NUM:return 9;case c.MODE_8BIT_BYTE:return 8;case c.MODE_KANJI:return 8;default:throw new Error("mode:"+a)}else if(27>b)switch(a){case c.MODE_NUMBER:return 12;case c.MODE_ALPHA_NUM:return 11;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 10;default:throw new Error("mode:"+a)}else{if(!(41>b))throw new Error("type:"+b);switch(a){case c.MODE_NUMBER:return 14;case c.MODE_ALPHA_NUM:return 13;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 12;default:throw new Error("mode:"+a)}}},getLostPoint:function(a){for(var b=a.getModuleCount(),c=0,d=0;b>d;d++)for(var e=0;b>e;e++){for(var f=0,g=a.isDark(d,e),h=-1;1>=h;h++)if(!(0>d+h||d+h>=b))for(var i=-1;1>=i;i++)0>e+i||e+i>=b||(0!=h||0!=i)&&g==a.isDark(d+h,e+i)&&f++;f>5&&(c+=3+f-5)}for(var d=0;b-1>d;d++)for(var e=0;b-1>e;e++){var j=0;a.isDark(d,e)&&j++,a.isDark(d+1,e)&&j++,a.isDark(d,e+1)&&j++,a.isDark(d+1,e+1)&&j++,(0==j||4==j)&&(c+=3)}for(var d=0;b>d;d++)for(var e=0;b-6>e;e++)a.isDark(d,e)&&!a.isDark(d,e+1)&&a.isDark(d,e+2)&&a.isDark(d,e+3)&&a.isDark(d,e+4)&&!a.isDark(d,e+5)&&a.isDark(d,e+6)&&(c+=40);for(var e=0;b>e;e++)for(var d=0;b-6>d;d++)a.isDark(d,e)&&!a.isDark(d+1,e)&&a.isDark(d+2,e)&&a.isDark(d+3,e)&&a.isDark(d+4,e)&&!a.isDark(d+5,e)&&a.isDark(d+6,e)&&(c+=40);for(var k=0,e=0;b>e;e++)for(var d=0;b>d;d++)a.isDark(d,e)&&k++;var l=Math.abs(100*k/b/b-50)/5;return c+=10*l}},g={glog:function(a){if(1>a)throw new Error("glog("+a+")");return g.LOG_TABLE[a]},gexp:function(a){for(;0>a;)a+=255;for(;a>=256;)a-=255;return g.EXP_TABLE[a]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)},h=0;8>h;h++)g.EXP_TABLE[h]=1<h;h++)g.EXP_TABLE[h]=g.EXP_TABLE[h-4]^g.EXP_TABLE[h-5]^g.EXP_TABLE[h-6]^g.EXP_TABLE[h-8];for(var h=0;255>h;h++)g.LOG_TABLE[g.EXP_TABLE[h]]=h;i.prototype={get:function(a){return this.num[a]},getLength:function(){return this.num.length},multiply:function(a){for(var b=new Array(this.getLength()+a.getLength()-1),c=0;cf;f++)for(var g=c[3*f+0],h=c[3*f+1],i=c[3*f+2],k=0;g>k;k++)e.push(new j(h,i));return e},j.getRsBlockTable=function(a,b){switch(b){case d.L:return j.RS_BLOCK_TABLE[4*(a-1)+0];case d.M:return j.RS_BLOCK_TABLE[4*(a-1)+1];case d.Q:return j.RS_BLOCK_TABLE[4*(a-1)+2];case d.H:return j.RS_BLOCK_TABLE[4*(a-1)+3];default:return void 0}},k.prototype={get:function(a){var b=Math.floor(a/8);return 1==(1&this.buffer[b]>>>7-a%8)},put:function(a,b){for(var c=0;b>c;c++)this.putBit(1==(1&a>>>b-c-1))},getLengthInBits:function(){return this.length},putBit:function(a){var b=Math.floor(this.length/8);this.buffer.length<=b&&this.buffer.push(0),a&&(this.buffer[b]|=128>>>this.length%8),this.length++}};var l=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]],o=function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){function g(a,b){var c=document.createElementNS("http://www.w3.org/2000/svg",a);for(var d in b)b.hasOwnProperty(d)&&c.setAttribute(d,b[d]);return c}var b=this._htOption,c=this._el,d=a.getModuleCount();Math.floor(b.width/d),Math.floor(b.height/d),this.clear();var h=g("svg",{viewBox:"0 0 "+String(d)+" "+String(d),width:"100%",height:"100%",fill:b.colorLight});h.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:xlink","http://www.w3.org/1999/xlink"),c.appendChild(h),h.appendChild(g("rect",{fill:b.colorDark,width:"1",height:"1",id:"template"}));for(var i=0;d>i;i++)for(var j=0;d>j;j++)if(a.isDark(i,j)){var k=g("use",{x:String(i),y:String(j)});k.setAttributeNS("http://www.w3.org/1999/xlink","href","#template"),h.appendChild(k)}},a.prototype.clear=function(){for(;this._el.hasChildNodes();)this._el.removeChild(this._el.lastChild)},a}(),p="svg"===document.documentElement.tagName.toLowerCase(),q=p?o:m()?function(){function a(){this._elImage.src=this._elCanvas.toDataURL("image/png"),this._elImage.style.display="block",this._elCanvas.style.display="none"}function d(a,b){var c=this;if(c._fFail=b,c._fSuccess=a,null===c._bSupportDataURI){var d=document.createElement("img"),e=function(){c._bSupportDataURI=!1,c._fFail&&_fFail.call(c)},f=function(){c._bSupportDataURI=!0,c._fSuccess&&c._fSuccess.call(c)};return d.onabort=e,d.onerror=e,d.onload=f,d.src="data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==",void 0}c._bSupportDataURI===!0&&c._fSuccess?c._fSuccess.call(c):c._bSupportDataURI===!1&&c._fFail&&c._fFail.call(c)}if(this._android&&this._android<=2.1){var b=1/window.devicePixelRatio,c=CanvasRenderingContext2D.prototype.drawImage;CanvasRenderingContext2D.prototype.drawImage=function(a,d,e,f,g,h,i,j){if("nodeName"in a&&/img/i.test(a.nodeName))for(var l=arguments.length-1;l>=1;l--)arguments[l]=arguments[l]*b;else"undefined"==typeof j&&(arguments[1]*=b,arguments[2]*=b,arguments[3]*=b,arguments[4]*=b);c.apply(this,arguments)}}var e=function(a,b){this._bIsPainted=!1,this._android=n(),this._htOption=b,this._elCanvas=document.createElement("canvas"),this._elCanvas.width=b.width,this._elCanvas.height=b.height,a.appendChild(this._elCanvas),this._el=a,this._oContext=this._elCanvas.getContext("2d"),this._bIsPainted=!1,this._elImage=document.createElement("img"),this._elImage.style.display="none",this._el.appendChild(this._elImage),this._bSupportDataURI=null};return e.prototype.draw=function(a){var b=this._elImage,c=this._oContext,d=this._htOption,e=a.getModuleCount(),f=d.width/e,g=d.height/e,h=Math.round(f),i=Math.round(g);b.style.display="none",this.clear();for(var j=0;e>j;j++)for(var k=0;e>k;k++){var l=a.isDark(j,k),m=k*f,n=j*g;c.strokeStyle=l?d.colorDark:d.colorLight,c.lineWidth=1,c.fillStyle=l?d.colorDark:d.colorLight,c.fillRect(m,n,f,g),c.strokeRect(Math.floor(m)+.5,Math.floor(n)+.5,h,i),c.strokeRect(Math.ceil(m)-.5,Math.ceil(n)-.5,h,i)}this._bIsPainted=!0},e.prototype.makeImage=function(){this._bIsPainted&&d.call(this,a)},e.prototype.isPainted=function(){return this._bIsPainted},e.prototype.clear=function(){this._oContext.clearRect(0,0,this._elCanvas.width,this._elCanvas.height),this._bIsPainted=!1},e.prototype.round=function(a){return a?Math.floor(1e3*a)/1e3:a},e}():function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){for(var b=this._htOption,c=this._el,d=a.getModuleCount(),e=Math.floor(b.width/d),f=Math.floor(b.height/d),g=[''],h=0;d>h;h++){g.push("");for(var i=0;d>i;i++)g.push('');g.push("")}g.push("
"),c.innerHTML=g.join("");var j=c.childNodes[0],k=(b.width-j.offsetWidth)/2,l=(b.height-j.offsetHeight)/2;k>0&&l>0&&(j.style.margin=l+"px "+k+"px")},a.prototype.clear=function(){this._el.innerHTML=""},a}();QRCode=function(a,b){if(this._htOption={width:256,height:256,typeNumber:4,colorDark:"#000000",colorLight:"#ffffff",correctLevel:d.H},"string"==typeof b&&(b={text:b}),b)for(var c in b)this._htOption[c]=b[c];"string"==typeof a&&(a=document.getElementById(a)),this._android=n(),this._el=a,this._oQRCode=null,this._oDrawing=new q(this._el,this._htOption),this._htOption.text&&this.makeCode(this._htOption.text)},QRCode.prototype.makeCode=function(a){this._oQRCode=new b(r(a,this._htOption.correctLevel),this._htOption.correctLevel),this._oQRCode.addData(a),this._oQRCode.make(),this._el.title=a,this._oDrawing.draw(this._oQRCode),this.makeImage()},QRCode.prototype.makeImage=function(){"function"==typeof this._oDrawing.makeImage&&(!this._android||this._android>=3)&&this._oDrawing.makeImage()},QRCode.prototype.clear=function(){this._oDrawing.clear()},QRCode.CorrectLevel=d}(); \ No newline at end of file diff --git a/data/www/js/playlist/playlists.js b/data/www/js/playlist/playlists.js index 46ce2b1..0731403 100644 --- a/data/www/js/playlist/playlists.js +++ b/data/www/js/playlist/playlists.js @@ -1,76 +1,24 @@ jQuery(document).ready(function ($) { - const $tableActive = $('table.active-playlists'); - const $tableInactive = $('table.inactive-playlists'); - - const getId = function ($el) { - return $el.is('tr') ? $el.attr('data-level') : $el.parents('tr:eq(0)').attr('data-level'); - }; - - const updateTable = function () { - $('table').each(function () { - if ($(this).find('tbody tr.playlist-item:visible').length === 0) { - $(this).find('tr.empty-tr').removeClass('hidden'); - } else { - $(this).find('tr.empty-tr').addClass('hidden'); - } - }); - }; const main = function () { + const qrcodeElement = document.getElementById('qrcode'); - }; - - $(document).on('change', 'input[type=checkbox]', function () { - $.ajax({ - url: '/playlist/toggle', - headers: {'Content-Type': 'application/json'}, - data: JSON.stringify({id: getId($(this)), enabled: $(this).is(':checked')}), - method: 'POST', - }); - - const $tr = $(this).parents('tr:eq(0)').remove().clone(); - - if ($(this).is(':checked')) { - $tableActive.append($tr); - } else { - $tableInactive.append($tr); + if (qrcodeElement) { + new QRCode(qrcodeElement, { + text: qrcodeElement.attributes['data-qrcode-payload'].value, + width: 128, + height: 128, + colorDark: '#222', + colorLight: '#fff', + correctLevel: QRCode.CorrectLevel.H + }); } - - updateTable(); - }); + }; $(document).on('click', '.playlist-add', function () { showModal('modal-playlist-add'); $('.modal-playlist-add input:eq(0)').focus().select(); }); - $(document).on('click', '.playlist-edit', function () { - const playlist = JSON.parse($(this).parents('tr:eq(0)').attr('data-entity')); - showModal('modal-playlist-edit'); - $('.modal-playlist-edit input:visible:eq(0)').focus().select(); - $('#playlist-edit-name').val(playlist.name); - $('#playlist-edit-time-sync').val(playlist.time_sync ? '1' : '0'); - $('#playlist-edit-id').val(playlist.id); - }); - - $(document).on('click', '.playlist-delete', function () { - if (confirm(l.js_playlist_delete_confirmation)) { - const $tr = $(this).parents('tr:eq(0)'); - $.ajax({ - method: 'DELETE', - url: '/playlist/delete', - headers: {'Content-Type': 'application/json'}, - data: JSON.stringify({id: getId($(this))}), - success: function(data) { - $tr.remove(); - updateTable(); - }, - error: function(data) { - $('.alert-error').html(data.responseJSON.message).removeClass('hidden'); - } - }); - } - }); - main(); }); diff --git a/data/www/scss/base/_context.scss b/data/www/scss/base/_context.scss index 9da8dee..066c052 100644 --- a/data/www/scss/base/_context.scss +++ b/data/www/scss/base/_context.scss @@ -36,7 +36,7 @@ main { margin-right: 20px; .trigger { - color: white; + color: $white; .avatar { width: 32px; diff --git a/data/www/scss/base/_html.scss b/data/www/scss/base/_html.scss index 8622cec..a130fdd 100644 --- a/data/www/scss/base/_html.scss +++ b/data/www/scss/base/_html.scss @@ -28,6 +28,15 @@ body, html { align-self: stretch; } +.vertical { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; + flex: 1; + align-self: stretch; +} + main { flex: 1; display: flex; @@ -51,7 +60,7 @@ main { border-bottom: $layoutBorder; h1 { - color: white; + color: $white; font-weight: 600; font-size: 24px; } @@ -63,16 +72,13 @@ main { justify-content: flex-end; align-items: center; + .btn, button { margin-left: 10px; } } } - .alert { - - } - .bottom-content { display: flex; flex-direction: row; diff --git a/data/www/scss/base/_menu.scss b/data/www/scss/base/_menu.scss index deb6c70..46d5750 100644 --- a/data/www/scss/base/_menu.scss +++ b/data/www/scss/base/_menu.scss @@ -103,7 +103,7 @@ menu { padding-left: 10px; i { - color: white; + color: $white; opacity: .2; background: transparent; display: flex; @@ -119,7 +119,7 @@ menu { } &:after { - background: white; + background: $white; content: ""; height: 195px; left: -200px; @@ -156,11 +156,11 @@ menu { } a { - color: white; + color: $white; font-weight: bold; i { - color: white; + color: $white; opacity: 1; } } diff --git a/data/www/scss/components/_alerts.scss b/data/www/scss/components/_alerts.scss index 884a350..2af861e 100644 --- a/data/www/scss/components/_alerts.scss +++ b/data/www/scss/components/_alerts.scss @@ -1,29 +1,36 @@ .alert { - padding: 20px 20px; - align-self: stretch; - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - border-radius: 4px; + padding: 20px 20px; + align-self: stretch; + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + border-radius: 4px; + + a { + color: inherit; + margin-left: 4px; + margin-right: 4px; + text-decoration: underline; + } } .alert-info { - color: $info; - background: rgba($info, .2); + color: $info; + background: rgba($info, .2); } .alert-success { - color: $success; - background: rgba($success, .2); + color: $success; + background: rgba($success, .2); } .alert-danger, .alert-error { - color: $danger; - background: rgba($danger, .2); + color: $danger; + background: rgba($danger, .2); } .alert i { - margin-right: 13px; + margin-right: 13px; } \ No newline at end of file diff --git a/data/www/scss/components/_breadcrumb.scss b/data/www/scss/components/_breadcrumb.scss index 6f618b3..1091983 100644 --- a/data/www/scss/components/_breadcrumb.scss +++ b/data/www/scss/components/_breadcrumb.scss @@ -38,7 +38,7 @@ flex-direction: row; justify-content: center; align-items: center; - color: white; + color: $white; text-align: center; padding: 0 3px; diff --git a/data/www/scss/components/_buttons.scss b/data/www/scss/components/_buttons.scss index 8631077..b304d4f 100644 --- a/data/www/scss/components/_buttons.scss +++ b/data/www/scss/components/_buttons.scss @@ -4,7 +4,7 @@ button, $shadowOffset: 2px; position: relative; - padding: 10px 13px 8px 10px; + padding: 10px 10px 8px 10px; font-size: 14px; color: #fff; cursor: pointer; @@ -35,15 +35,48 @@ button, color: #AAA; background: $neutralGrey; box-shadow: 0 $shadowOffset 0 0 darken($neutralGrey, 10%); - &:hover { box-shadow: 0 $shadowOffset 0 1px #222 inset; background: darken($neutralGrey, 10%); } - &:focus { background: darken($neutralGrey, 20%); } + + &:hover { + box-shadow: 0 $shadowOffset 0 1px #222 inset; + background: darken($neutralGrey, 10%); + } + + &:focus { + background: darken($neutralGrey, 20%); + } + } + + .btn-wire-neutral { + background: transparent; + border: 2px solid $neutralGrey; + color: rgba($white, .8); + box-shadow: none; + + &:hover { + background: rgba($neutralGrey, 0.05); + border-color: darken($neutralGrey, 10%); + color: darken($neutralGrey, 10%); + box-shadow: none; + } + + &:focus { + border-color: darken($neutralGrey, 20%); + background: transparent; + } } &.btn-naked { background: transparent; box-shadow: none; - &:hover { box-shadow: 0 $shadowOffset 0 1px #222 inset; background: darken($neutralGrey, 10%); } - &:focus { background: darken($neutralGrey, 20%); } + + &:hover { + box-shadow: 0 $shadowOffset 0 1px #222 inset; + background: darken($neutralGrey, 10%); + } + + &:focus { + background: darken($neutralGrey, 20%); + } } } diff --git a/data/www/scss/components/_dropdown.scss b/data/www/scss/components/_dropdown.scss index 6338e89..440c5b0 100644 --- a/data/www/scss/components/_dropdown.scss +++ b/data/www/scss/components/_dropdown.scss @@ -52,7 +52,7 @@ a { padding: 8px 16px 8px 8px; - color: white; + color: $white; display: flex; flex-direction: row; justify-content: flex-start; diff --git a/data/www/scss/components/_empty.scss b/data/www/scss/components/_empty.scss index d6567e5..01aac60 100644 --- a/data/www/scss/components/_empty.scss +++ b/data/www/scss/components/_empty.scss @@ -6,4 +6,19 @@ span.empty { border-radius: 2px; padding: 2px 4px; font-weight: bold; +} + + +.inner-empty { + display: flex; + flex: 1; + align-self: stretch; + justify-content: center; + align-items: center; + + i { + font-size: 90px; + opacity: 0.3; + text-shadow: 0 -1px #333, 0 0px .5px #444; + } } \ No newline at end of file diff --git a/data/www/scss/components/_explorer.scss b/data/www/scss/components/_explorer.scss index 631773b..1cfd8db 100644 --- a/data/www/scss/components/_explorer.scss +++ b/data/www/scss/components/_explorer.scss @@ -19,11 +19,11 @@ ul.explr-tree { } a { - color: white; + color: $white; padding-right: 80px; &:hover { - color: white; + color: $white; } &.active { diff --git a/data/www/scss/components/_modals.scss b/data/www/scss/components/_modals.scss index ecc59b1..6f15e63 100644 --- a/data/www/scss/components/_modals.scss +++ b/data/www/scss/components/_modals.scss @@ -22,7 +22,7 @@ background: $layoutBackground; border-radius: 10px; color: lighten($black, 20%); - padding: 40px; + padding: 40px; box-shadow: 0 2px #222; border: 1px solid #222; @@ -30,15 +30,27 @@ h2 { padding: 0; margin: 0 0 30px 0; - font-weight: normal; - color: #999; + font-weight: normal; + color: #999; } h3 { align-self: stretch; - border-bottom: 1px solid $lightGrey; - padding: 15px 15px; margin: 0; + font-size: 14px; + display: flex; + flex-direction: row; + justify-content: flex-start; + align-items: center; + color: white; + padding-bottom: 10px; + text-decoration: none; + + &.divide { + border-top: 1px solid #222; + margin-top: 20px; + padding-top: 20px; + } } } } diff --git a/data/www/scss/components/_panes.scss b/data/www/scss/components/_panes.scss index 55e69ca..4b4b539 100644 --- a/data/www/scss/components/_panes.scss +++ b/data/www/scss/components/_panes.scss @@ -118,16 +118,16 @@ table.panes { td { font-weight: bold; - color: white; + color: $white; i.icon-legend { - color: white; + color: $white; } span, i.icon-value { background-color: rgba($white, .3); - color: white; + color: $white; } &.description { diff --git a/data/www/scss/components/_pills.scss b/data/www/scss/components/_pills.scss index 27caba3..912594b 100644 --- a/data/www/scss/components/_pills.scss +++ b/data/www/scss/components/_pills.scss @@ -31,7 +31,7 @@ ul.pills { flex-direction: row; justify-content: center; align-items: center; - color: white; + color: $white; overflow: hidden; padding-right: 30px; text-align: center; diff --git a/data/www/scss/components/_switches.scss b/data/www/scss/components/_switches.scss index 997b3c8..f5fff41 100644 --- a/data/www/scss/components/_switches.scss +++ b/data/www/scss/components/_switches.scss @@ -1,116 +1,66 @@ -.pure-material-switch { - z-index: 0; - position: relative; - display: inline-block; -} +$toggleActiveColor: $limeGreen; +$containerWidth: 42px; +$containerHeight: 26px; +$containerRadius: 15px; +$containerShadowActive: 0 2px 2px #222 inset; +$containerShadowInactive: 0 2px 2px #111 inset; +$backgroundColorInactive: #222; +$backgroundColorActive: darken($toggleActiveColor, 30%); +$thumbColorActive: $toggleActiveColor; +$thumbColorInactive: #777; +$thumbWidth: 18px; +$thumbHeight: $thumbWidth; +$borderSize: 1px; +$animationSpeed: 0.2s; -.pure-material-switch > input { - appearance: none; - -moz-appearance: none; - -webkit-appearance: none; - z-index: -1; - position: absolute; - right: 6px; - top: -8px; - display: block; - margin: 0; - border-radius: 50%; - width: 40px; - height: 40px; - background-color: rgba($black, 0.38); - outline: none; - opacity: 0; - transform: scale(1); - pointer-events: none; - transition: opacity 0.3s 0.1s, transform 0.2s 0.1s; -} +.toggle { + position: relative; + display: flex; + flex-direction: row; + justify-content: flex-start; + align-items: center; -.pure-material-switch > span { - display: inline-block; - width: 100%; - cursor: pointer; -} + input { + display: none; -.pure-material-switch > span::before { - content: ""; - float: right; - display: inline-block; - margin: 5px 0 5px 10px; - border-radius: 7px; - width: 36px; - height: 14px; - background-color: rgba($black, 0.38); - vertical-align: top; - transition: background-color 0.2s, opacity 0.2s; -} + &:checked + label { + background: darken($thumbColorActive, 30%); + border: $borderSize solid rgba($white, .1); + box-shadow: $containerShadowActive; -.pure-material-switch > span::after { - content: ""; - position: absolute; - top: 2px; - right: 16px; - border-radius: 50%; - width: 20px; - height: 20px; - background-color: $white; - box-shadow: 0 3px 1px -2px rgba($black, 0.2), 0 2px 2px 0 rgba($black, 0.14), 0 1px 5px 0 rgba($black, 0.12); - transition: background-color 0.2s, transform 0.2s; -} + &::after { + content: ""; + display: block; + border-radius: 50%; + margin-left: calc($containerWidth - 21px); + width: $thumbWidth; + height: $thumbHeight; + transition: $animationSpeed; + background: $thumbColorActive; + box-shadow: 0 2px darken($thumbColorActive, 40%); + } + } + } -.pure-material-switch > input:checked { - right: -10px; - background-color: $limeGreen; -} + label { + width: $containerWidth + ($borderSize * 2); + height: $containerHeight; + border-radius: $containerRadius; + background: $backgroundColorInactive; + cursor: pointer; + border: $borderSize solid rgba($white, .1); + box-shadow: $containerShadowInactive; -.pure-material-switch > input:checked + span::before { - background-color: rgba($limeGreen, 0.6); -} - -.pure-material-switch > input:checked + span::after { - background-color: $limeGreen; - transform: translateX(16px); -} - -.pure-material-switch:hover > input { - opacity: 0.04; -} - -.pure-material-switch > input:focus { - opacity: 0.12; -} - -.pure-material-switch:hover > input:focus { - opacity: 0.16; -} - -.pure-material-switch > input:active { - opacity: 1; - transform: scale(0); - transition: transform 0s, opacity 0s; -} - -.pure-material-switch > input:active + span::before { - background-color: rgba($limeGreen, 0.6); -} - -.pure-material-switch > input:checked:active + span::before { - background-color: rgba($black, 0.38); -} - -.pure-material-switch > input:disabled { - opacity: 0; -} - -.pure-material-switch > input:disabled + span { - color: $black; - opacity: 0.38; - cursor: default; -} - -.pure-material-switch > input:disabled + span::before { - background-color: rgba($black, 0.38); -} - -.pure-material-switch > input:checked:disabled + span::before { - background-color: rgba($limeGreen, 0.6); + &::after { + content: ""; + display: block; + border-radius: 50%; + width: $thumbWidth; + height: $thumbHeight; + margin: 3px; + background: $thumbColorInactive; + box-shadow: 0 2px rgba(0,0,0,0.9); + transition: $animationSpeed; + } + } } diff --git a/data/www/scss/components/_tiles.scss b/data/www/scss/components/_tiles.scss new file mode 100644 index 0000000..4b69247 --- /dev/null +++ b/data/www/scss/components/_tiles.scss @@ -0,0 +1,117 @@ +.tiles { + flex: 1; + display: flex; + flex-direction: row; + justify-content: flex-start; + align-items: flex-start; + align-self: stretch; + + .tiles-inner { + display: flex; + flex: 1; + flex-direction: column; + flex-wrap: nowrap; + justify-content: flex-start; + align-items: flex-start; + align-self: stretch; + padding: 2px; + + .tiles-empty { + + } + + .tile-item { + display: flex; + flex-direction: row; + justify-content: flex-start; + align-items: center; + background: #222; + align-self: stretch; + color: $white; + margin: 1px; + padding: 15px; + + &:hover, + &.active { + background: #111; + + &:hover { + opacity: 1; + } + } + + + &.disabled { + + .tile-header { + .head-icon { + i { + color: #222; + } + } + } + } + + .tile-header { + display: flex; + flex-direction: row; + justify-content: flex-start; + align-items: center; + align-self: stretch; + + + .head-icon { + flex: 1; + + i { + font-size: 6px; + color: white; + opacity: .8; + display: flex; + } + } + + .status-icons { + display: flex; + flex-direction: row; + justify-content: flex-end; + align-items: center; + + i { + font-size: 16px; + margin-left: 10px; + } + } + } + + .tile-body { + flex: 1; + display: flex; + flex-direction: row; + justify-content: flex-start; + align-items: center; + font-size: 15px; + font-weight: normal; + letter-spacing: 0.8px; + line-height: 22px; + margin: 0 0 0 10px; + flex-wrap: nowrap; + } + + .tile-footer { + display: flex; + flex-direction: row; + justify-content: flex-end; + align-items: center; + margin: 0; + + .foot-span { + opacity: .8; + font-size: 13px; + font-family: "Courier New"; + } + } + + } + } +} \ No newline at end of file diff --git a/data/www/scss/forms/_forms.scss b/data/www/scss/forms/_forms.scss index 921201b..de8a5c2 100644 --- a/data/www/scss/forms/_forms.scss +++ b/data/www/scss/forms/_forms.scss @@ -1,10 +1,10 @@ .form-holder { - min-width: 686px; display: flex; flex-direction: column; justify-content: flex-start; align-items: flex-start; align-self: stretch; + flex: 1; form { max-width: 434px; @@ -24,172 +24,196 @@ form { font-size: 14px; margin: 0 0 25px 0; } +} - .form-group { - display: flex; - flex-direction: column; - justify-content: flex-start; - align-items: flex-start; - align-self: stretch; - width: 100%; +.form-group { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; + align-self: stretch; + width: 100%; + flex: 1; + margin-bottom: 20px; + + + label { flex: 1; - margin-bottom: 20px; + font-size: 12px; + display: flex; + flex-direction: row; + justify-content: flex-start; + align-items: center; + align-self: stretch; + color: #666666; + + &.btn-upload { + color: $white; + font-size: 14px; + flex: 0; + flex-basis: auto; + margin-top: 5px; + + input[type=file] { + display: none; + } + + input[type=text] { + margin-bottom: 2px; + padding-left: 0; + margin-left: 10px; + } + + i { + margin-left: 3px; + margin-right: 10px; + } + } + } + + .widget { + margin-top: 10px; + align-self: stretch; + display: flex; + flex-direction: row; - label { + div { + color: rgba($white, .7); + font-size: 14px; + } + + select, + input, + textarea { + outline: none; + padding: 8px 0 5px 8px; + border-radius: 2px; + border: 1px solid rgba($white, .05); flex: 1; - font-size: 12px; + background: #555; + box-shadow: 0 2px 1px #444, 0 4px 2px #333 inset; + color: #DDD; + font-size: 14px; + + &[disabled] { + color: #555; + background: none; + box-shadow: none; + border: none; + border-bottom: 1px solid #333; + border-radius: 0; + } + } + + + } + + + &.tab-select { + border-bottom: 1px solid #444; + display: flex; + flex-direction: row; + position: relative; + height: 48px; + padding: 48px 0 0 0; + flex: 0; + flex-basis: auto; + + .widget { + height: 49px; + margin-top: 0; display: flex; flex-direction: row; justify-content: flex-start; align-items: center; - align-self: stretch; - color: #666666; + position: absolute; + top: 0; + left: 0; + border-bottom: 2px solid $seaBlue; + color: $seaBlue; - &.btn-upload { - color: white; - font-size: 14px; - flex: 0; - flex-basis: auto; - margin-top: 5px; - - input[type=file] { - display: none; - } - - input[type=text] { - margin-bottom: 2px; - padding-left: 0; - margin-left: 10px; - } - - i { - margin-left: 3px; - margin-right: 10px; - } - } - } - - .widget { - margin-top: 10px; - align-self: stretch; - display: flex; - flex-direction: row; - - - div { - color: rgba($white, .7); - font-size: 14px; + select { + border: none; + background: none; + box-shadow: none; + padding: 10px 35px 10px 10px; + margin: 0; + color: inherit; + appearance: none; + -moz-appearance: none; + -webkit-appearance: none; + text-align: left; + font-weight: bold; + cursor: pointer; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + max-width: 200px; + z-index: 2; } - select, - input, - textarea { - outline: none; - padding: 8px 0 5px 8px; - border-radius: 2px; - border: 1px solid rgba($white, .05); - flex: 1; - background: #555; - box-shadow: 0 2px 1px #444, 0 4px 2px #333 inset; - color: #DDD; - font-size: 14px; + i { + margin-left: 10px; + margin-right: 0; - &[disabled] { - color: #555; - background: none; - box-shadow: none; - border: none; - border-bottom: 1px solid #333; - border-radius: 0; - } - } - - - } - - - &.tab-select { - border-bottom: 1px solid #444; - display: flex; - flex-direction: row; - position: relative; - height: 48px; - padding: 48px 0 0 0; - flex: 0; - flex-basis: auto; - - .widget { - height: 49px; - margin-top: 0; - display: flex; - flex-direction: row; - justify-content: flex-start; - align-items: center; - position: absolute; - top: 0; - left: 0; - border-bottom: 2px solid $seaBlue; - color: $seaBlue; - - select { - border: none; - background: none; - box-shadow: none; - padding: 10px 35px 10px 10px; - margin: 0; - color: inherit; - appearance: none; - -moz-appearance: none; - -webkit-appearance: none; - text-align: left; - font-weight: bold; - cursor: pointer; - border-top-left-radius: 4px; - border-top-right-radius: 4px; - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - max-width: 200px; - z-index: 2; - } - - i { - margin-left: 10px; - margin-right: 0; - - &.triangle { - margin-top: -4px; - margin-left: 0; - position: absolute; - right: 10px; - } + &.triangle { + margin-top: -4px; + margin-left: 0; + position: absolute; + right: 10px; } } } } - .actions { - display: flex; + &.form-group-horizontal { + margin: 10px 0 20px 0; flex-direction: row; - justify-content: flex-end; + justify-content: flex-start; align-items: center; - align-self: stretch; - margin: 20px 0 0 0; - button { - margin-left: 25px; - } - - &.actions-left { + .widget { + margin: 0; + display: flex; + flex-direction: row; justify-content: flex-start; - - button { - margin-left: 0; - margin-right: 25px; - } + align-items: center; + } + } +} + +.actions { + display: flex; + flex-direction: row; + justify-content: flex-end; + align-items: center; + align-self: stretch; + margin: 20px 0 0 0; + + button { + margin-left: 25px; + } + + &.actions-left { + justify-content: flex-start; + + button { + margin-left: 0; + margin-right: 25px; + } + } + + &.actions-center { + justify-content: center; + + button { + margin-left: 0; + margin-right: 0; } } } diff --git a/data/www/scss/layout/_header.scss b/data/www/scss/layout/_header.scss index 531a807..9adb183 100644 --- a/data/www/scss/layout/_header.scss +++ b/data/www/scss/layout/_header.scss @@ -84,5 +84,5 @@ header nav ul li a { header nav ul li a:hover, header nav ul li.active a { - color: white; + color: $white; } diff --git a/data/www/scss/main.scss b/data/www/scss/main.scss index 8ad429e..bf622e6 100644 --- a/data/www/scss/main.scss +++ b/data/www/scss/main.scss @@ -23,8 +23,9 @@ // Legacy @import 'components/panes'; +@import 'components/tiles'; @import 'components/empty'; -//@import 'components/switches'; +@import 'components/switches'; //@import 'components/cards'; //@import 'components/badges'; diff --git a/data/www/scss/pages/_content.scss b/data/www/scss/pages/_content.scss index 892e8c2..86b81d9 100644 --- a/data/www/scss/pages/_content.scss +++ b/data/www/scss/pages/_content.scss @@ -19,7 +19,7 @@ } .page-panel.right-panel { - flex: 1; + flex: 2; align-self: stretch; display: flex; flex-direction: column; @@ -29,7 +29,7 @@ padding: 20px; h3 { - color: white; + color: $white; padding: 10px 10px 10px 0; margin-bottom: 20px; font-size: 16px; diff --git a/data/www/scss/pages/_playlist.scss b/data/www/scss/pages/_playlist.scss index e04a48c..590529b 100644 --- a/data/www/scss/pages/_playlist.scss +++ b/data/www/scss/pages/_playlist.scss @@ -1,28 +1,155 @@ - .view-playlist-list main .main-container { + .modal-playlist-qrcode { + h2 { + text-align: center; + } + .qrcode-pic { + text-align: center; + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; -} + img { + border: 4px solid #555; + border-radius: $baseRadius; + } + } -.view-playlist-edit main .main-container { + } .bottom-content { .page-content { flex: 1; - .form-holder { - margin: 20px 20px 20px 10px; + &.with-right-panel { + flex: 0.5; + } + + .inner { + padding: 0; + + h3 { + font-size: 16px; + font-weight: 500; + color: #DDD; + text-decoration: none; + margin: 0 0 20px 0; + } + + .form-holder { + margin: 20px 10px 20px 20px; + border-right: 1px solid #222; + padding-right: 20px; + flex: 1.3; + + form { + max-width: initial; + } + + .form-group { + flex-grow: 0; + } + } + + .preview-holder { + margin: 20px 20px 20px 10px; + flex: 1; + + .form-group { + flex-grow: 0; + margin-bottom: 0; + + .widget { + a, + .btn { + margin-left: 10px; + } + + input[type=text] { + border: none; + background: #000; + border-radius: $baseRadius; + } + } + } + + h4 { + font-size: 14px; + display: flex; + flex-direction: row; + justify-content: flex-start; + align-items: center; + align-self: stretch; + color: white; + padding-bottom: 10px; + text-decoration: none; + + &.divide { + border-top: 1px solid #222; + margin-top: 20px; + padding-top: 20px; + } + } + + p { + font-size: 12px; + line-height: 18px; + display: flex; + margin-bottom: 5px; + flex-direction: row; + justify-content: flex-start; + align-items: center; + align-self: stretch; + color: #666666; + } + + .qrcode-pic { + margin-top: 10px; + img { + border: 1px dashed #555; + padding: 5px; + border-radius: $baseRadius; + } + } + + .preview { + background: black; + border: 1px solid rgba($white, .3); + border-radius: $baseRadius; + justify-content: center; + align-items: center; + align-self: stretch; + display: flex; + margin: 10px 0 20px 0; + height: 300px; + + iframe { + flex: 1; + align-self: stretch; + } + } + } + + .slides-holder { + margin-top: 40px; + border-top: 1px solid #222; + align-self: stretch; + padding-top: 20px; + } } } - .page-panel.right-panel { - + .page-panel.left-panel { + flex: 0.3; + max-width: initial; + justify-content: center; + align-items: center; + display: flex; } } } - - - diff --git a/data/www/scss/utils/_mixins.scss b/data/www/scss/utils/_mixins.scss index 45171d6..35d4015 100644 --- a/data/www/scss/utils/_mixins.scss +++ b/data/www/scss/utils/_mixins.scss @@ -58,6 +58,29 @@ background: darken($color, 20%); } } + + &.btn-wire-#{"#{$name}"} { + background: transparent; + box-shadow: none; + border: 2px solid $color; + color: rgba($white, .8); + + i.btn-match { + color: $color; + } + + &:hover { + background: rgba($color, 0.05); + border-color: darken($color, 10%); + color: darken($color, 10%); + box-shadow: none; + } + + &:focus { + border-color: darken($color, 20%); + background: transparent; + } + } } } } \ No newline at end of file diff --git a/lang/en.json b/lang/en.json index 74362d4..6f7dcfc 100644 --- a/lang/en.json +++ b/lang/en.json @@ -68,8 +68,12 @@ "js_slideshow_content_delete_confirmation": "Are you sure?", "playlist_page_title": "Playlists", - "playlist_button_add": "Add a playlist", - "playlist_panel_active": "Active playlists", + "playlist_button_add": "Add Playlist", + "playlist_button_delete": "Delete Playlist", + "playlist_panel_about_playlist": "About playlist", + "playlist_panel_content_management": "Content management", + "playlist_panel_preview": "Playlist preview", + "playlist_panel_preview_action": "Preview", "playlist_panel_inactive": "Inactive playlists", "playlist_panel_empty": "Currently, there are no playlists. %link% now.", "playlist_panel_th_name": "Name", @@ -78,10 +82,12 @@ "playlist_panel_th_activity": "Options", "playlist_form_add_title": "Add Playlist", "playlist_form_add_submit": "Add", - "playlist_form_edit_title": "Edit Playlist", - "playlist_form_edit_submit": "Save", + "playlist_form_preview_url_desc": "You can use this link to play this playlist on any browser you want. Use copy button to get that in your clipboard.", + "playlist_form_preview_qrcode_desc": "You can easily access your playlist using a tablet or phone. Just scan the QR code to begin.", + "playlist_form_preview_iframe_desc": "You can view the playlist without leaving this screen by starting the preview from here.", "playlist_form_label_name": "Enter playlist name", "playlist_form_label_time_sync": "Sync slides across players", + "playlist_form_label_enabled": "Enable/Disable playlist", "playlist_form_button_cancel": "Cancel", "js_playlist_delete_confirmation": "Are you sure?", "playlist_delete_has_slides": "Playlist has slides, please remove them before and retry", @@ -165,7 +171,7 @@ "settings_variable_desc_edition_auth_enabled": "Default user credentials will be admin/admin", "settings_variable_desc_external_url": "External url (i.e: https://studio-01.company.com or http://10.10.3.100)", "settings_variable_desc_slide_upload_limit": "Slide upload limit (in megabytes)", - "settings_variable_desc_default_slide_duration": "Introduction slide duration (in seconds)", + "settings_variable_desc_intro_slide_duration": "Introduction slide duration (in seconds)", "settings_variable_desc_default_slide_time_with_seconds": "Show the seconds on the clock in the introduction slide", "settings_variable_desc_polling_interval": "Refresh interval applied for settings to the player (in seconds)", "settings_variable_desc_playlist_default_time_sync": "Sync slides across players for default playlist", @@ -175,6 +181,7 @@ "settings_variable_desc_slide_animation_exit_effect": "Slide animation exit effect (generally better off without it)", "settings_variable_desc_slide_animation_speed": "Slide animation speed", + "settings_variable_desc_ro_start_counter": "Start counter", "settings_variable_desc_ro_last_folder_content": "Current folder in content explorer", "settings_variable_desc_ro_last_folder_node_player": "Current folder in player explorer", "settings_variable_desc_ro_editable": "Last application reboot datetime", @@ -214,6 +221,7 @@ "basic_month_11": "November", "basic_month_12": "December", + "common_untitled": "", "common_loading": "Loading...", "common_default_node_player_group": "Default Playgroup", "common_default_playlist": "Default Playlist", diff --git a/lang/es.json b/lang/es.json index abaddf3..52697f4 100644 --- a/lang/es.json +++ b/lang/es.json @@ -1,294 +1,287 @@ { - "dynmenu_content": "Contenido", - - "slideshow_slide_page_title": "Descripción General del Programa", - "slideshow_slide_goto_player": "Ir al reproductor", - "slideshow_slide_refresh_player": "Actualizar reproductor", - "slideshow_slide_refresh_player_success": "La señal de actualización del reproductor ha sido enviada, debería suceder pronto (%time% segundos máximo)", - "slideshow_slide_button_add": "Agregar una diapositiva", - "slideshow_slide_panel_active": "Diapositivas activas", - "slideshow_slide_panel_inactive": "Diapositivas inactivas", - "slideshow_slide_panel_empty": "Actualmente, no hay diapositivas. %link% ahora.", - "slideshow_slide_panel_th_content": "Contenido", - "slideshow_slide_panel_th_duration": "Termina después", - "slideshow_slide_panel_th_duration_unit": "seg", - "slideshow_slide_panel_th_enabled": "Habilitado", - "slideshow_slide_panel_th_cron_scheduled": "Inicio Programado", - "slideshow_slide_panel_th_activity": "Opciones", - "slideshow_slide_panel_td_cron_scheduled_loop": "Bucle", - "slideshow_slide_panel_td_cron_scheduled_notify": "Notificar", - "slideshow_slide_panel_td_cron_scheduled_bad_cron": "Valor de cron incorrecto", - "slideshow_slide_form_add_title": "Agregar Diapositiva", - "slideshow_slide_form_add_submit": "Agregar", - "slideshow_slide_form_edit_title": "Editar Diapositiva", - "slideshow_slide_form_edit_submit": "Guardar", - "slideshow_slide_form_section_content": "Medios", - "slideshow_slide_form_section_scheduling": "Programación", - "slideshow_slide_form_label_name": "Nombre", - "slideshow_slide_form_label_add_content": "Agregar a la biblioteca", - "slideshow_slide_form_label_from_library": "Dalla biblioteca", - "slideshow_slide_form_label_content_id": "Contenido", - "slideshow_slide_form_label_location": "Ubicación", - "slideshow_slide_form_label_type": "Tipo", - "slideshow_slide_form_label_object": "Objeto", - "slideshow_slide_form_label_duration": "Duración", - "slideshow_slide_form_label_duration_unit": "segundos", - "slideshow_slide_form_label_is_notification": "Actuar como notificación", - "slideshow_slide_form_label_cron_scheduled": "Inicio", - "slideshow_slide_form_label_cron_scheduled_end": "Fin", - "slideshow_slide_form_label_cron_scheduled_loop": "Siempre en bucle", - "slideshow_slide_form_label_cron_scheduled_duration": "Duración", - "slideshow_slide_form_label_cron_scheduled_stayloop": "Seguir el bucle", - "slideshow_slide_form_label_cron_scheduled_duration_unit": "segundos", - "slideshow_slide_form_label_cron_scheduled_datetime": "Fecha y Hora", - "slideshow_slide_form_label_cron_scheduled_datetime_placeholder": "Establecer una fecha y hora", - "slideshow_slide_form_label_cron_scheduled_cron": "Cron", - "slideshow_slide_form_widget_cron_scheduled_placeholder": "Usar formato crontab: * * * * *", - "slideshow_slide_form_button_cancel": "Cancelar", - "js_slideshow_slide_delete_confirmation": "¿Estás seguro?", - - "slideshow_content_page_title": "Biblioteca de contenidos", - "slideshow_content_button_add": "Nuevo Contenido", - "slideshow_content_referenced_in_slide_error": "Se hace referencia al contenido en una diapositiva; elimine la diapositiva primero", - "slideshow_content_panel_active": "Contenido", - "slideshow_content_panel_empty": "Actualmente, no hay contenido. %link% ahora.", - "slideshow_content_panel_th_name": "Nombre", - "slideshow_content_panel_th_activity": "Opciones", - "slideshow_content_form_add_title": "Agregar Contenido", - "slideshow_content_form_add_submit": "Agregar", - "slideshow_content_form_edit_title": "Editar Contenido", - "slideshow_content_form_edit_submit": "Guardar", - "slideshow_content_form_label_name": "Nombre", - "slideshow_content_form_label_location": "Ubicación", - "slideshow_content_form_label_type": "Tipo", - "slideshow_content_form_label_object": "Objeto", - "slideshow_content_form_button_cancel": "Cancelar", - "slideshow_content_form_button_upload": "Subir un archivo", - "slideshow_content_form_button_upload_choosen": "No hay archivos seleccionados", - "js_slideshow_content_delete_confirmation": "¿Estás seguro?", - - "playlist_page_title": "Playlist", - "playlist_button_add": "Agregar una lista de reproducción", - "playlist_panel_active": "Playlist activas", - "playlist_panel_inactive": "Playlist inactivas", - "playlist_panel_empty": "Actualmente, no hay playlist. %link% ahora.", - "playlist_panel_th_name": "Nombre", - "playlist_panel_th_duration": "Duración", - "playlist_panel_th_enabled": "Habilitado", - "playlist_panel_th_activity": "Opciones", - "playlist_form_add_title": "Agregar Playlist", - "playlist_form_add_submit": "Agregar", - "playlist_form_edit_title": "Editar Playlist", - "playlist_form_edit_submit": "Guardar", - "playlist_form_label_name": "Introduce el nombre de la playlist", - "playlist_form_label_time_sync": "Sincronizar diapositivas entre reproductores", - "playlist_form_button_cancel": "Cancelar", - "js_playlist_delete_confirmation": "¿Estás seguro?", - "playlist_delete_has_slides": "La lista de reproducción tiene diapositivas, por favor elimínelas antes y reintente", - "playlist_delete_has_node_player_groups": "La lista de reproducción está asignada a un playgroup", - - "fleet_node_player_page_title": "Reproductores", - "fleet_node_player_button_add": "Agregar un reproductor", - "fleet_node_player_panel_active": "Reproductores activos", - "fleet_node_player_panel_inactive": "Reproductores inactivos", - "fleet_node_player_panel_empty": "Actualmente, no hay reproductores. %link% ahora.", - "fleet_node_player_panel_th_name": "Nombre", - "fleet_node_player_panel_th_host": "Host", - "fleet_node_player_panel_th_group_id": "Grupo", - "fleet_node_player_panel_th_enabled": "Habilitado", - "fleet_node_player_panel_th_activity": "Opciones", - "fleet_node_player_form_add_title": "Agregar Reproductor", - "fleet_node_player_form_add_submit": "Agregar", - "fleet_node_player_form_edit_title": "Editar Reproductor", - "fleet_node_player_form_edit_submit": "Guardar", - "fleet_node_player_form_label_name": "Nombre", - "fleet_node_player_form_label_group_id": "Grupo", - "fleet_node_player_form_label_host": "Host", - "fleet_node_player_form_label_operating_system": "OS", - "fleet_node_player_form_button_cancel": "Cancelar", - "js_fleet_node_player_delete_confirmation": "¿Estás seguro?", - - "fleet_node_player_group_page_title": "Playgroups", - "fleet_node_player_group_button_add": "Agregar Playgroup", - "fleet_node_player_group_panel_active": "Playgroup activos", - "fleet_node_player_group_panel_empty": "Actualmente, no hay playgroup. %link% ahora.", - "fleet_node_player_group_panel_th_name": "Nombre", - "fleet_node_player_group_panel_th_playlist": "Lista de reproducción", - "fleet_node_player_group_panel_th_activity": "Opciones", - "fleet_node_player_group_form_add_title": "Agregar Playgroup", - "fleet_node_player_group_form_add_submit": "Agregar", - "fleet_node_player_group_form_edit_title": "Editar Playgroup", - "fleet_node_player_group_form_edit_submit": "Guardar", - "fleet_node_player_group_form_label_name": "Nombre", - "fleet_node_player_group_form_label_playlist_id": "Lista de reproducción", - "fleet_node_player_group_form_button_cancel": "Cancelar", - "js_fleet_node_player_group_delete_confirmation": "¿Estás seguro?", - "node_player_group_delete_has_node_player": "El playgroup tiene reproductores, por favor elimínelos o desasígnelos antes y reintente", - - "login_page_title": "Iniciar Sesión", - "auth_page_title": "Usuarios", - "auth_user_button_add": "Agregar un usuario", - "auth_user_panel_active": "Usuarios activos", - "auth_user_panel_inactive": "Usuarios inactivos", - "auth_user_panel_empty": "Actualmente, no hay usuarios. %link% ahora.", - "auth_user_panel_th_username": "Nombre de usuario", - "auth_user_panel_th_enabled": "Habilitado", - "auth_user_panel_th_activity": "Opciones", - "auth_user_form_add_title": "Agregar Usuario", - "auth_user_form_add_submit": "Agregar", - "auth_user_form_edit_title": "Editar Usuario", - "auth_user_form_edit_submit": "Guardar", - "auth_user_form_label_username": "Nombre de usuario", - "auth_user_form_label_password": "Contraseña", - "auth_user_form_button_cancel": "Cancelar", - "auth_user_delete_at_least_one_account": "Debe tener al menos un usuario activo mientras usa la función de autenticación", - "js_auth_user_delete_confirmation": "¿Estás seguro?", - - "settings_page_title": "Configuración", - "settings_plugin_page_title": "Plugins", - "settings_variable_panel_system_variables": "Configuración general", - "settings_variable_panel_plugin_variables": "Configuración de plugins", - "settings_variable_panel_th_description": "Descripción", - "settings_variable_panel_th_value": "Valor", - "settings_variable_panel_th_activity": "Opciones", - "settings_variable_form_edit_title": "Editar Configuración", - "settings_variable_form_edit_submit": "Guardar", - "settings_variable_form_label_name": "Nombre", - "settings_variable_form_label_value": "Valor", - "settings_variable_form_button_cancel": "Cancelar", - "settings_variable_form_error_not_playlist_enabled_while_fleet_player_enabled": "No puede deshabilitar playlist mientras la gestión de reproductores de flota está activada", - "settings_variable_desc_lang": "Idioma del servidor", - "settings_variable_desc_playlist_enabled": "Habilitar gestión de playlist", - "settings_variable_desc_fleet_player_enabled": "Habilitar gestión de reproductores de flota", - "settings_variable_desc_edition_fleet_player_enabled": "La gestión de playlist también se habilitará", - "settings_variable_desc_auth_enabled": "Habilitar gestión de autenticación", - "settings_variable_desc_edition_auth_enabled": "Las credenciales predeterminadas del usuario serán admin/admin", - "settings_variable_desc_external_url": "URL externa (ej.: https://studio-01.company.com o http://10.10.3.100)", - "settings_variable_desc_slide_upload_limit": "Límite de carga de diapositivas (en megabytes)", - "settings_variable_desc_default_slide_duration": "Duración de la diapositiva de introducción (en segundos)", - "settings_variable_desc_default_slide_time_with_seconds": "Mostrar los segundos en el reloj de la diapositiva de introducción", - "settings_variable_desc_polling_interval": "Intervalo de actualización aplicado para configuraciones del reproductor (en segundos)", - "settings_variable_desc_playlist_default_time_sync": "Sincronizar diapositivas entre reproductores para la lista de reproducción predeterminada", - - "settings_variable_desc_slide_animation_enabled": "Habilitar efecto de animación entre diapositivas", - "settings_variable_desc_slide_animation_entrance_effect": "Efecto de entrada de animación de diapositiva", - "settings_variable_desc_slide_animation_exit_effect": "Efecto de salida de animación de diapositiva (generalmente mejor sin él)", - "settings_variable_desc_slide_animation_speed": "Velocidad de animación de diapositiva", - - "settings_variable_desc_ro_last_folder_content": "Carpeta actual en el explorador de contenidos", - "settings_variable_desc_ro_last_folder_node_player": "Carpeta actual en el explorador del reproductor", - "settings_variable_desc_ro_editable": "Fecha y hora del último reinicio de la aplicación", - "settings_variable_desc_ro_last_slide_update": "Fecha y hora de la última actualización de diapositiva", - "settings_variable_desc_ro_refresh_player_request": "Fecha y hora de la última solicitud de actualización del reproductor", - - "sysinfo_page_title": "Información del sistema", - "sysinfo_panel_button_restart": "Reiniciar", - "sysinfo_panel_table_section_system": "Sistema", - "sysinfo_panel_table_section_application": "Aplicación", - "sysinfo_panel_title": "Información", - "sysinfo_panel_th_attribute": "Atributo", - "sysinfo_panel_th_value": "Valor", - "sysinfo_panel_td_ipaddr": "Dirección IP", - "logs_page_title": "Logs", - "logs_panel_last_logs": "Registros (últimas 100 líneas)", - "js_sysinfo_restart_confirmation": "¿Estás seguro?", - "js_sysinfo_restart_loading": "Reiniciando, por favor espera...", - - "basic_day_1": "Lunes", - "basic_day_2": "Martes", - "basic_day_3": "Miércoles", - "basic_day_4": "Jueves", - "basic_day_5": "Viernes", - "basic_day_6": "Sábado", - "basic_day_7": "Domingo", - "basic_month_1": "Enero", - "basic_month_2": "Febrero", - "basic_month_3": "Marzo", - "basic_month_4": "Abril", - "basic_month_5": "Mayo", - "basic_month_6": "Junio", - "basic_month_7": "Julio", - "basic_month_8": "Agosto", - "basic_month_9": "Septiembre", - "basic_month_10": "Octubre", - "basic_month_11": "Noviembre", - "basic_month_12": "Diciembre", - - "common_loading": "Cargando...", - "common_default_node_player_group": "Playgroup predeterminado", - "common_default_playlist": "Lista de reproducción predeterminada", - "common_unknown_ipaddr": "Dirección IP desconocida", - "common_empty": "[Vacío]", - "common_are_you_sure": "¿Estás seguro?", - "common_enable_plugin": "Habilitar este plugin", - "common_save": "Guardar", - "common_cancel": "Cancelar", - "common_close": "Cerrar", - "common_confirm": "Confirmar", - "common_submit": "Enviar", - "common_validate": "Validar", - "common_apply": "Aplicar", - "common_saved": "Los cambios se han guardado", - "common_new_folder": "Nuevo Carpeta", - "common_folder_not_empty_error": "La carpeta no está vacía, primero debes eliminar su contenido", - "logout": "Cerrar sesión", - "login_error_not_found": "Credenciales incorrectas", - "login_error_bad_credentials": "Credenciales incorrectas", - "login_form_title": "Iniciar sesión", - "login_form_username": "Nombre de usuario", - "login_form_password": "Contraseña", - "login_form_submit": "Conectar", - "utrack_title": "Acerca de los usuarios", - "created_at": "Creado el", - "updated_at": "Modificado el", - "created_by": "Creado por", - "updated_by": "Última actualización por", - "close": "Cerrar", - "anonymous": "Anónimo", - - "enum_animation_speed_slower": "Más lento", - "enum_animation_speed_slow": "Lento", - "enum_animation_speed_normal": "Normal", - "enum_animation_speed_fast": "Rápido", - "enum_animation_speed_faster": "Más rápido", - "enum_variable_section_general": "1. General", - "enum_variable_section_player_options": "2. Opciones del reproductor", - "enum_variable_section_player_animation": "3. Animación del reproductor", - "enum_variable_section_playlist": "4. Playlist", - "enum_variable_section_fleet": "5. Gestión de flota", - "enum_variable_section_security": "6. Seguridad", - "enum_application_language_english": "Inglés", - "enum_application_language_french": "Francés", - "enum_application_language_italian": "Italiano", - "enum_application_language_spanish": "Español", - "enum_content_type_url": "URL", - "enum_content_type_video": "Video", - "enum_content_type_picture": "Imagen", - "enum_content_type_youtube": "Youtube", - "enum_content_type_url_object_label": "Ingrese el enlace URL", - "enum_content_type_video_object_label": "Sube tu vídeo (solo MP4)", - "enum_content_type_picture_object_label": "Sube tu imagen", - "enum_content_type_youtube_object_label": "Ingrese la URL del vídeo de Youtube", - "enum_operating_system_raspbian": "Raspbian", - "enum_operating_system_debian": "Debian", - "enum_operating_system_windows": "Windows", - "enum_operating_system_macos": "MacOS", - "enum_operating_system_fedora": "Fedora", - "enum_operating_system_ubuntu": "Ubuntu", - "enum_operating_system_suse": "Suse", - "enum_operating_system_redhat": "RedHat", - "enum_operating_system_centos": "CentOS", - "enum_operating_system_other": "Otro", - - "sysinfo_rpi_model": "Modelo de Raspberry Pi", - "sysinfo_rpi_model_unknown": "No es una Raspberry Pi o la información del modelo no está disponible", - "sysinfo_storage_free_space": "Espacio de almacenamiento libre", - "sysinfo_memory_usage": "Uso de memoria", - "sysinfo_os_version": "Versión del SO", - "sysinfo_install_directory": "Directorio de instalación", - "sysinfo_network_interface": "Interfaz de red", - "sysinfo_mac_address": "Dirección MAC", - "sysinfo_ip_address": "Dirección IP", - - "player_default_welcome_message": "Para gestionar este reproductor, ve a un navegador en %link%" + "dynmenu_content": "Contenido", + "slideshow_slide_page_title": "Descripción General del Programa", + "slideshow_slide_goto_player": "Ir al reproductor", + "slideshow_slide_refresh_player": "Actualizar reproductor", + "slideshow_slide_refresh_player_success": "La señal de actualización del reproductor ha sido enviada, debería suceder pronto (%time% segundos máximo)", + "slideshow_slide_button_add": "Agregar una diapositiva", + "slideshow_slide_panel_active": "Diapositivas activas", + "slideshow_slide_panel_inactive": "Diapositivas inactivas", + "slideshow_slide_panel_empty": "Actualmente, no hay diapositivas. %link% ahora.", + "slideshow_slide_panel_th_content": "Contenido", + "slideshow_slide_panel_th_duration": "Termina después", + "slideshow_slide_panel_th_duration_unit": "seg", + "slideshow_slide_panel_th_enabled": "Habilitado", + "slideshow_slide_panel_th_cron_scheduled": "Inicio Programado", + "slideshow_slide_panel_th_activity": "Opciones", + "slideshow_slide_panel_td_cron_scheduled_loop": "Bucle", + "slideshow_slide_panel_td_cron_scheduled_notify": "Notificar", + "slideshow_slide_panel_td_cron_scheduled_bad_cron": "Valor de cron incorrecto", + "slideshow_slide_form_add_title": "Agregar Diapositiva", + "slideshow_slide_form_add_submit": "Agregar", + "slideshow_slide_form_edit_title": "Editar Diapositiva", + "slideshow_slide_form_edit_submit": "Guardar", + "slideshow_slide_form_section_content": "Medios", + "slideshow_slide_form_section_scheduling": "Programación", + "slideshow_slide_form_label_name": "Nombre", + "slideshow_slide_form_label_add_content": "Agregar a la biblioteca", + "slideshow_slide_form_label_from_library": "Dalla biblioteca", + "slideshow_slide_form_label_content_id": "Contenido", + "slideshow_slide_form_label_location": "Ubicación", + "slideshow_slide_form_label_type": "Tipo", + "slideshow_slide_form_label_object": "Objeto", + "slideshow_slide_form_label_duration": "Duración", + "slideshow_slide_form_label_duration_unit": "segundos", + "slideshow_slide_form_label_is_notification": "Actuar como notificación", + "slideshow_slide_form_label_cron_scheduled": "Inicio", + "slideshow_slide_form_label_cron_scheduled_end": "Fin", + "slideshow_slide_form_label_cron_scheduled_loop": "Siempre en bucle", + "slideshow_slide_form_label_cron_scheduled_duration": "Duración", + "slideshow_slide_form_label_cron_scheduled_stayloop": "Seguir el bucle", + "slideshow_slide_form_label_cron_scheduled_duration_unit": "segundos", + "slideshow_slide_form_label_cron_scheduled_datetime": "Fecha y Hora", + "slideshow_slide_form_label_cron_scheduled_datetime_placeholder": "Establecer una fecha y hora", + "slideshow_slide_form_label_cron_scheduled_cron": "Cron", + "slideshow_slide_form_widget_cron_scheduled_placeholder": "Usar formato crontab: * * * * *", + "slideshow_slide_form_button_cancel": "Cancelar", + "js_slideshow_slide_delete_confirmation": "¿Estás seguro?", + "slideshow_content_page_title": "Biblioteca de contenidos", + "slideshow_content_button_add": "Nuevo Contenido", + "slideshow_content_referenced_in_slide_error": "Se hace referencia al contenido en una diapositiva; elimine la diapositiva primero", + "slideshow_content_panel_active": "Contenido", + "slideshow_content_panel_empty": "Actualmente, no hay contenido. %link% ahora.", + "slideshow_content_panel_th_name": "Nombre", + "slideshow_content_panel_th_activity": "Opciones", + "slideshow_content_form_add_title": "Agregar Contenido", + "slideshow_content_form_add_submit": "Agregar", + "slideshow_content_form_edit_title": "Editar Contenido", + "slideshow_content_form_edit_submit": "Guardar", + "slideshow_content_form_label_name": "Nombre", + "slideshow_content_form_label_location": "Ubicación", + "slideshow_content_form_label_type": "Tipo", + "slideshow_content_form_label_object": "Objeto", + "slideshow_content_form_button_cancel": "Cancelar", + "slideshow_content_form_button_upload": "Subir un archivo", + "slideshow_content_form_button_upload_choosen": "No hay archivos seleccionados", + "js_slideshow_content_delete_confirmation": "¿Estás seguro?", + "playlist_page_title": "Playlists", + "playlist_button_add": "Agregar Playlist", + "playlist_button_delete": "Eliminar Playlist", + "playlist_panel_about_playlist": "Acerca de la playlist", + "playlist_panel_content_management": "Gestión de contenido", + "playlist_panel_preview": "Vista previa de la playlist", + "playlist_panel_preview_action": "Avance", + "playlist_panel_inactive": "Playlist inactivas", + "playlist_panel_empty": "Actualmente, no hay playlist. %link% ahora.", + "playlist_panel_th_name": "Nombre", + "playlist_panel_th_duration": "Duración", + "playlist_panel_th_enabled": "Habilitado", + "playlist_panel_th_activity": "Opciones", + "playlist_form_add_title": "Agregar Playlist", + "playlist_form_add_submit": "Agregar", + "playlist_form_preview_url_desc": "Puedes usar este enlace para reproducir esta playlist en cualquier navegador que desees. Usa el botón Copiar para guardarla en tu portapapeles.", + "playlist_form_preview_qrcode_desc": "Puedes acceder fácilmente a tu playlist usando una tableta o un teléfono. Simplemente escanea el código QR para comenzar.", + "playlist_form_preview_iframe_desc": "Puedes ver la playlist sin salir de esta pantalla iniciando la vista previa desde aquí.", + "playlist_form_label_name": "Introduce el nombre de la playlist", + "playlist_form_label_time_sync": "Sincronizar diapositivas entre reproductores", + "playlist_form_label_enabled": "Activar/Desactivar playlist", + "playlist_form_button_cancel": "Cancelar", + "js_playlist_delete_confirmation": "¿Estás seguro?", + "playlist_delete_has_slides": "La playlist tiene diapositivas, por favor elimínelas antes y reintente", + "playlist_delete_has_node_player_groups": "La playlist está asignada a un playgroup", + "fleet_node_player_page_title": "Reproductores", + "fleet_node_player_button_add": "Agregar un reproductor", + "fleet_node_player_panel_active": "Reproductores activos", + "fleet_node_player_panel_inactive": "Reproductores inactivos", + "fleet_node_player_panel_empty": "Actualmente, no hay reproductores. %link% ahora.", + "fleet_node_player_panel_th_name": "Nombre", + "fleet_node_player_panel_th_host": "Host", + "fleet_node_player_panel_th_group_id": "Grupo", + "fleet_node_player_panel_th_enabled": "Habilitado", + "fleet_node_player_panel_th_activity": "Opciones", + "fleet_node_player_form_add_title": "Agregar Reproductor", + "fleet_node_player_form_add_submit": "Agregar", + "fleet_node_player_form_edit_title": "Editar Reproductor", + "fleet_node_player_form_edit_submit": "Guardar", + "fleet_node_player_form_label_name": "Nombre", + "fleet_node_player_form_label_group_id": "Grupo", + "fleet_node_player_form_label_host": "Host", + "fleet_node_player_form_label_operating_system": "OS", + "fleet_node_player_form_button_cancel": "Cancelar", + "js_fleet_node_player_delete_confirmation": "¿Estás seguro?", + "fleet_node_player_group_page_title": "Playgroups", + "fleet_node_player_group_button_add": "Agregar Playgroup", + "fleet_node_player_group_panel_active": "Playgroup activos", + "fleet_node_player_group_panel_empty": "Actualmente, no hay playgroup. %link% ahora.", + "fleet_node_player_group_panel_th_name": "Nombre", + "fleet_node_player_group_panel_th_playlist": "Lista de reproducción", + "fleet_node_player_group_panel_th_activity": "Opciones", + "fleet_node_player_group_form_add_title": "Agregar Playgroup", + "fleet_node_player_group_form_add_submit": "Agregar", + "fleet_node_player_group_form_edit_title": "Editar Playgroup", + "fleet_node_player_group_form_edit_submit": "Guardar", + "fleet_node_player_group_form_label_name": "Nombre", + "fleet_node_player_group_form_label_playlist_id": "Lista de reproducción", + "fleet_node_player_group_form_button_cancel": "Cancelar", + "js_fleet_node_player_group_delete_confirmation": "¿Estás seguro?", + "node_player_group_delete_has_node_player": "El playgroup tiene reproductores, por favor elimínelos o desasígnelos antes y reintente", + "login_page_title": "Iniciar Sesión", + "auth_page_title": "Usuarios", + "auth_user_button_add": "Agregar un usuario", + "auth_user_panel_active": "Usuarios activos", + "auth_user_panel_inactive": "Usuarios inactivos", + "auth_user_panel_empty": "Actualmente, no hay usuarios. %link% ahora.", + "auth_user_panel_th_username": "Nombre de usuario", + "auth_user_panel_th_enabled": "Habilitado", + "auth_user_panel_th_activity": "Opciones", + "auth_user_form_add_title": "Agregar Usuario", + "auth_user_form_add_submit": "Agregar", + "auth_user_form_edit_title": "Editar Usuario", + "auth_user_form_edit_submit": "Guardar", + "auth_user_form_label_username": "Nombre de usuario", + "auth_user_form_label_password": "Contraseña", + "auth_user_form_button_cancel": "Cancelar", + "auth_user_delete_at_least_one_account": "Debe tener al menos un usuario activo mientras usa la función de autenticación", + "js_auth_user_delete_confirmation": "¿Estás seguro?", + "settings_page_title": "Configuración", + "settings_plugin_page_title": "Plugins", + "settings_variable_panel_system_variables": "Configuración general", + "settings_variable_panel_plugin_variables": "Configuración de plugins", + "settings_variable_panel_th_description": "Descripción", + "settings_variable_panel_th_value": "Valor", + "settings_variable_panel_th_activity": "Opciones", + "settings_variable_form_edit_title": "Editar Configuración", + "settings_variable_form_edit_submit": "Guardar", + "settings_variable_form_label_name": "Nombre", + "settings_variable_form_label_value": "Valor", + "settings_variable_form_button_cancel": "Cancelar", + "settings_variable_form_error_not_playlist_enabled_while_fleet_player_enabled": "No puede deshabilitar playlist mientras la gestión de reproductores de flota está activada", + "settings_variable_desc_lang": "Idioma del servidor", + "settings_variable_desc_playlist_enabled": "Habilitar gestión de playlist", + "settings_variable_desc_fleet_player_enabled": "Habilitar gestión de reproductores de flota", + "settings_variable_desc_edition_fleet_player_enabled": "La gestión de playlist también se habilitará", + "settings_variable_desc_auth_enabled": "Habilitar gestión de autenticación", + "settings_variable_desc_edition_auth_enabled": "Las credenciales predeterminadas del usuario serán admin/admin", + "settings_variable_desc_external_url": "URL externa (ej.: https://studio-01.company.com o http://10.10.3.100)", + "settings_variable_desc_slide_upload_limit": "Límite de carga de diapositivas (en megabytes)", + "settings_variable_desc_intro_slide_duration": "Duración de la diapositiva de introducción (en segundos)", + "settings_variable_desc_default_slide_time_with_seconds": "Mostrar los segundos en el reloj de la diapositiva de introducción", + "settings_variable_desc_polling_interval": "Intervalo de actualización aplicado para configuraciones del reproductor (en segundos)", + "settings_variable_desc_playlist_default_time_sync": "Sincronizar diapositivas entre reproductores para la playlist predeterminada", + "settings_variable_desc_slide_animation_enabled": "Habilitar efecto de animación entre diapositivas", + "settings_variable_desc_slide_animation_entrance_effect": "Efecto de entrada de animación de diapositiva", + "settings_variable_desc_slide_animation_exit_effect": "Efecto de salida de animación de diapositiva (generalmente mejor sin él)", + "settings_variable_desc_slide_animation_speed": "Velocidad de animación de diapositiva", + "settings_variable_desc_ro_start_counter": "Contador de inicio", + "settings_variable_desc_ro_last_folder_content": "Carpeta actual en el explorador de contenidos", + "settings_variable_desc_ro_last_folder_node_player": "Carpeta actual en el explorador del reproductor", + "settings_variable_desc_ro_editable": "Fecha y hora del último reinicio de la aplicación", + "settings_variable_desc_ro_last_slide_update": "Fecha y hora de la última actualización de diapositiva", + "settings_variable_desc_ro_refresh_player_request": "Fecha y hora de la última solicitud de actualización del reproductor", + "sysinfo_page_title": "Información del sistema", + "sysinfo_panel_button_restart": "Reiniciar", + "sysinfo_panel_table_section_system": "Sistema", + "sysinfo_panel_table_section_application": "Aplicación", + "sysinfo_panel_title": "Información", + "sysinfo_panel_th_attribute": "Atributo", + "sysinfo_panel_th_value": "Valor", + "sysinfo_panel_td_ipaddr": "Dirección IP", + "logs_page_title": "Logs", + "logs_panel_last_logs": "Registros (últimas 100 líneas)", + "js_sysinfo_restart_confirmation": "¿Estás seguro?", + "js_sysinfo_restart_loading": "Reiniciando, por favor espera...", + "basic_day_1": "Lunes", + "basic_day_2": "Martes", + "basic_day_3": "Miércoles", + "basic_day_4": "Jueves", + "basic_day_5": "Viernes", + "basic_day_6": "Sábado", + "basic_day_7": "Domingo", + "basic_month_1": "Enero", + "basic_month_2": "Febrero", + "basic_month_3": "Marzo", + "basic_month_4": "Abril", + "basic_month_5": "Mayo", + "basic_month_6": "Junio", + "basic_month_7": "Julio", + "basic_month_8": "Agosto", + "basic_month_9": "Septiembre", + "basic_month_10": "Octubre", + "basic_month_11": "Noviembre", + "basic_month_12": "Diciembre", + "common_untitled": "", + "common_loading": "Cargando...", + "common_default_node_player_group": "Playgroup predeterminado", + "common_default_playlist": "Lista de reproducción predeterminada", + "common_unknown_ipaddr": "Dirección IP desconocida", + "common_empty": "[Vacío]", + "common_are_you_sure": "¿Estás seguro?", + "common_enable_plugin": "Habilitar este plugin", + "common_save": "Guardar", + "common_cancel": "Cancelar", + "common_close": "Cerrar", + "common_confirm": "Confirmar", + "common_submit": "Enviar", + "common_validate": "Validar", + "common_apply": "Aplicar", + "common_saved": "Los cambios se han guardado", + "common_new_folder": "Nuevo Carpeta", + "common_folder_not_empty_error": "La carpeta no está vacía, primero debes eliminar su contenido", + "logout": "Cerrar sesión", + "login_error_not_found": "Credenciales incorrectas", + "login_error_bad_credentials": "Credenciales incorrectas", + "login_form_title": "Iniciar sesión", + "login_form_username": "Nombre de usuario", + "login_form_password": "Contraseña", + "login_form_submit": "Conectar", + "utrack_title": "Acerca de los usuarios", + "created_at": "Creado el", + "updated_at": "Modificado el", + "created_by": "Creado por", + "updated_by": "Última actualización por", + "close": "Cerrar", + "anonymous": "Anónimo", + "enum_animation_speed_slower": "Más lento", + "enum_animation_speed_slow": "Lento", + "enum_animation_speed_normal": "Normal", + "enum_animation_speed_fast": "Rápido", + "enum_animation_speed_faster": "Más rápido", + "enum_variable_section_general": "1. General", + "enum_variable_section_player_options": "2. Opciones del reproductor", + "enum_variable_section_player_animation": "3. Animación del reproductor", + "enum_variable_section_playlist": "4. Playlist", + "enum_variable_section_fleet": "5. Gestión de flota", + "enum_variable_section_security": "6. Seguridad", + "enum_application_language_english": "Inglés", + "enum_application_language_french": "Francés", + "enum_application_language_italian": "Italiano", + "enum_application_language_spanish": "Español", + "enum_content_type_url": "URL", + "enum_content_type_video": "Video", + "enum_content_type_picture": "Imagen", + "enum_content_type_youtube": "Youtube", + "enum_content_type_url_object_label": "Ingrese el enlace URL", + "enum_content_type_video_object_label": "Sube tu vídeo (solo MP4)", + "enum_content_type_picture_object_label": "Sube tu imagen", + "enum_content_type_youtube_object_label": "Ingrese la URL del vídeo de Youtube", + "enum_operating_system_raspbian": "Raspbian", + "enum_operating_system_debian": "Debian", + "enum_operating_system_windows": "Windows", + "enum_operating_system_macos": "MacOS", + "enum_operating_system_fedora": "Fedora", + "enum_operating_system_ubuntu": "Ubuntu", + "enum_operating_system_suse": "Suse", + "enum_operating_system_redhat": "RedHat", + "enum_operating_system_centos": "CentOS", + "enum_operating_system_other": "Otro", + "sysinfo_rpi_model": "Modelo de Raspberry Pi", + "sysinfo_rpi_model_unknown": "No es una Raspberry Pi o la información del modelo no está disponible", + "sysinfo_storage_free_space": "Espacio de almacenamiento libre", + "sysinfo_memory_usage": "Uso de memoria", + "sysinfo_os_version": "Versión del SO", + "sysinfo_install_directory": "Directorio de instalación", + "sysinfo_network_interface": "Interfaz de red", + "sysinfo_mac_address": "Dirección MAC", + "sysinfo_ip_address": "Dirección IP", + "player_default_welcome_message": "Para gestionar este reproductor, ve a un navegador en %link%" } diff --git a/lang/fr.json b/lang/fr.json index f1353d3..f5b8824 100644 --- a/lang/fr.json +++ b/lang/fr.json @@ -1,294 +1,288 @@ { - "dynmenu_content": "Contenu", - - "slideshow_slide_page_title": "Vue Planning", - "slideshow_slide_goto_player": "Voir le lecteur", - "slideshow_slide_refresh_player": "Rafraîchir le lecteur", - "slideshow_slide_refresh_player_success": "Un rafraîchissement du lecteur a été programmé, il devrait avoir lieu sous peu (%time% secondes maximum)", - "slideshow_slide_button_add": "Ajouter une slide", - "slideshow_slide_panel_active": "Slides actives", - "slideshow_slide_panel_inactive": "Slides inactives", - "slideshow_slide_panel_empty": "Actuellement, il n'y a aucune slide. %link% maintenant.", - "slideshow_slide_panel_th_content": "Contenu", - "slideshow_slide_panel_th_duration": "Fin après", - "slideshow_slide_panel_th_duration_unit": "sec", - "slideshow_slide_panel_th_enabled": "Activé", - "slideshow_slide_panel_th_cron_scheduled": "Programmation", - "slideshow_slide_panel_th_activity": "Options", - "slideshow_slide_panel_td_cron_scheduled_loop": "En boucle", - "slideshow_slide_panel_td_cron_scheduled_notify": "Notifie", - "slideshow_slide_panel_td_cron_scheduled_bad_cron": "Mauvaise valeur cron", - "slideshow_slide_form_add_title": "Ajout d'une slide", - "slideshow_slide_form_add_submit": "Ajouter", - "slideshow_slide_form_edit_title": "Modification d'une slide", - "slideshow_slide_form_edit_submit": "Enregistrer", - "slideshow_slide_form_section_content": "Media", - "slideshow_slide_form_section_scheduling": "Programmation", - "slideshow_slide_form_label_name": "Nom", - "slideshow_slide_form_label_add_content": "Ajouter à la bibliothèque", - "slideshow_slide_form_label_from_library": "Depuis la bibliothèque", - "slideshow_slide_form_label_content_id": "Contenu", - "slideshow_slide_form_label_location": "Chemin", - "slideshow_slide_form_label_type": "Type", - "slideshow_slide_form_label_object": "Objet", - "slideshow_slide_form_label_duration": "Durée", - "slideshow_slide_form_label_duration_unit": "secondes", - "slideshow_slide_form_label_is_notification": "Agit comme une notification", - "slideshow_slide_form_label_cron_scheduled": "Début", - "slideshow_slide_form_label_cron_scheduled_end": "Fin", - "slideshow_slide_form_label_cron_scheduled_loop": "Toujours en boucle", - "slideshow_slide_form_label_cron_scheduled_duration": "Durée", - "slideshow_slide_form_label_cron_scheduled_stayloop": "Suit la boucle", - "slideshow_slide_form_label_cron_scheduled_duration_unit": "secondes", - "slideshow_slide_form_label_cron_scheduled_datetime": "Date & Heure", - "slideshow_slide_form_label_cron_scheduled_datetime_placeholder": "Choisir une date et une heure", - "slideshow_slide_form_label_cron_scheduled_cron": "Cron", - "slideshow_slide_form_widget_cron_scheduled_placeholder": "Utiliser le format crontab: * * * * *", - "slideshow_slide_form_button_cancel": "Annuler", - "js_slideshow_slide_delete_confirmation": "Êtes-vous sûr ?", - - "slideshow_content_page_title": "Bibliothèque de contenus", - "slideshow_content_button_add": "Nouveau Contenu", - "slideshow_content_referenced_in_slide_error": "Le contenu est référencé dans une slide, supprimez d'abord la slide", - "slideshow_content_panel_active": "Contenus", - "slideshow_content_panel_empty": "Actuellement, il n'y a aucun contenu. %link% maintenant.", - "slideshow_content_panel_th_name": "Nom", - "slideshow_content_panel_th_activity": "Options", - "slideshow_content_form_add_title": "Ajout d'un contenu", - "slideshow_content_form_add_submit": "Ajouter", - "slideshow_content_form_edit_title": "Modification d'un contenu", - "slideshow_content_form_edit_submit": "Enregistrer", - "slideshow_content_form_label_name": "Nom de l'élément", - "slideshow_content_form_label_location": "Chemin", - "slideshow_content_form_label_type": "Type", - "slideshow_content_form_label_object": "Objet", - "slideshow_content_form_button_cancel": "Annuler", - "slideshow_content_form_button_upload": "Uploader un fichier", - "slideshow_content_form_button_upload_choosen": "Aucun fichier sélectionné", - "js_slideshow_content_delete_confirmation": "Êtes-vous sûr ?", - - "playlist_page_title": "Playlist", - "playlist_button_add": "Ajouter une playlist", - "playlist_panel_active": "Playlist actives", - "playlist_panel_inactive": "Playlist inactives", - "playlist_panel_empty": "Actuellement, il n'y a pas de playlist. %link% maintenant.", - "playlist_panel_th_name": "Nom", - "playlist_panel_th_duration": "Durée", - "playlist_panel_th_enabled": "Activé", - "playlist_panel_th_activity": "Options", - "playlist_form_add_title": "Ajout d'une Playlist", - "playlist_form_add_submit": "Ajouter", - "playlist_form_edit_title": "Modification d'une Playlist", - "playlist_form_edit_submit": "Enregistrer", - "playlist_form_label_name": "Entrez le nom de la playlist", - "playlist_form_label_time_sync": "Synchroniser les slides des lecteurs", - "playlist_form_button_cancel": "Annuler", - "js_playlist_delete_confirmation": "Êtes-vous sûr ?", - "playlist_delete_has_slides": "La playlist contient des slides, supprimez-les avant et réessayez", - "playlist_delete_has_node_player_groups": "La playlist est attribuée à un playgroup", - - "fleet_node_player_page_title": "Lecteurs", - "fleet_node_player_button_add": "Ajouter un lecteur", - "fleet_node_player_panel_active": "Players actifs", - "fleet_node_player_panel_inactive": "Players inactifs", - "fleet_node_player_panel_empty": "Actuellement, il n'y a pas de lecteurs. %link% maintenant.", - "fleet_node_player_panel_th_name": "Nom", - "fleet_node_player_panel_th_host": "Hôte", - "fleet_node_player_panel_th_group_id": "Groupe", - "fleet_node_player_panel_th_enabled": "Activé", - "fleet_node_player_panel_th_activity": "Options", - "fleet_node_player_form_add_title": "Ajout d'un lecteur", - "fleet_node_player_form_add_submit": "Ajouter", - "fleet_node_player_form_edit_title": "Modification d'un lecteur", - "fleet_node_player_form_edit_submit": "Enregistrer", - "fleet_node_player_form_label_name": "Nom", - "fleet_node_player_form_label_group_id": "Groupe", - "fleet_node_player_form_label_host": "Hôte", - "fleet_node_player_form_label_operating_system": "OS", - "fleet_node_player_form_button_cancel": "Annuler", - "js_fleet_node_player_delete_confirmation": "Êtes-vous sûr ?", - - "fleet_node_player_group_page_title": "Playgroups", - "fleet_node_player_group_button_add": "Ajouter un Playgroup", - "fleet_node_player_group_panel_active": "Playgroups", - "fleet_node_player_group_panel_empty": "Actuellement, il n'y a pas de playgroup. %link% maintenant.", - "fleet_node_player_group_panel_th_name": "Nom", - "fleet_node_player_group_panel_th_playlist": "Liste de lecture", - "fleet_node_player_group_panel_th_activity": "Options", - "fleet_node_player_group_form_add_title": "Ajout d'un playgroup", - "fleet_node_player_group_form_add_submit": "Ajouter", - "fleet_node_player_group_form_edit_title": "Modification d'un playgroup", - "fleet_node_player_group_form_edit_submit": "Enregistrer", - "fleet_node_player_group_form_label_name": "Nom", - "fleet_node_player_group_form_label_playlist_id": "Liste de lecture", - "fleet_node_player_group_form_button_cancel": "Annuler", - "js_fleet_node_player_group_delete_confirmation": "Êtes-vous sûr ?", - "node_player_group_delete_has_node_player": "Le playgroup a des lecteurs, supprimez-les ou réassignez-les avant de le supprimer", - - "login_page_title": "Connexion", - "auth_page_title": "Utilisateurs", - "auth_user_button_add": "Ajouter un utilisateur", - "auth_user_panel_active": "Utilisateurs actifs", - "auth_user_panel_inactive": "Utilisateurs inactifs", - "auth_user_panel_empty": "Actuellement, il n'y a pas d'utilisateurs. %link% maintenant.", - "auth_user_panel_th_username": "Nom d'utilisateur", - "auth_user_panel_th_enabled": "Activé", - "auth_user_panel_th_activity": "Options", - "auth_user_form_add_title": "Ajout d'un utilisateur", - "auth_user_form_add_submit": "Ajouter", - "auth_user_form_edit_title": "Modification d'un utilisateur", - "auth_user_form_edit_submit": "Enregistrer", - "auth_user_form_label_username": "Nom d'utilisateur", - "auth_user_form_label_password": "Mot de passe", - "auth_user_form_button_cancel": "Annuler", - "auth_user_delete_at_least_one_account": "Vous devez avoir au moins un utilisateur actif lorsque vous activez la gestion de l'authentification", - "js_auth_user_delete_confirmation": "Êtes-vous sûr ?", - - "settings_page_title": "Paramètres", - "settings_plugin_page_title": "Plugins", - "settings_variable_panel_system_variables": "Paramètres généraux", - "settings_variable_panel_plugin_variables": "Paramètres des plugins", - "settings_variable_panel_th_description": "Description", - "settings_variable_panel_th_value": "Valeur", - "settings_variable_panel_th_activity": "Options", - "settings_variable_form_edit_title": "Modification du paramètre", - "settings_variable_form_edit_submit": "Enregistrer", - "settings_variable_form_label_name": "Nom", - "settings_variable_form_label_value": "Valeur", - "settings_variable_form_button_cancel": "Annuler", - "settings_variable_form_error_not_playlist_enabled_while_fleet_player_enabled": "Vous ne pouvez pas désactiver les playlists tant que la gestion de flotte de lecteurs est activée", - "settings_variable_desc_lang": "Langage de l'application", - "settings_variable_desc_playlist_enabled": "Activer la gestion des playlists", - "settings_variable_desc_fleet_player_enabled": "Activer la gestion de flotte des players", - "settings_variable_desc_edition_fleet_player_enabled": "Les playlists seront également activées", - "settings_variable_desc_auth_enabled": "Activer la gestion de l'authentification", - "settings_variable_desc_edition_auth_enabled": "Les identifiants de l'utilisateur par défaut seront admin/admin", - "settings_variable_desc_external_url": "URL externe (i.e: https://studio-01.company.com or http://10.10.3.100)", - "settings_variable_desc_slide_upload_limit": "Limite d'upload du fichier d'une slide (en mégaoctets)", - "settings_variable_desc_default_slide_duration": "Durée de la slide d'introduction (en secondes)", - "settings_variable_desc_default_slide_time_with_seconds": "Afficher les secondes de l'horloge de la slide d'introduction", - "settings_variable_desc_polling_interval": "Intervalle de rafraîchissement des paramètres à appliquer au lecteur (en secondes)", - "settings_variable_desc_playlist_default_time_sync": "Synchroniser les slides des lecteurs pour la playlist par défaut", - - "settings_variable_desc_slide_animation_enabled": "Activer les effets d'animation entre les slides", - "settings_variable_desc_slide_animation_entrance_effect": "Effet d'animation d'arrivée de la slide", - "settings_variable_desc_slide_animation_exit_effect": "Effet d'animation de sortie de la slide (généralement mieux sans)", - "settings_variable_desc_slide_animation_speed": "Vitesse de l'animation de la slide", - - "settings_variable_desc_ro_last_folder_content": "Dossier courant dans l'explorateur de contenu", - "settings_variable_desc_ro_last_folder_node_player": "Dossier courant dans l'explorateur du lecteur", - "settings_variable_desc_ro_editable": "Date de dernier redémarrage de l'application", - "settings_variable_desc_ro_last_slide_update": "Date de dernière modification d'une slide", - "settings_variable_desc_ro_refresh_player_request": "Date de dernière demande de rafraîchissement du lecteur", - - "sysinfo_page_title": "Système", - "sysinfo_panel_button_restart": "Redémarrer", - "sysinfo_panel_table_section_system": "Système", - "sysinfo_panel_table_section_application": "Application", - "sysinfo_panel_title": "Informations", - "sysinfo_panel_th_attribute": "Attribut", - "sysinfo_panel_th_value": "Valeur", - "sysinfo_panel_td_ipaddr": "Adresse IP", - "logs_page_title": "Logs", - "logs_panel_last_logs": "Journaux (100 dernières lignes)", - "js_sysinfo_restart_confirmation": "Êtes-vous sûr ?", - "js_sysinfo_restart_loading": "Redémarrage en cours, veuillez patienter...", - - "basic_day_1": "Lundi", - "basic_day_2": "Mardi", - "basic_day_3": "Mercredi", - "basic_day_4": "Jeudi", - "basic_day_5": "Vendredi", - "basic_day_6": "Samedi", - "basic_day_7": "Dimanche", - "basic_month_1": "Janvier", - "basic_month_2": "Février", - "basic_month_3": "Mars", - "basic_month_4": "Avril", - "basic_month_5": "Mai", - "basic_month_6": "Juin", - "basic_month_7": "Juillet", - "basic_month_8": "Août", - "basic_month_9": "Septembre", - "basic_month_10": "Octobre", - "basic_month_11": "Novembre", - "basic_month_12": "Décembre", - - "common_loading": "Chargement...", - "common_default_node_player_group": "Playgroup par défaut", - "common_default_playlist": "Playlist par défaut", - "common_unknown_ipaddr": "Adresse IP inconnue", - "common_empty": "[Vide]", - "common_are_you_sure": "Êtes-vous sûr ?", - "common_enable_plugin": "Activer ce plugin", - "common_save": "Enregistrer", - "common_cancel": "Annuler", - "common_close": "Fermer", - "common_confirm": "Confirmer", - "common_submit": "Envoyer", - "common_validate": "Valider", - "common_apply": "Appliquer", - "common_saved": "Les modifications ont été enregistrées", - "common_new_folder": "Nouveau Dossier", - "common_folder_not_empty_error": "Le dossier n'est pas vide, vous devez d'abord supprimer son contenu", - "logout": "Déconnexion", - "login_error_not_found": "Identifiants invalides", - "login_error_bad_credentials": "Identifiants invalides", - "login_form_title": "Connexion", - "login_form_username": "Identifiant", - "login_form_password": "Mot de passe", - "login_form_submit": "Valider", - "utrack_title": "À propos des utilisateurs", - "created_at": "Création le", - "updated_at": "Modification le", - "created_by": "Création par", - "updated_by": "Dernière modification par", - "close": "Fermer", - "anonymous": "Anon", - - "enum_animation_speed_slower": "Très lent", - "enum_animation_speed_slow": "Lent", - "enum_animation_speed_normal": "Normal", - "enum_animation_speed_fast": "Rapide", - "enum_animation_speed_faster": "Très rapide", - "enum_variable_section_general": "1. Général", - "enum_variable_section_player_options": "2. Options du lecteur", - "enum_variable_section_player_animation": "3. Animation du lecteur", - "enum_variable_section_playlist": "4. Playlists", - "enum_variable_section_fleet": "5. Gestion de flotte", - "enum_variable_section_security": "6. Sécurité", - "enum_application_language_english": "Anglais", - "enum_application_language_french": "Français", - "enum_application_language_italian": "Italien", - "enum_application_language_spanish": "Espagnol", - "enum_content_type_url": "URL", - "enum_content_type_video": "Vidéo", - "enum_content_type_picture": "Image", - "enum_content_type_youtube": "Youtube", - "enum_content_type_url_object_label": "Entrez l'URL de la page", - "enum_content_type_video_object_label": "Uploadez votre vidéo (MP4 seulement)", - "enum_content_type_picture_object_label": "Uploadez votre image", - "enum_content_type_youtube_object_label": "Enrez l'URL de la vidéo Youtube", - "enum_operating_system_raspbian": "Raspbian", - "enum_operating_system_debian": "Debian", - "enum_operating_system_windows": "Windows", - "enum_operating_system_macos": "MacOS", - "enum_operating_system_fedora": "Fedora", - "enum_operating_system_ubuntu": "Ubuntu", - "enum_operating_system_suse": "Suse", - "enum_operating_system_redhat": "RedHat", - "enum_operating_system_centos": "CentOS", - "enum_operating_system_other": "Autre", - - "sysinfo_rpi_model": "Modèle du Raspberry Pi", - "sysinfo_rpi_model_unknown": "Le modèle n'est pas un Raspberry Pi", - "sysinfo_storage_free_space": "Stockage Disponible", - "sysinfo_memory_usage": "Utilisation Mémoire", - "sysinfo_os_version": "Version SE", - "sysinfo_install_directory": "Dossier Racine", - "sysinfo_network_interface": "Interface Réseau", - "sysinfo_mac_address": "Addresse MAC", - "sysinfo_ip_address": "Addresse IP", - - "player_default_welcome_message": "Pour gérer ce lecteur, allez sur un navigateur à l'adresse %link%" + "dynmenu_content": "Contenu", + "slideshow_slide_page_title": "Vue Planning", + "slideshow_slide_goto_player": "Voir le lecteur", + "slideshow_slide_refresh_player": "Rafraîchir le lecteur", + "slideshow_slide_refresh_player_success": "Un rafraîchissement du lecteur a été programmé, il devrait avoir lieu sous peu (%time% secondes maximum)", + "slideshow_slide_button_add": "Ajouter une slide", + "slideshow_slide_panel_active": "Slides actives", + "slideshow_slide_panel_inactive": "Slides inactives", + "slideshow_slide_panel_empty": "Actuellement, il n'y a aucune slide. %link% maintenant.", + "slideshow_slide_panel_th_content": "Contenu", + "slideshow_slide_panel_th_duration": "Fin après", + "slideshow_slide_panel_th_duration_unit": "sec", + "slideshow_slide_panel_th_enabled": "Activé", + "slideshow_slide_panel_th_cron_scheduled": "Programmation", + "slideshow_slide_panel_th_activity": "Options", + "slideshow_slide_panel_td_cron_scheduled_loop": "En boucle", + "slideshow_slide_panel_td_cron_scheduled_notify": "Notifie", + "slideshow_slide_panel_td_cron_scheduled_bad_cron": "Mauvaise valeur cron", + "slideshow_slide_form_add_title": "Ajout d'une slide", + "slideshow_slide_form_add_submit": "Ajouter", + "slideshow_slide_form_edit_title": "Modification d'une slide", + "slideshow_slide_form_edit_submit": "Enregistrer", + "slideshow_slide_form_section_content": "Media", + "slideshow_slide_form_section_scheduling": "Programmation", + "slideshow_slide_form_label_name": "Nom", + "slideshow_slide_form_label_add_content": "Ajouter à la bibliothèque", + "slideshow_slide_form_label_from_library": "Depuis la bibliothèque", + "slideshow_slide_form_label_content_id": "Contenu", + "slideshow_slide_form_label_location": "Chemin", + "slideshow_slide_form_label_type": "Type", + "slideshow_slide_form_label_object": "Objet", + "slideshow_slide_form_label_duration": "Durée", + "slideshow_slide_form_label_duration_unit": "secondes", + "slideshow_slide_form_label_is_notification": "Agit comme une notification", + "slideshow_slide_form_label_cron_scheduled": "Début", + "slideshow_slide_form_label_cron_scheduled_end": "Fin", + "slideshow_slide_form_label_cron_scheduled_loop": "Toujours en boucle", + "slideshow_slide_form_label_cron_scheduled_duration": "Durée", + "slideshow_slide_form_label_cron_scheduled_stayloop": "Suit la boucle", + "slideshow_slide_form_label_cron_scheduled_duration_unit": "secondes", + "slideshow_slide_form_label_cron_scheduled_datetime": "Date & Heure", + "slideshow_slide_form_label_cron_scheduled_datetime_placeholder": "Choisir une date et une heure", + "slideshow_slide_form_label_cron_scheduled_cron": "Cron", + "slideshow_slide_form_widget_cron_scheduled_placeholder": "Utiliser le format crontab: * * * * *", + "slideshow_slide_form_button_cancel": "Annuler", + "js_slideshow_slide_delete_confirmation": "Êtes-vous sûr ?", + "slideshow_content_page_title": "Bibliothèque de contenus", + "slideshow_content_button_add": "Nouveau Contenu", + "slideshow_content_referenced_in_slide_error": "Le contenu est référencé dans une slide, supprimez d'abord la slide", + "slideshow_content_panel_active": "Contenus", + "slideshow_content_panel_empty": "Actuellement, il n'y a aucun contenu. %link% maintenant.", + "slideshow_content_panel_th_name": "Nom", + "slideshow_content_panel_th_activity": "Options", + "slideshow_content_form_add_title": "Ajout d'un contenu", + "slideshow_content_form_add_submit": "Ajouter", + "slideshow_content_form_edit_title": "Modification d'un contenu", + "slideshow_content_form_edit_submit": "Enregistrer", + "slideshow_content_form_label_name": "Nom de l'élément", + "slideshow_content_form_label_location": "Chemin", + "slideshow_content_form_label_type": "Type", + "slideshow_content_form_label_object": "Objet", + "slideshow_content_form_button_cancel": "Annuler", + "slideshow_content_form_button_upload": "Uploader un fichier", + "slideshow_content_form_button_upload_choosen": "Aucun fichier sélectionné", + "js_slideshow_content_delete_confirmation": "Êtes-vous sûr ?", + "playlist_page_title": "Playlists", + "playlist_button_add": "Ajouter Playlist", + "playlist_button_delete": "Supprimer Playlist", + "playlist_panel_about_playlist": "À propos de la playlist", + "playlist_panel_content_management": "Elements de la playlist", + "playlist_panel_preview": "Playlist preview", + "playlist_panel_preview_action": "Prévisualiser", + "playlist_panel_inactive": "Playlist inactives", + "playlist_panel_empty": "Actuellement, il n'y a pas de playlist. %link% maintenant.", + "playlist_panel_th_name": "Nom", + "playlist_panel_th_duration": "Durée", + "playlist_panel_th_enabled": "Activé", + "playlist_panel_th_activity": "Options", + "playlist_form_add_title": "Ajout d'une Playlist", + "playlist_form_add_submit": "Ajouter", + "playlist_form_preview_url_desc": "Vous pouvez utiliser ce lien pour lire cette playlist sur n'importe quel navigateur de votre choix. Utilisez le bouton Copier pour l'obtenir dans votre presse-papiers.", + "playlist_form_preview_qrcode_desc": "Vous pouvez facilement accéder à votre playlist à l'aide d'une tablette ou d'un téléphone. Scannez simplement le code QR pour commencer.", + "playlist_form_preview_iframe_desc": "Vous pouvez visualiser la playlist sans quitter cet écran en démarrant l'aperçu à partir d'ici.", + "playlist_form_edit_submit": "Enregistrer", + "playlist_form_label_name": "Entrez le nom de la playlist", + "playlist_form_label_time_sync": "Synchroniser les slides des lecteurs", + "playlist_form_label_enabled": "Activer/Désactiver la playlist", + "playlist_form_button_cancel": "Annuler", + "js_playlist_delete_confirmation": "Êtes-vous sûr ?", + "playlist_delete_has_slides": "La playlist contient des slides, supprimez-les avant et réessayez", + "playlist_delete_has_node_player_groups": "La playlist est attribuée à un playgroup", + "fleet_node_player_page_title": "Lecteurs", + "fleet_node_player_button_add": "Ajouter un lecteur", + "fleet_node_player_panel_active": "Players actifs", + "fleet_node_player_panel_inactive": "Players inactifs", + "fleet_node_player_panel_empty": "Actuellement, il n'y a pas de lecteurs. %link% maintenant.", + "fleet_node_player_panel_th_name": "Nom", + "fleet_node_player_panel_th_host": "Hôte", + "fleet_node_player_panel_th_group_id": "Groupe", + "fleet_node_player_panel_th_enabled": "Activé", + "fleet_node_player_panel_th_activity": "Options", + "fleet_node_player_form_add_title": "Ajout d'un lecteur", + "fleet_node_player_form_add_submit": "Ajouter", + "fleet_node_player_form_edit_title": "Modification d'un lecteur", + "fleet_node_player_form_edit_submit": "Enregistrer", + "fleet_node_player_form_label_name": "Nom", + "fleet_node_player_form_label_group_id": "Groupe", + "fleet_node_player_form_label_host": "Hôte", + "fleet_node_player_form_label_operating_system": "OS", + "fleet_node_player_form_button_cancel": "Annuler", + "js_fleet_node_player_delete_confirmation": "Êtes-vous sûr ?", + "fleet_node_player_group_page_title": "Playgroups", + "fleet_node_player_group_button_add": "Ajouter un Playgroup", + "fleet_node_player_group_panel_active": "Playgroups", + "fleet_node_player_group_panel_empty": "Actuellement, il n'y a pas de playgroup. %link% maintenant.", + "fleet_node_player_group_panel_th_name": "Nom", + "fleet_node_player_group_panel_th_playlist": "Liste de lecture", + "fleet_node_player_group_panel_th_activity": "Options", + "fleet_node_player_group_form_add_title": "Ajout d'un playgroup", + "fleet_node_player_group_form_add_submit": "Ajouter", + "fleet_node_player_group_form_edit_title": "Modification d'un playgroup", + "fleet_node_player_group_form_edit_submit": "Enregistrer", + "fleet_node_player_group_form_label_name": "Nom", + "fleet_node_player_group_form_label_playlist_id": "Liste de lecture", + "fleet_node_player_group_form_button_cancel": "Annuler", + "js_fleet_node_player_group_delete_confirmation": "Êtes-vous sûr ?", + "node_player_group_delete_has_node_player": "Le playgroup a des lecteurs, supprimez-les ou réassignez-les avant de le supprimer", + "login_page_title": "Connexion", + "auth_page_title": "Utilisateurs", + "auth_user_button_add": "Ajouter un utilisateur", + "auth_user_panel_active": "Utilisateurs actifs", + "auth_user_panel_inactive": "Utilisateurs inactifs", + "auth_user_panel_empty": "Actuellement, il n'y a pas d'utilisateurs. %link% maintenant.", + "auth_user_panel_th_username": "Nom d'utilisateur", + "auth_user_panel_th_enabled": "Activé", + "auth_user_panel_th_activity": "Options", + "auth_user_form_add_title": "Ajout d'un utilisateur", + "auth_user_form_add_submit": "Ajouter", + "auth_user_form_edit_title": "Modification d'un utilisateur", + "auth_user_form_edit_submit": "Enregistrer", + "auth_user_form_label_username": "Nom d'utilisateur", + "auth_user_form_label_password": "Mot de passe", + "auth_user_form_button_cancel": "Annuler", + "auth_user_delete_at_least_one_account": "Vous devez avoir au moins un utilisateur actif lorsque vous activez la gestion de l'authentification", + "js_auth_user_delete_confirmation": "Êtes-vous sûr ?", + "settings_page_title": "Paramètres", + "settings_plugin_page_title": "Plugins", + "settings_variable_panel_system_variables": "Paramètres généraux", + "settings_variable_panel_plugin_variables": "Paramètres des plugins", + "settings_variable_panel_th_description": "Description", + "settings_variable_panel_th_value": "Valeur", + "settings_variable_panel_th_activity": "Options", + "settings_variable_form_edit_title": "Modification du paramètre", + "settings_variable_form_edit_submit": "Enregistrer", + "settings_variable_form_label_name": "Nom", + "settings_variable_form_label_value": "Valeur", + "settings_variable_form_button_cancel": "Annuler", + "settings_variable_form_error_not_playlist_enabled_while_fleet_player_enabled": "Vous ne pouvez pas désactiver les playlists tant que la gestion de flotte de lecteurs est activée", + "settings_variable_desc_lang": "Langage de l'application", + "settings_variable_desc_playlist_enabled": "Activer la gestion des playlists", + "settings_variable_desc_fleet_player_enabled": "Activer la gestion de flotte des players", + "settings_variable_desc_edition_fleet_player_enabled": "Les playlists seront également activées", + "settings_variable_desc_auth_enabled": "Activer la gestion de l'authentification", + "settings_variable_desc_edition_auth_enabled": "Les identifiants de l'utilisateur par défaut seront admin/admin", + "settings_variable_desc_external_url": "URL externe (i.e: https://studio-01.company.com or http://10.10.3.100)", + "settings_variable_desc_slide_upload_limit": "Limite d'upload du fichier d'une slide (en mégaoctets)", + "settings_variable_desc_intro_slide_duration": "Durée de la slide d'introduction (en secondes)", + "settings_variable_desc_default_slide_time_with_seconds": "Afficher les secondes de l'horloge de la slide d'introduction", + "settings_variable_desc_polling_interval": "Intervalle de rafraîchissement des paramètres à appliquer au lecteur (en secondes)", + "settings_variable_desc_playlist_default_time_sync": "Synchroniser les slides des lecteurs pour la playlist par défaut", + "settings_variable_desc_slide_animation_enabled": "Activer les effets d'animation entre les slides", + "settings_variable_desc_slide_animation_entrance_effect": "Effet d'animation d'arrivée de la slide", + "settings_variable_desc_slide_animation_exit_effect": "Effet d'animation de sortie de la slide (généralement mieux sans)", + "settings_variable_desc_slide_animation_speed": "Vitesse de l'animation de la slide", + "settings_variable_desc_ro_start_counter": "Compteur de démarrage", + "settings_variable_desc_ro_last_folder_content": "Dossier courant dans l'explorateur de contenu", + "settings_variable_desc_ro_last_folder_node_player": "Dossier courant dans l'explorateur du lecteur", + "settings_variable_desc_ro_editable": "Date de dernier redémarrage de l'application", + "settings_variable_desc_ro_last_slide_update": "Date de dernière modification d'une slide", + "settings_variable_desc_ro_refresh_player_request": "Date de dernière demande de rafraîchissement du lecteur", + "sysinfo_page_title": "Système", + "sysinfo_panel_button_restart": "Redémarrer", + "sysinfo_panel_table_section_system": "Système", + "sysinfo_panel_table_section_application": "Application", + "sysinfo_panel_title": "Informations", + "sysinfo_panel_th_attribute": "Attribut", + "sysinfo_panel_th_value": "Valeur", + "sysinfo_panel_td_ipaddr": "Adresse IP", + "logs_page_title": "Logs", + "logs_panel_last_logs": "Journaux (100 dernières lignes)", + "js_sysinfo_restart_confirmation": "Êtes-vous sûr ?", + "js_sysinfo_restart_loading": "Redémarrage en cours, veuillez patienter...", + "basic_day_1": "Lundi", + "basic_day_2": "Mardi", + "basic_day_3": "Mercredi", + "basic_day_4": "Jeudi", + "basic_day_5": "Vendredi", + "basic_day_6": "Samedi", + "basic_day_7": "Dimanche", + "basic_month_1": "Janvier", + "basic_month_2": "Février", + "basic_month_3": "Mars", + "basic_month_4": "Avril", + "basic_month_5": "Mai", + "basic_month_6": "Juin", + "basic_month_7": "Juillet", + "basic_month_8": "Août", + "basic_month_9": "Septembre", + "basic_month_10": "Octobre", + "basic_month_11": "Novembre", + "basic_month_12": "Décembre", + "common_untitled": "", + "common_loading": "Chargement...", + "common_default_node_player_group": "Playgroup par défaut", + "common_default_playlist": "Playlist par défaut", + "common_unknown_ipaddr": "Adresse IP inconnue", + "common_empty": "[Vide]", + "common_are_you_sure": "Êtes-vous sûr ?", + "common_enable_plugin": "Activer ce plugin", + "common_save": "Enregistrer", + "common_cancel": "Annuler", + "common_close": "Fermer", + "common_confirm": "Confirmer", + "common_submit": "Envoyer", + "common_validate": "Valider", + "common_apply": "Appliquer", + "common_saved": "Les modifications ont été enregistrées", + "common_new_folder": "Nouveau Dossier", + "common_folder_not_empty_error": "Le dossier n'est pas vide, vous devez d'abord supprimer son contenu", + "logout": "Déconnexion", + "login_error_not_found": "Identifiants invalides", + "login_error_bad_credentials": "Identifiants invalides", + "login_form_title": "Connexion", + "login_form_username": "Identifiant", + "login_form_password": "Mot de passe", + "login_form_submit": "Valider", + "utrack_title": "À propos des utilisateurs", + "created_at": "Création le", + "updated_at": "Modification le", + "created_by": "Création par", + "updated_by": "Dernière modification par", + "close": "Fermer", + "anonymous": "Anon", + "enum_animation_speed_slower": "Très lent", + "enum_animation_speed_slow": "Lent", + "enum_animation_speed_normal": "Normal", + "enum_animation_speed_fast": "Rapide", + "enum_animation_speed_faster": "Très rapide", + "enum_variable_section_general": "1. Général", + "enum_variable_section_player_options": "2. Options du lecteur", + "enum_variable_section_player_animation": "3. Animation du lecteur", + "enum_variable_section_playlist": "4. Playlists", + "enum_variable_section_fleet": "5. Gestion de flotte", + "enum_variable_section_security": "6. Sécurité", + "enum_application_language_english": "Anglais", + "enum_application_language_french": "Français", + "enum_application_language_italian": "Italien", + "enum_application_language_spanish": "Espagnol", + "enum_content_type_url": "URL", + "enum_content_type_video": "Vidéo", + "enum_content_type_picture": "Image", + "enum_content_type_youtube": "Youtube", + "enum_content_type_url_object_label": "Entrez l'URL de la page", + "enum_content_type_video_object_label": "Uploadez votre vidéo (MP4 seulement)", + "enum_content_type_picture_object_label": "Uploadez votre image", + "enum_content_type_youtube_object_label": "Enrez l'URL de la vidéo Youtube", + "enum_operating_system_raspbian": "Raspbian", + "enum_operating_system_debian": "Debian", + "enum_operating_system_windows": "Windows", + "enum_operating_system_macos": "MacOS", + "enum_operating_system_fedora": "Fedora", + "enum_operating_system_ubuntu": "Ubuntu", + "enum_operating_system_suse": "Suse", + "enum_operating_system_redhat": "RedHat", + "enum_operating_system_centos": "CentOS", + "enum_operating_system_other": "Autre", + "sysinfo_rpi_model": "Modèle du Raspberry Pi", + "sysinfo_rpi_model_unknown": "Le modèle n'est pas un Raspberry Pi", + "sysinfo_storage_free_space": "Stockage Disponible", + "sysinfo_memory_usage": "Utilisation Mémoire", + "sysinfo_os_version": "Version SE", + "sysinfo_install_directory": "Dossier Racine", + "sysinfo_network_interface": "Interface Réseau", + "sysinfo_mac_address": "Addresse MAC", + "sysinfo_ip_address": "Addresse IP", + "player_default_welcome_message": "Pour gérer ce lecteur, allez sur un navigateur à l'adresse %link%" } diff --git a/lang/it.json b/lang/it.json index 4d6df04..26ee4b9 100644 --- a/lang/it.json +++ b/lang/it.json @@ -1,294 +1,287 @@ { - "dynmenu_content": "Contenuti", - - "slideshow_slide_page_title": "Programmazione", - "slideshow_slide_goto_player": "Vai al player", - "slideshow_slide_refresh_player": "Aggiorna player", - "slideshow_slide_refresh_player_success": "L' aggiornamento è stato richiesto, sarà applicato in (%time% secondi)", - "slideshow_slide_button_add": "Aggiungi slide", - "slideshow_slide_panel_active": "Attiva slide", - "slideshow_slide_panel_inactive": "Slide inattive", - "slideshow_slide_panel_empty": "Attualmente, non ci sono slide. %link% adesso.", - "slideshow_slide_panel_th_content": "Contenuti", - "slideshow_slide_panel_th_duration": "Finito in", - "slideshow_slide_panel_th_duration_unit": "sec", - "slideshow_slide_panel_th_enabled": "Abilitato", - "slideshow_slide_panel_th_cron_scheduled": "Avvia programmazione", - "slideshow_slide_panel_th_activity": "Opzioni", - "slideshow_slide_panel_td_cron_scheduled_loop": "Loop", - "slideshow_slide_panel_td_cron_scheduled_notify": "Notificare", - "slideshow_slide_panel_td_cron_scheduled_bad_cron": "Valore cron errato", - "slideshow_slide_form_add_title": "Aggiungi Slide", - "slideshow_slide_form_add_submit": "Aggiungi", - "slideshow_slide_form_edit_title": "Modifica Slide", - "slideshow_slide_form_edit_submit": "Salva", - "slideshow_slide_form_section_content": "Media", - "slideshow_slide_form_section_scheduling": "Programmazione", - "slideshow_slide_form_label_name": "Nome", - "slideshow_slide_form_label_add_content": "Aggiunta alla biblioteca", - "slideshow_slide_form_label_from_library": "Dalla biblioteca", - "slideshow_slide_form_label_content_id": "Contenuti", - "slideshow_slide_form_label_location": "Posizione", - "slideshow_slide_form_label_type": "Tipo", - "slideshow_slide_form_label_object": "Oggetto", - "slideshow_slide_form_label_duration": "Durata", - "slideshow_slide_form_label_duration_unit": "Secondi", - "slideshow_slide_form_label_is_notification": "Agisce come una notifica", - "slideshow_slide_form_label_cron_scheduled": "Inizio", - "slideshow_slide_form_label_cron_scheduled_end": "Fine", - "slideshow_slide_form_label_cron_scheduled_loop": "Sempre in loop", - "slideshow_slide_form_label_cron_scheduled_duration": "Durata", - "slideshow_slide_form_label_cron_scheduled_stayloop": "Seguire il ciclo", - "slideshow_slide_form_label_cron_scheduled_duration_unit": "secondi", - "slideshow_slide_form_label_cron_scheduled_datetime": "Data e ora", - "slideshow_slide_form_label_cron_scheduled_datetime_placeholder": "Imposta Data e ora", - "slideshow_slide_form_label_cron_scheduled_cron": "Cron", - "slideshow_slide_form_widget_cron_scheduled_placeholder": "Utilizza formato crontab: * * * * *", - "slideshow_slide_form_button_cancel": "Annulla", - "js_slideshow_slide_delete_confirmation": "Sei sicuro?", - - "slideshow_content_page_title": "Libreria dei contenuti", - "slideshow_content_button_add": "Nuovo Contenuto", - "slideshow_content_referenced_in_slide_error": "Si fa riferimento al contenuto in una diapositiva, rimuovere prima la diapositiva", - "slideshow_content_panel_active": "Contenuti", - "slideshow_content_panel_empty": "Attualmente non ci sono contenuti. %link% adesso.", - "slideshow_content_panel_th_name": "Nome", - "slideshow_content_panel_th_activity": "Opzioni", - "slideshow_content_form_add_title": "Aggiunta di un contenuto", - "slideshow_content_form_add_submit": "Aggiungi", - "slideshow_content_form_edit_title": "Modifica di un contenuto", - "slideshow_content_form_edit_submit": "Salva", - "slideshow_content_form_label_name": "Nome", - "slideshow_content_form_label_location": "Posizione", - "slideshow_content_form_label_type": "Tipo", - "slideshow_content_form_label_object": "Oggetto", - "slideshow_content_form_button_cancel": "Annulla", - "slideshow_content_form_button_upload": "Carica un file", - "slideshow_content_form_button_upload_choosen": "Nessun file selezionato", - "js_slideshow_content_delete_confirmation": "Sei sicuro?", - - "playlist_page_title": "Playlist", - "playlist_button_add": "Aggiungi alla playlist", - "playlist_panel_active": "Attiva playlist", - "playlist_panel_inactive": "Playlist inattive", - "playlist_panel_empty": "Attualmente, non ci sono playlist. %link% adesso.", - "playlist_panel_th_name": "Nome", - "playlist_panel_th_duration": "Durata", - "playlist_panel_th_enabled": "Abilitata", - "playlist_panel_th_activity": "Opzioni", - "playlist_form_add_title": "Aggiungi Playlist", - "playlist_form_add_submit": "Aggiungi", - "playlist_form_edit_title": "Modifica Playlist", - "playlist_form_edit_submit": "Salva", - "playlist_form_label_name": "Inserisci il nome della playlist", - "playlist_form_label_time_sync": "Sincronizza le slide tra gli schermi", - "playlist_form_button_cancel": "Cancella", - "js_playlist_delete_confirmation": "Sei sicuro?", - "playlist_delete_has_slides": "Sono presenti slide nella playlist, annullale e riprova", - "playlist_delete_has_node_player_groups": "La playlist è collegata ad un playgroup", - - "fleet_node_player_page_title": "Schermi", - "fleet_node_player_button_add": "Aggiungi allo schermo", - "fleet_node_player_panel_active": "Schermi attivi", - "fleet_node_player_panel_inactive": "Schermi disattivi", - "fleet_node_player_panel_empty": "Attualmente, non ci sono schermi. %link% adesso.", - "fleet_node_player_panel_th_name": "Nome", - "fleet_node_player_panel_th_host": "Host", - "fleet_node_player_panel_th_group_id": "Gruppo", - "fleet_node_player_panel_th_enabled": "Abilitato", - "fleet_node_player_panel_th_activity": "Opzioni", - "fleet_node_player_form_add_title": "Aggiungi schermo", - "fleet_node_player_form_add_submit": "Aggiungi", - "fleet_node_player_form_edit_title": "Modifica schermo", - "fleet_node_player_form_edit_submit": "Salva", - "fleet_node_player_form_label_name": "Nome", - "fleet_node_player_form_label_group_id": "Group", - "fleet_node_player_form_label_host": "Host", - "fleet_node_player_form_label_operating_system": "OS", - "fleet_node_player_form_button_cancel": "Cancella", - "js_fleet_node_player_delete_confirmation": "Sei sicuro?", - - "fleet_node_player_group_page_title": "Playgroups", - "fleet_node_player_group_button_add": "Aggiungi Playgroup", - "fleet_node_player_group_panel_active": "Playgroup attivi", - "fleet_node_player_group_panel_empty": "Attualmente, non ci sono playgroup. %link% adesso.", - "fleet_node_player_group_panel_th_name": "Nome", - "fleet_node_player_group_panel_th_playlist": "Playlist", - "fleet_node_player_group_panel_th_activity": "Opzioni", - "fleet_node_player_group_form_add_title": "Aggiungi Playgroup", - "fleet_node_player_group_form_add_submit": "Aggiungi", - "fleet_node_player_group_form_edit_title": "Modifica Playgroup", - "fleet_node_player_group_form_edit_submit": "Salva", - "fleet_node_player_group_form_label_name": "Nome", - "fleet_node_player_group_form_label_playlist_id": "Playlist", - "fleet_node_player_group_form_button_cancel": "Cancella", - "js_fleet_node_player_group_delete_confirmation": "Sei sicuro?", - "node_player_group_delete_has_node_player": "Lo playgroup ha una playlist, rumuovila o riassegnala e riprova", - - "login_page_title": "Login", - "auth_page_title": "Utente", - "auth_user_button_add": "Aggiungi utente", - "auth_user_panel_active": "Utenti attivi", - "auth_user_panel_inactive": "Utenti inattivi", - "auth_user_panel_empty": "Attualmente, non ci sono utenti. %link% adesso.", - "auth_user_panel_th_username": "Username", - "auth_user_panel_th_enabled": "Abilitato", - "auth_user_panel_th_activity": "Opzioni", - "auth_user_form_add_title": "Aggiungi utente", - "auth_user_form_add_submit": "Aggiungi", - "auth_user_form_edit_title": "Modifica utente", - "auth_user_form_edit_submit": "Salva", - "auth_user_form_label_username": "Username", - "auth_user_form_label_password": "Password", - "auth_user_form_button_cancel": "Cancella", - "auth_user_delete_at_least_one_account": "È necessario avere almeno un utente attivo durante l'utilizzo della funzione di autenticazione", - "js_auth_user_delete_confirmation": "Sei sicuro?", - - "settings_page_title": "Impostazioni", - "settings_plugin_page_title": "Plugins", - "settings_variable_panel_system_variables": "Impostazioni generali", - "settings_variable_panel_plugin_variables": "Impostazioni Plugin", - "settings_variable_panel_th_description": "Descrizione", - "settings_variable_panel_th_value": "Valore", - "settings_variable_panel_th_activity": "Opzioni", - "settings_variable_form_edit_title": "Modifica impostazioni", - "settings_variable_form_edit_submit": "Salva", - "settings_variable_form_label_name": "Nome", - "settings_variable_form_label_value": "Valore", - "settings_variable_form_button_cancel": "Cancella", - "settings_variable_form_error_not_playlist_enabled_while_fleet_player_enabled": "Non puoi disattivare le playlist mentre è attiva la gestione degli schermi nella panoramica", - "settings_variable_desc_lang": "Lingua server", - "settings_variable_desc_playlist_enabled": "Abilita gestione playlist", - "settings_variable_desc_fleet_player_enabled": "Abilita panoramica gestione monitor", - "settings_variable_desc_edition_fleet_player_enabled": "Verrà abilitata anche la gestione delle playlist", - "settings_variable_desc_auth_enabled": "Abilita la gestione autenticazione", - "settings_variable_desc_edition_auth_enabled": "Le credenziali utente predefinite sono admin/admin", - "settings_variable_desc_external_url": "Url esterno (esempio: https://studio-01.company.com or http://10.10.3.100)", - "settings_variable_desc_slide_upload_limit": "Limite upload slide (in megabytes)", - "settings_variable_desc_default_slide_duration": "Durata introduzione slide (in secondi)", - "settings_variable_desc_default_slide_time_with_seconds": "Mostra secondi introduzione slide", - "settings_variable_desc_polling_interval": "Intervallo di aggiornamento applicato per le impostazioni del monitor (in secondi)", - "settings_variable_desc_playlist_default_time_sync": "Sincronizza le diapositive tra i lettori per la playlist predefinita", - - "settings_variable_desc_slide_animation_enabled": "Abilita l'effetto di animazione tra le diapositive", - "settings_variable_desc_slide_animation_entrance_effect": "Effetto ingresso diapositiva", - "settings_variable_desc_slide_animation_exit_effect": "Effetto di uscita della diapositiva (meglio senza)", - "settings_variable_desc_slide_animation_speed": "Velicita animazione slide", - - "settings_variable_desc_ro_last_folder_content": "Cartella corrente in Esplora contenuti", - "settings_variable_desc_ro_last_folder_node_player": "Cartella corrente in Player Explorer", - "settings_variable_desc_ro_editable": "Data/ora dell'ultimo riavvio dell'applicazione", - "settings_variable_desc_ro_last_slide_update": "Data e ora dell'ultimo aggiornamento della diapositiva", - "settings_variable_desc_ro_refresh_player_request": "Data e ora della richiesta di aggiornamento dell monitor", - - "sysinfo_page_title": "Informazione sistema", - "sysinfo_panel_button_restart": "Riavvia", - "sysinfo_panel_table_section_system": "Sistema", - "sysinfo_panel_table_section_application": "Applicazione", - "sysinfo_panel_title": "Informazioni", - "sysinfo_panel_th_attribute": "Attributi", - "sysinfo_panel_th_value": "Valore", - "sysinfo_panel_td_ipaddr": "Indirizzo ip", - "logs_page_title": "Logs", - "logs_panel_last_logs": "Logs (ultime 100 righe)", - "js_sysinfo_restart_confirmation": "Sei sicuro?", - "js_sysinfo_restart_loading": "Riavvio in corso, attendi...", - - "basic_day_1": "Lunedi", - "basic_day_2": "Martedi", - "basic_day_3": "Mercoledi", - "basic_day_4": "Giovedi", - "basic_day_5": "Venerdi", - "basic_day_6": "Sabato", - "basic_day_7": "Domenica", - "basic_month_1": "Gennaio", - "basic_month_2": "Febbrazio", - "basic_month_3": "Marzo", - "basic_month_4": "Aprile", - "basic_month_5": "Maggio", - "basic_month_6": "Giugno", - "basic_month_7": "Luglio", - "basic_month_8": "Agosto", - "basic_month_9": "Settembre", - "basic_month_10": "Ottobre", - "basic_month_11": "Novembre", - "basic_month_12": "Dicembre", - - "common_loading": "Caricamento...", - "common_default_node_player_group": "Playgroup di default", - "common_default_playlist": "Default playlist", - "common_unknown_ipaddr": "IP sconosciuto", - "common_empty": "[Empty]", - "common_are_you_sure": "Sei sicuro?", - "common_enable_plugin": "Attiva questo plugin", - "common_save": "Salva", - "common_cancel": "Annulla", - "common_close": "Chiudi", - "common_confirm": "Conferma", - "common_submit": "Invia", - "common_validate": "Convalida", - "common_apply": "Applica", - "common_saved": "Le modifiche sono state salvate", - "common_new_folder": "Nuovo Cartella", - "common_folder_not_empty_error": "La cartella non è vuota, devi prima eliminarne il contenuto", - "logout": "Logout", - "login_error_not_found": "Credenziali errate", - "login_error_bad_credentials": "Credenziali errate", - "login_form_title": "Accedi", - "login_form_username": "Username", - "login_form_password": "Password", - "login_form_submit": "Connetti", - "utrack_title": "Utente", - "created_at": "Creato il", - "updated_at": "Modificato il", - "created_by": "Creato da", - "updated_by": "Aggiornato da", - "close": "Chiuso", - "anonymous": "Anonimo", - - "enum_animation_speed_slower": "Lentamente", - "enum_animation_speed_slow": "Lento", - "enum_animation_speed_normal": "Normale", - "enum_animation_speed_fast": "Veloce", - "enum_animation_speed_faster": "Velocemente", - "enum_variable_section_general": "1. Generale", - "enum_variable_section_player_options": "2. Opzioni monitor", - "enum_variable_section_player_animation": "3. Animazioni monitor", - "enum_variable_section_playlist": "4. Playlist", - "enum_variable_section_fleet": "5. Gestione panoramica", - "enum_variable_section_security": "6. Sicurezza", - "enum_application_language_english": "Inglese", - "enum_application_language_french": "Francese", - "enum_application_language_italian": "Italiano", - "enum_application_language_spanish": "Spagnolo", - "enum_content_type_url": "URL", - "enum_content_type_video": "Video", - "enum_content_type_picture": "Immagine", - "enum_content_type_youtube": "Youtube", - "enum_content_type_url_object_label": "Inserisci il collegamento URL", - "enum_content_type_video_object_label": "Carica il tuo video (solo MP4)", - "enum_content_type_picture_object_label": "Carica la tua immagine", - "enum_content_type_youtube_object_label": "Inserisci l'URL del video Youtube", - "enum_operating_system_raspbian": "Raspbian", - "enum_operating_system_debian": "Debian", - "enum_operating_system_windows": "Windows", - "enum_operating_system_macos": "MacOS", - "enum_operating_system_fedora": "Fedora", - "enum_operating_system_ubuntu": "Ubuntu", - "enum_operating_system_suse": "Suse", - "enum_operating_system_redhat": "RedHat", - "enum_operating_system_centos": "CentOS", - "enum_operating_system_other": "Altro", - - "sysinfo_rpi_model": "Raspberry Pi Model", - "sysinfo_rpi_model_unknown": "Informazioni Raspberry Pi non disponibili", - "sysinfo_storage_free_space": "Spazio libero", - "sysinfo_memory_usage": "Memoria usata", - "sysinfo_os_version": "OS Version", - "sysinfo_install_directory": "Percorso installazione", - "sysinfo_network_interface": "interfaccia di rete", - "sysinfo_mac_address": "Indirizzo MAC", - "sysinfo_ip_address": "indirizzo IP", - - "player_default_welcome_message": "Per gestire questo lettore, vai al browser all'indirizzo %link%" + "dynmenu_content": "Contenuti", + "slideshow_slide_page_title": "Programmazione", + "slideshow_slide_goto_player": "Vai al player", + "slideshow_slide_refresh_player": "Aggiorna player", + "slideshow_slide_refresh_player_success": "L' aggiornamento è stato richiesto, sarà applicato in (%time% secondi)", + "slideshow_slide_button_add": "Aggiungi slide", + "slideshow_slide_panel_active": "Attiva slide", + "slideshow_slide_panel_inactive": "Slide inattive", + "slideshow_slide_panel_empty": "Attualmente, non ci sono slide. %link% adesso.", + "slideshow_slide_panel_th_content": "Contenuti", + "slideshow_slide_panel_th_duration": "Finito in", + "slideshow_slide_panel_th_duration_unit": "sec", + "slideshow_slide_panel_th_enabled": "Abilitato", + "slideshow_slide_panel_th_cron_scheduled": "Avvia programmazione", + "slideshow_slide_panel_th_activity": "Opzioni", + "slideshow_slide_panel_td_cron_scheduled_loop": "Loop", + "slideshow_slide_panel_td_cron_scheduled_notify": "Notificare", + "slideshow_slide_panel_td_cron_scheduled_bad_cron": "Valore cron errato", + "slideshow_slide_form_add_title": "Aggiungi Slide", + "slideshow_slide_form_add_submit": "Aggiungi", + "slideshow_slide_form_edit_title": "Modifica Slide", + "slideshow_slide_form_edit_submit": "Salva", + "slideshow_slide_form_section_content": "Media", + "slideshow_slide_form_section_scheduling": "Programmazione", + "slideshow_slide_form_label_name": "Nome", + "slideshow_slide_form_label_add_content": "Aggiunta alla biblioteca", + "slideshow_slide_form_label_from_library": "Dalla biblioteca", + "slideshow_slide_form_label_content_id": "Contenuti", + "slideshow_slide_form_label_location": "Posizione", + "slideshow_slide_form_label_type": "Tipo", + "slideshow_slide_form_label_object": "Oggetto", + "slideshow_slide_form_label_duration": "Durata", + "slideshow_slide_form_label_duration_unit": "Secondi", + "slideshow_slide_form_label_is_notification": "Agisce come una notifica", + "slideshow_slide_form_label_cron_scheduled": "Inizio", + "slideshow_slide_form_label_cron_scheduled_end": "Fine", + "slideshow_slide_form_label_cron_scheduled_loop": "Sempre in loop", + "slideshow_slide_form_label_cron_scheduled_duration": "Durata", + "slideshow_slide_form_label_cron_scheduled_stayloop": "Seguire il ciclo", + "slideshow_slide_form_label_cron_scheduled_duration_unit": "secondi", + "slideshow_slide_form_label_cron_scheduled_datetime": "Data e ora", + "slideshow_slide_form_label_cron_scheduled_datetime_placeholder": "Imposta Data e ora", + "slideshow_slide_form_label_cron_scheduled_cron": "Cron", + "slideshow_slide_form_widget_cron_scheduled_placeholder": "Utilizza formato crontab: * * * * *", + "slideshow_slide_form_button_cancel": "Annulla", + "js_slideshow_slide_delete_confirmation": "Sei sicuro?", + "slideshow_content_page_title": "Libreria dei contenuti", + "slideshow_content_button_add": "Nuovo Contenuto", + "slideshow_content_referenced_in_slide_error": "Si fa riferimento al contenuto in una diapositiva, rimuovere prima la diapositiva", + "slideshow_content_panel_active": "Contenuti", + "slideshow_content_panel_empty": "Attualmente non ci sono contenuti. %link% adesso.", + "slideshow_content_panel_th_name": "Nome", + "slideshow_content_panel_th_activity": "Opzioni", + "slideshow_content_form_add_title": "Aggiunta di un contenuto", + "slideshow_content_form_add_submit": "Aggiungi", + "slideshow_content_form_edit_title": "Modifica di un contenuto", + "slideshow_content_form_edit_submit": "Salva", + "slideshow_content_form_label_name": "Nome", + "slideshow_content_form_label_location": "Posizione", + "slideshow_content_form_label_type": "Tipo", + "slideshow_content_form_label_object": "Oggetto", + "slideshow_content_form_button_cancel": "Annulla", + "slideshow_content_form_button_upload": "Carica un file", + "slideshow_content_form_button_upload_choosen": "Nessun file selezionato", + "js_slideshow_content_delete_confirmation": "Sei sicuro?", + "playlist_page_title": "Playlists", + "playlist_button_add": "Aggiungi Playlist", + "playlist_button_delete": "Elimina Playlist", + "playlist_panel_about_playlist": "Informazioni sulla playlist", + "playlist_panel_content_management": "Gestione dei contenuti", + "playlist_panel_preview": "Anteprima della playlist", + "playlist_panel_preview_action": "Anteprima", + "playlist_panel_inactive": "Playlist inattive", + "playlist_panel_empty": "Attualmente, non ci sono playlist. %link% adesso.", + "playlist_panel_th_name": "Nome", + "playlist_panel_th_duration": "Durata", + "playlist_panel_th_enabled": "Abilitata", + "playlist_panel_th_activity": "Opzioni", + "playlist_form_add_title": "Aggiungi Playlist", + "playlist_form_add_submit": "Aggiungi", + "playlist_form_preview_url_desc": "Puoi utilizzare questo collegamento per riprodurre questa playlist su qualsiasi browser desideri. Utilizza il pulsante Copia per inserirla negli appunti.", + "playlist_form_preview_qrcode_desc": "Puoi accedere facilmente alla tua playlist utilizzando un tablet o un telefono. Basta scansionare il codice QR per iniziare.", + "playlist_form_preview_iframe_desc": "Puoi visualizzare la playlist senza uscire da questa schermata avviando l'anteprima da qui.", + "playlist_form_label_name": "Inserisci il nome della playlist", + "playlist_form_label_time_sync": "Sincronizza le slide tra gli schermi", + "playlist_form_label_enabled": "Abilita/Disabilita playlist", + "playlist_form_button_cancel": "Cancella", + "js_playlist_delete_confirmation": "Sei sicuro?", + "playlist_delete_has_slides": "Sono presenti slide nella playlist, annullale e riprova", + "playlist_delete_has_node_player_groups": "La playlist è collegata ad un playgroup", + "fleet_node_player_page_title": "Schermi", + "fleet_node_player_button_add": "Aggiungi allo schermo", + "fleet_node_player_panel_active": "Schermi attivi", + "fleet_node_player_panel_inactive": "Schermi disattivi", + "fleet_node_player_panel_empty": "Attualmente, non ci sono schermi. %link% adesso.", + "fleet_node_player_panel_th_name": "Nome", + "fleet_node_player_panel_th_host": "Host", + "fleet_node_player_panel_th_group_id": "Gruppo", + "fleet_node_player_panel_th_enabled": "Abilitato", + "fleet_node_player_panel_th_activity": "Opzioni", + "fleet_node_player_form_add_title": "Aggiungi schermo", + "fleet_node_player_form_add_submit": "Aggiungi", + "fleet_node_player_form_edit_title": "Modifica schermo", + "fleet_node_player_form_edit_submit": "Salva", + "fleet_node_player_form_label_name": "Nome", + "fleet_node_player_form_label_group_id": "Group", + "fleet_node_player_form_label_host": "Host", + "fleet_node_player_form_label_operating_system": "OS", + "fleet_node_player_form_button_cancel": "Cancella", + "js_fleet_node_player_delete_confirmation": "Sei sicuro?", + "fleet_node_player_group_page_title": "Playgroups", + "fleet_node_player_group_button_add": "Aggiungi Playgroup", + "fleet_node_player_group_panel_active": "Playgroup attivi", + "fleet_node_player_group_panel_empty": "Attualmente, non ci sono playgroup. %link% adesso.", + "fleet_node_player_group_panel_th_name": "Nome", + "fleet_node_player_group_panel_th_playlist": "Playlist", + "fleet_node_player_group_panel_th_activity": "Opzioni", + "fleet_node_player_group_form_add_title": "Aggiungi Playgroup", + "fleet_node_player_group_form_add_submit": "Aggiungi", + "fleet_node_player_group_form_edit_title": "Modifica Playgroup", + "fleet_node_player_group_form_edit_submit": "Salva", + "fleet_node_player_group_form_label_name": "Nome", + "fleet_node_player_group_form_label_playlist_id": "Playlist", + "fleet_node_player_group_form_button_cancel": "Cancella", + "js_fleet_node_player_group_delete_confirmation": "Sei sicuro?", + "node_player_group_delete_has_node_player": "Lo playgroup ha una playlist, rumuovila o riassegnala e riprova", + "login_page_title": "Login", + "auth_page_title": "Utente", + "auth_user_button_add": "Aggiungi utente", + "auth_user_panel_active": "Utenti attivi", + "auth_user_panel_inactive": "Utenti inattivi", + "auth_user_panel_empty": "Attualmente, non ci sono utenti. %link% adesso.", + "auth_user_panel_th_username": "Username", + "auth_user_panel_th_enabled": "Abilitato", + "auth_user_panel_th_activity": "Opzioni", + "auth_user_form_add_title": "Aggiungi utente", + "auth_user_form_add_submit": "Aggiungi", + "auth_user_form_edit_title": "Modifica utente", + "auth_user_form_edit_submit": "Salva", + "auth_user_form_label_username": "Username", + "auth_user_form_label_password": "Password", + "auth_user_form_button_cancel": "Cancella", + "auth_user_delete_at_least_one_account": "È necessario avere almeno un utente attivo durante l'utilizzo della funzione di autenticazione", + "js_auth_user_delete_confirmation": "Sei sicuro?", + "settings_page_title": "Impostazioni", + "settings_plugin_page_title": "Plugins", + "settings_variable_panel_system_variables": "Impostazioni generali", + "settings_variable_panel_plugin_variables": "Impostazioni Plugin", + "settings_variable_panel_th_description": "Descrizione", + "settings_variable_panel_th_value": "Valore", + "settings_variable_panel_th_activity": "Opzioni", + "settings_variable_form_edit_title": "Modifica impostazioni", + "settings_variable_form_edit_submit": "Salva", + "settings_variable_form_label_name": "Nome", + "settings_variable_form_label_value": "Valore", + "settings_variable_form_button_cancel": "Cancella", + "settings_variable_form_error_not_playlist_enabled_while_fleet_player_enabled": "Non puoi disattivare le playlist mentre è attiva la gestione degli schermi nella panoramica", + "settings_variable_desc_lang": "Lingua server", + "settings_variable_desc_playlist_enabled": "Abilita gestione playlist", + "settings_variable_desc_fleet_player_enabled": "Abilita panoramica gestione monitor", + "settings_variable_desc_edition_fleet_player_enabled": "Verrà abilitata anche la gestione delle playlist", + "settings_variable_desc_auth_enabled": "Abilita la gestione autenticazione", + "settings_variable_desc_edition_auth_enabled": "Le credenziali utente predefinite sono admin/admin", + "settings_variable_desc_external_url": "Url esterno (esempio: https://studio-01.company.com or http://10.10.3.100)", + "settings_variable_desc_slide_upload_limit": "Limite upload slide (in megabytes)", + "settings_variable_desc_intro_slide_duration": "Durata introduzione slide (in secondi)", + "settings_variable_desc_default_slide_time_with_seconds": "Mostra secondi introduzione slide", + "settings_variable_desc_polling_interval": "Intervallo di aggiornamento applicato per le impostazioni del monitor (in secondi)", + "settings_variable_desc_playlist_default_time_sync": "Sincronizza le diapositive tra i lettori per la playlist predefinita", + "settings_variable_desc_slide_animation_enabled": "Abilita l'effetto di animazione tra le diapositive", + "settings_variable_desc_slide_animation_entrance_effect": "Effetto ingresso diapositiva", + "settings_variable_desc_slide_animation_exit_effect": "Effetto di uscita della diapositiva (meglio senza)", + "settings_variable_desc_slide_animation_speed": "Velicita animazione slide", + "settings_variable_desc_ro_start_counter": "Avvia contatore", + "settings_variable_desc_ro_last_folder_content": "Cartella corrente in Esplora contenuti", + "settings_variable_desc_ro_last_folder_node_player": "Cartella corrente in Player Explorer", + "settings_variable_desc_ro_editable": "Data/ora dell'ultimo riavvio dell'applicazione", + "settings_variable_desc_ro_last_slide_update": "Data e ora dell'ultimo aggiornamento della diapositiva", + "settings_variable_desc_ro_refresh_player_request": "Data e ora della richiesta di aggiornamento dell monitor", + "sysinfo_page_title": "Informazione sistema", + "sysinfo_panel_button_restart": "Riavvia", + "sysinfo_panel_table_section_system": "Sistema", + "sysinfo_panel_table_section_application": "Applicazione", + "sysinfo_panel_title": "Informazioni", + "sysinfo_panel_th_attribute": "Attributi", + "sysinfo_panel_th_value": "Valore", + "sysinfo_panel_td_ipaddr": "Indirizzo ip", + "logs_page_title": "Logs", + "logs_panel_last_logs": "Logs (ultime 100 righe)", + "js_sysinfo_restart_confirmation": "Sei sicuro?", + "js_sysinfo_restart_loading": "Riavvio in corso, attendi...", + "basic_day_1": "Lunedi", + "basic_day_2": "Martedi", + "basic_day_3": "Mercoledi", + "basic_day_4": "Giovedi", + "basic_day_5": "Venerdi", + "basic_day_6": "Sabato", + "basic_day_7": "Domenica", + "basic_month_1": "Gennaio", + "basic_month_2": "Febbrazio", + "basic_month_3": "Marzo", + "basic_month_4": "Aprile", + "basic_month_5": "Maggio", + "basic_month_6": "Giugno", + "basic_month_7": "Luglio", + "basic_month_8": "Agosto", + "basic_month_9": "Settembre", + "basic_month_10": "Ottobre", + "basic_month_11": "Novembre", + "basic_month_12": "Dicembre", + "common_untitled": "", + "common_loading": "Caricamento...", + "common_default_node_player_group": "Playgroup di default", + "common_default_playlist": "Default playlist", + "common_unknown_ipaddr": "IP sconosciuto", + "common_empty": "[Empty]", + "common_are_you_sure": "Sei sicuro?", + "common_enable_plugin": "Attiva questo plugin", + "common_save": "Salva", + "common_cancel": "Annulla", + "common_close": "Chiudi", + "common_confirm": "Conferma", + "common_submit": "Invia", + "common_validate": "Convalida", + "common_apply": "Applica", + "common_saved": "Le modifiche sono state salvate", + "common_new_folder": "Nuovo Cartella", + "common_folder_not_empty_error": "La cartella non è vuota, devi prima eliminarne il contenuto", + "logout": "Logout", + "login_error_not_found": "Credenziali errate", + "login_error_bad_credentials": "Credenziali errate", + "login_form_title": "Accedi", + "login_form_username": "Username", + "login_form_password": "Password", + "login_form_submit": "Connetti", + "utrack_title": "Utente", + "created_at": "Creato il", + "updated_at": "Modificato il", + "created_by": "Creato da", + "updated_by": "Aggiornato da", + "close": "Chiuso", + "anonymous": "Anonimo", + "enum_animation_speed_slower": "Lentamente", + "enum_animation_speed_slow": "Lento", + "enum_animation_speed_normal": "Normale", + "enum_animation_speed_fast": "Veloce", + "enum_animation_speed_faster": "Velocemente", + "enum_variable_section_general": "1. Generale", + "enum_variable_section_player_options": "2. Opzioni monitor", + "enum_variable_section_player_animation": "3. Animazioni monitor", + "enum_variable_section_playlist": "4. Playlist", + "enum_variable_section_fleet": "5. Gestione panoramica", + "enum_variable_section_security": "6. Sicurezza", + "enum_application_language_english": "Inglese", + "enum_application_language_french": "Francese", + "enum_application_language_italian": "Italiano", + "enum_application_language_spanish": "Spagnolo", + "enum_content_type_url": "URL", + "enum_content_type_video": "Video", + "enum_content_type_picture": "Immagine", + "enum_content_type_youtube": "Youtube", + "enum_content_type_url_object_label": "Inserisci il collegamento URL", + "enum_content_type_video_object_label": "Carica il tuo video (solo MP4)", + "enum_content_type_picture_object_label": "Carica la tua immagine", + "enum_content_type_youtube_object_label": "Inserisci l'URL del video Youtube", + "enum_operating_system_raspbian": "Raspbian", + "enum_operating_system_debian": "Debian", + "enum_operating_system_windows": "Windows", + "enum_operating_system_macos": "MacOS", + "enum_operating_system_fedora": "Fedora", + "enum_operating_system_ubuntu": "Ubuntu", + "enum_operating_system_suse": "Suse", + "enum_operating_system_redhat": "RedHat", + "enum_operating_system_centos": "CentOS", + "enum_operating_system_other": "Altro", + "sysinfo_rpi_model": "Raspberry Pi Model", + "sysinfo_rpi_model_unknown": "Informazioni Raspberry Pi non disponibili", + "sysinfo_storage_free_space": "Spazio libero", + "sysinfo_memory_usage": "Memoria usata", + "sysinfo_os_version": "OS Version", + "sysinfo_install_directory": "Percorso installazione", + "sysinfo_network_interface": "interfaccia di rete", + "sysinfo_mac_address": "Indirizzo MAC", + "sysinfo_ip_address": "indirizzo IP", + "player_default_welcome_message": "Per gestire questo lettore, vai al browser all'indirizzo %link%" } \ No newline at end of file diff --git a/src/Application.py b/src/Application.py index 1f3970a..9ab0ae6 100644 --- a/src/Application.py +++ b/src/Application.py @@ -24,6 +24,11 @@ class Application: signal.signal(signal.SIGINT, self.signal_handler) def start(self) -> None: + variable = self._model_store.variable().get_one_by_name('start_counter') + + if variable: + self._model_store.variable().update_by_name(variable.name, variable.as_int() + 1) + self._web_server.run() def signal_handler(self, signal, frame) -> None: diff --git a/src/controller/AuthController.py b/src/controller/AuthController.py index e0753a8..46cab46 100644 --- a/src/controller/AuthController.py +++ b/src/controller/AuthController.py @@ -30,17 +30,17 @@ class AuthController(ObController): login_error = None if current_user.is_authenticated: - return redirect(url_for('slideshow_slide_list')) + return redirect(url_for('playlist')) if not self._model_store.variable().map().get('auth_enabled').as_bool(): - return redirect(url_for('slideshow_slide_list')) + return redirect(url_for('playlist')) if len(request.form): user = self._model_store.user().get_one_by_username(request.form['username'], enabled=True) if user: if user.password == self._model_store.user().encode_password(request.form['password']): login_user(user) - return redirect(url_for('slideshow_slide_list')) + return redirect(url_for('playlist')) else: login_error = 'bad_credentials' else: diff --git a/src/controller/PlayerController.py b/src/controller/PlayerController.py index c0f07fb..2ba7d04 100644 --- a/src/controller/PlayerController.py +++ b/src/controller/PlayerController.py @@ -37,13 +37,22 @@ class PlayerController(ObController): playlist_id = current_playlist.id if current_playlist else None items = self._get_playlist(playlist_id=playlist_id, preview_content_id=preview_content_id) + intro_slide_duration = self._model_store.variable().get_one_by_name('intro_slide_duration').eval() + + if items['preview_mode'] or request.args.get('intro', '1') == '0': + intro_slide_duration = 0 + + animation_enabled = self._model_store.variable().get_one_by_name('slide_animation_enabled').eval() + + if request.args.get('animation', '1') == '0': + animation_enabled = False return render_template( 'player/player.jinja.html', items=items, - default_slide_duration=0 if items['preview_mode'] else self._model_store.variable().get_one_by_name('default_slide_duration').eval(), + intro_slide_duration=intro_slide_duration, polling_interval=self._model_store.variable().get_one_by_name('polling_interval'), - slide_animation_enabled=self._model_store.variable().get_one_by_name('slide_animation_enabled'), + slide_animation_enabled=animation_enabled, slide_animation_entrance_effect=self._model_store.variable().get_one_by_name('slide_animation_entrance_effect'), slide_animation_exit_effect=self._model_store.variable().get_one_by_name('slide_animation_exit_effect'), slide_animation_speed=self._model_store.variable().get_one_by_name('slide_animation_speed'), diff --git a/src/controller/PlaylistController.py b/src/controller/PlaylistController.py index 7862d8f..b57e520 100644 --- a/src/controller/PlaylistController.py +++ b/src/controller/PlaylistController.py @@ -1,6 +1,7 @@ import json -from flask import Flask, render_template, redirect, request, url_for, jsonify +from flask import Flask, render_template, redirect, request, url_for, jsonify, abort +from src.exceptions.PlaylistSlugAlreadyExist import PlaylistSlugAlreadyExist from src.service.ModelStore import ModelStore from src.model.entity.Playlist import Playlist from src.interface.ObController import ObController @@ -17,20 +18,31 @@ class PlaylistController(ObController): return decorated_function def register(self): - self._app.add_url_rule('/playlist/list', 'playlist_list', self.guard_playlist(self._auth(self.playlist_list)), methods=['GET']) + self._app.add_url_rule('/playlist', 'playlist', self.guard_playlist(self._auth(self.playlist)), methods=['GET']) + self._app.add_url_rule('/playlist/list/', 'playlist_list', self.guard_playlist(self._auth(self.playlist_list)), methods=['GET']) self._app.add_url_rule('/playlist/add', 'playlist_add', self.guard_playlist(self._auth(self.playlist_add)), methods=['POST']) - self._app.add_url_rule('/playlist/edit', 'playlist_edit', self.guard_playlist(self._auth(self.playlist_edit)), methods=['POST']) - self._app.add_url_rule('/playlist/toggle', 'playlist_toggle', self.guard_playlist(self._auth(self.playlist_toggle)), methods=['POST']) - self._app.add_url_rule('/playlist/delete', 'playlist_delete', self.guard_playlist(self._auth(self.playlist_delete)), methods=['DELETE']) + self._app.add_url_rule('/playlist/save', 'playlist_save', self.guard_playlist(self._auth(self.playlist_save)), methods=['POST']) + self._app.add_url_rule('/playlist/delete/', 'playlist_delete', self.guard_playlist(self._auth(self.playlist_delete)), methods=['GET']) - def playlist_list(self): + def playlist(self): + return redirect(url_for('playlist_list', playlist_id=0)) + + def playlist_list(self, playlist_id: int = 0): + current_playlist = self._model_store.playlist().get(playlist_id) + playlists = self._model_store.playlist().get_all(sort="created_at", ascending=False) durations = self._model_store.playlist().get_durations_by_playlists() + + if not current_playlist and len(playlists) > 0: + current_playlist = playlists[0] + return render_template( 'playlist/list.jinja.html', - playlists=self._model_store.playlist().get_all(ascending=True), - enabled_playlists=self._model_store.playlist().get_enabled_playlists(with_default=True), - disabled_playlists=self._model_store.playlist().get_disabled_playlists(), - durations=durations + error=request.args.get('error', None), + current_playlist=current_playlist, + playlists=playlists, + durations=durations, + slides=self._model_store.slide().get_slides(playlist_id=current_playlist.id), + contents={content.id: content for content in self._model_store.content().get_contents()}, ) def playlist_add(self): @@ -40,32 +52,28 @@ class PlaylistController(ObController): time_sync=False ) - self._model_store.playlist().add_form(playlist) + try: + playlist = self._model_store.playlist().add_form(playlist) + except PlaylistSlugAlreadyExist as e: + abort(409) - return redirect(url_for('playlist_list')) + return redirect(url_for('playlist_list', playlist_id=playlist.id)) - def playlist_edit(self): + def playlist_save(self): self._model_store.playlist().update_form( id=request.form['id'], name=request.form['name'], - time_sync=request.form['time_sync'], + time_sync=True if 'time_sync' in request.form else False, + enabled=True if 'enabled' in request.form else False ) - return redirect(url_for('playlist_list')) + return redirect(url_for('playlist_list', playlist_id=request.form['id'])) - def playlist_toggle(self): - data = request.get_json() - self._model_store.playlist().update_enabled(data.get('id'), data.get('enabled')) - return jsonify({'status': 'ok'}) + def playlist_delete(self, playlist_id: int): + if self._model_store.slide().count_slides_for_playlist(playlist_id) > 0: + return redirect(url_for('playlist_list', playlist_id=playlist_id, error='playlist_delete_has_slides')) - def playlist_delete(self): - data = request.get_json() - id = data.get('id') + if self._model_store.node_player_group().count_node_player_groups_for_playlist(playlist_id) > 0: + return redirect(url_for('playlist_list', playlist_id=playlist_id, error='playlist_delete_has_node_player_groups')) - if self._model_store.slide().count_slides_for_playlist(id) > 0: - return jsonify({'status': 'error', 'message': self.t('playlist_delete_has_slides')}), 400 - - if self._model_store.node_player_group().count_node_player_groups_for_playlist(id) > 0: - return jsonify({'status': 'error', 'message': self.t('playlist_delete_has_node_player_groups')}), 400 - - self._model_store.playlist().delete(id) - return jsonify({'status': 'ok'}) + self._model_store.playlist().delete(playlist_id) + return redirect(url_for('playlist')) diff --git a/src/controller/SlideController.py b/src/controller/SlideController.py index 22e090a..c4b49d8 100644 --- a/src/controller/SlideController.py +++ b/src/controller/SlideController.py @@ -16,31 +16,14 @@ class SlideController(ObController): def register(self): self._app.add_url_rule('/manage', 'manage', self.manage, methods=['GET']) - self._app.add_url_rule('/slideshow', 'slideshow_slide_list', self._auth(self.slideshow), methods=['GET']) - self._app.add_url_rule('/slideshow/playlist/set/', 'slideshow_slide_list_playlist_use', self._auth(self.slideshow), methods=['GET']) self._app.add_url_rule('/slideshow/slide/add', 'slideshow_slide_add', self._auth(self.slideshow_slide_add), methods=['POST']) self._app.add_url_rule('/slideshow/slide/edit', 'slideshow_slide_edit', self._auth(self.slideshow_slide_edit), methods=['POST']) - self._app.add_url_rule('/slideshow/slide/toggle', 'slideshow_slide_toggle', self._auth(self.slideshow_slide_toggle), methods=['POST']) self._app.add_url_rule('/slideshow/slide/delete', 'slideshow_slide_delete', self._auth(self.slideshow_slide_delete), methods=['DELETE']) self._app.add_url_rule('/slideshow/slide/position', 'slideshow_slide_position', self._auth(self.slideshow_slide_position), methods=['POST']) - self._app.add_url_rule('/slideshow/player-refresh', 'slideshow_player_refresh', self._auth(self.slideshow_player_refresh), methods=['GET']) + self._app.add_url_rule('/slideshow/player-refresh', 'slideshow_player_refresh/', self._auth(self.slideshow_player_refresh), methods=['GET']) def manage(self): - return redirect(url_for('slideshow_slide_list')) - - def slideshow(self, playlist_id: int = 0): - current_playlist = self._model_store.playlist().get(playlist_id) - playlist_id = current_playlist.id if current_playlist else None - return render_template( - 'slideshow/slides/list.jinja.html', - current_playlist=current_playlist, - playlists=self._model_store.playlist().get_enabled_playlists(), - enabled_slides=self._model_store.slide().get_slides(playlist_id=playlist_id, enabled=True), - disabled_slides=self._model_store.slide().get_slides(playlist_id=playlist_id, enabled=False), - var_last_restart=self._model_store.variable().get_one_by_name('last_restart'), - contents={content.id: content.name for content in self._model_store.content().get_contents()}, - enum_content_type=ContentType - ) + return redirect(url_for('playlist')) def slideshow_slide_add(self): content = None @@ -67,9 +50,9 @@ class SlideController(ObController): self._post_update() if slide.playlist_id: - return redirect(url_for('slideshow_slide_list_playlist_use', playlist_id=slide.playlist_id)) + return redirect(url_for('playlist_list', playlist_id=slide.playlist_id)) - return redirect(url_for('slideshow_slide_list')) + return redirect(url_for('playlist')) def slideshow_slide_edit(self): slide = self._model_store.slide().update_form( @@ -83,15 +66,9 @@ class SlideController(ObController): self._post_update() if slide.playlist_id: - return redirect(url_for('slideshow_slide_list_playlist_use', playlist_id=slide.playlist_id)) + return redirect(url_for('playlist_list', playlist_id=slide.playlist_id)) - return redirect(url_for('slideshow_slide_list')) - - def slideshow_slide_toggle(self): - data = request.get_json() - self._model_store.slide().update_enabled(data.get('id'), data.get('enabled')) - self._post_update() - return jsonify({'status': 'ok'}) + return redirect(url_for('playlist')) def slideshow_slide_delete(self): data = request.get_json() @@ -105,11 +82,12 @@ class SlideController(ObController): self._post_update() return jsonify({'status': 'ok'}) - def slideshow_player_refresh(self): + def slideshow_player_refresh(self, playlist_id: int): self._model_store.variable().update_by_name("refresh_player_request", time.time()) return redirect( url_for( - 'slideshow_slide_list', + 'playlist_list', + playlist_id=playlist_id, refresh_player=self._model_store.variable().get_one_by_name('polling_interval').as_int() ) ) diff --git a/src/exceptions/PlaylistSlugAlreadyExist.py b/src/exceptions/PlaylistSlugAlreadyExist.py new file mode 100644 index 0000000..0f3113e --- /dev/null +++ b/src/exceptions/PlaylistSlugAlreadyExist.py @@ -0,0 +1,2 @@ +class PlaylistSlugAlreadyExist(Exception): + pass diff --git a/src/manager/DatabaseManager.py b/src/manager/DatabaseManager.py index d7f8809..e34ce3e 100644 --- a/src/manager/DatabaseManager.py +++ b/src/manager/DatabaseManager.py @@ -120,8 +120,13 @@ class DatabaseManager: params=tuple(v for v in values.values()) ) - def get_one_by_query(self, table_name: str, query: str = "1=1", sort: Optional[str] = None, ascending=True, values: dict = {}) -> list: - query = "select * from {} where {} {}".format(table_name, query, "ORDER BY {} {}".format(sort, "ASC" if ascending else "DESC") if sort else "") + def get_one_by_query(self, table_name: str, query: str = "1=1", values: dict = {}, sort: Optional[str] = None, ascending=True, limit: Optional[int] = None) -> list: + query = "select * from {} where {} {} {}".format( + table_name, + query, + "ORDER BY {} {}".format(sort, "ASC" if ascending else "DESC") if sort else "", + "LIMIT {}".format(limit) if limit else "" + ) lines = self.execute_read_query(query=query, params=tuple(v for v in values.values())) count = len(lines) @@ -216,6 +221,7 @@ class DatabaseManager: "DROP TABLE IF EXISTS fleet_studio", "ALTER TABLE slideshow RENAME TO slides", "DELETE FROM settings WHERE name = 'fleet_studio_enabled'", + "DELETE FROM settings WHERE name = 'default_slide_duration'", "UPDATE content SET uuid = id WHERE uuid = '' or uuid is null", ] diff --git a/src/manager/NodePlayerGroupManager.py b/src/manager/NodePlayerGroupManager.py index e540199..f9a40da 100644 --- a/src/manager/NodePlayerGroupManager.py +++ b/src/manager/NodePlayerGroupManager.py @@ -72,10 +72,9 @@ class NodePlayerGroupManager(ModelManager): def get_node_players_groups(self, playlist_id: Optional[int] = None) -> List[NodePlayerGroup]: query = " 1=1 " + if playlist_id: query = "{} {}".format(query, "AND playlist_id = {}".format(playlist_id)) - else: - query = "{} {}".format(query, "AND playlist_id is NULL") return self.get_by(query=query, sort="name") diff --git a/src/manager/PlaylistManager.py b/src/manager/PlaylistManager.py index 010b4d4..45f257d 100644 --- a/src/manager/PlaylistManager.py +++ b/src/manager/PlaylistManager.py @@ -3,7 +3,8 @@ import os from typing import Dict, Optional, List, Tuple, Union from src.model.entity.Playlist import Playlist -from src.util.utils import get_optional_string, get_yt_video_id, slugify +from src.util.utils import get_optional_string, get_yt_video_id, slugify, slugify_next +from src.exceptions.PlaylistSlugAlreadyExist import PlaylistSlugAlreadyExist from src.manager.DatabaseManager import DatabaseManager from src.manager.SlideManager import SlideManager from src.manager.LangManager import LangManager @@ -54,8 +55,8 @@ class PlaylistManager(ModelManager): def get_by(self, query, sort: Optional[str] = None, values: dict = {}) -> List[Playlist]: return self.hydrate_list(self._db.get_by_query(self.TABLE_NAME, query=query, sort=sort, values=values)) - def get_one_by(self, query, values: dict = {}) -> Optional[Playlist]: - object = self._db.get_one_by_query(self.TABLE_NAME, query=query, values=values) + def get_one_by(self, query, values: dict = {}, sort: Optional[str] = None, ascending=True, limit: Optional[int] = None) -> Optional[Playlist]: + object = self._db.get_one_by_query(self.TABLE_NAME, query=query, values=values, sort=sort, ascending=ascending, limit=limit) if not object: return None @@ -105,8 +106,25 @@ class PlaylistManager(ModelManager): for playlist_id, edits in edits_playlists.items(): self._db.update_by_id(self.TABLE_NAME, playlist_id, edits) + def get_available_slug(self, slug) -> str: + known_playlist = {"slug": slug} + next_slug = slug + while known_playlist is not None: + next_slug = slugify_next(next_slug) + known_playlist = self.get_one_by(query="slug = ?", values={"slug": next_slug}, sort="created_at", ascending=False, limit=1) + + return next_slug + def pre_add(self, playlist: Dict) -> Dict: playlist["slug"] = slugify(playlist["name"]) + + known_playlist = self.get_one_by(query="slug = ?", values={ + "slug": playlist["slug"] + }, sort="created_at", ascending=False, limit=1) + + if known_playlist: + playlist["slug"] = self.get_available_slug(playlist["slug"]) + self.user_manager.track_user_on_create(playlist) self.user_manager.track_user_on_update(playlist) return playlist @@ -131,7 +149,7 @@ class PlaylistManager(ModelManager): def post_delete(self, playlist_id: str) -> str: return playlist_id - def update_form(self, id: int, name: str, time_sync: bool) -> None: + def update_form(self, id: int, name: str, time_sync: bool, enabled: bool) -> None: playlist = self.get(id) if not playlist: @@ -139,13 +157,14 @@ class PlaylistManager(ModelManager): form = { "name": name, - "time_sync": time_sync + "time_sync": time_sync, + "enabled": enabled } self._db.update_by_id(self.TABLE_NAME, id, self.pre_update(form)) self.post_update(id) - def add_form(self, playlist: Union[Playlist, Dict]) -> None: + def add_form(self, playlist: Union[Playlist, Dict]) -> Playlist: form = playlist if not isinstance(playlist, dict): @@ -153,7 +172,11 @@ class PlaylistManager(ModelManager): del form['id'] self._db.add(self.TABLE_NAME, self.pre_add(form)) + playlist = self.get_one_by(query="slug = ?", values={ + "slug": form["slug"] + }) self.post_add(playlist.id) + return playlist def delete(self, id: int) -> None: playlist = self.get(id) diff --git a/src/manager/SlideManager.py b/src/manager/SlideManager.py index 7246a98..8b3940c 100644 --- a/src/manager/SlideManager.py +++ b/src/manager/SlideManager.py @@ -73,13 +73,14 @@ class SlideManager(ModelManager): for slide_id, edits in edits_slides.items(): self._db.update_by_id(self.TABLE_NAME, slide_id, edits) - def get_slides(self, playlist_id: Optional[int] = None, content_id: Optional[int] = None, enabled: bool = True) -> List[Slide]: - query = "enabled = {}".format("1" if enabled else "0") + def get_slides(self, playlist_id: Optional[int] = None, content_id: Optional[int] = None, enabled: Optional[bool] = None) -> List[Slide]: + query = " 1=1 " + + if enabled is not None: + query = "{} AND enabled = {} ".format(query, "1" if enabled else "0") if playlist_id: query = "{} {}".format(query, "AND playlist_id = {}".format(playlist_id)) - else: - query = "{} {}".format(query, "AND playlist_id is NULL") if content_id: query = "{} {}".format(query, "AND content_id = {}".format(content_id)) diff --git a/src/manager/VariableManager.py b/src/manager/VariableManager.py index f50300a..101be72 100644 --- a/src/manager/VariableManager.py +++ b/src/manager/VariableManager.py @@ -1,5 +1,6 @@ import json import time +import math from typing import Dict, Optional, List, Tuple, Union from src.manager.DatabaseManager import DatabaseManager @@ -111,7 +112,7 @@ class VariableManager: {"name": "slide_upload_limit", "section": self.t(VariableSection.GENERAL), "value": 32, "unit": VariableUnit.MEGABYTE, "type": VariableType.INT, "editable": True, "description": self.t('settings_variable_desc_slide_upload_limit'), "refresh_player": False}, ### Player Options - {"name": "default_slide_duration", "section": self.t(VariableSection.PLAYER_OPTIONS), "value": 3, "unit": VariableUnit.SECOND, "type": VariableType.INT, "editable": True, "description": self.t('settings_variable_desc_default_slide_duration'), "refresh_player": False}, + {"name": "intro_slide_duration", "section": self.t(VariableSection.PLAYER_OPTIONS), "value": 3, "unit": VariableUnit.SECOND, "type": VariableType.INT, "editable": True, "description": self.t('settings_variable_desc_intro_slide_duration'), "refresh_player": False}, {"name": "default_slide_time_with_seconds", "section": self.t(VariableSection.PLAYER_OPTIONS), "value": False, "type": VariableType.BOOL, "editable": True, "description": self.t('settings_variable_desc_default_slide_time_with_seconds'), "refresh_player": False}, {"name": "polling_interval", "section": self.t(VariableSection.PLAYER_OPTIONS), "value": 5, "unit": VariableUnit.SECOND, "type": VariableType.INT, "editable": True, "description": self.t('settings_variable_desc_polling_interval'), "refresh_player": True}, @@ -132,6 +133,7 @@ class VariableManager: {"name": "auth_enabled", "section": self.t(VariableSection.SECURITY), "value": False, "type": VariableType.BOOL, "editable": True, "description": self.t('settings_variable_desc_auth_enabled'), "description_edition": self.t('settings_variable_desc_edition_auth_enabled'), "refresh_player": False}, # Not editable (System information) + {"name": "start_counter", "value": 0, "type": VariableType.INT, "editable": False, "description": self.t('settings_variable_desc_ro_start_counter')}, {"name": "last_folder_content", "value": FOLDER_ROOT_PATH, "type": VariableType.STRING, "editable": False, "description": self.t('settings_variable_desc_ro_last_folder_content')}, {"name": "last_folder_node_player", "value": FOLDER_ROOT_PATH, "type": VariableType.STRING, "editable": False, "description": self.t('settings_variable_desc_ro_last_folder_node_player')}, {"name": "last_restart", "value": time.time(), "type": VariableType.TIMESTAMP, "editable": False, "description": self.t('settings_variable_desc_ro_editable')}, diff --git a/src/model/entity/Playlist.py b/src/model/entity/Playlist.py index 96a8105..572145e 100644 --- a/src/model/entity/Playlist.py +++ b/src/model/entity/Playlist.py @@ -89,7 +89,7 @@ class Playlist: return f"Playlist(" \ f"id='{self.id}',\n" \ f"name='{self.name}',\n" \ - f"nameslug='{self.slug}',\n" \ + f"slug='{self.slug}',\n" \ f"enabled='{self.enabled}',\n" \ f"time_sync='{self.time_sync}',\n" \ f"created_by='{self.created_by}',\n" \ diff --git a/src/model/enum/HookType.py b/src/model/enum/HookType.py index c29b8db..73eb49e 100644 --- a/src/model/enum/HookType.py +++ b/src/model/enum/HookType.py @@ -3,11 +3,6 @@ from enum import Enum class HookType(Enum): - H_SLIDESHOW_SLIDES_TOOLBAR_ACTIONS_START = 'h_slideshow_slides_toolbar_actions_start' - H_SLIDESHOW_SLIDES_TOOLBAR_ACTIONS_END = 'h_slideshow_slides_toolbar_actions_end' - H_SLIDESHOW_SLIDES_CSS = 'h_slideshow_slides_css' - H_SLIDESHOW_SLIDES_JAVASCRIPT = 'h_slideshow_slides_javascript' - H_SLIDESHOW_CONTENT_TOOLBAR_ACTIONS_START = 'h_slideshow_toolbar_actions_start' H_SLIDESHOW_CONTENT_TOOLBAR_ACTIONS_END = 'h_slideshow_toolbar_actions_end' H_SLIDESHOW_CONTENT_CSS = 'h_slideshow_css' diff --git a/src/util/utils.py b/src/util/utils.py index 8662ad1..d20e24b 100644 --- a/src/util/utils.py +++ b/src/util/utils.py @@ -255,3 +255,13 @@ def merge_dicts(dict1, dict2): def dictsort(dict1, attribute="position"): return dict(sorted(dict1.items(), key=lambda item: item[1][attribute])) + + +def slugify_next(slug: str) -> str: + parts = slug.rsplit('-', 1) + + if len(parts) > 1 and parts[-1].isdigit(): + next_number = int(parts[-1]) + 1 + return f"{parts[0]}-{next_number}" + else: + return f"{slug}-1" diff --git a/views/base.jinja.html b/views/base.jinja.html index c82820b..ae15b58 100755 --- a/views/base.jinja.html +++ b/views/base.jinja.html @@ -59,7 +59,7 @@ "position": 0, "pills": [ {"name": "Bibliothèque", "route": "slideshow_content_list", "icon": "fa-image"}, - {"name": "Playlists", "route": "playlist_list", "icon": "fa-play"}, + {"name": "Playlists", "route": "playlist", "icon": "fa-play"}, ] }, "configuration": { @@ -115,7 +115,7 @@ {% block header %}

- + Obscreen @@ -164,7 +164,8 @@

- {{ HOOK(H_SLIDESHOW_CONTENT_TOOLBAR_ACTIONS_START) }} + {{ HOOK(H_FLEET_NODE_PLAYER_TOOLBAR_ACTIONS_START) }}
- {{ HOOK(H_SLIDESHOW_CONTENT_TOOLBAR_ACTIONS_END) }} + {{ HOOK(H_FLEET_NODE_PLAYER_TOOLBAR_ACTIONS_END) }}
@@ -74,7 +73,7 @@ {% set node_player_children = node_players[folder.id]|default([]) %} {% set has_children = folder.children or node_player_children %} -
  • +
  • {{ folder.name }} diff --git a/views/player/player.jinja.html b/views/player/player.jinja.html index ef121b4..ecb9dc0 100755 --- a/views/player/player.jinja.html +++ b/views/player/player.jinja.html @@ -5,7 +5,7 @@ - {% if slide_animation_enabled.eval() %} + {% if slide_animation_enabled %} {% endif %}