'use strict';

// MODULES //

var getKeys = require( 'object-keys' ).shim();
var vdom2html = require( 'vdom-to-html' );
var hasOwnProp = require( '@stdlib/assert/has-own-property' );
var deepGet = require( '@stdlib/utils/deep-get' );
var setReadOnly = require( '@stdlib/utils/define-read-only-property' );
var namespace = require( '@stdlib/namespace' );
var docs = require( '@stdlib/repl/help' );


// VARIABLES //

var NO_HELP_TEXT = 'No help information available.';
var NAMESPACE = namespace();
var DOCS = docs();


// FUNCTIONS //

/**
* Prints help information.
*
* @private
* @param {*} alias - variable alias or value
*/
function help( alias ) {
	var txt;
	var i;

	// First check if provided an alias...
	if ( hasOwnProp( DOCS, alias ) ) {
		txt = DOCS[ alias ];
	} else {
		// Search through namespace values to see if provided a known value reference...
		for ( i = 0; i < NAMESPACE.length; i++ ) {
			if ( alias === NAMESPACE[ i ].value ) {
				if ( hasOwnProp( DOCS, NAMESPACE[ i ].alias ) ) {
					txt = DOCS[ NAMESPACE[ i ].alias ];
				}
				break;
			}
		}
		// If still unable to resolve help info, inform the user that no info is available...
		if ( txt === void 0 ) {
			txt = NO_HELP_TEXT;
		}
	}
	console.log( txt );
} // end FUNCTION help()

/**
* Prints the list of namespace aliases.
*
* @private
*/
function ns() {
	var keys;
	var i;

	keys = getKeys( DOCS );
	for ( i = 0; i < keys.length; i++ ) {
		console.log( keys[ i ] );
	}
} // end FUNCTION ns()


// MAIN //

/**
* Extends the browser global namespace.
*
* @private
*/
function main() {
	var paths;
	var parts;
	var keys;
	var tmp;
	var key;
	var o;
	var i;
	var j;
	var k;

	// Create an object tree from value aliases...
	tmp = {
		'help': help,
		'_help': help, // Firefox devtools already aliases `help` (and `?`) to a read-only value :(
		'require': require,
		'namespace': ns
	};
	paths = [];
	for ( i = 0; i < NAMESPACE.length; i++ ) {
		o = tmp;

		// Get the alias of the value to be added to the global context:
		key = NAMESPACE[ i ].alias;

		// Cache the alias path:
		paths.push( key );

		// An alias may be nested (e.g., `a.b.c`); if so, we need to recursively generate parent sub-trees...
		parts = key.split( '.' );
		for ( j = 0; j < parts.length-1; j++ ) {
			k = parts[ j ];
			if ( !hasOwnProp( o, k ) ) {
				o[ k ] = {};
			}
			o = o[ k ];
		}
		k = parts[ j ];

		// Attempt to add the value to the tree (checking for collisions):
		if ( hasOwnProp( o, k ) ) {
			throw new Error( 'invalid operation. Alias already exists in the global context. Alias: `'+key+'`. Value: `'+deepGet( tmp, key )+'`.' );
		} else {
			o[ k ] = NAMESPACE[ i ].value;
		}
	}
	// Walk the context tree and set each nested path to read-only...
	for ( i = 0; i < paths.length; i++ ) {
		parts = paths[ i ].split( '.' );
		if ( parts.length > 1 ) {
			o = tmp;
			for ( j = 0; j < parts.length; j++ ) {
				k = parts[ j ];
				setReadOnly( o, k, o[ k ] );
				o = o[ k ];
			}
		}
	}
	// Extend the global context...
	keys = getKeys( tmp );
	for ( i = 0; i < keys.length; i++ ) {
		key = keys[ i ];
		setReadOnly( global, key, tmp[ key ] );
	}
	// Include any additional third party libraries...
	setReadOnly( global, 'vdom2html', vdom2html );
} // end FUNCTION main()

main();

@@ -1230,16 +1230,50 @@
 ( txt );
+ // eslint-disable-line no-console
 %0A%7D // en
@@ -1474,24 +1474,58 @@
 keys%5B i %5D );
+ // eslint-disable-line no-console
 %0A%09%7D%0A%7D // end

Disable console warnings