System.register(['reactive-jsx', 'src/client/graphics.js', 'utils', 'src/client/vivide/vivide.js', 'src/client/literature.js', 'src/client/strings.js'], function (_export, _context) {
  "use strict";

  var _childText, _childExpression, _childElement, _children, _attributeExpression, _attributeStringLiteral, _attributes, _element, _addSourceLocation, pt, debounce, through, asDragImageFor, getObjectFor, removeTempKey, letsScript, MicrosoftAcademicEntities, Strings;

  return {
    setters: [function (_reactiveJsx) {
      _childText = _reactiveJsx.childText;
      _childExpression = _reactiveJsx.childExpression;
      _childElement = _reactiveJsx.childElement;
      _children = _reactiveJsx.children;
      _attributeExpression = _reactiveJsx.attributeExpression;
      _attributeStringLiteral = _reactiveJsx.attributeStringLiteral;
      _attributes = _reactiveJsx.attributes;
      _element = _reactiveJsx.element;
      _addSourceLocation = _reactiveJsx.addSourceLocation;
    }, function (_srcClientGraphicsJs) {
      pt = _srcClientGraphicsJs.pt;
    }, function (_utils) {
      debounce = _utils.debounce;
      through = _utils.through;
      asDragImageFor = _utils.asDragImageFor;
      getObjectFor = _utils.getObjectFor;
      removeTempKey = _utils.removeTempKey;
    }, function (_srcClientVivideVivideJs) {
      letsScript = _srcClientVivideVivideJs.letsScript;
    }, function (_srcClientLiteratureJs) {
      MicrosoftAcademicEntities = _srcClientLiteratureJs.MicrosoftAcademicEntities;
    }, function (_srcClientStringsJs) {
      Strings = _srcClientStringsJs.default;
    }],
    execute: function () {
      const __SystemJSRewritingHack = {};
      _recorder_._src_client_draganddrop_js = _recorder_._src_client_draganddrop_js || {};
      Object.defineProperty(_recorder_._src_client_draganddrop_js, '__unload__', {
        get() {
          return __unload__;
        },

        set(thisIsVererySecretVariableName) {
          _export('__unload__', __unload__ = thisIsVererySecretVariableName);

          return true;
        },

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._src_client_draganddrop_js, 'findDropContext', {
        get() {
          return findDropContext;
        },

        set(thisIsVererySecretVariableName) {
          findDropContext = thisIsVererySecretVariableName;
          return true;
        },

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._src_client_draganddrop_js, 'appendToContainerAt', {
        get() {
          return appendToContainerAt;
        },

        set(thisIsVererySecretVariableName) {
          appendToContainerAt = thisIsVererySecretVariableName;
          return true;
        },

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._src_client_draganddrop_js, 'applyDragCSSClass', {
        get() {
          return applyDragCSSClass;
        },

        set(thisIsVererySecretVariableName) {
          _export('applyDragCSSClass', applyDragCSSClass = thisIsVererySecretVariableName);

          return true;
        },

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._src_client_draganddrop_js, 'pt', {
        get() {
          return pt;
        },

        set(thisIsVererySecretVariableName) {
          pt = thisIsVererySecretVariableName;
          return true;
        },

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._src_client_draganddrop_js, 'removeTempKey', {
        get() {
          return removeTempKey;
        },

        set(thisIsVererySecretVariableName) {
          removeTempKey = thisIsVererySecretVariableName;
          return true;
        },

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._src_client_draganddrop_js, 'getObjectFor', {
        get() {
          return getObjectFor;
        },

        set(thisIsVererySecretVariableName) {
          getObjectFor = thisIsVererySecretVariableName;
          return true;
        },

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._src_client_draganddrop_js, 'asDragImageFor', {
        get() {
          return asDragImageFor;
        },

        set(thisIsVererySecretVariableName) {
          asDragImageFor = thisIsVererySecretVariableName;
          return true;
        },

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._src_client_draganddrop_js, 'through', {
        get() {
          return through;
        },

        set(thisIsVererySecretVariableName) {
          through = thisIsVererySecretVariableName;
          return true;
        },

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._src_client_draganddrop_js, 'debounce', {
        get() {
          return debounce;
        },

        set(thisIsVererySecretVariableName) {
          debounce = thisIsVererySecretVariableName;
          return true;
        },

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._src_client_draganddrop_js, 'letsScript', {
        get() {
          return letsScript;
        },

        set(thisIsVererySecretVariableName) {
          letsScript = thisIsVererySecretVariableName;
          return true;
        },

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._src_client_draganddrop_js, 'MicrosoftAcademicEntities', {
        get() {
          return MicrosoftAcademicEntities;
        },

        set(thisIsVererySecretVariableName) {
          MicrosoftAcademicEntities = thisIsVererySecretVariableName;
          return true;
        },

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._src_client_draganddrop_js, 'Strings', {
        get() {
          return Strings;
        },

        set(thisIsVererySecretVariableName) {
          Strings = thisIsVererySecretVariableName;
          return true;
        },

        enumerable: true,
        configurable: true
      });
      function applyDragCSSClass() {
        this.addEventListener('dragenter', evt => this.classList.add("drag"), false);
        this.addEventListener('dragleave', evt => this.classList.remove("drag"), false);
        this.addEventListener('drop', evt => this.classList.remove("drag"));
      }

      _export('applyDragCSSClass', applyDragCSSClass);

      function appendToContainerAt(node, evt) {
        dropOnDocumentBehavior.openAt(node, evt
        // document.body.appendChild(node);
        // lively.setGlobalPosition(node, pt(evt.clientX, evt.clientY));
        );
      }

      //class DataTransferItemHandler {
      //  handle() {
      //    
      //  }
      //}

      class DropOnBodyHandler {
        constructor(mimeType, handler) {
          this.mimeType = mimeType;
          this.handler = handler;
        }

        handle(evt) {
          const dt = evt.dataTransfer;
          if (!dt.types.includes(this.mimeType)) {
            return false;
          }

          const element = this.handler(dt.getData(this.mimeType));
          if (element) {
            if (element.then) {
              element.then(r => {
                appendToContainerAt(r, evt);
              });
            } else {
              appendToContainerAt(element, evt);
            }
            return true;
          } else {
            return false;
          }
        }
      }

      Object.defineProperty(_recorder_._src_client_draganddrop_js, 'DropOnBodyHandler', {
        get() {
          return DropOnBodyHandler;
        },

        set(thisIsVererySecretVariableName) {
          DropOnBodyHandler = thisIsVererySecretVariableName;
          return true;
        },

        enumerable: true,
        configurable: true
      });
      function findDropContext(element, path, container = document.body) {
        return path.find(ea => {
          return ea && (ea === container || ea.classList && ea.classList.contains("lively-content") || ea.localName == "lively-folder");
        }) || container;
      }

      // drop and a dragged html element into a container
      class DropElementHandler {
        constructor(container, customHandler) {
          this.container = container;
          if (customHandler) {
            this.handleElement = customHandler;
          }
        }

        handleElement(element, evt) {
          var container = findDropContext(element, evt.composedPath(), this.container);
          container.appendChild(element);
          lively.setGlobalPosition(element, lively.getPosition(evt));
          if (element.lastDragOffset) {
            lively.moveBy(element, element.lastDragOffset);
          }
        }

        handle(evt) {
          const dt = evt.dataTransfer;
          if (!dt.types.includes("lively/element")) {
            return false;
          }
          const tempKey = dt.getData("lively/element");
          const element = getObjectFor(tempKey);
          if (!element) return false;

          this.handleElement(element, evt);

          removeTempKey(tempKey);
          return true;
        }

        static handle(evt, container, cb) {
          new this(container, cb).handle(evt);
        }
      }

      _export('DropElementHandler', DropElementHandler);

      Object.defineProperty(_recorder_._src_client_draganddrop_js, 'DropElementHandler', {
        get() {
          return DropElementHandler;
        },

        set(thisIsVererySecretVariableName) {
          _export('DropElementHandler', DropElementHandler = thisIsVererySecretVariableName);

          return true;
        },

        enumerable: true,
        configurable: true
      });
      const dropOnDocumentBehavior = {

        removeListeners() {
          lively.removeEventListener("dropOnDocumentBehavior", document);
        },

        load() {
          // #HACK: we remove listeners here, because this module is called three times (without unloading in between!!)
          this.removeListeners();
          lively.addEventListener("dropOnDocumentBehavior", document, "dragover", this.onDragOver.bind(this));
          lively.addEventListener("dropOnDocumentBehavior", document, "drop", this.onDrop.bind(this));

          this.handlers = [
          // lively elements
          new DropElementHandler(document.body),
          // {
          //   handle(evt) {
          //     const dt = evt.dataTransfer;
          //     if(!dt.types.includes("lively/element")) { return false; }
          //     const tempKey = dt.getData("lively/element");
          //     const element = getObjectFor(tempKey);
          //     if (!element) return false;
          //     document.body.appendChild(element)
          //     lively.setGlobalPosition(element, lively.getPosition(evt))
          //     if (element.lastDragOffset) {
          //       lively.moveBy(element, element.lastDragOffset)
          //     }
          //     removeTempKey(tempKey);
          //     return true;
          //   }
          // },
          // vivide list
          {
            handle(evt) {
              const dt = evt.dataTransfer;
              if (!dt.types.includes("vivide")) {
                return false;
              }
              if (!dt.types.includes("javascript/object")) {
                return false;
              }
              const dataTempKey = dt.getData("javascript/object");
              const data = getObjectFor(dataTempKey);
              const viewTempKey = dt.getData("vivide/source-view");
              const sourceView = getObjectFor(viewTempKey);
              getObjectFor;
              letsScript(data, evt, sourceView);
              return true;
            }
          },

          // move a desktop item
          {
            handle(evt) {
              const dt = evt.dataTransfer;
              if (!dt.types.includes("desktop-icon/object")) {
                return false;
              }
              const tempKey = dt.getData("desktop-icon/object");
              const icon = getObjectFor(tempKey);
              removeTempKey(tempKey);

              const offset = dt.types.includes("desktop-icon/offset") ? JSON.parse(dt.getData("desktop-icon/offset")) : pt(0, 0);
              lively.setGlobalPosition(icon, pt(evt.clientX, evt.clientY).subPt(offset));
              return true;
            }
          },

          // knot/url to desktop item
          {
            handle(evt) {
              const dt = evt.dataTransfer;
              if (!dt.types.includes("knot/url")) {
                return false;
              }
              const knotURL = dt.getData("knot/url");

              _addSourceLocation(lively.create('knot-desktop-icon'), {
                file: 'https://lively-kernel.org/lively4/lively4-portal/src/client/draganddrop.js',
                end: {
                  column: 44,
                  line: 167
                },
                start: {
                  column: 10,
                  line: 167
                }
              }).through(icon => lively.setGlobalPosition(icon, pt(evt.clientX, evt.clientY))).then(icon => icon.knotURL = knotURL);

              return true;
            }
          }, new DropOnBodyHandler('text/uri-list', urlString => {
            if (!urlString.match(/^data\:image\/png/)) {
              return false;
            }

            return _element('img', _attributes(_attributeStringLiteral('class', 'lively-content'), _attributeExpression('src', urlString)), _children(), {
              file: 'https://lively-kernel.org/lively4/lively4-portal/src/client/draganddrop.js',
              end: {
                column: 65,
                line: 178
              },
              start: {
                column: 15,
                line: 178
              }
            });
          }),

          // open javascript/object in inspector
          {
            handle(evt) {
              const dt = evt.dataTransfer;
              if (!dt.types.includes("javascript/object")) {
                return false;
              }
              const tempKey = dt.getData("javascript/object");

              lively.openInspector(getObjectFor(tempKey), pt(evt.clientX, evt.clientY).subPt(lively.getGlobalPosition(document.body)));
              removeTempKey(tempKey);

              return true;
            }
          }, new DropOnBodyHandler('text/uri-list', urlString => {
            if (!urlString.match(/^plex:\//)) {
              return false;
            }
            var existing = document.body.querySelector(`plex-link[src="${urlString}"]`);
            if (existing) {
              existing.remove();
            }
            lively.notify("dropped " + urlString);
            return _element('plex-link', _attributes(_attributeExpression('src', urlString)), _children(), {
              file: 'https://lively-kernel.org/lively4/lively4-portal/src/client/draganddrop.js',
              end: {
                column: 54,
                line: 204
              },
              start: {
                column: 15,
                line: 204
              }
            });
          }),

          // #ExampleForLeo #Bibilograpy #TODO #Refactor
          new DropOnBodyHandler('text/uri-list', urlString => {
            if (!urlString.match(/^academic:\//)) {
              return false;
            }
            lively.notify("academic " + urlString);

            var infoSpan = _element('div', _attributes(_attributeStringLiteral('id', 'info')), _children(), {
              file: 'https://lively-kernel.org/lively4/lively4-portal/src/client/draganddrop.js',
              end: {
                column: 44,
                line: 212
              },
              start: {
                column: 23,
                line: 212
              }
            });
            var link = _element('div', _attributes(_attributeStringLiteral('class', 'lively-content'), _attributeStringLiteral('style', 'background-color: lightgray; border:1px solid orange')), _children(_childElement(_element('a', _attributes(_attributeExpression('href', urlString)), _children(_childText('\n            '), _childExpression(urlString), _childText('  \n        ')), {
              file: 'https://lively-kernel.org/lively4/lively4-portal/src/client/draganddrop.js',
              end: {
                column: 12,
                line: 215
              },
              start: {
                column: 108,
                line: 213
              }
            })), _childExpression(infoSpan)), {
              file: 'https://lively-kernel.org/lively4/lively4-portal/src/client/draganddrop.js',
              end: {
                column: 28,
                line: 215
              },
              start: {
                column: 19,
                line: 213
              }
            });

            (async () => {
              let info = "";
              for (var m of Strings.matchAll(/[Ii]d=([0-9]+)/, urlString)) {
                let id = m[1];
                let raw = await lively.files.loadJSON(`academic://raw:Id=${id}?attr=AuN,Ty,AA.AuN,Y,Ti,FN`);

                var entity = raw.entities[0];
                var type = MicrosoftAcademicEntities.getEntityType(entity.Ty);
                var label = "";
                if (type == "author") {
                  label = entity["AuN"];
                } else if (type == "field-of-study") {
                  label = entity["FN"];
                } else if (type == "paper") {
                  label = entity["Ti"];
                }

                info += `<span>${id}: ${type}, ${label}</span><br>`;
              }
              infoSpan.innerHTML = info;
            }

            // register the event... to be able to remove it again...
            )();lively.addEventListener("link", link, "click", evt => {
              // #TODO make this bevior persistent?
              evt.preventDefault();
              evt.stopPropagation();
              lively.openBrowser(urlString);
              return true;
            });
            return link;
          }), new DropOnBodyHandler('text/uri-list', urlString => {

            var link = _element('div', _attributes(_attributeStringLiteral('class', 'lively-content')), _children(_childElement(_element('a', _attributes(_attributeExpression('href', urlString)), _children(_childText('\n          '), _childExpression(urlString.replace(/\/$/, "").replace(/.*\//, "")), _childText('\n        ')), {
              file: 'https://lively-kernel.org/lively4/lively4-portal/src/client/draganddrop.js',
              end: {
                column: 12,
                line: 255
              },
              start: {
                column: 47,
                line: 253
              }
            }))), {
              file: 'https://lively-kernel.org/lively4/lively4-portal/src/client/draganddrop.js',
              end: {
                column: 18,
                line: 255
              },
              start: {
                column: 19,
                line: 253
              }
            });
            // register the event... to be able to remove it again...
            lively.addEventListener("link", link, "click", evt => {
              // #TODO make this bevior persistent?
              evt.preventDefault();
              evt.stopPropagation();
              lively.openBrowser(urlString);
              return true;
            });
            return link;
          }), new DropOnBodyHandler('application/lively4id', id => {
            var element = lively.elementByID(id);

            if (element && element.parentElement === document.body /* move element */) {
                return element;
              }

            lively.notify("drop id:" + id);

            return false;
          }), new DropOnBodyHandler('text/plain', async text => {
            // test for bibtex content
            if (text.match(/^\s*@[a-zA-Z]+\{/)) {
              const comp = await _element('lively-bibtex', _attributes(_attributeStringLiteral('style', 'width:700px')), _children(), {
                file: 'https://lively-kernel.org/lively4/lively4-portal/src/client/draganddrop.js',
                end: {
                  column: 83,
                  line: 283
                },
                start: {
                  column: 32,
                  line: 283
                }
              });
              comp.innerHTML = text;
              await comp.updateView();
              var entries = comp.querySelectorAll("lively-bibtex-entry");
              if (entries.length == 1) {
                entries[0].style.width = "700px";
                return entries[0];
              }
              return comp;
            }
            return false;
          }), new DropOnBodyHandler('text/html', htmlString => {
            const div = _element('div', _attributes(), _children(), {
              file: 'https://lively-kernel.org/lively4/lively4-portal/src/client/draganddrop.js',
              end: {
                column: 31,
                line: 298
              },
              start: {
                column: 20,
                line: 298
              }
            });
            div.innerHTML = htmlString;

            return div;
          }), new DropOnBodyHandler('text/plain', text => {
            return _element('p', _attributes(), _children(_childExpression(text)), {
              file: 'https://lively-kernel.org/lively4/lively4-portal/src/client/draganddrop.js',
              end: {
                column: 28,
                line: 306
              },
              start: {
                column: 15,
                line: 306
              }
            });
          }),

          // just an ui interaction, no data
          {
            handle(evt) {
              return evt.dataTransfer.types.includes("ui/interaction");
            }
          }];
        },

        openAt(node, evt) {
          var target = this.lastDropTarget || document.body;
          target.appendChild(node);
          lively.setGlobalPosition(node, pt(evt.clientX, evt.clientY));
          if (this.lastDropTargetHighlight) this.lastDropTargetHighlight.remove();
        },

        onDragOver(evt) {
          this.lastDropTarget = Array.from(evt.composedPath()).find(ea => ea && (ea.classList && ea.classList.contains("lively-content") || ea.localName == "lively-folder"));
          if (this.lastDropTargetHighlight) this.lastDropTargetHighlight.remove();
          this.lastDropTargetHighlight = lively.showElement(this.lastDropTarget);

          evt.stopPropagation();
          evt.preventDefault();
        },

        handleFiles(evt) {
          const files = evt.dataTransfer.files;

          if (files.length === 0) {
            return false;
          }

          lively.notify(`Dropped ${files.length} file(s).`);
          Array.from(files).forEach(async file => {
            const extension = lively.files.extension(file.name
            // #Research how do we deal with content vs. container... drop a picture here or a file that contains the picture? #Journal #Interesting
            );if (extension == "png" && !evt.ctrlKey) {
              // #Refactor #TODO use lively.files.readBlobAsDataURL
              const reader = new FileReader();
              reader.onload = event => {
                const dataURL = event.target.result.replace(/^data\:image\/png;/, `data:image/png;name=${file.name};`);
                const img = _element('img', _attributes(_attributeStringLiteral('class', 'lively-content'), _attributeExpression('src', dataURL)), _children(), {
                  file: 'https://lively-kernel.org/lively4/lively4-portal/src/client/draganddrop.js',
                  end: {
                    column: 74,
                    line: 352
                  },
                  start: {
                    column: 26,
                    line: 352
                  }
                });
                appendToContainerAt(img, evt);
              };
              reader.readAsDataURL(file);
            }
            // else if (extension == "html") {
            //   var source = await lively.files.readBlobAsText(file)
            //   lively.clipboard.pasteHTMLDataInto(source, document.body, false, lively.getPosition(evt));
            // } 
            else {
                var item = await _element('lively-file', _attributes(), _children(), {
                  file: 'https://lively-kernel.org/lively4/lively4-portal/src/client/draganddrop.js',
                  end: {
                    column: 55,
                    line: 362
                  },
                  start: {
                    column: 28,
                    line: 362
                  }
                });
                item.classList.add("lively-content" // for persistence
                // #TODO check for existing "file"
                );item.name = file.name;
                this.openAt(item, evt);
                item.url = await lively.files.readBlobAsDataURL(file);
              }
          });
          return true;
        },

        async onDrop(evt) {
          // var target = evt.composedPath().find(ea => ea.classList.contains("lively-content") )
          const dt = evt.dataTransfer;

          /*
          console.group("Drop Event on body");
          console.log(dt);
          console.log(`#files ${dt.files.length}`);
          console.log(Array.from(dt.items));
          lively.notify(Array.from(dt.types).join(" "));
          console.groupEnd();
          */

          evt.stopPropagation();
          evt.preventDefault();

          if (this.handleFiles(evt)) {
            return;
          }

          if (Array.from(dt.types).length > 0) {
            if (this.handlers.find(handler => handler.handle(evt))) {
              return;
            }
          }
          var cssText = evt.dataTransfer.getData("lively/cssText");
          if (this.lastDropTarget && cssText) {
            cssText.split(/; */).forEach(pair => {
              var name, value;
              [name, value] = pair.split(/: */);
              lively.notify("set " + this.lastDropTarget + "'s " + name + " to " + value);
              name = name.replace(/ /g, "");
              this.lastDropTarget.style[name] = value;
              // window.LastDT = this.lastDropTarget
              // window.LastName = name
              // window.LastCSS = value
              // target.style["background"] = "red"
            });
          } else {
            lively.warn("Dragged content contained neither files nor handled items");
          }
        }
      };

      Object.defineProperty(_recorder_._src_client_draganddrop_js, 'dropOnDocumentBehavior', {
        get() {
          return dropOnDocumentBehavior;
        },

        set(thisIsVererySecretVariableName) {
          dropOnDocumentBehavior = thisIsVererySecretVariableName;
          return true;
        },

        enumerable: true,
        configurable: true
      });
      function __unload__() {
        dropOnDocumentBehavior.removeListeners();
      }

      _export('__unload__', __unload__);

      dropOnDocumentBehavior.load();
    }
  };
});