require(name, from = []) {
			const L = this;
			let url = null;

			/* Class already loaded */
			if (classes[name] != null) {
				/* Circular dependency */
				if (from.indexOf(name) != -1)
					LuCI.prototype.raise('DependencyError',
						'Circular dependency: class "%s" depends on "%s"',
						name, from.join('" which depends on "'));

				return Promise.resolve(classes[name]);
			}

			url = '%s/%s.js%s'.format(env.base_url, name.replace(/\./g, '/'), (env.resource_version ? `?v=${env.resource_version}` : ''));
			from = [ name ].concat(from);

			const compileClass = res => {
				if (!res.ok)
					LuCI.prototype.raise('NetworkError',
						'HTTP error %d while loading class file "%s"', res.status, url);

				const source = res.text();
				const requirematch = /^require[ \t]+(\S+)(?:[ \t]+as[ \t]+([a-zA-Z_]\S*))?$/;
				const strictmatch = /^use[ \t]+strict$/;
				const depends = [];
				let args = '';

				/* find require statements in source */
				for (let i = 0, off = -1, prev = -1, quote = -1, comment = -1, esc = false; i < source.length; i++) {
					const chr = source.charCodeAt(i);

					if (esc) {
						esc = false;
					}
					else if (comment != -1) {
						if ((comment == 47 && chr == 10) || (comment == 42 && prev == 42 && chr == 47))
							comment = -1;
					}
					else if ((chr == 42 || chr == 47) && prev == 47) {
						comment = chr;
					}
					else if (chr == 92) {
						esc = true;
					}
					else if (chr == quote) {
						const s = source.substring(off, i), m = requirematch.exec(s);

						if (m) {
							const dep = m[1], as = m[2] || dep.replace(/[^a-zA-Z0-9_]/g, '_');
							depends.push(LuCI.prototype.require(dep, from));
							args += `, ${as}`;
						}
						else if (!strictmatch.exec(s)) {
							break;
						}

						off = -1;
						quote = -1;
					}
					else if (quote == -1 && (chr == 34 || chr == 39)) {
						off = i + 1;
						quote = chr;
					}

					prev = chr;
				}

				/* load dependencies and instantiate class */
				return Promise.all(depends).then(instances => {
					let _factory, _class;

					try {
						_factory = eval(
							'(function(window, document, L%s) { %s })\n\n//# sourceURL=%s\n'
								.format(args, source, res.url));
					}
					catch (error) {
						LuCI.prototype.raise('SyntaxError', '%s\n  in %s:%s',
							error.message, res.url, error.lineNumber ?? '?');
					}

					_factory.displayName = toCamelCase(`${name}ClassFactory`);
					_class = _factory.apply(_factory, [window, document, L].concat(instances));

					if (!Class.isSubclass(_class))
						LuCI.prototype.error('TypeError', '"%s" factory yields invalid constructor', name);

					if (_class.displayName == 'AnonymousClass')
						_class.displayName = toCamelCase(`${name}Class`);

					let ptr = Object.getPrototypeOf(L);
					let idx = 0;
					const parts = name.split(/\./);
					const instance = new _class();

					while (ptr && idx < parts.length - 1)
						ptr = ptr[parts[idx++]];

					if (ptr)
						ptr[parts[idx]] = instance;

					classes[name] = instance;

					return instance;
				});
			};

			/* Request class file */
			classes[name] = Request.get(url, { cache: true }).then(compileClass);

			return classes[name];
		}
Load an additional LuCI JavaScript class and its dependencies,
instantiate it and return the resulting class instance. Each
class is only loaded once. Subsequent attempts to load the same
class will return the already instantiated class.

@instance
@memberof LuCI

@param {string} name
The name of the class to load in dotted notation. Dots will
be replaced by spaces and joined with the runtime-determined
base URL of LuCI.js to form an absolute URL to load the class
file from.

@throws {DependencyError}
Throws a `DependencyError` when the class to load includes
circular dependencies.

@throws {NetworkError}
Throws `NetworkError` when the underlying {@link LuCI.request}
call failed.

@throws {SyntaxError}
Throws `SyntaxError` when the loaded class file code cannot
be interpreted by `eval`.

@throws {TypeError}
Throws `TypeError` when the class file could be loaded and
interpreted, but when invoking its code did not yield a valid
class instance.

@returns {Promise<LuCI.baseclass>}
Returns the instantiated class.