Index: frontend/node_modules/resolve-url-loader/index.js
===================================================================
--- frontend/node_modules/resolve-url-loader/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/resolve-url-loader/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,305 @@
+/*
+ * MIT License http://opensource.org/licenses/MIT
+ * Author: Ben Holloway @bholloway
+ */
+'use strict';
+
+var os                = require('os'),
+    path              = require('path'),
+    fs                = require('fs'),
+    util              = require('util'),
+    loaderUtils       = require('loader-utils'),
+    SourceMapConsumer = require('source-map').SourceMapConsumer;
+
+var adjustSourceMap = require('adjust-sourcemap-loader/lib/process');
+
+var valueProcessor   = require('./lib/value-processor'),
+    joinFn           = require('./lib/join-function'),
+    logToTestHarness = require('./lib/log-to-test-harness');
+
+const DEPRECATED_OPTIONS = {
+  engine: [
+    'DEP_RESOLVE_URL_LOADER_OPTION_ENGINE',
+    'the "engine" option is deprecated, "postcss" engine is the default, using "rework" engine is not advised'
+  ],
+  keepQuery: [
+    'DEP_RESOLVE_URL_LOADER_OPTION_KEEP_QUERY',
+    '"keepQuery" option has been removed, the query and/or hash are now always retained'
+  ],
+  absolute: [
+    'DEP_RESOLVE_URL_LOADER_OPTION_ABSOLUTE',
+    '"absolute" option has been removed, consider the "join" option if absolute paths must be processed'
+  ],
+  attempts: [
+    'DEP_RESOLVE_URL_LOADER_OPTION_ATTEMPTS',
+    '"attempts" option has been removed, consider the "join" option if search is needed'
+  ],
+  includeRoot: [
+    'DEP_RESOLVE_URL_LOADER_OPTION_INCLUDE_ROOT',
+    '"includeRoot" option has been removed, consider the "join" option if search is needed'
+  ],
+  fail: [
+    'DEP_RESOLVE_URL_LOADER_OPTION_FAIL',
+    '"fail" option has been removed'
+  ]
+};
+
+/**
+ * A webpack loader that resolves absolute url() paths relative to their original source file.
+ * Requires source-maps to do any meaningful work.
+ * @param {string} content Css content
+ * @param {object} sourceMap The source-map
+ * @returns {string|String}
+ */
+function resolveUrlLoader(content, sourceMap) {
+  /* jshint validthis:true */
+
+  // details of the file being processed
+  var loader = this;
+
+  // a relative loader.context is a problem
+  if (/^\./.test(loader.context)) {
+    return handleAsError(
+      'webpack misconfiguration',
+      'loader.context is relative, expected absolute'
+    );
+  }
+
+  // infer webpack version from new loader features
+  var isWebpackGte5 = 'getOptions' in loader && typeof loader.getOptions === 'function';
+
+  // webpack 1: prefer loader query, else options object
+  // webpack 2: prefer loader options
+  // webpack 3: deprecate loader.options object
+  // webpack 4: loader.options no longer defined
+  var rawOptions = loaderUtils.getOptions(loader),
+      options    = Object.assign(
+        {
+          sourceMap: loader.sourceMap,
+          engine   : 'postcss',
+          silent   : false,
+          removeCR : os.EOL.includes('\r'),
+          root     : false,
+          debug    : false,
+          join     : joinFn.defaultJoin
+        },
+        rawOptions
+      );
+
+  // maybe log options for the test harness
+  if (process.env.RESOLVE_URL_LOADER_TEST_HARNESS) {
+    logToTestHarness(
+      process[process.env.RESOLVE_URL_LOADER_TEST_HARNESS],
+      options
+    );
+  }
+
+  // deprecated options
+  var deprecatedItems = Object.entries(DEPRECATED_OPTIONS).filter(([key]) => key in rawOptions);
+  if (deprecatedItems.length) {
+    deprecatedItems.forEach(([, value]) => handleAsDeprecated(...value));
+  }
+
+  // validate join option
+  if (typeof options.join !== 'function') {
+    return handleAsError(
+      'loader misconfiguration',
+      '"join" option must be a Function'
+    );
+  } else if (options.join.length !== 2) {
+    return handleAsError(
+      'loader misconfiguration',
+      '"join" Function must take exactly 2 arguments (options, loader)'
+    );
+  }
+
+  // validate the result of calling the join option
+  var joinProper = options.join(options, loader);
+  if (typeof joinProper !== 'function') {
+    return handleAsError(
+      'loader misconfiguration',
+      '"join" option must itself return a Function when it is called'
+    );
+  } else if (joinProper.length !== 1) {
+    return handleAsError(
+      'loader misconfiguration',
+      '"join" Function must create a function that takes exactly 1 arguments (item)'
+    );
+  }
+
+  // validate root option
+  if (typeof options.root === 'string') {
+    var isValid = (options.root === '') ||
+      (path.isAbsolute(options.root) && fs.existsSync(options.root) && fs.statSync(options.root).isDirectory());
+
+    if (!isValid) {
+      return handleAsError(
+        'loader misconfiguration',
+        '"root" option must be an empty string or an absolute path to an existing directory'
+      );
+    }
+  } else if (options.root !== false) {
+    handleAsWarning(
+      'loader misconfiguration',
+      '"root" option must be string where used or false where unused'
+    );
+  }
+
+  // loader result is cacheable
+  loader.cacheable();
+
+  // incoming source-map
+  var sourceMapConsumer, absSourceMap;
+  if (sourceMap) {
+
+    // support non-standard string encoded source-map (per less-loader)
+    if (typeof sourceMap === 'string') {
+      try {
+        sourceMap = JSON.parse(sourceMap);
+      }
+      catch (exception) {
+        return handleAsError(
+          'source-map error',
+          'cannot parse source-map string (from less-loader?)'
+        );
+      }
+    }
+
+    // leverage adjust-sourcemap-loader's codecs to avoid having to make any assumptions about the sourcemap
+    //  historically this is a regular source of breakage
+    try {
+      absSourceMap = adjustSourceMap(loader, {format: 'absolute'}, sourceMap);
+    }
+    catch (exception) {
+      return handleAsError(
+        'source-map error',
+        exception.message
+      );
+    }
+
+    // prepare the adjusted sass source-map for later look-ups
+    sourceMapConsumer = new SourceMapConsumer(absSourceMap);
+  } else {
+    handleAsWarning(
+      'webpack misconfiguration',
+      'webpack or the upstream loader did not supply a source-map'
+    );
+  }
+
+  // choose a CSS engine
+  var enginePath    = /^[\w-]+$/.test(options.engine) && path.join(__dirname, 'lib', 'engine', options.engine + '.js');
+  var isValidEngine = fs.existsSync(enginePath);
+  if (!isValidEngine) {
+    return handleAsError(
+      'loader misconfiguration',
+      '"engine" option is not valid'
+    );
+  }
+
+  // allow engine to throw at initialisation
+  var engine;
+  try {
+    engine = require(enginePath);
+  } catch (error) {
+    return handleAsError(
+      'error initialising',
+      error
+    );
+  }
+
+  // process async
+  var callback = loader.async();
+  Promise
+    .resolve(engine(loader.resourcePath, content, {
+      outputSourceMap     : !!options.sourceMap,
+      absSourceMap        : absSourceMap,
+      sourceMapConsumer   : sourceMapConsumer,
+      removeCR            : options.removeCR,
+      transformDeclaration: valueProcessor({
+        join     : joinProper,
+        root     : options.root,
+        directory: path.dirname(loader.resourcePath)
+      })
+    }))
+    .catch(onFailure)
+    .then(onSuccess);
+
+  function onFailure(error) {
+    callback(encodeError('error processing CSS', error));
+  }
+
+  function onSuccess(result) {
+    if (result) {
+      // complete with source-map
+      //  webpack4 and earlier: source-map sources are relative to the file being processed
+      //  webpack5: source-map sources are relative to the project root but without a leading slash
+      if (options.sourceMap) {
+        var finalMap = adjustSourceMap(loader, {
+          format: isWebpackGte5 ? 'projectRelative' : 'sourceRelative'
+        }, result.map);
+        callback(null, result.content, finalMap);
+      }
+      // complete without source-map
+      else {
+        callback(null, result.content);
+      }
+    }
+  }
+
+  /**
+   * Trigger a node deprecation message for the given exception and return the original content.
+   * @param {string} code Deprecation code
+   * @param {string} message Deprecation message
+   * @returns {string} The original CSS content
+   */
+  function handleAsDeprecated(code, message) {
+    if (!options.silent) {
+      util.deprecate(() => undefined, message, code)();
+    }
+    return content;
+  }
+
+  /**
+   * Push a warning for the given exception and return the original content.
+   * @param {string} label Summary of the error
+   * @param {string|Error} [exception] Optional extended error details
+   * @returns {string} The original CSS content
+   */
+  function handleAsWarning(label, exception) {
+    if (!options.silent) {
+      loader.emitWarning(encodeError(label, exception));
+    }
+    return content;
+  }
+
+  /**
+   * Push a warning for the given exception and return the original content.
+   * @param {string} label Summary of the error
+   * @param {string|Error} [exception] Optional extended error details
+   * @returns {string} The original CSS content
+   */
+  function handleAsError(label, exception) {
+    loader.emitError(encodeError(label, exception));
+    return content;
+  }
+
+  function encodeError(label, exception) {
+    return new Error(
+      [
+        'resolve-url-loader',
+        ': ',
+        [label]
+          .concat(
+            (typeof exception === 'string') && exception ||
+            Array.isArray(exception) && exception ||
+            (exception instanceof Error) && [exception.message, exception.stack.split('\n')[1].trim()] ||
+            []
+          )
+          .filter(Boolean)
+          .join('\n  ')
+      ].join('')
+    );
+  }
+}
+
+module.exports = Object.assign(resolveUrlLoader, joinFn);
