<commit_before>var utils = require('./utils.js');

module.exports = function rejoinRuleset(node, parent, array, i) {
    var selector = node.selector.selectors;
    var block = node.block.declarations;

    if (!block.length) {
        return null;
    }

    var nodeCompareMarker = selector[0].info.compareMarker;
    var skippedCompareMarkers = {};

    for (i = i + 1; i < array.length; i++) {
        var next = array[i];

        if (next.type !== 'Ruleset') {
            return;
        }

        if (node.info.pseudoSignature !== next.info.pseudoSignature) {
            return;
        }

        var nextFirstSelector = next.selector.selectors[0];
        var nextBlock = next.block.declarations;
        var nextCompareMarker = nextFirstSelector.info.compareMarker;

        // if next ruleset has same marked as one of skipped then stop joining
        if (nextCompareMarker in skippedCompareMarkers) {
            return;
        }

        // try to join by selectors
        if (selector.length === 1) {
            if (selector[0].info.s === nextFirstSelector.info.s) {
                block.push.apply(block, nextBlock);
                array.splice(i, 1);
                i--;

                continue;
            }
        }

        if (!utils.isCompatibleSignatures(node, next)) {
            return;
        }

        // try to join by properties
        if (block.length === nextBlock.length) {
            var equalBlocks = true;

            for (var j = 0; j < block.length; j++) {
                if (block[j].info.s !== nextBlock[j].info.s) {
                    equalBlocks = false;
                    break;
                }
            }

            if (equalBlocks) {
                var nextStr = nextFirstSelector.info.s;

                for (var j = selector.length; j >= 0; j--) {
                    if (!j || nextStr > selector[j - 1].info.s) {
                        selector.splice(j, 0, nextFirstSelector);
                        break;
                    }
                }

                array.splice(i, 1);
                i--;

                continue;
            }
        }

        // go to next ruleset if current one can be skipped (has no equal specificity nor element selector)
        if (nextCompareMarker === nodeCompareMarker) {
            return;
        }

        skippedCompareMarkers[nextCompareMarker] = true;
    }
};<commit_msg>avoid selector duplicates when join blocks<commit_after>var utils = require('./utils.js');

module.exports = function rejoinRuleset(node, parent, array, i) {
    var selector = node.selector.selectors;
    var block = node.block.declarations;

    if (!block.length) {
        return null;
    }

    var nodeCompareMarker = selector[0].info.compareMarker;
    var skippedCompareMarkers = {};

    for (i = i + 1; i < array.length; i++) {
        var next = array[i];

        if (next.type !== 'Ruleset') {
            return;
        }

        if (node.info.pseudoSignature !== next.info.pseudoSignature) {
            return;
        }

        var nextFirstSelector = next.selector.selectors[0];
        var nextBlock = next.block.declarations;
        var nextCompareMarker = nextFirstSelector.info.compareMarker;

        // if next ruleset has same marked as one of skipped then stop joining
        if (nextCompareMarker in skippedCompareMarkers) {
            return;
        }

        // try to join by selectors
        if (selector.length === 1) {
            if (selector[0].info.s === nextFirstSelector.info.s) {
                block.push.apply(block, nextBlock);
                array.splice(i, 1);
                i--;

                continue;
            }
        }

        if (!utils.isCompatibleSignatures(node, next)) {
            return;
        }

        // try to join by properties
        if (block.length === nextBlock.length) {
            var equalBlocks = true;

            for (var j = 0; j < block.length; j++) {
                if (block[j].info.s !== nextBlock[j].info.s) {
                    equalBlocks = false;
                    break;
                }
            }

            if (equalBlocks) {
                var nextStr = nextFirstSelector.info.s;

                for (var j = selector.length; j >= 0; j--) {
                    var curStr = j ? selector[j - 1].info.s : null;

                    if (nextStr === curStr) {
                        break;
                    }

                    if (!curStr || nextStr > curStr) {
                        selector.splice(j, 0, nextFirstSelector);
                        break;
                    }
                }

                array.splice(i, 1);
                i--;

                continue;
            }
        }

        // go to next ruleset if current one can be skipped (has no equal specificity nor element selector)
        if (nextCompareMarker === nodeCompareMarker) {
            return;
        }

        skippedCompareMarkers[nextCompareMarker] = true;
    }
};
{'fraction_non_alphanumeric': 0.10705012981825444, 'fraction_numerical': 0.00439384861194328, 'mean_word_length': 1.3836268443598287, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, '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': '3511545', 'n_tokens_mistral': 1401, 'n_tokens_neox': 1297, 'n_words': 338}