System.register(['reactive-jsx', 'src/client/graphics.js', 'src/components/halo/lively-halo.js', 'utils', 'src/client/persistence.js'], function (_export, _context) {
  "use strict";

  var _addSourceLocation, pt, Halo, uuid, persistence;

  return {
    setters: [function (_reactiveJsx) {
      _addSourceLocation = _reactiveJsx.addSourceLocation;
    }, function (_srcClientGraphicsJs) {
      pt = _srcClientGraphicsJs.pt;
    }, function (_srcComponentsHaloLivelyHaloJs) {
      Halo = _srcComponentsHaloLivelyHaloJs.default;
    }, function (_utils) {
      uuid = _utils.uuid;
    }, function (_srcClientPersistenceJs) {
      persistence = _srcClientPersistenceJs.default;
    }],
    execute: function () {
      const __SystemJSRewritingHack = {};
      _recorder_._src_client_clipboard_js = _recorder_._src_client_clipboard_js || {};
      Object.defineProperty(_recorder_._src_client_clipboard_js, 'pt', {
        get() {
          return pt;
        },

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

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

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

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

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

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

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

        enumerable: true,
        configurable: true
      });
      class Clipboard {

        static load() {
          lively.removeEventListener("Clipboard", document);
          lively.removeEventListener("Clipboard", document.body);

          lively.addEventListener("Clipboard", document, "mousedown", evt => this.onBodyMouseDown(evt), true);
          lively.addEventListener("Clipboard", document.body, "paste", evt => this.onPaste(evt), true);
          lively.addEventListener("Clipboard", document.body, "cut", evt => this.onCut(evt));
          lively.addEventListener("Clipboard", document.body, "copy", evt => this.onCopy(evt));

          document.body.setAttribute("tabindex", 0 // just ensure focusabiltity

          );lively.clipboard = Clipboard; // #TODO make cyclic dependencies work
        }

        static onCut(evt) {
          if (!HaloService.areHalosActive() || !that) {
            return;
          }
          this.onCopy(evt);
          if (lively.selection.nodes.length > 0) {
            lively.selection.nodes.forEach(ea => {
              ea.remove();
            });
            lively.selection.remove();
          } else {
            that.remove();
          }
          Halo.hideHalos();
        }

        static nodesToHTML(nodes) {
          // prepare for serialization
          nodes.forEach(node => {
            node.querySelectorAll("*").forEach(ea => {
              if (ea.livelyPrepareSave) ea.livelyPrepareSave();
            });
          });

          return nodes.map(ea => ea.outerHTML).join("\n");
        }

        static onCopy(evt) {
          if (!HaloService.areHalosActive() || !that) {
            return;
          }
          evt.preventDefault();
          evt.stopPropagation();
          var nodes = [];
          if (lively.selection.nodes.length > 0) {
            nodes = lively.selection.nodes;
          } else if (that !== undefined) {
            nodes = [that];
          }
          var html = this.nodesToHTML(nodes);
          evt.clipboardData.setData('text/plain', html);
          evt.clipboardData.setData('text/html', html);
        }

        static initializeElements(all) {
          function makeLivelyIdNonConflicting(me, all) {
            const idAttribute = "data-lively-id";
            const id = me.getAttribute(idAttribute);
            if (!id) {
              return;
            }

            // if we have an ID, some other me might be lying around somewhere...
            const otherMe = lively.elementByID(id);
            if (!otherMe) {
              return;
            }

            // so there is an identiy crisis... so we have to become somebody new...
            const newId = uuid();
            me.setAttribute(idAttribute, newId);

            // ... and I have to notify my buddies that I am no longer myself
            const pattern = new RegExp(id, 'ig');
            all.forEach(other => {
              for (let i = 0; i < other.attributes.length; i++) {
                const attr = other.attributes[i];
                attr.value = attr.value.replace(pattern, newId);
              }
            });
          }

          all.forEach(child => makeLivelyIdNonConflicting(child, all));
          all.forEach(child => persistence.initLivelyObject(child));
        }

        static getTopLeft(elements) {
          var topLeft;
          elements.forEach(ea => {
            if (!topLeft) topLeft = lively.getGlobalPosition(ea);else topLeft = topLeft.minPt(lively.getGlobalPosition(ea));
          });
          return topLeft || pt(0, 0);
        }

        static pasteHTMLDataInto(data, container, flat, pos = this.lastClickPos) {
          // add everthing into a container 
          var div = _addSourceLocation(document.createElement("div"), {
            file: 'https://lively-kernel.org/lively4/lively4-augment/src/client/clipboard.js',
            end: {
              column: 43,
              line: 112
            },
            start: {
              column: 14,
              line: 112
            }
          });
          div.classList.add("lively-content");
          lively.setExtent(div, pt(800, 10));
          div.innerHTML = data;
          container.appendChild(div);
          lively.setPosition(div, pt(0, 0)

          // paste oriented at a shared topLeft
          );var topLevel = Array.from(div.querySelectorAll(":scope > *"));
          var all = Array.from(div.querySelectorAll("*"));

          this.initializeElements(all

          // somehow zIndex gets lost...
          );var zIndexMap = new Map();
          topLevel.forEach(ea => {
            zIndexMap.set(ea, ea.style.zIndex);
          }

          // topLevel = _.sortBy(topLevel, ea => ea.style && ea.style.zIndex).reverse()
          // topLevel.forEach(ea => ea.remove())
          // topLevel.forEach(ea => ea.style.zIndex = "")
          );topLevel.forEach(ea => div.appendChild(ea));
          var offset = (pos || pt(0, 0)).subPt(this.getTopLeft(topLevel));
          var result = div;

          // #TODO #CleanUp

          topLevel.forEach(child => {
            if (child.classList.contains("lively-content") || child.tagName == "LIVELY-WINDOW") {
              container.appendChild(child);
              lively.moveBy(child, offset);
              result = child; // return last result?
            }
          }

          // restore zIndex in an Async way... it seems focus is responsible for it #Hack
          );lively.sleep(0).then(() => {
            topLevel.forEach(ea => {
              ea.style.zIndex = zIndexMap.get(ea);
            });
          }

          // clean up if neccesary

          );if (div.childElementCount == 0) {
            div.remove // and get rid of the tmp container
            ();
          } else {
            // ajust position and content size
            lively.setGlobalPosition(div, pos || pt(0, 0));
            div.style.height = "max-content";
          }
          if (flat) {
            return topLevel;
          }
          lively.components.loadUnresolved(result, true, "pasteHTMLDataInto", true);

          return result;
        }

        static pasteTextDataInto(data, container) {
          var div = _addSourceLocation(document.createElement("div"), {
            file: 'https://lively-kernel.org/lively4/lively4-augment/src/client/clipboard.js',
            end: {
              column: 43,
              line: 175
            },
            start: {
              column: 14,
              line: 175
            }
          });
          div.innerHTML = data;
          div.classList.add("lively-content");
          container.appendChild(div);
          lively.components.loadUnresolved(div, true, "pasteHTMLDataInto", true);
          lively.setGlobalPosition(div, this.lastClickPos);
        }

        static pasteFileInto(fileItem, container) {
          var blob = fileItem.getAsFile();
          var reader = new FileReader();
          reader.onload = event => {
            var img = _addSourceLocation(document.createElement("img"), {
              file: 'https://lively-kernel.org/lively4/lively4-augment/src/client/clipboard.js',
              end: {
                column: 45,
                line: 187
              },
              start: {
                column: 16,
                line: 187
              }
            });
            img.src = event.target.result;
            img.classList.add("lively-content");
            container.appendChild(img);
            lively.setGlobalPosition(img, this.lastClickPos);
          }; // data url!
          reader.readAsDataURL(blob);
        }

        static onPaste(evt) {
          if (!this.lastClickPos) return; // we don't know where to paste it...this.lastClickPos
          // lively.notify("onPaste in " + this.lastTarget)

          if (!lively.hasGlobalFocus()) return;

          evt.stopPropagation();
          evt.preventDefault();
          lively.notify("paste");
          var data = evt.clipboardData.getData('text/html');
          if (data) {
            this.pasteHTMLDataInto(data, this.lastTarget);
            return;
          }

          data = evt.clipboardData.getData('text/plain');
          if (data) {
            this.pasteTextDataInto(data, this.lastTarget);
            return;
          }

          var items = (event.clipboardData || evt.clipboardData).items;
          if (items.length > 0) {
            for (var index in items) {
              var item = items[index];
              if (item.kind === 'file') {
                this.pasteFileInto(item, this.lastTarget);
              }
            }
            evt.stopPropagation();
            evt.preventDefault();
            return;
          }
        }

        static highlight(element) {
          if (this._highlight) this._highlight.remove();
          this._highlight = lively.showElement(element);
          this._highlight.innerHTML = "" + element.id;
          this._highlight.style.border = "1px solid blue";
        }

        static onBodyMouseDown(evt) {
          var target = evt.composedPath()[0];
          if (target == document.body.parentElement) target = document.body;

          if (target && target.classList) {
            if (target.classList.contains("lively-no-paste")) {
              target = evt.composedPath().find(ea => ea.tagName == "LIVELY-CONTAINER");
            } else {
              var container = evt.composedPath().find(ea => ea.tagName == "LIVELY-CONTAINER");
              if (container && !container.isEditing()) {
                target = container;
                var activeElement = container.shadowRoot.activeElement;
                if (activeElement && (activeElement.tagName == "INPUT" || activeElement.contentEditable)) {
                  // the element itself will handle the paste
                  this.lastTarget = null;
                  this.lastClickPos = null;
                  return;
                }
              } else {
                // this.lastTarget = container
                // } else {
                if (evt.composedPath().find(ea => ea.constructor.name == "ShadowRoot")) {
                  // #TODO is there a better test for the shadow root?
                  // lively.notify("shadow")
                  this.lastTarget = null;
                  this.lastClickPos = null;
                  return; // we are in the shadows
                }
              }
            }
            // this.highlight(target)
            lively.globalFocus();
            this.lastTarget = target;
            if (this.lastTarget.livelyTarget) {
              this.lastTarget = this.lastTarget.livelyTarget
              // lively.showElement(this.lastTarget)
              ();
            }
            this.lastClickPos = pt(evt.clientX, evt.clientY);
          }
        }
      }

      _export('default', Clipboard);

      Object.defineProperty(_recorder_._src_client_clipboard_js, 'Clipboard', {
        get() {
          return Clipboard;
        },

        set(thisIsVererySecretVariableName) {
          _export('default', Clipboard = thisIsVererySecretVariableName);

          return true;
        },

        enumerable: true,
        configurable: true
      });
      Clipboard.load();
    }
  };
});