function constructGroups() {
    const newUsedErrors = {};
    const newGroups = filteredConfigurationGroups.map((group, i) => {
      if (group.show === false) {
        return null;
      }
      return (
        <div key={`${group.label}-${i}`} className={classes.group}>

{group.label}

            <If condition={group.description && group.description.length > 0}>
              {group.description}
            </If>

            {group.properties.map((property, j) => {
              if (property.show === false) {
                return null;
              }
              // Hiding all plugin functions if pipeline is deployed
              if (
                disabled &&
                property.hasOwnProperty('widget-category') &&
                property['widget-category'] === 'plugin'
              ) {
                return null;
              }
              // Check if a field is present to display the error contextually
              const errorObjs =
                errors && errors.hasOwnProperty(property.name) ? errors[property.name] : null;
              if (errorObjs) {
                // Mark error as used
                newUsedErrors[property.name] = errors[property.name];
              }
              return (
                <PropertyRow
                  key={`${property.name}-${j}`}
                  widgetProperty={property}
                  pluginProperty={pluginProperties[property.name]}
                  value={values[property.name]}
                  onChange={changeParentHandler}
                  extraConfig={extraConfig}
                  disabled={disabled}
                  errors={errorObjs}
                />
              );
            })}


function constructOrphanErrors() {
    const orphanedErrors = new Set();
    // Error messages that are already displayed in a field should not be
    // displayed in the common area - orphan errors.
    const usedMessages = new Set();
    Object.values(usedErrors).forEach((errs: IErrorObj[]) => {
      errs.forEach((error) => {
        usedMessages.add(error.msg);
      });
    });

    if (errors) {
      Object.keys(errors).forEach((propName) => {
        if (propName === 'orphanErrors') {
          errors.orphanErrors.forEach((orphanError: IErrorObj) => {
            // Making use the error msg has not been displayed contextually
            // elsewhere.
            if (!usedMessages.has(orphanError.msg)) {
              orphanedErrors.add(orphanError.msg);
            }
          });
        }
        // If the error is not used and if the message is not used,
        // add it to orphan errors.
        else if (!usedErrors.hasOwnProperty(propName)) {
          errors[propName].forEach((error: IErrorObj) => {
            if (!usedMessages.has(error.msg)) {
              // If any error is not displayed contextually, and the error message
              // is not used by any other field, mark the error as orphan.
              orphanedErrors.add(error.msg);
            }
          });
        }
      });
    }
    return Array.from(orphanedErrors);
  }


function ConfigurationGroup(props) {
  return (
    <ThemeWrapper>
      <StyledConfigurationGroup {...props} />
    </ThemeWrapper>
  );
}


(theme): StyleRules => {
  return {
    group: {
      marginBottom: '20px',
    },
    groupTitle: {
      marginBottom: '15px',
    },
    h2Title: {
      ...h2Styles(theme),
      marginBottom: 0,
    },
    groupSubTitle: {
      color: theme.palette.grey[200],
    },
  };
}


({
  widgetJson,
  pluginProperties,
  values,
  inputSchema,
  onChange,
  disabled,
  classes,
  errors,
  validateProperties,
}) => {
  const [configurationGroups, setConfigurationGroups] = React.useState([]);
  const referenceValueForUnMount = React.useRef<{
    configurationGroups?: IFilteredConfigurationGroup[];
    values?: Record<string, string>;
  }>({});
  const [filteredConfigurationGroups, setFilteredConfigurationGroups] = React.useState([]);

  // Initialize the configurationGroups based on widgetJson and pluginProperties obtained from backend
  React.useEffect(() => {
    if (!pluginProperties) {
      return;
    }

    const widgetConfigurationGroup = objectQuery(widgetJson, 'configuration-groups');
    const widgetOutputs = objectQuery(widgetJson, 'outputs');
    const processedConfigurationGroup = processConfigurationGroups(
      pluginProperties,
      widgetConfigurationGroup,
      widgetOutputs
    );

    setConfigurationGroups(processedConfigurationGroup.configurationGroups);

    // set default values
    const defaultValues = processedConfigurationGroup.defaultValues;
    const newValues = {
      ...defaultValues,
      ...values,
    };

    changeParentHandler(newValues);
  }, [widgetJson, pluginProperties]);

  // Watch for changes in values to determine dynamic widget
  React.useEffect(() => {
    let newFilteredConfigurationGroup;

    try {
      newFilteredConfigurationGroup = filterByCondition(
        configurationGroups,
        widgetJson,
        pluginProperties,
        values
      );
    } catch (e) {
      newFilteredConfigurationGroup = configurationGroups;
      // tslint:disable:no-console
      console.log('Issue with applying filters: ', e);
    }

    referenceValueForUnMount.current = {
      configurationGroups: newFilteredConfigurationGroup,
      values,
    };

    setFilteredConfigurationGroups(newFilteredConfigurationGroup);
  }, [values, configurationGroups]);

  // This onUnMount is to make sure we clear out all properties that are hidden.
  React.useEffect(() => {
    return () => {
      const newValues = { ...referenceValueForUnMount.current.values };
      const configGroups = referenceValueForUnMount.current.configurationGroups;
      if (configGroups) {
        configGroups.forEach((group) => {
          group.properties.forEach((property) => {
            if (property.show === false) {
              delete newValues[property.name];
            }
          });
        });
      }
      changeParentHandler(newValues);
    };
  }, []);

  function changeParentHandler(updatedValues) {
    if (!onChange || typeof onChange !== 'function') {
      return;
    }

    onChange(removeEmptyJsonValues(updatedValues));
  }

  const extraConfig = {
    namespace: getCurrentNamespace(),
    properties: values,
    inputSchema,
    validateProperties,
  };

  // Used to keep track of error messages that found a widget
  // required to identify errors that did not find a widget,
  // they will be marked as orphan errors.
  const [usedErrors, setUsedErrors] = React.useState({});
  const [groups, setGroups] = React.useState([]);
  const [orphanErrors, setOrphanErrors] = React.useState([]);
  // TODO: Revisit these hooks for errors. These don't seem to be necessary.
  React.useEffect(() => {
    setGroups(constructGroups);
  }, [filteredConfigurationGroups, errors]);
  React.useEffect(() => {
    setOrphanErrors(constructOrphanErrors);
  }, [usedErrors]);

  function constructGroups() {
    const newUsedErrors = {};
    const newGroups = filteredConfigurationGroups.map((group, i) => {
      if (group.show === false) {
        return null;
      }
      return (
        <div key={`${group.label}-${i}`} className={classes.group}>

{group.label}

            <If condition={group.description && group.description.length > 0}>
              {group.description}
            </If>

            {group.properties.map((property, j) => {
              if (property.show === false) {
                return null;
              }
              // Hiding all plugin functions if pipeline is deployed
              if (
                disabled &&
                property.hasOwnProperty('widget-category') &&
                property['widget-category'] === 'plugin'
              ) {
                return null;
              }
              // Check if a field is present to display the error contextually
              const errorObjs =
                errors && errors.hasOwnProperty(property.name) ? errors[property.name] : null;
              if (errorObjs) {
                // Mark error as used
                newUsedErrors[property.name] = errors[property.name];
              }
              return (
                <PropertyRow
                  key={`${property.name}-${j}`}
                  widgetProperty={property}
                  pluginProperty={pluginProperties[property.name]}
                  value={values[property.name]}
                  onChange={changeParentHandler}
                  extraConfig={extraConfig}
                  disabled={disabled}
                  errors={errorObjs}
                />
              );
            })}


() => {
    if (!pluginProperties) {
      return;
    }

    const widgetConfigurationGroup = objectQuery(widgetJson, 'configuration-groups');
    const widgetOutputs = objectQuery(widgetJson, 'outputs');
    const processedConfigurationGroup = processConfigurationGroups(
      pluginProperties,
      widgetConfigurationGroup,
      widgetOutputs
    );

    setConfigurationGroups(processedConfigurationGroup.configurationGroups);

    // set default values
    const defaultValues = processedConfigurationGroup.defaultValues;
    const newValues = {
      ...defaultValues,
      ...values,
    };

    changeParentHandler(newValues);
  }


() => {
    let newFilteredConfigurationGroup;

    try {
      newFilteredConfigurationGroup = filterByCondition(
        configurationGroups,
        widgetJson,
        pluginProperties,
        values
      );
    } catch (e) {
      newFilteredConfigurationGroup = configurationGroups;
      // tslint:disable:no-console
      console.log('Issue with applying filters: ', e);
    }

    referenceValueForUnMount.current = {
      configurationGroups: newFilteredConfigurationGroup,
      values,
    };

    setFilteredConfigurationGroups(newFilteredConfigurationGroup);
  }


() => {
    return () => {
      const newValues = { ...referenceValueForUnMount.current.values };
      const configGroups = referenceValueForUnMount.current.configurationGroups;
      if (configGroups) {
        configGroups.forEach((group) => {
          group.properties.forEach((property) => {
            if (property.show === false) {
              delete newValues[property.name];
            }
          });
        });
      }
      changeParentHandler(newValues);
    };
  }


() => {
      const newValues = { ...referenceValueForUnMount.current.values };
      const configGroups = referenceValueForUnMount.current.configurationGroups;
      if (configGroups) {
        configGroups.forEach((group) => {
          group.properties.forEach((property) => {
            if (property.show === false) {
              delete newValues[property.name];
            }
          });
        });
      }
      changeParentHandler(newValues);
    }


(group) => {
          group.properties.forEach((property) => {
            if (property.show === false) {
              delete newValues[property.name];
            }
          });
        }


(property) => {
            if (property.show === false) {
              delete newValues[property.name];
            }
          }


() => {
    setGroups(constructGroups);
  }


() => {
    setOrphanErrors(constructOrphanErrors);
  }


(group, i) => {
      if (group.show === false) {
        return null;
      }
      return (
        <div key={`${group.label}-${i}`}


(property, j) => {
              if (property.show === false) {
                return null;
              }
              // Hiding all plugin functions if pipeline is deployed
              if (
                disabled &&
                property.hasOwnProperty('widget-category') &&
                property['widget-category'] === 'plugin'
              ) {
                return null;
              }
              // Check if a field is present to display the error contextually
              const errorObjs =
                errors && errors.hasOwnProperty(property.name) ? errors[property.name] : null;
              if (errorObjs) {
                // Mark error as used
                newUsedErrors[property.name] = errors[property.name];
              }
              return (
                <PropertyRow
                  key={`${property.name}-${j}`}


(errs: IErrorObj[]) => {
      errs.forEach((error) => {
        usedMessages.add(error.msg);
      });
    }


(error) => {
        usedMessages.add(error.msg);
      }


(propName) => {
        if (propName === 'orphanErrors') {
          errors.orphanErrors.forEach((orphanError: IErrorObj) => {
            // Making use the error msg has not been displayed contextually
            // elsewhere.
            if (!usedMessages.has(orphanError.msg)) {
              orphanedErrors.add(orphanError.msg);
            }
          });
        }
        // If the error is not used and if the message is not used,
        // add it to orphan errors.
        else if (!usedErrors.hasOwnProperty(propName)) {
          errors[propName].forEach((error: IErrorObj) => {
            if (!usedMessages.has(error.msg)) {
              // If any error is not displayed contextually, and the error message
              // is not used by any other field, mark the error as orphan.
              orphanedErrors.add(error.msg);
            }
          });
        }
      }


(orphanError: IErrorObj) => {
            // Making use the error msg has not been displayed contextually
            // elsewhere.
            if (!usedMessages.has(orphanError.msg)) {
              orphanedErrors.add(orphanError.msg);
            }
          }


(error: IErrorObj) => {
            if (!usedMessages.has(error.msg)) {
              // If any error is not displayed contextually, and the error message
              // is not used by any other field, mark the error as orphan.
              orphanedErrors.add(error.msg);
            }
          }


(error: string) => (
              <li>{error}</li>
            )


export interface IConfigurationGroupProps extends WithStyles<typeof styles> {
  widgetJson?: IWidgetJson;
  pluginProperties: PluginProperties;
  values: Record<string, string>;
  inputSchema?: any;
  disabled?: boolean;
  onChange?: (values: Record<string, string>) => void;
  errors: {
    [property: string]: IErrorObj[];
  };
  validateProperties?: () => void;
}


type => Coffee


coffee => coffee.flavours


@Entity()
export class Flavour {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  name: string;

  @ManyToMany(type => Coffee, coffee => coffee.flavours)
  coffees: Coffee[]
}


// eslint-disable-next-line @typescript-eslint/no-empty-interface,@typescript-eslint/no-unused-vars
export interface AugmentedSubmittables<ApiType extends ApiTypes> { }


export interface SubmittableExtrinsicFunction<ApiType extends ApiTypes, A extends AnyTuple = AnyTuple> extends CallBase<A> {
  (...params: any[]): SubmittableExtrinsic<ApiType>;
}


export interface SubmittableModuleExtrinsics<ApiType extends ApiTypes> {
  // only with is<Type> augmentation
  [index: string]: SubmittableExtrinsicFunction<ApiType>; // | AugmentedIsSubmittable<ApiType, AnyTuple>;
}


export type AugmentedSubmittable<T extends AnyFunction, A extends AnyTuple = AnyTuple> = T & CallBase<A>;


async ({ where }) => {
  // TODO: in multi-tenant app, you must add validation to ensure correct tenant
  const intern = await db.intern.findFirst({
    where,
    select: {
      interests: true,
      jobApplications: true,
      user: true,
      id: true,
      bio: true,
      oneliner: true,
      userId: true,
    },
  })

  if (!intern) throw new NotFoundError()

  return intern
}


export class ExperimentalAssayViewValidator implements Validator<ExperimentalAssayView> {

  static INSTANCE = new ExperimentalAssayViewValidator();
  generalV = GeneralDescValidator.INSTANCE;
  contribV = ContributionDescValidator.INSTANCE;
  bioV = SimpleBioDescValidator.INSTANCE;

  protected constructor() {
  }

  validate(obj: ExperimentalAssayView): string[] {
    let err: string[] = [];

    err = err.concat(this.generalV.validate(obj.generalDesc),
      this.contribV.validate(obj.contributionDesc),
      this.bioV.validate(obj));

    return err;
  }
}


validate(obj: ExperimentalAssayView): string[] {
    let err: string[] = [];

    err = err.concat(this.generalV.validate(obj.generalDesc),
      this.contribV.validate(obj.contributionDesc),
      this.bioV.validate(obj));

    return err;
  }


async (): Promise<RepositoryInfo[]> => {
  if (process.env.NODE_ENV === 'development') {
    return repoMock
  }
  const info = getUserInfoToLocalStorage()

  if (!info) {
    return []
  }

  const { name, token } = info

  const query = `query {
    user(login: ${name}) {
      repositories(last: 100) {
        edges {
          node {
            id
            name
            url
          }
        }
      }
      starredRepositories(last: 100) {
        edges {
          node {
            id
            name
            url
          }
        }
      }
    }
  }`

  try {
    const response = await fetch('https://api.github.com/graphql', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Accept: 'application/json',
        Authorization: `Bearer ${token}`,
      },
      body: JSON.stringify({ query }),
    })
    const json = await response.json()
    const userInfo = json.data.user
    const userRepositories = userInfo.repositories.edges.map(
      ({ node }: { node: RepositoryInfo }) => node,
    )
    const starredRepositories = userInfo.starredRepositories.edges.map(
      ({ node }: { node: RepositoryInfo }) => node,
    )

    return userRepositories.concat(starredRepositories)
  } catch (e) {
    console.error(e)
    return []
  }
}


({ node }: { node: RepositoryInfo }) => node


export interface RepositoryInfo {
  id: string
  name: string
  url: string
}


details => details.post


image => image.post


metadata => metadata.post


information => information.post


author => author.post


@Entity("sample2_post")
export class Post {

    @PrimaryGeneratedColumn()
    id: number;

    @Column()
    title: string;

    @Column()
    text: string;

    // post has relation with category, however inverse relation is not set (category does not have relation with post set)
    @OneToOne(type => PostCategory, {
        cascadeInsert: true,
        cascadeUpdate: true,
        cascadeRemove: true
    })
    @JoinColumn()
    category: PostCategory;

    // post has relation with details. cascade inserts here means if new PostDetails instance will be set to this
    // relation it will be inserted automatically to the db when you save this Post entity
    @OneToOne(type => PostDetails, details => details.post, {
        cascadeInsert: true
    })
    @JoinColumn()
    details: PostDetails;

    // post has relation with details. cascade update here means if new PostDetail instance will be set to this relation
    // it will be inserted automatically to the db when you save this Post entity
    @OneToOne(type => PostImage, image => image.post, {
        cascadeUpdate: true
    })
    @JoinColumn()
    image: PostImage;

    // post has relation with details. cascade update here means if new PostDetail instance will be set to this relation
    // it will be inserted automatically to the db when you save this Post entity
    @OneToOne(type => PostMetadata, metadata => metadata.post, {
        cascadeRemove: true
    })
    @JoinColumn()
    metadata: PostMetadata|null;

    // post has relation with details. full cascades here
    @OneToOne(type => PostInformation, information => information.post, {
        cascadeInsert: true,
        cascadeUpdate: true,
        cascadeRemove: true
    })
    @JoinColumn()
    information: PostInformation;

    // post has relation with details. not cascades here. means cannot be persisted, updated or removed
    @OneToOne(type => PostAuthor, author => author.post)
    @JoinColumn()
    author: PostAuthor;

}


ngOnInit() {
        this.model = [
            {
                label: 'Home',
                items:[
                    {label: 'Dashboard',icon: 'pi pi-fw pi-home', routerLink: ['/']}
                ]
            },
            {
                label: '管理',
                items: [
                    {label: '使用者', icon: 'pi pi-fw pi-user-edit', routerLink: ['/pages/user']},
                ]
            },
            {
                label: 'UI Components',
                items: [
                    {label: 'Form Layout', icon: 'pi pi-fw pi-id-card', routerLink: ['/uikit/formlayout']},
                    {label: 'Input', icon: 'pi pi-fw pi-check-square', routerLink: ['/uikit/input']},
                    {label: 'Float Label', icon: 'pi pi-fw pi-bookmark', routerLink: ['/uikit/floatlabel']},
                    {label: 'Invalid State', icon: 'pi pi-fw pi-exclamation-circle', routerLink: ['/uikit/invalidstate']},
                    {label: 'Button', icon: 'pi pi-fw pi-mobile', routerLink: ['/uikit/button'], class: 'rotated-icon'},
                    {label: 'Table', icon: 'pi pi-fw pi-table', routerLink: ['/uikit/table']},
                    {label: 'List', icon: 'pi pi-fw pi-list', routerLink: ['/uikit/list']},
                    {label: 'Tree', icon: 'pi pi-fw pi-share-alt', routerLink: ['/uikit/tree']},
                    {label: 'Panel', icon: 'pi pi-fw pi-tablet', routerLink: ['/uikit/panel']},
                    {label: 'Overlay', icon: 'pi pi-fw pi-clone', routerLink: ['/uikit/overlay']},
                    {label: 'Media', icon: 'pi pi-fw pi-image', routerLink: ['/uikit/media']},
                    {label: 'Menu', icon: 'pi pi-fw pi-bars', routerLink: ['/uikit/menu'], preventExact: true},
                    {label: 'Message', icon: 'pi pi-fw pi-comment', routerLink: ['/uikit/message']},
                    {label: 'File', icon: 'pi pi-fw pi-file', routerLink: ['/uikit/file']},
                    {label: 'Chart', icon: 'pi pi-fw pi-chart-bar', routerLink: ['/uikit/charts']},
                    {label: 'Misc', icon: 'pi pi-fw pi-circle', routerLink: ['/uikit/misc']}
                ]
            },
            {
                label:'Prime Blocks',
                items:[
                    {label: 'Free Blocks', icon: 'pi pi-fw pi-eye', routerLink: ['/blocks'], badge: 'NEW'},
                    {label: 'All Blocks', icon: 'pi pi-fw pi-globe', url: ['https://www.primefaces.org/primeblocks-ng'], target: '_blank'},
                ]
            },
            {label:'Utilities',
                items:[
                    {label: 'PrimeIcons', icon: 'pi pi-fw pi-prime', routerLink: ['/icons']},
                    {label: 'PrimeFlex', icon: 'pi pi-fw pi-desktop', url: ['https://www.primefaces.org/primeflex/'], target: '_blank'},
                ]
            },
            {
                label: 'Pages',
                items: [
                    {label: 'Crud', icon: 'pi pi-fw pi-user-edit', routerLink: ['/pages/crud']},
                    {label: 'Timeline', icon: 'pi pi-fw pi-calendar', routerLink: ['/pages/timeline']},
                    {label: 'Landing', icon: 'pi pi-fw pi-globe', routerLink: ['pages/landing']},
                    {label: 'Login', icon: 'pi pi-fw pi-sign-in', routerLink: ['pages/login']},
                    {label: 'Error', icon: 'pi pi-fw pi-times-circle', routerLink: ['pages/error']},
                    {label: 'Not Found', icon: 'pi pi-fw pi-exclamation-circle', routerLink: ['pages/notfound']},
                    {label: 'Access Denied', icon: 'pi pi-fw pi-lock', routerLink: ['pages/access']},
                    {label: 'Empty', icon: 'pi pi-fw pi-circle', routerLink: ['/pages/empty']}
                ]
            },
            {
                label: 'Hierarchy',
                items: [
                    {
                        label: 'Submenu 1', icon: 'pi pi-fw pi-bookmark',
                        items: [
                            {
                                label: 'Submenu 1.1', icon: 'pi pi-fw pi-bookmark',
                                items: [
                                    {label: 'Submenu 1.1.1', icon: 'pi pi-fw pi-bookmark'},
                                    {label: 'Submenu 1.1.2', icon: 'pi pi-fw pi-bookmark'},
                                    {label: 'Submenu 1.1.3', icon: 'pi pi-fw pi-bookmark'},
                                ]
                            },
                            {
                                label: 'Submenu 1.2', icon: 'pi pi-fw pi-bookmark',
                                items: [
                                    {label: 'Submenu 1.2.1', icon: 'pi pi-fw pi-bookmark'}
                                ]
                            },
                        ]
                    },
                    {
                        label: 'Submenu 2', icon: 'pi pi-fw pi-bookmark',
                        items: [
                            {
                                label: 'Submenu 2.1', icon: 'pi pi-fw pi-bookmark',
                                items: [
                                    {label: 'Submenu 2.1.1', icon: 'pi pi-fw pi-bookmark'},
                                    {label: 'Submenu 2.1.2', icon: 'pi pi-fw pi-bookmark'},
                                ]
                            },
                            {
                                label: 'Submenu 2.2', icon: 'pi pi-fw pi-bookmark',
                                items: [
                                    {label: 'Submenu 2.2.1', icon: 'pi pi-fw pi-bookmark'},
                                ]
                            },
                        ]
                    }
                ]
            },
            {
                label:'Get Started',
                items:[
                    {
                        label: 'Documentation', icon: 'pi pi-fw pi-question', routerLink: ['/documentation']
                    },
                    {
                        label: 'View Source', icon: 'pi pi-fw pi-search', url: ['https://github.com/primefaces/sakai-ng'], target: '_blank'
                    }
                ]
            }
        ];
    }


onKeydown(event: KeyboardEvent) {
        const nodeElement = (<HTMLDivElement> event.target);
        if (event.code === 'Enter' || event.code === 'Space') {
            nodeElement.click();
            event.preventDefault();
        }
    }


export interface GetExifReqBody {
    imgUrl: string;
}


/**
 * slug_cs will take envVar and then :
 * - replace any character by `-` except `0-9`, `a-z`, `.`, and `_`
 * - remove leading and trailing `-` character
 * - limit the string size to 63 characters
 * @param envVar to be slugged
 */
export function slug_cs(envVar: string): string {
  return trailHyphen(replaceAnyNonAlphanumericCharacter(envVar)).substring(
    0,
    MAX_SLUG_STRING_SIZE
  )
}


/**
 * slug will take envVar and then :
 * - put the variable content in lower case
 * - replace any character by `-` except `0-9`, `a-z`, `.`, and `_`
 * - remove leading and trailing `-` character
 * - limit the string size to 63 characters
 * @param envVar to be slugged
 */
export function slug(envVar: string): string {
  return slug_cs(envVar.toLowerCase())
}


/**
 * slugref_cs will take envVar and then :
 * - remove refs/(heads|tags|pull)/
 * - replace any character by `-` except `0-9`, `a-z`, `.`, and `_`
 * - remove leading and trailing `-` character
 * - limit the string size to 63 characters
 * @param envVar to be slugged
 */
export function slugref_cs(envVar: string): string {
  return slug_cs(removeRef(envVar))
}


/**
 * slugref will take envVar and then :
 * - remove refs/(heads|tags|pull)/
 * - put the variable content in lower case
 * - replace any character by `-` except `0-9`, `a-z`, `.`, and `_`
 * - remove leading and trailing `-` character
 * - limit the string size to 63 characters
 * @param envVar to be slugged
 */
export function slugref(envVar: string): string {
  return slugref_cs(envVar.toLowerCase())
}


/**
 * slugurl_cs will take envVar and then :
 * - replace any character by `-` except `0-9`, `a-z`
 * - remove leading and trailing `-` character
 * - limit the string size to 63 characters
 * @param envVar to be slugged
 */
export function slugurl_cs(envVar: string): string {
  return slug_cs(replaceAnyNonUrlCharactersWithHyphen(envVar))
}


/**
 * slugurl will take envVar and then :
 * - put the variable content in lower case
 * - replace any character by `-` except `0-9`, `a-z`
 * - remove leading and trailing `-` character
 * - limit the string size to 63 characters
 * @param envVar to be slugged
 */
export function slugurl(envVar: string): string {
  return slug(replaceAnyNonUrlCharactersWithHyphen(envVar))
}


/**
 * slugurlref_cs will take envVar and then :
 * - remove refs/(heads|tags|pull)/
 * - replace any character by `-` except `0-9`, `a-z`
 * - remove leading and trailing `-` character
 * - limit the string size to 63 characters
 * @param envVar to be slugged
 */
export function slugurlref_cs(envVar: string): string {
  return slugurl_cs(slugref_cs(envVar))
}


/**
 * slugurlref will take envVar and then :
 * - remove refs/(heads|tags|pull)/
 * - put the variable content in lower case
 * - replace any character by `-` except `0-9`, `a-z`
 * - remove leading and trailing `-` character
 * - limit the string size to 63 characters
 * @param envVar to be slugged
 */
export function slugurlref(envVar: string): string {
  return slugurl(slugref(envVar))
}


function trailHyphen(envVar: string): string {
  return envVar.replace(RegExp('^-*', 'g'), '').replace(RegExp('-*$', 'g'), '')
}


function replaceAnyNonAlphanumericCharacter(envVar: string): string {
  return envVar.replace(RegExp('[^a-zA-Z0-9._]', 'g'), '-')
}


function replaceAnyNonUrlCharactersWithHyphen(envVar: string): string {
  return envVar.replace(RegExp('[._]', 'g'), '-')
}


function removeRef(envVar: string): string {
  return envVar.replace(RegExp('^refs/(heads|tags|pull)/'), '')
}


user => {

      if(!user) { return null; }

      // Loads the post data
      if(id) { return this.db.document<PostData>(`users/${user.uid}/feed/${id}`).get(); }

      // Creates a new unique document id
      const newId = this.db.col(`users/${user.uid}/feed`).doc().id;

      // Returns an empty post
      return of({
        id: newId,
        tags: ['public'],
        author: user.uid,
        type: 'document', content: [{
          type: 'paragraph', content: [{
            type: 'text', value: ''
      }]}]} as PostData);
    }


/** Resolves the post document */
@Injectable()
export class PostResolver implements Resolve<PostData> {

  constructor(private auth: AuthService, private db: DatabaseService) { }

  /** Resolves the post content loading the requested id */
  public resolve(route: ActivatedRouteSnapshot): Observable<PostData> {

    // Resolves the id from the query parameter
    const id = route.queryParamMap.get('id');

    return this.auth.user$.pipe( take(1), switchMap( user => {

      if(!user) { return null; }

      // Loads the post data
      if(id) { return this.db.document<PostData>(`users/${user.uid}/feed/${id}`).get(); }

      // Creates a new unique document id
      const newId = this.db.col(`users/${user.uid}/feed`).doc().id;

      // Returns an empty post
      return of({
        id: newId,
        tags: ['public'],
        author: user.uid,
        type: 'document', content: [{
          type: 'paragraph', content: [{
            type: 'text', value: ''
      }]}]} as PostData);
    }));
  }
}


/** Resolves the post content loading the requested id */
public resolve(route: ActivatedRouteSnapshot): Observable<PostData> {

    // Resolves the id from the query parameter
    const id = route.queryParamMap.get('id');

    return this.auth.user$.pipe( take(1), switchMap( user => {

      if(!user) { return null; }

      // Loads the post data
      if(id) { return this.db.document<PostData>(`users/${user.uid}/feed/${id}`).get(); }

      // Creates a new unique document id
      const newId = this.db.col(`users/${user.uid}/feed`).doc().id;

      // Returns an empty post
      return of({
        id: newId,
        tags: ['public'],
        author: user.uid,
        type: 'document', content: [{
          type: 'paragraph', content: [{
            type: 'text', value: ''
      }]}]} as PostData);
    }));
  }


options => source =>
    source.pipe(
      map(data => {
        const hasValidConfig = Object.keys(options.fields).find(
          name => options.fields[name].operation === GroupByOperationID.groupBy
        );

        if (!hasValidConfig) {
          return data;
        }

        const processed: DataFrame[] = [];

        for (const frame of data) {
          const groupByFields: Field[] = [];

          for (const field of frame.fields) {
            if (shouldGroupOnField(field, options)) {
              groupByFields.push(field);
            }
          }

          if (groupByFields.length === 0) {
            continue; // No group by field in this frame, ignore the frame
          }

          // Group the values by fields and groups so we can get all values for a
          // group for a given field.
          const valuesByGroupKey: Record<string, Record<string, MutableField>> = {};
          for (let rowIndex = 0; rowIndex < frame.length; rowIndex++) {
            const groupKey = String(groupByFields.map(field => field.values.get(rowIndex)));
            const valuesByField = valuesByGroupKey[groupKey] ?? {};

            if (!valuesByGroupKey[groupKey]) {
              valuesByGroupKey[groupKey] = valuesByField;
            }

            for (let field of frame.fields) {
              const fieldName = getFieldDisplayName(field);

              if (!valuesByField[fieldName]) {
                valuesByField[fieldName] = {
                  name: fieldName,
                  type: field.type,
                  config: { ...field.config },
                  values: new ArrayVector(),
                };
              }

              valuesByField[fieldName].values.add(field.values.get(rowIndex));
            }
          }

          const fields: Field[] = [];
          const groupKeys = Object.keys(valuesByGroupKey);

          for (const field of groupByFields) {
            const values = new ArrayVector();
            const fieldName = getFieldDisplayName(field);

            for (let key of groupKeys) {
              const valuesByField = valuesByGroupKey[key];
              values.add(valuesByField[fieldName].values.get(0));
            }

            fields.push({
              name: field.name,
              type: field.type,
              config: {
                ...field.config,
              },
              values: values,
            });
          }

          // Then for each calculations configured, compute and add a new field (column)
          for (const field of frame.fields) {
            if (!shouldCalculateField(field, options)) {
              continue;
            }

            const fieldName = getFieldDisplayName(field);
            const aggregations = options.fields[fieldName].aggregations;
            const valuesByAggregation: Record<string, any[]> = {};

            for (const groupKey of groupKeys) {
              const fieldWithValuesForGroup = valuesByGroupKey[groupKey][fieldName];
              const results = reduceField({
                field: fieldWithValuesForGroup,
                reducers: aggregations,
              });

              for (const aggregation of aggregations) {
                if (!Array.isArray(valuesByAggregation[aggregation])) {
                  valuesByAggregation[aggregation] = [];
                }
                valuesByAggregation[aggregation].push(results[aggregation]);
              }
            }

            for (const aggregation of aggregations) {
              const aggregationField: Field = {
                name: `${fieldName} (${aggregation})`,
                values: new ArrayVector(valuesByAggregation[aggregation]),
                type: FieldType.other,
                config: {},
              };

              aggregationField.type = detectFieldType(aggregation, field, aggregationField);
              fields.push(aggregationField);
            }
          }

          processed.push({
            fields,
            length: groupKeys.length,
          });
        }

        return processed;
      })
    )


source =>
    source.pipe(
      map(data => {
        const hasValidConfig = Object.keys(options.fields).find(
          name => options.fields[name].operation === GroupByOperationID.groupBy
        );

        if (!hasValidConfig) {
          return data;
        }

        const processed: DataFrame[] = [];

        for (const frame of data) {
          const groupByFields: Field[] = [];

          for (const field of frame.fields) {
            if (shouldGroupOnField(field, options)) {
              groupByFields.push(field);
            }
          }

          if (groupByFields.length === 0) {
            continue; // No group by field in this frame, ignore the frame
          }

          // Group the values by fields and groups so we can get all values for a
          // group for a given field.
          const valuesByGroupKey: Record<string, Record<string, MutableField>> = {};
          for (let rowIndex = 0; rowIndex < frame.length; rowIndex++) {
            const groupKey = String(groupByFields.map(field => field.values.get(rowIndex)));
            const valuesByField = valuesByGroupKey[groupKey] ?? {};

            if (!valuesByGroupKey[groupKey]) {
              valuesByGroupKey[groupKey] = valuesByField;
            }

            for (let field of frame.fields) {
              const fieldName = getFieldDisplayName(field);

              if (!valuesByField[fieldName]) {
                valuesByField[fieldName] = {
                  name: fieldName,
                  type: field.type,
                  config: { ...field.config },
                  values: new ArrayVector(),
                };
              }

              valuesByField[fieldName].values.add(field.values.get(rowIndex));
            }
          }

          const fields: Field[] = [];
          const groupKeys = Object.keys(valuesByGroupKey);

          for (const field of groupByFields) {
            const values = new ArrayVector();
            const fieldName = getFieldDisplayName(field);

            for (let key of groupKeys) {
              const valuesByField = valuesByGroupKey[key];
              values.add(valuesByField[fieldName].values.get(0));
            }

            fields.push({
              name: field.name,
              type: field.type,
              config: {
                ...field.config,
              },
              values: values,
            });
          }

          // Then for each calculations configured, compute and add a new field (column)
          for (const field of frame.fields) {
            if (!shouldCalculateField(field, options)) {
              continue;
            }

            const fieldName = getFieldDisplayName(field);
            const aggregations = options.fields[fieldName].aggregations;
            const valuesByAggregation: Record<string, any[]> = {};

            for (const groupKey of groupKeys) {
              const fieldWithValuesForGroup = valuesByGroupKey[groupKey][fieldName];
              const results = reduceField({
                field: fieldWithValuesForGroup,
                reducers: aggregations,
              });

              for (const aggregation of aggregations) {
                if (!Array.isArray(valuesByAggregation[aggregation])) {
                  valuesByAggregation[aggregation] = [];
                }
                valuesByAggregation[aggregation].push(results[aggregation]);
              }
            }

            for (const aggregation of aggregations) {
              const aggregationField: Field = {
                name: `${fieldName} (${aggregation})`,
                values: new ArrayVector(valuesByAggregation[aggregation]),
                type: FieldType.other,
                config: {},
              };

              aggregationField.type = detectFieldType(aggregation, field, aggregationField);
              fields.push(aggregationField);
            }
          }

          processed.push({
            fields,
            length: groupKeys.length,
          });
        }

        return processed;
      })
    )


data => {
        const hasValidConfig = Object.keys(options.fields).find(
          name => options.fields[name].operation === GroupByOperationID.groupBy
        );

        if (!hasValidConfig) {
          return data;
        }

        const processed: DataFrame[] = [];

        for (const frame of data) {
          const groupByFields: Field[] = [];

          for (const field of frame.fields) {
            if (shouldGroupOnField(field, options)) {
              groupByFields.push(field);
            }
          }

          if (groupByFields.length === 0) {
            continue; // No group by field in this frame, ignore the frame
          }

          // Group the values by fields and groups so we can get all values for a
          // group for a given field.
          const valuesByGroupKey: Record<string, Record<string, MutableField>> = {};
          for (let rowIndex = 0; rowIndex < frame.length; rowIndex++) {
            const groupKey = String(groupByFields.map(field => field.values.get(rowIndex)));
            const valuesByField = valuesByGroupKey[groupKey] ?? {};

            if (!valuesByGroupKey[groupKey]) {
              valuesByGroupKey[groupKey] = valuesByField;
            }

            for (let field of frame.fields) {
              const fieldName = getFieldDisplayName(field);

              if (!valuesByField[fieldName]) {
                valuesByField[fieldName] = {
                  name: fieldName,
                  type: field.type,
                  config: { ...field.config },
                  values: new ArrayVector(),
                };
              }

              valuesByField[fieldName].values.add(field.values.get(rowIndex));
            }
          }

          const fields: Field[] = [];
          const groupKeys = Object.keys(valuesByGroupKey);

          for (const field of groupByFields) {
            const values = new ArrayVector();
            const fieldName = getFieldDisplayName(field);

            for (let key of groupKeys) {
              const valuesByField = valuesByGroupKey[key];
              values.add(valuesByField[fieldName].values.get(0));
            }

            fields.push({
              name: field.name,
              type: field.type,
              config: {
                ...field.config,
              },
              values: values,
            });
          }

          // Then for each calculations configured, compute and add a new field (column)
          for (const field of frame.fields) {
            if (!shouldCalculateField(field, options)) {
              continue;
            }

            const fieldName = getFieldDisplayName(field);
            const aggregations = options.fields[fieldName].aggregations;
            const valuesByAggregation: Record<string, any[]> = {};

            for (const groupKey of groupKeys) {
              const fieldWithValuesForGroup = valuesByGroupKey[groupKey][fieldName];
              const results = reduceField({
                field: fieldWithValuesForGroup,
                reducers: aggregations,
              });

              for (const aggregation of aggregations) {
                if (!Array.isArray(valuesByAggregation[aggregation])) {
                  valuesByAggregation[aggregation] = [];
                }
                valuesByAggregation[aggregation].push(results[aggregation]);
              }
            }

            for (const aggregation of aggregations) {
              const aggregationField: Field = {
                name: `${fieldName} (${aggregation})`,
                values: new ArrayVector(valuesByAggregation[aggregation]),
                type: FieldType.other,
                config: {},
              };

              aggregationField.type = detectFieldType(aggregation, field, aggregationField);
              fields.push(aggregationField);
            }
          }

          processed.push({
            fields,
            length: groupKeys.length,
          });
        }

        return processed;
      }


name => options.fields[name].operation === GroupByOperationID.groupBy


field => field.values.get(rowIndex)


(field: Field, options: GroupByTransformerOptions): boolean => {
  const fieldName = getFieldDisplayName(field);
  return options?.fields[fieldName]?.operation === GroupByOperationID.groupBy;
}


(field: Field, options: GroupByTransformerOptions): boolean => {
  const fieldName = getFieldDisplayName(field);
  return (
    options?.fields[fieldName]?.operation === GroupByOperationID.aggregate &&
    Array.isArray(options?.fields[fieldName].aggregations) &&
    options?.fields[fieldName].aggregations.length > 0
  );
}


(aggregation: string, sourceField: Field, targetField: Field): FieldType => {
  switch (aggregation) {
    case ReducerID.allIsNull:
      return FieldType.boolean;
    case ReducerID.last:
    case ReducerID.lastNotNull:
    case ReducerID.first:
    case ReducerID.firstNotNull:
      return sourceField.type;
    default:
      return guessFieldTypeForField(targetField) ?? FieldType.string;
  }
}


export interface GroupByFieldOptions {
  aggregations: ReducerID[];
  operation: GroupByOperationID | null;
}


export interface GroupByTransformerOptions {
  fields: Record<string, GroupByFieldOptions>;
}


export enum GroupByOperationID {
  aggregate = 'aggregate',
  groupBy = 'groupby',
}


class ModifyProperties {
    private projectConfig: egret.EgretProperty
    constructor() {
    }

    initProperties() {
        var projectPath = file.joinPath(egret.args.projectDir, "egretProperties.json");
        this.projectConfig = JSON.parse(file.read(projectPath));
    }

    save(version?: string) {
        if (version) {
            this.projectConfig.egret_version = version;
        }

        var projectPath = file.joinPath(egret.args.projectDir, "egretProperties.json");
        var content = JSON.stringify(this.projectConfig, null, "\t");
        file.save(projectPath, content);
    }

    upgradeModulePath() {
        let config = this.projectConfig
        for (let m of config.modules) {
            if (!m.path) {
                m.path = '${EGRET_APP_DATA}/' + config.egret_version;
            }
        }
    }
}


initProperties() {
        var projectPath = file.joinPath(egret.args.projectDir, "egretProperties.json");
        this.projectConfig = JSON.parse(file.read(projectPath));
    }


save(version?: string) {
        if (version) {
            this.projectConfig.egret_version = version;
        }

        var projectPath = file.joinPath(egret.args.projectDir, "egretProperties.json");
        var content = JSON.stringify(this.projectConfig, null, "\t");
        file.save(projectPath, content);
    }


upgradeModulePath() {
        let config = this.projectConfig
        for (let m of config.modules) {
            if (!m.path) {
                m.path = '${EGRET_APP_DATA}/' + config.egret_version;
            }
        }
    }


/**
 *
Contains the response to a successful CreatePolicy request.

 */
export interface CreatePolicyOutput extends __aws_sdk_types.MetadataBearer {
  /**
   *
A structure containing details about the new policy.

   */
  Policy?: _UnmarshalledPolicy;

  /**
   * Metadata about the response received, including the HTTP status code, HTTP headers, and any request identifiers recognized by the SDK.
   */
  $metadata: __aws_sdk_types.ResponseMetadata;
}


@NgModule({
  declarations: [
    AppComponent,
    FilterComponent,
    ScatterplotPatrimonioComponent,
    ResumoCandidatoComponent,
    JoyplotEstadosComponent,
    FactSheetComponent,
    AboutComponent,
    HomeComponent,
    ReadmeComponent,
    Top10Component,
    NoDataDialogComponent
    ],
  imports: [
    BrowserAnimationsModule,
    FlexLayoutModule,
    BrowserModule,
    FormsModule,
    ReactiveFormsModule,
    MatToolbarModule,
    MatTabsModule,
    MatButtonModule,
    MatIconModule,
    MatTooltipModule,
    MatCardModule,
    MatSidenavModule,
    MatCheckboxModule,
    MatOptionModule,
    MatSelectModule,
    MatAutocompleteModule,
    MatInputModule,
    MatSnackBarModule,
    MatSlideToggleModule,
    MatListModule,
    HttpClientModule,
    MatDialogModule,
    MatTableModule,
    MatSortModule,
    MatPaginatorModule,
    MatExpansionModule,
    AppRoutingModule
  ],
  providers: [
    HttpClientModule,
    RequestService,
    GlobalService,
    DataService,
    UtilsService,
    AlertService,
    CandidatoService,
    VisPatrimonioService,
    PermalinkService
  ],
  bootstrap: [AppComponent],
  entryComponents: [AboutComponent, ReadmeComponent, NoDataDialogComponent]
})
export class AppModule {}


/**
 * Create macro plugin.
 *
 * For example,
 * ```typescript
 * // vite.config.ts
 *
 * export default defineConfig({
 *   plugins: [
 *     createMacroPlugin({ ... })
 *       .use(provideSomeMacros({ ... }))
 *   ],
 * })
 * ```
 */
export function createMacroPlugin(
  /* istanbul ignore next */
  options: MacroPluginOptions = {}
): MacroPlugin {
  const {
    exclude,
    include,
    maxTraversals,
    typesPath,
    dev,
    ssr,
    watcherOptions,
    parserPlugins,
  } = options

  const uninstantiatedProviders: MacroProvider[] = []

  let runtime: Runtime | undefined

  const plugin: MacroPlugin = {
    use(...sources) {
      uninstantiatedProviders.push(...sources)
      return plugin
    },
    name: 'vite-plugin-macro',
    enforce: 'pre',
    configResolved: async (config) => {
      // create env
      const env = createEnvContext(
        dev ?? !config.isProduction,
        ssr ?? !!config.build.ssr,
        watcherOptions
      )

      // init runtime
      runtime = createRuntime(env, {
        filter: { exclude, include },
        transformer: { maxTraversals, parserPlugins },
      })

      // add providers
      uninstantiatedProviders.forEach((provider) => {
        runtime!.appendProvider(provider)
      })

      // call onStart hook and render types
      await Promise.all([
        runtime!.start(),
        runtime!.renderTypes(
          /* istanbul ignore next */
          typesPath || join(env.projectPath[0], 'macros.d.ts')
        ),
      ])
    },
    configureServer: async (server) => {
      ;(runtime!.internal.env.modules as InternalModules).__setServer(server)
    },
    resolveId: (id) => runtime?.resolveId(id),
    load: (id) => runtime?.load(id),
    transform: async (code, id) => {
      if (!(await runtime?.filter(id))) return
      const result = await runtime?.transform(code, id)
      return result && { code: result, map: null }
    },
    buildEnd: async () => {
      await runtime!.stop()
    },
  }

  return plugin
}


async (config) => {
      // create env
      const env = createEnvContext(
        dev ?? !config.isProduction,
        ssr ?? !!config.build.ssr,
        watcherOptions
      )

      // init runtime
      runtime = createRuntime(env, {
        filter: { exclude, include },
        transformer: { maxTraversals, parserPlugins },
      })

      // add providers
      uninstantiatedProviders.forEach((provider) => {
        runtime!.appendProvider(provider)
      })

      // call onStart hook and render types
      await Promise.all([
        runtime!.start(),
        runtime!.renderTypes(
          /* istanbul ignore next */
          typesPath || join(env.projectPath[0], 'macros.d.ts')
        ),
      ])
    }


(provider) => {
        runtime!.appendProvider(provider)
      }


async (server) => {
      ;(runtime!.internal.env.modules as InternalModules).__setServer(server)
    }


(id) => runtime?.resolveId(id)


(id) => runtime?.load(id)


async (code, id) => {
      if (!(await runtime?.filter(id))) return
      const result = await runtime?.transform(code, id)
      return result && { code: result, map: null }
    }


async () => {
      await runtime!.stop()
    }


export type MacroPlugin = Plugin & {
  /**
   * Register macro providers to this macro manager so that
   * all macros in providers and plugins share the same runtime.
   *
   * For macro plugins:
   *  > Some options like `maxTraversals` or `typesPath` will be overridden by
   *  > manager's, `parserPlugins` will be merged with the manager's one.
   *  >
   *  > After registered, the original macro plugin will be attached to the manager,
   *  > which means no need to add the plugin to Vite/Rollup 's plugins array again.
   * @param sources macro providers or plugins.
   */
  use(...sources: MacroProvider[]): MacroPlugin
}


export type MacroPluginOptions = FilterOptions &
  TransformerOptions & {
    /**
     * The path of the automatically generated type declaration file.
     *
     * @default '<projectDir>/macros.d.ts'
     */
    typesPath?: string

    /**
     * Is in dev mode.
     *
     * @default mode !== 'production'
     * @see https://vitejs.dev/guide/env-and-mode.html#modes
     */
    dev?: boolean

    /**
     * Is in SSR mode.
     *
     * @default whether there is an SSR configuration
     * @see https://vitejs.dev/guide/ssr.html
     */
    ssr?: boolean

    /**
     * Configure chokidar FSWatcher.
     *
     * @see https://github.com/paulmillr/chokidar#api
     */
    watcherOptions?: WatchOptions
  }


use(...sources) {
      uninstantiatedProviders.push(...sources)
      return plugin
    }


export default function TVSeriesSearch({query, onClick}: TVSeriesSearchProps) {
  const classes = useStyles();
  const [shows, setShows] = React.useState<Array<TVSeriesPreview>>([]);

  React.useEffect(()=> {
    if(query) {
      fetchShowsSearch(query)
        .then(foundShows=> setShows(foundShows));
      return;
    }
    setShows([]);
  }, [query]);

  return (
    <div className={classes.results}>
      {shows.map(show=>
        <Preview
          key={show.id}
          onClick={()=> onClick(show.id)}
          image={show.image?.medium}
          name={show.name}
          status={show.status}
          network={show.network}/>
      )}


({palette})=> ({
  results: {
    margin: "20px 0",
    display: "flex",
    overflow: "auto",
  },
})


()=> {
    if(query) {
      fetchShowsSearch(query)
        .then(foundShows=> setShows(foundShows));
      return;
    }
    setShows([]);
  }


foundShows=> setShows(foundShows)


show=>
        <Preview
          key


interface TVSeriesSearchProps {
  query: string;
  onClick: (seriesID: number)=> void;
}


(first, second) =>
      _.date.sortNewToOld(first.expiresDate, second.expiresDate)


(transaction) => transaction.offerCodeRefName


(transaction) => transaction.offerCodeRefName!


(transaction) => transaction.promotionalOfferId


(transaction) => transaction.promotionalOfferId!


/**
 * Creates a parsed subscription from a collection of parsed transactions.
 *
 * @internal
 */
export class ParsedSubscription {
  public allTransactions: AutoRenewableSubscriptionTransaction[]
  public latestExpireDateTransaction: AutoRenewableSubscriptionTransaction
  public renewalInfo?: ApplePendingRenewalInfo

  constructor(
    public originalTransactionId: string,
    public isEligibleIntroductoryOffer: boolean,
    transactions: AutoRenewableSubscriptionTransaction[], // the transactions for the originalTransactionId.
    renewalInfo?: ApplePendingRenewalInfo
  ) {
    if (transactions.length <= 0)
      throw new InternalError(
        "PrerequisiteNotMet",
        "It's assumed that a subscription is not created if there are no transactions recorded for it."
      )

    this.allTransactions = transactions.sort((first, second) =>
      _.date.sortNewToOld(first.expiresDate, second.expiresDate)
    )
    this.latestExpireDateTransaction = this.allTransactions[0] // there will be at least 1 transaction or there would not be an entry in the Map<>.
    this.renewalInfo = renewalInfo
  }

  parseSubscription(): AutoRenewableSubscription {
    const issues = this.issues()

    return {
      currentProductId: this.latestExpireDateTransaction.productId,
      originalTransactionId: this.originalTransactionId,
      subscriptionGroup: this.latestExpireDateTransaction.subscriptionGroupId,
      isInFreeTrialPeriod: this.latestExpireDateTransaction.inTrialPeriod,
      isEligibleIntroductoryOffer: this.isEligibleIntroductoryOffer,
      currentEndDate: this.currentEndDate(),
      status: this.status(),
      usedOfferCodes: this.usedOfferCodes(),
      usedPromotionalOffers: this.usedPromotionalOffers(),
      allTransactions: this.allTransactions,
      latestExpireDateTransaction: this.latestExpireDateTransaction,
      willAutoRenew: this.willAutoRenew(),
      willDowngradeToProductId: this.willDowngradeToProductId(),
      issuesStrings: this.issuesStrings(issues),
      issues,
      priceIncreaseAccepted: this.priceIncreaseAccepted(),
      gracePeriodExpireDate: this.gracePeriodExpireDate(),
      cancelledDate: this.cancelledDate(),
      expireDate: this.expireDate(),
      isInBillingRetry: this.isInBillingRetry()
    }
  }

  usedOfferCodes(): string[] {
    const set = new Set(this.allTransactions
      .filter((transaction) => transaction.offerCodeRefName)
      .map((transaction) => transaction.offerCodeRefName!))

    return [...set]
  }

  usedPromotionalOffers(): string[] {
    const set = new Set(this.allTransactions
      .filter((transaction) => transaction.promotionalOfferId)
      .map((transaction) => transaction.promotionalOfferId!))

    return [...set]
  }

  priceIncreaseAccepted(): boolean | undefined {
    let priceIncreaseAccepted: boolean | undefined
    if (this.renewalInfo?.price_consent_status) {
      priceIncreaseAccepted = this.renewalInfo.price_consent_status === "1"
    }

    return priceIncreaseAccepted
  }

  issues(): AutoRenewableSubscriptionIssues {
    return {
      notYetAcceptingPriceIncrease: this.priceIncreaseAccepted() === false,
      billingIssue: this.renewalInfo?.expiration_intent === "2" || this.gracePeriodExpireDate() !== undefined,
      willVoluntaryCancel: this.renewalInfo !== undefined && !this.willAutoRenew()
    }
  }

  issuesStrings(statuses: AutoRenewableSubscriptionIssues): AutoRenewableSubscriptionIssueString[] {
    const strings: AutoRenewableSubscriptionIssueString[] = []

    if (statuses.notYetAcceptingPriceIncrease) strings.push("not_yet_accepting_price_increase")
    if (statuses.billingIssue) strings.push("billing_issue")
    if (statuses.willVoluntaryCancel) strings.push("will_voluntary_cancel")

    return strings
  }

  willAutoRenew(): boolean {
    return this.renewalInfo?.auto_renew_status === "1" || false
  }

  gracePeriodExpireDate(): Date | undefined {
    if (this.renewalInfo?.grace_period_expires_date_ms) return new Date(parseInt(this.renewalInfo.grace_period_expires_date_ms!))

    return undefined
  }

  expireDate(): Date {
    return this.latestExpireDateTransaction.expiresDate
  }

  currentEndDate(): Date {
    return this.cancelledDate() || this.gracePeriodExpireDate() || this.expireDate()
  }

  willDowngradeToProductId(): string | undefined {
    return this.renewalInfo?.auto_renew_product_id
  }

  isInBillingRetry(): boolean {
    return this.renewalInfo?.is_in_billing_retry_period === "1" || false
  }

  cancelledDate(): Date | undefined {
    return this.latestExpireDateTransaction.cancelledDate
  }

  status(): AutoRenewableSubscriptionStatus {
    const inGracePeriod = this.renewalInfo?.grace_period_expires_date !== undefined || false
    if (inGracePeriod) return "grace_period"

    const isInBillingRetry = this.renewalInfo?.is_in_billing_retry_period === "1" || false
    if (isInBillingRetry) return "billing_retry_period"

    if (this.renewalInfo?.expiration_intent !== undefined) {
      const involuntaryCancelled = this.renewalInfo.expiration_intent === "2" || this.renewalInfo.expiration_intent === "4"
      if (involuntaryCancelled) return "involuntary_cancel"

      const voluntaryCancelled = this.renewalInfo.expiration_intent === "1" || false
      if (voluntaryCancelled) return "voluntary_cancel"

      return "other_not_active"
    }

    if (this.latestExpireDateTransaction.cancelledDate !== undefined || this.latestExpireDateTransaction.refundReason !== undefined) {
      const refunded = this.latestExpireDateTransaction.refundReason === "app_issue" || this.latestExpireDateTransaction.refundReason === "other"
      if (refunded) return "refunded"

      const upgraded = this.latestExpireDateTransaction.refundReason === "upgrade"
      if (upgraded) return "upgraded"

      return "other_not_active"
    }

    // Note: this should be caught by the "expiration_intent" of the pending renewal object but just in case, we want to catch when the customer has gone beyond the billing retry period and there is still a billing issue.
    if (this.latestExpireDateTransaction.expiresDate.getTime() < new Date().getTime()) {
      return "voluntary_cancel"
    }

    return "active"
  }
}


parseSubscription(): AutoRenewableSubscription {
    const issues = this.issues()

    return {
      currentProductId: this.latestExpireDateTransaction.productId,
      originalTransactionId: this.originalTransactionId,
      subscriptionGroup: this.latestExpireDateTransaction.subscriptionGroupId,
      isInFreeTrialPeriod: this.latestExpireDateTransaction.inTrialPeriod,
      isEligibleIntroductoryOffer: this.isEligibleIntroductoryOffer,
      currentEndDate: this.currentEndDate(),
      status: this.status(),
      usedOfferCodes: this.usedOfferCodes(),
      usedPromotionalOffers: this.usedPromotionalOffers(),
      allTransactions: this.allTransactions,
      latestExpireDateTransaction: this.latestExpireDateTransaction,
      willAutoRenew: this.willAutoRenew(),
      willDowngradeToProductId: this.willDowngradeToProductId(),
      issuesStrings: this.issuesStrings(issues),
      issues,
      priceIncreaseAccepted: this.priceIncreaseAccepted(),
      gracePeriodExpireDate: this.gracePeriodExpireDate(),
      cancelledDate: this.cancelledDate(),
      expireDate: this.expireDate(),
      isInBillingRetry: this.isInBillingRetry()
    }
  }


usedOfferCodes(): string[] {
    const set = new Set(this.allTransactions
      .filter((transaction) => transaction.offerCodeRefName)
      .map((transaction) => transaction.offerCodeRefName!))

    return [...set]
  }


usedPromotionalOffers(): string[] {
    const set = new Set(this.allTransactions
      .filter((transaction) => transaction.promotionalOfferId)
      .map((transaction) => transaction.promotionalOfferId!))

    return [...set]
  }


priceIncreaseAccepted(): boolean | undefined {
    let priceIncreaseAccepted: boolean | undefined
    if (this.renewalInfo?.price_consent_status) {
      priceIncreaseAccepted = this.renewalInfo.price_consent_status === "1"
    }

    return priceIncreaseAccepted
  }


issues(): AutoRenewableSubscriptionIssues {
    return {
      notYetAcceptingPriceIncrease: this.priceIncreaseAccepted() === false,
      billingIssue: this.renewalInfo?.expiration_intent === "2" || this.gracePeriodExpireDate() !== undefined,
      willVoluntaryCancel: this.renewalInfo !== undefined && !this.willAutoRenew()
    }
  }


issuesStrings(statuses: AutoRenewableSubscriptionIssues): AutoRenewableSubscriptionIssueString[] {
    const strings: AutoRenewableSubscriptionIssueString[] = []

    if (statuses.notYetAcceptingPriceIncrease) strings.push("not_yet_accepting_price_increase")
    if (statuses.billingIssue) strings.push("billing_issue")
    if (statuses.willVoluntaryCancel) strings.push("will_voluntary_cancel")

    return strings
  }


willAutoRenew(): boolean {
    return this.renewalInfo?.auto_renew_status === "1" || false
  }


gracePeriodExpireDate(): Date | undefined {
    if (this.renewalInfo?.grace_period_expires_date_ms) return new Date(parseInt(this.renewalInfo.grace_period_expires_date_ms!))

    return undefined
  }


expireDate(): Date {
    return this.latestExpireDateTransaction.expiresDate
  }


currentEndDate(): Date {
    return this.cancelledDate() || this.gracePeriodExpireDate() || this.expireDate()
  }


willDowngradeToProductId(): string | undefined {
    return this.renewalInfo?.auto_renew_product_id
  }


isInBillingRetry(): boolean {
    return this.renewalInfo?.is_in_billing_retry_period === "1" || false
  }


cancelledDate(): Date | undefined {
    return this.latestExpireDateTransaction.cancelledDate
  }


status(): AutoRenewableSubscriptionStatus {
    const inGracePeriod = this.renewalInfo?.grace_period_expires_date !== undefined || false
    if (inGracePeriod) return "grace_period"

    const isInBillingRetry = this.renewalInfo?.is_in_billing_retry_period === "1" || false
    if (isInBillingRetry) return "billing_retry_period"

    if (this.renewalInfo?.expiration_intent !== undefined) {
      const involuntaryCancelled = this.renewalInfo.expiration_intent === "2" || this.renewalInfo.expiration_intent === "4"
      if (involuntaryCancelled) return "involuntary_cancel"

      const voluntaryCancelled = this.renewalInfo.expiration_intent === "1" || false
      if (voluntaryCancelled) return "voluntary_cancel"

      return "other_not_active"
    }

    if (this.latestExpireDateTransaction.cancelledDate !== undefined || this.latestExpireDateTransaction.refundReason !== undefined) {
      const refunded = this.latestExpireDateTransaction.refundReason === "app_issue" || this.latestExpireDateTransaction.refundReason === "other"
      if (refunded) return "refunded"

      const upgraded = this.latestExpireDateTransaction.refundReason === "upgrade"
      if (upgraded) return "upgraded"

      return "other_not_active"
    }

    // Note: this should be caught by the "expiration_intent" of the pending renewal object but just in case, we want to catch when the customer has gone beyond the billing retry period and there is still a billing issue.
    if (this.latestExpireDateTransaction.expiresDate.getTime() < new Date().getTime()) {
      return "voluntary_cancel"
    }

    return "active"
  }


() => {
      this.isEE = true;
    }


() => {
      this.isEE = false;
    }


@Component({
  selector: 'importmanager',
  templateUrl: "./importmanager.component.html",
  styles: [
    '.vertical-van-tab {padding-left: 0px}',
    '.tabs-left {border-bottom: none; padding-top: 2px; border-right: 1px solid #ddd;}',
    '.tabs-left>li {float: none; margin-bottom: 2px;}',
    '.tabs-left>li {margin-right: -1px;}',
    '.tabs-left>li.active>a, .tabs-left>li.active>a:hover, .tabs-left>li.active>a:focus {border-bottom-color: #ddd; border-right-color: transparent;}',
    '.tabs-left>li>a {border-radius: 4px 0 0 4px; margin-right: 0; padding-left: 10px; display:block;}',

    '.not-allowed {opacity: 0.3; cursor: not-allowed;}',
    '.importer-description {margin: 20px; margin-bottom: 40px; margin-left: 15px;}',
    'img {float: left; border: none; margin: 15px;}',
    'li>a {font-size: 15px;}',
    'ul {list-style-type: none}'
  ]
})

class ImportManagerComponent {

  private currentTab = 'home';
  private isEE;
  private hints;

  constructor(private agentService: AgentService) {
    agentService.isActive().then(() => {
      this.isEE = true;
    }).catch(() => {
      this.isEE = false;
    })

    this.hints = {
      importDbFromSQL: "This is the Enterprise Edition, so you can migrate and synch your SQL database with Teleporter.",
      downloadEE: "You can migrate your SQL database with Teleporter but you cannot synch it as this is the Community Edition.
 " +
      "You can enjoy all the features simply downloading the Enterprise Edition."
    }
  }

  enablePopovers() {
    (<any>$('[data-toggle="popover"]')).popover({
      title: '',
      placement: 'right',
      trigger: 'focus'
    });
  }

  setTab(importer) {
    this.currentTab = importer;
  }

  isActive(tabName) {
    if(tabName === 'home' && this.currentTab === 'home') {
      return 'active';
    }
    else if(tabName === 'teleporter' && this.currentTab === 'teleporter') {
      return 'active';
    }
    else if(tabName === 'neo4jImporter' && this.currentTab === 'neo4jImporter') {
      return 'active';
    }
    return '';
  }

}


enablePopovers() {
    (<any>$('[data-toggle="popover"]')).popover({
      title: '',
      placement: 'right',
      trigger: 'focus'
    });
  }


setTab(importer) {
    this.currentTab = importer;
  }


isActive(tabName) {
    if(tabName === 'home' && this.currentTab === 'home') {
      return 'active';
    }
    else if(tabName === 'teleporter' && this.currentTab === 'teleporter') {
      return 'active';
    }
    else if(tabName === 'neo4jImporter' && this.currentTab === 'neo4jImporter') {
      return 'active';
    }
    return '';
  }


({ lcd }: Option) =>
  async (addressProvider: AddressProvider): Promise<ConfigResponse> => {
    const bAssetContractAddress = addressProvider.bLunaHub();
    const response: ConfigResponse = await lcd.wasm.contractQuery(
      bAssetContractAddress,
      {
        config: {},
      },
    );
    return response;
  }


async (addressProvider: AddressProvider): Promise<ConfigResponse> => {
    const bAssetContractAddress = addressProvider.bLunaHub();
    const response: ConfigResponse = await lcd.wasm.contractQuery(
      bAssetContractAddress,
      {
        config: {},
      },
    );
    return response;
  }


interface Option {
  lcd: LCDClient;
}


interface ConfigResponse {
  owner: string;
  reward_contract?: string;
  token_contract?: string;
  airdrop_registry_contract?: string;
}


(props: Props): React.ReactElement => {
  const theme = useTheme()
  return (
    <Box
      style={{
        display: "flex",
        justifyContent: "center",
        alignItems: "center",
        minWidth: "33%",
        maxWidth: "33%",
      }}


interface Props {
  previous?: SitePageContextPrevious | null
}


export class TagResourceCommand
  implements
    __aws_sdk_types.Command<
      InputTypesUnion,
      TagResourceInput,
      OutputTypesUnion,
      TagResourceOutput,
      KinesisAnalyticsV2ResolvedConfiguration,
      Blob
    > {
  readonly model = TagResource;
  readonly middlewareStack = new __aws_sdk_middleware_stack.MiddlewareStack<
    TagResourceInput,
    TagResourceOutput,
    Blob
  >();

  constructor(readonly input: TagResourceInput) {}

  resolveMiddleware(
    clientStack: __aws_sdk_middleware_stack.MiddlewareStack<
      InputTypesUnion,
      OutputTypesUnion,
      Blob
    >,
    configuration: KinesisAnalyticsV2ResolvedConfiguration
  ): __aws_sdk_types.Handler<TagResourceInput, TagResourceOutput> {
    const { handler } = configuration;
    const stack = clientStack.concat(this.middlewareStack);

    const handlerExecutionContext: __aws_sdk_types.HandlerExecutionContext = {
      logger: {} as any,
      model: this.model
    };

    return stack.resolve(
      handler<TagResourceInput, TagResourceOutput>(handlerExecutionContext),
      handlerExecutionContext
    );
  }
}


resolveMiddleware(
    clientStack: __aws_sdk_middleware_stack.MiddlewareStack<
      InputTypesUnion,
      OutputTypesUnion,
      Blob
    >,
    configuration: KinesisAnalyticsV2ResolvedConfiguration
  ): __aws_sdk_types.Handler<TagResourceInput, TagResourceOutput> {
    const { handler } = configuration;
    const stack = clientStack.concat(this.middlewareStack);

    const handlerExecutionContext: __aws_sdk_types.HandlerExecutionContext = {
      logger: {} as any,
      model: this.model
    };

    return stack.resolve(
      handler<TagResourceInput, TagResourceOutput>(handlerExecutionContext),
      handlerExecutionContext
    );
  }


interface CompatibleFieldsCollection {
          // Returns the fields that are compatible to be selected in the respective sections of a report criteria, given the fields already selected in the input report and user permissions.
          query(resource: Schema.Report, profileId: string): Dfareporting.Schema.CompatibleFields;
        }


interface FilesCollection {
          // Retrieves a report file. This method supports media download.
          get(profileId: string, reportId: string, fileId: string): Dfareporting.Schema.File;
          // Lists files for a report.
          list(profileId: string, reportId: string): Dfareporting.Schema.FileList;
          // Lists files for a report.
          list(profileId: string, reportId: string, optionalArgs: object): Dfareporting.Schema.FileList;
        }


interface AccountActiveAdSummariesCollection {
        // Gets the account's active ad summary by account ID.
        get(profileId: string, summaryAccountId: string): Dfareporting.Schema.AccountActiveAdSummary;
      }


interface AccountPermissionGroupsCollection {
        // Gets one account permission group by ID.
        get(profileId: string, id: string): Dfareporting.Schema.AccountPermissionGroup;
        // Retrieves the list of account permission groups.
        list(profileId: string): Dfareporting.Schema.AccountPermissionGroupsListResponse;
      }


interface AccountPermissionsCollection {
        // Gets one account permission by ID.
        get(profileId: string, id: string): Dfareporting.Schema.AccountPermission;
        // Retrieves the list of account permissions.
        list(profileId: string): Dfareporting.Schema.AccountPermissionsListResponse;
      }


interface AccountUserProfilesCollection {
        // Gets one account user profile by ID.
        get(profileId: string, id: string): Dfareporting.Schema.AccountUserProfile;
        // Inserts a new account user profile.
        insert(resource: Schema.AccountUserProfile, profileId: string): Dfareporting.Schema.AccountUserProfile;
        // Retrieves a list of account user profiles, possibly filtered. This method supports paging.
        list(profileId: string): Dfareporting.Schema.AccountUserProfilesListResponse;
        // Retrieves a list of account user profiles, possibly filtered. This method supports paging.
        list(profileId: string, optionalArgs: object): Dfareporting.Schema.AccountUserProfilesListResponse;
        // Updates an existing account user profile. This method supports patch semantics.
        patch(resource: Schema.AccountUserProfile, profileId: string, id: string): Dfareporting.Schema.AccountUserProfile;
        // Updates an existing account user profile.
        update(resource: Schema.AccountUserProfile, profileId: string): Dfareporting.Schema.AccountUserProfile;
      }


interface AccountsCollection {
        // Gets one account by ID.
        get(profileId: string, id: string): Dfareporting.Schema.Account;
        // Retrieves the list of accounts, possibly filtered. This method supports paging.
        list(profileId: string): Dfareporting.Schema.AccountsListResponse;
        // Retrieves the list of accounts, possibly filtered. This method supports paging.
        list(profileId: string, optionalArgs: object): Dfareporting.Schema.AccountsListResponse;
        // Updates an existing account. This method supports patch semantics.
        patch(resource: Schema.Account, profileId: string, id: string): Dfareporting.Schema.Account;
        // Updates an existing account.
        update(resource: Schema.Account, profileId: string): Dfareporting.Schema.Account;
      }


interface AdsCollection {
        // Gets one ad by ID.
        get(profileId: string, id: string): Dfareporting.Schema.Ad;
        // Inserts a new ad.
        insert(resource: Schema.Ad, profileId: string): Dfareporting.Schema.Ad;
        // Retrieves a list of ads, possibly filtered. This method supports paging.
        list(profileId: string): Dfareporting.Schema.AdsListResponse;
        // Retrieves a list of ads, possibly filtered. This method supports paging.
        list(profileId: string, optionalArgs: object): Dfareporting.Schema.AdsListResponse;
        // Updates an existing ad. This method supports patch semantics.
        patch(resource: Schema.Ad, profileId: string, id: string): Dfareporting.Schema.Ad;
        // Updates an existing ad.
        update(resource: Schema.Ad, profileId: string): Dfareporting.Schema.Ad;
      }


interface AdvertiserGroupsCollection {
        // Gets one advertiser group by ID.
        get(profileId: string, id: string): Dfareporting.Schema.AdvertiserGroup;
        // Inserts a new advertiser group.
        insert(resource: Schema.AdvertiserGroup, profileId: string): Dfareporting.Schema.AdvertiserGroup;
        // Retrieves a list of advertiser groups, possibly filtered. This method supports paging.
        list(profileId: string): Dfareporting.Schema.AdvertiserGroupsListResponse;
        // Retrieves a list of advertiser groups, possibly filtered. This method supports paging.
        list(profileId: string, optionalArgs: object): Dfareporting.Schema.AdvertiserGroupsListResponse;
        // Updates an existing advertiser group. This method supports patch semantics.
        patch(resource: Schema.AdvertiserGroup, profileId: string, id: string): Dfareporting.Schema.AdvertiserGroup;
        // Deletes an existing advertiser group.
        remove(profileId: string, id: string): void;
        // Updates an existing advertiser group.
        update(resource: Schema.AdvertiserGroup, profileId: string): Dfareporting.Schema.AdvertiserGroup;
      }


interface AdvertiserLandingPagesCollection {
        // Gets one landing page by ID.
        get(profileId: string, id: string): Dfareporting.Schema.LandingPage;
        // Inserts a new landing page.
        insert(resource: Schema.LandingPage, profileId: string): Dfareporting.Schema.LandingPage;
        // Retrieves a list of landing pages.
        list(profileId: string): Dfareporting.Schema.AdvertiserLandingPagesListResponse;
        // Retrieves a list of landing pages.
        list(profileId: string, optionalArgs: object): Dfareporting.Schema.AdvertiserLandingPagesListResponse;
        // Updates an existing landing page. This method supports patch semantics.
        patch(resource: Schema.LandingPage, profileId: string, id: string): Dfareporting.Schema.LandingPage;
        // Updates an existing landing page.
        update(resource: Schema.LandingPage, profileId: string): Dfareporting.Schema.LandingPage;
      }


interface AdvertisersCollection {
        // Gets one advertiser by ID.
        get(profileId: string, id: string): Dfareporting.Schema.Advertiser;
        // Inserts a new advertiser.
        insert(resource: Schema.Advertiser, profileId: string): Dfareporting.Schema.Advertiser;
        // Retrieves a list of advertisers, possibly filtered. This method supports paging.
        list(profileId: string): Dfareporting.Schema.AdvertisersListResponse;
        // Retrieves a list of advertisers, possibly filtered. This method supports paging.
        list(profileId: string, optionalArgs: object): Dfareporting.Schema.AdvertisersListResponse;
        // Updates an existing advertiser. This method supports patch semantics.
        patch(resource: Schema.Advertiser, profileId: string, id: string): Dfareporting.Schema.Advertiser;
        // Updates an existing advertiser.
        update(resource: Schema.Advertiser, profileId: string): Dfareporting.Schema.Advertiser;
      }


interface BrowsersCollection {
        // Retrieves a list of browsers.
        list(profileId: string): Dfareporting.Schema.BrowsersListResponse;
      }


interface CampaignCreativeAssociationsCollection {
        // Associates a creative with the specified campaign. This method creates a default ad with dimensions matching the creative in the campaign if such a default ad does not exist already.
        insert(resource: Schema.CampaignCreativeAssociation, profileId: string, campaignId: string): Dfareporting.Schema.CampaignCreativeAssociation;
        // Retrieves the list of creative IDs associated with the specified campaign. This method supports paging.
        list(profileId: string, campaignId: string): Dfareporting.Schema.CampaignCreativeAssociationsListResponse;
        // Retrieves the list of creative IDs associated with the specified campaign. This method supports paging.
        list(profileId: string, campaignId: string, optionalArgs: object): Dfareporting.Schema.CampaignCreativeAssociationsListResponse;
      }


interface CampaignsCollection {
        // Gets one campaign by ID.
        get(profileId: string, id: string): Dfareporting.Schema.Campaign;
        // Inserts a new campaign.
        insert(resource: Schema.Campaign, profileId: string): Dfareporting.Schema.Campaign;
        // Retrieves a list of campaigns, possibly filtered. This method supports paging.
        list(profileId: string): Dfareporting.Schema.CampaignsListResponse;
        // Retrieves a list of campaigns, possibly filtered. This method supports paging.
        list(profileId: string, optionalArgs: object): Dfareporting.Schema.CampaignsListResponse;
        // Updates an existing campaign. This method supports patch semantics.
        patch(resource: Schema.Campaign, profileId: string, id: string): Dfareporting.Schema.Campaign;
        // Updates an existing campaign.
        update(resource: Schema.Campaign, profileId: string): Dfareporting.Schema.Campaign;
      }


interface ChangeLogsCollection {
        // Gets one change log by ID.
        get(profileId: string, id: string): Dfareporting.Schema.ChangeLog;
        // Retrieves a list of change logs. This method supports paging.
        list(profileId: string): Dfareporting.Schema.ChangeLogsListResponse;
        // Retrieves a list of change logs. This method supports paging.
        list(profileId: string, optionalArgs: object): Dfareporting.Schema.ChangeLogsListResponse;
      }


interface CitiesCollection {
        // Retrieves a list of cities, possibly filtered.
        list(profileId: string): Dfareporting.Schema.CitiesListResponse;
        // Retrieves a list of cities, possibly filtered.
        list(profileId: string, optionalArgs: object): Dfareporting.Schema.CitiesListResponse;
      }


interface ConnectionTypesCollection {
        // Gets one connection type by ID.
        get(profileId: string, id: string): Dfareporting.Schema.ConnectionType;
        // Retrieves a list of connection types.
        list(profileId: string): Dfareporting.Schema.ConnectionTypesListResponse;
      }


interface ContentCategoriesCollection {
        // Gets one content category by ID.
        get(profileId: string, id: string): Dfareporting.Schema.ContentCategory;
        // Inserts a new content category.
        insert(resource: Schema.ContentCategory, profileId: string): Dfareporting.Schema.ContentCategory;
        // Retrieves a list of content categories, possibly filtered. This method supports paging.
        list(profileId: string): Dfareporting.Schema.ContentCategoriesListResponse;
        // Retrieves a list of content categories, possibly filtered. This method supports paging.
        list(profileId: string, optionalArgs: object): Dfareporting.Schema.ContentCategoriesListResponse;
        // Updates an existing content category. This method supports patch semantics.
        patch(resource: Schema.ContentCategory, profileId: string, id: string): Dfareporting.Schema.ContentCategory;
        // Deletes an existing content category.
        remove(profileId: string, id: string): void;
        // Updates an existing content category.
        update(resource: Schema.ContentCategory, profileId: string): Dfareporting.Schema.ContentCategory;
      }


interface ConversionsCollection {
        // Inserts conversions.
        batchinsert(resource: Schema.ConversionsBatchInsertRequest, profileId: string): Dfareporting.Schema.ConversionsBatchInsertResponse;
        // Updates existing conversions.
        batchupdate(resource: Schema.ConversionsBatchUpdateRequest, profileId: string): Dfareporting.Schema.ConversionsBatchUpdateResponse;
      }


interface CountriesCollection {
        // Gets one country by ID.
        get(profileId: string, dartId: string): Dfareporting.Schema.Country;
        // Retrieves a list of countries.
        list(profileId: string): Dfareporting.Schema.CountriesListResponse;
      }


interface CreativeAssetsCollection {
        // Inserts a new creative asset.
        insert(resource: Schema.CreativeAssetMetadata, profileId: string, advertiserId: string): Dfareporting.Schema.CreativeAssetMetadata;
        // Inserts a new creative asset.
        insert(resource: Schema.CreativeAssetMetadata, profileId: string, advertiserId: string, mediaData: any): Dfareporting.Schema.CreativeAssetMetadata;
      }


interface CreativeFieldValuesCollection {
        // Gets one creative field value by ID.
        get(profileId: string, creativeFieldId: string, id: string): Dfareporting.Schema.CreativeFieldValue;
        // Inserts a new creative field value.
        insert(resource: Schema.CreativeFieldValue, profileId: string, creativeFieldId: string): Dfareporting.Schema.CreativeFieldValue;
        // Retrieves a list of creative field values, possibly filtered. This method supports paging.
        list(profileId: string, creativeFieldId: string): Dfareporting.Schema.CreativeFieldValuesListResponse;
        // Retrieves a list of creative field values, possibly filtered. This method supports paging.
        list(profileId: string, creativeFieldId: string, optionalArgs: object): Dfareporting.Schema.CreativeFieldValuesListResponse;
        // Updates an existing creative field value. This method supports patch semantics.
        patch(resource: Schema.CreativeFieldValue, profileId: string, creativeFieldId: string, id: string): Dfareporting.Schema.CreativeFieldValue;
        // Deletes an existing creative field value.
        remove(profileId: string, creativeFieldId: string, id: string): void;
        // Updates an existing creative field value.
        update(resource: Schema.CreativeFieldValue, profileId: string, creativeFieldId: string): Dfareporting.Schema.CreativeFieldValue;
      }


interface CreativeFieldsCollection {
        // Gets one creative field by ID.
        get(profileId: string, id: string): Dfareporting.Schema.CreativeField;
        // Inserts a new creative field.
        insert(resource: Schema.CreativeField, profileId: string): Dfareporting.Schema.CreativeField;
        // Retrieves a list of creative fields, possibly filtered. This method supports paging.
        list(profileId: string): Dfareporting.Schema.CreativeFieldsListResponse;
        // Retrieves a list of creative fields, possibly filtered. This method supports paging.
        list(profileId: string, optionalArgs: object): Dfareporting.Schema.CreativeFieldsListResponse;
        // Updates an existing creative field. This method supports patch semantics.
        patch(resource: Schema.CreativeField, profileId: string, id: string): Dfareporting.Schema.CreativeField;
        // Deletes an existing creative field.
        remove(profileId: string, id: string): void;
        // Updates an existing creative field.
        update(resource: Schema.CreativeField, profileId: string): Dfareporting.Schema.CreativeField;
      }


interface CreativeGroupsCollection {
        // Gets one creative group by ID.
        get(profileId: string, id: string): Dfareporting.Schema.CreativeGroup;
        // Inserts a new creative group.
        insert(resource: Schema.CreativeGroup, profileId: string): Dfareporting.Schema.CreativeGroup;
        // Retrieves a list of creative groups, possibly filtered. This method supports paging.
        list(profileId: string): Dfareporting.Schema.CreativeGroupsListResponse;
        // Retrieves a list of creative groups, possibly filtered. This method supports paging.
        list(profileId: string, optionalArgs: object): Dfareporting.Schema.CreativeGroupsListResponse;
        // Updates an existing creative group. This method supports patch semantics.
        patch(resource: Schema.CreativeGroup, profileId: string, id: string): Dfareporting.Schema.CreativeGroup;
        // Updates an existing creative group.
        update(resource: Schema.CreativeGroup, profileId: string): Dfareporting.Schema.CreativeGroup;
      }


interface CreativesCollection {
        // Gets one creative by ID.
        get(profileId: string, id: string): Dfareporting.Schema.Creative;
        // Inserts a new creative.
        insert(resource: Schema.Creative, profileId: string): Dfareporting.Schema.Creative;
        // Retrieves a list of creatives, possibly filtered. This method supports paging.
        list(profileId: string): Dfareporting.Schema.CreativesListResponse;
        // Retrieves a list of creatives, possibly filtered. This method supports paging.
        list(profileId: string, optionalArgs: object): Dfareporting.Schema.CreativesListResponse;
        // Updates an existing creative. This method supports patch semantics.
        patch(resource: Schema.Creative, profileId: string, id: string): Dfareporting.Schema.Creative;
        // Updates an existing creative.
        update(resource: Schema.Creative, profileId: string): Dfareporting.Schema.Creative;
      }


interface DimensionValuesCollection {
        // Retrieves list of report dimension values for a list of filters.
        query(resource: Schema.DimensionValueRequest, profileId: string): Dfareporting.Schema.DimensionValueList;
        // Retrieves list of report dimension values for a list of filters.
        query(resource: Schema.DimensionValueRequest, profileId: string, optionalArgs: object): Dfareporting.Schema.DimensionValueList;
      }


interface DirectorySitesCollection {
        // Gets one directory site by ID.
        get(profileId: string, id: string): Dfareporting.Schema.DirectorySite;
        // Inserts a new directory site.
        insert(resource: Schema.DirectorySite, profileId: string): Dfareporting.Schema.DirectorySite;
        // Retrieves a list of directory sites, possibly filtered. This method supports paging.
        list(profileId: string): Dfareporting.Schema.DirectorySitesListResponse;
        // Retrieves a list of directory sites, possibly filtered. This method supports paging.
        list(profileId: string, optionalArgs: object): Dfareporting.Schema.DirectorySitesListResponse;
      }


interface DynamicTargetingKeysCollection {
        // Inserts a new dynamic targeting key. Keys must be created at the advertiser level before being assigned to the advertiser's ads, creatives, or placements. There is a maximum of 1000 keys per advertiser, out of which a maximum of 20 keys can be assigned per ad, creative, or placement.
        insert(resource: Schema.DynamicTargetingKey, profileId: string): Dfareporting.Schema.DynamicTargetingKey;
        // Retrieves a list of dynamic targeting keys.
        list(profileId: string): Dfareporting.Schema.DynamicTargetingKeysListResponse;
        // Retrieves a list of dynamic targeting keys.
        list(profileId: string, optionalArgs: object): Dfareporting.Schema.DynamicTargetingKeysListResponse;
        // Deletes an existing dynamic targeting key.
        remove(profileId: string, objectId: string, name: string, objectType: string): void;
      }


interface EventTagsCollection {
        // Gets one event tag by ID.
        get(profileId: string, id: string): Dfareporting.Schema.EventTag;
        // Inserts a new event tag.
        insert(resource: Schema.EventTag, profileId: string): Dfareporting.Schema.EventTag;
        // Retrieves a list of event tags, possibly filtered.
        list(profileId: string): Dfareporting.Schema.EventTagsListResponse;
        // Retrieves a list of event tags, possibly filtered.
        list(profileId: string, optionalArgs: object): Dfareporting.Schema.EventTagsListResponse;
        // Updates an existing event tag. This method supports patch semantics.
        patch(resource: Schema.EventTag, profileId: string, id: string): Dfareporting.Schema.EventTag;
        // Deletes an existing event tag.
        remove(profileId: string, id: string): void;
        // Updates an existing event tag.
        update(resource: Schema.EventTag, profileId: string): Dfareporting.Schema.EventTag;
      }


interface FilesCollection {
        // Retrieves a report file by its report ID and file ID. This method supports media download.
        get(reportId: string, fileId: string): Dfareporting.Schema.File;
        // Lists files for a user profile.
        list(profileId: string): Dfareporting.Schema.FileList;
        // Lists files for a user profile.
        list(profileId: string, optionalArgs: object): Dfareporting.Schema.FileList;
      }


interface FloodlightActivitiesCollection {
        // Generates a tag for a floodlight activity.
        generatetag(profileId: string): Dfareporting.Schema.FloodlightActivitiesGenerateTagResponse;
        // Generates a tag for a floodlight activity.
        generatetag(profileId: string, optionalArgs: object): Dfareporting.Schema.FloodlightActivitiesGenerateTagResponse;
        // Gets one floodlight activity by ID.
        get(profileId: string, id: string): Dfareporting.Schema.FloodlightActivity;
        // Inserts a new floodlight activity.
        insert(resource: Schema.FloodlightActivity, profileId: string): Dfareporting.Schema.FloodlightActivity;
        // Retrieves a list of floodlight activities, possibly filtered. This method supports paging.
        list(profileId: string): Dfareporting.Schema.FloodlightActivitiesListResponse;
        // Retrieves a list of floodlight activities, possibly filtered. This method supports paging.
        list(profileId: string, optionalArgs: object): Dfareporting.Schema.FloodlightActivitiesListResponse;
        // Updates an existing floodlight activity. This method supports patch semantics.
        patch(resource: Schema.FloodlightActivity, profileId: string, id: string): Dfareporting.Schema.FloodlightActivity;
        // Deletes an existing floodlight activity.
        remove(profileId: string, id: string): void;
        // Updates an existing floodlight activity.
        update(resource: Schema.FloodlightActivity, profileId: string): Dfareporting.Schema.FloodlightActivity;
      }


interface FloodlightActivityGroupsCollection {
        // Gets one floodlight activity group by ID.
        get(profileId: string, id: string): Dfareporting.Schema.FloodlightActivityGroup;
        // Inserts a new floodlight activity group.
        insert(resource: Schema.FloodlightActivityGroup, profileId: string): Dfareporting.Schema.FloodlightActivityGroup;
        // Retrieves a list of floodlight activity groups, possibly filtered. This method supports paging.
        list(profileId: string): Dfareporting.Schema.FloodlightActivityGroupsListResponse;
        // Retrieves a list of floodlight activity groups, possibly filtered. This method supports paging.
        list(profileId: string, optionalArgs: object): Dfareporting.Schema.FloodlightActivityGroupsListResponse;
        // Updates an existing floodlight activity group. This method supports patch semantics.
        patch(resource: Schema.FloodlightActivityGroup, profileId: string, id: string): Dfareporting.Schema.FloodlightActivityGroup;
        // Updates an existing floodlight activity group.
        update(resource: Schema.FloodlightActivityGroup, profileId: string): Dfareporting.Schema.FloodlightActivityGroup;
      }


interface FloodlightConfigurationsCollection {
        // Gets one floodlight configuration by ID.
        get(profileId: string, id: string): Dfareporting.Schema.FloodlightConfiguration;
        // Retrieves a list of floodlight configurations, possibly filtered.
        list(profileId: string): Dfareporting.Schema.FloodlightConfigurationsListResponse;
        // Retrieves a list of floodlight configurations, possibly filtered.
        list(profileId: string, optionalArgs: object): Dfareporting.Schema.FloodlightConfigurationsListResponse;
        // Updates an existing floodlight configuration. This method supports patch semantics.
        patch(resource: Schema.FloodlightConfiguration, profileId: string, id: string): Dfareporting.Schema.FloodlightConfiguration;
        // Updates an existing floodlight configuration.
        update(resource: Schema.FloodlightConfiguration, profileId: string): Dfareporting.Schema.FloodlightConfiguration;
      }


interface InventoryItemsCollection {
        // Gets one inventory item by ID.
        get(profileId: string, projectId: string, id: string): Dfareporting.Schema.InventoryItem;
        // Retrieves a list of inventory items, possibly filtered. This method supports paging.
        list(profileId: string, projectId: string): Dfareporting.Schema.InventoryItemsListResponse;
        // Retrieves a list of inventory items, possibly filtered. This method supports paging.
        list(profileId: string, projectId: string, optionalArgs: object): Dfareporting.Schema.InventoryItemsListResponse;
      }


interface LanguagesCollection {
        // Retrieves a list of languages.
        list(profileId: string): Dfareporting.Schema.LanguagesListResponse;
      }


interface MetrosCollection {
        // Retrieves a list of metros.
        list(profileId: string): Dfareporting.Schema.MetrosListResponse;
      }


interface MobileAppsCollection {
        // Gets one mobile app by ID.
        get(profileId: string, id: string): Dfareporting.Schema.MobileApp;
        // Retrieves list of available mobile apps.
        list(profileId: string): Dfareporting.Schema.MobileAppsListResponse;
        // Retrieves list of available mobile apps.
        list(profileId: string, optionalArgs: object): Dfareporting.Schema.MobileAppsListResponse;
      }


interface MobileCarriersCollection {
        // Gets one mobile carrier by ID.
        get(profileId: string, id: string): Dfareporting.Schema.MobileCarrier;
        // Retrieves a list of mobile carriers.
        list(profileId: string): Dfareporting.Schema.MobileCarriersListResponse;
      }


interface OperatingSystemVersionsCollection {
        // Gets one operating system version by ID.
        get(profileId: string, id: string): Dfareporting.Schema.OperatingSystemVersion;
        // Retrieves a list of operating system versions.
        list(profileId: string): Dfareporting.Schema.OperatingSystemVersionsListResponse;
      }


interface OperatingSystemsCollection {
        // Gets one operating system by DART ID.
        get(profileId: string, dartId: string): Dfareporting.Schema.OperatingSystem;
        // Retrieves a list of operating systems.
        list(profileId: string): Dfareporting.Schema.OperatingSystemsListResponse;
      }


interface OrderDocumentsCollection {
        // Gets one order document by ID.
        get(profileId: string, projectId: string, id: string): Dfareporting.Schema.OrderDocument;
        // Retrieves a list of order documents, possibly filtered. This method supports paging.
        list(profileId: string, projectId: string): Dfareporting.Schema.OrderDocumentsListResponse;
        // Retrieves a list of order documents, possibly filtered. This method supports paging.
        list(profileId: string, projectId: string, optionalArgs: object): Dfareporting.Schema.OrderDocumentsListResponse;
      }