'use strict' ; import type DataEventEmitter from '../DataEventEmitter' ; import type DataTable from '../DataTable' ; import type JSON from '../../Core/JSON' ; import type ModifierType from './ModifierType' ; import DataPromise from '../DataPromise.js' ; import U from '../../Core/Utilities.js' ; const { addEvent , fireEvent , merge } = U ; /** eslint-disable valid-jsdoc */ private abstract class DataModifier < TEvent extends DataEventEmitter . Event = DataModifier . Event > implements DataEventEmitter < ( TEvent | DataModifier . Event ) > { /**
     * Regular expression to extract the modifier name (group 1) from the
     * stringified class type.
     */ private static readonly nameRegExp = ( /^function\s+(\w*?)(?:Data)?(?:Modifier)?\s*\(/ ) ; /**
     * Registry as a record object with modifier names and their class.
     */ private static readonly registry = { } as Record < string , ModifierType > ; param { DataModifier } modifier return { boolean } public static addModifier ( modifier ) { const name = DataModifier . getName ( modifier ) , registry = DataModifier . registry ; if ( typeof name === 'undefined' || registry [ name ] ) { return false ; } registry [ name ] = modifier ; return true ; } return { Array < string > } public static getAllModifierNames ( ) { return Object . keys ( DataModifier . registry ) ; } return { Record < string , DataModifierRegistryType > } public static getAllModifiers ( ) { return merge ( DataModifier . registry ) ; } param { string } name return { DataModifier | undefined } public static getModifier ( name ) { return DataModifier . registry [ name ] ; } param { DataModifier } modifier return { string } private static getName ( modifier ) { return ( modifier . toString ( ) . match ( DataModifier . nameRegExp ) || [ '' , '' ] ) [ 1 ] ; } /**
     * Modifier options.
     */ public abstract readonly options : DataModifier . Options ; param { DataTable } dataTable param { DataModifier . BenchmarkOptions } options return { Array < number > } public benchmark ( dataTable , options ? ) { const results = [ ] ; const modifier = this as DataModifier < DataModifier . BenchmarkEvent | DataModifier . Event > ; const execute = ( ) : void => { modifier . modifyTable ( dataTable ) ; modifier . emit ( { type : 'afterBenchmarkIteration' } ) ; } ; const defaultOptions = { iterations : 1 } ; const { iterations } = merge ( defaultOptions , options ) ; modifier . on ( 'afterBenchmarkIteration' , ( ) : void => { if ( results . length === iterations ) { modifier . emit ( { type : 'afterBenchmark' , results } ) ; return ; } execute ( ) ; } ) ; const times = { startTime : 0 , endTime : 0 } ; modifier . on ( 'modify' , ( ) : void => { times . startTime = window . performance . now ( ) ; } ) ; modifier . on ( 'afterModify' , ( ) : void => { times . endTime = window . performance . now ( ) ; results . push ( times . endTime - times . startTime ) ; } ) ; execute ( ) ; return results ; } param { DataEventEmitter . Event } e public emit ( e ) { fireEvent ( this , e . type , e ) ; } param { Highcharts . DataTable } table param { DataEventEmitter . EventDetail } eventDetail return { Promise < Highcharts . DataTable > } public modify < T extends DataTable > ( table , eventDetail ? ) { const modifier = this ; return new DataPromise ( ( resolve , reject ) : void => { if ( table . modified === table ) { table . modified = table . clone ( false , eventDetail ) ; } try { resolve ( modifier . modifyTable ( table , eventDetail ) ) ; } catch ( e ) { modifier . emit ( { type : 'error' , detail : eventDetail , table } ) ; reject ( e ) ; } } ) ; } param { Highcharts . DataTable } table param { string } columnName param { number | undefined } rowIndex param { Highcharts . DataTableCellType } cellValue param { Highcharts . DataTableEventDetail } eventDetail return { Highcharts . DataTable } public modifyCell < T extends DataTable > ( table , columnName , rowIndex , cellValue , eventDetail ? ) { return this . modifyTable ( table ) ; } param { Highcharts . DataTable } table param { Highcharts . DataTableColumnCollection } columns param { number } rowIndex param { Highcharts . DataTableEventDetail } eventDetail return { Highcharts . DataTable } public modifyColumns < T extends DataTable > ( table , columns , rowIndex , eventDetail ? ) { return this . modifyTable ( table ) ; } param { Highcharts . DataTable } table param { Array < ( Highcharts . DataTableRow | Highcharts . DataTableRowObject ) > } rows param { number } rowIndex param { Highcharts . DataTableEventDetail } eventDetail return { Highcharts . DataTable } public modifyRows < T extends DataTable > ( table , rows , rowIndex , eventDetail ? ) { return this . modifyTable ( table ) ; } param { Highcharts . DataTable } table param { DataEventEmitter . EventDetail } eventDetail return { Highcharts . DataTable } public abstract modifyTable < T extends DataTable > ( table , eventDetail ? ) ; param { string } type param { DataEventEmitter . EventCallback } callback return { Function } public on ( type , callback ) { return addEvent ( this , type , callback ) ; } } /**
 * Additionally provided types for modifier events and options, and JSON
 * conversion.
 */ namespace DataModifier { param { DeepPartial < Options > } options export interface ClassConstructor { new ( options ? ) : DataModifier ; } /**
     * Benchmark event with additional event information.
     */ export interface BenchmarkEvent extends DataEventEmitter . Event { readonly type : ( 'afterBenchmark' | 'afterBenchmarkIteration' ) ; readonly results ? : Array < number > ; } /**
     * Benchmark options.
     */ export interface BenchmarkOptions { iterations : number ; } /**
     * Error event with additional event information.
     */ export interface ErrorEvent extends DataEventEmitter . Event { readonly type : 'error' ; readonly table : DataTable ; } /**
     * Event information.
     */ export type Event = ( BenchmarkEvent | ErrorEvent | ModifyEvent ) ; /**
     * Modify event with additional event information.
     */ export interface ModifyEvent extends DataEventEmitter . Event { readonly type : ( 'modify' | 'afterModify' ) ; readonly table : DataTable ; } /**
     * Options to configure the modifier.
     */ export interface Options extends JSON . Object { /**
         * Name of the related modifier for these options.
         */ modifier : string ; } } declare module './ModifierType' { interface ModifierTypeRegistry { '' : typeof DataModifier ; } } export default DataModifier ;