"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
function _assert() {
  const data = _interopRequireDefault(require("assert"));
  _assert = function () {
    return data;
  };
  return data;
}
function _plugin() {
  const data = require("@parcel/plugin");
  _plugin = function () {
    return data;
  };
  return data;
}
function _posthtml() {
  const data = _interopRequireDefault(require("posthtml"));
  _posthtml = function () {
    return data;
  };
  return data;
}
function _utils() {
  const data = require("@parcel/utils");
  _utils = function () {
    return data;
  };
  return data;
}
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var _default = exports.default = new (_plugin().Packager)({
  async package({
    bundle,
    bundleGraph,
    getInlineBundleContents
  }) {
    const assets = [];
    bundle.traverseAssets(asset => {
      assets.push(asset);
    });
    _assert().default.strictEqual(assets.length, 1, 'SVG bundles must only contain one asset');

    // Add bundles in the same bundle group that are not inline. For example, if two inline
    // bundles refer to the same library that is extracted into a shared bundle.
    let referencedBundles = [...(0, _utils().setDifference)(new Set(bundleGraph.getReferencedBundles(bundle)), new Set(bundleGraph.getReferencedBundles(bundle, {
      recursive: false
    })))];
    const asset = assets[0];
    const code = await asset.getCode();
    let {
      html: svg
    } = await (0, _posthtml().default)([tree => insertBundleReferences(referencedBundles, tree), tree => replaceInlineAssetContent(bundleGraph, getInlineBundleContents, tree)]).process(code, {
      directives: [{
        name: /^\?/,
        start: '<',
        end: '>'
      }],
      xmlMode: true
    });
    const {
      contents,
      map
    } = (0, _utils().replaceURLReferences)({
      bundle,
      bundleGraph,
      contents: svg,
      relative: false,
      getReplacement: contents => contents.replace(/"/g, '&quot;')
    });
    return (0, _utils().replaceInlineReferences)({
      bundle,
      bundleGraph,
      contents,
      getInlineBundleContents,
      getInlineReplacement: (dep, inlineType, contents) => ({
        from: dep.id,
        to: contents.replace(/"/g, '&quot;').trim()
      }),
      map
    });
  }
});
async function replaceInlineAssetContent(bundleGraph, getInlineBundleContents, tree) {
  const inlineNodes = [];
  tree.walk(node => {
    if (node.attrs && node.attrs['data-parcel-key']) {
      inlineNodes.push(node);
    }
    return node;
  });
  for (const node of inlineNodes) {
    const newContent = await getAssetContent(bundleGraph, getInlineBundleContents, node.attrs['data-parcel-key']);
    if (newContent === null) {
      continue;
    }
    node.content = await (0, _utils().blobToString)(newContent.contents);

    // Wrap scripts and styles with CDATA if needed to ensure characters are not interpreted as XML
    if (node.tag === 'script' || node.tag === 'style') {
      if (node.content.includes('<') || node.content.includes('&')) {
        node.content = node.content.replace(/]]>/g, ']\\]>');
        node.content = `<![CDATA[\n${node.content}\n]]>`;
      }
    }

    // remove attr from output
    delete node.attrs['data-parcel-key'];
  }
  return tree;
}
async function getAssetContent(bundleGraph, getInlineBundleContents, assetId) {
  let inlineBundle;
  bundleGraph.traverseBundles((bundle, context, {
    stop
  }) => {
    const entryAssets = bundle.getEntryAssets();
    if (entryAssets.some(a => a.uniqueKey === assetId)) {
      inlineBundle = bundle;
      stop();
    }
  });
  if (!inlineBundle) {
    return null;
  }
  const bundleResult = await getInlineBundleContents(inlineBundle, bundleGraph);
  return {
    bundle: inlineBundle,
    contents: bundleResult.contents
  };
}
function insertBundleReferences(siblingBundles, tree) {
  let scripts = [];
  let stylesheets = [];
  for (let bundle of siblingBundles) {
    if (bundle.type === 'css') {
      stylesheets.push(`<?xml-stylesheet href=${JSON.stringify((0, _utils().urlJoin)(bundle.target.publicUrl, bundle.name))}?>`);
    } else if (bundle.type === 'js') {
      scripts.push({
        tag: 'script',
        attrs: {
          href: (0, _utils().urlJoin)(bundle.target.publicUrl, bundle.name)
        }
      });
    }
  }
  tree.unshift(...stylesheets);
  if (scripts.length > 0) {
    tree.match({
      tag: 'svg'
    }, node => {
      node.content.unshift(...scripts);
    });
  }
}