<commit_before>'use strict';

/*!
 * Snakeskin
 * https://github.com/SnakeskinTpl/Snakeskin
 *
 * Released under the MIT license
 * https://github.com/SnakeskinTpl/Snakeskin/blob/master/LICENSE
 */

import Parser from './constructor';
import { r } from '../helpers/string';
import { any } from '../helpers/gcc';
import { HAS_CONSOLE_ERROR } from '../consts/hacks';
import { LEFT_BOUND, RIGHT_BOUND, ADV_LEFT_BOUND } from '../consts/literals';

const
	cutRgxp = /\/\*!!= (.*?) =\*\//g,
	privateRgxp = new RegExp(`${r(ADV_LEFT_BOUND)}?${r(LEFT_BOUND)}__.*?__.*?${r(RIGHT_BOUND)}`, 'g'),
	styleRgxp = /\t|[ ]{4}/g;

/**
 * Returns additional information for an error
 * @return {string}
 */
Parser.prototype.getAdvInfo = function () {
	const
		{eol, info, info: {line}} = this;

	if (!info) {
		return '';
	}

	let str = '';
	for (let key in info) {
		if (!info.hasOwnProperty(key)) {
			break;
		}

		const
			el = info[key];

		if (el != null) {
			if (el.innerHTML) {
				str += `${key}: (class: ${el.className || 'undefined'}, id: ${el.id || 'undefined'}); `;

			} else {
				str += `${key}: ${el}; `;
			}
		}
	}

	str = str
		.replace(/; $/, '');

	if (line) {
		let
			prfx = '',
			max = 0;

		for (let i = 8; i--;) {
			const
				pos = line - i - 2,
				space = new Array(String(line - 1).length - String(pos).length + 1).join(' ');

			let
				prev = this.lines[pos];

			if (prev != null) {
				prev = prev
					.replace(styleRgxp, '  ')
					.replace(privateRgxp, '')
					.replace(cutRgxp, '$1');

				let part;
				if (prev.trim()) {
					part = `${eol}  ${pos + 1} ${space}${prev}`;

				} else {
					part = `${eol}  ...`;
				}

				prfx += part;
				if (max < part.length) {
					max = part.length;
				}
			}
		}

		const
			current = (this.lines[line - 1] || '')
				.replace(styleRgxp, '  ')
				.replace(privateRgxp, '')
				.replace(cutRgxp, '$1');

		const
			chunk = `> ${line} ${current}`,
			sep = new Array(Math.max(max, chunk.length) || 5).join('-');

		str += eol + sep + prfx + eol + chunk + eol + sep;
	}

	return str + eol;
};

/**
 * Returns an error object
 * @param {string} msg - error message
 */
Parser.prototype.error = function (msg) {
	this.errors.push(msg);
	this.break = true;

	const
		report = `${msg}; ${this.getAdvInfo()}`,
		error = any(Object.assign(new Error(report), {name: 'SnakeskinError'}));

	if (this.onError) {
		this.onError(error);

	} else {
		if (!HAS_CONSOLE_ERROR || this.throws) {
			throw error;<commit_msg>:wrench:<commit_after>'use strict';

/*!
 * Snakeskin
 * https://github.com/SnakeskinTpl/Snakeskin
 *
 * Released under the MIT license
 * https://github.com/SnakeskinTpl/Snakeskin/blob/master/LICENSE
 */

import Parser from './constructor';
import { r } from '../helpers/string';
import { any } from '../helpers/gcc';
import { HAS_CONSOLE_ERROR } from '../consts/hacks';
import { LEFT_BOUND, RIGHT_BOUND, ADV_LEFT_BOUND } from '../consts/literals';

const
	cutRgxp = /\/\*!!= (.*?) =\*\//g,
	privateRgxp = new RegExp(`${r(ADV_LEFT_BOUND)}?${r(LEFT_BOUND)}__.*?__.*?${r(RIGHT_BOUND)}`, 'g'),
	styleRgxp = /\t|[ ]{4}/g;

/**
 * Returns additional information for an error
 * @return {string}
 */
Parser.prototype.getAdvInfo = function () {
	const
		{eol, info, info: {line}} = this;

	if (!info) {
		return '';
	}

	let str = '';
	for (let key in info) {
		if (!info.hasOwnProperty(key)) {
			break;
		}

		const
			el = info[key];

		if (el != null) {
			if (el.innerHTML) {
				str += `${key}: (class: ${el.className || 'undefined'}, id: ${el.id || 'undefined'}); `;

			} else {
				str += `${key}: ${el}; `;
			}
		}
	}

	str = str
		.replace(/; $/, '');

	if (line) {
		let
			prfx = '',
			max = 0;

		for (let i = 8; i--;) {
			const
				pos = line - i - 2,
				space = new Array(String(line - 1).length - String(pos).length + 1).join(' ');

			let
				prev = this.lines[pos];

			if (prev != null) {
				prev = prev
					.replace(styleRgxp, '  ')
					.replace(privateRgxp, '')
					.replace(cutRgxp, '$1');

				let part;
				if (prev.trim()) {
					part = `${eol}  ${pos + 1} ${space}${prev}`;

				} else {
					part = `${eol}  ...`;
				}

				prfx += part;
				if (max < part.length) {
					max = part.length;
				}
			}
		}

		const
			current = (this.lines[line - 1] || '')
				.replace(styleRgxp, '  ')
				.replace(privateRgxp, '')
				.replace(cutRgxp, '$1');

		const
			chunk = `> ${line} ${current}`,
			sep = new Array(Math.max(max, chunk.length) || 5).join('-');

		str += eol + sep + prfx + eol + chunk + eol + sep;
	}

	return this.pasteDangerBlocks(str) + eol;
};

/**
 * Returns an error object
 * @param {string} msg - error message
 */
Parser.prototype.error = function (msg) {
	this.errors.push(msg);
	this.break = true;

	const
		report = `${msg}; ${this.getAdvInfo()}`,
		error = any(Object.assign(new Error(report), {name: 'SnakeskinError'}));

	if (this.onError) {
		this.onError(error);

	} else {
		if (!HAS_CONSOLE_ERROR || this.throws) {
			throw error;
{'fraction_non_alphanumeric': 0.2126587381576295, 'fraction_numerical': 0.004434589800443459, 'mean_word_length': 2.719640179910045, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 4, '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': '5768432', 'n_tokens_mistral': 2200, 'n_tokens_neox': 1913, 'n_words': 415}