text: //================================================================
  // RS_WXPos.js
  // ---------------------------------------------------------------
  // The MIT License
  // Copyright (c) 2020 biud436
  // ---------------------------------------------------------------
  // Free for commercial and non commercial use.
  //================================================================
  /*:
   * @plugindesc <RS_WXPos>
   * @author biud436
   *          
   * @help
   *
   */
  
  var Imported = Imported || {};
  Imported.RS_WXPos = true;
  
  var RS = RS || {};
  RS.WXPos = RS.WXPos || {};
  
  (function($) {
      
      "use strict";
  
      var parameters = $plugins.filter(function (i) {
        return i.description.contains('<RS_WXPos>');
      });
      
      parameters = (parameters.length > 0) && parameters[0].parameters;
  
      let Config = {
          "Scene_Menu": {
              "Window_Gold": {
                  x: 300,
                  y: 0,
              },
          },
          "Scene_Title": {
              "Window_TitleCommand": {
                  x: 200,
                  y: 200,
              }
          }
      };    
  
      const utils = {
  
          configFile : "myWindowConfig.json",
  
          async writeConfigFile() {
              if(!Utils.isNwjs()) return;
              const fs = require('fs');
              const path = require('path');
              const {promisify} = require('util');
              const writeFile = promisify(fs.writeFile);
      
              let rootFolder = path.dirname(process.mainModule.filename).replace(/\\/g, "/");
              let contents = JSON.stringify(Config, null, "    ");
  
              await writeFile(path.join(rootFolder, "data", this.configFile), contents, "utf8")
                  .then(val => {
                      console.log(`myWindowConfig.json file is written completely!`);
                  }).catch(err => {
                      throw new Error(err);
                  })                
          },
  
          async readConfigFile() {
              if(!Utils.isNwjs()) return;
              const fs = require('fs');
              const path = require('path');
              const {promisify} = require('util');
              const readFile = promisify(fs.readFile);
      
              let rootFolder = path.dirname(process.mainModule.filename).replace(/\\/g, "/");
              let targetFile = path.join(rootFolder, "data", this.configFile);
  
              if(fs.existsSync(targetFile)) {
                  await readFile(targetFile, "utf8")
                  .then(contents => {
                      Config = JSON.parse(contents);
                      console.log(`myWindowConfig.json file is loaded successfully`);
                  }).catch(err => {
                      throw new Error(err);
                  })
              }            
          },
  
          async internalDownloadFile(url, filename, callback) {
      
              const options = {
                  port: 443,
                  headers: {},
              };
          
              let req = https.get(url, options, res => {
                  console.log('statusCode:', res.statusCode);
                  console.log('headers:', res.headers);
          
                  const headers = res.headers;
                  
                  if('content-disposition' in headers) {
                      if(/(?:filename=)(.*)/i.exec( headers['content-disposition'])) {
                          filename = RegExp.$1;
                      }
                  }
          
                  let out = fs.createWriteStream(filename);
                  let len = 1048576;
                  let isValid = false;
          
                  if("content-length" in res.headers) {
                      len = parseInt(res.headers["content-length"], 10);
                      isValid = true;
                  }
              
                  let cur = 0;
                  let total = len / 1048576;
                  
                  if(res.statusCode === 200) {
                      res.pipe(out);
              
                      res.on('data', c => {
                          cur += c.length;
                          if(isValid) {
                              console.log(`${filename} => ${(100.0 * cur / len).toFixed(0)}% (${(cur / total).toFixed(2)} MB)`);
                          }
                      });
                      res.on('end', async () => {
                          await callback(null, res);
                      });
                  }
              });
          
              req.on('error', async err => {
                  await callback(err, null);
              });
          
          },
  
          download(url, filename) {
              if(!Utils.isNwjs()) return;
              const {promisify} = require('util');
              const downloadFile = promisify(this.internalDownloadFile);
              downloadFile(url, filename).then(res => {
                  console.log(`Completed download the file called ${filename}`);
              }).catch(err => {
                  throw new Error(err);
              });
          }
          
      };
  
      /**
       * interactive는 버그가 있다.
       * GameCanvas의 zIndex가 다른 모든 HtmlElement보다 위에 있어야 동작한다.
       * 그렇게 하지 않으면, mousemove하고 pointermove만 동작하게 된다.
       */            
      Scene_Base.prototype.prepareInteraction = function() {
          let maxIndex = 0;
  
          this._tempCanvasIndex = parseInt(Graphics._canvas.style.zIndex);
  
          this.on("removed", () => {
              Graphics._canvas.style.zIndex = this._tempCanvasIndex;
          });
          
          for(const el of document.body.children) {
              let targetIndex = parseInt(el.style.zIndex);
              if(targetIndex > maxIndex) {
                  maxIndex = targetIndex;
              }
          }
  
          Graphics._canvas.style.zIndex = maxIndex + 1;
  
          this._isReadyToInteraction = true;
      }
  
      Scene_Base.prototype.handleTouchInsideWindow = function(ecurrentSceneName, e) {
  
          e.interactive = true;        
          e.hitArea = new PIXI.Rectangle(0, 0, e.width || 100, e.height || 100);
  
          const Events = [
              "mousedown",
              "mousemove",
              // "mouseout",
              // "mouseover",
              "mouseup",
              "mouseupoutside",
              "pointercancel",
              "pointerdown",
              "pointermove",
              "pointerout",
              "pointerover",
              "pointertap",
              "pointerup",
              "pointerupoutside"
          ];
  
          Events.forEach(evName => {
              e.on(evName, 
              /**
               * @param {Event} event
               */        
              (event) => {
                  console.log(evName);
                  const data = event.data;
  
                  const mouseX = data.global.x;
                  const mouseY = data.global.y;
              });
          })
  
          e.on("mouseover", (ev) => {
              e.opacity = 228;
          })
  
          e.on("mouseout", (ev) => {
              e.opacity = 40;     
          })
  
      };
  
      /**
       * 윈도우 내 특정 프로퍼티를 재정의합니다.
       * @param {String} currentSceneName
       * @param {Window} e
       */
      Scene_Base.prototype.resetWindow = function(currentSceneName, e) {
          if(e instanceof Window) {
              let name = e.constructor.name.toString();
              let config = Config[currentSceneName];
              const keys = Object.keys(config);
              if(keys.contains(name)) {
                  e.x = config[name].x;
                  e.y = config[name].y;
  
                  this.handleTouchInsideWindow(currentSceneName, e);
  
                  // 회전된 상태는 이 로직으로 감지 불가능
                  if(e.visible && e.opacity > 0) {
                      if(e.x < 0 && e.x > Graphics.boxWidth) {
                          e.visible = false;
                      }
                      if(e.visible && e.y < 0 && e.y > Graphics.boxHeight) {
                          e.visible = false;
                      }       
                  }
  
                  e._isWindow = false;
              }
          }
      };
  
      /**
       * 씬이 생성될 때, 모든 윈도우의 위치를 재설정합니다.
       */
      Scene_Base.prototype.initWithWindowPosition = function() {
          let currentSceneName = this.constructor.name.toString();
          this.children.forEach(e => this.resetWindow(currentSceneName, e));
          if(this._windowLayer) this._windowLayer.children.forEach(e => this.resetWindow(currentSceneName, e));
      };
  
      var alias_Scene_Menu_create = Scene_Menu.prototype.create;
      Scene_Menu.prototype.create = function() {
          alias_Scene_Menu_create.call(this);
          this.prepareInteraction();
          this.initWithWindowPosition();
      };          
  
  })(RS.WXPos);
  
  