System.register(['reactive-jsx', './preferences.js', 'src/external/focalStorage.js', 'utils', 'src/client/script-manager.js', 'src/components/halo/Connection.js'], function (_export, _context) {
  "use strict";

  var _addSourceLocation, preferences, focalStorage, debounce, scriptManager, Connection;

  return {
    setters: [function (_reactiveJsx) {
      _addSourceLocation = _reactiveJsx.addSourceLocation;
    }, function (_preferencesJs) {
      preferences = _preferencesJs.default;
    }, function (_srcExternalFocalStorageJs) {
      focalStorage = _srcExternalFocalStorageJs.default;
    }, function (_utils) {
      debounce = _utils.debounce;
    }, function (_srcClientScriptManagerJs) {
      scriptManager = _srcClientScriptManagerJs.default;
    }, function (_srcComponentsHaloConnectionJs) {
      Connection = _srcComponentsHaloConnectionJs.default;
    }],
    execute: function () {
      const __SystemJSRewritingHack = {};
      _recorder_._src_client_persistence_js = _recorder_._src_client_persistence_js || {};
      Object.defineProperty(_recorder_._src_client_persistence_js, 'isCurrentlyCloning', {
        get() {
          return isCurrentlyCloning;
        },

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

          return true;
        },

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

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

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

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

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

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

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

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

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

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

        enumerable: true,
        configurable: true
      });
      function isCurrentlyCloning() {
        return sessionStorage["lively.persistenceCurrentlyCloning"] === 'true';
      }

      _export('isCurrentlyCloning', isCurrentlyCloning);

      class Persistence {

        constructor() {
          var _context2;

          this.saveDelay = (_context2 = () => {
            this.saveLivelyContent();
            this.showMutationIndicator().style.backgroundColor = "rgba(10,10,10,0.3)";
          }, debounce).call(_context2, 3000 // save the world 3seconds after a change
          );
        }

        // work around non stavle module global state
        static get current() {
          if (!window.lively4persistence) {
            window.lively4persistence = new Persistence();
          }
          return window.lively4persistence;
        }
        static set current(obj) {
          window.lively4persistence = obj;
        }

        static enable() {
          this.disable();
          this.current = new Persistence();
          this.current.start();
        }

        static disable() {
          if (this.current) {
            this.current.stop();
          }
        }

        start() {
          this.observeHTMLChanges();
        }

        stop() {
          if (this.mutationObserver) this.mutationObserver.disconnect();
        }

        urlToKey(urlString) {
          urlString = "" + urlString;
          return "livelyWindows_" + urlString.replace(/^https?:\/\//, "").replace(/[^A-Za-z0-9]/, "_");
        }

        defaultTarget() {
          return document.body;
        }

        defaultURL() {
          return document.location.protocol + "//" + document.location.hostname + document.location.pathname;
        }

        getLivelyContentForURL(url) {
          url = url || this.defaultURL();
          return focalStorage.getItem(this.urlToKey(url.toString()));
        }

        setLivelyContentForURL(url, source) {
          url = url || this.defaultURL();
          return focalStorage.setItem(this.urlToKey(url.toString()), source);
        }

        async loadLivelyContentForURL(url, target) {
          var source = await this.getLivelyContentForURL(url);
          target = target || this.defaultTarget();
          var div = _addSourceLocation(document.createElement("div"), {
            file: 'https://lively-kernel.org/lively4/lively4-RP19-4/src/client/persistence.js',
            end: {
              column: 43,
              line: 79
            },
            start: {
              column: 14,
              line: 79
            }
          });
          div.innerHTML = source;
          var topLevel = Array.from(div.querySelectorAll(":scope > *"));
          var objs = Array.from(div.childNodes

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

          objs.map(ea => {
            if (ea.classList && ea.classList.contains('lively-preferences')) {
              target.querySelectorAll('div.lively-preferences').forEach(ele => ele.remove());
            }
            target.appendChild(ea);
          });
          await lively.components.loadUnresolved(target, true, "loadLivelyContentForURL", true

          // 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);
            });
          });

          objs.map(ea => {
            Persistence.initLivelyObject(ea);
          });
          return;
        }

        static initLivelyObject(obj) {
          if (!obj) return;
          try {
            scriptManager.findLively4Script(obj, false);
            if (obj.livelyLoad) obj.livelyLoad();
            Connection.deserializeFromObjectIfNeeded(obj);
            if (!obj.querySelectorAll) return;
            obj.querySelectorAll("*").forEach(ea => {
              if (ea.livelyLoad) ea.livelyLoad();
              Connection.deserializeFromObjectIfNeeded(ea);
            });
          } catch (e) {
            lively.showError(e);
          }
        }

        async storeLivelyContentForURL(url, target) {
          target = target || this.defaultTarget();
          this.isPersisting = true;
          var source = lively.html.getGlobalSource(target);
          this.setLivelyContentForURL(url, source);
          setTimeout(() => {
            this.isPersisting = false;
          }, 0 // the mutation events triggered are still pending here...
          );return source;
        }

        async saveLivelyContent() {
          // console.log("[peristence] save after " + 
          //   (Date.now() - this.lastSaved) +"ms")
          this.lastSaved = Date.now();
          await this.storeLivelyContentForURL
          // console.log("[peristence] saved lively content into focalStorage " + 
          //   (Date.now() - this.lastSaved) +"ms")
          ();
        }

        hasDoNotPersistTag(node) {
          var donotperist = node.attributes && node.attributes.hasOwnProperty('data-lively4-donotpersist');
          if (donotperist) return true;
          if (!node.parentElement) return false;
          return this.hasDoNotPersistTag(node.parentElement);
        }

        isBlacklisted(mutation) {
          if (mutation.target.tagName == "BODY") return true;
          if (mutation.target.tagName == "LIVELY-MENU") return true;
          if (mutation.target.tagName == "LIVELY-SELECTION") return true;
          if (mutation.target.tagName == "LIVELY-HAND") return true;
          if (mutation.target.tagName == "LIVELY-HALO") return true;
          if (mutation.target.tagName == "LIVELY-NOTIFICATION-LIST") return true;
          if (mutation.target.id == "mutationIndicator") return true;
          if (mutation.target.getAttribute && mutation.target.getAttribute("data-is-meta")) return true;
          if (this.hasDoNotPersistTag(mutation.target)) return true;
          return false;
        }

        showMutationIndicator() {
          var indicator = document.body.querySelector("#mutationIndicator");
          if (!indicator) {
            var div = _addSourceLocation(document.createElement("div"), {
              file: 'https://lively-kernel.org/lively4/lively4-RP19-4/src/client/persistence.js',
              end: {
                column: 45,
                line: 170
              },
              start: {
                column: 16,
                line: 170
              }
            });
            div.id = "mutationIndicator";
            document.body.appendChild(div);
            div.style.position = "fixed";
            div.style.right = "0px";
            div.style.top = "0px";
            div.style.width = "10px";
            div.style.height = "10px";
            div.style.backgroundColor = "blue";
            div.style.pointerEvents = "none";
            div.style.zIndex = 2000;

            indicator = div;
          }
          return indicator;
        }

        onMutation(mutations, observer) {
          if (this.isPersisting) {
            // console.log("ignore mutation ", mutations)
            return; // we mutate while persisting 
          }

          mutations.filter(ea => !this.isBlacklisted(ea)).forEach(record => {
            this.showMutationIndicator().style.backgroundColor = "rgba(200,0,0,0.5)";
            this.saveDelay();
          });
        }

        observeHTMLChanges(target) {
          target = target || this.defaultTarget();
          if (this.mutationObserver) this.mutationObserver.disconnect();
          this.mutationObserver = new MutationObserver((mutations, observer) => {
            this.onMutation(mutations, observer);
          });
          this.mutationObserver.observe(target, {
            childList: true,
            subtree: true,
            characterData: true,
            attributes: true });
        }

      }

      _export('default', Persistence);

      Object.defineProperty(_recorder_._src_client_persistence_js, 'Persistence', {
        get() {
          return Persistence;
        },

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

          return true;
        },

        enumerable: true,
        configurable: true
      });
    }
  };
});