ngOnInit() {
    this.productSubscription = this.store.select(fromDepositAccounts.getSelectedProduct)
      .filter(product => !!product)
      .subscribe(product => this.productIdentifer = product.identifier);

    this.dividendData$ = this.store.select(fromDepositAccounts.getDividends)
      .map(dividends => ({
        data: dividends,
        totalElements: dividends.length,
        totalPages: 1
      }));

    this.store.dispatch({
      type: LOAD_ALL,
      payload: this.productIdentifer
    });
  }


ngOnDestroy(): void {
    this.productSubscription.unsubscribe();
  }


(key: string, saga: unknown, store: InjectedStore) => {
  getInjectors(store).injectSaga(key, { saga })
}


({ text, className }: TitleProps): JSX.Element => (
  <h1
    className={cn('font-extrabold title', {
      [className || '']: className,
    })}
  >
    {text}
  </h1>


type TitleProps = {
  text: string;
  className?: string;
};


cn('font-extrabold title', {
      [className || '']: className,
    })


@Component({
  selector: 'app-section-one',
  templateUrl: './section-one.component.html',
  styleUrls: ['./section-one.component.css']
})
export class SectionOneComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}


(state: string, curr: string, index: number) => state + (index <= 3 || index >= 39 ? curr : '*')


(segment) => segment


@Pipe({
    name: 'obscureAddress',
})
export class ObscureAddressPipe implements PipeTransform {
    transform(value: string | null): string {
        if (value === null) {
            return '';
        }

        return value
            .split('')
            .reduce((state: string, curr: string, index: number) => state + (index <= 3 || index >= 39 ? curr : '*'))
            .split('*')
            .filter((segment) => segment)
            .join('***');
    }
}


transform(value: string | null): string {
        if (value === null) {
            return '';
        }

        return value
            .split('')
            .reduce((state: string, curr: string, index: number) => state + (index <= 3 || index >= 39 ? curr : '*'))
            .split('*')
            .filter((segment) => segment)
            .join('***');
    }


ev => {
         if (ev.which !== ENTER_KEY) {
            this.composing();
         }

         if (ev.which === ENTER_KEY && !ev.shiftKey) {
            this.paused();
         }
      }


() => {
      this.setState(STATE.PAUSED);
   }


(newValue, oldValue) => {
         let id = newValue.id;
         let newState = newValue.state;
         let oldState = (oldValue || {}).state;

         if (this.composingTimeout) {
            clearTimeout(this.composingTimeout);
         }

         if (id === this.id) {
            if (newState === STATE.COMPOSING) {
               this.composingTimeout = setTimeout(this.paused, 900);
            }

            func(newState, oldState);
         }
      }


(newState: STATE, oldState: STATE) => {
      let jid = this.contact.getJid();

      new Promise((resolve, reject) => {
         if (jid.isBare()) {
            resolve(true);
            return;
         }
         let hasSupport = this.plugin.getDiscoInfoRepository().hasFeature(jid, Namespace.get('CHATSTATES'));

         resolve(hasSupport);
      }).then(hasSupport => {
         if (hasSupport) {
            if (oldState === STATE.COMPOSING && newState === STATE.PAUSED) {
               this.connection.sendPaused(jid, this.contact.getType());
            } else if (oldState !== STATE.COMPOSING && newState === STATE.COMPOSING) {
               this.connection.sendComposing(jid, this.contact.getType());
            }
         }
      });
   }


(resolve, reject) => {
         if (jid.isBare()) {
            resolve(true);
            return;
         }
         let hasSupport = this.plugin.getDiscoInfoRepository().hasFeature(jid, Namespace.get('CHATSTATES'));

         resolve(hasSupport);
      }


hasSupport => {
         if (hasSupport) {
            if (oldState === STATE.COMPOSING && newState === STATE.PAUSED) {
               this.connection.sendPaused(jid, this.contact.getType());
            } else if (oldState !== STATE.COMPOSING && newState === STATE.COMPOSING) {
               this.connection.sendComposing(jid, this.contact.getType());
            }
         }
      }


export default class ChatStateMachine {
   private storage: IStorage;
   private connection: ChatStateConnection;

   private key;
   private composingTimeout;
   private id;

   constructor(private plugin: ChatStatePlugin, private chatWindow: ChatWindow, private contact: Contact) {
      this.storage = plugin.getStorage();
      this.connection = plugin.getChatStateConnection();
      this.key = 'state:' + this.contact.getId();

      this.addInputHandler();
      this.registerHook(this.stateChange);

      //@REVIEW is this also supported by MUC?
   }

   private addInputHandler() {
      let element = this.chatWindow.getDom();

      element.find('.jsxc-message-input').on('keydown', ev => {
         if (ev.which !== ENTER_KEY) {
            this.composing();
         }

         if (ev.which === ENTER_KEY && !ev.shiftKey) {
            this.paused();
         }
      });
   }

   private composing() {
      this.setState(STATE.COMPOSING);
   }

   private paused = () => {
      this.setState(STATE.PAUSED);
   };

   private registerHook(func: (newState: STATE, oldState: STATE) => void) {
      this.storage.registerHook(this.key, (newValue, oldValue) => {
         let id = newValue.id;
         let newState = newValue.state;
         let oldState = (oldValue || {}).state;

         if (this.composingTimeout) {
            clearTimeout(this.composingTimeout);
         }

         if (id === this.id) {
            if (newState === STATE.COMPOSING) {
               this.composingTimeout = setTimeout(this.paused, 900);
            }

            func(newState, oldState);
         }
      });
   }

   private setState(state: STATE) {
      this.id = Math.random();

      this.storage.setItem(this.key, {
         state,
         id: this.id,
      });
   }

   private stateChange = (newState: STATE, oldState: STATE) => {
      let jid = this.contact.getJid();

      new Promise((resolve, reject) => {
         if (jid.isBare()) {
            resolve(true);
            return;
         }
         let hasSupport = this.plugin.getDiscoInfoRepository().hasFeature(jid, Namespace.get('CHATSTATES'));

         resolve(hasSupport);
      }).then(hasSupport => {
         if (hasSupport) {
            if (oldState === STATE.COMPOSING && newState === STATE.PAUSED) {
               this.connection.sendPaused(jid, this.contact.getType());
            } else if (oldState !== STATE.COMPOSING && newState === STATE.COMPOSING) {
               this.connection.sendComposing(jid, this.contact.getType());
            }
         }
      });
   };
}


private addInputHandler() {
      let element = this.chatWindow.getDom();

      element.find('.jsxc-message-input').on('keydown', ev => {
         if (ev.which !== ENTER_KEY) {
            this.composing();
         }

         if (ev.which === ENTER_KEY && !ev.shiftKey) {
            this.paused();
         }
      });
   }


private composing() {
      this.setState(STATE.COMPOSING);
   }


private registerHook(func: (newState: STATE, oldState: STATE) => void) {
      this.storage.registerHook(this.key, (newValue, oldValue) => {
         let id = newValue.id;
         let newState = newValue.state;
         let oldState = (oldValue || {}).state;

         if (this.composingTimeout) {
            clearTimeout(this.composingTimeout);
         }

         if (id === this.id) {
            if (newState === STATE.COMPOSING) {
               this.composingTimeout = setTimeout(this.paused, 900);
            }

            func(newState, oldState);
         }
      });
   }


private setState(state: STATE) {
      this.id = Math.random();

      this.storage.setItem(this.key, {
         state,
         id: this.id,
      });
   }


() => {
  describe('intervalToAbbreviatedDurationString', () => {
    it('creates a duration string for a provided interval', () => {
      const startDate = new Date();
      const endDate = addDurationToDate(startDate, { months: 1, weeks: 1, days: 1, hours: 1, minutes: 1, seconds: 1 });
      expect(intervalToAbbreviatedDurationString({ start: startDate, end: endDate })).toEqual('1M 8d 1h 1m 1s');
    });
  });

  describe('parseDuration', () => {
    it('parses a duration string', () => {
      const durationString = '3M 5d 20m';
      expect(parseDuration(durationString)).toEqual({ months: '3', days: '5', minutes: '20' });
    });

    it('strips out non valid durations', () => {
      const durationString = '3M 6v 5b 4m';
      expect(parseDuration(durationString)).toEqual({ months: '3', minutes: '4' });
    });
  });
}


() => {
    it('creates a duration string for a provided interval', () => {
      const startDate = new Date();
      const endDate = addDurationToDate(startDate, { months: 1, weeks: 1, days: 1, hours: 1, minutes: 1, seconds: 1 });
      expect(intervalToAbbreviatedDurationString({ start: startDate, end: endDate })).toEqual('1M 8d 1h 1m 1s');
    });
  }


() => {
      const startDate = new Date();
      const endDate = addDurationToDate(startDate, { months: 1, weeks: 1, days: 1, hours: 1, minutes: 1, seconds: 1 });
      expect(intervalToAbbreviatedDurationString({ start: startDate, end: endDate })).toEqual('1M 8d 1h 1m 1s');
    }


() => {
    it('parses a duration string', () => {
      const durationString = '3M 5d 20m';
      expect(parseDuration(durationString)).toEqual({ months: '3', days: '5', minutes: '20' });
    });

    it('strips out non valid durations', () => {
      const durationString = '3M 6v 5b 4m';
      expect(parseDuration(durationString)).toEqual({ months: '3', minutes: '4' });
    });
  }


() => {
      const durationString = '3M 5d 20m';
      expect(parseDuration(durationString)).toEqual({ months: '3', days: '5', minutes: '20' });
    }


() => {
      const durationString = '3M 6v 5b 4m';
      expect(parseDuration(durationString)).toEqual({ months: '3', minutes: '4' });
    }


() => CrowdfundState


() => CrowdfundConfig


@ObjectType()
export class CrowdfundQuery implements BaseQuery, AndrQuery {
  @Field(() => String)
  contractAddress!: string

  @Field(() => String)
  owner!: Promise<string>

  @Field(() => [String])
  operators!: Promise<string[]>

  @Field(() => Boolean)
  isOperator!: Promise<boolean>

  @Field(() => CrowdfundState)
  state!: Promise<CrowdfundState>

  @Field(() => CrowdfundConfig)
  config!: Promise<CrowdfundConfig>
}


export class ExtensionsScannerService extends NativeExtensionsScannerService implements IExtensionsScannerService {

	constructor(
		@IFileService fileService: IFileService,
		@ILogService logService: ILogService,
		@INativeEnvironmentService environmentService: INativeEnvironmentService,
		@IProductService productService: IProductService,
	) {
		super(
			URI.file(environmentService.builtinExtensionsPath),
			URI.file(environmentService.extensionsPath),
			environmentService.userHome,
			URI.file(environmentService.userDataPath),
			fileService, logService, environmentService, productService);
	}

}


@NgModule({
  imports: [CommonModule],
})
export class PayactivUiAngularModule {}


(f7) => {
        Dom7(document).on('page:reinit', function (e) {
          self.user = store.state.user;
          if (store.state.user === undefined) {
            LoginHook.tryRestoreUserSession().then(() => self.pageReinit(true), err => self.pageReinit(false));
          } else {
            self.pageReinit(true);
          }
        });

        Dom7(document).on('page:afterin', function (e) {
          self.user = store.state.user;
          if (store.state.user === undefined) {
            LoginHook.tryRestoreUserSession().then(() => self.pageAfterNavigate(true), err => self.pageAfterNavigate(false));
          } else {
            self.pageAfterNavigate(true);
          }
        });
      }


() => self.pageReinit(true)


err => self.pageReinit(false)


() => self.pageAfterNavigate(true)


err => self.pageAfterNavigate(false)


export abstract class SVEPageComponent
 extends React.Component
 {
    protected f7router: F7Router.Router;
    protected f7route: F7Router.Route;
    protected user: SVEAccount | undefined;
    private error: ErrorState = {
        has: false,
        msg: ""
    };

    constructor(props) {
        super(props);
        const { f7route, f7router } = props;
        this.f7route = f7route;
        this.f7router = f7router;
        this.user = store.state.user;
        this.error = {
            has: false,
            msg: ""
        };
        LoginHook.add(this.onUserLoggedIn.bind(this));
    }

    public static getDerivedStateFromError(error) {
        console.log("STATIC: Catching error!", error);
        return {error: {
          has: true,
          msg: "Error" + JSON.stringify(error)
        }};
    }

    public componentDidCatch(error, errorInfo) {
        console.log("DYNAMIC: Catching error: ", error, errorInfo);
        this.error.has = true;
        this.error.msg = this.error.msg + "
\n Info: " + JSON.stringify(errorInfo) + "
\nError: " + JSON.stringify(error);
        this.forceUpdate();
    }

    private resolveError() {
        this.error.has = false;
        this.error.msg = "";
        window.location.reload();
    }

    protected onUserLoggedIn(user: SVEAccount) {

    }

    public render() {
        return (this.error.has) ? (
            <Page>
                <Navbar large sliding={false}>
              <NavTitle sliding>Ein kritischer Fehler trat auf!</NavTitle>
              <NavTitleLarge>Ein kritischer Fehler trat auf!</NavTitleLarge>
              <NavRight>
                <Link external iconF7="text_bubble" tooltip="Fehler melden" href={"mailto:info@felixlehner.de?subject=Webseitenfehler&body=Fehler%20trat%20auf%3A%0D%0A" + store.state.error.msg.replace("\\n", "\n")} />
                <Link style={{color: "green"}} iconF7="tornado" tooltip="Fehler auflösen" onClick={this.resolveError.bind(this)} />
              </NavRight>
            </Navbar>
            <Block>

                Es ist ein kritischer Fehler in der Webapp aufgetreten! Dies bedeutet jedoch nicht,
                dass die letzte Operation nicht gespeichert wurde. Auf dem Server kann alles in bester Ordnung sein.
                Dementsprechend wird niemand von diesem Fehler erfahren, wenn er nicht mit Hilfe des Sprechblasen-Icons per Mail gemeldet wird.
                Nach der Meldung kann über den Tornado hier wieder aufgeräumt werden, damit es weiter gehen kann!
                Vielen Dank für die Geduld - die App ist eben noch in der Entwicklung.

              <List accordionList>
                <ListItem accordionItem title="Fehlermeldung">
                  <AccordionContent>
                    <Block strong inset>

                        {store.state.error.msg}

                    </Block>
                  </AccordionContent>
                </ListItem>
              </List>
            </Block>
            </Page>
        ) : this.customRender()
    }

    protected abstract customRender(): any;
    protected pageReinit(isUserReady: boolean) { }
    protected pageAfterNavigate(isUserReady: boolean) { }

    public componentDidMount() {
      this.user = store.state.user;
      var self = this;
      f7ready((f7) => {
        Dom7(document).on('page:reinit', function (e) {
          self.user = store.state.user;
          if (store.state.user === undefined) {
            LoginHook.tryRestoreUserSession().then(() => self.pageReinit(true), err => self.pageReinit(false));
          } else {
            self.pageReinit(true);
          }
        });

        Dom7(document).on('page:afterin', function (e) {
          self.user = store.state.user;
          if (store.state.user === undefined) {
            LoginHook.tryRestoreUserSession().then(() => self.pageAfterNavigate(true), err => self.pageAfterNavigate(false));
          } else {
            self.pageAfterNavigate(true);
          }
        });
      });
    }

    public componentDidUpdate() {
      this.user = store.state.user;
    }
}


interface ErrorState {
    has: boolean;
    msg: string;
}


public static getDerivedStateFromError(error) {
        console.log("STATIC: Catching error!", error);
        return {error: {
          has: true,
          msg: "Error" + JSON.stringify(error)
        }};
    }


public componentDidCatch(error, errorInfo) {
        console.log("DYNAMIC: Catching error: ", error, errorInfo);
        this.error.has = true;
        this.error.msg = this.error.msg + "
\n Info: " + JSON.stringify(errorInfo) + "
\nError: " + JSON.stringify(error);
        this.forceUpdate();
    }


private resolveError() {
        this.error.has = false;
        this.error.msg = "";
        window.location.reload();
    }


protected onUserLoggedIn(user: SVEAccount) {

    }


public render() {
        return (this.error.has) ? (
            <Page>
                <Navbar large sliding={false}>
              <NavTitle sliding>Ein kritischer Fehler trat auf!</NavTitle>
              <NavTitleLarge>Ein kritischer Fehler trat auf!</NavTitleLarge>
              <NavRight>
                <Link external iconF7="text_bubble" tooltip="Fehler melden" href={"mailto:info@felixlehner.de?subject=Webseitenfehler&body=Fehler%20trat%20auf%3A%0D%0A" + store.state.error.msg.replace("\\n", "\n")} />
                <Link style={{color: "green"}} iconF7="tornado" tooltip="Fehler auflösen" onClick={this.resolveError.bind(this)} />
              </NavRight>
            </Navbar>
            <Block>

                Es ist ein kritischer Fehler in der Webapp aufgetreten! Dies bedeutet jedoch nicht,
                dass die letzte Operation nicht gespeichert wurde. Auf dem Server kann alles in bester Ordnung sein.
                Dementsprechend wird niemand von diesem Fehler erfahren, wenn er nicht mit Hilfe des Sprechblasen-Icons per Mail gemeldet wird.
                Nach der Meldung kann über den Tornado hier wieder aufgeräumt werden, damit es weiter gehen kann!
                Vielen Dank für die Geduld - die App ist eben noch in der Entwicklung.

              <List accordionList>
                <ListItem accordionItem title="Fehlermeldung">
                  <AccordionContent>
                    <Block strong inset>

                        {store.state.error.msg}

                    </Block>
                  </AccordionContent>
                </ListItem>
              </List>
            </Block>
            </Page>
        ) : this.customRender()
    }


protected abstract customRender(): any;


protected pageReinit(isUserReady: boolean) { }


protected pageAfterNavigate(isUserReady: boolean) { }


public componentDidMount() {
      this.user = store.state.user;
      var self = this;
      f7ready((f7) => {
        Dom7(document).on('page:reinit', function (e) {
          self.user = store.state.user;
          if (store.state.user === undefined) {
            LoginHook.tryRestoreUserSession().then(() => self.pageReinit(true), err => self.pageReinit(false));
          } else {
            self.pageReinit(true);
          }
        });

        Dom7(document).on('page:afterin', function (e) {
          self.user = store.state.user;
          if (store.state.user === undefined) {
            LoginHook.tryRestoreUserSession().then(() => self.pageAfterNavigate(true), err => self.pageAfterNavigate(false));
          } else {
            self.pageAfterNavigate(true);
          }
        });
      });
    }


public componentDidUpdate() {
      this.user = store.state.user;
    }


({
  children,
  content,
  author,
  isLiked,
  isAnswered,
  isHighlighted
}) => {
  return (
    <Container
      isLiked={isLiked}
      isAnswered={isAnswered}
      isHighlighted={isHighlighted}
    >

{content}

          {author.name}

          {children}

    </Container>


type QuestionProps = {
  content: string
  author: {
    name: string
    avatar: string
  }
  isLiked: boolean
  isAnswered: boolean
  isHighlighted: boolean
}


@NgModule({
  imports: [ RouterModule.forRoot(routes) ],
  exports: [ RouterModule ]
})
export class AppRoutingModule {}


declare class FetchLayer extends Layer {
    /**
     * @class FetchLayer
     * @classdesc Creates an image layer using a remote URL.
     * @param {Object|string} options - layer parameters or a url
     * @param {string} options.url the url of the image to fetch
     */
    constructor(options: any);
    url(url: string): this;
    /**
     * generate the string representation of the layer
     * @function FetchLayer#toString
     * @return {String}
     */
    toString(): string;
}


url(url: string): this;


/**
     * generate the string representation of the layer
     * @function FetchLayer#toString
     * @return {String}
     */
toString(): string;


export class DisassociateConnectorCommand extends $Command<
  DisassociateConnectorCommandInput,
  DisassociateConnectorCommandOutput,
  SMSClientResolvedConfig
> {
  // Start section: command_properties
  // End section: command_properties

  constructor(readonly input: DisassociateConnectorCommandInput) {
    // Start section: command_constructor
    super();
    // End section: command_constructor
  }

  resolveMiddleware(
    clientStack: MiddlewareStack<ServiceInputTypes, ServiceOutputTypes>,
    configuration: SMSClientResolvedConfig,
    options?: __HttpHandlerOptions
  ): Handler<DisassociateConnectorCommandInput, DisassociateConnectorCommandOutput> {
    this.middlewareStack.use(getSerdePlugin(configuration, this.serialize, this.deserialize));

    const stack = clientStack.concat(this.middlewareStack);

    const handlerExecutionContext: HandlerExecutionContext = {
      logger: {} as any,
    };
    const { requestHandler } = configuration;
    return stack.resolve(
      (request: FinalizeHandlerArguments<any>) =>
        requestHandler.handle(request.request as __HttpRequest, options || {}),
      handlerExecutionContext
    );
  }

  private serialize(input: DisassociateConnectorCommandInput, context: __SerdeContext): Promise<__HttpRequest> {
    return serializeAws_json1_1DisassociateConnectorCommand(input, context);
  }

  private deserialize(output: __HttpResponse, context: __SerdeContext): Promise<DisassociateConnectorCommandOutput> {
    return deserializeAws_json1_1DisassociateConnectorCommand(output, context);
  }

  // Start section: command_body_extra
  // End section: command_body_extra
}


export type DisassociateConnectorCommandInput = DisassociateConnectorRequest;


export type DisassociateConnectorCommandOutput = DisassociateConnectorResponse & __MetadataBearer;


resolveMiddleware(
    clientStack: MiddlewareStack<ServiceInputTypes, ServiceOutputTypes>,
    configuration: SMSClientResolvedConfig,
    options?: __HttpHandlerOptions
  ): Handler<DisassociateConnectorCommandInput, DisassociateConnectorCommandOutput> {
    this.middlewareStack.use(getSerdePlugin(configuration, this.serialize, this.deserialize));

    const stack = clientStack.concat(this.middlewareStack);

    const handlerExecutionContext: HandlerExecutionContext = {
      logger: {} as any,
    };
    const { requestHandler } = configuration;
    return stack.resolve(
      (request: FinalizeHandlerArguments<any>) =>
        requestHandler.handle(request.request as __HttpRequest, options || {}),
      handlerExecutionContext
    );
  }


private serialize(input: DisassociateConnectorCommandInput, context: __SerdeContext): Promise<__HttpRequest> {
    return serializeAws_json1_1DisassociateConnectorCommand(input, context);
  }


private deserialize(output: __HttpResponse, context: __SerdeContext): Promise<DisassociateConnectorCommandOutput> {
    return deserializeAws_json1_1DisassociateConnectorCommand(output, context);
  }


function validateGitHubToken(token: string) {
  if (token.length < 4) {
    throw new Error('GITHUB_TOKEN has invalid format');
  }
  switch (token.substring(0, 4)) {
    case 'ghp_':
      // Personal Access Tokens
      throw new Error(
        'GITHUB_TOKEN looks like Personal Access Token. `github-token` must be `${{ github.token }}` or `${{ secrets.GITHUB_TOKEN }}`.'
      );

    case 'gho_':
      // OAuth Access tokens
      throw new Error(
        'GITHUB_TOKEN looks like OAuth Access token. `github-token` must be `${{ github.token }}` or `${{ secrets.GITHUB_TOKEN }}`.'
      );

    case 'ghu_':
      // GitHub App user-to-server tokens
      throw new Error(
        'GITHUB_TOKEN looks like GitHub App user-to-server token. `github-token` must be `${{ github.token }}` or `${{ secrets.GITHUB_TOKEN }}`.'
      );

    case 'ghs_':
      // GitHub App server-to-server tokens
      return; // it's OK

    case 'ghr_':
      throw new Error(
        'GITHUB_TOKEN looks like GitHub App refresh token. `github-token` must be `${{ github.token }}` or `${{ secrets.GITHUB_TOKEN }}`.'
      );
  }
  // maybe Old Format Personal Access Tokens
  throw new Error(
    'GITHUB_TOKEN looks like Personal Access Token. `github-token` must be `${{ github.token }}` or `${{ secrets.GITHUB_TOKEN }}`.'
  );
}


// comes from the article "AWS federation comes to GitHub Actions"
// https://awsteele.com/blog/2021/09/15/aws-federation-comes-to-github-actions.html
function isIdTokenAvailable(): boolean {
  const token = process.env['ACTIONS_ID_TOKEN_REQUEST_TOKEN'];
  const url = process.env['ACTIONS_ID_TOKEN_REQUEST_URL'];
  return token && url ? true : false;
}


function assertIsDefined<T>(val: T): asserts val is NonNullable<T> {
  if (val === undefined || val === null) {
    throw new Error(`Missing required environment value. Are you running in GitHub Actions?`);
  }
}


export async function assumeRole(params: AssumeRoleParams) {
  const {GITHUB_REPOSITORY, GITHUB_WORKFLOW, GITHUB_RUN_ID, GITHUB_ACTOR, GITHUB_SHA, GITHUB_REF} = process.env;
  assertIsDefined(GITHUB_REPOSITORY);
  assertIsDefined(GITHUB_WORKFLOW);
  assertIsDefined(GITHUB_RUN_ID);
  assertIsDefined(GITHUB_ACTOR);
  assertIsDefined(GITHUB_SHA);
  validateGitHubToken(params.githubToken);
  const GITHUB_API_URL = process.env['GITHUB_API_URL'] || 'https://api.github.com';

  let idToken: string | undefined;
  if (isIdTokenAvailable()) {
    idToken = await core.getIDToken();
  }

  const payload: AssumeRolePayload = {
    github_token: params.githubToken,
    id_token: idToken,
    role_to_assume: params.roleToAssume,
    role_session_name: params.roleSessionName,
    duration_seconds: params.roleDurationSeconds,
    api_url: GITHUB_API_URL,
    repository: GITHUB_REPOSITORY,
    use_node_id: params.useNodeId,
    obfuscate_repository: params.obfuscateRepository,
    sha: GITHUB_SHA,
    role_session_tagging: params.roleSessionTagging,
    run_id: GITHUB_RUN_ID,
    workflow: GITHUB_WORKFLOW,
    actor: GITHUB_ACTOR,
    branch: GITHUB_REF || ''
  };
  const client = new http.HttpClient('actions-aws-assume-role');
  const result = await client.postJson<AssumeRoleResult | AssumeRoleError>(params.providerEndpoint, payload);
  if (result.statusCode !== 200) {
    const resp = result.result as AssumeRoleError;
    core.setFailed(resp.message);
    return;
  }
  const resp = result.result as AssumeRoleResult;

  if (resp.message) {
    core.info(resp.message);
  }

  if (resp.warning) {
    core.warning(resp.warning);
  }

  core.setSecret(resp.access_key_id);
  core.exportVariable('AWS_ACCESS_KEY_ID', resp.access_key_id);

  core.setSecret(resp.secret_access_key);
  core.exportVariable('AWS_SECRET_ACCESS_KEY', resp.secret_access_key);

  core.setSecret(resp.session_token);
  core.exportVariable('AWS_SESSION_TOKEN', resp.session_token);

  core.exportVariable('AWS_DEFAULT_REGION', params.awsRegion);
  core.exportVariable('AWS_REGION', params.awsRegion);
}


async function run() {
  try {
    const required = {
      required: true
    };
    const githubToken = core.getInput('github-token', required);
    const awsRegion = core.getInput('aws-region', required);
    const roleToAssume = core.getInput('role-to-assume', required);
    const roleDurationSeconds = Number.parseInt(core.getInput('role-duration-seconds', required));
    const roleSessionName = core.getInput('role-session-name', required);
    const roleSessionTagging = core.getBooleanInput('role-session-tagging', required);
    const providerEndpoint =
      core.getInput('provider-endpoint') || 'https://uw4qs7ndjj.execute-api.us-east-1.amazonaws.com/assume-role';
    const useNodeId = core.getBooleanInput('use-node-id', required);
    const obfuscateRepository = core.getInput('obfuscate-repository');
    await assumeRole({
      githubToken,
      awsRegion,
      roleToAssume,
      roleDurationSeconds,
      roleSessionName,
      roleSessionTagging,
      providerEndpoint,
      useNodeId,
      obfuscateRepository
    });
  } catch (error) {
    if (error instanceof Error) {
      core.setFailed(error);
    } else {
      core.setFailed(`${error}`);
    }
  }
}


interface AssumeRoleParams {
  githubToken: string;
  awsRegion: string;
  roleToAssume: string;
  roleDurationSeconds: number;
  roleSessionName: string;
  roleSessionTagging: boolean;
  providerEndpoint: string;
  useNodeId: boolean;
  obfuscateRepository: string;
}


interface AssumeRolePayload {
  github_token: string;
  id_token?: string;
  role_to_assume: string;
  role_session_name: string;
  duration_seconds: number;
  api_url: string;
  repository: string;
  use_node_id: boolean;
  obfuscate_repository: string;
  sha: string;
  role_session_tagging: boolean;
  run_id: string;
  workflow: string;
  actor: string;
  branch: string;
}


interface AssumeRoleResult {
  access_key_id: string;
  secret_access_key: string;
  session_token: string;
  message?: string;
  warning?: string;
}


interface AssumeRoleError {
  message: string;
}


@NgModule({
    imports: [
        TuiAddonDocModule,
        InheritedDocumentationModule,
        ReactiveFormsModule,
        FormsModule,
        CommonModule,
        TuiLinkModule,
        TuiInputDateTimeModule,
        TuiHintControllerModule,
        TuiTextfieldControllerModule,
        RouterModule.forChild(generateRoutes(ExampleTuiInputDateTimeComponent)),
    ],
    declarations: [
        ExampleTuiInputDateTimeComponent,
        TuiInputDateTimeExample1,
        TuiInputDateTimeExample2,
        TuiInputDateTimeExample3,
        TuiInputDateTimeExample4,
    ],
    exports: [ExampleTuiInputDateTimeComponent],
})
export class ExampleTuiInputDateTimeModule {}


(originalParam: g.GameMainParameterObject) => {
  const param: any = {} as GameMainParameterObject;
  Object.keys(originalParam).forEach((key) => {
    param[key] = (originalParam as any)[key];
  });
  // セッションパラメーター
  param.sessionParameter = {};
  // コンテンツが動作している環境がRPGアツマール上かどうか
  param.isAtsumaru = typeof window !== "undefined" && typeof window.RPGAtsumaru !== "undefined";
  // 乱数生成器
  param.random = g.game.random;

  const limitTickToWait = 3; // セッションパラメーターが来るまでに待つtick数

  const scene = new g.Scene({
    game: g.game
  });
  // セッションパラメーターを受け取ってゲームを開始します
  scene.message.add((msg) => {
    if (msg.data && msg.data.type === "start" && msg.data.parameters) {
      param.sessionParameter = msg.data.parameters; // sessionParameterフィールドを追加
      if (msg.data.parameters.randomSeed != null) {
        param.random = new g.XorshiftRandomGenerator(msg.data.parameters.randomSeed);
      }
      g.game.popScene();
      main(param);
    }
  });
  scene.loaded.add(() => {
    let currentTickCount = 0;
    scene.update.add(function() {
      currentTickCount++;
      // 待ち時間を超えた場合はゲームを開始します
      if (currentTickCount > limitTickToWait) {
        g.game.popScene();
        main(param);
      }
    });
  });
  g.game.pushScene(scene);
}


(key) => {
    param[key] = (originalParam as any)[key];
  }


(msg) => {
    if (msg.data && msg.data.type === "start" && msg.data.parameters) {
      param.sessionParameter = msg.data.parameters; // sessionParameterフィールドを追加
      if (msg.data.parameters.randomSeed != null) {
        param.random = new g.XorshiftRandomGenerator(msg.data.parameters.randomSeed);
      }
      g.game.popScene();
      main(param);
    }
  }


() => {
    let currentTickCount = 0;
    scene.update.add(function() {
      currentTickCount++;
      // 待ち時間を超えた場合はゲームを開始します
      if (currentTickCount > limitTickToWait) {
        g.game.popScene();
        main(param);
      }
    });
  }


data => {
				this.data = data;
				this.total_file_count_str = "Total Files: "+this.data.length;
				this.hideLoading_indicator = true;
			}


error => {}


event => {
			if (event.type === HttpEventType.UploadProgress) {
				this.progress.percentage = Math.round(100 * event.loaded / event.total);
			} else if (event instanceof HttpResponse) {
				this.s3path = event.body['s3path'];
				this.hideProgressbar = true;
				this.savetodb();
			}
		}


data => {
				this.getAllFromManagersBox();
				this.hideLoading_indicator = true;
				swal.fire('Save', 'Level added '+data['status'], 'success');
				this.resetall();
			}


(result) => {
		  if (result.value) {
			this.deletes3file(filedata);
		  }
		}


data1 => {
				this.managersboxService.deleteFromManagersBox(filedata._id).subscribe(data2 => {
						this.getAllFromManagersBox();
						this.hideLoading_indicator = true;
						swal.fire(
							'Save',
							'File deletion '+data2['status'],
							'success'
						);
						this.resetall();
					},
					error => {},
					() => {}
				);
			}


data2 => {
						this.getAllFromManagersBox();
						this.hideLoading_indicator = true;
						swal.fire(
							'Save',
							'File deletion '+data2['status'],
							'success'
						);
						this.resetall();
					}


@Component({
    selector: 'app-managersbox',
    templateUrl: './managersbox.component.html',
    styleUrls: ['./managersbox.component.scss'],
    animations: [routerTransition()]
})

export class ManagersboxComponent implements OnInit {
	@ViewChild('fileInput')
	fileInputVariable: ElementRef;
	baseUrl = environment.baseUrl+'s3api/download/';

	data: any = [];
	total_file_count_str: string = '';
	hideProgressbar: boolean = true;
	hideLoading_indicator: boolean = true;

	selectedFiles: FileList;
	currentFileUpload: File;
	progress: { percentage: number } = { percentage: 0 };

	displayname: string = '';
	s3name: string = '';
	filetype: string = '';
	s3path: string = '';

	constructor(private managersboxService: ManagersboxService) {
		this.hideProgressbar = true;
		this.hideLoading_indicator = true;
		this.getAllFromManagersBox();
	 }

	ngOnInit() {}

	getAllFromManagersBox(){
		this.managersboxService.getAllFromManagersBox().subscribe(data => {
				this.data = data;
				this.total_file_count_str = "Total Files: "+this.data.length;
				this.hideLoading_indicator = true;
			},
			error => {},
			() => {}
		);
	}

	filechooser_onchange(event) {
		if(event.target.files.length > 0){
			this.selectedFiles = event.target.files;
			this.displayname = event.target.files[0].name;
			this.filetype = this.displayname.split('.').pop();
			this.s3name = (new Date()).getTime()+'.'+this.filetype;
		}else{
			this.displayname = '';
			this.selectedFiles = null;
		}
	}

	uploadfile_button_click() {
		this.hideProgressbar = false;
		this.progress.percentage = 0;

		this.currentFileUpload = this.selectedFiles.item(0);
		this.managersboxService.pushFileToStorage(this.currentFileUpload, this.s3name).subscribe(event => {
			if (event.type === HttpEventType.UploadProgress) {
				this.progress.percentage = Math.round(100 * event.loaded / event.total);
			} else if (event instanceof HttpResponse) {
				this.s3path = event.body['s3path'];
				this.hideProgressbar = true;
				this.savetodb();
			}
		});
		//this.selectedFiles = undefined;
	}

	savetodb(){
		this.hideLoading_indicator = false;
		let body = {
			displayname: this.displayname,
			s3name: this.s3name,
			filetype: this.filetype,
			s3path: this.s3path
		}
		this.managersboxService.uploadToManagersBox(body).subscribe(data => {
				this.getAllFromManagersBox();
				this.hideLoading_indicator = true;
				swal.fire('Save', 'Level added '+data['status'], 'success');
				this.resetall();
			},
			error => {},
			() => {}
		);
	}

	delete_button_click(filedata){
		swal.fire({
		  title: 'Are you sure?',
		  text: "Do you want to delete this file?",
		  type: 'warning',
		  showCancelButton: true,
		  confirmButtonColor: '#3085d6',
		  cancelButtonColor: '#d33',
		  confirmButtonText: 'Yes'
		}).then((result) => {
		  if (result.value) {
			this.deletes3file(filedata);
		  }
		});
	}

	deletes3file(filedata){
		this.hideLoading_indicator = false;
		this.managersboxService.deleteFromStorage(filedata.s3name).subscribe(data1 => {
				this.managersboxService.deleteFromManagersBox(filedata._id).subscribe(data2 => {
						this.getAllFromManagersBox();
						this.hideLoading_indicator = true;
						swal.fire(
							'Save',
							'File deletion '+data2['status'],
							'success'
						);
						this.resetall();
					},
					error => {},
					() => {}
				);
			},
			error => {},
			() => {}
		);
	}

	resetall(){
		this.hideProgressbar = true;
		this.progress.percentage = 0;
		this.selectedFiles = null;
		this.fileInputVariable.nativeElement.value = "";
	}
}


getAllFromManagersBox(){
		this.managersboxService.getAllFromManagersBox().subscribe(data => {
				this.data = data;
				this.total_file_count_str = "Total Files: "+this.data.length;
				this.hideLoading_indicator = true;
			},
			error => {},
			() => {}
		);
	}


filechooser_onchange(event) {
		if(event.target.files.length > 0){
			this.selectedFiles = event.target.files;
			this.displayname = event.target.files[0].name;
			this.filetype = this.displayname.split('.').pop();
			this.s3name = (new Date()).getTime()+'.'+this.filetype;
		}else{
			this.displayname = '';
			this.selectedFiles = null;
		}
	}


uploadfile_button_click() {
		this.hideProgressbar = false;
		this.progress.percentage = 0;

		this.currentFileUpload = this.selectedFiles.item(0);
		this.managersboxService.pushFileToStorage(this.currentFileUpload, this.s3name).subscribe(event => {
			if (event.type === HttpEventType.UploadProgress) {
				this.progress.percentage = Math.round(100 * event.loaded / event.total);
			} else if (event instanceof HttpResponse) {
				this.s3path = event.body['s3path'];
				this.hideProgressbar = true;
				this.savetodb();
			}
		});
		//this.selectedFiles = undefined;
	}


savetodb(){
		this.hideLoading_indicator = false;
		let body = {
			displayname: this.displayname,
			s3name: this.s3name,
			filetype: this.filetype,
			s3path: this.s3path
		}
		this.managersboxService.uploadToManagersBox(body).subscribe(data => {
				this.getAllFromManagersBox();
				this.hideLoading_indicator = true;
				swal.fire('Save', 'Level added '+data['status'], 'success');
				this.resetall();
			},
			error => {},
			() => {}
		);
	}


delete_button_click(filedata){
		swal.fire({
		  title: 'Are you sure?',
		  text: "Do you want to delete this file?",
		  type: 'warning',
		  showCancelButton: true,
		  confirmButtonColor: '#3085d6',
		  cancelButtonColor: '#d33',
		  confirmButtonText: 'Yes'
		}).then((result) => {
		  if (result.value) {
			this.deletes3file(filedata);
		  }
		});
	}


deletes3file(filedata){
		this.hideLoading_indicator = false;
		this.managersboxService.deleteFromStorage(filedata.s3name).subscribe(data1 => {
				this.managersboxService.deleteFromManagersBox(filedata._id).subscribe(data2 => {
						this.getAllFromManagersBox();
						this.hideLoading_indicator = true;
						swal.fire(
							'Save',
							'File deletion '+data2['status'],
							'success'
						);
						this.resetall();
					},
					error => {},
					() => {}
				);
			},
			error => {},
			() => {}
		);
	}


resetall(){
		this.hideProgressbar = true;
		this.progress.percentage = 0;
		this.selectedFiles = null;
		this.fileInputVariable.nativeElement.value = "";
	}


/**
 * Ring constructor
 * @constructor
 * @augments Konva.Shape
 * @memberof Konva
 * @param {Object} config
 * @param {Number} config.innerRadius
 * @param {Number} config.outerRadius
 * @param {Boolean} [config.clockwise]
 * @@shapeParams
 * @@nodeParams
 * @example
 * var ring = new Konva.Ring({
 *   innerRadius: 40,
 *   outerRadius: 80,
 *   fill: 'red',
 *   stroke: 'black',
 *   strokeWidth: 5
 * });
 */
export class Ring extends Shape<RingConfig> {
  _sceneFunc(context) {
    context.beginPath();
    context.arc(0, 0, this.innerRadius(), 0, PIx2, false);
    context.moveTo(this.outerRadius(), 0);
    context.arc(0, 0, this.outerRadius(), PIx2, 0, true);
    context.closePath();
    context.fillStrokeShape(this);
  }
  getWidth() {
    return this.outerRadius() * 2;
  }
  getHeight() {
    return this.outerRadius() * 2;
  }
  setWidth(width) {
    this.outerRadius(width / 2);
  }
  setHeight(height) {
    this.outerRadius(height / 2);
  }

  outerRadius: GetSet<number, this>;
  innerRadius: GetSet<number, this>;
}


export interface RingConfig extends ShapeConfig {
  innerRadius: number;
  outerRadius: number;
  clockwise?: boolean;
}


_sceneFunc(context) {
    context.beginPath();
    context.arc(0, 0, this.innerRadius(), 0, PIx2, false);
    context.moveTo(this.outerRadius(), 0);
    context.arc(0, 0, this.outerRadius(), PIx2, 0, true);
    context.closePath();
    context.fillStrokeShape(this);
  }


getWidth() {
    return this.outerRadius() * 2;
  }


getHeight() {
    return this.outerRadius() * 2;
  }


setWidth(width) {
    this.outerRadius(width / 2);
  }


setHeight(height) {
    this.outerRadius(height / 2);
  }


export function isNil(value?: string | null): value is null | undefined {
  return value == null;
}


export interface ColumnResizeSet {
    columns: Column[];
    ratios: number[];
    width: number;
}


export interface ColumnState {
    colId: string;
    hide?: boolean;
    aggFunc?: string | IAggFunc | null;
    width?: number;
    pivotIndex?: number | null;
    pinned?: boolean | string | 'left' | 'right';
    rowGroupIndex?: number | null;
    flex?: number;
}


init(): void;


onAutoGroupColumnDefChanged(): void;


setColumnDefs(columnDefs: (ColDef | ColGroupDef)[], source?: ColumnEventType): void;


isAutoRowHeightActive(): boolean;


getAllAutoRowHeightCols(): Column[];


getDisplayedColumnsStartingAt(column: Column): Column[];


setVirtualViewportPosition(scrollWidth: number, scrollPosition: number): void;


isPivotMode(): boolean;


setPivotMode(pivotMode: boolean, source?: ColumnEventType): void;


getSecondaryPivotColumn(pivotKeys: string[], valueColKey: Column | string): Column | null;


autoSizeColumns(keys: (string | Column)[], skipHeader?: boolean, source?: ColumnEventType): void;


autoSizeColumn(key: string | Column | null, skipHeader?: boolean, source?: ColumnEventType): void;


autoSizeAllColumns(skipHeader?: boolean, source?: ColumnEventType): void;


getAllDisplayedColumnGroups(): ColumnGroupChild[] | null;


getPrimaryColumnTree(): OriginalColumnGroupChild[];


getHeaderRowCount(): number;


getLeftDisplayedColumnGroups(): ColumnGroupChild[];


getRightDisplayedColumnGroups(): ColumnGroupChild[];


getCenterDisplayedColumnGroups(): ColumnGroupChild[];


getDisplayedColumnGroups(type: string): ColumnGroupChild[];


isColumnDisplayed(column: Column): boolean;


getAllDisplayedColumns(): Column[];


getAllDisplayedVirtualColumns(): Column[];


getDisplayedLeftColumnsForRow(rowNode: RowNode): Column[];


getDisplayedRightColumnsForRow(rowNode: RowNode): Column[];


getAllDisplayedCenterVirtualColumnsForRow(rowNode: RowNode): Column[];


getPinnedLeftContainerWidth(): number;


getPinnedRightContainerWidth(): number;


updatePrimaryColumnList(keys: (string | Column)[] | null, masterList: Column[], actionIsAdd: boolean, columnCallback: (column: Column) => void, eventType: string, source?: ColumnEventType): void;


setRowGroupColumns(colKeys: (string | Column)[], source?: ColumnEventType): void;


addRowGroupColumn(key: string | Column | null, source?: ColumnEventType): void;


addRowGroupColumns(keys: (string | Column)[], source?: ColumnEventType): void;


removeRowGroupColumns(keys: (string | Column)[] | null, source?: ColumnEventType): void;


removeRowGroupColumn(key: string | Column | null, source?: ColumnEventType): void;


addPivotColumns(keys: (string | Column)[], source?: ColumnEventType): void;


setPivotColumns(colKeys: (string | Column)[], source?: ColumnEventType): void;


addPivotColumn(key: string | Column, source?: ColumnEventType): void;


removePivotColumns(keys: (string | Column)[], source?: ColumnEventType): void;


removePivotColumn(key: string | Column, source?: ColumnEventType): void;


setValueColumns(colKeys: (string | Column)[], source?: ColumnEventType): void;


addValueColumns(keys: (string | Column)[], source?: ColumnEventType): void;


addValueColumn(colKey: (string | Column) | null | undefined, source?: ColumnEventType): void;


removeValueColumn(colKey: (string | Column), source?: ColumnEventType): void;


removeValueColumns(keys: (string | Column)[], source?: ColumnEventType): void;


setColumnWidths(columnWidths: {
        key: string | Column;
        newWidth: number;
    }[], shiftKey: boolean, // @takeFromAdjacent - if user has 'shift' pressed, then pixels are taken from adjacent column
    finished: boolean, // @finished - ends up in the event, tells the user if more events are to come
    source?: ColumnEventType): void;


resizeColumnSets(resizeSets: ColumnResizeSet[], finished: boolean, source: ColumnEventType): void;


setColumnAggFunc(column: Column | null | undefined, aggFunc: string, source?: ColumnEventType): void;


moveRowGroupColumn(fromIndex: number, toIndex: number, source?: ColumnEventType): void;


moveColumns(columnsToMoveKeys: (string | Column)[], toIndex: number, source?: ColumnEventType): void;


doesMovePassRules(columnsToMove: Column[], toIndex: number): boolean;


doesMovePassLockedPositions(proposedColumnOrder: Column[]): boolean;


doesMovePassMarryChildren(allColumnsCopy: Column[]): boolean;


moveColumn(key: string | Column, toIndex: number, source?: ColumnEventType): void;


moveColumnByIndex(fromIndex: number, toIndex: number, source?: ColumnEventType): void;


getBodyContainerWidth(): number;


getContainerWidth(pinned: string): number;


getValueColumns(): Column[];


getPivotColumns(): Column[];


isPivotActive(): boolean;


getRowGroupColumns(): Column[];


getDisplayedCenterColumns(): Column[];


getDisplayedLeftColumns(): Column[];


getDisplayedRightColumns(): Column[];


getDisplayedColumns(type: string): Column[];


getAllPrimaryColumns(): Column[] | null;


getSecondaryColumns(): Column[] | null;


getAllColumnsForQuickFilter(): Column[];


getAllGridColumns(): Column[];


isEmpty(): boolean;


isRowGroupEmpty(): boolean;


setColumnVisible(key: string | Column, visible: boolean, source?: ColumnEventType): void;


setColumnsVisible(keys: (string | Column)[], visible: boolean, source?: ColumnEventType): void;


setColumnPinned(key: string | Column | null, pinned: string | boolean | null, source?: ColumnEventType): void;


setColumnsPinned(keys: (string | Column)[], pinned: string | boolean | null, source?: ColumnEventType): void;


getDisplayedColBefore(col: Column): Column | null;


getDisplayedColAfter(col: Column): Column | null;


getDisplayedGroupAfter(columnGroup: ColumnGroup): ColumnGroup | null;


getDisplayedGroupBefore(columnGroup: ColumnGroup): ColumnGroup | null;


getDisplayedGroupAtDirection(columnGroup: ColumnGroup, direction: 'After' | 'Before'): ColumnGroup | null;


getColumnGroupAtLevel(column: Column, level: number): ColumnGroup | null;


isPinningLeft(): boolean;


isPinningRight(): boolean;


getPrimaryAndSecondaryAndAutoColumns(): Column[];


getColumnState(): ColumnState[];


resetColumnState(suppressEverythingEvent?: boolean, source?: ColumnEventType): void;


setColumnState(columnStates: ColumnState[], suppressEverythingEvent?: boolean, source?: ColumnEventType): boolean;


getGridColumns(keys: (string | Column)[]): Column[];


getColumnWithValidation(key: string | Column | undefined): Column | null;


getPrimaryColumn(key: string | Column): Column | null;


getGridColumn(key: string | Column): Column | null;


getDisplayNameForColumn(column: Column | null, location: string | null, includeAggFunc?: boolean): string | null;


getDisplayNameForOriginalColumnGroup(columnGroup: ColumnGroup | null, originalColumnGroup: OriginalColumnGroup | null, location: string): string | null;


getDisplayNameForColumnGroup(columnGroup: ColumnGroup, location: string): string | null;


getColumnGroup(colId: string | ColumnGroup, instanceId?: number): ColumnGroup | null;


isReady(): boolean;


resetColumnGroupState(source?: ColumnEventType): void;


getColumnGroupState(): {
        groupId: string;
        open: boolean;
    }[];


setColumnGroupState(stateItems: {
        groupId: string;
        open: boolean | undefined;
    }[], source?: ColumnEventType): void;


setColumnGroupOpened(key: OriginalColumnGroup | string | undefined, newValue: boolean, source?: ColumnEventType): void;


getOriginalColumnGroup(key: OriginalColumnGroup | string): OriginalColumnGroup | null;


getGroupDisplayColumns(): Column[];


isSecondaryColumnsPresent(): boolean;


setSecondaryColumns(colDefs: (ColDef | ColGroupDef)[] | null, source?: ColumnEventType): void;


isPrimaryColumnGroupsPresent(): boolean;


getVirtualHeaderGroupRow(type: string, dept: number): ColumnGroupChild[];


refreshFlexedColumns(updatedFlexViewportWidth?: number, source?: ColumnEventType, silent?: boolean): void;


sizeColumnsToFit(gridWidth: any, source?: ColumnEventType, silent?: boolean): void;


getGroupAutoColumns(): Column[] | null;


getGridBalancedTree(): OriginalColumnGroupChild[];


hasFloatingFilters(): boolean;


getFirstDisplayedColumn(): Column;


export default class BulletList extends Extension {
    constructor(props?: ExtensionProps);
    readonly name: string;
    readonly group: string;
    readonly showMenu: boolean;
    readonly schema: {
        content: string;
        group: string;
        parseDOM: {
            tag: string;
            getAttrs(dom: any): {
                id: any;
            };
        }[];
        attrs: {
            id: {
                default: string;
            };
        };
        toDOM(node: any): (string | number | {
            class: any;
        })[];
    };
    readonly icon: JSX.Element;
    readonly hideBlockMenuOnFocus: boolean;
    active(state: any): boolean;
    enable(state: any): boolean;
    onClick(state: any, dispatch: any): boolean;
    customMenu({ state, dispatch }: {
        state: any;
        dispatch: any;
    }): JSX.Element;
}


active(state: any): boolean;


enable(state: any): boolean;


onClick(state: any, dispatch: any): boolean;


customMenu({ state, dispatch }: {
        state: any;
        dispatch: any;
    }): JSX.Element;


() => {
  return (
    <>
      <ProductCard
          product={product}
          initialValues={{
              count:4,
              maxCount:10
          }}


export class tsSettingDtDto {
  id: number;
  @IsNotEmpty()
  setTimeStampId: number;
  @IsNotEmpty()
  placeName: string;
  latitude: number;
  longitude: number;
  radius: number;
  description: string;
  @IsNotEmpty()
  isActive: boolean;

  companyId: number;
  createdBy: number;
  createdDate: Date;
  modifiedBy: number;
  modifiedDate: Date;
  isDeleted: boolean;
  userId: number;
}


(state) => state.noticias.sugerida


(data) => {
                const f = data;

                if (f != null) {
                    Toast.show({text: "Sugerimos leer: " + f.titulo, duration: Toast.DURATION.SHORT});
                }
            }


(r: any) => {
            console.log("resultados buscarAhora: " +JSON.stringify(r));
            this.resultados = r;
        }


(e) => {
            console.log("error buscarAhora " + e);
            Toast.show({text: "Error en la busqueda", duration: Toast.DURATION.SHORT})
        }


@Component({
    selector: "Search",
    moduleId: module.id,
    templateUrl: "./search.component.html",
    //providers: [NoticiasService]
})

export class SearchComponent implements OnInit {

    resultados: Array<string>;

    layout: ElementRef;

    constructor (

        private noticias: NoticiasService,
        private store: Store<AppState>

        ) {

        // Use the component constructor to inject providers.
    }

    ngOnInit(): void {
        // Init your component properties here.

        /*this.noticias.agregar("Hola");
        this.noticias.agregar("Holaa");
        this.noticias.agregar("Holaaa");*/

        this.store.select((state) => state.noticias.sugerida)
            .subscribe((data) => {
                const f = data;

                if (f != null) {
                    Toast.show({text: "Sugerimos leer: " + f.titulo, duration: Toast.DURATION.SHORT});
                }
            });
    }

    onDrawerButtonTap(): void {
        const sideDrawer = <RadSideDrawer>app.getRootView();
        sideDrawer.showDrawer();
    }

    onItemTap(x):void {
        console.dir(x);

        //this.store.dispatch(new NuevaNoticiaAction(new Noticia(args.view.bindingContext)));
    }

  buscarAhora(s: string) {
        /*this.resultados = this.noticias.buscar().filter((x) => x.indexOf(s) >= 0);

        const layout = <View>this.layout.nativeElement;

        layout.animate({
            backgroundColor: new Color("white"),
            duration: 3000,
            delay: 1500

        }).then(() => layout.animate({

            backgroundColor: new Color("black"),
            duration: 3000,
            delay: 1500
        }));*/

        console.dir("buscarAhora" + s);
        this.noticias.buscar(s).then((r: any) => {
            console.log("resultados buscarAhora: " +JSON.stringify(r));
            this.resultados = r;
        }, (e) => {
            console.log("error buscarAhora " + e);
            Toast.show({text: "Error en la busqueda", duration: Toast.DURATION.SHORT})
        })
    }
}


ngOnInit(): void {
        // Init your component properties here.

        /*this.noticias.agregar("Hola");
        this.noticias.agregar("Holaa");
        this.noticias.agregar("Holaaa");*/

        this.store.select((state) => state.noticias.sugerida)
            .subscribe((data) => {
                const f = data;

                if (f != null) {
                    Toast.show({text: "Sugerimos leer: " + f.titulo, duration: Toast.DURATION.SHORT});
                }
            });
    }


onDrawerButtonTap(): void {
        const sideDrawer = <RadSideDrawer>app.getRootView();
        sideDrawer.showDrawer();
    }


onItemTap(x):void {
        console.dir(x);

        //this.store.dispatch(new NuevaNoticiaAction(new Noticia(args.view.bindingContext)));
    }


buscarAhora(s: string) {
        /*this.resultados = this.noticias.buscar().filter((x) => x.indexOf(s) >= 0);

        const layout = <View>this.layout.nativeElement;

        layout.animate({
            backgroundColor: new Color("white"),
            duration: 3000,
            delay: 1500

        }).then(() => layout.animate({

            backgroundColor: new Color("black"),
            duration: 3000,
            delay: 1500
        }));*/

        console.dir("buscarAhora" + s);
        this.noticias.buscar(s).then((r: any) => {
            console.log("resultados buscarAhora: " +JSON.stringify(r));
            this.resultados = r;
        }, (e) => {
            console.log("error buscarAhora " + e);
            Toast.show({text: "Error en la busqueda", duration: Toast.DURATION.SHORT})
        })
    }


function convertHourToMinutes( time: string ){
    if(!time)
        return false;
    const [hours, minutes] = time.split(':').map(Number);
    return 60*hours + minutes;
}


export class StoreServiceResponseType {
    store: StoreType;
    products: ProductType[]
}


function wantMaterials(vf: ViewFlags) { return vf.materials && RenderMode.SmoothShade === vf.renderMode; }


function wantLighting(vf: ViewFlags) {
  return RenderMode.SmoothShade === vf.renderMode && vf.lighting;
}


() => SurfaceGeometry.create(this.meshData, params.surface.indices)


() => SilhouetteEdgeGeometry.createSilhouettes(this.meshData, edges.silhouettes!)


() => EdgeGeometry.create(this.meshData, edges.segments!)


() => PolylineEdgeGeometry.create(this.meshData, edges.polylines!)


(prim) => prim.collectStatistics(stats)


(prim) => prim.addCommands(cmds)


(prim) => prim.addHiliteCommands(cmds, pass)


/** @internal */
export class MeshData implements WebGLDisposable {
  public readonly edgeWidth: number;
  public readonly hasFeatures: boolean;
  public readonly uniformFeatureId?: number; // Used strictly by BatchPrimitiveCommand.computeisFlashed for flashing volume classification primitives.
  public readonly texture?: Texture;
  public readonly materialInfo?: MaterialInfo;
  public readonly type: SurfaceType;
  public readonly fillFlags: FillFlags;
  public readonly edgeLineCode: number; // Must call LineCode.valueFromLinePixels(val: LinePixels) and set the output to edgeLineCode
  public readonly isPlanar: boolean;
  public readonly hasBakedLighting: boolean;
  public readonly hasFixedNormals: boolean;   // Fixed normals will not be flipped to face front (Terrain skirts).
  public readonly lut: VertexLUT;
  public readonly viewIndependentOrigin?: Point3d;
  private readonly _textureAlwaysDisplayed: boolean;

  private constructor(lut: VertexLUT, params: MeshParams, viOrigin: Point3d | undefined) {
    this.lut = lut;
    this.viewIndependentOrigin = viOrigin;

    this.hasFeatures = FeatureIndexType.Empty !== params.vertices.featureIndexType;
    if (FeatureIndexType.Uniform === params.vertices.featureIndexType)
      this.uniformFeatureId = params.vertices.uniformFeatureID;

    if (undefined !== params.surface.textureMapping) {
      this.texture = params.surface.textureMapping.texture as Texture;
      this._textureAlwaysDisplayed = params.surface.textureMapping.alwaysDisplayed;
    } else {
      this.texture = undefined;
      this._textureAlwaysDisplayed = false;
    }

    this.materialInfo = createMaterialInfo(params.surface.material);

    this.type = params.surface.type;
    this.fillFlags = params.surface.fillFlags;
    this.isPlanar = params.isPlanar;
    this.hasBakedLighting = params.surface.hasBakedLighting;
    this.hasFixedNormals = params.surface.hasFixedNormals;
    const edges = params.edges;
    this.edgeWidth = undefined !== edges ? edges.weight : 1;
    this.edgeLineCode = LineCode.valueFromLinePixels(undefined !== edges ? edges.linePixels : LinePixels.Solid);
  }

  public static create(params: MeshParams, viOrigin: Point3d | undefined): MeshData | undefined {
    const lut = VertexLUT.createFromVertexTable(params.vertices, params.auxChannels);
    return undefined !== lut ? new MeshData(lut, params, viOrigin) : undefined;
  }

  public get isDisposed(): boolean { return undefined === this.texture && this.lut.isDisposed; }

  public dispose() {
    dispose(this.lut);
    if (this._ownsTexture)
      this.texture!.dispose();
  }

  public get isGlyph() { return undefined !== this.texture && this.texture.isGlyph; }
  public get isTextureAlwaysDisplayed() { return this.isGlyph || this._textureAlwaysDisplayed; }

  // Returns true if no one else owns this texture. Implies that the texture should be disposed when this object is disposed, and the texture's memory should be tracked as belonging to this object.
  private get _ownsTexture(): boolean {
    return undefined !== this.texture && undefined === this.texture.key && !this.texture.isOwned;
  }

  public collectStatistics(stats: RenderMemory.Statistics): void {
    stats.addVertexTable(this.lut.bytesUsed);
    if (this._ownsTexture)
      stats.addTexture(this.texture!.bytesUsed);
  }
}


/** @internal */
export class MeshGraphic extends Graphic {
  public readonly meshData: MeshData;
  private readonly _primitives: Primitive[] = [];
  private readonly _instances?: InstanceBuffers;

  public static create(params: MeshParams, instancesOrVIOrigin?: InstancedGraphicParams | Point3d): MeshGraphic | undefined {
    const viOrigin = instancesOrVIOrigin instanceof Point3d ? instancesOrVIOrigin : undefined;
    const instances = undefined === viOrigin ? instancesOrVIOrigin as InstancedGraphicParams : undefined;
    const buffers = undefined !== instances ? InstanceBuffers.create(instances, true) : undefined;
    if (undefined === buffers && undefined !== instances)
      return undefined;

    const data = MeshData.create(params, viOrigin);
    return undefined !== data ? new MeshGraphic(data, params, buffers) : undefined;
  }

  private addPrimitive(createGeom: () => CachedGeometry | undefined, instances?: InstanceBuffers) {
    const primitive = Primitive.createShared(createGeom, instances);
    if (undefined !== primitive)
      this._primitives.push(primitive);
  }

  private constructor(data: MeshData, params: MeshParams, instances?: InstanceBuffers) {
    super();
    this.meshData = data;
    this._instances = instances;

    this.addPrimitive(() => SurfaceGeometry.create(this.meshData, params.surface.indices), instances);

    // Classifiers are surfaces only...no edges.
    if (this.surfaceType === SurfaceType.VolumeClassifier || undefined === params.edges)
      return;

    const edges = params.edges;
    if (undefined !== edges.silhouettes)
      this.addPrimitive(() => SilhouetteEdgeGeometry.createSilhouettes(this.meshData, edges.silhouettes!), instances);

    if (undefined !== edges.segments)
      this.addPrimitive(() => EdgeGeometry.create(this.meshData, edges.segments!), instances);

    if (undefined !== edges.polylines)
      this.addPrimitive(() => PolylineEdgeGeometry.create(this.meshData, edges.polylines!), instances);
  }

  public get isDisposed(): boolean { return this.meshData.isDisposed && 0 === this._primitives.length; }

  public dispose() {
    dispose(this.meshData);
    for (const primitive of this._primitives)
      dispose(primitive);

    this._primitives.length = 0;
  }

  public collectStatistics(stats: RenderMemory.Statistics): void {
    this.meshData.collectStatistics(stats);
    this._primitives.forEach((prim) => prim.collectStatistics(stats));

    // Only count the shared instance buffers once...
    if (undefined !== this._instances)
      this._instances.collectStatistics(stats);
  }

  public addCommands(cmds: RenderCommands): void { this._primitives.forEach((prim) => prim.addCommands(cmds)); }
  public addHiliteCommands(cmds: RenderCommands, pass: RenderPass): void { this._primitives.forEach((prim) => prim.addHiliteCommands(cmds, pass)); }

  public get surfaceType(): SurfaceType { return this.meshData.type; }
}


/** Defines one aspect of the geometry of a mesh (surface or edges)
 * @internal
 */
export abstract class MeshGeometry extends LUTGeometry {
  public readonly mesh: MeshData;
  protected readonly _numIndices: number;

  public get asMesh() { return this; }
  protected _getLineWeight(params: ShaderProgramParams): number { return this.computeEdgeWeight(params); }

  // Convenience accessors...
  public get edgeWidth() { return this.mesh.edgeWidth; }
  public get edgeLineCode() { return this.mesh.edgeLineCode; }
  public get hasFeatures() { return this.mesh.hasFeatures; }
  public get surfaceType() { return this.mesh.type; }
  public get fillFlags() { return this.mesh.fillFlags; }
  public get isPlanar() { return this.mesh.isPlanar; }
  public get colorInfo(): ColorInfo { return this.mesh.lut.colorInfo; }
  public get uniformColor(): FloatRgba | undefined { return this.colorInfo.isUniform ? this.colorInfo.uniform : undefined; }
  public get texture() { return this.mesh.texture; }
  public get hasBakedLighting() { return this.mesh.hasBakedLighting; }
  public get hasFixedNormals() { return this.mesh.hasFixedNormals; }
  public get lut() { return this.mesh.lut; }
  public get hasScalarAnimation() { return this.mesh.lut.hasScalarAnimation; }

  protected constructor(mesh: MeshData, numIndices: number) {
    super(mesh.viewIndependentOrigin);
    this._numIndices = numIndices;
    this.mesh = mesh;
  }

  protected computeEdgeWeight(params: ShaderProgramParams): number { return params.target.getEdgeWeight(params, this.edgeWidth); }
  protected computeEdgeLineCode(params: ShaderProgramParams): number { return params.target.getEdgeLineCode(params, this.edgeLineCode); }
  protected computeEdgeColor(target: Target): ColorInfo { return target.isEdgeColorOverridden ? target.edgeColor : this.colorInfo; }
  protected computeEdgePass(target: Target): RenderPass {
    if (target.isDrawingShadowMap)
      return RenderPass.None;

    const vf = target.currentViewFlags;
    if (RenderMode.SmoothShade === vf.renderMode && !vf.visibleEdges) {
      return RenderPass.None;
    }

    // Only want translucent edges in wireframe mode.
    const isTranslucent = RenderMode.Wireframe === vf.renderMode && vf.transparency && this.colorInfo.hasTranslucency;
    return isTranslucent ? RenderPass.Translucent : RenderPass.OpaqueLinear;
  }
}


/** @internal */
export class EdgeGeometry extends MeshGeometry {
  public readonly buffers: BuffersContainer;
  protected readonly _indices: BufferHandle;
  protected readonly _endPointAndQuadIndices: BufferHandle;

  public get lutBuffers() { return this.buffers; }
  public get asSurface() { return undefined; }
  public get asEdge() { return this; }
  public get asSilhouette(): SilhouetteEdgeGeometry | undefined { return undefined; }

  public static create(mesh: MeshData, edges: SegmentEdgeParams): EdgeGeometry | undefined {
    const indexBuffer = BufferHandle.createArrayBuffer(edges.indices.data);
    const endPointBuffer = BufferHandle.createArrayBuffer(edges.endPointAndQuadIndices);
    return undefined !== indexBuffer && undefined !== endPointBuffer ? new EdgeGeometry(indexBuffer, endPointBuffer, edges.indices.length, mesh) : undefined;
  }

  public get isDisposed(): boolean {
    return this.buffers.isDisposed
      && this._indices.isDisposed
      && this._endPointAndQuadIndices.isDisposed;
  }

  public dispose() {
    dispose(this.buffers);
    dispose(this._indices);
    dispose(this._endPointAndQuadIndices);
  }

  public collectStatistics(stats: RenderMemory.Statistics): void {
    stats.addVisibleEdges(this._indices.bytesUsed + this._endPointAndQuadIndices.bytesUsed);
  }

  protected _draw(numInstances: number, instanceBuffersContainer?: BuffersContainer): void {
    const bufs = instanceBuffersContainer !== undefined ? instanceBuffersContainer : this.buffers;

    bufs.bind();
    System.instance.drawArrays(GL.PrimitiveType.Triangles, 0, this._numIndices, numInstances);
    bufs.unbind();
  }

  protected _wantWoWReversal(_target: Target): boolean { return true; }
  protected _getLineCode(params: ShaderProgramParams): number { return this.computeEdgeLineCode(params); }
  public get techniqueId(): TechniqueId { return TechniqueId.Edge; }
  public getRenderPass(target: Target): RenderPass { return this.computeEdgePass(target); }
  public get renderOrder(): RenderOrder { return this.isPlanar ? RenderOrder.PlanarEdge : RenderOrder.Edge; }
  public getColor(target: Target): ColorInfo { return this.computeEdgeColor(target); }
  public get endPointAndQuadIndices(): BufferHandle { return this._endPointAndQuadIndices; }

  protected constructor(indices: BufferHandle, endPointAndQuadsIndices: BufferHandle, numIndices: number, mesh: MeshData) {
    super(mesh, numIndices);
    this.buffers = BuffersContainer.create();
    const attrPos = AttributeMap.findAttribute("a_pos", TechniqueId.Edge, false);
    const attrEndPointAndQuadIndices = AttributeMap.findAttribute("a_endPointAndQuadIndices", TechniqueId.Edge, false);
    assert(attrPos !== undefined);
    assert(attrEndPointAndQuadIndices !== undefined);
    this.buffers.addBuffer(indices, [BufferParameters.create(attrPos!.location, 3, GL.DataType.UnsignedByte, false, 0, 0, false)]);
    this.buffers.addBuffer(endPointAndQuadsIndices, [BufferParameters.create(attrEndPointAndQuadIndices!.location, 4, GL.DataType.UnsignedByte, false, 0, 0, false)]);
    this._indices = indices;
    this._endPointAndQuadIndices = endPointAndQuadsIndices;
  }
}


/** @internal */
export class SilhouetteEdgeGeometry extends EdgeGeometry {
  private readonly _normalPairs: BufferHandle;

  public get asSilhouette() { return this; }

  public static createSilhouettes(mesh: MeshData, params: SilhouetteParams): SilhouetteEdgeGeometry | undefined {
    const indexBuffer = BufferHandle.createArrayBuffer(params.indices.data);
    const endPointBuffer = BufferHandle.createArrayBuffer(params.endPointAndQuadIndices);
    const normalsBuffer = BufferHandle.createArrayBuffer(params.normalPairs);
    return undefined !== indexBuffer && undefined !== endPointBuffer && undefined !== normalsBuffer ? new SilhouetteEdgeGeometry(indexBuffer, endPointBuffer, normalsBuffer, params.indices.length, mesh) : undefined;
  }

  public get isDisposed(): boolean { return super.isDisposed && this._normalPairs.isDisposed; }

  public dispose() {
    super.dispose();
    dispose(this._normalPairs);
  }

  public collectStatistics(stats: RenderMemory.Statistics): void {
    stats.addSilhouetteEdges(this._indices.bytesUsed + this._endPointAndQuadIndices.bytesUsed + this._normalPairs.bytesUsed);
  }

  public get techniqueId(): TechniqueId { return TechniqueId.SilhouetteEdge; }
  public get renderOrder(): RenderOrder { return this.isPlanar ? RenderOrder.PlanarSilhouette : RenderOrder.Silhouette; }
  public get normalPairs(): BufferHandle { return this._normalPairs; }

  private constructor(indices: BufferHandle, endPointAndQuadsIndices: BufferHandle, normalPairs: BufferHandle, numIndices: number, mesh: MeshData) {
    super(indices, endPointAndQuadsIndices, numIndices, mesh);
    const attrNormals = AttributeMap.findAttribute("a_normals", TechniqueId.SilhouetteEdge, false);
    assert(attrNormals !== undefined);
    this.buffers.addBuffer(normalPairs, [BufferParameters.create(attrNormals!.location, 4, GL.DataType.UnsignedByte, false, 0, 0, false)]);
    this._normalPairs = normalPairs;
  }
}


/** @internal */
export class PolylineEdgeGeometry extends MeshGeometry {
  private _buffers: PolylineBuffers;

  public get lutBuffers() { return this._buffers.buffers; }

  public static create(mesh: MeshData, polyline: TesselatedPolyline): PolylineEdgeGeometry | undefined {
    const buffers = PolylineBuffers.create(polyline);
    return undefined !== buffers ? new PolylineEdgeGeometry(polyline.indices.length, buffers, mesh) : undefined;
  }

  public get isDisposed(): boolean { return this._buffers.isDisposed; }

  public dispose() {
    dispose(this._buffers);
  }

  public collectStatistics(stats: RenderMemory.Statistics): void {
    this._buffers.collectStatistics(stats, RenderMemory.BufferType.PolylineEdges);
  }

  protected _wantWoWReversal(_target: Target): boolean { return true; }
  protected _getLineWeight(params: ShaderProgramParams): number { return this.computeEdgeWeight(params); }
  protected _getLineCode(params: ShaderProgramParams): number { return this.computeEdgeLineCode(params); }
  public get techniqueId(): TechniqueId { return TechniqueId.Polyline; }
  public getRenderPass(target: Target): RenderPass { return this.computeEdgePass(target); }
  public get renderOrder(): RenderOrder { return this.isPlanar ? RenderOrder.PlanarEdge : RenderOrder.Edge; }
  public get polylineBuffers(): PolylineBuffers { return this._buffers; }

  protected _draw(numInstances: number, instanceBuffersContainer?: BuffersContainer): void {
    const gl = System.instance;
    const bufs = instanceBuffersContainer !== undefined ? instanceBuffersContainer : this._buffers.buffers;

    bufs.bind();
    gl.drawArrays(GL.PrimitiveType.Triangles, 0, this._numIndices, numInstances);
    bufs.unbind();
  }

  private constructor(numIndices: number, buffers: PolylineBuffers, mesh: MeshData) {
    super(mesh, numIndices);
    this._buffers = buffers;
  }
}


public static create(params: MeshParams, viOrigin: Point3d | undefined): MeshData | undefined {
    const lut = VertexLUT.createFromVertexTable(params.vertices, params.auxChannels);
    return undefined !== lut ? new MeshData(lut, params, viOrigin) : undefined;
  }


public dispose() {
    dispose(this.lut);
    if (this._ownsTexture)
      this.texture!.dispose();
  }


public collectStatistics(stats: RenderMemory.Statistics): void {
    stats.addVertexTable(this.lut.bytesUsed);
    if (this._ownsTexture)
      stats.addTexture(this.texture!.bytesUsed);
  }


public static create(params: MeshParams, instancesOrVIOrigin?: InstancedGraphicParams | Point3d): MeshGraphic | undefined {
    const viOrigin = instancesOrVIOrigin instanceof Point3d ? instancesOrVIOrigin : undefined;
    const instances = undefined === viOrigin ? instancesOrVIOrigin as InstancedGraphicParams : undefined;
    const buffers = undefined !== instances ? InstanceBuffers.create(instances, true) : undefined;
    if (undefined === buffers && undefined !== instances)
      return undefined;

    const data = MeshData.create(params, viOrigin);
    return undefined !== data ? new MeshGraphic(data, params, buffers) : undefined;
  }


private addPrimitive(createGeom: () => CachedGeometry | undefined, instances?: InstanceBuffers) {
    const primitive = Primitive.createShared(createGeom, instances);
    if (undefined !== primitive)
      this._primitives.push(primitive);
  }


public dispose() {
    dispose(this.meshData);
    for (const primitive of this._primitives)
      dispose(primitive);

    this._primitives.length = 0;
  }


public collectStatistics(stats: RenderMemory.Statistics): void {
    this.meshData.collectStatistics(stats);
    this._primitives.forEach((prim) => prim.collectStatistics(stats));

    // Only count the shared instance buffers once...
    if (undefined !== this._instances)
      this._instances.collectStatistics(stats);
  }


public addCommands(cmds: RenderCommands): void { this._primitives.forEach((prim) => prim.addCommands(cmds)); }


public addHiliteCommands(cmds: RenderCommands, pass: RenderPass): void { this._primitives.forEach((prim) => prim.addHiliteCommands(cmds, pass)); }


protected _getLineWeight(params: ShaderProgramParams): number { return this.computeEdgeWeight(params); }


protected computeEdgeWeight(params: ShaderProgramParams): number { return params.target.getEdgeWeight(params, this.edgeWidth); }


protected computeEdgeLineCode(params: ShaderProgramParams): number { return params.target.getEdgeLineCode(params, this.edgeLineCode); }


protected computeEdgeColor(target: Target): ColorInfo { return target.isEdgeColorOverridden ? target.edgeColor : this.colorInfo; }


protected computeEdgePass(target: Target): RenderPass {
    if (target.isDrawingShadowMap)
      return RenderPass.None;

    const vf = target.currentViewFlags;
    if (RenderMode.SmoothShade === vf.renderMode && !vf.visibleEdges) {
      return RenderPass.None;
    }

    // Only want translucent edges in wireframe mode.
    const isTranslucent = RenderMode.Wireframe === vf.renderMode && vf.transparency && this.colorInfo.hasTranslucency;
    return isTranslucent ? RenderPass.Translucent : RenderPass.OpaqueLinear;
  }


public static create(mesh: MeshData, edges: SegmentEdgeParams): EdgeGeometry | undefined {
    const indexBuffer = BufferHandle.createArrayBuffer(edges.indices.data);
    const endPointBuffer = BufferHandle.createArrayBuffer(edges.endPointAndQuadIndices);
    return undefined !== indexBuffer && undefined !== endPointBuffer ? new EdgeGeometry(indexBuffer, endPointBuffer, edges.indices.length, mesh) : undefined;
  }


public dispose() {
    dispose(this.buffers);
    dispose(this._indices);
    dispose(this._endPointAndQuadIndices);
  }


public collectStatistics(stats: RenderMemory.Statistics): void {
    stats.addVisibleEdges(this._indices.bytesUsed + this._endPointAndQuadIndices.bytesUsed);
  }


protected _draw(numInstances: number, instanceBuffersContainer?: BuffersContainer): void {
    const bufs = instanceBuffersContainer !== undefined ? instanceBuffersContainer : this.buffers;

    bufs.bind();
    System.instance.drawArrays(GL.PrimitiveType.Triangles, 0, this._numIndices, numInstances);
    bufs.unbind();
  }


protected _wantWoWReversal(_target: Target): boolean { return true; }


protected _getLineCode(params: ShaderProgramParams): number { return this.computeEdgeLineCode(params); }


public getRenderPass(target: Target): RenderPass { return this.computeEdgePass(target); }


public getColor(target: Target): ColorInfo { return this.computeEdgeColor(target); }


public static createSilhouettes(mesh: MeshData, params: SilhouetteParams): SilhouetteEdgeGeometry | undefined {
    const indexBuffer = BufferHandle.createArrayBuffer(params.indices.data);
    const endPointBuffer = BufferHandle.createArrayBuffer(params.endPointAndQuadIndices);
    const normalsBuffer = BufferHandle.createArrayBuffer(params.normalPairs);
    return undefined !== indexBuffer && undefined !== endPointBuffer && undefined !== normalsBuffer ? new SilhouetteEdgeGeometry(indexBuffer, endPointBuffer, normalsBuffer, params.indices.length, mesh) : undefined;
  }


public dispose() {
    super.dispose();
    dispose(this._normalPairs);
  }


public collectStatistics(stats: RenderMemory.Statistics): void {
    stats.addSilhouetteEdges(this._indices.bytesUsed + this._endPointAndQuadIndices.bytesUsed + this._normalPairs.bytesUsed);
  }


public static create(mesh: MeshData, polyline: TesselatedPolyline): PolylineEdgeGeometry | undefined {
    const buffers = PolylineBuffers.create(polyline);
    return undefined !== buffers ? new PolylineEdgeGeometry(polyline.indices.length, buffers, mesh) : undefined;
  }


public dispose() {
    dispose(this._buffers);
  }


public collectStatistics(stats: RenderMemory.Statistics): void {
    this._buffers.collectStatistics(stats, RenderMemory.BufferType.PolylineEdges);
  }


protected _draw(numInstances: number, instanceBuffersContainer?: BuffersContainer): void {
    const gl = System.instance;
    const bufs = instanceBuffersContainer !== undefined ? instanceBuffersContainer : this._buffers.buffers;

    bufs.bind();
    gl.drawArrays(GL.PrimitiveType.Triangles, 0, this._numIndices, numInstances);
    bufs.unbind();
  }


public static create(mesh: MeshData, indices: VertexIndices): SurfaceGeometry | undefined {
    const indexBuffer = BufferHandle.createArrayBuffer(indices.data);
    return undefined !== indexBuffer ? new SurfaceGeometry(indexBuffer, indices.length, mesh) : undefined;
  }


public dispose() {
    dispose(this._buffers);
    dispose(this._indices);
  }


public collectStatistics(stats: RenderMemory.Statistics): void {
    stats.addSurface(this._indices.bytesUsed);
  }


protected _draw(numInstances: number, instanceBuffersContainer?: BuffersContainer): void {
    const system = System.instance;
    const gl = system.context;
    const offset = RenderOrder.BlankingRegion === this.renderOrder;
    const bufs = instanceBuffersContainer !== undefined ? instanceBuffersContainer : this._buffers;

    if (offset) {
      gl.enable(GL.POLYGON_OFFSET_FILL);
      gl.polygonOffset(1.0, 1.0);
    }

    bufs.bind();
    const primType = system.drawSurfacesAsWiremesh ? GL.PrimitiveType.Lines : GL.PrimitiveType.Triangles;
    system.drawArrays(primType, 0, this._numIndices, numInstances);
    bufs.unbind();

    if (offset) {
      gl.disable(GL.POLYGON_OFFSET_FILL);
    }
  }


public wantMixMonochromeColor(target: Target): boolean {
    // Text relies on white-on-white reversal.
    return !this.isGlyph && (this.isLitSurface || this.wantTextures(target, this.isTextured));
  }


public getColor(target: Target) {
    if (FillFlags.Background === (this.fillFlags & FillFlags.Background))
      return target.uniforms.style.backgroundColorInfo;
    else
      return this.colorInfo;
  }


public getRenderPass(target: Target): RenderPass {
    // Classifiers have a dedicated pass
    if (this.isClassifier)
      return RenderPass.Classification;

    const opaquePass = this.isPlanar ? RenderPass.OpaquePlanar : RenderPass.OpaqueGeneral;

    // When reading pixels, glyphs are always opaque. Otherwise always transparent (for anti-aliasing).
    if (this.isGlyph)
      return target.isReadPixelsInProgress ? opaquePass : RenderPass.Translucent;

    const vf = target.currentViewFlags;

    // In wireframe, unless fill is explicitly enabled for planar region, surface does not draw
    if (RenderMode.Wireframe === vf.renderMode && !this.mesh.isTextureAlwaysDisplayed) {
      const fillFlags = this.fillFlags;
      const showFill = FillFlags.Always === (fillFlags & FillFlags.Always) || (vf.fill && FillFlags.ByView === (fillFlags & FillFlags.ByView));
      if (!showFill)
        return RenderPass.None;
    }

    // If transparency disabled by render mode or view flag, always draw opaque.
    if (!vf.transparency || RenderMode.SolidFill === vf.renderMode || RenderMode.HiddenLine === vf.renderMode)
      return opaquePass;

    let hasAlpha = false;

    // If the material overrides alpha (currently, everything except the default - aka "no" - material), alpha comes from the material
    const mat = this.isLit && wantMaterials(vf) ? this.mesh.materialInfo : undefined;
    if (undefined !== mat && mat.overridesAlpha)
      hasAlpha = mat.hasTranslucency;

    // A texture can contain translucent pixels. Its alpha is also always multiplied by the material's alpha
    const tex = this.wantTextures(target, true) ? this.texture : undefined;
    if (!hasAlpha && undefined !== tex)
      hasAlpha = tex.hasTranslucency;

    // If we have a material overriding transparency, OR a texture, transparency comes solely from them. Otherwise, use element transparency.
    if (undefined === tex && (undefined === mat || !mat.overridesAlpha))
      hasAlpha = this.getColor(target).hasTranslucency;

    return hasAlpha ? RenderPass.Translucent : opaquePass;
  }


protected _wantWoWReversal(target: Target): boolean {
    const fillFlags = this.fillFlags;
    if (FillFlags.None !== (fillFlags & FillFlags.Background))
      return false; // fill color explicitly from background

    if (FillFlags.None !== (fillFlags & FillFlags.Always))
      return true; // fill displayed even in wireframe

    const vf = target.currentViewFlags;
    if (RenderMode.Wireframe === vf.renderMode || vf.visibleEdges)
      return false; // never invert surfaces when edges are displayed

    if (this.isLit && wantLighting(vf))
      return false;

    // Don't invert white pixels of textures...
    return !this.wantTextures(target, this.isTextured);
  }


public computeSurfaceFlags(params: ShaderProgramParams): SurfaceFlags {
    const target = params.target;
    const vf = target.currentViewFlags;

    const useMaterial = wantMaterials(vf);
    let flags = useMaterial ? SurfaceFlags.None : SurfaceFlags.IgnoreMaterial;
    if (this.isLit) {
      flags |= SurfaceFlags.HasNormals;
      if (wantLighting(vf)) {
        flags |= SurfaceFlags.ApplyLighting;
        if (this.hasFixedNormals)
          flags |= SurfaceFlags.NoFaceFront;
      }

      // Textured meshes store normal in place of color index.
      // Untextured lit meshes store normal where textured meshes would store UV coords.
      // Tell shader where to find normal.
      if (!this.isTextured) {
        flags |= SurfaceFlags.HasColorAndNormal;
      }
    }

    if (this.wantTextures(target, this.isTextured)) {
      flags |= SurfaceFlags.HasTexture;
      if (useMaterial && undefined !== this.mesh.materialInfo && this.mesh.materialInfo.overridesAlpha && RenderPass.Translucent === params.renderPass)
        flags |= SurfaceFlags.MultiplyAlpha;
    }

    switch (params.renderPass) {
      // NB: We need this for opaque pass due to SolidFill (must compute transparency, discard below threshold, render opaque at or above threshold)
      case RenderPass.OpaqueLinear:
      case RenderPass.OpaquePlanar:
      case RenderPass.OpaqueGeneral:
      case RenderPass.Translucent:
      case RenderPass.WorldOverlay:
      case RenderPass.OpaqueLayers:
      case RenderPass.TranslucentLayers:
      case RenderPass.OverlayLayers: {
        const mode = vf.renderMode;
        if (!this.isGlyph && (RenderMode.HiddenLine === mode || RenderMode.SolidFill === mode)) {
          flags |= SurfaceFlags.TransparencyThreshold;
          if (RenderMode.HiddenLine === mode && FillFlags.Always !== (this.fillFlags & FillFlags.Always)) {
            // fill flags test for text - doesn't render with bg fill in hidden line mode.
            flags |= SurfaceFlags.BackgroundFill;
          }
          break;
        }
      }
    }

    if (params.target.isDrawingShadowMap)
      flags |= SurfaceFlags.TransparencyThreshold;

    return flags;
  }


private wantTextures(target: Target, surfaceTextureExists: boolean): boolean {
    if (this.hasScalarAnimation && undefined !== target.analysisTexture)
      return true;

    if (!surfaceTextureExists)
      return false;

    if (this.mesh.isTextureAlwaysDisplayed)
      return true;

    const fill = this.fillFlags;
    const flags = target.currentViewFlags;

    // ###TODO need to distinguish between gradient fill and actual textures...
    switch (flags.renderMode) {
      case RenderMode.SmoothShade:
        return flags.textures;
      case RenderMode.Wireframe:
        return FillFlags.Always === (fill & FillFlags.Always) || (flags.fill && FillFlags.ByView === (fill & FillFlags.ByView));
      default:
        return FillFlags.Always === (fill & FillFlags.Always);
    }
  }


data => {
                    this.datas = data;
                    console.log('value : ' + this.datas[0]);
                }


ref => ref
            .where('status', '==', 'pending')
            .where('useremail', '==', this.value)


dataArray => {
            this.totalpendingBookCount = dataArray.length;
            console.log('XX' + this.totalpendingBookCount )
        }


ref => ref
            .where('status', '==', 'completed')
            .where('useremail', '==', this.value)


dataArray => {
            this.totalnotratedBookCount = dataArray.length;
        }


ref => ref
            .where('status', '==', 'rated')
            .where('useremail', '==', this.value)


dataArray => {
            this.totalcompletedBookCount = dataArray.length;
        }


ref => ref
            .where('status', '==', 'ongoing')
            .where('useremail', '==', this.value)


dataArray => {
            this.totalOngoingBookCount = dataArray.length;
        }


ref => ref.where('email', '==', this.value)


@Component({
    selector: 'app-userprofile',
    templateUrl: './userprofile.component.html',
    styleUrls: ['./userprofile.component.scss']
})

export class UserprofileComponent implements OnInit {
    value: string;
    data: Observable<Item[]>;
    datas: Item[];
    isReceived = false;
    [x: string]: any;
    user = JSON.parse(localStorage.getItem('users'));
    totalpendingBookCount: number;
    totalnotratedBookCount: number;
    totalfinishedratedBookCount: number;
    totalOngoingBookCount: string;

    constructor(public _Activatedroute: ActivatedRoute,
        public ebass: AngularFirestore,
        public authService: AuthService,
        public router: Router) {
    }

    ngOnInit() {
        this.value = this._Activatedroute.snapshot.paramMap.get('email');
        if (this.user) {
            if (this.user.email === this.value) {
                this.getData().subscribe(data => {
                    this.datas = data;
                    console.log('value : ' + this.datas[0]);
                })
            } else {
                // someone logged & parameter email is not his
                window.alert('please login with ' + this._Activatedroute.snapshot.paramMap.get('email'));
                console.log('please log with ' + this.value);
            }
        } else {
            // no user logged in
            this.router.navigate(['signin']);
            window.alert('First u have to log to access this page');
            console.log('please loging before access this page');
        }

        // console.log('value1 : ' + this.value);
        // this.pendingwork = this.ebass.collection('bookings', ref => ref
        // .where('useremail', '==', this.value)
        // .where('status', '==', 'pending')).valueChanges();
        // this.pendingwork.subscribe(dataArray => {
        //     this.totalpendingBookCount = dataArray.length;
        // });

        this.pendingwork = this.ebass.collection('bookings', ref => ref
            .where('status', '==', 'pending')
            .where('useremail', '==', this.value)).valueChanges();
        this.pendingwork.subscribe(dataArray => {
            this.totalpendingBookCount = dataArray.length;
            console.log('XX' + this.totalpendingBookCount )
        });

        this.notrated = this.ebass.collection('bookings', ref => ref
            .where('status', '==', 'completed')
            .where('useremail', '==', this.value)).valueChanges();
        this.notrated.subscribe(dataArray => {
            this.totalnotratedBookCount = dataArray.length;
        });

        this.completed = this.ebass.collection('bookings', ref => ref
            .where('status', '==', 'rated')
            .where('useremail', '==', this.value)).valueChanges();
        this.completed.subscribe(dataArray => {
            this.totalcompletedBookCount = dataArray.length;
        });

        this.ongoing = this.ebass.collection('bookings', ref => ref
            .where('status', '==', 'ongoing')
            .where('useremail', '==', this.value)).valueChanges();
        this.ongoing.subscribe(dataArray => {
            this.totalOngoingBookCount = dataArray.length;
        });

    }

    getData() {
        this.data = this.ebass.collection('users', ref => ref.where('email', '==', this.value)).valueChanges();
        console.log("data" + this.data);
        return this.data;

    }

}


interface Item {
    uid?: string;
    username?: string;
    idNumber?: string;
    email?: string;
    emailVerified?: boolean;
    jobType?: string;
    mobile?: string;
}


ngOnInit() {
        this.value = this._Activatedroute.snapshot.paramMap.get('email');
        if (this.user) {
            if (this.user.email === this.value) {
                this.getData().subscribe(data => {
                    this.datas = data;
                    console.log('value : ' + this.datas[0]);
                })
            } else {
                // someone logged & parameter email is not his
                window.alert('please login with ' + this._Activatedroute.snapshot.paramMap.get('email'));
                console.log('please log with ' + this.value);
            }
        } else {
            // no user logged in
            this.router.navigate(['signin']);
            window.alert('First u have to log to access this page');
            console.log('please loging before access this page');
        }

        // console.log('value1 : ' + this.value);
        // this.pendingwork = this.ebass.collection('bookings', ref => ref
        // .where('useremail', '==', this.value)
        // .where('status', '==', 'pending')).valueChanges();
        // this.pendingwork.subscribe(dataArray => {
        //     this.totalpendingBookCount = dataArray.length;
        // });

        this.pendingwork = this.ebass.collection('bookings', ref => ref
            .where('status', '==', 'pending')
            .where('useremail', '==', this.value)).valueChanges();
        this.pendingwork.subscribe(dataArray => {
            this.totalpendingBookCount = dataArray.length;
            console.log('XX' + this.totalpendingBookCount )
        });

        this.notrated = this.ebass.collection('bookings', ref => ref
            .where('status', '==', 'completed')
            .where('useremail', '==', this.value)).valueChanges();
        this.notrated.subscribe(dataArray => {
            this.totalnotratedBookCount = dataArray.length;
        });

        this.completed = this.ebass.collection('bookings', ref => ref
            .where('status', '==', 'rated')
            .where('useremail', '==', this.value)).valueChanges();
        this.completed.subscribe(dataArray => {
            this.totalcompletedBookCount = dataArray.length;
        });

        this.ongoing = this.ebass.collection('bookings', ref => ref
            .where('status', '==', 'ongoing')
            .where('useremail', '==', this.value)).valueChanges();
        this.ongoing.subscribe(dataArray => {
            this.totalOngoingBookCount = dataArray.length;
        });

    }


getData() {
        this.data = this.ebass.collection('users', ref => ref.where('email', '==', this.value)).valueChanges();
        console.log("data" + this.data);
        return this.data;

    }


export default function AdminArticles(props: any) {
    const jwtContext = useContext(JwtContext);
    const history = useHistory();
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    const { categoryId, courseId }: any = useParams();
    useEffect(() => {
        if (jwtContext.token === null) {
            history.push('/admin/login');
        } else {
            fetchCourse(courseId);
        }
    }, [jwtContext, history, courseId]);
    const [isLoading, setIsLoading] = useState(true);
    const [course, setCourse]: any = useState(null);
    const fetchCourse = (id: number) => {
        fetch(`/api/v1/course/${id}`).then(res => res.json()).then(data => {
            setCourse(data);
            setIsLoading(false);
        }).catch(err => {
            console.error(err);
            alert("Ups! Coś poszło nie tak ...");
        });
    }
    const editArticle = (articleId: number) => {
        history.push(`/admin/article/${articleId}`);
    }
    const [asking, setAsking] = useState(false);
    const [toDelete, setToDelete] = useState(0);
    const deleteArticleStarter = (articleId: number) => {
        setToDelete(articleId);
        setAsking(true);
    }
    const deleteArticle = (articleId: number) => {
        setIsLoading(true);
        fetch(`/api/v1/article/${articleId}`, {
            method: 'DELETE',
            headers: [
                ['Authorization', `somerandomword ${jwtContext.token}`]
            ]
        }).then(() => {
            fetchCourse(courseId);
        })
            .catch(err => {
                console.error(err);
                alert('Ups! Coś poszło nie tak ...');
        })
    }
    return (<>
        {asking ? <Dialog name={"Usuwanie artykułu"} onCancel={() => {setAsking(false)}} onConfirm={() => { deleteArticle(toDelete) }} ></Dialog> : <></>}


() => {
        if (jwtContext.token === null) {
            history.push('/admin/login');
        } else {
            fetchCourse(courseId);
        }
    }


(id: number) => {
        fetch(`/api/v1/course/${id}`).then(res => res.json()).then(data => {
            setCourse(data);
            setIsLoading(false);
        }).catch(err => {
            console.error(err);
            alert("Ups! Coś poszło nie tak ...");
        });
    }


data => {
            setCourse(data);
            setIsLoading(false);
        }


err => {
            console.error(err);
            alert("Ups! Coś poszło nie tak ...");
        }


(articleId: number) => {
        history.push(`/admin/article/${articleId}`);
    }


(articleId: number) => {
        setToDelete(articleId);
        setAsking(true);
    }


(articleId: number) => {
        setIsLoading(true);
        fetch(`/api/v1/article/${articleId}`, {
            method: 'DELETE',
            headers: [
                ['Authorization', `somerandomword ${jwtContext.token}`]
            ]
        }).then(() => {
            fetchCourse(courseId);
        })
            .catch(err => {
                console.error(err);
                alert('Ups! Coś poszło nie tak ...');
        })
    }


() => {
            fetchCourse(courseId);
        }


err => {
                console.error(err);
                alert('Ups! Coś poszło nie tak ...');
        }


(item: any, index: number) =>
                            <AdminArticle key


asking ? <Dialog name={"Usuwanie artykułu"} onCancel={() => {setAsking(false)}} onConfirm={() => { deleteArticle(toDelete) }} >


//-----------------------------------------------------------------------------
// Sprite_Timer
//
// The sprite for displaying the timer.
export class Sprite_Timer extends Sprite {
  _seconds = 0

  constructor()
  constructor(thisClass: Constructable<Sprite_Timer>)
  constructor(arg?: any) {
    super(Sprite);
    if (typeof arg === "function" && arg === Sprite_Timer) {
      return;
    }
    this.initialize(...arguments);
  }

  initialize(..._: any): void {
    super.initialize();
    this._seconds = 0;
    this.createBitmap();
    this.update();
  };

  destroy(options?: any): void {
    this.bitmap!.destroy();
    super.destroy(options);
  };

  createBitmap(): void {
    this.bitmap = new Bitmap(96, 48);
    this.bitmap.fontFace = this.fontFace();
    this.bitmap.fontSize = this.fontSize();
    this.bitmap.outlineColor = ColorManager.outlineColor();
  };

  fontFace(): string {
    return $gameSystem.numberFontFace();
  };

  fontSize(): number {
    return $gameSystem.mainFontSize() + 8;
  };

  update(): void {
    super.update();
    this.updateBitmap();
    this.updatePosition();
    this.updateVisibility();
  };

  updateBitmap(): void {
    if (this._seconds !== $gameTimer.seconds()) {
        this._seconds = $gameTimer.seconds();
        this.redraw();
    }
  };

  redraw(): void {
    const text = this.timerText();
    const width = this.bitmap!.width;
    const height = this.bitmap!.height;
    this.bitmap!.clear();
    this.bitmap!.drawText(text, 0, 0, width, height, "center");
  };

  timerText(): string {
    const min = Math.floor(this._seconds / 60) % 60;
    const sec = this._seconds % 60;
    return min.padZero(2) + ":" + sec.padZero(2);
  };

  updatePosition(): void {
    this.x = (Graphics.width - this.bitmap!.width) / 2;
    this.y = 0;
  };

  updateVisibility(): void {
    this.visible = $gameTimer.isWorking();
  };
}


initialize(..._: any): void {
    super.initialize();
    this._seconds = 0;
    this.createBitmap();
    this.update();
  }


destroy(options?: any): void {
    this.bitmap!.destroy();
    super.destroy(options);
  }


createBitmap(): void {
    this.bitmap = new Bitmap(96, 48);
    this.bitmap.fontFace = this.fontFace();
    this.bitmap.fontSize = this.fontSize();
    this.bitmap.outlineColor = ColorManager.outlineColor();
  }


fontFace(): string {
    return $gameSystem.numberFontFace();
  }


fontSize(): number {
    return $gameSystem.mainFontSize() + 8;
  }


update(): void {
    super.update();
    this.updateBitmap();
    this.updatePosition();
    this.updateVisibility();
  }


updateBitmap(): void {
    if (this._seconds !== $gameTimer.seconds()) {
        this._seconds = $gameTimer.seconds();
        this.redraw();
    }
  }


redraw(): void {
    const text = this.timerText();
    const width = this.bitmap!.width;
    const height = this.bitmap!.height;
    this.bitmap!.clear();
    this.bitmap!.drawText(text, 0, 0, width, height, "center");
  }


timerText(): string {
    const min = Math.floor(this._seconds / 60) % 60;
    const sec = this._seconds % 60;
    return min.padZero(2) + ":" + sec.padZero(2);
  }