webpackJsonp([0],[
/* 0 */,
/* 1 */
/***/ (function(module, exports, __webpack_require__) {

/* WEBPACK VAR INJECTION */(function(process) {var logify_input = __webpack_require__(76).logify_input;

module.exports = function(condition) {

    // assert
    if( condition ) {
        return condition;
    }


    // parse arguments
    var msgs = [];
    var opts = {};
    var args = [].slice.call(arguments, 1);
    for(var i in args) {
        var arg = args[i];
        var is_option_arg = false;
        for(var j in arg) {
            is_option_arg = !!option_keys[j]
            if( ! is_option_arg ) {
                break;
            }
        }
        if( is_option_arg ) {
            for(var j in arg) {
                if( !option_keys[j] ) {
                    var msg = 'Unkonwn option `'+j+'`';
                    throw new Error('Reassert: [Internal Error]: '+msg);
                }
                opts[j] = arg[j];
            }
        } else {
            msgs.push(arg);
        }
    }


    // determine whether we are in production
    var prod = is_prod();


    var is_browser = typeof window !== "undefined";

    // build message
    var message = 'Assertion-Error'+(prod?'[prod]':'[dev]')+': '+condition+'!=true';
    for(var i in msgs) {
        var msg = msgs[i];
        if( is_browser && msg instanceof Object ) {
            console.error(msg);
        }
        var str = logify_input(msg);
        message += '\n'+str;
    }
    var error = new Error(message);


    // throw logic
    var throw_now = ! prod || opts[option_keys.is_hard] || ! opts[option_keys.is_soft];
    if( throw_now ) {
        throw error;
    } else {
        setTimeout(function() {
            throw error;
        }, 0);
    }


    // convenience to write code like `if( ! require('reassert')(condition) ) return;`
    return condition;
};


function is_prod() {
    var prod_browser = typeof window !== "undefined" && window.location.hostname !== 'localhost';
    var prod_nodejs = typeof process !== "undefined" && undefined === 'production';
    return prod_browser || prod_nodejs;
}


var option_keys = {
    is_hard: 'is_hard',
    is_soft: 'is_soft',
};

/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(25)))

/***/ }),
/* 2 */,
/* 3 */,
/* 4 */,
/* 5 */,
/* 6 */,
/* 7 */,
/* 8 */,
/* 9 */,
/* 10 */,
/* 11 */,
/* 12 */,
/* 13 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


if (undefined === 'production') {
  module.exports = __webpack_require__(93);
} else {
  module.exports = __webpack_require__(94);
}


/***/ }),
/* 14 */,
/* 15 */,
/* 16 */,
/* 17 */,
/* 18 */,
/* 19 */,
/* 20 */,
/* 21 */,
/* 22 */,
/* 23 */,
/* 24 */,
/* 25 */
/***/ (function(module, exports) {

// shim for using process in browser
var process = module.exports = {};

// cached from whatever global is present so that test runners that stub it
// don't break things.  But we need to wrap it in a try catch in case it is
// wrapped in strict mode code which doesn't define any globals.  It's inside a
// function because try/catches deoptimize in certain engines.

var cachedSetTimeout;
var cachedClearTimeout;

function defaultSetTimout() {
    throw new Error('setTimeout has not been defined');
}
function defaultClearTimeout () {
    throw new Error('clearTimeout has not been defined');
}
(function () {
    try {
        if (typeof setTimeout === 'function') {
            cachedSetTimeout = setTimeout;
        } else {
            cachedSetTimeout = defaultSetTimout;
        }
    } catch (e) {
        cachedSetTimeout = defaultSetTimout;
    }
    try {
        if (typeof clearTimeout === 'function') {
            cachedClearTimeout = clearTimeout;
        } else {
            cachedClearTimeout = defaultClearTimeout;
        }
    } catch (e) {
        cachedClearTimeout = defaultClearTimeout;
    }
} ())
function runTimeout(fun) {
    if (cachedSetTimeout === setTimeout) {
        //normal enviroments in sane situations
        return setTimeout(fun, 0);
    }
    // if setTimeout wasn't available but was latter defined
    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
        cachedSetTimeout = setTimeout;
        return setTimeout(fun, 0);
    }
    try {
        // when when somebody has screwed with setTimeout but no I.E. maddness
        return cachedSetTimeout(fun, 0);
    } catch(e){
        try {
            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
            return cachedSetTimeout.call(null, fun, 0);
        } catch(e){
            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
            return cachedSetTimeout.call(this, fun, 0);
        }
    }


}
function runClearTimeout(marker) {
    if (cachedClearTimeout === clearTimeout) {
        //normal enviroments in sane situations
        return clearTimeout(marker);
    }
    // if clearTimeout wasn't available but was latter defined
    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
        cachedClearTimeout = clearTimeout;
        return clearTimeout(marker);
    }
    try {
        // when when somebody has screwed with setTimeout but no I.E. maddness
        return cachedClearTimeout(marker);
    } catch (e){
        try {
            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally
            return cachedClearTimeout.call(null, marker);
        } catch (e){
            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
            // Some versions of I.E. have different rules for clearTimeout vs setTimeout
            return cachedClearTimeout.call(this, marker);
        }
    }



}
var queue = [];
var draining = false;
var currentQueue;
var queueIndex = -1;

function cleanUpNextTick() {
    if (!draining || !currentQueue) {
        return;
    }
    draining = false;
    if (currentQueue.length) {
        queue = currentQueue.concat(queue);
    } else {
        queueIndex = -1;
    }
    if (queue.length) {
        drainQueue();
    }
}

function drainQueue() {
    if (draining) {
        return;
    }
    var timeout = runTimeout(cleanUpNextTick);
    draining = true;

    var len = queue.length;
    while(len) {
        currentQueue = queue;
        queue = [];
        while (++queueIndex < len) {
            if (currentQueue) {
                currentQueue[queueIndex].run();
            }
        }
        queueIndex = -1;
        len = queue.length;
    }
    currentQueue = null;
    draining = false;
    runClearTimeout(timeout);
}

process.nextTick = function (fun) {
    var args = new Array(arguments.length - 1);
    if (arguments.length > 1) {
        for (var i = 1; i < arguments.length; i++) {
            args[i - 1] = arguments[i];
        }
    }
    queue.push(new Item(fun, args));
    if (queue.length === 1 && !draining) {
        runTimeout(drainQueue);
    }
};

// v8 likes predictible objects
function Item(fun, array) {
    this.fun = fun;
    this.array = array;
}
Item.prototype.run = function () {
    this.fun.apply(null, this.array);
};
process.title = 'browser';
process.browser = true;
process.env = {};
process.argv = [];
process.version = ''; // empty string to avoid regexp issues
process.versions = {};

function noop() {}

process.on = noop;
process.addListener = noop;
process.once = noop;
process.off = noop;
process.removeListener = noop;
process.removeAllListeners = noop;
process.emit = noop;
process.prependListener = noop;
process.prependOnceListener = noop;

process.listeners = function (name) { return [] }

process.binding = function (name) {
    throw new Error('process.binding is not supported');
};

process.cwd = function () { return '/' };
process.chdir = function (dir) {
    throw new Error('process.chdir is not supported');
};
process.umask = function() { return 0; };


/***/ }),
/* 26 */,
/* 27 */,
/* 28 */,
/* 29 */,
/* 30 */,
/* 31 */,
/* 32 */,
/* 33 */,
/* 34 */,
/* 35 */,
/* 36 */,
/* 37 */,
/* 38 */,
/* 39 */,
/* 40 */,
/* 41 */,
/* 42 */,
/* 43 */,
/* 44 */,
/* 45 */,
/* 46 */,
/* 47 */,
/* 48 */,
/* 49 */
/***/ (function(module, exports, __webpack_require__) {

__webpack_require__(50);
module.exports = __webpack_require__(74);


/***/ }),
/* 50 */
/***/ (function(module, exports) {

throw new Error("Module build failed: Error: ENOENT: no such file or directory, open '/home/romu/code/@reframe/node_modules/@rebuild/serve/utils/autoreload/client/index.js'");

/***/ }),
/* 51 */,
/* 52 */,
/* 53 */,
/* 54 */,
/* 55 */,
/* 56 */,
/* 57 */,
/* 58 */,
/* 59 */,
/* 60 */,
/* 61 */,
/* 62 */,
/* 63 */,
/* 64 */,
/* 65 */,
/* 66 */,
/* 67 */,
/* 68 */,
/* 69 */,
/* 70 */,
/* 71 */,
/* 72 */,
/* 73 */,
/* 74 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var hydratePage = __webpack_require__(75);
var pageConfig = __webpack_require__(121);

// hybrid cjs and ES6 module import
pageConfig = Object.keys(pageConfig).length === 1 && pageConfig.default || pageConfig;

hydratePage(pageConfig);

/***/ }),
/* 75 */
/***/ (function(module, exports, __webpack_require__) {

const assert = __webpack_require__(1);
const assert_usage = assert;

const Repage = __webpack_require__(77);
const {hydratePage: repage_hydratePage} = __webpack_require__(79);

const RepageRouterCrossroads = __webpack_require__(82);
const RepageRenderer = __webpack_require__(87);
const RepageRendererReact = __webpack_require__(90);
const RepageNavigator = __webpack_require__(106);

module.exports = hydratePage;

async function hydratePage(page) {
    const repage = new Repage();

    repage.addPlugins([
        RepageRouterCrossroads,
        RepageRenderer,
        RepageRendererReact,
        RepageNavigator,
    ]);

    return await repage_hydratePage(repage, page);
}


/***/ }),
/* 76 */
/***/ (function(module, exports) {

log.logify_input = logify_input;

module.exports = log;

var project_name = 'Reassert';
var stringification_name = '(Reassert-stringification)';

function log() {
    for(var i in arguments) {
        var input = arguments[i];
        var str = logify_input(input);
        console.log(str);
    }
}

function logify_input(input) {
    if( ! input ) {
        return input;
    }

    if( input.constructor === Array ) {
        return stringify_object(input);
    }

    var PREFIX_UGLY = '[object ';
    var input_str = input.toString();
    if( input_str.slice(0, PREFIX_UGLY.length) === PREFIX_UGLY ) {
        return stringify_object(input);
    }

    return input_str;
}

function stringify_object(obj) {
    const obj_copy = get_copy_with_prettier_stringify(obj);
    try {
        return JSON.stringify(obj_copy, null, 2);
    } catch(e) {
        return obj_copy.toString()+'['+e+'][Error]'+stringification_name;
    }
}

function get_copy_with_prettier_stringify(el) {
    if( ! (el instanceof Object) ) {
        return el;
    }
    if( el instanceof RegExp ) {
        if( ! el.toJSON ) {
            el.toJSON = function() {
                var str = '[RegExp: '+el.toString()+']';
                return str;
            };
        }
        return el;
    }
    if( el instanceof Function ) {
        if( ! el.toJSON ) {
            el.toJSON = function() {
                var str = (
                    ! el.name ? (
                        '[Function]'
                    ) : (
                        '[Function: '+el.name+']'
                    )
                );
                return str;
            };
        }
        return el;
    }

    if( el.constructor === Object || el.constructor === Array ) {
        const el_copy = new (el.constructor);
        for(var key in el) {
            el_copy[key] = get_copy_with_prettier_stringify(el[key]);
        }
        return el_copy;
    }

    return el;
}


/***/ }),
/* 77 */
/***/ (function(module, exports, __webpack_require__) {

const Repage = __webpack_require__(78);
module.exports = Repage;


/***/ }),
/* 78 */
/***/ (function(module, exports, __webpack_require__) {

const assert = __webpack_require__(1);
const assert_usage = assert;
const assert_internal = assert;

module.exports = Repage;

function Repage() {
    const page_objects = [];
    const plugins__global = [];

    return {
        addPages,
        addPlugins,
        getAllPageHandlers,
        getPageHandler,
        getMatchingPageHandler,
        isRepageObject: true,
        plugins: plugins__global,
    };

    function addPages(_pages) {
        assert_usage(
            _pages && _pages.constructor===Array,
            _pages,
            '`addPages()` expects an array as argument but got value printed above instead.',
        );
        _pages.forEach(page_object => {
            assert_page_object({page_object});
            page_objects.push(page_object);
        });
    }

    function getPageHandler(page_object) {
        const page_handler = {};

        // assign plugins
        [
            ...plugins__global,
            ...(page_object.plugins||[]),
        ]
        .map(({pageMixin}) => pageMixin)
        .filter(Boolean)
        .forEach(plugin__page_mixin => {
            assign(page_handler, plugin__page_mixin);
        })

        // assign page object
        assign(page_handler, page_object);
        delete page_handler.plugins;

        return page_handler;
    }

    function assign(obj1, obj2) {
        for(const key in obj2) {
            if( obj1[key] instanceof Array || obj2[key] instanceof Array ) {
                obj1[key] = [
                    ...to_array(obj1[key]),
                    ...to_array(obj2[key]),
                ];
            } else {
                obj1[key] = obj2[key];
            }
        }

        return;

        function to_array(val) {
            if( val instanceof Array ) {
                return val;
            }
            if( val===null || val===undefined ) {
                return [];
            }
            return [val];
        }
    }

    function addPlugins(_plugins) {
        _plugins
        .forEach(plugin => {
            assert_plugin(plugin);
            plugins__global.push(plugin);
        });
    }

    function getAllPageHandlers({isRunningInBrowser}) {
        return (
            page_objects.map(page_object => {
                const page_handler = getPageHandler(page_object);
                assert_page_handler({page_handler, isRunningInBrowser});
                return page_handler;
            })
        );
    }

    function getMatchingPageHandler({url, canBeNull=false, isRunningInBrowser}) {
        const page_handlers = getAllPageHandlers({isRunningInBrowser})

        page_handlers.forEach(page_handler => {
            assert_usage(
                page_handler.routeObject,
                page_handler,
                "Above printed page is missing the routeObject while trying to get the page matching a given url."
            );
        });

        const matchingPages = (
            page_handlers.filter(page_handler => page_handler.routeObject.doesMatchUrl(url, page_handler))
        );

        if( matchingPages.length === 0 && canBeNull ) {
            return null;
        }

        assert_usage(
            matchingPages.length>=1,
            "Couldn't find a page for `"+url+"`.",
            '(You can set the option `canBeNull: true` to make `getMatchingPageHandler` return null instead of throwing an error.)'
        );

        const page_handler = matchingPages[0];
        return page_handler;
    }

}

function assert_plugin(plugin) {
    assert_usage(
        !(plugin instanceof Function),
        plugin,
        'You are trying to add a plugin function but you should add a plugin instance instead. I.e. call the plugin function and add the returned value instead of adding the plugin function itself.'
    );
    assert_usage(
        plugin && plugin.constructor===Object,
        plugin,
        'The plugin instance printed above is not a plain JavaScript object but should be.'
    );
    assert_usage(
        plugin.name,
        plugin,
        'Plugin is required to have a name, i.e. the plugin object printed above is missing the `name` property.'
    );
    assert_usage(
        plugin.pageMixin || plugin.navigationHandler,
        plugin,
        "Trying to add a plugin that has no functionality, i.e. the plugin object printed above is missing `pageMixin` or `navigationHandler`."
    );
}

function assert_page_object({page_object}) {
    assert_usage(
        page_object.route || page_object.view,
        page_object,
        "The above printed page object is not valid; The property `route` or `view` needs to be defined."
    );

    (page_object.plugins||[])
    .forEach(({pageMixin}) => {
        assert_usage(pageMixin);
    })
}

function assert_page_handler({page_handler, isRunningInBrowser}) {
    assert_render_function({page_handler, isRunningInBrowser});
}

function assert_render_function({page_handler, isRunningInBrowser}) {
    assert_internal([true, false].includes(isRunningInBrowser));
    const fn_name = isRunningInBrowser ? 'renderToDom' : 'renderToHtml';
    const fn = page_handler[fn_name];
    assert_usage(
        fn===null || fn instanceof Function,
        page_handler,
        "The above printed page handler has `"+fn_name+"=="+fn+"`.",
        "But `"+fn_name+"` is expected to be either `null` or a function."
    );
}


/***/ }),
/* 79 */
/***/ (function(module, exports, __webpack_require__) {

const hydratePage = __webpack_require__(80);
module.exports = {hydratePage};


/***/ }),
/* 80 */
/***/ (function(module, exports, __webpack_require__) {

const assert = __webpack_require__(1);
const assert_usage = assert;
const assert_internal = assert;
const parseUri = __webpack_require__(81);

module.exports = hydratePage;

function hydratePage(repage, page_object) {
    assert_usage(
        repage && repage.isRepageObject && page_object,
        "Wrong arguments"
    );

    const navigation_handler = get_navigation_handler(repage);
    const uri = navigation_handler.getCurrentRoute();
    const url = parseUri(uri);
    const page = repage.getPageHandler(page_object);
    assert_usage(
        page.renderToDom,
        page
    );
    page.renderToDom({page, url});
}

function get_navigation_handler(repage) {
    assert_repage(repage);

    const navigation_handler = {};

    repage.plugins.forEach(plugin => {
        if( plugin.navigationHandler ) {
            Object.assign(navigation_handler, plugin.navigationHandler);
        }
    });

    return navigation_handler;
}

function assert_repage(repage) {
    repage.plugins.forEach(plugin => {
        assert_usage(
            plugin.isAllowedInBrowser===true,
            plugin,
            'Trying to add a plugin that is not allowed in the browser.',
            'I.e. the above printed object specifying the plugin is not having its property `isAllowedInBrowser` set to `true`.',
            'Make sure to load the browser side of the plugin.'
        );
    });
}


/***/ }),
/* 81 */
/***/ (function(module, exports, __webpack_require__) {

const assert = __webpack_require__(1);
const assert_usage = assert;

module.exports = parseUri;

function parseUri(uri) {
    assert_usage(uri && uri.constructor===String, uri);

    const FAKE_BASE = 'https://i-do-not-exist.example.org';

    const _URL = (
        typeof URL !== 'undefined' ? (
            URL
        ) : (
            eval('require')('url').URL
        )
    );

    const url_object = new _URL(uri, FAKE_BASE);

    const origin = (
        url_object.origin === FAKE_BASE ? (
            null
        ) : (
            url_object.origin
        )
    );

    const url = {
        origin,
        pathname: url_object.pathname,
        search: url_object.search,
        hash: url_object.hash,
    };

    Object.defineProperty(url, 'toString', {value: () => JSON.stringify(url)});

    validateUrl(url);

    return url;
}

function validateUrl(url) {
    assert(url && url.constructor===Object, url);
    assert(url.pathname && url.pathname.constructor===String && url.pathname.startsWith('/'), url);
}


/***/ }),
/* 82 */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__(83);


/***/ }),
/* 83 */
/***/ (function(module, exports, __webpack_require__) {

//const assert = require('assert');
const assert = __webpack_require__(1);
const assert_usage = assert;
const assert_internal = assert;

// undocumented APIs;
//  - https://github.com/millermedeiros/crossroads.js/blob/master/dev/tests/spec/lexer.spec.js
const crossroads = __webpack_require__(84);

module.exports = {
    name: __webpack_require__(86).name,
    isAllowedInBrowser: true,
    pageMixin: {
        routeObject: {
            doesMatchUrl,
            getRouteArguments,
            hasOnlyOneUniqueRoute,
            getRouteUri,
         // getRouteString,
        },
    },
};

function doesMatchUrl(url, pageInfo) {
    assert_url(url);
    const route_crossroad = get_route_crossroads(pageInfo);

    const ret = route_crossroad.match(url.pathname);
    assert_internal([true, false].includes(ret));
    return ret;
}

function getRouteArguments(url, pageInfo) {
    assert_url(url);
    const route_crossroad = get_route_crossroads(pageInfo, {can_be_null: true});
    if( ! route_crossroad || ! route_crossroad.match(url.pathname) ) {
        return null;
    }
    const routeArguments = route_crossroad._getParamsObject(url.pathname);
    assert_internal(routeArguments.constructor===Object, routeArguments);
    return routeArguments;
}

function hasOnlyOneUniqueRoute(pageInfo) {
    assert_page_info(pageInfo);
    const {route} = pageInfo;
    const paramIds = crossroads.patternLexer.getParamIds(route);
    assert(paramIds.constructor===Array);
    return paramIds.length===0;
}

function getRouteUri(routeArguments, pageInfo) {
    const route_crossroad = get_route_crossroads(pageInfo);
    return route_crossroad.interpolate(routeArguments);
}

/*
function getRouteString() {
    const route_crossroad = parse_route_string(route);
    return route_crossroad._pattern;
}
*/

function get_route_crossroads(pageInfo, {can_be_null=false}={}) {
    assert_internal([true, false].includes(can_be_null));
    assert_page_info(pageInfo, {can_be_null});
    const {route} = pageInfo;
    if( can_be_null && ! route ) {
        return null;
    }
    assert_internal(route);
    const route_crossroad = parse_route_string(route);
    return route_crossroad;
}

function parse_route_string(route_string) {
    assert_internal(route_string.constructor===String, route_string);
    const router = crossroads.create();
    const route_crossroad = router.addRoute(route_string);
    return route_crossroad;
}

function assert_url(url) {
    assert(url && url.constructor===Object, url);
    assert(url.pathname && url.pathname.constructor===String && url.pathname.startsWith('/'), url);
}

function assert_page_info(pageInfo, {can_be_null}={}) {
    assert_usage(
        can_be_null || pageInfo.route,
        pageInfo
    );
}


/***/ }),
/* 84 */
/***/ (function(module, exports, __webpack_require__) {

var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/** @license
 * crossroads <http://millermedeiros.github.com/crossroads.js/>
 * Author: Miller Medeiros | MIT License
 * v0.12.2 (2015/07/31 18:37)
 */

(function () {
var factory = function (signals) {

    var crossroads,
        _hasOptionalGroupBug,
        UNDEF;

    // Helpers -----------
    //====================

    // IE 7-8 capture optional groups as empty strings while other browsers
    // capture as `undefined`
    _hasOptionalGroupBug = (/t(.+)?/).exec('t')[1] === '';

    function arrayIndexOf(arr, val) {
        if (arr.indexOf) {
            return arr.indexOf(val);
        } else {
            //Array.indexOf doesn't work on IE 6-7
            var n = arr.length;
            while (n--) {
                if (arr[n] === val) {
                    return n;
                }
            }
            return -1;
        }
    }

    function arrayRemove(arr, item) {
        var i = arrayIndexOf(arr, item);
        if (i !== -1) {
            arr.splice(i, 1);
        }
    }

    function isKind(val, kind) {
        return '[object '+ kind +']' === Object.prototype.toString.call(val);
    }

    function isRegExp(val) {
        return isKind(val, 'RegExp');
    }

    function isArray(val) {
        return isKind(val, 'Array');
    }

    function isFunction(val) {
        return typeof val === 'function';
    }

    //borrowed from AMD-utils
    function typecastValue(val) {
        var r;
        if (val === null || val === 'null') {
            r = null;
        } else if (val === 'true') {
            r = true;
        } else if (val === 'false') {
            r = false;
        } else if (val === UNDEF || val === 'undefined') {
            r = UNDEF;
        } else if (val === '' || isNaN(val)) {
            //isNaN('') returns false
            r = val;
        } else {
            //parseFloat(null || '') returns NaN
            r = parseFloat(val);
        }
        return r;
    }

    function typecastArrayValues(values) {
        var n = values.length,
            result = [];
        while (n--) {
            result[n] = typecastValue(values[n]);
        }
        return result;
    }

    // borrowed from MOUT
    function decodeQueryString(queryStr, shouldTypecast) {
        var queryArr = (queryStr || '').replace('?', '').split('&'),
            reg = /([^=]+)=(.+)/,
            i = -1,
            obj = {},
            equalIndex, cur, pValue, pName;

        while ((cur = queryArr[++i])) {
            equalIndex = cur.indexOf('=');
            pName = cur.substring(0, equalIndex);
            pValue = decodeURIComponent(cur.substring(equalIndex + 1));
            if (shouldTypecast !== false) {
                pValue = typecastValue(pValue);
            }
            if (pName in obj){
                if(isArray(obj[pName])){
                    obj[pName].push(pValue);
                } else {
                    obj[pName] = [obj[pName], pValue];
                }
            } else {
                obj[pName] = pValue;
           }
        }
        return obj;
    }


    // Crossroads --------
    //====================

    /**
     * @constructor
     */
    function Crossroads() {
        this.bypassed = new signals.Signal();
        this.routed = new signals.Signal();
        this._routes = [];
        this._prevRoutes = [];
        this._piped = [];
        this.resetState();
    }

    Crossroads.prototype = {

        greedy : false,

        greedyEnabled : true,

        ignoreCase : true,

        ignoreState : false,

        shouldTypecast : false,

        normalizeFn : null,

        resetState : function(){
            this._prevRoutes.length = 0;
            this._prevMatchedRequest = null;
            this._prevBypassedRequest = null;
        },

        create : function () {
            return new Crossroads();
        },

        addRoute : function (pattern, callback, priority) {
            var route = new Route(pattern, callback, priority, this);
            this._sortedInsert(route);
            return route;
        },

        removeRoute : function (route) {
            arrayRemove(this._routes, route);
            route._destroy();
        },

        removeAllRoutes : function () {
            var n = this.getNumRoutes();
            while (n--) {
                this._routes[n]._destroy();
            }
            this._routes.length = 0;
        },

        parse : function (request, defaultArgs) {
            request = request || '';
            defaultArgs = defaultArgs || [];

            // should only care about different requests if ignoreState isn't true
            if ( !this.ignoreState &&
                (request === this._prevMatchedRequest ||
                 request === this._prevBypassedRequest) ) {
                return;
            }

            var routes = this._getMatchedRoutes(request),
                i = 0,
                n = routes.length,
                cur;

            if (n) {
                this._prevMatchedRequest = request;

                this._notifyPrevRoutes(routes, request);
                this._prevRoutes = routes;
                //should be incremental loop, execute routes in order
                while (i < n) {
                    cur = routes[i];
                    cur.route.matched.dispatch.apply(cur.route.matched, defaultArgs.concat(cur.params));
                    cur.isFirst = !i;
                    this.routed.dispatch.apply(this.routed, defaultArgs.concat([request, cur]));
                    i += 1;
                }
            } else {
                this._prevBypassedRequest = request;
                this.bypassed.dispatch.apply(this.bypassed, defaultArgs.concat([request]));
            }

            this._pipeParse(request, defaultArgs);
        },

        _notifyPrevRoutes : function(matchedRoutes, request) {
            var i = 0, prev;
            while (prev = this._prevRoutes[i++]) {
                //check if switched exist since route may be disposed
                if(prev.route.switched && this._didSwitch(prev.route, matchedRoutes)) {
                    prev.route.switched.dispatch(request);
                }
            }
        },

        _didSwitch : function (route, matchedRoutes){
            var matched,
                i = 0;
            while (matched = matchedRoutes[i++]) {
                // only dispatch switched if it is going to a different route
                if (matched.route === route) {
                    return false;
                }
            }
            return true;
        },

        _pipeParse : function(request, defaultArgs) {
            var i = 0, route;
            while (route = this._piped[i++]) {
                route.parse(request, defaultArgs);
            }
        },

        getNumRoutes : function () {
            return this._routes.length;
        },

        _sortedInsert : function (route) {
            //simplified insertion sort
            var routes = this._routes,
                n = routes.length;
            do { --n; } while (routes[n] && route._priority <= routes[n]._priority);
            routes.splice(n+1, 0, route);
        },

        _getMatchedRoutes : function (request) {
            var res = [],
                routes = this._routes,
                n = routes.length,
                route;
            //should be decrement loop since higher priorities are added at the end of array
            while (route = routes[--n]) {
                if ((!res.length || this.greedy || route.greedy) && route.match(request)) {
                    res.push({
                        route : route,
                        params : route._getParamsArray(request)
                    });
                }
                if (!this.greedyEnabled && res.length) {
                    break;
                }
            }
            return res;
        },

        pipe : function (otherRouter) {
            this._piped.push(otherRouter);
        },

        unpipe : function (otherRouter) {
            arrayRemove(this._piped, otherRouter);
        },

        toString : function () {
            return '[crossroads numRoutes:'+ this.getNumRoutes() +']';
        }
    };

    //"static" instance
    crossroads = new Crossroads();
    crossroads.VERSION = '0.12.2';

    crossroads.NORM_AS_ARRAY = function (req, vals) {
        return [vals.vals_];
    };

    crossroads.NORM_AS_OBJECT = function (req, vals) {
        return [vals];
    };


    // Route --------------
    //=====================

    /**
     * @constructor
     */
    function Route(pattern, callback, priority, router) {
        var isRegexPattern = isRegExp(pattern),
            patternLexer = router.patternLexer;
        this._router = router;
        this._pattern = pattern;
        this._paramsIds = isRegexPattern? null : patternLexer.getParamIds(pattern);
        this._optionalParamsIds = isRegexPattern? null : patternLexer.getOptionalParamsIds(pattern);
        this._matchRegexp = isRegexPattern? pattern : patternLexer.compilePattern(pattern, router.ignoreCase);
        this.matched = new signals.Signal();
        this.switched = new signals.Signal();
        if (callback) {
            this.matched.add(callback);
        }
        this._priority = priority || 0;
    }

    Route.prototype = {

        greedy : false,

        rules : void(0),

        match : function (request) {
            request = request || '';
            return this._matchRegexp.test(request) && this._validateParams(request); //validate params even if regexp because of `request_` rule.
        },

        _validateParams : function (request) {
            var rules = this.rules,
                values = this._getParamsObject(request),
                key;
            for (key in rules) {
                // normalize_ isn't a validation rule... (#39)
                if(key !== 'normalize_' && rules.hasOwnProperty(key) && ! this._isValidParam(request, key, values)){
                    return false;
                }
            }
            return true;
        },

        _isValidParam : function (request, prop, values) {
            var validationRule = this.rules[prop],
                val = values[prop],
                isValid = false,
                isQuery = (prop.indexOf('?') === 0);

            if (val == null && this._optionalParamsIds && arrayIndexOf(this._optionalParamsIds, prop) !== -1) {
                isValid = true;
            }
            else if (isRegExp(validationRule)) {
                if (isQuery) {
                    val = values[prop +'_']; //use raw string
                }
                isValid = validationRule.test(val);
            }
            else if (isArray(validationRule)) {
                if (isQuery) {
                    val = values[prop +'_']; //use raw string
                }
                isValid = this._isValidArrayRule(validationRule, val);
            }
            else if (isFunction(validationRule)) {
                isValid = validationRule(val, request, values);
            }

            return isValid; //fail silently if validationRule is from an unsupported type
        },

        _isValidArrayRule : function (arr, val) {
            if (! this._router.ignoreCase) {
                return arrayIndexOf(arr, val) !== -1;
            }

            if (typeof val === 'string') {
                val = val.toLowerCase();
            }

            var n = arr.length,
                item,
                compareVal;

            while (n--) {
                item = arr[n];
                compareVal = (typeof item === 'string')? item.toLowerCase() : item;
                if (compareVal === val) {
                    return true;
                }
            }
            return false;
        },

        _getParamsObject : function (request) {
            var shouldTypecast = this._router.shouldTypecast,
                values = this._router.patternLexer.getParamValues(request, this._matchRegexp, shouldTypecast),
                o = {},
                n = values.length,
                param, val;
            while (n--) {
                val = values[n];
                if (this._paramsIds) {
                    param = this._paramsIds[n];
                    if (param.indexOf('?') === 0 && val) {
                        //make a copy of the original string so array and
                        //RegExp validation can be applied properly
                        o[param +'_'] = val;
                        //update vals_ array as well since it will be used
                        //during dispatch
                        val = decodeQueryString(val, shouldTypecast);
                        values[n] = val;
                    }
                    // IE will capture optional groups as empty strings while other
                    // browsers will capture `undefined` so normalize behavior.
                    // see: #gh-58, #gh-59, #gh-60
                    if ( _hasOptionalGroupBug && val === '' && arrayIndexOf(this._optionalParamsIds, param) !== -1 ) {
                        val = void(0);
                        values[n] = val;
                    }
                    o[param] = val;
                }
                //alias to paths and for RegExp pattern
                o[n] = val;
            }
            o.request_ = shouldTypecast? typecastValue(request) : request;
            o.vals_ = values;
            return o;
        },

        _getParamsArray : function (request) {
            var norm = this.rules? this.rules.normalize_ : null,
                params;
            norm = norm || this._router.normalizeFn; // default normalize
            if (norm && isFunction(norm)) {
                params = norm(request, this._getParamsObject(request));
            } else {
                params = this._getParamsObject(request).vals_;
            }
            return params;
        },

        interpolate : function(replacements) {
            var str = this._router.patternLexer.interpolate(this._pattern, replacements);
            if (! this._validateParams(str) ) {
                throw new Error('Generated string doesn\'t validate against `Route.rules`.');
            }
            return str;
        },

        dispose : function () {
            this._router.removeRoute(this);
        },

        _destroy : function () {
            this.matched.dispose();
            this.switched.dispose();
            this.matched = this.switched = this._pattern = this._matchRegexp = null;
        },

        toString : function () {
            return '[Route pattern:"'+ this._pattern +'", numListeners:'+ this.matched.getNumListeners() +']';
        }

    };



    // Pattern Lexer ------
    //=====================

    Crossroads.prototype.patternLexer = (function () {

        var
            //match chars that should be escaped on string regexp
            ESCAPE_CHARS_REGEXP = /[\\.+*?\^$\[\](){}\/'#]/g,

            //trailing slashes (begin/end of string)
            LOOSE_SLASHES_REGEXP = /^\/|\/$/g,
            LEGACY_SLASHES_REGEXP = /\/$/g,

            //params - everything between `{ }` or `: :`
            PARAMS_REGEXP = /(?:\{|:)([^}:]+)(?:\}|:)/g,

            //used to save params during compile (avoid escaping things that
            //shouldn't be escaped).
            TOKENS = {
                'OS' : {
                    //optional slashes
                    //slash between `::` or `}:` or `\w:` or `:{?` or `}{?` or `\w{?`
                    rgx : /([:}]|\w(?=\/))\/?(:|(?:\{\?))/g,
                    save : '$1{{id}}$2',
                    res : '\\/?'
                },
                'RS' : {
                    //required slashes
                    //used to insert slash between `:{` and `}{`
                    rgx : /([:}])\/?(\{)/g,
                    save : '$1{{id}}$2',
                    res : '\\/'
                },
                'RQ' : {
                    //required query string - everything in between `{? }`
                    rgx : /\{\?([^}]+)\}/g,
                    //everything from `?` till `#` or end of string
                    res : '\\?([^#]+)'
                },
                'OQ' : {
                    //optional query string - everything in between `:? :`
                    rgx : /:\?([^:]+):/g,
                    //everything from `?` till `#` or end of string
                    res : '(?:\\?([^#]*))?'
                },
                'OR' : {
                    //optional rest - everything in between `: *:`
                    rgx : /:([^:]+)\*:/g,
                    res : '(.*)?' // optional group to avoid passing empty string as captured
                },
                'RR' : {
                    //rest param - everything in between `{ *}`
                    rgx : /\{([^}]+)\*\}/g,
                    res : '(.+)'
                },
                // required/optional params should come after rest segments
                'RP' : {
                    //required params - everything between `{ }`
                    rgx : /\{([^}]+)\}/g,
                    res : '([^\\/?]+)'
                },
                'OP' : {
                    //optional params - everything between `: :`
                    rgx : /:([^:]+):/g,
                    res : '([^\\/?]+)?\/?'
                }
            },

            LOOSE_SLASH = 1,
            STRICT_SLASH = 2,
            LEGACY_SLASH = 3,

            _slashMode = LOOSE_SLASH;


        function precompileTokens(){
            var key, cur;
            for (key in TOKENS) {
                if (TOKENS.hasOwnProperty(key)) {
                    cur = TOKENS[key];
                    cur.id = '__CR_'+ key +'__';
                    cur.save = ('save' in cur)? cur.save.replace('{{id}}', cur.id) : cur.id;
                    cur.rRestore = new RegExp(cur.id, 'g');
                }
            }
        }
        precompileTokens();


        function captureVals(regex, pattern) {
            var vals = [], match;
            // very important to reset lastIndex since RegExp can have "g" flag
            // and multiple runs might affect the result, specially if matching
            // same string multiple times on IE 7-8
            regex.lastIndex = 0;
            while (match = regex.exec(pattern)) {
                vals.push(match[1]);
            }
            return vals;
        }

        function getParamIds(pattern) {
            return captureVals(PARAMS_REGEXP, pattern);
        }

        function getOptionalParamsIds(pattern) {
            return captureVals(TOKENS.OP.rgx, pattern);
        }

        function compilePattern(pattern, ignoreCase) {
            pattern = pattern || '';

            if(pattern){
                if (_slashMode === LOOSE_SLASH) {
                    pattern = pattern.replace(LOOSE_SLASHES_REGEXP, '');
                }
                else if (_slashMode === LEGACY_SLASH) {
                    pattern = pattern.replace(LEGACY_SLASHES_REGEXP, '');
                }

                //save tokens
                pattern = replaceTokens(pattern, 'rgx', 'save');
                //regexp escape
                pattern = pattern.replace(ESCAPE_CHARS_REGEXP, '\\$&');
                //restore tokens
                pattern = replaceTokens(pattern, 'rRestore', 'res');

                if (_slashMode === LOOSE_SLASH) {
                    pattern = '\\/?'+ pattern;
                }
            }

            if (_slashMode !== STRICT_SLASH) {
                //single slash is treated as empty and end slash is optional
                pattern += '\\/?';
            }
            return new RegExp('^'+ pattern + '$', ignoreCase? 'i' : '');
        }

        function replaceTokens(pattern, regexpName, replaceName) {
            var cur, key;
            for (key in TOKENS) {
                if (TOKENS.hasOwnProperty(key)) {
                    cur = TOKENS[key];
                    pattern = pattern.replace(cur[regexpName], cur[replaceName]);
                }
            }
            return pattern;
        }

        function getParamValues(request, regexp, shouldTypecast) {
            var vals = regexp.exec(request);
            if (vals) {
                vals.shift();
                if (shouldTypecast) {
                    vals = typecastArrayValues(vals);
                }
            }
            return vals;
        }

        function interpolate(pattern, replacements) {
            // default to an empty object because pattern might have just
            // optional arguments
            replacements = replacements || {};
            if (typeof pattern !== 'string') {
                throw new Error('Route pattern should be a string.');
            }

            var replaceFn = function(match, prop){
                    var val;
                    prop = (prop.substr(0, 1) === '?')? prop.substr(1) : prop;
                    if (replacements[prop] != null) {
                        if (typeof replacements[prop] === 'object') {
                            var queryParts = [], rep;
                            for(var key in replacements[prop]) {
                                rep = replacements[prop][key];
                                if (isArray(rep)) {
                                    for (var k in rep) {
                                        if ( key.slice(-2) == '[]' ) {
                                            queryParts.push(encodeURI(key.slice(0, -2)) + '[]=' + encodeURI(rep[k]));
                                        } else {
                                            queryParts.push(encodeURI(key + '=' + rep[k]));
                                        }
                                    }
                                }
                                else {
                                    queryParts.push(encodeURI(key + '=' + rep));
                                }
                            }
                            val = '?' + queryParts.join('&');
                        } else {
                            // make sure value is a string see #gh-54
                            val = String(replacements[prop]);
                        }

                        if (match.indexOf('*') === -1 && val.indexOf('/') !== -1) {
                            throw new Error('Invalid value "'+ val +'" for segment "'+ match +'".');
                        }
                    }
                    else if (match.indexOf('{') !== -1) {
                        throw new Error('The segment '+ match +' is required.');
                    }
                    else {
                        val = '';
                    }
                    return val;
                };

            if (! TOKENS.OS.trail) {
                TOKENS.OS.trail = new RegExp('(?:'+ TOKENS.OS.id +')+$');
            }

            return pattern
                        .replace(TOKENS.OS.rgx, TOKENS.OS.save)
                        .replace(PARAMS_REGEXP, replaceFn)
                        .replace(TOKENS.OS.trail, '') // remove trailing
                        .replace(TOKENS.OS.rRestore, '/'); // add slash between segments
        }

        //API
        return {
            strict : function(){
                _slashMode = STRICT_SLASH;
            },
            loose : function(){
                _slashMode = LOOSE_SLASH;
            },
            legacy : function(){
                _slashMode = LEGACY_SLASH;
            },
            getParamIds : getParamIds,
            getOptionalParamsIds : getOptionalParamsIds,
            getParamValues : getParamValues,
            compilePattern : compilePattern,
            interpolate : interpolate
        };

    }());


    return crossroads;
};

if (true) {
    !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(85)], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
				__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
				(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
} else if (typeof module !== 'undefined' && module.exports) { //Node
    module.exports = factory(require('signals'));
} else {
    /*jshint sub:true */
    window['crossroads'] = factory(window['signals']);
}

}());



/***/ }),
/* 85 */
/***/ (function(module, exports) {

throw new Error("Module build failed: Error: ENOENT: no such file or directory, open '/home/romu/code/@reframe/node_modules/signals/dist/signals.js'");

/***/ }),
/* 86 */
/***/ (function(module, exports) {

module.exports = {"name":"@repage/router-crossroads","version":"0.0.1-rc.1","browser":"./browser.js","main":"./server.js","dependencies":{"crossroads":"^0.12.2"},"publishConfig":{"access":"public"},"repository":"github:brillout/repage"}

/***/ }),
/* 87 */
/***/ (function(module, exports, __webpack_require__) {

const assert = __webpack_require__(1);
const assert_usage = assert;
const assert_internal = assert;

const {run, prepare} = __webpack_require__(88);

module.exports = {
    name: __webpack_require__(89).name,
    isAllowedInBrowser: true,
    pageMixin: {
        renderToDom,
    },
};

async function renderToDom(args) {
    const {page, url} = args;

    args = await prepare(args, {persist_output_in_memory_cache: true});

    args = (
        Object.assign(
            {
                renderDomContext: {},
                route: get_route_object(page, url),
            },
            args
        )
    )

    await run(page.renderDomBegin, args);
    await run(page.renderDomLoad, args);
    await run(page.renderDomApply, args, true);
    await run(page.renderDomEnd, args);
}

function get_route_object(page, url) {
    const route = {url};
    const route_args = page.routeObject.getRouteArguments(url, page);
    assert_internal(route_args===null || route_args.constructor===Object);
    if( route_args ) {
        route.args = route_args;
    } else {
        Object.defineProperty(
            route,
            'args',
            { get: () => {
                assert_usage(
                    false,
                    page,
                    "The route arguments `route.args` for the url `"+url+"` are not available for the page printed above since the page doesn't define a route."
                );
            } }
        );
    }
    return route;
}


/***/ }),
/* 88 */
/***/ (function(module, exports, __webpack_require__) {


const assert = __webpack_require__(1);
const assert_usage = assert;
const assert_internal = assert;

module.exports = {
    run,
    prepare,
};

async function run(fcts, args, sequentially) {
    if( ! fcts ) {
        return;
    }
    assert_internal(fcts.constructor===Array, fcts);

    if( ! sequentially ) {
        return (
            Promise.all(fcts.map(fn => fn(args)))
        );
    }

    for(const fn of fcts) {
        await fn(args);
    }
}

async function prepare(args, {persist_output_in_memory_cache=false}={}) {
    let {page} = args;

    /*
    const load_page_data_output = await load_page_data({page, persist_output_in_memory_cache});
    page = {...page, ...load_page_data_output};
    */

    const init_output = await call_init({page, persist_output_in_memory_cache});

    args = Object.assign({}, init_output, args, {page});

    return args;
}

async function call_init({page, persist_output_in_memory_cache}) {
    assert_internal(page);
    assert_internal([true, false].includes(persist_output_in_memory_cache));

    if( ! page.init ) {
        return {};
    }
    assert_internal(page.init.originalFunctions);
    assert_internal(page.init.originalFunctions.length === 1);
    const orgFn = page.init.originalFunctions[0];

    const memory_cache_key = '__INTERNAL_DO_NOT_USE__output';

    //*
    if( persist_output_in_memory_cache && orgFn[memory_cache_key] ) {
        return orgFn[memory_cache_key];
    }
    //*/

    const init_output = await page.init();
    assert_usage(
        init_output && init_output.constructor===Object,
        "Page:",
        page,
        "Page `init`:",
        page.init,
        "Page `init` return value:",
        init_output,
        "Page `init` return value constructor:",
        init_output.constructor,
        "The above printed page `init` function should return a plain JavaScript object but returns the value printed above instead."
    );
    orgFn[memory_cache_key] = init_output;
    return init_output;
}

/*
async function load_page_data({page, persist_output_in_memory_cache}) {
    if( ! page.pageInfoLoader ) {
        return {};
    }

    const load_page_data_output = await page.pageInfoLoader();

    return load_page_data_output;
}
*/


/***/ }),
/* 89 */
/***/ (function(module, exports) {

module.exports = {"name":"@repage/renderer","version":"0.0.1-rc.1","browser":"./browser.js","main":"./server.js","publishConfig":{"access":"public"},"repository":"github:brillout/repage"}

/***/ }),
/* 90 */
/***/ (function(module, exports, __webpack_require__) {

const assert = __webpack_require__(1);
const assert_usage = assert;
const assert_internal = assert;
const ReactDOM = __webpack_require__(91);
const HtmlCrust = __webpack_require__(103);
const {getReactElement, get_initial_props, loadData, get_views} = __webpack_require__(104);

module.exports = {
    name: __webpack_require__(105).name,
    isAllowedInBrowser: true,
    pageMixin: {
        renderDomLoad: [
            loadData,
        ],
        renderDomApply: [
            renderDomApply,
        ],
    },
};

async function renderDomApply({page, renderDomContext, route}) {
    HtmlCrust.renderToDom(page);

    const views = get_views(page);

    const initial_props = get_initial_props(route, renderDomContext);

    const promises = (
        views.map(view_object => {
            return render_view({view_object, initial_props});
        })
    );

    for(const promise of promises) {
        await promise;
    }
}

function render_view({view_object, initial_props}) {
    const {react_component, container_id} = view_object;
    assert_internal(react_component);
    assert_internal(container_id);

    const react_element = getReactElement({react_component, initial_props});

    const container = get_or_create_container(container_id);

    const do_hydrate = container.firstChild !== null;

    return render_to_dom({react_element, container, do_hydrate});
}

function render_to_dom({react_element, container, do_hydrate}) {
    return new Promise(resolve => {
        do_it(resolve);
    });

    function do_it(resolve) {
        if( do_hydrate ) {
            ReactDOM.hydrate(react_element, container, resolve);
        } else {
            ReactDOM.render(react_element, container, resolve);
        }
    }
}

function get_or_create_container(container_id) {
    let container = document.body.querySelector('#'+container_id);
    if( ! container ) {
        container = create_dom_element({dom_id: container_id});
    }
    return container;
}

function create_dom_element({dom_id}) {
    const el = document.createElement('div');
    el.id = dom_id;
    const firstChild = document.body.firstChild;
    if( ! firstChild ) {
        document.body.appendChild(el);
    } else {
        document.body.insertBefore(el, firstChild);
    }
    return el;
}


/***/ }),
/* 91 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


function checkDCE() {
  /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
  if (
    typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined' ||
    typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE !== 'function'
  ) {
    return;
  }
  if (undefined !== 'production') {
    // This branch is unreachable because this function is only called
    // in production, but the condition is true only in development.
    // Therefore if the branch is still here, dead code elimination wasn't
    // properly applied.
    // Don't change the message. React DevTools relies on it. Also make sure
    // this message doesn't occur elsewhere in this function, or it will cause
    // a false positive.
    throw new Error('^_^');
  }
  try {
    // Verify that the code above has been dead code eliminated (DCE'd).
    __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(checkDCE);
  } catch (err) {
    // DevTools shouldn't crash React, no matter what.
    // We should still report in case we break this code.
    console.error(err);
  }
}

if (undefined === 'production') {
  // DCE check should happen before ReactDOM bundle executes so that
  // DevTools can report bad minification during injection.
  checkDCE();
  module.exports = __webpack_require__(92);
} else {
  module.exports = __webpack_require__(98);
}


/***/ }),
/* 92 */
/***/ (function(module, exports) {

throw new Error("Module build failed: Error: ENOENT: no such file or directory, open '/home/romu/code/@reframe/node_modules/react-dom/cjs/react-dom.production.min.js'");

/***/ }),
/* 93 */
/***/ (function(module, exports) {

throw new Error("Module build failed: Error: ENOENT: no such file or directory, open '/home/romu/code/@reframe/node_modules/react/cjs/react.production.min.js'");

/***/ }),
/* 94 */
/***/ (function(module, exports) {

throw new Error("Module build failed: Error: ENOENT: no such file or directory, open '/home/romu/code/@reframe/node_modules/react/cjs/react.development.js'");

/***/ }),
/* 95 */,
/* 96 */,
/* 97 */,
/* 98 */
/***/ (function(module, exports) {

throw new Error("Module build failed: Error: ENOENT: no such file or directory, open '/home/romu/code/@reframe/node_modules/react-dom/cjs/react-dom.development.js'");

/***/ }),
/* 99 */,
/* 100 */,
/* 101 */,
/* 102 */,
/* 103 */
/***/ (function(module, exports, __webpack_require__) {

const assert = __webpack_require__(1);
const assert_usage = assert;
const assert_internal = assert;

module.exports = {renderToDom, renderToHtml};

const HTML_TAB = '  ';

function renderToHtml(pageObject) {

    const {html} = pageObject;

    if( html ) {
        return html;
    }

    const html_body = render_body_to_html(pageObject);
    const html_head = render_head_to_html(pageObject);

    const html_html = wrap('html', [html_head, html_body]);

    return (
        '<!DOCTYPE html>\n'+
        html_html
    );

}

function render_head_to_html(pageObject) {
    const {
        title,
        description,
        charset='utf-8',
        viewport='width=device-width, initial-scale=1, maximum-scale=1',
        styles,
        head,
        headHtml,
    } = pageObject;

    if( headHtml ) {
        return wrap('head', headHtml);
    }

    const head_tags = [];
    if( styles ) {
        assert_usage(styles.forEach, styles);
        styles.forEach(href => {
            assert_usage(
                href && href.constructor===String && href.startsWith('/'),
                pageObject,
                styles
            );
            head_tags.push(`<link href="${href}" rel="stylesheet">`);
        });
    }
    if( title ) {
        head_tags.push(`<title>${title}</title>`);
    }
    if( description ) {
        head_tags.push(`<meta name="description" content="${description}">`);
    }
    if( viewport ) {
        head_tags.push(`<meta name="viewport" content="${viewport}">`);
    }
    if( charset ) {
        head_tags.push(`<meta charset="${charset}">`);
    }
    if( head ) {
        if( head.constructor === String ) {
            head_tags.push(head);
        } else if( head.constructor === Array ) {
            head_tags.push(...head);
        } else {
            assert_usage(false);
        }
    }

    const html_head = (
        head_tags.length === 0 ? (
            ''
        ) : (
            wrap('head', head_tags)
        )
    );

    return html_head;
}

function render_body_to_html(pageObject) {
    const {
        scripts,
        body,
        bodyHtml,
    } = pageObject;

    if( bodyHtml ) {
        return wrap('body', bodyHtml);
    }

    assert_usage(!scripts || scripts.forEach);
    const body__addendum = (
        (scripts||[])
        .map(spec => {
            assert_usage(
                spec
            );
            if( spec.constructor === String ) {
                spec = {src: spec};
            }
            assert_usage(spec.constructor===Object, spec);
            let innerHTML;
            if( spec.code ) {
                innerHTML = spec.code;
                delete spec.code;
            }
            assert_usage(
                !spec.diskPath
            );
            assert_usage(
                !spec.src || spec.src.startsWith('/') || spec.src.startsWith('http'),
                spec,
                spec.src
            );
            spec.type = spec.type || 'text/javascript';
            assert_usage(spec.src || spec.innerHTML);
            return generate_html_element('script', spec, innerHTML);
        })
        .join('\n')
    );

    const html_body = wrap('body', [body, body__addendum]);

    return html_body;

    function generate_html_element(tagName, attrs, innerHTML) {
        assert_internal(attrs.constructor===Object);
        assert_tagName(tagName);
        return (
            [
                '<'+tagName,
                (
                    Object.entries(attrs)
                    .map(([attr_name, attr_value]) => {
                        if( ! attr_value ) {
                            return '';
                        }
                        if( attr_value===true ) {
                            return ' '+attr_name;
                        }
                        assert_attr_name(attr_name);
                        assert_attr_value(attr_value);
                        return ' '+attr_name+'="'+attr_value+'"';
                    })
                    .join('')
                ),
                '>',
                innerHTML||'',
                '</'+tagName+'>',
            ].join('')
        )
    }

    function assert_tagName(tagName) {
        assert_internal(tagName, pageObject, tagName);
        assert_usage(/^[a-zA-Z]+$/.test(tagName), pageObject, tagName);
    }
    function assert_attr_name(attr_name) {
        assert_usage(attr_name, pageObject, attr_name);
        assert_usage(/^[a-zA-Z-]+$/.test(attr_name), pageObject, attr_name);
    }
    function assert_attr_value(attr_value) {
        assert_usage(attr_value, pageObject, attr_value);
        assert_usage(!attr_value.includes('"'), pageObject, attr_value);
    }
}

function wrap(tag, content) {
    assert_internal([String, Array].includes(content.constructor));
    const content_array = content.constructor===Array ? content : [content];
    return (
        [
            '<'+tag+'>',
            ...(
                content_array
                .filter(Boolean)
                .join('\n')
                .split('\n')
                .filter(Boolean)
                .map(line => HTML_TAB+line)
            ),
            '</'+tag+'>',
        ]
        .filter(Boolean)
        .join('\n')
    );
}

function renderToDom(pageObject) {
    const doc = document;
    assert(doc);
    assert(doc.documentElement);
    assert(doc.body);
    assert(doc.querySelector);
    assert(doc.createElement);

    assert_usage(!pageObject.body);

    {
        const {title} = pageObject;
        doc.title = title || '';
    }

    {
        const {description} = pageObject;
        const dom_el__meta_desc = (() => {
            const el = doc.querySelector('meta[name="description"]');
            if( el ) {
                return el;
            }
            const new_el = doc.createElement('meta');
            new_el.setAttribute('name', 'description');
            return new_el;
        })();
        dom_el__meta_desc.setAttribute('content', description || '');
    }
}


/***/ }),
/* 104 */
/***/ (function(module, exports, __webpack_require__) {

const assert = __webpack_require__(1);
const assert_usage = assert;
const assert_internal = assert;

const React = __webpack_require__(13);

const rootContainerId = 'react-root';

module.exports = {
    getReactElement,
    get_initial_props,
    loadData,
    get_views,
};

function get_initial_props(route, contextObject) {
    assert_internal(route);
    assert_internal(contextObject.initialProps, contextObject);
    const initial_props = Object.assign({route}, contextObject.initialProps);
    return initial_props;
}

function getReactElement({react_component, initial_props}) {
    return React.createElement(react_component, initial_props);
}

function get_views(page) {
    const {view: view_page_prop} = page;

    if( ! view_page_prop ) {
        return [];
    }

    const views = (
        (
            view_page_prop.constructor !== Array ? (
                [view_page_prop]
            ) : (
                view_page_prop
            )
        ).map(view => {
            assert_usage(
                view
            );
            if( view.constructor!==Object || ! view.view ) {
                return {
                    react_component: view,
                    container_id: rootContainerId,
                };
            }
            return {
                react_component: view.view,
                container_id: view.containerId || rootContainerId,
            };
        })
    );

    views.forEach((view_object, i) => {
        assert_internal(view_object.react_component);
        assert_internal(view_object.container_id);
        assert_internal(Object.keys(view_object).length===2);

        views.slice(0, i).forEach(view_object_2 => {
            assert_usage(
                view_object.container_id !== view_object_2.container_id,
                page,
                view_object,
                view_object_2,
                "The two views printed above of the page printed above have the same container id"
            );
        });
    });

    return views;
}

async function loadData(args) {
    const {page, renderHtmlContext, renderDomContext} = args;
    assert(!renderHtmlContext || !renderDomContext);
    const context = renderHtmlContext || renderDomContext;
    context.initialProps = (
        page.getInitialProps ? (
            await page.getInitialProps(args)
        ) : (
            {}
        )
    );
}


/***/ }),
/* 105 */
/***/ (function(module, exports) {

module.exports = {"name":"@repage/renderer-react","version":"0.0.1-rc.1","browser":"./browser.js","main":"./server.js","dependencies":{"@brillout/html-crust":"^0.0.1","react":"^16.1.1","react-dom":"^16.1.1"},"publishConfig":{"access":"public"},"repository":"github:brillout/repage"}

/***/ }),
/* 106 */
/***/ (function(module, exports, __webpack_require__) {

const assert = __webpack_require__(1);
const assert_usage = assert;
const assert_internal = assert;
const { createHistory, createHashHistory } = __webpack_require__(107);

// Using history@2 and not history@3 because of listeners being called twice

module.exports = RepageNavigator();
module.exports.RepageNavigator = RepageNavigator;

function RepageNavigator () {

    const navigationHandler = {
        getCurrentRoute,
        getUrlOrigin,
    };

    return {
        name: __webpack_require__(120).name,
        isAllowedInBrowser: true,
        navigationHandler,
    };

    function getUrlOrigin() {
        return window.location.origin;
    }

    function getCurrentRoute() {
        const current_route = window.location.href.replace(window.location.origin, '');
        assert_internal(current_route.startsWith('/'));
        return current_route;
    }
}


/***/ }),
/* 107 */
/***/ (function(module, exports) {

throw new Error("Module build failed: Error: ENOENT: no such file or directory, open '/home/romu/code/@reframe/node_modules/history/lib/index.js'");

/***/ }),
/* 108 */,
/* 109 */,
/* 110 */,
/* 111 */,
/* 112 */,
/* 113 */,
/* 114 */,
/* 115 */,
/* 116 */,
/* 117 */,
/* 118 */,
/* 119 */,
/* 120 */
/***/ (function(module, exports) {

module.exports = {"name":"@repage/navigator","version":"0.0.1-rc.1","browser":"./browser.js","main":"./server.js","dependencies":{"history":"2.x.x","reassert":"^1.0.0"},"publishConfig":{"access":"public"},"repository":"github:brillout/repage"}

/***/ }),
/* 121 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_react__ = __webpack_require__(13);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_react__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__landing_css__ = __webpack_require__(122);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__landing_css___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1__landing_css__);





const LandingComponent = () => __WEBPACK_IMPORTED_MODULE_0_react___default.a.createElement(
    'div',
    null,
    __WEBPACK_IMPORTED_MODULE_0_react___default.a.createElement(
        'div',
        { className: 'blue-on-red' },
        'Blue on red.'
    ),
    __WEBPACK_IMPORTED_MODULE_0_react___default.a.createElement(
        'div',
        { className: 'red-on-blue' },
        'Red on blue.'
    )
);

const LandingPage = {
    route: '/',
    view: LandingComponent
};

/* harmony default export */ __webpack_exports__["default"] = (LandingPage);

/***/ }),
/* 122 */
/***/ (function(module, exports, __webpack_require__) {


var content = __webpack_require__(123);

if(typeof content === 'string') content = [[module.i, content, '']];

var transform;
var insertInto;



var options = {"hmr":true}

options.transform = transform
options.insertInto = undefined;

var update = __webpack_require__(125)(content, options);

if(content.locals) module.exports = content.locals;

if(false) {
	module.hot.accept("!!../../../node_modules/css-loader/index.js!../../../node_modules/postcss-loader/lib/index.js??ref--2-2!../../../build/node_modules/@rebuild/config/fallback-loader.js??ref--4-0!./landing.css", function() {
		var newContent = require("!!../../../node_modules/css-loader/index.js!../../../node_modules/postcss-loader/lib/index.js??ref--2-2!../../../build/node_modules/@rebuild/config/fallback-loader.js??ref--4-0!./landing.css");

		if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];

		var locals = (function(a, b) {
			var key, idx = 0;

			for(key in a) {
				if(!b || a[key] !== b[key]) return false;
				idx++;
			}

			for(key in b) idx--;

			return idx === 0;
		}(content.locals, newContent.locals));

		if(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');

		update(newContent);
	});

	module.hot.dispose(function() { update(); });
}

/***/ }),
/* 123 */
/***/ (function(module, exports, __webpack_require__) {

exports = module.exports = __webpack_require__(124)(false);
// imports


// module
exports.push([module.i, ".red-on-blue {\n  background-color: #88f;\n  color: #f88\n}\n\n.blue-on-red {\n  background-color: #f88;\n  color: #88f\n}\n\n.red-on-blue,\n.blue-on-red {\n  font-size: 2em;\n  width: 300px;\n  padding: 20px;\n  margin: 10px\n}\n", ""]);

// exports


/***/ }),
/* 124 */
/***/ (function(module, exports) {

throw new Error("Module build failed: Error: ENOENT: no such file or directory, open '/home/romu/code/@reframe/node_modules/css-loader/lib/css-base.js'");

/***/ }),
/* 125 */
/***/ (function(module, exports, __webpack_require__) {

/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/

var stylesInDom = {};

var	memoize = function (fn) {
	var memo;

	return function () {
		if (typeof memo === "undefined") memo = fn.apply(this, arguments);
		return memo;
	};
};

var isOldIE = memoize(function () {
	// Test for IE <= 9 as proposed by Browserhacks
	// @see http://browserhacks.com/#hack-e71d8692f65334173fee715c222cb805
	// Tests for existence of standard globals is to allow style-loader
	// to operate correctly into non-standard environments
	// @see https://github.com/webpack-contrib/style-loader/issues/177
	return window && document && document.all && !window.atob;
});

var getTarget = function (target) {
  return document.querySelector(target);
};

var getElement = (function (fn) {
	var memo = {};

	return function(target) {
                // If passing function in options, then use it for resolve "head" element.
                // Useful for Shadow Root style i.e
                // {
                //   insertInto: function () { return document.querySelector("#foo").shadowRoot }
                // }
                if (typeof target === 'function') {
                        return target();
                }
                if (typeof memo[target] === "undefined") {
			var styleTarget = getTarget.call(this, target);
			// Special case to return head of iframe instead of iframe itself
			if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {
				try {
					// This will throw an exception if access to iframe is blocked
					// due to cross-origin restrictions
					styleTarget = styleTarget.contentDocument.head;
				} catch(e) {
					styleTarget = null;
				}
			}
			memo[target] = styleTarget;
		}
		return memo[target]
	};
})();

var singleton = null;
var	singletonCounter = 0;
var	stylesInsertedAtTop = [];

var	fixUrls = __webpack_require__(126);

module.exports = function(list, options) {
	if (typeof DEBUG !== "undefined" && DEBUG) {
		if (typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment");
	}

	options = options || {};

	options.attrs = typeof options.attrs === "object" ? options.attrs : {};

	// Force single-tag solution on IE6-9, which has a hard limit on the # of <style>
	// tags it will allow on a page
	if (!options.singleton && typeof options.singleton !== "boolean") options.singleton = isOldIE();

	// By default, add <style> tags to the <head> element
        if (!options.insertInto) options.insertInto = "head";

	// By default, add <style> tags to the bottom of the target
	if (!options.insertAt) options.insertAt = "bottom";

	var styles = listToStyles(list, options);

	addStylesToDom(styles, options);

	return function update (newList) {
		var mayRemove = [];

		for (var i = 0; i < styles.length; i++) {
			var item = styles[i];
			var domStyle = stylesInDom[item.id];

			domStyle.refs--;
			mayRemove.push(domStyle);
		}

		if(newList) {
			var newStyles = listToStyles(newList, options);
			addStylesToDom(newStyles, options);
		}

		for (var i = 0; i < mayRemove.length; i++) {
			var domStyle = mayRemove[i];

			if(domStyle.refs === 0) {
				for (var j = 0; j < domStyle.parts.length; j++) domStyle.parts[j]();

				delete stylesInDom[domStyle.id];
			}
		}
	};
};

function addStylesToDom (styles, options) {
	for (var i = 0; i < styles.length; i++) {
		var item = styles[i];
		var domStyle = stylesInDom[item.id];

		if(domStyle) {
			domStyle.refs++;

			for(var j = 0; j < domStyle.parts.length; j++) {
				domStyle.parts[j](item.parts[j]);
			}

			for(; j < item.parts.length; j++) {
				domStyle.parts.push(addStyle(item.parts[j], options));
			}
		} else {
			var parts = [];

			for(var j = 0; j < item.parts.length; j++) {
				parts.push(addStyle(item.parts[j], options));
			}

			stylesInDom[item.id] = {id: item.id, refs: 1, parts: parts};
		}
	}
}

function listToStyles (list, options) {
	var styles = [];
	var newStyles = {};

	for (var i = 0; i < list.length; i++) {
		var item = list[i];
		var id = options.base ? item[0] + options.base : item[0];
		var css = item[1];
		var media = item[2];
		var sourceMap = item[3];
		var part = {css: css, media: media, sourceMap: sourceMap};

		if(!newStyles[id]) styles.push(newStyles[id] = {id: id, parts: [part]});
		else newStyles[id].parts.push(part);
	}

	return styles;
}

function insertStyleElement (options, style) {
	var target = getElement(options.insertInto)

	if (!target) {
		throw new Error("Couldn't find a style target. This probably means that the value for the 'insertInto' parameter is invalid.");
	}

	var lastStyleElementInsertedAtTop = stylesInsertedAtTop[stylesInsertedAtTop.length - 1];

	if (options.insertAt === "top") {
		if (!lastStyleElementInsertedAtTop) {
			target.insertBefore(style, target.firstChild);
		} else if (lastStyleElementInsertedAtTop.nextSibling) {
			target.insertBefore(style, lastStyleElementInsertedAtTop.nextSibling);
		} else {
			target.appendChild(style);
		}
		stylesInsertedAtTop.push(style);
	} else if (options.insertAt === "bottom") {
		target.appendChild(style);
	} else if (typeof options.insertAt === "object" && options.insertAt.before) {
		var nextSibling = getElement(options.insertInto + " " + options.insertAt.before);
		target.insertBefore(style, nextSibling);
	} else {
		throw new Error("[Style Loader]\n\n Invalid value for parameter 'insertAt' ('options.insertAt') found.\n Must be 'top', 'bottom', or Object.\n (https://github.com/webpack-contrib/style-loader#insertat)\n");
	}
}

function removeStyleElement (style) {
	if (style.parentNode === null) return false;
	style.parentNode.removeChild(style);

	var idx = stylesInsertedAtTop.indexOf(style);
	if(idx >= 0) {
		stylesInsertedAtTop.splice(idx, 1);
	}
}

function createStyleElement (options) {
	var style = document.createElement("style");

	options.attrs.type = "text/css";

	addAttrs(style, options.attrs);
	insertStyleElement(options, style);

	return style;
}

function createLinkElement (options) {
	var link = document.createElement("link");

	options.attrs.type = "text/css";
	options.attrs.rel = "stylesheet";

	addAttrs(link, options.attrs);
	insertStyleElement(options, link);

	return link;
}

function addAttrs (el, attrs) {
	Object.keys(attrs).forEach(function (key) {
		el.setAttribute(key, attrs[key]);
	});
}

function addStyle (obj, options) {
	var style, update, remove, result;

	// If a transform function was defined, run it on the css
	if (options.transform && obj.css) {
	    result = options.transform(obj.css);

	    if (result) {
	    	// If transform returns a value, use that instead of the original css.
	    	// This allows running runtime transformations on the css.
	    	obj.css = result;
	    } else {
	    	// If the transform function returns a falsy value, don't add this css.
	    	// This allows conditional loading of css
	    	return function() {
	    		// noop
	    	};
	    }
	}

	if (options.singleton) {
		var styleIndex = singletonCounter++;

		style = singleton || (singleton = createStyleElement(options));

		update = applyToSingletonTag.bind(null, style, styleIndex, false);
		remove = applyToSingletonTag.bind(null, style, styleIndex, true);

	} else if (
		obj.sourceMap &&
		typeof URL === "function" &&
		typeof URL.createObjectURL === "function" &&
		typeof URL.revokeObjectURL === "function" &&
		typeof Blob === "function" &&
		typeof btoa === "function"
	) {
		style = createLinkElement(options);
		update = updateLink.bind(null, style, options);
		remove = function () {
			removeStyleElement(style);

			if(style.href) URL.revokeObjectURL(style.href);
		};
	} else {
		style = createStyleElement(options);
		update = applyToTag.bind(null, style);
		remove = function () {
			removeStyleElement(style);
		};
	}

	update(obj);

	return function updateStyle (newObj) {
		if (newObj) {
			if (
				newObj.css === obj.css &&
				newObj.media === obj.media &&
				newObj.sourceMap === obj.sourceMap
			) {
				return;
			}

			update(obj = newObj);
		} else {
			remove();
		}
	};
}

var replaceText = (function () {
	var textStore = [];

	return function (index, replacement) {
		textStore[index] = replacement;

		return textStore.filter(Boolean).join('\n');
	};
})();

function applyToSingletonTag (style, index, remove, obj) {
	var css = remove ? "" : obj.css;

	if (style.styleSheet) {
		style.styleSheet.cssText = replaceText(index, css);
	} else {
		var cssNode = document.createTextNode(css);
		var childNodes = style.childNodes;

		if (childNodes[index]) style.removeChild(childNodes[index]);

		if (childNodes.length) {
			style.insertBefore(cssNode, childNodes[index]);
		} else {
			style.appendChild(cssNode);
		}
	}
}

function applyToTag (style, obj) {
	var css = obj.css;
	var media = obj.media;

	if(media) {
		style.setAttribute("media", media)
	}

	if(style.styleSheet) {
		style.styleSheet.cssText = css;
	} else {
		while(style.firstChild) {
			style.removeChild(style.firstChild);
		}

		style.appendChild(document.createTextNode(css));
	}
}

function updateLink (link, options, obj) {
	var css = obj.css;
	var sourceMap = obj.sourceMap;

	/*
		If convertToAbsoluteUrls isn't defined, but sourcemaps are enabled
		and there is no publicPath defined then lets turn convertToAbsoluteUrls
		on by default.  Otherwise default to the convertToAbsoluteUrls option
		directly
	*/
	var autoFixUrls = options.convertToAbsoluteUrls === undefined && sourceMap;

	if (options.convertToAbsoluteUrls || autoFixUrls) {
		css = fixUrls(css);
	}

	if (sourceMap) {
		// http://stackoverflow.com/a/26603875
		css += "\n/*# sourceMappingURL=data:application/json;base64," + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))) + " */";
	}

	var blob = new Blob([css], { type: "text/css" });

	var oldSrc = link.href;

	link.href = URL.createObjectURL(blob);

	if(oldSrc) URL.revokeObjectURL(oldSrc);
}


/***/ }),
/* 126 */
/***/ (function(module, exports) {


/**
 * When source maps are enabled, `style-loader` uses a link element with a data-uri to
 * embed the css on the page. This breaks all relative urls because now they are relative to a
 * bundle instead of the current page.
 *
 * One solution is to only use full urls, but that may be impossible.
 *
 * Instead, this function "fixes" the relative urls to be absolute according to the current page location.
 *
 * A rudimentary test suite is located at `test/fixUrls.js` and can be run via the `npm test` command.
 *
 */

module.exports = function (css) {
  // get current location
  var location = typeof window !== "undefined" && window.location;

  if (!location) {
    throw new Error("fixUrls requires window.location");
  }

	// blank or null?
	if (!css || typeof css !== "string") {
	  return css;
  }

  var baseUrl = location.protocol + "//" + location.host;
  var currentDir = baseUrl + location.pathname.replace(/\/[^\/]*$/, "/");

	// convert each url(...)
	/*
	This regular expression is just a way to recursively match brackets within
	a string.

	 /url\s*\(  = Match on the word "url" with any whitespace after it and then a parens
	   (  = Start a capturing group
	     (?:  = Start a non-capturing group
	         [^)(]  = Match anything that isn't a parentheses
	         |  = OR
	         \(  = Match a start parentheses
	             (?:  = Start another non-capturing groups
	                 [^)(]+  = Match anything that isn't a parentheses
	                 |  = OR
	                 \(  = Match a start parentheses
	                     [^)(]*  = Match anything that isn't a parentheses
	                 \)  = Match a end parentheses
	             )  = End Group
              *\) = Match anything and then a close parens
          )  = Close non-capturing group
          *  = Match anything
       )  = Close capturing group
	 \)  = Match a close parens

	 /gi  = Get all matches, not the first.  Be case insensitive.
	 */
	var fixedCss = css.replace(/url\s*\(((?:[^)(]|\((?:[^)(]+|\([^)(]*\))*\))*)\)/gi, function(fullMatch, origUrl) {
		// strip quotes (if they exist)
		var unquotedOrigUrl = origUrl
			.trim()
			.replace(/^"(.*)"$/, function(o, $1){ return $1; })
			.replace(/^'(.*)'$/, function(o, $1){ return $1; });

		// already a full url? no change
		if (/^(#|data:|http:\/\/|https:\/\/|file:\/\/\/)/i.test(unquotedOrigUrl)) {
		  return fullMatch;
		}

		// convert the url to a full url
		var newUrl;

		if (unquotedOrigUrl.indexOf("//") === 0) {
		  	//TODO: should we add protocol?
			newUrl = unquotedOrigUrl;
		} else if (unquotedOrigUrl.indexOf("/") === 0) {
			// path should be relative to the base url
			newUrl = baseUrl + unquotedOrigUrl; // already starts with '/'
		} else {
			// path should be relative to current directory
			newUrl = currentDir + unquotedOrigUrl.replace(/^\.\//, ""); // Strip leading './'
		}

		// send back the fixed url(...)
		return "url(" + JSON.stringify(newUrl) + ")";
	});

	// send back the fixed css
	return fixedCss;
};


/***/ })
],[49]);
//# sourceMappingURL=landing.entry.hash_269d3ee9a7b4a5fc0843.js.map