├── _h5ai ├── robots.txt ├── public │ ├── images │ │ ├── fallback │ │ │ ├── file.png │ │ │ ├── folder.png │ │ │ └── folder-parent.png │ │ ├── favicon │ │ │ ├── favicon-152.png │ │ │ ├── favicon-16.png │ │ │ ├── favicon-32.png │ │ │ ├── favicon-16-32.ico │ │ │ └── favicon.svg │ │ ├── themes │ │ │ ├── default │ │ │ │ ├── aud.svg │ │ │ │ ├── vid.svg │ │ │ │ ├── folder.svg │ │ │ │ ├── x.svg │ │ │ │ ├── file.svg │ │ │ │ ├── ar.svg │ │ │ │ ├── folder-page.svg │ │ │ │ ├── txt.svg │ │ │ │ ├── folder-parent.svg │ │ │ │ ├── img.svg │ │ │ │ └── bin.svg │ │ │ ├── comity │ │ │ │ ├── txt-md.svg │ │ │ │ ├── txt-rb.svg │ │ │ │ ├── ar-apk.svg │ │ │ │ ├── txt-script.svg │ │ │ │ ├── txt-php.svg │ │ │ │ ├── txt-html.svg │ │ │ │ ├── txt-css.svg │ │ │ │ ├── txt-py.svg │ │ │ │ ├── txt-js.svg │ │ │ │ ├── x-pdf.svg │ │ │ │ ├── txt-less.svg │ │ │ │ ├── txt-rust.svg │ │ │ │ ├── ar-rpm.svg │ │ │ │ ├── ar-deb.svg │ │ │ │ └── txt-go.svg │ │ │ └── README.md │ │ └── ui │ │ │ ├── crumb.svg │ │ │ ├── sort.svg │ │ │ ├── download.svg │ │ │ ├── preview-next.svg │ │ │ ├── preview-prev.svg │ │ │ ├── preview-raw.svg │ │ │ ├── selected.svg │ │ │ ├── tree-indicator.svg │ │ │ ├── sidebar.svg │ │ │ ├── view-details.svg │ │ │ ├── back.svg │ │ │ ├── view-icons.svg │ │ │ ├── preview-fullscreen.svg │ │ │ ├── preview-no-fullscreen.svg │ │ │ ├── preview-close.svg │ │ │ ├── view-grid.svg │ │ │ ├── tree-toggle.svg │ │ │ ├── info-toggle.svg │ │ │ ├── spinner.svg │ │ │ ├── filter.svg │ │ │ ├── search.svg │ │ │ └── paypal.svg │ ├── ext │ │ └── README.md │ ├── cache │ │ └── README.md │ ├── .htaccess │ ├── index.php │ ├── login.php │ └── css │ │ └── styles.css ├── private │ ├── cache │ │ └── README.md │ ├── conf │ │ ├── l10n │ │ │ ├── sk.json │ │ │ ├── tr.json │ │ │ ├── nb.json │ │ │ ├── ro.json │ │ │ ├── sr.json │ │ │ ├── he.json │ │ │ ├── hu.json │ │ │ ├── sv.json │ │ │ ├── da.json │ │ │ ├── hi.json │ │ │ ├── af.json │ │ │ ├── fi.json │ │ │ ├── hr.json │ │ │ ├── sl.json │ │ │ ├── it.json │ │ │ ├── ja.json │ │ │ ├── pt.json │ │ │ ├── uk.json │ │ │ ├── bg.json │ │ │ ├── cs.json │ │ │ ├── el.json │ │ │ ├── ko.json │ │ │ ├── ru.json │ │ │ ├── zh-cn.json │ │ │ ├── zh-tw.json │ │ │ ├── de.json │ │ │ ├── et.json │ │ │ ├── nl.json │ │ │ ├── pl.json │ │ │ ├── lv.json │ │ │ ├── es.json │ │ │ ├── fr.json │ │ │ └── en.json │ │ ├── types.json │ │ └── options.json │ └── php │ │ ├── core │ │ ├── class-session.php │ │ ├── class-logger.php │ │ ├── class-theme.php │ │ ├── class-request.php │ │ ├── class-fallback.php │ │ ├── class-json.php │ │ ├── class-filesize.php │ │ ├── class-item.php │ │ ├── class-util.php │ │ ├── class-api.php │ │ ├── class-setup.php │ │ └── class-context.php │ │ ├── pages │ │ ├── info.php │ │ └── index.php │ │ ├── ext │ │ ├── class-search.php │ │ ├── class-custom.php │ │ ├── class-archive.php │ │ └── class-thumb.php │ │ └── class-bootstrap.php ├── README.md ├── .htaccess └── CHANGELOG.md ├── .gitattributes ├── subtovtt.sh ├── hls_general.sh ├── hls_aria2.sh └── README.md /_h5ai/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: / -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.js linguist-language=php 2 | *.css linguist-language=php 3 | *.html linguist-language=php -------------------------------------------------------------------------------- /_h5ai/public/images/fallback/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pearlulu/h5ai_dplayer/HEAD/_h5ai/public/images/fallback/file.png -------------------------------------------------------------------------------- /_h5ai/public/images/fallback/folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pearlulu/h5ai_dplayer/HEAD/_h5ai/public/images/fallback/folder.png -------------------------------------------------------------------------------- /_h5ai/public/images/favicon/favicon-152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pearlulu/h5ai_dplayer/HEAD/_h5ai/public/images/favicon/favicon-152.png -------------------------------------------------------------------------------- /_h5ai/public/images/favicon/favicon-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pearlulu/h5ai_dplayer/HEAD/_h5ai/public/images/favicon/favicon-16.png -------------------------------------------------------------------------------- /_h5ai/public/images/favicon/favicon-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pearlulu/h5ai_dplayer/HEAD/_h5ai/public/images/favicon/favicon-32.png -------------------------------------------------------------------------------- /_h5ai/public/images/favicon/favicon-16-32.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pearlulu/h5ai_dplayer/HEAD/_h5ai/public/images/favicon/favicon-16-32.ico -------------------------------------------------------------------------------- /_h5ai/public/images/fallback/folder-parent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pearlulu/h5ai_dplayer/HEAD/_h5ai/public/images/fallback/folder-parent.png -------------------------------------------------------------------------------- /_h5ai/public/images/themes/default/aud.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_h5ai/public/images/themes/default/vid.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_h5ai/public/images/themes/default/folder.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_h5ai/public/images/favicon/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_h5ai/public/images/themes/default/x.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_h5ai/public/images/themes/default/file.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_h5ai/public/images/themes/default/ar.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_h5ai/public/ext/README.md: -------------------------------------------------------------------------------- 1 | # Extensions 2 | 3 | This directory is used for additional script and style files. You have to add 4 | them manualy to the `resources` section in `_h5ai/private/conf/options.json`. 5 | -------------------------------------------------------------------------------- /_h5ai/public/images/themes/default/folder-page.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_h5ai/public/images/themes/default/txt.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_h5ai/public/images/themes/default/folder-parent.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_h5ai/public/images/themes/default/img.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_h5ai/public/images/ui/crumb.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_h5ai/public/images/ui/sort.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_h5ai/public/images/ui/download.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_h5ai/public/images/ui/preview-next.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_h5ai/public/images/ui/preview-prev.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_h5ai/public/images/ui/preview-raw.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_h5ai/public/images/ui/selected.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_h5ai/public/images/ui/tree-indicator.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_h5ai/public/images/ui/sidebar.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_h5ai/public/images/ui/view-details.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_h5ai/public/images/ui/back.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_h5ai/public/images/ui/view-icons.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_h5ai/public/cache/README.md: -------------------------------------------------------------------------------- 1 | # Cache 2 | 3 | Public cache. 4 | 5 | This directory is used for server side caching. To use caching make this 6 | directory writable for your webserver. 7 | 8 | There is no critical data in here. You can savely remove any content. This 9 | will clear the cache. 10 | -------------------------------------------------------------------------------- /_h5ai/public/images/ui/preview-fullscreen.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_h5ai/private/cache/README.md: -------------------------------------------------------------------------------- 1 | # Cache 2 | 3 | Private cache. 4 | 5 | This directory is used for server side caching. To use caching make this 6 | directory writable for your webserver. 7 | 8 | There is no critical data in here. You can savely remove any content. This 9 | will clear the cache. 10 | -------------------------------------------------------------------------------- /_h5ai/public/.htaccess: -------------------------------------------------------------------------------- 1 | ## make this folder accessible 2 | 3 | # Apache < 2.3 4 | 5 | Order allow,deny 6 | Allow from all 7 | Satisfy All 8 | 9 | 10 | # Apache ≥ 2.3 11 | 12 | Require all granted 13 | 14 | -------------------------------------------------------------------------------- /_h5ai/public/images/themes/comity/txt-md.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_h5ai/public/images/ui/preview-no-fullscreen.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_h5ai/public/images/ui/preview-close.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_h5ai/public/images/ui/view-grid.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_h5ai/public/images/ui/tree-toggle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_h5ai/public/images/ui/info-toggle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_h5ai/private/conf/l10n/sk.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "slovenčina", 3 | 4 | "details": "podrobnosti", 5 | "empty": "prázdny", 6 | "files": "súborov", 7 | "folders": "priečinkov", 8 | "icons": "ikony", 9 | "lastModified": "Upravené", 10 | "name": "Názov", 11 | "parentDirectory": "Nadriadený priečinok", 12 | "size": "Velkosť" 13 | } 14 | -------------------------------------------------------------------------------- /_h5ai/private/conf/l10n/tr.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "türkçe", 3 | 4 | "details": "detaylar", 5 | "download": "indir", 6 | "empty": "boş", 7 | "files": "dosyalar", 8 | "folders": "klasörler", 9 | "icons": "ikonlar", 10 | "lastModified": "Son Düzenleme", 11 | "name": "İsim", 12 | "parentDirectory": "Üst Dizin", 13 | "size": "Boyut" 14 | } 15 | -------------------------------------------------------------------------------- /_h5ai/private/conf/l10n/nb.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "norwegian", 3 | 4 | "details": "detaljer", 5 | "download": "last ned", 6 | "empty": "tom", 7 | "files": "filer", 8 | "folders": "mapper", 9 | "icons": "ikoner", 10 | "lastModified": "Sist endret", 11 | "name": "Navn", 12 | "noMatch": "ingen treff", 13 | "parentDirectory": "Overordnet mappe", 14 | "size": "Størrelse" 15 | } 16 | -------------------------------------------------------------------------------- /_h5ai/private/conf/l10n/ro.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "română", 3 | 4 | "details": "detalii", 5 | "download": "descarcă", 6 | "empty": "gol", 7 | "files": "fişiere", 8 | "folders": "dosar", 9 | "icons": "pictograme", 10 | "lastModified": "ultima modificare", 11 | "name": "nume", 12 | "noMatch": "0 rezultate", 13 | "parentDirectory": "dosar părinte", 14 | "size": "mărime" 15 | } 16 | -------------------------------------------------------------------------------- /_h5ai/private/conf/l10n/sr.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "srpski", 3 | 4 | "details": "detalji", 5 | "download": "download", 6 | "empty": "prazno", 7 | "files": "fajlovi", 8 | "folders": "direktorijum", 9 | "icons": "ikone", 10 | "lastModified": "Poslednja modifikacija", 11 | "name": "Ime", 12 | "noMatch": "bez poklapanja", 13 | "parentDirectory": "Roditeljski direktorijum", 14 | "size": "Veličina" 15 | } 16 | -------------------------------------------------------------------------------- /_h5ai/public/images/themes/README.md: -------------------------------------------------------------------------------- 1 | # Themes 2 | 3 | This directory will contain any themes you add. At the moment there are only 4 | icon themes supported. The folder structure is: `/.`, 5 | with `` one of `svg`, `png` or `jpg`. 6 | 7 | To select a theme use the option `view > theme` in file `conf/options.json`. 8 | 9 | You will find the previously included icon themes [here](https://github.com/lrsjng/h5ai-themes). 10 | -------------------------------------------------------------------------------- /_h5ai/private/conf/l10n/he.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "עברית", 3 | 4 | "dateFormat": "DD.MM.YYYY HH:mm", 5 | "details": "פרטים", 6 | "download": "הורדה", 7 | "empty": "ריק", 8 | "files": "קבצים", 9 | "filter": "סינון", 10 | "folders": "תיקיות", 11 | "icons": "צלמיות", 12 | "lastModified": "שינוי אחרון", 13 | "name": "שם", 14 | "noMatch": "אין תוצאות", 15 | "parentDirectory": "תיקיית הורה", 16 | "size": "גודל" 17 | } 18 | -------------------------------------------------------------------------------- /_h5ai/private/conf/l10n/hu.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "magyar", 3 | 4 | "dateFormat": "YYYY-MM-DD HH:mm", 5 | "details": "részletek", 6 | "download": "letöltés", 7 | "empty": "üres", 8 | "files": "fájlok", 9 | "folders": "mappák", 10 | "icons": "ikonok", 11 | "lastModified": "Utoljára módosítva", 12 | "name": "Név", 13 | "noMatch": "nincs találat", 14 | "parentDirectory": "Szülő könyvtár", 15 | "size": "Méret" 16 | } 17 | -------------------------------------------------------------------------------- /_h5ai/private/conf/l10n/sv.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "svenska", 3 | 4 | "details": "detaljerad", 5 | "download": "ladda ner", 6 | "empty": "tom", 7 | "files": "filer", 8 | "folders": "kataloger", 9 | "grid": "rutnät", 10 | "icons": "ikoner", 11 | "lastModified": "Senast ändrad", 12 | "name": "Filnamn", 13 | "noMatch": "ingen matchning", 14 | "parentDirectory": "Till överordnad mapp", 15 | "size": "Filstorlek" 16 | } 17 | -------------------------------------------------------------------------------- /_h5ai/public/images/ui/spinner.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /_h5ai/public/images/ui/filter.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /_h5ai/public/images/ui/search.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /_h5ai/private/conf/l10n/da.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "dansk", 3 | 4 | "dateFormat": "DD-MM-YYYY HH:mm", 5 | "details": "detaljer", 6 | "download": "download", 7 | "empty": "tom", 8 | "files": "filer", 9 | "filter": "filter", 10 | "folders": "mapper", 11 | "grid": "grid", 12 | "icons": "ikoner", 13 | "lastModified": "Sidst ændret", 14 | "name": "Navn", 15 | "noMatch": "ingen match", 16 | "parentDirectory": "Overordnet mappe", 17 | "size": "Størrelse" 18 | } 19 | -------------------------------------------------------------------------------- /_h5ai/private/conf/l10n/hi.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "हिंदी", 3 | 4 | "dateFormat": "DD.MM.YYYY HH:mm", 5 | "details": "विस्तार", 6 | "download": "डाउनलोड", 7 | "empty": "खाली", 8 | "files": "फ़ाइलें", 9 | "filter": "फ़िल्टर", 10 | "folders": "फोल्डर", 11 | "grid": "ग्रिड", 12 | "icons": "आइकॉन", 13 | "lastModified": "पिछला परिवर्तन", 14 | "name": "नाम", 15 | "noMatch": "कोई समानता नहीं", 16 | "parentDirectory": "मूल डायरेक्टरी", 17 | "size": "माप" 18 | } 19 | -------------------------------------------------------------------------------- /_h5ai/private/conf/l10n/af.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "afrikaans", 3 | 4 | "dateFormat": "YYYY-MM-DD HH:mm", 5 | "details": "besonderhede", 6 | "download": "aflaai", 7 | "empty": "leeg", 8 | "files": "lêers", 9 | "filter": "filter", 10 | "folders": "gidse", 11 | "grid": "rooster", 12 | "icons": "ikone", 13 | "lastModified": "Laas verander", 14 | "name": "Naam", 15 | "noMatch": "geen resultaat", 16 | "parentDirectory": "Hoër Vlak", 17 | "size": "Grootte" 18 | } 19 | -------------------------------------------------------------------------------- /_h5ai/private/conf/l10n/fi.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "finnish", 3 | 4 | "dateFormat": "DD.MM.YYYY HH:mm", 5 | "details": "tiedot", 6 | "download": "lataa", 7 | "empty": "tyhjä", 8 | "files": "tiedostoa", 9 | "filter": "suodata", 10 | "folders": "hakemistoa", 11 | "grid": "ruudukko", 12 | "icons": "ikonit", 13 | "lastModified": "Viimeksi muokattu", 14 | "name": "Nimi", 15 | "noMatch": "ei osumia", 16 | "parentDirectory": "Ylähakemisto", 17 | "size": "Koko" 18 | } 19 | -------------------------------------------------------------------------------- /_h5ai/private/conf/l10n/hr.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "hrvatski", 3 | 4 | "dateFormat": "YYYY-MM-DD HH:mm", 5 | "details": "detalji", 6 | "download": "preuzmi", 7 | "empty": "prazno", 8 | "files": "datoteka", 9 | "filter": "filter", 10 | "folders": "direktorij(a)", 11 | "grid": "mreža", 12 | "icons": "ikone", 13 | "lastModified": "Posljednja izmjena", 14 | "name": "Naziv", 15 | "noMatch": "nema rezultata", 16 | "parentDirectory": "Natrag", 17 | "size": "Veličina" 18 | } 19 | -------------------------------------------------------------------------------- /_h5ai/private/conf/l10n/sl.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "slovenščina", 3 | 4 | "dateFormat": "DD. MM. YYYY HH:mm", 5 | "details": "podrobnosti", 6 | "download": "prenesi", 7 | "empty": "prazno", 8 | "files": "datoteke", 9 | "filter": "filter", 10 | "folders": "mape", 11 | "grid": "mreža", 12 | "icons": "ikone", 13 | "lastModified": "Zadnja sprememba", 14 | "name": "Ime", 15 | "noMatch": "ni zadetkov", 16 | "parentDirectory": "Nadrejena mapa", 17 | "size": "Velikost" 18 | } 19 | -------------------------------------------------------------------------------- /_h5ai/private/conf/l10n/it.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "italiano", 3 | 4 | "dateFormat": "DD-MM-YYYY HH:mm", 5 | "details": "dettagli", 6 | "download": "download", 7 | "empty": "vuota", 8 | "files": "file", 9 | "filter": "filtra", 10 | "folders": "cartelle", 11 | "grid": "griglia", 12 | "icons": "icone", 13 | "lastModified": "Ultima modifica", 14 | "name": "Nome", 15 | "noMatch": "nessun risultato", 16 | "parentDirectory": "Cartella Superiore", 17 | "size": "Dimensione" 18 | } 19 | -------------------------------------------------------------------------------- /_h5ai/private/conf/l10n/ja.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "日本語", 3 | 4 | "dateFormat": "YYYY-MM-DD HH:mm", 5 | "details": "詳細", 6 | "download": "ダウンロード", 7 | "empty": "(空)", 8 | "files": "ファイル", 9 | "filter": "フィルター", 10 | "folders": "フォルダー", 11 | "grid": "グリッド", 12 | "icons": "アイコン", 13 | "language": "言語", 14 | "lastModified": "最終変更日時", 15 | "name": "名前", 16 | "noMatch": "一致する項目が見つかりません", 17 | "parentDirectory": "親ディレクトリへ", 18 | "size": "サイズ", 19 | "view": "ビュー" 20 | } 21 | -------------------------------------------------------------------------------- /_h5ai/private/conf/l10n/pt.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "português", 3 | 4 | "dateFormat": "DD-MM-YYYY HH:mm", 5 | "details": "detalhes", 6 | "download": "descarregar", 7 | "empty": "vazio", 8 | "files": "arquivos", 9 | "filter": "filtro", 10 | "folders": "pastas", 11 | "grid": "grelha", 12 | "icons": "ícones", 13 | "lastModified": "última modificação", 14 | "name": "Nome", 15 | "noMatch": "sem resultados", 16 | "parentDirectory": "diretório acima", 17 | "size": "Tamanho" 18 | } 19 | -------------------------------------------------------------------------------- /_h5ai/private/conf/l10n/uk.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "українська", 3 | 4 | "dateFormat": "YYYY-MM-DD HH:mm", 5 | "details": "Деталі", 6 | "download": "Завантажити", 7 | "empty": "Порожньо", 8 | "files": "Файли(ів)", 9 | "filter": "Фільтр", 10 | "folders": "Тек(и)", 11 | "grid": "Гратка", 12 | "icons": "Піктограми", 13 | "lastModified": "Останні зміни", 14 | "name": "Ім'я", 15 | "noMatch": "Немає співпадінь", 16 | "parentDirectory": "Головна тека", 17 | "size": "Розмір" 18 | } 19 | -------------------------------------------------------------------------------- /_h5ai/private/conf/l10n/bg.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "български", 3 | 4 | "dateFormat": "DD-MM-YYYY HH:mm", 5 | "details": "детайли", 6 | "download": "изтегляне", 7 | "empty": "празна", 8 | "files": "файлове", 9 | "filter": "филтър", 10 | "folders": "директории", 11 | "grid": "мрежа", 12 | "icons": "икони", 13 | "lastModified": "Последна промяна", 14 | "name": "Име", 15 | "noMatch": "няма съвпадение", 16 | "parentDirectory": "Предходна директория", 17 | "size": "Размер" 18 | } 19 | -------------------------------------------------------------------------------- /_h5ai/private/conf/l10n/cs.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "čeština", 3 | 4 | "dateFormat": "DD.MM.YYYY HH:mm", 5 | "details": "Podrobnosti", 6 | "download": "Stáhnout", 7 | "empty": "Prázdná složka", 8 | "files": "souborů", 9 | "filter": "Filtr", 10 | "folders": "složek", 11 | "grid": "Seznam", 12 | "icons": "Velké ikony", 13 | "lastModified": "Datum změny", 14 | "name": "Název", 15 | "noMatch": "Žádná shoda", 16 | "parentDirectory": "Nadřazený adresář", 17 | "size": "Velikost" 18 | } 19 | -------------------------------------------------------------------------------- /_h5ai/private/conf/l10n/el.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "ελληνικά", 3 | 4 | "dateFormat": "DD/MM/YYYY HH:mm", 5 | "details": "λεπτομέρειες", 6 | "download": "μεταμόρφωση", 7 | "empty": "κενό", 8 | "files": "αρχεία", 9 | "filter": "φίλτρο", 10 | "folders": "φάκελοι", 11 | "grid": "πλέγμα", 12 | "icons": "εικονίδια", 13 | "lastModified": "Τελευταία τροποποίηση", 14 | "name": "Όνομα", 15 | "noMatch": "κανένα αποτέλεσμα", 16 | "parentDirectory": "Προηγούμενος Κατάλογος", 17 | "size": "Μέγεθος" 18 | } 19 | -------------------------------------------------------------------------------- /_h5ai/private/conf/l10n/ko.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "한국어", 3 | 4 | "dateFormat": "YYYY-MM-DD HH:mm", 5 | "details": "자세히", 6 | "download": "다운로드", 7 | "empty": "빈 폴더", 8 | "files": "파일", 9 | "filter": "필터", 10 | "folders": "폴더", 11 | "grid": "그리드", 12 | "icons": "아이콘", 13 | "language": "언어", 14 | "lastModified": "최근 수정일", 15 | "name": "파일명", 16 | "noMatch": "해당파일이 없습니다.", 17 | "parentDirectory": "상위폴더", 18 | "search": "검색", 19 | "size": "크기", 20 | "tree": "트리", 21 | "view": "보기" 22 | } 23 | -------------------------------------------------------------------------------- /_h5ai/private/conf/l10n/ru.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "русский", 3 | 4 | "dateFormat": "YYYY-MM-DD HH:mm", 5 | "details": "Детали", 6 | "download": "Скачать", 7 | "empty": "Пусто", 8 | "files": "Файлы", 9 | "filter": "Фильтр", 10 | "folders": "Папки", 11 | "grid": "Сетка", 12 | "icons": "Иконки", 13 | "language": "Язык", 14 | "lastModified": "Последние изменения", 15 | "name": "Имя", 16 | "noMatch": "Нет совпадений", 17 | "parentDirectory": "Главная директория", 18 | "size": "Размер", 19 | "view": "Вид" 20 | } 21 | -------------------------------------------------------------------------------- /_h5ai/private/conf/l10n/zh-cn.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "简体中文", 3 | 4 | "dateFormat": "YYYY-MM-DD HH:mm", 5 | "details": "详情", 6 | "download": "下载", 7 | "empty": "空文件夹", 8 | "files": "文件", 9 | "filter": "过滤", 10 | "folders": "文件夹", 11 | "grid": "网格", 12 | "icons": "图标", 13 | "language": "语言", 14 | "lastModified": "修改时间", 15 | "name": "文件名", 16 | "noMatch": "无匹配项", 17 | "parentDirectory": "父文件夹", 18 | "search": "搜索", 19 | "size": "大小", 20 | "tree": "树形目录", 21 | "view": "视图", 22 | "info": "信息" 23 | } 24 | -------------------------------------------------------------------------------- /_h5ai/private/conf/l10n/zh-tw.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "正體中文", 3 | 4 | "dateFormat": "YYYY-MM-DD HH:mm", 5 | "details": "詳細資料", 6 | "download": "下載", 7 | "empty": "空資料夾", 8 | "files": "檔案", 9 | "filter": "過濾", 10 | "folders": "資料夾", 11 | "grid": "網格", 12 | "icons": "圖示", 13 | "language": "語言", 14 | "lastModified": "上次修改", 15 | "name": "檔名", 16 | "noMatch": "沒有符合的檔案", 17 | "parentDirectory": "上層目錄", 18 | "search": "搜尋", 19 | "size": "大小", 20 | "tree": "樹形目錄", 21 | "view": "檢視", 22 | "info": "資訊" 23 | } 24 | -------------------------------------------------------------------------------- /_h5ai/private/php/core/class-session.php: -------------------------------------------------------------------------------- 1 | store = &$store; 9 | } 10 | 11 | public function set($key, $value) { 12 | $key = Session::$KEY_PREFIX . $key; 13 | $this->store[$key] = $value; 14 | } 15 | 16 | public function get($key, $default = null) { 17 | $key = Session::$KEY_PREFIX . $key; 18 | return array_key_exists($key, $this->store) ? $this->store[$key] : $default; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /_h5ai/private/conf/l10n/de.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "deutsch", 3 | 4 | "dateFormat": "DD.MM.YYYY HH:mm", 5 | "details": "Details", 6 | "download": "Download", 7 | "empty": "leer", 8 | "files": "Dateien", 9 | "filter": "filtern", 10 | "folders": "Ordner", 11 | "grid": "Gitter", 12 | "icons": "Icons", 13 | "language": "Sprache", 14 | "lastModified": "Geändert", 15 | "name": "Name", 16 | "noMatch": "keine Treffer", 17 | "parentDirectory": "Übergeordnetes Verzeichnis", 18 | "search": "suchen", 19 | "size": "Größe", 20 | "tree": "Baum", 21 | "view": "Ansicht" 22 | } 23 | -------------------------------------------------------------------------------- /_h5ai/private/conf/l10n/et.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "estonian", 3 | 4 | "dateFormat": "DD-MM-YYYY HH.mm", 5 | "details": "täpsem info", 6 | "download": "laadi alla", 7 | "empty": "tühi", 8 | "files": "failid", 9 | "filter": "filter", 10 | "folders": "kataloogid", 11 | "grid": "võre", 12 | "icons": "ikoonid", 13 | "language": "Keel", 14 | "lastModified": "Viimati muudetud", 15 | "name": "Nimi", 16 | "noMatch": "ei leitud sobivat", 17 | "parentDirectory": "Emakataloog", 18 | "search": "otsi", 19 | "size": "Suurus", 20 | "tree": "Puu", 21 | "view": "Vaade" 22 | } 23 | -------------------------------------------------------------------------------- /_h5ai/private/conf/l10n/nl.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "nederlands", 3 | 4 | "dateFormat": "YYYY-MM-DD HH:mm", 5 | "details": "details", 6 | "download": "download", 7 | "empty": "leeg", 8 | "files": "bestanden", 9 | "filter": "filter", 10 | "folders": "mappen", 11 | "grid": "grid", 12 | "icons": "iconen", 13 | "language": "Taal", 14 | "lastModified": "Laatste wijziging", 15 | "name": "Naam", 16 | "noMatch": "geen overeenkomst", 17 | "parentDirectory": "Bovenliggende map", 18 | "search": "zoeken", 19 | "size": "Grootte", 20 | "tree": "Boom", 21 | "view": "Bekijk" 22 | } 23 | -------------------------------------------------------------------------------- /_h5ai/private/conf/l10n/pl.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "polski", 3 | 4 | "dateFormat": "YYYY-MM-DD HH:mm", 5 | "details": "szczegóły", 6 | "download": "pobierz", 7 | "empty": "pusty", 8 | "files": "plików", 9 | "filter": "filtr", 10 | "folders": "folderów", 11 | "grid": "kafelki", 12 | "icons": "ikony", 13 | "language": "Język", 14 | "lastModified": "Ostatnia modyfikacja", 15 | "name": "Nazwa", 16 | "noMatch": "nie znaleziono", 17 | "parentDirectory": "Katalog nadrzędny", 18 | "search": "szukaj", 19 | "size": "Rozmiar", 20 | "tree": "Drzewo", 21 | "view": "Układ" 22 | } 23 | -------------------------------------------------------------------------------- /_h5ai/private/conf/l10n/lv.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "latviešu", 3 | 4 | "dateFormat": "YYYY-MM-DD HH:mm", 5 | "details": "detaļas", 6 | "download": "lejupielādēt", 7 | "empty": "tukšs", 8 | "files": "faili", 9 | "filter": "filtrēt", 10 | "folders": "mapes", 11 | "grid": "režģis", 12 | "icons": "ikonas", 13 | "language": "Valoda", 14 | "lastModified": "Pēdējoreiz modificēts", 15 | "name": "Nosaukums", 16 | "noMatch": "nav sakritības", 17 | "parentDirectory": "Vecākdirektorijs", 18 | "search": "meklēt", 19 | "size": "Izmērs", 20 | "tree": "Koks", 21 | "view": "Skats" 22 | } 23 | -------------------------------------------------------------------------------- /_h5ai/private/conf/l10n/es.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "español", 3 | 4 | "dateFormat": "DD/MM/YYYY HH:mm", 5 | "details": "Detalles", 6 | "download": "Descargar", 7 | "empty": "vacío", 8 | "files": "Archivos", 9 | "filter": "Filtrar", 10 | "folders": "Directorios", 11 | "grid": "Cuadrícula", 12 | "icons": "Íconos", 13 | "language": "Idioma", 14 | "lastModified": "Última modificación", 15 | "name": "Nombre", 16 | "noMatch": "Sin coincidencias", 17 | "parentDirectory": "Directorio superior", 18 | "search": "buscar", 19 | "size": "Tamaño", 20 | "tree": "Arbol", 21 | "view": "Vista" 22 | } 23 | -------------------------------------------------------------------------------- /_h5ai/private/conf/l10n/fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "français", 3 | 4 | "dateFormat": "DD/MM/YYYY HH:mm", 5 | "details": "détails", 6 | "download": "télécharger", 7 | "empty": "vide", 8 | "files": "Fichiers", 9 | "filter": "filtrer", 10 | "folders": "Répertoires", 11 | "grid": "grille", 12 | "icons": "icônes", 13 | "language": "Langue", 14 | "lastModified": "Dernière modification", 15 | "name": "Nom", 16 | "noMatch": "rien trouvé", 17 | "parentDirectory": "Dossier parent", 18 | "search": "rechercher", 19 | "size": "Taille", 20 | "tree": "Arborescence", 21 | "view": "Disposition" 22 | } 23 | -------------------------------------------------------------------------------- /_h5ai/public/images/themes/comity/txt-rb.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /subtovtt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | subdir="/data/video" 4 | 5 | function sub(){ 6 | for file in "$1"/* 7 | do 8 | if [[ -d "$file" && "${file:0-2}" != "_h5ai" && "${file:0-2}" != "__" ]]; then 9 | sub "$file" 10 | else 11 | if [[ "${file##*.}" == "ass" || "${file##*.}" == "srt" ]]; then 12 | filenotype="${file%.*}" 13 | if [[ ! -f "${filenotype}.vtt" ]]; then 14 | ffmpeg -i "$file" "${filenotype}.vtt" 15 | # rm "$file" 16 | fi 17 | fi 18 | fi 19 | done 20 | } 21 | sub "$subdir" 22 | 23 | echo "sub finish" 24 | -------------------------------------------------------------------------------- /_h5ai/public/images/themes/comity/ar-apk.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_h5ai/private/conf/l10n/en.json: -------------------------------------------------------------------------------- 1 | /* only here as a reference, these values are the hardcoded defaults */ 2 | { 3 | "lang": "english", 4 | 5 | "dateFormat": "YYYY-MM-DD HH:mm", 6 | "details": "details", 7 | "download": "download", 8 | "empty": "empty", 9 | "files": "files", 10 | "filter": "filter", 11 | "folders": "folders", 12 | "grid": "grid", 13 | "icons": "icons", 14 | "language": "Language", 15 | "lastModified": "Last modified", 16 | "name": "Name", 17 | "noMatch": "no match", 18 | "parentDirectory": "Parent Directory", 19 | "search": "search", 20 | "size": "Size", 21 | "tree": "Tree", 22 | "view": "View" 23 | } 24 | -------------------------------------------------------------------------------- /_h5ai/public/index.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_h5ai/public/images/themes/comity/txt-script.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /hls_general.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | BASEDIR="/data/video" 4 | 5 | function hlsfile(){ 6 | file="$1" 7 | if [[ "${file##*.}" == "mp4" || "${file##*.}" == "mkv" ]]; then 8 | filename="${file##*/}" 9 | m3u8dir="${file%/*}/__${filename}__" 10 | if [[ ! -d "${m3u8dir}" && ! -f "${file}.aria2" ]]; then 11 | mkdir -p "${m3u8dir}" 12 | ffmpeg -i "${file}" -c copy -bsf:v h264_mp4toannexb -hls_time 6 -hls_list_size 0 -hls_segment_filename "${m3u8dir}/%04d.ts" "${m3u8dir}/video.m3u8" > /dev/null 2>&1 13 | # echo 'Rikka' > "${file}" 14 | fi 15 | fi 16 | } 17 | 18 | function scandir(){ 19 | for dirfile in "$1"/* 20 | do 21 | if [[ -d "${dirfile}" && "${dirfile:0-5}" != "_h5ai" && "${dirfile:0-2}" != "__" ]]; then 22 | scandir "${dirfile}" 23 | else 24 | hlsfile "${dirfile}" 25 | fi 26 | done 27 | } 28 | scandir "${BASEDIR}" 29 | 30 | echo "hls finish" 31 | -------------------------------------------------------------------------------- /_h5ai/private/php/core/class-logger.php: -------------------------------------------------------------------------------- 1 | context = $context; 9 | } 10 | 11 | public function get_icons() { 12 | $public_path = $this->context->get_setup()->get('PUBLIC_PATH'); 13 | $theme = $this->context->query_option('view.theme', '-NONE-'); 14 | $theme_path = $public_path . '/images/themes/' . $theme; 15 | 16 | $icons = []; 17 | 18 | if (is_dir($theme_path)) { 19 | if ($dir = opendir($theme_path)) { 20 | while (($name = readdir($dir)) !== false) { 21 | $path_parts = pathinfo($name); 22 | if (in_array(@$path_parts['extension'], Theme::$EXTENSIONS)) { 23 | $icons[$path_parts['filename']] = $theme . '/' . $name; 24 | } 25 | } 26 | closedir($dir); 27 | } 28 | } 29 | 30 | return $icons; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /hls_aria2.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DOWNPATH="/data/download/" 4 | 5 | SRC="$3" 6 | 7 | function hlsfile(){ 8 | file="$1" 9 | if [[ "${file##*.}" == "mp4" || "${file##*.}" == "mkv" ]]; then 10 | filename="${file##*/}" 11 | m3u8dir="${file%/*}/__${filename}__" 12 | if [[ ! -d "${m3u8dir}" && ! -f "${file}.aria2" ]]; then 13 | mkdir -p "${m3u8dir}" 14 | ffmpeg -i "${file}" -c copy -bsf:v h264_mp4toannexb -hls_time 6 -hls_list_size 0 -hls_segment_filename "${m3u8dir}/%04d.ts" "${m3u8dir}/video.m3u8" > /dev/null 2>&1 15 | # echo 'Rikka' > "${file}" 16 | fi 17 | fi 18 | } 19 | 20 | function scandir(){ 21 | for dirfile in "$1"/* 22 | do 23 | if [[ -d "${dirfile}" && "${dirfile:0-5}" != "_h5ai" && "${dirfile:0-2}" != "__" ]]; then 24 | scandir "${dirfile}" 25 | else 26 | hlsfile "${dirfile}" 27 | fi 28 | done 29 | } 30 | 31 | # magnet 32 | if [[ "$2" == "0" ]]; then 33 | exit 0 34 | fi 35 | 36 | # single file 37 | if [[ "$2" == "1" ]]; then 38 | hlsfile "${SRC}" 39 | fi 40 | 41 | # bt folder 42 | if [[ "$2" -gt "1" ]]; then 43 | SRCA="${SRC#${DOWNPATH}}" 44 | FileFolder="${DOWNPATH}${SRCA%%\/*}" 45 | scandir "${FileFolder}" 46 | fi 47 | -------------------------------------------------------------------------------- /_h5ai/public/images/themes/comity/txt-php.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_h5ai/public/images/themes/comity/txt-html.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /_h5ai/public/images/themes/comity/txt-css.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /_h5ai/private/php/pages/info.php: -------------------------------------------------------------------------------- 1 | h5ai info page - v0.29.2 2 |
Works best with JavaScript enabled!Works best in modern browsers!powered by h5ai
-------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2020.02.06 2 | 3 | 更新dplayer到最新dev版本(修复了和flv.js搭配产生的BUG) 4 | 更新hls到最新版本(修复了特殊文件名BUG,总算不用hack了) 5 | 增加flv.js支持播放flv视频 6 | 支持播放自建直播流 7 | 优化了播放器加载逻辑 8 | 9 | ### 说明 10 | 11 | 1. 支持hls播放切片视频,flv视频,可播放hls切片直播,flv直播流 12 | 13 | 2. 支持简单的登录验证,默认用户名密码都是admin。 14 | 如果不想要用户名密码,把_h5ai/public/index.php里第二行include 'login.php'注销。 15 | 修改用户名密码在_h5ai/public/login.php。 16 | 17 | 3. 考虑到方便手动管理视频切片文件,会自动按照下面的目录结构播放video.m3u8,如果没有切片则会播放原始视频。 18 | 切片文件夹和文件默认都是隐藏的,不会在h5ai中显示,可以手动修改_h5ai/private/conf/options.json配置是否隐藏。 19 | ``` 20 | ├── __abcd.mp4__ 21 | │   └── video.m3u8 22 | └── abcd.mp4 23 | ``` 24 | 25 | ### 简易自动切片 26 | 27 | ##### 搭配Aria2 28 | aria2配置文件增加 29 | ``` 30 | on-download-complete=/data/aria2/hls_aria2.sh 31 | ``` 32 | hls_aria2.sh --> 下载完成后复制原始视频流编码自动切片。自行修改下载路径DOWNPATH(注意需要结尾的"/")。 33 | 34 | ##### 通用转换切片文件 35 | hls_general.sh --> 将指定目录及所有子目录下的全部视频文件切片。自行修改目录绝对路径(注意结尾无"/")。 36 | 37 | ##### ass,srt字幕转vtt字幕 38 | 如果存在同视频文件名的vtt字幕,会自动载入字幕文件。 39 | subtovtt.sh --> 将指定目录及所有子目录下的全部字幕文件转换为vtt字幕。自行修改目录绝对路径(注意结尾无"/")。 40 | 41 | ### 直播流 42 | 比较复杂,有需求的人也不多,感兴趣可以自行研究 43 | 44 | 可以搭建livego直播服务器,中转播放youtube等国外直播,需要ffmpeg, streamlink/youtube-dl, livego。 45 | 46 | 若直播流取名为movie 47 | 通过ffmpeg推流到livego链接为 rtmp://127.0.0.1:1935/live/movie 48 | 49 | nginx反代 /live 到 127.0.0.1:7001,在h5ai显示的目录下新建movie.live.flv,点击就会播放名为movie的flv直播流(推荐,延迟低,稳定)。 50 | 51 | nginx反代 /live 到 127.0.0.1:7002,在h5ai显示的目录下新建movie.live.flv,点击就会播放名为movie的hls切片直播流(20s延迟)。 52 | -------------------------------------------------------------------------------- /_h5ai/private/php/ext/class-search.php: -------------------------------------------------------------------------------- 1 | context = $context; 8 | } 9 | 10 | public function get_paths($root, $pattern = null, $ignorecase = false) { 11 | $paths = []; 12 | if ($pattern && $this->context->is_managed_path($root)) { 13 | $re = Util::wrap_pattern($pattern); 14 | if ($ignorecase) { 15 | $re .= 'i'; 16 | } 17 | $names = $this->context->read_dir($root); 18 | foreach ($names as $name) { 19 | $path = $root . '/' . $name; 20 | if (preg_match($re, @basename($path))) { 21 | $paths[] = $path; 22 | } 23 | if (@is_dir($path)) { 24 | $paths = array_merge($paths, $this->get_paths($path, $pattern, $ignorecase)); 25 | } 26 | } 27 | } 28 | return $paths; 29 | } 30 | 31 | public function get_items($href, $pattern = null, $ignorecase = false) { 32 | $cache = []; 33 | $root = $this->context->to_path($href); 34 | $paths = $this->get_paths($root, $pattern, $ignorecase); 35 | $items = array_map(function ($path) { 36 | return Item::get($this->context, $path, $cache)->to_json_object(); 37 | }, $paths); 38 | return $items; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /_h5ai/private/php/core/class-request.php: -------------------------------------------------------------------------------- 1 | params = $data !== null ? $data : $params; 9 | } 10 | 11 | public function query($keypath = '', $default = Util::NO_DEFAULT) { 12 | $value = Util::array_query($this->params, $keypath, Util::NO_DEFAULT); 13 | 14 | if ($value === Util::NO_DEFAULT) { 15 | Util::json_fail(Util::ERR_MISSING_PARAM, 'parameter \'' . $keypath . '\' is missing', $default === Util::NO_DEFAULT); 16 | return $default; 17 | } 18 | 19 | return $value; 20 | } 21 | 22 | public function query_boolean($keypath = '', $default = Util::NO_DEFAULT) { 23 | $value = $this->query($keypath, $default); 24 | return filter_var($value, FILTER_VALIDATE_BOOLEAN); 25 | } 26 | 27 | public function query_numeric($keypath = '', $default = Util::NO_DEFAULT) { 28 | $value = $this->query($keypath, $default); 29 | Util::json_fail(Util::ERR_ILLIGAL_PARAM, 'parameter \'' . $keypath . '\' is not numeric', !is_numeric($value)); 30 | return intval($value, 10); 31 | } 32 | 33 | public function query_array($keypath = '', $default = Util::NO_DEFAULT) { 34 | $value = $this->query($keypath, $default); 35 | Util::json_fail(Util::ERR_ILLIGAL_PARAM, 'parameter \'' . $keypath . '\' is no array', !is_array($value)); 36 | return $value; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /_h5ai/public/images/themes/comity/txt-py.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /_h5ai/private/php/pages/index.php: -------------------------------------------------------------------------------- 1 | index - powered by h5ai v0.29.2 (https://larsjung.de/h5ai/) 2 |
Works best with JavaScript enabled!Works best in modern browsers!powered by h5ai
-------------------------------------------------------------------------------- /_h5ai/private/php/class-bootstrap.php: -------------------------------------------------------------------------------- 1 | query_boolean('refresh', false)); 16 | $context = new Context($session, $request, $setup); 17 | 18 | if ($context->is_api_request()) { 19 | (new Api($context))->apply(); 20 | } elseif ($context->is_info_request()) { 21 | $public_href = $setup->get('PUBLIC_HREF'); 22 | $x_head_tags = $context->get_x_head_html(); 23 | $fallback_mode = false; 24 | require __DIR__ . '/pages/info.php'; 25 | } else { 26 | $public_href = $setup->get('PUBLIC_HREF'); 27 | $x_head_tags = $context->get_x_head_html(); 28 | $fallback_mode = $context->is_fallback_mode(); 29 | $fallback_html = (new Fallback($context))->get_html(); 30 | require __DIR__ . '/pages/index.php'; 31 | } 32 | } 33 | 34 | public static function autoload($class_name) { 35 | $filename = 'class-' . strtolower($class_name) . '.php'; 36 | 37 | foreach (Bootstrap::$autopaths as $path) { 38 | $file = __DIR__ . '/' . $path . '/' . $filename; 39 | if (file_exists($file)) { 40 | require_once $file; 41 | return true; 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /_h5ai/private/php/core/class-fallback.php: -------------------------------------------------------------------------------- 1 | context = $context; 8 | } 9 | 10 | public function get_html($path = null) { 11 | if (!$path) { 12 | $path = $this->context->get_current_path(); 13 | } 14 | $fallback_images_href = $this->context->get_setup()->get('PUBLIC_HREF') . 'images/fallback/'; 15 | 16 | $cache = []; 17 | $folder = Item::get($this->context, $path, $cache); 18 | $items = $folder->get_content($cache); 19 | uasort($items, ['Item', 'cmp']); 20 | 21 | $html = ''; 22 | 23 | $html .= ''; 24 | $html .= ''; 25 | $html .= ''; 26 | $html .= ''; 27 | $html .= ''; 28 | $html .= ''; 29 | 30 | if ($folder->get_parent($cache)) { 31 | $html .= ''; 32 | $html .= ''; 33 | $html .= ''; 34 | $html .= ''; 35 | $html .= ''; 36 | $html .= ''; 37 | } 38 | 39 | foreach ($items as $item) { 40 | $type = $item->is_folder ? 'folder' : 'file'; 41 | 42 | $html .= ''; 43 | $html .= ''; 44 | $html .= ''; 45 | $html .= ''; 46 | $html .= ''; 47 | $html .= ''; 48 | } 49 | 50 | $html .= '
NameLast modifiedSize
folder-parentParent Directory
' . $type . '' . basename($item->path) . '' . date('Y-m-d H:i', $item->date) . '' . ($item->size !== null ? intval($item->size / 1000) . ' KB' : '' ) . '
'; 51 | 52 | return $html; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /_h5ai/private/php/core/class-json.php: -------------------------------------------------------------------------------- 1 | context = $context; 9 | } 10 | 11 | private function read_custom_file($path, $name, &$content, &$type) { 12 | $file_prefix = $this->context->get_setup()->get('FILE_PREFIX'); 13 | 14 | foreach (Custom::$EXTENSIONS as $ext) { 15 | $file = $path . '/' . $file_prefix . '.' . $name . '.' . $ext; 16 | if (is_readable($file)) { 17 | $content = file_get_contents($file); 18 | $type = $ext; 19 | return; 20 | } 21 | } 22 | } 23 | 24 | public function get_customizations($href) { 25 | if (!$this->context->query_option('custom.enabled', false)) { 26 | return [ 27 | 'header' => ['content' => null, 'type' => null], 28 | 'footer' => ['content' => null, 'type' => null] 29 | ]; 30 | } 31 | 32 | $root_path = $this->context->get_setup()->get('FILE_PREFIX'); 33 | $path = $this->context->to_path($href); 34 | 35 | $header = null; 36 | $header_type = null; 37 | $footer = null; 38 | $footer_type = null; 39 | 40 | $this->read_custom_file($path, 'header', $header, $header_type); 41 | $this->read_custom_file($path, 'footer', $footer, $footer_type); 42 | 43 | while ($header === null || $footer === null) { 44 | if ($header === null) { 45 | $this->read_custom_file($path, 'headers', $header, $header_type); 46 | } 47 | if ($footer === null) { 48 | $this->read_custom_file($path, 'footers', $footer, $footer_type); 49 | } 50 | if ($path === $root_path) { 51 | break; 52 | } 53 | $parent_path = Util::normalize_path(dirname($path)); 54 | if ($parent_path === $path) { 55 | break; 56 | } 57 | $path = $parent_path; 58 | } 59 | 60 | return [ 61 | 'header' => ['content' => $header, 'type' => $header_type], 62 | 'footer' => ['content' => $footer, 'type' => $footer_type] 63 | ]; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /_h5ai/public/images/themes/comity/txt-js.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_h5ai/public/images/themes/comity/x-pdf.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_h5ai/private/php/core/class-filesize.php: -------------------------------------------------------------------------------- 1 | size($path, $withFoldersize, $withDu); 9 | } 10 | 11 | public static function getCachedSize($path, $withFoldersize, $withDu) { 12 | if (array_key_exists($path, Filesize::$cache)) { 13 | return Filesize::$cache[$path]; 14 | } 15 | 16 | $size = Filesize::getSize($path, $withFoldersize, $withDu); 17 | 18 | Filesize::$cache[$path] = $size; 19 | return $size; 20 | } 21 | 22 | 23 | private function __construct() {} 24 | 25 | private function read_dir($path) { 26 | $paths = []; 27 | if (is_dir($path)) { 28 | foreach (scandir($path) as $name) { 29 | if ($name !== '.' && $name !== '..') { 30 | $paths[] = $path . '/' . $name; 31 | } 32 | } 33 | } 34 | return $paths; 35 | } 36 | 37 | private function php_filesize($path, $recursive = false) { 38 | // if (PHP_INT_SIZE < 8) { 39 | // } 40 | $size = @filesize($path); 41 | 42 | if (!is_dir($path) || !$recursive) { 43 | return $size; 44 | } 45 | 46 | foreach ($this->read_dir($path) as $p) { 47 | $size += $this->php_filesize($p, true); 48 | } 49 | return $size; 50 | } 51 | 52 | 53 | private function exec($cmdv) { 54 | $cmd = implode(' ', array_map('escapeshellarg', $cmdv)); 55 | $lines = []; 56 | $rc = null; 57 | exec($cmd, $lines, $rc); 58 | return $lines; 59 | } 60 | 61 | private function exec_du_all($paths) { 62 | $cmdv = array_merge(['du', '-sbL'], $paths); 63 | $lines = $this->exec($cmdv); 64 | 65 | $sizes = []; 66 | foreach ($lines as $line) { 67 | $parts = preg_split('/[\s]+/', $line, 2); 68 | $size = intval($parts[0], 10); 69 | $path = $parts[1]; 70 | $sizes[$path] = $size; 71 | } 72 | return $sizes; 73 | } 74 | 75 | private function exec_du($path) { 76 | $sizes = $this->exec_du_all([$path]); 77 | return $sizes[$path]; 78 | } 79 | 80 | 81 | private function size($path, $withFoldersize = false, $withDu = false) { 82 | if (is_file($path)) { 83 | return $this->php_filesize($path); 84 | } 85 | 86 | if (is_dir($path) && $withFoldersize) { 87 | if ($withDu) { 88 | return $this->exec_du($path); 89 | } 90 | 91 | return $this->php_filesize($path, true); 92 | } 93 | 94 | return null; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /_h5ai/private/php/core/class-item.php: -------------------------------------------------------------------------------- 1 | is_folder && !$item2->is_folder) { 6 | return -1; 7 | } 8 | if (!$item1->is_folder && $item2->is_folder) { 9 | return 1; 10 | } 11 | 12 | return strcasecmp($item1->path, $item2->path); 13 | } 14 | 15 | public static function get($context, $path, &$cache) { 16 | if (!Util::starts_with($path, $context->get_setup()->get('ROOT_PATH'))) { 17 | return null; 18 | } 19 | 20 | if (is_array($cache) && array_key_exists($path, $cache)) { 21 | return $cache[$path]; 22 | } 23 | 24 | $item = new Item($context, $path); 25 | 26 | if (is_array($cache)) { 27 | $cache[$path] = $item; 28 | } 29 | return $item; 30 | } 31 | 32 | public $context; 33 | public $path; 34 | public $href; 35 | public $date; 36 | public $size; 37 | public $is_folder; 38 | public $is_content_fetched; 39 | 40 | private function __construct($context, $path) { 41 | $this->context = $context; 42 | 43 | $this->path = Util::normalize_path($path, false); 44 | $this->is_folder = is_dir($this->path); 45 | $this->href = $context->to_href($this->path, $this->is_folder); 46 | $this->date = @filemtime($this->path); 47 | $this->size = Util::filesize($context, $this->path); 48 | $this->is_content_fetched = false; 49 | } 50 | 51 | public function to_json_object() { 52 | $obj = [ 53 | 'href' => $this->href, 54 | 'time' => $this->date * 1000, // seconds (PHP) to milliseconds (JavaScript) 55 | 'size' => $this->size 56 | ]; 57 | 58 | if ($this->is_folder) { 59 | $obj['managed'] = $this->context->is_managed_href($this->href); 60 | $obj['fetched'] = $this->is_content_fetched; 61 | } 62 | 63 | return $obj; 64 | } 65 | 66 | public function get_parent(&$cache) { 67 | $parent_path = Util::normalize_path(dirname($this->path), false); 68 | if ($parent_path !== $this->path && Util::starts_with($parent_path, $this->context->get_setup()->get('ROOT_PATH'))) { 69 | return Item::get($this->context, $parent_path, $cache); 70 | } 71 | return null; 72 | } 73 | 74 | public function get_content(&$cache) { 75 | $items = []; 76 | 77 | if (!$this->context->is_managed_href($this->href)) { 78 | return $items; 79 | } 80 | 81 | $files = $this->context->read_dir($this->path); 82 | foreach ($files as $file) { 83 | $item = Item::get($this->context, $this->path . '/' . $file, $cache); 84 | $items[$item->path] = $item; 85 | } 86 | 87 | $this->is_content_fetched = true; 88 | 89 | return $items; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /_h5ai/README.md: -------------------------------------------------------------------------------- 1 | # h5ai 2 | 3 | [![license][license-img]][github] [![web][web-img]][web] [![github][github-img]][github] 4 | 5 | A modern HTTP web server index for Apache httpd, lighttpd, nginx and Cherokee. 6 | 7 | 8 | ## Important 9 | 10 | * Do **not** install any files from the `src` folder, they need to be 11 | preprocessed to work correctly! 12 | * Find a preprocessed package and detailed install instructions on the 13 | [project page][web]. 14 | * For bug reports and feature requests please use [issues][github-issues]. 15 | 16 | 17 | ## Build 18 | 19 | There are installation ready packages for the latest [releases][release] and 20 | [dev builds][develop]. But to build **h5ai** yourself either `git clone` or 21 | download the repository. From within the root folder run the following 22 | commands to find a fresh zipball in folder `build` (tested on linux only, 23 | requires [`node 6.0+`][node] to be installed). 24 | 25 | ~~~sh 26 | > npm install 27 | > npm run build 28 | ~~~ 29 | 30 | 31 | ## License 32 | 33 | The MIT License (MIT) 34 | 35 | Copyright (c) 2019 Lars Jung (https://larsjung.de) 36 | 37 | Permission is hereby granted, free of charge, to any person obtaining a copy 38 | of this software and associated documentation files (the "Software"), to deal 39 | in the Software without restriction, including without limitation the rights 40 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 41 | copies of the Software, and to permit persons to whom the Software is 42 | furnished to do so, subject to the following conditions: 43 | 44 | The above copyright notice and this permission notice shall be included in 45 | all copies or substantial portions of the Software. 46 | 47 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 48 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 49 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 50 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 51 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 52 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 53 | THE SOFTWARE. 54 | 55 | 56 | ## References 57 | 58 | **h5ai** profits from other projects, all of them licensed under the MIT license 59 | too. Exceptions are some [Material Design icons][material-design-icons] (CC BY 4.0). 60 | 61 | 62 | [web]: https://larsjung.de/h5ai/ 63 | [github]: https://github.com/lrsjng/h5ai 64 | [github-issues]: https://github.com/lrsjng/h5ai/issues 65 | [release]: https://release.larsjung.de/h5ai/ 66 | [develop]: https://release.larsjung.de/h5ai/develop/ 67 | [node]: https://nodejs.org 68 | [material-design-icons]: https://github.com/google/material-design-icons 69 | 70 | [license-img]: https://img.shields.io/badge/license-MIT-a0a060.svg?style=flat-square 71 | [web-img]: https://img.shields.io/badge/web-larsjung.de/h5ai-a0a060.svg?style=flat-square 72 | [github-img]: https://img.shields.io/badge/github-lrsjng/h5ai-a0a060.svg?style=flat-square 73 | -------------------------------------------------------------------------------- /_h5ai/private/php/core/class-util.php: -------------------------------------------------------------------------------- 1 | $err, 'msg' => $msg]); 26 | } 27 | } 28 | 29 | public static function array_query($array, $keypath = '', $default = Util::NO_DEFAULT) { 30 | $value = $array; 31 | 32 | $keys = array_filter(explode('.', $keypath)); 33 | foreach ($keys as $key) { 34 | if (!is_array($value) || !array_key_exists($key, $value)) { 35 | return $default; 36 | } 37 | $value = $value[$key]; 38 | } 39 | 40 | return $value; 41 | } 42 | 43 | public static function starts_with($sequence, $head) { 44 | return substr($sequence, 0, strlen($head)) === $head; 45 | } 46 | 47 | public static function ends_with($sequence, $tail) { 48 | $len = strlen($tail); 49 | return $len === 0 ? true : substr($sequence, -$len) === $tail; 50 | } 51 | 52 | public static function wrap_pattern($pattern) { 53 | return Util::RE_DELIMITER . str_replace(Util::RE_DELIMITER, '\\' . Util::RE_DELIMITER, $pattern) . Util::RE_DELIMITER; 54 | } 55 | 56 | public static function passthru_cmd($cmd) { 57 | $rc = null; 58 | passthru($cmd, $rc); 59 | return $rc; 60 | } 61 | 62 | public static function exec_cmdv($cmdv) { 63 | if (!is_array($cmdv)) { 64 | $cmdv = func_get_args(); 65 | } 66 | $cmd = implode(' ', array_map('escapeshellarg', $cmdv)); 67 | 68 | $lines = []; 69 | $rc = null; 70 | exec($cmd, $lines, $rc); 71 | return implode("\n", $lines); 72 | } 73 | 74 | public static function exec_0($cmd) { 75 | $lines = []; 76 | $rc = null; 77 | try { 78 | @exec($cmd, $lines, $rc); 79 | return $rc === 0; 80 | } catch (Exception $e) {} 81 | return false; 82 | } 83 | 84 | public static function filesize($context, $path) { 85 | $withFoldersize = $context->query_option('foldersize.enabled', false); 86 | $withDu = $context->get_setup()->get('HAS_CMD_DU') && $context->query_option('foldersize.type', null) === 'shell-du'; 87 | return Filesize::getCachedSize($path, $withFoldersize, $withDu); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /_h5ai/public/images/themes/comity/txt-less.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /_h5ai/private/conf/types.json: -------------------------------------------------------------------------------- 1 | /* h5ai v0.29.2 - https://larsjung.de/h5ai/ */ 2 | { 3 | "ar": ["*.tar.bz2", "*.crx"], 4 | "ar-apk": ["*.apk"], 5 | "ar-deb": ["*.deb"], 6 | "ar-gz": ["*.gz", "*.tar.gz", "*.tgz"], 7 | "ar-rar": ["*.rar"], 8 | "ar-rpm": ["*.rpm"], 9 | "ar-tar": ["*.tar"], 10 | "ar-zip": ["*.7z", "*.bz2", "*.jar", "*.lzma", "*.war", "*.z", "*.Z", "*.zip"], 11 | "aud": ["*.aif", "*.aiff", "*.flac", "*.m4a", "*.mid", "*.mp3", "*.mpa", "*.ra", "*.ogg", "*.wav", "*.wma"], 12 | "aud-pls": ["*.m3u", "*.m3u8", "*.pls"], 13 | "bin": ["*.class", "*.o", "*.so"], 14 | "bin-exe": ["*.bat", "*.cmd", "*.exe"], 15 | "img": ["*.xpm"], 16 | "img-bmp": ["*.bmp"], 17 | "img-gif": ["*.gif"], 18 | "img-ico": ["*.ico"], 19 | "img-jpg": ["*.jpg", "*.jpeg"], 20 | "img-png": ["*.png"], 21 | "img-raw": ["*.cr2", "*.nef"], 22 | "img-svg": ["*.svg"], 23 | "img-tiff": ["*.tiff"], 24 | "txt": ["*.text", "*.txt"], 25 | "txt-build": ["*.pom", "build.xml", "pom.xml"], 26 | "txt-c": ["*.c"], 27 | "txt-cpp": ["*.cpp"], 28 | "txt-css": ["*.css"], 29 | "txt-diff": ["*.diff", "*.patch"], 30 | "txt-go": ["*.go"], 31 | "txt-h": ["*.h"], 32 | "txt-html": ["*.htm", "*.html", "*.shtml", "*.xhtml"], 33 | "txt-hpp": ["*.hpp"], 34 | "txt-java": ["*.java"], 35 | "txt-scala": ["*.scala"], 36 | "txt-js": ["*.js"], 37 | "txt-json": ["*.json"], 38 | "txt-less": ["*.less"], 39 | "txt-log": ["*.log", "changelog*"], 40 | "txt-md": ["*.markdown", "*.md"], 41 | "txt-php": ["*.php"], 42 | "txt-py": ["*.py"], 43 | "txt-rb": ["*.rb"], 44 | "txt-rss": ["*.rss"], 45 | "txt-rtf": ["*.rtf"], 46 | "txt-rust": ["*.rs", "*.rlib"], 47 | "txt-script": ["*.conf", "*.bsh", "*.csh", "*.ini", "*.ksh", "*.sh", "*.shar", "*.tcl", "*.zsh"], 48 | "txt-source": [], 49 | "txt-tex": ["*.tex"], 50 | "txt-vcal": ["*.vcal"], 51 | "txt-xml": ["*.xml"], 52 | "vid": [], 53 | "vid-avi": ["*.avi"], 54 | "vid-flv": ["*.flv"], 55 | "vid-mkv": ["*.mkv"], 56 | "vid-mov": ["*.mov"], 57 | "vid-mp4": ["*.mp4", "*.m4v"], 58 | "vid-mpg": ["*.mpg"], 59 | "vid-rm": ["*.rm"], 60 | "vid-swf": ["*.swf"], 61 | "vid-ts": ["*.ts"], 62 | "vid-vob": ["*.vob"], 63 | "vid-webm": ["*.webm"], 64 | "vid-wmv": ["*.wmv"], 65 | "x": [], 66 | "x-bak": ["*.bak", "*~"], 67 | "x-calc": ["*.ods", "*.ots", "*.xlr", "*.xls", "*.xlsx"], 68 | "x-disc": ["*.cue", "*.iso"], 69 | "x-doc": ["*.doc", "*.docx", "*.odm", "*.odt", "*.ott"], 70 | "x-draw": ["*.drw"], 71 | "x-eps": ["*.eps"], 72 | "x-pdf": ["*.pdf"], 73 | "x-pres": ["*.odp", "*.otp", "*.pps", "*.ppt", "*.pptx"], 74 | "x-ps": ["*.ps"], 75 | "x-psd": ["*.psd"] 76 | } 77 | -------------------------------------------------------------------------------- /_h5ai/public/login.php: -------------------------------------------------------------------------------- 1 | 23 | 24 | 25 | 26 | 27 | 28 | 100 | 101 | 102 |
103 |
104 |

请登录

105 | 106 | 107 | 108 |
109 |
110 | 111 | 112 | 117 | -------------------------------------------------------------------------------- /_h5ai/public/images/themes/comity/txt-rust.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_h5ai/public/images/themes/comity/ar-rpm.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /_h5ai/public/images/ui/paypal.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /_h5ai/private/php/core/class-api.php: -------------------------------------------------------------------------------- 1 | context = $context; 10 | $this->request = $context->get_request(); 11 | $this->setup = $context->get_setup(); 12 | } 13 | 14 | public function apply() { 15 | $action = $this->request->query('action'); 16 | $supported = ['download', 'get', 'login', 'logout']; 17 | Util::json_fail(Util::ERR_UNSUPPORTED, 'unsupported action', !in_array($action, $supported)); 18 | 19 | $methodname = 'on_' . $action; 20 | $this->$methodname(); 21 | } 22 | 23 | private function on_download() { 24 | Util::json_fail(Util::ERR_DISABLED, 'download disabled', !$this->context->query_option('download.enabled', false)); 25 | 26 | $as = $this->request->query('as'); 27 | $type = $this->request->query('type'); 28 | $base_href = $this->request->query('baseHref'); 29 | $hrefs = $this->request->query('hrefs', ''); 30 | 31 | $archive = new Archive($this->context); 32 | 33 | set_time_limit(0); 34 | header('Content-Type: application/octet-stream'); 35 | header('Content-Disposition: attachment; filename="' . $as . '"'); 36 | header('Connection: close'); 37 | $ok = $archive->output($type, $base_href, $hrefs); 38 | 39 | Util::json_fail(Util::ERR_FAILED, 'packaging failed', !$ok); 40 | exit; 41 | } 42 | 43 | private function on_get() { 44 | $response = []; 45 | 46 | foreach (['langs', 'options', 'types'] as $name) { 47 | if ($this->request->query_boolean($name, false)) { 48 | $methodname = 'get_' . $name; 49 | $response[$name] = $this->context->$methodname(); 50 | } 51 | } 52 | 53 | if ($this->request->query_boolean('setup', false)) { 54 | $response['setup'] = $this->setup->to_jsono($this->context->is_admin()); 55 | } 56 | 57 | if ($this->request->query_boolean('theme', false)) { 58 | $theme = new Theme($this->context); 59 | $response['theme'] = $theme->get_icons(); 60 | } 61 | 62 | if ($this->request->query('items', false)) { 63 | $href = $this->request->query('items.href'); 64 | $what = $this->request->query_numeric('items.what'); 65 | $response['items'] = $this->context->get_items($href, $what); 66 | } 67 | 68 | if ($this->request->query('custom', false)) { 69 | Util::json_fail(Util::ERR_DISABLED, 'custom disabled', !$this->context->query_option('custom.enabled', false)); 70 | $href = $this->request->query('custom'); 71 | $custom = new Custom($this->context); 72 | $response['custom'] = $custom->get_customizations($href); 73 | } 74 | 75 | if ($this->request->query('l10n', false)) { 76 | Util::json_fail(Util::ERR_DISABLED, 'l10n disabled', !$this->context->query_option('l10n.enabled', false)); 77 | $iso_codes = $this->request->query_array('l10n'); 78 | $iso_codes = array_filter($iso_codes); 79 | $response['l10n'] = $this->context->get_l10n($iso_codes); 80 | } 81 | 82 | if ($this->request->query('search', false)) { 83 | Util::json_fail(Util::ERR_DISABLED, 'search disabled', !$this->context->query_option('search.enabled', false)); 84 | $href = $this->request->query('search.href'); 85 | $pattern = $this->request->query('search.pattern'); 86 | $ignorecase = $this->request->query_boolean('search.ignorecase', false); 87 | $search = new Search($this->context); 88 | $response['search'] = $search->get_items($href, $pattern, $ignorecase); 89 | } 90 | 91 | if ($this->request->query('thumbs', false)) { 92 | Util::json_fail(Util::ERR_DISABLED, 'thumbnails disabled', !$this->context->query_option('thumbnails.enabled', false)); 93 | Util::json_fail(Util::ERR_UNSUPPORTED, 'thumbnails not supported', !$this->setup->get('HAS_PHP_JPEG')); 94 | $thumbs = $this->request->query_array('thumbs'); 95 | $response['thumbs'] = $this->context->get_thumbs($thumbs); 96 | } 97 | 98 | Util::json_exit($response); 99 | } 100 | 101 | private function on_login() { 102 | $pass = $this->request->query('pass'); 103 | Util::json_exit(['asAdmin' => $this->context->login_admin($pass)]); 104 | } 105 | 106 | private function on_logout() { 107 | Util::json_exit(['asAdmin' => $this->context->logout_admin()]); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /_h5ai/public/images/themes/comity/ar-deb.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /_h5ai/public/images/themes/comity/txt-go.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /_h5ai/private/php/ext/class-archive.php: -------------------------------------------------------------------------------- 1 | context = $context; 17 | } 18 | 19 | public function output($type, $base_href, $hrefs) { 20 | $this->base_path = $this->context->to_path($base_href); 21 | if (!$this->context->is_managed_path($this->base_path)) { 22 | return false; 23 | } 24 | 25 | $this->dirs = []; 26 | $this->files = []; 27 | 28 | $this->add_hrefs($hrefs); 29 | 30 | if (count($this->dirs) === 0 && count($this->files) === 0) { 31 | if ($type === 'php-tar') { 32 | $this->add_dir($this->base_path, '/'); 33 | } else { 34 | $this->add_dir($this->base_path, '.'); 35 | } 36 | } 37 | 38 | if ($type === 'php-tar') { 39 | return $this->php_tar($this->dirs, $this->files); 40 | } elseif ($type === 'shell-tar') { 41 | return $this->shell_cmd(Archive::$TAR_PASSTHRU_CMD); 42 | } elseif ($type === 'shell-zip') { 43 | return $this->shell_cmd(Archive::$ZIP_PASSTHRU_CMD); 44 | } 45 | return false; 46 | } 47 | 48 | private function shell_cmd($cmd) { 49 | $cmd = str_replace('[ROOTDIR]', escapeshellarg($this->base_path), $cmd); 50 | $cmd = str_replace('[DIRS]', count($this->dirs) ? implode(' ', array_map('escapeshellarg', $this->dirs)) : '', $cmd); 51 | $cmd = str_replace('[FILES]', count($this->files) ? implode(' ', array_map('escapeshellarg', $this->files)) : '', $cmd); 52 | try { 53 | Util::passthru_cmd($cmd); 54 | } catch (Exeption $err) { 55 | return false; 56 | } 57 | return true; 58 | } 59 | 60 | private function php_tar($dirs, $files) { 61 | $filesizes = []; 62 | $total_size = 512 * count($dirs); 63 | foreach (array_keys($files) as $real_file) { 64 | $size = filesize($real_file); 65 | 66 | $filesizes[$real_file] = $size; 67 | $total_size += 512 + $size; 68 | if ($size % 512 != 0) { 69 | $total_size += 512 - ($size % 512); 70 | } 71 | } 72 | 73 | header('Content-Length: ' . $total_size); 74 | 75 | foreach ($dirs as $real_dir => $archived_dir) { 76 | echo $this->php_tar_header($archived_dir, 0, @filemtime($real_dir . DIRECTORY_SEPARATOR . '.'), 5); 77 | } 78 | 79 | foreach ($files as $real_file => $archived_file) { 80 | $size = $filesizes[$real_file]; 81 | 82 | echo $this->php_tar_header($archived_file, $size, @filemtime($real_file), 0); 83 | $this->print_file($real_file); 84 | 85 | if ($size % 512 != 0) { 86 | echo str_repeat(Archive::NULL_BYTE, 512 - ($size % 512)); 87 | } 88 | } 89 | 90 | return true; 91 | } 92 | 93 | private function php_tar_header($filename, $size, $mtime, $type) { 94 | $name = substr(basename($filename), -99); 95 | $prefix = substr(Util::normalize_path(dirname($filename)), -154); 96 | if ($prefix === '.') { 97 | $prefix = ''; 98 | } 99 | 100 | $header = 101 | str_pad($name, 100, Archive::NULL_BYTE) // filename [100] 102 | . '0000755' . Archive::NULL_BYTE // file mode [8] 103 | . '0000000' . Archive::NULL_BYTE // uid [8] 104 | . '0000000' . Archive::NULL_BYTE // gid [8] 105 | . str_pad(decoct($size), 11, '0', STR_PAD_LEFT) . Archive::NULL_BYTE // file size [12] 106 | . str_pad(decoct($mtime), 11, '0', STR_PAD_LEFT) . Archive::NULL_BYTE // file modification time [12] 107 | . ' ' // checksum [8] 108 | . str_pad($type, 1) // file type [1] 109 | . str_repeat(Archive::NULL_BYTE, 100) // linkname [100] 110 | . 'ustar' . Archive::NULL_BYTE // magic [6] 111 | . '00' // version [2] 112 | . str_repeat(Archive::NULL_BYTE, 80) // uname, gname, defmajor, devminor [32 + 32 + 8 + 8] 113 | . str_pad($prefix, 155, Archive::NULL_BYTE) // filename [155] 114 | . str_repeat(Archive::NULL_BYTE, 12); // fill [12] 115 | assert(strlen($header) === 512); 116 | 117 | // checksum 118 | $checksum = array_sum(array_map('ord', str_split($header))); 119 | $checksum = str_pad(decoct($checksum), 6, '0', STR_PAD_LEFT) . Archive::NULL_BYTE . ' '; 120 | $header = substr_replace($header, $checksum, 148, 8); 121 | 122 | return $header; 123 | } 124 | 125 | private function print_file($file) { 126 | // Send file content in segments to not hit PHP's memory limit (default: 128M) 127 | if ($fd = fopen($file, 'rb')) { 128 | while (!feof($fd)) { 129 | print fread($fd, Archive::$SEGMENT_SIZE); 130 | @ob_flush(); 131 | @flush(); 132 | } 133 | fclose($fd); 134 | } 135 | } 136 | 137 | private function add_hrefs($hrefs) { 138 | foreach ($hrefs as $href) { 139 | if (trim($href) === '') { 140 | continue; 141 | } 142 | 143 | $d = Util::normalize_path(dirname($href), true); 144 | $n = basename($href); 145 | 146 | if ($this->context->is_managed_href($d) && !$this->context->is_hidden($n)) { 147 | 148 | $real_file = $this->context->to_path($href); 149 | $archived_file = preg_replace('!^' . preg_quote(Util::normalize_path($this->base_path, true)) . '!', '', $real_file); 150 | 151 | if (is_dir($real_file)) { 152 | $this->add_dir($real_file, $archived_file); 153 | } else { 154 | $this->add_file($real_file, $archived_file); 155 | } 156 | } 157 | } 158 | } 159 | 160 | private function add_file($real_file, $archived_file) { 161 | if (is_readable($real_file)) { 162 | $this->files[$real_file] = $archived_file; 163 | } 164 | } 165 | 166 | private function add_dir($real_dir, $archived_dir) { 167 | if ($this->context->is_managed_path($real_dir)) { 168 | $this->dirs[$real_dir] = $archived_dir; 169 | 170 | $files = $this->context->read_dir($real_dir); 171 | foreach ($files as $file) { 172 | $real_file = $real_dir . '/' . $file; 173 | $archived_file = $archived_dir . '/' . $file; 174 | 175 | if (is_dir($real_file)) { 176 | $this->add_dir($real_file, $archived_file); 177 | } else { 178 | $this->add_file($real_file, $archived_file); 179 | } 180 | } 181 | } 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /_h5ai/private/php/core/class-setup.php: -------------------------------------------------------------------------------- 1 | store = []; 9 | $this->refresh = $refresh; 10 | 11 | $this->add_globals_and_envs(); 12 | $this->add_php_checks(); 13 | $this->add_app_metadata(); 14 | $this->add_server_metadata_and_check(); 15 | $this->add_paths(); 16 | $this->add_sys_cmd_checks(); 17 | } 18 | 19 | private function set($key, $value) { 20 | if (array_key_exists($key, $this->store)) { 21 | Logger::log('setup key already taken', [ 22 | 'key' => $key, 23 | 'value' => $value, 24 | 'found' => $this->store[$key] 25 | ]); 26 | exit; 27 | } 28 | if (!is_string($value) && !is_bool($value)) { 29 | Logger::log('setup value neither string nor boolean', [ 30 | 'key' => $key, 31 | 'value' => $value 32 | ]); 33 | exit; 34 | } 35 | 36 | $this->store[$key] = $value; 37 | } 38 | 39 | public function get($key) { 40 | if (!array_key_exists($key, $this->store)) { 41 | Logger::log('setup key not found', ['key' => $key]); 42 | exit; 43 | } 44 | 45 | return $this->store[$key]; 46 | } 47 | 48 | private function add_globals_and_envs() { 49 | $this->set('PHP_VERSION', PHP_VERSION); 50 | $this->set('MIN_PHP_VERSION', MIN_PHP_VERSION); 51 | $this->set('PHP_ARCH', (PHP_INT_SIZE * 8) . '-bit'); 52 | 53 | $this->set('REQUEST_METHOD', $_SERVER['REQUEST_METHOD']); 54 | $this->set('REQUEST_HREF', parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)); 55 | $this->set('SCRIPT_NAME', $_SERVER['SCRIPT_NAME']); 56 | $this->set('SERVER_SOFTWARE', $_SERVER['SERVER_SOFTWARE']); 57 | $this->set('HTTP_USER_AGENT', $_SERVER['HTTP_USER_AGENT']); 58 | } 59 | 60 | private function add_php_checks() { 61 | $this->set('HAS_PHP_EXIF', function_exists('exif_thumbnail')); 62 | 63 | $has_php_jpeg = false; 64 | if (function_exists('gd_info')) { 65 | $infos = gd_info(); 66 | $has_php_jpeg = array_key_exists('JPEG Support', $infos) && $infos['JPEG Support']; 67 | } 68 | $this->set('HAS_PHP_JPEG', $has_php_jpeg); 69 | } 70 | 71 | private function add_app_metadata() { 72 | $this->set('NAME', 'h5ai'); 73 | $this->set('VERSION', H5AI_VERSION); 74 | $this->set('FILE_PREFIX', '_h5ai'); 75 | } 76 | 77 | private function add_server_metadata_and_check() { 78 | $server_software = $this->get('SERVER_SOFTWARE'); 79 | $server_name = null; 80 | $server_version = null; 81 | 82 | if ($server_software && preg_match('#^(.*?)(?:/(.*?))?(?: |$)#', strtolower($server_software), $matches)) { 83 | $server_name = $matches[1]; 84 | $server_version = count($matches) > 2 ? $matches[2] : ''; 85 | } 86 | 87 | $this->set('SERVER_NAME', $server_name); 88 | $this->set('SERVER_VERSION', $server_version); 89 | $this->set('HAS_SERVER', in_array($server_name, ['apache', 'lighttpd', 'nginx', 'cherokee'])); 90 | } 91 | 92 | private function add_paths() { 93 | $script_name = $this->get('SCRIPT_NAME'); 94 | if ($this->get('SERVER_NAME') === 'lighttpd') { 95 | $script_name = preg_replace('#^.*?//#', '/', $script_name); 96 | } 97 | 98 | $this->set('H5AI_HREF', Util::normalize_path(dirname(dirname($script_name)), true)); 99 | $this->set('H5AI_PATH', Util::normalize_path(dirname(dirname(dirname(dirname(__FILE__)))), false)); 100 | 101 | $this->set('ROOT_HREF', Util::normalize_path(dirname($this->get('H5AI_HREF')), true)); 102 | $this->set('ROOT_PATH', Util::normalize_path(dirname($this->get('H5AI_PATH')), false)); 103 | 104 | $this->set('PUBLIC_HREF', Util::normalize_path($this->get('H5AI_HREF') . '/public/', true)); 105 | $this->set('PUBLIC_PATH', Util::normalize_path($this->get('H5AI_PATH') . '/public/', false)); 106 | 107 | $this->set('INDEX_HREF', Util::normalize_path($this->get('PUBLIC_HREF') . '/index.php', false)); 108 | $this->set('CACHE_PUB_HREF', Util::normalize_path($this->get('PUBLIC_HREF') . '/cache', true)); 109 | $this->set('CACHE_PUB_PATH', Util::normalize_path($this->get('PUBLIC_PATH') . '/cache', false)); 110 | $this->set('HAS_WRITABLE_CACHE_PUB', @is_writable($this->get('CACHE_PUB_PATH'))); 111 | 112 | $this->set('PRIVATE_PATH', Util::normalize_path($this->get('H5AI_PATH') . '/private', false)); 113 | $this->set('CONF_PATH', Util::normalize_path($this->get('PRIVATE_PATH') . '/conf', false)); 114 | $this->set('CACHE_PRV_PATH', Util::normalize_path($this->get('PRIVATE_PATH') . '/cache', false)); 115 | $this->set('HAS_WRITABLE_CACHE_PRV', @is_writable($this->get('CACHE_PRV_PATH'))); 116 | } 117 | 118 | private function add_sys_cmd_checks() { 119 | $cmds_cache_path = Util::normalize_path($this->get('CACHE_PRV_PATH') . '/cmds.json', false); 120 | 121 | $cmds = Json::load($cmds_cache_path); 122 | if (sizeof($cmds) === 0 || $this->refresh) { 123 | $cmds['command'] = Util::exec_0('command -v command'); 124 | $cmds['which'] = Util::exec_0('which which') || Util::exec_0('which which.exe'); 125 | 126 | $cmd = false; 127 | if ($cmds['command']) { 128 | $cmd = 'command -v'; 129 | } elseif ($cmds['which']) { 130 | $cmd = 'which'; 131 | } 132 | 133 | foreach (['avconv', 'convert', 'du', 'ffmpeg', 'gm', 'tar', 'zip'] as $c) { 134 | $cmds[$c] = ($cmd !== false) && (Util::exec_0($cmd . ' ' . $c) || Util::exec_0($cmd . ' ' . $c . '.exe')); 135 | } 136 | 137 | Json::save($cmds_cache_path, $cmds); 138 | } 139 | foreach ($cmds as $c => $has) { 140 | $this->set('HAS_CMD_' . strtoupper($c), $has); 141 | } 142 | } 143 | 144 | public function to_jsono($as_admin = false) { 145 | $keys = [ 146 | 'PUBLIC_HREF', 147 | 'ROOT_HREF' 148 | ]; 149 | 150 | if ($as_admin) { 151 | $keys = array_merge($keys, [ 152 | 'VERSION', 153 | 154 | 'PHP_VERSION', 155 | 'MIN_PHP_VERSION', 156 | 'PHP_ARCH', 157 | 'HAS_PHP_EXIF', 158 | 'HAS_PHP_JPEG', 159 | 160 | 'SERVER_NAME', 161 | 'SERVER_VERSION', 162 | 'HAS_SERVER', 163 | 164 | 'INDEX_HREF', 165 | 166 | 'HAS_WRITABLE_CACHE_PUB', 167 | 'HAS_WRITABLE_CACHE_PRV', 168 | 169 | 'HAS_CMD_AVCONV', 170 | 'HAS_CMD_CONVERT', 171 | 'HAS_CMD_DU', 172 | 'HAS_CMD_FFMPEG', 173 | 'HAS_CMD_GM', 174 | 'HAS_CMD_TAR', 175 | 'HAS_CMD_ZIP' 176 | ]); 177 | } 178 | 179 | $jsono = ['AS_ADMIN' => $as_admin]; 180 | foreach ($keys as $key) { 181 | $jsono[$key] = $this->get($key); 182 | } 183 | return $jsono; 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /_h5ai/.htaccess: -------------------------------------------------------------------------------- 1 | ## details here: https://github.com/h5bp/server-configs-apache 2 | 3 | 4 | 5 | ## SECURITY ################################################################### 6 | 7 | DirectoryIndex disabled 8 | FileETag None 9 | ServerSignature Off 10 | 11 | # Apache < 2.3 12 | 13 | Order allow,deny 14 | Deny from all 15 | Satisfy All 16 | 17 | 18 | # Apache ≥ 2.3 19 | 20 | Require all denied 21 | 22 | 23 | 24 | Header set X-Content-Type-Options "nosniff" 25 | Header unset ETag 26 | Header unset X-Powered-By 27 | 28 | 29 | 30 | Options -Indexes 31 | 32 | 33 | 34 | 35 | ## COMPAT ##################################################################### 36 | 37 | AddDefaultCharset utf-8 38 | 39 | 40 | AddCharset utf-8 .css .html .js .json .php .svg 41 | 42 | AddType application/font-woff woff 43 | AddType application/font-woff2 woff2 44 | AddType application/json json 45 | AddType application/javascript js 46 | AddType application/vnd.ms-fontobject eot 47 | AddType application/x-font-ttf ttc ttf 48 | AddType image/jpeg jpeg jpg 49 | AddType image/png png 50 | AddType image/svg+xml svg svgz 51 | AddType image/x-icon ico 52 | AddType font/opentype otf 53 | AddType text/css css 54 | AddType text/html html 55 | 56 | 57 | 58 | 59 | ## SPEED ###################################################################### 60 | 61 | 62 | ExpiresActive on 63 | ExpiresDefault "access plus 1 month" 64 | 65 | ExpiresByType application/json "access plus 0 seconds" 66 | 67 | ExpiresByType text/html "access plus 1 minute" 68 | 69 | ExpiresByType image/x-icon "access plus 1 week" 70 | 71 | ExpiresByType application/javascript "access plus 1 year" 72 | ExpiresByType image/jpeg "access plus 1 year" 73 | ExpiresByType image/png "access plus 1 year" 74 | ExpiresByType image/svg+xml "access plus 1 year" 75 | ExpiresByType text/css "access plus 1 year" 76 | 77 | 78 | 79 | 80 | 81 | SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding 82 | RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding 83 | 84 | 85 | 86 | # Apache ≥ 2.3 87 | 88 | # mod_filter as module only available for Apache ≥ 2.3.7 89 | 90 | AddOutputFilterByType DEFLATE "application/atom+xml" \ 91 | "application/javascript" \ 92 | "application/json" \ 93 | "application/ld+json" \ 94 | "application/manifest+json" \ 95 | "application/rdf+xml" \ 96 | "application/rss+xml" \ 97 | "application/schema+json" \ 98 | "application/vnd.geo+json" \ 99 | "application/vnd.ms-fontobject" \ 100 | "application/x-font-ttf" \ 101 | "application/x-javascript" \ 102 | "application/x-web-app-manifest+json" \ 103 | "application/xhtml+xml" \ 104 | "application/xml" \ 105 | "font/eot" \ 106 | "font/opentype" \ 107 | "image/bmp" \ 108 | "image/svg+xml" \ 109 | "image/vnd.microsoft.icon" \ 110 | "image/x-icon" \ 111 | "text/cache-manifest" \ 112 | "text/css" \ 113 | "text/html" \ 114 | "text/javascript" \ 115 | "text/plain" \ 116 | "text/vcard" \ 117 | "text/vnd.rim.location.xloc" \ 118 | "text/vtt" \ 119 | "text/x-component" \ 120 | "text/x-cross-domain-policy" \ 121 | "text/xml" 122 | 123 | 124 | 125 | # Apache < 2.3 126 | 127 | AddOutputFilterByType DEFLATE "application/atom+xml" \ 128 | "application/javascript" \ 129 | "application/json" \ 130 | "application/ld+json" \ 131 | "application/manifest+json" \ 132 | "application/rdf+xml" \ 133 | "application/rss+xml" \ 134 | "application/schema+json" \ 135 | "application/vnd.geo+json" \ 136 | "application/vnd.ms-fontobject" \ 137 | "application/x-font-ttf" \ 138 | "application/x-javascript" \ 139 | "application/x-web-app-manifest+json" \ 140 | "application/xhtml+xml" \ 141 | "application/xml" \ 142 | "font/eot" \ 143 | "font/opentype" \ 144 | "image/bmp" \ 145 | "image/svg+xml" \ 146 | "image/vnd.microsoft.icon" \ 147 | "image/x-icon" \ 148 | "text/cache-manifest" \ 149 | "text/css" \ 150 | "text/html" \ 151 | "text/javascript" \ 152 | "text/plain" \ 153 | "text/vcard" \ 154 | "text/vnd.rim.location.xloc" \ 155 | "text/vtt" \ 156 | "text/x-component" \ 157 | "text/x-cross-domain-policy" \ 158 | "text/xml" 159 | 160 | 161 | 162 | AddEncoding gzip gz 163 | AddEncoding gzip svgz 164 | 165 | 166 | -------------------------------------------------------------------------------- /_h5ai/private/php/ext/class-thumb.php: -------------------------------------------------------------------------------- 1 | context = $context; 17 | $this->setup = $context->get_setup(); 18 | $this->thumbs_path = $this->setup->get('CACHE_PUB_PATH') . '/' . Thumb::$THUMB_CACHE; 19 | $this->thumbs_href = $this->setup->get('CACHE_PUB_HREF') . Thumb::$THUMB_CACHE; 20 | 21 | if (!is_dir($this->thumbs_path)) { 22 | @mkdir($this->thumbs_path, 0755, true); 23 | } 24 | } 25 | 26 | public function thumb($type, $source_href, $width, $height) { 27 | $source_path = $this->context->to_path($source_href); 28 | if (!file_exists($source_path) || Util::starts_with($source_path, $this->setup->get('CACHE_PUB_PATH'))) { 29 | return null; 30 | } 31 | 32 | $capture_path = $source_path; 33 | if ($type === 'img') { 34 | $capture_path = $source_path; 35 | } elseif ($type === 'mov') { 36 | if ($this->setup->get('HAS_CMD_AVCONV')) { 37 | $capture_path = $this->capture(Thumb::$AVCONV_CMDV, $source_path); 38 | } elseif ($this->setup->get('HAS_CMD_FFMPEG')) { 39 | $capture_path = $this->capture(Thumb::$FFMPEG_CMDV, $source_path); 40 | } 41 | } elseif ($type === 'doc') { 42 | if ($this->setup->get('HAS_CMD_CONVERT')) { 43 | $capture_path = $this->capture(Thumb::$CONVERT_CMDV, $source_path); 44 | } elseif ($this->setup->get('HAS_CMD_GM')) { 45 | $capture_path = $this->capture(Thumb::$GM_CONVERT_CMDV, $source_path); 46 | } 47 | } 48 | 49 | return $this->thumb_href($capture_path, $width, $height); 50 | } 51 | 52 | private function thumb_href($source_path, $width, $height) { 53 | if (!file_exists($source_path)) { 54 | return null; 55 | } 56 | 57 | $name = 'thumb-' . sha1($source_path) . '-' . $width . 'x' . $height . '.jpg'; 58 | $thumb_path = $this->thumbs_path . '/' . $name; 59 | $thumb_href = $this->thumbs_href . '/' . $name; 60 | 61 | if (!file_exists($thumb_path) || filemtime($source_path) >= filemtime($thumb_path)) { 62 | $image = new Image(); 63 | 64 | $et = false; 65 | if ($this->setup->get('HAS_PHP_EXIF') && $this->context->query_option('thumbnails.exif', false) === true && $height != 0) { 66 | $et = @exif_thumbnail($source_path); 67 | } 68 | if($et !== false) { 69 | file_put_contents($thumb_path, $et); 70 | $image->set_source($thumb_path); 71 | $image->normalize_exif_orientation($source_path); 72 | } else { 73 | $image->set_source($source_path); 74 | } 75 | 76 | $image->thumb($width, $height); 77 | $image->save_dest_jpeg($thumb_path, 80); 78 | } 79 | 80 | return file_exists($thumb_path) ? $thumb_href : null; 81 | } 82 | 83 | private function capture($cmdv, $source_path) { 84 | if (!file_exists($source_path)) { 85 | return null; 86 | } 87 | 88 | $capture_path = $this->thumbs_path . '/capture-' . sha1($source_path) . '.jpg'; 89 | 90 | if (!file_exists($capture_path) || filemtime($source_path) >= filemtime($capture_path)) { 91 | foreach ($cmdv as &$arg) { 92 | $arg = str_replace('[SRC]', $source_path, $arg); 93 | $arg = str_replace('[DEST]', $capture_path, $arg); 94 | } 95 | 96 | Util::exec_cmdv($cmdv); 97 | } 98 | 99 | return file_exists($capture_path) ? $capture_path : null; 100 | } 101 | } 102 | 103 | class Image { 104 | private $source_file; 105 | private $source; 106 | private $width; 107 | private $height; 108 | private $type; 109 | private $dest; 110 | 111 | public function __construct($filename = null) { 112 | $this->source_file = null; 113 | $this->source = null; 114 | $this->width = null; 115 | $this->height = null; 116 | $this->type = null; 117 | 118 | $this->dest = null; 119 | 120 | $this->set_source($filename); 121 | } 122 | 123 | public function __destruct() { 124 | $this->release_source(); 125 | $this->release_dest(); 126 | } 127 | 128 | public function set_source($filename) { 129 | $this->release_source(); 130 | $this->release_dest(); 131 | 132 | if (is_null($filename)) { 133 | return; 134 | } 135 | 136 | $this->source_file = $filename; 137 | 138 | list($this->width, $this->height, $this->type) = @getimagesize($this->source_file); 139 | 140 | if (!$this->width || !$this->height) { 141 | $this->source_file = null; 142 | $this->width = null; 143 | $this->height = null; 144 | $this->type = null; 145 | return; 146 | } 147 | 148 | $this->source = imagecreatefromstring(file_get_contents($this->source_file)); 149 | } 150 | 151 | public function save_dest_jpeg($filename, $quality = 80) { 152 | if (!is_null($this->dest)) { 153 | @imagejpeg($this->dest, $filename, $quality); 154 | @chmod($filename, 0775); 155 | } 156 | } 157 | 158 | public function release_dest() { 159 | if (!is_null($this->dest)) { 160 | @imagedestroy($this->dest); 161 | $this->dest = null; 162 | } 163 | } 164 | 165 | public function release_source() { 166 | if (!is_null($this->source)) { 167 | @imagedestroy($this->source); 168 | $this->source_file = null; 169 | $this->source = null; 170 | $this->width = null; 171 | $this->height = null; 172 | $this->type = null; 173 | } 174 | } 175 | 176 | public function thumb($width, $height) { 177 | if (is_null($this->source)) { 178 | return; 179 | } 180 | 181 | $src_r = 1.0 * $this->width / $this->height; 182 | 183 | if ($height == 0) { 184 | if ($src_r >= 1) { 185 | $height = 1.0 * $width / $src_r; 186 | } else { 187 | $height = $width; 188 | $width = 1.0 * $height * $src_r; 189 | } 190 | if ($width > $this->width) { 191 | $width = $this->width; 192 | $height = $this->height; 193 | } 194 | } 195 | 196 | $ratio = 1.0 * $width / $height; 197 | 198 | if ($src_r <= $ratio) { 199 | $src_w = $this->width; 200 | $src_h = $src_w / $ratio; 201 | $src_x = 0; 202 | } else { 203 | $src_h = $this->height; 204 | $src_w = $src_h * $ratio; 205 | $src_x = 0.5 * ($this->width - $src_w); 206 | } 207 | 208 | $width = intval($width); 209 | $height = intval($height); 210 | $src_x = intval($src_x); 211 | $src_w = intval($src_w); 212 | $src_h = intval($src_h); 213 | 214 | $this->dest = imagecreatetruecolor($width, $height); 215 | $icol = imagecolorallocate($this->dest, 255, 255, 255); 216 | imagefill($this->dest, 0, 0, $icol); 217 | imagecopyresampled($this->dest, $this->source, 0, 0, $src_x, 0, $width, $height, $src_w, $src_h); 218 | } 219 | 220 | public function rotate($angle) { 221 | if (is_null($this->source) || ($angle !== 90 && $angle !== 180 && $angle !== 270)) { 222 | return; 223 | } 224 | 225 | $this->source = imagerotate($this->source, $angle, 0); 226 | if ( $angle === 90 || $angle === 270 ) { 227 | list($this->width, $this->height) = [$this->height, $this->width]; 228 | } 229 | } 230 | 231 | public function normalize_exif_orientation($exif_source_file = null) { 232 | if (is_null($this->source) || !function_exists('exif_read_data')) { 233 | return; 234 | } 235 | 236 | if ($exif_source_file === null) { 237 | $exif_source_file = $this->source_file; 238 | } 239 | 240 | $exif = exif_read_data($exif_source_file); 241 | switch (@$exif['Orientation']) { 242 | case 3: 243 | $this->rotate(180); 244 | break; 245 | case 6: 246 | $this->rotate(270); 247 | break; 248 | case 8: 249 | $this->rotate(90); 250 | break; 251 | } 252 | } 253 | } 254 | -------------------------------------------------------------------------------- /_h5ai/private/php/core/class-context.php: -------------------------------------------------------------------------------- 1 | session = $session; 15 | $this->request = $request; 16 | $this->setup = $setup; 17 | 18 | $this->options = Json::load($this->setup->get('CONF_PATH') . '/options.json'); 19 | 20 | $this->passhash = $this->query_option('passhash', ''); 21 | $this->options['hasCustomPasshash'] = strcasecmp($this->passhash, Context::$DEFAULT_PASSHASH) !== 0; 22 | unset($this->options['passhash']); 23 | } 24 | 25 | public function get_session() { 26 | return $this->session; 27 | } 28 | 29 | public function get_request() { 30 | return $this->request; 31 | } 32 | 33 | public function get_setup() { 34 | return $this->setup; 35 | } 36 | 37 | public function get_options() { 38 | return $this->options; 39 | } 40 | 41 | public function query_option($keypath = '', $default = null) { 42 | return Util::array_query($this->options, $keypath, $default); 43 | } 44 | 45 | public function get_types() { 46 | return Json::load($this->setup->get('CONF_PATH') . '/types.json'); 47 | } 48 | 49 | public function login_admin($pass) { 50 | $this->session->set(Context::$AS_ADMIN_SESSION_KEY, strcasecmp(hash('sha512', $pass), $this->passhash) === 0); 51 | return $this->session->get(Context::$AS_ADMIN_SESSION_KEY); 52 | } 53 | 54 | public function logout_admin() { 55 | $this->session->set(Context::$AS_ADMIN_SESSION_KEY, false); 56 | return $this->session->get(Context::$AS_ADMIN_SESSION_KEY); 57 | } 58 | 59 | public function is_admin() { 60 | return $this->session->get(Context::$AS_ADMIN_SESSION_KEY); 61 | } 62 | 63 | public function is_api_request() { 64 | return strtolower($this->setup->get('REQUEST_METHOD')) === 'post'; 65 | } 66 | 67 | public function is_info_request() { 68 | return Util::starts_with($this->setup->get('REQUEST_HREF') . '/', $this->setup->get('PUBLIC_HREF')); 69 | } 70 | 71 | public function is_text_browser() { 72 | return preg_match('/curl|links|lynx|w3m/i', $this->setup->get('HTTP_USER_AGENT')) === 1; 73 | } 74 | 75 | public function is_fallback_mode() { 76 | return $this->query_option('view.fallbackMode', false) || $this->is_text_browser(); 77 | } 78 | 79 | public function to_href($path, $trailing_slash = true) { 80 | $rel_path = substr($path, strlen($this->setup->get('ROOT_PATH'))); 81 | $parts = explode('/', $rel_path); 82 | $encoded_parts = []; 83 | foreach ($parts as $part) { 84 | if ($part != '') { 85 | $encoded_parts[] = rawurlencode($part); 86 | } 87 | } 88 | 89 | return Util::normalize_path($this->setup->get('ROOT_HREF') . implode('/', $encoded_parts), $trailing_slash); 90 | } 91 | 92 | public function to_path($href) { 93 | $rel_href = substr($href, strlen($this->setup->get('ROOT_HREF'))); 94 | return Util::normalize_path($this->setup->get('ROOT_PATH') . '/' . rawurldecode($rel_href)); 95 | } 96 | 97 | public function is_hidden($name) { 98 | // always hide 99 | if ($name === '.' || $name === '..') { 100 | return true; 101 | } 102 | 103 | foreach ($this->query_option('view.hidden', []) as $re) { 104 | $re = Util::wrap_pattern($re); 105 | if (preg_match($re, $name)) { 106 | return true; 107 | } 108 | } 109 | 110 | return false; 111 | } 112 | 113 | public function read_dir($path) { 114 | $names = []; 115 | if (is_dir($path)) { 116 | foreach (scandir($path) as $name) { 117 | if ( 118 | $this->is_hidden($name) 119 | || $this->is_hidden($this->to_href($path) . $name) 120 | || (!is_readable($path . '/' . $name) && $this->query_option('view.hideIf403', false)) 121 | ) { 122 | continue; 123 | } 124 | $names[] = $name; 125 | } 126 | } 127 | return $names; 128 | } 129 | 130 | public function is_managed_href($href) { 131 | return $this->is_managed_path($this->to_path($href)); 132 | } 133 | 134 | public function is_managed_path($path) { 135 | if (!is_dir($path) || strpos($path, '../') !== false || strpos($path, '/..') !== false || $path === '..') { 136 | return false; 137 | } 138 | 139 | if (strpos($path, $this->setup->get('PUBLIC_PATH')) === 0) { 140 | return false; 141 | } 142 | 143 | if (strpos($path, $this->setup->get('PRIVATE_PATH')) === 0) { 144 | return false; 145 | } 146 | 147 | foreach ($this->query_option('view.unmanaged', []) as $name) { 148 | if (file_exists($path . '/' . $name)) { 149 | return false; 150 | } 151 | } 152 | 153 | while ($path !== $this->setup->get('ROOT_PATH')) { 154 | if (@is_dir($path . '/_h5ai/private/conf')) { 155 | return false; 156 | } 157 | $parent_path = Util::normalize_path(dirname($path)); 158 | if ($parent_path === $path) { 159 | return false; 160 | } 161 | $path = $parent_path; 162 | } 163 | return true; 164 | } 165 | 166 | public function get_current_path() { 167 | $current_href = Util::normalize_path($this->setup->get('REQUEST_HREF'), true); 168 | $current_path = $this->to_path($current_href); 169 | 170 | if (!is_dir($current_path)) { 171 | $current_path = Util::normalize_path(dirname($current_path), false); 172 | } 173 | 174 | return $current_path; 175 | } 176 | 177 | public function get_items($href, $what) { 178 | if (!$this->is_managed_href($href)) { 179 | return []; 180 | } 181 | 182 | $cache = []; 183 | $folder = Item::get($this, $this->to_path($href), $cache); 184 | 185 | // add content of subfolders 186 | if ($what >= 2 && $folder !== null) { 187 | foreach ($folder->get_content($cache) as $item) { 188 | $item->get_content($cache); 189 | } 190 | $folder = $folder->get_parent($cache); 191 | } 192 | 193 | // add content of this folder and all parent folders 194 | while ($what >= 1 && $folder !== null) { 195 | $folder->get_content($cache); 196 | $folder = $folder->get_parent($cache); 197 | } 198 | 199 | uasort($cache, ['Item', 'cmp']); 200 | $result = []; 201 | foreach ($cache as $p => $item) { 202 | $result[] = $item->to_json_object(); 203 | } 204 | 205 | return $result; 206 | } 207 | 208 | public function get_langs() { 209 | $langs = []; 210 | $l10n_path = $this->setup->get('CONF_PATH') . '/l10n'; 211 | if (is_dir($l10n_path)) { 212 | if ($dir = opendir($l10n_path)) { 213 | while (($file = readdir($dir)) !== false) { 214 | if (Util::ends_with($file, '.json')) { 215 | $translations = Json::load($l10n_path . '/' . $file); 216 | $langs[basename($file, '.json')] = $translations['lang']; 217 | } 218 | } 219 | closedir($dir); 220 | } 221 | } 222 | ksort($langs); 223 | return $langs; 224 | } 225 | 226 | public function get_l10n($iso_codes) { 227 | $results = []; 228 | 229 | foreach ($iso_codes as $iso_code) { 230 | $file = $this->setup->get('CONF_PATH') . '/l10n/' . $iso_code . '.json'; 231 | $results[$iso_code] = Json::load($file); 232 | $results[$iso_code]['isoCode'] = $iso_code; 233 | } 234 | 235 | return $results; 236 | } 237 | 238 | public function get_thumbs($requests) { 239 | $hrefs = []; 240 | 241 | foreach ($requests as $req) { 242 | $thumb = new Thumb($this); 243 | $hrefs[] = $thumb->thumb($req['type'], $req['href'], $req['width'], $req['height']); 244 | } 245 | 246 | return $hrefs; 247 | } 248 | 249 | private function prefix_x_head_href($href) { 250 | if (preg_match('@^(https?://|/)@i', $href)) { 251 | return $href; 252 | } 253 | 254 | return $this->setup->get('PUBLIC_HREF') . 'ext/' . $href; 255 | } 256 | 257 | private function get_fonts_html() { 258 | $fonts = $this->query_option('view.fonts', []); 259 | $fonts_mono = $this->query_option('view.fontsMono', []); 260 | 261 | $html = ''; 272 | 273 | return $html; 274 | } 275 | 276 | public function get_x_head_html() { 277 | $scripts = $this->query_option('resources.scripts', []); 278 | $styles = $this->query_option('resources.styles', []); 279 | 280 | $html = ''; 281 | 282 | foreach ($styles as $href) { 283 | $html .= ''; 284 | } 285 | 286 | foreach ($scripts as $href) { 287 | $html .= ''; 288 | } 289 | 290 | $html .= $this->get_fonts_html(); 291 | 292 | return $html; 293 | } 294 | } 295 | -------------------------------------------------------------------------------- /_h5ai/private/conf/options.json: -------------------------------------------------------------------------------- 1 | /* h5ai v0.29.2 - https://larsjung.de/h5ai/ */ 2 | { 3 | /* 4 | Password hash. 5 | 6 | SHA512 hash of the info page password, the preset password is the empty string. 7 | Online hash generator: http://md5hashing.net/hashing/sha512 8 | */ 9 | "passhash": "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e", 10 | 11 | 12 | 13 | /* 14 | Resources. 15 | 16 | Additional script and style tags added to all pages. Paths not beginning 17 | with "http://", "https://" or "/" will be looked up relative to 18 | "_h5ai/public/ext/" (no check for existence). 19 | 20 | - scripts: array of strings 21 | - styles: array of strings 22 | */ 23 | "resources": { 24 | "scripts": [], 25 | "styles": [ 26 | "//fonts.googleapis.com/css?family=Ubuntu:300,400,700%7CUbuntu+Mono:400,700" 27 | ] 28 | }, 29 | 30 | 31 | 32 | /* 33 | General view options. 34 | 35 | - binaryPrefix: boolean, set to true uses 1024B=1KiB when formatting file sizes (see http://en.wikipedia.org/wiki/Binary_prefix) 36 | - disableSidebar: boolean, hides sidebar and toggle button 37 | - fallbackMode: boolean, serve fallback mode 38 | - fastBrowsing: boolean, use History API if available (no need to reload the whole page) 39 | - fonts: array of strings, fonts to use in regular context 40 | - fontsMono: array of strings, fonts to use in monopspaced context 41 | - hidden: array of strings, don't list items matching these regular expressions 42 | - hideFolders: boolean, hide all folders in the main view 43 | - hideIf403: boolean, hide files and folders that are not readable by the server 44 | - hideParentFolder: boolean, hide parent folder links in the main view 45 | - maxIconSize: number, max size for icons in the main view 46 | - modes: array of strings, subset of ["details", "grid", "icons"] 47 | the first value indicates the default view mode. If only one value 48 | is given the view mode is fixed and the selector buttons are hidden. 49 | The user selected view mode is also stored local in modern browsers 50 | so that it will be persistent. 51 | - modeToggle: boolean, show a view mode toggle in the toolbar, or "next" 52 | - setParentFolderLabels: boolean, set parent folder labels to real folder names 53 | - sizes: array of numbers 54 | the first value indicates the default view size. If only one value 55 | is given the view size is fixed and the selector buttons are hidden. 56 | The user selected view size is also stored local in modern browsers 57 | so that it will be persistent. 58 | - theme: string, name of one of the folders in "_h5ai/images/themes", defaults to "default" 59 | - unmanaged: array of strings, don't manage folders containing one of those files 60 | - unmanagedInNewWindow: boolean, open unmanaged links in new window/tab 61 | */ 62 | "view": { 63 | "binaryPrefix": false, 64 | "disableSidebar": false, 65 | "fallbackMode": false, 66 | "fastBrowsing": true, 67 | "fonts": ["Ubuntu", "Roboto", "Helvetica", "Arial", "sans-serif"], 68 | "fontsMono": ["Ubuntu Mono", "Monaco", "Lucida Sans Typewriter", "monospace"], 69 | "hidden": ["^\\.", "^_h5ai","^robots.txt","^__","\\.m3u8$"], 70 | "hideFolders": false, 71 | "hideIf403": true, 72 | "hideParentFolder": false, 73 | "maxIconSize": 40, 74 | "modes": ["details", "grid", "icons"], 75 | "modeToggle": false, 76 | "setParentFolderLabels": true, 77 | "sizes": [20, 40, 60, 80, 100, 140, 180, 220, 260, 300], 78 | "theme": "comity", 79 | "unmanaged": ["index.html", "index.htm", "index.php"], 80 | "unmanagedInNewWindow": false 81 | }, 82 | 83 | 84 | 85 | /*** Extensions (in alphabetical order) ***/ 86 | 87 | /* 88 | Watch and update current folder content. 89 | 90 | - interval: number, update interval in milliseconds, at least 1000 91 | */ 92 | "autorefresh": { 93 | "enabled": false, 94 | "interval": 5000 95 | }, 96 | 97 | /* 98 | Show a clickable breadcrumb. 99 | */ 100 | "crumb": { 101 | "enabled": true 102 | }, 103 | 104 | /* 105 | Allow customized header and footer files. 106 | First checks for files "_h5ai.header.html" and "_h5ai.footer.html" in the current directory. 107 | If not successful it checks all parent directories (starting in the current directory) for 108 | files "_h5ai.headers.html" and "_h5ai.footers.html". 109 | Note the different filenames: "header" (only current) - "headers" (current and sub directories)! 110 | The file's content will be placed inside a
tag above/below the main content. 111 | If a file's extension is ".md" instead of ".html" its content will be interpreted as markdown. 112 | */ 113 | "custom": { 114 | "enabled": true 115 | }, 116 | 117 | /* 118 | Enable packaged download of selected entries. 119 | To select files the "select"-extension needs to be enabled. 120 | 121 | - type: string, "php-tar", "shell-tar" or "shell-zip" 122 | - packageName: string, basename of the download package, null for current filename or foldername 123 | - alwaysVisible: boolean, always show download button (defaults to download the current folder) 124 | */ 125 | "download": { 126 | "enabled": true, 127 | "type": "php-tar", 128 | "packageName": null, 129 | "alwaysVisible": false 130 | }, 131 | 132 | /* 133 | Allow filtering the displayed files and folders in current folder. 134 | Checks for substrings. 135 | 136 | If advanced is enabled it checks entries for right order of characters, 137 | i.e. "ab" matches "ab", "axb", "xaxbx" but not "ba". Space separated 138 | sequences get OR-ed. Searches will be treated as JavaScript regular 139 | expressions if you prefix them with "re:". 140 | 141 | - advanced: boolean, use advanced pattern parsing 142 | - debounceTime: number, debounce wait time in milliseconds 143 | - ignorecase: boolean, ignore case 144 | */ 145 | "filter": { 146 | "enabled": false, 147 | "advanced": true, 148 | "debounceTime": 100, 149 | "ignorecase": true 150 | }, 151 | 152 | /* 153 | Calc the size of folders. 154 | This operation is real slow. The calculated sizes differ slightly for both 155 | calculation types since "php" only adds the file size, while "shell-du" 156 | also adds the sizes for the actual folder files. 157 | 158 | - type: string, "php" (sloooow) or "shell-du" (sloow) 159 | */ 160 | "foldersize": { 161 | "enabled": false, 162 | "type": "php" 163 | }, 164 | 165 | /* 166 | Adds Google Universial Analytics asynchronous tracking code. 167 | see: https://developers.google.com/analytics/devguides/collection/analyticsjs/ 168 | 169 | - id: string, account ID 170 | */ 171 | "google-analytics-ua": { 172 | "enabled": false, 173 | "id": "UA-000000-0" 174 | }, 175 | 176 | /* 177 | Enable a generic info side bar. 178 | 179 | - show: boolean, initial visible to first time users 180 | - qrcode: boolean, show a QR-Code 181 | - qrColor: string, QR-Code fill color 182 | */ 183 | "info": { 184 | "enabled": true, 185 | "show": false, 186 | "qrcode": true, 187 | "qrFill": "#999", 188 | "qrBack": "#fff" 189 | }, 190 | 191 | /* 192 | Localization, for example "en", "de" etc. - see "_h5ai/conf/l10n" folder for 193 | possible values. Adjust it to your needs. If lang is not found 194 | it defaults to "en". 195 | 196 | - lang: string, default language 197 | - useBroserLang: boolean, try to use browser language 198 | */ 199 | "l10n": { 200 | "enabled": true, 201 | "lang": "zh-cn", 202 | "useBrowserLang": true 203 | }, 204 | 205 | /* 206 | Adds Piwik tracker javascript code. 207 | 208 | - baseURL: string, do not include the protocol, e.g. "mydomain.tld/piwik" 209 | - idSite: number 210 | */ 211 | "piwik-analytics": { 212 | "enabled": false, 213 | "baseURL": "some/url", 214 | "idSite": 1 215 | }, 216 | 217 | /* 218 | Play a audio preview on click. 219 | 220 | - autoplay: start playing as soon as ready 221 | - types: array of strings 222 | */ 223 | "preview-aud": { 224 | "enabled": true, 225 | "autoplay": true, 226 | "types": ["aud"] 227 | }, 228 | 229 | /* 230 | Show an image preview on click. 231 | 232 | - types: array of strings 233 | - size: number, sample size, or false for original size 234 | */ 235 | "preview-img": { 236 | "enabled": true, 237 | "size": false, 238 | "types": ["img", "img-bmp", "img-gif", "img-ico", "img-jpg", "img-png", "img-raw", "img-svg"] 239 | }, 240 | 241 | /* 242 | Show text file preview on click. 243 | 244 | Available styles are: 245 | 0: floating text 246 | 1: fixed width text 247 | 2: markdown 248 | 3: syntax highlighting 249 | 250 | - styles: dict string to int, maps types to styles 251 | */ 252 | "preview-txt": { 253 | "enabled": true, 254 | "styles": { 255 | "txt": 1, 256 | "txt-authors": 1, 257 | "txt-c": 3, 258 | "txt-cpp": 3, 259 | "txt-css": 3, 260 | "txt-diff": 1, 261 | "txt-go": 3, 262 | "txt-h": 3, 263 | "txt-hpp": 3, 264 | "txt-install": 1, 265 | "txt-js": 3, 266 | "txt-json": 3, 267 | "txt-less": 3, 268 | "txt-license": 1, 269 | "txt-log": 1, 270 | "txt-makefile": 1, 271 | "txt-md": 2, 272 | "txt-py": 3, 273 | "txt-rb": 3, 274 | "txt-readme": 1, 275 | "txt-rtf": 1, 276 | "txt-rust": 3, 277 | "txt-script": 3, 278 | "txt-xml": 1 279 | } 280 | }, 281 | 282 | /* 283 | Play a video preview on click. 284 | 285 | - autoplay: start playing as soon as ready 286 | - types: array of strings 287 | */ 288 | "preview-vid": { 289 | "enabled": true, 290 | "autoplay": true, 291 | "types": ["vid-avi", "vid-flv", "vid-mkv", "vid-mov", "vid-mp4", "vid-mpg", "vid-webm"] 292 | }, 293 | 294 | /* 295 | Allow searching files and folders in and below current folder. 296 | Checks for substrings. 297 | 298 | If advanced is enabled it checks entries for right order of characters, 299 | i.e. "ab" matches "ab", "axb", "xaxbx" but not "ba". Space separated 300 | sequences get OR-ed. Searches will be treated as JavaScript regular 301 | expressions if you prefix them with "re:". 302 | 303 | - advanced: boolean, use advanced pattern parsing 304 | - debounceTime: number, debounce wait time in milliseconds 305 | - ignorecase: boolean, ignore case 306 | */ 307 | "search": { 308 | "enabled": false, 309 | "advanced": true, 310 | "debounceTime": 300, 311 | "ignorecase": true 312 | }, 313 | 314 | /* 315 | Make entries selectable. 316 | At the moment only needed for packaged download. 317 | 318 | - clickndrag: boolean, allow first mouse button + drag selection 319 | - checkboxes: boolean, show a checkbox on mouse over item 320 | */ 321 | "select": { 322 | "enabled": true, 323 | "clickndrag": true, 324 | "checkboxes": true 325 | }, 326 | 327 | /* 328 | Default sort order. 329 | "column" and "reverse" are locally stored. 330 | 331 | - column: number, 0 for "Name", 1 for "Date", 2 for "Size" 332 | - reverse: boolean, false for ascending, true for descending 333 | - ignorecase: boolean, compare ignorecase 334 | - natural: boolean, use natural sort order 335 | - folders: number, where to place folders, 0 for "top", 1 for "in place", 2 for "bottom" 336 | */ 337 | "sort": { 338 | "enabled": true, 339 | "column": 0, 340 | "reverse": false, 341 | "ignorecase": true, 342 | "natural": true, 343 | "folders": 0 344 | }, 345 | 346 | /* 347 | Show thumbnails for image files. Needs the "/_h5ai/cache" folder to be 348 | writable for the web Server. 349 | 350 | - img: array of strings 351 | - mov: array of strings 352 | - doc: array of strings 353 | - delay: number, delay in milliseconds after "dom-ready" before thumb-requesting starts 354 | - size: number, size in pixel of the generated thumbnails 355 | - exif: boolean, use included EXIF thumbs if possible 356 | - chunksize: int, number of thumbs per request 357 | */ 358 | "thumbnails": { 359 | "enabled": true, 360 | "img": ["img-bmp", "img-gif", "img-ico", "img-jpg", "img-png"], 361 | "mov": ["vid-avi", "vid-flv", "vid-mkv", "vid-mov", "vid-mp4", "vid-mpg", "vid-webm"], 362 | "doc": ["x-pdf", "x-ps"], 363 | "delay": 1, 364 | "size": 240, 365 | "exif": false, 366 | "chunksize": 20 367 | }, 368 | 369 | /* 370 | Replace window title with current breadcrumb. 371 | */ 372 | "title": { 373 | "enabled": true 374 | }, 375 | 376 | /* 377 | Show a folder tree. 378 | Note that this might affect performance significantly. 379 | 380 | - show: boolean, initial visible to first time users 381 | - maxSubfolders: number, max number of subfolders to show in tree 382 | - naturalSort: boolean, use natural sort order for folders 383 | - ignorecase: boolean, sort ignorecase 384 | */ 385 | "tree": { 386 | "enabled": true, 387 | "show": true, 388 | "maxSubfolders": 50, 389 | "naturalSort": true, 390 | "ignorecase": true 391 | } 392 | } 393 | -------------------------------------------------------------------------------- /_h5ai/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | 4 | ## v0.29.2 - *2019-03-22* 5 | 6 | * update `babel-loader` to 7.1.1 7 | * update `eslint` to 5.15.3 8 | * update `ghu` to 0.13.0 9 | * update `jsdom` to 14.0.0 10 | * update `kjua` to 0.2.0 11 | * update `lolight` to 1.0.0 12 | * update `scar` to 1.2.0 13 | 14 | 15 | ## v0.29.1 - *2019-01-20* 16 | 17 | * replace `babel-preset-es2015` with `babel-preset-env` 18 | * update `eslint` to 5.14.1 19 | * update `ghu` to 0.12.0 20 | * update `jsdom` to 9.2.0 21 | * update `kjua` to 0.1.2 22 | * update `lolight` to 0.6.0 23 | * update `marked` to 0.6.1 24 | * update `normalize.css` to 8.0.1 25 | * update `scar` to 1.0.0 26 | 27 | 28 | ## v0.29.0 - *2016-08-12* 29 | 30 | * back to cleaner visual experience 31 | * add option to disable sidebar 32 | * add options to filter/search ignore case 33 | * replace PHP `getenv` calls with `$_SERVER` lookups 34 | * add `view.fallbackMode` option to generally serve only fallback mode 35 | * serve fallback mode for text browsers (`curl`, `links`, `lynx`, `w3m`) 36 | * change type `txt-svg` to `img-svg`, no thumbs but preview 37 | * fix a tree indentation glitch 38 | * fix shell command detection on Windows 39 | * fix Piwik anayltics 40 | * fix `.htaccess` auth issues 41 | * fix drag-select on scrollable content 42 | * fix download-all function 43 | * fix audio and video preview loading 44 | * fix thumbnail request issues 45 | * add `rust` type and icon 46 | * add `autoplay` option to audio and video preview 47 | * add `--dereference` to `shell-du` to follow sym links 48 | * remove *Install* section from `README.md`, causes too much trouble 49 | * remove peer5 support 50 | * update build process to use `node 6.0+`, no need for babel now 51 | * replace `jquery-qrcode` with [`kjua`](https://larsjung.de/kjua/) 52 | * replace `prism` with [`lolight`](https://larsjung.de/lolight/) 53 | * move deps to `package.json` (`normalize.css`, `kjua`, `lolight` and `marked`) 54 | * remove `jQuery` 55 | * remove `lodash` 56 | * remove [`modulejs`](https://larsjung.de/modulejs/) for now 57 | * reduce JS code by 60% (~250kb -> ~100kb) 58 | * update languages (`et`, `nl`, `pl`) 59 | 60 | 61 | ## v0.28.0 - *2015-12-19* 62 | 63 | * now require PHP 5.5.0+ 64 | * change index path to `/_h5ai/public/index.php` 65 | * now only `/_h5ai/public/` needs to be web-accessible 66 | * add support for custom script and style additions 67 | * add options to set font families 68 | * add search 69 | * add ignorecase sorting option to tree 70 | * add wide links in tree view 71 | * add IE edge mode 72 | * add frontend tests 73 | * fix some styles in IE10 74 | * fix preview bottom bar for small screen widths 75 | * lots of code cleanup and refactorings 76 | * change API 77 | * update build process, now uses [`ghu`](https://larsjung.de/ghu/) 78 | * switch from jshint and jscs to [`eslint`](http://eslint.org/) 79 | * update `jQuery` to 2.1.4 80 | * update `lodash` to 3.9.3 (add debounce and trim) 81 | * update `marked` to 0.3.5 82 | * update `modulejs` to 1.13.0 83 | * update `prism` to 2015-12-19 84 | * update h5bp styles to 5.2.0 85 | * update `normalize.css` to 3.0.3 86 | * remove `Moment.js` 87 | 88 | 89 | ## v0.27.0 - *2015-04-06* 90 | 91 | * new layout 92 | * add editorconfig 93 | * drop support for IE9 (gets fallback) 94 | * update sidebar settings 95 | * add info sidebar 96 | * add opt-out for click'n'drag selection 97 | * add package name option for single selections 98 | * add initial support for Peer5 99 | * add option to down-sample images for preview 100 | * add option for natural sorting in tree sidebar 101 | * fix problems with files/folders named `0` 102 | * change font from `Ubuntu` to `Roboto` (smaller footprint, clearer for small sizes) 103 | * switch back to Google Fonts 104 | * improve PDF thumbnail quality 105 | * improve drag-select 106 | * improve image preview 107 | * prevent listing `_h5ai` folder and subfolders 108 | * update build process, now uses [`mkr`](https://larsjung.de/mkr/) and [`fQuery`](https://larsjung.de/fquery/) 109 | * update `jQuery` to 2.1.3 110 | * update `jQuery.qrcode` to 0.11.0 111 | * update `Lo-Dash` to 3.6.0 112 | * update `Modernizr` to 2.8.3 113 | * update `modulejs` to 1.4.0 114 | * update `Moment.js` to 2.9.0 115 | * update `Prism` to 2015-04-05 116 | * remove deprecated Google Analytics code 117 | * remove `jQuery.fracs` 118 | * remove `jQuery.scrollpanel` 119 | * remove `jQuery.mousewheel` 120 | * update languages (`af`, `es`, `ja`, `ko`, `ru`, `zh-cn`) 121 | 122 | 123 | ## v0.26.1 - *2014-08-17* 124 | 125 | * fix links 126 | 127 | 128 | ## v0.26.0 - *2014-08-16* 129 | 130 | * remove True Type fonts 131 | * outsource themes to [h5ai-themes](https://github.com/lrsjng/h5ai-themes) 132 | * add filesize fallback for large files and 32bit PHP 133 | * fix server detection 134 | * add config file tests to info page 135 | * remove JSON shim 136 | * add caching of command checks 137 | * update `jQuery.mousewheel` to 3.1.12 138 | * update `jQuery.qrcode` to 0.8.0 139 | * replace `markdown` with [`marked`](https://github.com/chjj/marked) 0.3.2 140 | * update `modulejs` to 0.4.5 141 | * update `Moment.js` to 2.8.1 142 | * replace `underscore` with [`Lo-Dash`](https://github.com/lodash/lodash) 2.4.1 143 | * replace `SyntaxHighlighter` with [`Prism`](http://prismjs.com) 2014-08-04 144 | 145 | 146 | ## v0.25.2 - *2014-07-01* 147 | 148 | * add optional info page protection 149 | * fix `short_open_tag` issues for PHP < 5.4.0 150 | * fix default folder download (`alwaysVisible` option) 151 | * minor fixes 152 | 153 | 154 | ## v0.25.1 - *2014-06-25* 155 | 156 | * fix broken paths for filenames containing '+' characters 157 | * fix Google Universal Analytics 158 | * fix file type check 159 | 160 | 161 | ## v0.25.0 - *2014-06-22* 162 | 163 | * add sidebar 164 | * add initial theme support 165 | * add icons from [Evolvere Icon Theme](http://franksouza183.deviantart.com/art/Evolvere-Icon-theme-440718295) 166 | * add PHP variant to calc folder sizes 167 | * add scroll position reset on location change (issue [#279](https://github.com/lrsjng/h5ai/issues/279)) 168 | * add option to hide unreadable files 169 | * add option where to place folders (top, inplace, bottom) 170 | * add markdown support for custom header and footer files 171 | * add video and audio preview via HTML5 elements (no fallback, works best in Chrome) 172 | * add filter reset on location change 173 | * add option to make download button always visible 174 | * add Google UA support 175 | * extend selectable icon sizes (add 128px, 192px, 256px, 384px) 176 | * improve preview GUI 177 | * disable thumbs in `cache` folder 178 | * fix QR code URI origin (issue [#287](https://github.com/lrsjng/h5ai/issues/287)) 179 | * replace PHP backtick operator with `exec` 180 | * remove server side file manipulation extensions `dropbox`, `delete` and `rename` 181 | * update `H5BP` to 4.3.0 182 | * update `jQuery` to 2.1.1 183 | * update `json2.js` to 2014-02-04 184 | * update `markdown-js` to 0.5.0 185 | * update `Modernizr` to 2.8.2 186 | * update `Moment.js` to 2.6.0 187 | * update `Underscore.js` to 1.6.0 188 | * update languages (`bg`, `ko`, `pt`, `sl`, `sv`, `zh-cn`) 189 | 190 | 191 | ## v0.24.1 - *2014-04-09* 192 | 193 | * security fixes! (issues [#268](https://github.com/lrsjng/h5ai/issues/268), [#269](https://github.com/lrsjng/h5ai/issues/269)) 194 | * fix WinOS command detection 195 | * update languages (`fi`, `fr`, `hi`, `it`, `zh-tw`) 196 | 197 | 198 | ## v0.24.0 - *2013-09-04* 199 | 200 | * updates image and text preview 201 | * adds variable icon sizes 202 | * adds optional natural sort of items 203 | * adds optional checkboxes to select items 204 | * adds text preview modes: none, fixed, markdown 205 | * optionally hide folders in main view 206 | * makes use of EXIF thumbnails optional 207 | * fixes file deletion of multiple files 208 | * fixes `setParentFolderLabels = false` 209 | * fixes shell-arg and RegExp escape issues 210 | * cleans code 211 | * updates info page `/_h5ai` 212 | * adds `aiff` to `audio` types 213 | * adds `da` translation by Ronnie Milbo 214 | * updates to `pl` translation by Mark 215 | 216 | 217 | ## v0.23.0 - *2013-07-21* 218 | 219 | * removes `aai` mode! 220 | * drops support for IE7+8 (simple fallback, same as no javascript) 221 | * uses History API if available (way faster browsing) 222 | * faster thumbnail generation if EXIF thumbnails available 223 | * adds optional custom headers/footers that are propageted to all subfolders 224 | * optional hide parent folder links 225 | * some fixes on previews 226 | * speeds up packaged downloads 227 | * add line wrap and line highlighting (on hover) to text preview 228 | * new design (colors, images) 229 | * now uses scalable images for the interface 230 | * fixes filter (ignore parent folder, display of `no match`) 231 | * lots of small fixes 232 | * updates `H5BP` to 4.2.0 233 | * updates `jQuery` to 2.0.3 234 | * updates `jQuery.mousewheel` to 3.1.3 235 | * updates `Moment.js` to 2.1.0 236 | * updates `markdown-js` to 0.4.0-9c21acdf08 237 | * updates `json2.js` to 2013-05-26 238 | * adds `uk` translation by Viktor Matveenko 239 | * updates to `pl` translation by Mark 240 | 241 | 242 | ## v0.22.1 - *2012-10-16* 243 | 244 | * bug fix concerning API requests in PHP mode 245 | * minor changes in responsive styles 246 | 247 | 248 | ## v0.22 - *2012-10-14* 249 | 250 | * general changes h5ai directory layout and configuration 251 | * splits configuration file (`config.json`) into files `options.json`, `types.json` and `langs.json` 252 | * localization now in separate files 253 | * adds auto-refresh 254 | * adds drag'n'drop upload (PHP, experimental) 255 | * adds file deletion (PHP, experimental) 256 | * cleans and improves PHP code 257 | * PHP no longer respects htaccess restrictions (so be careful) 258 | * PHP ignore patterns might include paths now 259 | * improves separation between aai and php mode 260 | * improves performance in aai mode 261 | * adds optional binary prefixes for file sizes 262 | * improves filter: autofocus on keypress, clear on `ESC` 263 | * download packages now packaged relative to current folder 264 | * download package name changable 265 | * splits type `js` into `js` and `json` 266 | * prevents some errors with files > 2GB on 32bit OS 267 | * adds max subfolder size in tree view 268 | * adds ctrl-click file selection 269 | * adds Piwik analytics extension 270 | * temp download packages are now stored in the `cache`-folder and deleted as soon as possible 271 | * updates translations 272 | * adds `he` translation by [Tomer Cohen](https://github.com/tomer) 273 | * updates 3rd party libs 274 | 275 | 276 | ## v0.21 - *2012-08-06* 277 | 278 | * fixes misaligned image previews 279 | * adds no JavaScript fallback to PHP version 280 | * fixes duplicate tree entries and empty main views 281 | * adds Google Analytics support (async) 282 | * improves filter (now ignorecase, now only checks if chars in right order) 283 | * adds keyboard support to image preview (space, enter, backspace, left, right, up, down, f, esc) 284 | * adds text file preview and highlighting with [SyntaxHighlighter](http://alexgorbatchev.com/SyntaxHighlighter/) (same keys as img preview) 285 | * adds Markdown preview with [markdown-js](https://github.com/evilstreak/markdown-js) 286 | * adds new type `markdown` 287 | * changes language code `gr` to `el` 288 | * adds localization for filter placeholder 289 | * adds `hu` translation by [Rodolffo](https://github.com/Rodolffo) 290 | * updates to [jQuery.qrcode](https://larsjung.de/qrcode/) 0.2 291 | * updates to [jQuery.scrollpanel](https://larsjung.de/scrollpanel/) 0.1 292 | * updates to [modulejs](https://larsjung.de/modulejs/) 0.2 293 | * updates to [Moment.js](http://momentjs.com) 1.7.0 294 | * updates to [Underscore.js](http://underscorejs.org) 1.3.3 295 | 296 | 297 | ## v0.20 - *2012-05-11* 298 | 299 | * adds image preview 300 | * adds thumbnails for video and pdf 301 | * adds support for lighttpd, nginx and cherokee and maybe other webservers with PHP 302 | * adds folder size in PHP version via shell `du` 303 | * fixes some localization problems 304 | * updates info page at `/_h5ai/` 305 | * switches to JSHint 306 | 307 | 308 | ## v0.19 - *2012-04-19* 309 | 310 | * adds lots of config options 311 | * changes in `config.js` and `h5ai.htaccess` 312 | * fixes js problems in IE 7+8 313 | * hides broken tree view in IE < 9, adds a message to the footer 314 | * removes hash changes since they break logical browser history 315 | * fixes thumbnail size for portrait images in icon view 316 | * fixes problems with file type recognition 317 | * adds an info page at `/_h5ai/` 318 | * sort order is preserved while browsing 319 | * removes PHP error messages on thumbnail generation 320 | * fixes PHP some problems with packed download 321 | * adds support for tarred downloads 322 | * changes crumb image for folders with an index file 323 | * adds `index.php` to use h5ai in non-Apache environments 324 | * switches from [Datejs](http://www.datejs.com) to [Moment.js](http://momentjs.com) 325 | * adds [underscore.js](http://underscorejs.org) 326 | * fixes mousewheel problems, updates [jQuery.mousewheel](https://github.com/brandonaaron/jquery-mousewheel) to 3.0.6 327 | * updates `lv` translation 328 | * adds `ro` translation by [Jakob Cosoroabă](https://github.com/midday) 329 | * adds `ja` translation by [metasta](https://github.com/metasta) 330 | * adds `nb` translation by [Sindre Sorhus](https://github.com/sindresorhus) 331 | * adds `sr` translation by [vBm](https://github.com/vBm) 332 | * adds `gr` translation by [xhmikosr](https://github.com/xhmikosr) 333 | 334 | 335 | ## v0.18 - *2012-02-24* 336 | 337 | * adds optional QRCode display 338 | * adds optional filtering for displayed files and folders 339 | * updates design 340 | * improves zipped download 341 | * adds support for zipped download of htaccess restricted files 342 | * changes h5ai.htaccess 343 | * custom headers/footers are now optional and disabled by default 344 | * fixes problems with folder recognition in the JS version 345 | * fixes include problems in PHP version 346 | * fixes path problems on servers running on Windows in PHP version 347 | * fixes broken links in custom headers/footers while zipped download enabled 348 | * fixes problems with thumbnails for files with single or double quotes in filename 349 | * improves url hashes 350 | * updates year in `LICENSE.TXT` 351 | * updates es translation 352 | * adds `zh-tw` translation by [Yao Wei](https://github.com/medicalwei) 353 | * updates `zh-cn` translation 354 | 355 | 356 | ## v0.17 - *2011-11-28* 357 | 358 | * h5ai is now located in `_h5ai` to reduce collisions 359 | * switches from HTML5 Boilerplate reset to normalization 360 | * adds some style changes for small devices 361 | * configuration (options, types, translations) now via `config.js` 362 | * icons for JS version are now configured via `config.js` 363 | * sort order configuration changed 364 | * sorting is now done without page reload 365 | * adds `customHeader` and `customFooter` to `config.js` 366 | * supports restricted folders to some extent 367 | * some style changes on tree and language menu 368 | * fixes total file/folder count in status bar 369 | * adds support for use with userdir (requires some manual changes) 370 | 371 | 372 | ## v0.16 - *2011-11-02* 373 | 374 | * sorts translations in `options.js` 375 | * improves HTML head sections 376 | * refactors JavaScript and PHP a lot 377 | * improves/fixes file selection for zipped download 378 | * fixes scrollbar and header/footer link issues (didn't work when zipped download enabled) 379 | * adds support for ctrl-select 380 | * `dateFormat` in `options.js` changed, now affecting JS and PHP version 381 | * `dateFormat` is localizable by adding it to a translation in `options.js` 382 | * PHP version is now configurable via `php/config.php` (set custom doc root and other PHP related things) 383 | * image thumbs and zipped download is disabled by default now, but works fine if PHP is configured 384 | 385 | 386 | ## v0.15.2 - *2011-09-18* 387 | 388 | * adds `it` translation by [Salvo Gentile](https://github.com/SalvoGentile) and [Marco Patriarca](https://github.com/Fexys) 389 | * switches build process from scripp to wepp 390 | 391 | 392 | ## v0.15.1 - *2011-09-06* 393 | 394 | * fixes security issues with the zipped download feature 395 | * makes zipped download optional (but enabled by default) 396 | 397 | 398 | ## v0.15 - *2011-09-04* 399 | 400 | * adds zipped download for selected files 401 | * cleans and refactores 402 | 403 | 404 | ## v0.14.1 - *2011-09-01* 405 | 406 | * display meta information in bottom bar (icon view) 407 | * adds `zh-cn` translation by [Dongsheng Cai](https://github.com/dongsheng) 408 | * adds `pl` translation by Radosław Zając 409 | * adds `ru` translation by Богдан Илюхин 410 | 411 | 412 | ## v0.14 - *2011-08-16* 413 | 414 | * adds image thumbnails for PHP version 415 | * new option `slideTree` to turn off auto slide in 416 | 417 | 418 | ## v0.13.2 - *2011-08-12* 419 | 420 | * changes in `/h5ai/.htaccess` ... PHP configuration ... 421 | 422 | 423 | ## v0.13.1 - *2011-08-12* 424 | 425 | * fixes initial tree display 426 | * adds sort order option 427 | * adds/fixes some translations 428 | * adds `lv` translation by Sandis Veinbergs 429 | 430 | 431 | ## v0.13 - *2011-08-06* 432 | 433 | * adds PHP implementation! (should work with PHP 5.2+) 434 | * adds new options 435 | * changes layout of the bottom bar to display status information 436 | * adds language selector to the bottom bar 437 | * quotes keys in `options.js` to make it valid json 438 | * changes value of option `lang` from `undefined` to `null` 439 | * adds some new keys to `h5aiLangs` 440 | * adds browser caching rules for css and js 441 | * adds `pt` translation by [Jonnathan](https://github.com/jonnsl) 442 | * adds `bg` translation by George Andonov 443 | 444 | 445 | ## v0.12.3 - *2011-07-30* 446 | 447 | * adds `tr` translation by [Batuhan Icoz](https://github.com/batuhanicoz) 448 | 449 | 450 | ## v0.12.2 - *2011-07-30* 451 | 452 | * adds `es` translation by Jose David Calderon Serrano 453 | 454 | 455 | ## v0.12.1 - *2011-07-29* 456 | 457 | * fixes unchecked use of console.log 458 | 459 | 460 | ## v0.12 - *2011-07-28* 461 | 462 | * improves performance 463 | 464 | 465 | ## v0.11 - *2011-07-27* 466 | 467 | * changes license to MIT license, see `LICENSE.txt` 468 | 469 | 470 | ## v0.10.2 - *2011-07-26* 471 | 472 | * improves tree scrollbar 473 | 474 | 475 | ## v0.10.1 - *2011-07-24* 476 | 477 | * fixes problems with ' in links 478 | 479 | 480 | ## v0.10 - *2011-07-24* 481 | 482 | * fixes problems with XAMPP on Windows (see `dot.htaccess` comments for instructions) 483 | * fixes tree fade-in-fade-out effect for small displays ([issue #6](https://github.com/lrsjng/h5ai/issues/6)) 484 | * adds custom scrollbar to tree ([issue #6](https://github.com/lrsjng/h5ai/issues/6)) 485 | * fixes broken links caused by URI encoding/decoding ([issue #9](https://github.com/lrsjng/h5ai/issues/9)) 486 | * adds "empty" to localization (hope Google Translate did a good job here) 487 | 488 | 489 | ## v0.9 - *2011-07-18* 490 | 491 | * links hover states between crumb, extended view and tree 492 | * fixes size of tree view (now there's a ugly scrollbar, hopefully will be fixed) 493 | * refactores js to improve performance and cleaned code 494 | * adds caching for folder status codes and content 495 | * adds `fr` translation by [Nicolas](https://github.com/Nicosmos) 496 | * adds `nl` translation by [Stefan de Konink](https://github.com/skinkie) 497 | * adds `sv` translation by Oscar Carlsson 498 | 499 | 500 | ## v0.8 - *2011-07-08* 501 | 502 | * removes slashes from folder labels 503 | * optionally rename parent folder entries to real folder names, see `options.js` 504 | * long breadcrumbs (multiple rows) no longer hide content 505 | * error folder icons are opaque now 506 | * refactores js a lot (again...) 507 | 508 | 509 | ## v0.7 - *2011-07-07* 510 | 511 | * removes shadows 512 | * smarter tree side bar 513 | 514 | 515 | ## v0.6 - *2011-07-05* 516 | 517 | * refactores js 518 | * adds localization, see `options.js` 519 | 520 | 521 | ## v0.5.3 - *2011-07-04* 522 | 523 | * refactores js 524 | * adds basic options support via `options.js` 525 | * adds comments to `options.js` 526 | * adds optional tree sidebar 527 | 528 | 529 | ## v0.5.2 - *2011-07-02* 530 | 531 | * details view adjusts to window width 532 | * links icon for *.gz and *.bz2 533 | 534 | 535 | ## v0.5.1 - *2011-07-01* 536 | 537 | * disables tree sidebar for now, since it had unwanted side effects 538 | 539 | 540 | ## v0.5 - *2011-07-01* 541 | 542 | * adds tree sidebar 543 | * some refactorings 544 | 545 | 546 | ## v0.4 - *2011-06-27* 547 | 548 | * adds better fallback, in case JavaScript is disabled 549 | * rewrites js, fixed middle-button click etc. problems 550 | * refactors css 551 | * sorts, adds and moves icons and images 552 | * updates dot.access 553 | 554 | 555 | ## v0.3.2 - *2011-06-24* 556 | 557 | * removes lib versions from file names 558 | * adds 'empty' indicator for icons view 559 | 560 | 561 | ## v0.3.1 - *2011-06-24* 562 | 563 | * refactores js 564 | * adds `folderClick` and `fileClick` callback hooks 565 | * fixes .emtpy style 566 | 567 | 568 | ## v0.3 - *2011-06-23* 569 | 570 | * includes build stuff, files previously found in the base directory are now located in folder `target` 571 | * styles and scripts are now minified 572 | * adds Modernizr 2.0.4 for future use 573 | * updates jQuery to version 1.6.1 574 | 575 | 576 | ## v0.2.3 - *2011-06-17* 577 | 578 | * more refactoring in main.js 579 | 580 | 581 | ## v0.2.2 - *2011-06-16* 582 | 583 | * refactores a lot, adds some comments 584 | * includes fixes from [NumEricR](https://github.com/NumEricR) 585 | * adds top/bottom message support, only basicly styled 586 | 587 | 588 | ## v0.2.1 - *2011-06-16* 589 | 590 | * fixes croped filenames 591 | * fixes missing .png extension in header 592 | * adds some color to the links 593 | * adds changelog 594 | 595 | 596 | ## v0.2 - *2011-06-15* 597 | 598 | * adds icon view 599 | -------------------------------------------------------------------------------- /_h5ai/public/css/styles.css: -------------------------------------------------------------------------------- 1 | /* h5ai v0.29.2 - https://larsjung.de/h5ai/ */ 2 | @charset "utf-8";/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:0;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}button,[type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button::-moz-focus-inner,[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none}::-moz-selection{color:#fff;background:#ff4081;text-shadow:none}::selection{color:#fff;background:#ff4081;text-shadow:none}*:focus{outline:0}code,pre{font-family:"Ubuntu Mono","Monaco","Lucida Sans Typewriter","monospace";font-size:15px;font-weight:normal;color:rgba(0,0,0,0.87)}audio,canvas,iframe,img,svg,video{vertical-align:middle}textarea{resize:vertical}.hidden{display:none!important}.invisible{visibility:hidden}.clearfix:before,.clearfix:after{content:" ";display:table}.clearfix:after{clear:both}.raised{box-shadow:0 1px 10px 0 rgba(0,0,0,0.5)}.popup{box-shadow:0 1px 20px 0 rgba(0,0,0,0.5)}.rounded{border-radius:2px}.clear-appearance{-moz-appearance:none;-ms-appearance:none;-webkit-appearance:none}.eased-transition{transition:all .2s ease-in-out}.flex-base{display:flex;flex-wrap:nowrap;justify-content:flex-start;align-content:flex-start;align-items:stretch}.flex-column{display:flex;flex-wrap:nowrap;justify-content:flex-start;align-content:flex-start;align-items:stretch;flex-direction:column}.flex-row{display:flex;flex-wrap:nowrap;justify-content:flex-start;align-content:flex-start;align-items:stretch;flex-direction:row}.el-button{border-radius:2px;transition:all .2s ease-in-out;color:#fff;background:#42a5f5;cursor:pointer;text-decoration:none}.el-button:hover{box-shadow:0 1px 10px 0 rgba(0,0,0,0.5)}.el-input{border-radius:2px;-moz-appearance:none;-ms-appearance:none;-webkit-appearance:none;background:#fff;border:0;outline:0;background:#fafafa;border:1px solid rgba(0,0,0,0.05)}#cm-overlay{position:fixed;left:0;top:0;right:0;bottom:0;overflow:hidden;z-index:200}#cm-overlay .cm-panel{box-shadow:0 1px 20px 0 rgba(0,0,0,0.5);border-radius:2px;display:block;position:absolute;left:100px;top:100px;color:rgba(0,0,0,0.87);background:#fff;z-index:10;overflow:auto;min-width:200px}#cm-overlay .cm-panel ul{margin:0;padding:0;list-style:none;text-align:left}#cm-overlay .cm-label{padding:8px 16px;white-space:nowrap;font-weight:bold}#cm-overlay .cm-entry{padding:8px 16px;white-space:nowrap;cursor:pointer}#cm-overlay .cm-entry:hover{color:#42a5f5;background:rgba(0,0,0,0.03)}#cm-overlay .cm-icon{position:relative;top:-2px}#cm-overlay .cm-icon img{width:20px;height:20px}#cm-overlay .cm-icon.no-icon{opacity:0}#cm-overlay .cm-text{margin:0 0 0 12px}#cm-overlay .cm-sep{height:1px;margin:8px 0;padding:0;border-top:1px solid rgba(0,0,0,0.08)}#crumbbar{overflow:hidden;height:48px;font-size:16px;padding:0 8px}#crumbbar a,#crumbbar a:active,#crumbbar a:visited{color:rgba(0,0,0,0.87);cursor:pointer;text-decoration:none}#crumbbar a.active,#crumbbar a:active.active,#crumbbar a:visited.active{font-weight:bold}#crumbbar a:hover,#crumbbar a:active:hover,#crumbbar a:visited:hover{color:#42a5f5}#crumbbar a:focus,#crumbbar a:active:focus,#crumbbar a:visited:focus{outline:0}#crumbbar .crumb{transition:all .2s ease-in-out;display:inline-block}#crumbbar .sep{width:24px;height:24px;padding:12px 0;line-height:48px;display:inline-block;vertical-align:top}#crumbbar .crumb:first-of-type .sep{width:0}#crumbbar .label{line-height:48px;display:inline-block;vertical-align:top;padding:0 8px}#crumbbar .hint{width:20px;height:20px;padding:16px 0 0 0;line-height:48px;display:inline-block;vertical-align:top;position:relative;top:-2px}#content-header,#content-footer{margin:16px;padding:8px;color:rgba(0,0,0,0.87)}#content-header a,#content-footer a,#content-header a:active,#content-footer a:active,#content-header a:visited,#content-footer a:visited{color:#42a5f5;text-decoration:none;cursor:pointer}#content-header a:hover,#content-footer a:hover,#content-header a:active:hover,#content-footer a:active:hover,#content-header a:visited:hover,#content-footer a:visited:hover{color:#212121}#content-header h1,#content-footer h1,#content-header h2,#content-footer h2,#content-header h3,#content-footer h3,#content-header h4,#content-footer h4,#content-header h5,#content-footer h5,#content-header h6,#content-footer h6,#content-header p,#content-footer p{margin:.1em 0}#filter input{display:none;border:0;font-size:16px;color:rgba(0,0,0,0.87);background:transparent;outline:0;width:160px;padding:0 12px 0 4px;line-height:48px;vertical-align:top}#filter.active input{display:inline-block}#filter.pending input{color:rgba(0,0,0,0.26)}#info{overflow:auto;flex:0 0 auto;order:99;padding:32px 32px 32px 48px;white-space:nowrap;overflow-x:hidden;width:240px}#info .icon{width:240px;height:180px}#info .icon img{border-radius:2px;display:block;overflow:hidden;margin:0 auto;width:180px;height:180px}#info .icon .thumb{width:240px}#info .block{border-top:1px solid rgba(0,0,0,0.05);border-bottom:1px solid rgba(0,0,0,0.05);margin:0 0 24px 0;padding:24px 0}#info .label{font-size:16px;margin-bottom:16px}#info .time,#info .size,#info .content{line-height:20px;height:20px}#info .qrcode{margin:0 auto;width:200px}#info .qrcode img{display:block}#pv-content-aud{box-shadow:0 1px 10px 0 rgba(0,0,0,0.5);position:absolute;max-width:100%;max-height:100%}#pv-content-img{box-shadow:0 1px 10px 0 rgba(0,0,0,0.5);position:absolute;max-width:100%;max-height:100%;background-color:#f8f8f8;background-image:-webkit-linear-gradient(45deg,#e8e8e8 25%,transparent 25%,transparent 75%,#e8e8e8 75%,#e8e8e8),-webkit-linear-gradient(45deg,#e8e8e8 25%,transparent 25%,transparent 75%,#e8e8e8 75%,#e8e8e8);background-size:60px 60px;background-position:0 0,30px 30px}#pv-content-img.loading{opacity:.5;margin-top:32px;width:240px;height:240px;border-radius:1000px;overflow:hidden}#pv-content-txt{box-shadow:0 1px 10px 0 rgba(0,0,0,0.5);box-sizing:border-box;max-width:960px;text-align:left;background:#fff;margin:0 auto;padding:8px;overflow:auto}#pv-content-txt a,#pv-content-txt a:active,#pv-content-txt a:visited{color:#2080ff;text-decoration:none;cursor:pointer}#pv-content-txt a:hover,#pv-content-txt a:active:hover,#pv-content-txt a:visited:hover{color:#68a9ff}pre#pv-content-txt code{line-height:1.2em}div#pv-content-txt{font-size:1.1em;padding:8px 24px}div#pv-content-txt code{color:#008200}#pv-content-vid{box-shadow:0 1px 10px 0 rgba(0,0,0,0.5);position:absolute;max-width:100%;max-height:100%}#pv-content-vid:-webkit-full-screen{top:auto!important;left:auto!important}#pv-overlay{position:fixed;left:0;top:0;right:0;bottom:0;z-index:100;background:rgba(0,0,0,0.5);transition:background-color .3s ease-in-out;text-align:center}#pv-overlay.fullscreen{background:#212121}#pv-container{position:absolute}#pv-spinner{position:absolute}#pv-spinner .back{width:240px;height:240px;margin:-120px -120px;border-radius:120px;opacity:.5;overflow:hidden}#pv-spinner .spinner{width:100px;height:100px;margin:-50px -50px}#pv-prev-area,#pv-next-area{position:absolute;top:50%;cursor:pointer}#pv-prev-area img,#pv-next-area img{transition:all .2s ease-in-out;display:block;width:48px;height:48px;margin:-36px 0;padding:12px;opacity:.5}#pv-prev-area:hover img,#pv-next-area:hover img{box-shadow:0 1px 10px 0 rgba(0,0,0,0.5);opacity:1;background:rgba(27,27,27,0.8)}#pv-prev-area{left:0}#pv-prev-area img{border-radius:0 8px 8px 0;padding-left:48px}#pv-next-area{right:0}#pv-next-area img{border-radius:8px 0 0 8px;padding-right:48px}#pv-buttons{list-style:none;list-style-image:none;margin:0;padding:0}#pv-buttons img{position:relative;width:24px;height:24px;padding:12px}#pv-buttons .bar-label{transition:all .2s ease-in-out;display:block;color:#fff;height:48px;line-height:48px;padding:0 12px;opacity:.7}#pv-buttons .bar-button{transition:all .2s ease-in-out;display:block;line-height:48px;opacity:.7;cursor:pointer}#pv-buttons .bar-button:hover{opacity:1;background:rgba(255,255,255,0.1)}#pv-buttons .bar-left{float:left}#pv-buttons .bar-right{float:right}#pv-bottombar{box-shadow:0 1px 10px 0 rgba(0,0,0,0.5);position:fixed;z-index:5;left:0;right:0;bottom:0;background:#1b1b1b;height:48px}#pv-overlay.fullscreen #pv-bottombar{opacity:.5}@media only screen and (max-width:700px){#pv-prev-area,#pv-next-area{display:none!important}}#search input{display:none;border:0;font-size:16px;color:rgba(0,0,0,0.87);background:transparent;outline:0;width:160px;padding:0 12px 0 4px;line-height:48px;vertical-align:top}#search.active input{display:inline-block}#search.pending input{color:rgba(0,0,0,0.26)}#selection-rect{position:absolute;left:0;top:0;z-index:2;border:1px dashed rgba(0,0,0,0.15);background:rgba(0,0,0,0.1)}html.drag-select,html.drag-select *{cursor:move!important;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}html.drag-select #view .item:hover,html.drag-select * #view .item:hover{box-shadow:none!important}#view .selector{display:none;position:absolute;left:0;top:0;width:22px;height:22px;background:#42a5f5;cursor:pointer;border-radius:0 0 2px 0;opacity:.6}#view .selector:hover{opacity:.8}#view .selector img{width:100%;height:100%}#view .item:hover .selector{display:block}#view .item.selected:not(.selecting),#view .item.selecting:not(.selected){color:#fff;background:#42a5f5}#view .item.selected:not(.selecting) .selector,#view .item.selecting:not(.selected) .selector{display:block;opacity:1}#view .item.selected:not(.selecting):hover,#view .item.selecting:not(.selected):hover{color:#fff;background:#42a5f5}#view .no-match{display:none;margin-top:36px;text-align:center;color:rgba(0,0,0,0.05);font-size:5em;font-weight:bold}#tree{overflow:auto;flex:0 0 auto;order:1;padding:32px 32px 32px 16px;white-space:nowrap;max-width:250px;overflow-x:hidden}#tree a,#tree a:active,#tree a.visited{display:block;margin-left:20px;padding:3px 0;text-decoration:none;color:rgba(0,0,0,0.87)}#tree a:hover,#tree a:active:hover,#tree a.visited:hover{color:#42a5f5}#tree .active>a{font-weight:bold}#tree .indicator{display:block;float:left;padding:3px 0;position:relative;top:-2px;cursor:pointer}#tree .indicator img{width:20px;height:20px;zoom:1}#tree .item{clear:left}#tree .item.open>.indicator img{-webkit-transform:rotate(90deg);transform:rotate(90deg)}#tree .item.unknown>.indicator{opacity:.3}#tree .item.none>.indicator{opacity:0;cursor:inherit}#tree .item.unknown>.content,#tree .item.none>.content,#tree .item.closed>.content{display:none}#tree .icon{position:relative;top:-2px}#tree .icon img{width:20px;height:20px}#tree .label{margin:0 0 0 4px}#tree .content{margin:0;padding:0 0 0 20px}#tree .summary{color:rgba(0,0,0,0.26);padding:0 0 0 8px}#root.info #content{flex:1 1 auto;order:50;color:rgba(0,0,0,0.87);text-align:center}#root.info code{margin:0 .2em;padding:2px 4px;border-radius:4px;letter-spacing:.05em;background:#fafafa;border:1px solid rgba(0,0,0,0.05);font-size:.9em}#root.info #header a{transition:all .2s ease-in-out;font-size:4em;font-weight:300;margin:.8em 0 0 0;color:rgba(0,0,0,0.87);text-decoration:none}#root.info #header a:hover{color:#42a5f5}#root.info #support{margin:24px auto;padding:18px 0 6px 0;width:292px;background:#fafafa;border:1px solid rgba(0,0,0,0.05);border-radius:4px}#root.info #support input[type="image"]{border:0;width:100px;padding:12px 48px}#root.info #pass{border-radius:2px;-moz-appearance:none;-ms-appearance:none;-webkit-appearance:none;background:#fff;border:0;outline:0;background:#fafafa;border:1px solid rgba(0,0,0,0.05);display:inline-block;margin:8px;padding:0 12px;line-height:28px;width:200px;vertical-align:top}#root.info #login,#root.info #logout{border-radius:2px;transition:all .2s ease-in-out;color:#fff;background:#42a5f5;cursor:pointer;text-decoration:none;display:inline-block;margin:8px;padding:0 12px;line-height:28px;vertical-align:top}#root.info #login:hover,#root.info #logout:hover{box-shadow:0 1px 10px 0 rgba(0,0,0,0.5)}#root.info #hint{margin:12px auto;width:320px}#root.info #tests{display:inline-block;text-align:left;list-style-type:none;margin:48px 0;padding:0}#root.info #tests .test{background:#fff;margin:12px 0 0 0;padding:8px 12px 12px 12px;border-bottom:1px solid rgba(0,0,0,0.05)}#root.info #tests .label{display:inline-block;width:250px;font-size:1.4em}#root.info #tests .result{display:inline-block;width:250px;text-align:right;font-size:1.4em;font-weight:bold}#root.info #tests .result.passed{color:#4caf50}#root.info #tests .result.failed{color:#f44336}#root.info #tests .info{margin:4px 0 0 0}#content{overflow:auto;flex:1 1 auto;order:50;position:relative}#fallback{display:none;max-width:960px;margin:16px auto;padding:32px 16px}#fallback table{display:block;width:100%;border-collapse:collapse;background:#fff}#fallback th,#fallback td{padding:6px;text-align:left;border:0;border-bottom:1px solid #f0f0f0}#fallback th{color:#aaa;font-weight:normal;line-height:36px}#fallback td{overflow:hidden;white-space:nowrap}#fallback a,#fallback a:active,#fallback a:visited{display:block;color:inherit;text-decoration:none;cursor:pointer}#fallback a:hover,#fallback a:active:hover,#fallback a:visited:hover{color:#42a5f5}#fallback .fb-i{width:20px;padding-left:12px}#fallback .fb-i img{width:20px;height:20px;position:relative;top:-1px}#fallback .fb-n{width:682px;max-width:682px}#fallback .fb-d{text-align:right;width:160px;min-width:160px}#fallback .fb-s{text-align:right;width:70px;min-width:70px;padding-right:12px}#fallback-hints{display:none;overflow:hidden;text-align:right;background:#fafafa;border-bottom:1px solid rgba(0,0,0,0.05)}#fallback-hints a,#fallback-hints a:active,#fallback-hints a:visited{transition:all .2s ease-in-out;display:inline-block;line-height:48px;color:rgba(0,0,0,0.54);text-decoration:none;outline:0}#fallback-hints a:hover,#fallback-hints a:active:hover,#fallback-hints a:visited:hover{color:#42a5f5}#fallback-hints .backlink{margin:0 16px}#fallback-hints .noJsMsg,#fallback-hints .noBrowserMsg{display:none;margin:0 16px;color:#f44336}html.no-js #root,html.no-browser #root{position:static;overflow:auto}html.no-js #fallback,html.no-browser #fallback,html.no-js #fallback-hints,html.no-browser #fallback-hints{display:block}html.no-js .noJsMsg{display:inline!important}html.no-browser .noBrowserMsg{display:inline!important}#mainrow{display:flex;flex-wrap:nowrap;justify-content:flex-start;align-content:flex-start;align-items:stretch;flex-direction:row;flex:1 1 auto;order:50;height:0}#notification{position:fixed;left:50%;width:200px;margin-left:-100px;z-index:100;padding:3px 6px 6px 6px;color:#fff;background:rgba(0,0,0,0.2);border-radius:0 0 4px 4px;text-align:center;overflow:hidden}#root{display:flex;flex-wrap:nowrap;justify-content:flex-start;align-content:flex-start;align-items:stretch;flex-direction:column;position:absolute;left:0;top:0;right:0;bottom:0;overflow:hidden;background:#fff;line-height:1.4}#root,input,select{font-family:"Ubuntu","Roboto","Helvetica","Arial","sans-serif";font-size:13px;font-weight:normal;color:rgba(0,0,0,0.87)}#sidebar{overflow-x:hidden;overflow-y:auto;flex:0 0 auto;order:0;background:#fafafa;border-right:1px solid rgba(0,0,0,0.05);padding:16px;position:absolute;top:48px;min-height:100%;z-index:1}#sidebar .block{display:block;margin:0 0 24px 0;width:168px}#sidebar .block h1{font-size:1em;margin:2px 0 6px 0}#sidebar .button{border-radius:2px;transition:all .2s ease-in-out;display:inline-block;margin:4px;color:rgba(0,0,0,0.87);cursor:pointer}#sidebar .button:hover{background:rgba(0,0,0,0.03)}#sidebar .button.active{background:rgba(0,0,0,0.03);box-shadow:inset 0 0 4px 0 rgba(0,0,0,0.4)}#sidebar .button img{width:24px;height:24px;padding:12px}#sidebar .select{border-radius:2px;background:transparent;overflow:hidden;outline:0;width:160px;margin:4px;line-height:48px}#sidebar input,#sidebar select{-moz-appearance:none;-ms-appearance:none;-webkit-appearance:none;background:transparent;width:100%;border:0 solid #000;cursor:pointer;outline:0}#sidebar input:hover,#sidebar select:hover{background:rgba(0,0,0,0.03)}#sidebar select{width:187px;padding:0 8px;height:48px;line-height:48px}#sidebar input[type='range']{border-radius:2px;width:144px;margin:4px;padding:8px;vertical-align:middle;height:32px;line-height:32px}#sidebar .range-track{-moz-appearance:none;-ms-appearance:none;-webkit-appearance:none;border-width:0;border-radius:20px;background:#e0e0e0;height:6px}#sidebar .range-thumb{-moz-appearance:none;-ms-appearance:none;-webkit-appearance:none;border-width:0;border-radius:20px;background:#616161;width:16px;height:16px}#sidebar input[type='range']::-webkit-slider-runnable-track{-moz-appearance:none;-ms-appearance:none;-webkit-appearance:none;border-width:0;border-radius:20px;background:#e0e0e0;height:6px}#sidebar input[type='range']::-moz-range-track{-moz-appearance:none;-ms-appearance:none;-webkit-appearance:none;border-width:0;border-radius:20px;background:#e0e0e0;height:6px}#sidebar input[type='range']::-ms-track{-moz-appearance:none;-ms-appearance:none;-webkit-appearance:none;border-width:0;border-radius:20px;background:#e0e0e0;height:6px}#sidebar input[type='range']::-ms-fill-lower{-moz-appearance:none;-ms-appearance:none;-webkit-appearance:none;border-width:0;border-radius:20px;background:#e0e0e0;height:6px}#sidebar input[type='range']::-ms-fill-upper{-moz-appearance:none;-ms-appearance:none;-webkit-appearance:none;border-width:0;border-radius:20px;background:#e0e0e0;height:6px}#sidebar input[type='range']::-webkit-slider-thumb{-moz-appearance:none;-ms-appearance:none;-webkit-appearance:none;border-width:0;border-radius:20px;background:#616161;width:16px;height:16px;margin-top:-5px}#sidebar input[type='range']::-moz-range-thumb{-moz-appearance:none;-ms-appearance:none;-webkit-appearance:none;border-width:0;border-radius:20px;background:#616161;width:16px;height:16px}#sidebar input[type='range']::-ms-thumb{-moz-appearance:none;-ms-appearance:none;-webkit-appearance:none;border-width:0;border-radius:20px;background:#616161;width:16px;height:16px}#sidebar #view-size{display:block}#topbar{display:flex;flex-wrap:nowrap;justify-content:flex-start;align-content:flex-start;align-items:stretch;flex-direction:row;overflow:hidden;flex:0 0 auto;order:1;background:#fafafa;border-bottom:1px solid rgba(0,0,0,0.05);z-index:1}#toolbar{overflow:hidden;flex:0 0 auto;order:1;height:48px}#toolbar .tool{transition:all .2s ease-in-out;display:inline-block;cursor:pointer}#toolbar .tool img{display:inline-block;width:24px;height:24px;padding:12px}#toolbar .tool:hover{background:rgba(0,0,0,0.03)}#flowbar{overflow:hidden;flex:1 1 auto;order:2;height:48px}#backlink{transition:all .2s ease-in-out;display:block;flex:0 0 auto;order:99;text-align:center;padding:6px 12px;overflow:hidden;height:36px}#backlink,#backlink:active,#backlink:visited{color:rgba(0,0,0,0.26);cursor:pointer;text-decoration:none}#backlink:hover{color:#42a5f5;background:rgba(0,0,0,0.03)}#backlink:focus{outline:0}#backlink div{line-height:18px;white-space:nowrap}#view.view-details{margin:32px}#view.view-details .header{position:relative;white-space:nowrap;display:list-item;border-bottom:1px solid rgba(0,0,0,0.07);border-radius:2px 2px 0 0}#view.view-details .header .label,#view.view-details .header .date,#view.view-details .header .size{transition:all .2s ease-in-out;line-height:24px;padding:0 8px 16px 8px;opacity:.4;outline:0}#view.view-details .header .label:hover,#view.view-details .header .date:hover,#view.view-details .header .size:hover{opacity:1;color:#42a5f5}#view.view-details .header .sort{display:none;position:relative;top:-2px;width:20px;height:20px;padding:0 4px}#view.view-details .header .ascending .sort{display:inline}#view.view-details .header .descending .sort{display:inline;-webkit-transform:rotate(180deg);transform:rotate(180deg);zoom:1}#view.view-details .item{overflow:hidden;border-bottom:1px solid rgba(0,0,0,0.07)}#view.view-details .item:hover{box-shadow:0 1px 10px 0 rgba(0,0,0,0.5);z-index:1}#view.view-details .item:last-child{border-radius:0 0 2px 2px}#view.view-details .square{display:inline-block;position:absolute;left:16px;top:-1px;padding:8px}#view.view-details .square .thumb{border-radius:2px;box-shadow:0 0 1px 0 rgba(0,0,0,0.2)}#view.view-details .label,#view.view-details .date,#view.view-details .size{padding:0 8px}#view.view-details .date{position:absolute;right:116px;top:0}#view.view-details .size{position:absolute;right:16px;top:0}#view.view-details .item .label,#view.view-details .item .date,#view.view-details .item .size{line-height:30px}#view.view-details .square{width:16px;height:16px}#view.view-details .square img{width:16px;height:16px}#view.view-details .label{margin:0 246px 0 48px}#view.view-details.width-0 .label{margin-right:4px}#view.view-details.width-0 .date{display:none}#view.view-details.width-0 .size{display:none}#view.view-details.width-1 .label{margin-right:64px}#view.view-details.width-1 .date{display:none}#view.view-grid{margin:28px}#view.view-grid .item{border-radius:2px;overflow:hidden;float:left;margin:8px}#view.view-grid .item:hover{box-shadow:0 1px 10px 0 rgba(0,0,0,0.5)}#view.view-grid .square{display:inline-block;vertical-align:top}#view.view-grid .label{display:inline-block;vertical-align:top;width:180px;padding:0 8px}#view.view-grid .date,#view.view-grid .size{display:none}#view.view-grid .label{line-height:48px}#view.view-grid .square{width:48px;height:48px}#view.view-grid .square img{width:48px;height:48px}#view.view-icons{margin:28px}#view.view-icons .item{border-radius:2px;overflow:hidden;float:left;margin:8px}#view.view-icons .item:hover{box-shadow:0 1px 10px 0 rgba(0,0,0,0.5)}#view.view-icons .landscape{display:block;background:#fafafa}#view.view-icons .label{padding:0 6px;line-height:24px;text-align:center}#view.view-icons .date,#view.view-icons .size{display:none}#view.view-icons .item{width:128px}#view.view-icons .landscape{width:128px;height:96px}#view.view-icons .landscape img{width:96px;height:96px}#view.view-icons .landscape .thumb{width:128px}#view a,#view a:active,#view a:visited{display:block;color:inherit;cursor:pointer;text-decoration:none}#view ul{margin:0;padding:0;list-style:none}#view .header{display:none}#view .item{position:relative;white-space:nowrap;background:#fff}#view .item:hover{color:#42a5f5;background:#fafafa}#view .folder-parent .date,#view .folder-parent .size{display:none}#view .icon{display:none;text-align:center}#view .icon img{position:relative;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%)}#view .icon .thumb{max-width:none;max-height:none}#view .label{display:block;overflow:hidden;text-align:left;text-overflow:ellipsis}#view .date{text-align:right;width:130px}#view .size{text-align:right;width:80px}#view #view-hint{display:block;margin-top:36px;text-align:center;color:rgba(0,0,0,0.05);font-size:5em;font-weight:bold}@media only screen and (max-width:700px){#crumbbar .crumb:not(.active){display:none}#crumbbar .crumb.active .sep{width:0}#tree,#info{display:none!important}}@media print{*,*:before,*:after,*:first-letter ,*:first-line {background:transparent!important;color:#000!important;box-shadow:none!important;text-shadow:none!important}#toolbar,#sidebar,#tree,#info{display:none!important}} --------------------------------------------------------------------------------