System.register(["reactive-jsx", "src/client/markdown.js", "src/components/widgets/lively-morph.js", "src/client/morphic/component-loader.js", "src/external/markdown-it.js", "src/external/markdown-it-hashtag.js", "src/external/markdown-it-tasks.js", "src/external/markdown-it-attrs.js", "src/external/markdown-it-sourcemap.js", "src/external/highlight.js", "src/client/persistence.js", "src/client/strings.js", "src/external/upndown.js", "src/client/graphics.js", "src/client/fileindex.js"], function (_export, _context) {
  "use strict";

  var _attributeStringLiteral, _children, _attributes, _element, _addSourceLocation, Markdown, Morph, components, MarkdownIt, MarkdownItHashtag, MarkdownItTasks, MarkdownItAttrs, MarkdownItSourcemap, persistence, Strings, Upndown, pt, FileIndex;

  return {
    setters: [function (_reactiveJsx) {
      _attributeStringLiteral = _reactiveJsx.attributeStringLiteral;
      _children = _reactiveJsx.children;
      _attributes = _reactiveJsx.attributes;
      _element = _reactiveJsx.element;
      _addSourceLocation = _reactiveJsx.addSourceLocation;
    }, function (_srcClientMarkdownJs) {
      Markdown = _srcClientMarkdownJs.default;
    }, function (_srcComponentsWidgetsLivelyMorphJs) {
      Morph = _srcComponentsWidgetsLivelyMorphJs.default;
    }, function (_srcClientMorphicComponentLoaderJs) {
      components = _srcClientMorphicComponentLoaderJs.default;
    }, function (_srcExternalMarkdownItJs) {
      MarkdownIt = _srcExternalMarkdownItJs.default;
    }, function (_srcExternalMarkdownItHashtagJs) {
      MarkdownItHashtag = _srcExternalMarkdownItHashtagJs.default;
    }, function (_srcExternalMarkdownItTasksJs) {
      MarkdownItTasks = _srcExternalMarkdownItTasksJs.default;
    }, function (_srcExternalMarkdownItAttrsJs) {
      MarkdownItAttrs = _srcExternalMarkdownItAttrsJs.default;
    }, function (_srcExternalMarkdownItSourcemapJs) {
      MarkdownItSourcemap = _srcExternalMarkdownItSourcemapJs.default;
    }, function (_srcExternalHighlightJs) {}, function (_srcClientPersistenceJs) {
      persistence = _srcClientPersistenceJs.default;
    }, function (_srcClientStringsJs) {
      Strings = _srcClientStringsJs.default;
    }, function (_srcExternalUpndownJs) {
      Upndown = _srcExternalUpndownJs.default;
    }, function (_srcClientGraphicsJs) {
      pt = _srcClientGraphicsJs.pt;
    }, function (_srcClientFileindexJs) {
      FileIndex = _srcClientFileindexJs.default;
    }],
    execute: function () {
      const __SystemJSRewritingHack = {};
      _recorder_._src_components_widgets_lively_markdown_js = _recorder_._src_components_widgets_lively_markdown_js || {};
      Object.defineProperty(_recorder_._src_components_widgets_lively_markdown_js, "Markdown", {
        get() {
          return Markdown;
        },

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

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._src_components_widgets_lively_markdown_js, "Morph", {
        get() {
          return Morph;
        },

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

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._src_components_widgets_lively_markdown_js, "components", {
        get() {
          return components;
        },

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

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._src_components_widgets_lively_markdown_js, "MarkdownIt", {
        get() {
          return MarkdownIt;
        },

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

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._src_components_widgets_lively_markdown_js, "MarkdownItHashtag", {
        get() {
          return MarkdownItHashtag;
        },

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

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._src_components_widgets_lively_markdown_js, "MarkdownItTasks", {
        get() {
          return MarkdownItTasks;
        },

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

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._src_components_widgets_lively_markdown_js, "MarkdownItAttrs", {
        get() {
          return MarkdownItAttrs;
        },

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

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._src_components_widgets_lively_markdown_js, "MarkdownItSourcemap", {
        get() {
          return MarkdownItSourcemap;
        },

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

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

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

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

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

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._src_components_widgets_lively_markdown_js, "Upndown", {
        get() {
          return Upndown;
        },

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

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

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

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._src_components_widgets_lively_markdown_js, "FileIndex", {
        get() {
          return FileIndex;
        },

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

        enumerable: true,
        configurable: true
      });
      class LivelyMarkdown extends Morph {
        async initialize() {
          this.windowTitle = "LivelyMarkdown";
          this.registerButtons();

          this.updateView().then(() => {
            if (this.getAttribute("mode") == "presentation") {
              this.startPresentation();
            }
          });
          this._attrObserver = new MutationObserver(mutations => {
            mutations.forEach(mutation => {
              if (mutation.type == "attributes") {
                // console.log("observation", mutation.attributeName,mutation.target.getAttribute(mutation.attributeName));
                this.attributeChangedCallback(mutation.attributeName, mutation.oldValue, mutation.target.getAttribute(mutation.attributeName));
              }
            });
          });
          this._attrObserver.observe(this, { attributes: true });
        }
        attributeChangedCallback(attr, oldVal, newVal) {
          var method = "on" + Strings.toUpperCaseFirst(attr) + "Changed";
          if (this[method]) this[method](newVal, oldVal);
        }

        onContenteditableChanged(value, oldVal) {
          this.get("#content").setAttribute("contenteditable", value);
        }

        async renderMarkdown(root, content) {
          var md = new MarkdownIt({
            html: true, // Enable HTML tags in source
            xhtmlOut: false, // Use '/' to close single tags (<br />).
            // This is only for full CommonMark compatibility.
            breaks: false, // Convert '\n' in paragraphs into <br>
            langPrefix: 'language-', // CSS language prefix for fenced blocks. Can be
            // useful for external highlighters.
            linkify: false, // Autoconvert URL-like text to links

            // Enable some language-neutral replacement + quotes beautification
            typographer: false,

            // Highlighter function. Should return escaped HTML,
            // or '' if the source string is not changed and should be escaped externaly.
            // If result starts with <pre... internal wrapper is skipped.
            highlight: function (str, lang) {
              if (lang && hljs.getLanguage(lang)) {
                try {
                  hljs.configure({ tabReplace: '  ' });
                  return hljs.highlight(lang, str, true).value;
                } catch (__) {}
              }

              return '<pre class="hljs"><code>' + md.utils.escapeHtml(str) + '</code></pre>';
            }
          });
          md.use(MarkdownItHashtag);
          md.use(MarkdownItTasks);
          md.use(MarkdownItAttrs);
          md.use(MarkdownItSourcemap

          // md.use(MarkdownItContainer)

          );md.renderer.rules.hashtag_open = function (tokens, idx) {
            var tagName = tokens[idx].content;
            if (tagName.match(/^[A-Za-z][A-Za-z0-9]+/))
              // return `<a href="javascript:lively.openSearchWidget('#${tagName}')" class="tag">`;
              return `<a href="search://#${tagName}" class="tag">`;else return `<a href="javascript:lively.openIssue('${tagName}')" class="issue">`;
          };
          if (!content) return;
          if (content.match(/markdown-config .*presentation=true/)) {
            var configPresentation = true;
          }

          content = content.replace(/<lively-script><script>/g, "<script>").replace(/<\/script><\/lively-script>/g, "</script>").replace(/<lively-script>/g, "<script>").replace(/<\/lively-script>/g, "</script>"

          // var enhancedMarkdown = lively.html.enhanceMarkdown(content);
          // var htmlSource = md.render(enhancedMarkdown);
          );var htmlSource = md.render(content);
          // replace only scripts, that are actual scripts
          htmlSource = htmlSource.replace(/<script(.*?)>((:?\n|.)*?)<\/script>/gm, (original, args, content) => args.match(`type=`) ? original : `<lively-script${args}><script>${content}</script></lively-script>`);

          var tmpDiv = _addSourceLocation(document.createElement("div"), {
            file: 'https://lively-kernel.org/lively4/lively4-augment/src/components/widgets/lively-markdown.js',
            end: {
              column: 46,
              line: 127
            },
            start: {
              column: 17,
              line: 127
            }
          });
          tmpDiv.innerHTML = htmlSource; // so we still have some control over it

          await this.replaceImageTagsWithSpecificTags(tmpDiv);

          var dir = this.getDir();
          if (dir) {
            lively.html.fixLinks([tmpDiv], this.getDir(), path => this.followPath(path));
          }

          this.beatifyInplaceHashtagNavigation(tmpDiv);

          root.innerHTML = "";
          tmpDiv.childNodes.forEach(ea => {
            root.appendChild(ea);
          });

          root.querySelectorAll("input[type=checkbox]").forEach(ea => {
            ea.disabled = false;
            ea.addEventListener("click", evt => {
              if (ea.checked) {
                ea.setAttribute("checked", "true");
              } else {
                ea.removeAttribute("checked");
              }
            });
          });

          if (configPresentation) this.startPresentation

          // #TODO: fixme
          //root.querySelectorAll("pre code").forEach( block => {
          //  highlight.highlightBlock(block);
          //});

          ();var container = lively.query(this, "lively-container");
          root.hidden = true;
          await lively.fillTemplateStyles(root, "", container && container.getDir());
          root.hidden = false;

          // custom lively modifications... second round of parsing content in the DOM
          Markdown.parseAndReplaceLatex(root);

          await components.loadUnresolved(root, true, "lively-markdown.js", true);
          await persistence.initLivelyObject(root);
        }

        async updateView() {
          return this.renderMarkdown(this.get("#content"), (await this.getContent()));
        }

        async replaceImageTagsWithSpecificTags(tmpDiv) {

          for (let imgTag of tmpDiv.querySelectorAll("img")) {
            var noFileEnding = !imgTag.src.match(/\.[A-Za-z0-9]+$/);
            if (noFileEnding || imgTag.src.match(/\.drawio$/)) {
              // we have to guess or look what img could have been meant
              // (a) lets see if is a drawio figuure
              // #TODO check if there is actually an pdf
              var figure = await _element("lively-drawio", _attributes(), _children(), {
                file: 'https://lively-kernel.org/lively4/lively4-augment/src/components/widgets/lively-markdown.js',
                end: {
                  column: 59,
                  line: 189
                },
                start: {
                  column: 28,
                  line: 189
                }
              });

              for (let attr of imgTag.attributes) {
                if (attr.name == "src") {
                  // use attributes to retain RAW data
                  let src = imgTag.getAttribute("src") + (noFileEnding ? ".drawio" : "");
                  // console.log("REPLACE DRAWIO: " + src)
                  figure.setAttribute("src", src);
                } else {
                  figure.setAttribute(attr.name, attr.value);
                }
              }
              figure.update();
              imgTag.parentElement.insertBefore(figure, imgTag);
              imgTag.remove();
            } else if (noFileEnding || imgTag.src.match(/\.html$/)) {
              // console.log("[lively-markdown] create lively-import")
              var importElement = await _element("lively-import", _attributes(), _children(), {
                file: 'https://lively-kernel.org/lively4/lively4-augment/src/components/widgets/lively-markdown.js',
                end: {
                  column: 66,
                  line: 206
                },
                start: {
                  column: 35,
                  line: 206
                }
              });
              for (let attr of imgTag.attributes) {
                if (attr.name == "src") {
                  let src = imgTag.getAttribute("src");
                  importElement.setAttribute("src", src);
                } else {
                  importElement.setAttribute(attr.name, attr.value);
                }
              }
              imgTag.parentElement.insertBefore(importElement, imgTag);
              imgTag.remove();
            }
          }
        }

        beatifyInplaceHashtagNavigation(tmpDiv) {
          /* Beatify Inplace Hashtag Navigation #TODO #Refactor #MoveToBetterPlace */
          tmpDiv.querySelectorAll("a.tag").forEach(eaLink => {
            // #Example for absolute CSS positioning #Hack: 
            // (1) the relative "span" itself is positioned through the dynamic layout without taking space itself
            // (2) the absolute "div" element than has total freedom to posiiton itself relative to (1)
            var searchContainerAnchor = _element("span", _attributes(_attributeStringLiteral("style", "position:relative; width: 0; height: 0")), _children(), {
              file: 'https://lively-kernel.org/lively4/lively4-augment/src/components/widgets/lively-markdown.js',
              end: {
                column: 95,
                line: 228
              },
              start: {
                column: 35,
                line: 228
              }
            });
            var searchContainer = _element("div", _attributes(_attributeStringLiteral("style", "width:500px; height:200px; overflow: auto; background-color:lightgray; z-index:1000")), _children(), {
              file: 'https://lively-kernel.org/lively4/lively4-augment/src/components/widgets/lively-markdown.js',
              end: {
                column: 131,
                line: 229
              },
              start: {
                column: 28,
                line: 229
              }
            });
            lively.setPosition(searchContainer, pt(0, 0) // make absolute...
            );searchContainerAnchor.appendChild(searchContainer);

            var shadow = searchContainer.attachShadow({ mode: 'open' });
            var lastEntered;
            var lastLeft;
            eaLink.addEventListener("mouseenter", async () => {
              lastEntered = Date.now();

              var root = lively4url;
              var result = "";
              var searchString = eaLink.href.replace("search://", "");
              await Promise.all([FileIndex.current().db.files.each(file => {
                if (file.url.startsWith(root) && file.content) {
                  var m = file.content.match(searchString);
                  if (m) {
                    result += `<li><a href="${file.url}#${searchString.replace(/#/g, "")}">${file.url.replace(lively4url, "")}</a></li>`;
                  }
                }
              }), lively.sleep(100)]);

              if (lastLeft > lastEntered) return;

              // document.body.appendChild(searchContainer)
              eaLink.appendChild(searchContainerAnchor

              // lively.setGlobalPosition(searchContainer, lively.getGlobalPosition(eaLink).addPt(pt(0,15)))

              // lively.setPosition(searchContainer, pt(0,0), "relative")
              );searchContainer.style.overflow = "visible";

              // #Continue here!!! getPosition does not work on non absolute objects...
              // lively.setPosition(searchContainer, lively.getBounds(eaLink).topLeft().addPt(pt(0,15)))
              searchContainer.innerHTML = "search";
              // searchContainer.isMetaNode = true
              searchContainer.id = "lively-search-container";
              shadow.innerHTML = "";

              // ok, lets try some eye candy
              searchContainer.style.opacity = 0;
              searchContainer.style.transition = "opacity 0.5s ease-in-out";
              searchContainer.style.opacity = 0.8;

              shadow.innerHTML = `<ol style="font-size:12pt">${result}<ol>`;
              lively.html.fixLinks(shadow.childNodes, this.getDir(), path => this.followPath(path));
            });

            eaLink.addEventListener("mouseleave", async () => {
              lastLeft = Date.now();
              await lively.sleep(500);
              if (lastEntered > lastLeft) return; // we came back

              searchContainer.style.transition = "opacity 0.5s ease-in-out";
              searchContainer.style.opacity = 0;

              await lively.sleep(1000);
              searchContainerAnchor.remove();
            });
          });
        }

        followPath(path) {
          lively.notify("follow " + path);
          window.open(path);
        }

        async setContent(content) {
          this.textContent = content;
          return this.updateView();
        }

        async getContent() {
          var src = this.getAttribute("src");
          if (src) {
            return fetch(src).then(r => r.text());
          }
          return this.textContent;
        }

        setDir(dir) {
          this.setAttribute("dir", dir);
        }

        getDir() {
          return this.getAttribute("dir");
        }

        async setSrc(src) {
          this.setAttribute("src", src);
          return this.updateView();
        }

        async htmlAsMarkdownSource() {
          var htmlSource = this.get("#content").innerHTML;
          var markdownConverter = new Upndown();
          markdownConverter.tabindent = "  ";
          markdownConverter.bullet = "- ";

          var source = await markdownConverter.convert(htmlSource, {
            keepHtml: true
          });
          return source;
        }

        getSrc() {
          return this.getAttribute("src");
        }

        onPresentationButton() {
          lively.notify("presentation: " + this.getAttribute("mode"));
          if (this.getAttribute("mode") == "presentation") {
            this.stopPresentation();
          } else {
            this.startPresentation();
          }
        }

        async startPresentation() {
          this.setAttribute("mode", "presentation");
          if (this.parentElement && this.parentElement.tagName == "LIVELY-CONTAINER") {
            this.parentElement.setAttribute("mode", "presentation");
          }
          if (this.get("lively-presentation")) {
            return this.get("lively-presentation");
          }

          var comp = _addSourceLocation(document.createElement("lively-presentation"), {
            file: 'https://lively-kernel.org/lively4/lively4-augment/src/components/widgets/lively-markdown.js',
            end: {
              column: 60,
              line: 357
            },
            start: {
              column: 15,
              line: 357
            }
          });
          await lively.components.openIn(this.get("#content"), comp);
          comp.convertSiblings();
          comp.start();

          // if (this.get("#presentationButton"))
          //   this.get("#presentationButton").remove()

          return comp;
        }

        async stopPresentation() {
          this.setAttribute("mode", "");
          if (this.parentElement.tagName == "LIVELY-CONTAINER") {
            this.parentElement.setAttribute("mode", "");
          }
          this.updateView();
        }

        livelyExample() {
          this.setDir(lively4url + "/docs/");
          return this.setContent(`
# a script

<script>
lively.notify("scripts still run")
</script>

\`\`\`javascript {.foo}
function foo() {
  var a = "hello"
  return a + a
}
\`\`\`

## Foo {.blub style="background-color:yellow"}

This is a #Hashtag and

It goes on an on!

![](https://lively-kernel.org/lively4/lively4-jens/demos/sample.drawio)

`);
        }

        async livelyExample3() {
          await this.setSrc(lively4url + "/README.md");
        }

        livelyExample2() {
          this.setDir(lively4url + "/docs/");
          return this.setContent(`
# Hello World

- list item 1 [a link]("markdown.md")
- list item 2


`);
        }

      }

      _export("default", LivelyMarkdown);

      Object.defineProperty(_recorder_._src_components_widgets_lively_markdown_js, "LivelyMarkdown", {
        get() {
          return LivelyMarkdown;
        },

        set(thisIsVererySecretVariableName) {
          _export("default", LivelyMarkdown = thisIsVererySecretVariableName);

          return true;
        },

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