<commit_before>/**
    Enum for view status.
    @enum {number}
*/
no.viewStatus = {
    unknown: undefined,
    ok: 1,
    loading: 2,
    error: 3,
    failed: 4
};
// ----------------------------------------------------------------------------------------------------------------- //

/**
    @constructor
    @param {string} id          Уникальный id класса. Важно! Это не id инстанса, у всех блоков этого класса один id.
    @param {!Object} params     Параметры блока (участвуют при построении ключа).
    @param {no.View=} parent    Родительский view.
*/
no.View = function(id, params, parent) {
    this.init(id, params, parent);
}

/**
    Метод инициализации view. Нужен такой отдельный метод, чтобы было проще наследоваться.
    @param {string} id          Уникальный id класса. Важно! Это не id инстанса, у всех блоков этого класса один id.
    @param {!Object} params     Параметры блока (участвуют при построении ключа).
    @param {no.View=} parent    Родительский view.
*/
no.View.prototype.init = function(id, params, parent) {
    this.id = id;
    this.params = params;
    this.parent = parent || null;

    var info = this.info = no.View.info(id);

    /** @type { Object.<string, { type, view: no.View }> } */
    var views = this.views = {};

    var layout = info.layout;
    for (var view_id in layout) {
        var type = layout[ view_id ];

        var view = (type === null) ? this.subBox( view_id, params ) : this.subView( view_id, params );
        views[ view_id ] = view;
    }

    /** @type {Element} */
    this.node;

    /** @type {no.viewStatus|undefined} */
    this.status;

    return this;
};

// ----------------------------------------------------------------------------------------------------------------- //

no.View._cache = {};

// ----------------------------------------------------------------------------------------------------------------- //

/**
    @typedef {function(
        new:no.View,
        string,
        !Object
    )}
*/
no.View.type_class;

// ----------------------------------------------------------------------------------------------------------------- //

/**
    @typedef {{
        layout: Object,
        models: Object
    }}
*/
no.View.type_info;

// ----------------------------------------------------------------------------------------------------------------- //

/** @type { Object.<string, no.View.type_info> } */
no.View._infos = {};

/** @type { Object.<string, no.View.type_class> } */
no.View._classes = {};

// ----------------------------------------------------------------------------------------------------------------- //

/**
    @param {string} id
    @param {no.View.type_info=} info
    @param {no.View.type_class=} class_
*/
no.View.register = function(id, info, class_) {
    info = info || {};
    class_ = class_ || no.View;

    var models = info.models = info.models || [];

    var keyParams = {};
    for (var i = 0, l = info.models.length; i < l; i++) {
        var model_id = info.models[i];
        no.extend( keyParams, no.Model.info( model_id ).keyParams );
    }

    var layout = info.layout = info.layout || {};

    for (var view_id in layout) {<commit_msg>no.View now has keyParams too<commit_after>/**
    Enum for view status.
    @enum {number}
*/
no.viewStatus = {
    unknown: undefined,
    ok: 1,
    loading: 2,
    error: 3,
    failed: 4
};
// ----------------------------------------------------------------------------------------------------------------- //

/**
    @constructor
    @param {string} id          Уникальный id класса. Важно! Это не id инстанса, у всех блоков этого класса один id.
    @param {!Object} params     Параметры блока (участвуют при построении ключа).
    @param {no.View=} parent    Родительский view.
*/
no.View = function(id, params, parent) {
    this.init(id, params, parent);
}

/**
    Метод инициализации view. Нужен такой отдельный метод, чтобы было проще наследоваться.
    @param {string} id          Уникальный id класса. Важно! Это не id инстанса, у всех блоков этого класса один id.
    @param {!Object} params     Параметры блока (участвуют при построении ключа).
    @param {no.View=} parent    Родительский view.
*/
no.View.prototype.init = function(id, params, parent) {
    this.id = id;
    this.params = params;
    this.parent = parent || null;

    var info = this.info = no.View.info(id);

    /** @type { Object.<string, { type, view: no.View }> } */
    var views = this.views = {};

    var layout = info.layout;
    for (var view_id in layout) {
        var type = layout[ view_id ];

        var view = (type === null) ? this.subBox( view_id, params ) : this.subView( view_id, params );
        views[ view_id ] = view;
    }

    /** @type {Element} */
    this.node;

    /** @type {no.viewStatus|undefined} */
    this.status;

    return this;
};

// ----------------------------------------------------------------------------------------------------------------- //

no.View._cache = {};

// ----------------------------------------------------------------------------------------------------------------- //

/**
    @typedef {function(
        new:no.View,
        string,
        !Object
    )}
*/
no.View.type_class;

// ----------------------------------------------------------------------------------------------------------------- //

/**
    @typedef {{
        layout: Object,
        models: Object
    }}
*/
no.View.type_info;

// ----------------------------------------------------------------------------------------------------------------- //

/** @type { Object.<string, no.View.type_info> } */
no.View._infos = {};

/** @type { Object.<string, no.View.type_class> } */
no.View._classes = {};

// ----------------------------------------------------------------------------------------------------------------- //

/**
    @param {string} id
    @param {no.View.type_info=} info
    @param {no.View.type_class=} class_
*/
no.View.register = function(id, info, class_) {
    info = info || {};
    class_ = class_ || no.View;

    var models = info.models = info.models || [];

    var keyParams = info.keyParams || {};
    for (var i = 0, l = info.models.length; i < l; i++) {
        var model_id = info.models[i];
        no.extend( keyParams, no.Model.info( model_id ).keyParams );
    }

    var layout = info.layout = info.layout || {};

    for (var view_id in layout) {
{'fraction_non_alphanumeric': 0.3376095118898623, 'fraction_numerical': 0.0015644555694618273, 'mean_word_length': 1.2006884681583476, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '64863', 'n_tokens_mistral': 1823, 'n_tokens_neox': 1864, 'n_words': 461}