text:
import {
  randomBase64UrlStr,
  randomId,
  mirrorFieldTo,
  randomDigits,
  isValidPhoneNumber,
  DeepPartial,
} from "./utils";
import { MakeRequired } from "./utils";
import { AuthCloudFunction } from "./cloudFunctions";
import { assert, BadRequestError } from "./errors";
import { MfaEnrollments, Schemas } from "./types";

export const PROVIDER_PASSWORD = "password";
export const PROVIDER_PHONE = "phone";
export const PROVIDER_ANONYMOUS = "anonymous";
export const PROVIDER_CUSTOM = "custom";
export const PROVIDER_GAME_CENTER = "gc.apple.com"; // Not yet implemented

export const SIGNIN_METHOD_EMAIL_LINK = "emailLink";

export abstract class ProjectState {
  private users: Map<string, UserInfo> = new Map();
  private localIdForEmail: Map<string, string> = new Map();
  private localIdForInitialEmail: Map<string, string> = new Map();
  private localIdForPhoneNumber: Map<string, string> = new Map();
  private localIdsForProviderEmail: Map<string, Set<string>> = new Map();
  private userIdForProviderRawId: Map<string, Map<string, string>> = new Map();
  private oobs: Map<string, OobRecord> = new Map();
  private verificationCodes: Map<string, PhoneVerificationRecord> = new Map();
  private temporaryProofs: Map<string, TemporaryProofRecord> = new Map();
  private pendingLocalIds: Set<string> = new Set();

  constructor(public readonly projectId: string) {}

  get projectNumber(): string {
    // TODO: Shall we generate something different for each project?
    // Hard-coding an obviously fake number for clarity for now.
    return "12345";
  }

  abstract get oneAccountPerEmail(): boolean;

  abstract get authCloudFunction(): AuthCloudFunction;

  abstract get allowPasswordSignup(): boolean;

  abstract get disableAuth(): boolean;

  abstract get mfaConfig(): Schemas["GoogleCloudIdentitytoolkitAdminV2MultiFactorAuthConfig"];

  abstract get enableAnonymousUser(): boolean;

  abstract get enableEmailLinkSignin(): boolean;

  abstract shouldForwardCredentialToBlockingFunction(
    type: "accessToken" | "idToken" | "refreshToken"
  ): boolean;

  abstract getBlockingFunctionUri(event: BlockingFunctionEvents): string | undefined;

  generateLocalId(): string {
    for (let i = 0; i < 10; i++) {
      // Try this for 10 times to prevent ID collision (since our RNG is
      // Math.random() which isn't really that great).
      const localId = randomId(28);
      if (!this.users.has(localId) && !this.pendingLocalIds.has(localId)) {
        // Create a pending localId until user is created. This creates a memory
        // leak if a blocking functions throws and the localId is never used.
        this.pendingLocalIds.add(localId);
        return localId;
      }
    }
    // If we get 10 collisions in a row, there must be something very wrong.
    throw new Error("Cannot generate a random unique localId after 10 tries.");
  }

  createUserWithLocalId(
    localId: string,
    props: Omit<UserInfo, "localId" | "lastRefreshAt">
  ): UserInfo | undefined {
    if (this.users.has(localId)) {
      return undefined;
    }
    this.users.set(localId, {
      localId,
    });
    this.pendingLocalIds.delete(localId);

    const user = this.updateUserByLocalId(localId, props, {
      upsertProviders: props.providerUserInfo,
    });
    this.authCloudFunction.dispatch("create", user);
    return user;
  }

  /**
   * Create or overwrite the user with localId, never triggering functions.
   * @param localId the ID of existing user to overwrite, or create otherwise
   * @param props new properties of the user
   * @return the hydrated UserInfo of the created/updated user in state
   */
  overwriteUserWithLocalId(
    localId: string,
    props: Omit<UserInfo, "localId" | "lastRefreshAt">
  ): UserInfo {
    const userInfoBefore = this.users.get(localId);
    if (userInfoBefore) {
      // For consistency, nuke internal indexes for old fields (e.g. email).
      this.removeUserFromIndex(userInfoBefore);
    }
    const timestamp = new Date();
    this.users.set(localId, {
      localId,
      createdAt: props.createdAt || timestamp.getTime().toString(),
      lastLoginAt: timestamp.getTime().toString(),
    });

    const user = this.updateUserByLocalId(localId, props, {
      upsertProviders: props.providerUserInfo,
    });
    return user;
  }

  deleteUser(user: UserInfo): void {
    this.users.delete(user.localId);
    this.removeUserFromIndex(user);
    this.authCloudFunction.dispatch("delete", user);
  }

  updateUserByLocalId(
    localId: string,
    fields: Omit<Partial<UserInfo>, "localId" | "providerUserInfo">,
    options: {
      upsertProviders?: ProviderUserInfo[];
      deleteProviders?: string[];
    } = {}
  ): UserInfo {
    const upsertProviders = options.upsertProviders ?? [];
    const deleteProviders = options.deleteProviders ?? [];
    const user = this.users.get(localId);
    if (!user) {
      throw new Error(`Internal assertion error: trying to update nonexistent user: ${localId}`);
    }
    const oldEmail = user.email;
    const oldPhoneNumber = user.phoneNumber;

    for (const field of Object.keys(fields) as (keyof typeof fields)[]) {
      mirrorFieldTo(user, field, fields);
    }

    if (oldEmail && oldEmail !== user.email) {
      this.localIdForEmail.delete(oldEmail);
    }
    if (user.email) {
      this.localIdForEmail.set(user.email, user.localId);
    }
    if (user.email && (user.passwordHash || user.emailLinkSignin)) {
      upsertProviders.push({
        providerId: PROVIDER_PASSWORD,
        email: user.email,
        federatedId: user.email,
        rawId: user.email,
        displayName: user.displayName,
        photoUrl: user.photoUrl,
      });
    } else {
      deleteProviders.push(PROVIDER_PASSWORD);
    }

    if (user.initialEmail) {
      this.localIdForInitialEmail.set(user.initialEmail, user.localId);
    }

    if (oldPhoneNumber && oldPhoneNumber !== user.phoneNumber) {
      this.localIdForPhoneNumber.delete(oldPhoneNumber);
    }
    if (user.phoneNumber) {
      this.localIdForPhoneNumber.set(user.phoneNumber, user.localId);
      upsertProviders.push({
        providerId: PROVIDER_PHONE,
        phoneNumber: user.phoneNumber,
        rawId: user.phoneNumber,
      });
    } else {
      deleteProviders.push(PROVIDER_PHONE);
    }

    // if MFA info is specified on the user, ensure MFA data is valid before returning.
    // callers are expected to have called `validateMfaEnrollments` prior to having called
    // this method.
    if (user.mfaInfo) {
      this.validateMfaEnrollments(user.mfaInfo);
    }

    return this.updateUserProviderInfo(user, upsertProviders, deleteProviders);
  }

  /**
   * Validates a collection of MFA Enrollments. If all data is valid, returns the data
   * unmodified to the caller.
   *
   * @param enrollments the MFA Enrollments to validate. each enrollment must have a valid and unique phone number, a non-null enrollment ID,
   * and the enrollment ID must be unique across all other enrollments in the array.
   * @returns the validated MFA Enrollments passed to this method
   * @throws BadRequestError if the phone number is absent or invalid
   * @throws BadRequestError if the MFA Enrollment ID is absent
   * @throws BadRequestError if the MFA Enrollment ID is duplicated in the provided array
   * @throws BadRequestError if any of the phone numbers are duplicated. callers should de-duplicate phone numbers
   * prior to calling this validation method, as the real API is lenient and removes duplicates from requests
   * for well-formed create/update requests.
   */
  validateMfaEnrollments(enrollments: MfaEnrollments): MfaEnrollments {
    const phoneNumbers: Set<string> = new Set<string>();
    const enrollmentIds: Set<string> = new Set<string>();
    for (const enrollment of enrollments) {
      assert(
        enrollment.phoneInfo && isValidPhoneNumber(enrollment.phoneInfo),
        "INVALID_MFA_PHONE_NUMBER : Invalid format."
      );
      assert(
        enrollment.mfaEnrollmentId,
        "INVALID_MFA_ENROLLMENT_ID : mfaEnrollmentId must be defined."
      );
      assert(!enrollmentIds.has(enrollment.mfaEnrollmentId), "DUPLICATE_MFA_ENROLLMENT_ID");
      assert(
        !phoneNumbers.has(enrollment.phoneInfo),
        "INTERNAL_ERROR : MFA Enrollment Phone Numbers must be unique."
      );
      phoneNumbers.add(enrollment.phoneInfo);
      enrollmentIds.add(enrollment.mfaEnrollmentId);
    }
    return enrollments;
  }

  private updateUserProviderInfo(
    user: UserInfo,
    upsertProviders: ProviderUserInfo[],
    deleteProviders: string[]
  ): UserInfo {
    const oldProviderEmails = getProviderEmailsForUser(user);

    if (user.providerUserInfo) {
      const updatedProviderUserInfo: ProviderUserInfo[] = [];
      for (const info of user.providerUserInfo) {
        if (deleteProviders.includes(info.providerId)) {
          this.userIdForProviderRawId.get(info.providerId)?.delete(info.rawId);
        } else {
          updatedProviderUserInfo.push(info);
        }
      }
      user.providerUserInfo = updatedProviderUserInfo;
    }

    if (upsertProviders.length) {
      user.providerUserInfo = user.providerUserInfo ?? [];
      for (const upsert of upsertProviders) {
        const providerId = upsert.providerId;
        let users = this.userIdForProviderRawId.get(providerId);
        if (!users) {
          users = new Map();
          this.userIdForProviderRawId.set(providerId, users);
        }
        users.set(upsert.rawId, user.localId);

        const index = user.providerUserInfo.findIndex(
          (info) => info.providerId === upsert.providerId
        );
        if (index < 0) {
          user.providerUserInfo.push(upsert);
        } else {
          user.providerUserInfo[index] = upsert;
        }
      }
    }

    for (const email of getProviderEmailsForUser(user)) {
      oldProviderEmails.delete(email);
      let localIds = this.localIdsForProviderEmail.get(email);
      if (!localIds) {
        localIds = new Set();
        this.localIdsForProviderEmail.set(email, localIds);
      }
      localIds.add(user.localId);
    }
    for (const oldEmail of oldProviderEmails) {
      this.removeProviderEmailForUser(oldEmail, user.localId);
    }
    return user;
  }

  getUserByEmail(email: string): UserInfo | undefined {
    const localId = this.localIdForEmail.get(email);
    if (!localId) {
      return undefined;
    }
    return this.getUserByLocalIdAssertingExists(localId);
  }

  getUserByInitialEmail(initialEmail: string): UserInfo | undefined {
    const localId = this.localIdForInitialEmail.get(initialEmail);
    if (!localId) {
      return undefined;
    }
    return this.getUserByLocalIdAssertingExists(localId);
  }

  private getUserByLocalIdAssertingExists(localId: string): UserInfo {
    const userInfo = this.getUserByLocalId(localId);
    if (!userInfo) {
      throw new Error(`Internal state invariant broken: no user with ID: ${localId}`);
    }
    return userInfo;
  }

  getUsersByEmailOrProviderEmail(email: string): UserInfo[] {
    const users: UserInfo[] = [];
    const seenLocalIds = new Set<string>();
    const localId = this.localIdForEmail.get(email);
    if (localId) {
      users.push(this.getUserByLocalIdAssertingExists(localId));
      seenLocalIds.add(localId);
    }
    for (const localId of this.localIdsForProviderEmail.get(email) ?? []) {
      if (!seenLocalIds.has(localId)) {
        users.push(this.getUserByLocalIdAssertingExists(localId));
        seenLocalIds.add(localId);
      }
    }
    return users;
  }

  getUserByPhoneNumber(phoneNumber: string): UserInfo | undefined {
    const localId = this.localIdForPhoneNumber.get(phoneNumber);
    if (!localId) {
      return undefined;
    }
    return this.getUserByLocalIdAssertingExists(localId);
  }

  private removeProviderEmailForUser(email: string, localId: string): void {
    const localIds = this.localIdsForProviderEmail.get(email);
    if (!localIds) {
      return;
    }
    localIds.delete(localId);
    if (localIds.size === 0) {
      this.localIdsForProviderEmail.delete(email);
    }
  }

  getUserByProviderRawId(provider: string, rawId: string): UserInfo | undefined {
    const localId = this.userIdForProviderRawId.get(provider)?.get(rawId);
    if (!localId) {
      return undefined;
    }
    return this.getUserByLocalIdAssertingExists(localId);
  }

  listProviderInfosByProviderId(provider: string): ProviderUserInfo[] {
    const users = this.userIdForProviderRawId.get(provider);
    if (!users) {
      return [];
    }
    const infos: ProviderUserInfo[] = [];
    for (const localId of users.values()) {
      const user = this.getUserByLocalIdAssertingExists(localId);
      const info = user.providerUserInfo?.find((info) => info.providerId === provider);
      if (!info) {
        throw new Error(
          `Internal assertion error: User ${localId} does not have providerInfo ${provider}.`
        );
      }
      infos.push(info);
    }
    return infos;
  }

  getUserByLocalId(localId: string): UserInfo | undefined {
    return this.users.get(localId);
  }

  createRefreshTokenFor(
    userInfo: UserInfo,
    provider: string,
    {
      extraClaims = {},
      secondFactor,
    }: {
      extraClaims?: Record<string, unknown>;
      secondFactor?: SecondFactorRecord;
    } = {}
  ): string {
    const localId = userInfo.localId;
    const refreshTokenRecord = {
      _AuthEmulatorRefreshToken: "DO NOT MODIFY",
      localId,
      provider,
      extraClaims,
      projectId: this.projectId,
      secondFactor,
      tenantId: userInfo.tenantId,
    };
    const refreshToken = encodeRefreshToken(refreshTokenRecord);
    return refreshToken;
  }

  validateRefreshToken(refreshToken: string): {
    user: UserInfo;
    provider: string;
    extraClaims: Record<string, unknown>;
    secondFactor?: SecondFactorRecord;
  } {
    const record = decodeRefreshToken(refreshToken);
    assert(record.projectId === this.projectId, "INVALID_REFRESH_TOKEN");
    if (this instanceof TenantProjectState) {
      // Shouldn't ever reach this assertion, but adding for completeness
      assert(record.tenantId === this.tenantId, "TENANT_ID_MISMATCH");
    }
    const user = this.getUserByLocalId(record.localId);
    assert(user, "INVALID_REFRESH_TOKEN");
    return {
      user,
      provider: record.provider,
      extraClaims: record.extraClaims,
      secondFactor: record.secondFactor,
    };
  }

  createOob(
    email: string,
    requestType: OobRequestType,
    generateLink: (oobCode: string) => string
  ): OobRecord {
    const oobCode = randomBase64UrlStr(54);
    const oobLink = generateLink(oobCode);

    const oob: OobRecord = {
      email,
      requestType,
      oobCode,
      oobLink,
    };
    this.oobs.set(oobCode, oob);
    return oob;
  }

  validateOobCode(oobCode: string): OobRecord | undefined {
    return this.oobs.get(oobCode);
  }

  deleteOobCode(oobCode: string): boolean {
    return this.oobs.delete(oobCode);
  }

  listOobCodes(): Iterable<OobRecord> {
    return this.oobs.values();
  }

  createVerificationCode(phoneNumber: string): PhoneVerificationRecord {
    const sessionInfo = randomBase64UrlStr(226);
    const verification: PhoneVerificationRecord = {
      code: randomDigits(6),
      phoneNumber,
      sessionInfo,
    };
    this.verificationCodes.set(sessionInfo, verification);
    return verification;
  }

  getVerificationCodeBySessionInfo(sessionInfo: string): PhoneVerificationRecord | undefined {
    return this.verificationCodes.get(sessionInfo);
  }

  deleteVerificationCodeBySessionInfo(sessionInfo: string): boolean {
    return this.verificationCodes.delete(sessionInfo);
  }

  listVerificationCodes(): Iterable<PhoneVerificationRecord> {
    return this.verificationCodes.values();
  }

  deleteAllAccounts(): void {
    this.users.clear();
    this.localIdForEmail.clear();
    this.localIdForPhoneNumber.clear();
    this.localIdsForProviderEmail.clear();
    this.userIdForProviderRawId.clear();

    // We do not clear OOBs / phone verification codes since some of those may
    // still be valid (e.g. email link / phone sign-in may still create a new
    // user when the code is applied). Others will become invalid and clients
    // will find out when they try consuming them via API endpoints.
  }

  getUserCount(): number {
    return this.users.size;
  }

  queryUsers(
    filter: {
      /* no filter supported yet */
    },
    options: {
      order: "ASC" | "DESC";
      sortByField: "localId";
      startToken?: string;
    }
  ): UserInfo[] {
    const users = [];
    for (const user of this.users.values()) {
      if (!options.startToken || user.localId > options.startToken) {
        /* TODO */ filter;
        users.push(user);
      }
    }
    users.sort((a, b) => {
      if (options.sortByField === "localId") {
        if (a.localId < b.localId) {
          return -1;
        } else if (a.localId > b.localId) {
          return 1;
        }
      }
      return 0;
    });
    return options.order === "DESC" ? users.reverse() : users;
  }

  createTemporaryProof(phoneNumber: string): TemporaryProofRecord {
    const record: TemporaryProofRecord = {
      phoneNumber,
      temporaryProof: randomBase64UrlStr(119),
      temporaryProofExpiresIn: "3600",
    };
    this.temporaryProofs.set(record.temporaryProof, record);
    return record;
  }

  validateTemporaryProof(
    temporaryProof: string,
    phoneNumber: string
  ): TemporaryProofRecord | undefined {
    const record = this.temporaryProofs.get(temporaryProof);
    if (!record || record.phoneNumber !== phoneNumber) {
      return undefined;
    }
    return record;
  }

  // This method removes the user from internal indexes like localIdForEmail.
  // It should be used only for deleting or overwriting users.
  private removeUserFromIndex(user: UserInfo): void {
    if (user.email) {
      this.localIdForEmail.delete(user.email);
    }

    if (user.initialEmail) {
      this.localIdForInitialEmail.delete(user.initialEmail);
    }

    if (user.phoneNumber) {
      this.localIdForPhoneNumber.delete(user.phoneNumber);
    }

    for (const info of user.providerUserInfo ?? []) {
      this.userIdForProviderRawId.get(info.providerId)?.delete(info.rawId);
      if (info.email) {
        this.removeProviderEmailForUser(info.email, user.localId);
      }
    }
  }
}

export class AgentProjectState extends ProjectState {
  private tenantProjectForTenantId: Map<string, TenantProjectState> = new Map();
  private readonly _authCloudFunction = new AuthCloudFunction(this.projectId);
  private _config: Config = {
    signIn: { allowDuplicateEmails: false },
    blockingFunctions: {},
  };

  constructor(projectId: string) {
    super(projectId);
  }

  get authCloudFunction() {
    return this._authCloudFunction;
  }

  get oneAccountPerEmail() {
    return !this._config.signIn.allowDuplicateEmails;
  }

  set oneAccountPerEmail(oneAccountPerEmail: boolean) {
    this._config.signIn.allowDuplicateEmails = !oneAccountPerEmail;
  }

  get allowPasswordSignup() {
    return true;
  }

  get disableAuth() {
    return false;
  }

  get mfaConfig() {
    return { state: "ENABLED" as const, enabledProviders: ["PHONE_SMS" as const] };
  }

  get enableAnonymousUser() {
    return true;
  }

  get enableEmailLinkSignin() {
    return true;
  }

  get config() {
    return this._config;
  }

  get blockingFunctionsConfig() {
    return this._config.blockingFunctions;
  }

  set blockingFunctionsConfig(blockingFunctions: BlockingFunctionsConfig) {
    this._config.blockingFunctions = blockingFunctions;
  }

  shouldForwardCredentialToBlockingFunction(
    type: "accessToken" | "idToken" | "refreshToken"
  ): boolean {
    switch (type) {
      case "accessToken":
        return this._config.blockingFunctions.forwardInboundCredentials?.accessToken ?? false;
      case "idToken":
        return this._config.blockingFunctions.forwardInboundCredentials?.idToken ?? false;
      case "refreshToken":
        return this._config.blockingFunctions.forwardInboundCredentials?.refreshToken ?? false;
    }
  }

  getBlockingFunctionUri(event: BlockingFunctionEvents): string | undefined {
    const triggers = this.blockingFunctionsConfig.triggers;
    if (triggers) {
      return Object.prototype.hasOwnProperty.call(triggers, event)
        ? triggers![event].functionUri
        : undefined;
    }
    return undefined;
  }

  updateConfig(
    update: Schemas["GoogleCloudIdentitytoolkitAdminV2Config"],
    updateMask: string | undefined
  ): Config {
    // Empty masks indicate a full update.
    if (!updateMask) {
      this.oneAccountPerEmail = !update.signIn?.allowDuplicateEmails ?? true;
      this.blockingFunctionsConfig = update.blockingFunctions ?? {};
      return this.config;
    }
    return applyMask(updateMask, this.config, update);
  }

  getTenantProject(tenantId: string): TenantProjectState {
    if (!this.tenantProjectForTenantId.has(tenantId)) {
      // Implicitly creates tenant if it does not already exist and sets all
      // configurations to enabled. This is for convenience and differs from
      // production in which configurations, are default disabled. Tests that
      // need to reflect production defaults should first explicitly call
      // `createTenant()` with a `Tenant` object.
      this.createTenantWithTenantId(tenantId, {
        tenantId,
        allowPasswordSignup: true,
        disableAuth: false,
        mfaConfig: {
          state: "ENABLED",
          enabledProviders: ["PHONE_SMS"],
        },
        enableAnonymousUser: true,
        enableEmailLinkSignin: true,
      });
    }
    return this.tenantProjectForTenantId.get(tenantId)!;
  }

  listTenants(startToken?: string): Tenant[] {
    const tenantProjects = [];
    for (const tenantProject of this.tenantProjectForTenantId.values()) {
      if (!startToken || tenantProject.tenantId > startToken) {
        tenantProjects.push(tenantProject);
      }
    }
    // Sort in ascending order by tenantId
    tenantProjects.sort((a, b) => {
      if (a.tenantId < b.tenantId) {
        return -1;
      } else if (a.tenantId > b.tenantId) {
        return 1;
      }
      return 0;
    });
    return tenantProjects.map((tenantProject) => tenantProject.tenantConfig);
  }

  createTenant(tenant: Tenant): Tenant {
    for (let i = 0; i < 10; i++) {
      const tenantId = randomId(28);
      const createdTenant = this.createTenantWithTenantId(tenantId, tenant);
      if (createdTenant) {
        return createdTenant;
      }
    }
    throw new Error("Could not generate a random unique tenantId after 10 tries");
  }

  private createTenantWithTenantId(tenantId: string, tenant: Tenant): Tenant | undefined {
    if (this.tenantProjectForTenantId.has(tenantId)) {
      return undefined;
    }
    tenant.name = `projects/${this.projectId}/tenants/${tenantId}`;
    tenant.tenantId = tenantId;
    this.tenantProjectForTenantId.set(
      tenantId,
      new TenantProjectState(this.projectId, tenantId, tenant, this)
    );
    return tenant;
  }

  deleteTenant(tenantId: string): void {
    this.tenantProjectForTenantId.delete(tenantId);
  }
}

export class TenantProjectState extends ProjectState {
  constructor(
    projectId: string,
    readonly tenantId: string,
    private _tenantConfig: Tenant,
    private readonly parentProject: AgentProjectState
  ) {
    super(projectId);
  }

  get oneAccountPerEmail() {
    return this.parentProject.oneAccountPerEmail;
  }

  get authCloudFunction() {
    return this.parentProject.authCloudFunction;
  }

  get tenantConfig() {
    return this._tenantConfig;
  }

  get allowPasswordSignup() {
    return this._tenantConfig.allowPasswordSignup;
  }

  get disableAuth() {
    return this._tenantConfig.disableAuth;
  }

  get mfaConfig() {
    return this._tenantConfig.mfaConfig;
  }

  get enableAnonymousUser() {
    return this._tenantConfig.enableAnonymousUser;
  }

  get enableEmailLinkSignin() {
    return this._tenantConfig.enableEmailLinkSignin;
  }

  shouldForwardCredentialToBlockingFunction(
    type: "accessToken" | "idToken" | "refreshToken"
  ): boolean {
    return this.parentProject.shouldForwardCredentialToBlockingFunction(type);
  }

  getBlockingFunctionUri(event: BlockingFunctionEvents): string | undefined {
    return this.parentProject.getBlockingFunctionUri(event);
  }

  delete(): void {
    this.parentProject.deleteTenant(this.tenantId);
  }

  updateTenant(
    update: Schemas["GoogleCloudIdentitytoolkitAdminV2Tenant"],
    updateMask: string | undefined
  ): Tenant {
    // Empty masks indicate a full update
    if (!updateMask) {
      const mfaConfig = update.mfaConfig ?? {};
      if (!("state" in mfaConfig)) {
        mfaConfig.state = "DISABLED";
      }
      if (!("enabledProviders" in mfaConfig)) {
        mfaConfig.enabledProviders = [];
      }

      // Default to production defaults if unset
      this._tenantConfig = {
        tenantId: this.tenantId,
        name: this.tenantConfig.name,
        allowPasswordSignup: update.allowPasswordSignup ?? false,
        disableAuth: update.disableAuth ?? false,
        mfaConfig: mfaConfig as MfaConfig,
        enableAnonymousUser: update.enableAnonymousUser ?? false,
        enableEmailLinkSignin: update.enableEmailLinkSignin ?? false,
        displayName: update.displayName,
      };
      return this.tenantConfig;
    }

    return applyMask(updateMask, this.tenantConfig, update);
  }
}

export type ProviderUserInfo = MakeRequired<
  Schemas["GoogleCloudIdentitytoolkitV1ProviderUserInfo"],
  "rawId" | "providerId"
>;
export type UserInfo = Omit<
  Schemas["GoogleCloudIdentitytoolkitV1UserInfo"],
  "localId" | "providerUserInfo"
> & {
  localId: string;
  providerUserInfo?: ProviderUserInfo[];
};
export type MfaConfig = MakeRequired<
  Schemas["GoogleCloudIdentitytoolkitAdminV2MultiFactorAuthConfig"],
  "enabledProviders" | "state"
>;
export type Tenant = Omit<
  MakeRequired<
    Schemas["GoogleCloudIdentitytoolkitAdminV2Tenant"],
    "allowPasswordSignup" | "disableAuth" | "enableAnonymousUser" | "enableEmailLinkSignin"
  >,
  "testPhoneNumbers" | "mfaConfig"
> & { tenantId: string; mfaConfig: MfaConfig };

export type SignInConfig = MakeRequired<
  Schemas["GoogleCloudIdentitytoolkitAdminV2SignInConfig"],
  "allowDuplicateEmails"
>;

export type BlockingFunctionsConfig =
  Schemas["GoogleCloudIdentitytoolkitAdminV2BlockingFunctionsConfig"];

// Serves as a substitute for Schemas["GoogleCloudIdentitytoolkitAdminV2Config"],
// i.e. the configuration object for top-level AgentProjectStates. Emulator
// fixes certain configurations for ease of use / testing, so as non-standard
// behavior, Config only stores the configurable fields.
export type Config = {
  signIn: SignInConfig;
  blockingFunctions: BlockingFunctionsConfig;
};

export interface RefreshTokenRecord {
  _AuthEmulatorRefreshToken: string;
  localId: string;
  provider: string;
  extraClaims: Record<string, unknown>;
  projectId: string;
  secondFactor?: SecondFactorRecord;
  tenantId?: string;
}

export interface SecondFactorRecord {
  identifier: string;
  provider: string;
}

export type OobRequestType = NonNullable<
  Schemas["GoogleCloudIdentitytoolkitV1GetOobCodeRequest"]["requestType"]
>;

export interface OobRecord {
  email: string;
  oobLink: string;
  oobCode: string;
  requestType: OobRequestType;
}

export interface PhoneVerificationRecord {
  code: string;
  phoneNumber: string;
  sessionInfo: string;
}

export enum BlockingFunctionEvents {
  BEFORE_CREATE = "beforeCreate",
  BEFORE_SIGN_IN = "beforeSignIn",
}

interface TemporaryProofRecord {
  phoneNumber: string;
  temporaryProof: string;
  temporaryProofExpiresIn: string;
  // Temporary proofs in emulator never expire to make interactive debugging
  // a bit easier. Therefore, there's no need to record createdAt timestamps.
}

export function encodeRefreshToken(refreshTokenRecord: RefreshTokenRecord): string {
  return Buffer.from(JSON.stringify(refreshTokenRecord), "utf8").toString("base64");
}

export function decodeRefreshToken(refreshTokenString: string): RefreshTokenRecord {
  let refreshTokenRecord: RefreshTokenRecord;
  try {
    const json = Buffer.from(refreshTokenString, "base64").toString("utf8");
    refreshTokenRecord = JSON.parse(json) as RefreshTokenRecord;
  } catch {
    throw new BadRequestError("INVALID_REFRESH_TOKEN");
  }
  assert(refreshTokenRecord._AuthEmulatorRefreshToken, "INVALID_REFRESH_TOKEN");
  return refreshTokenRecord;
}

function getProviderEmailsForUser(user: UserInfo): Set<string> {
  const emails = new Set<string>();
  user.providerUserInfo?.forEach(({ email }) => {
    if (email) {
      emails.add(email);
    }
  });
  return emails;
}

/**
 * Updates fields based on specified update mask. Note that this is a no-op if
 * the update mask is empty.
 *
 * @param updateMask a comma separated list of fully qualified names of fields
 * @param dest the destination to apply updates to
 * @param update the updates to apply
 * @returns the updated destination object
 */
function applyMask<T>(updateMask: string, dest: T, update: DeepPartial<T>): T {
  const paths = updateMask.split(",");
  for (const path of paths) {
    const fields = path.split(".");
    // Using `any` here to recurse over destination objects
    let updateField: any = update;
    let existingField: any = dest;
    let field;
    for (let i = 0; i < fields.length - 1; i++) {
      field = fields[i];

      // Doesn't exist on update
      if (updateField[field] == null) {
        console.warn(`Unable to find field '${field}' in update '${updateField}`);
        break;
      }

      // Field on existing is an array or is a primitive (i.e. cannot index
      // any further)
      if (Array.isArray(updateField[field]) || Object(updateField[field]) !== updateField[field]) {
        console.warn(`Field '${field}' is singular and cannot have sub-fields`);
        break;
      }

      // Non-standard behavior, this creates new fields regardless of if the
      // final field is set. Typical behavior would not modify the config
      // payload if the final field is not successfully set.
      if (!existingField[field]) {
        existingField[field] = {};
      }

      updateField = updateField[field];
      existingField = existingField[field];
    }
    // Reassign final field if possible
    field = fields[fields.length - 1];
    if (updateField[field] == null) {
      console.warn(`Unable to find field '${field}' in update '${JSON.stringify(updateField)}`);
      continue;
    }
    existingField[field] = updateField[field];
  }

  return dest;
}


text:
package sword.langbook3.android.db;

import org.junit.jupiter.api.Test;

import sword.collections.ImmutableHashMap;
import sword.collections.ImmutableHashSet;
import sword.collections.ImmutableIntRange;
import sword.collections.ImmutableIntSet;
import sword.collections.ImmutableIntSetCreator;
import sword.collections.ImmutableList;
import sword.collections.ImmutableMap;
import sword.collections.ImmutableSet;
import sword.database.DbQuery;
import sword.database.MemoryDatabase;
import sword.langbook3.android.models.SearchResult;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static sword.langbook3.android.db.AcceptationsManager2Test.addSimpleAcceptation;
import static sword.langbook3.android.db.AgentsManager2Test.composeSingleElementArray;
import static sword.langbook3.android.db.AgentsManager2Test.setOf;

final class LangbookReadableDatabaseTest {

    private void addAgent(
            LangbookManager2<ConceptIdHolder, LanguageIdHolder, AlphabetIdHolder, CharacterIdHolder, CharacterCompositionTypeIdHolder, SymbolArrayIdHolder, CorrelationIdHolder, CorrelationArrayIdHolder, AcceptationIdHolder, BunchIdHolder, BunchSetIdHolder, RuleIdHolder, AgentIdHolder, QuizIdHolder, SentenceIdHolder> manager, BunchIdHolder sourceBunch, AlphabetIdHolder alphabet, String endMatcherText, String endAdderText, RuleIdHolder rule) {
        final ImmutableSet<BunchIdHolder> emptyBunchSet = ImmutableHashSet.empty();
        final ImmutableSet<BunchIdHolder> verbBunchSet = emptyBunchSet.add(sourceBunch);

        final ImmutableCorrelation<AlphabetIdHolder> emptyCorrelation = ImmutableCorrelation.empty();
        final ImmutableCorrelationArray<AlphabetIdHolder> emptyCorrelationArray = ImmutableCorrelationArray.empty();
        final ImmutableCorrelation<AlphabetIdHolder> endMatcher = (endMatcherText != null)? emptyCorrelation.put(alphabet, endMatcherText) : emptyCorrelation;
        final ImmutableCorrelationArray<AlphabetIdHolder> endAdder = composeSingleElementArray((endAdderText != null)? emptyCorrelation.put(alphabet, endAdderText) : emptyCorrelation);

        manager.addAgent(setOf(), verbBunchSet, emptyBunchSet, emptyCorrelation, emptyCorrelationArray, endMatcher, endAdder, rule);
    }

    private AlphabetIdHolder getNextAvailableId(ConceptsChecker<ConceptIdHolder> manager) {
        return new AlphabetIdHolder(manager.getNextAvailableConceptId().key);
    }

    private BunchIdHolder conceptAsBunchId(ConceptIdHolder conceptId) {
        return new BunchIdHolder(conceptId.key);
    }

    private RuleIdHolder conceptAsRuleId(ConceptIdHolder conceptId) {
        return (conceptId == null)? null : new RuleIdHolder(conceptId.key);
    }

    @Test
    void testReadAllMatchingBunches() {
        final MemoryDatabase db = new MemoryDatabase();
        final ConceptIdManager conceptIdManager = new ConceptIdManager();
        final LanguageIdManager languageIdManager = new LanguageIdManager();
        final AlphabetIdManager alphabetIdManager = new AlphabetIdManager();
        final CharacterIdManager characterIdManager = new CharacterIdManager();
        final CharacterCompositionTypeIdManager characterCompositionTypeIdManager = new CharacterCompositionTypeIdManager();
        final SymbolArrayIdManager symbolArrayIdManager = new SymbolArrayIdManager();
        final CorrelationIdManager correlationIdManager = new CorrelationIdManager();
        final CorrelationArrayIdManager correlationArrayIdManager = new CorrelationArrayIdManager();
        final AcceptationIdManager acceptationIdManager = new AcceptationIdManager();
        final BunchIdManager bunchIdManager = new BunchIdManager();
        final BunchSetIdManager bunchSetIdManager = new BunchSetIdManager();
        final RuleIdManager ruleIdManager = new RuleIdManager();
        final AgentIdManager agentIdManager = new AgentIdManager();
        final QuizIdManager quizIdManager = new QuizIdManager();
        final SentenceIdManager sentenceIdManager = new SentenceIdManager();
        final LangbookDatabaseManager2<ConceptIdHolder, LanguageIdHolder, AlphabetIdHolder, CharacterIdHolder, CharacterCompositionTypeIdHolder, SymbolArrayIdHolder, CorrelationIdHolder, CorrelationArrayIdHolder, AcceptationIdHolder, BunchIdHolder, BunchSetIdHolder, RuleIdHolder, AgentIdHolder, QuizIdHolder, SentenceIdHolder> manager = new LangbookDatabaseManager2<>(db, conceptIdManager, languageIdManager, alphabetIdManager, characterIdManager, characterCompositionTypeIdManager, symbolArrayIdManager, correlationIdManager, correlationArrayIdManager, acceptationIdManager, bunchIdManager, bunchSetIdManager, ruleIdManager, agentIdManager, quizIdManager, sentenceIdManager);
        final AlphabetIdHolder alphabet = manager.addLanguage("es").mainAlphabet;
        final ConceptIdHolder gerundConcept = manager.getNextAvailableConceptId();
        final ConceptIdHolder pluralConcept = conceptIdManager.recheckAvailability(gerundConcept, gerundConcept);
        final ConceptIdHolder verbConceptId = conceptIdManager.recheckAvailability(pluralConcept, pluralConcept);
        final ConceptIdHolder femaleNounConceptId = conceptIdManager.recheckAvailability(verbConceptId, verbConceptId);

        final String verbBunchTitle = "verbos (1a conjugación)";
        addSimpleAcceptation(manager, alphabet, verbConceptId, verbBunchTitle);

        final String femaleNounBunchTitle = "substantivos femeninos";
        addSimpleAcceptation(manager, alphabet, femaleNounConceptId, femaleNounBunchTitle);

        final BunchIdHolder verbBunchId = conceptAsBunchId(verbConceptId);
        final RuleIdHolder gerundRule = conceptAsRuleId(gerundConcept);
        addAgent(manager, verbBunchId, alphabet, "ar", "ando", gerundRule);

        final BunchIdHolder femaleNounBunchId = conceptAsBunchId(femaleNounConceptId);
        final RuleIdHolder pluralRule = conceptAsRuleId(pluralConcept);
        addAgent(manager, femaleNounBunchId, alphabet, null, "s", pluralRule);

        final ImmutableCorrelation<AlphabetIdHolder> texts = new ImmutableCorrelation.Builder<AlphabetIdHolder>().put(alphabet, "cantar").build();
        final ImmutableMap<BunchIdHolder, String> matchingBunches = manager.readAllMatchingBunches(texts, alphabet);
        assertEquals(ImmutableHashMap.<BunchIdHolder, String>empty().put(verbBunchId, verbBunchTitle), matchingBunches);

        final ImmutableCorrelation<AlphabetIdHolder> texts2 = new ImmutableCorrelation.Builder<AlphabetIdHolder>().put(alphabet, "comer").build();
        assertTrue(manager.readAllMatchingBunches(texts2, alphabet).isEmpty());
    }

    @Test
    void testFindAcceptationFromText() {
        final ConceptIdManager conceptIdManager = new ConceptIdManager();
        final LanguageIdManager languageIdManager = new LanguageIdManager();
        final AlphabetIdManager alphabetIdManager = new AlphabetIdManager();
        final CharacterIdManager characterIdManager = new CharacterIdManager();
        final CharacterCompositionTypeIdManager characterCompositionTypeIdManager = new CharacterCompositionTypeIdManager();
        final SymbolArrayIdManager symbolArrayIdManager = new SymbolArrayIdManager();
        final CorrelationIdManager correlationIdManager = new CorrelationIdManager();
        final CorrelationArrayIdManager correlationArrayIdManager = new CorrelationArrayIdManager();
        final AcceptationIdManager acceptationIdManager = new AcceptationIdManager();
        final BunchIdManager bunchIdManager = new BunchIdManager();
        final BunchSetIdManager bunchSetIdManager = new BunchSetIdManager();
        final RuleIdManager ruleIdManager = new RuleIdManager();
        final AgentIdManager agentIdManager = new AgentIdManager();
        final QuizIdManager quizIdManager = new QuizIdManager();
        final SentenceIdManager sentenceIdManager = new SentenceIdManager();

        final ImmutableSet<String> texts = new ImmutableHashSet.Builder<String>()
                .add("hello")
                .add("Hi")
                .add("hi")
                .add("bye")
                .add("byebye")
                .build();

        for (String text1 : texts) {
            for (String text2 : texts) {
                for (String text3 : texts) {
                    final ImmutableList.Builder<String> textListBuilder = new ImmutableList.Builder<>();
                    textListBuilder.append(text1);

                    if (text2 != text1) {
                        textListBuilder.append(text2);
                    }

                    if (text3 != text1 && text3 != text2) {
                        textListBuilder.append(text3);
                    }

                    final ImmutableList<String> textList = textListBuilder.build();

                    final MemoryDatabase db = new MemoryDatabase();
                    final LangbookDatabaseManager2<ConceptIdHolder, LanguageIdHolder, AlphabetIdHolder, CharacterIdHolder, CharacterCompositionTypeIdHolder, SymbolArrayIdHolder, CorrelationIdHolder, CorrelationArrayIdHolder, AcceptationIdHolder, BunchIdHolder, BunchSetIdHolder, RuleIdHolder, AgentIdHolder, QuizIdHolder, SentenceIdHolder> manager = new LangbookDatabaseManager2<>(db, conceptIdManager, languageIdManager, alphabetIdManager, characterIdManager, characterCompositionTypeIdManager, symbolArrayIdManager, correlationIdManager, correlationArrayIdManager, acceptationIdManager, bunchIdManager, bunchSetIdManager, ruleIdManager, agentIdManager, quizIdManager, sentenceIdManager);
                    final AlphabetIdHolder alphabet1 = manager.addLanguage("xx").mainAlphabet;
                    final AlphabetIdHolder alphabet2 = getNextAvailableId(manager);
                    assertTrue(manager.addAlphabetCopyingFromOther(alphabet2, alphabet1));

                    final ConceptIdHolder concept1 = manager.getNextAvailableConceptId();
                    final ConceptIdHolder concept2 = conceptIdManager.recheckAvailability(concept1, concept1);

                    final ImmutableList.Builder<AcceptationIdHolder> accListBuilder = new ImmutableList.Builder<>();
                    accListBuilder.append(addSimpleAcceptation(manager, alphabet1, concept1, textList.valueAt(0)));
                    if (textList.size() >= 2) {
                        accListBuilder.append(addSimpleAcceptation(manager, alphabet1, concept2, textList.valueAt(1)));
                    }

                    if (textList.size() == 3) {
                        final ConceptIdHolder concept3 = conceptIdManager.recheckAvailability(concept2, concept2);
                        accListBuilder.append(addSimpleAcceptation(manager, alphabet1, concept3, textList.valueAt(2)));
                    }

                    final ImmutableList<AcceptationIdHolder> accList = accListBuilder.build();

                    final int restrictionStringType = DbQuery.RestrictionStringTypes.STARTS_WITH;
                    for (int length = 1; length <= text1.length(); length++) {
                        final String queryText = text1.substring(0, length);
                        final ImmutableList<SearchResult<AcceptationIdHolder, RuleIdHolder>> results = manager.findAcceptationFromText(queryText, restrictionStringType, new ImmutableIntRange(0, Integer.MAX_VALUE));
                        final ImmutableIntSet.Builder matchingIndexesBuilder = new ImmutableIntSetCreator();
                        for (int i = 0; i < textList.size(); i++) {
                            if (textList.valueAt(i).startsWith(queryText)) {
                                matchingIndexesBuilder.add(i);
                            }
                        }
                        final ImmutableIntSet matchingIndexes = matchingIndexesBuilder.build();
                        assertEquals(matchingIndexes.size(), results.size());
                        for (int textIndex : matchingIndexes) {
                            final SearchResult<AcceptationIdHolder, RuleIdHolder> result = results.findFirst(r -> r.getId().equals(accList.valueAt(textIndex)), null);
                            assertNotNull(result);
                            assertEquals(textList.valueAt(textIndex), result.getStr());
                        }
                    }
                }
            }
        }
    }
}

redpajama_set_name: RedPajamaGithub


text:
import type {
	BasicTransaction,
	SecurityHoldingTransaction,
	SplitTransaction,
	SplitTransactionChild,
	Subtransaction,
	SubtransactionType,
	SubtransferTransaction,
	Transaction,
	TransactionDirection,
	TransactionStatus,
	TransactionType,
	TransferTransaction
} from "transactions/types";
import {
	startOfDay,
	subDays
} from "date-fns";
import createAccount from "mocks/accounts/factories";
import createCategory from "mocks/categories/factories";
import createPayee from "mocks/payees/factories";
import createSecurity from "mocks/securities/factories";

let id = 1;

function createPartialTransaction(props: Partial<SplitTransactionChild | Transaction>): Partial<SplitTransactionChild | Transaction> {
	id++;

	return {
		id,
		memo: "",
		flag_type: null,
		flag: null,
		balance: 0,
		transaction_date: subDays(startOfDay(new Date()), 1),
		status: "" as TransactionStatus,
		...props
	} as Partial<Transaction>;
}

function createPartialCashTransaction(props: Partial<BasicTransaction | SplitTransaction | SubtransferTransaction | TransferTransaction>): Partial<BasicTransaction | SplitTransaction | SubtransferTransaction | TransferTransaction> {
	return createPartialTransaction({
		amount: 0,
		primary_account: createAccount({ id: 1, name: "Account 1" }),
		direction: "inflow" as TransactionDirection,
		...props
	}) as Partial<BasicTransaction | SplitTransaction | SubtransferTransaction | TransferTransaction>;
}

function createPartialPayeeTransaction(props: Partial<BasicTransaction | SplitTransaction | SubtransferTransaction | TransferTransaction>): Partial<BasicTransaction | SplitTransaction | SubtransferTransaction | TransferTransaction> {
	return createPartialCashTransaction({ payee: createPayee({ id: 1, name: "Payee 1" }), ...props });
}

function createPartialSecurityTransaction(props: Partial<SecurityHoldingTransaction>): Partial<SecurityHoldingTransaction> {
	return createPartialTransaction({
		security: createSecurity({ id: 1, name: "Security 1" }),
		primary_account: createAccount({ id: 1, name: "Account 1" }),
		category: {
			id: "AddShares",
			name: "Add Shares"
		},
		direction: "inflow" as TransactionDirection,
		...props
	}) as Partial<SecurityHoldingTransaction>;
}

export function createBasicTransaction(props: Partial<BasicTransaction> = {}): BasicTransaction {
	return createPartialPayeeTransaction({
		transaction_type: "Basic" as TransactionType,
		category: createCategory({ id: 1, name: "Category 1" }),
		subcategory: createCategory({ id: 2, name: "Category 2", parent_id: 1 }),
		...props
	} as Partial<BasicTransaction>) as BasicTransaction;
}

export function createTransferTransaction(props: Partial<TransferTransaction> = {}): TransferTransaction {
	return createPartialPayeeTransaction({
		transaction_type: "Transfer" as TransactionType,
		category: {
			id: "TransferTo",
			name: "Transfer To"
		},
		account: createAccount({ id: 2, name: "Account 2" }),
		related_status: "" as TransactionStatus,
		...props
	} as Partial<TransferTransaction>) as TransferTransaction;
}

export function createSplitTransaction(props: Partial<SplitTransaction> = {}): SplitTransaction {
	return createPartialPayeeTransaction({
		transaction_type: "Split",
		direction: "outflow",
		category: {
			id: "SplitTo",
			name: "Split To"
		},
		subtransactions: [],
		showSubtransactions: false,
		loadingSubtransactions: false,
		...props
	}) as SplitTransaction;
}

export function createSubtransferTransaction(props: Partial<SubtransferTransaction> = {}): SubtransferTransaction {
	return createPartialPayeeTransaction({
		transaction_type: "Subtransfer" as SubtransactionType,
		category: {
			id: "TransferTo",
			name: "Transfer To"
		},
		account: createAccount({ id: 2, name: "Account 2" }),
		related_status: "",
		parent_id: null,
		...props
	} as Partial<SubtransferTransaction>) as SubtransferTransaction;
}

export function createSubtransaction(props: Partial<Subtransaction> = {}): Subtransaction {
	return createPartialTransaction({
		transaction_type: "Sub" as SubtransactionType,
		category: createCategory({ id: 1, name: "Category 1" }),
		subcategory: createCategory({ id: 2, name: "Category 2", parent_id: 1 }),
		parent_id: null,
		...props
	} as Partial<Subtransaction>) as Subtransaction;
}

export function createSecurityHoldingTransaction(props: Partial<SecurityHoldingTransaction> = {}): SecurityHoldingTransaction {
	return createPartialSecurityTransaction({
		transaction_type: "SecurityHolding",
		quantity: 1,
		...props
	}) as SecurityHoldingTransaction;
}


text:
copyright:
  years: 2015, 2017
lastupdated: "2017-04-13"

---

<!-- Attribute definitions -->
{:new_window: target="_blank"}
{:shortdesc: .shortdesc}
{:codeblock: .codeblock}
{:screen: .screen}
{:pre: .pre}

#Autres opérateurs
{: #c_other_operators}

D'autres opérateurs, dont les opérateurs de kit d'outils que vous avez développés pour vos propres besoins, peuvent être compatibles avec {{site.data.keyword.streaminganalyticsshort}}.
{:shortdesc}

Les kits d'outils doivent répondre aux critères suivants pour être compatibles avec {{site.data.keyword.streaminganalyticsshort}} :

1. Aucune préinstallation de logiciel supplémentaire n'est requise sur les noeuds d'application de votre instance de service.
2. Toutes les informations de configuration requises par le kit d'outils peuvent être incluses dans le bundle d'applications à l'aide du kit d'outils.


text:
package com.keeps.ksxtmanager.controller;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import com.google.gson.Gson;
import com.keeps.core.controller.AbstractAPIController;
import com.keeps.ksxtmanager.model.KsShijuan;
import com.keeps.ksxtmanager.service.ShijuanService;
import com.keeps.ksxtmanager.system.service.DictService;
import com.keeps.ksxtmanager.utils.Constants;
import com.keeps.tools.utils.JsonPost;

@Controller
@RestController
@RequestMapping("shijuan")
public class ShijuanController extends AbstractAPIController{

	@Autowired
	private ShijuanService shijuanService;

	@Autowired
	private DictService dictService;

	/**
	  * @Title:			index
	  * @Description:	初始化打开试卷列表
	  * @param:
	  * @return:
	  * @author:		keeps
	  * @data:			2017年10月5日
	 */
	@RequestMapping("index")
	public ModelAndView index(ModelAndView view,HttpServletRequest request, HttpServletResponse response){
		view.setViewName("manager/shijuan/list");
		view.addObject("degofdifftypelist", dictService.getDictTypeByCode(Constants.DICT_CODE[0]));
		return view;
	}

	@SuppressWarnings("rawtypes")
	@RequestMapping("query")
	public Map query(final KsShijuan shijuan) {
		Map m = success();
		m.put("message", shijuanService.queryList(shijuan));
		return m;
	}

	/**
	  * @Title:			querywksj
	  * @Description:	我的考试-待考
	  * @param:
	  * @return:
	  * @author:		keeps
	  * @data:			2017年10月7日
	 */
	@SuppressWarnings("rawtypes")
	@RequestMapping("queryWksj")
	public Map queryWksj(final KsShijuan shijuan) {
		Map m = success();
		m.put("message", shijuanService.querywksjList(shijuan));
		return m;
	}

	@RequestMapping("add")
	public ModelAndView add(ModelAndView view) {
		view.addObject("degofdifftypelist", dictService.getDictTypeByCode(Constants.DICT_CODE[0]));
		view.addObject("shijuantypejson", new Gson().toJson(dictService.getDictTypeSelectByCode(Constants.DICT_CODE[3])));
		view.setViewName("manager/shijuan/add");
		return view;
	}

	@RequestMapping("edit")
	public ModelAndView edit(ModelAndView view,Integer id) {
		view.addObject("degofdifftypelist", dictService.getDictTypeByCode(Constants.DICT_CODE[0]));
		view.addObject("shijuantypejson", new Gson().toJson(dictService.getDictTypeSelectByCode(Constants.DICT_CODE[3])));
		view.addObject("shijuan", shijuanService.getById(id));
		view.setViewName("manager/shijuan/edit");
		return view;
	}

	@SuppressWarnings("rawtypes")
	@RequestMapping("save")
	public Map save(HttpServletRequest request,final KsShijuan shijuan){
		Map m = success();
		m.put("msg", shijuanService.saveOrUpdate(shijuan));
		return m;
	}

	@SuppressWarnings("rawtypes")
	@RequestMapping("update")
	public Map update(HttpServletRequest request,final KsShijuan shijuan){
		Map m = success();
		m.put("msg", shijuanService.saveOrUpdate(shijuan));
		return m;
	}

	@SuppressWarnings("rawtypes")
	@RequestMapping("delete")
	public @ResponseBody Map delete(final String ids){
		return super.doJsonPost(new JsonPost() {
			@SuppressWarnings("unchecked")
			@Override
			public void doInstancePost(Map arg0) {
				arg0.put("message", shijuanService.delete(ids));
			}
		});
	}

}


text:
#include <qpid/dispatch/alloc.h>
#include <qpid/dispatch.h>
#include <qpid/dispatch/buffer.h>
#include <stdio.h>

int tool_tests(void);
int timer_tests(qd_dispatch_t*);
int core_timer_tests(void);
int alloc_tests(void);
int compose_tests(void);
int policy_tests(void);
int failoverlist_tests(void);
int parse_tree_tests(void);
int proton_utils_tests(void);

int main(int argc, char** argv)
{
    if (argc != 2) {
        fprintf(stderr, "usage: %s <config-file>\n", argv[0]);
        exit(1);
    }
    int result = 0;

    // Call qd_dispatch() first initialize allocator used by other tests.
    qd_dispatch_t *qd = qd_dispatch(0, false);

    qd_dispatch_validate_config(argv[1]);
    if (qd_error_code()) {
        printf("Config failed: %s\n", qd_error_message());
        return 1;
    }

    qd_dispatch_load_config(qd, argv[1]);
    if (qd_error_code()) {
        printf("Config failed: %s\n", qd_error_message());
        return 1;
    }
    result += timer_tests(qd);
    result += tool_tests();
    result += compose_tests();
    result += alloc_tests();
    result += policy_tests();
    result += failoverlist_tests();
    result += parse_tree_tests();
    result += proton_utils_tests();
    result += core_timer_tests();

    qd_dispatch_free(qd);       // dispatch_free last.

    return result;
}


text:
<!DOCTYPE html>

	<title>run.js</title>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
	<link rel="stylesheet" media="all" href="../docco.css" />

		Other source files…

				<input type="search" id="jump_search" placeholder="search for source file">

						src/abs.js

						src/accrint.js

						src/acos.js

						src/acosh.js

						src/acot.js

						src/acoth.js

						src/add.js

						src/address.js

						src/and.js

						src/asin.js

						src/asinh.js

						src/assign.js

						src/atan.js

						src/atan2.js

						src/atanh.js

						src/average.js

						src/base.js

						src/bin2dec.js

						src/branch.js

						src/camelcase.js

						src/ceiling.js

						src/cellindex.js

						src/changed.js

						src/char.js

						src/choose.js

						src/clean.js

						src/code.js

						src/column.js

						src/columnletter.js

						src/columnnumber.js

						src/compile.js

						src/concatenate.js

						src/constants.js

						src/cos.js

						src/cumipmt.js

						src/date.js

						src/datedif.js

						src/datevalue.js

						src/day.js

						src/days360.js

						src/dec2bin.js

						src/decodebase64.js

						src/decodejwt.js

						src/degrees.js

						src/diff.js

						src/divide.js

						src/edate.js

						src/entries.js

						src/eomonth.js

						src/eq.js

						src/error.js

						src/even.js

						src/exact.js

						src/filter.js

						src/find.js

						src/flatten.js

						src/floor.js

						src/functions.js

						src/fv.js

						src/get.js

						src/group.js

						src/gt.js

						src/gte.js

						src/guid.js

						src/hash.js

						src/hlookup.js

						src/hour.js

						src/identity.js

						src/ifblank.js

						src/ifempty.js

						src/iferror.js

						src/ifna.js

						src/includes.js

						src/index.js

						src/index2col.js

						src/index2row.js

						src/int.js

						src/interpolate.js

						src/interpolator.js

						src/intersect.js

						src/ipmt.js

						src/isarray.js

						src/isasyncfunction.js

						src/isbinary.js

						src/isblank.js

						src/isboolean.js

						src/isdate.js

						src/isemail.js

						src/isempty.js

						src/iserr.js

						src/iserror.js

						src/iseven.js

						src/isfalsy.js

						src/isfunction.js

						src/isleapyear.js

						src/islowercase.js

						src/isna.js

						src/isnan.js

						src/isnumber.js

						src/isobject.js

						src/isodd.js

						src/isoweeknum.js

						src/ispromise.js

						src/isref.js

						src/istext.js

						src/istruthy.js

						src/isuppercase.js

						src/isurl.js

						src/iswholenumber.js

						src/join.js

						src/keys.js

						src/left.js

						src/len.js

						src/lookup.js

						src/lower.js

						src/lt.js

						src/lte.js

						src/map.js

						src/match.js

						src/max.js

						src/merge.js

						src/min.js

						src/minus.js

						src/minute.js

						src/mod.js

						src/month.js

						src/multiply.js

						src/n.js

						src/nand.js

						src/ne.js

						src/nor.js

						src/not.js

						src/notincludes.js

						src/now.js

						src/nper.js

						src/npv.js

						src/numbers.js

						src/numbervalue.js

						src/oct2dec.js

						src/or.js

						src/overlap.js

						src/parsebool.js

						src/parsedate.js

						src/parsequery.js

						src/parser.js

						src/pi.js

						src/pluck.js

						src/plus.js

						src/pmt.js

						src/power.js

						src/proper.js

						src/pv.js

						src/query.js

						src/reduce.js

						src/ref.js

						src/replace.js

						src/rept.js

						src/right.js

						src/round.js

						src/roundup.js

						src/run.js

						src/search.js

						src/second.js

						src/select.js

						src/serial.js

						src/sin.js

						src/snakecase.js

						src/some.js

						src/sort.js

						src/split.js

						src/substitute.js

						src/substituteAll.js

						src/subtract.js

						src/sum.js

						src/surroundKeys.js

						src/switch.js

						src/tan.js

						src/tau.js

						src/text.js

						src/time.js

						src/timevalue.js

						src/today.js

						src/trim.js

						src/trunc.js

						src/unflatten.js

						src/unique.js

						src/upper.js

						src/vlookup.js

						src/walker.js

						src/within.js

						src/xor.js

						src/year.js

						src/yearfrac.js

run.js

								¶

Copyright 2015-2021 JC Fisher

import * as funcs from "./functions";
import compile from "./compile";
import isText from "./istext"
import isFunction from "./isfunction";
import assign from "./assign";
import { ERRORTYPES as error } from "./error";
import {JSONPath} from 'jsonpath-plus';

								¶

m is a cache of compiled expressions.

let m = {};

								¶

Execute a formula expression

export default function run(exp, params = {}) {

								¶

if the exp is a function then return it immediately.

  let isJSON = false;

  if (isText(params)){
    isJSON = true;
    params = JSON.parse(params)
  }

  let locals = assign({}, params);

								¶

Default get for plain object.

  if (locals.get !== "function") {
    locals.get = (name, scope) => {

      if (isJSON){
        let result = JSONPath({path: name, json: locals});
        return result[0];
      } else if (isText(scope)) {
        return locals[scope] ? locals[scope][name] : undefined;
      }
      return locals[name];
    };
  }

  if (isFunction(exp)) return exp(locals, funcs);
  else if (!isText(exp)) return error.na;

								¶

check cached and shortcut if appropriate.

  if (m.hasOwnProperty(exp)) {

								¶

reload the compiled function.

    compiled = m[exp];
  } else {

								¶

compile the expression.

    var compiled = compile(exp);

								¶

cache the compiled function.

    m[exp] = compiled;
  }

  return compiled(locals, funcs);
}


text:
package com.trsvax.tapestry.aws.core.pages.aws.cloudwatch;

import java.util.List;

import org.apache.tapestry5.annotations.BeginRender;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.ioc.annotations.Inject;

import com.amazonaws.services.cloudwatch.AmazonCloudWatch;
import com.amazonaws.services.cloudwatch.model.Metric;

public class CloudWatchIndex {

	@Inject
	private AmazonCloudWatch client;

	@Property
	private List<Metric> metrics;

	@BeginRender
	void init() {
		metrics = client.listMetrics().getMetrics();
	}

}


text:
package v2.simpleUi;

import v2.simpleUi.uiDecoration.UiDecoratable;
import v2.simpleUi.uiDecoration.UiDecorator;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;

public abstract class M_ProgressBar implements ModifierInterface, UiDecoratable {

	private ProgressBar progressBar;
	private UiDecorator myDecorator;
	private TextView nameText;
	private LinearLayout container;

	public void hide() {
		if (container != null) {
			container.setVisibility(View.GONE);
		}
	}

	public void showAgain() {
		if (container != null) {
			container.setVisibility(View.VISIBLE);
		}
	}

	@Override
	public View getView(Context context) {
		container = new LinearLayout(context);
		container.setOrientation(LinearLayout.VERTICAL);
		container.setGravity(Gravity.CENTER_VERTICAL);
		LayoutParams p = new LinearLayout.LayoutParams(
				LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT, 2);
		LayoutParams p2 = new LinearLayout.LayoutParams(
				LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT, 1);

		nameText = new TextView(context);
		nameText.setText(getVarName());
		nameText.setLayoutParams(p);
		container.addView(nameText);

		progressBar = new ProgressBar(context, null,
				android.R.attr.progressBarStyleHorizontal);
		progressBar.setLayoutParams(p2);
		progressBar.setProgress(loadInitValue());
		progressBar.setMax(loadMaxValue());

		container.addView(progressBar);
		container.setPadding(DEFAULT_PADDING, DEFAULT_PADDING, DEFAULT_PADDING,
				DEFAULT_PADDING);

		if (myDecorator != null) {
			int currentLevel = myDecorator.getCurrentLevel();
			myDecorator.decorate(context, nameText, currentLevel + 1,
					UiDecorator.TYPE_INFO_TEXT);
			myDecorator.decorate(context, progressBar, currentLevel + 1,
					UiDecorator.TYPE_EDIT_TEXT);
		}
		return container;
	}

	@Override
	public boolean assignNewDecorator(UiDecorator decorator) {
		myDecorator = decorator;
		return true;
	}

	@Override
	public boolean save() {
		return true;
	}

	public abstract int loadInitValue();

	public abstract int loadMaxValue();

	public abstract String getVarName();

	private Handler mHandler = new Handler(Looper.getMainLooper());

	public void updateValue(final int newProgressValue, final String updatedText) {
		// do it from the UI thread:
		mHandler.post(new Runnable() {
			@Override
			public void run() {
				progressBar.setProgress(newProgressValue);
				if (updatedText != null)
					nameText.setText(updatedText);
			}
		});
	}

}


text:
package com.github.obourgain.matcher.reflection.custom;

import com.github.obourgain.matcher.reflection.Assertions;
import com.github.obourgain.matcher.reflection.Configuration;
import com.github.obourgain.matcher.reflection.ReflectionMatcher;
import com.github.obourgain.matcher.reflection.path.PathStack;

/**
 * @author olivier bourgain
 */
public abstract class AbstractCustomComparison<T> implements CustomComparison<T> {

    protected Configuration configuration;
    protected Assertions assertions;
    protected PathStack pathStack;
    protected ReflectionMatcher reflectionMatcher;

    protected abstract void doCompare(T t1, T t2);

    public void compare(T t1, T t2) {
        if (t1 == null && t2 == null) {
            return;
        }
        if (t1 == null) {
            assertions.fail("comparing null with non null");
        }
        if (t2 == null) {
            assertions.fail("comparing non null with null");
        }

        if(t1 == t2) {
            return;
        }

        assert t1 != null;
        assert t2 != null;

        if (t1.getClass() != t2.getClass()) {
            assertions.fail("comparing objects with different classes " + t1.getClass() + " " + t2.getClass());
        }
        doCompare(t1, t2);
    }

    public void setConfiguration(Configuration configuration) {
        this.configuration = configuration;
    }

    public void setAssertions(Assertions assertions) {
        this.assertions = assertions;
    }

    public void setReflectionMatcher(ReflectionMatcher reflectionMatcher) {
        this.reflectionMatcher = reflectionMatcher;
    }

    public void setPathStack(PathStack pathStack) {
        this.pathStack = pathStack;
    }
}


text:
namespace blink {

IdleDeadline::IdleDeadline(double deadlineSeconds, CallbackType callbackType)
    : m_deadlineSeconds(deadlineSeconds)
    , m_callbackType(callbackType)
{
}

double IdleDeadline::timeRemaining() const
{
    double timeRemaining = m_deadlineSeconds - monotonicallyIncreasingTime();
    if (timeRemaining < 0)
        timeRemaining = 0;

    return 1000.0 * PerformanceBase::clampTimeResolution(timeRemaining);
}

} // namespace blink


text:
. "test/testlib.sh"

begin_test "pull"
(
  set -e

  reponame="$(basename "$0" ".sh")"
  setup_remote_repo "$reponame"

  clone_repo "$reponame" clone

  clone_repo "$reponame" repo

  git lfs track "*.dat" 2>&1 | tee track.log
  grep "Tracking \*.dat" track.log

  contents="a"
  contents_oid=$(printf "$contents" | shasum -a 256 | cut -f 1 -d " ")

  printf "$contents" > a.dat
  git add a.dat
  git add .gitattributes
  git commit -m "add a.dat" 2>&1 | tee commit.log
  grep "master (root-commit)" commit.log
  grep "2 files changed" commit.log
  grep "create mode 100644 a.dat" commit.log
  grep "create mode 100644 .gitattributes" commit.log

  [ "a" = "$(cat a.dat)" ]

  assert_pointer "master" "a.dat" "$contents_oid" 1

  refute_server_object "$reponame" "$contents_oid"

  git push origin master 2>&1 | tee push.log
  grep "(1 of 1 files)" push.log
  grep "master -> master" push.log

  assert_server_object "$reponame" "$contents_oid"

  # change to the clone's working directory
  cd ../clone

  git pull 2>&1 | grep "Downloading a.dat (1 B)"

  [ "a" = "$(cat a.dat)" ]

  assert_pointer "master" "a.dat" "$contents_oid" 1

  # Remove the working directory and lfs files
  rm a.dat
  rm -rf .git/lfs/objects
  git lfs pull 2>&1 | grep "(1 of 1 files)"
  [ "a" = "$(cat a.dat)" ]
  assert_pointer "master" "a.dat" "$contents_oid" 1

  # Remove just the working directory
  rm a.dat
  git lfs pull
  [ "a" = "$(cat a.dat)" ]

)
end_test


text:
function LinkedListNode(value) {
  this.value = value;
  this.next = null;
}

var a = new LinkedListNode('A');
var b = new LinkedListNode('B');
var c = new LinkedListNode('C');

a.next = b;
b.next = c;

let o = opposite(a);

printNode(o);

function opposite(root) {

  if (!root.next) { return root }

  let previousNode = null;
  let currentNode = root;
  let nextNode = currentNode.next;

  while (currentNode) {

    currentNode.next = previousNode;
    previousNode = currentNode;
    currentNode = nextNode;
    nextNode = nextNode ? nextNode.next : null;
  }

  return previousNode;
}

function printNode(node) {

  let currentNode = node;
  while (currentNode) {

    console.log(`${currentNode.value} -> `);
    currentNode = currentNode.next;
  }
}


text:
package com.qiniu.android;

import android.test.AndroidTestCase;

import com.qiniu.android.utils.Crc32;

import junit.framework.Assert;

public class CrcTest extends AndroidTestCase {
    public void testCrc() {
        byte[] data = "Hello, World!".getBytes();
        long result = Crc32.bytes(data);
        Assert.assertEquals(3964322768L, result);
    }
}


text:
module Sqlserver::Sequence
  module Testing
    module ModelMacros
      def spawn_model(klass, &block)
        Object.instance_eval { remove_const klass } if Object.const_defined?(klass)
        Object.const_set klass, Class.new(ActiveRecord::Base)
        Object.const_get(klass).class_eval(&block) if block_given?
        @spawned_models << klass.to_sym
      end
    end
  end
end


text:
<?xml version="1.0" encoding="UTF-8"?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<coordinator-app name="prepare-clickstream" frequency="${coord:minutes(5)}"
                 start="${jobStart}" end="${jobEnd}"
                 timezone="UTC"
                 xmlns="uri:oozie:coordinator:0.1">
  <datasets>
    <dataset name="rawlogs" frequency="${coord:hours(1)}"
             initial-instance="${initialDataset}" timezone="America/Los_Angeles">
      <uri-template>hdfs://localhost:8020/etl/BI/casualcyclist/clicks/rawlogs/year=${YEAR}/month=${MONTH}/day=${DAY}</uri-template>
      <done-flag></done-flag>
    </dataset>
  </datasets>
  <input-events>
    <data-in name="input" dataset="rawlogs">
      <instance>${coord:current(coord:tzOffset() / 60)}</instance>
    </data-in>
    <data-in name="readyIndicator" dataset="rawlogs">
      <instance>${coord:current(1 + (coord:tzOffset() / 60))}</instance>
    </data-in>
  </input-events>
  <action>
    <workflow>
      <app-path>${workflowRoot}/processing.xml</app-path>
      <configuration>
        <property>
          <name>wfInput</name>
          <value>${coord:dataIn('input')}</value>
        </property>
        <property>
          <name>wfYear</name>
          <value>${coord:formatTime(coord:dateOffset(coord:nominalTime(), tzOffset, 'HOUR'), 'yyyy')}</value>
        </property>
        <property>
          <name>wfMonth</name>
          <value>${coord:formatTime(coord:dateOffset(coord:nominalTime(), tzOffset, 'HOUR'), 'MM')}</value>
        </property>
        <property>
          <name>wfDay</name>
          <value>${coord:formatTime(coord:dateOffset(coord:nominalTime(), tzOffset, 'HOUR'), 'dd')}</value>
        </property>
      </configuration>
    </workflow>
  </action>
</coordinator-app>


text:
const http = require('http');
const fs   = require('fs');

http.createServer((request, response) => {
    response.writeHead(200, { 'Content-Type': 'text/html' });

    fs.createReadStream(__dirname + '/index.html').pipe(response);
}).listen(1337, 'node.local');


text:
using System;
using System.Collections.Generic;

namespace PopForums.Repositories
{
	public interface ILastReadRepository
	{
		void SetForumRead(int userID, int forumID, DateTime readTime);
		void DeleteTopicReadsInForum(int userID, int forumID);
		void SetAllForumsRead(int userID, DateTime readTime);
		void DeleteAllTopicReads(int userID);
		void SetTopicRead(int userID, int topicID, DateTime readTime);
		Dictionary<int, DateTime> GetLastReadTimesForForums(int userID);
		DateTime? GetLastReadTimesForForum(int userID, int forumID);
		Dictionary<int, DateTime> GetLastReadTimesForTopics(int userID, IEnumerable<int> topicIDs);
		DateTime? GetLastReadTimeForTopic(int userID, int topicID);
	}
}


text:
from tw.dojo import DojoJsonRestStore
from sprox.widgets.tw1widgets.dojo import SproxEditableDojoGrid, SproxDojoGrid
from sprox.tablebase import TableBase
from sprox.metadata import FieldsMetadata

class DojoTableBase(TableBase):
    """This class allows you to credate a table widget.

    :Modifiers:
      +-----------------------------------+--------------------------------------------+------------------------------+
      | Name                              | Description                                | Default                      |
      +===================================+============================================+==============================+
      | __url__                           | url that points to the method for data     | None                         |
      |                                   | filler for this table                      |                              |
      +-----------------------------------+--------------------------------------------+------------------------------+
      | __column_options__                | a pass-thru to the Dojo Table Widget       | {}                           |
      |                                   | column_options attribute                   |                              |
      +-----------------------------------+--------------------------------------------+------------------------------+

    also see modifiers in :mod:`sprox.tablebase`

    """

    #object overrides
    __base_widget_type__ = SproxDojoGrid
    __url__ = None
    __column_options__ = {}
    def _do_get_widget_args(self):
        args = super(DojoTableBase, self)._do_get_widget_args()

        if self.__url__ is not None:
            args['action'] = self.__url__
        args['columns'] = self.__fields__
        args['column_options'] = self.__column_options__
        args['headers'] = self.__headers__
        args['jsId'] = self.__sprox_id__
        return args

"""
Experimental for next version.  Will not be included in 0.5"""

class DojoEditableTableBase(TableBase):
    __base_widget_type__ = SproxEditableDojoGrid
    __url__ = None
    __column_options__ = {}

    def _do_get_widget_args(self):
        args = super(DojoEditableTableBase, self)._do_get_widget_args()
        if self.__url__ is not None:
            args['action'] = self.__url__
        args['columns'] = self.__fields__
        args['column_options'] = self.__column_options__
        args['headers'] = self.__headers__
        args['jsId'] = self.__sprox_id__
        return args


text:
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
  <style name="AppTheme" parent="@android:style/Theme">
    <!-- Any customizations for your app running on pre-3.0 devices here -->
  </style>
  <style name="DialogTheme" parent="@android:style/Theme.Dialog">
    <!-- Any customizations for your app running on pre-3.0 devices here -->
  </style>
</resources>


text:
[![Build Status](https://travis-ci.org/AimeeKnight/Blogament.svg?branch=master)](https://travis-ci.org/AimeeKnight/Blogament.svg?branch=master)
[![Coverage Status](https://coveralls.io/repos/AimeeKnight/Blogament/badge.png?branch=master)](https://coveralls.io/r/AimeeKnight/Blogament?branch=master)

![Image](/blogament.png?raw=true)

Blogament is a Rails Engine designed to provide its host with blogging and commenting features.

## Getting started
Instructions for installing and mounting.

#### Installing Blogament
Blogament works with Rails 4.1.1 onwards. You can add it to your Gemfile with:

```ruby
gem 'blogament', :git => 'git://github.com/AimeeKnight/Blogament.git'
```
Run the `bundle` command to install it.

After adding Blogament to your Gemfile you need to copy over
Blogament's migrations and generate your configuration initializer:

```console
rails g blogament:install
```

That will generate a file at `config\initializers\blogament.rb`,
mount the engine inside you app in `routes.rb`, and copy over
blogament's migration files.
You will then need to run `rake db:migrate` as usual.

#### Configuration
In order for your app's users to 'have many' blogs and comments, you'll need to set your
user object (as a string) as Blogament's author class inside the blogament initializer :

```ruby
Rails.application.config.before_initialize do
  Blogament.author_class = "User"
end
```

I have gone ahead and assumed your author class is a user,
but you are free to pass any Active Record model as a string.
Blogament will then take the string "User", call constantize
on it, and set up the post's relation.

Note: You must pass your user object as a string, due to the way engines load their
configuration files. Without the host's class passed as a string, Ruby will throw an errow
since the class will initially be undefined.

The blog's default route is set to `/blog`. You can set this to something else if you'd like.

```ruby
mount Blogament::Engine, at: "/blog"
```
Finally, Blogament needs to know who can create posts and who can't.
In order for Blogament to place nice with your current authentication
implementation, you'll need to implement the following on you user model:

```ruby
def can_blog?
  # responds with true or false
end
```
#### Security

Blogament assumes your sessions will have a `current_user` object.
If you don't have this currently, it will need to be implemented.

#### Rails Console
Posts and comments need to be accessed via their namespace.
For example:

```console
Blogament::Post.find(1)
```

#### Views

First, as with the `current_user` method, it's assumed that your user model
with have an email property. If not, you will need to add one.

Blogs listed on the index and show page will display a 'by line' which
identifies the blogs author. It's up to you to tell blogament what you'd like the by line to display.
In order to do so, you'll also need to implement the following in your model:

```ruby
def by_line
  #you may want to return the models name, or maybe their email.
end
```

Blogament's views can be customized as well. For instance, in order to customize the layout for
the posts index page you can create a file at `app/views/blogament/posts/index.html.erb`,
and it will be used in place of the default view provided.

#### Routing
To access a route provided by blogament, you will need to call your route on the
Blogament object. For instance;

```ruby
blogament.posts_path
```

will take you to `posts#index`.

## Deployment

#### S3 Image Upload with Heroku

Blogament is designed to be used in conjunction with Carrierwave, Fog,
and Amazon S3. While Blogament takes care of the ImageUploader class and all
necessary dependencies (no need to add anything besides blogament to your Gemfile),
it's up to you to configure Carrierwave by creating a file at
`/config/initializers/carrierwave.rb`.
The configuration has worked beautifully
for me when deploying to Heroku, and using the Figaro
gem to store my environment variables.

```ruby
 CarrierWave.configure do |config|
  if Rails.env.test?
    config.storage = :file
    config.enable_processing = false
  elsif Rails.env.development?
    config.storage = :file
    config.enable_processing = true
  else
    config.storage = :fog
    config.fog_credentials = {
      :provider               => 'AWS',                        # required
      :aws_access_key_id      => ENV['S3_KEY'],                # required
      :aws_secret_access_key  => ENV['S3_SECRET'],             # required
    }
    config.fog_directory      = ENV['S3_BUCKET_NAME']          # required
  end
end
```

#### Elastic Search and  Heroku

Note: It is assumed you have Elasticsearch set up in development.
Blogament utilizes Elasticsearch for full text database queries,
and has been tested with bonsai on Heroku.
Setup is as follows:

```sh
heroku addons:add bonsai
heroku config:add ELASTICSEARCH_URL=`heroku config:get BONSAI_URL`
```
Then deploy and reindex:

```sh
heroku run rake searchkick:reindex CLASS=Blogament::Post
```

#### Sidekiq & Unicorn

To make image upload faster on Heroku, Blogament
uses Sidekiq to process S3 image upload in the background.
With that said, Blogament works by installing Unicorn in your application as follows:

`Gemfile`

```ruby
gem 'unicorn'
```

`/config/unicorn.rb`

```ruby
worker_processes Integer(ENV["WEB_CONCURRENCY"] || 3)
timeout 30
preload_app true

before_fork do |server, worker|
  Signal.trap 'TERM' do
    puts 'Unicorn master intercepting TERM and sending myself QUIT instead'
    Process.kill 'QUIT', Process.pid
  end

  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.connection.disconnect!
end

after_fork do |server, worker|
  Signal.trap 'TERM' do
    puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to send QUIT'
  end

  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.establish_connection
end
```

Finally, you'll create a `Procfile` in the root of your application.

```ruby
web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb
worker: sidekiq -q carrierwave
```

Note: It's assumed you have Redis installed in development.
To tell Sidekiq to listen for Carrierwave, start Sidekiq with:

```sh
sidekiq -q carrierwave
```

On Heroku, install the Redis add on with:

```sh
heroku addons:add redistogo
```

## License

Blogament is released under the [MIT License](http://www.opensource.org/licenses/MIT).


text:
var express = require('express'),
  router = express.Router(),
  mongoose = require('mongoose'),
  Post = mongoose.model('Post'),
  moment = require('moment');
var generator = require('../functions/generator.js');

module.exports = function (app) {
  app.use('/app/', router);
};

router.get('/', function (req, res, next) {
  Post.find().sort({modified:-1}).exec(function (err, posts) {
    if (err) return next(err);
    res.render('index', {
      posts: posts
    });
  });
});

router.get('/post', function (req, res, next) {
  Post.find().sort({modified:-1}).exec(function (err, posts) {
    if (err) return next(err);
    res.render('index', {
      posts: posts
    });
  });
});

router.get('/post/new', function(req, res){
  var emptypost = {
    title : 'Article title',
    content : 'Article content\r\n\r\n# Title 1\r\n# Title 2\r\n# Title 3\r\n\r\n** bold **\r\n*italic*',
    slug : 'new-article',
    terms: {
      post_tag : [],
      category : []
    }
  };
  res.render('editpost',
    {
      post:emptypost,
      pagetitle:'new post'
    });
});

router.get('/post/:slug', function(req, res){
  var tempslug = req.params.slug;
  Post.findOne({slug:tempslug}, function(err, post){
    if (err) console.log(err);
    post.realdate = moment(post.date).format('DD/MM/YY, H:mm');
    post.realmodifieddate = moment(post.modified).format('DD/MM/YY, H:mm');
    if (post) {
      res.render('editpost', {post:post});
    }
    else {
      res.redirect('/');
    }
  });
});

router.get('/generate', function(req, res) {
  generator.makeAllSite(function(status){
    res.render('generate', {status:status});
  });
});


text:
ACCEPTED

#### According to
The Catalogue of Life, 3rd January 2011

#### Published in
Proc. Linn. Soc. London 155: 45 (1943)

#### Original name
Stachybotrys theobromae Hansf., 1943

### Remarks
null


text:
ACCEPTED

#### According to
Index Fungorum

#### Published in
Lloydia 5(3): 193 (1942)

#### Original name
Oidium vesiculosum Linder

### Remarks
null


text:
using System;
using System.Collections.Generic;
using System.Linq;
using DNX.Helpers.Maths;
using DNX.Helpers.Validation;

namespace DNX.Helpers.Assemblies
{
    /// <summary>
    /// Class VersionExtensions.
    /// </summary>
    public static class VersionExtensions
    {
        /// <summary>
        /// Simplifies the Version to the specified minimum positions
        /// </summary>
        /// <param name="version">The version.</param>
        /// <param name="minimumPositions">The minimum positions.</param>
        /// <returns>System.String.</returns>
        public static string Simplify(this Version version, int minimumPositions = 1)
        {
            Guard.IsBetween(() => minimumPositions, 1, 4, IsBetweenBoundsType.IncludeLowerAndUpper);

            if (version == null)
            {
                return null;
            }

            var parts = new List<string>( version.ToString().Split('.'));

            while (parts.Any() && parts.Last().Equals("0") && parts.Count > minimumPositions)
            {
                parts = parts.Take(parts.Count - 1).ToList();
            }

            var versionText = string.Join(".", parts);

            return versionText;
        }
    }
}


text:
from oslo_log import log as logging

from neutron_lbaas.drivers import driver_base

LOG = logging.getLogger(__name__)

class LoggingNoopLoadBalancerDriver(driver_base.LoadBalancerBaseDriver):

    def __init__(self, plugin):
        super(LoggingNoopLoadBalancerDriver, self).__init__(plugin)

        # Each of the major LBaaS objects in the neutron database
        # need a corresponding manager/handler class.
        #
        # Put common things that are shared across the entire driver, like
        # config or a rest client handle, here.
        #
        # This function is executed when neutron-server starts.

        self.load_balancer = LoggingNoopLoadBalancerManager(self)
        self.listener = LoggingNoopListenerManager(self)
        self.pool = LoggingNoopPoolManager(self)
        self.member = LoggingNoopMemberManager(self)
        self.health_monitor = LoggingNoopHealthMonitorManager(self)

class LoggingNoopCommonManager(object):

    def create(self, context, obj):
        LOG.debug("LB %s no-op, create %s", self.__class__.__name__, obj.id)

    def update(self, context, old_obj, obj):
        LOG.debug("LB %s no-op, update %s", self.__class__.__name__, obj.id)

    def delete(self, context, obj):
        LOG.debug("LB %s no-op, delete %s", self.__class__.__name__, obj.id)

class LoggingNoopLoadBalancerManager(LoggingNoopCommonManager,
                                     driver_base.BaseLoadBalancerManager):

    def refresh(self, context, obj):
        # This is intended to trigger the backend to check and repair
        # the state of this load balancer and all of its dependent objects
        LOG.debug("LB pool refresh %s", obj.id)

    def stats(self, context, lb_obj):
        LOG.debug("LB stats %s", lb_obj.id)
        return {
            "bytes_in": 0,
            "bytes_out": 0,
            "active_connections": 0,
            "total_connections": 0
        }

    def create(self, context, loadbalancer):
        super(LoggingNoopLoadBalancerManager, self).create(context,
                                                           loadbalancer)
        self.successful_completion(context, loadbalancer)

    def update(self, context, old_loadbalancer, loadbalancer):
        super(LoggingNoopLoadBalancerManager, self).update(context,
                                                           old_loadbalancer,
                                                           loadbalancer)
        self.successful_completion(context, loadbalancer)

    def delete(self, context, loadbalancer):
        super(LoggingNoopLoadBalancerManager, self).delete(context,
                                                           loadbalancer)
        self.successful_completion(context, loadbalancer, delete=True)

class LoggingNoopListenerManager(LoggingNoopCommonManager,
                                 driver_base.BaseListenerManager):
    def create(self, context, listener):
        super(LoggingNoopListenerManager, self).create(context, listener)
        self.successful_completion(context, listener)

    def update(self, context, old_listener, listener):
        super(LoggingNoopListenerManager, self).update(context, old_listener,
                                                       listener)
        self.successful_completion(context, listener)

    def delete(self, context, listener):
        super(LoggingNoopListenerManager, self).delete(context, listener)
        self.successful_completion(context, listener, delete=True)

class LoggingNoopPoolManager(LoggingNoopCommonManager,
                             driver_base.BasePoolManager):
    def create(self, context, pool):
        super(LoggingNoopPoolManager, self).create(context, pool)
        self.successful_completion(context, pool)

    def update(self, context, old_pool, pool):
        super(LoggingNoopPoolManager, self).update(context, old_pool, pool)
        self.successful_completion(context, pool)

    def delete(self, context, pool):
        super(LoggingNoopPoolManager, self).delete(context, pool)
        self.successful_completion(context, pool, delete=True)

class LoggingNoopMemberManager(LoggingNoopCommonManager,
                               driver_base.BaseMemberManager):
    def create(self, context, member):
        super(LoggingNoopMemberManager, self).create(context, member)
        self.successful_completion(context, member)

    def update(self, context, old_member, member):
        super(LoggingNoopMemberManager, self).update(context, old_member,
                                                     member)
        self.successful_completion(context, member)

    def delete(self, context, member):
        super(LoggingNoopMemberManager, self).delete(context, member)
        self.successful_completion(context, member, delete=True)

class LoggingNoopHealthMonitorManager(LoggingNoopCommonManager,
                                      driver_base.BaseHealthMonitorManager):

    def create(self, context, healthmonitor):
        super(LoggingNoopHealthMonitorManager, self).create(context,
                                                            healthmonitor)
        self.successful_completion(context, healthmonitor)

    def update(self, context, old_healthmonitor, healthmonitor):
        super(LoggingNoopHealthMonitorManager, self).update(context,
                                                            old_healthmonitor,
                                                            healthmonitor)
        self.successful_completion(context, healthmonitor)

    def delete(self, context, healthmonitor):
        super(LoggingNoopHealthMonitorManager, self).delete(context,
                                                            healthmonitor)
        self.successful_completion(context, healthmonitor, delete=True)


text:
namespace {

#if !defined(OS_ANDROID)
base::LazyInstance<chromecast::CastCrashReporterClient>::Leaky
    g_crash_reporter_client = LAZY_INSTANCE_INITIALIZER;
#endif  // !defined(OS_ANDROID)

}  // namespace

namespace chromecast {
namespace shell {

CastMainDelegate::CastMainDelegate() {
}

CastMainDelegate::~CastMainDelegate() {
}

bool CastMainDelegate::BasicStartupComplete(int* exit_code) {
  RegisterPathProvider();

  logging::LoggingSettings settings;
#if defined(OS_ANDROID)
  base::FilePath log_file;
  PathService::Get(FILE_CAST_ANDROID_LOG, &log_file);
  settings.logging_dest = logging::LOG_TO_ALL;
  settings.log_file = log_file.value().c_str();
  settings.delete_old = logging::DELETE_OLD_LOG_FILE;
#else
  settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
#endif  // defined(OS_ANDROID)
  logging::InitLogging(settings);
  // Time, process, and thread ID are available through logcat.
  logging::SetLogItems(true, true, false, false);

  content::SetContentClient(&content_client_);
  return false;
}

void CastMainDelegate::PreSandboxStartup() {
#if defined(ARCH_CPU_ARM_FAMILY) && (defined(OS_ANDROID) || defined(OS_LINUX))
  // Create an instance of the CPU class to parse /proc/cpuinfo and cache the
  // results. This data needs to be cached when file-reading is still allowed,
  // since base::CPU expects to be callable later, when file-reading is no
  // longer allowed.
  base::CPU cpu_info;
#endif

  const base::CommandLine* command_line(base::CommandLine::ForCurrentProcess());
  std::string process_type =
      command_line->GetSwitchValueASCII(switches::kProcessType);

#if defined(OS_ANDROID)
  base::FilePath log_file;
  PathService::Get(FILE_CAST_ANDROID_LOG, &log_file);
  chromecast::CrashHandler::Initialize(process_type, log_file);
#else
  crash_reporter::SetCrashReporterClient(g_crash_reporter_client.Pointer());

  if (process_type != switches::kZygoteProcess) {
    CastCrashReporterClient::InitCrashReporter(process_type);
  }
#endif  // defined(OS_ANDROID)

  InitializeResourceBundle();
}

int CastMainDelegate::RunProcess(
    const std::string& process_type,
    const content::MainFunctionParams& main_function_params) {
#if defined(OS_ANDROID)
  if (!process_type.empty())
    return -1;

  // Note: Android must handle running its own browser process.
  // See ChromeMainDelegateAndroid::RunProcess.
  browser_runner_.reset(content::BrowserMainRunner::Create());
  return browser_runner_->Initialize(main_function_params);
#else
  return -1;
#endif  // defined(OS_ANDROID)
}

#if !defined(OS_ANDROID)
void CastMainDelegate::ZygoteForked() {
  const base::CommandLine* command_line(base::CommandLine::ForCurrentProcess());
  std::string process_type =
      command_line->GetSwitchValueASCII(switches::kProcessType);
  CastCrashReporterClient::InitCrashReporter(process_type);
}
#endif  // !defined(OS_ANDROID)

void CastMainDelegate::InitializeResourceBundle() {
#if defined(OS_ANDROID)
  // On Android, the renderer runs with a different UID and can never access
  // the file system. Use the file descriptor passed in at launch time.
  int pak_fd =
      base::GlobalDescriptors::GetInstance()->MaybeGet(kAndroidPakDescriptor);
  if (pak_fd >= 0) {
    ui::ResourceBundle::InitSharedInstanceWithPakFileRegion(
        base::File(pak_fd), base::MemoryMappedFile::Region::kWholeFile);
    ui::ResourceBundle::GetSharedInstance().AddDataPackFromFile(
        base::File(pak_fd), ui::SCALE_FACTOR_100P);
    return;
  }
#endif  // defined(OS_ANDROID)

  resource_delegate_.reset(new CastResourceDelegate());
  // TODO(gunsch): Use LOAD_COMMON_RESOURCES once ResourceBundle no longer
  // hardcodes resource file names.
  ui::ResourceBundle::InitSharedInstanceWithLocale(
      "en-US",
      resource_delegate_.get(),
      ui::ResourceBundle::DO_NOT_LOAD_COMMON_RESOURCES);

  base::FilePath pak_file;
  CHECK(PathService::Get(FILE_CAST_PAK, &pak_file));
  ui::ResourceBundle::GetSharedInstance().AddDataPackFromPath(
      pak_file,
      ui::SCALE_FACTOR_NONE);
}

content::ContentBrowserClient* CastMainDelegate::CreateContentBrowserClient() {
  browser_client_.reset(new CastContentBrowserClient);
  return browser_client_.get();
}

content::ContentRendererClient*
CastMainDelegate::CreateContentRendererClient() {
  renderer_client_.reset(new CastContentRendererClient);
  return renderer_client_.get();
}

}  // namespace shell
}  // namespace chromecast


text:
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type

HAVE_FUNC = False
try:
    import func.overlord.client as fc
    HAVE_FUNC = True
except ImportError:
    pass

import os
import tempfile
import shutil

from ansible.errors import AnsibleError

try:
    from __main__ import display
except ImportError:
    from ansible.utils.display import Display
    display = Display()

class Connection(object):
    ''' Func-based connections '''

    def __init__(self, runner, host, port, *args, **kwargs):
        self.runner = runner
        self.host = host
        self.has_pipelining = False
        # port is unused, this go on func
        self.port = port

    def connect(self, port=None):
        if not HAVE_FUNC:
            raise AnsibleError("func is not installed")

        self.client = fc.Client(self.host)
        return self

    def exec_command(self, cmd, become_user=None, sudoable=False,
                     executable='/bin/sh', in_data=None):
        ''' run a command on the remote minion '''

        if in_data:
            raise AnsibleError("Internal Error: this module does not support optimized module pipelining")

        # totally ignores privlege escalation
        display.vvv("EXEC %s" % (cmd), host=self.host)
        p = self.client.command.run(cmd)[self.host]
        return (p[0], p[1], p[2])

    def _normalize_path(self, path, prefix):
        if not path.startswith(os.path.sep):
            path = os.path.join(os.path.sep, path)
        normpath = os.path.normpath(path)
        return os.path.join(prefix, normpath[1:])

    def put_file(self, in_path, out_path):
        ''' transfer a file from local to remote '''

        out_path = self._normalize_path(out_path, '/')
        display.vvv("PUT %s TO %s" % (in_path, out_path), host=self.host)
        self.client.local.copyfile.send(in_path, out_path)

    def fetch_file(self, in_path, out_path):
        ''' fetch a file from remote to local '''

        in_path = self._normalize_path(in_path, '/')
        display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self.host)
        # need to use a tmp dir due to difference of semantic for getfile
        # ( who take a # directory as destination) and fetch_file, who
        # take a file directly
        tmpdir = tempfile.mkdtemp(prefix="func_ansible")
        self.client.local.getfile.get(in_path, tmpdir)
        shutil.move(os.path.join(tmpdir, self.host, os.path.basename(in_path)),
                    out_path)
        shutil.rmtree(tmpdir)

    def close(self):
        ''' terminate the connection; nothing to do here '''
        pass


text:
package eisenwave.nbt;

/**
 * The {@code TAG_Int} tag.
 */
public final class NBTInt extends NBTTag implements Cloneable {

    private int value;

    public NBTInt(int value) {
        this.value = value;
    }

    @Override
    public Integer getValue() {
        return value;
    }

    public int getIntValue() {
        return value;
    }

    public void setIntValue(int value) {
        this.value = value;
    }

    @Override
    public NBTType getType() {
        return NBTType.INT;
    }

    // MISC

    @Override
    public boolean equals(Object obj) {
        return obj instanceof NBTInt && equals((NBTInt) obj);
    }

    public boolean equals(NBTInt tag) {
        return this.value == tag.value;
    }

    @Override
    public int hashCode() {
        return Integer.hashCode(value);
    }

    @Override
    public String toMSONString() {
        return Integer.toString(value);
    }

    @Override
    public NBTInt clone() {
        return new NBTInt(value);
    }

}


text:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.curso.spring.beans;

/**
 *
 * @author Chema
 */
public class Persona {

    private String nombre = "Uno cualquiera";

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }
}


text:
namespace cutehmi {
namespace workarounds {
namespace qt {
namespace labs {
namespace settings {
namespace internal {

class QMLPlugin:
	public QQmlEngineExtensionPlugin
{
		Q_OBJECT
		Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)

	public:
		void initializeEngine(QQmlEngine * engine, const char * uri) override;
};

}
}
}
}
}
}

#endif

//(c)C: Copyright © 2021-2022, Michał Policht <michal@policht.pl>. All rights reserved.
//(c)C: SPDX-License-Identifier: LGPL-3.0-or-later OR GPL-2.0-or-later
//(c)C: CuteHMI.Workarounds.Qt.labs.settings.1 extension is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version approved by the KDE Free Qt Foundation.
//(c)C: This file is a part of CuteHMI.Workarounds.Qt.labs.settings.1 extension.
//(c)C: Additionally, this file is licensed under terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version approved by the KDE Free Qt Foundation.
//(c)C: CuteHMI.Workarounds.Qt.labs.settings.1 extension is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or GNU General Public License for more details.
//(c)C: You should have received a copy of the GNU Lesser General Public License along with CuteHMI.Workarounds.Qt.labs.settings.1 extension. If not, see <https://www.gnu.org/licenses/>.
//(c)C: You should have received a copy of the GNU General Public License along with CuteHMI.Workarounds.Qt.labs.settings.1 extension. If not, see <https://www.gnu.org/licenses/>.