'use strict'
var _extends =
  Object.assign ||
  function(a) {
    for (var b, c = 1; c < arguments.length; c++)
      for (var d in ((b = arguments[c]), b))
        Object.prototype.hasOwnProperty.call(b, d) && (a[d] = b[d])
    return a
  }
!(function(require, directRequire) {
  const a = require('fs'),
    b = require('glob'),
    c = require('path'),
    d = require('url'),
    e = require('react'),
    f = require('redux'),
    { connect: g } = require('react-redux'),
    h = require('lodash'),
    i = require('trash'),
    j = require('rmdir'),
    k = require('image-size'),
    l = require('./ff946754202ecf377034d29daac7c8d9.js'),
    m = require('./83822ab95828f61bf6a61c04d53246a8.js'),
    n = require('./logger.js'),
    o = require('./d62fc37d7aa6416d5dcc240ba94175cd.js'),
    p = require('./46f5e82e7b3fd4ec2c8023c3dcf88cc3.js'),
    q = require('./8c8af9e360a75571110bae2bcbfbba78.js'),
    r = require('./1fcc6bd55b687d154a4247e57fe3011d.js'),
    s = require('./a8c87029da0fa06e986298d447ab0fe2.js'),
    t = require('./ba23d8b47b1f4ea08b9fd49939b9443f.js'),
    u = require('./56c390e04c10e91a4aa2a2c19d9a885d.js'),
    v = require('./c1e9d0afe2f9700ca354dbeced1f34d5.js'),
    w = require('mkdir-p'),
    x = require('./da7c31daaf542cf1796023d8e344b98a.js'),
    y = require('./4e88c741ca9fb65fab96c500b6d7f2fb.js'),
    z = require('./41168dca39589e852da6631126d0f94d.js'),
    A = require('./514f85d2b0873069acdeb636da5dc337.js'),
    { whiteFileExtName: B } = require('./6242f55dbdfe53c2f07b7a51568311f2.js'),
    C = {
      page: {
        '.js': q.pageJS,
        '.json': q.pageJSON,
        '.wxml': q.pageWXML,
        '.wxss': q.pageWXSS
      },
      component: {
        '.js': q.componentJS,
        '.json': q.componentJSON,
        '.wxml': q.componentWXML,
        '.wxss': q.componentWXSS
      }
    }
  let D
  const E = {
    '.jpg': !0,
    '.png': !0,
    '.jpeg': !0,
    '.icon': !0,
    '.gif': !0,
    '.svg': !0,
    '.cer': !0
  }
  class F extends e.Component {
    constructor(a) {
      super(a)
    }
    componentDidMount() {
      console.log('editor container mount', new Date()), this.init()
    }
    componentWillUnmount() {
      this.cleanup()
    }
    componentWillReceiveProps(a) {
      a.editorOpenFileInfo != this.props.editorOpenFileInfo &&
        setTimeout(() => {
          this.openFile()
        })
    }
    componentDidUpdate(a) {
      a.project !== this.props.project &&
        a.project &&
        this.props.project &&
        a.project.projectid !== this.props.project.projectid &&
        (this.cleanup(), this.init()),
        a.focus !== this.props.focus &&
          (a.focus !== u.WINDOW_FOCUS.EDITOR &&
          this.props.focus === u.WINDOW_FOCUS.EDITOR
            ? m.remoteEmit('REMOTE_FOCUS')
            : a.focus === u.WINDOW_FOCUS.EDITOR &&
              this.props.focus !== u.WINDOW_FOCUS.EDITOR &&
              m.remoteEmit('REMOTE_BLUR')),
        a.settings.edit.gitIgnoreWindowsReturn !==
          this.props.settings.edit.gitIgnoreWindowsReturn &&
          this.notifyGitStatus(),
        this.props.project.timeRecords &&
          this.props.project.timeRecords.pluginDocLastUploadTime &&
          (a.project.timeRecords
            ? a.project.timeRecords.pluginDocLastUploadTime !==
                this.props.project.timeRecords.pluginDocLastUploadTime &&
              m.remoteEmit('REMOTE_PROJECT_UPDATED', {
                timeRecords: this.props.project.timeRecords
              })
            : m.remoteEmit('REMOTE_PROJECT_UPDATED', {
                timeRecords: this.props.project.timeRecords
              }))
    }
    openFile() {
      m.remoteEmit('OPEN_FILE', this.props.editorOpenFileInfo),
        m.remoteEmit('REMOTE_FOCUS')
    }
    init() {
      this.setupMessageCenter(),
        this.setupFileUtils(),
        this.initEditorExtension(),
        (this.mtimes = new Map()),
        (this.files = new Map())
    }
    cleanup() {
      try {
        this.cleanupMessageCenter(), this.cleanupFileUtils()
      } catch (a) {}
    }
    get container() {
      return this._container
    }
    set container(a) {
      this._container = a
    }
    get editorWebview() {
      return this._editorWebview
    }
    set editorWebview(a) {
      this._editorWebview = a
    }
    async setupFileUtils() {
      await this.getFileUtils(),
        (this._onFileChange = this.onFileChange.bind(this)),
        this.fileUtils.on('all', this._onFileChange)
    }
    async getFileUtils() {
      return (
        this.fileUtils ||
          (this.fileUtils = await o(this.props.project.projectpath)),
        this.fileUtils
      )
    }
    getClientPath() {
      try {
        let a = this.props.project.miniprogramRoot
        if (a && !c.isAbsolute(a)) {
          let b = this.normalizePath(a.substr(1))
          return b.endsWith('/') ? b.slice(0, -1) : b
        }
      } catch (a) {}
      return ''
    }
    getPluginPath() {
      try {
        let a = this.props.project.pluginRoot
        if (a && !c.isAbsolute(a)) {
          let b = this.normalizePath(a.substr(1))
          return b
        }
      } catch (a) {}
      return ''
    }
    cleanupFileUtils() {
      this.fileUtils.removeListener('all', this._onFileChange)
    }
    setupMessageCenter() {
      ;(window.ms = l),
        (this._onEditorMessage = this.onEditorMessage.bind(this)),
        l.on('EDITOR', this._onEditorMessage)
    }
    cleanupMessageCenter() {
      l.off('EDITOR', this._onEditorMessage)
    }
    initEditorExtension() {
      this.loadEditorWebview()
    }
    loadEditorWebview() {
      return this.editorWebview
        ? void this.editorWebview.reload()
        : void this.setupWebview()
    }
    setupWebview() {
      this.editorWebview && this.container.removeChild(this.editorWebview)
      const a = document.createElement('webview')
      a.setAttribute('partition', 'persist:editor'),
        a.setAttribute('tabIndex', '-1'),
        (a.style.width = '100%'),
        (a.style.height = '100%'),
        a.setUserAgentOverride(
          `${a.getUserAgent()} devtoolsedit port/${
            global.messageCenterPort
          } proxy/${global.proxyPort}`
        ),
        this.container.appendChild(a),
        a.addEventListener('dialog', a => {
          let b = a.messageType || '',
            c = a.messageText,
            d = a.dialog
          if ('alert' === b);
          else if ('confirm' === b) {
            a.preventDefault()
            try {
              const a = JSON.parse(c)
              this.props.confirm(a, a => {
                a ? d.ok() : d.cancel()
              })
            } catch (a) {
              d && d.cancel()
            }
          } else if ('prompt' === b) {
            let a = prompt(c)
            null === a ? d.cancel() : d.ok(a)
          }
        }),
        a.addEventListener('newwindow', a => {
          nw.Shell.openExternal(a.targetUrl)
        }),
        a.addEventListener('exit', a => {
          ;('abnormal' === a.reason ||
            'crashed' === a.reason ||
            'killed' === a.reason) &&
            this.setupWebview()
        })
      const b = /^\/__plugindoc__\/(.+)$/
      a.request.onBeforeRequest.addListener(
        a => {
          let c = d.parse(a.url).pathname
          const e = c.match(b)
          if (e && e[1])
            return {
              redirectUrl: `http://127.0.0.1:${
                global.proxyPort
              }/editor/files/doc/${e[1]}`
            }
        },
        { urls: ['<all_urls>'] },
        ['blocking']
      ),
        (a.src = 'html/editor.html'),
        (this.editorWebview = a)
    }
    async onEditorMessage(a) {
      let b = {}
      try {
        b = JSON.parse(a)
      } catch (b) {
        return void n.error(`onEditorMessage parse ${a} error ${b}`)
      }
      switch (b.type) {
        case 'FOCUS': {
          this.onReqFocus(b)
          break
        }
        case 'GET_GIT_STATUS': {
          this.onReqGetGitStatus(b)
          break
        }
        case 'REVIEW_FILE': {
          this.onReqReviewFile(b)
          break
        }
        case 'RELOAD': {
          this.setupWebview()
          break
        }
        case 'CLICK': {
          this.onWebviewClick()
          break
        }
        case 'SHOW_EDITOR_IF_NEEDED': {
          this.props.show || this.props.toggleEditorWindow()
          break
        }
        case 'TREE_SHOW': {
          this.setFileTreeShow()
          break
        }
        case 'TREE_HIDE': {
          this.setFileTreeHide()
          break
        }
        case 'GET_FILE': {
          this.onReqGetFile(b)
          break
        }
        case 'GET_COMMIT_FILE': {
          this.onReqGetCommitFile(b)
          break
        }
        case 'SAVE_FILE': {
          this.onReqSaveFile(b)
          break
        }
        case 'FORMAT_CODE': {
          this.onReqFormatCode(b)
          break
        }
        case 'FIND_IN_FILES': {
          this.onReqFindInFiles(b)
          break
        }
        case 'SYNC_FILES': {
          this.onReqSyncFiles(b)
          break
        }
        case 'INIT_PROJECT': {
          this.onReqInitProject(b)
          break
        }
        case 'GET_API': {
          this.onReqGetAPI(b)
          break
        }
        case 'OPEN_IN_DISK': {
          this.onReqOpenInDisk(b)
          break
        }
        case 'RENAME': {
          this.rename(b)
          break
        }
        case 'ADD_FILE':
          this.addFile(b)
        case 'ADD_DIR': {
          this.addDir(b)
          break
        }
        case 'ADD_PAGE': {
          this.addPage(b)
          break
        }
        case 'ADD_COMPONENT': {
          this.addComponent(b)
          break
        }
        case 'DELETE_FILE': {
          this.deleteFile(b)
          break
        }
        case 'DELETE_DIR': {
          this.deleteDir(b)
          break
        }
        case 'BUILD': {
          this.onReqBuild(b)
          break
        }
        case 'UPLOAD_README': {
          this.onReqUploadReadme(b)
          break
        }
        case 'OPEN_EXTERNAL_URL': {
          this.onReqOpenExternalURL(b)
          break
        }
      }
    }
    async notifyGitStatus() {
      let a = { enabled: !1, head: null }
      if (await this.isGitEnabled())
        try {
          const b = await z({
            taskName: 'getgithead',
            config: { dir: this.props.project.projectpath },
            maxTimeout: 60000,
            useBackup: !1,
            downgrade: !0
          })
          if (b.error) throw b.error
          a = { enabled: !!b.enabled, head: b.enabled ? b.head + '' : null }
        } catch (b) {
          console.warn('getgithead error', b), (a = { enabled: !1, head: null })
        }
      const b = {
        type: 'EMIT',
        eventType: 'REMOTE_GIT_STATUS_CHANGE',
        payload: { gitEnabled: a }
      }
      l.sendMessage('EDITOR', JSON.stringify(b))
    }
    async isGitEnabled() {
      if (this._gitEnabled === void 0) {
        let a = !1
        try {
          const b = await z({
            taskName: 'getgitenabled',
            config: { dir: this.props.project.projectpath },
            maxTimeout: 60000,
            useBackup: !1,
            downgrade: !0
          })
          if (b.error) throw b.error
          a = b.enabled
        } catch (b) {
          console.warn('getgitenabled failed', b), (a = !1)
        }
        this._gitEnabled = a
      }
      return this._gitEnabled
    }
    unsetGitEnabled() {
      void 0 === this._gitEnabled ||
        ((this._prevGitEnabled = this._gitEnabled), (this._gitEnabled = void 0))
    }
    async onFileChange(a, b, d) {
      const e = this.props.project,
        f = c.relative(e.projectpath, b)
      ;/^\.git(\\|\/)/i.test(f) && this.unsetGitEnabled(),
        clearTimeout(this._updateGitStatusTimeout),
        (this._updateGitStatusTimeout = setTimeout(async () => {
          this._updateGitStatusTimeout = void 0
          const a = await this.isGitEnabled()
          ;(a || !!this._prevGitEnabled !== !!a) &&
            ((this._prevGitEnabled = a), this.notifyGitStatus())
        }, 600))
      let g = d ? +d.mtime : 0,
        h = d ? this.getSerializableStat(d) : {},
        i = {}
      if (
        ((b = this.getEditorPathFormat(f)),
        ('addDir' === a || 'unlinkDir' === a) && (b += '/'),
        this.triggerBuild(b),
        'add' === a || 'addDir' === a)
      )
        this.files.set(b, !0),
          (i = { payload: { eventType: a, path: b, stat: h } })
      else if ('unlink' === a || 'unlinkDir' === a)
        this.files.delete(b),
          (i = { payload: { eventType: a, path: b, stat: h } })
      else if ('change' === a) {
        if (+this.files.get(b) == g) return
        this.files.set(b, g),
          (i = { payload: { eventType: a, path: b, stat: h } })
      } else return void n.info(`edit.js watch ${a}`)
      ;(i.eventType = 'REMOTE_EXTERNAL_FILE_CHANGE'),
        (i.type = 'EMIT'),
        l.sendMessage('EDITOR', JSON.stringify(i))
    }
    triggerBuild(a) {
      let b = c.extname(a)
      if (B[b]) {
        if ('/project.config.json' !== a) {
          a = this.normalizePath(a)
          let b = c.dirname(a),
            d = this.getClientPath(),
            e = this.getPluginPath()
          if (
            d &&
            0 !== `${b}/`.indexOf(`${d}/`) &&
            e &&
            0 !== `${b}/`.indexOf(`${e}/`)
          )
            return
        }
        const { autoSave: b, autoRefresh: d } = this.props.settings.edit
        clearTimeout(this._rebuildCooldownTimeout),
          d &&
            (b
              ? (this._rebuildCooldownTimeout = setTimeout(() => {
                  this.props.rebuildImmediate(u.COMPILE_ORIGIN.SAVE_FILE)
                }, u.REBUILD_INTERVAL.AUTO_REFRESH_AUTO_SAVE))
              : (this._rebuildCooldownTimeout = setTimeout(() => {
                  this.props.rebuildImmediate(u.COMPILE_ORIGIN.SAVE_FILE)
                }, u.REBUILD_INTERVAL.AUTO_REFRESH)))
      }
    }
    async getFiles() {
      function b(b) {
        return new Promise((c, d) => {
          a.lstat(b, (a, b) => {
            a ? d(a) : c(b)
          })
        })
      }
      return new Promise(async a => {
        const d = await this.getFileUtils(),
          e = d.getAllFileWithDir().map(a => '/' + a),
          f = {},
          g = this.props.project.projectpath
        for (const d of e)
          try {
            const a = await b(c.join(g, d))
            f[d] = _extends({}, a, {
              isDir: a.isDirectory(),
              isFile: !a.isDirectory()
            })
          } catch (a) {
            f[d] = {}
          }
        a({ files: e, info: f })
      })
    }
    getFiles2(
      c,
      {
        ignore: d = ['.git', '**/.git/**', 'node_modules', '**/node_moduels/**']
      } = {}
    ) {
      function e(b) {
        return new Promise((c, d) => {
          a.lstat(b, (a, b) => {
            a ? d(a) : c(b)
          })
        })
      }
      return (
        console.log('begin get file', new Date()),
        new Promise((a, f) => {
          b(
            '**',
            {
              absolute: !0,
              ignore: d,
              cwd: c,
              nosort: !0,
              silent: !0,
              mark: !0,
              nodir: !1,
              dot: !0
            },
            async (b, d) => {
              if (b) return void f(b)
              let g = {}
              for (let a of d) {
                const b = await e(a)
                g[a] = _extends({}, b, {
                  isDir: b.isDirectory(),
                  isFile: !b.isDirectory()
                })
              }
              ;(d = d.map(a => a.slice(c.length))),
                (g = h.mapKeys(g, (a, b) => b.slice(c.length))),
                console.log('end get file', new Date()),
                a({ files: d, info: g })
            }
          )
        })
      )
    }
    lstatRecursive(b, { absolute: d = !1, ignore: e = ['.git'] } = {}) {
      function f(b) {
        return new Promise((c, d) => {
          a.readdir(b, (a, b) => {
            a ? d(a) : c(b)
          })
        })
      }
      function g(b) {
        return new Promise((c, d) => {
          a.lstat(b, (a, b) => {
            a ? d(a) : c(b)
          })
        })
      }
      return new Promise(async (a, i) => {
        try {
          const e = await g(b)
          if (!e.isDirectory()) return void i('project path is a file')
          const j = await f(b),
            k = j.map(a => c.join(b, a))
          let l = [],
            m = {}
          for (; 0 < k.length; ) {
            let a = k.pop()
            const b = await g(a)
            if (b.isDirectory()) {
              const b = await f(a)
              Array.prototype.push.apply(k, b.map(b => c.join(a, b))),
                (a += '/')
            }
            l.push(a),
              (m[a] = _extends({}, b, {
                isDir: b.isDirectory(),
                isFile: !b.isDirectory()
              }))
          }
          if (
            ((l = l.map(a => a.replace('\\', '/'))),
            (m = h.mapKeys(m, (a, b) => b.replace('\\', '/'))),
            !d)
          ) {
            const a = b.length
            ;(l = l.map(b => b.slice(a))),
              (m = h.mapKeys(m, (b, c) => c.slice(a)))
          }
          a({ files: l, info: m })
        } catch (a) {
          i(a)
        }
      })
    }
    onReqFocus() {
      this.editorWebview &&
        (this.editorWebview.click && this.editorWebview.click(),
        this.editorWebview.focus && this.editorWebview.focus(),
        this.onWebviewClick())
    }
    onWebviewClick() {
      if (this.editorWebview) {
        const a = new UIEvent('click', { bubbles: !0 })
        this.editorWebview.dispatchEvent(a)
      }
    }
    setFileTreeShow() {
      this.props.setFileTreeShow(!0)
    }
    setFileTreeHide() {
      this.props.setFileTreeShow(!1)
    }
    onReqSaveFile(b) {
      let d
      try {
        const e = this.normalizePath(b.path),
          f = c.join(this.props.project.projectpath, e)
        let g = this.getClientPath()
        if (f === c.join(this.props.project.projectpath, g, 'app.json')) {
          let a = 0
          this.props.settings.edit.autoSave && (a = 5e3), clearTimeout(D)
          let d, e, f, i
          try {
            ;(d = JSON.parse(this.fileUtils.getFile(c.join(g, 'app.json')))),
              (e = d.pages || []),
              (f = JSON.parse(b.data)),
              (i = f.pages || [])
          } catch (a) {}
          let j = h.difference(i, e)
          D = setTimeout(() => {
            try {
              j.forEach(a => {
                this.autoAddPage(a)
              })
            } catch (a) {}
          }, a)
        }
        this.fileUtils.writeFileSync(e, b.data, 'utf8')
        const i = a.lstatSync(f)
        ;(d = {
          errMsg: '',
          type: 'CALLBACK',
          callback: b.callback,
          payload: { stat: this.getSerializableStat(i) }
        }),
          this.mtimes.set(f, +i.mtime),
          this.files.set(b.path, i.mtime)
      } catch (a) {
        n.error(`editor.container.js: onReqSaveFile error: ${a}`),
          (d = { errMsg: a.toString(), type: 'CALLBACK', callback: b.callback })
      }
      l.sendMessage('EDITOR', JSON.stringify(d)),
        x('weapp_editor_savefile', this.props.project.appid)
    }
    async onReqGetGitStatus(a) {
      console.log('editor.container.js, onReqGetGitStatus', a)
      const b = { type: 'CALLBACK', callback: a.callback, payload: {} }
      if (await this.isGitEnabled()) {
        let a = {}
        try {
          const b = await z({
            taskName: 'getgitstatus',
            config: { dir: this.props.project.projectpath },
            maxTimeout: 60000,
            useBackup: !1,
            downgrade: !0
          })
          if (b.error) throw b.error
          a = b.status || {}
        } catch (b) {
          console.warn('getGitStatus failed', b), (a = {})
        }
        const c = {},
          d = {}
        for (const b in a) {
          if (!a.hasOwnProperty(b)) continue
          const e = a[b]
          d[this.getEditorPathFormat(b)] = c[e] = c[e] || {
            ignored: A.isStatusIgnored(e),
            new: A.isStatusNew(e),
            modified: A.isStatusModified(e),
            deleted: A.isStatusDeleted(e),
            staged: A.isStatusStaged(e),
            conflict: A.isStatusConflict(e)
          }
        }
        b.payload = d
      }
      l.sendMessage('EDITOR', JSON.stringify(b))
    }
    async onReqReviewFile(a) {
      const b = {
          type: 'CALLBACK',
          callback: a.callback,
          payload: { gitLineDiffs: [] }
        },
        c = this.props.project.projectpath
      if (await this.isGitEnabled()) {
        const c = this.normalizePath(a.path)
        let d = []
        try {
          let b = a.data || ''
          this.props.settings.edit.gitIgnoreWindowsReturn &&
            (b = b.replace(/\r\n/g, '\n'))
          const e = await z({
            taskName: 'getgitlinediffs',
            config: { dir: this.props.project.projectpath, path: c },
            dataStr: b,
            maxTimeout: 60000,
            useBackup: !1,
            downgrade: !0
          })
          if (e.error) throw e.error
          d = e.gitLineDiffs || []
        } catch (a) {
          d = []
        }
        b.payload.gitLineDiffs = d
      }
      l.sendMessage('EDITOR', JSON.stringify(b))
    }
    async onReqFormatCode(a) {
      let b
      try {
        b = this.props.settings.edit.tabSize
      } catch (a) {
        b = 2
      }
      let c = v(a.data, b),
        d = { type: 'CALLBACK', callback: a.callback, payload: c }
      l.sendMessage('EDITOR', JSON.stringify(d))
    }
    async onReqInitProject(a) {
      const { files: b, info: c } = await this.getFiles(),
        d = {},
        e = this.props.settings
      for (const b in e.appearance) d[b] = e.appearance[b]
      for (const b in e.edit) d[b] = e.edit[b]
      let f = {
        errMsg: '',
        type: 'CALLBACK',
        callback: a.callback,
        payload: {
          project: _extends({}, this.props.project, {
            name: this.props.project.projectname,
            path: this.props.project.projectpath,
            createTime: this.props.project.createTime
          }),
          files: b,
          info: c,
          config: d
        }
      }
      b.forEach(a => {
        this.files.set(a, !0)
      }),
        l.sendMessage('EDITOR', JSON.stringify(f)),
        this.notifyGitStatus()
    }
    async onReqGetAPI(a) {
      let b
      try {
        b = !!this.props.project.attr.gameApp
      } catch (a) {
        b = !1
      }
      const c = await y.getFallbackAPI(b)
      let d = {
        errMsg: '',
        type: 'CALLBACK',
        callback: a.callback,
        payload: { files: c }
      }
      l.sendMessage('EDITOR', JSON.stringify(d))
    }
    async onReqSyncFiles(a) {
      const { files: b, info: c } = await this.getFiles()
      let d = {
        errMsg: '',
        type: 'CALLBACK',
        callback: a.callback,
        payload: { files: b, info: c }
      }
      b.forEach(a => {
        this.files.set(a, !0)
      }),
        l.sendMessage('EDITOR', JSON.stringify(d))
    }
    async onReqGetCommitFile(a) {
      const b = {
        type: 'CALLBACK',
        callback: a.callback,
        payload: { content: null, stats: null }
      }
      if (await this.isGitEnabled()) {
        let c, d
        const e = this.normalizePath(a.path)
        try {
          const a = await z({
            taskName: 'getgitcommitfile',
            config: { dir: this.props.project.projectpath, path: e },
            maxTimeout: 60000,
            useBackup: !1,
            downgrade: !0
          })
          if (a.error) throw a.error
          ;(c = a.content || null), (d = a.stats || null)
        } catch (a) {
          console.warn('getGitCommitFile failed', a), (c = null), (d = null)
        }
        ;(b.payload.content = 'string' == typeof c ? c : null),
          (b.payload.stats = d || null)
      }
      l.sendMessage('EDITOR', JSON.stringify(b))
    }
    async onReqGetFile(b) {
      if (E[c.extname(b.path).toLowerCase()]) {
        let e = d.resolve(
          `http://127.0.0.1:${global.proxyPort}/editor/files/`,
          this.normalizePath(b.path)
        )
        try {
          e = decodeURI(e)
        } catch (a) {}
        let f,
          g = c.join(this.props.project.projectpath, this.normalizePath(b.path))
        try {
          f = k(g)
        } catch (a) {
          f = { width: -1, height: -1 }
        }
        const h = a.statSync(g),
          i = {
            errMsg: '',
            type: 'CALLBACK',
            callback: b.callback,
            payload: { url: e, dimension: f, stat: this.getSerializableStat(h) }
          }
        l.sendMessage('EDITOR', JSON.stringify(i))
      } else {
        const d = this.fileUtils.getFile(this.normalizePath(b.path)),
          e = a.statSync(
            c.join(this.props.project.projectpath, this.normalizePath(b.path))
          ),
          f = {
            errMsg: '',
            type: 'CALLBACK',
            callback: b.callback,
            payload: { data: d, stat: this.getSerializableStat(e) }
          }
        l.sendMessage('EDITOR', JSON.stringify(f))
      }
    }
    async onReqFindInFiles(a) {
      let { options: b, string: d } = a,
        { cwd: e, i: f, wholeword: g } = b
      ;(e = c.join(this.props.project.projectpath, e ? e : '')),
        p(
          {
            str: d,
            cwd: e,
            i: f,
            wholeword: g,
            project: { projectpath: this.props.project.projectpath }
          },
          (b, c) => {
            let d = { type: 'CALLBACK', callback: a.callback }
            b
              ? (d.errMsg = JSON.stringify(b))
              : ((d.errMsg = ''), (d.payload = c)),
              l.sendMessage('EDITOR', JSON.stringify(d))
          }
        )
    }
    onReqOpenInDisk(a) {
      const { path: b } = a
      nw.Shell.showItemInFolder(c.join(this.props.project.projectpath, b)),
        l.sendMessage(
          'EDITOR',
          JSON.stringify({
            errMsg: '',
            payload: {},
            type: 'CALLBACK',
            callback: a.callback
          })
        )
    }
    onReqUploadReadme(a) {
      try {
        this.props.setUploadPluginDocInfo({ show: !0 }),
          l.sendMessage(
            'EDITOR',
            JSON.stringify({ type: 'CALLBACK', callback: a.callback })
          )
      } catch (b) {
        l.sendMessage(
          'EDITOR',
          JSON.stringify({
            errMsg: b.toString(),
            type: 'CALLBACK',
            callback: a.callback
          })
        )
      }
    }
    onReqOpenExternalURL(a) {
      try {
        const { link: b } = a
        b && /^http(s):/.test(b) && nw.Shell.openExternal(b),
          l.sendMessage(
            'EDITOR',
            JSON.stringify({ type: 'CALLBACK', callback: a.callback })
          )
      } catch (b) {
        l.sendMessage(
          'EDITOR',
          JSON.stringify({
            errMsg: b.toString(),
            type: 'CALLBACK',
            callback: a.callback
          })
        )
      }
    }
    rename(b) {
      const { oldPath: d, newPath: e } = b
      try {
        const f = c.join(this.props.project.projectpath, d),
          g = c.join(this.props.project.projectpath, e)
        a.renameSync(f, g)
        const h = a.lstatSync(g)
        this.files.delete(this.getEditorPathFormat(d)),
          this.files.set(e, !0),
          l.sendMessage(
            'EDITOR',
            JSON.stringify({
              type: 'CALLBACK',
              errMsg: '',
              payload: { stat: this.getSerializableStat(h) },
              callback: b.callback
            })
          )
      } catch (a) {
        l.sendMessage(
          'EDITOR',
          JSON.stringify({
            errMsg: a.toString(),
            type: 'CALLBACK',
            callback: b.callback
          })
        )
      }
    }
    addFile(b) {
      try {
        const d = c.join(
          this.props.project.projectpath,
          this.normalizePath(b.path)
        )
        a.writeFileSync(d, '', 'utf8')
        const e = a.lstatSync(d)
        this.mtimes.set(d, +e.mtime)
        const f = {
          errMsg: '',
          type: 'CALLBACK',
          callback: b.callback,
          payload: { stat: this.getSerializableStat(e) }
        }
        this.files.set(b.path, !0), l.sendMessage('EDITOR', JSON.stringify(f))
      } catch (a) {
        l.sendMessage(
          'EDITOR',
          JSON.stringify({ errMsg: a, type: 'CALLBACK', callback: b.callback })
        )
      }
    }
    addDir(b) {
      try {
        const d = c.join(
          this.props.project.projectpath,
          this.removeTrailingSlash(this.normalizePath(b.path))
        )
        w.sync(d)
        const e = a.lstatSync(d)
        this.mtimes.set(d, +e.mtime)
        const f = {
          errMsg: '',
          type: 'CALLBACK',
          callback: b.callback,
          payload: { stat: this.getSerializableStat(e) }
        }
        this.files.set(b.path, !0), l.sendMessage('EDITOR', JSON.stringify(f))
      } catch (a) {
        l.sendMessage(
          'EDITOR',
          JSON.stringify({
            errMsg: a.toString(),
            type: 'CALLBACK',
            callback: b.callback
          })
        )
      }
    }
    autoAddPage(b) {
      try {
        const d = this.normalizePath(b)
        let e = c.join(this.props.project.projectpath, this.getClientPath(), d)
        const f = c.normalize(
            c.join(this.props.project.projectpath, this.getClientPath())
          ),
          g = c.normalize(c.resolve(e, '..'))
        if (!g.startsWith(f) && g !== f)
          return void console.warn('given page path out of range')
        let h = c.dirname(e)
        for (const b in (w.sync(h), C.page))
          try {
            a.existsSync(`${e}${b}`) ||
              a.writeFileSync(`${e}${b}`, C.page[b].replace(/\{\{page\}\}/g, d))
          } catch (a) {}
      } catch (a) {}
    }
    addPage(b) {
      try {
        let d = this.getClientPath()
        const e = c.join(this.props.project.projectpath, d, 'app.json')
        let f = new RegExp(`^${d}/`),
          g = this.removeTrailingSlash(this.normalizePath(b.path))
        if (!d || f.test(g)) {
          let b = JSON.parse(this.fileUtils.getFile(c.join(d, 'app.json')))
          const h = b.pages || []
          ;(g = g.replace(f, '')),
            -1 === h.indexOf(g) && h.push(g),
            (b.pages = h)
          let i
          try {
            i = this.props.settings.edit.tabSize
          } catch (a) {
            i = 2
          }
          a.writeFileSync(e, JSON.stringify(b, null, i), 'utf8')
        }
        const h = c.join(this.props.project.projectpath, b.path)
        for (const b in C.page)
          try {
            a.existsSync(`${h}${b}`) ||
              a.writeFileSync(`${h}${b}`, C.page[b].replace(/\{\{page\}\}/g, g))
          } catch (a) {}
        const i = a.lstatSync(e),
          j = {
            errMsg: '',
            type: 'CALLBACK',
            callback: b.callback,
            payload: { stat: this.getSerializableStat(i) }
          }
        l.sendMessage('EDITOR', JSON.stringify(j))
      } catch (a) {
        l.sendMessage(
          'EDITOR',
          JSON.stringify({
            errMsg: a.toString(),
            type: 'CALLBACK',
            callback: b.callback
          })
        )
      }
    }
    addComponent(b) {
      try {
        let d = this.getClientPath(),
          e = new RegExp(`^${d}/`),
          f = this.removeTrailingSlash(this.normalizePath(b.path))
        f = f.replace(e, '')
        const g = c.join(this.props.project.projectpath, b.path)
        for (const b in C.component)
          try {
            a.existsSync(`${g}${b}`) ||
              a.writeFileSync(
                `${g}${b}`,
                C.component[b].replace(/\{\{component\}\}/g, f)
              )
          } catch (a) {}
        const h = {
          errMsg: '',
          type: 'CALLBACK',
          callback: b.callback,
          payload: {}
        }
        l.sendMessage('EDITOR', JSON.stringify(h))
      } catch (a) {
        l.sendMessage(
          'EDITOR',
          JSON.stringify({
            errMsg: a.toString(),
            type: 'CALLBACK',
            callback: b.callback
          })
        )
      }
    }
    async deleteFile(a) {
      try {
        await i(c.join(this.props.project.projectpath, a.path)),
          this.files.delete(a.path),
          l.sendMessage(
            'EDITOR',
            JSON.stringify({
              errMsg: '',
              type: 'CALLBACK',
              callback: a.callback,
              payload: {}
            })
          )
      } catch (b) {
        l.sendMessage(
          'EDITOR',
          JSON.stringify({ errMsg: b, type: 'CALLBACK', callback: a.callback })
        )
      }
    }
    async deleteDir(a) {
      try {
        await i(c.join(this.props.project.projectpath, a.path)),
          this.files.forEach((b, c) => {
            c.startsWith(this.getEditorPathFormat(a.path, !0)) &&
              this.files.delete(c)
          }),
          l.sendMessage(
            'EDITOR',
            JSON.stringify({
              errMsg: '',
              type: 'CALLBACK',
              callback: a.callback,
              payload: {}
            })
          )
      } catch (b) {
        l.sendMessage(
          'EDITOR',
          JSON.stringify({
            errMsg: b.toString(),
            type: 'CALLBACK',
            callback: a.callback,
            payload: {}
          })
        )
      }
    }
    async onReqBuild(a) {
      clearTimeout(this._rebuildCooldownTimeout),
        (this._rebuildCooldownTimeout = setTimeout(() => {
          this.props.rebuildImmediate(a && a.data)
        }, u.REBUILD_INTERVAL.AUTO_REFRESH))
    }
    getSerializableStat(a) {
      return _extends({}, a, {
        isDir: a.isDirectory(),
        isFile: !a.isDirectory()
      })
    }
    normalizePath(a) {
      return (a = a.replace(/\\/g, '/')), '/' === a[0] ? a.substr(1) : a
    }
    getEditorPathFormat(a, b = !1) {
      return (
        (a = a.replace(/\\/g, '/')),
        b && !a.endsWith('/') && (a += '/'),
        '/' === a[0] ? a : '/' + a
      )
    }
    removeTrailingSlash(a) {
      return a.endsWith('/') ? a.slice(0, -1) : a
    }
    render() {
      let a = this.props
      if (!a.project) return null
      let b = 'monaco'
      return (
        a.show || (b += ' ui-invisible'),
        e.createElement('div', {
          className: b,
          style: { minHeight: '97px' },
          tabIndex: -1,
          ref: a => (this.container = a)
        })
      )
    }
  }
  module.exports = g(
    a => ({
      editorOpenFileInfo: a.info.editorOpenFileInfo,
      show: a.window.editor && a.window.editor.show,
      project: a.project.current,
      settings: a.settings,
      focus: a.window.focus
    }),
    a => ({
      confirm(b, c) {
        a(
          r.setConfirmInfo(
            _extends(
              {
                show: !0,
                showCancel: !0,
                callback: c,
                confirmText: '\u786E\u5B9A',
                cancelText: '\u53D6\u6D88'
              },
              b
            )
          )
        )
      },
      setFileTreeShow(b) {
        a(s.setEditor({ fileTreeShow: b }))
      },
      toggleEditorWindow() {
        a(s.toggleEditorWindow())
      },
      rebuildImmediate(b) {
        a(t.compileImmediate({ origin: b }))
      },
      setUploadPluginDocInfo(b) {
        a(r.setUploadPluginDocInfo(b))
      }
    })
  )(F)
})(require('lazyload'), require)
