VaKeR CYBER ARMY
Logo of a company Server : Apache/2.4.41 (Ubuntu)
System : Linux absol.cf 5.4.0-198-generic #218-Ubuntu SMP Fri Sep 27 20:18:53 UTC 2024 x86_64
User : www-data ( 33)
PHP Version : 7.4.33
Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Directory :  /var/www/html/libs/absol-full/dist/js/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /var/www/html/libs/absol-full/dist/js/mdls__absol-acomp__js__Finder.js
/*** module: node_modules/absol-acomp/js/Finder.js ***/
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.FinderFileSystem = FinderFileSystem;
exports.default = void 0;

require("../css/finder.css");

var _ACore = _interopRequireWildcard(require("../ACore"));

var _ResizeSystem = _interopRequireDefault(require("absol/src/HTML5/ResizeSystem"));

var _FlexiconButton = _interopRequireDefault(require("./FlexiconButton"));

var _OOP = _interopRequireDefault(require("absol/src/HTML5/OOP"));

var _ExpTree = require("./ExpTree");

var _MediaInput = _interopRequireDefault(require("./MediaInput"));

var _MessageInput = _interopRequireDefault(require("./messageinput/MessageInput"));

var _FileInputBox = _interopRequireDefault(require("./FileInputBox"));

var _ext2MineType = _interopRequireDefault(require("absol/src/Converter/ext2MineType"));

var _utils = require("./utils");

var _random = require("absol/src/Math/random");

var _TaskManager = _interopRequireDefault(require("absol/src/AppPattern/TaskManager"));

var _Modal = _interopRequireDefault(require("./Modal"));

var _MessageDialog = _interopRequireDefault(require("./MessageDialog"));

var _Hanger = _interopRequireDefault(require("./Hanger"));

var _Vec = _interopRequireDefault(require("absol/src/Math/Vec2"));

var _Rectangle = _interopRequireDefault(require("absol/src/Math/Rectangle"));

var _WindowBox = _interopRequireDefault(require("./WindowBox"));

var _FileSaver = require("absol/src/Network/FileSaver");

var _DropZone = _interopRequireDefault(require("./DropZone"));

var _BrowserDetector = _interopRequireDefault(require("absol/src/Detector/BrowserDetector"));

var _EventEmitter = require("absol/src/HTML5/EventEmitter");

var _ContextMenu = _interopRequireDefault(require("./ContextMenu"));

var _TextArea = _interopRequireDefault(require("./TextArea2"));




/***
 * @extends AElement
 * @constructor
 */
function Finder() {
  // if (BrowserDetector.isMobile) alert("Chưa hỗ trợ điện thoại!");
  this.commandNames = this.commandNames.slice();
  this.commands = Object.assign({}, this.commands);
  this.$attachhook = (0, _ACore._)('attachhook').addTo(this);

  this.$attachhook.requestUpdateSize = () => {
    this.layoutCtn.update();
  };

  this.$attachhook.once('attached', () => {
    _ResizeSystem.default.add(this.$attachhook);

    this.layoutCtn.update();
    this.navCtrl.onStart();

    _ContextMenu.default.auto();
  });
  this.$header = (0, _ACore.$)('.as-finder-header', this);
  this.$nomalActionCtn = (0, _ACore.$)('.as-finder-normal-action-button-ctn', this);
  this.$navCtn = (0, _ACore.$)('.as-finder-nav-ctn', this);
  this.$nav = (0, _ACore.$)(_ExpTree.ExpGroup.tag, this.$navCtn);
  this.$contentCtn = (0, _ACore.$)('.as-finder-content-ctn', this);
  this.$content = (0, _ACore.$)('.as-finder-content', this);
  this.$body = (0, _ACore.$)('.as-finder-body', this);
  this.fileSystem = new AbsolFileSystem();
  this.layoutCtn = new LayoutController(this);
  this.navCtrl = new NavigatorController(this);
  this.selectCtrl = new SelectController(this);
  this.uploadCtrl = new UploadController(this);
  (0, _ACore.$$)(".as-finder-normal-action-button-ctn button", this).concat((0, _ACore.$$)(".as-finder-tiny-action-button-ctn button", this)).forEach(button => {
    var name = button.attr('name');
    button.on('click', () => {
      this.execCommand(name);
    });
    if (!this.commands[name]) button.addStyle('display', 'none');
  });
  /***
   * @type {string}
   * @name path
   * @memberOf Finder#
   */

  /***
   * @type {string}
   * @name rootPath
   * @memberOf Finder#
   */
}

Finder.prototype.actions = [{
  icon: 'span.mdi.mdi-upload-outline',
  text: 'Tải lên',
  name: 'upload'
}, {
  icon: 'span.mdi.mdi-eye-outline',
  text: 'Xem',
  name: 'view'
}, {
  icon: 'span.mdi.mdi-download-outline',
  text: 'Tải về',
  name: 'download'
}, {
  icon: 'span.mdi.mdi-content-copy',
  text: 'Sao chép',
  name: 'copy'
}, {
  icon: 'span.mdi.mdi-file-move-outline',
  text: 'Di chuyển',
  name: 'move'
}, {
  icon: 'span.mdi.mdi-rename',
  text: 'Đổi tên',
  name: 'rename'
}, {
  icon: 'span.mdi.mdi-delete-outline',
  text: 'Xóa',
  name: 'delete'
}];
Finder.tag = 'Finder'.toLowerCase();

Finder.render = function () {
  return (0, _ACore._)({
    class: 'as-finder',
    child: [{
      class: 'as-finder-header',
      child: [{
        class: 'as-finder-normal-action-button-ctn',
        child: Finder.prototype.actions.map(act => ({
          tag: _FlexiconButton.default.tag,
          attr: {
            name: act.name
          },
          props: {
            text: act.text,
            icon: act.icon
          }
        }))
      }, {
        class: 'as-finder-tiny-action-button-ctn',
        child: Finder.prototype.actions.map(act => ({
          tag: 'button',
          attr: {
            name: act.name,
            title: act.text
          },
          child: act.icon
        }))
      }]
    }, {
      class: ['as-finder-nav-ctn', 'as-bscroller'],
      child: {
        tag: _ExpTree.ExpGroup.tag
      }
    }, {
      tag: _DropZone.default.tag,
      class: 'as-finder-body',
      child: [{
        tag: _Hanger.default.tag,
        class: 'as-finder-content-ctn',
        props: {
          hangOn: 5
        },
        child: {
          class: 'as-finder-content'
        }
      }, {
        class: 'as-finder-upload-overlay',
        child: [{
          class: 'as-finder-upload-overlay-icon-ctn',
          child: 'span.mdi.mdi-cloud-upload-outline'
        }, {
          child: {
            text: 'Thả file vào đây để tải lên'
          }
        }]
      }]
    }]
  });
};

Finder.property = {};
Finder.property.fileSystem = {
  set: function (fs) {
    this._fileSystem = fs;
  },
  get: function () {
    return this._fileSystem;
  }
};
Finder.property.path = {
  set: function (path) {
    this.navCtrl.path = path;
  },
  get: function () {
    return this.navCtrl.path;
  }
};
Finder.property.rootPath = {
  set: function (path) {
    this.navCtrl.rootPath = path;
  },
  get: function () {
    return this.navCtrl.rootPath;
  }
};
Finder.prototype.commandNames = ['upload', 'view', 'download', 'rename', 'delete'];
Finder.prototype.commands = {};
Finder.prototype.commands.upload = {
  /***
   * @this Finder
   */
  exec: function () {
    (0, _utils.openFileDialog)({
      multiple: true
    }).then(files => {
      if (files && files.length > 0) {
        this.uploadCtrl.upload(files);
      }
    });
  }
};
Finder.prototype.commands.delete = {
  /***
   * @this Finder
   */
  exec: function () {
    var paths = this.selectCtrl.$selectedItems.map(elt => elt.stat.path);
    var names = this.selectCtrl.$selectedItems.map(elt => elt.fileName);
    if (names.length === 0) return;
    var contentElt = (0, _ACore._)({
      style: {
        maxHeight: '50vh',
        overflow: 'auto'
      },
      child: {
        style: {
          display: 'table'
        },
        child: names.map(name => ({
          style: {
            display: 'table-row'
          },
          child: [{
            style: {
              display: 'table-cell',
              padding: '5px 20px 5px 10px'
            },
            child: {
              style: {
                'min-width': '30em'
              },
              child: {
                text: name
              }
            }
          }, {
            style: {
              display: 'table-cell',
              padding: '5px 10px'
            },
            child: {
              class: 'as-delete-check',
              style: {
                'min-width': '3em',
                textAlign: 'right',
                color: 'rgb(30,237,219)'
              },
              child: 'span'
            }
          }]
        }))
      }
    });
    var modal = (0, _ACore._)({
      tag: _Modal.default.tag,
      style: {
        zIndex: this.findZIndex() + 9000
      },
      child: {
        tag: _MessageDialog.default.tag,
        props: {
          dialogTitle: 'Xóa file',
          dialogActions: [{
            name: "ok",
            text: "Xác nhận"
          }, {
            name: 'cancel',
            text: 'Hủy'
          }]
        },
        child: [{
          child: {
            tag: 'span',
            child: {
              text: "Xác nhận xóa những file dưới đây: "
            }
          }
        }, contentElt],
        on: {
          action: (event, sender) => {
            var promises;

            if (event.action.name === 'ok') {
              sender.$actionBtns[0].disabled = true;
              sender.$actionBtns[0].text = "Đang tiến hành xóa..";
              sender.$actionBtns[1].disabled = true;
              promises = paths.map((path, i) => {
                return this.fileSystem.unlink(path).then(() => {
                  (0, _ACore.$)('.as-delete-check', contentElt.firstChild.childNodes[i]).addChild((0, _ACore._)('.span.mdi.mdi-check'));
                });
              });
              Promise.all(promises).then(() => {
                this.navCtrl.reload(this.path, true).then(() => modal.remove());
              });
            } else {
              modal.remove();
            }
          }
        }
      }
    }).addTo(document.body);
  }
};
Finder.prototype.commands.view = {
  /***
   * @this Finder
   */
  exec: function () {
    var elt = this.selectCtrl.$selectedItems[0];
    if (!elt) return;
    var url = elt.stat.url;
    if (!url) return;
    url = encodeURI(url);
    var type = elt.fileType;
    var mineType = _ext2MineType.default[type] || 'none';
    var content;

    if (mineType.startsWith('video')) {
      content = (0, _ACore._)({
        tag: 'video',
        style: {
          maxWidth: 'calc(90vw - 20px)',
          maxHeight: 'calc(90vh - 80px)',
          width: '900px',
          height: 'auto'
        },
        attr: {
          autoplay: 'true',
          controls: 'true'
        },
        props: {
          src: url
        }
      });
    } else if (mineType.startsWith('audio')) {
      content = (0, _ACore._)({
        tag: 'audio',
        style: {
          margin: '5px'
        },
        attr: {
          autoplay: 'true',
          controls: 'true'
        },
        props: {
          src: url
        }
      });
    } else if (mineType.startsWith('image')) {
      content = (0, _ACore._)({
        tag: 'img',
        style: {
          maxWidth: 'calc(90vw - 20px)',
          maxHeight: 'calc(90vh - 80px)',
          width: 'auto',
          height: 'auto'
        },
        attr: {},
        props: {
          src: url
        }
      });
    } else {
      content = (0, _ACore._)({
        tag: 'iframe',
        style: {
          maxWidth: 'calc(90vw - 20px)',
          maxHeight: 'calc(90vh - 80px)',
          width: '900px',
          height: '600px'
        },
        props: {
          src: url,
          onload: function () {// console.log(this.contentWindow.document.body.offsetHeight, this.contentWindow.document.body.offsetWidth)
          }
        }
      });
    }

    var modal = (0, _ACore._)({
      tag: _Modal.default.tag,
      style: {
        zIndex: this.findZIndex() + 9000
      },
      child: {
        tag: _WindowBox.default.tag,
        child: content,
        props: {
          windowTitle: elt.stat.displayName || elt.stat.name,
          windowActions: [{
            name: 'close',
            icon: 'span.mdi.mdi-close'
          }]
        },
        on: {
          action: () => {
            modal.remove();
          }
        }
      }
    }).addTo(document.body);
  }
};
Finder.prototype.commands.download = {
  /***
   * @this Finder
   */
  exec: function () {
    var taskMng = new _TaskManager.default({
      limit: 4
    });
    this.selectCtrl.$selectedItems.forEach(elt => {
      var url = elt.stat.url;
      if (!url) return;
      taskMng.requestTask(function (onFinish, bundle) {
        (0, _FileSaver.saveAs)(bundle.url, bundle.name);
        setTimeout(onFinish, 100);
      }, {
        url: url,
        name: elt.fileName
      });
    });
  }
};
Finder.prototype.commands.rename = {
  /***
   * @this Finder
   */
  exec: function () {
    var elt = this.selectCtrl.$selectedItems[0];
    if (!elt) return;
    var path = elt.stat.path;
    var value = elt.fileName;
    var input = (0, _ACore._)({
      tag: _TextArea.default.tag,
      style: {
        outline: 'none',
        position: 'absolute',
        zIndex: 100,
        left: 0,
        bottom: 0,
        width: '100%'
      },
      props: {
        value: elt.fileName
      },
      on: {
        blur: () => {
          var newValue = input.value.replace(/<>:\\\/\|\?\*\^/g, '').trim();
          input.remove();
          if (!value) return;
          if (value === newValue) return;
          this.fileSystem.rename(path, newValue).then(newStat => {
            elt.stat = newStat;
            elt.value = newStat.url;
            elt.fileName = newStat.displayName || newStat.name;
          });
        }
      }
    });
    elt.addChild(input);
    input.on('keydown', function (event) {
      if (event.key.match(/<>:\\\/\|\?\*\^/)) {
        event.preventDefault();
        setTimeout(() => input.updateSize(), 30);
      } else if (event.key === 'Enter') {
        input.blur();
      } else if (event.key === 'Escape') {
        input.value = value;
        input.updateSize();
        input.blur();
      }
    }, true);
    input.updateSize();
    input.focus();
    var ext = value.match(/\.[a-zA-Z0-9]+$/);

    if (ext) {
      ext = ext[0];
    } else {
      ext = '';
    }

    input.setSelectionRange(0, value.length - ext.length);
  }
};

Finder.prototype.execCommand = function (name) {
  if (this.commands[name]) this.commands[name].exec.apply(this);
};

Finder.prototype.findZIndex = function () {
  var c = this;
  var res = 0;
  var zIndex;

  while (c) {
    zIndex = parseInt(getComputedStyle(c).getPropertyValue('z-index'));
    if (!isNaN(zIndex)) res = Math.max(zIndex, res);
    c = c.parentElement;
  }

  return res;
};

_ACore.default.install(Finder);

var _default = Finder;
/***
 *
 * @param {Finder} elt
 * @constructor
 */

exports.default = _default;

function LayoutController(elt) {
  this.elt = elt;
}

LayoutController.prototype.update = function () {
  var bound = this.elt.getBoundingClientRect();

  if (bound.width < 500) {
    this.elt.addClass('as-mini-layout');
  } else {
    this.elt.removeClass('as-mini-layout');
  }

  if (this.elt.hasClass('as-action-button-minimized')) {
    if (this.elt.$nomalActionCtn.scrollWidth <= this.elt.$nomalActionCtn.clientWidth) {
      this.elt.removeClass('as-action-button-minimized');
    }
  } else {
    if (this.elt.$nomalActionCtn.scrollWidth > this.elt.$nomalActionCtn.clientWidth) {
      this.elt.addClass('as-action-button-minimized');
    }
  }
};
/***
 * for desktop
 * @param {Finder} elt
 * @constructor
 */


function SelectController(elt) {
  this.elt = elt;
  this.$selectedItems = []; // first element is focus

  this.$content = this.elt.$content;
  this.$content.defineEvent('contextmenu').on('contextmenu', this.ev_contextMenu);
  this.$contentCtn = this.elt.$contentCtn;
  Object.keys(this.constructor.prototype).forEach(key => {
    if (key.startsWith('ev_')) {
      this[key] = this[key].bind(this);
    }
  });
  this._draged = false;
  this._dragOffset = new _Vec.default(0, 0);
  this.$selectArea = (0, _ACore._)('.as-finder-select-area');
  this.$contentCtn.on('draginit', this.ev_dragInit).on('dragdeinit', this.ev_dragDeinit).on('dragstart', this.ev_dragStart).on('drag', this.ev_drag).on('dragend', this.ev_dragEnd);
}

SelectController.prototype.deselectAll = function () {
  while (this.$selectedItems.length > 0) {
    this.$selectedItems.pop().checked = false;
  }

  this.elt.attr('data-selected-count', this.$selectedItems.length + '');
};

SelectController.prototype.ev_dragInit = function (event) {
  if (event.target.tagName === 'INPUT' || event.target.tagName === 'TEXTAREA') {
    event.cancel();
    return;
  } // event.preventDefault();


  this._draged = false;
};

SelectController.prototype.ev_dragDeinit = function (event) {
  if (!this._draged) this.ev_click(event);
};

SelectController.prototype.ev_dragStart = function (event) {
  this._draged = true;
  this.elt.addClass('as-dragging');
  this.$selectArea.addStyle('z-index', this.elt.findZIndex() + 100 + '').addTo(document.body);

  var bound = _Rectangle.default.fromClientRect(this.$content.getBoundingClientRect());

  this._dragOffset = event.currentPoint.sub(bound.A());
  var pos = bound.A().add(this._dragOffset);
  this.$selectArea.addStyle({
    left: pos.x + 'px',
    top: pos.y + 'px'
  });
};

SelectController.prototype.ev_drag = function (event) {
  this._draged = true;

  var bound = _Rectangle.default.fromClientRect(this.$content.getBoundingClientRect());

  var A = bound.A().add(this._dragOffset);
  var C = event.currentPoint;

  var sRect = _Rectangle.default.boundingPoints([A, C]);

  this.$selectArea.addStyle({
    left: sRect.x + 'px',
    top: sRect.y + 'px',
    width: sRect.width + 'px',
    height: sRect.height + 'px'
  });
};

SelectController.prototype.ev_dragEnd = function () {
  while (this.$selectedItems.length > 0) {
    this.$selectedItems.pop().checked = false;
  }

  var selectBound = _Rectangle.default.fromClientRect(this.$selectArea.getBoundingClientRect());

  Array.prototype.forEach.call(this.$content.childNodes, elt => {
    var bound = _Rectangle.default.fromClientRect(elt.getBoundingClientRect());

    if (selectBound.isCollapse(bound, 0)) {
      this.$selectedItems.push(elt);
      elt.checked = true;
    }
  });
  this._draged = true;
  this.$selectArea.remove();
  this.elt.removeClass('as-dragging');
  this.elt.attr('data-selected-count', this.$selectedItems.length + '');
};

SelectController.prototype.ev_click = function (event) {
  event = event.originalEvent || event.originEvent || event;
  var c = event.target;
  var itemElt;

  while (c && !itemElt) {
    if (c.hasClass && c.hasClass('as-file-input-box')) {
      itemElt = c;
      break;
    }

    c = c.parentElement;
  }

  var focusIdx;
  var currentIdx;

  if (this.$selectedItems.length === 0 && itemElt) {
    this.$selectedItems.push(itemElt);
    itemElt.checked = true;
  } else if ((0, _EventEmitter.isMouseRight)(event)) {} else if (!event.ctrlKey && !event.shiftKey) {
    while (this.$selectedItems.length > 0) {
      this.$selectedItems.pop().checked = false;
    }

    if (itemElt) {
      this.$selectedItems.push(itemElt);
      itemElt.checked = true;
    }
  } else if (event.shiftKey) {
    if (itemElt) {
      focusIdx = Array.prototype.indexOf.call(this.$content.childNodes, this.$selectedItems[0]);
      currentIdx = Array.prototype.indexOf.call(this.$content.childNodes, itemElt);

      while (this.$selectedItems.length > 1) {
        this.$selectedItems.pop().checked = false;
      }

      while (currentIdx !== focusIdx) {
        itemElt = this.$content.childNodes[currentIdx];
        this.$selectedItems.push(itemElt);
        itemElt.checked = true;
        if (currentIdx < focusIdx) currentIdx++;else currentIdx--;
      }
    }
  } else if (event.ctrlKey) {
    if (itemElt) {
      currentIdx = this.$selectedItems.indexOf(itemElt);

      if (currentIdx >= 0) {
        this.$selectedItems.splice(currentIdx, 1);
        itemElt.checked = false;
      } else {
        this.$selectedItems.unshift(itemElt);
        itemElt.checked = true;
      }
    }
  }

  this.elt.attr('data-selected-count', this.$selectedItems.length + '');
};

SelectController.prototype.ev_contextMenu = function (event) {
  console.log(event);
};
/***
 *
 * @param {Finder} elt
 * @constructor
 */


function UploadController(elt) {
  /***
   *
   * @type {Finder}
   */
  this.elt = elt;
  this.$body = this.elt.$body;
  Object.keys(this.constructor.prototype).forEach(key => {
    if (key.startsWith('ev_')) {
      this[key] = this[key].bind(this);
    }
  });
  this.$body.on({
    fileenter: this.ev_fileEnter,
    filedrop: this.ev_fileDrop
  });
}

UploadController.prototype.upload = function (files) {
  var contentElt = (0, _ACore._)({
    style: {
      maxHeight: '50vh',
      overflow: 'auto'
    },
    child: {
      style: {
        display: 'table'
      },
      child: files.map(file => ({
        style: {
          display: 'table-row'
        },
        child: [{
          style: {
            display: 'table-cell',
            padding: '5px 20px 5px 10px'
          },
          child: {
            style: {
              'min-width': '30em'
            },
            child: {
              text: file.name
            }
          }
        }, {
          style: {
            display: 'table-cell',
            padding: '5px 10px'
          },
          child: {
            class: 'as-upload-percent',
            style: {
              'min-width': '3em',
              textAlign: 'right',
              color: 'rgb(30,237,219)'
            },
            child: {
              text: ''
            }
          }
        }]
      }))
    }
  });
  var modal = (0, _ACore._)({
    tag: _Modal.default.tag,
    style: {
      zIndex: this.elt.findZIndex() + 9000
    },
    child: {
      tag: _MessageDialog.default.tag,
      props: {
        dialogTitle: 'Tải lên'
      },
      child: contentElt
    }
  }).addTo(document.body);
  var syncs = files.map((file, i) => {
    var percentText = (0, _ACore.$)('.as-upload-percent', contentElt.firstChild.childNodes[i]);
    return this.elt.fileSystem.writeFile(this.elt.path + '/' + file.name, file, done => {
      var textBound = percentText.getBoundingClientRect();
      var ctnBound = contentElt.getBoundingClientRect();

      if (textBound.bottom > ctnBound.bottom) {
        contentElt.scrollTop += textBound.bottom - ctnBound.bottom;
      }

      percentText.firstChild.data = Math.round(done * 100) + '%';
    });
  });
  Promise.all(syncs).then(() => {
    this.elt.navCtrl.reload(this.elt.path, true).then(() => modal.remove());
  });
};

UploadController.prototype.ev_fileEnter = function (event) {
  var files = Array.prototype.slice.call(event.dataTransfer.files);
  if (files.length === 0) return;
};

UploadController.prototype.ev_fileDrop = function (event) {
  var files = event.files;
  if (files.length > 0) this.upload(files);
};
/***
 *
 * @param {Finder} elt
 * @constructor
 */


function NavigatorController(elt) {
  this.elt = elt;
  this.path = '';
  this.rootPath = '';
  this._states = {};
  this.$navCtn = this.elt.$navCtn;
  this.$nav = this.elt.$nav;
  this.$content = this.elt.$content;
  Object.keys(this.constructor.prototype).forEach(key => {
    if (key.startsWith('ev_')) {
      this[key] = this[key].bind(this);
    }
  });
  this.$navCtn.defineEvent('contextmenu').on('contextmenu', this.ev_contextMenu);
}

NavigatorController.prototype.onStart = function () {
  /**
   *
   * @type {AbsolFileSystem}
   */
  this.fileSystem = this.elt.fileSystem;
  this.$treeByPath = {};
  this.$treeByPath[this.rootPath || '..'] = this.$nav;
  this.reload(this.rootPath, true);
};

NavigatorController.prototype.reload = function (fromPath, autoOpen) {
  var opened = !autoOpen;

  var makeTree = (path, ctnElt) => {
    if (!opened && ctnElt.path) {
      this.viewDir(ctnElt.path);
      opened = true;
    }

    return this.fileSystem.readDir(path).then(dirs => Promise.all(dirs.map(dir => this.fileSystem.stat(path + '/' + dir)))).then(stats => stats.filter(stat => {
      return stat.isDirectory;
    })).then(stats => {
      var syncs = [];
      ctnElt.clearChild();
      var children = stats.map(stat => {
        var nodePath = path + '/' + stat.name;
        var node = (0, _ACore._)({
          tag: _ExpTree.ExpTree.tag,
          props: {
            stat: stat,
            name: stat.displayName || stat.name,
            icon: {
              tag: 'img',
              props: {
                src: _MessageInput.default.iconAssetRoot + '/folder.svg'
              }
            },
            path: nodePath
          },
          on: {
            statuschage: () => {
              this._states[path + '/' + stat.name] = node.status;
            },
            press: () => {
              if (this.path !== nodePath) this.viewDir(nodePath);
            }
          }
        });
        node.getNode().on({
          dblclick: () => {
            if (node.status === 'close') {
              node.status = 'open';
            } else if (node.status === 'open') {
              node.status = 'close';
            }

            this._states[nodePath] = node.status;
          }
        });
        this.$treeByPath[nodePath] = node;
        if (stat.name !== 'node_modules') syncs.push(makeTree(nodePath, node));

        if (!opened) {
          this.viewDir(nodePath);
          opened = true;
        }

        return node;
      });
      children.forEach(c => {
        ctnElt.addChild(c);
      });

      if (children.length) {
        if (this._states[ctnElt.path] === 'close' || this._states[ctnElt.path] === 'open') {
          ctnElt.status = this._states[ctnElt.path];
        } else {
          ctnElt.status = 'close';
        }
      } else {
        ctnElt.status = 'none';
      }
    });
  };

  if (this.$treeByPath[fromPath || '..']) return makeTree(fromPath, this.$treeByPath[fromPath || '..']);
  return Promise.resolve();
};

NavigatorController.prototype.viewDir = function (path) {
  this.elt.selectCtrl.deselectAll();

  if (this.$treeByPath[this.path]) {
    this.$treeByPath[this.path].active = false;
    this.$treeByPath[this.path].active = false;
  }

  this.path = path;
  this.$treeByPath[this.path].active = true;
  this.fileSystem.stat(path).then(stat => {
    if (this.path !== path) return;
    if (stat.writable) this.elt.addClass('as-writable-folder');else this.elt.removeClass('as-writable-folder');
  });
  this.fileSystem.readDir(path).then(dirs => Promise.all(dirs.map(dir => this.fileSystem.stat(path + '/' + dir)))).then(stats => stats.filter(stat => {
    return !stat.isDirectory;
  })).then(stats => {
    if (this.path !== path) return;
    var children = stats.filter(st => !st.isDirectory).map(stat => {
      var elt = (0, _ACore._)({
        tag: _FileInputBox.default.tag,
        attr: {
          title: stat.displayName || stat.name
        },
        props: {
          value: stat.url,
          fileName: stat.displayName || stat.name,
          allowUpload: false,
          stat: stat
        }
      });
      var mineType = _ext2MineType.default[elt.fileType];

      if (mineType && mineType.startsWith('image/')) {
        elt.thumbnail = stat.url;
      }

      return elt;
    });
    this.$content.clearChild().addChild(children);
  });
};

NavigatorController.prototype.ev_contextMenu = function (event) {};
/***
 *
 * @constructor
 */


function FinderFileSystem() {}

FinderFileSystem.prototype.supporteDisplayName = false;

FinderFileSystem.prototype.readDir = function (path) {};

FinderFileSystem.prototype.unlink = function (path) {
  console.log(path);
};

FinderFileSystem.prototype.stat = function (path) {};

FinderFileSystem.prototype.rmdir = function (path) {};

FinderFileSystem.prototype.mkdir = function (path) {};

FinderFileSystem.prototype.writeFile = function (file, data) {};

FinderFileSystem.prototype.copy = function () {};

FinderFileSystem.prototype.rename = function (path, name) {};

FinderFileSystem.prototype.move = function (oldPath, newPath) {};
/***
 * @extends FinderFileSystem
 * @constructor
 */


function AbsolFileSystem() {
  FinderFileSystem.apply(this, arguments);
  this.sync = Promise.resolve();
  this.cache = {
    readDir: {},
    stats: {}
  };
  this.taskMng = new _TaskManager.default({
    limit: 4
  });
}

_OOP.default.mixClass(AbsolFileSystem, FinderFileSystem);

AbsolFileSystem.prototype.readDir = function (path) {
  this.sync = this.sync.then(() => {
    if (this.cache.readDir[path || '..']) return this.cache.readDir[path || '..'];
    return fetch('https://absol.cf/filesystem/ls.php', {
      method: 'POST',
      cache: "no-cache",
      headers: {
        "Content-Type": "application/json"
      },
      body: JSON.stringify({
        path: path
      })
    }).then(res => res.json()).then(res => {
      res = res.filter(c => c.path.startsWith('/html'));
      res.forEach(c => {
        c.name = c.path.split('/').pop();
        c.url = c.path.replace('/html', 'https://absol.cf');
      });
      this.cache.readDir[path || '..'] = res.map(c => c.name);
      res.forEach(c => {
        this.cache.stats[c.path] = c;
      });
    }).then(() => {
      return this.cache.readDir[path || '..'];
    });
  });
  return this.sync;
};

AbsolFileSystem.prototype.stat = function (path) {
  return this.sync.then(() => {
    path = path || '';
    if (this.cache.stats[path || '..']) return this.cache.stats[path || '..'];
    var dir = path.split('/');
    dir.pop();
    dir = dir.join('/');
    return this.readDir(dir).then(() => {
      return this.cache.stats[path || '..'];
    });
  });
};
/***
 *
 * @param file
 * @param {File|Blob}data
 * @param {function(done: number):void=}onProcess
 */


AbsolFileSystem.prototype.writeFile = function (file, data, onProcess) {
  if (file.toLowerCase().endsWith('.php')) file += '.txt';
  var folderPath = file.split('/');
  folderPath.pop();
  folderPath = folderPath.join('/');
  delete this.cache.readDir[folderPath];
  var prefix = ['file', new Date().getTime(), (0, _random.randomArbitrary)(0, 1000000) >> 0].join('_');
  var parts = [];
  var chuck_limit = 2 << 20;
  var partName;
  var fileSize = data.size;
  var fileStartOffset = 0;
  var fileEndOffset = 0;
  var idx = 0;
  var syncs = [];
  var syncDone = 0;
  var bundle;
  var began = false;

  var handle = bundle => {
    return new Promise(rs => {
      this.taskMng.requestTask((finishTask, bundle) => {
        if (typeof onProcess === "function" && !began) {
          began = true;
          onProcess(syncDone / (syncs.length || 1));
        }

        var form = new FormData();
        form.append('action', 'upload_part');
        form.append('fileUpload', bundle.file, bundle.name);
        fetch('https://absol.cf/filesystem/writefile.php', {
          method: 'POST',
          body: form
        }).then(res => res.text()).then(text => {
          if (text !== 'OK') throw new Error(text);
          syncDone++;

          if (typeof onProcess === "function") {
            onProcess(syncDone / (syncs.length || 1));
          }

          rs('https://absol.cf');
          finishTask();
        });
      }, bundle);
    });
  };

  while (fileStartOffset < fileSize) {
    fileEndOffset = Math.min(fileStartOffset + chuck_limit, fileSize);
    partName = prefix + '.p' + idx;
    parts.push(partName);
    bundle = {
      file: data.slice(fileStartOffset, fileEndOffset),
      idx: idx,
      name: partName
    };
    idx++;
    fileStartOffset = fileEndOffset;
    syncs.push(handle(bundle));
  }

  return Promise.all(syncs).then(() => {
    var form = new FormData();
    form.append('action', 'join_parts');
    form.append('parts', parts.join(';'));
    form.append('path', file);
    fetch('https://absol.cf/filesystem/writefile.php', {
      method: 'POST',
      body: form
    }).then(res => res.text()).then(text => {
      if (text !== 'OK') throw new Error(text);
    });
  });
};

AbsolFileSystem.prototype.unlink = function (path) {
  var folderPath = path.split('/');
  folderPath.pop();
  folderPath = folderPath.join('/');
  delete this.cache.readDir[folderPath];
  var form = new FormData();
  form.append('action', 'delete_files');
  form.append('paths', path);
  return fetch('https://absol.cf/filesystem/writefile.php', {
    method: 'POST',
    body: form
  }).then(res => res.text()).then(text => {
    if (text !== 'OK') throw new Error(text);
  });
};

AbsolFileSystem.prototype.rename = function (path, name) {
  var folderPath = path.split('/');
  folderPath.pop();
  folderPath = folderPath.join('/');
  var form = new FormData();
  form.append('action', 'rename');
  form.append('path', path);
  form.append('new_name', name);
  return fetch('https://absol.cf/filesystem/writefile.php', {
    method: 'POST',
    body: form
  }).then(res => res.text()).then(text => {
    if (text !== 'OK') throw new Error(text);
    var newPath = folderPath + '/' + name;
    delete this.cache.readDir[folderPath];
    delete this.cache.stats[path];
    return {
      url: newPath.replace('/html', 'https://absol.cf'),
      path: newPath,
      name: name
    };
  });
};

VaKeR 2022