@Injectable({
  providedIn: 'root'
})
export class DaffMagentoCategoryResponseTransformService implements DaffCategoryResponseTransformerInterface<DaffGetCategoryResponse> {

  constructor(
    @Inject(DaffCategoryTransformer) private magentoCategoryTransformerService: DaffCategoryTransformerInterface<DaffCategory>,
    private magentoCategoryPageConfigurationTransformerService: DaffMagentoCategoryPageConfigTransformerService,
    @Inject(DaffProductTransformer) private magentoProductTransformerService: DaffProductTransformerInterface<DaffProductUnion>
  ) {}

  transform(completeCategory: CompleteCategoryResponse): DaffGetCategoryResponse {
    return {
      category: this.magentoCategoryTransformerService.transform(completeCategory.category),
      categoryPageConfigurationState: this.magentoCategoryPageConfigurationTransformerService.transform(completeCategory.category, completeCategory.sortsAndFilters),
      products: this.magentoProductTransformerService.transformMany(completeCategory.category.products.items)
    }
  }
}


transform(completeCategory: CompleteCategoryResponse): DaffGetCategoryResponse {
    return {
      category: this.magentoCategoryTransformerService.transform(completeCategory.category),
      categoryPageConfigurationState: this.magentoCategoryPageConfigurationTransformerService.transform(completeCategory.category, completeCategory.sortsAndFilters),
      products: this.magentoProductTransformerService.transformMany(completeCategory.category.products.items)
    }
  }


declare class TypeScriptClassImpl {
	interface : boolean;
	deprecated : boolean;
	constructor(arg1 : ASTNode);
	constructor(arg1 : TypeScriptClassStub);
}


declare interface TypeScriptClassImpl extends TypeScriptClassBase<TypeScriptClassStub>, TypeScriptClass {}


() => {
	it("should render", () => {
		const { container } = render(<TransactionDetail label="Test">test</TransactionDetail>);

		expect(container).toMatchSnapshot();
	});

	it("should render without border", () => {
		const { container } = render(
			<TransactionDetail label="Test" border={false}>
				test
			</TransactionDetail>,
		);

		expect(container).toMatchSnapshot();
	});

	it.each(["top", "bottom"])("should render with %s border", (position) => {
		const { container } = render(
			<TransactionDetail label="Test" borderPosition={position}>
				test
			</TransactionDetail>,
		);

		expect(container).toMatchSnapshot();
	});

	it("should render without padding", () => {
		const { container } = render(
			<TransactionDetail label="Test" padding={false}>
				test
			</TransactionDetail>,
		);

		expect(container).toMatchSnapshot();
	});

	it("should render with extra children", () => {
		const { container, getByTestId } = render(
			<TransactionDetail label="Test" padding={false} extra={<div data-testid="TEST_CHILD" />}>
				test
			</TransactionDetail>,
		);

		expect(getByTestId("TEST_CHILD")).toBeInTheDocument();
		expect(container).toMatchSnapshot();
	}


() => {
		const { container } = render(<TransactionDetail label="Test">test</TransactionDetail>);

		expect(container).toMatchSnapshot();
	}


() => {
		const { container } = render(
			<TransactionDetail label="Test" border={false}>
				test
			</TransactionDetail>,
		);

		expect(container).toMatchSnapshot();
	}


(position) => {
		const { container } = render(
			<TransactionDetail label="Test" borderPosition={position}>
				test
			</TransactionDetail>,
		);

		expect(container).toMatchSnapshot();
	}


() => {
		const { container } = render(
			<TransactionDetail label="Test" padding={false}>
				test
			</TransactionDetail>,
		);

		expect(container).toMatchSnapshot();
	}


() => {
		const { container, getByTestId } = render(
			<TransactionDetail label="Test" padding={false} extra={<div data-testid="TEST_CHILD" />}


/////////////////////////////////////////////////////////////////////
// Reference file logic
////////////////////////////////////////////////////////////////////
// Updates the reference file
export function updateReferenceFile(files: string[], generatedFiles: string[], referenceFile: string, referencePath: string, eol: string): boolean {
    var referenceIntro = '/// <reference path="';
    var referenceEnd = '" />';
    var referenceMatch = /\/\/\/ <reference path=\"(.*?)\"/;
    var ourSignatureStart = '//grunt-start';
    var ourSignatureEnd = '//grunt-end';

    // remove the generated files from files:
    files = _.difference(files, generatedFiles);

    var lines = []; // All lines of the file
    var origFileLines = []; // The lines we do not modify and send out as is. Lines will we reach grunt-ts generated
    var origFileReferences = []; // The list of files already there that we do not need to manage

    // Location of our generated references
    // By default at start of file
    var signatureSectionPosition = 0;
    var i;

    // Read the original file if it exists
    var referenceContents = '';
    if (fs.existsSync(referenceFile)) {
        referenceContents = fs.readFileSync(referenceFile).toString();
        lines = referenceContents.split(/\r\n|\r|\n/);

        var inSignatureSection = false;

        // By default our signature goes at end of file
        signatureSectionPosition = lines.length;

        for (i = 0; i < lines.length; i++) {

            var line = _.trim(lines[i]);

            // Skip logic for our generated section
            if (_.includes(line, ourSignatureStart)) {
                // Wait for the end signature:
                signatureSectionPosition = i;
                inSignatureSection = true;
                continue;
            }
            if (_.includes(line, ourSignatureEnd)) {
                inSignatureSection = false;
                continue;
            }
            if (inSignatureSection) {
                continue;
            }

            // store the line
            origFileLines.push(line);

            // Fetch the existing reference's filename if any:
            if (_.includes(line, referenceIntro)) {
                var match = line.match(referenceMatch);
                var filename = match[1];
                origFileReferences.push(filename);
            }
        }
    }

    // Put in the generated files
    generatedFiles = _.map(generatedFiles, (file) => referenceIntro + utils.makeRelativePath(referencePath, file) + referenceEnd);
    var contents = utils.insertArrayAt([ourSignatureStart], 1, generatedFiles);

    // Put in the new / observed missing files:
    files.forEach((filename: string) => {
        // The file we are about to add
        var filepath = utils.makeRelativePath(referencePath, filename);

        // If there are orig references
        if (origFileReferences.length) {
            if (_.includes(origFileReferences, filepath)) {
                return;
            }
        }

        // Finally add the filepath
        contents.push(referenceIntro + filepath + referenceEnd);
    });
    contents.push(ourSignatureEnd);

    var updatedFileLines = utils.insertArrayAt(origFileLines, signatureSectionPosition, contents);
    var updatedFileContents = updatedFileLines.join(eol);

    // Modify the orig contents to put in our contents only if changed
    // Also Return whether the file was changed
    if (updatedFileContents !== referenceContents) {
        grunt.file.write(referenceFile, updatedFileContents);
        return true;
    }
    else {
        return false;
    }
}


(file) => referenceIntro + utils.makeRelativePath(referencePath, file) + referenceEnd


(filename: string) => {
        // The file we are about to add
        var filepath = utils.makeRelativePath(referencePath, filename);

        // If there are orig references
        if (origFileReferences.length) {
            if (_.includes(origFileReferences, filepath)) {
                return;
            }
        }

        // Finally add the filepath
        contents.push(referenceIntro + filepath + referenceEnd);
    }


export class HookData {
  table: Table
  pageNumber: number
  settings: any
  doc: any
  cursor: { x: number; y: number }

  get pageCount() {
    return this.pageNumber
  }

  constructor() {
    let table = state().table
    this.table = table
    this.pageNumber = table.pageNumber
    this.settings = table.settings
    this.cursor = table.cursor
    this.doc = state().doc
  }
}


export class CellHookData extends HookData {
  cell: Cell
  row: Row
  column: Column
  section: 'head' | 'body' | 'foot'

  constructor(cell: Cell, row: Row, column: Column) {
    super()

    this.cell = cell
    this.row = row
    this.column = column
    this.section = row.section
  }
}


function handleDisplacement(event) {
  for (let [objId, nativeAd] of nativeViews) {
    const nativeRect = nativeAd.element.getBoundingClientRect()

    if (nativeAd.props.x === nativeRect.x && nativeAd.props.y === nativeRect.y)
      continue

    nativeAd.props.x = nativeRect.x
    nativeAd.props.y = nativeRect.y

    nativeAd.setProps(nativeAd.props)
  }
}


export class NativeAlreadyDefinedError extends Error {
  public NativeAlreadyDefinedError() {
    this.name = "NativeAlreadyDefinedError"
    this.message = "Native object with the id specified already defined"
  }
}


export class Native extends Ads {

  public element: HTMLElement
  public props: NativeAdProps

  constructor() {
    super(Native.name.toLowerCase())
    this.props = {} as NativeAdProps
  }

  on(eventName: NativeAdEvents, handler: () => void): void {
    super.on(eventName, handler);
  }

  private beforeCreateHook(options: NativeAdOptions): void {
    const elementId: string = options.div;

    if (nativeViews.has(elementId))
      throw new NativeAlreadyDefinedError()

    this.element = document.getElementById(elementId)
    this.props = this.refreshProps()
    console.log(`Props: ${JSON.stringify(this.props)}`);

    const mutationObserver = new MutationObserver(this.handleMutation);
    mutationObserver.observe(this.element, { attributes: true })
    nativeViews.set(elementId, this)

  }

  async create(options: NativeAdOptions): Promise<Native> {
    if (this.id != null)
      return this

    this.beforeCreateHook(options);

    const result = await asyncExec('HMSAds', 'createAd', [this.objectName, options])
    this.id = result.id
    return this
  }

  private refreshProps(): NativeAdProps {
    const elementRect = this.element.getBoundingClientRect()
    const elementStyle = window.getComputedStyle(this.element, null)

    this.props.x = elementRect.x;
    this.props.y = elementRect.y;
    this.props.width = elementRect.width;
    this.props.height = elementRect.height;
    this.props.paddingLeft = parseInt(elementStyle.getPropertyValue("padding-left"));
    this.props.paddingTop = parseInt(elementStyle.getPropertyValue("padding-top"));
    this.props.borderLeft = parseInt(elementStyle.getPropertyValue("border-left-width"));
    this.props.borderTop = parseInt(elementStyle.getPropertyValue("border-top-width"));

    return this.props
  }

  private handleMutation() {
    this.setProps(this.refreshProps())
  }

  // Call this function, from ionic application for scroll events
  scroll(): Promise<void>{
    const nativeRect = this.element.getBoundingClientRect()

    if (this.props.x === nativeRect.x && this.props.y === nativeRect.y)
      return;

    return this.setProps(this.refreshProps())
  }

  loadAd(params: NativeAdLoadOptions): Promise<void> {
    return this.call('loadAd', params)
  }
  isLoaded(): Promise<IsLoadedResult> {
    return this.call('isLoaded')
  }
  isLoading(): Promise<IsLoadingResult> {
    return this.call('isLoading')
  }
  show(): Promise<void> {
    return this.call('show', this.refreshProps())
  }
  destroy(): Promise<void> {
    nativeViews.delete(this.element.id)
    return this.call('destroy')
  }
  setProps(props?: NativeAdProps): Promise<void> {
    return this.call('setProps', props)
  }

}


public NativeAlreadyDefinedError() {
    this.name = "NativeAlreadyDefinedError"
    this.message = "Native object with the id specified already defined"
  }


on(eventName: NativeAdEvents, handler: () => void): void {
    super.on(eventName, handler);
  }


private beforeCreateHook(options: NativeAdOptions): void {
    const elementId: string = options.div;

    if (nativeViews.has(elementId))
      throw new NativeAlreadyDefinedError()

    this.element = document.getElementById(elementId)
    this.props = this.refreshProps()
    console.log(`Props: ${JSON.stringify(this.props)}`);

    const mutationObserver = new MutationObserver(this.handleMutation);
    mutationObserver.observe(this.element, { attributes: true })
    nativeViews.set(elementId, this)

  }


async create(options: NativeAdOptions): Promise<Native> {
    if (this.id != null)
      return this

    this.beforeCreateHook(options);

    const result = await asyncExec('HMSAds', 'createAd', [this.objectName, options])
    this.id = result.id
    return this
  }


private refreshProps(): NativeAdProps {
    const elementRect = this.element.getBoundingClientRect()
    const elementStyle = window.getComputedStyle(this.element, null)

    this.props.x = elementRect.x;
    this.props.y = elementRect.y;
    this.props.width = elementRect.width;
    this.props.height = elementRect.height;
    this.props.paddingLeft = parseInt(elementStyle.getPropertyValue("padding-left"));
    this.props.paddingTop = parseInt(elementStyle.getPropertyValue("padding-top"));
    this.props.borderLeft = parseInt(elementStyle.getPropertyValue("border-left-width"));
    this.props.borderTop = parseInt(elementStyle.getPropertyValue("border-top-width"));

    return this.props
  }


private handleMutation() {
    this.setProps(this.refreshProps())
  }


// Call this function, from ionic application for scroll events
scroll(): Promise<void>{
    const nativeRect = this.element.getBoundingClientRect()

    if (this.props.x === nativeRect.x && this.props.y === nativeRect.y)
      return;

    return this.setProps(this.refreshProps())
  }


loadAd(params: NativeAdLoadOptions): Promise<void> {
    return this.call('loadAd', params)
  }


isLoaded(): Promise<IsLoadedResult> {
    return this.call('isLoaded')
  }


isLoading(): Promise<IsLoadingResult> {
    return this.call('isLoading')
  }


show(): Promise<void> {
    return this.call('show', this.refreshProps())
  }


destroy(): Promise<void> {
    nativeViews.delete(this.element.id)
    return this.call('destroy')
  }


setProps(props?: NativeAdProps): Promise<void> {
    return this.call('setProps', props)
  }


(obj, ret) => {
        delete ret._id, delete ret.__v
      }


export function annotationQueryFields() {
    const fields = DEFAULT_ANNOTATION_QUERY_FIELDS;
    if (SHOW_MUTATION_ASSESSOR) {
        fields.push('mutation_assessor');
    }
    return fields;
}


({ query: _getContentQuery }: Request, res: Response) => {
            const getContentQuery: GetContentQuery = plainToClass(GetContentQuery, _getContentQuery);
            validate(getContentQuery).then(validationErrors => {
                const [ validationError ] = validationErrors;
                if (validationError) {
                    const { constraints } = validationError;
                    res.send(responseService.BadRequest(JSON.stringify(constraints)));
                    return;
                };

                const { page } = getContentQuery;
                contentRepository.find({ where: { page } }).then(result => {
                    res.send(responseService.Success(result));
                }).catch(error => {
                    res.send(responseService.InternalServerError(JSON.stringify(error)));
                })
            }).catch(error => {
                res.send(responseService.InternalServerError(JSON.stringify(error)));
            })
        }


validationErrors => {
                const [ validationError ] = validationErrors;
                if (validationError) {
                    const { constraints } = validationError;
                    res.send(responseService.BadRequest(JSON.stringify(constraints)));
                    return;
                };

                const { page } = getContentQuery;
                contentRepository.find({ where: { page } }).then(result => {
                    res.send(responseService.Success(result));
                }).catch(error => {
                    res.send(responseService.InternalServerError(JSON.stringify(error)));
                })
            }


result => {
                    res.send(responseService.Success(result));
                }


error => {
                    res.send(responseService.InternalServerError(JSON.stringify(error)));
                }


error => {
                res.send(responseService.InternalServerError(JSON.stringify(error)));
            }


({ body: _createContentInput }: Request, res: Response) => {
            const createContentInput: CreateContentInput = plainToClass(CreateContentInput, _createContentInput);
            validate(createContentInput).then(validationErrors => {
                const [ validationError ] = validationErrors;
                if (validationError) {
                    const { constraints } = validationError;
                    res.send(responseService.BadRequest(JSON.stringify(constraints)));
                    return;
                };

                const page = createContentInput.page.id;
                contentRepository.find({ where: { page } }).then(result => {
                    const { seq, seqBase } = getNextSequence(result);
                    createContentInput.seq = seq;
                    createContentInput.seqBase = seqBase;
                    return contentRepository.save(createContentInput);
                }).then(result => {
                    const { id } = result;
                    res.send(responseService.Success(id));
                }).catch(error => {
                    res.send(responseService.InternalServerError(JSON.stringify(error)));
                })
            }).catch(error => {
                res.send(responseService.InternalServerError(JSON.stringify(error)));
            })
        }


validationErrors => {
                const [ validationError ] = validationErrors;
                if (validationError) {
                    const { constraints } = validationError;
                    res.send(responseService.BadRequest(JSON.stringify(constraints)));
                    return;
                };

                const page = createContentInput.page.id;
                contentRepository.find({ where: { page } }).then(result => {
                    const { seq, seqBase } = getNextSequence(result);
                    createContentInput.seq = seq;
                    createContentInput.seqBase = seqBase;
                    return contentRepository.save(createContentInput);
                }).then(result => {
                    const { id } = result;
                    res.send(responseService.Success(id));
                }).catch(error => {
                    res.send(responseService.InternalServerError(JSON.stringify(error)));
                })
            }


result => {
                    const { seq, seqBase } = getNextSequence(result);
                    createContentInput.seq = seq;
                    createContentInput.seqBase = seqBase;
                    return contentRepository.save(createContentInput);
                }


result => {
                    const { id } = result;
                    res.send(responseService.Success(id));
                }


({ body: updateContentInput, params: { id } }: Request, res: Response) => {
            contentRepository.update({ id }, updateContentInput).then(_ => {
                res.send(responseService.Success(true));
            }).catch(error => {
                res.send(responseService.InternalServerError(JSON.stringify(error)));
            });
        }


_ => {
                res.send(responseService.Success(true));
            }


({ params: { id } }: Request, res: Response) => {
            contentRepository.delete({ id }).then(_ => {
                res.send(responseService.Success(true));
            }).catch(error => {
                res.send(responseService.InternalServerError(JSON.stringify(error)));
            });
        }


({ params: { id } }: Request, res: Response) => {
            let target;
            contentRepository.findOne(id).then(result => {
                const { page } = result;
                target = result;
                return contentRepository.find({ where: { page } });
            }).then(result => {
                const nextSequence = getUpSequence(result, target);
                return contentRepository.update({ id }, nextSequence);
            }).then(_ => {
                res.send(responseService.Success(true));
            }).catch(error => {
                res.send(responseService.InternalServerError(JSON.stringify(error)));
            });
        }


result => {
                const { page } = result;
                target = result;
                return contentRepository.find({ where: { page } });
            }


result => {
                const nextSequence = getUpSequence(result, target);
                return contentRepository.update({ id }, nextSequence);
            }


({ params: { id } }: Request, res: Response) => {
            let target;
            contentRepository.findOne(id).then(result => {
                const { page } = result;
                target = result;
                return contentRepository.find({ where: { page } });
            }).then(result => {
                const nextSequence = getDownSequence(result, target);
                return contentRepository.update({ id }, nextSequence);
            }).then(_ => {
                res.send(responseService.Success(true));
            }).catch(error => {
                res.send(responseService.InternalServerError(JSON.stringify(error)));
            });
        }


result => {
                const nextSequence = getDownSequence(result, target);
                return contentRepository.update({ id }, nextSequence);
            }


export class ContentService {
    constructor(
        private contentRepository: Repository<Content>,
        private responseService: ResponseService
    ) { }

    list(): ControllerFn {
        const responseService = this.responseService;
        const contentRepository = this.contentRepository;

        return ({ query: _getContentQuery }: Request, res: Response) => {
            const getContentQuery: GetContentQuery = plainToClass(GetContentQuery, _getContentQuery);
            validate(getContentQuery).then(validationErrors => {
                const [ validationError ] = validationErrors;
                if (validationError) {
                    const { constraints } = validationError;
                    res.send(responseService.BadRequest(JSON.stringify(constraints)));
                    return;
                };

                const { page } = getContentQuery;
                contentRepository.find({ where: { page } }).then(result => {
                    res.send(responseService.Success(result));
                }).catch(error => {
                    res.send(responseService.InternalServerError(JSON.stringify(error)));
                })
            }).catch(error => {
                res.send(responseService.InternalServerError(JSON.stringify(error)));
            })
        }
    }

    create(): ControllerFn {
        const responseService = this.responseService;
        const contentRepository = this.contentRepository;

        return ({ body: _createContentInput }: Request, res: Response) => {
            const createContentInput: CreateContentInput = plainToClass(CreateContentInput, _createContentInput);
            validate(createContentInput).then(validationErrors => {
                const [ validationError ] = validationErrors;
                if (validationError) {
                    const { constraints } = validationError;
                    res.send(responseService.BadRequest(JSON.stringify(constraints)));
                    return;
                };

                const page = createContentInput.page.id;
                contentRepository.find({ where: { page } }).then(result => {
                    const { seq, seqBase } = getNextSequence(result);
                    createContentInput.seq = seq;
                    createContentInput.seqBase = seqBase;
                    return contentRepository.save(createContentInput);
                }).then(result => {
                    const { id } = result;
                    res.send(responseService.Success(id));
                }).catch(error => {
                    res.send(responseService.InternalServerError(JSON.stringify(error)));
                })
            }).catch(error => {
                res.send(responseService.InternalServerError(JSON.stringify(error)));
            })
        }
    }

    update(): ControllerFn {
        const responseService = this.responseService;
        const contentRepository = this.contentRepository;

        return ({ body: updateContentInput, params: { id } }: Request, res: Response) => {
            contentRepository.update({ id }, updateContentInput).then(_ => {
                res.send(responseService.Success(true));
            }).catch(error => {
                res.send(responseService.InternalServerError(JSON.stringify(error)));
            });
        }
    }

    delete(): ControllerFn {
        const responseService = this.responseService;
        const contentRepository = this.contentRepository;

        return ({ params: { id } }: Request, res: Response) => {
            contentRepository.delete({ id }).then(_ => {
                res.send(responseService.Success(true));
            }).catch(error => {
                res.send(responseService.InternalServerError(JSON.stringify(error)));
            });
        }
    }

    upSeq(): ControllerFn {
        const responseService = this.responseService;
        const contentRepository = this.contentRepository;

        return ({ params: { id } }: Request, res: Response) => {
            let target;
            contentRepository.findOne(id).then(result => {
                const { page } = result;
                target = result;
                return contentRepository.find({ where: { page } });
            }).then(result => {
                const nextSequence = getUpSequence(result, target);
                return contentRepository.update({ id }, nextSequence);
            }).then(_ => {
                res.send(responseService.Success(true));
            }).catch(error => {
                res.send(responseService.InternalServerError(JSON.stringify(error)));
            });
        }
    }

    downSeq(): ControllerFn {
        const responseService = this.responseService;
        const contentRepository = this.contentRepository;

        return ({ params: { id } }: Request, res: Response) => {
            let target;
            contentRepository.findOne(id).then(result => {
                const { page } = result;
                target = result;
                return contentRepository.find({ where: { page } });
            }).then(result => {
                const nextSequence = getDownSequence(result, target);
                return contentRepository.update({ id }, nextSequence);
            }).then(_ => {
                res.send(responseService.Success(true));
            }).catch(error => {
                res.send(responseService.InternalServerError(JSON.stringify(error)));
            });
        }
    }
}


list(): ControllerFn {
        const responseService = this.responseService;
        const contentRepository = this.contentRepository;

        return ({ query: _getContentQuery }: Request, res: Response) => {
            const getContentQuery: GetContentQuery = plainToClass(GetContentQuery, _getContentQuery);
            validate(getContentQuery).then(validationErrors => {
                const [ validationError ] = validationErrors;
                if (validationError) {
                    const { constraints } = validationError;
                    res.send(responseService.BadRequest(JSON.stringify(constraints)));
                    return;
                };

                const { page } = getContentQuery;
                contentRepository.find({ where: { page } }).then(result => {
                    res.send(responseService.Success(result));
                }).catch(error => {
                    res.send(responseService.InternalServerError(JSON.stringify(error)));
                })
            }).catch(error => {
                res.send(responseService.InternalServerError(JSON.stringify(error)));
            })
        }
    }


create(): ControllerFn {
        const responseService = this.responseService;
        const contentRepository = this.contentRepository;

        return ({ body: _createContentInput }: Request, res: Response) => {
            const createContentInput: CreateContentInput = plainToClass(CreateContentInput, _createContentInput);
            validate(createContentInput).then(validationErrors => {
                const [ validationError ] = validationErrors;
                if (validationError) {
                    const { constraints } = validationError;
                    res.send(responseService.BadRequest(JSON.stringify(constraints)));
                    return;
                };

                const page = createContentInput.page.id;
                contentRepository.find({ where: { page } }).then(result => {
                    const { seq, seqBase } = getNextSequence(result);
                    createContentInput.seq = seq;
                    createContentInput.seqBase = seqBase;
                    return contentRepository.save(createContentInput);
                }).then(result => {
                    const { id } = result;
                    res.send(responseService.Success(id));
                }).catch(error => {
                    res.send(responseService.InternalServerError(JSON.stringify(error)));
                })
            }).catch(error => {
                res.send(responseService.InternalServerError(JSON.stringify(error)));
            })
        }
    }


update(): ControllerFn {
        const responseService = this.responseService;
        const contentRepository = this.contentRepository;

        return ({ body: updateContentInput, params: { id } }: Request, res: Response) => {
            contentRepository.update({ id }, updateContentInput).then(_ => {
                res.send(responseService.Success(true));
            }).catch(error => {
                res.send(responseService.InternalServerError(JSON.stringify(error)));
            });
        }
    }


delete(): ControllerFn {
        const responseService = this.responseService;
        const contentRepository = this.contentRepository;

        return ({ params: { id } }: Request, res: Response) => {
            contentRepository.delete({ id }).then(_ => {
                res.send(responseService.Success(true));
            }).catch(error => {
                res.send(responseService.InternalServerError(JSON.stringify(error)));
            });
        }
    }


upSeq(): ControllerFn {
        const responseService = this.responseService;
        const contentRepository = this.contentRepository;

        return ({ params: { id } }: Request, res: Response) => {
            let target;
            contentRepository.findOne(id).then(result => {
                const { page } = result;
                target = result;
                return contentRepository.find({ where: { page } });
            }).then(result => {
                const nextSequence = getUpSequence(result, target);
                return contentRepository.update({ id }, nextSequence);
            }).then(_ => {
                res.send(responseService.Success(true));
            }).catch(error => {
                res.send(responseService.InternalServerError(JSON.stringify(error)));
            });
        }
    }


downSeq(): ControllerFn {
        const responseService = this.responseService;
        const contentRepository = this.contentRepository;

        return ({ params: { id } }: Request, res: Response) => {
            let target;
            contentRepository.findOne(id).then(result => {
                const { page } = result;
                target = result;
                return contentRepository.find({ where: { page } });
            }).then(result => {
                const nextSequence = getDownSequence(result, target);
                return contentRepository.update({ id }, nextSequence);
            }).then(_ => {
                res.send(responseService.Success(true));
            }).catch(error => {
                res.send(responseService.InternalServerError(JSON.stringify(error)));
            });
        }
    }


@NgModule({
    declarations: [
        DialogSampleComponent
    ],
    imports: [
        IgxComponentsModule,
        IgxDirectivesModule,
        PageHeaderModule
    ]
})
export class DialogSampleModule { }


export enum SortType{
    ASC = 'asc',
    DESC = 'desc'
}


@Component({
    moduleId: module.id,
    selector: "license-section",
    templateUrl: "license-section.component.html",
    encapsulation: ViewEncapsulation.None,
    changeDetection: ChangeDetectionStrategy.OnPush
})
export class LicenseSectionComponent extends AbstractBaseComponent {

    @Input() document: OasDocument;

    constructor(private changeDetectorRef: ChangeDetectorRef, private documentService: DocumentService,
                private commandService: CommandService, public licenseService: LicenseService,
                private selectionService: SelectionService) {
        super(changeDetectorRef, documentService, selectionService);
    }

    /**
     * Returns true if a license has been configured for this API.
     */
    public hasLicense(): boolean {
        if (this.document.info && this.document.info.license) {
            return true;
        }
        return false;
    }

    /**
     * Returns the resolved license or null if not found.
     */
    public license(): ILicense {
        return this.licenseService.findLicense(this.licenseUrl());
    }

    /**
     * Returns the license model.
     */
    public licenseModel(): OasLicense {
        if (this.document.info && this.document.info.license) {
            return this.document.info.license;
        } else {
            return null;
        }
    }

    /**
     * returns the license name.
     */
    public licenseName(): string {
        if (this.document.info && this.document.info.license) {
            return this.document.info.license.name;
        } else {
            return "";
        }
    }

    /**
     * returns the license url.
     */
    public licenseUrl(): string {
        if (this.document.info && this.document.info.license) {
            return this.document.info.license.url;
        } else {
            return "";
        }
    }

    /**
     * Called when the user chooses a new license in the Choose License dialog.
     * @param licenseInfo
     */
    public setLicense(licenseInfo: any): void {
        let command: ICommand = CommandFactory.createChangeLicenseCommand(licenseInfo.name, licenseInfo.url);
        this.commandService.emit(command);
        let path = Library.createNodePath(this.document);
        path.appendSegment("info", false);
        path.appendSegment("license", false);
        this.selectionService.select(path.toString());
    }

    /**
     * Called when the user chooses to remove the license.
     */
    public deleteLicense(): void {
        let command: ICommand = CommandFactory.createDeleteLicenseCommand(this.document.info);
        this.commandService.emit(command);
    }

}


/**
     * Returns true if a license has been configured for this API.
     */
public hasLicense(): boolean {
        if (this.document.info && this.document.info.license) {
            return true;
        }
        return false;
    }


/**
     * Returns the resolved license or null if not found.
     */
public license(): ILicense {
        return this.licenseService.findLicense(this.licenseUrl());
    }


/**
     * Returns the license model.
     */
public licenseModel(): OasLicense {
        if (this.document.info && this.document.info.license) {
            return this.document.info.license;
        } else {
            return null;
        }
    }


/**
     * returns the license name.
     */
public licenseName(): string {
        if (this.document.info && this.document.info.license) {
            return this.document.info.license.name;
        } else {
            return "";
        }
    }


/**
     * returns the license url.
     */
public licenseUrl(): string {
        if (this.document.info && this.document.info.license) {
            return this.document.info.license.url;
        } else {
            return "";
        }
    }


/**
     * Called when the user chooses a new license in the Choose License dialog.
     * @param licenseInfo
     */
public setLicense(licenseInfo: any): void {
        let command: ICommand = CommandFactory.createChangeLicenseCommand(licenseInfo.name, licenseInfo.url);
        this.commandService.emit(command);
        let path = Library.createNodePath(this.document);
        path.appendSegment("info", false);
        path.appendSegment("license", false);
        this.selectionService.select(path.toString());
    }


/**
     * Called when the user chooses to remove the license.
     */
public deleteLicense(): void {
        let command: ICommand = CommandFactory.createDeleteLicenseCommand(this.document.info);
        this.commandService.emit(command);
    }


(doi: string) =>
  'https://doi.org/' + encodeURIComponent(doi.replace(/^.*?(10\.)/, '$1'))


(url: string, contents: string): Element => {
  const element = document.createElement('a')
  element.setAttribute('href', url)
  element.innerHTML = contents // IMPORTANT: this is HTML so must be sanitised later

  return element
}


(contents: string): Element => {
  const element = document.createElement('span')
  element.innerHTML = contents // IMPORTANT: this is HTML so must be sanitised later

  return element
}


(
  field: string,
  itemData: CSL.Data,
  str: string
): Element => {
  switch (field) {
    case 'title': {
      if (itemData.DOI) {
        return createLink(createDoiUrl(itemData.DOI), str)
      }

      if (itemData.URL) {
        return createLink(itemData.URL, str)
      }

      return createSpan(str)
    }

    case 'URL':
      return createLink(str, str)

    case 'DOI':
      return createLink(createDoiUrl(str), str)

    default:
      return createSpan(str)
  }
}


(
  params,
  prePunct,
  str,
  postPunct
) => {
  if (params.context === 'bibliography') {
    const fields = params.variableNames.join(' ')

    const element = wrapVariable(fields, params.itemData, str)

    element.setAttribute('data-field', fields)

    return `${prePunct}${element.outerHTML}${postPunct}`
  }

  return `${prePunct}${str}${postPunct}`
}


(standard: systemlokalitet)


(standard: 8333 eller testnetværk: 18333)


(standard: 8332 eller testnetværk: 18332)


(standard: 127.0.0.1)


(standard: 100)


(value, key) => {
			let uri = URI.parse(key);
			callback.apply(thisArg, [uri, this.get(uri), this]);
		}


collection => {
				collection.forEach((uri, diagnostics) => {
					let idx = index.get(uri.toString());
					if (typeof idx === 'undefined') {
						idx = res.length;
						index.set(uri.toString(), idx);
						res.push([uri, []]);
					}
					res[idx][1] = res[idx][1].concat(...diagnostics);
				});
			}


(uri, diagnostics) => {
					let idx = index.get(uri.toString());
					if (typeof idx === 'undefined') {
						idx = res.length;
						index.set(uri.toString(), idx);
						res.push([uri, []]);
					}
					res[idx][1] = res[idx][1].concat(...diagnostics);
				}


collection => {
			if (collection.has(resource)) {
				res = res.concat(collection.get(resource));
			}
		}


export class DiagnosticCollection implements vscode.DiagnosticCollection {

	private readonly _name: string;
	private readonly _owner: string;
	private readonly _maxDiagnosticsPerFile: number;
	private readonly _onDidChangeDiagnostics: Emitter<(vscode.Uri | string)[]>;
	private readonly _proxy: MainThreadDiagnosticsShape;

	private _isDisposed = false;
	private _data = new Map<string, vscode.Diagnostic[]>();

	constructor(name: string, owner: string, maxDiagnosticsPerFile: number, proxy: MainThreadDiagnosticsShape, onDidChangeDiagnostics: Emitter<(vscode.Uri | string)[]>) {
		this._name = name;
		this._owner = owner;
		this._maxDiagnosticsPerFile = maxDiagnosticsPerFile;
		this._proxy = proxy;
		this._onDidChangeDiagnostics = onDidChangeDiagnostics;
	}

	dispose(): void {
		if (!this._isDisposed) {
			this._onDidChangeDiagnostics.fire(keys(this._data));
			this._proxy.$clear(this._owner);
			this._data = undefined;
			this._isDisposed = true;
		}
	}

	get name(): string {
		this._checkDisposed();
		return this._name;
	}

	set(uri: vscode.Uri, diagnostics: vscode.Diagnostic[]): void;
	set(entries: [vscode.Uri, vscode.Diagnostic[]][]): void;
	set(first: vscode.Uri | [vscode.Uri, vscode.Diagnostic[]][], diagnostics?: vscode.Diagnostic[]) {

		if (!first) {
			// this set-call is a clear-call
			this.clear();
			return;
		}

		// the actual implementation for #set

		this._checkDisposed();
		let toSync: vscode.Uri[] = [];
		let hasChanged = true;

		if (first instanceof URI) {

			// check if this has actually changed
			hasChanged = hasChanged && !equals(diagnostics, this.get(first), Diagnostic.isEqual);

			if (!diagnostics) {
				// remove this entry
				this.delete(first);
				return;
			}

			// update single row
			this._data.set(first.toString(), diagnostics.slice());
			toSync = [first];

		} else if (Array.isArray(first)) {
			// update many rows
			toSync = [];
			let lastUri: vscode.Uri | undefined;

			// ensure stable-sort
			mergeSort(first, DiagnosticCollection._compareIndexedTuplesByUri);

			for (const tuple of first) {
				const [uri, diagnostics] = tuple;
				if (!lastUri || uri.toString() !== lastUri.toString()) {
					if (lastUri && this._data.get(lastUri.toString()).length === 0) {
						this._data.delete(lastUri.toString());
					}
					lastUri = uri;
					toSync.push(uri);
					this._data.set(uri.toString(), []);
				}

				if (!diagnostics) {
					// [Uri, undefined] means clear this
					this._data.get(uri.toString()).length = 0;
				} else {
					this._data.get(uri.toString()).push(...diagnostics);
				}
			}
		}

		// send event for extensions
		this._onDidChangeDiagnostics.fire(toSync);

		// if nothing has changed then there is nothing else to do
		// we have updated the diagnostics but we don't send a message
		// to the renderer. tho we have still send an event for other
		// extensions because the diagnostic might carry more information
		// than known to us
		if (!hasChanged) {
			return;
		}
		// compute change and send to main side
		const entries: [URI, IMarkerData[]][] = [];
		for (let uri of toSync) {
			let marker: IMarkerData[] | undefined;
			let diagnostics = this._data.get(uri.toString());
			if (diagnostics) {

				// no more than N diagnostics per file
				if (diagnostics.length > this._maxDiagnosticsPerFile) {
					marker = [];
					const order = [DiagnosticSeverity.Error, DiagnosticSeverity.Warning, DiagnosticSeverity.Information, DiagnosticSeverity.Hint];
					orderLoop: for (let i = 0; i < 4; i++) {
						for (let diagnostic of diagnostics) {
							if (diagnostic.severity === order[i]) {
								const len = marker.push(converter.Diagnostic.from(diagnostic));
								if (len === this._maxDiagnosticsPerFile) {
									break orderLoop;
								}
							}
						}
					}

					// add 'signal' marker for showing omitted errors/warnings
					marker.push({
						severity: MarkerSeverity.Info,
						message: localize({ key: 'limitHit', comment: ['amount of errors/warning skipped due to limits'] }, "Not showing {0} further errors and warnings.", diagnostics.length - this._maxDiagnosticsPerFile),
						startLineNumber: marker[marker.length - 1].startLineNumber,
						startColumn: marker[marker.length - 1].startColumn,
						endLineNumber: marker[marker.length - 1].endLineNumber,
						endColumn: marker[marker.length - 1].endColumn
					});
				} else {
					marker = diagnostics.map(converter.Diagnostic.from);
				}
			}

			entries.push([uri, marker]);
		}

		this._proxy.$changeMany(this._owner, entries);
	}

	delete(uri: vscode.Uri): void {
		this._checkDisposed();
		this._onDidChangeDiagnostics.fire([uri]);
		this._data.delete(uri.toString());
		this._proxy.$changeMany(this._owner, [[uri, undefined]]);
	}

	clear(): void {
		this._checkDisposed();
		this._onDidChangeDiagnostics.fire(keys(this._data));
		this._data.clear();
		this._proxy.$clear(this._owner);
	}

	forEach(callback: (uri: URI, diagnostics: vscode.Diagnostic[], collection: DiagnosticCollection) => any, thisArg?: any): void {
		this._checkDisposed();
		this._data.forEach((value, key) => {
			let uri = URI.parse(key);
			callback.apply(thisArg, [uri, this.get(uri), this]);
		});
	}

	get(uri: URI): vscode.Diagnostic[] {
		this._checkDisposed();
		let result = this._data.get(uri.toString());
		if (Array.isArray(result)) {
			return <vscode.Diagnostic[]>Object.freeze(result.slice(0));
		}
		return undefined;
	}

	has(uri: URI): boolean {
		this._checkDisposed();
		return Array.isArray(this._data.get(uri.toString()));
	}

	private _checkDisposed() {
		if (this._isDisposed) {
			throw new Error('illegal state - object is disposed');
		}
	}

	private static _compareIndexedTuplesByUri(a: [vscode.Uri, vscode.Diagnostic[]], b: [vscode.Uri, vscode.Diagnostic[]]): number {
		if (a[0].toString() < b[0].toString()) {
			return -1;
		} else if (a[0].toString() > b[0].toString()) {
			return 1;
		} else {
			return 0;
		}
	}
}


export class ExtHostDiagnostics implements ExtHostDiagnosticsShape {

	private static _idPool: number = 0;
	private static readonly _maxDiagnosticsPerFile: number = 1000;

	private readonly _proxy: MainThreadDiagnosticsShape;
	private readonly _collections = new Map<string, DiagnosticCollection>();
	private readonly _onDidChangeDiagnostics = new Emitter<(vscode.Uri | string)[]>();

	static _debouncer(last: (vscode.Uri | string)[], current: (vscode.Uri | string)[]): (vscode.Uri | string)[] {
		if (!last) {
			return current;
		} else {
			return last.concat(current);
		}
	}

	static _mapper(last: (vscode.Uri | string)[]): { uris: vscode.Uri[] } {
		let uris: vscode.Uri[] = [];
		let map = new Set<string>();
		for (const uri of last) {
			if (typeof uri === 'string') {
				if (!map.has(uri)) {
					map.add(uri);
					uris.push(URI.parse(uri));
				}
			} else {
				if (!map.has(uri.toString())) {
					map.add(uri.toString());
					uris.push(uri);
				}
			}
		}
		Object.freeze(uris);
		return { uris };
	}

	readonly onDidChangeDiagnostics: Event<vscode.DiagnosticChangeEvent> = Event.map(Event.debounce(this._onDidChangeDiagnostics.event, ExtHostDiagnostics._debouncer, 50), ExtHostDiagnostics._mapper);

	constructor(mainContext: IMainContext) {
		this._proxy = mainContext.getProxy(MainContext.MainThreadDiagnostics);
	}

	createDiagnosticCollection(name?: string): vscode.DiagnosticCollection {
		let { _collections, _proxy, _onDidChangeDiagnostics } = this;
		let owner: string;
		if (!name) {
			name = '_generated_diagnostic_collection_name_#' + ExtHostDiagnostics._idPool++;
			owner = name;
		} else if (!_collections.has(name)) {
			owner = name;
		} else {
			console.warn(`DiagnosticCollection with name '${name}' does already exist.`);
			do {
				owner = name + ExtHostDiagnostics._idPool++;
			} while (_collections.has(owner));
		}

		const result = new class extends DiagnosticCollection {
			constructor() {
				super(name!, owner, ExtHostDiagnostics._maxDiagnosticsPerFile, _proxy, _onDidChangeDiagnostics);
				_collections.set(owner, this);
			}
			dispose() {
				super.dispose();
				_collections.delete(owner);
			}
		};

		return result;
	}

	getDiagnostics(resource: vscode.Uri): vscode.Diagnostic[];
	getDiagnostics(): [vscode.Uri, vscode.Diagnostic[]][];
	getDiagnostics(resource?: vscode.Uri): vscode.Diagnostic[] | [vscode.Uri, vscode.Diagnostic[]][];
	getDiagnostics(resource?: vscode.Uri): vscode.Diagnostic[] | [vscode.Uri, vscode.Diagnostic[]][] {
		if (resource) {
			return this._getDiagnostics(resource);
		} else {
			let index = new Map<string, number>();
			let res: [vscode.Uri, vscode.Diagnostic[]][] = [];
			this._collections.forEach(collection => {
				collection.forEach((uri, diagnostics) => {
					let idx = index.get(uri.toString());
					if (typeof idx === 'undefined') {
						idx = res.length;
						index.set(uri.toString(), idx);
						res.push([uri, []]);
					}
					res[idx][1] = res[idx][1].concat(...diagnostics);
				});
			});
			return res;
		}
	}

	private _getDiagnostics(resource: vscode.Uri): vscode.Diagnostic[] {
		let res: vscode.Diagnostic[] = [];
		this._collections.forEach(collection => {
			if (collection.has(resource)) {
				res = res.concat(collection.get(resource));
			}
		});
		return res;
	}
}


dispose(): void {
		if (!this._isDisposed) {
			this._onDidChangeDiagnostics.fire(keys(this._data));
			this._proxy.$clear(this._owner);
			this._data = undefined;
			this._isDisposed = true;
		}
	}


set(uri: vscode.Uri, diagnostics: vscode.Diagnostic[]): void;


set(entries: [vscode.Uri, vscode.Diagnostic[]][]): void;


set(first: vscode.Uri | [vscode.Uri, vscode.Diagnostic[]][], diagnostics?: vscode.Diagnostic[]) {

		if (!first) {
			// this set-call is a clear-call
			this.clear();
			return;
		}

		// the actual implementation for #set

		this._checkDisposed();
		let toSync: vscode.Uri[] = [];
		let hasChanged = true;

		if (first instanceof URI) {

			// check if this has actually changed
			hasChanged = hasChanged && !equals(diagnostics, this.get(first), Diagnostic.isEqual);

			if (!diagnostics) {
				// remove this entry
				this.delete(first);
				return;
			}

			// update single row
			this._data.set(first.toString(), diagnostics.slice());
			toSync = [first];

		} else if (Array.isArray(first)) {
			// update many rows
			toSync = [];
			let lastUri: vscode.Uri | undefined;

			// ensure stable-sort
			mergeSort(first, DiagnosticCollection._compareIndexedTuplesByUri);

			for (const tuple of first) {
				const [uri, diagnostics] = tuple;
				if (!lastUri || uri.toString() !== lastUri.toString()) {
					if (lastUri && this._data.get(lastUri.toString()).length === 0) {
						this._data.delete(lastUri.toString());
					}
					lastUri = uri;
					toSync.push(uri);
					this._data.set(uri.toString(), []);
				}

				if (!diagnostics) {
					// [Uri, undefined] means clear this
					this._data.get(uri.toString()).length = 0;
				} else {
					this._data.get(uri.toString()).push(...diagnostics);
				}
			}
		}

		// send event for extensions
		this._onDidChangeDiagnostics.fire(toSync);

		// if nothing has changed then there is nothing else to do
		// we have updated the diagnostics but we don't send a message
		// to the renderer. tho we have still send an event for other
		// extensions because the diagnostic might carry more information
		// than known to us
		if (!hasChanged) {
			return;
		}
		// compute change and send to main side
		const entries: [URI, IMarkerData[]][] = [];
		for (let uri of toSync) {
			let marker: IMarkerData[] | undefined;
			let diagnostics = this._data.get(uri.toString());
			if (diagnostics) {

				// no more than N diagnostics per file
				if (diagnostics.length > this._maxDiagnosticsPerFile) {
					marker = [];
					const order = [DiagnosticSeverity.Error, DiagnosticSeverity.Warning, DiagnosticSeverity.Information, DiagnosticSeverity.Hint];
					orderLoop: for (let i = 0; i < 4; i++) {
						for (let diagnostic of diagnostics) {
							if (diagnostic.severity === order[i]) {
								const len = marker.push(converter.Diagnostic.from(diagnostic));
								if (len === this._maxDiagnosticsPerFile) {
									break orderLoop;
								}
							}
						}
					}

					// add 'signal' marker for showing omitted errors/warnings
					marker.push({
						severity: MarkerSeverity.Info,
						message: localize({ key: 'limitHit', comment: ['amount of errors/warning skipped due to limits'] }, "Not showing {0} further errors and warnings.", diagnostics.length - this._maxDiagnosticsPerFile),
						startLineNumber: marker[marker.length - 1].startLineNumber,
						startColumn: marker[marker.length - 1].startColumn,
						endLineNumber: marker[marker.length - 1].endLineNumber,
						endColumn: marker[marker.length - 1].endColumn
					});
				} else {
					marker = diagnostics.map(converter.Diagnostic.from);
				}
			}

			entries.push([uri, marker]);
		}

		this._proxy.$changeMany(this._owner, entries);
	}


delete(uri: vscode.Uri): void {
		this._checkDisposed();
		this._onDidChangeDiagnostics.fire([uri]);
		this._data.delete(uri.toString());
		this._proxy.$changeMany(this._owner, [[uri, undefined]]);
	}


clear(): void {
		this._checkDisposed();
		this._onDidChangeDiagnostics.fire(keys(this._data));
		this._data.clear();
		this._proxy.$clear(this._owner);
	}


forEach(callback: (uri: URI, diagnostics: vscode.Diagnostic[], collection: DiagnosticCollection) => any, thisArg?: any): void {
		this._checkDisposed();
		this._data.forEach((value, key) => {
			let uri = URI.parse(key);
			callback.apply(thisArg, [uri, this.get(uri), this]);
		});
	}


get(uri: URI): vscode.Diagnostic[] {
		this._checkDisposed();
		let result = this._data.get(uri.toString());
		if (Array.isArray(result)) {
			return <vscode.Diagnostic[]>Object.freeze(result.slice(0));
		}
		return undefined;
	}


has(uri: URI): boolean {
		this._checkDisposed();
		return Array.isArray(this._data.get(uri.toString()));
	}


private _checkDisposed() {
		if (this._isDisposed) {
			throw new Error('illegal state - object is disposed');
		}
	}


private static _compareIndexedTuplesByUri(a: [vscode.Uri, vscode.Diagnostic[]], b: [vscode.Uri, vscode.Diagnostic[]]): number {
		if (a[0].toString() < b[0].toString()) {
			return -1;
		} else if (a[0].toString() > b[0].toString()) {
			return 1;
		} else {
			return 0;
		}
	}


static _debouncer(last: (vscode.Uri | string)[], current: (vscode.Uri | string)[]): (vscode.Uri | string)[] {
		if (!last) {
			return current;
		} else {
			return last.concat(current);
		}
	}


static _mapper(last: (vscode.Uri | string)[]): { uris: vscode.Uri[] } {
		let uris: vscode.Uri[] = [];
		let map = new Set<string>();
		for (const uri of last) {
			if (typeof uri === 'string') {
				if (!map.has(uri)) {
					map.add(uri);
					uris.push(URI.parse(uri));
				}
			} else {
				if (!map.has(uri.toString())) {
					map.add(uri.toString());
					uris.push(uri);
				}
			}
		}
		Object.freeze(uris);
		return { uris };
	}


createDiagnosticCollection(name?: string): vscode.DiagnosticCollection {
		let { _collections, _proxy, _onDidChangeDiagnostics } = this;
		let owner: string;
		if (!name) {
			name = '_generated_diagnostic_collection_name_#' + ExtHostDiagnostics._idPool++;
			owner = name;
		} else if (!_collections.has(name)) {
			owner = name;
		} else {
			console.warn(`DiagnosticCollection with name '${name}' does already exist.`);
			do {
				owner = name + ExtHostDiagnostics._idPool++;
			} while (_collections.has(owner));
		}

		const result = new class extends DiagnosticCollection {
			constructor() {
				super(name!, owner, ExtHostDiagnostics._maxDiagnosticsPerFile, _proxy, _onDidChangeDiagnostics);
				_collections.set(owner, this);
			}
			dispose() {
				super.dispose();
				_collections.delete(owner);
			}
		};

		return result;
	}


dispose() {
				super.dispose();
				_collections.delete(owner);
			}


getDiagnostics(resource: vscode.Uri): vscode.Diagnostic[];


getDiagnostics(): [vscode.Uri, vscode.Diagnostic[]][];


getDiagnostics(resource?: vscode.Uri): vscode.Diagnostic[] | [vscode.Uri, vscode.Diagnostic[]][];


getDiagnostics(resource?: vscode.Uri): vscode.Diagnostic[] | [vscode.Uri, vscode.Diagnostic[]][] {
		if (resource) {
			return this._getDiagnostics(resource);
		} else {
			let index = new Map<string, number>();
			let res: [vscode.Uri, vscode.Diagnostic[]][] = [];
			this._collections.forEach(collection => {
				collection.forEach((uri, diagnostics) => {
					let idx = index.get(uri.toString());
					if (typeof idx === 'undefined') {
						idx = res.length;
						index.set(uri.toString(), idx);
						res.push([uri, []]);
					}
					res[idx][1] = res[idx][1].concat(...diagnostics);
				});
			});
			return res;
		}
	}


private _getDiagnostics(resource: vscode.Uri): vscode.Diagnostic[] {
		let res: vscode.Diagnostic[] = [];
		this._collections.forEach(collection => {
			if (collection.has(resource)) {
				res = res.concat(collection.get(resource));
			}
		});
		return res;
	}


({
  title,
  url,
  imgSrc,
}: {
  imgSrc: string;
  title: string;
  url: string;
}) => (
  <Grid item


({
  title,
  url,
  description,
}: {
  description: string;
  title: string;
  url: string;
}) => (
  <Grid item


({
  title,
  link,
  description,
  imgSrc,
  ltr,
}: {
  title: string;
  link: string;
  description: string;
  imgSrc: string;
  ltr: boolean;
}) => {
  const [showDescription, setShowDescription] = window.React.useState(false);
  const openDescription = window.React.useCallback(
    () => setShowDescription(true),
    [setShowDescription]
  );
  const closeDescription = window.React.useCallback(
    () => setShowDescription(false),
    [setShowDescription]
  );
  const imageGrid = (
    <Grid item xs={isBrowser ? 4 : 2}>
      <Image src={imgSrc} aspectRatio={1} style={{ borderRadius: 8 }}


() => setShowDescription(true)


() => setShowDescription(false)


({ projects }: { projects: Projects }) => (
  <Grid container


({ name, url, description, image }, i) =>
      image && description ? (
        <Project
          key={i}


d => {
  (d as HTMLDivElement).style.paddingTop = "0";
  window.ReactDOM.render(
    <ProjectsPage projects={window[d.id] as Projects} />,
    d
  );
}


interface Window {
    [k: string]: Projects;
    React: typeof React;
    ReactDOM: typeof ReactDOM;
  }


type Projects = {
  name: string;
  url: string;
  description?: string;
  image?: string;
}[];


url ? (
          <Link href={url} target="_blank" rel="noopener">
            {title}
          </Link>
        ) : (
          title
        )


async function copyFile(from: string, to = from) {
  to = join("npm", to);
  await ensureDir(dirname(to));
  await Deno.copyFile(from, to);
}


@Component({
  selector: 'app-page-2',
  templateUrl: './parent.component.html',
  styleUrls: ['./parent.component.scss']
})
export class Page2ParentComponent implements OnInit {

  parentMessage = "Message from the Parent : Do something awesome with Angular. 😎"
  parentMessageList = ["Al Kindi", "Friedrich Nietzsche", "Pierre de Fermat", "Andrew Wiles"]
  items = ['item1', 'item2', 'item3', 'item4'];

  addItem(newItem: string) {
    this.items.push(newItem);
  }

  constructor() { }

  ngOnInit(): void {}

}

T003-Routing With 2 Components(routing)/src/app/page-2/parent.component.ts


addItem(newItem: string) {
    this.items.push(newItem);
  }


(callback) => {
                this._connectionResolver.resolve(correlationId, (err, connection) => {
                    this._connection = connection;
                    if (callback != null)
                        callback(err);
                });
            }


(err, connection) => {
                    this._connection = connection;
                    if (callback != null)
                        callback(err);
                }


(callback) => {
                let aws = require('aws-sdk');

                aws.config.update({
                    accessKeyId: this._connection.getAccessId(),
                    secretAccessKey: this._connection.getAccessKey(),
                    region: this._connection.getRegion()
                });

                this._logsClient = new aws.CloudWatchLogs({ apiVersion: '2014-03-28' });
                this._metricsClient = new aws.CloudWatch({ apiVersion: '2010-08-01' });

                callback();
            }


(err, data) => {
            if (err) {
                // this._logger.error(correlationId, "Error while describeLogGroups: %s; Stack: %s", err, err.stack);
                console.log(err, err.stack);
            }

            if (callback) callback(err, data);
        }


(err, data) => {
            if (err) {
                // this._logger.error(correlationId, "Error while describeLogStreams: %s; Stack: %s", err, err.stack);
                console.log(err, err.stack);
            }

            if (callback) callback(err, data);
        }


(callback) => {
                let listMetricsparams: any;
                if (metric) {
                    listMetricsparams = {
                        Namespace: namespace,
                        MetricName: metric
                    };
                } else {
                    listMetricsparams = {
                        Namespace: namespace
                    };
                }

                this._metricsClient.listMetrics(listMetricsparams, function (err, data) {
                    if (err) {
                        // this._logger.error(correlationId, "Error while listMetrics: %s; Stack: %s", err, err.stack);
                        console.log(err, err.stack); // an error occurred
                    } else {
                        metrics = data.Metrics;
                    }

                    if (callback) callback(err);
                });
            }


(callback) => {
                if (metrics.length == 0) {
                    // this._logger.trace(correlationId, "Not found metrics data for %s namespace", namespace);
                    console.log("Not found metrics data for %s namespace", namespace);
                    callback(null, "Not found metrics data for " + namespace + " namespace");
                    return;
                }

                // metricDataQueries max size is 100. in case of many metrics created array of arrays
                let metricDataQueriesAll: any[][];
                metricDataQueriesAll = [];
                let i = 0;

                metrics.forEach(metric => {
                    let dimensions = [];
                    metric.Dimensions.forEach(dimension => {
                        dimensions.push({
                            Name: dimension.Name,
                            Value: dimension.Value
                        })
                    });

                    // initialize array
                    if (!metricDataQueriesAll[i]) {
                        metricDataQueriesAll[i] = [];
                    } else if (metricDataQueriesAll[i].length == 100) {
                        i++;
                        metricDataQueriesAll[i] = [];
                    }

                    let rndString = RandomString.nextAlphaChar().toLowerCase() + Math.random().toString(36).slice(5);
                    metricDataQueriesAll[i].push({
                        Id: rndString,
                        Label: metric.MetricName + " " + dimensions[0].Value,
                        MetricStat: {
                            Metric: {
                                Dimensions: dimensions,
                                MetricName: metric.MetricName,
                                Namespace: metric.Namespace
                            },
                            Period: period,
                            Stat: type,
                            Unit: unit
                        },
                        ReturnData: true
                    });
                });

                let result = [];

                async.each(metricDataQueriesAll, (metricDataQueries, callback) => {
                    let getMetricDataParams = {
                        EndTime: endTime,
                        MetricDataQueries: metricDataQueries,
                        StartTime: startTime,
                        // MaxDatapoints: 0,
                        ScanBy: CloudwatchScanBy.TimestampAscending
                    };

                    this._metricsClient.getMetricData(getMetricDataParams, (err, data) => {
                        result.push(data);
                        callback(err, data);
                    });

                }, (err) => {
                    if (err) {
                        // this._logger.error(correlationId, "Error while getMetricData: %s; Stack: %s", err, err.stack);
                        console.log(err, err.stack); // an error occurred
                    }
                    if (callback) callback(err, result);

                });

            }


metric => {
                    let dimensions = [];
                    metric.Dimensions.forEach(dimension => {
                        dimensions.push({
                            Name: dimension.Name,
                            Value: dimension.Value
                        })
                    });

                    // initialize array
                    if (!metricDataQueriesAll[i]) {
                        metricDataQueriesAll[i] = [];
                    } else if (metricDataQueriesAll[i].length == 100) {
                        i++;
                        metricDataQueriesAll[i] = [];
                    }

                    let rndString = RandomString.nextAlphaChar().toLowerCase() + Math.random().toString(36).slice(5);
                    metricDataQueriesAll[i].push({
                        Id: rndString,
                        Label: metric.MetricName + " " + dimensions[0].Value,
                        MetricStat: {
                            Metric: {
                                Dimensions: dimensions,
                                MetricName: metric.MetricName,
                                Namespace: metric.Namespace
                            },
                            Period: period,
                            Stat: type,
                            Unit: unit
                        },
                        ReturnData: true
                    });
                }


dimension => {
                        dimensions.push({
                            Name: dimension.Name,
                            Value: dimension.Value
                        })
                    }


(metricDataQueries, callback) => {
                    let getMetricDataParams = {
                        EndTime: endTime,
                        MetricDataQueries: metricDataQueries,
                        StartTime: startTime,
                        // MaxDatapoints: 0,
                        ScanBy: CloudwatchScanBy.TimestampAscending
                    };

                    this._metricsClient.getMetricData(getMetricDataParams, (err, data) => {
                        result.push(data);
                        callback(err, data);
                    });

                }


(err, data) => {
                        result.push(data);
                        callback(err, data);
                    }


(err) => {
                    if (err) {
                        // this._logger.error(correlationId, "Error while getMetricData: %s; Stack: %s", err, err.stack);
                        console.log(err, err.stack); // an error occurred
                    }
                    if (callback) callback(err, result);

                }


public getCommandSet(): CommandSet {
        if (this._commandSet == null)
            this._commandSet = new CloudwatchCommandSet(this);
        return this._commandSet;
    }


public configure(config: ConfigParams): void {
        this._logger.configure(config);
        this._dependencyResolver.configure(config);
        this._connectionResolver.configure(config);
    }


public setReferences(references: IReferences): void {
        this._logger.setReferences(references);
        this._dependencyResolver.setReferences(references);
        this._connectionResolver.setReferences(references);
    }


public isOpen(): boolean {
        return this._opened;
    }


public open(correlationId: string, callback: (err: any) => void): void {
        if (this._opened) {
            callback(null);
            return;
        }

        this._opened = true;

        async.series([
            (callback) => {
                this._connectionResolver.resolve(correlationId, (err, connection) => {
                    this._connection = connection;
                    if (callback != null)
                        callback(err);
                });
            },
            (callback) => {
                let aws = require('aws-sdk');

                aws.config.update({
                    accessKeyId: this._connection.getAccessId(),
                    secretAccessKey: this._connection.getAccessKey(),
                    region: this._connection.getRegion()
                });

                this._logsClient = new aws.CloudWatchLogs({ apiVersion: '2014-03-28' });
                this._metricsClient = new aws.CloudWatch({ apiVersion: '2010-08-01' });

                callback();
            }
        ], callback);
    }


public close(correlationId: string, callback: (err: any) => void): void {
        this._opened = false;
        this._logsClient = null;

        if (callback) callback(null);
    }


public getLogGroups(correlationId: string, logGroupNamePrefix?: string, limit?: number,
        callback?: (err: any, result: string) => void) {
        var params = {
            limit: limit ? limit : 50, // 50 is default
            logGroupNamePrefix: logGroupNamePrefix ? logGroupNamePrefix : null
        };

        this._logsClient.describeLogGroups(params, (err, data) => {
            if (err) {
                // this._logger.error(correlationId, "Error while describeLogGroups: %s; Stack: %s", err, err.stack);
                console.log(err, err.stack);
            }

            if (callback) callback(err, data);
        })
    }


public getLogStreams(correlationId: string, logGroupName: string, logStreamNamePrefix?: string, limit?: number,
        callback?: (err: any, result: string) => void) {
        var params = {
            logGroupName: logGroupName,
            descending: false,
            limit: limit ? limit : 50, // 50 is default
            logStreamNamePrefix: logStreamNamePrefix ? logStreamNamePrefix : null
        };

        this._logsClient.describeLogStreams(params, (err, data) => {
            if (err) {
                // this._logger.error(correlationId, "Error while describeLogStreams: %s; Stack: %s", err, err.stack);
                console.log(err, err.stack);
            }

            if (callback) callback(err, data);
        });
    }


public getLogEvents(correlationId: string, group: string, stream: string, startTime: Date, endTime: Date,
        filter: string, limit?: number, callback?: (err: any, results: string) => void): void {
        var params = {
            logGroupName: group, /* required */
            logStreamNames: [stream], /* required */
            filterPattern: filter,
            startTime: startTime.getTime(),
            endTime: endTime.getTime(),
            limit: limit ? limit : 10000
        };
        this._logsClient.filterLogEvents(params, function (err, data) {
            if (err) {
                // this._logger.error(correlationId, "Error while filterLogEvents: %s; Stack: %s", err, err.stack);
                console.log(err, err.stack); // an error occurred
            }

            if (callback) callback(err, data);
        });
    }


public getMetricData(correlationId: string, namespace: string, startTime: Date, endTime: Date,
        period: number, type: string, unit: string, metric: string, callback?: (err: any, result: string) => void): void {

        let metrics: any;

        async.series([
            (callback) => {
                let listMetricsparams: any;
                if (metric) {
                    listMetricsparams = {
                        Namespace: namespace,
                        MetricName: metric
                    };
                } else {
                    listMetricsparams = {
                        Namespace: namespace
                    };
                }

                this._metricsClient.listMetrics(listMetricsparams, function (err, data) {
                    if (err) {
                        // this._logger.error(correlationId, "Error while listMetrics: %s; Stack: %s", err, err.stack);
                        console.log(err, err.stack); // an error occurred
                    } else {
                        metrics = data.Metrics;
                    }

                    if (callback) callback(err);
                });
            },
            (callback) => {
                if (metrics.length == 0) {
                    // this._logger.trace(correlationId, "Not found metrics data for %s namespace", namespace);
                    console.log("Not found metrics data for %s namespace", namespace);
                    callback(null, "Not found metrics data for " + namespace + " namespace");
                    return;
                }

                // metricDataQueries max size is 100. in case of many metrics created array of arrays
                let metricDataQueriesAll: any[][];
                metricDataQueriesAll = [];
                let i = 0;

                metrics.forEach(metric => {
                    let dimensions = [];
                    metric.Dimensions.forEach(dimension => {
                        dimensions.push({
                            Name: dimension.Name,
                            Value: dimension.Value
                        })
                    });

                    // initialize array
                    if (!metricDataQueriesAll[i]) {
                        metricDataQueriesAll[i] = [];
                    } else if (metricDataQueriesAll[i].length == 100) {
                        i++;
                        metricDataQueriesAll[i] = [];
                    }

                    let rndString = RandomString.nextAlphaChar().toLowerCase() + Math.random().toString(36).slice(5);
                    metricDataQueriesAll[i].push({
                        Id: rndString,
                        Label: metric.MetricName + " " + dimensions[0].Value,
                        MetricStat: {
                            Metric: {
                                Dimensions: dimensions,
                                MetricName: metric.MetricName,
                                Namespace: metric.Namespace
                            },
                            Period: period,
                            Stat: type,
                            Unit: unit
                        },
                        ReturnData: true
                    });
                });

                let result = [];

                async.each(metricDataQueriesAll, (metricDataQueries, callback) => {
                    let getMetricDataParams = {
                        EndTime: endTime,
                        MetricDataQueries: metricDataQueries,
                        StartTime: startTime,
                        // MaxDatapoints: 0,
                        ScanBy: CloudwatchScanBy.TimestampAscending
                    };

                    this._metricsClient.getMetricData(getMetricDataParams, (err, data) => {
                        result.push(data);
                        callback(err, data);
                    });

                }, (err) => {
                    if (err) {
                        // this._logger.error(correlationId, "Error while getMetricData: %s; Stack: %s", err, err.stack);
                        console.log(err, err.stack); // an error occurred
                    }
                    if (callback) callback(err, result);

                });

            }
        ], callback);
    }


// --------------------------------
// SIZES
// --------------------------------
export enum ESizes {
  one = 'one',
  two = 'two',
  three = 'three',
  four = 'four',
  five = 'five',
  six = 'six',
  seven = 'seven',
  eight = 'eight',
  nine = 'nine',
  ten = 'ten',
  eleven = 'eleven',
  twelve = 'twelve',
}


export enum ESizesTypes {
  spacing = 'spacing',
  typography = 'typography',
  container = 'container'
}


export type TSizes = keyof typeof ESizes;


export type TSizesTypes = keyof typeof ESizesTypes;


({
    tooltip = 'Add to list',
    popoverLayout = ['right', 'top'],
    itemId,
    itemType,

    ...IIconButtonProps
}) => {
    const selfRef = useRef<HTMLAnchorElement>(null);

    const environment = useSelector(currentEnvironmentSelector);
    // Loads all boards that has this item owned by the user
    const {
        data: boardIds,
        forceFetch: fetchBoardIds,
        isLoading: isLoadingBoardIds,
    } = useResource(
        React.useCallback(
            () =>
                BoardResource.getItemBoardIds(environment.id, itemType, itemId),
            [environment.id, itemType, itemId]
        ),
        {
            fetchOnMount: false,
        }
    );

    // Controls on/off of the board picker popover
    const [showSelectBoardPopover, setShowSelectBoardPopover] = useState(false);
    useEffect(() => {
        // If we are showing the board picker popover,
        // we have to show which board has the item
        if (showSelectBoardPopover) {
            fetchBoardIds();
        }
    }, [showSelectBoardPopover]);

    // Controls on/off of the board creation popover
    const [showCreateModal, setShowCreateModal] = useState(false);

    const dispatch: Dispatch = useDispatch();

    // Either show modal and hide popover or vice versa
    const flipShowModalAndPopover = React.useCallback((showModal: boolean) => {
        setShowCreateModal(showModal);
        setShowSelectBoardPopover(!showModal);
    }, []);

    // Add or remove the user item to board
    const handleAddOrRemoveBoardItem = React.useCallback(
        async (boardId: number, boardName: string = 'Untitled') => {
            if (!(boardIds || []).includes(boardId)) {
                // Add item
                await dispatch(addBoardItem(boardId, itemType, itemId));
                toast.success(`Item added to the list "${boardName}"!`);
            } else {
                // remove item
                await dispatch(deleteBoardItem(boardId, itemType, itemId));
                toast.success(`Item removed from the list "${boardName}"!`);
            }
            setShowSelectBoardPopover(false);
        },
        [itemType, itemId, boardIds]
    );

    const handleAfterBoardCreation = React.useCallback(
        async (rawBoard: IBoardRaw) => {
            await handleAddOrRemoveBoardItem(rawBoard.id, rawBoard.name);
            setShowCreateModal(false);
            setShowSelectBoardPopover(false); // just in case
        },
        [handleAddOrRemoveBoardItem]
    );

    // Rendering ----------------------------------------------
    const boardPickerPopover = showSelectBoardPopover ? (
        <Popover
            onHide={()


() =>
                BoardResource.getItemBoardIds(environment.id, itemType, itemId)


() => {
        // If we are showing the board picker popover,
        // we have to show which board has the item
        if (showSelectBoardPopover) {
            fetchBoardIds();
        }
    }


(showModal: boolean) => {
        setShowCreateModal(showModal);
        setShowSelectBoardPopover(!showModal);
    }


async (boardId: number, boardName: string = 'Untitled') => {
            if (!(boardIds || []).includes(boardId)) {
                // Add item
                await dispatch(addBoardItem(boardId, itemType, itemId));
                toast.success(`Item added to the list "${boardName}"!`);
            } else {
                // remove item
                await dispatch(deleteBoardItem(boardId, itemType, itemId));
                toast.success(`Item removed from the list "${boardName}"!`);
            }
            setShowSelectBoardPopover(false);
        }


async (rawBoard: IBoardRaw) => {
            await handleAddOrRemoveBoardItem(rawBoard.id, rawBoard.name);
            setShowCreateModal(false);
            setShowSelectBoardPopover(false); // just in case
        }


export interface ICreateDataDocButtonProps extends Partial<IIconButtonProps> {
    // from own Props
    tooltipPos?: TooltipDirection;
    tooltip?: string;
    popoverLayout?: PopoverLayout;
    itemId: number;
    itemType: BoardItemType;
}


isLoadingBoardIds ? (
                    <Loading


async (): Promise<string> => {
    // TODO:
    const jobId = ulid()
    console.log('enqueue: ', jobId)
    return jobId
  }


class ResourceManagementQueue implements AppQueue {
  private static queue: AppQueue | null = null

  enqueue = async (): Promise<string> => {
    // TODO:
    const jobId = ulid()
    console.log('enqueue: ', jobId)
    return jobId
  }

  constructor(connectionOption: { host: string; port: number }) {
    console.log(connectionOption)
  }

  static async getQueue(): Promise<AppQueue> {
    if (!this.queue) {
      const { redis } = await Config.getConfig()
      this.queue = new ResourceManagementQueue(redis)
    }
    return this.queue
  }
}


static async getQueue(): Promise<AppQueue> {
    if (!this.queue) {
      const { redis } = await Config.getConfig()
      this.queue = new ResourceManagementQueue(redis)
    }
    return this.queue
  }


({ children }: Props) => {
  const [mounted, setMounted] = React.useState(false);
  useSSREffect(() => {
    setMounted(true);
  }, []);
  return <>{mounted && children}


() => {
    setMounted(true);
  }


type Props = {
  children?: React.ReactNode;
};


export default function withTwindApp<Base = typeof App>(
  config?: Configuration,
  BaseApp?: Base,
): Base


export default function withTwindApp<Base = typeof App>(BaseApp?: Base): Base


export default function withTwindApp<Base = typeof App>(
  configOrBase?: Configuration | Base,
  BaseApp?: Base,
): Base {
  if (typeof configOrBase == 'function') {
    BaseApp = configOrBase
    configOrBase = {}
  }

  // If this run on the server _document.js has already done the setup
  if (typeof window !== 'undefined') {
    setup(configOrBase)
  }

  // @ts-ignore
  return BaseApp || App
}


pessoa => {
      this.funcionario.pessoa = this.pessoa = { id: pessoa.id, nome: pessoa.nome }
    }


id => {
      form.reset();

      this.toastyService.success('Funcionário salvo com sucesso!');
    }


ex => {
      this.toastyService.error('Erro tentando salvar funcionário');
      return Observable.throw(this.errorHandlerService.handle(ex.error[0].messageUser));
    }


@Component({
  selector: 'npj-cadastro-funcionario',
  templateUrl: './cadastro-funcionario.component.html'
})
export class CadastroFuncionarioComponent implements OnInit {

  pessoa: any;

  funcionario = new Funcionario();

  constructor(
    private funcionarioService: FuncionarioService,
    private toastyService: ToastyService,
    private errorHandlerService: ErrorHandlerService
  ) { }

  ngOnInit() {
    this.funcionarioService.findByPessoaId().subscribe(pessoa => {
      this.funcionario.pessoa = this.pessoa = { id: pessoa.id, nome: pessoa.nome }
    });
  }

  save(form: FormGroup) {
    this.funcionarioService.save(this.funcionario).subscribe(id => {
      form.reset();

      this.toastyService.success('Funcionário salvo com sucesso!');
    }, ex => {
      this.toastyService.error('Erro tentando salvar funcionário');
      return Observable.throw(this.errorHandlerService.handle(ex.error[0].messageUser));
    })
  }

}


ngOnInit() {
    this.funcionarioService.findByPessoaId().subscribe(pessoa => {
      this.funcionario.pessoa = this.pessoa = { id: pessoa.id, nome: pessoa.nome }
    });
  }


save(form: FormGroup) {
    this.funcionarioService.save(this.funcionario).subscribe(id => {
      form.reset();

      this.toastyService.success('Funcionário salvo com sucesso!');
    }, ex => {
      this.toastyService.error('Erro tentando salvar funcionário');
      return Observable.throw(this.errorHandlerService.handle(ex.error[0].messageUser));
    })
  }


() => {
  test('is rendered', () => {
    const component = render(
      <EuiSuggest {...requiredProps} suggestions={sampleItems} />
    );

    expect(component).toMatchSnapshot();
  });

  describe('props', () => {
    describe('status', () => {
      ALL_STATUSES.forEach((status) => {
        test(`status: ${status} is rendered`, () => {
          const component = render(
            <EuiSuggest
              {...requiredProps}
              suggestions={sampleItems}
              status={status}
            />
          );

          expect(component).toMatchSnapshot();
        });
      });
    });

    test('append', () => {
      const component = render(
        <EuiSuggest
          {...requiredProps}
          suggestions={sampleItems}
          append={Appended}
        />
      );

      expect(component).toMatchSnapshot();
    });

    describe('tooltipContent', () => {
      ALL_STATUSES.forEach((status) => {
        test(`tooltipContent for status: ${status} is rendered`, () => {
          const component = render(
            <EuiSuggest
              {...requiredProps}
              suggestions={sampleItems}
              status={status}
              tooltipContent={status}
            />
          );

          expect(component).toMatchSnapshot();
        });
      });
    });

    test('isVirtualized', () => {
      const component = mount(
        <EuiSuggest
          {...requiredProps}
          suggestions={sampleItems}
          isVirtualized
        />
      );

      expect(component).toMatchSnapshot();
    });

    test('maxHeight', () => {
      const component = mount(
        <EuiSuggest
          {...requiredProps}
          suggestions={sampleItems}
          maxHeight="50vh"
        />
      );

      expect(component).toMatchSnapshot();
    });

    describe('options', () => {
      test('standard', () => {
        const _sampleItems: EuiSuggestionProps[] = sampleItems.map(
          (item, idx) => ({
            ...item,
            labelDisplay: idx === 0 ? 'fixed' : 'expand',
            descriptionDisplay: idx === 0 ? 'truncate' : 'wrap',
            labelWidth: idx === 0 ? '70' : 80,
          })
        );
        const component = render(
          <EuiSuggest {...requiredProps} suggestions={_sampleItems} />
        );

        expect(component).toMatchSnapshot();
      });

      test('common', () => {
        const _sampleItems: EuiSuggestionProps[] = sampleItems.map((item) => ({
          ...item,
          'aria-label': 'sampleItem',
          'data-test-subj': 'sampleItem',
          className: 'sampleItem',
          id: 'sampleItem',
        }));
        const component = render(
          <EuiSuggest {...requiredProps} suggestions={_sampleItems} />
        );

        expect(component).toMatchSnapshot();
      });
    });

    describe('onItemClick', () => {
      it('passes an onChange callback to the underlying EuiSelectable, which will fire on list item clicks and enter keypresses', () => {
        const onItemClick = jest.fn();
        const component = shallow(
          <EuiSuggest
            {...requiredProps}
            suggestions={sampleItems}
            onItemClick={onItemClick}
          />
        );

        const options = component.find(EuiSelectable).prop('options');
        options[1].checked = 'on';
        component.find(EuiSelectable).simulate('change', options);

        expect(onItemClick).toHaveBeenCalledWith(sampleItems[1]);
      });
    });

    test('remaining EuiFieldSearch props are spread to the search input', () => {
      const component = render(
        <EuiSuggest
          {...requiredProps}
          suggestions={sampleItems}
          name="testName"
          id="testId"
          placeholder="Start typing"
          value="Controlled value"
          isInvalid={true}
          compressed={true}
          fullWidth={false}
          isClearable={true}
        />
      );

      expect(component).toMatchSnapshot();
    });
  });
}


() => {
    const component = render(
      <EuiSuggest {...requiredProps} suggestions={sampleItems} />
    );

    expect(component).toMatchSnapshot();
  }


() => {
    describe('status', () => {
      ALL_STATUSES.forEach((status) => {
        test(`status: ${status} is rendered`, () => {
          const component = render(
            <EuiSuggest
              {...requiredProps}
              suggestions={sampleItems}
              status={status}
            />
          );

          expect(component).toMatchSnapshot();
        });
      });
    });

    test('append', () => {
      const component = render(
        <EuiSuggest
          {...requiredProps}
          suggestions={sampleItems}
          append={Appended}
        />
      );

      expect(component).toMatchSnapshot();
    });

    describe('tooltipContent', () => {
      ALL_STATUSES.forEach((status) => {
        test(`tooltipContent for status: ${status} is rendered`, () => {
          const component = render(
            <EuiSuggest
              {...requiredProps}
              suggestions={sampleItems}
              status={status}
              tooltipContent={status}
            />
          );

          expect(component).toMatchSnapshot();
        });
      });
    });

    test('isVirtualized', () => {
      const component = mount(
        <EuiSuggest
          {...requiredProps}
          suggestions={sampleItems}
          isVirtualized
        />
      );

      expect(component).toMatchSnapshot();
    });

    test('maxHeight', () => {
      const component = mount(
        <EuiSuggest
          {...requiredProps}
          suggestions={sampleItems}
          maxHeight="50vh"
        />
      );

      expect(component).toMatchSnapshot();
    });

    describe('options', () => {
      test('standard', () => {
        const _sampleItems: EuiSuggestionProps[] = sampleItems.map(
          (item, idx) => ({
            ...item,
            labelDisplay: idx === 0 ? 'fixed' : 'expand',
            descriptionDisplay: idx === 0 ? 'truncate' : 'wrap',
            labelWidth: idx === 0 ? '70' : 80,
          })
        );
        const component = render(
          <EuiSuggest {...requiredProps} suggestions={_sampleItems} />
        );

        expect(component).toMatchSnapshot();
      });

      test('common', () => {
        const _sampleItems: EuiSuggestionProps[] = sampleItems.map((item) => ({
          ...item,
          'aria-label': 'sampleItem',
          'data-test-subj': 'sampleItem',
          className: 'sampleItem',
          id: 'sampleItem',
        }));
        const component = render(
          <EuiSuggest {...requiredProps} suggestions={_sampleItems} />
        );

        expect(component).toMatchSnapshot();
      });
    });

    describe('onItemClick', () => {
      it('passes an onChange callback to the underlying EuiSelectable, which will fire on list item clicks and enter keypresses', () => {
        const onItemClick = jest.fn();
        const component = shallow(
          <EuiSuggest
            {...requiredProps}
            suggestions={sampleItems}
            onItemClick={onItemClick}
          />
        );

        const options = component.find(EuiSelectable).prop('options');
        options[1].checked = 'on';
        component.find(EuiSelectable).simulate('change', options);

        expect(onItemClick).toHaveBeenCalledWith(sampleItems[1]);
      });
    });

    test('remaining EuiFieldSearch props are spread to the search input', () => {
      const component = render(
        <EuiSuggest
          {...requiredProps}
          suggestions={sampleItems}
          name="testName"
          id="testId"
          placeholder="Start typing"
          value="Controlled value"
          isInvalid={true}
          compressed={true}
          fullWidth={false}
          isClearable={true}
        />
      );

      expect(component).toMatchSnapshot();
    });
  }


() => {
      ALL_STATUSES.forEach((status) => {
        test(`status: ${status} is rendered`, () => {
          const component = render(
            <EuiSuggest
              {...requiredProps}
              suggestions={sampleItems}
              status={status}
            />
          );

          expect(component).toMatchSnapshot();
        });
      });
    }


(status) => {
        test(`status: ${status} is rendered`, () => {
          const component = render(
            <EuiSuggest
              {...requiredProps}
              suggestions={sampleItems}
              status={status}
            />
          );

          expect(component).toMatchSnapshot();
        });
      }


() => {
          const component = render(
            <EuiSuggest
              {...requiredProps}
              suggestions={sampleItems}
              status={status}
            />
          );

          expect(component).toMatchSnapshot();
        }


() => {
      const component = render(
        <EuiSuggest
          {...requiredProps}
          suggestions={sampleItems}
          append={Appended}
        />
      );

      expect(component).toMatchSnapshot();
    }


() => {
      ALL_STATUSES.forEach((status) => {
        test(`tooltipContent for status: ${status} is rendered`, () => {
          const component = render(
            <EuiSuggest
              {...requiredProps}
              suggestions={sampleItems}
              status={status}
              tooltipContent={status}
            />
          );

          expect(component).toMatchSnapshot();
        });
      });
    }


(status) => {
        test(`tooltipContent for status: ${status} is rendered`, () => {
          const component = render(
            <EuiSuggest
              {...requiredProps}
              suggestions={sampleItems}
              status={status}
              tooltipContent={status}
            />
          );

          expect(component).toMatchSnapshot();
        });
      }


() => {
          const component = render(
            <EuiSuggest
              {...requiredProps}
              suggestions={sampleItems}
              status={status}
              tooltipContent={status}
            />
          );

          expect(component).toMatchSnapshot();
        }


() => {
      const component = mount(
        <EuiSuggest
          {...requiredProps}
          suggestions={sampleItems}
          isVirtualized
        />
      );

      expect(component).toMatchSnapshot();
    }


() => {
      const component = mount(
        <EuiSuggest
          {...requiredProps}
          suggestions={sampleItems}
          maxHeight="50vh"
        />
      );

      expect(component).toMatchSnapshot();
    }


() => {
      test('standard', () => {
        const _sampleItems: EuiSuggestionProps[] = sampleItems.map(
          (item, idx) => ({
            ...item,
            labelDisplay: idx === 0 ? 'fixed' : 'expand',
            descriptionDisplay: idx === 0 ? 'truncate' : 'wrap',
            labelWidth: idx === 0 ? '70' : 80,
          })
        );
        const component = render(
          <EuiSuggest {...requiredProps} suggestions={_sampleItems} />
        );

        expect(component).toMatchSnapshot();
      });

      test('common', () => {
        const _sampleItems: EuiSuggestionProps[] = sampleItems.map((item) => ({
          ...item,
          'aria-label': 'sampleItem',
          'data-test-subj': 'sampleItem',
          className: 'sampleItem',
          id: 'sampleItem',
        }));
        const component = render(
          <EuiSuggest {...requiredProps} suggestions={_sampleItems} />
        );

        expect(component).toMatchSnapshot();
      });
    }


() => {
        const _sampleItems: EuiSuggestionProps[] = sampleItems.map(
          (item, idx) => ({
            ...item,
            labelDisplay: idx === 0 ? 'fixed' : 'expand',
            descriptionDisplay: idx === 0 ? 'truncate' : 'wrap',
            labelWidth: idx === 0 ? '70' : 80,
          })
        );
        const component = render(
          <EuiSuggest {...requiredProps} suggestions={_sampleItems} />
        );

        expect(component).toMatchSnapshot();
      }


(item, idx) => ({
            ...item,
            labelDisplay: idx === 0 ? 'fixed' : 'expand',
            descriptionDisplay: idx === 0 ? 'truncate' : 'wrap',
            labelWidth: idx === 0 ? '70' : 80,
          })


() => {
        const _sampleItems: EuiSuggestionProps[] = sampleItems.map((item) => ({
          ...item,
          'aria-label': 'sampleItem',
          'data-test-subj': 'sampleItem',
          className: 'sampleItem',
          id: 'sampleItem',
        }));
        const component = render(
          <EuiSuggest {...requiredProps} suggestions={_sampleItems} />
        );

        expect(component).toMatchSnapshot();
      }


(item) => ({
          ...item,
          'aria-label': 'sampleItem',
          'data-test-subj': 'sampleItem',
          className: 'sampleItem',
          id: 'sampleItem',
        })


() => {
      it('passes an onChange callback to the underlying EuiSelectable, which will fire on list item clicks and enter keypresses', () => {
        const onItemClick = jest.fn();
        const component = shallow(
          <EuiSuggest
            {...requiredProps}
            suggestions={sampleItems}
            onItemClick={onItemClick}
          />
        );

        const options = component.find(EuiSelectable).prop('options');
        options[1].checked = 'on';
        component.find(EuiSelectable).simulate('change', options);

        expect(onItemClick).toHaveBeenCalledWith(sampleItems[1]);
      });
    }


() => {
        const onItemClick = jest.fn();
        const component = shallow(
          <EuiSuggest
            {...requiredProps}
            suggestions={sampleItems}
            onItemClick={onItemClick}
          />
        );

        const options = component.find(EuiSelectable).prop('options');
        options[1].checked = 'on';
        component.find(EuiSelectable).simulate('change', options);

        expect(onItemClick).toHaveBeenCalledWith(sampleItems[1]);
      }


() => {
      const component = render(
        <EuiSuggest
          {...requiredProps}
          suggestions={sampleItems}
          name="testName"
          id="testId"
          placeholder="Start typing"
          value="Controlled value"
          isInvalid={true}
          compressed={true}
          fullWidth={false}
          isClearable={true}
        />
      );

      expect(component).toMatchSnapshot();
    }


@NgModule({
  declarations: [
    BoringAvatarBeamComponent
  ],
  imports: [
  ],
  exports: [
    BoringAvatarBeamComponent
  ]
})
export class BoringAvatarBeamModule { }


() => {
  it('should return an array containing the normalized versions', () => {
    const versions = ['1.0.0', '2.0', '3', '1.0.0-beta', '2.0-beta', '2-beta']
    const result = normalizeVersionsToSemver(versions)
    expect(result)
      .to.be.an('array')
      .deep.equal([
        '1.0.0',
        '2.0.0',
        '3.0.0',
        '1.0.0-beta',
        '2.0.0-beta',
        '2.0.0-beta',
      ])
  })
}