function StatusIcon({ status }) {
  switch (status as QueueStatus) {
    case 'Waiting':
      return <InProgress16 />;
    case 'In Service':
      return <Group16 />;
    default:
      return null;
  }
}


function ActiveVisitsTable() {
  const { t } = useTranslation();
  const isDesktop = useLayoutType() === 'desktop';
  const { visitQueueEntries, isLoading } = useVisitQueueEntries();
  const { services } = useServices();
  const [contentSwitcherValue, setContentSwitcherValue] = useState<TableSize>(0);
  const [filteredRows, setFilteredRows] = useState<Array<MappedVisitQueueEntry>>([]);
  const [filter, setFilter] = useState('');
  const [tableSize, setTableSize] = useState<DataTableSize>('compact');
  const [showOverlay, setShowOverlay] = useState(false);

  useEffect(() => {
    if (contentSwitcherValue === 0) {
      setTableSize('compact');
    } else if (contentSwitcherValue === 1) {
      setTableSize('normal');
    }
  }, [contentSwitcherValue]);

  useEffect(() => {
    if (filter) {
      setFilteredRows(visitQueueEntries?.filter((entry) => entry.service === filter && /waiting/i.exec(entry.status)));
      setFilter('');
    }
  }, [filter, filteredRows, visitQueueEntries]);

  const tableHeaders = useMemo(
    () => [
      {
        id: 0,
        header: t('name', 'Name'),
        key: 'name',
      },
      {
        id: 1,
        header: t('priority', 'Priority'),
        key: 'priority',
      },
      {
        id: 2,
        header: t('status', 'Status'),
        key: 'status',
      },
      {
        id: 3,
        header: t('waitTime', 'Wait time (mins)'),
        key: 'waitTime',
      },
    ],
    [t],
  );

  const getTagType = (priority: string) => {
    switch (priority as MappedQueuePriority) {
      case 'Emergency':
        return 'red';
      case 'Not Urgent':
        return 'green';
      default:
        return 'gray';
    }
  };

  const buildStatusString = (status: QueueStatus, service: QueueService) => {
    if (!status || !service) {
      return '';
    }

    if (status === 'Waiting') {
      return `${status} for ${service}`;
    } else if (status === 'In Service') {
      return `Attending ${service}`;
    }
  };

  const tableRows = useMemo(() => {
    return (filteredRows.length ? filteredRows : visitQueueEntries)?.map((entry) => ({
      ...entry,
      name: {
        content: (
          <ConfigurableLink to={`\${openmrsSpaBase}/patient/${entry.patientUuid}/chart`}>{entry.name}</ConfigurableLink>
        ),
      },
      priority: {
        content: (
          <>
            {entry?.priorityComment ? (
              <TooltipDefinition
                className={styles.tooltip}
                align="start"
                direction="bottom"
                tooltipText={entry.priorityComment}>
                <Tag
                  className={entry.priority === 'Priority' ? styles.priorityTag : styles.tag}
                  type={getTagType(entry.priority as string)}


() => {
    if (contentSwitcherValue === 0) {
      setTableSize('compact');
    } else if (contentSwitcherValue === 1) {
      setTableSize('normal');
    }
  }


() => {
    if (filter) {
      setFilteredRows(visitQueueEntries?.filter((entry) => entry.service === filter && /waiting/i.exec(entry.status)));
      setFilter('');
    }
  }


(entry) => entry.service === filter && /waiting/i.exec(entry.status)


() => [
      {
        id: 0,
        header: t('name', 'Name'),
        key: 'name',
      },
      {
        id: 1,
        header: t('priority', 'Priority'),
        key: 'priority',
      },
      {
        id: 2,
        header: t('status', 'Status'),
        key: 'status',
      },
      {
        id: 3,
        header: t('waitTime', 'Wait time (mins)'),
        key: 'waitTime',
      },
    ]


(priority: string) => {
    switch (priority as MappedQueuePriority) {
      case 'Emergency':
        return 'red';
      case 'Not Urgent':
        return 'green';
      default:
        return 'gray';
    }
  }


(status: QueueStatus, service: QueueService) => {
    if (!status || !service) {
      return '';
    }

    if (status === 'Waiting') {
      return `${status} for ${service}`;
    } else if (status === 'In Service') {
      return `Attending ${service}`;
    }
  }


() => {
    return (filteredRows.length ? filteredRows : visitQueueEntries)?.map((entry) => ({
      ...entry,
      name: {
        content: (
          <ConfigurableLink to={`\${openmrsSpaBase}/patient/${entry.patientUuid}/chart`}>{entry.name}</ConfigurableLink>
        ),
      }


(entry) => ({
      ...entry,
      name: {
        content: (
          <ConfigurableLink to={`\${openmrsSpaBase}/patient/${entry.patientUuid}/chart`}>{entry.name}</ConfigurableLink>
        )


({ selectedItem }) => {
    setFilter(selectedItem);
  }


({ rowIds, headers, cellsById, inputValue, getCellId }: FilterProps): Array<string> => {
    return rowIds.filter((rowId) =>
      headers.some(({ key }) => {
        const id = getCellId(rowId, key);
        if (typeof cellsById[id].value === 'boolean') {
          return false;
        }
        if (cellsById[id].value.hasOwnProperty('content')) {
          return ('' + cellsById[id].value.content.props.children).toLowerCase().includes(inputValue.toLowerCase());
        }
        return ('' + cellsById[id].value).toLowerCase().includes(inputValue.toLowerCase());
      }),
    );
  }


(rowId) =>
      headers.some(({ key }) => {
        const id = getCellId(rowId, key);
        if (typeof cellsById[id].value === 'boolean') {
          return false;
        }
        if (cellsById[id].value.hasOwnProperty('content')) {
          return ('' + cellsById[id].value.content.props.children).toLowerCase().includes(inputValue.toLowerCase());
        }
        return ('' + cellsById[id].value).toLowerCase().includes(inputValue.toLowerCase());
      })


({ key }) => {
        const id = getCellId(rowId, key);
        if (typeof cellsById[id].value === 'boolean') {
          return false;
        }
        if (cellsById[id].value.hasOwnProperty('content')) {
          return ('' + cellsById[id].value.content.props.children).toLowerCase().includes(inputValue.toLowerCase());
        }
        return ('' + cellsById[id].value).toLowerCase().includes(inputValue.toLowerCase());
      }


(header) => (
                      <TableHeader {...getHeaderProps({ header })}>{header.header}</TableHeader>
                    )


(row, index) => {
                    return (
                      <React.Fragment key={row.id}>
                        <TableExpandRow {...getRowProps({ row })}>
                          {row.cells.map((cell) => (
                            <TableCell key={cell.id}>{cell.value?.content ?? cell.value}</TableCell>
                          )


(cell) => (
                            <TableCell key={cell.id}>{cell.value?.content ?? cell.value}</TableCell>


() => setShowOverlay(false)


type TableSize = 0 | 1;


type FilterProps = {
  rowIds: Array<string>;
  headers: Array<DataTableHeader>;
  cellsById: any;
  inputValue: string;
  getCellId: (row, key) => string;
};


t('editPatientDetails', 'Edit patient details')


t('setWaitTimeManually', 'Set wait time manually')


t('endVisit', 'End visit')


t('endVisit', 'End Visit')


priorityComment ? (
              <TooltipDefinition
                className={styles.tooltip}
                align="start"
                direction="bottom"
                tooltipText={entry.priorityComment}>
                <Tag
                  className={entry


getTagType(entry


buildStatusString(entry


t('activeVisits', 'Active visits')


t('view', 'View')


t('default', 'Default')


t('large', 'Large')


t('addPatientList', 'Add patient to list')


t('showPatientsWaitingFor', 'Show patients waiting for')


t('searchThisList', 'Search this list')


t('previousVisit', 'Previous visit')


t('addPatientToList', 'Add patient to list')


t('noPatientsToDisplay', 'No patients to display')


export interface UInt64Value {
  'value'?: (number | string | Long);
}


export interface UInt64Value__Output {
  'value': (string);
}


/**
 * This builds the production app.
 * if the current branch should be migrated, it runs migrations first.
 */
function buildProd() {
  let buildCommand = DEFAULT_BUILD_COMMAND;
  const shouldMigrate = process.env.NODE_ENV === 'production';

  if (shouldMigrate) {
    buildCommand = `yarn db:deploy && ${buildCommand}`;
  }

  const child = spawn(buildCommand, {
    shell: true,
    stdio: 'inherit',
  });

  child.on('exit', function (code) {
    process.exit(code);
  });
}


function expectMissingParameters(response: any, parameters: string, next: any) {
      expectBadRequest(response, `Missing required parameters: ${parameters}`, next)
    }


function expectRequireOneOf(response: any, parameters: string, next: any) {
      expectBadRequest(response, `Missing required parameters: Must have at least one of ${parameters}`, next)
    }


function expectBadRequest(response: any, message: string, next: any) {
    expect(response.statusCode).toBe(400)
    expect(response.sent).toEqual({
      status: 'bad-request',
      message
    })
    expect(next).not.toHaveBeenCalled()
  }


function expectInvalidToken(response: any) {
    expect(response.statusCode).toBe(401)
    expect(response.sent).toEqual({ status: 'unauthorized' })
    expect(next).not.toHaveBeenCalled()
  }


function createResponse(): any {
  return {
    status(code: number) {
      this.statusCode = code
      return this
    },
    send(obj: any) {
      this.sent = obj
      return this
    }
  }
}


() => {
  let request: any
  let response: any
  let next: any

  beforeEach(() => {
    request = {
      body: {}
    }

    response = createResponse()

    next = jasmine.createSpy()
  })

  describe('requireAll', () => {
    it('should respond 400 when parameters are missing', () => {
      const handler = requireAll(['name', 'age'], (req, res) => req.body)

      handler(request, response, next)

      expectMissingParameters(response, 'name, age', next)
    })

    it('should respond 400 when some parameters are missing', () => {
      const handler = requireAll(['name', 'age', 'surname'], (req, res) => req.body)

      request.body = { name: 'pepe' }

      handler(request, response, next)

      expectMissingParameters(response, 'age, surname', next)
    })

    it('should work when all parameters are provided', () => {
      const handler = requireAll(['name', 'age'], (req, res) => req.body)

      request.body = { name: 'pepe', age: 33 }

      handler(request, response, next)

      expect(next).toHaveBeenCalled()
    })

    function expectMissingParameters(response: any, parameters: string, next: any) {
      expectBadRequest(response, `Missing required parameters: ${parameters}`, next)
    }
  })

  describe('requireOneOf', () => {
    it('should respond 400 when all parameters are missing', () => {
      const handler = requireOneOf(['id', 'userId'], (req, res) => req.body)

      handler(request, response, next)

      expectRequireOneOf(response, 'id, userId', next)
    })

    it('should respond ok when any of the parameters is included', () => {
      const handler = requireOneOf(['id', 'userId'], (req, res) => req.body)

      request.body = { id: 'id' }
      handler(request, response, next)
      expect(next).toHaveBeenCalled()

      next = jasmine.createSpy()
      request.body = { userId: 'userId' }
      handler(request, response, next)
      expect(next).toHaveBeenCalled()
    })

    function expectRequireOneOf(response: any, parameters: string, next: any) {
      expectBadRequest(response, `Missing required parameters: Must have at least one of ${parameters}`, next)
    }
  })

  function expectBadRequest(response: any, message: string, next: any) {
    expect(response.statusCode).toBe(400)
    expect(response.sent).toEqual({
      status: 'bad-request',
      message
    })
    expect(next).not.toHaveBeenCalled()
  }
}


() => {
    request = {
      body: {}
    }

    response = createResponse()

    next = jasmine.createSpy()
  }


() => {
    it('should respond 400 when parameters are missing', () => {
      const handler = requireAll(['name', 'age'], (req, res) => req.body)

      handler(request, response, next)

      expectMissingParameters(response, 'name, age', next)
    })

    it('should respond 400 when some parameters are missing', () => {
      const handler = requireAll(['name', 'age', 'surname'], (req, res) => req.body)

      request.body = { name: 'pepe' }

      handler(request, response, next)

      expectMissingParameters(response, 'age, surname', next)
    })

    it('should work when all parameters are provided', () => {
      const handler = requireAll(['name', 'age'], (req, res) => req.body)

      request.body = { name: 'pepe', age: 33 }

      handler(request, response, next)

      expect(next).toHaveBeenCalled()
    })

    function expectMissingParameters(response: any, parameters: string, next: any) {
      expectBadRequest(response, `Missing required parameters: ${parameters}`, next)
    }
  }


() => {
      const handler = requireAll(['name', 'age'], (req, res) => req.body)

      handler(request, response, next)

      expectMissingParameters(response, 'name, age', next)
    }


(req, res) => req.body


() => {
      const handler = requireAll(['name', 'age', 'surname'], (req, res) => req.body)

      request.body = { name: 'pepe' }

      handler(request, response, next)

      expectMissingParameters(response, 'age, surname', next)
    }


() => {
      const handler = requireAll(['name', 'age'], (req, res) => req.body)

      request.body = { name: 'pepe', age: 33 }

      handler(request, response, next)

      expect(next).toHaveBeenCalled()
    }


() => {
    it('should respond 400 when all parameters are missing', () => {
      const handler = requireOneOf(['id', 'userId'], (req, res) => req.body)

      handler(request, response, next)

      expectRequireOneOf(response, 'id, userId', next)
    })

    it('should respond ok when any of the parameters is included', () => {
      const handler = requireOneOf(['id', 'userId'], (req, res) => req.body)

      request.body = { id: 'id' }
      handler(request, response, next)
      expect(next).toHaveBeenCalled()

      next = jasmine.createSpy()
      request.body = { userId: 'userId' }
      handler(request, response, next)
      expect(next).toHaveBeenCalled()
    })

    function expectRequireOneOf(response: any, parameters: string, next: any) {
      expectBadRequest(response, `Missing required parameters: Must have at least one of ${parameters}`, next)
    }
  }


() => {
      const handler = requireOneOf(['id', 'userId'], (req, res) => req.body)

      handler(request, response, next)

      expectRequireOneOf(response, 'id, userId', next)
    }


() => {
      const handler = requireOneOf(['id', 'userId'], (req, res) => req.body)

      request.body = { id: 'id' }
      handler(request, response, next)
      expect(next).toHaveBeenCalled()

      next = jasmine.createSpy()
      request.body = { userId: 'userId' }
      handler(request, response, next)
      expect(next).toHaveBeenCalled()
    }


() => {
  let request: any
  let response: any
  let realm: any
  let next: any
  let authenticated: boolean = true

  const validToken = 'valid-token'

  beforeEach(() => {
    authenticated = true
    request = {
      header(header: string) {
        return this._token
      },
      body: { userId: 'userId' }
    }
    response = createResponse()
    realm = {
      getClientById(id) {
        return {
          getToken: () => validToken,
          isAuthenticated: () => authenticated
        }
      }
    }
    next = jasmine.createSpy()
  })

  it('should reject when no token is provided', () => {
    const handler = validatePeerToken(() => realm)

    handler(request, response, next)

    expectInvalidToken(response)
  })

  it('should reject when the token is not the one in the realm', () => {
    const handler = validatePeerToken(() => realm)

    request._token = 'not-valid-token'

    handler(request, response, next)

    expectInvalidToken(response)
  })

  it('should allow when the token is the one in the realm', () => {
    const handler = validatePeerToken(() => realm)

    request._token = validToken

    handler(request, response, next)

    expect(next).toHaveBeenCalled()
  })

  it('should reject when the user is not authenticated', () => {
    const handler = validatePeerToken(() => realm)

    request._token = validToken

    authenticated = false

    handler(request, response, next)

    expectInvalidToken(response)
  })

  function expectInvalidToken(response: any) {
    expect(response.statusCode).toBe(401)
    expect(response.sent).toEqual({ status: 'unauthorized' })
    expect(next).not.toHaveBeenCalled()
  }
}


() => {
    authenticated = true
    request = {
      header(header: string) {
        return this._token
      },
      body: { userId: 'userId' }
    }
    response = createResponse()
    realm = {
      getClientById(id) {
        return {
          getToken: () => validToken,
          isAuthenticated: () => authenticated
        }
      }
    }
    next = jasmine.createSpy()
  }


() => validToken


() => authenticated


() => {
    const handler = validatePeerToken(() => realm)

    handler(request, response, next)

    expectInvalidToken(response)
  }


() => realm


() => {
    const handler = validatePeerToken(() => realm)

    request._token = 'not-valid-token'

    handler(request, response, next)

    expectInvalidToken(response)
  }


() => {
    const handler = validatePeerToken(() => realm)

    request._token = validToken

    handler(request, response, next)

    expect(next).toHaveBeenCalled()
  }


() => {
    const handler = validatePeerToken(() => realm)

    request._token = validToken

    authenticated = false

    handler(request, response, next)

    expectInvalidToken(response)
  }


header(header: string) {
        return this._token
      }


getClientById(id) {
        return {
          getToken: () => validToken,
          isAuthenticated: () => authenticated
        }
      }


status(code: number) {
      this.statusCode = code
      return this
    }


send(obj: any) {
      this.sent = obj
      return this
    }


export enum PlatformDictionary {
  SPOTIFY = 'Spotify',
  ITUNES = 'iTunes',
  APPLE_MUSIC = 'Apple Music',
  YOUTUBE = 'YouTube',
  YOUTUBE_MUSIC = 'YouTube Music',
  GOOGLE = 'Google Play Music',
  GOOGLE_STORE = 'Google Play Music Store',
  PANDORA = 'Pandora',
  DEEZER = 'Deezer',
  TIDAL = 'Tidal',
  AMAZON_STORE = 'Amazon Music Store',
  AMAZON_MUSIC = 'Amazon Music',
  SOUNDCLOUD = 'SoundCloud',
  NAPSTER = 'Napster',
  YANDEX = 'Яндекс.Музыка',
  SPINRILLA = 'Spinrilla',
  VK = 'VK',
  BOOM = 'BOOM',
}


(m: string) => {
  const matched = m.match(/\.\/([0-9a-zA-Z_]*)\.json/);
  if (matched) {
    echarts.registerMap(matched[1], maps(m));
  } else {
    console.warn(
      "Can't register map: JSON file Should be named according to the following rules: /([0-9a-zA-Z_]*).json/."
    );
  }
}


() => ({
  tips: css`
    padding: 0 10%;
    height: 100%;
    background: rgba(128, 128, 128, 0.1);
    overflow: auto;
  `,
  tipsTitle: css`
    margin: 48px 0 32px;
    text-align: center;
  `,
  wrapper: css`
    position: relative;
  `,
})


({ options, data, width, height, theme }) => {
  const styles = getStyles();
  const echartRef = useRef<HTMLDivElement>(null);
  const [chart, setChart] = useState<echarts.ECharts>();
  const [tips, setTips] = useState<Error | undefined>();

  const resetOption = debounce(
    () => {
      if (!chart) {
        return;
      }
      if (data.state && data.state !== 'Done') {
        return;
      }
      try {
        setTips(undefined);
        chart.clear();
        let getOption = new Function(funcParams, options.getOption);
        const o = getOption(data, theme, chart, echarts);
        o && chart.setOption(o);
      } catch (err) {
        console.error('Editor content error!', err);
        setTips(err);
      }
    },
    150,
    { leading: true }
  );

  useEffect(() => {
    if (echartRef.current) {
      chart?.clear();
      chart?.dispose();
      setChart(echarts.init(echartRef.current, options.followTheme ? theme.type : undefined));
    }

    return () => {
      chart?.clear();
      chart?.dispose();
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [echartRef.current, options.followTheme]);

  useEffect(() => {
    chart?.resize();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [width, height]);

  useEffect(() => {
    chart && resetOption();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [chart, options.getOption, data]);

  return (
    <>
      {tips && (

Editor content error!

          {(tips.stack || tips.message).split('\n').map(s => (

{s}

          ))}


() => {
      if (!chart) {
        return;
      }
      if (data.state && data.state !== 'Done') {
        return;
      }
      try {
        setTips(undefined);
        chart.clear();
        let getOption = new Function(funcParams, options.getOption);
        const o = getOption(data, theme, chart, echarts);
        o && chart.setOption(o);
      } catch (err) {
        console.error('Editor content error!', err);
        setTips(err);
      }
    }


() => {
    if (echartRef.current) {
      chart?.clear();
      chart?.dispose();
      setChart(echarts.init(echartRef.current, options.followTheme ? theme.type : undefined));
    }

    return () => {
      chart?.clear();
      chart?.dispose();
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }


() => {
      chart?.clear();
      chart?.dispose();
    }


() => {
    chart?.resize();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }


() => {
    chart && resetOption();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }


s => (
            <p>{s}</p>
          )


interface Props extends PanelProps<SimpleOptions> {
  theme: GrafanaTheme;
}


cx(
          styles


() => {
        let { background = "blue"} = this.props;
        return (
            <div className="water" style={{background}}


export default class WaveComponent extends Component<Props, State> {

    render = () => {
        let { background = "blue"} = this.props;
        return (
            <div className="water" style={{background}}


interface Props {
    background: string

}


interface State {

}


(event:ProgressEvent) => {
  this.service.notify(this.createProgress(event));
    }


() => {
    this.service.endTracking();
  }


@Injectable()
export class ProgressService {
  private uploadProgress: Subject<any>;
  private downloadProgress: Subject<any>;
   startTracking() {
    this.uploadProgress = new Subject();
    return this.uploadProgress;
  }

  notify(progress) {
    if (this.uploadProgress)
      this.uploadProgress.next(progress);
  }

  endTracking() {
    if (this.uploadProgress)
      this.uploadProgress.complete();
  }

}


@Injectable()
export class BrowserXhrWithProgress extends BrowserXhr {

  constructor(private service: ProgressService) { super(); }

  build(): XMLHttpRequest {
    var xhr: XMLHttpRequest = super.build();

  //   //for downloads
  //   xhr.onprogress = (event) => {
  //     this.service.downloadProgress.next(this.createProgress(event));
  // }

  xhr.upload.onprogress = (event:ProgressEvent) => {
  this.service.notify(this.createProgress(event));
    };

  xhr.upload.onloadend = () => {
    this.service.endTracking();
  }
  return xhr;

}

  private createProgress(event : ProgressEvent) {
    return {
        total: event.total,
        percentage: Math.round(event.loaded / event.total * 100)
    };
  }
}


startTracking() {
    this.uploadProgress = new Subject();
    return this.uploadProgress;
  }


notify(progress) {
    if (this.uploadProgress)
      this.uploadProgress.next(progress);
  }


endTracking() {
    if (this.uploadProgress)
      this.uploadProgress.complete();
  }


build(): XMLHttpRequest {
    var xhr: XMLHttpRequest = super.build();

  //   //for downloads
  //   xhr.onprogress = (event) => {
  //     this.service.downloadProgress.next(this.createProgress(event));
  // }

  xhr.upload.onprogress = (event:ProgressEvent) => {
  this.service.notify(this.createProgress(event));
    };

  xhr.upload.onloadend = () => {
    this.service.endTracking();
  }
  return xhr;

}


private createProgress(event : ProgressEvent) {
    return {
        total: event.total,
        percentage: Math.round(event.loaded / event.total * 100)
    };
  }


/**
 * Returns an Observable that delays the emission of items from the source Observable
 * by a given timeout or until a given Date.
 * @param {number|Date} delay the timeout value or date until which the emission of the source items is delayed.
 * @param {Scheduler} [scheduler] the Scheduler to use for managing the timers that handle the timeout for each item.
 * @return {Observable} an Observable that delays the emissions of the source Observable by the specified timeout or Date.
 * @method delay
 * @owner Observable
 */
export function delay<T>(delay: number|Date,
                         scheduler: Scheduler = async): Observable<T> {
  const absoluteDelay = isDate(delay);
  const delayFor = absoluteDelay ? (+delay - scheduler.now()) : Math.abs(<number>delay);
  return this.lift(new DelayOperator(delayFor, scheduler));
}


class DelayOperator<T> implements Operator<T, T> {
  constructor(private delay: number,
              private scheduler: Scheduler) {
  }

  call(subscriber: Subscriber<T>): Subscriber<T> {
    return new DelaySubscriber(subscriber, this.delay, this.scheduler);
  }
}


class DelaySubscriber<T> extends Subscriber<T> {
  private queue: Array<any> = [];
  private active: boolean = false;
  private errored: boolean = false;

  private static dispatch(state: any): void {
    const source = state.source;
    const queue = source.queue;
    const scheduler = state.scheduler;
    const destination = state.destination;

    while (queue.length > 0 && (queue[0].time - scheduler.now()) <= 0) {
      queue.shift().notification.observe(destination);
    }

    if (queue.length > 0) {
      const delay = Math.max(0, queue[0].time - scheduler.now());
      (<any> this).schedule(state, delay);
    } else {
      source.active = false;
    }
  }

  constructor(destination: Subscriber<T>,
              private delay: number,
              private scheduler: Scheduler) {
    super(destination);
  }

  private _schedule(scheduler: Scheduler): void {
    this.active = true;
    this.add(scheduler.schedule(DelaySubscriber.dispatch, this.delay, {
      source: this, destination: this.destination, scheduler: scheduler
    }));
  }

  private scheduleNotification(notification: Notification<any>): void {
    if (this.errored === true) {
      return;
    }

    const scheduler = this.scheduler;
    const message = new DelayMessage(scheduler.now() + this.delay, notification);
    this.queue.push(message);

    if (this.active === false) {
      this._schedule(scheduler);
    }
  }

  protected _next(value: T) {
    this.scheduleNotification(Notification.createNext(value));
  }

  protected _error(err: any) {
    this.errored = true;
    this.queue = [];
    this.destination.error(err);
  }

  protected _complete() {
    this.scheduleNotification(Notification.createComplete());
  }
}


class DelayMessage<T> {
  constructor(private time: number,
              private notification: any) {
  }
}


export interface DelaySignature<T> {
  (delay: number | Date, scheduler?: Scheduler): Observable<T>;
}


call(subscriber: Subscriber<T>): Subscriber<T> {
    return new DelaySubscriber(subscriber, this.delay, this.scheduler);
  }


private static dispatch(state: any): void {
    const source = state.source;
    const queue = source.queue;
    const scheduler = state.scheduler;
    const destination = state.destination;

    while (queue.length > 0 && (queue[0].time - scheduler.now()) <= 0) {
      queue.shift().notification.observe(destination);
    }

    if (queue.length > 0) {
      const delay = Math.max(0, queue[0].time - scheduler.now());
      (<any> this).schedule(state, delay);
    } else {
      source.active = false;
    }
  }


private _schedule(scheduler: Scheduler): void {
    this.active = true;
    this.add(scheduler.schedule(DelaySubscriber.dispatch, this.delay, {
      source: this, destination: this.destination, scheduler: scheduler
    }));
  }


private scheduleNotification(notification: Notification<any>): void {
    if (this.errored === true) {
      return;
    }

    const scheduler = this.scheduler;
    const message = new DelayMessage(scheduler.now() + this.delay, notification);
    this.queue.push(message);

    if (this.active === false) {
      this._schedule(scheduler);
    }
  }


protected _next(value: T) {
    this.scheduleNotification(Notification.createNext(value));
  }


protected _error(err: any) {
    this.errored = true;
    this.queue = [];
    this.destination.error(err);
  }


protected _complete() {
    this.scheduleNotification(Notification.createComplete());
  }


m => `enter : ${m}`


val => {
            console.log('Text value changed : ' + val);
        }


// SampleForm
@Component({
    // tslint:disable-next-line:component-selector
    selector: 'page-sample-form',
    template: '<hlc-clr-form [definition]="definition"></hlc-clr-form>'
})
export class PageSampleFormComponent {
    readonly definition: ClrFormLayouts.ClrFormLayout = {
        kind: 'fields',
        fields: [{ id: 'name', kind: 'TextField', props: { label: 'Name', placeholder: 'enter person name' } }]
    };
}


@NgModule({
    declarations: [PageSampleFormComponent],
    exports: [PageSampleFormComponent],
    imports: [HlcClrFormModule]
})
export class PageSampleFormModule {}


//
// SampleFormObservableProp
@Component({
    // tslint:disable-next-line:component-selector
    selector: 'page-sample-obs-prop-form',
    template: '<hlc-clr-form [definition]="definition"></hlc-clr-form>'
})
export class PageSampleFormObsPropComponent {
    readonly definition: ClrFormLayouts.ClrFormLayout = {
        kind: 'fields',
        fields: [
            {
                id: 'name',
                kind: 'TextField',
                props: {
                    label: 'Name',
                    placeholder: interval(1000).pipe(
                        take(100),
                        map(m => `enter : ${m}`)
                    )
                }
            }
        ]
    };
}


@NgModule({
    declarations: [PageSampleFormObsPropComponent],
    exports: [PageSampleFormObsPropComponent],
    imports: [HlcClrFormModule]
})
export class PageSampleFormObsPropModule {}


//
// SampleOutputForm
@Component({
    // tslint:disable-next-line:component-selector
    selector: 'page-sample-output-form',
    template: '<hlc-clr-form [definition]="definition"></hlc-clr-form>'
})
export class PageSampleOutputComponent implements OnDestroy {
    readonly destroy$ = new Subject();
    readonly subj = new Subject<string>();

    readonly definition: ClrFormLayouts.ClrFormLayout;

    constructor() {
        this.definition = {
            kind: 'fields',
            fields: [
                {
                    id: 'name',
                    kind: 'TextField',
                    props: {
                        label: 'Name',
                        valueChange: this.subj
                    }
                }
            ]
        };

        this.subj.pipe(takeUntil(this.destroy$)).subscribe(val => {
            console.log('Text value changed : ' + val);
        });
    }

    ngOnDestroy() {
        this.destroy$.next();
    }
}


@NgModule({
    declarations: [PageSampleOutputComponent],
    exports: [PageSampleOutputComponent],
    imports: [HlcClrFormModule]
})
export class PageSampleOutputFormModule {}


//
@Component({
    selector: 'hlc-first-form',
    templateUrl: './first-form.component.html',
    styleUrls: ['./first-form.component.scss'],
    changeDetection: ChangeDetectionStrategy.OnPush
})
export class FirstFormComponent implements OnInit {
    pageSampleFormCode = pageSampleFormCode;
    pageSampleFormObservableProp = pageSampleFormObservableProp;
    pageSampleOutputForm = pageSampleOutputForm;

    constructor() {}

    ngOnInit() {}
}


ngOnDestroy() {
        this.destroy$.next();
    }


@NgModule({
  imports: [
    FormsModule,
    MatButtonModule,
    MatCardModule,
    MatCheckboxModule,
    MatRadioModule,
    MatSlideToggleModule,
    ReactiveFormsModule,
  ],
  declarations: EXAMPLES,
  exports: EXAMPLES,
})
export class SlideToggleExamplesModule {
}


class ServerMiddleware implements Middleware {
  public use(io, socket, next) {
    console.log('ServerMiddleware');
    next();
  }
}


@Injectable()
class ControllerMiddleware implements Middleware {
  public use(io, socket, args, next) {
    console.log('ControllerMiddleware');
    next();
  }
}


@Controller('/', [ControllerMiddleware, ControllerMiddleware, ControllerMiddleware])
@Injectable()
class ConnectionController {

  constructor(@Inject(MESSAGE) private welcomeMessage: string) {}

  @Connect()
  public connect(@Socket() socket: SocketIO.Socket) {
    console.log('Socket.id=', socket.id);
  }

  @Event('message')
  public message(@Args() message: string) {
    console.log('Message', this.welcomeMessage, message);
  }

}


public use(io, socket, next) {
    console.log('ServerMiddleware');
    next();
  }


public use(io, socket, args, next) {
    console.log('ControllerMiddleware');
    next();
  }


@Connect()
  public connect(@Socket() socket: SocketIO.Socket) {
    console.log('Socket.id=', socket.id);
  }


@Event('message')
  public message(@Args() message: string) {
    console.log('Message', this.welcomeMessage, message);
  }


@Controller('courses')
export class CoursesController {
    constructor(private coursesService: CoursesService) {
    }

    @Get()
    getAllCourses() {
        return this.coursesService.displayAllCourses();
    }

    @Get('popular')
    getPopularCourses() {
        return this.coursesService.displayPopularCourses();
    }
}


@Get()
    getAllCourses() {
        return this.coursesService.displayAllCourses();
    }


@Get('popular')
    getPopularCourses() {
        return this.coursesService.displayPopularCourses();
    }


@Component({
  selector: 'app-new-channel-dialog',
  templateUrl: './new-channel-dialog.component.html',
  styleUrls: ['./new-channel-dialog.component.css']
})
export class NewChannelDialog implements OnInit {

  public channelTitle = "";

  constructor(public dialogRef: MdDialogRef<any>) { }

  ngOnInit() {
  }

  public create() {
    console.log(this.channelTitle);
    this.dialogRef.close(true);
  }

}


public create() {
    console.log(this.channelTitle);
    this.dialogRef.close(true);
  }


export interface BetRecord {
		RecordNumber:string;
		OpenNumber:string;
		Sum:string;
		BetAmount:string;
		WinAmount:string;
		RecordTime:string;
	}


() => {
  return (
    <RequireAuthenticated>
      <TopIndexTemplate />
    </RequireAuthenticated>
  );
}


export declare function bindResizeHandler(interactable: Interact.Interactable, resizeHandlerProps: ResizeHandlerProps): Interact.Interactable;


export declare function setIsResizing(value: boolean): void;


export declare function isResizing(): boolean;


export interface ResizeHandlerProps {
    layoutItemId: string;
    onResizeStart?: (id: string, initWidth: number, initHeight: number) => void;
    onResizing?: (id: string, x: number, y: number, dw: number, dh: number, shiftKey?: boolean) => void;
    onResizeEnd?: (id: string, x: number, y: number, dw: number, dh: number, shiftKey?: boolean) => void;
}


export default function NeonText(props: NeonTextProps){
    const { text, custom_style } = props;

    if(text.length < 4) throw new Error("text.length should > 4");

    const brand_style = custom_style?.brand_style ? custom_style.brand_style : {};
    const text_style = custom_style?.text_style ? custom_style.text_style : {};

    return(

              {text.slice(0,1)}{text.slice(1,2)}{text.slice(2)}

    )
}


export type NeonTextProps = {
    text: string
    custom_style?: {
        brand_style?: CSSProperties
        text_style?: CSSProperties
    }
}


() => {
    document.addEventListener('click', this.onDocClick);
    document.addEventListener('touchstart', this.onDocClick);
    document.addEventListener('keydown', this.onEscPress);
  }


() => {
    document.removeEventListener('click', this.onDocClick);
    document.removeEventListener('touchstart', this.onDocClick);
    document.removeEventListener('keydown', this.onEscPress);
  }


(event: MouseEvent | TouchEvent) => {
    const { isOpen, parentRef, onToggle, getMenuRef } = this.props;
    const menuRef = getMenuRef && getMenuRef();
    const clickedOnToggle = parentRef && parentRef.current && parentRef.current.contains(event.target as Node);
    const clickedWithinMenu = menuRef && menuRef.contains && menuRef.contains(event.target as Node);
    if (isOpen && !(clickedOnToggle || clickedWithinMenu)) {
      onToggle(false, event);
    }
  }


(event: KeyboardEvent) => {
    const { parentRef, getMenuRef } = this.props;
    const keyCode = event.keyCode || event.which;
    const menuRef = getMenuRef && getMenuRef();
    const escFromToggle = parentRef && parentRef.current && parentRef.current.contains(event.target as Node);
    const escFromWithinMenu = menuRef && menuRef.contains && menuRef.contains(event.target as Node);
    if (
      this.props.isOpen &&
      (keyCode === KEY_CODES.ESCAPE_KEY || event.key === 'Tab') &&
      (escFromToggle || escFromWithinMenu)
    ) {
      this.props.onToggle(false, event);
      this.buttonRef.current.focus();
    }
  }


(event: React.KeyboardEvent<any>) => {
    if (event.key === 'Tab' && !this.props.isOpen) {
      return;
    }
    if ((event.key === 'Tab' || event.key === 'Enter' || event.key === ' ') && this.props.isOpen) {
      if (!this.props.bubbleEvent) {
        event.stopPropagation();
      }
      event.preventDefault();

      this.props.onToggle(!this.props.isOpen, event);
    } else if ((event.key === 'Enter' || event.key === ' ') && !this.props.isOpen) {
      if (!this.props.bubbleEvent) {
        event.stopPropagation();
      }
      event.preventDefault();

      this.props.onToggle(!this.props.isOpen, event);
      this.props.onEnter();
    }
  }


export class Toggle extends React.Component<ToggleProps> {
  static displayName = 'Toggle';
  private buttonRef = React.createRef<HTMLButtonElement>();

  static defaultProps: PickOptional<ToggleProps> = {
    className: '',
    isOpen: false,
    isActive: false,
    isDisabled: false,
    isPlain: false,
    isPrimary: false,
    isSplitButton: false,
    onToggle: () => {},
    onEnter: () => {},
    bubbleEvent: false
  };

  componentDidMount = () => {
    document.addEventListener('click', this.onDocClick);
    document.addEventListener('touchstart', this.onDocClick);
    document.addEventListener('keydown', this.onEscPress);
  };

  componentWillUnmount = () => {
    document.removeEventListener('click', this.onDocClick);
    document.removeEventListener('touchstart', this.onDocClick);
    document.removeEventListener('keydown', this.onEscPress);
  };

  onDocClick = (event: MouseEvent | TouchEvent) => {
    const { isOpen, parentRef, onToggle, getMenuRef } = this.props;
    const menuRef = getMenuRef && getMenuRef();
    const clickedOnToggle = parentRef && parentRef.current && parentRef.current.contains(event.target as Node);
    const clickedWithinMenu = menuRef && menuRef.contains && menuRef.contains(event.target as Node);
    if (isOpen && !(clickedOnToggle || clickedWithinMenu)) {
      onToggle(false, event);
    }
  };

  onEscPress = (event: KeyboardEvent) => {
    const { parentRef, getMenuRef } = this.props;
    const keyCode = event.keyCode || event.which;
    const menuRef = getMenuRef && getMenuRef();
    const escFromToggle = parentRef && parentRef.current && parentRef.current.contains(event.target as Node);
    const escFromWithinMenu = menuRef && menuRef.contains && menuRef.contains(event.target as Node);
    if (
      this.props.isOpen &&
      (keyCode === KEY_CODES.ESCAPE_KEY || event.key === 'Tab') &&
      (escFromToggle || escFromWithinMenu)
    ) {
      this.props.onToggle(false, event);
      this.buttonRef.current.focus();
    }
  };

  onKeyDown = (event: React.KeyboardEvent<any>) => {
    if (event.key === 'Tab' && !this.props.isOpen) {
      return;
    }
    if ((event.key === 'Tab' || event.key === 'Enter' || event.key === ' ') && this.props.isOpen) {
      if (!this.props.bubbleEvent) {
        event.stopPropagation();
      }
      event.preventDefault();

      this.props.onToggle(!this.props.isOpen, event);
    } else if ((event.key === 'Enter' || event.key === ' ') && !this.props.isOpen) {
      if (!this.props.bubbleEvent) {
        event.stopPropagation();
      }
      event.preventDefault();

      this.props.onToggle(!this.props.isOpen, event);
      this.props.onEnter();
    }
  };

  render() {
    const {
      className,
      children,
      isOpen,
      isDisabled,
      isPlain,
      isPrimary,
      isSplitButton,
      onToggle,
      'aria-haspopup': ariaHasPopup,
      /* eslint-disable @typescript-eslint/no-unused-vars */
      isActive,
      bubbleEvent,
      onEnter,
      parentRef,
      getMenuRef,
      /* eslint-enable @typescript-eslint/no-unused-vars */
      id,
      type,
      ...props
    } = this.props;
    return (
      <DropdownContext.Consumer>
        {({ toggleClass }) => (
          <button
            {...props}
            id={id}
            ref={this.buttonRef}
            className={css(
              isSplitButton ? styles.dropdownToggleButton : toggleClass || styles.dropdownToggle,
              isActive && styles.modifiers.active,
              isPlain && styles.modifiers.plain,
              isPrimary && styles.modifiers.primary,
              className
            )}
            type={type || 'button'}


export interface ToggleProps {
  /** HTML ID of dropdown toggle */
  id: string;
  /** Type to put on the button */
  type?: 'button' | 'submit' | 'reset';
  /** Anything which can be rendered as dropdown toggle */
  children?: React.ReactNode;
  /** Classes applied to root element of dropdown toggle */
  className?: string;
  /** Flag to indicate if menu is opened */
  isOpen?: boolean;
  /** Callback called when toggle is clicked */
  onToggle?: (
    isOpen: boolean,
    event: MouseEvent | TouchEvent | KeyboardEvent | React.KeyboardEvent<any> | React.MouseEvent<HTMLButtonElement>
  ) => void;
  /** Callback called when the Enter key is pressed */
  onEnter?: () => void;
  /** Element which wraps toggle */
  parentRef?: any;
  /** The menu element */
  getMenuRef?: () => HTMLElement;
  /** Forces active state */
  isActive?: boolean;
  /** Disables the dropdown toggle */
  isDisabled?: boolean;
  /** Display the toggle with no border or background */
  isPlain?: boolean;
  /** Display the toggle with a primary button style */
  isPrimary?: boolean;
  /** Style the toggle as a child of a split button */
  isSplitButton?: boolean;
  /** Flag for aria popup */
  'aria-haspopup'?: boolean | 'listbox' | 'menu' | 'dialog' | 'grid' | 'tree';
  /** Allows selecting toggle to select parent */
  bubbleEvent?: boolean;
}


render() {
    const {
      className,
      children,
      isOpen,
      isDisabled,
      isPlain,
      isPrimary,
      isSplitButton,
      onToggle,
      'aria-haspopup': ariaHasPopup,
      /* eslint-disable @typescript-eslint/no-unused-vars */
      isActive,
      bubbleEvent,
      onEnter,
      parentRef,
      getMenuRef,
      /* eslint-enable @typescript-eslint/no-unused-vars */
      id,
      type,
      ...props
    } = this.props;
    return (
      <DropdownContext.Consumer>
        {({ toggleClass }) => (
          <button
            {...props}
            id={id}
            ref={this.buttonRef}
            className={css(
              isSplitButton ? styles.dropdownToggleButton : toggleClass || styles.dropdownToggle,
              isActive && styles.modifiers.active,
              isPlain && styles.modifiers.plain,
              isPrimary && styles.modifiers.primary,
              className
            )}


css(
              isSplitButton ? styles


onToggle(!isOpen, event)


(): ElementFinder => element(by.id('update-vehicle__license-plate'))


(): ElementFinder => element(by.id('update-vehicle__error-license-plate-required'))


(): ElementFinder => element(by.id('update-vehicle__error-license-plate-max-length'))


(): ElementFinder => element(by.id('update-vehicle__error-license-plate-min-length'))


(): ElementFinder => element(by.id('update-vehicle__vehicle-name'))


(): ElementFinder => element(by.id('update-vehicle__error--vehicle-name-required'))


(): ElementFinder => element(by.id('update-vehicle__vehicle-type'))


(option: string): ElementFinder => element(by.id(`update-vehicle__vehicle-type--option-${option}`))


(): ElementFinder => element(by.id('update-vehicle__error--vehicle-type-required'))


(): ElementFinder => element(by.id('update-vehicle__btn-update'))


export class UpdateVehiclePage {
    private VEHICLE = {
        licensePlateInput: (): ElementFinder => element(by.id('update-vehicle__license-plate')),
        requiredLicensePlateError: (): ElementFinder => element(by.id('update-vehicle__error-license-plate-required')),
        maxLengthLicensePlateError: (): ElementFinder => element(by.id('update-vehicle__error-license-plate-max-length')),
        minLengthLicensePlateError: (): ElementFinder => element(by.id('update-vehicle__error-license-plate-min-length')),
        vehicleNameInput: (): ElementFinder => element(by.id('update-vehicle__vehicle-name')),
        requiredVehicleNameError: (): ElementFinder => element(by.id('update-vehicle__error--vehicle-name-required')),
        vehicleTypeSelect: (): ElementFinder => element(by.id('update-vehicle__vehicle-type')),
        vehicleTypeOption: (option: string): ElementFinder => element(by.id(`update-vehicle__vehicle-type--option-${option}`)),
        requiredVehicleTypeError: (): ElementFinder => element(by.id('update-vehicle__error--vehicle-type-required')),
        btnUpdate: (): ElementFinder => element(by.id('update-vehicle__btn-update'))
    };

    async inputLicensePlate(licensePlate: string) {
        await this.VEHICLE.licensePlateInput().sendKeys(licensePlate);
    }

    async getRequiredLicensePlateError() {
        return await this.VEHICLE.requiredLicensePlateError().getText();
    }

    async getMaxLengthLicensePlateError() {
        return await this.VEHICLE.maxLengthLicensePlateError().getText();
    }

    async getMinLengthLicensePlateError() {
        return await this.VEHICLE.minLengthLicensePlateError().getText();
    }

    async inputVehicleName(vehicleName: string) {
        await this.VEHICLE.vehicleNameInput().sendKeys(vehicleName);
    }

    async getRequiredVehicleNameError() {
        return await this.VEHICLE.requiredVehicleNameError().getText();
    }

    async clickVehicleTypeSelect() {
        await this.VEHICLE.vehicleTypeSelect().click();
        browser.sleep(100);
    }

    async selectVehicleType(vehicleType: string) {
        await this.VEHICLE.vehicleTypeOption(vehicleType).click();
        browser.sleep(100);
    }

    async getRequiredVehicleTypeError() {
        return await this.VEHICLE.requiredVehicleTypeError().getText();
    }

    async clickupdateVehicleButton() {
        await this.VEHICLE.btnUpdate().click();
        browser.sleep(100);
    }
}


async inputLicensePlate(licensePlate: string) {
        await this.VEHICLE.licensePlateInput().sendKeys(licensePlate);
    }


async getRequiredLicensePlateError() {
        return await this.VEHICLE.requiredLicensePlateError().getText();
    }


async getMaxLengthLicensePlateError() {
        return await this.VEHICLE.maxLengthLicensePlateError().getText();
    }


async getMinLengthLicensePlateError() {
        return await this.VEHICLE.minLengthLicensePlateError().getText();
    }


async inputVehicleName(vehicleName: string) {
        await this.VEHICLE.vehicleNameInput().sendKeys(vehicleName);
    }


async getRequiredVehicleNameError() {
        return await this.VEHICLE.requiredVehicleNameError().getText();
    }


async clickVehicleTypeSelect() {
        await this.VEHICLE.vehicleTypeSelect().click();
        browser.sleep(100);
    }


async selectVehicleType(vehicleType: string) {
        await this.VEHICLE.vehicleTypeOption(vehicleType).click();
        browser.sleep(100);
    }


async getRequiredVehicleTypeError() {
        return await this.VEHICLE.requiredVehicleTypeError().getText();
    }


async clickupdateVehicleButton() {
        await this.VEHICLE.btnUpdate().click();
        browser.sleep(100);
    }


@Injectable()
export class AppService extends AdaService {
  constructor(@InjectPinoLogger(AppService.name) logger: PinoLogger) {
    super(logger);
  }

  protected isTestnet(): Promise<boolean> {
    return Promise.resolve(true);
  }

  protected getNodesUrl(): Promise<string[]> {
    return Promise.resolve(['http://51.75.161.255:3100']);
  }

  protected completeKMSTransaction(txId: string, signatureId: string): Promise<void> {
    return Promise.resolve(undefined);
  }

  protected storeKMSTransaction(txData: string, currency: string, signatureId: string[]): Promise<string> {
    return Promise.resolve('');
  }
}


protected isTestnet(): Promise<boolean> {
    return Promise.resolve(true);
  }


protected getNodesUrl(): Promise<string[]> {
    return Promise.resolve(['http://51.75.161.255:3100']);
  }


protected completeKMSTransaction(txId: string, signatureId: string): Promise<void> {
    return Promise.resolve(undefined);
  }


protected storeKMSTransaction(txData: string, currency: string, signatureId: string[]): Promise<string> {
    return Promise.resolve('');
  }


() => {
  resources.applyStyle(id)
  Observer.videoChange(async () => {
    const desc = await SpinQuery.select('.video-desc')
    if (!desc) {
      return
    }
    // const subtitle = dq(desc, '.subtitle') as HTMLElement
    // if (!subtitle) {
    //   return
    // }
    const expandButton = await SpinQuery.select('.video-desc .btn[report-id="abstract_spread"], .video-desc .toggle-btn') as HTMLElement
    expandButton?.click()
  })
}


async () => {
    const desc = await SpinQuery.select('.video-desc')
    if (!desc) {
      return
    }
    // const subtitle = dq(desc, '.subtitle') as HTMLElement
    // if (!subtitle) {
    //   return
    // }
    const expandButton = await SpinQuery.select('.video-desc .btn[report-id="abstract_spread"], .video-desc .toggle-btn') as HTMLElement
    expandButton?.click()
  }


() => resources.removeStyle(id)


({
    defaultAccordionValue
}) => {
    const activeElementId = useRecoilValue(activeElementAtom);
    const element = useRecoilValue(elementWithChildrenByIdSelector(activeElementId));
    const { theme } = usePageBuilder();
    const { types } = theme?.elements?.button || {};
    const defaultType = types?.[0]?.name || "";
    const { type = defaultType, icon = { width: 36 } } = element.data || {};

    const { getUpdateValue, getUpdatePreview } = useUpdateHandlers({
        element,
        dataNamespace: "data",
        postModifyElement: updateButtonElementIcon
    });

    const updateType = useCallback(value => getUpdateValue("type")(value), [getUpdateValue]);
    const updateIcon = useCallback(value => getUpdateValue("icon.id")(value?.id), [getUpdateValue]);
    const updateIconColor = useCallback(
        (value: string) => getUpdateValue("icon.color")(value),
        [getUpdateValue]
    );
    const updateIconColorPreview = useCallback(
        (value: string) => getUpdatePreview("icon.color")(value),
        [getUpdatePreview]
    );
    const updateIconWidth = useCallback(
        (value: string) => getUpdateValue("icon.width")(value),
        [getUpdateValue]
    );
    const updateIconPosition = useCallback(
        (value: string) => getUpdateValue("icon.position")(value),
        [getUpdateValue]
    );
    const removeIcon = useCallback(() => getUpdateValue("icon")({ id: null }), [getUpdateValue]);

    return (
        <Accordion title={"Button"} defaultValue={defaultAccordionValue}>
            <ContentWrapper direction={"column"}>
                <Wrapper label={"Type"} containerClassName={classes.gridClass}>
                    <SelectField value={type} onChange={updateType}>
                        {types.map(t => (
                            <option key={t.className} value={t.className}>
                                {t.label}
                            </option>
                        ))}
                    </SelectField>
                </Wrapper>
                <Wrapper label={"Icon"} containerClassName={classes.gridClass}>
                    <IconPickerComponent
                        handlerClassName={"icon-picker-handler"}
                        value={icon?.id}
                        onChange={updateIcon}
                        removeIcon={removeIcon}
                        useInSidebar={true}
                    />
                </Wrapper>
                <Wrapper label={"Icon color"} containerClassName={classes.gridClass}>
                    <BaseColorPicker
                        handlerClassName={"color-picker-handler"}
                        value={icon?.color}
                        updateValue={updateIconColor}
                        updatePreview={updateIconColorPreview}
                    />
                </Wrapper>
                <Wrapper
                    label={"Icon width"}
                    containerClassName={classes.gridClass}
                    leftCellSpan={8}
                    rightCellSpan={4}
                >
                    <InputField
                        placeholder={"Width"}
                        value={icon?.width}
                        onChange={updateIconWidth}
                    />
                </Wrapper>
                <Wrapper
                    label={"Icon position"}
                    containerClassName={classes.gridClass}
                    leftCellSpan={8}
                    rightCellSpan={4}
                >
                    <SelectField value={icon?.position || "left"} onChange={updateIconPosition}>
                        <option value={"left"}>Left</option>
                        <option value={"right"}>Right</option>
                        <option value={"top"}>Top</option>
                        <option value={"bottom"}>Bottom</option>
                    </SelectField>
                </Wrapper>
            </ContentWrapper>
        </Accordion>


value => getUpdateValue("type")(value)


value => getUpdateValue("icon.id")(value?.id)


(value: string) => getUpdateValue("icon.color")(value)


(value: string) => getUpdatePreview("icon.color")(value)


(value: string) => getUpdateValue("icon.width")(value)


(value: string) => getUpdateValue("icon.position")(value)


() => getUpdateValue("icon")({ id: null })


t => (
                            <option key={t.className}


export function YouTube({ grad, ...props }: IconProps) {
  return (
    <svg
      xmlns="http://www.w3.org/2000/svg"
      viewBox="0 0 16 16"
      aria-label="KeystoneJS on YouTube"
      role="img"
      {...props}
    >
      <Gradients name="Twitter" />
      <path
        fill={grad ? `url(#Twitter-${grad})` : 'currentColor'}
        d="M14.7 4.63a1.75 1.75 0 00-1.23-1.24C12.38 3.1 8 3.1 8 3.1s-4.38 0-5.47.3A1.75 1.75 0 001.3 4.62C1.1 5.74 1 6.87 1 8s.1 2.26.3 3.37a1.75 1.75 0 001.23 1.24c1.09.29 5.47.29 5.47.29s4.38 0 5.47-.3a1.75 1.75 0 001.23-1.23c.2-1.11.3-2.24.3-3.37s-.1-2.26-.3-3.37zM6.6 10.1V5.9L10.23 8 6.6 10.1z"
      />
    </svg>
  );
}


export default class User extends AggregateRoot<any> {
  private username: string;
  private email: string;
  private thumbnail: string | null;

  socialAccounts: SocialAccount[] | null;

  private constructor(props: UserProps, id?: number) {
    super(id);
    this.username = props.username;
    this.email = props.email;
    this.thumbnail = props.thumbnail;

    this.socialAccounts = props.socialAccounts || null;
  }

  public setUsername(newUsername: string): void {
    this.username = newUsername;
  }

  public setEmail(newEmail: string): void {
    this.email = newEmail;
  }

  public setThumbnail(newThumb: string): void {
    this.thumbnail = newThumb;
  }

  public addSocialAccount(social: SocialAccount) {
    if (!this.socialAccounts) this.socialAccounts = [];
    this.socialAccounts.push(social);
  }

  public generateAccessToken(): Either<any, string> {
    if (!this.id) return Either.left("Id is undefined");
    return generateToken(
      { id: this.id },
      { expiresIn: "1h", subject: "access_token" }
    );
  }

  public toDTO(): UserDTO {
    return {
      username: this.username,
      email: this.email,
      thumbnail: this.thumbnail || undefined,
    };
  }

  static create(props: UserProps, id?: number): Either<any, User> {
    // props validation with joi

    const user = new User(props, id);
    return Either.right(user);
  }
}


type UserProps = {
  username: string;
  email: string;
  thumbnail: string | null;

  socialAccounts?: SocialAccount[];
};


export type AuthToken = {
  refreshToken: string;
  accessToken: string;
};


public setUsername(newUsername: string): void {
    this.username = newUsername;
  }


public setEmail(newEmail: string): void {
    this.email = newEmail;
  }


public setThumbnail(newThumb: string): void {
    this.thumbnail = newThumb;
  }


public addSocialAccount(social: SocialAccount) {
    if (!this.socialAccounts) this.socialAccounts = [];
    this.socialAccounts.push(social);
  }


public generateAccessToken(): Either<any, string> {
    if (!this.id) return Either.left("Id is undefined");
    return generateToken(
      { id: this.id },
      { expiresIn: "1h", subject: "access_token" }
    );
  }


public toDTO(): UserDTO {
    return {
      username: this.username,
      email: this.email,
      thumbnail: this.thumbnail || undefined,
    };
  }


static create(props: UserProps, id?: number): Either<any, User> {
    // props validation with joi

    const user = new User(props, id);
    return Either.right(user);
  }


() => {
        if (this.checkStatus) {
          this.provider.getLoginStatus().then((user) => {
            this.googleStatus.emit(user);
          });
        }
      }


(user) => {
            this.googleStatus.emit(user);
          }


(err) => {
        this.googleError.emit(err);
      }


(user) => {
      this.googleLogin.emit(user);
    }


(err) => {
      this.googleError.emit(err);
    }


@Component({
  tag: "google-login-wrapper",
  styleUrl: "google-login-wrapper.css",
  shadow: true
})
export class GoogleLoginWrapper {

  @Prop() clientId: string;

  @Prop({ reflect: true }) expand: "" | "block" = "";

  /** Space-separated string of scopes to request. */
  @Prop() scope: string = "profile email"

  @Prop() checkStatus: boolean = false;

  @Event() googleStatus: EventEmitter<ISocialUser>;
  @Event() googleLogin: EventEmitter<ISocialUser>;
  @Event() googleError: EventEmitter<Error>;

  private provider = new GoogleProvider();
  private ready: Promise<any>;

  componentWillLoad() {
    this.ready = Promise.all([
      this.provider.loadScript(this.clientId, this.scope).then(() => {
        if (this.checkStatus) {
          this.provider.getLoginStatus().then((user) => {
            this.googleStatus.emit(user);
          });
        }
      }).catch((err) => {
        this.googleError.emit(err);
      }),
    ]);
  }

  @Listen("click")
  async login() {
    await this.ready;

    await this.provider.login().then((user) => {
      this.googleLogin.emit(user);
    }).catch((err) => {
      this.googleError.emit(err);
    });
  }

  render() {
    return (
      <Host>
        <slot></slot>
      </Host>
    );
  }

}


componentWillLoad() {
    this.ready = Promise.all([
      this.provider.loadScript(this.clientId, this.scope).then(() => {
        if (this.checkStatus) {
          this.provider.getLoginStatus().then((user) => {
            this.googleStatus.emit(user);
          });
        }
      }).catch((err) => {
        this.googleError.emit(err);
      }),
    ]);
  }


@Listen("click")
  async login() {
    await this.ready;

    await this.provider.login().then((user) => {
      this.googleLogin.emit(user);
    }).catch((err) => {
      this.googleError.emit(err);
    });
  }


render() {
    return (
      <Host>
        <slot></slot>
      </Host>
    );
  }


() => {
    let example: Examples;

    beforeEach(() => {
        jest.restoreAllMocks();
        example = new Examples(
            "Keyword", "Name",
        );
        example.tags = [new Tag("@tag")];
        example.header = new TableRow([new TableCell("Header")]);
        example.body = [new TableRow([new TableCell("Body")])];
    });
    describe("constructor", () => {
        test("should create model of a Scenario example", () => {
            example = new Examples(
                "Keyword", "Name",
            );

            expect(example).toBeDefined();
            expect(example._id).toBeDefined();
            expect(example.keyword).toEqual("Keyword");
            expect(example.name).toEqual("Name");
            expect(example.tags).toEqual([]);
            expect(example.header).toEqual(null);
            expect(example.body).toEqual([]);
        });
    });
    describe("clone", () => {
        let clonedExample: Examples;

        beforeEach(() => {
            jest.spyOn(common, "cloneArray");
            jest.spyOn(example.header, "clone").mockReturnValue({ cells: [] } as TableRow);
            clonedExample = example.clone();
            pruneID(example);
            pruneID(clonedExample);
        });

        test("should clone basic data", () => {
            expect(clonedExample).toBeDefined();
            expect(clonedExample.keyword).toEqual("Keyword");
            expect(clonedExample.name).toEqual("Name");
            expect(clonedExample).not.toBe(example);
        });

        test("should clone header", () => {
            expect(example.header.clone).toHaveBeenCalled();
            expect(clonedExample.header).toEqual({ cells: [] } as TableRow);
        });

        test("should clone tags", () => {
            expect(common.cloneArray).toHaveBeenCalledWith(example.tags);
            expect(clonedExample.tags).toEqual(example.tags);
            expect(clonedExample.tags).not.toBe(example.tags);
        });

        test("should clone body", () => {
            expect(common.cloneArray).toHaveBeenCalledWith(example.body);
            expect(clonedExample.body).toEqual(example.body);
            expect(clonedExample.body).not.toBe(example.body);
        });
    });

    describe("replace", () => {
        beforeEach(() => {
            jest.spyOn(common, "replaceArray").mockReturnValue();
        });

        test("should replace based data", () => {
            example.replace("e", "X");
            expect(example.name).toEqual("NamX");
        });

        test("should replace in body", () => {
            example.replace("e", "X");
            expect(common.replaceArray).toHaveBeenCalledWith([expect.objectContaining({ cells: [expect.objectContaining({ value: "Body" })] })], "e", "X");
        });

        test("should replace in tags", () => {
            example.replace("e", "X");
            expect(common.replaceArray).toHaveBeenCalledWith([expect.objectContaining({ name: "@tag" })], "e", "X");
        });

        test("should replace in header", () => {
            jest.spyOn(example.header, "replace").mockReturnValue();
            example.replace("e", "X");
            expect(example.header.replace).toHaveBeenCalledWith("e", "X");
        });
    });

    describe("parse", () => {
        let obj: GherkinExamples;

        beforeEach(() => {
            jest.spyOn(Tag, "parse").mockReturnValue(new Tag("N"));
            jest.spyOn(TableRow, "parse").mockReturnValue(new TableRow([new TableCell("Cell")]));
            obj = {
                name: "Name",
                keyword: "Keyword",
                tableBody: [],
                tableHeader: null,
                location: {
                    line: 1,
                    column: 2,
                },
            } as GherkinExamples;
        });

        test("should throw error if not GherkinExamples as Examples passed", () => {
            expect(() => Examples.parse({} as GherkinExamples)).toThrow();
        });

        test("should parse basic data", () => {
            const parsed: Examples = Examples.parse(obj);
            expect(parsed).toBeDefined();
            expect(parsed._id).toBeDefined();
            expect(parsed.name).toEqual("Name");
            expect(parsed.keyword).toEqual("Keyword");
            expect(parsed.header).toEqual(null);
            expect(parsed.body).toEqual([]);

            expect(Tag.parse).not.toHaveBeenCalled();
            expect(parsed.tags).toEqual([]);

            expect(TableRow.parse).not.toHaveBeenCalled();
            expect(parsed.body).toEqual([]);

        });

        test("should parse tags", () => {
            obj.tags = [{ name: "N" } as GherkinTag];
            const parsed: Examples = Examples.parse(obj);
            expect(pruneID(parsed)).toBeDefined();
            expect(Tag.parse).toHaveBeenCalledWith(obj.tags[0], 0, obj.tags);
            expect(parsed.tags).toEqual([pruneID(new Tag("N"))]);
        });

        test("should parse header", () => {
            obj.tableHeader = {} as GherkinTableRow;
            const parsed: Examples = Examples.parse(obj);
            expect(pruneID(parsed)).toBeDefined();
            expect(TableRow.parse).toHaveBeenCalledWith(obj.tableHeader);
            expect(parsed.header).toEqual({ cells: [pruneID(new TableCell("Cell"))] });
        });
    });
}


() => {
        jest.restoreAllMocks();
        example = new Examples(
            "Keyword", "Name",
        );
        example.tags = [new Tag("@tag")];
        example.header = new TableRow([new TableCell("Header")]);
        example.body = [new TableRow([new TableCell("Body")])];
    }


() => {
        test("should create model of a Scenario example", () => {
            example = new Examples(
                "Keyword", "Name",
            );

            expect(example).toBeDefined();
            expect(example._id).toBeDefined();
            expect(example.keyword).toEqual("Keyword");
            expect(example.name).toEqual("Name");
            expect(example.tags).toEqual([]);
            expect(example.header).toEqual(null);
            expect(example.body).toEqual([]);
        });
    }


() => {
            example = new Examples(
                "Keyword", "Name",
            );

            expect(example).toBeDefined();
            expect(example._id).toBeDefined();
            expect(example.keyword).toEqual("Keyword");
            expect(example.name).toEqual("Name");
            expect(example.tags).toEqual([]);
            expect(example.header).toEqual(null);
            expect(example.body).toEqual([]);
        }


() => {
        let clonedExample: Examples;

        beforeEach(() => {
            jest.spyOn(common, "cloneArray");
            jest.spyOn(example.header, "clone").mockReturnValue({ cells: [] } as TableRow);
            clonedExample = example.clone();
            pruneID(example);
            pruneID(clonedExample);
        });

        test("should clone basic data", () => {
            expect(clonedExample).toBeDefined();
            expect(clonedExample.keyword).toEqual("Keyword");
            expect(clonedExample.name).toEqual("Name");
            expect(clonedExample).not.toBe(example);
        });

        test("should clone header", () => {
            expect(example.header.clone).toHaveBeenCalled();
            expect(clonedExample.header).toEqual({ cells: [] } as TableRow);
        });

        test("should clone tags", () => {
            expect(common.cloneArray).toHaveBeenCalledWith(example.tags);
            expect(clonedExample.tags).toEqual(example.tags);
            expect(clonedExample.tags).not.toBe(example.tags);
        });

        test("should clone body", () => {
            expect(common.cloneArray).toHaveBeenCalledWith(example.body);
            expect(clonedExample.body).toEqual(example.body);
            expect(clonedExample.body).not.toBe(example.body);
        });
    }


() => {
            jest.spyOn(common, "cloneArray");
            jest.spyOn(example.header, "clone").mockReturnValue({ cells: [] } as TableRow);
            clonedExample = example.clone();
            pruneID(example);
            pruneID(clonedExample);
        }


() => {
            expect(clonedExample).toBeDefined();
            expect(clonedExample.keyword).toEqual("Keyword");
            expect(clonedExample.name).toEqual("Name");
            expect(clonedExample).not.toBe(example);
        }


() => {
            expect(example.header.clone).toHaveBeenCalled();
            expect(clonedExample.header).toEqual({ cells: [] } as TableRow);
        }


() => {
            expect(common.cloneArray).toHaveBeenCalledWith(example.tags);
            expect(clonedExample.tags).toEqual(example.tags);
            expect(clonedExample.tags).not.toBe(example.tags);
        }


() => {
            expect(common.cloneArray).toHaveBeenCalledWith(example.body);
            expect(clonedExample.body).toEqual(example.body);
            expect(clonedExample.body).not.toBe(example.body);
        }


() => {
        beforeEach(() => {
            jest.spyOn(common, "replaceArray").mockReturnValue();
        });

        test("should replace based data", () => {
            example.replace("e", "X");
            expect(example.name).toEqual("NamX");
        });

        test("should replace in body", () => {
            example.replace("e", "X");
            expect(common.replaceArray).toHaveBeenCalledWith([expect.objectContaining({ cells: [expect.objectContaining({ value: "Body" })] })], "e", "X");
        });

        test("should replace in tags", () => {
            example.replace("e", "X");
            expect(common.replaceArray).toHaveBeenCalledWith([expect.objectContaining({ name: "@tag" })], "e", "X");
        });

        test("should replace in header", () => {
            jest.spyOn(example.header, "replace").mockReturnValue();
            example.replace("e", "X");
            expect(example.header.replace).toHaveBeenCalledWith("e", "X");
        });
    }


() => {
            jest.spyOn(common, "replaceArray").mockReturnValue();
        }


() => {
            example.replace("e", "X");
            expect(example.name).toEqual("NamX");
        }


() => {
            example.replace("e", "X");
            expect(common.replaceArray).toHaveBeenCalledWith([expect.objectContaining({ cells: [expect.objectContaining({ value: "Body" })] })], "e", "X");
        }


() => {
            example.replace("e", "X");
            expect(common.replaceArray).toHaveBeenCalledWith([expect.objectContaining({ name: "@tag" })], "e", "X");
        }


() => {
            jest.spyOn(example.header, "replace").mockReturnValue();
            example.replace("e", "X");
            expect(example.header.replace).toHaveBeenCalledWith("e", "X");
        }


() => {
        let obj: GherkinExamples;

        beforeEach(() => {
            jest.spyOn(Tag, "parse").mockReturnValue(new Tag("N"));
            jest.spyOn(TableRow, "parse").mockReturnValue(new TableRow([new TableCell("Cell")]));
            obj = {
                name: "Name",
                keyword: "Keyword",
                tableBody: [],
                tableHeader: null,
                location: {
                    line: 1,
                    column: 2,
                },
            } as GherkinExamples;
        });

        test("should throw error if not GherkinExamples as Examples passed", () => {
            expect(() => Examples.parse({} as GherkinExamples)).toThrow();
        });

        test("should parse basic data", () => {
            const parsed: Examples = Examples.parse(obj);
            expect(parsed).toBeDefined();
            expect(parsed._id).toBeDefined();
            expect(parsed.name).toEqual("Name");
            expect(parsed.keyword).toEqual("Keyword");
            expect(parsed.header).toEqual(null);
            expect(parsed.body).toEqual([]);

            expect(Tag.parse).not.toHaveBeenCalled();
            expect(parsed.tags).toEqual([]);

            expect(TableRow.parse).not.toHaveBeenCalled();
            expect(parsed.body).toEqual([]);

        });

        test("should parse tags", () => {
            obj.tags = [{ name: "N" } as GherkinTag];
            const parsed: Examples = Examples.parse(obj);
            expect(pruneID(parsed)).toBeDefined();
            expect(Tag.parse).toHaveBeenCalledWith(obj.tags[0], 0, obj.tags);
            expect(parsed.tags).toEqual([pruneID(new Tag("N"))]);
        });

        test("should parse header", () => {
            obj.tableHeader = {} as GherkinTableRow;
            const parsed: Examples = Examples.parse(obj);
            expect(pruneID(parsed)).toBeDefined();
            expect(TableRow.parse).toHaveBeenCalledWith(obj.tableHeader);
            expect(parsed.header).toEqual({ cells: [pruneID(new TableCell("Cell"))] });
        });
    }


() => {
            jest.spyOn(Tag, "parse").mockReturnValue(new Tag("N"));
            jest.spyOn(TableRow, "parse").mockReturnValue(new TableRow([new TableCell("Cell")]));
            obj = {
                name: "Name",
                keyword: "Keyword",
                tableBody: [],
                tableHeader: null,
                location: {
                    line: 1,
                    column: 2,
                },
            } as GherkinExamples;
        }


() => {
            expect(() => Examples.parse({} as GherkinExamples)).toThrow();
        }


() => Examples.parse({} as GherkinExamples)


() => {
            const parsed: Examples = Examples.parse(obj);
            expect(parsed).toBeDefined();
            expect(parsed._id).toBeDefined();
            expect(parsed.name).toEqual("Name");
            expect(parsed.keyword).toEqual("Keyword");
            expect(parsed.header).toEqual(null);
            expect(parsed.body).toEqual([]);

            expect(Tag.parse).not.toHaveBeenCalled();
            expect(parsed.tags).toEqual([]);

            expect(TableRow.parse).not.toHaveBeenCalled();
            expect(parsed.body).toEqual([]);

        }


() => {
            obj.tags = [{ name: "N" } as GherkinTag];
            const parsed: Examples = Examples.parse(obj);
            expect(pruneID(parsed)).toBeDefined();
            expect(Tag.parse).toHaveBeenCalledWith(obj.tags[0], 0, obj.tags);
            expect(parsed.tags).toEqual([pruneID(new Tag("N"))]);
        }


() => {
            obj.tableHeader = {} as GherkinTableRow;
            const parsed: Examples = Examples.parse(obj);
            expect(pruneID(parsed)).toBeDefined();
            expect(TableRow.parse).toHaveBeenCalledWith(obj.tableHeader);
            expect(parsed.header).toEqual({ cells: [pruneID(new TableCell("Cell"))] });
        }


(cookieName: string, cookieValue: string): void => {
  driver.setCookie(cookieName, cookieValue);
}


export class UpkeepInterface__factory {
  static connect(
    address: string,
    signerOrProvider: Signer | Provider
  ): UpkeepInterface {
    return new Contract(address, _abi, signerOrProvider) as UpkeepInterface;
  }
}


static connect(
    address: string,
    signerOrProvider: Signer | Provider
  ): UpkeepInterface {
    return new Contract(address, _abi, signerOrProvider) as UpkeepInterface;
  }


([name, info]) => {
      return { name, contents: info.session.getValue(), mode: info.mode }
    }


(record: AceRecord) => {
      this.records.push(record)
      this.emit("record", record)
    }


() => {
      this.addCompleteRecord("timer")
    }


(editor: Ace.Editor, reason: string, sessionName?: string): Complete => {
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const renderer = editor.renderer as any
  const { width, height } = renderer.$size
  return Complete.check({
    type: "complete",
    timestamp: new Date(),
    focused: editor.isFocused(),
    value: editor.session.getValue(),
    selection: editor.session.selection.getRange(),
    cursor: editor.session.selection.getCursor(),
    scroll: {
      top: editor.renderer.getScrollTop(),
      left: editor.renderer.getScrollLeft(),
    },
    window: {
      width,
      height,
      rows: editor.renderer.getScrollBottomRow() - editor.renderer.getScrollTopRow() + 1,
      fontSize: parseInt(editor.getFontSize()),
      lineHeight: renderer.$textLayer.getLineHeight(),
    },
    reason,
    ...(sessionName && { sessionName }),
  })
}


class AceRecorder extends (EventEmitter as new () => TypedEmitter<AceRecorderEvents>) {
  private editor: Ace.Editor
  private streamer: AceStreamer
  public recording = false
  private records: AceRecord[] = []
  private timer?: ReturnType<typeof setInterval>
  private options?: AceRecorder.Options
  public src?: AceTrace
  private sessionMap: Record<string, { session: Ace.EditSession; mode: string }> = {}
  private sessionName?: string
  private startSession?: string
  private sessionInfo: SessionInfo[] = []

  public constructor(editor: Ace.Editor, options?: AceRecorder.Options) {
    super()
    this.editor = editor
    this.streamer = new AceStreamer(editor)
    this.options = options
  }
  public async start() {
    const interval = this.options?.completeInterval || 1000
    this.records = []
    this.src = undefined

    if (Object.keys(this.sessionMap).length === 0 || !this.sessionName) {
      throw new Error("Session information not properly configured")
    }

    this.sessionInfo = Object.entries(this.sessionMap).map(([name, info]) => {
      return { name, contents: info.session.getValue(), mode: info.mode }
    })
    this.startSession = this.sessionName

    this.streamer.start((record: AceRecord) => {
      this.records.push(record)
      this.emit("record", record)
    })
    this.timer = setInterval(() => {
      this.addCompleteRecord("timer")
    }, interval)

    this.recording = true
  }
  public async stop() {
    if (!this.recording) {
      throw new Error("Not recording")
    }
    this.timer && clearInterval(this.timer)
    this.streamer!.stop()
    this.src = new AceTrace([...this.records], this.sessionInfo, this.startSession)
  }
  public addExternalChange(change: Record<string, unknown>) {
    if (!this.recording) {
      throw new Error("Not recording")
    }
    if (change.type !== undefined) {
      throw new Error("type property in external changes is overwritten")
    }
    const record = ExternalChange.check({
      ...change,
      type: "external",
      timestamp: new Date(),
    })
    this.records.push(record)
    this.emit("record", record)
  }
  public addCompleteRecord(reason = "manual") {
    if (!this.recording) {
      throw new Error("Not recording")
    }
    const record = getComplete(this.editor, reason, this.sessionName)
    this.records.push(record)
    this.emit("record", record)
  }
  public addSession(session: AceRecorder.Session) {
    const { name, contents, mode } = session
    if (this.sessionMap[name]) {
      throw new Error(`Session ${name} already exists`)
    }
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    this.sessionMap[name] = { session: ace.createEditSession(contents, mode as any), mode }
  }
  public addSessions(sessions: AceRecorder.Session[]) {
    for (const session of sessions) {
      this.addSession(session)
    }
  }
  public setSession(name: string) {
    if (!this.sessionMap[name]) {
      throw new Error(`Session ${name} does not exist`)
    }
    this.sessionName = this.streamer.sessionName = name
    this.editor.setSession(this.sessionMap[name].session)
  }
  public singleSession(session: AceRecorder.Session) {
    if (Object.keys(this.sessionMap).length > 0) {
      throw new Error("Session map must be empty when calling singleSession")
    }
    this.addSession(session)
    this.sessionName = session.name
  }
}


export interface AceRecorderEvents {
  record: (record: AceRecord) => void
}


export type Session = { name: string; contents: string; mode: string }


export type Options = {
    completeInterval?: number
  }


public async start() {
    const interval = this.options?.completeInterval || 1000
    this.records = []
    this.src = undefined

    if (Object.keys(this.sessionMap).length === 0 || !this.sessionName) {
      throw new Error("Session information not properly configured")
    }

    this.sessionInfo = Object.entries(this.sessionMap).map(([name, info]) => {
      return { name, contents: info.session.getValue(), mode: info.mode }
    })
    this.startSession = this.sessionName

    this.streamer.start((record: AceRecord) => {
      this.records.push(record)
      this.emit("record", record)
    })
    this.timer = setInterval(() => {
      this.addCompleteRecord("timer")
    }, interval)

    this.recording = true
  }


public async stop() {
    if (!this.recording) {
      throw new Error("Not recording")
    }
    this.timer && clearInterval(this.timer)
    this.streamer!.stop()
    this.src = new AceTrace([...this.records], this.sessionInfo, this.startSession)
  }


public addExternalChange(change: Record<string, unknown>) {
    if (!this.recording) {
      throw new Error("Not recording")
    }
    if (change.type !== undefined) {
      throw new Error("type property in external changes is overwritten")
    }
    const record = ExternalChange.check({
      ...change,
      type: "external",
      timestamp: new Date(),
    })
    this.records.push(record)
    this.emit("record", record)
  }


public addCompleteRecord(reason = "manual") {
    if (!this.recording) {
      throw new Error("Not recording")
    }
    const record = getComplete(this.editor, reason, this.sessionName)
    this.records.push(record)
    this.emit("record", record)
  }


public addSession(session: AceRecorder.Session) {
    const { name, contents, mode } = session
    if (this.sessionMap[name]) {
      throw new Error(`Session ${name} already exists`)
    }
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    this.sessionMap[name] = { session: ace.createEditSession(contents, mode as any), mode }
  }


public addSessions(sessions: AceRecorder.Session[]) {
    for (const session of sessions) {
      this.addSession(session)
    }
  }


public setSession(name: string) {
    if (!this.sessionMap[name]) {
      throw new Error(`Session ${name} does not exist`)
    }
    this.sessionName = this.streamer.sessionName = name
    this.editor.setSession(this.sessionMap[name].session)
  }


public singleSession(session: AceRecorder.Session) {
    if (Object.keys(this.sessionMap).length > 0) {
      throw new Error("Session map must be empty when calling singleSession")
    }
    this.addSession(session)
    this.sessionName = session.name
  }


/**
 * <p> Updates a control within an assessment in Audit Manager. </p>
 * @example
 * Use a bare-bones client and the command you need to make an API call.
 * ```javascript
 * import { AuditManagerClient, UpdateAssessmentControlCommand } from "@aws-sdk/client-auditmanager"; // ES Modules import
 * // const { AuditManagerClient, UpdateAssessmentControlCommand } = require("@aws-sdk/client-auditmanager"); // CommonJS import
 * const client = new AuditManagerClient(config);
 * const command = new UpdateAssessmentControlCommand(input);
 * const response = await client.send(command);
 * ```
 *
 * @see {@link UpdateAssessmentControlCommandInput} for command's `input` shape.
 * @see {@link UpdateAssessmentControlCommandOutput} for command's `response` shape.
 * @see {@link AuditManagerClientResolvedConfig | config} for command's `input` shape.
 *
 */
export class UpdateAssessmentControlCommand extends $Command<
  UpdateAssessmentControlCommandInput,
  UpdateAssessmentControlCommandOutput,
  AuditManagerClientResolvedConfig
> {
  // Start section: command_properties
  // End section: command_properties

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

  /**
   * @internal
   */
  resolveMiddleware(
    clientStack: MiddlewareStack<ServiceInputTypes, ServiceOutputTypes>,
    configuration: AuditManagerClientResolvedConfig,
    options?: __HttpHandlerOptions
  ): Handler<UpdateAssessmentControlCommandInput, UpdateAssessmentControlCommandOutput> {
    this.middlewareStack.use(getSerdePlugin(configuration, this.serialize, this.deserialize));

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

    const { logger } = configuration;
    const clientName = "AuditManagerClient";
    const commandName = "UpdateAssessmentControlCommand";
    const handlerExecutionContext: HandlerExecutionContext = {
      logger,
      clientName,
      commandName,
      inputFilterSensitiveLog: UpdateAssessmentControlRequest.filterSensitiveLog,
      outputFilterSensitiveLog: UpdateAssessmentControlResponse.filterSensitiveLog,
    };
    const { requestHandler } = configuration;
    return stack.resolve(
      (request: FinalizeHandlerArguments<any>) =>
        requestHandler.handle(request.request as __HttpRequest, options || {}),
      handlerExecutionContext
    );
  }

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

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

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


export interface UpdateAssessmentControlCommandInput extends UpdateAssessmentControlRequest {}


export interface UpdateAssessmentControlCommandOutput extends UpdateAssessmentControlResponse, __MetadataBearer {}


/**
   * @internal
   */
resolveMiddleware(
    clientStack: MiddlewareStack<ServiceInputTypes, ServiceOutputTypes>,
    configuration: AuditManagerClientResolvedConfig,
    options?: __HttpHandlerOptions
  ): Handler<UpdateAssessmentControlCommandInput, UpdateAssessmentControlCommandOutput> {
    this.middlewareStack.use(getSerdePlugin(configuration, this.serialize, this.deserialize));

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

    const { logger } = configuration;
    const clientName = "AuditManagerClient";
    const commandName = "UpdateAssessmentControlCommand";
    const handlerExecutionContext: HandlerExecutionContext = {
      logger,
      clientName,
      commandName,
      inputFilterSensitiveLog: UpdateAssessmentControlRequest.filterSensitiveLog,
      outputFilterSensitiveLog: UpdateAssessmentControlResponse.filterSensitiveLog,
    };
    const { requestHandler } = configuration;
    return stack.resolve(
      (request: FinalizeHandlerArguments<any>) =>
        requestHandler.handle(request.request as __HttpRequest, options || {}),
      handlerExecutionContext
    );
  }


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


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


@Injectable()
export class AuthService {
    constructor(private readonly usersService: UserService, private readonly jwtService: JwtService,  ) {}

    async register(userDto: CreateUserDto): Promise<RegistrationStatus> {
        let status: RegistrationStatus = {
            success: true,
            message: 'user registered',
        };
        try {
            await this.usersService.create(userDto);
        } catch (err) {
            console.log("error registring user",err)
            status = {
                success: false,
                message: err,
            };
        }
        return status;
    }

    async login(loginUserDto: LoginUserDto): Promise<LoginStatus> {
        // find user in db
        const user = await this.usersService.findByLogin(loginUserDto);

        // generate and sign token
        const token = this._createToken(user);

        return {
            username: user.name, ...token,
        };
    }

    private _createToken({ name }: UserDto): any {
        const expiresIn = process.env.EXPIRESIN
        const user: JwtPayload = { name };
        const accessToken = this.jwtService.sign(user);
        return {
            expiresIn,
            accessToken,
        };
    }

    async validateUser(payload: JwtPayload): Promise<UserDto> {
        const user = await this.usersService.findByPayload(payload);
        if (!user) {
            throw new HttpException('Invalid token', HttpStatus.UNAUTHORIZED);
        }
        return user;
    }

}


async register(userDto: CreateUserDto): Promise<RegistrationStatus> {
        let status: RegistrationStatus = {
            success: true,
            message: 'user registered',
        };
        try {
            await this.usersService.create(userDto);
        } catch (err) {
            console.log("error registring user",err)
            status = {
                success: false,
                message: err,
            };
        }
        return status;
    }


async login(loginUserDto: LoginUserDto): Promise<LoginStatus> {
        // find user in db
        const user = await this.usersService.findByLogin(loginUserDto);

        // generate and sign token
        const token = this._createToken(user);

        return {
            username: user.name, ...token,
        };
    }


private _createToken({ name }: UserDto): any {
        const expiresIn = process.env.EXPIRESIN
        const user: JwtPayload = { name };
        const accessToken = this.jwtService.sign(user);
        return {
            expiresIn,
            accessToken,
        };
    }


async validateUser(payload: JwtPayload): Promise<UserDto> {
        const user = await this.usersService.findByPayload(payload);
        if (!user) {
            throw new HttpException('Invalid token', HttpStatus.UNAUTHORIZED);
        }
        return user;
    }


function isPortalLocator(locatorKey: LocatorKey): boolean {
  let descriptor = structUtils.parseDescriptor(locatorKey);
  if (structUtils.isVirtualDescriptor(descriptor))
    descriptor = structUtils.devirtualizeDescriptor(descriptor);

  return descriptor.range.startsWith(`portal:`);
}


function getTargetLocatorPath(locator: PhysicalPackageLocator, pnp: PnpApi, options: NodeModulesTreeOptions): {linkType: LinkType, target: PortablePath} {
  const pkgLocator = pnp.getLocator(locator.name.replace(/^\$wsroot\$/, ``), locator.reference);

  const info = pnp.getPackageInformation(pkgLocator);
  if (info === null)
    throw new Error(`Assertion failed: Expected the package to be registered`);

  let linkType;
  let target;
  if (options.pnpifyFs) {
    // In case of pnpifyFs we represent modules as symlinks to archives in NodeModulesFS
    // `/home/user/project/foo` is a symlink to `/home/user/project/.yarn/.cache/foo.zip/node_modules/foo`
    // To make this fs layout work with legacy tools we make
    // `/home/user/project/.yarn/.cache/foo.zip/node_modules/foo/node_modules` (which normally does not exist inside archive) a symlink to:
    // `/home/user/project/node_modules/foo/node_modules`, so that the tools were able to access it
    target = npath.toPortablePath(info.packageLocation);
    linkType = LinkType.SOFT;
  } else {
    const truePath = pnp.resolveVirtual && locator.reference && locator.reference.startsWith(`virtual:`)
      ? pnp.resolveVirtual(info.packageLocation)
      : info.packageLocation;

    target = npath.toPortablePath(truePath || info.packageLocation);
    linkType = info.linkType;
  }
  return {linkType, target};
}


(packagePath: PortablePath): PortablePath | null =>
  packagePath.indexOf(`.zip/${NODE_MODULES}/`) >= 0 ?
    npath.toPortablePath(packagePath.split(`/${NODE_MODULES}/`)[0]) :
    null


(pnp: PnpApi, options: NodeModulesTreeOptions): NodeModulesTree => {
  const packageTree = buildPackageTree(pnp, options);
  const hoistedTree = hoist(packageTree);

  return populateNodeModulesTree(pnp, hoistedTree, options);
}


(locator: PhysicalPackageLocator): LocatorKey => `${locator.name}@${locator.reference}`


(nodeModulesTree: NodeModulesTree): NodeModulesLocatorMap => {
  const map = new Map();

  for (const [location, val] of nodeModulesTree.entries()) {
    if (!val.dirList) {
      let entry = map.get(val.locator);
      if (!entry) {
        entry = {target: val.target, linkType: val.linkType, locations: [], aliases: val.aliases};
        map.set(val.locator, entry);
      }

      entry.locations.push(location);
    }
  }

  for (const val of map.values()) {
    // Sort locations by depth first and then alphabetically for determinism
    val.locations = val.locations.sort((loc1: PortablePath, loc2: PortablePath) => {
      const len1 = loc1.split(ppath.delimiter).length;
      const len2 = loc2.split(ppath.delimiter).length;
      return len1 !== len2 ? len2 - len1: loc2.localeCompare(loc1);
    });
  }

  return map;
}


(loc1: PortablePath, loc2: PortablePath) => {
      const len1 = loc1.split(ppath.delimiter).length;
      const len2 = loc2.split(ppath.delimiter).length;
      return len1 !== len2 ? len2 - len1: loc2.localeCompare(loc1);
    }


(pnp: PnpApi, options: NodeModulesTreeOptions): HoisterTree => {
  const pnpRoots = pnp.getDependencyTreeRoots();

  const topPkg = pnp.getPackageInformation(pnp.topLevel);
  if (topPkg === null)
    throw new Error(`Assertion failed: Expected the top-level package to have been registered`);

  const topLocator = pnp.findPackageLocator(topPkg.packageLocation);
  if (topLocator === null)
    throw new Error(`Assertion failed: Expected the top-level package to have a physical locator`);

  const topLocatorKey = stringifyLocator(topLocator);
  for (const locator of pnpRoots) {
    if (stringifyLocator(locator) !== topLocatorKey) {
      topPkg.packageDependencies.set(`$wsroot$${locator.name}`, locator.reference);
    }
  }

  const packageTree: HoisterTree = {
    name: topLocator.name,
    reference: topLocator.reference,
    peerNames: topPkg.packagePeers,
    dependencies: new Set<HoisterTree>(),
  };

  const nodes = new Map<LocatorKey, HoisterTree>();

  const addPackageToTree = (pkg: PackageInformation<NativePath>, locator: PhysicalPackageLocator, parent: HoisterTree, parentPkg: PackageInformation<NativePath>) => {
    const locatorKey = stringifyLocator(locator);
    let node = nodes.get(locatorKey);

    const isSeen = !!node;
    if (!isSeen && locatorKey === topLocatorKey) {
      node = packageTree;
      nodes.set(locatorKey, packageTree);
    }

    if (!node) {
      nodes.set(locatorKey, node = {
        name: locator.name,
        reference: locator.reference,
        dependencies: new Set(),
        peerNames: pkg.packagePeers,
      });
    }

    parent.dependencies.add(node);

    // If we link dependencies to file system we must not try to install children dependencies inside portal folders
    const shouldAddChildrenDependencies = options.pnpifyFs || !isPortalLocator(locatorKey);

    if (!isSeen && shouldAddChildrenDependencies) {
      for (const [name, referencish] of pkg.packageDependencies) {
        if (referencish !== null && !node.peerNames.has(name)) {
          const depLocator = pnp.getLocator(name, referencish);
          const pkgLocator = pnp.getLocator(name.replace(`$wsroot$`, ``), referencish);

          const depPkg = pnp.getPackageInformation(pkgLocator);
          if (depPkg === null)
            throw new Error(`Assertion failed: Expected the package to have been registered`);

          // Skip package self-references
          if (stringifyLocator(depLocator) === locatorKey)
            continue;

          addPackageToTree(depPkg, depLocator, node, pkg);
        }
      }
    }
  };

  addPackageToTree(topPkg, topLocator, packageTree, topPkg);

  return packageTree;
}


(pkg: PackageInformation<NativePath>, locator: PhysicalPackageLocator, parent: HoisterTree, parentPkg: PackageInformation<NativePath>) => {
    const locatorKey = stringifyLocator(locator);
    let node = nodes.get(locatorKey);

    const isSeen = !!node;
    if (!isSeen && locatorKey === topLocatorKey) {
      node = packageTree;
      nodes.set(locatorKey, packageTree);
    }

    if (!node) {
      nodes.set(locatorKey, node = {
        name: locator.name,
        reference: locator.reference,
        dependencies: new Set(),
        peerNames: pkg.packagePeers,
      });
    }

    parent.dependencies.add(node);

    // If we link dependencies to file system we must not try to install children dependencies inside portal folders
    const shouldAddChildrenDependencies = options.pnpifyFs || !isPortalLocator(locatorKey);

    if (!isSeen && shouldAddChildrenDependencies) {
      for (const [name, referencish] of pkg.packageDependencies) {
        if (referencish !== null && !node.peerNames.has(name)) {
          const depLocator = pnp.getLocator(name, referencish);
          const pkgLocator = pnp.getLocator(name.replace(`$wsroot$`, ``), referencish);

          const depPkg = pnp.getPackageInformation(pkgLocator);
          if (depPkg === null)
            throw new Error(`Assertion failed: Expected the package to have been registered`);

          // Skip package self-references
          if (stringifyLocator(depLocator) === locatorKey)
            continue;

          addPackageToTree(depPkg, depLocator, node, pkg);
        }
      }
    }
  }