function Html(args) {
        this._vm = null;

        if (debugMode && !isBrowser) {
            this._vm = require('vm');
            this._sandbox = Object.create(null);
            this._vm.createContext(this._sandbox);
        }

        // function (process,...){...}() prevents [this] to exist for the 'vm.runInNewContext()' method
        this._js = `
        'use strict';
(function (process, window, global, module, require, compilePage, compilePageSync, navigator, undefined) {
    delete Html._js;
    delete Html._vm;
    delete Html._sandbox;
    ${args.js}
}).call();`;

        // User section.
        if (debugMode)
            this.__dbg = { viewName: args.filePath, template: args.template, pos: [] }

        this.$ =
            this.layout = null;
        // Private
        let sectionName = null;
        let sections = args.parsedSections;

        this.__val = function (i) {
            return args.jsValues.getAt(i);
        };

        this.__renderLayout = (done) => {
            if (!this.layout) // if the layout is not defined..
                return Promise.resolve().then(() => done(null, args.html)), null;

            // looking for the `Layout`..
            args.er.isLayout = true; // the crutch
            args.findPartial(this.layout, args.filePath, args.er, (err, result) => {
                args.er.isLayout = false;
                if (err) return done(err);
                let compileOpt = {
                    scope: args.scope,
                    template: result.data,
                    filePath: result.filePath,
                    model: args.model,
                    bodyHtml: args.html,
                    findPartial: args.findPartial,
                    findPartialSync: args.findPartialSync,
                    parsedSections: args.parsedSections,
                    partialsCache: args.partialsCache,
                    viewData: args.viewData
                };
                compile(compileOpt, done);
            });
        };

        this.__sec = function (name) { // in section
            if (!sectionName) {
                sectionName = name;
            }
            else if (sectionName === name) {
                sections[sectionName][args.filePath].compiled = true;
                sectionName = null;
            }
            else {
                throw new Error(`Unexpected section name = '${name}'.`); // Cannot be tested via user-inputs.
            }
        };

        this.raw = function (val) { // render
            if (!isVisibleValue(val)) // 'undefined' can be passed when `Html.raw()` is used by user in the view, in this case it will be wrapped into `Html.ecnode()` anyway an it will call `Html.raw` passing 'undefined' to it.
                return;

            if (sectionName) {
                let sec = sections[sectionName][args.filePath];
                if (!sec.compiled) // it could have been compiled already if it's defined in a partial view which is rendred more than once
                    sec.html += val;
            }
            else {
                args.html += val;
            }
        };

        this.encode = function (val) {
            var encoded = this.getEncoded(val);
            this.raw(encoded);
        };

        this.getEncoded = function (val) {
            if (!isVisibleValue(val))
                return '';

            if (typeof val === "number" || val instanceof Number || val instanceof HtmlString)
                return val;

            if (String.is(val))
                return htmlEncode(val);

            return htmlEncode(val.toString());
        };

        this.body = function () {
            return new HtmlString(args.bodyHtml);
        };

        this.section = function (name, required) {
            if (!args.filePath)
                throw new Error("'args.filePath' is not set.");

            let secGroup = sections[name];

            if (secGroup) {
                if (secGroup.renderedBy)
                    throw args.er.sectionsAlreadyRendered(name, secGroup.renderedBy, args.filePath); // TESTME:

                let html = '';

                for (var key in secGroup) {
                    if (secGroup.hasOwnProperty(key)) {
                        let sec = secGroup[key];

                        if (!sec.compiled)
                            throw args.er.sectionIsNotCompiled(name, args.filePath); // [#3.2]

                        html += sec.html;
                    }
                }

                secGroup.renderedBy = args.filePath;
                return new HtmlString(html);
            }
            else {
                if (required)
                    throw args.er.sectionIsNotFound(name, args.filePath); // [#3.3]
            }

            return '';
        };

        this.getPartial = function (viewName, viewModel) {
            let compileOpt = {
                scope: args.scope,
                model: viewModel === undefined ? args.model : viewModel, // if is not set explicitly, set default (parent) model
                findPartial: args.findPartial,
                findPartialSync: args.findPartialSync,
                sections,
                parsedSections: args.parsedSections,
                partialsCache: args.partialsCache,
                viewData: args.viewData
            };

            // Read file and complie to JS.
            let partial = args.findPartialSync(viewName, args.filePath, args.er, args.partialsCache);
            compileOpt.template = partial.data;
            compileOpt.filePath = partial.filePath;

            if (partial.js) { // if it's taken from cache
                compileOpt.js = partial.js;
                compileOpt.jsValues = partial.jsValues;
            }

            let { html, precompiled } = compileSync(compileOpt);
            partial.js = precompiled.js; // put to cache
            partial.jsValues = precompiled.jsValues; // put to cache

            return html;
        };

        this.partial = function (viewName, viewModel) {
            var partialHtml = this.getPartial(viewName, viewModel);
            this.raw(partialHtml)
        };
    }
function Html(args) {
        this._vm = null;

        if (debugMode && !isBrowser) {
            this._vm = require('vm');
            this._sandbox = Object.create(null);
            this._vm.createContext(this._sandbox);
        }

        
        this._js = `
        'use strict';
(function (process, window, global, module, require, compilePage, compilePageSync, navigator, undefined) {
    delete Html._js;
    delete Html._vm;
    delete Html._sandbox;
    ${args.js}
}).call();`;

        
        if (debugMode)
            this.__dbg = { viewName: args.filePath, template: args.template, pos: [] }

        this.$ =
            this.layout = null;
        
        let sectionName = null;
        let sections = args.parsedSections;

        this.__val = function (i) {
            return args.jsValues.getAt(i);
        };

        this.__renderLayout = (done) => {
            if (!this.layout) 
                return Promise.resolve().then(() => done(null, args.html)), null;

            
            args.er.isLayout = true; 
            args.findPartial(this.layout, args.filePath, args.er, (err, result) => {
                args.er.isLayout = false;
                if (err) return done(err);
                let compileOpt = {
                    scope: args.scope,
                    template: result.data,
                    filePath: result.filePath,
                    model: args.model,
                    bodyHtml: args.html,
                    findPartial: args.findPartial,
                    findPartialSync: args.findPartialSync,
                    parsedSections: args.parsedSections,
                    partialsCache: args.partialsCache,
                    viewData: args.viewData
                };
                compile(compileOpt, done);
            });
        };

        this.__sec = function (name) { 
            if (!sectionName) {
                sectionName = name;
            }
            else if (sectionName === name) {
                sections[sectionName][args.filePath].compiled = true;
                sectionName = null;
            }
            else {
                throw new Error(`Unexpected section name = '${name}'.`); 
            }
        };

        this.raw = function (val) { 
            if (!isVisibleValue(val)) 
                return;

            if (sectionName) {
                let sec = sections[sectionName][args.filePath];
                if (!sec.compiled) 
                    sec.html += val;
            }
            else {
                args.html += val;
            }
        };

        this.encode = function (val) {
            var encoded = this.getEncoded(val);
            this.raw(encoded);
        };

        this.getEncoded = function (val) {
            if (!isVisibleValue(val))
                return '';

            if (typeof val === "number" || val instanceof Number || val instanceof HtmlString)
                return val;

            if (String.is(val))
                return htmlEncode(val);

            return htmlEncode(val.toString());
        };

        this.body = function () {
            return new HtmlString(args.bodyHtml);
        };

        this.section = function (name, required) {
            if (!args.filePath)
                throw new Error("'args.filePath' is not set.");

            let secGroup = sections[name];

            if (secGroup) {
                if (secGroup.renderedBy)
                    throw args.er.sectionsAlreadyRendered(name, secGroup.renderedBy, args.filePath); 

                let html = '';

                for (var key in secGroup) {
                    if (secGroup.hasOwnProperty(key)) {
                        let sec = secGroup[key];

                        if (!sec.compiled)
                            throw args.er.sectionIsNotCompiled(name, args.filePath); 

                        html += sec.html;
                    }
                }

                secGroup.renderedBy = args.filePath;
                return new HtmlString(html);
            }
            else {
                if (required)
                    throw args.er.sectionIsNotFound(name, args.filePath); 
            }

            return '';
        };

        this.getPartial = function (viewName, viewModel) {
            let compileOpt = {
                scope: args.scope,
                model: viewModel === undefined ? args.model : viewModel, 
                findPartial: args.findPartial,
                findPartialSync: args.findPartialSync,
                sections,
                parsedSections: args.parsedSections,
                partialsCache: args.partialsCache,
                viewData: args.viewData
            };

            
            let partial = args.findPartialSync(viewName, args.filePath, args.er, args.partialsCache);
            compileOpt.template = partial.data;
            compileOpt.filePath = partial.filePath;

            if (partial.js) { 
                compileOpt.js = partial.js;
                compileOpt.jsValues = partial.jsValues;
            }

            let { html, precompiled } = compileSync(compileOpt);
            partial.js = precompiled.js; 
            partial.jsValues = precompiled.jsValues; 

            return html;
        };

        this.partial = function (viewName, viewModel) {
            var partialHtml = this.getPartial(viewName, viewModel);
            this.raw(partialHtml)
        };
    }
function Html ( args ) { this . _vm = null ; if ( debugMode && ! isBrowser ) { this . _vm = require ( 'vm' ) ; this . _sandbox = Object . create ( null ) ; this . _vm . createContext ( this . _sandbox ) ; } // function (process,...){...}() prevents [this] to exist for the 'vm.runInNewContext()' method this . _js = ` ${ args . js } ` ; // User section. if ( debugMode ) this . __dbg = { viewName : args . filePath , template : args . template , pos : [ ] } this . $ = this . layout = null ; // Private let sectionName = null ; let sections = args . parsedSections ; this . __val = function ( i ) { return args . jsValues . getAt ( i ) ; } ; this . __renderLayout = ( done ) => { if ( ! this . layout ) // if the layout is not defined.. return Promise . resolve ( ) . then ( ( ) => done ( null , args . html ) ) , null ; // looking for the `Layout`.. args . er . isLayout = true ; // the crutch args . findPartial ( this . layout , args . filePath , args . er , ( err , result ) => { args . er . isLayout = false ; if ( err ) return done ( err ) ; let compileOpt = { scope : args . scope , template : result . data , filePath : result . filePath , model : args . model , bodyHtml : args . html , findPartial : args . findPartial , findPartialSync : args . findPartialSync , parsedSections : args . parsedSections , partialsCache : args . partialsCache , viewData : args . viewData } ; compile ( compileOpt , done ) ; } ) ; } ; this . __sec = function ( name ) { // in section if ( ! sectionName ) { sectionName = name ; } else if ( sectionName === name ) { sections [ sectionName ] [ args . filePath ] . compiled = true ; sectionName = null ; } else { throw new Error ( ` ${ name } ` ) ; // Cannot be tested via user-inputs. } } ; this . raw = function ( val ) { // render if ( ! isVisibleValue ( val ) ) // 'undefined' can be passed when `Html.raw()` is used by user in the view, in this case it will be wrapped into `Html.ecnode()` anyway an it will call `Html.raw` passing 'undefined' to it. return ; if ( sectionName ) { let sec = sections [ sectionName ] [ args . filePath ] ; if ( ! sec . compiled ) // it could have been compiled already if it's defined in a partial view which is rendred more than once sec . html += val ; } else { args . html += val ; } } ; this . encode = function ( val ) { var encoded = this . getEncoded ( val ) ; this . raw ( encoded ) ; } ; this . getEncoded = function ( val ) { if ( ! isVisibleValue ( val ) ) return '' ; if ( typeof val === "number" || val instanceof Number || val instanceof HtmlString ) return val ; if ( String . is ( val ) ) return htmlEncode ( val ) ; return htmlEncode ( val . toString ( ) ) ; } ; this . body = function ( ) { return new HtmlString ( args . bodyHtml ) ; } ; this . section = function ( name , required ) { if ( ! args . filePath ) throw new Error ( "'args.filePath' is not set." ) ; let secGroup = sections [ name ] ; if ( secGroup ) { if ( secGroup . renderedBy ) throw args . er . sectionsAlreadyRendered ( name , secGroup . renderedBy , args . filePath ) ; // TESTME: let html = '' ; for ( var key in secGroup ) { if ( secGroup . hasOwnProperty ( key ) ) { let sec = secGroup [ key ] ; if ( ! sec . compiled ) throw args . er . sectionIsNotCompiled ( name , args . filePath ) ; // [#3.2] html += sec . html ; } } secGroup . renderedBy = args . filePath ; return new HtmlString ( html ) ; } else { if ( required ) throw args . er . sectionIsNotFound ( name , args . filePath ) ; // [#3.3] } return '' ; } ; this . getPartial = function ( viewName , viewModel ) { let compileOpt = { scope : args . scope , model : viewModel === undefined ? args . model : viewModel , // if is not set explicitly, set default (parent) model findPartial : args . findPartial , findPartialSync : args . findPartialSync , sections , parsedSections : args . parsedSections , partialsCache : args . partialsCache , viewData : args . viewData } ; // Read file and complie to JS. let partial = args . findPartialSync ( viewName , args . filePath , args . er , args . partialsCache ) ; compileOpt . template = partial . data ; compileOpt . filePath = partial . filePath ; if ( partial . js ) { // if it's taken from cache compileOpt . js = partial . js ; compileOpt . jsValues = partial . jsValues ; } let { html , precompiled } = compileSync ( compileOpt ) ; partial . js = precompiled . js ; // put to cache partial . jsValues = precompiled . jsValues ; // put to cache return html ; } ; this . partial = function ( viewName , viewModel ) { var partialHtml = this . getPartial ( viewName , viewModel ) ; this . raw ( partialHtml ) } ; }
////////////////// /   Html class //////////////////
////////////////// / Html class //////////////////