hfs 3.2.1 → 3.3.0-alpha1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/admin/assets/{af-U8Sl5sCM.js → af-CevhRske.js} +1 -1
- package/admin/assets/{am-n9TdXja0.js → am-4ouVTwuo.js} +1 -1
- package/admin/assets/{ar-CUpxfuw5.js → ar-71cK8dbb.js} +1 -1
- package/admin/assets/{ar-dz-DC58Z9cj.js → ar-dz-CO7oh1gG.js} +1 -1
- package/admin/assets/{ar-iq-BDkrto6W.js → ar-iq-CjG6db8J.js} +1 -1
- package/admin/assets/{ar-kw-Bz806GvG.js → ar-kw-DMsdR225.js} +1 -1
- package/admin/assets/{ar-ly-DW7JaKir.js → ar-ly-ZhxIwUOA.js} +1 -1
- package/admin/assets/{ar-ma-BuveKbkq.js → ar-ma-Bo3Z1RyK.js} +1 -1
- package/admin/assets/{ar-sa-DRvob1Jp.js → ar-sa-Db44biae.js} +1 -1
- package/admin/assets/{ar-tn-Cae7pfui.js → ar-tn-DNWRixE0.js} +1 -1
- package/admin/assets/{az-B7PpjwCU.js → az-B6LcmVzB.js} +1 -1
- package/admin/assets/{be-DSy_sPdD.js → be-Dp0KhO5x.js} +1 -1
- package/admin/assets/{bg-Djacfatx.js → bg-TsOJJvBm.js} +1 -1
- package/admin/assets/{bi-DOLGYGEN.js → bi-DstczOGo.js} +1 -1
- package/admin/assets/{bm-BmR133he.js → bm-Bf09NN15.js} +1 -1
- package/admin/assets/{bn-DsjLUmm3.js → bn-Da3tHLgx.js} +1 -1
- package/admin/assets/{bn-bd-C3SafRtu.js → bn-bd-CeSalisC.js} +1 -1
- package/admin/assets/{bo-DsMRUw9A.js → bo-Ctxe0IKQ.js} +1 -1
- package/admin/assets/{br-BxR8Zm95.js → br-Y3dPq3Tj.js} +1 -1
- package/admin/assets/{bs-gH68uvCb.js → bs-BbAlSeZx.js} +1 -1
- package/admin/assets/{ca-DfGL180b.js → ca-8-Nn97gi.js} +1 -1
- package/admin/assets/{cs-D4lFVAq6.js → cs-BD5ArFNW.js} +1 -1
- package/admin/assets/{cv-CFyqoRN7.js → cv-CdMFVXGr.js} +1 -1
- package/admin/assets/{cy-DuubtylZ.js → cy-B3QEYlIT.js} +1 -1
- package/admin/assets/{da-Cp7c-T-B.js → da-Bju2YQ9G.js} +1 -1
- package/admin/assets/{de-CeQXU72n.js → de-DdzCTquR.js} +1 -1
- package/admin/assets/{de-at-Cx01BLTk.js → de-at-DgyKCkPl.js} +1 -1
- package/admin/assets/{de-ch-K5Vn_bWQ.js → de-ch-Dk9qkzvn.js} +1 -1
- package/admin/assets/{dist-CfPsVFTp.js → dist-KY_8edrw.js} +1 -1
- package/admin/assets/{dv-DB4pdLQj.js → dv-C5KWK8o4.js} +1 -1
- package/admin/assets/{el-CNA5lg_z.js → el-BDL_lPlM.js} +1 -1
- package/admin/assets/{en-Bpua-Wb5.js → en-Ds3H1Wec.js} +1 -1
- package/admin/assets/{en-au-CKwJ7DKC.js → en-au-CgltfNUb.js} +1 -1
- package/admin/assets/{en-ca-D8vKBgWW.js → en-ca-DEsKzbWO.js} +1 -1
- package/admin/assets/{en-in-Bhx4y1uu.js → en-gb-21AYC3Ik.js} +1 -1
- package/admin/assets/{en-ie-0gd4plad.js → en-ie-aN3g-yqK.js} +1 -1
- package/admin/assets/{en-il-BYIz25Pw.js → en-il-CZl2d7NK.js} +1 -1
- package/admin/assets/{en-tt-Bk-if7Re.js → en-in-C7Kv4c3w.js} +1 -1
- package/admin/assets/{en-nz-CtIJOjgh.js → en-nz-DA_sIaGR.js} +1 -1
- package/admin/assets/{en-sg-iygWx8GW.js → en-sg-CP5PJpZf.js} +1 -1
- package/admin/assets/{en-gb-C3jRv20Y.js → en-tt-B5vDLhL7.js} +1 -1
- package/admin/assets/{eo-DAvER5ej.js → eo-VE1KDD1u.js} +1 -1
- package/admin/assets/{es-C98a0Ggy.js → es-SUzi5oTU.js} +1 -1
- package/admin/assets/{es-do-TCakoZXN.js → es-do-Iri0eWm8.js} +1 -1
- package/admin/assets/{es-mx-BCj7c6Zn.js → es-mx-DwneKeOc.js} +1 -1
- package/admin/assets/{es-pr-rsR3Q8oM.js → es-pr-C4zPUdA1.js} +1 -1
- package/admin/assets/{es-us-DC9NM1XV.js → es-us-BPS67etc.js} +1 -1
- package/admin/assets/{esm-BQaMpob3.js → esm-CyNQ7bBW.js} +1 -1
- package/admin/assets/{et-tJ-d1AZX.js → et-Ciqbfae0.js} +1 -1
- package/admin/assets/{eu-xzUajtaj.js → eu-CGhOwQpe.js} +1 -1
- package/admin/assets/{fa-kR15gQkC.js → fa-BWZiAv_E.js} +1 -1
- package/admin/assets/{fi-DQjRBOgG.js → fi-DJmgkVsJ.js} +1 -1
- package/admin/assets/{fo-BHMXHU45.js → fo-DVez5N-g.js} +1 -1
- package/admin/assets/{fr-DGS71Nvo.js → fr-D206itJo.js} +1 -1
- package/admin/assets/{fr-ca-Bkzyy0tT.js → fr-ca-C6JiEHfi.js} +1 -1
- package/admin/assets/{fr-ch-BRrWrRWV.js → fr-ch-DUTEuSU_.js} +1 -1
- package/admin/assets/{fy-Dkv180q7.js → fy-C_r06zH-.js} +1 -1
- package/admin/assets/{ga-xsoXuVDY.js → ga-CrdQqAN5.js} +1 -1
- package/admin/assets/{gd-cLPVqYdG.js → gd-iWHfhKAH.js} +1 -1
- package/admin/assets/{gl-BUG0DHTt.js → gl-zgfy-pQ0.js} +1 -1
- package/admin/assets/{gom-latn-BKRncAa1.js → gom-latn-CMZ7Vj7V.js} +1 -1
- package/admin/assets/{gu-BpmXErqK.js → gu-DNqIMjZc.js} +1 -1
- package/admin/assets/{he-DNxd9A8z.js → he-OJBbYFzL.js} +1 -1
- package/admin/assets/{hi-dNFE6t75.js → hi-ByrMhKpX.js} +1 -1
- package/admin/assets/{hr-DNZiZtn4.js → hr-CfRZXzCu.js} +1 -1
- package/admin/assets/{ht-B1LoCeln.js → ht-DDrMtLzJ.js} +1 -1
- package/admin/assets/{hu-q6SYps3j.js → hu-Ckeq3R6_.js} +1 -1
- package/admin/assets/{hy-am-BLa2HL3i.js → hy-am-OpZy7Nvg.js} +1 -1
- package/admin/assets/{id-4zvXdXSK.js → id-BE8-Ys79.js} +1 -1
- package/admin/assets/{index-D2UH6ajh.js → index-34fRsXFH.js} +128 -123
- package/admin/assets/{is-B7wmPDNy.js → is-BOxJcH5N.js} +1 -1
- package/admin/assets/{it-CGm31WTp.js → it-BFlrIXvP.js} +1 -1
- package/admin/assets/{it-ch-HfVNoF64.js → it-ch-ILAp-lZZ.js} +1 -1
- package/admin/assets/{ja-RGFi1Jc2.js → ja-CbbYAYyn.js} +1 -1
- package/admin/assets/{jv-BclbE5yu.js → jv-CuLkRQCH.js} +1 -1
- package/admin/assets/{ka-D3ZrxVjT.js → ka-BFeRDN-I.js} +1 -1
- package/admin/assets/{kk-B7aIapNy.js → kk-CMvQxaPk.js} +1 -1
- package/admin/assets/{km-DPwsGner.js → km-BdQbDUNF.js} +1 -1
- package/admin/assets/{kn-CuXmm_DG.js → kn-CE5AS6Nx.js} +1 -1
- package/admin/assets/{ko-BlPgy9aF.js → ko-Ctl1mHOt.js} +1 -1
- package/admin/assets/{ku-B6w51rl_.js → ku-Blbo7opr.js} +1 -1
- package/admin/assets/{ky-RLmSGZmf.js → ky-iCha_cZX.js} +1 -1
- package/admin/assets/{lb-AKcfj05J.js → lb-BaP0S6h1.js} +1 -1
- package/admin/assets/{lo-VBKOzJn1.js → lo-B_Q4zUMa.js} +1 -1
- package/admin/assets/{lt-53JaHFcf.js → lt-BOaP1KGX.js} +1 -1
- package/admin/assets/{lv-DGOgmu9w.js → lv-S1XMSUX1.js} +1 -1
- package/admin/assets/{me-zNrvFUXX.js → me-ChOLVJHC.js} +1 -1
- package/admin/assets/{mi-BBDE1uK4.js → mi-CnoIUOGl.js} +1 -1
- package/admin/assets/{mk-2LiSrAS9.js → mk-BoEaxVXE.js} +1 -1
- package/admin/assets/{ml-BEwbrVql.js → ml-BuvmVn6P.js} +1 -1
- package/admin/assets/{mn-LuMGd2Ic.js → mn-2bvGd1HI.js} +1 -1
- package/admin/assets/{mr-C_dFhleR.js → mr-BAoAWQmy.js} +1 -1
- package/admin/assets/{ms-BHnmZJI4.js → ms-C2eT9r-f.js} +1 -1
- package/admin/assets/{ms-my-FcVPbGSE.js → ms-my-D2ZXdcAf.js} +1 -1
- package/admin/assets/{mt-DzhvOV5Z.js → mt-BL5JZC4T.js} +1 -1
- package/admin/assets/{my-Mmp3v0PH.js → my-CuJ4L0Ji.js} +1 -1
- package/admin/assets/{nb-CYPvI8e3.js → nb-CjE6cT80.js} +1 -1
- package/admin/assets/{ne-BtVsV5BN.js → ne-BL9I0cb1.js} +1 -1
- package/admin/assets/{nl-C6aRDFNr.js → nl-Dt3mtMln.js} +1 -1
- package/admin/assets/{nl-be-X-pQSY5N.js → nl-be-Am1mjZK9.js} +1 -1
- package/admin/assets/{nn-C1m9zYBT.js → nn-ChSewyYy.js} +1 -1
- package/admin/assets/{oc-lnc-CFT7xZs-.js → oc-lnc-x6_ChCE9.js} +1 -1
- package/admin/assets/{pa-in-Bby4AmI2.js → pa-in-DVyN8o2P.js} +1 -1
- package/admin/assets/{pl-MmIf2tXf.js → pl-CqcuAUGV.js} +1 -1
- package/admin/assets/{pt-DHCh_z9j.js → pt-B2BPpD7K.js} +1 -1
- package/admin/assets/{pt-br-Cu8EXyIK.js → pt-br-oBVRyUzP.js} +1 -1
- package/admin/assets/{rn-DZUJ5hf0.js → rn-B3e3nkfp.js} +1 -1
- package/admin/assets/{ro-BRHg1GDk.js → ro-C2tWFx0Q.js} +1 -1
- package/admin/assets/{ru-Wv8fMN5W.js → ru-CCsEUnFL.js} +1 -1
- package/admin/assets/{rw-B_XP1EHM.js → rw-CaCkWlGA.js} +1 -1
- package/admin/assets/{sd-_X3CAPlB.js → sd-90Zixcez.js} +1 -1
- package/admin/assets/{se-FItkWaOK.js → se-DaZXpLsK.js} +1 -1
- package/admin/assets/{sha512-UQMP5wnF.js → sha512-DlGRFb_l.js} +1 -1
- package/admin/assets/{si-DhVYEiDt.js → si-CSoBAkgi.js} +1 -1
- package/admin/assets/{sk-cWZR9gF4.js → sk-pgQaqa2z.js} +1 -1
- package/admin/assets/{sl-CJckZkV8.js → sl-Cr5kSdA7.js} +1 -1
- package/admin/assets/{sq-B7eoM8fS.js → sq-Pxi2MZOP.js} +1 -1
- package/admin/assets/{sr-SfiQA7kg.js → sr-Fdc9-lC-.js} +1 -1
- package/admin/assets/{sr-cyrl-Db8Rrl0U.js → sr-cyrl-06jNWqpg.js} +1 -1
- package/admin/assets/{ss-Bian2WDB.js → ss-BjEzSMit.js} +1 -1
- package/admin/assets/{sv-D-Dsf8uN.js → sv-CqWqUpcA.js} +1 -1
- package/admin/assets/{sv-fi-BBv1GPVJ.js → sv-fi-CsO2xQHd.js} +1 -1
- package/admin/assets/{sw-BIzZvuq6.js → sw-xQUdgYhn.js} +1 -1
- package/admin/assets/{ta-C2JoHqar.js → ta-epbFrZ1M.js} +1 -1
- package/admin/assets/{te-ByKFS-hT.js → te-DusTwU6q.js} +1 -1
- package/admin/assets/{tet-Bq9OQkFH.js → tet-ylc9v4gl.js} +1 -1
- package/admin/assets/{tg-BPqYCigR.js → tg-2QfVTAJf.js} +1 -1
- package/admin/assets/{th-m4ghaYsj.js → th-QIm0Mh7I.js} +1 -1
- package/admin/assets/{tk-CFxWTO9D.js → tk-140KMZeW.js} +1 -1
- package/admin/assets/{tl-ph-BiBY15io.js → tl-ph-S7IZkbx3.js} +1 -1
- package/admin/assets/{tlh-CyBfXfLa.js → tlh-C2fYb34-.js} +1 -1
- package/admin/assets/{tr-69QiF4Yn.js → tr-Be-IM6i4.js} +1 -1
- package/admin/assets/{tzl-BG9jvswA.js → tzl-DMy30zde.js} +1 -1
- package/admin/assets/{tzm-IJGtGn0k.js → tzm-Cu882cHO.js} +1 -1
- package/admin/assets/{tzm-latn-CAelnev_.js → tzm-latn-BYxpYHet.js} +1 -1
- package/admin/assets/{ug-cn-CKlXJ1Cr.js → ug-cn-Cl8Jqk2E.js} +1 -1
- package/admin/assets/{uk-DazXNZ9b.js → uk-B-8XymtC.js} +1 -1
- package/admin/assets/{ur-BFAjqt9p.js → ur-ChGuAlvQ.js} +1 -1
- package/admin/assets/{uz-CjoAOeqe.js → uz-QbfaW7fT.js} +1 -1
- package/admin/assets/{uz-latn-CzIzARA0.js → uz-latn-DIQivLCy.js} +1 -1
- package/admin/assets/{vi-DZuOT62g.js → vi-C2CmYlDu.js} +1 -1
- package/admin/assets/{x-pseudo-DlpsSPis.js → x-pseudo-BWgm1XlP.js} +1 -1
- package/admin/assets/{yo-BvI53ejW.js → yo-8bNbPP6u.js} +1 -1
- package/admin/assets/{zh-ci4y7UyJ.js → zh-CeNSRZ4r.js} +1 -1
- package/admin/assets/{zh-cn-CwOh6Lhp.js → zh-cn-BlbF5C_X.js} +1 -1
- package/admin/assets/{zh-hk-CPgMd5VF.js → zh-hk-kg1c_VSK.js} +1 -1
- package/admin/assets/{zh-tw-DJiWMOSA.js → zh-tw-BCl4UsPA.js} +1 -1
- package/admin/index.html +1 -1
- package/frontend/assets/{dist-legacy-CFPnugjA.js → dist-legacy-DYE1EOcc.js} +1 -1
- package/frontend/assets/index-legacy-Br-Lpsst.js +1 -0
- package/frontend/assets/{lib-legacy-CCULxbTk.js → lib-legacy-C4Gw_0kX.js} +1 -1
- package/frontend/assets/{sha512-legacy-D8zcvvqa.js → sha512-legacy-D3RbPSpl.js} +1 -1
- package/frontend/index.html +1 -1
- package/npm-shrinkwrap.json +16 -12
- package/package.json +6 -5
- package/src/AsapStream.js +18 -14
- package/src/SendList.js +42 -16
- package/src/ThrottledStream.js +3 -3
- package/src/acme.js +23 -10
- package/src/adminApis.js +7 -6
- package/src/api.accounts.js +11 -7
- package/src/api.auth.js +8 -5
- package/src/api.cert.js +1 -1
- package/src/api.get_file_list.js +4 -3
- package/src/api.lang.js +3 -2
- package/src/api.monitor.js +1 -1
- package/src/api.net.js +3 -1
- package/src/api.plugins.js +2 -0
- package/src/api.vfs.js +5 -4
- package/src/apiMiddleware.js +5 -1
- package/src/auth.js +4 -1
- package/src/basicWeb.js +1 -1
- package/src/block.js +5 -4
- package/src/commands.js +6 -5
- package/src/comments.js +29 -13
- package/src/config.js +7 -4
- package/src/connections.js +3 -2
- package/src/consoleLog.js +5 -1
- package/src/cross-const.js +27 -1
- package/src/cross.js +32 -33
- package/src/ddns.js +1 -4
- package/src/events.js +1 -4
- package/src/fileAttr.js +6 -2
- package/src/frontEndApis.js +7 -3
- package/src/geo.js +8 -2
- package/src/github.js +10 -9
- package/src/index.js +1 -1
- package/src/ips.js +24 -3
- package/src/langs/embedded.js +2 -1
- package/src/langs/hfs-lang-ar.json +1 -0
- package/src/langs/hfs-lang-bg.json +1 -0
- package/src/langs/hfs-lang-de.json +1 -0
- package/src/langs/hfs-lang-el.json +1 -0
- package/src/langs/hfs-lang-es.json +1 -0
- package/src/langs/hfs-lang-fi.json +1 -0
- package/src/langs/hfs-lang-fr.json +1 -0
- package/src/langs/hfs-lang-hu.json +1 -0
- package/src/langs/hfs-lang-it.json +1 -0
- package/src/langs/hfs-lang-ja.json +1 -0
- package/src/langs/hfs-lang-ko.json +1 -0
- package/src/langs/hfs-lang-lt.json +1 -0
- package/src/langs/hfs-lang-ms.json +1 -0
- package/src/langs/hfs-lang-nl.json +1 -0
- package/src/langs/hfs-lang-pl.json +182 -0
- package/src/langs/hfs-lang-pt-br.json +1 -0
- package/src/langs/hfs-lang-ro.json +1 -0
- package/src/langs/hfs-lang-ru.json +1 -0
- package/src/langs/hfs-lang-sr-latn.json +1 -0
- package/src/langs/hfs-lang-sr.json +1 -0
- package/src/langs/hfs-lang-th.json +1 -0
- package/src/langs/hfs-lang-tr.json +1 -0
- package/src/langs/hfs-lang-uk.json +1 -0
- package/src/langs/hfs-lang-vi.json +1 -0
- package/src/langs/hfs-lang-zh-tw.json +1 -0
- package/src/langs/hfs-lang-zh.json +1 -0
- package/src/listen.js +18 -14
- package/src/log.js +11 -2
- package/src/middlewares.js +8 -6
- package/src/misc.js +3 -3
- package/src/multipartUpload.js +1 -2
- package/src/nat.js +5 -3
- package/src/outboundProxy.js +8 -0
- package/src/perm.js +5 -3
- package/src/plugins.js +58 -36
- package/src/selfCheck.js +8 -7
- package/src/serveFile.js +8 -6
- package/src/serveGuiAndSharedFiles.js +7 -6
- package/src/serveGuiFiles.js +13 -1
- package/src/serverCode.js +27 -0
- package/src/throttler.js +3 -2
- package/src/update.js +9 -3
- package/src/upload.js +30 -12
- package/src/uploadOwners.js +95 -0
- package/src/util-files.js +4 -2
- package/src/util-http.js +3 -1
- package/src/vfs.js +36 -28
- package/src/walkDir.js +24 -11
- package/src/watchLoad.js +13 -2
- package/src/webdav.js +16 -2
- package/src/zip.js +4 -3
- package/frontend/assets/index-legacy-CCOgiwQJ.js +0 -1
package/src/cross.js
CHANGED
|
@@ -17,7 +17,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
17
17
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
18
|
};
|
|
19
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
-
exports.VFS_STORED_KEYS = exports.PERM_KEYS = exports.defaultPerms = exports.WHO_ADMIN = exports.WHO_ANY_ACCOUNT = exports.WHO_NO_ONE = exports.WHO_ANYONE = exports.LIST = exports.
|
|
20
|
+
exports.VFS_STORED_KEYS = exports.PERM_KEYS = exports.defaultPerms = exports.WHO_ADMIN = exports.WHO_ANY_ACCOUNT = exports.WHO_NO_ONE = exports.WHO_ANYONE = exports.LIST = exports.THEME_OPTIONS = exports.SORT_BY_OPTIONS = exports.FRONTEND_OPTIONS = exports.MAX_TILE_SIZE = exports.DAY = exports.HOUR = exports.MINUTE = exports.WIKI_URL = exports.REPO_URL = exports.WEBSITE = void 0;
|
|
21
21
|
exports.isWhoObject = isWhoObject;
|
|
22
22
|
exports.formatBytes = formatBytes;
|
|
23
23
|
exports.formatSpeed = formatSpeed;
|
|
@@ -92,6 +92,7 @@ exports.safeDecodeURIComponent = safeDecodeURIComponent;
|
|
|
92
92
|
exports.popKey = popKey;
|
|
93
93
|
exports.patchKey = patchKey;
|
|
94
94
|
exports.retry = retry;
|
|
95
|
+
exports.callAsPromise = callAsPromise;
|
|
95
96
|
exports.toMutable = toMutable;
|
|
96
97
|
exports.shortenAgent = shortenAgent;
|
|
97
98
|
// This file is part of HFS - Copyright 2021-2023, Massimo Melina <a@rejetto.com> - License https://www.gnu.org/licenses/gpl-3.0.txt
|
|
@@ -108,26 +109,21 @@ exports.HOUR = 60 * exports.MINUTE;
|
|
|
108
109
|
exports.DAY = 24 * exports.HOUR;
|
|
109
110
|
exports.MAX_TILE_SIZE = 10;
|
|
110
111
|
exports.FRONTEND_OPTIONS = {
|
|
111
|
-
file_menu_on_link: true,
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
112
|
+
[cross_const_1.CFG.file_menu_on_link]: true,
|
|
113
|
+
[cross_const_1.CFG.menu_at_top]: false,
|
|
114
|
+
[cross_const_1.CFG.tile_size]: 0,
|
|
115
|
+
[cross_const_1.CFG.page_size]: 100,
|
|
116
|
+
[cross_const_1.CFG.sort_by]: 'name',
|
|
117
|
+
[cross_const_1.CFG.invert_order]: false,
|
|
118
|
+
[cross_const_1.CFG.folders_first]: true,
|
|
119
|
+
[cross_const_1.CFG.sort_numerics]: false,
|
|
120
|
+
[cross_const_1.CFG.title_with_path]: true,
|
|
121
|
+
[cross_const_1.CFG.theme]: '',
|
|
122
|
+
[cross_const_1.CFG.auto_play_seconds]: 5,
|
|
123
|
+
[cross_const_1.CFG.disableTranslation]: false,
|
|
122
124
|
};
|
|
123
125
|
exports.SORT_BY_OPTIONS = ['name', 'extension', 'size', 'time', 'creation'];
|
|
124
126
|
exports.THEME_OPTIONS = { auto: '', light: 'light', dark: 'dark' };
|
|
125
|
-
// had found an interesting way to infer a type from all the calls to defineConfig (by the literals passed), but would not be usable also by admin-panel
|
|
126
|
-
exports.CFG = constMap(['geo_enable', 'geo_allow', 'geo_list', 'geo_allow_unknown', 'dynamic_dns_url',
|
|
127
|
-
'log', 'error_log', 'log_rotation', 'dont_log_net', 'log_gui', 'log_api', 'log_ua', 'log_spam', 'track_ips',
|
|
128
|
-
'max_downloads', 'max_downloads_per_ip', 'max_downloads_per_account', 'roots', 'force_address', 'split_uploads',
|
|
129
|
-
'force_lang', 'suspend_plugins', 'base_url', 'size_1024', 'disable_custom_html', 'comments_storage',
|
|
130
|
-
'force_webdav_login', 'webdav_initial_auth', 'outbound_proxy', 'mapped_port', 'upnp_enabled', 'show_uploader']);
|
|
131
127
|
exports.LIST = { add: '+', remove: '-', update: '=', props: 'props', ready: 'ready', error: 'e' };
|
|
132
128
|
exports.WHO_ANYONE = true;
|
|
133
129
|
exports.WHO_NO_ONE = false;
|
|
@@ -144,9 +140,6 @@ exports.defaultPerms = {
|
|
|
144
140
|
exports.PERM_KEYS = typedKeys(exports.defaultPerms);
|
|
145
141
|
exports.VFS_STORED_KEYS = ['name', 'source', 'masks', 'default', 'accept', 'rename',
|
|
146
142
|
'mime', 'url', 'target', 'comment', 'icon', 'order', 'children', ...exports.PERM_KEYS];
|
|
147
|
-
function constMap(a) {
|
|
148
|
-
return Object.fromEntries(a.map(x => [x, x]));
|
|
149
|
-
}
|
|
150
143
|
function isWhoObject(v) {
|
|
151
144
|
return v !== null && typeof v === 'object' && !Array.isArray(v);
|
|
152
145
|
}
|
|
@@ -190,13 +183,13 @@ function haveTimeout(ms, job, error) {
|
|
|
190
183
|
function objFromKeys(src, getValue) {
|
|
191
184
|
return Object.fromEntries(src.map(k => [k, getValue(k)]));
|
|
192
185
|
}
|
|
193
|
-
function enforceFinal(sub, s, evenEmpty = false) {
|
|
186
|
+
function enforceFinal(sub, s = '', evenEmpty = false) {
|
|
194
187
|
return (s ? !s.endsWith(sub) : evenEmpty) ? s + sub : s;
|
|
195
188
|
}
|
|
196
189
|
function removeFinal(sub, s) {
|
|
197
190
|
return s.endsWith(sub) ? s.slice(0, -sub.length) : s;
|
|
198
191
|
}
|
|
199
|
-
function enforceStarting(sub, s, evenEmpty = false) {
|
|
192
|
+
function enforceStarting(sub, s = '', evenEmpty = false) {
|
|
200
193
|
return (s ? !s.startsWith(sub) : evenEmpty) ? sub + s : s;
|
|
201
194
|
}
|
|
202
195
|
function removeStarting(sub, s) {
|
|
@@ -451,7 +444,7 @@ function xlate(input, table) {
|
|
|
451
444
|
}
|
|
452
445
|
// remove brackets and port (if any)
|
|
453
446
|
function normalizeHost(host) {
|
|
454
|
-
return host[0] === '[' ? host.slice(1, host.indexOf(']')) : host
|
|
447
|
+
return host[0] === '[' ? host.slice(1, host.indexOf(']')) : host.split(':')[0];
|
|
455
448
|
}
|
|
456
449
|
function isIpLocalHost(ip) {
|
|
457
450
|
return ip === '::1' || ip.endsWith('127.0.0.1');
|
|
@@ -565,16 +558,22 @@ function patchKey(o, k, replacer) {
|
|
|
565
558
|
o[k] = replacer(o[k]);
|
|
566
559
|
return o;
|
|
567
560
|
}
|
|
568
|
-
//
|
|
561
|
+
// retry rejected operations because filesystem resources may be released late
|
|
569
562
|
async function retry(cb, delay = 1000) {
|
|
570
|
-
let
|
|
571
|
-
while (true)
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
563
|
+
let retries = 3;
|
|
564
|
+
while (true)
|
|
565
|
+
try {
|
|
566
|
+
return await cb();
|
|
567
|
+
}
|
|
568
|
+
catch (e) {
|
|
569
|
+
if (!retries--)
|
|
570
|
+
throw e;
|
|
571
|
+
await wait(delay);
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
// normalize callback results and synchronous throws into a promise
|
|
575
|
+
function callAsPromise(callback) {
|
|
576
|
+
return Promise.resolve().then(callback);
|
|
578
577
|
}
|
|
579
578
|
function toMutable(value) {
|
|
580
579
|
return Array.isArray(value) ? value.slice() : { ...value };
|
package/src/ddns.js
CHANGED
|
@@ -73,10 +73,7 @@ async function get_dynamic_dns_error() {
|
|
|
73
73
|
if (last)
|
|
74
74
|
this.push(last); // start by sending current state
|
|
75
75
|
unsub = events_1.default.on('dynamicDnsError', x => this.push(x)); // send updates, if any. This simplified way to manage the data stream is acceptable for this case of extremely low throughput
|
|
76
|
-
|
|
77
|
-
async destroy() {
|
|
78
|
-
unsub();
|
|
79
|
-
this.push(null);
|
|
76
|
+
this.once('close', unsub);
|
|
80
77
|
}
|
|
81
78
|
});
|
|
82
79
|
}
|
package/src/events.js
CHANGED
|
@@ -19,10 +19,7 @@ class BetterEventEmitter {
|
|
|
19
19
|
this.emit(e + LISTENERS_SUFFIX, cbs, listener);
|
|
20
20
|
}
|
|
21
21
|
if (callNow)
|
|
22
|
-
|
|
23
|
-
listener();
|
|
24
|
-
}
|
|
25
|
-
catch { }
|
|
22
|
+
Promise.resolve().then(listener).catch(console.error);
|
|
26
23
|
return () => {
|
|
27
24
|
for (const e of event) {
|
|
28
25
|
const cbs = this.listeners.get(e);
|
package/src/fileAttr.js
CHANGED
|
@@ -35,7 +35,7 @@ async function storeFileAttr(path, k, v) {
|
|
|
35
35
|
return true;
|
|
36
36
|
}
|
|
37
37
|
// fallback to our kv-storage
|
|
38
|
-
return await exports.fileAttrDb.put(fileAttrKey(path, k), v)?.
|
|
38
|
+
return await exports.fileAttrDb.put(fileAttrKey(path, k), v)?.then(() => true, (e) => {
|
|
39
39
|
console.error("Couldn't store metadata on", path, String(e.message || e));
|
|
40
40
|
return false;
|
|
41
41
|
}) ?? true; // if put is undefined, the value was already there
|
|
@@ -45,11 +45,15 @@ async function loadFileAttr(path, k) {
|
|
|
45
45
|
.then((x) => x === '' ? undefined : (0, cross_1.tryJson)(String(x)), () => exports.fileAttrDb.isOpen() ? exports.fileAttrDb.get(fileAttrKey(path, k)).catch(console.error) : null)
|
|
46
46
|
?? undefined; // normalize, as we get null instead of undefined on windows
|
|
47
47
|
}
|
|
48
|
+
// remove file-attr for files that don't exist anymore
|
|
48
49
|
async function purgeFileAttr() {
|
|
49
50
|
let n = 0;
|
|
50
51
|
await Promise.all(Array.from(exports.fileAttrDb.keys()).map(k => {
|
|
51
52
|
const fn = splitFileAttrKey(k)?.filePath;
|
|
52
|
-
return fn && (0, promises_1.access)(fn).catch(() =>
|
|
53
|
+
return fn && (0, promises_1.access)(fn).catch(() => {
|
|
54
|
+
n++;
|
|
55
|
+
return exports.fileAttrDb.del(k);
|
|
56
|
+
});
|
|
53
57
|
}));
|
|
54
58
|
if (n)
|
|
55
59
|
await exports.fileAttrDb.rewrite();
|
package/src/frontEndApis.js
CHANGED
|
@@ -20,6 +20,7 @@ const promises_1 = require("fs/promises");
|
|
|
20
20
|
const path_1 = require("path");
|
|
21
21
|
const upload_1 = require("./upload");
|
|
22
22
|
const misc_1 = require("./misc");
|
|
23
|
+
const uploadOwners_1 = require("./uploadOwners");
|
|
23
24
|
const config_1 = require("./config");
|
|
24
25
|
const comments_1 = require("./comments");
|
|
25
26
|
const SendList_1 = require("./SendList");
|
|
@@ -99,7 +100,7 @@ exports.frontEndApis = {
|
|
|
99
100
|
throw new apiMiddleware_1.ApiError(const_1.HTTP_NOT_FOUND);
|
|
100
101
|
if ((0, vfs_1.isRoot)(node) || !(0, util_files_1.isValidFileName)(dest))
|
|
101
102
|
return new apiMiddleware_1.ApiError(const_1.HTTP_FORBIDDEN);
|
|
102
|
-
await requestedRename(node, dest, ctx);
|
|
103
|
+
await requestedRename(node, dest, ctx, uri);
|
|
103
104
|
return {};
|
|
104
105
|
},
|
|
105
106
|
async move_files({ uri_from, uri_to }, ctx) {
|
|
@@ -126,7 +127,8 @@ exports.frontEndApis = {
|
|
|
126
127
|
return new apiMiddleware_1.ApiError(const_1.HTTP_UNAUTHORIZED);
|
|
127
128
|
if (!node.source)
|
|
128
129
|
return new apiMiddleware_1.ApiError(const_1.HTTP_FAILED_DEPENDENCY);
|
|
129
|
-
await (0, comments_1.setCommentFor)(node.source, comment)
|
|
130
|
+
if (!await (0, comments_1.setCommentFor)(node.source, comment))
|
|
131
|
+
return new apiMiddleware_1.ApiError(const_1.HTTP_SERVER_ERROR);
|
|
130
132
|
return {};
|
|
131
133
|
},
|
|
132
134
|
async get_folder_size_partial({ id }) {
|
|
@@ -199,11 +201,12 @@ async function moveFiles(uri_from, uri_to, ctx, override) {
|
|
|
199
201
|
await (0, promises_1.copyFile)(src, dest);
|
|
200
202
|
await (0, promises_1.unlink)(src);
|
|
201
203
|
}).then(() => (0, misc_1.moveStoredFileAttrs)(src, dest))
|
|
204
|
+
.then(() => (0, uploadOwners_1.moveUploadOwner)(from1, (0, misc_1.join)(uri_to, destName)))
|
|
202
205
|
.catch(e => e.code || String(e));
|
|
203
206
|
}))
|
|
204
207
|
};
|
|
205
208
|
}
|
|
206
|
-
async function requestedRename(node, newName, ctx) {
|
|
209
|
+
async function requestedRename(node, newName, ctx, uri = ctx.path) {
|
|
207
210
|
if (!node)
|
|
208
211
|
throw new apiMiddleware_1.ApiError(const_1.HTTP_NOT_FOUND);
|
|
209
212
|
// requestedRename is exported, so keep disk rename confinement here even when callers pre-validate
|
|
@@ -223,6 +226,7 @@ async function requestedRename(node, newName, ctx) {
|
|
|
223
226
|
const destSource = (0, path_1.join)((0, path_1.dirname)(node.source), newName);
|
|
224
227
|
await (0, promises_1.rename)(node.source, destSource);
|
|
225
228
|
await (0, misc_1.moveStoredFileAttrs)(node.source, destSource);
|
|
229
|
+
await (0, uploadOwners_1.moveUploadOwner)(uri, (0, misc_1.join)((0, path_1.dirname)(uri), (0, misc_1.pathEncode)(newName)));
|
|
226
230
|
(0, comments_1.getCommentFor)(node.source).then(c => {
|
|
227
231
|
if (!c)
|
|
228
232
|
return;
|
package/src/geo.js
CHANGED
|
@@ -15,12 +15,18 @@ const enabled = (0, config_1.defineConfig)(misc_1.CFG.geo_enable, false);
|
|
|
15
15
|
const allow = (0, config_1.defineConfig)(misc_1.CFG.geo_allow, null);
|
|
16
16
|
const list = (0, config_1.defineConfig)(misc_1.CFG.geo_list, []);
|
|
17
17
|
const allowUnknown = (0, config_1.defineConfig)(misc_1.CFG.geo_allow_unknown, false);
|
|
18
|
-
|
|
18
|
+
const ignoreNet = (0, config_1.defineConfig)(misc_1.CFG.geo_ignore_net, '', v => (0, misc_1.makeNetMatcher)(v));
|
|
19
|
+
let filesCheck = Promise.resolve();
|
|
20
|
+
enabled.sub(() => {
|
|
21
|
+
filesCheck = checkFiles().catch((e) => console.error('Failed to load geo-ip db:', e?.message || String(e)));
|
|
22
|
+
});
|
|
19
23
|
setInterval(checkFiles, misc_1.DAY); // keep updated at run-time
|
|
20
24
|
// benchmark: memoize can make this 44x faster
|
|
21
25
|
exports.ip2country = lodash_1.default.memoize((ip) => ip2location.getCountryShortAsync(ip).then(v => v === '-' ? '' : v, () => ''));
|
|
22
26
|
const geoFilter = async (ctx, next) => {
|
|
23
|
-
if (enabled.get() && !(0, misc_1.isLocalHost)(ctx) && !(0, misc_1.isIpLan)(ctx.ip)) {
|
|
27
|
+
if (enabled.get() && !(0, misc_1.isLocalHost)(ctx) && !(0, misc_1.isIpLan)(ctx.ip) && !ignoreNet.compiled()(ctx.ip)) {
|
|
28
|
+
if (!isOpen()) // keep startup independent of the geo db download, but don't classify external requests before the db had a chance to load
|
|
29
|
+
await filesCheck;
|
|
24
30
|
const { connection } = ctx.state;
|
|
25
31
|
const country = connection.country ??= await (0, exports.ip2country)(ctx.ip);
|
|
26
32
|
if (country)
|
package/src/github.js
CHANGED
|
@@ -122,18 +122,19 @@ async function downloadPlugin(repo, { branch = '', overwrite = false } = {}) {
|
|
|
122
122
|
if (wasRunning)
|
|
123
123
|
await (0, plugins_1.stopPlugin)(folder); // stop old
|
|
124
124
|
// move data, and consider late release of the resource, up to a few seconds
|
|
125
|
-
await (0, misc_1.retry)(() => (0, promises_1.rename)((0, path_1.join)(installPath, plugins_1.STORAGE_FOLDER), (0, path_1.join)(tempInstallPath, plugins_1.STORAGE_FOLDER))
|
|
126
|
-
|
|
125
|
+
await (0, misc_1.retry)(() => (0, promises_1.rename)((0, path_1.join)(installPath, plugins_1.STORAGE_FOLDER), (0, path_1.join)(tempInstallPath, plugins_1.STORAGE_FOLDER)).catch(e => {
|
|
126
|
+
if (e.code !== 'ENOENT')
|
|
127
|
+
throw e;
|
|
128
|
+
}));
|
|
127
129
|
// delete old folder (if any), but it may fail in the presence of .node files, so we rename it first as a precaution (clearing require.cache doesn't help). Especially on Windows, it may be impossible to delete dll files until our process is terminated (in which case, retrying is useless).
|
|
128
130
|
const deleteMe = installPath + plugins_1.DELETE_ME_SUFFIX;
|
|
129
|
-
await (0, misc_1.retry)(() => (0, promises_1.rename)(installPath, deleteMe).
|
|
130
|
-
if (e.code
|
|
131
|
-
|
|
132
|
-
console.warn("Error renaming old plugin folder:", String(e));
|
|
133
|
-
}));
|
|
134
|
-
await (0, misc_1.retry)(() => (0, promises_1.rm)(deleteMe, { recursive: true, force: true /*ignore ENOENT*/ }).then(() => 1, e => {
|
|
135
|
-
console.warn("Error deleting old plugin folder:", String(e));
|
|
131
|
+
await (0, misc_1.retry)(() => (0, promises_1.rename)(installPath, deleteMe).catch(e => {
|
|
132
|
+
if (e.code !== 'ENOENT')
|
|
133
|
+
throw e;
|
|
136
134
|
}));
|
|
135
|
+
// a disabled leftover cannot block replacement and will be cleaned at startup
|
|
136
|
+
await (0, misc_1.retry)(() => (0, promises_1.rm)(deleteMe, { recursive: true, force: true /*ignore ENOENT*/ }))
|
|
137
|
+
.catch(e => console.warn("Error deleting old plugin folder:", String(e)));
|
|
137
138
|
// final replace
|
|
138
139
|
await (0, promises_1.rename)(tempInstallPath, installPath)
|
|
139
140
|
.catch(e => { throw e.code !== 'ENOENT' ? e : new apiMiddleware_1.ApiError(const_1.HTTP_NOT_ACCEPTABLE, "missing main file"); });
|
package/src/index.js
CHANGED
|
@@ -86,7 +86,7 @@ process.on('uncaughtException', (err) => {
|
|
|
86
86
|
// this warning is scaring users, and has been removed in node 20.12.0 https://github.com/nodejs/node/pull/51204
|
|
87
87
|
const original = process.emitWarning;
|
|
88
88
|
process.emitWarning = warn => String(warn).startsWith('An error event has already been emitted') || original.call(process, warn);
|
|
89
|
-
(0, config_1.defineConfig)(
|
|
89
|
+
(0, config_1.defineConfig)(misc_1.CFG.proxies, 0).sub(n => {
|
|
90
90
|
exports.app.proxy = n > 0;
|
|
91
91
|
exports.app.maxIpsCount = n;
|
|
92
92
|
});
|
package/src/ips.js
CHANGED
|
@@ -14,9 +14,30 @@ exports.ips = new kvstorage_1.KvStorage({
|
|
|
14
14
|
});
|
|
15
15
|
(0, first_1.onProcessExit)(() => exports.ips.close());
|
|
16
16
|
const trackIpsMw = async (ctx, next) => {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
const tracking = exports.ips.isOpen() && !(0, misc_1.isLocalHost)(ctx);
|
|
18
|
+
const ts = new Date;
|
|
19
|
+
const country = ctx.state.connection.country;
|
|
20
|
+
let failed = false;
|
|
21
|
+
// defer storage update until downstream middlewares have assigned status or thrown
|
|
22
|
+
try {
|
|
23
|
+
await next();
|
|
24
|
+
}
|
|
25
|
+
catch (e) {
|
|
26
|
+
failed = true;
|
|
27
|
+
throw e;
|
|
28
|
+
}
|
|
29
|
+
finally {
|
|
30
|
+
if (tracking) {
|
|
31
|
+
// keep the counter update here so failures from downstream middlewares are counted with the final status
|
|
32
|
+
const was = exports.ips.getSync(ctx.ip);
|
|
33
|
+
void exports.ips.put(ctx.ip, {
|
|
34
|
+
ts,
|
|
35
|
+
country,
|
|
36
|
+
served: (was?.served || 0) + (failed || ctx.status >= 400 ? 0 : 1),
|
|
37
|
+
failed: (was?.failed || 0) + (failed || ctx.status >= 400 ? 1 : 0),
|
|
38
|
+
}).catch(e => console.error("Couldn't track IP", ctx.ip, String(e)));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
20
41
|
};
|
|
21
42
|
exports.trackIpsMw = trackIpsMw;
|
|
22
43
|
trackIps.sub(v => {
|
package/src/langs/embedded.js
CHANGED
|
@@ -13,6 +13,7 @@ const hfs_lang_ko_json_1 = __importDefault(require("./hfs-lang-ko.json"));
|
|
|
13
13
|
const hfs_lang_ms_json_1 = __importDefault(require("./hfs-lang-ms.json"));
|
|
14
14
|
const hfs_lang_zh_tw_json_1 = __importDefault(require("./hfs-lang-zh-tw.json"));
|
|
15
15
|
const hfs_lang_fr_json_1 = __importDefault(require("./hfs-lang-fr.json"));
|
|
16
|
+
const hfs_lang_pl_json_1 = __importDefault(require("./hfs-lang-pl.json"));
|
|
16
17
|
const hfs_lang_pt_br_json_1 = __importDefault(require("./hfs-lang-pt-br.json"));
|
|
17
18
|
const hfs_lang_vi_json_1 = __importDefault(require("./hfs-lang-vi.json"));
|
|
18
19
|
const hfs_lang_es_json_1 = __importDefault(require("./hfs-lang-es.json"));
|
|
@@ -28,4 +29,4 @@ const hfs_lang_uk_json_1 = __importDefault(require("./hfs-lang-uk.json"));
|
|
|
28
29
|
const hfs_lang_ar_json_1 = __importDefault(require("./hfs-lang-ar.json"));
|
|
29
30
|
const hfs_lang_lt_json_1 = __importDefault(require("./hfs-lang-lt.json"));
|
|
30
31
|
const hfs_lang_bg_json_1 = __importDefault(require("./hfs-lang-bg.json"));
|
|
31
|
-
exports.default = { it: hfs_lang_it_json_1.default, zh: hfs_lang_zh_json_1.default, ru: hfs_lang_ru_json_1.default, sr: hfs_lang_sr_json_1.default, 'sr-latn': hfs_lang_sr_latn_json_1.default, ko: hfs_lang_ko_json_1.default, ms: hfs_lang_ms_json_1.default, 'zh-tw': hfs_lang_zh_tw_json_1.default, fr: hfs_lang_fr_json_1.default, 'pt-br': hfs_lang_pt_br_json_1.default, vi: hfs_lang_vi_json_1.default, es: hfs_lang_es_json_1.default, nl: hfs_lang_nl_json_1.default, el: hfs_lang_el_json_1.default, de: hfs_lang_de_json_1.default, fi: hfs_lang_fi_json_1.default, hu: hfs_lang_hu_json_1.default, ja: hfs_lang_ja_json_1.default, ro: hfs_lang_ro_json_1.default, tr: hfs_lang_tr_json_1.default, th: hfs_lang_th_json_1.default, uk: hfs_lang_uk_json_1.default, ar: hfs_lang_ar_json_1.default, lt: hfs_lang_lt_json_1.default, bg: hfs_lang_bg_json_1.default };
|
|
32
|
+
exports.default = { it: hfs_lang_it_json_1.default, zh: hfs_lang_zh_json_1.default, ru: hfs_lang_ru_json_1.default, sr: hfs_lang_sr_json_1.default, 'sr-latn': hfs_lang_sr_latn_json_1.default, ko: hfs_lang_ko_json_1.default, ms: hfs_lang_ms_json_1.default, 'zh-tw': hfs_lang_zh_tw_json_1.default, fr: hfs_lang_fr_json_1.default, pl: hfs_lang_pl_json_1.default, 'pt-br': hfs_lang_pt_br_json_1.default, vi: hfs_lang_vi_json_1.default, es: hfs_lang_es_json_1.default, nl: hfs_lang_nl_json_1.default, el: hfs_lang_el_json_1.default, de: hfs_lang_de_json_1.default, fi: hfs_lang_fi_json_1.default, hu: hfs_lang_hu_json_1.default, ja: hfs_lang_ja_json_1.default, ro: hfs_lang_ro_json_1.default, tr: hfs_lang_tr_json_1.default, th: hfs_lang_th_json_1.default, uk: hfs_lang_uk_json_1.default, ar: hfs_lang_ar_json_1.default, lt: hfs_lang_lt_json_1.default, bg: hfs_lang_bg_json_1.default };
|
|
@@ -96,6 +96,7 @@
|
|
|
96
96
|
"upload_finished": "{n} تم رفعه ({size})",
|
|
97
97
|
"upload_errors": "{n} فشلوا",
|
|
98
98
|
"upload_file_rejected": "بعض الملفات لم تُقبل",
|
|
99
|
+
"delete_unfinished_upload": "هل تريد إزالة الرفع غير المكتمل؟",
|
|
99
100
|
"File menu": "قائمة الملف",
|
|
100
101
|
"Folder menu": "قائمة المجلد",
|
|
101
102
|
"Name": "الاسم",
|
|
@@ -94,6 +94,7 @@
|
|
|
94
94
|
"upload_finished": "{n} завършени ({size})",
|
|
95
95
|
"upload_errors": "{n} неуспешни",
|
|
96
96
|
"upload_file_rejected": "Някои файлове не бяха приети",
|
|
97
|
+
"delete_unfinished_upload": "Премахване на незавършеното качване?",
|
|
97
98
|
"File menu": "Меню на файл",
|
|
98
99
|
"Folder menu": "Меню на папка",
|
|
99
100
|
"Name": "Име",
|
|
@@ -96,6 +96,7 @@
|
|
|
96
96
|
"upload_finished": "{n} fertig ({size})",
|
|
97
97
|
"upload_errors": "{n} fehlgeschlagen",
|
|
98
98
|
"upload_file_rejected": "Einige Dateien wurden nicht akzeptiert",
|
|
99
|
+
"delete_unfinished_upload": "Unvollständigen Upload entfernen?",
|
|
99
100
|
"File menu": "Dateimenü",
|
|
100
101
|
"Folder menu": "Ordnermenü",
|
|
101
102
|
"Name": "Name",
|
|
@@ -96,6 +96,7 @@
|
|
|
96
96
|
"upload_finished": "{n} ολοκληρώθηκαν ({size})",
|
|
97
97
|
"upload_errors": "{n} απέτυχαν",
|
|
98
98
|
"upload_file_rejected": "Κάποια αρχεία δεν γίνονται δεκτά",
|
|
99
|
+
"delete_unfinished_upload": "Να αφαιρεθεί η ημιτελής μεταφόρτωση;",
|
|
99
100
|
"File menu": "Μενού αρχείου",
|
|
100
101
|
"Folder menu": "Μενού φακέλου",
|
|
101
102
|
"Name": "Όνομα",
|
|
@@ -96,6 +96,7 @@
|
|
|
96
96
|
"upload_finished": "{n} completado ({size})",
|
|
97
97
|
"upload_errors": "{n} fallido",
|
|
98
98
|
"upload_file_rejected": "Algunos archivos no fueron aceptados",
|
|
99
|
+
"delete_unfinished_upload": "¿Eliminar la subida sin terminar?",
|
|
99
100
|
"File menu": "Archivo",
|
|
100
101
|
"Folder menu": "Carpeta",
|
|
101
102
|
"Name": "Nombre",
|
|
@@ -96,6 +96,7 @@
|
|
|
96
96
|
"upload_finished": "{n} tiedostoa tai kansiota lähetetty onnistuneesti ({size})",
|
|
97
97
|
"upload_errors": "{n} epäonnistui",
|
|
98
98
|
"upload_file_rejected": "Joitakin tiedostoja ei hyväksytty",
|
|
99
|
+
"delete_unfinished_upload": "Poistetaanko keskeneräinen lähetys?",
|
|
99
100
|
"File menu": "Tiedostovalikko",
|
|
100
101
|
"Folder menu": "Kansiovalikko",
|
|
101
102
|
"Name": "Nimi",
|
|
@@ -96,6 +96,7 @@
|
|
|
96
96
|
"upload_finished": "{n} terminé(s) ({size})",
|
|
97
97
|
"upload_errors": "{n} échoués",
|
|
98
98
|
"upload_file_rejected": "Certains fichiers ont été refusés",
|
|
99
|
+
"delete_unfinished_upload": "Supprimer l'envoi inachevé ?",
|
|
99
100
|
"File menu": "Menu du fichier",
|
|
100
101
|
"Folder menu": "Menu du dossier",
|
|
101
102
|
"Name": "Nom",
|
|
@@ -97,6 +97,7 @@
|
|
|
97
97
|
"upload_finished": "{n} kész ({size})",
|
|
98
98
|
"upload_errors": "{n} sikertelen",
|
|
99
99
|
"upload_file_rejected": "Egyes fájlokat nem sikerült feltölteni",
|
|
100
|
+
"delete_unfinished_upload": "Eltávolítja a befejezetlen feltöltést?",
|
|
100
101
|
"download counter": "letöltés számláló",
|
|
101
102
|
"File menu": "Fájl menü",
|
|
102
103
|
"Folder menu": "Mappa menü",
|
|
@@ -89,6 +89,7 @@
|
|
|
89
89
|
"upload_finished": "{n,plural, one{# riuscito} other{# riusciti}} ({size})",
|
|
90
90
|
"upload_errors": "{n,plural, one{# fallito} other{# falliti}}",
|
|
91
91
|
"upload_file_rejected": "Alcuni file non sono stati accettati",
|
|
92
|
+
"delete_unfinished_upload": "Rimuovere l'upload incompleto?",
|
|
92
93
|
"File menu": "Menu file",
|
|
93
94
|
"Folder menu": "Menu cartella",
|
|
94
95
|
"Name": "Nome",
|
|
@@ -95,6 +95,7 @@
|
|
|
95
95
|
"upload_finished": "{n} baigta ({size})",
|
|
96
96
|
"upload_errors": "{n} nepavyko",
|
|
97
97
|
"upload_file_rejected": "Kai kurie failai nebuvo priimti",
|
|
98
|
+
"delete_unfinished_upload": "Pašalinti nebaigtą įkėlimą?",
|
|
98
99
|
"File menu": "Failo meniu",
|
|
99
100
|
"Folder menu": "Aplanko meniu",
|
|
100
101
|
"Name": "Pavadinimas",
|
|
@@ -59,6 +59,7 @@
|
|
|
59
59
|
"upload_finished": "{n} selesai ({size})",
|
|
60
60
|
"upload_errors": "{n} gagal",
|
|
61
61
|
"upload_file_rejected": "Beberapa fail tidak diterima",
|
|
62
|
+
"delete_unfinished_upload": "Alih keluar muat naik yang belum selesai?",
|
|
62
63
|
"ready_to_upload": "{n,plural,one{# fail} other{# fail}}, {size}, sedia untuk dimuat naik",
|
|
63
64
|
"Send": "Hantar",
|
|
64
65
|
"download counter": "pengira muat turun",
|
|
@@ -95,6 +95,7 @@
|
|
|
95
95
|
"upload_finished": "{n} voltooid ({size})",
|
|
96
96
|
"upload_errors": "{n} niet voltooid",
|
|
97
97
|
"upload_file_rejected": "Sommige bestanden zijn niet geaccepteerd",
|
|
98
|
+
"delete_unfinished_upload": "Onvoltooide upload verwijderen?",
|
|
98
99
|
"File menu": "Bestand menu",
|
|
99
100
|
"Folder menu": "Map menu",
|
|
100
101
|
"Name": "Naam",
|