From 13c0db3539879b13fd491978ef5ceccdf586e7b7 Mon Sep 17 00:00:00 2001 From: Michael Reber Date: Sun, 3 Jul 2022 22:27:47 +0200 Subject: [PATCH] Update to maintainer version --- .gitignore | 3 +- README.md | 7 +- assets/css/login.css | 306 ++ assets/css/styles.css | 506 +-- {images => assets/images}/background.jpg | Bin assets/images/michu-it_logo_weiss.png | Bin 0 -> 40172 bytes assets/js/script.js | 210 +- index.php | 235 +- login.php | 595 +--- manage.php | 4110 ++++++++++++++++++++++ phpinfo.php | 3 + scan.php | 23 +- 12 files changed, 5159 insertions(+), 839 deletions(-) create mode 100644 assets/css/login.css rename {images => assets/images}/background.jpg (100%) create mode 100644 assets/images/michu-it_logo_weiss.png create mode 100644 manage.php create mode 100644 phpinfo.php diff --git a/.gitignore b/.gitignore index 3102eaa..72f1563 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1 @@ -# Ignore the dev_files directory -_NEW +._* \ No newline at end of file diff --git a/README.md b/README.md index 439a290..2260032 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,7 @@ -# web-learning-manager +# Netcloud Learning Manager +The Netcloud learning manager is a webtool, which was developed for all employees of the company Netcloud AG, in order to educate themselves independently and personally with licensed videos from LinkedIn Learning and the Linuxacademy. + +The application can be accessed at the following URL: https://learning-manager.apps.netcloud.local/ + +The password is in our internal wiki. \ No newline at end of file diff --git a/assets/css/login.css b/assets/css/login.css new file mode 100644 index 0000000..c9f1a9d --- /dev/null +++ b/assets/css/login.css @@ -0,0 +1,306 @@ +*, +*:before, +*:after { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +html, +body { + font-size: 62.5%; + height: 100%; + overflow: hidden; +} + +@media (max-width: 768px) { + + html, + body { + font-size: 50%; + } +} + +svg { + display: inline-block; + width: 2rem; + height: 2rem; + overflow: visible; +} + +.svg-icon { + cursor: pointer; +} + +.svg-icon path { + stroke: rgba(255, 255, 255, 0.9); + fill: none; + stroke-width: 1; +} + +input, +button { + outline: none; + border: none; +} + +.netcloud-logo { + background-image: url("../../assets/images/Netcloud-Logo_Weiss.png"); + width: 104px; + height: 60px; + background-size: contain; + margin-top: 30px; + background-repeat: no-repeat; +} + +.container { + position: relative; + height: 100%; + background-image: url("../../assets/images/background.jpg"); + background-size: cover; + overflow: auto; + font-family: "Open Sans", Helvetica, Arial, sans-serif; +} + +.row { + position: absolute; + top: 50%; + left: 50%; + margin-left: -15rem; + margin-top: -26.5rem; + width: 30rem; + height: 53rem; + overflow: hidden; +} + +.login { + position: relative; + height: 100%; + background: -webkit-linear-gradient(top, rgba(113, 113, 113, 0.8) 0%, rgba(0, 0, 0, 0.6) 100%); + background: linear-gradient(to bottom, rgb(96 121 148 / 80%) 0%, rgb(2 24 47 / 65%) 100%); + -webkit-transition: opacity 0.1s, -webkit-transform 0.3s cubic-bezier(0.17, -0.65, 0.665, 1.25); + transition: opacity 0.1s, -webkit-transform 0.3s cubic-bezier(0.17, -0.65, 0.665, 1.25); + transition: opacity 0.1s, transform 0.3s cubic-bezier(0.17, -0.65, 0.665, 1.25); + transition: opacity 0.1s, transform 0.3s cubic-bezier(0.17, -0.65, 0.665, 1.25), -webkit-transform 0.3s cubic-bezier(0.17, -0.65, 0.665, 1.25); + -webkit-transform: scale(1); + transform: scale(1); +} + +.login.inactive { + opacity: 0; + -webkit-transform: scale(1.1); + transform: scale(1.1); +} + +.login__lock { + position: absolute; + /*top: 8rem;*/ + left: 10rem; + width: 14rem; + height: 2.8rem; + font-size: 128px; + +} + +@media screen and (min-width: 769px) { + .login__lock { + font-size: 152px; + } +} + +.login__check { + position: absolute; + top: 16rem; + left: 13.5rem; + width: 14rem; + height: 2.8rem; + background: #fff; + -webkit-transform-origin: 0 100%; + transform-origin: 0 100%; + -webkit-transform: rotate(-45deg); + transform: rotate(-45deg); +} + +.login__check:before { + content: ""; + position: absolute; + left: 0; + bottom: 100%; + width: 2.8rem; + height: 5.2rem; + background: #fff; + box-shadow: inset -0.2rem -2rem 2rem rgba(0, 0, 0, 0.2); +} + +.login__form { + position: absolute; + top: 50%; + left: 0; + width: 100%; + height: 50%; + padding: 1.5rem 2.5rem; + text-align: center; +} + +.login__row { + height: 5rem; + padding-top: 1rem; + border-bottom: 1px solid rgba(255, 255, 255, 0.2); +} + +.login__icon { + margin-bottom: -0.4rem; + margin-right: 0.5rem; +} + +.login__icon.name path { + stroke-dasharray: 73.50196075439453; + stroke-dashoffset: 73.50196075439453; + -webkit-animation: animatePath 2s 0.5s forwards; + animation: animatePath 2s 0.5s forwards; +} + +.login__icon.pass path { + stroke-dasharray: 92.10662841796875; + stroke-dashoffset: 92.10662841796875; + -webkit-animation: animatePath 2s 0.5s forwards; + animation: animatePath 2s 0.5s forwards; +} + +.login__input { + display: inline-block; + width: 22rem; + height: 100%; + padding-left: 1.5rem; + font-size: 1.5rem; + background: transparent; + color: #FDFCFD; +} + +.login__submit { + position: relative; + width: 100%; + height: 4rem; + margin: 5rem 0 2.2rem; + color: rgba(255, 255, 255, 0.8); + background: #383838; + font-size: 1.5rem; + border-radius: 3rem; + cursor: pointer; + overflow: hidden; + -webkit-transition: width 0.3s 0.15s, font-size 0.1s 0.15s; + transition: width 0.3s 0.15s, font-size 0.1s 0.15s; +} + +.login__submit:after { + content: ""; + position: absolute; + top: 50%; + left: 50%; + margin-left: -1.5rem; + margin-top: -1.5rem; + width: 3rem; + height: 3rem; + border: 2px dotted #fff; + border-radius: 50%; + border-left: none; + border-bottom: none; + -webkit-transition: opacity 0.1s 0.4s; + transition: opacity 0.1s 0.4s; + opacity: 0; +} + +.login__submit.processing { + width: 4rem; + font-size: 0; +} + +.login__submit.processing:after { + opacity: 1; + -webkit-animation: rotate 0.5s 0.4s infinite linear; + animation: rotate 0.5s 0.4s infinite linear; +} + +.login__submit.success { + -webkit-transition: opacity 0.1s 0.3s, background-color 0.1s 0.3s, -webkit-transform 0.3s 0.1s ease-out; + transition: opacity 0.1s 0.3s, background-color 0.1s 0.3s, -webkit-transform 0.3s 0.1s ease-out; + transition: transform 0.3s 0.1s ease-out, opacity 0.1s 0.3s, background-color 0.1s 0.3s; + transition: transform 0.3s 0.1s ease-out, opacity 0.1s 0.3s, background-color 0.1s 0.3s, -webkit-transform 0.3s 0.1s ease-out; + -webkit-transform: scale(30); + transform: scale(30); + opacity: 0.9; +} + +.login__submit.success:after { + -webkit-transition: opacity 0.1s 0s; + transition: opacity 0.1s 0s; + opacity: 0; + -webkit-animation: none; + animation: none; +} + +.login__signup { + font-size: 1.2rem; + color: #ABA8AE; +} + +.login__signup a { + color: #fff; + cursor: pointer; +} + +.ripple { + position: absolute; + width: 15rem; + height: 15rem; + margin-left: -7.5rem; + margin-top: -7.5rem; + background: rgba(0, 0, 0, 0.4); + -webkit-transform: scale(0); + transform: scale(0); + -webkit-animation: animRipple 0.4s; + animation: animRipple 0.4s; + border-radius: 50%; +} + +@-webkit-keyframes animRipple { + to { + -webkit-transform: scale(3.5); + transform: scale(3.5); + opacity: 0; + } +} + +@keyframes animRipple { + to { + -webkit-transform: scale(3.5); + transform: scale(3.5); + opacity: 0; + } +} + +@-webkit-keyframes rotate { + to { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} + +@keyframes rotate { + to { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} + +@-webkit-keyframes animatePath { + to { + stroke-dashoffset: 0; + } +} + +@keyframes animatePath { + to { + stroke-dashoffset: 0; + } +} \ No newline at end of file diff --git a/assets/css/styles.css b/assets/css/styles.css index 56e1228..18b17d1 100644 --- a/assets/css/styles.css +++ b/assets/css/styles.css @@ -1,32 +1,43 @@ @charset "utf-8"; - - /*------------------------- Simple reset --------------------------*/ -*{ - margin:0; - padding:0; +* { + margin: 0; + padding: 0; font-family: system-ui; } -html { - /* Full height */ - height: 100%; +html { + /* Full height */ + height: 100%; /* The image used */ - background-image: url("../../images/background.jpg"); - - background-color: #373743; - /* Center and scale the image nicely */ - background-position: center center; - background-size: cover; - + background-image: url("../../assets/images/background.jpg"); + background-color: #373743; + /* Center and scale the image nicely */ + background-position: center center; + background-size: cover; font: 14px normal Arial, Helvetica, sans-serif; z-index: -4; overflow-y: scroll; + /*Fix for moving page because of scrole baar*/ +} + +.netcloud-logo { + background-image: url("../../assets/images/michu-it_logo_weiss.png"); + width: 132px; + height: 60px; + float: right; + background-size: contain; + margin-top: 46px; + background-repeat: no-repeat; + margin-right: 8px; } +.compensate-for-scrollbar { + margin-right: inherit !important; +} /*------------------------- File manager @@ -34,9 +45,11 @@ html { .filemanager { width: 95%; - max-width:1340px; + max-width: 1340px; + min-height: 500px; position: relative; margin: 30px auto 50px; + background-color: rgb(0 0 0 / 40%); } @media all and (max-width: 965px) { @@ -49,24 +62,93 @@ html { .filemanager .header { font-size: large; height: 30px; - background-color: beige; + background-color: #002751!important; text-align: center; padding-top: 5px; + color: white; + font-weight: 700; } + #nowWatched { display: none; } .fancybox-slide { - padding: 20px 50px !important; + padding: 20px 50px !important; +} + +/*------------------------- + Page loader +-------------------------*/ + +.loader, +.loader:before, +.loader:after { + background: #ffffff; + -webkit-animation: load1 1s infinite ease-in-out; + animation: load1 1s infinite ease-in-out; + width: 1em; + height: 4em; +} + +.loader { + color: #ffffff; + text-indent: -9999em; + margin: 88px auto; + position: relative; + font-size: 11px; + -webkit-transform: translateZ(0); + -ms-transform: translateZ(0); + transform: translateZ(0); + -webkit-animation-delay: -0.16s; + animation-delay: -0.16s; +} +.loader:before, +.loader:after { + position: absolute; + top: 0; + content: ''; +} +.loader:before { + left: -1.5em; + -webkit-animation-delay: -0.32s; + animation-delay: -0.32s; +} +.loader:after { + left: 1.5em; +} +@-webkit-keyframes load1 { + 0%, + 80%, + 100% { + box-shadow: 0 0; + height: 4em; + } + 40% { + box-shadow: 0 -2em; + height: 5em; + } +} +@keyframes load1 { + 0%, + 80%, + 100% { + box-shadow: 0 0; + height: 4em; + } + 40% { + box-shadow: 0 -2em; + height: 5em; + } } + /*------------------------- Breadcrumps -------------------------*/ .filemanager .breadcrumbs { color: #ffffff; - margin-left:20px; + margin-left: 20px; font-size: 13px; font-weight: 700; line-height: 35px; @@ -82,13 +164,12 @@ html { } .filemanager .breadcrumbs .arrow { - color: #6a6a72; + color: #6a6a72; font-size: 13px; font-weight: 700; line-height: 20px; } - /*------------------------- Search box -------------------------*/ @@ -104,12 +185,13 @@ html { width: 40px; height: 40px; margin-top: 6px; + margin-right: 15px; } .filemanager .search:before { content: ''; position: absolute; - margin-top:12px; + margin-top: 12px; width: 10px; height: 11px; border-radius: 50%; @@ -149,21 +231,27 @@ html { -webkit-appearance: none; } -::-webkit-input-placeholder { /* WebKit browsers */ - color: #4d535e; -} -:-moz-placeholder { /* Mozilla Firefox 4 to 18 */ - color: #4d535e; - opacity: 1; +::-webkit-input-placeholder { + /* WebKit browsers */ + color: #4d535e; } -::-moz-placeholder { /* Mozilla Firefox 19+ */ - color: #4d535e; - opacity: 1; + +:-moz-placeholder { + /* Mozilla Firefox 4 to 18 */ + color: #4d535e; + opacity: 1; } -:-ms-input-placeholder { /* Internet Explorer 10+ */ - color: #4d535e; + +::-moz-placeholder { + /* Mozilla Firefox 19+ */ + color: #4d535e; + opacity: 1; } +:-ms-input-placeholder { + /* Internet Explorer 10+ */ + color: #4d535e; +} /*------------------------- Content area @@ -175,8 +263,10 @@ html { } .filemanager .data.animated { - -webkit-animation: showSlowlyElement 700ms; /* Chrome, Safari, Opera */ - animation: showSlowlyElement 700ms; /* Standard syntax */ + -webkit-animation: showSlowlyElement 700ms; + /* Chrome, Safari, Opera */ + animation: showSlowlyElement 700ms; + /* Standard syntax */ } .filemanager .data li { @@ -252,20 +342,23 @@ html { margin: 0 auto; display: none; font-family: Arial; - -webkit-animation: showSlowlyElement 700ms; /* Chrome, Safari, Opera */ - animation: showSlowlyElement 700ms; /* Standard syntax */ + -webkit-animation: showSlowlyElement 700ms; + /* Chrome, Safari, Opera */ + animation: showSlowlyElement 700ms; + /* Standard syntax */ } .filemanager .nothingfound .nofiles { margin: 30px auto; top: 3em; border-radius: 50%; - position:relative; + position: relative; background-color: #d72f6e; width: 11em; height: 11em; line-height: 11.4em; } + .filemanager .nothingfound .nofiles:after { content: '×'; position: absolute; @@ -287,27 +380,38 @@ html { } @media all and (max-width:965px) { - .filemanager .data li { width: 100%; margin: 5px 0; } - } /* Chrome, Safari, Opera */ + @-webkit-keyframes showSlowlyElement { - 100% { transform: scale(1); opacity: 1; } - 0% { transform: scale(1.2); opacity: 0; } + 100% { + transform: scale(1); + opacity: 1; + } + 0% { + transform: scale(1.2); + opacity: 0; + } } /* Standard syntax */ + @keyframes showSlowlyElement { - 100% { transform: scale(1); opacity: 1; } - 0% { transform: scale(1.2); opacity: 0; } + 100% { + transform: scale(1); + opacity: 1; + } + 0% { + transform: scale(1.2); + opacity: 0; + } } - /*------------------------- Icons -------------------------*/ @@ -315,42 +419,41 @@ html { .icon { font-size: 23px; } + .icon.folder { display: inline-block; margin: 1em 0.3em 0em 1em; background-color: transparent; overflow: hidden; } + .icon.folder:before { content: ''; float: left; - background-color: #7ba1ad; - + background-color: #002751!important; width: 1.5em; height: 0.45em; - margin-left: 0.07em; margin-bottom: -0.07em; - border-top-left-radius: 0.1em; border-top-right-radius: 0.1em; - - box-shadow: 1.25em 0.25em 0 0em #7ba1ad; + box-shadow: 1.25em 0.25em 0 0em #002751!important; } + .icon.folder:after { content: ''; float: left; clear: left; - - background-color: #a0d4e4; + background-color: #01356d!important; width: 3em; height: 2.25em; - border-radius: 0.1em; } + .icon.folder.full:before { height: 0.55em; } + .icon.folder.full:after { height: 2.15em; box-shadow: 0 -0.12em 0 0 #ffffff; @@ -369,10 +472,12 @@ html { overflow: hidden; box-shadow: 1.74em -2.1em 0 0 #A4A7AC inset; } + .icon.file:first-line { font-size: 13px; font-weight: 700; } + .icon.file:after { content: ''; position: absolute; @@ -384,129 +489,75 @@ html { right: -4px; } -.icon.file.f-avi, -.icon.file.f-flv, -.icon.file.f-mkv, -.icon.file.f-mov, -.icon.file.f-mpeg, -.icon.file.f-mpg, -.icon.file.f-mp4, -.icon.file.f-m4v, -.icon.file.f-wmv { +.icon.file.f-avi, .icon.file.f-flv, .icon.file.f-mkv, .icon.file.f-mov, .icon.file.f-mpeg, .icon.file.f-mpg, .icon.file.f-mp4, .icon.file.f-m4v, .icon.file.f-wmv { box-shadow: 1.74em -2.1em 0 0 #7e70ee inset; } -.icon.file.f-avi:after, -.icon.file.f-flv:after, -.icon.file.f-mkv:after, -.icon.file.f-mov:after, -.icon.file.f-mpeg:after, -.icon.file.f-mpg:after, -.icon.file.f-mp4:after, -.icon.file.f-m4v:after, -.icon.file.f-wmv:after { + +.icon.file.f-avi:after, .icon.file.f-flv:after, .icon.file.f-mkv:after, .icon.file.f-mov:after, .icon.file.f-mpeg:after, .icon.file.f-mpg:after, .icon.file.f-mp4:after, .icon.file.f-m4v:after, .icon.file.f-wmv:after { border-bottom-color: #5649c1; } -.icon.file.f-mp2, -.icon.file.f-mp3, -.icon.file.f-m3u, -.icon.file.f-wma, -.icon.file.f-xls, -.icon.file.f-xlsx { +.icon.file.f-mp2, .icon.file.f-mp3, .icon.file.f-m3u, .icon.file.f-wma, .icon.file.f-xls, .icon.file.f-xlsx { box-shadow: 1.74em -2.1em 0 0 #5bab6e inset; } -.icon.file.f-mp2:after, -.icon.file.f-mp3:after, -.icon.file.f-m3u:after, -.icon.file.f-wma:after, -.icon.file.f-xls:after, -.icon.file.f-xlsx:after { + +.icon.file.f-mp2:after, .icon.file.f-mp3:after, .icon.file.f-m3u:after, .icon.file.f-wma:after, .icon.file.f-xls:after, .icon.file.f-xlsx:after { border-bottom-color: #448353; } -.icon.file.f-doc, -.icon.file.f-docx, -.icon.file.f-psd{ +.icon.file.f-doc, .icon.file.f-docx, .icon.file.f-psd { box-shadow: 1.74em -2.1em 0 0 #03689b inset; } -.icon.file.f-doc:after, -.icon.file.f-docx:after, -.icon.file.f-psd:after { +.icon.file.f-doc:after, .icon.file.f-docx:after, .icon.file.f-psd:after { border-bottom-color: #2980b9; } -.icon.file.f-gif, -.icon.file.f-jpg, -.icon.file.f-jpeg, -.icon.file.f-pdf, -.icon.file.f-png { +.icon.file.f-gif, .icon.file.f-jpg, .icon.file.f-jpeg, .icon.file.f-pdf, .icon.file.f-png { box-shadow: 1.74em -2.1em 0 0 #e15955 inset; } -.icon.file.f-gif:after, -.icon.file.f-jpg:after, -.icon.file.f-jpeg:after, -.icon.file.f-pdf:after, -.icon.file.f-png:after { + +.icon.file.f-gif:after, .icon.file.f-jpg:after, .icon.file.f-jpeg:after, .icon.file.f-pdf:after, .icon.file.f-png:after { border-bottom-color: #c6393f; } -.icon.file.f-deb, -.icon.file.f-dmg, -.icon.file.f-gz, -.icon.file.f-rar, -.icon.file.f-zip, -.icon.file.f-7z { +.icon.file.f-deb, .icon.file.f-dmg, .icon.file.f-gz, .icon.file.f-rar, .icon.file.f-zip, .icon.file.f-7z { box-shadow: 1.74em -2.1em 0 0 #867c75 inset; } -.icon.file.f-deb:after, -.icon.file.f-dmg:after, -.icon.file.f-gz:after, -.icon.file.f-rar:after, -.icon.file.f-zip:after, -.icon.file.f-7z:after { + +.icon.file.f-deb:after, .icon.file.f-dmg:after, .icon.file.f-gz:after, .icon.file.f-rar:after, .icon.file.f-zip:after, .icon.file.f-7z:after { border-bottom-color: #685f58; } -.icon.file.f-html, -.icon.file.f-rtf, -.icon.file.f-xml, -.icon.file.f-xhtml { +.icon.file.f-html, .icon.file.f-rtf, .icon.file.f-xml, .icon.file.f-xhtml { box-shadow: 1.74em -2.1em 0 0 #a94bb7 inset; } -.icon.file.f-html:after, -.icon.file.f-rtf:after, -.icon.file.f-xml:after, -.icon.file.f-xhtml:after { + +.icon.file.f-html:after, .icon.file.f-rtf:after, .icon.file.f-xml:after, .icon.file.f-xhtml:after { border-bottom-color: #d65de8; } .icon.file.f-js { box-shadow: 1.74em -2.1em 0 0 #d0c54d inset; } + .icon.file.f-js:after { border-bottom-color: #a69f4e; } -.icon.file.f-css, -.icon.file.f-saas, -.icon.file.f-scss { +.icon.file.f-css, .icon.file.f-saas, .icon.file.f-scss { box-shadow: 1.74em -2.1em 0 0 #44afa6 inset; } -.icon.file.f-css:after, -.icon.file.f-saas:after, -.icon.file.f-scss:after { + +.icon.file.f-css:after, .icon.file.f-saas:after, .icon.file.f-scss:after { border-bottom-color: #30837c; } - /*---------------------------- The Demo Footer -----------------------------*/ - footer { - width: 770px; font: normal 16px Arial, Helvetica, sans-serif; padding: 15px 35px; @@ -514,28 +565,26 @@ footer { bottom: 0; left: 50%; margin-left: -420px; - - background-color:#1f1f1f; - background-image:linear-gradient(to bottom, #1f1f1f, #101010); - - border-radius:2px 2px 0 0; - box-shadow: 0 -1px 4px rgba(0,0,0,0.4); - z-index:1; + background-color: #1f1f1f; + background-image: linear-gradient(to bottom, #1f1f1f, #101010); + border-radius: 2px 2px 0 0; + box-shadow: 0 -1px 4px rgba(0, 0, 0, 0.4); + z-index: 1; } -footer a.tz{ - font-weight:normal; - font-size:16px !important; - text-decoration:none !important; - display:block; +footer a.tz { + font-weight: normal; + font-size: 16px !important; + text-decoration: none !important; + display: block; margin-right: 300px; - text-overflow:ellipsis; + text-overflow: ellipsis; white-space: nowrap; - color:#bfbfbf !important; - z-index:1; + color: #bfbfbf !important; + z-index: 1; } -footer a.tz:before{ +footer a.tz:before { content: ''; width: 138px; height: 20px; @@ -544,17 +593,17 @@ footer a.tz:before{ bottom: -3px; } -footer .close{ +footer .close { position: absolute; cursor: pointer; width: 8px; height: 8px; - top:10px; - right:10px; + top: 10px; + right: 10px; z-index: 3; } -footer #tzine-actions{ +footer #tzine-actions { position: absolute; top: 8px; width: 500px; @@ -564,7 +613,7 @@ footer #tzine-actions{ z-index: 2; } -footer #tzine-actions iframe{ +footer #tzine-actions iframe { display: inline-block; height: 21px; width: 95px; @@ -574,84 +623,95 @@ footer #tzine-actions iframe{ } @media (max-width: 1024px) { - #bsaHolder, footer{ display:none;} + #bsaHolder, footer { + display: none; + } } - - - /* Popup Test */ .popup { - position: relative; - display: inline-block; - cursor: pointer; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; + position: relative; + display: inline-block; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; } /* The actual popup */ + .popup .popuptext { - visibility: hidden; - width: 160px; - background-color: #555; - color: #fff; - text-align: center; - border-radius: 6px; - padding: 8px 0; - position: absolute; - z-index: 1; - bottom: 125%; - left: 50%; - margin-left: -80px; + visibility: hidden; + width: 160px; + background-color: #555; + color: #fff; + text-align: center; + border-radius: 6px; + padding: 8px 0; + position: absolute; + z-index: 1; + bottom: 125%; + left: 50%; + margin-left: -80px; } /* Popup arrow */ + .popup .popuptext::after { - content: ""; - position: absolute; - top: 100%; - left: 50%; - margin-left: -5px; - border-width: 5px; - border-style: solid; - border-color: #555 transparent transparent transparent; + content: ""; + position: absolute; + top: 100%; + left: 50%; + margin-left: -5px; + border-width: 5px; + border-style: solid; + border-color: #555 transparent transparent transparent; } /* Toggle this class - hide and show the popup */ + .popup .show { - visibility: visible; - -webkit-animation: fadeIn 1s; - animation: fadeIn 1s; + visibility: visible; + -webkit-animation: fadeIn 1s; + animation: fadeIn 1s; } /* Add animation (fade in the popup) */ + @-webkit-keyframes fadeIn { - from {opacity: 0;} - to {opacity: 1;} + from { + opacity: 0; + } + to { + opacity: 1; + } } @keyframes fadeIn { - from {opacity: 0;} - to {opacity:1 ;} + from { + opacity: 0; + } + to { + opacity: 1; + } } .button { - background-color: #373743; - border: none; - color: white; - padding: 15px 32px; - margin-left: 10px; - margin-top:40px; - text-align: center; - text-decoration: none; - display: inline-block; - width: 200px; - font-size: 16px; - cursor: pointer; - border-radius: 3px; + background-color: #373743; + border: none; + color: white; + padding: 15px 32px; + margin-left: 10px; + margin-top: 40px; + text-align: center; + text-decoration: none; + display: inline-block; + width: 200px; + font-size: 16px; + cursor: pointer; + border-radius: 3px; cursor: pointer; box-sizing: border-box; transition: 0.3s background-color; @@ -665,16 +725,48 @@ footer #tzine-actions iframe{ min-height: 700px; } -/* michu naming fixes:*/ +/* naming fixes:*/ .filemanager .data li .name { - width: 194px; - top: 22px; - white-space: inherit; - margin-left: 12px; + width: 194px; + top: 22px; + white-space: inherit; + margin-left: 12px; } .icon.file { - margin: 0.9em 0.6em 0.8em 0.6em; + margin: 0.9em 0.6em 0.8em 0.6em; /*margin: 5px 0px 0px -60px;*/ } + +.fancybox-slide > div:nth-child(2) { + display: block !important; +} + +.fancybox-is-sliding .fancybox-slide, .fancybox-slide--current, .fancybox-slide--next, .fancybox-slide--previous { + display: flex !important; +} + +.speedControl { + width: 2em !important; + padding: 2px !important; + border: 1px inset silver !important; + box-sizing: border-box !important; + background: black !important; + align-self: stretch !important; + margin: 0 0 0 0.5em !important; + border-radius: 4px !important; + overflow: hidden !important; +} + +.indicator { + user-select: none; + color: white; + height: 25%; + display: flex; + justify-content: center; + align-items: center; + background-image: linear-gradient( to left top, #002751, #b3b3b3); + font-size: 0.7em; + font-family: sans-serif; +} \ No newline at end of file diff --git a/images/background.jpg b/assets/images/background.jpg similarity index 100% rename from images/background.jpg rename to assets/images/background.jpg diff --git a/assets/images/michu-it_logo_weiss.png b/assets/images/michu-it_logo_weiss.png new file mode 100644 index 0000000000000000000000000000000000000000..5dc01bb59e9c8e0f3985b9fde9df44b894321780 GIT binary patch literal 40172 zcmc$`2{_bW-#zwJSw&oq0Qx{J`AP^e3 zijpn_a@-pNA(K0K0z8pW_BMb(PP-y+-O^SO0 ztMeZOLbV+mSNvz|W~cYYJOX?CiS<3HadFf?tDl_&Ug>j_dGSN!;u6!zUgwcd%;xXqKsN6>1oDDs@$3}e)`AkFRGOzDzFiOs z*yJTx<_07v)r=#KeER`}Y|<>2;4 zYgCEvn=P6>2D$&ZGo0~wR>47@=)uS-YW;e#1+t&h!m(74O^BOpBeyhJ&>01EXSwwh z2sxG8HHtcgV+v-8^|mC=j|YZWGWI*xkWDq9ajkbNNtS}U3%qo*ZUlVJm>|7 z-fbAteOB#R6NA```Q)reZ!P3g=}$PiJ1U*dd@oV79QROcchDn8r+!yJ%_B~i>^CIb zh(qn^@k~nX-O1hN`(mMG*SZ*6*R3xY+!PK{gv?w`xbrA~tH5nY-8maCG97Z3C#EefBi&5YN!J;W_mh3S3JrL)20p2c>2Tj- z5Unu}5Ami+AHbehfUKbp1bWtN?N+XW9h}IDQubv3-e=g8V7ixd z3dhOHv>)AQH<6i_zVdnW(JhJ-QZXNt&(3wJJU)4Pn(hjH&L*q7iq2>f(=qxBDmurc zqzYo%wLJ~DXy38tm6{yG#av}O9y6fDn8;+0yE;5KZi&xFh(cb!dnmUl*rf3713kZM zn8YsKBf*H9m#{HWRCHIF9^VsW?h|5}F@BO`{J8Sl6TWZ3q&IAyk`Ysz%=T_%My_WU zf4*?qh(gV9S5KG77lx%l!#qvZ?R#l zc|Lk;0Nd74KFwH`_CU2EO983J880?-b4&XsPgG}S*|pFVxPf-USG&Sc2OwHCeVKlE zefCg=5MQSGeR*lDW^T(W)R(jViG>;|({avjo54Scm?i%PefRuz`+<{&=XfI%no>UT z*c+5py*X2+Syu8|+PHMcsfubOSoQ^Lho=4Po4hwnZwAXZ%2$5>^a_ zL=^9L%^CjhE;Hh;JsvV|$8Ow8C-2EfYW_IY^}}Gv!JEsc+FPKaveLQ2zq0NA$BK^? zMHL&!jNXQ#J@v=bI zK;*&kJ;!a!g@aaf5HhCVYsCk2=^SIJK{d7kQg-}Nfv7v*M# zah4ZR1mS(&uUdpKY^2(z3ORl}gh#PF^W*Rb>0T4t`i|QE+L6}xoI`d|T^6Y$RX0r8 zMw~_xsx+$1AHF&fd0Eu|Gf}Z|*lqE_g8QQ3NaeTsH<;I2l?THO-TQAI7Tk)zRnX)T zW*Su+6&w|JNkYcr@~6uSB9ei>x8F0pP~j5DGs|>?4yOv57P)crct zDzH|j=Gj=$n1J6;-$#C*mh(5fiE|6r)^M zpW{Gde~~OC=u;4ie3-nLTsb(EoOFEX1U#hbxa_IRmtHX8xi;@UF+F+KU2r9(}d4uZ##@pzTQFFzURuw}V^mJLfqfVmEWPX~Cd3I=Y zicq1H3752xuk&jCg}e)#xmKc5zF&VbW}{k$TRIW*lXOgs)f_}G{H7Q2UDijW*t7SDyiT_nHsKS`vSfT<3a^Mf#p(o4mbpciiZ^(aurL z=h{_<>o)|1Q3yin?%UnPE!pD*$Ni`)Pl-^|c0^8ZE&s?0R@Mt2KGz-YuDpYzk2BQx zWu5ihxkYJdbJ7=PS)iS+Cso*>JH|)FUBK@nBW1fBd@WROTCZEfGo|+4uk7C6y`{?iB?*NZkA0o(Gy6MD26K18q%3u`czDmI z=dCPL1MOZzLu-y*pG90f^@df3!#GObX5ZB_aCJYIT#nKqpkl{uOmXTVW2MsK*Wr@d z(c1Ox)$OWV*=NMWHpMROcC6(sh85EqvCUy@I&=tMeD3%~C0zFF&%eKLBi&;+pszVM zm8)0N%;j?5sITz$bU{W_pxhURQTK)TgMy~KJ1^wWt+VQ5cS+@yv-ob--In>JhsA{A z%Gt1t(#8qDmoJ@dM!q}?W{S2vRlmA2lmF4awAlh#m-1k3yV7lNxKyn~zCp)zYO561 z=rw-5uBFz%ZDhi0hV_|D>Vep%rQb;XNc1R8y&utHvOaaAWg|n5JK*D7fi9HjKC&rl2qR66_xtd@YQRy*M#(wXd(Qz9DaR$}p&wOjJ{slmdAt4r!n{ z9>l`in)IDokMuI5YjcJw=JMtA&E;JQBa^2&!_B;(+tmu;Xp3gIwzWsP$a0YC8addJHnJQ> zVj6-PuD5LOBUOCeZS{OL^%1^~2q_y5c{%nQ-qL`8vn|?+-P_s8#Y5U#mg5gyY4G{* zu>c4ApCM>RSq{ZRhU~@~+U&Pb?zZgW{DOQ4K|x`52`PRdaZwR5;p^u!c(|oM18oq0k8|~OclyKJ1|eYUWb16}g7yGoh5jDvdLM;GdE7_+ z2hxAP{x1xGXf-tc=J9XW;_Uo43lFri7ud#M0{OS2J@kECZ3T2~Jy4$R2wP<@u*|Ff z*o_BT*Y=I6%+y=4p;9gt%0&Z+WGuFRESSdl22GrUr1D1L_%6vlvhyrpF@FB z+E}5j{zrrVECJ=Nk3u>9!+f>>p-6UNpkH=wBczKB3gdB&gWU!pZHIDqwgNgpI$PP> z3b?x1bFlxdS?OCSCzLx_DcFw4zdnZpkiZ>fhjaoj{sIgB>`FsJ8t&qOwsJw(!j)t> zz&`nrNE>M>D@lZ%l$0Q!l%$;vpOA#87@xJUxDcO|ogKnT)W+IcP*mz4^OaBt&qG^0 zoPXq&HYfz3@y|txSV`I1ii?W#35y_v`6R?eMft3Rt*rR0Y!D*iQexItQldvP2CLC> zM}o*;<@B#q4_9RaD2j`VSR<@$B=|(^?Ckh#Y(;JOBt^so`Rt@b5h6Ci*0#1nwjAt- z#&AdmEXnH7{bV_W{(5M9Xp~N#e?1fx6$C#5LWlqUHQ?@lH{hS|4P1~w2f`fehX!>d zc0CZ=fOy5l#6-mYdajN1wskUALIU}C94!Sf{nvMQ|K**CkmO&l3_NVzZ=swIr7Fvz zhj6zA(}77G#+H9dRo~Vdt#0LG>+bPa(7I`5|JNrc-JBf{E1%D zR)`}D@UZf-wc%htdWiftUhqG&x1;%(`?kQ+{%Z&Up+QjUA0gyumgt3<{P7O~FBhA?642iY{m*=CY~7LnBDR0!^7j(h{}=iFw@Uh- zSkph0{Qp`>|Ltb%Bt!&7ZN|XtR#G++VxrbI;&ve9{9hLL zpEA+^bBp_LjO@@3|2E414U7BV;rHJv>3^0S|9@A~pMZT7?gaktNO<(S(vk1pK8yx` zDlzGQ7xn(9HV8^HX^`pvo7^vKV`GaDk&@!Gu@M#G6A?Mg{dOW&e4v0ph}qa!iAza< zO5$iWsQ<6I|L?r@FV*)yG6*Q?4?q6hOMqYg?nZ1~KyY;jy~ZpIDg%K$w1g`u>U+Of z9P>*)xAy#Cujkw+*HAJFGEa!2vNm&eJmrm`Ix6_-aL0kj9}wd0jIn&iPeiS;@v}5K z7^5+0L_$ngHqow~vn;il=C;O7ETi^s?I+#bA*b4d!Y@&TW($&w^{^S74SiXcS5#M6 zRJ*fRThb6uBz;exYx*?mzp+<*-_h}GuZTJ?kq)#?G3+IXS+R_9f#6ZkfPLm%G4hd<(nWRB{*r#|`}q8xt8BJ*{tnzXX+_@!A=+-f?m z|D`g;pSM9-${|cA?^wc{plNdlm>684CPFhF^Ro$eW5eW1M{Gs^!A3bYakhr@h*&rs zl?A)ZSy+Fk+H};?L0|+f<%0Ed93rl{e1?@f)@30NMiXzeS9e=CJ0Eg*wgrK3Q$f9h zKNUi|Rt4e^QLr?{Wrm)DGf8hPdKc4597`cC@n6|XXPPwOd|w`){4*nnJ7z+;hJ_dT zOqc5pY>tdIgPo7F@> z4f*&K4+qzYOO{iXxoWkB7FbLTe&9^%2O65AIa?g>pScSbH`zW2AIanK52=2UQ@Cn= z9T|&1Py3AeGX2r0D8&$_9ETYE^mOGiL!CKmXktkiUzAvX`$NmiE zHiCNVs16sQ^FGcOKl>T6CLppGD3G+8iOaKocC@F=)3FoEZ>UWQp50eZMAxhQKAL&% z9F@hn?5E4vr-R|DW6&!#XZ{e>z6S`Zw|1)ivM8FOJ>bFcAxp*!zfyiwwz?NO;u4F_ z#c@qndZ;i794+-2`}=1&7J)fxtP583`VV95b@LDCO8l)alk4OMjn$h6=GW(R;M9{; zlz+x&iUI-aMkWmEZTR}^nNO9;x7L>@6kPPOe4nLKiVC04?JW9mnYXkM030;2rzl!cNr7H8R6Gz_aT9X{nINznI+=DK4+vOA(tcKf(M7P=mXQoYEAVSi$9 zE}=dSU18hw0B*|hjr?dsOF#nOwpDA5dawA@>%oaPv4(eE+gZYCRkpQzH%p_c-lXd6taN6j4#Iw+GFfSgV|$S&)tij!(N2$ zndnFT;T0qdY;~(Jc4KK%X6g*ZQ}O&DKaHfp42(P3#*x^b91nYS#YhZGj6ti721Bl? zCmMCgND>wP(1&Cx9T#vHvasmq?=XiBvHMWIISNDZ*Ll3@zt%6G(K*@@giZuJXkO%~ z`75|UPcY)!TPv5(6!T0g-aR4)sZ}^GQ0x9og_yOf-yy?&82BKN%zWSg(s9r|&0bn1 zccz?KGI(R+#%B6CkLyR%q_UOCb(sZ_CAbbZ%4144DfqT6C3xjBPe04l=_4m%XVU+j zRc;EE6~NYUv&F&0RB9!DNFGf;cJ=+Us1hbVX6*)I;>L+1Ls$61{+_x+?dQI3?-U@~ zyg&&e#KrR%_MHfOq{`~S=#PutwW^FDV zZbURZj;61c{TKAexfSH@e+lw;qtxav+*#Y+lqYUYMt$sN^{B}hO@JEc>#vdq>)Mzl zEIpQRQWAmdk0lY;h3b}H$gA{T4Ml34x_abYhcT7UqXaR26=^u?7XL7?ap##phK0y# z$mv_Y<177IgZn?(8edo3Q%tDRyJ?IlgtiIt6&__H1&-K>$7XHm0&`#9PI22FY_w|C zqx)^`BYUjxlLY*K?8b4>=HFPQaVsV<=XzqE%pV!gqYw%KC>*f7J~sg783g+GE05JO zw|;hNT_@fZ^ZMnJSI_FHesaMAi~l1xcBIPhM5?BWT$Wr<=Ukx@M30`2;qnh(I->!H zP@2>F2{MRZ&3rm7$KW*^v#^dM6J&TyfnpX^pVtKDw5rxraS6=NV=>K5z{hfW`)$0E z{#>6b1Z{s&Fq<}Twa}X#J{;d>_78?afT5&3{hC5p5ogCdS4tI|Q&m=-q?)z1Eg5r-C79!|o=RxyzYq=ec><4TkxG+Nr$}~M-4?n2;x*fZ0 z;(N7lKl7*egY<;<)L!;C~43?|^8O&cu#SaDm2n()ub4ZdMRv-)`& zJv47~abw-lfp5T51dx_7U7RnZuYcb3vX5kTv*urkNoct8N=WFD*k3enhE!7kCB;QK ze~i%-Pr$E0yL6FIAB<}4kmrJ$Sz7?dPn*FvOm$JRYQ3{C&*v9hHlDhPNmY{n94T_} z=3hA?qb&ynccH1G#K@~-%nJb zxGUK5uyc;TuqavCe1qUv5g`F;9 zfo{r+FCPpjSZ$#$s*9@^aT1OHuuz!0`rdT+axB`v-LX4<^&vyS^xo5qN3x+AkLpZ& zCCY(EV?;6H4=e(GkP*~jL z=BIIJiqZa2OGX*eBo$-FE9cih#Eh0XN;cZQD!q=J` ze>{rq@>%eRC~u3n;Ikse)OcyY_hd^61mOrBOPbp{N|iCx40z?{(o6Mnt#skVSP64s zXN}8_C2p*Bu+-qIVYK^_fV0k_{}1yz(1uoCzDd6-B&XBMszY(4fKDc$fJv_NgDsbC z3mGgA;A(q47x+5)s?Nh{hKOQ6rq7OET30DrUyY-DRC9UR%dFq)JW*VIe*N>+qwU*1 zqd+ZfiNK#(N4+%W@zLsV9a+9K;0U6Ia>@uNronpk$@{H}5XtTdGJjppSM;f7q;b+# zeZ|r2<=Y|E?Qf&%;l0IJuhvVdLi)>5V(O0CDI-7BOfKCkPQ#|RyVebDh3hm?8c-TH zs)gzZ{ako+b+RP?{7zSNBc#vi)ra~X*kmpRYHkAJSFAV2@qg9WL}pDJ@fQZ ztsVDVpwt`t$@Qyy!FvoZQ)+5BRyv4$|6y?$_-8%addicQN^Aff=C3khGj@VcHvpRi zh-pZu^O_3~Zo@rh43=|$5dP;v@eDUTgv_Lp1NTgD(aG z5fmu*u`6>)*vo(o5&ckFf4PKT{~i)rgWWJ`s%W*lI3d060K}nEd#BgD1RfH%Qj|tImC8v0SZTEj2~^o{L1@Og#fkS)ZIYM zcr=O$PSC)XBw}2RUtmo-WGo09g3e}(psoORms8{xiZtj@`=F)exs$o?A4(A=tQOZg zcsjzt`4Pwck@&e~-{m9QqqrR+@w_2%vbF?^pNEbKl-fHT((?oLZti>=%cFxze?4X% zfjW!`huZHmmp|Kk>pNaOS97C;l(=Dc)WRsRL%q+o3KmmB$DaTA;e^FYz)k3soyee- z*bQHJqp144SK~1W!NytQRAby*?v}%EEhb97*o(Jm{Ezqc^_=iW7lhXUu=|0A?udm2G7r(V=$U zlFcweD)|~b6e&9`?bUf}0@xLZ;12LL?6OM+-Mcibi-dZSj_yNz;YW?-?YyduiQ-t% zyVz@U>TqOSKWqPKmbY9B_hjn6_sy~;A4Hs86K~frjE)oK6bcfH82>2#zf@c1y+OLP?d+RMS&!}wMNqSb0!*y22UOV%UeXdhojaxtaJZa2^G z?~b&JU-N@>DP*Tr`|+M1=v&`H1a)fJ&FjK z=-7$K=a#`c^*0iep>x64v3ULE^C|~&vVO;zNwv;0sdA%R%MIjVgj2$(-$8PZ7w(?^ zv#cNrj`u8$BQTmyk4QzVon8k^BWi!G!nWSekcLKZ=G{nYRlVo0eh+@{rAQjnhYPkB z7$4q_zJS;0D3};ansPqUS35lw;R1k6411?z5?KUzd=L`*U%!XZWOK|v+N(168`OMD z%-~PNwFPddk}`MviCC)ngclSfKW3K^-PcC~f^?pwB6$15rq}YPBZr#%v`&3h+o~__ z@*6%li0&Rigb+7s)Ou8Jx?`T=SG9fty(~)12 z<1{6u+BYADnec-74;SkwD=RA(J474Ghx@cHXYQIln0Bbd)j`ccHB$_F1x<<1AlAV& zV$cb=t>fWGR-HKwq#A5xVt}=~^Y(ZGUZ|jOLHtJhW-cwJ%5!()PS?&jjqt&vUvl=l zdrYO?eC;n{ZouX)AC-UR;%Cj;2(!}bdRSuY#y7RyJ*q##ia|rYr`(EhDNi;svDNPm z8wYS?79*u*R3e*8BKCbWT%-|h%*x6d%;Ud=5!4I0aV%OjWk!1aY>m1Xt6$vwH_Wx~ z8(c?5CB**T^j^RkvErEX9Tw(xp#H=%o2?Fa1e-J1YaP2Y9Upca8#U5CU{F_>Ji`0X`@& z*n1xen%0lM=pDvyOj)Frnr;88y{vd%C?Z@jJCwGTeS)CKhZXJdT!^p)&OJrbm*SE< zpaF^@P-tPTOqgkdS4?HE(~5j!5H*K-AGzi!s5kW|`IujZ@FHrwSOT7Yr}=G4BKwqi zHJ@$cSWan4(V5zfN~5n)g6fVApMA(aVOV9Hm&XN*WoY``q4k_|gV@Wl`T`xXtGQMt z(JZ+M1!C~g=o(y6tf&s*NU#vd{v!(1>D}nJ<1nOoaCI(L;$~j|>ACYZyTK3nMs&>& zhDS)zNJqz!vo^&7>N2Iugzx@3->#L0NWhvZT$0dXI5@UY_cSwS>GrBuQ$;T;zocdF z=#8oCw&XJ~pHib$O3^>zJc#3Fhy*9dF0eTVM!60(7)mKre`Ar==0RVWOsbxF;KV(( znUZ=o)akN;n!Jn$+evaFNb49WGSOTa{VuR2n7-%3crUcqDyKxHxF>G(i^Ds0@&Ma$`2j26^b!6bu055FF(B)1) ziusQ`&M`CK=|$A%L8gnV0IkBE-pCbRA9(?RFQzJs3HWLpivkQac>4@nviQ=A&h$M> zd7{H7;FhdZWp>KS%B7&FGQVh}nHc5BGQpOZ=-4yP(^L_fQ&T+3>s{^{hX*%>4u7~k zpx)V-I9$Q9W#2|B zr%D<4r}3UNklS-B_a_*2_&FbidfO-p)T7<1(`j+e@;|e%)h(V2JJ7C3(YI5P31|UX z9}fh;9Zm}ee4lLPH%aRZoqCv;$3R$Z&?h%*vv5itxCM|cBSlu`ru+-%Yn&rEgv-J7@u@P4YI}p3pQYVzB|m?6x|{s!oWTf49)h6Qcz<^9 z8t=Qk1^{hLs(n^(sz|JfV#Um#gXFw4?47w%dY5(CSHYwNp%p87=ev9q&?Q6Uc^dj9 zTBG@2bhy-Ax92yYr5nyyDvg%C`b&b-@z_sPS3wXSs&ce6WNg%uZ!9d#SyRb;D~RQiy}9z9g-rgMMXbsRDx)aU~vT%KaWp2gBpzVO)nHpEgUeLz8B1Z zm*0yN;V@R}jqDTf7W?^vf7CkJFc(V7E+`%ZJ5yU~m->QT^Z5MOnQj_^kNQC7Z z-#(>Whr&Yr@IIHcY@I7X0O?e z7SdWexXW80-Ij9^DwbDE5G;NyRl*EH0~62YMs`OdI!94A&dP*_Y>@JEMA&W8egUSAY(Pw$o9D-rm5@54$mdHoyTK5471=;27>UC`k%&M@84R zYKoT4O`_DSyuj$Q|3Ll5mx1!u(>>DfN9yeRzp=>q@2`Npex@!gO#(_Ly0gm6p89#l znc426pV<}prs**WsJGkc!8eXGvOOQ19%6})w#P~k(ZcFQQqA=ovs?`x1rYTOf0gQ< z+i+@FKXYz>d{Y204MqKrj#`qYz3r0Z9lDw0#bsX!+4VZQY4~HM`N~V4P;)cO6>Rdl z2Gm6KkwC<);$dDNk+o@%X<4wkhTFHFq~lpv=leuHZ}Q2kKlnYCAo9hZr9>Kn{Ur}UkikWbcY#(l5PVxC?;E6r#E`W;Q2u7MJhUa2K<%fICCr5 zE3mM>_31U*VqcZVTFbq0gAz`zjRA_Ss9o3DmzjPly_mrDh2tnOXPR@C;{@5(=`y24 zPPngvMcDypqiY|GvgC@vd+V_Q?7qa?R@$E*$*3k}jPCiKHth+w>UmKUC9C?lRPqA* zTpQE}xUv#hk2v<5EJ4L*JayQ+3G(4ih=iF{hK&{sCCO1V&HA-bE0bqvqe`6ZjBrDC z3-90wjWb43mxUy?`%!1?RJU_*v^0IbeS*c~%(-h%tW3s1pSC&Z&)pG=_G?~>uX}Cz zQ2WttB01PG3~3V!A!j3xfc(jL|XHg1Q29un6SI3r@PN#x#cZ&hI&;_3-1iJ71Q zjZ7S)IjuU6PZPZZj0C@R!pR_rd;mIE&sSF%5<&Wj5h#JPV59@r3Ra?~YuUnkfk(zp z^C9+MI=CI^%9p9|=-Ici2H`&LDTxG)_P4M?Akg-Rx8&R$y9IYpYVH6>uuQLudPrf6KnW<0H~y zsGET2(%(SR)Gmehr)pA5=Vh<4Jy;EhSu#i%b113LTE8df$3Z`E`~piq7nSy<+byg? zB=-YIxzh3u1y_#5SUiXv;b~ST<;qwl2yS{efIRaZ;P6hcn1_*g^-YU*N9sCzv2NkC ztly_6V~XPFv8uFS4)yQPZBdt9936Kg+h2gr??>2!CFJ{ zU^ffEVhV9NLSdjP*LH<^Hwjg}+kw?!F|TkaJ0RO_RRWSJjro50t>Q2YMFdF_^Nm`- z59PS>i{0Y{?N7ZpQp1z6hM=h_;`{JT(KhhqI*~ZzmiZ0J%gmTdtfI}V5N)2*eJ0k) z1Lxq`urY3Mev3>|%ar&9;yd=0-zZu9lf(<_PNmc4i$*DzK{0Y3lvK+H&&8Q91uJ43 z?2;1!#*yj}H2*CUpdQ=;S8fypz3~*+!=CP|1psA;7mxeN$CiszcB2e72J2JcDv!rI3;|($ zhU<-zp+D2TPwAq6MP*}?Y#4{zR!4wZj$>Qk7`Loii=%0kcq=RTavcZ~uB?7QD<5GR z{J#f4^-Q~!klW@4+En0pzYp%VLs5P(lo6be3LPu(rVVw_T9!M6Y2(1~*xqOxagtz+*)hKe&6Zlz!pj~5EkAmC zp60uc_WLt8PpS3#Ee8}+_$?E6!vxHiZj#as$R9ercG$C%=(zxcs~MKaDC=gD6Xbl} zzkNsf;fhY-v8aqfZ{8{T(%QG=Kko(Mc?h`VvlvL)r>EdD3q)J@mojyV)1j~Z5eqo> zxdu1lZGeJ`d?m?Qi(sn7ES}#l$fNnm>w7e9WyxNKJ&OR%)pqB)^)u36-8bvmJtXfJ zUq9~15Q())9=HULbZh(a9+Vj|(7`uFu&yUk5mD))>P2#g2)qIuX?QbWL-j3+_pWnU z5I%N-CiY-y9|d6CZq-7pQE!&p)vyyL=$#UOzx2ENb{4^&tAqh_(}xjk!mmk>4r_qx z6%g&yy$w3SWrE5b@Z~4~JsXZHw(lUguA#j649a*?K`@@nPl{hhq3$9DmE&v>pg>wD<3~rFMM0^jge~7`YA8`=|YS*V(JWJ31s3S)S#fY1!G%W zcq!M&45+c6B2in6&2IH4T;ezC8+CfQ59ENKJsDV3XdR=YaFWJp*EYut9C04!d7#V#BD0D?hfG!0&H9k* zW$s;m51VMzw%0sR`jlxavp<;Uo1(~{-ewfQP6LSg4x_JLqkD29_=X4sq6$i;8=D<{ zwpfeqm}!5|FtI?p5-Q%tEIm~vysj`>ws1@y_y*3;yNmMkf3n#G8;}AdZ!Bb5JgA?; zWqP=5u5P_tKX!XkBT5F687C#QASDwj3#13hyr=T}$E*q5f5rf}&u)%2!h(>%E}&DB zqwuCO8{|h3*q(0huzV_dJBMtx%4NJ#K>Ma7%ZS$^>vXMiunE5zdj03w(w!9#mZqrV zPsOegAwimUwNd8g`CYr=-;1a#LGuQIGzU|lqIMfzRkD_(`KxLFtb01Pt}Qqbxl@ukVps*};I3pBpmy7**d z;TTaYFUaq30}9u{23#Vd4mLfi67U|d99M z*|=jMfi3J9R&bc z&kKIzUSqZbB|H7qh81|@>aF&Vv?Qt53w12%f#~(JLq2q^+gI*Cl?kFqhWbWx_}DRJ zg%6G+Zhzf5+`7VOEyx`7Mc^>Z4@No;I!m>~>iu{q65hMWvv4OL6!~nRLbYWW^jrY_ zxPQ}u{c!mB74jXT&+0*agWGnFy~e_~=&Hbsbm=wR`&zf{$Hjr(Tg5qjE<4|6$gJxI z1^Gb1C86O2f@D`bIuAErZYF`g8b^KR3`sP$+!h99hi7 z+6!h3M1hNZ8fGznm0(}h$fUiz+eC3^E6K!%E6j*@M`CMO>zhj=X4p3l#|cV^M-1#y z-=)2Z@jJ+P{8<95plJNLL}#64%FNgu8tlc>eGaFjZh%Pp=unI5p(CI$MRjp>>;!SB z?&o~5=%^b8c`&S@CTa|1*<1VadYnFitI?L;YlR=X)3H_=omv)x#AV)Y`MoZCOCS52 ziEj>j?S$!i%U(e^vM4s&{SX!lxOo6lx`qFI{Z;zM*$3NuMYCg)dmnN#@b}CHs4M`6 zA&S1&n09E@@gLLWx7L$bfH*R$Xx#udbWp@Ev(uY6aJ9#BBl>{8!qP1{J=~21eW^^2 zy&sjO^}9RV+n@b>faiAnnIu8Ef-gcfn|TfWB?vV_UfxA0Uu?yrN7k+Z^1qp-eKTg3 zfApywaIpHZEhb{dug6z>7A*d8sR^9jDPQlVAkkpE6VXqjI3+P39nC)n_!#t(5Kl`S zE6qnOKwXFFP^$%pb|YK%15R(Z%gTE??6PYc8@)*Vfd}nXG^v==G<2p$3HTy_xPr?y z%f2h;KUtayEp1uI@|0_uT$Y=3ad|Mi=c3cPx=FH_+v}h%>n5pU`K9f@Qfl%0Uv&+^ ze8;%>1`I#8w_985Np|l}e!$S-lfpZfeqmiB3tDx5Gag4hy>~kQ%NKd{NZ<+ll{qoE zRvQEBDJ$IkHxW<^U1*sE*GPK5D5(rB#liK^PGa_>K+7qt7`m3iTOVVYd3N6ipWXYY zE}s|)F5!V1R}3vSRBD*^W$ssKe)<9Y`?!7iu3EhOGs<>9bu+%XHUOhu11KKb_jDiL ziFy5pS)@G+K9XZ{R(8VbV?k5GAh?XFcottjv*(V`7HjsQ-7ImH-oa^Bi$vWIygnPA`O|6F;NVDvHF+npar2!Z&u#nij=P9ZOK;M+ z#nx^TX$xLOWpS-em7oy-BN;Qk#$rbE&yIvdjF%rwM3Ht^hn{7J-@)$x#HSUc+{gh| zQn%HSgQ6ff0{NxKFMcDAMbIC(&#%rN{Ag&SHgBm@>D>d}y_zQg#SO40&Wq!Wa~7#A z?p>YUTaq#$u=q9gMbs(uT6U_fH(Z&s^+|yDs7llM#B<|@ma$4Y#pYhS&FfCEl}Og< zcc^+nwKRfL^pFbNGHKOQe#lfnU})s4TMV0DeJ_4!(kQ)KNWF-^R-0OYY-6Y&TLQqH zC_D+}ukMBevG=r3soqePn_8L9vRo{~puah5UjrnFB78fhk{;V|6&Z;S(2zPp0DXMqKs@sfOJaY3hlFP`1Q&Yu{v!d7N?g9%-F<5L3q;rurl zk%;HH!j7gBT$NM5ulbbju*}ql9%vIBeQT#(?vPK*+V5Lf)J58{?lB8;gc$31C+$3q z(cW@QGzjSf%^N7ORkz=CE;tGpfFc7_xli%qSFrJ;i%vKk3O+m`?Nx7C43Llc>6Y{Y zY(NmM1{9}vE+G`5zvWo2m1b3UXce}02BsAzt@0+^cE=>*XjEJMX&?$XDgq01uNp7k z-3Bi_ZPn$r?<=2R0}qEGL1hs$ZJdBBy^!l!XJvwn`v4l15)KuJ*UNgWgfrtSOR6Dm zct*qh2NTiw^Vi&gY00j^x32YZ-|&ZxJ22@r~h5PD*7Z^mEpW8gHtYU z5S(#ijlQR@;jJ~7Yola&zHb0qYy=R}%W-iI{xzO7o1fQxQ2At#m#SmcZHO(^u08qQ41^^~+n};*Au{K@QXLXszaP z?i*~w^LSN)Tzz3E1#_d#j7C37rvOEwyn7+>%~^mSemKw1jKMwS>E8SD2)Z(P-W zme^RcJ=qjY9(UM=P+4w%cs=^^it6;x;@2Z0K5)d z$g1NQCVwo{M{2roDzLar6}`>Yq-m{7MTX9IQFp)!J~7+2?1{+AYE%%?@UY(@@F5sMz1MYcBsAETBLpES8 zk=4(FR@i=_gUiN$bLjA5++>aYix&ptGy24Xx;f$y;*QcCfZ=<{8@?=@cT=Yewcqvlz+xea8s0j(YCNg0cIzdXHaeW(ZZAHc&hrAro``+$|W1 z1TJo^-#OTPObrg?$8lBsHyrf|j@+#Pe-EW`q7rT>E?#_%D+s^}<(x^t2M=h@0Dy_P z6yom!21??+#`)*oyI7Yo!~A4KW~U(jv7kksiPU<5!=)C12`_ zUqz29vU8Q+GDaAlbc8(C<}Fa{ZT4`Qudl0|o#XZy_Wd@-Pf}=@ z2geY8f*FBqJv|~f;Jq&so9-G+SEc&y&l#9U*8D0f7gs6#B$aq=-^Fm1Mxit{L zTUkNL)vhH+MPTEtVdLE?#P$4Ht64|UkY%zk^yho)=VosEbEwb?{r9{+T2gOn{bH76 zHWtQ-2P8ghz&&ubU^BIM>PknQ+sE!j^Jr;@>DR%tH*C7R`TLStN^4yM19VsqFIF^o zE#^qE4dgBGV7NLR2XD?0br2%;t<&w;)qc3E}`TP%O1`>?xLb zp3QI3sTL{PMy0xywyoc-a^AlF=(H9!Xp-K1EB zXqPPwto*AIfQghUylyGYx4yhWgh1jWLjjC=tP6ZkL9_GbS;L0Ytte=X9r!!&BtcW1lgD;l6bU zUdj$Bp@fdPrkGL2{X0}REp5GqO7~Y6R#=a^Jz1Iw*$t%pB}{1Z9$MEc+oP)YIxVu> zkbEtYxGPCz3Yeya5M%Vfi!xDUChbv7Q~m3cK+ayaTjb{$UPsZQIE$Ur!yKxHJ}hDf z^8V@CgLcXdpq09jFpM=7aT%hCugW_;{Dj#d62h3%TQBfNURPI&9<3Zd?X>I$tq`)6 zEc4jm!yIZ*J|Md04_~U;qLLtzrokjP9LkjM zcfY7yn1W4J#3V%`;Y6gYv+6p!pYzPU-j^2B!4#bcEY56y(a?^r1e~QR9?p*|Bq}tM zG-6=MtaXmj=g$zfwBaMsd)5j;gy)IvpC_5LEhR6g<{#{@19ks6`4Oya$3BiYPWgb$ zJiexO)OEY8Z_)AVbbZv}(DemDDnA@K-*C zmBAps#-|o;R=L_z-?|id>kvE5lg<+K;2}6OI7Eh>9u^S=FTd=&dl`$+VKqWlD9AQh zmcS)+cpD`TH;CWv=O)HStVYWVWxk!@$lq3N=?nnJJMg3KWJJD)Lx2x%d2 zhFT?OpPLUFQRD?p<14qFqY#~SbLv)%?CZ2I)Z-s(nRX~^=WZzt@#Erd)5QE}yS|7s zUl#V`SWs*+&b6QCw)}YvX9=y}et4*ZvWT~K4%fsRJZ+H<2Xe)(AQb7i?>T27oC0NG z5Ziv;vZV5i@TrrBf|TZNF!q`GI18%3jq6VkAJ-|aUS$sfg5d~zHDV_h{D=@tO%~SX z9$tAkBs>sgZTCuo6_iGYe06IpzA~qJ@;qv_(D@9PLV4`z8RjBGTg+YQimH3{*2!_; z+h%!Etm-MJ>Hrw)s`%s9xdSoO{^_LeVy&PQu0|@XwV5o2NOnAl&=rQ6=q~8!5+A#L zl305Vv$VUvGGj0jKKA%{z4Py1B+LYPzK3~)y?6EPaC$ZhmYyPrgB_#!EGODBvKBh? zCiV$qg8fS!+iMQ-iB;j^xtj`#tDA*tWdh;#JX3*UD;zk7lP$ntBnMc? zs-gFw$h~}9k73i9M3T1K#M=kq&&Ha$=)!@@#jj&8zh!S#9C!Qey*+}i9TgQBq8TYy z04g>;ySC-LXXgOZG!VnDfvl}ooFE)Ew)85P-xyLUY{*PmdjlK`J~n1MBW0Nvws!=+ zNC)p9=viB_s8OiZms3P)W8q{;Y?5hj{-fK9$=q!hLXz8o_99$7t_k#3z8fG7`TTiqOFZ=p`z@}+z?IR-^Dm)-F^ zP>DG7ep-VhxkdSv(p*Dx&kyr@)JEX$EY+t7mOZ&rKrjr*j^k%XF7}ZgT`aI>w{!cT zFu(Kglvq+kqcL}<{U?7Y%!4OS|k{BU|}9qBsuS(vGmNu`3V`QWbS?G$q+ z5~?4}1tcCvmr+(846m1!jh1)z4h;2;Y+F85>7g{wKYinYZ6d|s_11m1ouL$kaF_$( z$t?ze28d3+c6_|Y-jMvA*}Y|tJYw|w)L^0PZRdF8NN3bgNUn*z#qAZwD#ILP#{5x$ za{yQfI8YKXCXqk`5vS%G)nXosOjO!3vkHIM;nIxw73MTlGi^U+0ATjkkPM*Iu=>Tl zOGV&B&lHRIIFH0Eco)W)^*Y?WC_STUW#|4Qkmu0K?+4Ai%R3L}MH%av?R?1--V9{V zXSE)EdWoU@?EV&_egR>Qkfzc3f_u$UW&Ywi*)zwWl#9!JuU#L19B$$vE1IKrG)B4y zkHRl;hjX3fH`)9oi%>g z^k7(&1yGC_p7WH36Cc|eMT@rZu6+Kj*KnsbnAdh$iI9J4a6hQK{Ey`hL)qdc4UFB+ z`?D)x6%yM@$h!50<@mE&dTmxf=~we*SnRAPTafpx3G^lWbv;n&eL{qixuj%GKbDo4 zs)#!ISh`)>!+!VRX|$W+!zgH;A%=VhkN&M)KnmOHVmI5o--hgqY#D94%+Y6sroMfo zDPM<&zaWDWu<4vl-I%Qt1Z8nbra9N{;56(QcZyziTMfNz}1VIDN=LV|oC$9Y8K5NZ;uqSlJ zbr8%FGdKV+=x5^J)t}Kkv1=gN!nu$7jO77xm_jrU9gTBWF>^x!)2L!4nO z0s!?^+G&^hjZ&jtOO|k5bs4L6xd*HrVW(D=HE847^E2f9P%V@GLkkn+6?}rV@4Ct^ zxW)ExE2}%r3)=;Sroj1vGxNa_f@4(LhW&SSCc46{46pr0`6olXap)3jh4yQxe2bwd z*RahSQqH{YQ-X9X)fp&{-EPrv7Cyy`hs#)7^xoc7Q>ufhnNLwc;c98&`cxsRiI+!p zwIMvZZk_yEGTdh!t+w&CHL*{LY0rSefhozWCWKzBFj|;mYIi)iCajMHp`%BG;)lxI z$}O9;7>D?5tb-UVWb%82Qu)N)aJz|}VDT7528BnP*Ox^@*__jUS)!>X8R;v1ECToz?CyC|#A+!T!R@hWo9YLK{J&vMC_M>z-6 z8m7(DImO4I8zn3j zjiAF4{idtTXo7PVUU|nxLHyf}f|i+Cc!iwqOtt9p6ClV0i#Lz2M{RoMm$Zxf%8oMA zxXKCBxBUl(7cnT@6(Nec0*!iIikDpS821Bi=rH2J+2(GO8hW%VgI(l?&(}?jrZb!S zOE-X|cG_=dhv|XPa`L>}O09IU>gk8g|EmVh>w9%Ml~IM6$^b7-`*_9se%3iI7Z;^8 zy%*GlcJIJ3OX?28@_VUo5&UI*WyF!5ye?1^zuI5Zjul-m^;D(YSuM(-L#R35 ztksY}DF_j`nCS9K!H8nazVQ3!7Zx{78ZgUJ7x(BqssmQ)%?@9cZgmW#@f9dtHB-PDa>Zl$iASvf##?hv7`FJ0TMJ%g zVLj4SUT-hSZEoi6qJsrz_#@p{Ta_jLG`tj3^xQ5)urPjMG1MCQ@24uN6783EnzHcxjnrf_KhR2Gd+Od7VRIGWG?Tr6gU;uudH>T zIaS6GG<{JKZM1RhnUpHSXdccPK8bf z_-eu98rKdUUNS@We6F!$MJWvllmKLkfnSFOjZozOEDvnIzs`(I`A}LY>vh42R2By; zgb(k;RBN3&|9rTevay#tb1NyK8UENY7L!gHDw4JuYjiZry3=A_jQ$wkHQz9T4pu`2 ze1{k^n!PSs66a9411fi?Q?;C{xh3^HBJH%qr-uGi{}&9S$hK6W<^o z$FJP5$`?R*Ge|;*hMA~f6Agp(#4%jr3+%aU-NMe6tgpd`lZ8WWZj)Cp4!L|TRBSYY z0aD7{bZDsHy{;Y9xpVlG;uB8xyR{;FyGGb?3an-mb81dvGPYS zKGYa~DXb112g;z(Iy(UgdZ+Y-m|;-_M95bN_xu8&-X2%zZ@4nmxsLJ~>&<5$S$%0> zXI~3T-YILjCOfqTRF#9odwR}U5F9WNye9ZD>)AhA?`d?KbrP=EI5*ksJe}c~$gwh6 zS9&-bVlQj%Hi~yO#j4e8gbF0PQq~7Dn*MN5NEi4fB-G|0>3o~Kf=8o->#hAfZ`esM z1!X{O!Q+$#Gpe=?H_xT0R)1a#w+4>KB30lHfm$KC_iAgv&DIbnWkIlbRO?JnR zQdCxf{bTUbL%slf$Ci014ELJf*&J+S=T+`M$ArJky<(117=*yWlh10M@UOfdu+@wZ ziuI8S@}7znIY*Ta?T%TXlYb7?H8xW)Z>ZXh$crZ+;|XWV)P(-*B2*OgGVBGcm(E=u zv(%M2A&|;CYt=Eyi2^#wpEL>Uw`@iQ`#m~m?HWcXi;>3#K#PeJ^47C7Bd{t z4$hQrVDy1oa(xBy8=-(8YkvINKE31iq%+p={rxE_ z$e!Bqg-&RQyy#{g==0lbdY|CfLUwDhNAIpz0MGvLyNF&B1%qEZ4=CA)mQ&XjBSnsA zJSGbm|5d#JIr%w&y6Nhcw2{)QR1w~@6-Im2P6aH&z_j!NKdAC`)Iumo?Cb6oc=M%Y z?8}QQR%%e<;$<8YK!PmZrFq|9rV5y)$0;Gen_TnqFu)r-QKWsVMODRYtjW6f7!0hE z>i{!k=i_^-68O!#kw-NU0*~%?oUN%o57t_3!nzs)ylF4xQIERWjWfiL*Y*j8GQdfz zgvu#wEEH?}To_Or5ml>DI%VS?-n3DX72r0CeDFjM8>FDKEl&RXN$959^&3pMS}fSvvfc0K}ffX~g%7jY_v&W2t^g z^fHAc+FmtGS?`dykCP(^ICqKz<4obwNPajl=&CnGZ4GVixfkqwVXo#bz4qIG_u~~% zk`@`3iRJhX6bgcy`Q4QIOS1QxH8Y=+bMzu8(bm@nMs5!bu1__37p_<7!C5$+cs!o^eA_Kh`;OD9iD*xX6}%haa;)bJS~A zAcxo1`2&HBjz-8)_pLKnH_Tgs8f#U_CmrE7e>o^8;s6Vlxwm&>j^WPYnPWLQ?)|V3 z8e_0KOzk=BUAz2VEvZU!2>~wj-IWpo;sJCU3{eJCx2I(g-;Fq^oTnE#aD&@Go~%ATh~SZtB9(3GO5JMH3ik)DL@bZ+A9c^N3j zv9zr^L}nQ0(IdbQfCd7124YN=&8j(>Pk>H|iyft8c+MR+rACE*00E9UT%Tv;u6LOZgfSD=0(89Vx3NV3~Eos&BWXwgT?M*xMe!wssG%tqs0QwZ>fWNCjD3j!?1=9IfPQKW zNELXAXk9gFzx)8tMX+U!ZPLd%$KN zJ-jgFP&_m|OxUa}L&^&D_j?LW#fa8pEuu!k&*<^G0;1VGj}~aG;p6Q8)B5{$RVwS$wtAI+Bn zk#ydyvnT4JQz`H}%P`5@c5XnL^UN`_nmIfyEch`T9dFI<7KyMIt0gGGeV;5ELgr28 zTRyBz?d~O1?pz7GoC#sQ$f|{noyy(a1(*hyOG;|*tX)2uhlZR7AhQJXb--+#Gz1m@ zT86Q!3#(Mj_A5lv{ElXz30isg^LC;|iFb~N@@RgJBJ8{VBa3b&6FBB-8i3&) z=#r|V)8lbrV1MxZPOY8PJ)1pp$JWRc%Xr-ICr*>8THlyWtlI8U5bRy?&A+lv1%sB$ zIPVO*nx}3NMRy33YXzF~u4z3}skU7|cEh3_tYn3zijGYuU9l2eriH5YIk@H`?0W*v zF1J7qZ`e(QdtHJySlP|v#uQhDLn-vkn0$j7KIDamZv3DB%D0cCNPbpY;Dnd{r3;d5 zfY}2sXI4*X4SE@}SBQ9oFKk7_iP{tzXi_(ba7v!r=Ltmx)W!kNJX}r%jhHoFv@>iSdCWe#F;2;^ZAQ3K3;s!J#?7t_t0%&{;=Aa2&%Xx7WjVmS1NpiPQ?D$}2s)fx*d0zo2f%`m}-h8`Ua*3jNt@5k2bZ(3A zMHwN4_k|l)bTkaP)UQg@#W0?&p=8yXP*y2)n2yvO%}5v_JLDoY&$sEU2Nyh_y&i@g zwKh$2xiCIedW3)pax%M<^?LYJ&i$YAcZ54LL=NAJUs9c>5^iHrzEd?NMbn3ulN4?< zEd1x5ogbRpojLxVrDe$L`PCh4oT&Btzg8NeQ z<&81BvJFtF1oXSXt8CF+!7QYa#nefatPQo+mj^=$JsIk!0ha^r{>5yf-YW~dSe=LB zv;3I#xNXwgVX1{Gl`dbBZ4zw|+PJwZ);uY_fR zE6=Q0(pxvt9@<#-!rB!vAWXd-lO*R?7Vu`o5^KTUeiI_({qw^TTNWtt704nWVBRm5 z*leNcK<KV<6ZdCIVws||FM_aa!&e}AQ;Z`DdrN;ZnDmgg)Q}enF4O?Q2E{uh*!3fyFiWvL zE<^a(c?u!Vg+#p@HPV{+YoB$+4J|3p5jhu^G8=nHnb_5ygvLnxeVYvGy9=7%dDWDA z&p5YM2ZcOUyEt)nx9R#~zGo)V{3H}#h;Re?6Ue%HOp3j6>Uzx3<+a4BFEsx|i^YJ* z)kR_PaiFoIFIzF$^}2{{~I0jv#ISqC;LnP^5&{SQKJsGw8Z9y zQth9L0}90X>ERoTAOYcP67{LIV|FH+YQR$?zCrqMB=7qhCJ?#%wd2d~ z0!A`Aq6O}oj7X(2)zgBC0Gm#-aNx?_e+y)2;HBO?DG1nNC>o02=k1(159QGH&s7I6 z>ZfWbo0AX@*d&keRGI%5Li9dYCJ?ooQmwK04BZ^?oUQz(!*UU}@b!;+(sYJvoL4}b zxNl|*wKl0r_yRV%1da!+@Ww5nsp9Vg`PP_@RJZqG1@@J^F>*IIcOHcR*MuI^pxC!A z@|lc=lOq{!AI&%$}V zfFoO|m~SqvkRZnJ+1>YDgKJoMnTEJ6Bj3i(@pg8T3~*R z#z|+?0s%GOF?s}`@g4v^kE721Su-&B9=LxM1%}7>*z5U}yOX=FH4iL`(REO}Bl5Y& zOxJ%Tc~xRZo%o`|oNUFVJ0TEXTpR~(<3>{m^-v@8ho4$3XUw*PF=a$~ z7!-a(NYdmk-yGWbJpxVyxYRoD<)~gD6BGxgCeF^Zz*k%k55W8&6x@H;OM&fLIF?#A zIl(OEQmC;GKz`Um@KSL(YeXfWHEpY+K0?Yo6iPWK*5Zhrzcp*_6DST&4 z0_VMt#rw~N?L3~o1Y>WrH<5d%!G=ydISkVH^!d}PGF|E0yjRaV6obO;1)k09Rqa$D z)Iw)Puq+$P3rnyVQ~DDfqKpU3`Xmo=G&<(hWcivZE<{dH3XwV1>l^$ru0CZej6Iy zi#@}eKLl@{Q6dDLw?dji_cK79gT$1w;b=eBAoPUH^!BrnBkM^ChpEAQy8EGsyYLgx z3!=Elc9W1pNv`0`NnuSJ51^i8)U;t)()HBAen061d{8v;p9;<*c}ij}yh%c^km6}U zY1)HADBj?S;W*!RvZ|e}*o_iQ(ApZY3-lmbqi6jJn|rD?MLpA< zNRFfWz|H9Xx;$?I6Uszs)9Yq@N#?1*_39lxWda7AE2of855uK{me=>1=7lz*AAB^A zoGqH15|%Edlckn(6-eFDI<@@>GR-Vul_F3yCLI&MHx+8yR@y81kgPRWH1$I~NlvBv2yT?!CGaGYs|%^%(qjE@ zS199F^vRP5fQp^yE}AW2aiV4b#mC+--$+dHDEQ;TVI_pC6h}KTH|+ggXOx637C-O^ zKoiEI)TmF`qd(8?*Dbc9_@LteB`)xTH;$RM^#51$;QK z^u>N$v#RZPnc;x?9Myu-3LKBmvLdEgFH3}}aOhF}S0Ct{sqR?hP2*&EEY7U=aZJaFqxvzcuMIBInNIN~q==;6MM}OL~@`lnAeLHp>fM#@od#lK{D+3k$ zPMH_Xy8FQMs7=;@Ivn1xm%x`|f~cT%2!IB&RGh`j8di&$XcsXLNB;yL0)KI(gI-Pe zE%qF*@cz&#!5Z;@-yb`_GpSG7m59-TZRY70?+<(`5C?`wSlCrAb=2)x;_?d{sl|P| z8d`Tt09e^e&%epf{AnvvR<=J&c#j=*0m7%oC|fSaKy}&=CdtUyqckGL*ZemU;g8(u zPQOM5;H7L(*DwptQp{D$kruXflyc!5HD?ziimK+T4TietSEIz09!4PZJx_D z)aB^S!H?@8)@0G2JQP+ir8jq^BHm_ZxkM zJE+?uAzDBg(2m!|nCO!8YZyBjAc(rz7h3myiRiQD)>Oc0oN`P7gX`ihzV z&C^&%KahiTM96PCh$6^}{B`%!D!j3_J3v-o9kYHB-~h3cCB_b7z7q*;FB55EyqJ1h zI&^>zSO`|6X(M|T_v~B(UHBglTfM;MlxP4fLq$ipzg&WbTQP5OM|9@EUAr&VTT3s~9e*cM zS&yI959rPc*_|k3cNv&^@H2y!2Fz^C&Lv$dlT}H^gIzAR>pfS2{8&*S{54))FfS;- zTW^(YiRMzEp}84`G37nLKz{~T)lXYQx zG-CD99eV3|zJjZj&mD4i;*oxX%`bN=B)KJz9_`Fxy|38|D;p;GkuU|V=v+K@FnpCO}r>8a!r!Y3d=+rW@gXr*oM!JUx0p|M6oaMWaj){E#M3)oa^(RqTEbD9 zKZd{)GC;M}oV4j7wPCqB$@}$YFAFmPO0=ID^0+??d9go>n$q+)4QYNdTaaOkdLx%% zD$nvcBnr0|8l!^j^RAu@_8|H|$7oJxD}~y3OsqeJGJz2wB>xKwge}wN zpET@{4j<2;l+=T6V$HEnqHS3lX3ZeHCfJ~s&B9zCSlXBwr z0C9A5mr-gj46PsRzT9@SLgamp6YQkWuu zBVE=FJ)8?D$Bv@Pr^7>mXTQhs*TRF0$p|FEMlhv&jX1TvkO{W7Hu6 z5sK$E>_4-X#7^;k9G2~r8o$*waY$~F#i$q-vKyx&*rKsou;@@B_=UD$i9A2@h*%1_ zG~Iq~BJ)8%zPScmMgGQD5lRy$kq+Y5iirC z2lfi^aV5y=^x3Pu0d^9xMC6l`u)~6(-o}Bv?#Ag^RXLdv(&ESIUk7@gCpWX=B5GArwcMWd8GJS>|YR$-`iMXr(cVo3eOs>EK(C*btulLKNfa_Bo2&`up^w zwvmui!z)XCX|XN!U~j$^vl;vWXec7C*+=3ta7=qrn3kFmam4{jIEWxf$+4WI_=m9L zE4YOEjW;6D#!CBjnV&F|bf2Ha6Fu)cARYK=^SVhvm)F1DGhyrV%rQqFnxAs}vv|K2 zS>|Sdbcp8_^Veo)KrZse$NX`ebD;|>3-t8Q2<%Dn5*u7K6l-}r$< z{m!Co(ms~F)k>J6Yy0r&HdsfL@1m}EP~Jn|BLHxdk?9meO=iQgTrcJ~&aJ7#3WxxQ z#7IvOUN4&#U)c6oCxz9)B+JUKLVSHB(o3tiXuavm#Ic8G0`;M?Ca7re5kQ<%d}Mt> zqU^?(n6maHQj!}KfRSqnGWz6ON>;Gs5@V(D$|`faS*6X8C;MiNj0wdGwc{*(sc=L1 zNXQ(a%i%aXyi6};HpB(kmZyPxS#Umx4~uCL&HgV<($# zp+?x;JS@bTqxl3N!AJN%_e@1y>MhDhIrD2@kBx%Wx*81da!(7snM?JlNy%iQpARk3 z=3-gJmD0so8Xo=qbB)CT7kmpQ_3vMFeSz1(@4H0^?XZx$?FN_zpMn#a@h>ESDaK+x zJzf_l@;#oY>|hHWK$S$tBJyHO;3V&a@uge}m3&010s~JKZL#eb=bITa(>(QD$YK{@(2VRyo+3;jF5W zOFn|jrmI^GaYd%^(fD>}ukdf)@LPEQ^`ht}Qyy0=w2L;4 zc?->KT39-T-VH?V*ByP^I!L0}JO?XmkGF?lmKhG(! ze;k>E{Zp0lX$sUwAmzk39d5fq=qZ}CjiHXz!FjXw&UA^Xi^~F_Le)_KYjiU;eLD_O zc;k3ts{zRG@8CIh|B7|bI{n99K-j0Tx270h_*^PJ{aBk%t0$GGJwui)>j=B(&?DJy z!&g5dWMX1$)@x%=-VckIs}AzHi5-5wXx#j`i-(5cX=22jydXXJw>n*A{CC4Fwl-jw z5Mc)y1C=7{G^}C|gvzj^eT!;y#qQ6BjrhkQb?4{?nSg!@iL}hQrg+`L5Kw;iWrfyhJT8OaBVz~21!04T z&7`^W%dQ*ZhI^WlA?|^v8lmVdIL6d9@x-;a&m$rhVKRcVo9@XUJMzyQ*$N;Hhc>w; zC!YbYu>klXjBY*#*#LC1ASgjgaDIoRodH4@!ZjmNeU?2F{=40LAT8n0V|&;sO<%Ufr56PK`wJT{RqIEQBHi5~2xf?!zC`zhDsMcpNlmp<6|sF?GkU4GBeFvo%)tx1u)t~`CGZ9R4+_b$AcAqf4;)y-=XFcb&lh&kmJJ4 z=~QA0ch({&wBD2}kRPVZ;_4f9>;|T8(-rE+`Hpt&fL0Az_FxR(@945<((Sn)zkF6* zKa?T+lw1cg^w}eCvUD4$8!7kzY@N_2E)v+1*sP%N%L)Vn3TfcAUbr zihEjJz`7LNqCT~ztP;S05CAT3rs|YF*t%ef23S8o2Q9O4ua+it$Y_R5B!VGhQhP;! zZ_h0z2@@oPzRa3$jEcW5=9~0}Ll={HjC=aD#wp`b9z1r>{lJ{*&dnp@BEf1B(m;q| zbThFNjB@a=)0I?%!EuP6CfFhkpw_cdIXbrqYAa~hR%E7Ht>Dr{`~Bj2#c6f&Gt@FD z-CV6FS_6qUvn67{eG;;6wpY2vZr9D0$^3Zpn%5XChKe8g7VeYzDA4^!D%Lw-9>&2t zcIAcigQyuBARO%!Ec59rVmV0^lunq27izVZ@LN<^5LA3GAs+~*Mpind&Vkg=*AgCU zzuz5FBg4iE`<|tNct|_2sHi;O$O$B9W`hjJ7JzU~e*~OlAwn4vDQRh1KU1CmeJ{bS zBk^R~+18XwK}%U(y~+ar)H^S(>5jPyU2X-I#B_wGS>V9L7dhP&kah4(%_*sDOrZEo zwHsXtgcvshE!#zxv^5*Z>lB)8n&+Lv_rHx4!+kSWv?{%Z_#$;v08jmV3Q7NnLK}y(!i&MBvvZ>;8?uWf4>zt`XfE)@b}kngtw{L znB>ph+LW5BiAze0M$r$ePLg3UAAkjb1i7^A1c(}I5bu7z5oD) zxVg!@x;`?VKBpv&QZUudB6&B5oCr55<;YE zRR)C!!l_SSlair4KzEo!Yc=ig1W)+77Z2&mNVz@Gl9hzOdc0S=FgtvQX=+!WD~C$R zHSczYeLZxMrhFR>u6OmLdeMK@T7Zbg3+TNUi~8=)v2qqD&C&3$=LJfRuSH@Ef=sz~ou>;PQrrj8o>hvet-$A>xV{?^AXNalk0ASu9izW}m2?L+wB0>{4h7gh!3{k<|s6^uQSaDlET=N|Y zpnCHL@m%Q_S%v2dp*@tK%Tmx_S2^+IvK`}5Nt|!S{>M2HQAlC7u>?Ju2ksgx2M%!7 zAh!O}oi+eW2a!KoLn85uVTnuLJdN|=Eq={AfFbdH{hjN2mf;Wjx|X{8vs+F6rWuKA zyY1SO{d#tH1E8fO0iRUJ6o`ORu<0_embAN>(72WnsZ0Y2w?AVkj!Vje9Nup+wqt+l zA^@i)^Malf`|$WB7ekMs6D49hMHDS@nEf48m9VK6yQW8Nj=?*$$?j3NT4Wctp8TL$ zb%p6H;X2F&oq7sp5zCb~H2G;&4=1 ziymJ3VswoO&r1jO>(_ZjSnL!LBGvzrknXV-YoYTZBx9M*SKQ zy$Nzvj{#i^=t__SC%xabg4#dlAq@p`c<_+GvuT1Xx3C$&eLIfsgzT;gOLKBOLFG$v z5*>i+30TqyOftb+gelVN^_Mp-1*pV0BMKBiMY^b?_!L$1!82o?fb<-rgxQfd5BA>mD#6@(qfx((fg~ouxpynqB9->FC*TMnN<>M7vNf_M zzxt+jreGzeNkfJ|yD4#HDd-F2EAoWsUz;p&EFxUvAQ-MgmU86)f?zG;h8c5{5|}d-T)BcvfJ4<$E-ApQL>&sk&u8_kP0!B(#H1`1yd*Hxu(dsfeQy?IiPNz=p&sLf0u*xp@g3DT~n z3>fz|t7ue4l`y!8g(h-{1n7CKZXvAD+8MdvKqllw=A(J>4TMjh`D?n_c>_=QW1Dcx zgIEMt6~`I9hzbS@1vjvINK643IRyMi4C*+4=D~YNQ+e=K&HEp`>E4-PRAESq$NX_U zpl1UD5v~GVOSqlYkepJt-#3u&OeN|7y-8J4M99{Qvk$zC0-{x2tJGus4k@>0&(Rp& zr^ceWzn^8!iVIzK1+^bIQ~6t=a+Fl-#VHNi;6LM+OVkD)Me_$AV3YQ_K`sWf%;F$N zx}se7ZlwVa+2KpUZ)&zNPG?16d60H7`%6ZQm*%;isV=iX7hrz5X#*f;8k$~iAbtmM zkbxa#0ODtWl0EO5DY@J$FN z9ToQloqX8-%k}3E27{eg0C(>VYQU`Dg+Io8L7xg)zjClLY~g8%yGE5hKY^BLEKGvN z8joy$`SrdVdg*V38w+{<9zi?^IT68lyc`5t1kVTR0&Qu*uDEY523h*|o?mLQLJr5r-m^V$V>xQ_BiN^J4xPUY0PaxF8d8^WM`c!gV-WFA6Hc8zi-cob9z)#F6kQe>HeUes3cf`%-2Cs8o zYU7n?`RH;&(;A5Az)j~bzG)#H2;m%M3Gru(NOX4_-Ph>CGQVh76vvqYWBm^=0LV4i zp{C%M&PfzL$yK?|{P%<7Iara$W3t51ru!Xo3gTOt!Sz5Z=<6AyD4Ulin^km$h0?y5 z#LP2_tD@=S9c}is&q`z#`Iz5OFxg~>0)8KMDTI!SSQ#Cag#bVF=p+87+AK>E?SJG( zLOyn-EHC6uh=0M6SH~FtYGq>-kCJwHCx$-0A2{!#vy#4+0w86#Js_NATEpHb7|w5O zb?bZHh)B6kyvAQ9*=7Uv^{V@x@cYlS-AVEIwAWnJ6eJq;BSx{7pxGTYDKi}2%yH-B z*?1)Z(g&nn1IGy)oKT2sL(`2d>>~P!vg7Jo{{MzcAJ;TblIz!v)XyBomWRipcq zL56M<&tlqWxL5t?8vpW zXfa;ZIJHNXJXuWa9RiWZS0t9wtjYL_58D{r?p?GIS~*=jRk(6m+)PlK#o)TY)z8xE0f|FUA3TRx(b-_t1mhYt@)t=+QQdv#iO zUzgLlM{o59qm$&{hh}sGBw&98$N>Aa08|z=1uT`|*gVm2Y6}YqLh*6=MF(DQdNzd4 z@_c+-(NVn+D-4cMTwW!3 zTcqC(=<3{(QlO42L4e|rNA=QjG3a!CCYY3_$G`Ay#BUYg-Uc}%AaUJ_e|ev? zrUm3RE8BJj%MV2cC#;0*Cl!NqPI_3+jE;m|J>kQABv+!1?0g#k;J?L*I@(4ydjbD; zY<$9df)GJ&%v}{6DObzvR|iqN)HF4?mn8}yHP#g$_Z{Ir7|!V&_|^Gq|E?c@P0Vjj z)^Kxs_RtgR%bAyer8Vu^9BF8`SC*k1k`j&r;l#YO^aN_Jp*;VTBHKf%`jx2TFTI2o zxp1cufGmk1gRciK_Pe$>;Ci4)nHU*U3Mhi6JN4C1-&W@SYjPxV1mgFA)l(YX0^j~< z@14pK64`YiFSxU%)_k=bWGc+@d#WnK4q~JOSI&wn+c_F=E}yvjU?k%x3B%(Nii+Qi z1R;-F-OATCRG{L@Q%Dok9*`P<3m4qR?v`A56@fL<`Zp9HIvbtNFA>jF(LABxV)ybg zkhYtPss%?Nz7s*ek(4zMl0jTnoN+5_+Wv@H9gPd$W~t~5S0;ccep^r5E`!t!VqD`K zMDoX%PN2gqLzD+IhJUFNX%3$Hdx0z+&_5w|8b{!|61K4jPrQ(~6Xsw=1eB(O#aXcS z{p2HsA#x+?BsCokrLC(KmeLppF32|=QWhr<#yCzeEva1WKA=YRZQ{h^GeXv83FUZr z?bz;X1ZZm#Iy7<6`d6<3t|jzAbNK#(65)D#l|ihR;|GVdd3z}k#?AuIh}(V|U^0j+ z2k{wvcPI$TwB-RQPMVqWy<^UTnQM}Qe6~pSp8?ta#@_&|rtQfqt_tm(DQlC|fb)S; zzlq(peEj<3ml#FRx+Q$s74#4&K%6~N3b6PpM4nfG?n-)x5+m5yp1b{fu3-g#^uzc% z!Hy{dCH543pK|_ap6X!b0w?T`OyzUNHNv;4WRjHsa>-XSWM<>THh*Y}-#GN>tMAn8 z&vCG2y9fL{G-5+9&l1kYTfcv^a;i2+wNIXx%|+wyCDhO9Y+M4VovGit$}0((1J^WP z{n(q#b*w(vwYImC`C?yIuCXAG+#=IL#b2$5XMa(hVhVHGN&KzQd?rwEX+)58$skLAt{`b0*t;qOd)8 z^P{ee1Y_LRLZfxq+rkx-A+Tc1oOh+@pb}_DkUA)m;y08?2J!D-^V326;yxQx9q(SE z3KDF$QPvtoey^WS)i~q$q1J+Ey3IYcWmmvpMuVj7n$pDWC^hK<5@u)mZ--Wzli(0? zWUu7HdbDyBf;8ZmCSY6&x}>bpKNR!R8(9l;dgRYzBU~m%OpzL{w?Z|7Q@0B?=95*O zan<9$H$bC!5ws`*d1E5`n~%4tHgeEQmUOLfXR4;=HJQTv;VBEGZPyFz3{8N!O@e@K zh;sd3KpRU?P83QJ#?odRw4kz;^sN8B4m&H79!v@wXes~+d;WSnOq~Ht^W|`E&&+u3 z<;~rJ(i3%2QxK;F#1%N`#iov`himCs%>&*bkGg2YFXWK`YyEdSr13z3)%R!aUC`x1 z?&`ud*5&0#MFcbmvC|n2E^>1AgfI#^J!Kl)ufUF;Kid?{TC3QlVyELibthXMNPfUi z_gQu%J-E~RzoHdNLPGEz|MU+rhix_>&h9F7B(HAS2hi@0WB8CvZ_gz8wLh{d^I|C&Q@}k1fMgsR}ZSl<1m!wnV4MMe z@0aH1>slS~sM{`=SVI)uyWny_aQ5lasyx;6Kp&vb774=RR0NhEgVg&I$x9YAZn3|W z`(r>lSBT&=&A*2>Zro~p^B~%5;5`@;Aaoy>MOFQ_*?6`u@RT@|hG%=0Ab3FJB50db zY$pt!o*JAW66E2Vzm)&4bL|bS<8HCwuw~v}MSwQQu3N$}xn}xYQp&!!fo+?SL&1m9 zS(2@KS_iZ>VSvk)~M{eM>3`@SNlAnf!bw-61^#l#QoPT-bqFRY9b<+Gv|J2hk;w4oe*2w@}=mM~qovA6-|JrGUI>N!A4^jMKV zd5L>H?6W>*2%4r^3NJt12T57r=fw@s>E_4*1eZShQ~q%2-6CmyEM%iUaCmfgMoQHr z+Quc;qP|gSUH$I^QHO!wz6cI~63Zu`uv!t3#~{bWVt~|-AA*_vDFtGt;V-iqWA#9} zBRtFeZ}7&mup))Nm0dvU*|9r}r2rF7*t`<)E!H()r$k?oNUL=>ARhDYd5g$_U+n|} zc(^K`FSolDFg0C+(s?8|dJ#~`1> zA)X`Xqgao-_ohe_#5Y{5yu?8nmP8S-KI(!-1d2SI!?Q|0?-8A$dUn(4 zeMi7Nd;_k)ozVFA>++j}R*jY*IyT+C%LD-Awckk{TO`7&+V10@^;q=8uwcYTBY45& zzs0W{bR(Pv2WwLlJKW>xU87=Z*rnRRv7QyLuS6)=f)hFHrZ>6- zOB*F86hQ}sfWIP;c=u0B{n`Kfe0qAc3=o4UL2E(hI$w$76;JxZN^p;rcY)}9I!cC< z%|@>qI|bIF1JLZ_@0aan1b+hXKnAD<)L(AhG8-(MD{gB06NyyN&^FS=Nu^@hJ_O&@ z9{QH?c%?ML`zo{nc+LZESh4(jT5=G-z8LH%2{I-08AE!jy7{a<C@!}`zkK@W*Z99XV9Ny1-U~ml;M_q02T@7V_KP-Xm=JLF zY%vXv*KZGbvkV;`R$~WL4l(qg=GTD}c&=>^5B8xa@#=>-XW*IKo2`3rYpHWlF{B=u z(THt3`EQ5k2d$0z(m=N}@HxWEv2_pLMSwXAD&<{7*#WjLfI{e995}Ch1AyWqAr$hE zUI+zmJvST05_|q**W@ku`lbKg1{^er;W#xIq5S5CpD9}V{}pxiK}ls%0CzXq5lu5v zakBgH7(K95**AF#VwXVl*b zi)3k0_1OuxQyJrY0CBDm@0{m5Eq35FD|QOVR;M+Kt8inb+iYCwe4OtL@G{H9;6a_G zOv4H^E%P}+p8&Yk)+qC2vN>}*{_#bs5+02A`Go-%a3qpeK~-B`EYKO8K6nB-Xng`k z7IwH+9D!4D{jFUb6^2W>4YCeX1uq2#VgeB8Jk%yb#Zex6o2u8ZC`hl)sui>7-#|az z$G~N)1uTTf6TY)@MAIJ8%f<05js$AkZUWlvZlD3%+Q7mTjcDk;Q99NBbqCb7L4(=e z9VD0?=BZh-_hmfsk6f>tds= z24BVr{q2Y(JZopHollVt83D;g`0mxM#>fcR)qh*pnO|ix%Ox>eS5V%;sYB;b-pI8e zO$vz&3ik#IT8G~GSA{Iw5cdI1n$_VmYcX~(RGJ<5i?<1304X1_6AVw886aw|Ay zG4VdlioY#-+LLddAT7eo~c%LsEi$ zMEY>-D3QuytKg!cWhn2#kE8wTy_@}$X!-Yg<&8lau5HGe;dSGiy*P8mQJ?FcdeZCgsjZ<4e|ixVm#Z?_ zh*9oadZL_KxrAB705|MR+H5E9iz6QWN!+$E?MH(>+(d^2oE=KGK^uT%nKejB!x=NP z;UbV%hrS}wiZCk~s0pL?@Fko$t!2+$Uq`@gVc-r28x?wJgOO Otherwise delete!!! -// icon = '', -// iconpath = 'images/icons/' + f.path + '.png'; - - -// function imageExists(image_url){ - -// var http = new XMLHttpRequest(); - -// http.open('HEAD', image_url, false); -// http.send(); -// -// return http.status != 404; -// } - -// if (imageExists(iconpath)) { -// icon = '
'; -// } else if(itemsLength) { -// icon = ''; -// } - - if(itemsLength) { + // Function need to checked by MR! -> Otherwise delete!!! + // icon = '', + // iconpath = 'images/icons/' + f.path + '.png'; + + + // function imageExists(image_url){ + + // var http = new XMLHttpRequest(); + + // http.open('HEAD', image_url, false); + // http.send(); + // + // return http.status != 404; + // } + + // if (imageExists(iconpath)) { + // icon = '
'; + // } else if(itemsLength) { + // icon = ''; + // } + + if (itemsLength) { icon = ''; - } + } - if(itemsLength == 1) { + if (itemsLength == 1) { itemsLength += ' item'; } - else if(itemsLength > 1) { + else if (itemsLength > 1) { itemsLength += ' items'; } else { itemsLength = 'Empty'; } - - var folder = $('
  • '+icon+'' + name + ' ' + itemsLength + '
  • '); + + var folder = $('
  • ' + icon + '' + name + ' ' + itemsLength + '
  • '); fileList.append(folder) - + }); } - if(scannedFiles.length) { + if (scannedFiles.length) { - scannedFiles.forEach(function(f) { + scannedFiles.forEach(function (f) { var fileSize = bytesToSize(f.size), name = escapeHTML(f.name), fileType = name.split('.'), icon = ''; - fileType = fileType[fileType.length-1]; - + fileType = fileType[fileType.length - 1]; + if (fileType == "db") { return; } if (fileType == "jpg") { icon = '
    '; - var file = $('
  • '+icon+''+ name +' '+fileSize+'
  • '); + var file = $('
  • ' + icon + '' + name + ' ' + fileSize + '
  • '); } else if (fileType == "jpeg") { icon = '
    '; - var file = $('
  • '+icon+''+ name +' '+fileSize+'
  • ');file.appendTo(fileList); + var file = $('
  • ' + icon + '' + name + ' ' + fileSize + '
  • '); file.appendTo(fileList); } else if (fileType == "png") { icon = '
    '; - var file = $('
  • '+icon+''+ name +' '+fileSize+'
  • ');file.appendTo(fileList); + var file = $('
  • ' + icon + '' + name + ' ' + fileSize + '
  • '); file.appendTo(fileList); } else if (fileType == "gif") { icon = '
    '; - var file = $('
  • '+icon+''+ name +' '+fileSize+'
  • ');file.appendTo(fileList); + var file = $('
  • ' + icon + '' + name + ' ' + fileSize + '
  • '); file.appendTo(fileList); } else { - icon = '.'+fileType+''; - } - + icon = '.' + fileType + ''; + } + if (fileType == "mp4") { - + // adding watched courses to cookie information - dev //var arr = ['001 - Course Introduction.mp4', 'bar', 'Home/IT Basics and Sysadmin Topics/DNS and BIND Deep Dive/004 - DNS Concepts - Terms and Definitions.mp4']; //var json_str = JSON.stringify(arr); //setCookie('watchedVideoArray', json_str); - - - - var style=""; + + var style = ""; // https://stackoverflow.com/questions/2980143/i-want-to-store-javascript-array-as-a-cookie/2980163 // get saved cookie information - var json_str=getCookie("watchedVideoArray"); + var json_str = getCookie("watchedVideoArray"); if (json_str != "") { var arr_watchstatus = JSON.parse(json_str); if (arr_watchstatus.includes(f.path)) { - style='style="display: inline;"'; + style = 'style="display: inline;"'; } } - - var file = $('
  • '+icon+''+ name +' '+fileSize+'
  • '); - + + var file = $('
  • ' + icon + '' + name + ' ' + fileSize + '
  • '); + } else { - var file = $('
  • '+icon+''+ name +' '+fileSize+'
  • '); + var file = $('
  • ' + icon + '' + name + ' ' + fileSize + '
  • '); } - + file.appendTo(fileList); }); } - // Generate the breadcrumbs var url = ''; - if(filemanager.hasClass('searching')){ + if (filemanager.hasClass('searching')) { url = 'Search results: '; fileList.removeClass('animated'); @@ -405,29 +398,28 @@ $(function(){ var name = u.split('/'); if (i !== breadcrumbsUrls.length - 1) { - url += '' + name[name.length-1] + ' '; - document.getElementById("backButton").href = "#"+u; + url += '' + name[name.length - 1] + ' '; + document.getElementById("backButton").href = "#" + u; } else { - url += '' + name[name.length-1] + ''; + url += '' + name[name.length - 1] + ''; } }); } breadcrumbs.text('').append(url); - // Show the generated elements - fileList.fadeIn(); + // Show the generated elements and hide loader + document.querySelector(".loader").style.display = "none"; + fileList.fadeIn(); } - // This function escapes special html characters in names function escapeHTML(text) { - return text.replace(/\&/g,'&').replace(/\/g,'>'); + return text.replace(/\&/g, '&').replace(/\/g, '>'); } - // Convert file sizes from bytes to human readable units function bytesToSize(bytes) { var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']; diff --git a/index.php b/index.php index 5fbe93c..bea3a31 100644 --- a/index.php +++ b/index.php @@ -1,109 +1,154 @@ +require(__DIR__ . '/login.php'); +define('PROJECT_ROOT', getcwd()); +?> - - - MIT Learning Manager 2.5 - - - - - - - - - - - - - - - - - -
    -
    - MIT Learning Manager -
    - - - Go Back - Home - -
      -
      -
      - Error! - No files here. -
      - + + + + Michu IT Learning Manager 2.0 + + + + + + + + + + + + + + + + + + +
      +
      + Michu IT Learning Manager
      + + + + Go Back + Home + + +
      Loading...
      + +
        +
        +
        + Error! - No files here. +
        + +
        - - - - - - + + + + - - + }); + + + + \ No newline at end of file diff --git a/login.php b/login.php index b131f5c..c18caeb 100644 --- a/login.php +++ b/login.php @@ -1,36 +1,39 @@ - - - - - Please provide password! - - - - - - - - + if (!function_exists('showLoginPasswordProtect')) { + // show login form + function showLoginPasswordProtect($error_msg) + { +?> + + - -
        - - -
        -
        - - + + + Please provide MLP + + + + + + + + + + - - + +
        + + +
        + + + + + + + + +$val) { - $lp = (USE_USERNAME ? $key : '') .'%'.$val; - if ($_COOKIE['verify'] == md5($lp)) { - $found = true; - // prolong timeout - if (TIMEOUT_CHECK_ACTIVITY) { - setcookie("verify", md5($lp), $timeout, '/'); - } - break; + $login = isset($_POST['access_login']) ? $_POST['access_login'] : ''; + $pass = $_POST['access_password']; + if ( + !USE_USERNAME && !in_array($pass, $LOGIN_INFORMATION) + || (USE_USERNAME && (!array_key_exists($login, $LOGIN_INFORMATION) || $LOGIN_INFORMATION[$login] != $pass)) + ) { + showLoginPasswordProtect("wrong password!"); + } else { + // set cookie if password was validated + setcookie("verify", md5($login . '%' . $pass), $timeout, '/'); + + // Some programs (like Form1 Bilder) check $_POST array to see if parameters passed + // So need to clear password protector variables + unset($_POST['access_login']); + unset($_POST['access_password']); + unset($_POST['Submit']); + //header('Location: ' . $logoutURL . "/$script_path"); + header('Location: ' . $logoutURL . "/study"); + } + } else { + // check if password cookie is set + if (!isset($_COOKIE['verify'])) { + showLoginPasswordProtect(""); + } + // check if cookie is good + $found = false; + foreach ($LOGIN_INFORMATION as $key => $val) { + $lp = (USE_USERNAME ? $key : '') . '%' . $val; + if ($_COOKIE['verify'] == md5($lp)) { + $found = true; + // prolong timeout + if (TIMEOUT_CHECK_ACTIVITY) { + setcookie("verify", md5($lp), $timeout, '/'); + } + break; + } + } + if (!$found) { + showLoginPasswordProtect(""); } - } - if (!$found) { - showLoginPasswordProtect(""); - } } } ?> \ No newline at end of file diff --git a/manage.php b/manage.php new file mode 100644 index 0000000..c885a69 --- /dev/null +++ b/manage.php @@ -0,0 +1,4110 @@ + 'Password', 'Username2' => 'Password2', ...) +$auth_users = array( + 'admin' => '$2y$10$HFP49dcc1ZDL3kqIknYGFOykI7HxIk3eW7BMtyUn03D8m56R/4pLe' //, + //'user' => '$2y$10$Fg6Dz8oH9fPoZ2jJan5tZuv6Z4Kp7avtQ9bDfrdRntXtPeiMAZyGO' +); + +//set application theme +//options - 'light' and 'dark' +$theme = 'light'; + +// Readonly users +// e.g. array('users', 'guest', ...) +$readonly_users = array( + 'user' +); + +// Enable highlight.js (https://highlightjs.org/) on view's page +$use_highlightjs = false; + +// highlight.js style +// for dark theme use 'ir-black' +$highlightjs_style = 'vs'; + +// Enable ace.js (https://ace.c9.io/) on view's page +$edit_files = false; + +// Default timezone for date() and time() +// Doc - http://php.net/manual/en/timezones.php +$default_timezone = 'Europe/Zurich'; // UTC + +// Root path for file manager +// use absolute path of directory i.e: '/var/www/folder' or $_SERVER['DOCUMENT_ROOT'].'/folder' +$root_path = $_SERVER['DOCUMENT_ROOT'].'Home'; + +// Root url for links in file manager.Relative to $http_host. Variants: '', 'path/to/subfolder' +// Will not working if $root_path will be outside of server document root +$root_url = ''; + +// Server hostname. Can set manually if wrong +$http_host = $_SERVER['HTTP_HOST']; + +// user specific directories +// array('Username' => 'Directory path', 'Username2' => 'Directory path', ...) +$directories_users = array(); + +// input encoding for iconv +$iconv_input_encoding = 'UTF-8'; + +// date() format for file modification date +// Doc - https://www.php.net/manual/en/function.date.php +$datetime_format = 'Y-m-d H:i'; + +// Allowed file extensions for create and rename files +// e.g. 'txt,html,css,js' +$allowed_file_extensions = ''; + +// Allowed file extensions for upload files +// e.g. 'gif,png,jpg,html,txt' +$allowed_upload_extensions = ''; + +// Favicon path. This can be either a full url to an .PNG image, or a path based on the document root. +// full path, e.g http://example.com/favicon.png +// local path, e.g images/icons/favicon.png +$favicon_path = 'favicon.ico'; + +// Files and folders to excluded from listing +// e.g. array('myfile.html', 'personal-folder', '*.php', ...) +$exclude_items = array(); + +// Online office Docs Viewer +// Availabe rules are 'google', 'microsoft' or false +// google => View documents using Google Docs Viewer +// microsoft => View documents using Microsoft Web Apps Viewer +// false => disable online doc viewer +$online_viewer = 'false'; + +// Sticky Nav bar +// true => enable sticky header +// false => disable sticky header +$sticky_navbar = true; + +// Maximum file upload size +// Increase the following values in php.ini to work properly +// memory_limit, upload_max_filesize, post_max_size +$max_upload_size_bytes = 6000; + +// Possible rules are 'OFF', 'AND' or 'OR' +// OFF => Don't check connection IP, defaults to OFF +// AND => Connection must be on the whitelist, and not on the blacklist +// OR => Connection must be on the whitelist, or not on the blacklist +$ip_ruleset = 'OFF'; + +// Should users be notified of their block? +$ip_silent = true; + +// IP-addresses, both ipv4 and ipv6 +$ip_whitelist = array( + '127.0.0.1', // local ipv4 + '::1' // local ipv6 +); + +// IP-addresses, both ipv4 and ipv6 +$ip_blacklist = array( + '0.0.0.0', // non-routable meta ipv4 + '::' // non-routable meta ipv6 +); + +// if User has the customized config file, try to use it to override the default config above +$config_file = './config.php'; +if (is_readable($config_file)) { + @include($config_file); +} + +// --- EDIT BELOW CAREFULLY OR DO NOT EDIT AT ALL --- + +// max upload file size +define('MAX_UPLOAD_SIZE', $max_upload_size_bytes); + +define('FM_THEME', $theme); + +// private key and session name to store to the session +if ( !defined( 'FM_SESSION_ID')) { + define('FM_SESSION_ID', 'filemanager'); +} + +// Configuration +$cfg = new FM_Config(); + +// Default language +$lang = isset($cfg->data['lang']) ? $cfg->data['lang'] : 'en'; + +// Show or hide files and folders that starts with a dot +$show_hidden_files = isset($cfg->data['show_hidden']) ? $cfg->data['show_hidden'] : true; + +// PHP error reporting - false = Turns off Errors, true = Turns on Errors +$report_errors = isset($cfg->data['error_reporting']) ? $cfg->data['error_reporting'] : true; + +// Hide Permissions and Owner cols in file-listing +$hide_Cols = isset($cfg->data['hide_Cols']) ? $cfg->data['hide_Cols'] : true; + +// Show directory size: true or speedup output: false +$calc_folder = isset($cfg->data['calc_folder']) ? $cfg->data['calc_folder'] : true; + +//available languages +$lang_list = array( + 'en' => 'English' +); + +if ($report_errors == true) { + @ini_set('error_reporting', E_ALL); + @ini_set('display_errors', 1); +} else { + @ini_set('error_reporting', E_ALL); + @ini_set('display_errors', 0); +} + +// if fm included +if (defined('FM_EMBED')) { + $use_auth = false; + $sticky_navbar = false; +} else { + @set_time_limit(600); + + date_default_timezone_set($default_timezone); + + ini_set('default_charset', 'UTF-8'); + if (version_compare(PHP_VERSION, '5.6.0', '<') && function_exists('mb_internal_encoding')) { + mb_internal_encoding('UTF-8'); + } + if (function_exists('mb_regex_encoding')) { + mb_regex_encoding('UTF-8'); + } + + session_cache_limiter(''); + session_name(FM_SESSION_ID ); + function session_error_handling_function($code, $msg, $file, $line) { + // Permission denied for default session, try to create a new one + if ($code == 2) { + session_abort(); + session_id(session_create_id()); + @session_start(); + } + } + set_error_handler('session_error_handling_function'); + session_start(); + restore_error_handler(); +} + +if (empty($auth_users)) { + $use_auth = false; +} + +$is_https = isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == 1) + || isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https'; + +// update $root_url based on user specific directories +if (isset($_SESSION[FM_SESSION_ID]['logged']) && !empty($directories_users[$_SESSION[FM_SESSION_ID]['logged']])) { + $wd = fm_clean_path(dirname($_SERVER['PHP_SELF'])); + $root_url = $root_url.$wd.DIRECTORY_SEPARATOR.$directories_users[$_SESSION[FM_SESSION_ID]['logged']]; +} +// clean $root_url +$root_url = fm_clean_path($root_url); + +// abs path for site +defined('FM_ROOT_URL') || define('FM_ROOT_URL', ($is_https ? 'https' : 'http') . '://' . $http_host . (!empty($root_url) ? '/' . $root_url : '')); +defined('FM_SELF_URL') || define('FM_SELF_URL', ($is_https ? 'https' : 'http') . '://' . $http_host . $_SERVER['PHP_SELF']); + +// logout +if (isset($_GET['logout'])) { + unset($_SESSION[FM_SESSION_ID]['logged']); + fm_redirect(FM_SELF_URL); +} + +// Show image here +if (isset($_GET['img'])) { + fm_show_image($_GET['img']); +} + +// Validate connection IP +if($ip_ruleset != 'OFF'){ + $clientIp = $_SERVER['REMOTE_ADDR']; + + $proceed = false; + + $whitelisted = in_array($clientIp, $ip_whitelist); + $blacklisted = in_array($clientIp, $ip_blacklist); + + if($ip_ruleset == 'AND'){ + if($whitelisted == true && $blacklisted == false){ + $proceed = true; + } + } else + if($ip_ruleset == 'OR'){ + if($whitelisted == true || $blacklisted == false){ + $proceed = true; + } + } + + if($proceed == false){ + trigger_error('User connection denied from: ' . $clientIp, E_USER_WARNING); + + if($ip_silent == false){ + fm_set_msg('Access denied. IP restriction applicable', 'error'); + fm_show_header_login(); + fm_show_message(); + } + + exit(); + } +} + +// Auth +if ($use_auth) { + if (isset($_SESSION[FM_SESSION_ID]['logged'], $auth_users[$_SESSION[FM_SESSION_ID]['logged']])) { + // Logged + } elseif (isset($_POST['fm_usr'], $_POST['fm_pwd'])) { + // Logging In + sleep(1); + if(function_exists('password_verify')) { + if (isset($auth_users[$_POST['fm_usr']]) && isset($_POST['fm_pwd']) && password_verify($_POST['fm_pwd'], $auth_users[$_POST['fm_usr']])) { + $_SESSION[FM_SESSION_ID]['logged'] = $_POST['fm_usr']; + fm_set_msg(lng('You are logged in')); + fm_redirect(FM_SELF_URL . '?p='); + } else { + unset($_SESSION[FM_SESSION_ID]['logged']); + fm_set_msg(lng('Login failed. Invalid username or password'), 'error'); + fm_redirect(FM_SELF_URL); + } + } else { + fm_set_msg(lng('password_hash not supported, Upgrade PHP version'), 'error');; + } + } else { + // Form + unset($_SESSION[FM_SESSION_ID]['logged']); + fm_show_header_login(); + ?> +
        +
        +
        +
        +
        +
        + +
        +
        + +
        +
        +
        +
        + + Root path \"{$root_path}\" not found!"; + exit; +} + +defined('FM_SHOW_HIDDEN') || define('FM_SHOW_HIDDEN', $show_hidden_files); +defined('FM_ROOT_PATH') || define('FM_ROOT_PATH', $root_path); +defined('FM_LANG') || define('FM_LANG', $lang); +defined('FM_FILE_EXTENSION') || define('FM_FILE_EXTENSION', $allowed_file_extensions); +defined('FM_UPLOAD_EXTENSION') || define('FM_UPLOAD_EXTENSION', $allowed_upload_extensions); +defined('FM_EXCLUDE_ITEMS') || define('FM_EXCLUDE_ITEMS', $exclude_items); +defined('FM_DOC_VIEWER') || define('FM_DOC_VIEWER', $online_viewer); +define('FM_READONLY', $use_auth && !empty($readonly_users) && isset($_SESSION[FM_SESSION_ID]['logged']) && in_array($_SESSION[FM_SESSION_ID]['logged'], $readonly_users)); +define('FM_IS_WIN', DIRECTORY_SEPARATOR == '\\'); + +// always use ?p= +if (!isset($_GET['p']) && empty($_FILES)) { + fm_redirect(FM_SELF_URL . '?p='); +} + +// get path +$p = isset($_GET['p']) ? $_GET['p'] : (isset($_POST['p']) ? $_POST['p'] : ''); + +// clean path +$p = fm_clean_path($p); + +// for ajax request - save +$input = file_get_contents('php://input'); +$_POST = (strpos($input, 'ajax') != FALSE && strpos($input, 'save') != FALSE) ? json_decode($input, true) : $_POST; + +// instead globals vars +define('FM_PATH', $p); +define('FM_USE_AUTH', $use_auth); +define('FM_EDIT_FILE', $edit_files); +defined('FM_ICONV_INPUT_ENC') || define('FM_ICONV_INPUT_ENC', $iconv_input_encoding); +defined('FM_USE_HIGHLIGHTJS') || define('FM_USE_HIGHLIGHTJS', $use_highlightjs); +defined('FM_HIGHLIGHTJS_STYLE') || define('FM_HIGHLIGHTJS_STYLE', $highlightjs_style); +defined('FM_DATETIME_FORMAT') || define('FM_DATETIME_FORMAT', $datetime_format); + +unset($p, $use_auth, $iconv_input_encoding, $use_highlightjs, $highlightjs_style); + +/*************************** ACTIONS ***************************/ + +// AJAX Request +if (isset($_POST['ajax']) && !FM_READONLY) { + + // save + if (isset($_POST['type']) && $_POST['type'] == "save") { + // get current path + $path = FM_ROOT_PATH; + if (FM_PATH != '') { + $path .= '/' . FM_PATH; + } + // check path + if (!is_dir($path)) { + fm_redirect(FM_SELF_URL . '?p='); + } + $file = $_GET['edit']; + $file = fm_clean_path($file); + $file = str_replace('/', '', $file); + if ($file == '' || !is_file($path . '/' . $file)) { + fm_set_msg('File not found', 'error'); + fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH)); + } + header('X-XSS-Protection:0'); + $file_path = $path . '/' . $file; + + $writedata = $_POST['content']; + $fd = fopen($file_path, "w"); + $write_results = @fwrite($fd, $writedata); + fclose($fd); + if ($write_results === false){ + header("HTTP/1.1 500 Internal Server Error"); + die("Could Not Write File! - Check Permissions / Ownership"); + } + die(true); + } + + //search : get list of files from the current folder + if(isset($_POST['type']) && $_POST['type']=="search") { + $dir = FM_ROOT_PATH; + $response = scan(fm_clean_path($_POST['path']), $_POST['content']); + echo json_encode($response); + exit(); + } + + // backup files + if (isset($_POST['type']) && $_POST['type'] == "backup" && !empty($_POST['file'])) { + $fileName = $_POST['file']; + $fullPath = FM_ROOT_PATH . '/'; + if (!empty($_POST['path'])) { + $relativeDirPath = fm_clean_path($_POST['path']); + $fullPath .= "{$relativeDirPath}/"; + } + $date = date("dMy-His"); + $newFileName = "{$fileName}-{$date}.bak"; + $fullyQualifiedFileName = $fullPath . $fileName; + try { + if (!file_exists($fullyQualifiedFileName)) { + throw new Exception("File {$fileName} not found"); + } + if (copy($fullyQualifiedFileName, $fullPath . $newFileName)) { + echo "Backup {$newFileName} created"; + } else { + throw new Exception("Could not copy file {$fileName}"); + } + } catch (Exception $e) { + echo $e->getMessage(); + } + } + + // Save Config + if (isset($_POST['type']) && $_POST['type'] == "settings") { + global $cfg, $lang, $report_errors, $show_hidden_files, $lang_list, $hide_Cols, $calc_folder; + $newLng = $_POST['js-language']; + fm_get_translations([]); + if (!array_key_exists($newLng, $lang_list)) { + $newLng = 'en'; + } + + $erp = isset($_POST['js-error-report']) && $_POST['js-error-report'] == "true" ? true : false; + $shf = isset($_POST['js-show-hidden']) && $_POST['js-show-hidden'] == "true" ? true : false; + $hco = isset($_POST['js-hide-cols']) && $_POST['js-hide-cols'] == "true" ? true : false; + $caf = isset($_POST['js-calc-folder']) && $_POST['js-calc-folder'] == "true" ? true : false; + + if ($cfg->data['lang'] != $newLng) { + $cfg->data['lang'] = $newLng; + $lang = $newLng; + } + if ($cfg->data['error_reporting'] != $erp) { + $cfg->data['error_reporting'] = $erp; + $report_errors = $erp; + } + if ($cfg->data['show_hidden'] != $shf) { + $cfg->data['show_hidden'] = $shf; + $show_hidden_files = $shf; + } + if ($cfg->data['show_hidden'] != $shf) { + $cfg->data['show_hidden'] = $shf; + $show_hidden_files = $shf; + } + if ($cfg->data['hide_Cols'] != $hco) { + $cfg->data['hide_Cols'] = $hco; + $hide_Cols = $hco; + } + if ($cfg->data['calc_folder'] != $caf) { + $cfg->data['calc_folder'] = $caf; + $calc_folder = $caf; + } + $cfg->save(); + echo true; + } + + // new password hash + if (isset($_POST['type']) && $_POST['type'] == "pwdhash") { + $res = isset($_POST['inputPassword2']) && !empty($_POST['inputPassword2']) ? password_hash($_POST['inputPassword2'], PASSWORD_DEFAULT) : ''; + echo $res; + } + + //upload using url + if(isset($_POST['type']) && $_POST['type'] == "upload" && !empty($_REQUEST["uploadurl"])) { + $path = FM_ROOT_PATH; + if (FM_PATH != '') { + $path .= '/' . FM_PATH; + } + + $url = !empty($_REQUEST["uploadurl"]) && preg_match("|^http(s)?://.+$|", stripslashes($_REQUEST["uploadurl"])) ? stripslashes($_REQUEST["uploadurl"]) : null; + $use_curl = false; + $temp_file = tempnam(sys_get_temp_dir(), "upload-"); + $fileinfo = new stdClass(); + $fileinfo->name = trim(basename($url), ".\x00..\x20"); + + $allowed = (FM_UPLOAD_EXTENSION) ? explode(',', FM_UPLOAD_EXTENSION) : false; + $ext = strtolower(pathinfo($fileinfo->name, PATHINFO_EXTENSION)); + $isFileAllowed = ($allowed) ? in_array($ext, $allowed) : true; + + function event_callback ($message) { + global $callback; + echo json_encode($message); + } + + function get_file_path () { + global $path, $fileinfo, $temp_file; + return $path."/".basename($fileinfo->name); + } + + $err = false; + + if(!$isFileAllowed) { + $err = array("message" => "File extension is not allowed"); + event_callback(array("fail" => $err)); + exit(); + } + + if (!$url) { + $success = false; + } else if ($use_curl) { + @$fp = fopen($temp_file, "w"); + @$ch = curl_init($url); + curl_setopt($ch, CURLOPT_NOPROGRESS, false ); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($ch, CURLOPT_FILE, $fp); + @$success = curl_exec($ch); + $curl_info = curl_getinfo($ch); + if (!$success) { + $err = array("message" => curl_error($ch)); + } + @curl_close($ch); + fclose($fp); + $fileinfo->size = $curl_info["size_download"]; + $fileinfo->type = $curl_info["content_type"]; + } else { + $ctx = stream_context_create(); + @$success = copy($url, $temp_file, $ctx); + if (!$success) { + $err = error_get_last(); + } + } + + if ($success) { + $success = rename($temp_file, get_file_path()); + } + + if ($success) { + event_callback(array("done" => $fileinfo)); + } else { + unlink($temp_file); + if (!$err) { + $err = array("message" => "Invalid url parameter"); + } + event_callback(array("fail" => $err)); + } + } + + exit(); +} + +// Delete file / folder +if (isset($_GET['del']) && !FM_READONLY) { + $del = str_replace( '/', '', fm_clean_path( $_GET['del'] ) ); + if ($del != '' && $del != '..' && $del != '.') { + $path = FM_ROOT_PATH; + if (FM_PATH != '') { + $path .= '/' . FM_PATH; + } + $is_dir = is_dir($path . '/' . $del); + if (fm_rdelete($path . '/' . $del)) { + $msg = $is_dir ? 'Folder %s deleted' : 'File %s deleted'; + fm_set_msg(sprintf($msg, fm_enc($del))); + } else { + $msg = $is_dir ? 'Folder %s not deleted' : 'File %s not deleted'; + fm_set_msg(sprintf($msg, fm_enc($del)), 'error'); + } + } else { + fm_set_msg('Invalid file or folder name', 'error'); + } + fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH)); +} + +// Create folder +if (isset($_GET['new']) && isset($_GET['type']) && !FM_READONLY) { + $type = $_GET['type']; + $new = str_replace( '/', '', fm_clean_path( strip_tags( $_GET['new'] ) ) ); + if (fm_isvalid_filename($new) && $new != '' && $new != '..' && $new != '.') { + $path = FM_ROOT_PATH; + if (FM_PATH != '') { + $path .= '/' . FM_PATH; + } + if ($_GET['type'] == "file") { + if (!file_exists($path . '/' . $new)) { + if(fm_is_valid_ext($new)) { + @fopen($path . '/' . $new, 'w') or die('Cannot open file: ' . $new); + fm_set_msg(sprintf(lng('File').' %s '.lng('Created'), fm_enc($new))); + } else { + fm_set_msg('File extension is not allowed', 'error'); + } + } else { + fm_set_msg(sprintf('File %s already exists', fm_enc($new)), 'alert'); + } + } else { + if (fm_mkdir($path . '/' . $new, false) === true) { + fm_set_msg(sprintf(lng('Folder').' %s '.lng('Created'), $new)); + } elseif (fm_mkdir($path . '/' . $new, false) === $path . '/' . $new) { + fm_set_msg(sprintf('Folder %s already exists', fm_enc($new)), 'alert'); + } else { + fm_set_msg(sprintf('Folder %s not created', fm_enc($new)), 'error'); + } + } + } else { + fm_set_msg('Invalid characters in file or folder name', 'error'); + } + fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH)); +} + +// Copy folder / file +if (isset($_GET['copy'], $_GET['finish']) && !FM_READONLY) { + // from + $copy = $_GET['copy']; + $copy = fm_clean_path($copy); + // empty path + if ($copy == '') { + fm_set_msg('Source path not defined', 'error'); + fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH)); + } + // abs path from + $from = FM_ROOT_PATH . '/' . $copy; + // abs path to + $dest = FM_ROOT_PATH; + if (FM_PATH != '') { + $dest .= '/' . FM_PATH; + } + $dest .= '/' . basename($from); + // move? + $move = isset($_GET['move']); + // copy/move/duplicate + if ($from != $dest) { + $msg_from = trim(FM_PATH . '/' . basename($from), '/'); + if ($move) { // Move and to != from so just perform move + $rename = fm_rename($from, $dest); + if ($rename) { + fm_set_msg(sprintf('Moved from %s to %s', fm_enc($copy), fm_enc($msg_from))); + } elseif ($rename === null) { + fm_set_msg('File or folder with this path already exists', 'alert'); + + } else { + fm_set_msg(sprintf('Error while moving from %s to %s', fm_enc($copy), fm_enc($msg_from)), 'error'); + } + } else { // Not move and to != from so copy with original name + if (fm_rcopy($from, $dest)) { + fm_set_msg(sprintf('Copied from %s to %s', fm_enc($copy), fm_enc($msg_from))); + } else { + fm_set_msg(sprintf('Error while copying from %s to %s', fm_enc($copy), fm_enc($msg_from)), 'error'); + } + } + } else { + if (!$move){ //Not move and to = from so duplicate + $msg_from = trim(FM_PATH . '/' . basename($from), '/'); + $fn_parts = pathinfo($from); + $extension_suffix = ''; + if(!is_dir($from)){ + $extension_suffix = '.'.$fn_parts['extension']; + } + //Create new name for duplicate + $fn_duplicate = $fn_parts['dirname'].'/'.$fn_parts['filename'].'-'.date('YmdHis').$extension_suffix; + $loop_count = 0; + $max_loop = 1000; + // Check if a file with the duplicate name already exists, if so, make new name (edge case...) + while(file_exists($fn_duplicate) & $loop_count < $max_loop){ + $fn_parts = pathinfo($fn_duplicate); + $fn_duplicate = $fn_parts['dirname'].'/'.$fn_parts['filename'].'-copy'.$extension_suffix; + $loop_count++; + } + if (fm_rcopy($from, $fn_duplicate, False)) { + fm_set_msg(sprintf('Copyied from %s to %s', fm_enc($copy), fm_enc($fn_duplicate))); + } else { + fm_set_msg(sprintf('Error while copying from %s to %s', fm_enc($copy), fm_enc($fn_duplicate)), 'error'); + } + } + else{ + fm_set_msg('Paths must be not equal', 'alert'); + } + } + fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH)); +} + +// Mass copy files/ folders +if (isset($_POST['file'], $_POST['copy_to'], $_POST['finish']) && !FM_READONLY) { + // from + $path = FM_ROOT_PATH; + if (FM_PATH != '') { + $path .= '/' . FM_PATH; + } + // to + $copy_to_path = FM_ROOT_PATH; + $copy_to = fm_clean_path($_POST['copy_to']); + if ($copy_to != '') { + $copy_to_path .= '/' . $copy_to; + } + if ($path == $copy_to_path) { + fm_set_msg('Paths must be not equal', 'alert'); + fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH)); + } + if (!is_dir($copy_to_path)) { + if (!fm_mkdir($copy_to_path, true)) { + fm_set_msg('Unable to create destination folder', 'error'); + fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH)); + } + } + // move? + $move = isset($_POST['move']); + // copy/move + $errors = 0; + $files = $_POST['file']; + if (is_array($files) && count($files)) { + foreach ($files as $f) { + if ($f != '') { + // abs path from + $from = $path . '/' . $f; + // abs path to + $dest = $copy_to_path . '/' . $f; + // do + if ($move) { + $rename = fm_rename($from, $dest); + if ($rename === false) { + $errors++; + } + } else { + if (!fm_rcopy($from, $dest)) { + $errors++; + } + } + } + } + if ($errors == 0) { + $msg = $move ? 'Selected files and folders moved' : 'Selected files and folders copied'; + fm_set_msg($msg); + } else { + $msg = $move ? 'Error while moving items' : 'Error while copying items'; + fm_set_msg($msg, 'error'); + } + } else { + fm_set_msg('Nothing selected', 'alert'); + } + fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH)); +} + +// Rename +if (isset($_GET['ren'], $_GET['to']) && !FM_READONLY) { + // old name + $old = $_GET['ren']; + $old = fm_clean_path($old); + $old = str_replace('/', '', $old); + // new name + $new = $_GET['to']; + $new = fm_clean_path(strip_tags($new)); + $new = str_replace('/', '', $new); + // path + $path = FM_ROOT_PATH; + if (FM_PATH != '') { + $path .= '/' . FM_PATH; + } + // rename + if (fm_isvalid_filename($new) && $old != '' && $new != '') { + if (fm_rename($path . '/' . $old, $path . '/' . $new)) { + fm_set_msg(sprintf('Renamed from %s to %s', fm_enc($old), fm_enc($new))); + } else { + fm_set_msg(sprintf('Error while renaming from %s to %s', fm_enc($old), fm_enc($new)), 'error'); + } + } else { + fm_set_msg('Invalid characters in file name', 'error'); + } + fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH)); +} + +// Download +if (isset($_GET['dl'])) { + $dl = $_GET['dl']; + $dl = fm_clean_path($dl); + $dl = str_replace('/', '', $dl); + $path = FM_ROOT_PATH; + if (FM_PATH != '') { + $path .= '/' . FM_PATH; + } + if ($dl != '' && is_file($path . '/' . $dl)) { + fm_download_file($path . '/' . $dl, $dl, 1024); + exit; + } else { + fm_set_msg('File not found', 'error'); + fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH)); + } +} + +// Upload +if (!empty($_FILES) && !FM_READONLY) { + $override_file_name = false; + $f = $_FILES; + $path = FM_ROOT_PATH; + $ds = DIRECTORY_SEPARATOR; + if (FM_PATH != '') { + $path .= '/' . FM_PATH; + } + + $errors = 0; + $uploads = 0; + $allowed = (FM_UPLOAD_EXTENSION) ? explode(',', FM_UPLOAD_EXTENSION) : false; + $response = array ( + 'status' => 'error', + 'info' => 'Oops! Try again' + ); + + $filename = $f['file']['name']; + $tmp_name = $f['file']['tmp_name']; + $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION)); + $isFileAllowed = ($allowed) ? in_array($ext, $allowed) : true; + + $targetPath = $path . $ds; + if ( is_writable($targetPath) ) { + $fullPath = $path . '/' . $_REQUEST['fullpath']; + $folder = substr($fullPath, 0, strrpos($fullPath, "/")); + + if(file_exists ($fullPath) && !$override_file_name) { + $ext_1 = $ext ? '.'.$ext : ''; + $fullPath = str_replace($ext_1, '', $fullPath) .'_'. date('ymdHis'). $ext_1; + } + + if (!is_dir($folder)) { + $old = umask(0); + mkdir($folder, 0777, true); + umask($old); + } + + if (empty($f['file']['error']) && !empty($tmp_name) && $tmp_name != 'none' && $isFileAllowed) { + if (move_uploaded_file($tmp_name, $fullPath)) { + // Be sure that the file has been uploaded + if ( file_exists($fullPath) ) { + $response = array ( + 'status' => 'success', + 'info' => "file upload successful" + ); + } else { + $response = array ( + 'status' => 'error', + 'info' => 'Couldn\'t upload the requested file.' + ); + } + } else { + $response = array ( + 'status' => 'error', + 'info' => "Error while uploading files. Uploaded files $uploads", + ); + } + } + } else { + $response = array ( + 'status' => 'error', + 'info' => 'The specified folder for upload isn\'t writeable.' + ); + } + // Return the response + echo json_encode($response); + exit(); +} + +// Mass deleting +if (isset($_POST['group'], $_POST['delete']) && !FM_READONLY) { + $path = FM_ROOT_PATH; + if (FM_PATH != '') { + $path .= '/' . FM_PATH; + } + + $errors = 0; + $files = $_POST['file']; + if (is_array($files) && count($files)) { + foreach ($files as $f) { + if ($f != '') { + $new_path = $path . '/' . $f; + if (!fm_rdelete($new_path)) { + $errors++; + } + } + } + if ($errors == 0) { + fm_set_msg('Selected files and folder deleted'); + } else { + fm_set_msg('Error while deleting items', 'error'); + } + } else { + fm_set_msg('Nothing selected', 'alert'); + } + + fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH)); +} + +// Pack files +if (isset($_POST['group']) && (isset($_POST['zip']) || isset($_POST['tar'])) && !FM_READONLY) { + $path = FM_ROOT_PATH; + $ext = 'zip'; + if (FM_PATH != '') { + $path .= '/' . FM_PATH; + } + + //set pack type + $ext = isset($_POST['tar']) ? 'tar' : 'zip'; + + + if (($ext == "zip" && !class_exists('ZipArchive')) || ($ext == "tar" && !class_exists('PharData'))) { + fm_set_msg('Operations with archives are not available', 'error'); + fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH)); + } + + $files = $_POST['file']; + if (!empty($files)) { + chdir($path); + + if (count($files) == 1) { + $one_file = reset($files); + $one_file = basename($one_file); + $zipname = $one_file . '_' . date('ymd_His') . '.'.$ext; + } else { + $zipname = 'archive_' . date('ymd_His') . '.'.$ext; + } + + if($ext == 'zip') { + $zipper = new FM_Zipper(); + $res = $zipper->create($zipname, $files); + } elseif ($ext == 'tar') { + $tar = new FM_Zipper_Tar(); + $res = $tar->create($zipname, $files); + } + + if ($res) { + fm_set_msg(sprintf('Archive %s created', fm_enc($zipname))); + } else { + fm_set_msg('Archive not created', 'error'); + } + } else { + fm_set_msg('Nothing selected', 'alert'); + } + + fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH)); +} + +// Unpack +if (isset($_GET['unzip']) && !FM_READONLY) { + $unzip = $_GET['unzip']; + $unzip = fm_clean_path($unzip); + $unzip = str_replace('/', '', $unzip); + $isValid = false; + + $path = FM_ROOT_PATH; + if (FM_PATH != '') { + $path .= '/' . FM_PATH; + } + + if ($unzip != '' && is_file($path . '/' . $unzip)) { + $zip_path = $path . '/' . $unzip; + $ext = pathinfo($zip_path, PATHINFO_EXTENSION); + $isValid = true; + } else { + fm_set_msg('File not found', 'error'); + } + + + if (($ext == "zip" && !class_exists('ZipArchive')) || ($ext == "tar" && !class_exists('PharData'))) { + fm_set_msg('Operations with archives are not available', 'error'); + fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH)); + } + + if ($isValid) { + //to folder + $tofolder = ''; + if (isset($_GET['tofolder'])) { + $tofolder = pathinfo($zip_path, PATHINFO_FILENAME); + if (fm_mkdir($path . '/' . $tofolder, true)) { + $path .= '/' . $tofolder; + } + } + + if($ext == "zip") { + $zipper = new FM_Zipper(); + $res = $zipper->unzip($zip_path, $path); + } elseif ($ext == "tar") { + try { + $gzipper = new PharData($zip_path); + if (@$gzipper->extractTo($path,null, true)) { + $res = true; + } else { + $res = false; + } + } catch (Exception $e) { + //TODO:: need to handle the error + $res = true; + } + } + + if ($res) { + fm_set_msg('Archive unpacked'); + } else { + fm_set_msg('Archive not unpacked', 'error'); + } + + } else { + fm_set_msg('File not found', 'error'); + } + fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH)); +} + +// Change Perms (not for Windows) +if (isset($_POST['chmod']) && !FM_READONLY && !FM_IS_WIN) { + $path = FM_ROOT_PATH; + if (FM_PATH != '') { + $path .= '/' . FM_PATH; + } + + $file = $_POST['chmod']; + $file = fm_clean_path($file); + $file = str_replace('/', '', $file); + if ($file == '' || (!is_file($path . '/' . $file) && !is_dir($path . '/' . $file))) { + fm_set_msg('File not found', 'error'); + fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH)); + } + + $mode = 0; + if (!empty($_POST['ur'])) { + $mode |= 0400; + } + if (!empty($_POST['uw'])) { + $mode |= 0200; + } + if (!empty($_POST['ux'])) { + $mode |= 0100; + } + if (!empty($_POST['gr'])) { + $mode |= 0040; + } + if (!empty($_POST['gw'])) { + $mode |= 0020; + } + if (!empty($_POST['gx'])) { + $mode |= 0010; + } + if (!empty($_POST['or'])) { + $mode |= 0004; + } + if (!empty($_POST['ow'])) { + $mode |= 0002; + } + if (!empty($_POST['ox'])) { + $mode |= 0001; + } + + if (@chmod($path . '/' . $file, $mode)) { + fm_set_msg('Permissions changed'); + } else { + fm_set_msg('Permissions not changed', 'error'); + } + + fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH)); +} + +/*************************** /ACTIONS ***************************/ + +// get current path +$path = FM_ROOT_PATH; +if (FM_PATH != '') { + $path .= '/' . FM_PATH; +} + +// check path +if (!is_dir($path)) { + fm_redirect(FM_SELF_URL . '?p='); +} + +// get parent folder +$parent = fm_get_parent_path(FM_PATH); + +$objects = is_readable($path) ? scandir($path) : array(); +$folders = array(); +$files = array(); +$current_path = array_slice(explode("/",$path), -1)[0]; +if (is_array($objects) && fm_is_exclude_items($current_path)) { + foreach ($objects as $file) { + if ($file == '.' || $file == '..') { + continue; + } + if (!FM_SHOW_HIDDEN && substr($file, 0, 1) === '.') { + continue; + } + $new_path = $path . '/' . $file; + if (@is_file($new_path) && fm_is_exclude_items($file)) { + $files[] = $file; + } elseif (@is_dir($new_path) && $file != '.' && $file != '..' && fm_is_exclude_items($file)) { + $folders[] = $file; + } + } +} + +if (!empty($files)) { + natcasesort($files); +} +if (!empty($folders)) { + natcasesort($folders); +} + +// upload form +if (isset($_GET['upload']) && !FM_READONLY) { + fm_show_header(); // HEADER + fm_show_nav_path(FM_PATH); // current path + //get the allowed file extensions + function getUploadExt() { + $extArr = explode(',', FM_UPLOAD_EXTENSION); + if(FM_UPLOAD_EXTENSION && $extArr) { + array_walk($extArr, function(&$x) {$x = ".$x";}); + return implode(',', $extArr); + } + return ''; + } + ?> + + +
        + +
        +
        + +
        +
        +

        + + : +

        + +
        + + +
        + +
        +
        + + +
        +
        +
        + + + +
        +
        +
        +
        +
        +
        +
        + + + ' . PHP_EOL; + } + ?> +

        : , ', $copy_files) ?>

        +

        :
        + + / +

        +

        +

        +   + +

        + +
        +
        +
        + +
        +

        Copying

        +

        + Source path:
        + Destination folder: +

        +

        + Copy   + Move   + Cancel +

        +

        Select folder

        + +
        + + +
        +
        +
        + + +
        +
        +
        + +
        + +
        + +
        +
        + +
        + +
        +
        + + +
        +
        +
        + +
        + +
        +
        + + +
        +
        +
        + +
        + +
        +
        + + +
        +
        +
        + +
        + +
        +
        + + +
        +
        +
        + +
        +
        + +
        +
        + +
        +
        +
        +
        + + +
        +
        +
        + + +
        +
        +
        +
        +

        Netcloud Learning Manager

        +

        Provides learning videos for internal use.

        +

        by Netcloud AG

        +
        + +
        + +
        +
        +
        + +
        +
        + +

        ""

        +

        + Full path:
        + File size:
        + MIME-type:
        + + Files in archive:
        + Total size:
        + Size in archive:
        + Compression: %
        + '; + } + // Text info + if ($is_text) { + $is_utf8 = fm_is_utf8($content); + if (function_exists('iconv')) { + if (!$is_utf8) { + $content = iconv(FM_ICONV_INPUT_ENC, 'UTF-8//IGNORE', $content); + } + } + echo 'Charset: ' . ($is_utf8 ? 'utf-8' : '8 bit') . '
        '; + } + ?> +

        +

        +   + +   + +   + +   + + +   + +   + + +

        + '; + } else if($online_viewer == 'microsoft') { + echo ''; + } + } elseif ($is_zip) { + // ZIP content + if ($filenames !== false) { + echo ''; + foreach ($filenames as $fn) { + if ($fn['folder']) { + echo '' . fm_enc($fn['name']) . '
        '; + } else { + echo $fn['name'] . ' (' . fm_get_filesize($fn['filesize']) . ')
        '; + } + } + echo '
        '; + } else { + echo '

        Error while fetching archive info

        '; + } + } elseif ($is_image) { + // Image content + if (in_array($ext, array('gif', 'jpg', 'jpeg', 'png', 'bmp', 'ico', 'svg'))) { + echo '

        '; + } + } elseif ($is_audio) { + // Audio content + echo '

        '; + } elseif ($is_video) { + // Video content + echo '
        '; + } elseif ($is_text) { + if (FM_USE_HIGHLIGHTJS) { + // highlight + $hljs_classes = array( + 'shtml' => 'xml', + 'htaccess' => 'apache', + 'phtml' => 'php', + 'lock' => 'json', + 'svg' => 'xml', + ); + $hljs_class = isset($hljs_classes[$ext]) ? 'lang-' . $hljs_classes[$ext] : 'lang-' . $ext; + if (empty($ext) || in_array(strtolower($file), fm_get_text_names()) || preg_match('#\.min\.(css|js)$#i', $file)) { + $hljs_class = 'nohighlight'; + } + $content = '
        ' . fm_enc($content) . '
        '; + } elseif (in_array($ext, array('php', 'php4', 'php5', 'phtml', 'phps'))) { + // php highlight + $content = highlight_string($content, true); + } else { + $content = '
        ' . fm_enc($content) . '
        '; + } + echo $content; + } + ?> +
        +
        + +
        +
        +
        + +
        +
        + + + + + + + + + + + +
        +
        + ' . htmlspecialchars($content) . ''; + } elseif ($is_text) { + echo '
        ' . htmlspecialchars($content) . '
        '; + } else { + fm_set_msg('FILE EXTENSION HAS NOT SUPPORTED', 'error'); + } + ?> +
        + +
        +
        +
        + +
        +
        +

        + Full path:
        +

        +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + +

        +   + +

        +
        +
        +
        +
        + +
        + + +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + '?'); + $group = array('name' => '?'); + } + ?> + + + + + + + + + + + + + '?'); + $group = array('name' => '?'); + } + ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        +
        + + +
        +
        ..
        +
        + + +
        +
        +
        + ' . readlink($path . '/' . $f) . '' : '') ?>
        +
        "> + + + + + + + + +
        +
        + + +
        +
        +
        + + + + + + + + + ' . readlink($path . '/' . $f) . '' : '') ?> +
        +
        "> + + + + + + + + + + + +
        + '.fm_get_filesize($all_files_size).'' ?> + '.$num_files.'' ?> + '.$num_folders.'' ?> + '.fm_get_filesize(@memory_get_usage(true)).'' ?> + '.fm_get_filesize(@disk_free_space($path)) .' '.lng('FreeOf').' '.fm_get_filesize(@disk_total_space($path)).''; ?> +
        +
        + +
        + +
        + +
        + + +
        + +
        + += $time1 && $upd) { + return false; + } + } + $ok = copy($f1, $f2); + if ($ok) { + touch($f2, $time1); + } + return $ok; +} + +/** + * Get mime type + * @param string $file_path + * @return mixed|string + */ +function fm_get_mime_type($file_path) +{ + if (function_exists('finfo_open')) { + $finfo = finfo_open(FILEINFO_MIME_TYPE); + $mime = finfo_file($finfo, $file_path); + finfo_close($finfo); + return $mime; + } elseif (function_exists('mime_content_type')) { + return mime_content_type($file_path); + } elseif (!stristr(ini_get('disable_functions'), 'shell_exec')) { + $file = escapeshellarg($file_path); + $mime = shell_exec('file -bi ' . $file); + return $mime; + } else { + return '--'; + } +} + +/** + * HTTP Redirect + * @param string $url + * @param int $code + */ +function fm_redirect($url, $code = 302) +{ + header('Location: ' . $url, true, $code); + exit; +} + +/** + * Path traversal prevention and clean the url + * It replaces (consecutive) occurrences of / and \\ with whatever is in DIRECTORY_SEPARATOR, and processes /. and /.. fine. + * @param $path + * @return string + */ +function get_absolute_path($path) { + $path = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $path); + $parts = array_filter(explode(DIRECTORY_SEPARATOR, $path), 'strlen'); + $absolutes = array(); + foreach ($parts as $part) { + if ('.' == $part) continue; + if ('..' == $part) { + array_pop($absolutes); + } else { + $absolutes[] = $part; + } + } + return implode(DIRECTORY_SEPARATOR, $absolutes); +} + +/** + * Clean path + * @param string $path + * @return string + */ +function fm_clean_path($path, $trim = true) +{ + $path = $trim ? trim($path) : $path; + $path = trim($path, '\\/'); + $path = str_replace(array('../', '..\\'), '', $path); + $path = get_absolute_path($path); + if ($path == '..') { + $path = ''; + } + return str_replace('\\', '/', $path); +} + +/** + * Get parent path + * @param string $path + * @return bool|string + */ +function fm_get_parent_path($path) +{ + $path = fm_clean_path($path); + if ($path != '') { + $array = explode('/', $path); + if (count($array) > 1) { + $array = array_slice($array, 0, -1); + return implode('/', $array); + } + return ''; + } + return false; +} + +/** + * Check file is in exclude list + * @param string $file + * @return bool + */ +function fm_is_exclude_items($file) { + $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION)); + if(!in_array($file, FM_EXCLUDE_ITEMS) && !in_array("*.$ext", FM_EXCLUDE_ITEMS)) { + return true; + } + return false; +} + +/** + * get language translations from json file + * @param int $tr + * @return array + */ +function fm_get_translations($tr) { + try { + $content = @file_get_contents('translation.json'); + if($content !== FALSE) { + $lng = json_decode($content, TRUE); + global $lang_list; + foreach ($lng["language"] as $key => $value) + { + $code = $value["code"]; + $lang_list[$code] = $value["name"]; + if ($tr) + $tr[$code] = $value["translation"]; + } + return $tr; + } + + } + catch (Exception $e) { + echo $e; + } +} + +/** + * @param $file + * Recover all file sizes larger than > 2GB. + * Works on php 32bits and 64bits and supports linux + * @return int|string + */ +function fm_get_size($file) +{ + static $iswin; + static $isdarwin; + if (!isset($iswin)) { + $iswin = (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN'); + } + if (!isset($isdarwin)) { + $isdarwin = (strtoupper(substr(PHP_OS, 0)) == "DARWIN"); + } + + static $exec_works; + if (!isset($exec_works)) { + $exec_works = (function_exists('exec') && !ini_get('safe_mode') && @exec('echo EXEC') == 'EXEC'); + } + + // try a shell command + if ($exec_works) { + $arg = escapeshellarg($file); + $cmd = ($iswin) ? "for %F in (\"$file\") do @echo %~zF" : ($isdarwin ? "stat -f%z $arg" : "stat -c%s $arg"); + @exec($cmd, $output); + if (is_array($output) && ctype_digit($size = trim(implode("\n", $output)))) { + return $size; + } + } + + // try the Windows COM interface + if ($iswin && class_exists("COM")) { + try { + $fsobj = new COM('Scripting.FileSystemObject'); + $f = $fsobj->GetFile( realpath($file) ); + $size = $f->Size; + } catch (Exception $e) { + $size = null; + } + if (ctype_digit($size)) { + return $size; + } + } + + // if all else fails + return filesize($file); +} + +/** + * Get nice filesize + * @param int $size + * @return string + */ +function fm_get_filesize($size) +{ + $size = (float) $size; + $units = array('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'); + $power = $size > 0 ? floor(log($size, 1024)) : 0; + return sprintf('%s %s', round($size / pow(1024, $power), 2), $units[$power]); +} + +/** + * Get director total size + * @param string $directory + * @return int + */ +function fm_get_directorysize($directory) { + global $calc_folder; + if ($calc_folder==true) { // Slower output + $size = 0; $count= 0; $dirCount= 0; + foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory)) as $file) + if ($file->isFile()) + { $size+=$file->getSize(); + $count++; + } + else if ($file->isDir()) { $dirCount++; } + // return [$size, $count, $dirCount]; + return $size; + } + else return 'Folder'; // Quick output +} + +/** + * Get info about zip archive + * @param string $path + * @return array|bool + */ +function fm_get_zif_info($path, $ext) { + if ($ext == 'zip' && function_exists('zip_open')) { + $arch = zip_open($path); + if ($arch) { + $filenames = array(); + while ($zip_entry = zip_read($arch)) { + $zip_name = zip_entry_name($zip_entry); + $zip_folder = substr($zip_name, -1) == '/'; + $filenames[] = array( + 'name' => $zip_name, + 'filesize' => zip_entry_filesize($zip_entry), + 'compressed_size' => zip_entry_compressedsize($zip_entry), + 'folder' => $zip_folder + //'compression_method' => zip_entry_compressionmethod($zip_entry), + ); + } + zip_close($arch); + return $filenames; + } + } elseif($ext == 'tar' && class_exists('PharData')) { + $archive = new PharData($path); + $filenames = array(); + foreach(new RecursiveIteratorIterator($archive) as $file) { + $parent_info = $file->getPathInfo(); + $zip_name = str_replace("phar://".$path, '', $file->getPathName()); + $zip_name = substr($zip_name, ($pos = strpos($zip_name, '/')) !== false ? $pos + 1 : 0); + $zip_folder = $parent_info->getFileName(); + $zip_info = new SplFileInfo($file); + $filenames[] = array( + 'name' => $zip_name, + 'filesize' => $zip_info->getSize(), + 'compressed_size' => $file->getCompressedSize(), + 'folder' => $zip_folder + ); + } + return $filenames; + } + return false; +} + +/** + * Encode html entities + * @param string $text + * @return string + */ +function fm_enc($text) +{ + return htmlspecialchars($text, ENT_QUOTES, 'UTF-8'); +} + +/** + * Prevent XSS attacks + * @param string $text + * @return string + */ +function fm_isvalid_filename($text) { + return (strpbrk($text, '/?%*:|"<>') === FALSE) ? true : false; +} + +/** + * Save message in session + * @param string $msg + * @param string $status + */ +function fm_set_msg($msg, $status = 'ok') +{ + $_SESSION[FM_SESSION_ID]['message'] = $msg; + $_SESSION[FM_SESSION_ID]['status'] = $status; +} + +/** + * Check if string is in UTF-8 + * @param string $string + * @return int + */ +function fm_is_utf8($string) +{ + return preg_match('//u', $string); +} + +/** + * Convert file name to UTF-8 in Windows + * @param string $filename + * @return string + */ +function fm_convert_win($filename) +{ + if (FM_IS_WIN && function_exists('iconv')) { + $filename = iconv(FM_ICONV_INPUT_ENC, 'UTF-8//IGNORE', $filename); + } + return $filename; +} + +/** + * @param $obj + * @return array + */ +function fm_object_to_array($obj) +{ + if (!is_object($obj) && !is_array($obj)) { + return $obj; + } + if (is_object($obj)) { + $obj = get_object_vars($obj); + } + return array_map('fm_object_to_array', $obj); +} + +/** + * Get CSS classname for file + * @param string $path + * @return string + */ +function fm_get_file_icon_class($path) +{ + // get extension + $ext = strtolower(pathinfo($path, PATHINFO_EXTENSION)); + + switch ($ext) { + case 'ico': + case 'gif': + case 'jpg': + case 'jpeg': + case 'jpc': + case 'jp2': + case 'jpx': + case 'xbm': + case 'wbmp': + case 'png': + case 'bmp': + case 'tif': + case 'tiff': + case 'svg': + $img = 'fa fa-picture-o'; + break; + case 'passwd': + case 'ftpquota': + case 'sql': + case 'js': + case 'json': + case 'sh': + case 'config': + case 'twig': + case 'tpl': + case 'md': + case 'gitignore': + case 'c': + case 'cpp': + case 'cs': + case 'py': + case 'map': + case 'lock': + case 'dtd': + $img = 'fa fa-file-code-o'; + break; + case 'txt': + case 'ini': + case 'conf': + case 'log': + case 'htaccess': + $img = 'fa fa-file-text-o'; + break; + case 'css': + case 'less': + case 'sass': + case 'scss': + $img = 'fa fa-css3'; + break; + case 'zip': + case 'rar': + case 'gz': + case 'tar': + case '7z': + $img = 'fa fa-file-archive-o'; + break; + case 'php': + case 'php4': + case 'php5': + case 'phps': + case 'phtml': + $img = 'fa fa-code'; + break; + case 'htm': + case 'html': + case 'shtml': + case 'xhtml': + $img = 'fa fa-html5'; + break; + case 'xml': + case 'xsl': + $img = 'fa fa-file-excel-o'; + break; + case 'wav': + case 'mp3': + case 'mp2': + case 'm4a': + case 'aac': + case 'ogg': + case 'oga': + case 'wma': + case 'mka': + case 'flac': + case 'ac3': + case 'tds': + $img = 'fa fa-music'; + break; + case 'm3u': + case 'm3u8': + case 'pls': + case 'cue': + $img = 'fa fa-headphones'; + break; + case 'avi': + case 'mpg': + case 'mpeg': + case 'mp4': + case 'm4v': + case 'flv': + case 'f4v': + case 'ogm': + case 'ogv': + case 'mov': + case 'mkv': + case '3gp': + case 'asf': + case 'wmv': + $img = 'fa fa-file-video-o'; + break; + case 'eml': + case 'msg': + $img = 'fa fa-envelope-o'; + break; + case 'xls': + case 'xlsx': + case 'ods': + $img = 'fa fa-file-excel-o'; + break; + case 'csv': + $img = 'fa fa-file-text-o'; + break; + case 'bak': + $img = 'fa fa-clipboard'; + break; + case 'doc': + case 'docx': + case 'odt': + $img = 'fa fa-file-word-o'; + break; + case 'ppt': + case 'pptx': + $img = 'fa fa-file-powerpoint-o'; + break; + case 'ttf': + case 'ttc': + case 'otf': + case 'woff': + case 'woff2': + case 'eot': + case 'fon': + $img = 'fa fa-font'; + break; + case 'pdf': + $img = 'fa fa-file-pdf-o'; + break; + case 'psd': + case 'ai': + case 'eps': + case 'fla': + case 'swf': + $img = 'fa fa-file-image-o'; + break; + case 'exe': + case 'msi': + $img = 'fa fa-file-o'; + break; + case 'bat': + $img = 'fa fa-terminal'; + break; + default: + $img = 'fa fa-info-circle'; + } + + return $img; +} + +/** + * Get image files extensions + * @return array + */ +function fm_get_image_exts() +{ + return array('ico', 'gif', 'jpg', 'jpeg', 'jpc', 'jp2', 'jpx', 'xbm', 'wbmp', 'png', 'bmp', 'tif', 'tiff', 'psd', 'svg'); +} + +/** + * Get video files extensions + * @return array + */ +function fm_get_video_exts() +{ + return array('avi', 'webm', 'wmv', 'mp4', 'm4v', 'ogm', 'ogv', 'mov', 'mkv'); +} + +/** + * Get audio files extensions + * @return array + */ +function fm_get_audio_exts() +{ + return array('wav', 'mp3', 'ogg', 'm4a'); +} + +/** + * Get text file extensions + * @return array + */ +function fm_get_text_exts() +{ + return array( + 'txt', 'css', 'ini', 'conf', 'log', 'htaccess', 'passwd', 'ftpquota', 'sql', 'js', 'json', 'sh', 'config', + 'php', 'php4', 'php5', 'phps', 'phtml', 'htm', 'html', 'shtml', 'xhtml', 'xml', 'xsl', 'm3u', 'm3u8', 'pls', 'cue', + 'eml', 'msg', 'csv', 'bat', 'twig', 'tpl', 'md', 'gitignore', 'less', 'sass', 'scss', 'c', 'cpp', 'cs', 'py', + 'map', 'lock', 'dtd', 'svg', 'scss', 'asp', 'aspx', 'asx', 'asmx', 'ashx', 'jsx', 'jsp', 'jspx', 'cfm', 'cgi' + ); +} + +/** + * Get mime types of text files + * @return array + */ +function fm_get_text_mimes() +{ + return array( + 'application/xml', + 'application/javascript', + 'application/x-javascript', + 'image/svg+xml', + 'message/rfc822', + ); +} + +/** + * Get file names of text files w/o extensions + * @return array + */ +function fm_get_text_names() +{ + return array( + 'license', + 'readme', + 'authors', + 'contributors', + 'changelog', + ); +} + +/** + * Get online docs viewer supported files extensions + * @return array + */ +function fm_get_onlineViewer_exts() +{ + return array('doc', 'docx', 'xls', 'xlsx', 'pdf', 'ppt', 'pptx', 'ai', 'psd', 'dxf', 'xps', 'rar', 'odt', 'ods'); +} + +function fm_get_file_mimes($extension) +{ + $fileTypes['swf'] = 'application/x-shockwave-flash'; + $fileTypes['pdf'] = 'application/pdf'; + $fileTypes['exe'] = 'application/octet-stream'; + $fileTypes['zip'] = 'application/zip'; + $fileTypes['doc'] = 'application/msword'; + $fileTypes['xls'] = 'application/vnd.ms-excel'; + $fileTypes['ppt'] = 'application/vnd.ms-powerpoint'; + $fileTypes['gif'] = 'image/gif'; + $fileTypes['png'] = 'image/png'; + $fileTypes['jpeg'] = 'image/jpg'; + $fileTypes['jpg'] = 'image/jpg'; + $fileTypes['rar'] = 'application/rar'; + + $fileTypes['ra'] = 'audio/x-pn-realaudio'; + $fileTypes['ram'] = 'audio/x-pn-realaudio'; + $fileTypes['ogg'] = 'audio/x-pn-realaudio'; + + $fileTypes['wav'] = 'video/x-msvideo'; + $fileTypes['wmv'] = 'video/x-msvideo'; + $fileTypes['avi'] = 'video/x-msvideo'; + $fileTypes['asf'] = 'video/x-msvideo'; + $fileTypes['divx'] = 'video/x-msvideo'; + + $fileTypes['mp3'] = 'audio/mpeg'; + $fileTypes['mp4'] = 'audio/mpeg'; + $fileTypes['mpeg'] = 'video/mpeg'; + $fileTypes['mpg'] = 'video/mpeg'; + $fileTypes['mpe'] = 'video/mpeg'; + $fileTypes['mov'] = 'video/quicktime'; + $fileTypes['swf'] = 'video/quicktime'; + $fileTypes['3gp'] = 'video/quicktime'; + $fileTypes['m4a'] = 'video/quicktime'; + $fileTypes['aac'] = 'video/quicktime'; + $fileTypes['m3u'] = 'video/quicktime'; + + $fileTypes['php'] = ['application/x-php']; + $fileTypes['html'] = ['text/html']; + $fileTypes['txt'] = ['text/plain']; + return $fileTypes[$extension]; +} + +/** + * This function scans the files and folder recursively, and return matching files + * @param string $dir + * @param string $filter + * @return json + */ + function scan($dir, $filter = '') { + $path = FM_ROOT_PATH.'/'.$dir; + if($dir) { + $ite = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)); + $rii = new RegexIterator($ite, "/(" . $filter . ")/i"); + + $files = array(); + foreach ($rii as $file) { + if (!$file->isDir()) { + $fileName = $file->getFilename(); + $location = str_replace(FM_ROOT_PATH, '', $file->getPath()); + $files[] = array( + "name" => $fileName, + "type" => "file", + "path" => $location, + ); + } + } + return $files; + } +} + +/* +Parameters: downloadFile(File Location, File Name, +max speed, is streaming +If streaming - videos will show as videos, images as images +instead of download prompt +https://stackoverflow.com/a/13821992/1164642 +*/ + +function fm_download_file($fileLocation, $fileName, $chunkSize = 1024) +{ + if (connection_status() != 0) + return (false); + $extension = pathinfo($fileName, PATHINFO_EXTENSION); + + $contentType = fm_get_file_mimes($extension); + header("Cache-Control: public"); + header("Content-Transfer-Encoding: binary\n"); + header('Content-Type: $contentType'); + + $contentDisposition = 'attachment'; + + + if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE")) { + $fileName = preg_replace('/\./', '%2e', $fileName, substr_count($fileName, '.') - 1); + header("Content-Disposition: $contentDisposition;filename=\"$fileName\""); + } else { + header("Content-Disposition: $contentDisposition;filename=\"$fileName\""); + } + + header("Accept-Ranges: bytes"); + $range = 0; + $size = filesize($fileLocation); + + if (isset($_SERVER['HTTP_RANGE'])) { + list($a, $range) = explode("=", $_SERVER['HTTP_RANGE']); + str_replace($range, "-", $range); + $size2 = $size - 1; + $new_length = $size - $range; + header("HTTP/1.1 206 Partial Content"); + header("Content-Length: $new_length"); + header("Content-Range: bytes $range$size2/$size"); + } else { + $size2 = $size - 1; + header("Content-Range: bytes 0-$size2/$size"); + header("Content-Length: " . $size); + } + + if ($size == 0) { + die('Zero byte file! Aborting download'); + } + @ini_set('magic_quotes_runtime', 0); + $fp = fopen("$fileLocation", "rb"); + + fseek($fp, $range); + + while (!feof($fp) and (connection_status() == 0)) { + set_time_limit(0); + print(@fread($fp, 1024*$chunkSize)); + flush(); + ob_flush(); + sleep(1); + } + fclose($fp); + + return ((connection_status() == 0) and !connection_aborted()); +} + +function fm_get_theme() { + $result = ''; + if(FM_THEME == "dark") { + $result = "text-white bg-dark"; + } + return $result; +} + +/** + * Class to work with zip files (using ZipArchive) + */ +class FM_Zipper +{ + private $zip; + + public function __construct() + { + $this->zip = new ZipArchive(); + } + + /** + * Create archive with name $filename and files $files (RELATIVE PATHS!) + * @param string $filename + * @param array|string $files + * @return bool + */ + public function create($filename, $files) + { + $res = $this->zip->open($filename, ZipArchive::CREATE); + if ($res !== true) { + return false; + } + if (is_array($files)) { + foreach ($files as $f) { + if (!$this->addFileOrDir($f)) { + $this->zip->close(); + return false; + } + } + $this->zip->close(); + return true; + } else { + if ($this->addFileOrDir($files)) { + $this->zip->close(); + return true; + } + return false; + } + } + + /** + * Extract archive $filename to folder $path (RELATIVE OR ABSOLUTE PATHS) + * @param string $filename + * @param string $path + * @return bool + */ + public function unzip($filename, $path) + { + $res = $this->zip->open($filename); + if ($res !== true) { + return false; + } + if ($this->zip->extractTo($path)) { + $this->zip->close(); + return true; + } + return false; + } + + /** + * Add file/folder to archive + * @param string $filename + * @return bool + */ + private function addFileOrDir($filename) + { + if (is_file($filename)) { + return $this->zip->addFile($filename); + } elseif (is_dir($filename)) { + return $this->addDir($filename); + } + return false; + } + + /** + * Add folder recursively + * @param string $path + * @return bool + */ + private function addDir($path) + { + if (!$this->zip->addEmptyDir($path)) { + return false; + } + $objects = scandir($path); + if (is_array($objects)) { + foreach ($objects as $file) { + if ($file != '.' && $file != '..') { + if (is_dir($path . '/' . $file)) { + if (!$this->addDir($path . '/' . $file)) { + return false; + } + } elseif (is_file($path . '/' . $file)) { + if (!$this->zip->addFile($path . '/' . $file)) { + return false; + } + } + } + } + return true; + } + return false; + } +} + +/** + * Class to work with Tar files (using PharData) + */ +class FM_Zipper_Tar +{ + private $tar; + + public function __construct() + { + $this->tar = null; + } + + /** + * Create archive with name $filename and files $files (RELATIVE PATHS!) + * @param string $filename + * @param array|string $files + * @return bool + */ + public function create($filename, $files) + { + $this->tar = new PharData($filename); + if (is_array($files)) { + foreach ($files as $f) { + if (!$this->addFileOrDir($f)) { + return false; + } + } + return true; + } else { + if ($this->addFileOrDir($files)) { + return true; + } + return false; + } + } + + /** + * Extract archive $filename to folder $path (RELATIVE OR ABSOLUTE PATHS) + * @param string $filename + * @param string $path + * @return bool + */ + public function unzip($filename, $path) + { + $res = $this->tar->open($filename); + if ($res !== true) { + return false; + } + if ($this->tar->extractTo($path)) { + return true; + } + return false; + } + + /** + * Add file/folder to archive + * @param string $filename + * @return bool + */ + private function addFileOrDir($filename) + { + if (is_file($filename)) { + try { + $this->tar->addFile($filename); + return true; + } catch (Exception $e) { + return false; + } + } elseif (is_dir($filename)) { + return $this->addDir($filename); + } + return false; + } + + /** + * Add folder recursively + * @param string $path + * @return bool + */ + private function addDir($path) + { + $objects = scandir($path); + if (is_array($objects)) { + foreach ($objects as $file) { + if ($file != '.' && $file != '..') { + if (is_dir($path . '/' . $file)) { + if (!$this->addDir($path . '/' . $file)) { + return false; + } + } elseif (is_file($path . '/' . $file)) { + try { + $this->tar->addFile($path . '/' . $file); + } catch (Exception $e) { + return false; + } + } + } + } + return true; + } + return false; + } +} + + + +/** + * Save Configuration + */ + class FM_Config +{ + var $data; + + function __construct() + { + global $root_path, $root_url, $CONFIG; + $fm_url = $root_url.$_SERVER["PHP_SELF"]; + $this->data = array( + 'lang' => 'en', + 'error_reporting' => true, + 'show_hidden' => true + ); + $data = false; + if (strlen($CONFIG)) { + $data = fm_object_to_array(json_decode($CONFIG)); + } else { + $msg = 'Netcloud File Manager
        Error: Cannot load configuration'; + if (substr($fm_url, -1) == '/') { + $fm_url = rtrim($fm_url, '/'); + $msg .= '
        '; + $msg .= '
        Seems like you have a trailing slash on the URL.'; + $msg .= '
        Try this link: ' . $fm_url . ''; + } + die($msg); + } + if (is_array($data) && count($data)) $this->data = $data; + else $this->save(); + } + + function save() + { + $fm_file = __FILE__; + $var_name = '$CONFIG'; + $var_value = var_export(json_encode($this->data), true); + $config_string = " + + ' . $_SESSION[FM_SESSION_ID]['message'] . '

        '; + unset($_SESSION[FM_SESSION_ID]['message']); + unset($_SESSION[FM_SESSION_ID]['status']); + } +} + +/** + * Show page header in Login Form + */ +function fm_show_header_login() +{ +$sprites_ver = '20160315'; +header("Content-Type: text/html; charset=utf-8"); +header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); +header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0"); +header("Pragma: no-cache"); + +global $lang, $root_url, $favicon_path; +?> + + + + + + + + + <?php echo fm_enc(APP_TITLE) ?> + + + + + + + +"> +
        + + +
        + + + + + + + + + + + + + + <?php echo fm_enc(APP_TITLE) ?> + + + + + + + + + + + + "> +
        + + + + + + + + + +
        + + + + + + + + + + + + + +
        + + + 'Qk04AgAAAAAAADYAAAAoAAAAEAAAABAAAAABABAAAAAAAAICAAASCwAAEgsAAAAAAAAAAAAAIQQhBCEEIQQhBCEEIQQhBCEEIQ + QhBCEEIQQhBCEEIQQhBCEEIQQhBHNO3n/ef95/vXetNSEEIQQhBCEEIQQhBCEEIQQhBCEEc07ef95/3n/ef95/1lohBCEEIQQhBCEEIQQhBCEEIQ + RzTt5/3n8hBDFG3n/efyEEIQQhBCEEIQQhBCEEIQQhBHNO3n/efyEEMUbef95/IQQhBCEEIQQhBCEEIQQhBCEErTVzTnNOIQQxRt5/3n8hBCEEIQ + QhBCEEIQQhBCEEIQQhBCEEIQQhBDFG3n/efyEEIQQhBCEEIQQhBCEEIQQhBCEEIQQxRt5/3n+cc2stIQQhBCEEIQQhBCEEIQQhBCEEIQQIIZxz3n + /ef5xzay0hBCEEIQQhBCEEIQQhBCEEIQQhBCEEIQQhBDFG3n/efyEEIQQhBCEEIQQhBCEEIQQhBK01c05zTiEEMUbef95/IQQhBCEEIQQhBCEEIQ + QhBCEEc07ef95/IQQxRt5/3n8hBCEEIQQhBCEEIQQhBCEEIQRzTt5/3n8hBDFG3n/efyEEIQQhBCEEIQQhBCEEIQQhBKUUOWfef95/3n/ef95/IQ + QhBCEEIQQhBCEEIQQhBCEEIQQhBJRW3n/ef95/3n8hBCEEIQQhBCEEIQQhBCEEIQQhBCEEIQQhBCEEIQQhBCEEIQQhBCEEIQQAAA==' + ); +} + +?> diff --git a/phpinfo.php b/phpinfo.php new file mode 100644 index 0000000..968c8df --- /dev/null +++ b/phpinfo.php @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/scan.php b/scan.php index 6ea7d2f..eae8ed1 100644 --- a/scan.php +++ b/scan.php @@ -5,22 +5,23 @@ $dir = "Home"; $response = scan($dir); // This function scans the files folder recursively, and builds a large array -function scan($dir){ +function scan($dir) +{ $files = array(); // Is there actually such a folder/file? - if(file_exists($dir)){ - - foreach(scandir($dir) as $f) { - - if(!$f || $f[0] == '.') { + if (file_exists($dir)) { + + foreach (scandir($dir) as $f) { + + if (!$f || $f[0] == '.') { continue; // Ignore hidden files } - if(is_dir($dir . '/' . $f)) { + if (is_dir($dir . '/' . $f)) { // Remove Synology Temp-Folders, if they exists! - if($f != '@eaDir') { + if ($f != '@eaDir') { // The path is a folder $files[] = array( "name" => $f, @@ -29,8 +30,7 @@ function scan($dir){ "items" => scan($dir . '/' . $f) // Recursively get the contents of the folder ); } - } - else if (is_file($dir . '/' . $f)) { + } else if (is_file($dir . '/' . $f)) { // It is a file $files[] = array( "name" => $f, @@ -40,7 +40,6 @@ function scan($dir){ ); } } - } return $files; @@ -54,4 +53,4 @@ echo json_encode(array( "type" => "folder", "path" => $dir, "items" => $response -)); \ No newline at end of file +));