<commit_before>import { ContentChildren, Directive, EventEmitter, HostBinding, HostListener, Input, OnChanges, OnDestroy, OnInit, Output, QueryList, Self } from '@angular/core';
import { SelectionAreaConfig, SelectionEventsHelper, SelectionItem } from 'e2e4';

import { OnDeselectedEvent } from './contract/on-deselected-event';
import { OnSelectedEvent } from './contract/on-selected-event';
import { OnSelectionChangedEvent } from './contract/on-selection-changed-event';
import { SelectionEventsEmitter } from './contract/selection-events-emitter';
import { RtSelectionService } from './selection-service';

@Directive({
    providers: [RtSelectionService],
    selector: '[rtSelectionAreaFor]'
})
export class SelectionAreaForDirective implements SelectionEventsEmitter, OnInit, OnChanges, OnDestroy, SelectionAreaConfig {
    @ContentChildren(SelectionAreaForDirective) public childSelectionAreas: QueryList<SelectionAreaForDirective>;
    private tabIndexPrivate: number;
    public selectionEventsHelper: SelectionEventsHelper;

    @Input() public horizontal: boolean = false;
    @Input() public multiple: boolean = true;
    @Input('rtSelectionAreaFor') public items: Array<SelectionItem>;
    @Input() public autoSelectFirst: boolean = false;
    @Input() public toggleOnly: boolean = false;
    @Input() public set trackBy(value: (index: number, item: any) => any) {
        if (typeof value !== 'function') {
            throw new Error('trackBy parameter value must be a function');
        }
        this.selectionService.trackByFn = value;
    }
    @Output() public itemSelected: EventEmitter<OnSelectedEvent> = new EventEmitter<OnSelectedEvent>();
    @Output() public itemDeselected: EventEmitter<OnDeselectedEvent> = new EventEmitter<OnDeselectedEvent>();
    @Output() public selectionChanged: EventEmitter<OnSelectionChangedEvent> = new EventEmitter<OnSelectionChangedEvent>();

    constructor( @Self() public selectionService: RtSelectionService) {
        this.selectionService.areaEventsEmitter = this;
        this.selectionEventsHelper = new SelectionEventsHelper(this);
    }
    public ngOnDestroy(): void {
        this.selectionService.destroy();
    }
    public ngOnChanges(changes: any): void {
        // we doesn't set itemsSource to empty arrays to keep selection when trackByFn is provided
        // it's must not be a problem since on destroy selections will be destroyed by this component <commit_msg>chore(selection): use `SimpleChange` for better typing<commit_after>import { ContentChildren, Directive, EventEmitter, HostBinding, HostListener, Input, OnChanges, OnDestroy, OnInit, Output, QueryList, Self, SimpleChange } from '@angular/core';
import { SelectionAreaConfig, SelectionEventsHelper, SelectionItem } from 'e2e4';

import { OnDeselectedEvent } from './contract/on-deselected-event';
import { OnSelectedEvent } from './contract/on-selected-event';
import { OnSelectionChangedEvent } from './contract/on-selection-changed-event';
import { SelectionEventsEmitter } from './contract/selection-events-emitter';
import { RtSelectionService } from './selection-service';

@Directive({
    providers: [RtSelectionService],
    selector: '[rtSelectionAreaFor]'
})
export class SelectionAreaForDirective implements SelectionEventsEmitter, OnInit, OnChanges, OnDestroy, SelectionAreaConfig {
    @ContentChildren(SelectionAreaForDirective) public childSelectionAreas: QueryList<SelectionAreaForDirective>;
    private tabIndexPrivate: number;
    public selectionEventsHelper: SelectionEventsHelper;

    @Input() public horizontal: boolean = false;
    @Input() public multiple: boolean = true;
    @Input('rtSelectionAreaFor') public items: Array<SelectionItem>;
    @Input() public autoSelectFirst: boolean = false;
    @Input() public toggleOnly: boolean = false;
    @Input() public set trackBy(value: (index: number, item: any) => any) {
        if (typeof value !== 'function') {
            throw new Error('trackBy parameter value must be a function');
        }
        this.selectionService.trackByFn = value;
    }
    @Output() public itemSelected: EventEmitter<OnSelectedEvent> = new EventEmitter<OnSelectedEvent>();
    @Output() public itemDeselected: EventEmitter<OnDeselectedEvent> = new EventEmitter<OnDeselectedEvent>();
    @Output() public selectionChanged: EventEmitter<OnSelectionChangedEvent> = new EventEmitter<OnSelectionChangedEvent>();

    constructor( @Self() public selectionService: RtSelectionService) {
        this.selectionService.areaEventsEmitter = this;
        this.selectionEventsHelper = new SelectionEventsHelper(this);
    }
    public ngOnDestroy(): void {
        this.selectionService.destroy();
    }
    public ngOnChanges(changes: { items?: SimpleChange }): void {
        // we doesn't set itemsSource to empty arrays to keep selection when trackByFn is provided
        // it's must not be a problem since on destroy selections will be destroyed by this component 
{'fraction_non_alphanumeric': 0.10157194679564692, 'fraction_numerical': 0.0008061265618702137, 'mean_word_length': 4.922434367541766, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 21, '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': '1219193', 'n_tokens_mistral': 1248, 'n_tokens_neox': 1253, 'n_words': 365}