(err, cmd) => {
                                if (err) {
                                    return ctx.reject(err);
                                }
                                if (cmd.status < 200 || cmd.status >= 300) {
                                    // expecting a 235 response, just in case allow everything in 2xx range
                                    return ctx.reject('User failed to authenticate');
                                }

                                console.log('User authenticated! (%s)', cmd.response);

                                // all checks passed
                                return ctx.resolve();
                            }


(err, info: SendmailTransport.SentMessageInfo) => {
        if (!err) {
            console.log(info.envelope);
            console.log(info.messageId);
        }
    }


(err, info: SESTransport.SentMessageInfo) => {
        if (!err) {
            console.log(info.envelope);
            console.log(info.messageId);
        }
    }


(err, info: StreamTransport.SentMessageInfo) => {
        if (!err) {
            console.log(info.envelope);
            console.log(info.messageId);
            // if ('pipe' in info.message) {
            if (info.message instanceof stream.Readable) {
                info.message.pipe(process.stdout);
            }
        }
    }


(key) => key.toUpperCase()


(err, info: StreamTransport.SentMessageInfo) => {
        if (!err) {
            console.log(info.envelope);
            console.log(info.messageId);
            console.log(info.message.toString());
        }
    }


(err, info: JSONTransport.SentMessageInfo) => {
        if (!err) {
            console.log(info.envelope);
            console.log(info.messageId);
            console.log(info.message); // JSON string
        }
    }


(err, html) => {
            if (err) {
                callback(err);
                return;
            }
            console.log('HTML contents: %s', html.toString());
            callback();
        }


(mail, callback) => {
        if (!mail.data.text && mail.data.html && typeof mail.data.html === 'string') {
            mail.data.text = mail.data.html.replace(/<[^>]*>/g, ' ');
        }
        callback();
    }


(mail, callback) => {
        // apply output transformer to the raw message stream
        mail.message.transform(transformer);
        callback();
    }


(mail, callback) => {
        const addresses = mail.message.getAddresses();
        console.log('From: %s', JSON.stringify(addresses.from));
        console.log('To: %s', JSON.stringify(addresses.to));
        console.log('Cc: %s', JSON.stringify(addresses.cc));
        console.log('Bcc: %s', JSON.stringify(addresses.bcc));
        callback();
    }


() => {
                callback(null, { SentMessageInfo: 'baz' });
            }


(err) => {
        if (err) throw err;
        connection.login({ user: 'user', pass: 'pass' }, (err) => {
            if (err) throw err;
            connection.send({ from: 'a@example.com', to: 'b@example.net' }, 'message', (err, info) => {
                if (err) {
                    const code: string = err.code || '???';
                    const response: string = err.response || '???';
                    const responseCode: number = err.responseCode || 0;
                    const command: string = err.command || '???';
                    throw err;
                }
                connection.reset(() => {
                    if (err) throw err;
                    connection.quit();
                    connection.close();
                });
            });
        });
    }


(err) => {
            if (err) throw err;
            connection.send({ from: 'a@example.com', to: 'b@example.net' }, 'message', (err, info) => {
                if (err) {
                    const code: string = err.code || '???';
                    const response: string = err.response || '???';
                    const responseCode: number = err.responseCode || 0;
                    const command: string = err.command || '???';
                    throw err;
                }
                connection.reset(() => {
                    if (err) throw err;
                    connection.quit();
                    connection.close();
                });
            });
        }


(err, info) => {
                if (err) {
                    const code: string = err.code || '???';
                    const response: string = err.response || '???';
                    const responseCode: number = err.responseCode || 0;
                    const command: string = err.command || '???';
                    throw err;
                }
                connection.reset(() => {
                    if (err) throw err;
                    connection.quit();
                    connection.close();
                });
            }


() => {
                    if (err) throw err;
                    connection.quit();
                    connection.close();
                }


(err, message) => {
        process.stdout.write(message);
    }


(err, msg) => {
        const msgAsString: string = msg.toString();
    }


(input) => {
        const isReadable: boolean = input.readable;
        return input;
    }


(err, value) => {
        if (!err) {
            console.log(value);
        }
    }


(value) => console.log(value)


(err, accessToken) => {
        if (err) throw err;
        const token: string = xoauth2.buildXOAuth2Token(accessToken);
    }


class Transport implements nodemailer.Transport {
        name = 'minimal';
        version = '0.1.0';
        constructor(options: Options) { }
        send(mail: MailMessage, callback: (err: Error | null, info: SentMessageInfo) => void): void {
            const input = mail.message.createReadStream();
            input.pipe(process.stdout);
            input.on('end', () => {
                callback(null, { SentMessageInfo: 'baz' });
            });
        }
    }


interface MailOptions extends Mail.Options {
        mailOption?: 'foo';
    }


interface Options extends MailOptions, nodemailer.TransportOptions {
        transportOptions: 'bar';
    }


interface SentMessageInfo {
        SentMessageInfo: 'baz';
    }


send(mail: MailMessage, callback: (err: Error | null, info: SentMessageInfo) => void): void {
            const input = mail.message.createReadStream();
            input.pipe(process.stdout);
            input.on('end', () => {
                callback(null, { SentMessageInfo: 'baz' });
            });
        }


export async function* paginateListFirewallRuleGroups(
  config: Route53ResolverPaginationConfiguration,
  input: ListFirewallRuleGroupsCommandInput,
  ...additionalArguments: any
): Paginator<ListFirewallRuleGroupsCommandOutput> {
  // ToDo: replace with actual type instead of typeof input.NextToken
  let token: typeof input.NextToken | undefined = config.startingToken || undefined;
  let hasNext = true;
  let page: ListFirewallRuleGroupsCommandOutput;
  while (hasNext) {
    input.NextToken = token;
    input["MaxResults"] = config.pageSize;
    if (config.client instanceof Route53Resolver) {
      page = await makePagedRequest(config.client, input, ...additionalArguments);
    } else if (config.client instanceof Route53ResolverClient) {
      page = await makePagedClientRequest(config.client, input, ...additionalArguments);
    } else {
      throw new Error("Invalid client, expected Route53Resolver | Route53ResolverClient");
    }
    yield page;
    token = page.NextToken;
    hasNext = !!token;
  }
  // @ts-ignore
  return undefined;
}


async (
  client: Route53ResolverClient,
  input: ListFirewallRuleGroupsCommandInput,
  ...args: any
): Promise<ListFirewallRuleGroupsCommandOutput> => {
  // @ts-ignore
  return await client.send(new ListFirewallRuleGroupsCommand(input), ...args);
}


async (
  client: Route53Resolver,
  input: ListFirewallRuleGroupsCommandInput,
  ...args: any
): Promise<ListFirewallRuleGroupsCommandOutput> => {
  // @ts-ignore
  return await client.listFirewallRuleGroups(input, ...args);
}


action => action.modifiers.education.informationTechnology.value.greaterThanOrEqualTo(5)


() => this.stats.finance.money


() => {
    return new Decimal(growth(this.timesCalculated, 2000, 1.15));
  }


() => this.stats.finance.investment


() => {
    return new Decimal(16);
  }


@SerializeAllOn('emit')
@UnlocksWhen(action => action.modifiers.education.informationTechnology.value.greaterThanOrEqualTo(5))
@NoMultiplier
export class DatingSite extends Action {
  money = new MoneyCostMutation(() => this.stats.finance.money, () => {
    return new Decimal(growth(this.timesCalculated, 2000, 1.15));
  });

  investment = new Mutation(() => this.stats.finance.investment, () => {
    return new Decimal(16);
  });
}


function withDefault(raw: string, def: number) {
                const res = parseInt(raw);
                if (isNaN(res)) {
                    return def;
                }
                return res;
            }


function isTemporaryAsset(asset: pxt.Asset) {
        return asset && !asset.meta.displayName;
    }


() => {
                const result = fv.getResult();
                const project = pxt.react.getTilemapProject();

                if (result) {
                    const old = this.getValue();
                    if (pxt.assetEquals(this.asset, result)) return;

                    const oldId = isTemporaryAsset(this.asset) ? null : this.asset.id;
                    let newId = isTemporaryAsset(result) ? null : result.id;

                    if (!oldId && newId === this.sourceBlock_.id) {
                        // The temporary assets we create just use the block id as the id; give it something
                        // a little nicer
                        result.id = project.generateNewID(result.type);
                        newId = result.id;
                    }

                    this.pendingEdit = true;

                    if (result.meta?.displayName) this.disposeOfTemporaryAsset();
                    this.asset = result;
                    const lastRevision = project.revision();

                    this.onEditorClose(this.asset);
                    this.updateAssetListener();
                    this.updateAssetMeta();
                    this.redrawPreview();

                    this.undoRedoState = fv.getPersistentData();

                    if (this.sourceBlock_ && Blockly.Events.isEnabled()) {
                        const event = new BlocklyTilemapChange(
                            this.sourceBlock_, 'field', this.name, old, this.getValue(), lastRevision, project.revision());

                        if (oldId !== newId) {
                            event.oldAssetId = oldId;
                            event.newAssetId = newId;
                        }

                        Blockly.Events.fire(event);
                    }
                    this.pendingEdit = false;
                }
            }


id => id !== this.sourceBlock_.id


id => this.sourceBlock_.workspace.getBlockById(id)


() => {
            if (this.pendingEdit) return;
            const id = this.getBlockData();
            if (id) {
                this.asset = pxt.react.getTilemapProject().lookupAsset(this.getAssetType(), id);
            }
            this.redrawPreview();
        }


export class BlocklyTilemapChange extends Blockly.Events.BlockChange {
        oldAssetId: string;
        newAssetId: string;
        fieldName: string;

        constructor(block: Blockly.Block, element: string, name: string, oldValue: any, newValue: any, protected oldRevision: number, protected newRevision: number) {
            super(block, element, name, oldValue, newValue);
            this.fieldName = name;
        }

        isNull() {
            return this.oldRevision === this.newRevision && super.isNull();
        }

        run(forward: boolean) {
            if (this.newAssetId || this.oldAssetId) {
                const block = this.getEventWorkspace_().getBlockById(this.blockId);

                if (forward) {
                    pxt.blocks.setBlockDataForField(block, this.fieldName, this.newAssetId);
                }
                else {
                    pxt.blocks.setBlockDataForField(block, this.fieldName, this.oldAssetId);
                }
            }

            if (forward) {
                pxt.react.getTilemapProject().redo();
                super.run(forward);
            }
            else {
                pxt.react.getTilemapProject().undo();
                super.run(forward);
            }

            const ws = this.getEventWorkspace_();

            // Fire an event to force a recompile, but make sure it doesn't end up on the undo stack
            const ev = new BlocklyTilemapChange(
                ws.getBlockById(this.blockId), 'tilemap-revision', "revision", null, pxt.react.getTilemapProject().revision(), 0, 0);
            ev.recordUndo = false;

            Blockly.Events.fire(ev)
        }
    }


export interface FieldAssetEditorOptions {
        initWidth: string;
        initHeight: string;

        disableResize: string;
    }


interface ParsedFieldAssetEditorOptions {
        initWidth: number;
        initHeight: number;
        disableResize: boolean;
    }


protected abstract getAssetType(): pxt.AssetType;


protected abstract createNewAsset(text?: string): pxt.Asset;


protected abstract getValueText(): string;


onInit() {
            this.redrawPreview();
        }


onValueChanged(newValue: string) {
            this.parseValueText(newValue);
            this.redrawPreview();
            return this.getValueText();
        }


showEditor_() {
            if (this.isGreyBlock) return;

            const params: any = {...this.params};

            params.blocksInfo = this.blocksInfo;

            let editorKind: string;

            switch (this.asset.type) {
                case pxt.AssetType.Tile:
                case pxt.AssetType.Image:
                    editorKind = "image-editor";
                    params.temporaryAssets = getTemporaryAssets(this.sourceBlock_.workspace, pxt.AssetType.Image);
                    break;
                case pxt.AssetType.Animation:
                    editorKind = "animation-editor";
                    params.temporaryAssets = getTemporaryAssets(this.sourceBlock_.workspace, pxt.AssetType.Image)
                        .concat(getTemporaryAssets(this.sourceBlock_.workspace, pxt.AssetType.Animation));
                    break;
                case pxt.AssetType.Tilemap:
                    editorKind = "tilemap-editor";
                    const project = pxt.react.getTilemapProject();
                    pxt.sprite.addMissingTilemapTilesAndReferences(project, this.asset);
                    break;
            }

            const fv = pxt.react.getFieldEditorView(editorKind, this.asset, params);

            if (this.undoRedoState) {
                fv.restorePersistentData(this.undoRedoState);
            }

            pxt.react.getTilemapProject().pushUndo();

            fv.onHide(() => {
                const result = fv.getResult();
                const project = pxt.react.getTilemapProject();

                if (result) {
                    const old = this.getValue();
                    if (pxt.assetEquals(this.asset, result)) return;

                    const oldId = isTemporaryAsset(this.asset) ? null : this.asset.id;
                    let newId = isTemporaryAsset(result) ? null : result.id;

                    if (!oldId && newId === this.sourceBlock_.id) {
                        // The temporary assets we create just use the block id as the id; give it something
                        // a little nicer
                        result.id = project.generateNewID(result.type);
                        newId = result.id;
                    }

                    this.pendingEdit = true;

                    if (result.meta?.displayName) this.disposeOfTemporaryAsset();
                    this.asset = result;
                    const lastRevision = project.revision();

                    this.onEditorClose(this.asset);
                    this.updateAssetListener();
                    this.updateAssetMeta();
                    this.redrawPreview();

                    this.undoRedoState = fv.getPersistentData();

                    if (this.sourceBlock_ && Blockly.Events.isEnabled()) {
                        const event = new BlocklyTilemapChange(
                            this.sourceBlock_, 'field', this.name, old, this.getValue(), lastRevision, project.revision());

                        if (oldId !== newId) {
                            event.oldAssetId = oldId;
                            event.newAssetId = newId;
                        }

                        Blockly.Events.fire(event);
                    }
                    this.pendingEdit = false;
                }
            });

            fv.show();
        }


render_() {
            if (this.isGreyBlock && !this.textElement_) {
                this.createTextElement_();
            }
            super.render_();

            if (!this.isGreyBlock) {
                this.size_.height = TOTAL_HEIGHT;
                this.size_.width = TOTAL_WIDTH;
            }
        }


getDisplayText_() {
            // This is only used when isGreyBlock is true
            const text = pxt.Util.htmlUnescape(this.valueText);
            return text.substr(0, text.indexOf("(")) + "(...)";;
        }


updateEditable() {
            if (this.isGreyBlock && this.fieldGroup_) {
                const group = this.fieldGroup_;
                Blockly.utils.dom.removeClass(group, 'blocklyNonEditableText');
                Blockly.utils.dom.removeClass(group, 'blocklyEditableText');
                group.style.cursor = '';
            }
            else {
                super.updateEditable();
            }
        }


getValue() {
            if (this.isGreyBlock) return pxt.Util.htmlUnescape(this.valueText);

            return this.getValueText();
        }


onDispose() {
            if (this.sourceBlock_?.workspace && !this.sourceBlock_.workspace.rendered) {
                this.disposeOfTemporaryAsset();
            }
            pxt.react.getTilemapProject().removeChangeListener(this.getAssetType(), this.assetChangeListener);
        }


disposeOfTemporaryAsset() {
            if (this.isTemporaryAsset()) {
                pxt.react.getTilemapProject().removeAsset(this.asset);
                this.setBlockData(null);
                this.asset = undefined;
            }
        }


clearTemporaryAssetData() {
            if (this.isTemporaryAsset()) {
                this.setBlockData(null);
            }
        }


isTemporaryAsset() {
            return isTemporaryAsset(this.asset);
        }


getAsset() {
            return this.asset;
        }


updateAsset(asset: pxt.Asset) {
            this.asset = asset;
            this.setValue(this.getValue());
        }


protected onEditorClose(newValue: pxt.Asset) {
            // Subclass
        }


protected redrawPreview() {
            if (!this.fieldGroup_) return;
            pxsim.U.clear(this.fieldGroup_);

            if (this.isGreyBlock) {
                this.createTextElement_();
                this.render_();
                this.updateEditable();
                return;
            }

            const bg = new svg.Rect()
                .at(X_PADDING, Y_PADDING)
                .size(BG_WIDTH, BG_WIDTH)
                .setClass("blocklySpriteField")
                .stroke("#898989", 1)
                .corner(4);

            this.fieldGroup_.appendChild(bg.el);

            if (this.asset) {
                let dataURI: string;
                switch (this.asset.type) {
                    case pxt.AssetType.Image:
                    case pxt.AssetType.Tile:
                        dataURI = bitmapToImageURI(pxt.sprite.Bitmap.fromData(this.asset.bitmap), PREVIEW_WIDTH, this.lightMode);
                        break;
                    case pxt.AssetType.Animation:
                        dataURI = bitmapToImageURI(pxt.sprite.Bitmap.fromData(this.asset.frames[0]), PREVIEW_WIDTH, this.lightMode);
                        break;
                    case pxt.AssetType.Tilemap:
                        dataURI = tilemapToImageURI(this.asset.data, PREVIEW_WIDTH, this.lightMode);
                        break;
                }
                const img = new svg.Image()
                    .src(dataURI)
                    .at(X_PADDING + BG_PADDING, Y_PADDING + BG_PADDING)
                    .size(PREVIEW_WIDTH, PREVIEW_WIDTH);
                this.fieldGroup_.appendChild(img.el);
            }
        }


protected parseValueText(newText: string) {
            newText = pxt.Util.htmlUnescape(newText);
            if (this.sourceBlock_ && !this.sourceBlock_.isInFlyout) {
                const project = pxt.react.getTilemapProject();

                const id = this.getBlockData();
                const existing = project.lookupAsset(this.getAssetType(), id);
                if (existing && !(newText && this.isEmpty)) {
                    this.asset = existing;
                }
                else {
                    this.setBlockData(null);
                    if (this.asset) {
                        if (this.sourceBlock_ && this.asset.meta.blockIDs) {
                            this.asset.meta.blockIDs = this.asset.meta.blockIDs.filter(id => id !== this.sourceBlock_.id);

                            if (!this.isTemporaryAsset()) {
                                project.updateAsset(this.asset);
                            }
                        }
                    }
                    this.isEmpty = !newText;
                    this.asset = this.createNewAsset(newText);
                }
                this.updateAssetMeta();
                this.updateAssetListener();
            }
        }


protected parseFieldOptions(opts: U): V {
            // NOTE: This implementation is duplicated in pxtcompiler/emitter/service.ts
            // TODO: Refactor to share implementation.
            const parsed: ParsedFieldAssetEditorOptions = {
                initWidth: 16,
                initHeight: 16,
                disableResize: false,
            };

            if (!opts) {
                return parsed as V;
            }

            if (opts.disableResize) {
                parsed.disableResize = opts.disableResize.toLowerCase() === "true" || opts.disableResize === "1";
            }

            parsed.initWidth = withDefault(opts.initWidth, parsed.initWidth);
            parsed.initHeight = withDefault(opts.initHeight, parsed.initHeight);

            return parsed as V;

            function withDefault(raw: string, def: number) {
                const res = parseInt(raw);
                if (isNaN(res)) {
                    return def;
                }
                return res;
            }
        }


protected updateAssetMeta() {
            if (!this.asset) return;

            if (!this.asset.meta) {
                this.asset.meta = {};
            }

            if (!this.asset.meta.blockIDs) {
                this.asset.meta.blockIDs = [];
            }

            if (this.sourceBlock_) {
                if (this.asset.meta.blockIDs.indexOf(this.sourceBlock_.id) === -1) {
                    const blockIDs = this.asset.meta.blockIDs;
                    if (blockIDs.length && this.isTemporaryAsset() && blockIDs.some(id => this.sourceBlock_.workspace.getBlockById(id))) {
                        // This temporary asset is already used, so we should clone a copy for ourselves
                        this.asset = pxt.cloneAsset(this.asset)
                        this.asset.meta.blockIDs = [];
                    }
                    this.asset.meta.blockIDs.push(this.sourceBlock_.id);
                }
                this.setBlockData(this.asset.id);
            }

            if (!this.isTemporaryAsset()) {
                pxt.react.getTilemapProject().updateAsset(this.asset);
            }
            else {
                this.asset.meta.temporaryInfo = {
                    blockId: this.sourceBlock_.id,
                    fieldName: this.name
                };
            }
        }


protected updateAssetListener() {
            pxt.react.getTilemapProject().removeChangeListener(this.getAssetType(), this.assetChangeListener);
            if (this.asset && !this.isTemporaryAsset()) {
                pxt.react.getTilemapProject().addChangeListener(this.asset, this.assetChangeListener);
            }
        }


isNull() {
            return this.oldRevision === this.newRevision && super.isNull();
        }


run(forward: boolean) {
            if (this.newAssetId || this.oldAssetId) {
                const block = this.getEventWorkspace_().getBlockById(this.blockId);

                if (forward) {
                    pxt.blocks.setBlockDataForField(block, this.fieldName, this.newAssetId);
                }
                else {
                    pxt.blocks.setBlockDataForField(block, this.fieldName, this.oldAssetId);
                }
            }

            if (forward) {
                pxt.react.getTilemapProject().redo();
                super.run(forward);
            }
            else {
                pxt.react.getTilemapProject().undo();
                super.run(forward);
            }

            const ws = this.getEventWorkspace_();

            // Fire an event to force a recompile, but make sure it doesn't end up on the undo stack
            const ev = new BlocklyTilemapChange(
                ws.getBlockById(this.blockId), 'tilemap-revision', "revision", null, pxt.react.getTilemapProject().revision(), 0, 0);
            ev.recordUndo = false;

            Blockly.Events.fire(ev)
        }


() => {
    it('a event without a name is invalid', async () => {
        const missingName: any = { ...minimalModel };
        delete missingName.name;

        return new Event(missingName).validate((e) => {
            expect(e).not.toBeNull();
            if (e) expect(e.name).toBe(Error.ValidationError.name);
        });
    });

    it('a minimal event is valid', async () => {
        return new Event(minimalModel).validate();
    });

    it('a fully specified event is valid', async () => {
        return new Event(fullModel).validate();
    });
}


async () => {
        const missingName: any = { ...minimalModel };
        delete missingName.name;

        return new Event(missingName).validate((e) => {
            expect(e).not.toBeNull();
            if (e) expect(e.name).toBe(Error.ValidationError.name);
        });
    }


(e) => {
            expect(e).not.toBeNull();
            if (e) expect(e.name).toBe(Error.ValidationError.name);
        }


async () => {
        return new Event(minimalModel).validate();
    }


async () => {
        return new Event(fullModel).validate();
    }


export default function publicRouterWithDb(dataIntermediate: DataIntermediary) {
  let publicRouter = express.Router();

  publicRouter.use((req, res, next) => {
    winston.log('verbose', 'Public Teams request');
    next();
  });

  function handleServerError(req, res) {
    return (err) => {
      if (err instanceof NotFoundError) {
        res.status(404).send(err.toString());
      } else {
        winston.log('error', err);
        res.status(500).send();
      }
    }
  }

  publicRouter.get('/teams', (req, res) => {
    dataIntermediate.getTeams()
    .then(teams => teams.map(t => t.stripPrivateData()))
    .then(teams => res.json(teams))
    .catch(handleServerError(req, res))
  })

  publicRouter.get('/teams/:id', (req, res) => {
    let id = req.params.id;
    dataIntermediate.getTeam(id)
    .then(team => team.stripPrivateData())
    .then(team => res.json(team))
    .catch(handleServerError(req, res))
  })

  return publicRouter;
}


function handleServerError(req, res) {
    return (err) => {
      if (err instanceof NotFoundError) {
        res.status(404).send(err.toString());
      } else {
        winston.log('error', err);
        res.status(500).send();
      }
    }
  }


(req, res, next) => {
    winston.log('verbose', 'Public Teams request');
    next();
  }


(err) => {
      if (err instanceof NotFoundError) {
        res.status(404).send(err.toString());
      } else {
        winston.log('error', err);
        res.status(500).send();
      }
    }


(req, res) => {
    dataIntermediate.getTeams()
    .then(teams => teams.map(t => t.stripPrivateData()))
    .then(teams => res.json(teams))
    .catch(handleServerError(req, res))
  }


teams => teams.map(t => t.stripPrivateData())


t => t.stripPrivateData()


teams => res.json(teams)


(req, res) => {
    let id = req.params.id;
    dataIntermediate.getTeam(id)
    .then(team => team.stripPrivateData())
    .then(team => res.json(team))
    .catch(handleServerError(req, res))
  }


team => team.stripPrivateData()


team => res.json(team)


export interface AFGPipelineSupportHologram extends AFGFactoryHologram {
  /**
   * The most fitting mesh for our aim height.
   */
  mSupportMesh: FPoleHeightMesh;

  /**
   * if you should be able to adjust the vrticale direction of the connection and top part of the pole
   */
  mCanAdjustVerticalAngle: boolean;

  /**
   * The connection conveyors snap to, used when placing a support automatically.
   */
  mSnapConnection: UFGPipeConnectionComponentBase;

  /**
   * Used to rotate the connection and top part vetically
   */
  mVerticalAngle: float;

  /**
   * The support mesh.
   */
  mSupportMeshComponent: Unknown<'UStaticMeshComponent'>;

  /**
   * The support mesh.
   */
  mSupportTopPartMeshComponent: Unknown<'UStaticMeshComponent'>;

  /**
   * The scene component for adjusting the length of the support.
   */
  mSupportLengthComponent: Unknown<'USceneComponent'>;
}


export class FlowNodePersistenceFacade implements IFlowNodePersistenceFacade {

  private flowNodeInstanceService: IFlowNodeInstanceService;
  private loggingApiService: ILoggingApi;

  constructor(
    flowNodeInstanceService: IFlowNodeInstanceService,
    loggingApiService: ILoggingApi,
  ) {
    this.flowNodeInstanceService = flowNodeInstanceService;
    this.loggingApiService = loggingApiService;
  }

  public async persistOnEnter(
    flowNode: Model.Base.FlowNode,
    flowNodeInstanceId: string,
    processToken: ProcessToken,
    previousFlowNodeInstanceId?: string,
  ): Promise<void> {

    await this.flowNodeInstanceService.persistOnEnter(flowNode, flowNodeInstanceId, processToken, previousFlowNodeInstanceId);

    const now = moment.utc().toDate();

    this.loggingApiService.writeLogForFlowNode(
      processToken.correlationId,
      processToken.processModelId,
      processToken.processInstanceId,
      flowNodeInstanceId,
      flowNode.id,
      LogLevel.info,
      MetricMeasurementPoint.onFlowNodeEnter,
      processToken.payload,
      'Flow Node execution started.',
      now,
    );
  }

  public async persistOnExit(
    flowNode: Model.Base.FlowNode,
    flowNodeInstanceId: string,
    processToken: ProcessToken,
  ): Promise<void> {

    await this.flowNodeInstanceService.persistOnExit(flowNode, flowNodeInstanceId, processToken);

    const now = moment.utc().toDate();

    this.loggingApiService.writeLogForFlowNode(
      processToken.correlationId,
      processToken.processModelId,
      processToken.processInstanceId,
      flowNodeInstanceId,
      flowNode.id,
      LogLevel.info,
      MetricMeasurementPoint.onFlowNodeExit,
      processToken.payload,
      'Flow Node execution finished.',
      now,
    );
  }

  public async persistOnTerminate(
    flowNode: Model.Base.FlowNode,
    flowNodeInstanceId: string,
    processToken: ProcessToken,
  ): Promise<void> {

    await this.flowNodeInstanceService.persistOnTerminate(flowNode, flowNodeInstanceId, processToken);

    const now = moment.utc().toDate();

    this.loggingApiService.writeLogForFlowNode(
      processToken.correlationId,
      processToken.processModelId,
      processToken.processInstanceId,
      flowNodeInstanceId,
      flowNode.id,
      LogLevel.error,
      MetricMeasurementPoint.onFlowNodeExit,
      processToken.payload,
      'Flow Node execution terminated.',
      now,
    );
  }

  public async persistOnError(
    flowNode: Model.Base.FlowNode,
    flowNodeInstanceId: string,
    processToken: ProcessToken,
    error: Error,
  ): Promise<void> {

    await this.flowNodeInstanceService.persistOnError(flowNode, flowNodeInstanceId, processToken, error);

    const now = moment.utc().toDate();

    this.loggingApiService.writeLogForFlowNode(
      processToken.correlationId,
      processToken.processModelId,
      processToken.processInstanceId,
      flowNodeInstanceId,
      flowNode.id,
      LogLevel.error,
      MetricMeasurementPoint.onFlowNodeError,
      processToken.payload,
      `Flow Node execution failed: ${error.message}`,
      now,
      error,
    );
  }

  public async persistOnSuspend(
    flowNode: Model.Base.FlowNode,
    flowNodeInstanceId: string,
    processToken: ProcessToken,
  ): Promise<void> {

    await this.flowNodeInstanceService.suspend(flowNode.id, flowNodeInstanceId, processToken);

    const now = moment.utc().toDate();

    this.loggingApiService.writeLogForFlowNode(
      processToken.correlationId,
      processToken.processModelId,
      processToken.processInstanceId,
      flowNodeInstanceId,
      flowNode.id,
      LogLevel.info,
      MetricMeasurementPoint.onFlowNodeSuspend,
      processToken.payload,
      'Flow Node execution suspended.',
      now,
    );
  }

  public async persistOnResume(
    flowNode: Model.Base.FlowNode,
    flowNodeInstanceId: string,
    processToken: ProcessToken,
  ): Promise<void> {

    await this.flowNodeInstanceService.resume(flowNode.id, flowNodeInstanceId, processToken);

    const now = moment.utc().toDate();

    this.loggingApiService.writeLogForFlowNode(
      processToken.correlationId,
      processToken.processModelId,
      processToken.processInstanceId,
      flowNodeInstanceId,
      flowNode.id,
      LogLevel.info,
      MetricMeasurementPoint.onFlowNodeResume,
      processToken.payload,
      'Flow Node execution resumed.',
      now,
    );
  }

}


public async persistOnEnter(
    flowNode: Model.Base.FlowNode,
    flowNodeInstanceId: string,
    processToken: ProcessToken,
    previousFlowNodeInstanceId?: string,
  ): Promise<void> {

    await this.flowNodeInstanceService.persistOnEnter(flowNode, flowNodeInstanceId, processToken, previousFlowNodeInstanceId);

    const now = moment.utc().toDate();

    this.loggingApiService.writeLogForFlowNode(
      processToken.correlationId,
      processToken.processModelId,
      processToken.processInstanceId,
      flowNodeInstanceId,
      flowNode.id,
      LogLevel.info,
      MetricMeasurementPoint.onFlowNodeEnter,
      processToken.payload,
      'Flow Node execution started.',
      now,
    );
  }


public async persistOnExit(
    flowNode: Model.Base.FlowNode,
    flowNodeInstanceId: string,
    processToken: ProcessToken,
  ): Promise<void> {

    await this.flowNodeInstanceService.persistOnExit(flowNode, flowNodeInstanceId, processToken);

    const now = moment.utc().toDate();

    this.loggingApiService.writeLogForFlowNode(
      processToken.correlationId,
      processToken.processModelId,
      processToken.processInstanceId,
      flowNodeInstanceId,
      flowNode.id,
      LogLevel.info,
      MetricMeasurementPoint.onFlowNodeExit,
      processToken.payload,
      'Flow Node execution finished.',
      now,
    );
  }


public async persistOnTerminate(
    flowNode: Model.Base.FlowNode,
    flowNodeInstanceId: string,
    processToken: ProcessToken,
  ): Promise<void> {

    await this.flowNodeInstanceService.persistOnTerminate(flowNode, flowNodeInstanceId, processToken);

    const now = moment.utc().toDate();

    this.loggingApiService.writeLogForFlowNode(
      processToken.correlationId,
      processToken.processModelId,
      processToken.processInstanceId,
      flowNodeInstanceId,
      flowNode.id,
      LogLevel.error,
      MetricMeasurementPoint.onFlowNodeExit,
      processToken.payload,
      'Flow Node execution terminated.',
      now,
    );
  }


public async persistOnError(
    flowNode: Model.Base.FlowNode,
    flowNodeInstanceId: string,
    processToken: ProcessToken,
    error: Error,
  ): Promise<void> {

    await this.flowNodeInstanceService.persistOnError(flowNode, flowNodeInstanceId, processToken, error);

    const now = moment.utc().toDate();

    this.loggingApiService.writeLogForFlowNode(
      processToken.correlationId,
      processToken.processModelId,
      processToken.processInstanceId,
      flowNodeInstanceId,
      flowNode.id,
      LogLevel.error,
      MetricMeasurementPoint.onFlowNodeError,
      processToken.payload,
      `Flow Node execution failed: ${error.message}`,
      now,
      error,
    );
  }


public async persistOnSuspend(
    flowNode: Model.Base.FlowNode,
    flowNodeInstanceId: string,
    processToken: ProcessToken,
  ): Promise<void> {

    await this.flowNodeInstanceService.suspend(flowNode.id, flowNodeInstanceId, processToken);

    const now = moment.utc().toDate();

    this.loggingApiService.writeLogForFlowNode(
      processToken.correlationId,
      processToken.processModelId,
      processToken.processInstanceId,
      flowNodeInstanceId,
      flowNode.id,
      LogLevel.info,
      MetricMeasurementPoint.onFlowNodeSuspend,
      processToken.payload,
      'Flow Node execution suspended.',
      now,
    );
  }


public async persistOnResume(
    flowNode: Model.Base.FlowNode,
    flowNodeInstanceId: string,
    processToken: ProcessToken,
  ): Promise<void> {

    await this.flowNodeInstanceService.resume(flowNode.id, flowNodeInstanceId, processToken);

    const now = moment.utc().toDate();

    this.loggingApiService.writeLogForFlowNode(
      processToken.correlationId,
      processToken.processModelId,
      processToken.processInstanceId,
      flowNodeInstanceId,
      flowNode.id,
      LogLevel.info,
      MetricMeasurementPoint.onFlowNodeResume,
      processToken.payload,
      'Flow Node execution resumed.',
      now,
    );
  }


export class Command extends EnjoComponent<CommandOptions> {
  /**
   * The invoke triggers.
   * @type {string[]}
   */
  public triggers: string[];

  /**
   * Whether to start typing before running this command.
   * @type {boolean}
   */
  public typing: boolean;

  /**
   * The type of channel this command can be ran in.
   * @type {ChannelType}
   */
  public channel?: ChannelType;

  /**
   * The permissions needed for this command.
   * @type {CommandPermissions}
   */
  public permissions: Required<CommandPermissions>;

  /**
   * @param {Enjo} client The client instance.
   * @param {CommandOptions} options The command options.
   */
  public constructor(client: Enjo, options: CommandOptions) {
    options = mergeObjects(options, COMMAND_DEFAULTS);
    super(client, options);

    this.triggers = options.triggers ?? [];
    this.typing = options.typing ?? true;
    this.channel = options.channel;
    this.permissions = mergeObjects(
      options.permissions ?? {},
      PERMISSION_DEFAULTS
    );
  }

  /**
   * The ratelimit options.
   * @type {RatelimitOptions}
   */
  public get ratelimit(): Required<RatelimitOptions> {
    if (typeof this.options.ratelimit === "string") {
      const r = RATELIMIT_REGEXP.exec(this.options.ratelimit);
      if (!r) return RATELIMIT_DEFAULTS;

      const [, type, bucket, reset, unit, stack] = r;
      return {
        bucket: +(bucket ?? 1),
        type: type as RatelimitType,
        reset: unit ? Duration.parse(`${reset}${unit}`) : +(reset ?? 5000),
        stack: !!stack,
      };
    }

    return mergeObjects(this.options.ratelimit ?? {}, RATELIMIT_DEFAULTS);
  }

  /**
   * Called whenever one of the triggers is invoked.
   * @param {Context} ctx The context.
   * @param {Dictionary} args Parsed arguments.
   */
  public exec(ctx: Context, args: Dictionary): unknown {
    void ctx;
    void args;
    throw new Error(`${this.constructor.name}#exec: Method not implemented.`);
  }
}


export interface RatelimitOptions {
  /**
   * Whether to stack the reset cooldown if the target is already limited.
   * @type {boolean}
   */
  readonly stack?: boolean;

  /**
   * The amount of invokes before getting limited.
   * @type {number}
   * @example
   * 2
   */
  readonly bucket?: number;

  /**
   * The amount of time before the ratelimit resets.
   * @type {number | string}
   * @example
   * "30s"
   */
  readonly reset: number;

  /**
   * The type of ratelimit.
   * Either "user", "guild", or "channel".
   * @type {RatelimitType}
   */
  readonly type?: RatelimitType;
}


export interface CommandDescription {
  /**
   * Description content.
   * @type {string}
   * @example
   * "Bans the provided member(s)"
   */
  readonly content: string;

  /**
   * Extended description content.
   * @type {string}
   * @example
   * [
   *  "Bans up to 10 members for a certain reason, you can also provide a duration.",
   *  "Example: `!ban @2D @aesthetical garbage people --duration 10m`"
   * ]
   */
  readonly extended?: string | string[];
}


export interface CommandPermissions {
  /**
   * Permissions the invoker needs to run this command.
   * @type {PermissionResolvable | MissingPermissionResolver}
   * @example
   * ["BanMembers"]
   */
  readonly invoker?: PermissionResolvable | MissingPermissionResolver;

  /**
   * Permissions the client needs for this command to be ran.
   * @type {PermissionResolvable | MissingPermissionResolver}
   * @example
   * ["BanMembers"]
   */
  readonly client?: PermissionResolvable | MissingPermissionResolver;

  /**
   * Whether the invoker has to be the bot owner to use this command.
   * @type {boolean}
   */
  readonly botOwner?: boolean;

  /**
   * Whether the invoker has to be the guild owner to use this command.
   * @type {boolean}
   */
  readonly guildOwner?: boolean;
}


export interface CommandOptions extends ComponentOptions {
  /**
   * The triggers of this command. You need at least one trigger for the command to be invokable.
   * @type {string[]}
   * @example
   * ["ping", "latency"]
   */
  readonly triggers?: string[];

  /**
   * The description of this command.
   * @type {string | CommandDescription}
   * @example
   * {
   *   content: "Bans the provided member(s)",
   *   extended: [
   *    "Bans up to 10 members for a certain reason, you can also provide a duration.",
   *    "Example: `!ban @2D @aesthetical garbage people --duration 10m`"
   *   ]
   * }
   */
  readonly description?: string | CommandDescription;

  /**
   * Example usages of this command.
   * @type {string | ExampleGetter}
   * @example
   * (prefix) => [
   *  `${prefix}help ping`
   * ]
   */
  readonly examples?: any[] | ExampleGetter;

  /**
   * The permissions that this command needs.
   * @type {CommandPermissions}
   * @example
   * {
   *   invoker: Permission.BanMembers,
   *   client: Permission.BanMembers
   * }
   */
  readonly permissions?: CommandPermissions;

  /**
   * The type of channel this command can run in.
   * @type {ChannelType}
   * @example
   * "guild"
   */
  readonly channel?: ChannelType;

  /**
   * This commands usage.
   * @type {string}
   * @example
   * "[command name]"
   */
  readonly usage?: string;

  /**
   * Whether to start typing before running the command.
   * @type {boolean}
   */
  readonly typing?: boolean;

  /**
   * The ratelimit type.
   * @type {string | RatelimitOptions}
   * @example
   * {
   *   ratelimit: "guild:4/3s",
   *   ratelimit: {
   *     bucket: 4,
   *     reset: 3e4,
   *     type: "guild"
   *   }
   * }
   */
  readonly ratelimit?: string | RatelimitOptions;
}


export type ExampleGetter = (prefix: string) => string[];


export type MissingPermissionResolver = (ctx: Context) => null | unknown;


export type ChannelType = "guild" | "dm";


export type RatelimitType =
  | ("ch" | "channel")
  | ("usr" | "user")
  | ("g" | "guild");


/**
   * Called whenever one of the triggers is invoked.
   * @param {Context} ctx The context.
   * @param {Dictionary} args Parsed arguments.
   */
public exec(ctx: Context, args: Dictionary): unknown {
    void ctx;
    void args;
    throw new Error(`${this.constructor.name}#exec: Method not implemented.`);
  }


(a, b) => {
                return a.date - b.date;
            }


@Injectable()
export class ChatroomService {

    getChat(): Chat {
        const me = {
            name: 'Me',
            pictureUrl: 'https://i.imgur.com/y3cKSmP.png',
            coverUrl: 'https://i.imgur.com/xutC5nY.jpg',
            admin: false
        };
        const other = {
            name: faker.name.findName(),
            pictureUrl: 'https://i.imgur.com/y3cKSmP.png',
            coverUrl: 'https://i.imgur.com/xutC5nY.jpg',
            admin: false
        };
        const system = {
            name: 'Notification',
            pictureUrl: '',
            coverUrl: '',
            admin: true
        }

        const messages = [];
        for (let i = 0; i < 4; i++) {
            const sender = faker.random.boolean() ? me : other;
            const content = faker.lorem.sentence();
            const date = faker.date.recent();

            messages.push({
                sender: sender,
                content: content,
                date: date
            });
        }

        const chat = {
            participants: {
                me: me,
                other: other,
                system: system
            },
            messages: messages.sort((a, b) => {
                return a.date - b.date;
            })
        };

        return chat;
    }
}


export interface User {
    name: string;
    pictureUrl: string;
    coverUrl: string;
    admin: boolean;
}


export interface Message {
    sender: User;
    content: string;
    date: Date;
  }


export interface Participants {
    me: User;
    other: User;
    system: User;
}


export interface Chat {
    participants: Participants;
    messages: Array<Message>;
}


getChat(): Chat {
        const me = {
            name: 'Me',
            pictureUrl: 'https://i.imgur.com/y3cKSmP.png',
            coverUrl: 'https://i.imgur.com/xutC5nY.jpg',
            admin: false
        };
        const other = {
            name: faker.name.findName(),
            pictureUrl: 'https://i.imgur.com/y3cKSmP.png',
            coverUrl: 'https://i.imgur.com/xutC5nY.jpg',
            admin: false
        };
        const system = {
            name: 'Notification',
            pictureUrl: '',
            coverUrl: '',
            admin: true
        }

        const messages = [];
        for (let i = 0; i < 4; i++) {
            const sender = faker.random.boolean() ? me : other;
            const content = faker.lorem.sentence();
            const date = faker.date.recent();

            messages.push({
                sender: sender,
                content: content,
                date: date
            });
        }

        const chat = {
            participants: {
                me: me,
                other: other,
                system: system
            },
            messages: messages.sort((a, b) => {
                return a.date - b.date;
            })
        };

        return chat;
    }


() => {
        this.module.RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED", this.COMBAT_LOG_EVENT_UNFILTERED);
    }


() => {
        this.module.UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED");
    }


(event: string, ...__args: any[]) => {
        let [, cleuEvent, , sourceGUID, , , , , , , , arg12, , , arg15] = CombatLogGetCurrentEventInfo();
        if (sourceGUID == this.ovale.playerGUID) {
            this.profiler.StartProfiling("OvaleSpellDamage_COMBAT_LOG_EVENT_UNFILTERED");
            if (CLEU_DAMAGE_EVENT[cleuEvent]) {
                let [spellId, amount] = [arg12, arg15];
                this.value[spellId] = amount;
                this.ovale.needRefresh();
            }
            this.profiler.StopProfiling("OvaleSpellDamage_COMBAT_LOG_EVENT_UNFILTERED");
        }
    }


export class OvaleSpellDamageClass {
    value: LuaArray<number> = {}
    private module: AceModule & AceEvent;
    private profiler: Profiler;

    constructor(private ovale: OvaleClass, ovaleProfiler: OvaleProfilerClass) {
        this.module = ovale.createModule("OvaleSpellDamage", this.OnInitialize, this.OnDisable, aceEvent);
        this.profiler = ovaleProfiler.create(this.module.GetName());
    }

    private OnInitialize = () => {
        this.module.RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED", this.COMBAT_LOG_EVENT_UNFILTERED);
    }

    private OnDisable = () => {
        this.module.UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED");
    }

    private COMBAT_LOG_EVENT_UNFILTERED = (event: string, ...__args: any[]) => {
        let [, cleuEvent, , sourceGUID, , , , , , , , arg12, , , arg15] = CombatLogGetCurrentEventInfo();
        if (sourceGUID == this.ovale.playerGUID) {
            this.profiler.StartProfiling("OvaleSpellDamage_COMBAT_LOG_EVENT_UNFILTERED");
            if (CLEU_DAMAGE_EVENT[cleuEvent]) {
                let [spellId, amount] = [arg12, arg15];
                this.value[spellId] = amount;
                this.ovale.needRefresh();
            }
            this.profiler.StopProfiling("OvaleSpellDamage_COMBAT_LOG_EVENT_UNFILTERED");
        }
    }
    Get(spellId: number) {
        return this.value[spellId];
    }
}


Get(spellId: number) {
        return this.value[spellId];
    }


export function isForInStatement(node: Node): node is ForInStatement {
	return node.type === NodeType.ForInStatement;
}


export default class ForInStatement extends StatementBase {
	type: NodeType.tForInStatement;
	left: VariableDeclaration | PatternNode;
	right: ExpressionNode;
	body: StatementNode;

	bind() {
		this.left.bind();
		this.left.deoptimizePath(EMPTY_PATH);
		this.right.bind();
		this.body.bind();
	}

	createScope(parentScope: Scope) {
		this.scope = new BlockScope(parentScope);
	}

	hasEffects(options: ExecutionPathOptions): boolean {
		return (
			(this.left &&
				(this.left.hasEffects(options) ||
					this.left.hasEffectsWhenAssignedAtPath(EMPTY_PATH, options))) ||
			(this.right && this.right.hasEffects(options)) ||
			this.body.hasEffects(options.setIgnoreBreakStatements())
		);
	}

	include() {
		this.included = true;
		this.left.includeWithAllDeclaredVariables();
		this.left.deoptimizePath(EMPTY_PATH);
		this.right.include();
		this.body.include();
	}

	render(code: MagicString, options: RenderOptions) {
		this.left.render(code, options, NO_SEMICOLON);
		this.right.render(code, options, NO_SEMICOLON);
		this.body.render(code, options);
	}
}


bind() {
		this.left.bind();
		this.left.deoptimizePath(EMPTY_PATH);
		this.right.bind();
		this.body.bind();
	}


createScope(parentScope: Scope) {
		this.scope = new BlockScope(parentScope);
	}


hasEffects(options: ExecutionPathOptions): boolean {
		return (
			(this.left &&
				(this.left.hasEffects(options) ||
					this.left.hasEffectsWhenAssignedAtPath(EMPTY_PATH, options))) ||
			(this.right && this.right.hasEffects(options)) ||
			this.body.hasEffects(options.setIgnoreBreakStatements())
		);
	}


include() {
		this.included = true;
		this.left.includeWithAllDeclaredVariables();
		this.left.deoptimizePath(EMPTY_PATH);
		this.right.include();
		this.body.include();
	}


render(code: MagicString, options: RenderOptions) {
		this.left.render(code, options, NO_SEMICOLON);
		this.right.render(code, options, NO_SEMICOLON);
		this.body.render(code, options);
	}


() => {

    test('get datetime value returns a datetime string', () => {
        const result = MacroMethods.getDateTimeValue(`{![${mockMetaData.valueElements[2].developerName}]}`);
        expect(result).toEqual(datetimeFormattedMock);
    });

    test('get number value returns a number', () => {
        const result = MacroMethods.getNumberValue(`{![${mockMetaData.valueElements[3].developerName}]}`);
        expect(result).toEqual(mockState.values.test4.contentValue);
    });

    test('get object value returns an object', () => {
        const result = MacroMethods.getObject(`{![${mockMetaData.valueElements[4].developerName}]}`);
        expect(result).toEqual(mockState.values.test5.objectData[0]);
    });

    test('get array value returns an array', () => {
        const result = MacroMethods.getArray(`{![${mockMetaData.valueElements[7].developerName}]}`);
        expect(result).toEqual(mockState.values.test8.objectData);
    });

    test('Setter functions insert passed value into macro state', () => {

        const spy = jest.spyOn(utils, 'setStateValue');

        setMacroState(mockState);
        MacroMethods.initMethods(mockMetaData);

        MacroMethods.setDateTimeValue(
            `{![${mockState.values.test3.developerName}]}`,
            datetimeMock,
        );
        const mockDateTimeProps = {
            contentValue: datetimeFormattedMock,
            objectData: null,
            pageComponentId: null,
        };
        expect(spy).toHaveBeenCalledWith(
            mockState.values.test3.id,
            mockDateTimeProps,
        );

        const mockObjectContentValue = { properties: [] };
        MacroMethods.setObject(
            `{![${mockState.values.test5.developerName}]}`,
            mockObjectContentValue,
        );
        const mockObjectProps = {
            contentValue: null,
            objectData: [mockObjectContentValue],
            pageComponentId: null,
        };
        expect(spy).toHaveBeenCalledWith(
            mockState.values.test5.id,
            mockObjectProps,
        );

        const mockArrayContentValue = [1, 2, 3];
        MacroMethods.setArray(
            `{![${mockState.values.test8.developerName}]}`,
            mockArrayContentValue,
        );
        const mockArrayProps = {
            contentValue: null,
            objectData: mockArrayContentValue,
            pageComponentId: null,
        };
        expect(spy).toHaveBeenCalledWith(
            mockState.values.test8.id,
            mockArrayProps,
        );
    });

    test('Binding property methods should return an object with values mapping to property methods', () => {
        const result = bindValuePropertyFunctions();
        for (const key in MacroPropertyMethods) {
            // eslint-disable-next-line no-prototype-builtins
            if (MacroPropertyMethods.hasOwnProperty(key)) {
                const func = MacroPropertyMethods[key];
                expect(result[func.name]).toEqual(MacroPropertyMethods[key]);
            }
        }
    });
}


() => {
        const result = MacroMethods.getDateTimeValue(`{![${mockMetaData.valueElements[2].developerName}]}`);
        expect(result).toEqual(datetimeFormattedMock);
    }


() => {
        const result = MacroMethods.getNumberValue(`{![${mockMetaData.valueElements[3].developerName}]}`);
        expect(result).toEqual(mockState.values.test4.contentValue);
    }


() => {
        const result = MacroMethods.getObject(`{![${mockMetaData.valueElements[4].developerName}]}`);
        expect(result).toEqual(mockState.values.test5.objectData[0]);
    }


() => {
        const result = MacroMethods.getArray(`{![${mockMetaData.valueElements[7].developerName}]}`);
        expect(result).toEqual(mockState.values.test8.objectData);
    }


() => {

        const spy = jest.spyOn(utils, 'setStateValue');

        setMacroState(mockState);
        MacroMethods.initMethods(mockMetaData);

        MacroMethods.setDateTimeValue(
            `{![${mockState.values.test3.developerName}]}`,
            datetimeMock,
        );
        const mockDateTimeProps = {
            contentValue: datetimeFormattedMock,
            objectData: null,
            pageComponentId: null,
        };
        expect(spy).toHaveBeenCalledWith(
            mockState.values.test3.id,
            mockDateTimeProps,
        );

        const mockObjectContentValue = { properties: [] };
        MacroMethods.setObject(
            `{![${mockState.values.test5.developerName}]}`,
            mockObjectContentValue,
        );
        const mockObjectProps = {
            contentValue: null,
            objectData: [mockObjectContentValue],
            pageComponentId: null,
        };
        expect(spy).toHaveBeenCalledWith(
            mockState.values.test5.id,
            mockObjectProps,
        );

        const mockArrayContentValue = [1, 2, 3];
        MacroMethods.setArray(
            `{![${mockState.values.test8.developerName}]}`,
            mockArrayContentValue,
        );
        const mockArrayProps = {
            contentValue: null,
            objectData: mockArrayContentValue,
            pageComponentId: null,
        };
        expect(spy).toHaveBeenCalledWith(
            mockState.values.test8.id,
            mockArrayProps,
        );
    }


() => {
        const result = bindValuePropertyFunctions();
        for (const key in MacroPropertyMethods) {
            // eslint-disable-next-line no-prototype-builtins
            if (MacroPropertyMethods.hasOwnProperty(key)) {
                const func = MacroPropertyMethods[key];
                expect(result[func.name]).toEqual(MacroPropertyMethods[key]);
            }
        }
    }


export function parseHSV(h: number, s: number, v: number): string {
  var r = v
  var g = v
  var b = v
  if (s > 0) {
    h = h * 6.0
    const i = Math.floor(h)
    const f = h - i
    switch (i) {
      default:
      case 0:
        g *= 1 - s * (1 - f);
        b *= 1 - s;
        break;
      case 1:
        r *= 1 - s * f;
        b *= 1 - s;
        break;
      case 2:
        r *= 1 - s;
        b *= 1 - s * (1 - f);
        break;
      case 3:
        r *= 1 - s;
        g *= 1 - s * f;
        break;
      case 4:
        r *= 1 - s * (1 - f);
        g *= 1 - s;
        break;
      case 5:
        g *= 1 - s;
        b *= 1 - s * f;
        break;
    }
  }
  return "#" + [r, g, b].map(v => {
    var str = Math.round(255 * v).toString(16)
    while (str.length < 2) {
      str = "0" + str
    }
    return str
  }).join('')
}


v => {
    var str = Math.round(255 * v).toString(16)
    while (str.length < 2) {
      str = "0" + str
    }
    return str
  }


({
  description = '',
  lang = 'en',
  meta = [],
  title,
}) => {
  const siteMetadata = useSiteMetadata()

  const metaDescription: string = description || siteMetadata.description || ''

  return (
    <Helmet
      htmlAttributes={{
        lang,
      }}


interface SeoProps {
  lang?: string
  meta?: { name: string; content: string }[]
  description?: string
  title: string
}


decode(buffer: Buffer): void {
        if (buffer.length !== 42 && buffer.length !== 48 && buffer.length !== 49 && buffer.length !== 51 && buffer.length !== 59 && buffer.length !== 60) {
            throw new DecodingError(ERROR_BAD_LENGTH);
        }
        let ofs = 0;
        this.unlockedPositionOffsetDegrees = buffer.readInt16LE(ofs);
        ofs += 2;
        this.lockedPositionOffsetDegrees = buffer.readInt16LE(ofs);
        ofs += 2;
        this.singleLockedPositionOffsetDegrees = buffer.readInt16LE(ofs);
        ofs += 2;
        this.unlockedToLockedTransitionOffsetDegrees = buffer.readInt16LE(ofs);
        ofs += 2;
        if (buffer.length > 42) {
            this.lockngoTimeout = buffer.readUInt8(ofs);
            ofs += 1;
            this.singleButtonPressAction = buffer.readUInt8(ofs);
            ofs += 1;
            this.doubleButtonPressAction = buffer.readUInt8(ofs);
            ofs += 1;
            this.detachedCylinder = buffer.readUInt8(ofs) === 1;
            ofs += 1;
            this.batteryType = buffer.readUInt8(ofs);
            ofs += 1;
            this.automaticBatteryTypeDetection = buffer.readUInt8(ofs) === 1;
            ofs += 1;
            if (buffer.length > 48) {
                this.unlatchDuration = buffer.readUInt8(ofs);
                ofs += 1;
                if (buffer.length > 49) {
                    this.autoLockTimeout = buffer.readUInt16LE(ofs);
                    ofs += 2;
                    if (buffer.length > 51) {
                        this.autoUnlockDisabled = buffer.readUInt8(ofs) === 1;
                        ofs += 1;
                        this.nightmodeEnabled = buffer.readUInt8(ofs) === 1;
                        ofs += 1;
                        this.nightmodeStartTime = Time.decode(buffer, ofs);
                        ofs += 2;
                        this.nightmodeEndTime = Time.decode(buffer, ofs);
                        ofs += 2;
                        this.nightmodeAutoLockEnabled = buffer.readUInt8(ofs) === 1;
                        ofs += 1;
                        this.nightmodeAutoUnlockDisabled = buffer.readUInt8(ofs) === 1;
                        ofs += 1;
                        if (buffer.length > 59) {
                            this.nightmodeImmediateLockOnStart = buffer.readUInt8(ofs) === 1;
                            ofs += 1;
                        }
                    }
                }
            }
        }
        this.nonce = buffer.slice(ofs, ofs + 32);
        ofs += 32;
        this.securityPin = buffer.readUInt16LE(ofs);
    }


encode(): Buffer {
        const buffer = Buffer.alloc(60);
        let ofs = 0;
        buffer.writeInt16LE(this.unlockedPositionOffsetDegrees, ofs);
        ofs += 2;
        buffer.writeInt16LE(this.lockedPositionOffsetDegrees, ofs);
        ofs += 2;
        buffer.writeInt16LE(this.singleLockedPositionOffsetDegrees, ofs);
        ofs += 2;
        buffer.writeInt16LE(this.unlockedToLockedTransitionOffsetDegrees, ofs);
        ofs += 2;
        if (this.lockngoTimeout !== undefined) {
            buffer.writeUInt8(this.lockngoTimeout, ofs);
            ofs += 1;
            buffer.writeUInt8(this.singleButtonPressAction ?? 0, ofs);
            ofs += 1;
            buffer.writeUInt8(this.doubleButtonPressAction ?? 0, ofs);
            ofs += 1;
            buffer.writeUInt8(this.detachedCylinder ?? false ? 1 : 0, ofs);
            ofs += 1;
            buffer.writeUInt8(this.batteryType ?? 0, ofs);
            ofs += 1;
            buffer.writeUInt8(this.automaticBatteryTypeDetection ?? false ? 1 : 0, ofs);
            ofs += 1;
            if (this.unlatchDuration !== undefined) {
                buffer.writeUInt8(this.unlatchDuration ?? 0, ofs);
                ofs += 1;
                if (this.autoLockTimeout !== undefined) {
                    buffer.writeUInt16LE(this.autoLockTimeout ?? 0, ofs);
                    ofs += 2;
                    if (this.autoUnlockDisabled !== undefined) {
                        buffer.writeUInt8(this.autoUnlockDisabled ?? false ? 1 : 0, ofs);
                        ofs += 1;
                        buffer.writeUInt8(this.nightmodeEnabled ?? false ? 1 : 0, ofs);
                        ofs += 1;
                        (this.nightmodeStartTime ?? new Time(0, 0)).encode(buffer, ofs);
                        ofs += 2;
                        (this.nightmodeEndTime ?? new Time(0, 0)).encode(buffer, ofs);
                        ofs += 2;
                        buffer.writeUInt8(this.nightmodeAutoLockEnabled ?? false ? 1 : 0, ofs);
                        ofs += 1;
                        buffer.writeUInt8(this.nightmodeAutoUnlockDisabled ?? false ? 1 : 0, ofs);
                        ofs += 1;
                        if (this.nightmodeImmediateLockOnStart !== undefined) {
                            buffer.writeUInt8(this.nightmodeImmediateLockOnStart ?? false ? 1 : 0, ofs);
                            ofs += 1;
                        }
                    }
                }
            }
        }
        this.nonce.copy(buffer, ofs);
        ofs += 32;
        buffer.writeUInt16LE(this.securityPin, ofs);
        ofs += 2;
        return buffer.slice(0, ofs);
    }


toString(): string {
        let str = "SetAdvancedConfigCommand {";
        str += "\n  unlockedPositionOffsetDegrees: " + "0x" + this.unlockedPositionOffsetDegrees.toString(16).padStart(4, "0");
        str += "\n  lockedPositionOffsetDegrees: " + "0x" + this.lockedPositionOffsetDegrees.toString(16).padStart(4, "0");
        str += "\n  singleLockedPositionOffsetDegrees: " + "0x" + this.singleLockedPositionOffsetDegrees.toString(16).padStart(4, "0");
        str += "\n  unlockedToLockedTransitionOffsetDegrees: " + "0x" + this.unlockedToLockedTransitionOffsetDegrees.toString(16).padStart(4, "0");
        if (this.lockngoTimeout !== undefined) {
            str += "\n  lockngoTimeout: " + "0x" + this.lockngoTimeout.toString(16).padStart(2, "0");
            str += "\n  singleButtonPressAction: " + "0x" + (this.singleButtonPressAction ?? 0).toString(16).padStart(2, "0");
            str += "\n  doubleButtonPressAction: " + "0x" + (this.doubleButtonPressAction ?? 0).toString(16).padStart(2, "0");
            str += "\n  detachedCylinder: " + this.detachedCylinder ?? false;
            str += "\n  batteryType: " + "0x" + (this.batteryType ?? 0).toString(16).padStart(2, "0");
            str += "\n  automaticBatteryTypeDetection: " + this.automaticBatteryTypeDetection ?? false;
            if (this.unlatchDuration !== undefined) {
                str += "\n  unlatchDuration: " + "0x" + (this.unlatchDuration ?? 0).toString(16).padStart(2, "0");
                if (this.autoLockTimeout !== undefined) {
                    str += "\n  autoLockTimeout: " + "0x" + (this.autoLockTimeout ?? 0).toString(16).padStart(4, "0");
                    if (this.autoUnlockDisabled !== undefined) {
                        str += "\n  autoUnlockDisabled: " + this.autoUnlockDisabled ?? false;
                        str += "\n  nightmodeEnabled: " + this.nightmodeEnabled ?? false;
                        str += "\n  nightmodeStartTime: " + (this.nightmodeStartTime ?? new Time(0, 0)).toString();
                        str += "\n  nightmodeEndTime: " + (this.nightmodeEndTime ?? new Time(0, 0)).toString();
                        str += "\n  nightmodeAutoLockEnabled: " + this.nightmodeAutoLockEnabled ?? false;
                        str += "\n  nightmodeAutoUnlockDisabled: " + this.nightmodeAutoUnlockDisabled ?? false;
                        if (this.nightmodeImmediateLockOnStart !== undefined) {
                            str += "\n  nightmodeImmediateLockOnStart: " + this.nightmodeImmediateLockOnStart ?? false;
                        }
                    }
                }
            }
        }
        str += "\n  nonce: " + "0x" + this.nonce.toString("hex");
        str += "\n  securityPin: " + "0x" + this.securityPin.toString(16).padStart(4, "0");
        str += "\n}";
        return str;
    }


() => {
  let component: ButtonComponent;
  let fixture: ComponentFixture<ButtonComponent>;

  beforeEach(waitForAsync(() => {
    TestBed.configureTestingModule({
      declarations: [ ButtonComponent ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(ButtonComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
}


() => {
    TestBed.configureTestingModule({
      declarations: [ ButtonComponent ]
    })
    .compileComponents();
  }


() => {
    fixture = TestBed.createComponent(ButtonComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  }


export interface BaseParams {
  table: Table<string, string>
  client: DynamoDB.DocumentClient
}


export default function Content(): JSX.Element {
  const {
    tabs
  } = useProps();
  const {
    w
  } = useRndState();
  const dragHandleClass = useRndDragHandleClass();

  return <Tabs {...{
    ...tabs,
    contentPadding: 'none',
    classNameForTabBar: dragHandleClass,
    classNameForTabItem: CLASS_J_RND_CANCEL,
    classNameForTabScroller: CLASS_J_RND_CANCEL,
    width: w // 通知宽度变化
  }} />;
}


function drawContent(hypotenuse: number, random: Random): Canvas {
  // Create a canvas with content which can easily be scaled
  const canvas = new Canvas(hypotenuse, hypotenuse);
  const ctx = canvas.getContext("2d");

  const columnHeight = hypotenuse / COLUMNS;
  const offsets: number[] = [];

  ctx.shadowColor = SHADOW_COLOR;
  ctx.shadowBlur = columnHeight / 3;
  // Draw each column
  for (let column = 0; column < COLUMNS; column++) {
    // Get a color combo not used before
    let paletteOffset = random.intBetween(0, 6) * 2;
    while(offsets.includes(paletteOffset)) paletteOffset = random.intBetween(0, 6) * 2;
    offsets.push(paletteOffset);

    // Create a gradient
    const gradient = ctx.createLinearGradient(0, 0, random.intBetween(ctx.canvas.width * 0.2, ctx.canvas.width), random.intBetween(ctx.canvas.height * 0.2, ctx.canvas.height));
    gradient.addColorStop(0, palette[paletteOffset]);
    gradient.addColorStop(1, palette[paletteOffset + 1]);
    ctx.fillStyle = gradient;

    // Create a random curve for the user
    const frequencyOffset = random.floatBetween(MIN_FREQUENCY_OFFSET / (FREQUENCY_SCALE * hypotenuse), MAX_FREQUENCY_OFFSET / (FREQUENCY_SCALE * hypotenuse));
    const periodOffset = random.intBetween(0, 360);
    const curve = new Curve(Math.max(1, GAP * hypotenuse), -10, ctx.canvas.width + 10, x => CURVE_SCALE * hypotenuse * Math.sin((x + periodOffset) * frequencyOffset * 180 / Math.PI));

    // Draw the curves in reverse order so that each gradient covers the before
    ctx.beginPath();
    ctx.moveTo(-10, 0);
    ctx.translate(0, (COLUMNS - column) * columnHeight);
    curve.draw(ctx);
    ctx.translate(0, -(COLUMNS - column) * columnHeight);
    ctx.lineTo(ctx.canvas.width + 10, 0);
    ctx.fill();
  }

  return canvas;
}


async (ctx, random) => {
  const hypotenuse = Math.round(Math.sqrt(Math.pow(ctx.canvas.width, 2) + Math.pow(ctx.canvas.height, 2)));
  // Rotate the canvas around its center
  ctx.translate(ctx.canvas.width / 2, ctx.canvas.height / 2);
  ctx.rotate(random.intBetween(0, 90) * 180 / Math.PI);
  ctx.translate(-ctx.canvas.width / 2, -ctx.canvas.height / 2);

  // Create the content and draw it
  ctx.imageSmoothingEnabled = true;
  const canvas = drawContent(hypotenuse, random);
  ctx.drawImage((canvas as unknown) as CanvasImageSource, (ctx.canvas.width - hypotenuse) / 2, (ctx.canvas.height - hypotenuse) / 2, hypotenuse, hypotenuse);
}


x => CURVE_SCALE * hypotenuse * Math.sin((x + periodOffset) * frequencyOffset * 180 / Math.PI)


export class UpdateProductCostDto {
  @ApiProperty()
  @IsNumber()
  cost: number;
}


export class CaseExpense {
    Id: number;
    ExpenseName: string;
    ExpenseDate: Date;
    Category: string;
    Description: string;
    Amount: number;
    AssociateContactId: number;
    BillDocument: string;
    CaseId: number;
    UpdatedTime: Date;
    IsActive: boolean;
    IsPaid: boolean;
    Billable: boolean;
}


() => console.log(`Example app listening on port ${PORT}!`)


export interface SygIconProps extends CommonProps,  {
  /**
     * Node passed into the SVG element.
     */
    children?: React.ReactNode,
    /**
     * The color of the component. It supports those theme colors that make sense for this component.
     * You can use the `htmlColor` prop to apply a color attribute to the SVG element.
     */
    color?: 'inherit' | 'primary' | 'secondary' | 'action' | 'disabled' | 'error',
    /**
     * The fontSize applied to the icon. Defaults to 24px, but can be configure to inherit font size.
     */
    fontSize?: 'inherit' | 'default' | 'small' | 'large',
    /**
     * Override the default viewboxApplies a color attribute to the SVG element.
     */
    viewBox?: string,
}


/**
 * @ignore - do not document.
 */
function PickersCalendar<TDate>(props: PickersCalendarProps<TDate> & WithStyles<typeof styles>) {
  const {
    allowKeyboardControl,
    allowSameDateSelection,
    onFocusedDayChange: changeFocusedDay,
    classes,
    className,
    currentMonth,
    date,
    disableHighlightToday,
    focusedDay,
    isDateDisabled,
    isMonthSwitchingAnimating,
    loading,
    onChange,
    onMonthSwitchingAnimationEnd,
    reduceAnimations,
    renderDay,
    renderLoading = () => ...,
    showDaysOutsideCurrentMonth,
    slideDirection,
    TransitionProps,
  } =


(theme: Theme): StyleRules<PickersCalendarClassKey> => ({
  root: {
    minHeight: weeksContainerHeight,
  },
  loadingContainer: {
    display: 'flex',
    justifyContent: 'center',
    alignItems: 'center',
    minHeight: weeksContainerHeight,
  },
  weekContainer: {
    overflow: 'hidden',
  },
  week: {
    margin: `${DAY_MARGIN}px 0`,
    display: 'flex',
    justifyContent: 'center',
  },
  daysHeader: {
    display: 'flex',
    justifyContent: 'center',
    alignItems: 'center',
  },
  weekDayLabel: {
    width: 36,
    height: 40,
    margin: '0 2px',
    textAlign: 'center',
    display: 'flex',
    justifyContent: 'center',
    alignItems: 'center',
    color: theme.palette.text.secondary,
  },
})


() => <span data-mui-test


(day: TDate, isFinish: PickerSelectionState = 'finish') => {
      // TODO possibly buggy line figure out and add tests
      const finalDate = Array.isArray(date) ? day : utils.mergeDateAndTime(day, date || now);

      onChange(finalDate, isFinish);
    }


(selectedDateItem) => selectedDateItem && utils.startOfDay(selectedDateItem)


(day, i) => (
          <Typography
            aria-hidden


(week) => (
              <div role="row"


(day) => {
                  const pickersDayProps: PickersDayProps<TDate> = {
                    key: (day as any)?.toString(),
                    day,
                    isAnimating: isMonthSwitchingAnimating,
                    disabled: isDateDisabled(day),
                    allowKeyboardControl,
                    allowSameDateSelection,
                    autoFocus:
                      allowKeyboardControl &&
                      focusedDay !== null &&
                      utils.isSameDay(day, focusedDay),
                    today: utils.isSameDay(day, now),
                    outsideCurrentMonth: utils.getMonth(day) !== currentMonthNumber,
                    selected: selectedDates.some(
                      (selectedDate) => selectedDate && utils.isSameDay(selectedDate, day),
                    ),
                    disableHighlightToday,
                    showDaysOutsideCurrentMonth,
                    onDayFocus: changeFocusedDay,
                    onDaySelect: handleDaySelect,
                  };

                  return renderDay ? (
                    renderDay(day, selectedDates, pickersDayProps)
                  ) : (
                    <div role="cell" key={pickersDayProps.key}>
                      <PickersDay {...pickersDayProps} />
                    </div>


(selectedDate) => selectedDate && utils.isSameDay(selectedDate, day)


export interface ExportedCalendarProps<TDate>
  extends Pick<
    PickersDayProps<TDate>,
    'disableHighlightToday' | 'showDaysOutsideCurrentMonth' | 'allowSameDateSelection'
  > {
  /**
   * Enables keyboard listener for moving between days in calendar.
   * Defaults to `true` unless the `ClockPicker` is used inside a `Static*` picker component.
   */
  allowKeyboardControl?: boolean;
  /**
   * If `true` renders `LoadingComponent` in calendar instead of calendar view.
   * Can be used to preload information and show it in calendar.
   * @default false
   */
  loading?: boolean;
  /**
   * Calendar onChange.
   */
  onChange: PickerOnChangeFn<TDate>;
  /**
   * Custom renderer for day. Check the [PickersDay](https://material-ui.com/api/pickers-day/) component.
   */
  renderDay?: (
    day: TDate,
    selectedDates: Array<TDate | null>,
    pickersDayProps: PickersDayProps<TDate>,
  ) => JSX.Element;
  /**
   * Component displaying when passed `loading` true.
   * @default () => "..."
   */
  renderLoading?: () => React.ReactNode;
}


export interface PickersCalendarProps<TDate> extends ExportedCalendarProps<TDate> {
  className?: string;
  currentMonth: TDate;
  date: TDate | [TDate | null, TDate | null] | null;
  focusedDay: TDate | null;
  isDateDisabled: (day: TDate) => boolean;
  isMonthSwitchingAnimating: boolean;
  onFocusedDayChange: (newFocusedDay: TDate) => void;
  onMonthSwitchingAnimationEnd: () => void;
  reduceAnimations: boolean;
  slideDirection: SlideDirection;
  TransitionProps?: Partial<SlideTransitionProps>;
}


export type PickersCalendarClassKey =
  | 'root'
  | 'loadingContainer'
  | 'weekContainer'
  | 'week'
  | 'daysHeader'
  | 'weekDayLabel';


renderLoading()


clsx(classes


/**
 *
Enables the ADM channel for an application or updates the status and settings of the ADM channel for an application.

 * @example
 * Use a bare-bones client and the command you need to make an API call.
 * ```javascript
 * import { PinpointClient, UpdateAdmChannelCommand } from "@aws-sdk/client-pinpoint"; // ES Modules import
 * // const { PinpointClient, UpdateAdmChannelCommand } = require("@aws-sdk/client-pinpoint"); // CommonJS import
 * const client = new PinpointClient(config);
 * const command = new UpdateAdmChannelCommand(input);
 * const response = await client.send(command);
 * ```
 *
 * @see {@link UpdateAdmChannelCommandInput} for command's `input` shape.
 * @see {@link UpdateAdmChannelCommandOutput} for command's `response` shape.
 * @see {@link PinpointClientResolvedConfig | config} for command's `input` shape.
 *
 */
export class UpdateAdmChannelCommand extends $Command<
  UpdateAdmChannelCommandInput,
  UpdateAdmChannelCommandOutput,
  PinpointClientResolvedConfig
> {
  // Start section: command_properties
  // End section: command_properties

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

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

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

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

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

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

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


export interface UpdateAdmChannelCommandInput extends UpdateAdmChannelRequest {}


export interface UpdateAdmChannelCommandOutput extends UpdateAdmChannelResponse, __MetadataBearer {}


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

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

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


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


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


(time: number) => {
  return new Promise(function (resolve) {
    setTimeout(resolve, time);
  });
}


export type Middleware = (
  request: NextApiRequest,
  response: NextApiResponse,
  next: NextHandler
) => void


() => {
  const apiClient = useApiClient();
  const { data: onAirData } = useQuery("onAir", () => apiClient.getOnAir());
  const { data: favoritesData } = useQuery(
    ["favorites", FavoriteStatus.Watching],
    () => apiClient.getFavorites(FavoriteStatus.Watching),
  );

  usePageTitle();

  return (
    <SectionList>
      {favoritesData && favoritesData.data.length > 0 && (
        <Section
          title="Continue Watching"
          iconActions={
            <LinkButton
              to="/profile"
              variant="plain-primary"
              icon={ChevronRightIcon}
              iconOnly
              title="My Favorites"
              aria-label="My Favorites"
            />
          }


() => apiClient.getOnAir()


() => apiClient.getFavorites(FavoriteStatus.Watching)


(props?:Args) => {

    props = props ? {...DEFAULT_ARGS, ...props} : DEFAULT_ARGS;
    const {} = props

    return `<menu-play ${argsToAttrs(props)}></menu-play>`;
}


interface Args {
}


async (text: string) => {
    if (!process.env.GOOGLE_APPLICATION_CREDENTIALS) {
        throw new Error("GOOGLE_APPLICATION_CREDENTIALS is not set");
    }

    const request = {
        session: sessionPath,
        queryInput: {
            text: {
                text: text,
                languageCode: "en-US",
            },
        },
    };

    return await sessionClient.detectIntent(request);
}


export function normalizePoint(
  bbox: Rectangle,
  args: {
    x?: string | number
    y?: string | number
  } = {},
) {
  return new Point(
    NumberExt.normalizePercentage(args.x, bbox.width),
    NumberExt.normalizePercentage(args.y, bbox.height),
  )
}


export function toResult<T>(
  point: Point,
  angle?: number,
  rawArgs?: T,
): PortLayout.Result {
  return {
    position: point.toJSON(),
    rotation: angle,
    ...rawArgs,
  }
}


(date_time:DatePickerOutPut) => {
		const {onToDateUpdate} = this.props

		this.setState({advance_pill : null})
		onToDateUpdate(date_time)
	}


(date_time:DatePickerOutPut) => {
		const {onFromDateUpdate} = this.props

		this.setState({advance_pill : null})
		onFromDateUpdate(date_time)
	}


() => {
		const {advance_pill} = this.state
		const {format, weekStartsOn,
			from_date, to_date,
			colors
		} = this.props

		const common_props = {format, weekStartsOn, otherDateRangeIndex: 0}

		return (
			<div className={styles.wrapper} style={{color: colors.primary_font_color}}


() => {
		const {format,
			onFromDateUpdate, onToDateUpdate} = this.props
		const lastMonth = subMonths(new Date(), 1)

		let from_ts = startOfMonth(lastMonth)
		let to_ts = endOfMonth(lastMonth)
		this.setState({advance_pill: 'lm'})
		// call related handlers
		onFromDateUpdate(generateDatePickerOutput(
			from_ts.getDate(), from_ts.getMonth(), from_ts.getFullYear(), format
		))
		onToDateUpdate(generateDatePickerOutput(
			to_ts.getDate(), to_ts.getMonth(), to_ts.getFullYear(), format
		))
	}


() => {
		const {format,
			onFromDateUpdate, onToDateUpdate} = this.props
		const now = new Date()

		const from_ts = startOfMonth(now)
		const to_ts = endOfMonth(now)
		this.setState({advance_pill: 'tm'})
		// call related handlers
		onFromDateUpdate(generateDatePickerOutput(
			from_ts.getDate(), from_ts.getMonth(), from_ts.getFullYear(), format
		))
		onToDateUpdate(generateDatePickerOutput(
			to_ts.getDate(), to_ts.getMonth(), to_ts.getFullYear(), format
		))
	}


() => {
		const {weekStartsOn, format,
			onFromDateUpdate, onToDateUpdate} = this.props
		const now = new Date()
		// @ts-ignore
		const from_ts = startOfWeek(now, {weekStartsOn})
		// @ts-ignore
		const to_ts = endOfWeek(now, {weekStartsOn})
		this.setState({advance_pill: 'tw'})
		// call related handlers
		onFromDateUpdate(generateDatePickerOutput(
			from_ts.getDate(), from_ts.getMonth(), from_ts.getFullYear(), format
		))
		onToDateUpdate(generateDatePickerOutput(
			to_ts.getDate(), to_ts.getMonth(), to_ts.getFullYear(), format
		))
	}


() => {
		const {weekStartsOn, format,
			onFromDateUpdate, onToDateUpdate} = this.props
		const now = new Date()
		// @ts-ignore
		let from_ts = startOfWeek(now, {weekStartsOn})
		from_ts = subWeeks(from_ts, 1)
		// @ts-ignore
		let to_ts = endOfWeek(now, {weekStartsOn})
		to_ts = subWeeks(to_ts, 1)
		this.setState({advance_pill: 'lw'})
		// call related handlers
		onFromDateUpdate(generateDatePickerOutput(
			from_ts.getDate(), from_ts.getMonth(), from_ts.getFullYear(), format
		))
		onToDateUpdate(generateDatePickerOutput(
			to_ts.getDate(), to_ts.getMonth(), to_ts.getFullYear(), format
		))
	}


export default class DateRangeCalendarPicker extends React.Component<DateRangePickerProps, DateRangeCalendarPickerStates> {

	state = {
		// from date is selected as default
		is_to_date : false,
		// which advance pill is selected
		advance_pill : null,
	}

	static defaultProps = {
		from_date : defaultConfigs.date,
		to_date : defaultConfigs.date,
		weekStartsOn : dateDefaultConfigs.weekStartsOn,
		format : dateDefaultConfigs.format,
		closeButtonText: 'Close'
	}

	handleToDateUpdate = (date_time:DatePickerOutPut) => {
		const {onToDateUpdate} = this.props

		this.setState({advance_pill : null})
		onToDateUpdate(date_time)
	}

	handleFromDateUpdate = (date_time:DatePickerOutPut) => {
		const {onFromDateUpdate} = this.props

		this.setState({advance_pill : null})
		onFromDateUpdate(date_time)
	}

	render = () => {
		const {advance_pill} = this.state
		const {format, weekStartsOn,
			from_date, to_date,
			colors
		} = this.props

		const common_props = {format, weekStartsOn, otherDateRangeIndex: 0}

		return (
			<div className={styles.wrapper} style={{color: colors.primary_font_color}}


getActivePillColors(colors, advance_pill


field => {
                const crossFilteringField = {...field};
                crossFilteringField.colId = field.colId + '-filtered-out';
                fields.push(crossFilteringField);
            }


(map, series, i) => {
            const matchingIndex = seriesDefinitions.findIndex((s: any) =>
                s.xField.colId === series.xKey &&
                s.yField.colId === series.yKey &&
                ((!s.sizeField && !series.sizeKey) || (s.sizeField && s.sizeField.colId === series.sizeKey)));

            if (matchingIndex === i) {
                map.set(series.yKey, series);
            } else {
                chart.removeSeries(series);
            }

            return map;
        }


(s: any) =>
                s.xField.colId === series.xKey &&
                s.yField.colId === series.yKey &&
                ((!s.sizeField && !series.sizeKey) || (s.sizeField && s.sizeField.colId === series.sizeKey))


fill => {
                fillsMod.push(fill);
                fillsMod.push(hexToRGBA(fill, '0.3'));
            }


stroke => {
                strokesMod.push(stroke);
                strokesMod.push(hexToRGBA(stroke, '0.3'));
            }


(seriesDefinition, index) => {
            const existingSeries = existingSeriesById.get(seriesDefinition!.yField.colId);
            const series = existingSeries || AgChart.createComponent({
                ...seriesOverrides,
                type: 'scatter',
            }, 'scatter.series');

            if (!series) { return; }

            const {
                xField: xFieldDefinition,
                yField: yFieldDefinition,
                sizeField: sizeFieldDefinition
            } = seriesDefinition!;

            series.title = `${yFieldDefinition.displayName} vs ${xFieldDefinition.displayName}`;
            series.xKey = xFieldDefinition.colId;
            series.xName = xFieldDefinition.displayName;
            series.yKey = yFieldDefinition.colId;
            series.yName = yFieldDefinition.displayName;
            series.data = params.data;
            series.fill = fills[index % fills.length];
            series.stroke = strokes[index % strokes.length];

            if (sizeFieldDefinition) {
                series.sizeKey = sizeFieldDefinition.colId;
                series.sizeName = sizeFieldDefinition.displayName;
            } else {
                series.sizeKey = undefined;
            }

            if (labelFieldDefinition) {
                series.labelKey = labelFieldDefinition.id;
                series.labelName = labelFieldDefinition.name;
            } else {
                series.labelKey = series.yKey;
            }

            const isFilteredOutYKey =  yFieldDefinition.colId.indexOf('-filtered-out') > -1;
            if (this.crossFiltering) {

                if (!isFilteredOutYKey) {
                    // sync toggling of legend item with hidden 'filtered out' item
                    chart.legend.addEventListener('click', (event: LegendClickEvent) => {
                        series!.toggleSeriesItem(event.itemId + '-filtered-out', event.enabled);
                    });
                }

                if (dataDomain) {
                    series.marker.domain = dataDomain;
                }

                chart.tooltip.delay = 500;

                // hide 'filtered out' legend items
                if (isFilteredOutYKey) {
                    series!.showInLegend = false;
                }

                // add node click cross filtering callback to series
                series!.addEventListener('nodeClick', this.crossFilterCallback);
            }

            if (!existingSeries) {
                chart.addSeriesAfter(series, previousSeries);
            }

            previousSeries = series;
        }


(event: LegendClickEvent) => {
                        series!.toggleSeriesItem(event.itemId + '-filtered-out', event.enabled);
                    }


(currentXField, i) => i % 3 === 0 ? ({
                    xField: currentXField,
                    yField: fields[i + 1],
                    sizeField: fields[i + 2],
                }) : null


x => x && x.yField && x.sizeField


(currentXField, i) => i % 2 === 0 ? ({
                xField: currentXField,
                yField: fields[i + 1],
            }) : null


x => x && x.yField


(yField, i) => i % 2 === 1 ? ({
                    xField,
                    yField,
                    sizeField: fields[i + 1],
                }) : null


x => x && x.sizeField


(value, i) => i > 0


yField => ({ xField, yField })


d => {
                if (typeof d[sizeColId] !== 'undefined') {
                    allSizePoints.push(d[sizeColId]);
                }
                if (typeof d[sizeColId + '-filtered-out'] !== 'undefined') {
                    allSizePoints.push(d[sizeColId + '-filtered-out']);
                }
            }


interface SeriesDefinition {
    xField: FieldDefinition;
    yField: FieldDefinition;
    sizeField?: FieldDefinition;
}


protected createChart(): CartesianChart {
        return AgChart.create({
            type: 'scatter',
            container: this.chartProxyParams.parentElement,
            theme: this.chartTheme,
            axes: this.getAxes()
        });
    }


public update(params: UpdateChartParams): void {
        if (params.fields.length < 2) {
            this.chart.removeAllSeries();
            return;
        }

        let fields = params.fields;

        if (this.crossFiltering) {
            // add additional filtered out field
            fields.forEach(field => {
                const crossFilteringField = {...field};
                crossFilteringField.colId = field.colId + '-filtered-out';
                fields.push(crossFilteringField);
            });
        }

        const paired = this.chartOptions[this.standaloneChartType].paired;
        const seriesDefinitions = this.getSeriesDefinitions(fields, paired);

        let dataDomain: number[] | undefined;
        if (this.crossFiltering) {
            dataDomain = this.getCrossFilteringDataDomain(seriesDefinitions, params);
        }

        const { chart } = this;

        const existingSeriesById = (chart.series as ScatterSeries[]).reduceRight((map, series, i) => {
            const matchingIndex = seriesDefinitions.findIndex((s: any) =>
                s.xField.colId === series.xKey &&
                s.yField.colId === series.yKey &&
                ((!s.sizeField && !series.sizeKey) || (s.sizeField && s.sizeField.colId === series.sizeKey)));

            if (matchingIndex === i) {
                map.set(series.yKey, series);
            } else {
                chart.removeSeries(series);
            }

            return map;
        }, new Map<string, ScatterSeries>());

        let { fills, strokes } = this.chartTheme.palette;
        if (this.crossFiltering) {
            // introduce cross filtering transparent fills
            const fillsMod: string[] = [];
            fills.forEach(fill => {
                fillsMod.push(fill);
                fillsMod.push(hexToRGBA(fill, '0.3'));
            });
            fills = fillsMod;

            // introduce cross filtering transparent strokes
            const strokesMod: string[] = [];
            strokes.forEach(stroke => {
                strokesMod.push(stroke);
                strokesMod.push(hexToRGBA(stroke, '0.3'));
            });
            strokes = strokesMod;
        }

        const labelFieldDefinition = params.category.id === ChartDataModel.DEFAULT_CATEGORY ? undefined : params.category;
        let previousSeries: ScatterSeries | undefined;

        const seriesOverrides = this.chartOptions[this.standaloneChartType].series;
        seriesDefinitions.forEach((seriesDefinition, index) => {
            const existingSeries = existingSeriesById.get(seriesDefinition!.yField.colId);
            const series = existingSeries || AgChart.createComponent({
                ...seriesOverrides,
                type: 'scatter',
            }, 'scatter.series');

            if (!series) { return; }

            const {
                xField: xFieldDefinition,
                yField: yFieldDefinition,
                sizeField: sizeFieldDefinition
            } = seriesDefinition!;

            series.title = `${yFieldDefinition.displayName} vs ${xFieldDefinition.displayName}`;
            series.xKey = xFieldDefinition.colId;
            series.xName = xFieldDefinition.displayName;
            series.yKey = yFieldDefinition.colId;
            series.yName = yFieldDefinition.displayName;
            series.data = params.data;
            series.fill = fills[index % fills.length];
            series.stroke = strokes[index % strokes.length];

            if (sizeFieldDefinition) {
                series.sizeKey = sizeFieldDefinition.colId;
                series.sizeName = sizeFieldDefinition.displayName;
            } else {
                series.sizeKey = undefined;
            }

            if (labelFieldDefinition) {
                series.labelKey = labelFieldDefinition.id;
                series.labelName = labelFieldDefinition.name;
            } else {
                series.labelKey = series.yKey;
            }

            const isFilteredOutYKey =  yFieldDefinition.colId.indexOf('-filtered-out') > -1;
            if (this.crossFiltering) {

                if (!isFilteredOutYKey) {
                    // sync toggling of legend item with hidden 'filtered out' item
                    chart.legend.addEventListener('click', (event: LegendClickEvent) => {
                        series!.toggleSeriesItem(event.itemId + '-filtered-out', event.enabled);
                    });
                }

                if (dataDomain) {
                    series.marker.domain = dataDomain;
                }

                chart.tooltip.delay = 500;

                // hide 'filtered out' legend items
                if (isFilteredOutYKey) {
                    series!.showInLegend = false;
                }

                // add node click cross filtering callback to series
                series!.addEventListener('nodeClick', this.crossFilterCallback);
            }

            if (!existingSeries) {
                chart.addSeriesAfter(series, previousSeries);
            }

            previousSeries = series;
        });
    }


private getSeriesDefinitions(fields: FieldDefinition[], paired: boolean): (SeriesDefinition | null)[] {
        if (fields.length < 2) { return []; }

        const isBubbleChart = this.chartType === 'bubble';

        if (paired) {
            if (isBubbleChart) {
                return fields.map((currentXField, i) => i % 3 === 0 ? ({
                    xField: currentXField,
                    yField: fields[i + 1],
                    sizeField: fields[i + 2],
                }) : null).filter(x => x && x.yField && x.sizeField);
            }
            return fields.map((currentXField, i) => i % 2 === 0 ? ({
                xField: currentXField,
                yField: fields[i + 1],
            }) : null).filter(x => x && x.yField);
        }

        const xField = fields[0];

        if (isBubbleChart) {
            return fields
                .map((yField, i) => i % 2 === 1 ? ({
                    xField,
                    yField,
                    sizeField: fields[i + 1],
                }) : null)
                .filter(x => x && x.sizeField);
        }

        return fields.filter((value, i) => i > 0).map(yField => ({ xField, yField }));
    }


private getCrossFilteringDataDomain(seriesDefinitions: (SeriesDefinition | null)[], params: UpdateChartParams) {
        let domain;
        if (seriesDefinitions[0] && seriesDefinitions[0].sizeField) {
            const sizeColId = seriesDefinitions[0].sizeField!.colId;
            let allSizePoints: any[] = [];
            params.data.forEach(d => {
                if (typeof d[sizeColId] !== 'undefined') {
                    allSizePoints.push(d[sizeColId]);
                }
                if (typeof d[sizeColId + '-filtered-out'] !== 'undefined') {
                    allSizePoints.push(d[sizeColId + '-filtered-out']);
                }
            })
            if (allSizePoints.length > 0) {
                domain = [Math.min(...allSizePoints), Math.max(...allSizePoints)];
            }
        }
        return domain;
    }