<commit_before>export { NeuralNet_Base as Base };

import * as Pool from "../../util/Pool.js";
import * as Recyclable from "../../util/Recyclable.js";
import * as ValueMax from "../../util/ValueMax.js";
import * as Embedding from "../Embedding.js";
import * as Stage from "../Stage.js";
import * as StageParamsCreator from "./NeuralNet_StageParamsCreator.js";
import { Params } from "./NeuralNet_Params.js";
import { InferencedParams } from "./NeuralNet_InferencedParams.js";

/**
 * This is the base class of NeuralNet.
 *
 *
 * NeuralNet is composed of an embedding and multiple stages.
 *
 *
 *
 * @member {boolean} bInitOk
 *  If true, this object initialized (i.e. initer()) successfully.
 *
 * @member {number} weightElementOffsetBegin
 *   The position which is started (inclusive) to extract from inputWeightArray by initer().
 *
 * @member {number} weightElementOffsetEnd
 *   The position which is ended to (non-inclusive) extract from inputWeightArray by initer(). Where to extract next weights.
 * Only meaningful when ( this.bInitOk == true ).
 *
 * @member {Embedding.Base} embedding
 *   The embedding layer before all stages of this neuralNet.
 *
 * @member {Stage.Base[]} stageArray
 *   All computation stages of this neuralNet.
 *
 * @member {Stage.Base} stage0
 *   The first computation stage of this neuralNet.
 *
 * @member {Stage.Base} stageLast
 *   The last computation stage of this neuralNet. It may be the same as this.stage0 when there is only one stage inside this neuralNet.
 *
 * @member {number} output_height
 *   The output image height of this neuralNet's last stage.
 *
 * @member {number} output_width
 *   The output image width of this neuralNet's last stage.
 *
 * @member {number} output_channelCount
 *   The output channel count of this neuralNet's last stage.
 *
 * @member {number} tensorWeightCountTotal
 *   The total wieght count used in tensors. Not including Params, because they are not used in tensors. Including inferenced
 * weights, if they are used in tensors.
 *
 * @member {number} tensorWeightCountExtracted
 *   The wieght count extracted from inputWeightArray and used in tensors. Not including Params, because they are not used in
 * tensors. Not including inferenced weights (even if they are used in tensors), because they are not extracted from inputWeightArray.
 *
 */
class NeuralNet_Base extends Recyclable.Root {

  /**
  * Used as default NeuralNet.Base provider for conforming to Recyclable interface.
  */
  static Pool = new Pool.Root( "NeuralNet.Base.Pool", NeuralNet_Base, NeuralNet_Base.setAsConstructor );

  /**
  */
  constructor() {
    super();
    NeuralNet_Base.setAsConstructor_self.call( this );
  }

  /** @override */
  static setAsConstructor() {
    super.setAsConstructor();
    NeuralNet_Base.setAsConstructor_self.call( this );
    return this;
  }

  /** @override */
  static setAsConstructor_self() {
    // Nothing to do here (for NeuralNet.Base).
  }

  /**
  * Generator for initializing this object.
  *
  * @param {ValueMax.Percentage.Aggregate} progressParent
  *   Some new progressToAdvance will be created and added to progressParent. The created progressToAdvance will be
  * increased when every time advanced. The progressParent.getRoot() will be returned when every time yield.
  *
  * @param {NeuralNet.Params} params
  *   A Params object. The params.init() will be called to extract parameters. This params will be owned and destroyed by this .initer().
  * So caller should not use it again.
  *
  * @param {ActivationEscaping.ScaleBoundsArray} inputScaleBoundsArray0
  *   The element value bounds (per channel) of input0. Usually, it is The .output0 of the previous NeuralNet value bounds
  * set. It will be kept (not cloned) directly. So caller should not modify them.
  *
  * @yield {ValueMax.Percentage.Aggregate}
  *   Yield ( value = progressParent.getRoot() ) when ( done = false ).
  *
  * @yield {boolean}
  *   Yield ( value = true ) when ( done = true ) successfully.
  *   Yield ( value = false ) when ( done = true ) failed.
  *
  */
  * initer( progressParent, inputWeightArray, weightElementOffsetBegin, params, inputScaleBoundsArray0 ) {

    // 0. Prepare

    this.weightElementOffsetEnd = this.weightElementOffsetBegin = weightElementOffsetBegin;
    this.bInitOk = false;

    // Estimate the maximum value of progress.
    let progressMax =
      1    // for extracting parameters from inputWeightArray.
      ;

    let progressRoot = progressParent.getRoot();
    let progressToAdvance = progressParent.addChild( ValueMax.Percentage.Concrete.Pool.get_or_create_by( progressMax ) ); // For parameters extracting.
    let progressForEmbedding = progressParent.addChild( ValueMax.Percentage.Aggregate.Pool.get_or_create_by() ); // for embedding extracting.
    let progressForStages = progressParent.addChild( ValueMax.Percentage.Aggregate.Pool.get_or_create_by() ); // for stage0, stage1, stage2, ...

    // 1. Extract parameters.
    if ( !params )
      return false;

    if ( !params.init( inputWeightArray, weightElementOffsetBegin ) )
      return false;  // e.g. input array does not have enough data.
    this.weightElementOffsetEnd = params.weightElementOffsetEnd;

    // Get parameters' real (adjusted) values.
    //
    // Do not keep params in this.params so that the inputWeightArray could be released.
    this.input_height = params.input_height;
    this.input_width = params.input_width;
    this.input_channelCount = params.input_channelCount;
    this.vocabularyChannelCount = params.vocabularyChannelCount;
    this.vocabularyCountPerInputChannel = params.vocabularyCountPerInputChannel;
    this.nConvStageTypeId = params.nConvStageTypeId;
    this.nConvStageTypeName = params.nConvStageTypeName;
    this.stageCountRequested = params.stageCountRequested;
    this.blockCountRequested = params.blockCountRequested;
    this.bKeepInputTensor = params.bKeepInputTensor;

    // The parameters which are determined (inferenced) from the above parameters.
    {
      this.bEmbedVocabularyId = params.inferencedParams.bEmbedVocabularyId;
    }

    this.tensorWeightCountExtracted = 0;
    this.tensorWeightCountTotal = 0;

    ++progressToAdvance.value;
    yield progressRoot;  // Parameters extracted. Report progress.

    let input_ScaleBoundsArray;

    // 2. Create embedding layer.
    {
      let EmbeddingParamsClass = params.EmbeddingParamsClass_get();
      let embeddingParams = EmbeddingParamsClass.Pool.get_or_create_by(
        this.input_height, this.input_width, this.input_channelCount,
        this.vocabularyChannelCount, this.vocabularyCountPerInputChannel,
        this.bEmbedVocabularyId,
        this.bKeepInputTensor
      );

      this.embedding = Embedding.AddGatherReshape.Pool.get_or_create_by();
      let embeddingIniter = this.embedding.initer( progressForEmbedding,
        inputWeightArray, this.weightElementOffsetEnd, embeddingParams,
        inputScaleBoundsArray0
      );

      this.bInitOk = yield* embeddingIniter;
      if ( !this.bInitOk )
        return false;
      this.weightElementOffsetEnd = this.embedding.weightElementOffsetEnd;

      this.tensorWeightCountTotal += this.embedding.tensorWeightCountTotal;
      this.tensorWeightCountExtracted += this.embedding.tensorWeightCountExtracted;

      input_ScaleBoundsArray = this.embedding.boundsArraySet.output0;
    }

    // 3. Create every stages.
    let stageParamsCreator;
    try {
      let StageParamsClass = params.StageParamsClass_get();

      stageParamsCreator = InferencedParams.create_StageParamsCreator_byNeuralNetParams( params );
      stageParamsCreator.determine_stageCount();

      for ( let i = 0; i < stageParamsCreator.stageCount; ++i ) { // Progress for stage0, 1, 2, 3, ...
        progressForStages.addChild( ValueMax.Percentage.Aggregate.Pool.get_or_create_by() );
      }

      let stageParams, stage, stageIniter;
      let next_input_height, next_input_width, next_input_channelCount;

      this.stageArray = Recyclable.OwnerArray.Pool.get_or_create_by(); // Note: OwnerArray can not accept length as parameter.
      this.stageArray.length = stageParamsCreator.stageCount;

      for ( let i = 0; i < this.stageArray.length; ++i ) { // Stage0, 1, 2, 3, ..., StageLast.

        if ( 0 == i ) { // Stage0.
          stageParamsCreator.configTo_beforeStage0();
        } else { // (i.e. stage1, 2, 3, ...)
          stageParamsCreator.configTo_beforeStageN_exceptStage0( i, next_input_height, next_input_width, next_input_channelCount );
        }

        // StageLast. (Note: Stage0 may also be StageLast.)
        if ( ( this.stageArray.length - 1 ) == i ) {
          stageParamsCreator.configTo_beforeStageLast();
        }

        stageParams = stageParamsCreator.create_StageParams( StageParamsClass ); // Create current stage parameters.

        stage = this.stageArray[ i ] = Stage.Base.Pool.get_or_create_by();
        stageIniter = stage.initer( progressForStages.children[ i ],
          inputWeightArray, this.weightElementOffsetEnd, stageParams,
          input_ScaleBoundsArray
        );

        this.bInitOk = yield* stageIniter;
        if ( !this.bInitOk )
          return false;
        this.weightElementOffsetEnd = stage.weightElementOffsetEnd;

        this.tensorWeightCountTotal += stage.tensorWeightCountTotal;
        this.tensorWeightCountExtracted += stage.tensorWeightCountExtracted;

        input_ScaleBoundsArray = stage.output0.scaleBoundsArray;
      }

      this.stage0 = this.stageArray[ 0 ]; // Shortcut to the first stage.
      this.stageLast = this.stageArray[ this.stageArray.length - 1 ]; // Shortcut to the last stage.

      this.dispose_intermediate_ScaleBoundsArray(); // Release all intermediate stages' bounds array set for reducing memory footprint.

      this.bInitOk = true;
      return this.bInitOk;

    } finally {
      if ( stageParamsCreator ) {
        stageParamsCreator.channelShuffler = null; // (Because ownership has been transferred to this NeuralNet object.)
        stageParamsCreator.disposeResources_and_recycleToPool();
        stageParamsCreator = null;
      }
      if ( params ) {
        params.disposeResources_and_recycleToPool();
        params = undefined;
      }
    }
  }

  /**
  * Initialize this object by calling initer() and advance the generator by loop until done.
  *
  * @return {boolean}
  *   Return true if successfully (and progressParent.valuePercentage will be equal to 100).
  *   Return false if failed (and progressParent.valuePercentage will be less than 100).
  *
  * @see Stage.Base.init()
  */
  init( progressParent, inputWeightArray, weightElementOffsetBegin, params, inputScaleBoundsArray0 ) {

    let initer = this.initer( progressParent, inputWeightArray, weightElementOffsetBegin, params, inputScaleBoundsArray0 );
    let initerNext;
    do {
      initerNext = initer.next();
    } while ( ! initerNext.done ); // When ( false == initerNext.done ), the ( initerNext.value ) will be progressParent.getRoot().

    let bInitOk = initerNext.value; // When ( true == initerNext.done ), the ( initerNext.value ) will be initialization successfully or failed.
    return bInitOk;
  }

  /** @override */
  disposeResources() {
    this.stageLast = null; // It is just a reference into this.stageArray[].
    this.stage0 = null; // It is just a reference into this.stageArray[].

    if ( this.stageArray ) {
      this.stageArray.disposeResources_and_recycleToPool();
      this.stageArray = null;
    }

    if ( this.embedding ) {
      this.embedding.disposeResources_and_recycleToPool();
      this.embedding = null;
    }

    this.tensorWeightCountTotal = 0;
    this.tensorWeightCountExtracted = 0;

    this.weightElementOffsetBegin = this.weightElementOffsetEnd = -1;
    this.bInitOk = false;

    super.disposeResources();
  }

  /**
   * Release all ScaleBoundsArray (inside tensor placeholder) except .stage0.inputX and .stageLast.outputX
   *
   * This could reduce memory footprint by releasing unused scale bounds array.
   */
  dispose_intermediate_ScaleBoundsArray() {
    if ( !this.stageArray )
      return;

    { // 1. Release stageLast's inputs' ScaleBoundsArray. (Note: .stageLast.outputX are kept.)
      this.stageLast.input1?.ScaleBoundsArray_dispose();
      this.stageLast.input0.ScaleBoundsArray_dispose();
    }

    // 2. Release intermediate (i.e. except stage0 and stageLast) stages' inputs' and outputs' ScaleBoundsArray.
    for ( let i = ( this.stageArray.length - 2 ); i >= 1; --i ) {
      let stage = this.stageArray[ i ];
      stage.output1?.ScaleBoundsArray_dispose();
      stage.output0.ScaleBoundsArray_dispose();
      stage.input1?.ScaleBoundsArray_dispose();
      stage.input0.ScaleBoundsArray_dispose();
    }

    { // 3. Release stage0's outputs' ScaleBoundsArray. (Note: .stage0.inputX are kept.)
      this.stage0.output1?.ScaleBoundsArray_dispose();
      this.stage0.output0.ScaleBoundsArray_dispose();
    }
  }

  /** Process input, destroy or keep input, return result.
  *
  * @param {tf.tensor3d} inputTensor
  *   The source input image ( height x width x channel ) which will be processed. This inputTensor may or may not be disposed
  * according to init()'s bKeepInputTensor.
  *
  * @return {tf.tensor3d}
  *   Return a new tensor. All other intermediate tensors were disposed.
  */
  apply( inputTensor ) {

    let outputTensor = this.embedding.apply( inputTensor );

    let stageArray = this.stageArray;
    for ( let i = 0; i < stageArray.length; ++i ) {
      outputTensor = stageArray[ i ].apply( outputTensor );
    }

    return outputTensor;
  }

  /** How many stages inside this neuralNet are created. (may different from this.stageCountRequested.) */
  get stageCount() {
    return this.stageArray.length;
  }

  get output_height() {
    return this.stageLast.output0.height;
  }

  get output_width() {
    return this.stageLast.output0.width;
  }

  get output_channelCount() {
    return this.stageLast.output0.channelCount;
  }

  /**
  * @return {string} The description string of all (adjusted) parameters of initer().
  *
  * @override
  */
  toString() {
    let str = ``
      + `input_height=${this.input_height}, `
      + `input_width=${this.input_width}, `
      + `input_channelCount=${this.input_channelCount}, `
      + `vocabularyChannelCount=${this.vocabularyChannelCount}, `
      + `vocabularyCountPerInputChannel=${this.vocabularyCountPerInputChannel}, `
      + `nConvStageTypeName=${this.nConvStageTypeName}(${this.nConvStageTypeId}), `
      + `stageCountRequested=${this.stageCountRequested}, `
      + `blockCountRequested=${this.blockCountRequested}, `
      + `bKeepInputTensor=${this.bKeepInputTensor}, `

      + `stageCount=${this.stageCount}, `
      + `output_height=${this.output_height}, output_width=${this.output_width}, output_channelCount=${this.output_channelCount}`
    ;
    return str;
  }

}

<commit_msg>disposeResources<commit_after>export { NeuralNet_Base as Base };

import * as Pool from "../../util/Pool.js";
import * as Recyclable from "../../util/Recyclable.js";
import * as ValueMax from "../../util/ValueMax.js";
import * as Embedding from "../Embedding.js";
import * as Stage from "../Stage.js";
import * as StageParamsCreator from "./NeuralNet_StageParamsCreator.js";
import { Params } from "./NeuralNet_Params.js";
import { InferencedParams } from "./NeuralNet_InferencedParams.js";

/**
 * This is the base class of NeuralNet.
 *
 *
 * NeuralNet is composed of an embedding and multiple stages.
 *
 *
 *
 * @member {boolean} bInitOk
 *  If true, this object initialized (i.e. initer()) successfully.
 *
 * @member {number} weightElementOffsetBegin
 *   The position which is started (inclusive) to extract from inputWeightArray by initer().
 *
 * @member {number} weightElementOffsetEnd
 *   The position which is ended to (non-inclusive) extract from inputWeightArray by initer(). Where to extract next weights.
 * Only meaningful when ( this.bInitOk == true ).
 *
 * @member {Embedding.Base} embedding
 *   The embedding layer before all stages of this neuralNet.
 *
 * @member {Stage.Base[]} stageArray
 *   All computation stages of this neuralNet.
 *
 * @member {Stage.Base} stage0
 *   The first computation stage of this neuralNet.
 *
 * @member {Stage.Base} stageLast
 *   The last computation stage of this neuralNet. It may be the same as this.stage0 when there is only one stage inside this neuralNet.
 *
 * @member {number} output_height
 *   The output image height of this neuralNet's last stage.
 *
 * @member {number} output_width
 *   The output image width of this neuralNet's last stage.
 *
 * @member {number} output_channelCount
 *   The output channel count of this neuralNet's last stage.
 *
 * @member {number} tensorWeightCountTotal
 *   The total wieght count used in tensors. Not including Params, because they are not used in tensors. Including inferenced
 * weights, if they are used in tensors.
 *
 * @member {number} tensorWeightCountExtracted
 *   The wieght count extracted from inputWeightArray and used in tensors. Not including Params, because they are not used in
 * tensors. Not including inferenced weights (even if they are used in tensors), because they are not extracted from inputWeightArray.
 *
 */
class NeuralNet_Base extends Recyclable.Root {

  /**
  * Used as default NeuralNet.Base provider for conforming to Recyclable interface.
  */
  static Pool = new Pool.Root( "NeuralNet.Base.Pool", NeuralNet_Base, NeuralNet_Base.setAsConstructor );

  /**
  */
  constructor() {
    super();
    NeuralNet_Base.setAsConstructor_self.call( this );
  }

  /** @override */
  static setAsConstructor() {
    super.setAsConstructor();
    NeuralNet_Base.setAsConstructor_self.call( this );
    return this;
  }

  /** @override */
  static setAsConstructor_self() {
    // Nothing to do here (for NeuralNet.Base).
  }

  /**
  * Generator for initializing this object.
  *
  * @param {ValueMax.Percentage.Aggregate} progressParent
  *   Some new progressToAdvance will be created and added to progressParent. The created progressToAdvance will be
  * increased when every time advanced. The progressParent.getRoot() will be returned when every time yield.
  *
  * @param {NeuralNet.Params} params
  *   A Params object. The params.init() will be called to extract parameters. This params will be owned and destroyed by this .initer().
  * So caller should not use it again.
  *
  * @param {ActivationEscaping.ScaleBoundsArray} inputScaleBoundsArray0
  *   The element value bounds (per channel) of input0. Usually, it is The .output0 of the previous NeuralNet value bounds
  * set. It will be kept (not cloned) directly. So caller should not modify them.
  *
  * @yield {ValueMax.Percentage.Aggregate}
  *   Yield ( value = progressParent.getRoot() ) when ( done = false ).
  *
  * @yield {boolean}
  *   Yield ( value = true ) when ( done = true ) successfully.
  *   Yield ( value = false ) when ( done = true ) failed.
  *
  */
  * initer( progressParent, inputWeightArray, weightElementOffsetBegin, params, inputScaleBoundsArray0 ) {

    // 0. Prepare

    this.weightElementOffsetEnd = this.weightElementOffsetBegin = weightElementOffsetBegin;
    this.bInitOk = false;

    // Estimate the maximum value of progress.
    let progressMax =
      1    // for extracting parameters from inputWeightArray.
      ;

    let progressRoot = progressParent.getRoot();
    let progressToAdvance = progressParent.addChild( ValueMax.Percentage.Concrete.Pool.get_or_create_by( progressMax ) ); // For parameters extracting.
    let progressForEmbedding = progressParent.addChild( ValueMax.Percentage.Aggregate.Pool.get_or_create_by() ); // for embedding extracting.
    let progressForStages = progressParent.addChild( ValueMax.Percentage.Aggregate.Pool.get_or_create_by() ); // for stage0, stage1, stage2, ...

    // 1. Extract parameters.
    if ( !params )
      return false;

    if ( !params.init( inputWeightArray, weightElementOffsetBegin ) )
      return false;  // e.g. input array does not have enough data.
    this.weightElementOffsetEnd = params.weightElementOffsetEnd;

    // Get parameters' real (adjusted) values.
    //
    // Do not keep params in this.params so that the inputWeightArray could be released.
    this.input_height = params.input_height;
    this.input_width = params.input_width;
    this.input_channelCount = params.input_channelCount;
    this.vocabularyChannelCount = params.vocabularyChannelCount;
    this.vocabularyCountPerInputChannel = params.vocabularyCountPerInputChannel;
    this.nConvStageTypeId = params.nConvStageTypeId;
    this.nConvStageTypeName = params.nConvStageTypeName;
    this.stageCountRequested = params.stageCountRequested;
    this.blockCountRequested = params.blockCountRequested;
    this.bKeepInputTensor = params.bKeepInputTensor;

    // The parameters which are determined (inferenced) from the above parameters.
    {
      this.bEmbedVocabularyId = params.inferencedParams.bEmbedVocabularyId;
    }

    this.tensorWeightCountExtracted = 0;
    this.tensorWeightCountTotal = 0;

    ++progressToAdvance.value;
    yield progressRoot;  // Parameters extracted. Report progress.

    let input_ScaleBoundsArray;

    // 2. Create embedding layer.
    {
      let EmbeddingParamsClass = params.EmbeddingParamsClass_get();
      let embeddingParams = EmbeddingParamsClass.Pool.get_or_create_by(
        this.input_height, this.input_width, this.input_channelCount,
        this.vocabularyChannelCount, this.vocabularyCountPerInputChannel,
        this.bEmbedVocabularyId,
        this.bKeepInputTensor
      );

      this.embedding = Embedding.AddGatherReshape.Pool.get_or_create_by();
      let embeddingIniter = this.embedding.initer( progressForEmbedding,
        inputWeightArray, this.weightElementOffsetEnd, embeddingParams,
        inputScaleBoundsArray0
      );

      this.bInitOk = yield* embeddingIniter;
      if ( !this.bInitOk )
        return false;
      this.weightElementOffsetEnd = this.embedding.weightElementOffsetEnd;

      this.tensorWeightCountTotal += this.embedding.tensorWeightCountTotal;
      this.tensorWeightCountExtracted += this.embedding.tensorWeightCountExtracted;

      input_ScaleBoundsArray = this.embedding.boundsArraySet.output0;
    }

    // 3. Create every stages.
    let stageParamsCreator;
    try {
      let StageParamsClass = params.StageParamsClass_get();

      stageParamsCreator = InferencedParams.create_StageParamsCreator_byNeuralNetParams( params );
      stageParamsCreator.determine_stageCount();

      for ( let i = 0; i < stageParamsCreator.stageCount; ++i ) { // Progress for stage0, 1, 2, 3, ...
        progressForStages.addChild( ValueMax.Percentage.Aggregate.Pool.get_or_create_by() );
      }

      let stageParams, stage, stageIniter;
      let next_input_height, next_input_width, next_input_channelCount;

      this.stageArray = Recyclable.OwnerArray.Pool.get_or_create_by(); // Note: OwnerArray can not accept length as parameter.
      this.stageArray.length = stageParamsCreator.stageCount;

      for ( let i = 0; i < this.stageArray.length; ++i ) { // Stage0, 1, 2, 3, ..., StageLast.

        if ( 0 == i ) { // Stage0.
          stageParamsCreator.configTo_beforeStage0();
        } else { // (i.e. stage1, 2, 3, ...)
          stageParamsCreator.configTo_beforeStageN_exceptStage0( i, next_input_height, next_input_width, next_input_channelCount );
        }

        // StageLast. (Note: Stage0 may also be StageLast.)
        if ( ( this.stageArray.length - 1 ) == i ) {
          stageParamsCreator.configTo_beforeStageLast();
        }

        stageParams = stageParamsCreator.create_StageParams( StageParamsClass ); // Create current stage parameters.

        stage = this.stageArray[ i ] = Stage.Base.Pool.get_or_create_by();
        stageIniter = stage.initer( progressForStages.children[ i ],
          inputWeightArray, this.weightElementOffsetEnd, stageParams,
          input_ScaleBoundsArray
        );

        this.bInitOk = yield* stageIniter;
        if ( !this.bInitOk )
          return false;
        this.weightElementOffsetEnd = stage.weightElementOffsetEnd;

        this.tensorWeightCountTotal += stage.tensorWeightCountTotal;
        this.tensorWeightCountExtracted += stage.tensorWeightCountExtracted;

        input_ScaleBoundsArray = stage.output0.scaleBoundsArray;
      }

      this.stage0 = this.stageArray[ 0 ]; // Shortcut to the first stage.
      this.stageLast = this.stageArray[ this.stageArray.length - 1 ]; // Shortcut to the last stage.

      this.dispose_intermediate_ScaleBoundsArray(); // Release all intermediate stages' bounds array set for reducing memory footprint.

      this.bInitOk = true;
      return this.bInitOk;

    } finally {
      if ( stageParamsCreator ) {
        stageParamsCreator.channelShuffler = null; // (Because ownership has been transferred to this NeuralNet object.)
        stageParamsCreator.disposeResources_and_recycleToPool();
        stageParamsCreator = null;
      }
      if ( params ) {
        params.disposeResources_and_recycleToPool();
        params = undefined;
      }
    }
  }

  /**
  * Initialize this object by calling initer() and advance the generator by loop until done.
  *
  * @return {boolean}
  *   Return true if successfully (and progressParent.valuePercentage will be equal to 100).
  *   Return false if failed (and progressParent.valuePercentage will be less than 100).
  *
  * @see Stage.Base.init()
  */
  init( progressParent, inputWeightArray, weightElementOffsetBegin, params, inputScaleBoundsArray0 ) {

    let initer = this.initer( progressParent, inputWeightArray, weightElementOffsetBegin, params, inputScaleBoundsArray0 );
    let initerNext;
    do {
      initerNext = initer.next();
    } while ( ! initerNext.done ); // When ( false == initerNext.done ), the ( initerNext.value ) will be progressParent.getRoot().

    let bInitOk = initerNext.value; // When ( true == initerNext.done ), the ( initerNext.value ) will be initialization successfully or failed.
    return bInitOk;
  }

  /** @override */
  disposeResources() {
    this.stageLast = null; // It is just a reference into this.stageArray[].
    this.stage0 = null; // It is just a reference into this.stageArray[].

    if ( this.stageArray ) {
      this.stageArray.disposeResources_and_recycleToPool();
      this.stageArray = null;
    }

    if ( this.embedding ) {
      this.embedding.disposeResources_and_recycleToPool();
      this.embedding = null;
    }

    this.bEmbedVocabularyId = undefined;

    this.bKeepInputTensor = undefined;
    this.blockCountRequested = undefined;
    this.stageCountRequested = undefined;
    this.nConvStageTypeName = undefined;
    this.nConvStageTypeId = undefined;
    this.vocabularyCountPerInputChannel = undefined;
    this.vocabularyChannelCount = undefined;
    this.input_channelCount = undefined;
    this.input_width = undefined;
    this.input_height = undefined;

    this.tensorWeightCountTotal = undefined;
    this.tensorWeightCountExtracted = undefined;

    this.weightElementOffsetBegin = undefined;
    this.weightElementOffsetEnd = undefined;
    this.bInitOk = undefined;

    super.disposeResources();
  }

  /**
   * Release all ScaleBoundsArray (inside tensor placeholder) except .stage0.inputX and .stageLast.outputX
   *
   * This could reduce memory footprint by releasing unused scale bounds array.
   */
  dispose_intermediate_ScaleBoundsArray() {
    if ( !this.stageArray )
      return;

    { // 1. Release stageLast's inputs' ScaleBoundsArray. (Note: .stageLast.outputX are kept.)
      this.stageLast.input1?.ScaleBoundsArray_dispose();
      this.stageLast.input0.ScaleBoundsArray_dispose();
    }

    // 2. Release intermediate (i.e. except stage0 and stageLast) stages' inputs' and outputs' ScaleBoundsArray.
    for ( let i = ( this.stageArray.length - 2 ); i >= 1; --i ) {
      let stage = this.stageArray[ i ];
      stage.output1?.ScaleBoundsArray_dispose();
      stage.output0.ScaleBoundsArray_dispose();
      stage.input1?.ScaleBoundsArray_dispose();
      stage.input0.ScaleBoundsArray_dispose();
    }

    { // 3. Release stage0's outputs' ScaleBoundsArray. (Note: .stage0.inputX are kept.)
      this.stage0.output1?.ScaleBoundsArray_dispose();
      this.stage0.output0.ScaleBoundsArray_dispose();
    }
  }

  /** Process input, destroy or keep input, return result.
  *
  * @param {tf.tensor3d} inputTensor
  *   The source input image ( height x width x channel ) which will be processed. This inputTensor may or may not be disposed
  * according to init()'s bKeepInputTensor.
  *
  * @return {tf.tensor3d}
  *   Return a new tensor. All other intermediate tensors were disposed.
  */
  apply( inputTensor ) {

    let outputTensor = this.embedding.apply( inputTensor );

    let stageArray = this.stageArray;
    for ( let i = 0; i < stageArray.length; ++i ) {
      outputTensor = stageArray[ i ].apply( outputTensor );
    }

    return outputTensor;
  }

  /** How many stages inside this neuralNet are created. (may different from this.stageCountRequested.) */
  get stageCount() {
    return this.stageArray.length;
  }

  get output_height() {
    return this.stageLast.output0.height;
  }

  get output_width() {
    return this.stageLast.output0.width;
  }

  get output_channelCount() {
    return this.stageLast.output0.channelCount;
  }

  /**
  * @return {string} The description string of all (adjusted) parameters of initer().
  *
  * @override
  */
  toString() {
    let str = ``
      + `input_height=${this.input_height}, `
      + `input_width=${this.input_width}, `
      + `input_channelCount=${this.input_channelCount}, `
      + `vocabularyChannelCount=${this.vocabularyChannelCount}, `
      + `vocabularyCountPerInputChannel=${this.vocabularyCountPerInputChannel}, `
      + `nConvStageTypeName=${this.nConvStageTypeName}(${this.nConvStageTypeId}), `
      + `stageCountRequested=${this.stageCountRequested}, `
      + `blockCountRequested=${this.blockCountRequested}, `
      + `bKeepInputTensor=${this.bKeepInputTensor}, `

      + `stageCount=${this.stageCount}, `
      + `output_height=${this.output_height}, output_width=${this.output_width}, output_channelCount=${this.output_channelCount}`
    ;
    return str;
  }

}

<|endoftext|>


<commit_before>'use strict';

const React = require('react');
const { createContainer } = require('sovereign');
const Button = require('react-material/components/Button');

const Overlay = require('../components/overlay');
const OverlayTitle = require('../components/overlay-title');
const OverlayFooter = require('../components/overlay-footer');

class DeleteProjectOverlay extends React.Component {
  render(){
    const {
      name,
      handlers
    } = this.props;

    const {
      deleteProject,
      showProjectsOverlay
    } = handlers;

    return (
      <Overlay>
        <OverlayTitle>Are you sure you want to delete {name}?</OverlayTitle>
        <OverlayFooter>
          <Button onClick={() => deleteProject(name)}>Yes</Button>
          <Button onClick={showProjectsOverlay}>No</Button>
        </OverlayFooter>
      </Overlay>
    );
  }
}

module.exports = createContainer(DeleteProjectOverlay, {
  getStores({ store }){
    return {
      store
    };
  },

  getPropsFromStores({ store }){
    const { deleteProjectName } = store.getState();

    return {
      name: deleteProjectName
    };
  }
});
<commit_msg>use history to cancel project deletion<commit_after>'use strict';

const React = require('react');
const { createContainer } = require('sovereign');
const Button = require('react-material/components/Button');

const Overlay = require('../components/overlay');
const OverlayTitle = require('../components/overlay-title');
const OverlayFooter = require('../components/overlay-footer');
const history = require('../lib/history');

class DeleteProjectOverlay extends React.Component {
  render(){
    const {
      name,
      handlers
    } = this.props;

    const {
      deleteProject
    } = handlers;

    return (
      <Overlay>
        <OverlayTitle>Are you sure you want to delete {name}?</OverlayTitle>
        <OverlayFooter>
          <Button onClick={() => deleteProject(name)}>Yes</Button>
          <Button onClick={history.goBack}>No</Button>
        </OverlayFooter>
      </Overlay>
    );
  }
}

module.exports = createContainer(DeleteProjectOverlay, {
  getStores({ store }){
    return {
      store
    };
  },

  getPropsFromStores({ store }){
    const { deleteProjectName } = store.getState();

    return {
      name: deleteProjectName
    };
  }
});
<|endoftext|>


<commit_before>let Rx = require(`rx`)
let fromEvent = require(`./fromevent`)
let VDOM = {
  h: require(`./virtual-hyperscript`),
  diff: require(`virtual-dom/diff`),
  patch: require(`virtual-dom/patch`),
  parse: typeof window !== `undefined` ? require(`vdom-parser`) : () => {},
}
let {transposeVTree} = require(`./transposition`)
let matchesSelector
// Try-catch to prevent unnecessary import of DOM-specifics in Node.js env:
try {
  matchesSelector = require(`matches-selector`)
} catch (err) {
  matchesSelector = () => {}
}

function isElement(obj) {
  return typeof HTMLElement === `object` ?
    obj instanceof HTMLElement || obj instanceof DocumentFragment : //DOM2
    obj && typeof obj === `object` && obj !== null &&
    (obj.nodeType === 1 || obj.nodeType === 11) &&
    typeof obj.nodeName === `string`
}

function wrapTopLevelVTree(vtree, rootElem) {
  const {id: vtreeId = ``} = vtree.properties
  const {className: vtreeClass = ``} = vtree.properties
  const sameId = vtreeId === rootElem.id
  const sameClass = vtreeClass === rootElem.className
  const sameTagName = vtree.tagName.toUpperCase() === rootElem.tagName
  if (sameId && sameClass && sameTagName) {
    return vtree
  }
  let attrs = {}
  if (rootElem.id) { attrs.id = rootElem.id }
  if (rootElem.className) { attrs.className = rootElem.className }
  return VDOM.h(rootElem.tagName, attrs, [vtree])
}

function makeDiffAndPatchToElement$(rootElem) {
  return function diffAndPatchToElement$([oldVTree, newVTree]) {
    if (typeof newVTree === `undefined`) { return Rx.Observable.empty() }

    let prevVTree = wrapTopLevelVTree(oldVTree, rootElem)
    let nextVTree = wrapTopLevelVTree(newVTree, rootElem)
    /* eslint-disable */
    rootElem = VDOM.patch(rootElem, VDOM.diff(prevVTree, nextVTree))
    /* eslint-enable */
    return Rx.Observable.just(rootElem)
  }
}

function renderRawRootElem$(vtree$, domContainer) {
  let diffAndPatchToElement$ = makeDiffAndPatchToElement$(domContainer)
  return vtree$
    .flatMapLatest(transposeVTree)
    .startWith(VDOM.parse(domContainer))
    .pairwise()
    .flatMap(diffAndPatchToElement$)
}

function isolateSource(source, scope) {
  return source.select(`.cycle-scope-${scope}`)
}

function isolateSink(sink, scope) {
  return sink.map(vtree => {
    const {className: vtreeClass = ``} = vtree.properties
    if (vtreeClass.indexOf(`cycle-scope-${scope}`) === -1) {
      const c = `${vtreeClass} cycle-scope-${scope}`.trim()
      vtree.properties.className = c
    }
    if (vtree.properties.attributes) { // for svg root elements
      const vtreeAttrClass = vtree.properties.attributes[`class`] || ``
      if (vtreeAttrClass.indexOf(`cycle-scope-${scope}`) === -1) {
        const cattr = `${vtreeAttrClass} cycle-scope-${scope}`.trim()
        vtree.properties.attributes[`class`] = cattr
      }
    }
    return vtree
  })
}

function makeIsStrictlyInRootScope(namespace) {
  const classIsForeign = c => {
    const matched = c.match(/cycle-scope-(\S+)/)
    return matched && namespace.indexOf(`.${c}`) === -1
  }
  const classIsDomestic = c => {
    const matched = c.match(/cycle-scope-(\S+)/)
    return matched && namespace.indexOf(`.${c}`) !== -1
  }
  return function isStrictlyInRootScope(leaf) {
    for (let el = leaf; el !== null; el = el.parentElement) {
      const split = String.prototype.split
      const classList = el.classList || split.call(el.className, ` `)
      if (Array.prototype.some.call(classList, classIsDomestic)) {
        return true
      }
      if (Array.prototype.some.call(classList, classIsForeign)) {
        return false
      }
    }
    return true
  }
}

function makeEventsSelector(rootEl$, namespace) {
  return function events(eventName, useCapture = false) {
    if (typeof eventName !== `string`) {
      throw new Error(`DOM driver's events() expects argument to be a ` +
        `string representing the event type to listen for.`)
    }
    const isStrictlyInRootScope = makeIsStrictlyInRootScope(namespace)

    return rootEl$
      .first()
      .flatMapLatest(rootEl => {
        if (rootEl.length === 0) {
          return Rx.Observable.empty()
        }
        if (!namespace || namespace.length === 0) {
          return fromEvent(rootEl, eventName, useCapture)
        }
        const descendantSelector = namespace.join(` `)
        if (matchesSelector(rootEl, descendantSelector)) { // is root Element
          return fromEvent(rootEl, eventName, useCapture)
        }
        const topSelector = namespace.join(``)
        return fromEvent(rootEl, eventName, useCapture).filter(ev => {
          if (matchesSelector(ev.srcElement, descendantSelector) ||
              matchesSelector(ev.srcElement, topSelector))
          {
            return isStrictlyInRootScope(ev.srcElement)
          }
          return false
        })
      })
      .share()
  }
}

function makeElementSelector(rootEl$) {
  return function select(selector) {
    if (typeof selector !== `string`) {
      throw new Error(`DOM driver's select() expects the argument to be a ` +
        `string as a CSS selector`)
    }

    const namespace = this.namespace
    const trimmedSelector = selector.trim()
    const childNamespace = trimmedSelector === `:root` ?
      namespace :
      namespace.concat(trimmedSelector)
    const element$ = rootEl$.map(rootEl => {
      if (childNamespace.join(``) === ``) {
        return rootEl
      }
      let nodeList = rootEl.querySelectorAll(childNamespace.join(` `))
      if (nodeList.length === 0) {
        nodeList = rootEl.querySelectorAll(childNamespace.join(``))
      }
      const array = Array.prototype.slice.call(nodeList)
      return array.filter(makeIsStrictlyInRootScope(childNamespace))
    })
    return {
      observable: element$,
      namespace: childNamespace,
      select: makeElementSelector(rootEl$),
      events: makeEventsSelector(rootEl$, childNamespace),
      isolateSource,
      isolateSink,
    }
  }
}

function validateDOMSink(vtree$) {
  if (!vtree$ || typeof vtree$.subscribe !== `function`) {
    throw new Error(`The DOM driver function expects as input an ` +
      `Observable of virtual DOM elements`)
  }
}

function defaultOnErrorFn(msg) {
  if (console && console.error) {
    console.error(msg)
  } else {
    console.log(msg)
  }
}

function makeDOMDriver(container, options) {
  // Find and prepare the container
  let domContainer = typeof container === `string` ?
    document.querySelector(container) :
    container
  // Check pre-conditions
  if (typeof container === `string` && domContainer === null) {
    throw new Error(`Cannot render into unknown element \`${container}\``)
  } else if (!isElement(domContainer)) {
    throw new Error(`Given container is not a DOM element neither a selector ` +
      `string.`)
  }
  const {onError = defaultOnErrorFn} = options || {}
  if (typeof onError !== `function`) {
    throw new Error(`You provided an \`onError\` to makeDOMDriver but it was ` +
      `not a function. It should be a callback function to handle errors.`)
  }

  return function domDriver(vtree$) {
    validateDOMSink(vtree$)
    let rootElem$ = renderRawRootElem$(vtree$, domContainer)
      .startWith(domContainer)
      .doOnError(onError)
      .replay(null, 1)
    let disposable = rootElem$.connect()
    return {
      observable: rootElem$,
      namespace: [],
      select: makeElementSelector(rootElem$),
      events: makeEventsSelector(rootElem$, []),
      dispose: () => disposable.dispose(),
      isolateSource,
      isolateSink,
    }
  }
}

module.exports = {
  isElement,
  wrapTopLevelVTree,
  makeDiffAndPatchToElement$,
  renderRawRootElem$,
  validateDOMSink,

  makeDOMDriver,
}
<commit_msg>Replace event.srcElement with event.target<commit_after>let Rx = require(`rx`)
let fromEvent = require(`./fromevent`)
let VDOM = {
  h: require(`./virtual-hyperscript`),
  diff: require(`virtual-dom/diff`),
  patch: require(`virtual-dom/patch`),
  parse: typeof window !== `undefined` ? require(`vdom-parser`) : () => {},
}
let {transposeVTree} = require(`./transposition`)
let matchesSelector
// Try-catch to prevent unnecessary import of DOM-specifics in Node.js env:
try {
  matchesSelector = require(`matches-selector`)
} catch (err) {
  matchesSelector = () => {}
}

function isElement(obj) {
  return typeof HTMLElement === `object` ?
    obj instanceof HTMLElement || obj instanceof DocumentFragment : //DOM2
    obj && typeof obj === `object` && obj !== null &&
    (obj.nodeType === 1 || obj.nodeType === 11) &&
    typeof obj.nodeName === `string`
}

function wrapTopLevelVTree(vtree, rootElem) {
  const {id: vtreeId = ``} = vtree.properties
  const {className: vtreeClass = ``} = vtree.properties
  const sameId = vtreeId === rootElem.id
  const sameClass = vtreeClass === rootElem.className
  const sameTagName = vtree.tagName.toUpperCase() === rootElem.tagName
  if (sameId && sameClass && sameTagName) {
    return vtree
  }
  let attrs = {}
  if (rootElem.id) { attrs.id = rootElem.id }
  if (rootElem.className) { attrs.className = rootElem.className }
  return VDOM.h(rootElem.tagName, attrs, [vtree])
}

function makeDiffAndPatchToElement$(rootElem) {
  return function diffAndPatchToElement$([oldVTree, newVTree]) {
    if (typeof newVTree === `undefined`) { return Rx.Observable.empty() }

    let prevVTree = wrapTopLevelVTree(oldVTree, rootElem)
    let nextVTree = wrapTopLevelVTree(newVTree, rootElem)
    /* eslint-disable */
    rootElem = VDOM.patch(rootElem, VDOM.diff(prevVTree, nextVTree))
    /* eslint-enable */
    return Rx.Observable.just(rootElem)
  }
}

function renderRawRootElem$(vtree$, domContainer) {
  let diffAndPatchToElement$ = makeDiffAndPatchToElement$(domContainer)
  return vtree$
    .flatMapLatest(transposeVTree)
    .startWith(VDOM.parse(domContainer))
    .pairwise()
    .flatMap(diffAndPatchToElement$)
}

function isolateSource(source, scope) {
  return source.select(`.cycle-scope-${scope}`)
}

function isolateSink(sink, scope) {
  return sink.map(vtree => {
    const {className: vtreeClass = ``} = vtree.properties
    if (vtreeClass.indexOf(`cycle-scope-${scope}`) === -1) {
      const c = `${vtreeClass} cycle-scope-${scope}`.trim()
      vtree.properties.className = c
    }
    if (vtree.properties.attributes) { // for svg root elements
      const vtreeAttrClass = vtree.properties.attributes[`class`] || ``
      if (vtreeAttrClass.indexOf(`cycle-scope-${scope}`) === -1) {
        const cattr = `${vtreeAttrClass} cycle-scope-${scope}`.trim()
        vtree.properties.attributes[`class`] = cattr
      }
    }
    return vtree
  })
}

function makeIsStrictlyInRootScope(namespace) {
  const classIsForeign = c => {
    const matched = c.match(/cycle-scope-(\S+)/)
    return matched && namespace.indexOf(`.${c}`) === -1
  }
  const classIsDomestic = c => {
    const matched = c.match(/cycle-scope-(\S+)/)
    return matched && namespace.indexOf(`.${c}`) !== -1
  }
  return function isStrictlyInRootScope(leaf) {
    for (let el = leaf; el !== null; el = el.parentElement) {
      const split = String.prototype.split
      const classList = el.classList || split.call(el.className, ` `)
      if (Array.prototype.some.call(classList, classIsDomestic)) {
        return true
      }
      if (Array.prototype.some.call(classList, classIsForeign)) {
        return false
      }
    }
    return true
  }
}

function makeEventsSelector(rootEl$, namespace) {
  return function events(eventName, useCapture = false) {
    if (typeof eventName !== `string`) {
      throw new Error(`DOM driver's events() expects argument to be a ` +
        `string representing the event type to listen for.`)
    }
    const isStrictlyInRootScope = makeIsStrictlyInRootScope(namespace)

    return rootEl$
      .first()
      .flatMapLatest(rootEl => {
        if (rootEl.length === 0) {
          return Rx.Observable.empty()
        }
        if (!namespace || namespace.length === 0) {
          return fromEvent(rootEl, eventName, useCapture)
        }
        const descendantSelector = namespace.join(` `)
        if (matchesSelector(rootEl, descendantSelector)) { // is root Element
          return fromEvent(rootEl, eventName, useCapture)
        }
        const topSelector = namespace.join(``)
        return fromEvent(rootEl, eventName, useCapture).filter(ev => {
          if (matchesSelector(ev.target, descendantSelector) ||
              matchesSelector(ev.target, topSelector))
          {
            return isStrictlyInRootScope(ev.target)
          }
          return false
        })
      })
      .share()
  }
}

function makeElementSelector(rootEl$) {
  return function select(selector) {
    if (typeof selector !== `string`) {
      throw new Error(`DOM driver's select() expects the argument to be a ` +
        `string as a CSS selector`)
    }

    const namespace = this.namespace
    const trimmedSelector = selector.trim()
    const childNamespace = trimmedSelector === `:root` ?
      namespace :
      namespace.concat(trimmedSelector)
    const element$ = rootEl$.map(rootEl => {
      if (childNamespace.join(``) === ``) {
        return rootEl
      }
      let nodeList = rootEl.querySelectorAll(childNamespace.join(` `))
      if (nodeList.length === 0) {
        nodeList = rootEl.querySelectorAll(childNamespace.join(``))
      }
      const array = Array.prototype.slice.call(nodeList)
      return array.filter(makeIsStrictlyInRootScope(childNamespace))
    })
    return {
      observable: element$,
      namespace: childNamespace,
      select: makeElementSelector(rootEl$),
      events: makeEventsSelector(rootEl$, childNamespace),
      isolateSource,
      isolateSink,
    }
  }
}

function validateDOMSink(vtree$) {
  if (!vtree$ || typeof vtree$.subscribe !== `function`) {
    throw new Error(`The DOM driver function expects as input an ` +
      `Observable of virtual DOM elements`)
  }
}

function defaultOnErrorFn(msg) {
  if (console && console.error) {
    console.error(msg)
  } else {
    console.log(msg)
  }
}

function makeDOMDriver(container, options) {
  // Find and prepare the container
  let domContainer = typeof container === `string` ?
    document.querySelector(container) :
    container
  // Check pre-conditions
  if (typeof container === `string` && domContainer === null) {
    throw new Error(`Cannot render into unknown element \`${container}\``)
  } else if (!isElement(domContainer)) {
    throw new Error(`Given container is not a DOM element neither a selector ` +
      `string.`)
  }
  const {onError = defaultOnErrorFn} = options || {}
  if (typeof onError !== `function`) {
    throw new Error(`You provided an \`onError\` to makeDOMDriver but it was ` +
      `not a function. It should be a callback function to handle errors.`)
  }

  return function domDriver(vtree$) {
    validateDOMSink(vtree$)
    let rootElem$ = renderRawRootElem$(vtree$, domContainer)
      .startWith(domContainer)
      .doOnError(onError)
      .replay(null, 1)
    let disposable = rootElem$.connect()
    return {
      observable: rootElem$,
      namespace: [],
      select: makeElementSelector(rootElem$),
      events: makeEventsSelector(rootElem$, []),
      dispose: () => disposable.dispose(),
      isolateSource,
      isolateSink,
    }
  }
}

module.exports = {
  isElement,
  wrapTopLevelVTree,
  makeDiffAndPatchToElement$,
  renderRawRootElem$,
  validateDOMSink,

  makeDOMDriver,
}
<|endoftext|>


<commit_before>self.port.on('buildLinkMarkdown', () => {
  const selected = window.getSelection().toString();
  const title = window.document.title;
  const url = window.location.href;
  const result = [];
  if (selected) {
    result.push(selected);
  } else {
    result.push(title);
  }
  result.push(url);
  self.port.emit('copyToSystem', result.join(' '));
});
<commit_msg>feat(create): build markdown link<commit_after>self.port.on('buildLinkMarkdown', () => {
  const selected = window.getSelection().toString();
  const title = window.document.title;
  const url = window.location.href;
  const result = [];
  if (selected) {
    result.push(`[${selected}]`);
  } else {
    result.push(`[${title}]`);
  }
  result.push(`(${url})`);
  self.port.emit('copyToSystem', result.join(''));
});
<|endoftext|>


<commit_before>TC.control = TC.control || {};

if (!TC.Control) {
    TC.syncLoadJS(TC.apiLocation + 'TC/Control.js');
}
if (!TC.Feature || !TC.feature.Polyline) {
    TC.syncLoadJS(TC.apiLocation + 'TC/feature/Polyline.js');
}
if (!TC.Feature || !TC.feature.Polygon) {
    TC.syncLoadJS(TC.apiLocation + 'TC/feature/Polygon.js');
}

TC.Consts.event.DRAWEND = 'drawend.tc';
TC.Consts.event.DRAWCANCEL = 'drawcancel.tc';

TC.control.Draw = function () {
    var self = this;

    TC.Control.apply(self, arguments);
    this.renderPromise().then(function () {
        self.history = [];
        self.historyIndex = 0;
        self.reset = true;
        self.callBack = null;
        self.measure = false;
        self._cancelClick = false;

        self.mode = self.options.mode || TC.Consts.geom.POLYLINE;

        if (self.options.measure)
            self.measure = self.options.measure
        if ($.isFunction(self.options.callback))
            self.callBack = self.options.callback;

        self.wrap = new TC.wrap.control.Draw(self);

        self._$newBtn = self._$div.find('.tc-ctl-draw-btn-new').on(TC.Consts.event.CLICK, function () {
            self.new();
        });

        self._$cancelBtn = self._$div.find('.tc-ctl-draw-btn-cancel').on(TC.Consts.event.CLICK, function () {
            self.cancel();
        });

        self._$endBtn = self._$div.find('.tc-ctl-draw-btn-end').on(TC.Consts.event.CLICK, function () {
            if (!$(this).hasClass(TC.Consts.classes.DISABLED)) {
                self.end();
            }
        });

        self._$undoBtn = self._$div.find('.tc-ctl-draw-btn-undo').on(TC.Consts.event.CLICK, function () {
            if (!$(this).hasClass(TC.Consts.classes.DISABLED)) {
                self.undo();
            }
        });

        self._$redoBtn = self._$div.find('.tc-ctl-draw-btn-redo').on(TC.Consts.event.CLICK, function () {
            if (!$(this).hasClass(TC.Consts.classes.DISABLED)) {
                self.redo();
            }
        });

        self.$events.on(TC.Consts.event.MEASURE + ' ' + TC.Consts.event.MEASUREPARTIAL, function (e) {

        }).on(TC.Consts.event.MEASURE, function (e) {
            self.historyIndex = 0;
            self.history.length = self.historyIndex;
            self._$undoBtn.addClass(TC.Consts.classes.DISABLED);
            self._$redoBtn.addClass(TC.Consts.classes.DISABLED);
        });
        self.$events.on(TC.Consts.event.POINT, function (e) {
            if (self.layer.features && self.layer.features.length > 0) {
                self.layer.clearFeatures();
                self.resetValues();
            }
            self.history.length = self.historyIndex;
            self.history[self.historyIndex++] = e.point;
            self._$undoBtn.toggleClass(TC.Consts.classes.DISABLED, self.historyIndex <= 0);
            self._$redoBtn.addClass(TC.Consts.classes.DISABLED);
            self._$endBtn.removeClass(TC.Consts.classes.DISABLED);
        });
        self.$events.on(TC.Consts.event.DRAWEND, function (e) {
            self.historyIndex = 0;
            self.history.length = self.historyIndex;
            self._$undoBtn.addClass(TC.Consts.classes.DISABLED);
            self._$redoBtn.addClass(TC.Consts.classes.DISABLED);
            if (self.callBack)
                self.callBack(e.geometry);
        });

    });
};

TC.inherit(TC.control.Draw, TC.Control);

(function () {
    var ctlProto = TC.control.Draw.prototype;

    ctlProto.CLASS = 'tc-ctl-draw';

    if (TC.isDebug) {
        ctlProto.template = TC.apiLocation + "TC/templates/Draw.html";
    }
    else {
        ctlProto.template = function () { dust.register(ctlProto.CLASS, body_0); function body_0(chk, ctx) { return chk.w(" ").h("i18n", ctx, {}, { "$key": "new" }).w("").h("i18n", ctx, {}, { "$key": "undo" }).w("").h("i18n", ctx, {}, { "$key": "redo" }).w("").h("i18n", ctx, {}, { "$key": "end" }).w("").h("i18n", ctx, {}, { "$key": "cancel" }).w(" "); } body_0.__dustBody = !0; return body_0 };
    }

    ctlProto.render = function (callback) {
        var self = this;
        var strToolTip;
        switch (self.options.mode) {
            case TC.Consts.geom.POLYLINE:
                strToolTip = self.getLocaleString('drawLine');
                break;
            case TC.Consts.geom.POLYGON:
                strToolTip = self.getLocaleString('drawPolygon');
                break;
            default:
                strToolTip = self.getLocaleString('draw');
                break;
        }
        self.renderData({ tooltip: strToolTip }, function () {
            if ($.isFunction(callback)) {
                callback();
            }
        });
    };

    ctlProto.register = function (map) {
        var self = this;
        TC.Control.prototype.register.call(self, map);
        map.loaded(function () {
            if (self.options.layer) {
                if (typeof (self.options.layer) === "string") {

                }
                else
                    self.layer = self.options.layer;
            }
            else {
                var map = self.map;
                map.loaded(function () {
                    self.layerPromise = map.addLayer({
                        id: TC.getUID(),
                        title: 'DrawControl',
                        stealth: true,
                        type: TC.Consts.layerType.VECTOR,
                        styles: {
                            point: $.extend({}, map.options.styles.point, { fillOpacity: 0 }),
                            line: map.options.styles.line,
                            polygon: map.options.styles.polygon
                        }
                    });

                    $.when(self.layerPromise).then(function (layer) {
                        self.layer = layer;
                        self.layer.map.putLayerOnTop(self.layer);
                    });
                });
            }
        });
    };

    ctlProto.new = function () {
        var self = this;
        self.layer.clearFeatures();
        self.setMode(self.mode, true);
    };

    ctlProto.undo = function () {
        var self = this;
        var result = this.wrap.undo();
        if (result) {
            self.historyIndex--;
            self._$redoBtn.removeClass(TC.Consts.classes.DISABLED);

            if (self.historyIndex <= 0) {
                self.resetValues();

            }
        }

        return result;
    };

    ctlProto.redo = function () {
        var self = this;
        var result = this.wrap.redo();
        if (result) {
            self.historyIndex++;
            self._$undoBtn.removeClass(TC.Consts.classes.DISABLED);
        }
        self._$redoBtn.toggleClass(TC.Consts.classes.DISABLED, self.historyIndex >= self.history.length);
        return result;
    };

    ctlProto.cancel = function () {
        var self = this;
        self._cancelClick = true;
        this.setMode(null, false);
        self.resetValues();
        self.$events.trigger($.Event(TC.Consts.event.DRAWCANCEL, { ctrl: self }));
    };

    ctlProto.activate = function () {
        var self = this;
        self._$newBtn.addClass(TC.Consts.classes.ACTIVE);
        TC.Control.prototype.activate.call(self);
        self.wrap.activate(self.mode);
    };

    ctlProto.deactivate = function () {
        var self = this;
        if (self._$newBtn) {
            self._$newBtn.removeClass(TC.Consts.classes.ACTIVE);
        }
        TC.Control.prototype.deactivate.call(self, !self._cancelClick);
        if (self.wrap) {
            self.wrap.deactivate();
        }
        self.resetValues();
        self.$events.trigger($.Event(TC.Consts.event.DRAWCANCEL, { ctrl: self }));
        self._cancelClick = false;
    };

    ctlProto.isExclusive = function () {
        return true;
    };

    ctlProto.end = function () {
        var self = this;
        self.wrap.end();
        self.resetValues();
    };

    ctlProto.setMode = function (mode, activate) {
        var self = this;

        if (mode)
            self.mode = mode;

        if (activate && mode) {
            self.layer.map.putLayerOnTop(self.layer);
            self.activate();
        }
        else {
            self.deactivate();
        }

        var event = activate ? TC.Consts.event.CONTROLACTIVATE : TC.Consts.event.CONTROLDEACTIVATE;
        if (self.map) {
            self.map.$events.trigger($.Event(event, { control: self }));
        }
    };

    ctlProto.getLayer = function () {
        var self = this;
        return self.layer ? self.layer : self.layerPromise;
    };

    ctlProto.resetValues = function () {
        var self = this;
        self._$undoBtn.addClass(TC.Consts.classes.DISABLED);
        self._$redoBtn.addClass(TC.Consts.classes.DISABLED);
    };

})();<commit_msg>Redo interface, upgrade compatibility<commit_after>TC.control = TC.control || {};

if (!TC.Control) {
    TC.syncLoadJS(TC.apiLocation + 'TC/Control.js');
}
if (!TC.Feature || !TC.feature.Point) {
    TC.syncLoadJS(TC.apiLocation + 'TC/feature/Point.js');
}
if (!TC.Feature || !TC.feature.Polyline) {
    TC.syncLoadJS(TC.apiLocation + 'TC/feature/Polyline.js');
}
if (!TC.Feature || !TC.feature.Polygon) {
    TC.syncLoadJS(TC.apiLocation + 'TC/feature/Polygon.js');
}

TC.Consts.event.DRAWSTART = 'drawstart.tc';
TC.Consts.event.DRAWEND = 'drawend.tc';
TC.Consts.event.DRAWCANCEL = 'drawcancel.tc';
TC.Consts.event.MEASURE = 'measure.tc';
TC.Consts.event.MEASUREPARTIAL = 'measurepartial.tc';

(function () {

    TC.control.Draw = function () {
        var self = this;

        TC.Control.apply(self, arguments);

        self._classSelector = '.' + self.CLASS;

        self._pointClass = self.CLASS + '-point';
        self._lineClass = self.CLASS + '-line';
        self._polygonClass = self.CLASS + '-polygon';

        self.history = [];
        self.historyIndex = 0;
        this.renderPromise().then(function () {
            self.reset = true;
            self.callBack = null;
            self.measure = false;
            self._cancelClick = false;

            self.mode = self.options.mode || TC.Consts.geom.POLYLINE;

            if (self.options.measure)
                self.measure = self.options.measure
            if ($.isFunction(self.options.callback))
                self.callBack = self.options.callback;

            self.wrap = new TC.wrap.control.Draw(self);

            self._$newBtn = self._$div.find(self._classSelector + '-btn-new').on(TC.Consts.event.CLICK, function () {
                self.new();
            });

            self._$cancelBtn = self._$div.find(self._classSelector + '-btn-cancel').on(TC.Consts.event.CLICK, function () {
                self.cancel();
            });

            self._$endBtn = self._$div.find(self._classSelector + '-btn-end').on(TC.Consts.event.CLICK, function () {
                self.end();
            });

            self._$undoBtn = self._$div.find(self._classSelector + '-btn-undo').on(TC.Consts.event.CLICK, function () {
                self.undo();
            });

            self._$redoBtn = self._$div.find(self._classSelector + '-btn-redo').on(TC.Consts.event.CLICK, function () {
                self.redo();
            });

            self.$events.on(TC.Consts.event.MEASURE, function (e) {
                self.resetValues();
            });
            self.$events.on(TC.Consts.event.POINT, function (e) {
                if (self.layer && self.layer.features && self.layer.features.length > 0) {
                    self.layer.clearFeatures();
                    self.resetValues();
                }

                self.history.length = self.historyIndex;
                self.history[self.historyIndex++] = e.point;

                setDrawState(self);
            });
            self.$events.on(TC.Consts.event.DRAWEND, function (e) {
                setFeatureAddReadyState(self);
                if (self.callBack) {
                    self.callBack(e.geometry);
                }
            });

        });
    };

    TC.inherit(TC.control.Draw, TC.Control);

    var ctlProto = TC.control.Draw.prototype;

    ctlProto.CLASS = 'tc-ctl-draw';

    var setDrawState = function (ctl) {
        ctl._$endBtn.prop('disabled',
            ctl.historyIndex === 0 ||
            (ctl.mode === TC.Consts.geom.POLYGON && ctl.historyIndex < 3) ||
            (ctl.mode === TC.Consts.geom.POLYLINE && ctl.historyIndex < 2));
        ctl._$redoBtn.prop('disabled', ctl.history.length === ctl.historyIndex);
        ctl._$undoBtn.prop('disabled', ctl.historyIndex === 0);
    };

    var setFeatureAddReadyState = function (ctl) {
        ctl.resetValues();
        ctl._$endBtn.prop('disabled', true);
        ctl._$cancelBtn.prop('disabled', false);
    };

    if (TC.isDebug) {
        ctlProto.template = TC.apiLocation + "TC/templates/Draw.html";
    }
    else {
        ctlProto.template = function () { dust.register(ctlProto.CLASS, body_0); function body_0(chk, ctx) { return chk.w(" <button class=\"tc-ctl-btn tc-ctl-draw-btn-new\" title=\"").f(ctx.get(["tooltip"], false), ctx, "h").w("\">").h("i18n", ctx, {}, { "$key": "new" }).w("</button><button class=\"tc-ctl-btn tc-ctl-draw-btn-undo\" disabled title=\"").h("i18n", ctx, {}, { "$key": "undo" }).w("\">").h("i18n", ctx, {}, { "$key": "undo" }).w("</button><button class=\"tc-ctl-btn tc-ctl-draw-btn-redo\" disabled title=\"").h("i18n", ctx, {}, { "$key": "redo" }).w("\">").h("i18n", ctx, {}, { "$key": "redo" }).w("</button><button class=\"tc-ctl-btn tc-ctl-draw-btn-end\" title=\"").h("i18n", ctx, {}, { "$key": "end" }).w("\">").h("i18n", ctx, {}, { "$key": "end" }).w("</button><button class=\"tc-ctl-btn tc-ctl-draw-btn-cancel\" title=\"").h("i18n", ctx, {}, { "$key": "cancel" }).w("\">").h("i18n", ctx, {}, { "$key": "cancel" }).w("</button> "); } body_0.__dustBody = !0; return body_0 };
    }

    ctlProto.render = function (callback) {
        var self = this;
        var strToolTip;
        switch (self.options.mode) {
            case TC.Consts.geom.POLYLINE:
            case TC.Consts.geom.MULTIPOLYLINE:
                strToolTip = self.getLocaleString('drawLine');
                self._$div.addClass(self._lineClass);
                break;
            case TC.Consts.geom.POLYGON:
            case TC.Consts.geom.MULTIPOLYGON:
                strToolTip = self.getLocaleString('drawPolygon');
                self._$div.addClass(self._polygonClass);
                break;
            case TC.Consts.geom.POINT:
            case TC.Consts.geom.MULTIPOINT:
                strToolTip = self.getLocaleString('draw');
                self._$div.addClass(self._pointClass);
                break;
            default:
                strToolTip = self.getLocaleString('draw');
                break;
        }
        self.renderData({ tooltip: strToolTip }, function () {
            if ($.isFunction(callback)) {
                callback();
            }
        });
    };

    ctlProto.register = function (map) {
        var self = this;
        TC.Control.prototype.register.call(self, map);
        map.loaded(function () {
            if (self.options.layer) {
                self.setLayer(self.options.layer);
            }
            else {
                // Si self.options.layer === false se instancia el control sin capa asociada
                if (typeof self.options.layer !== 'boolean') {
                    map.loaded(function () {
                        self.layerPromise = map.addLayer({
                            id: TC.getUID(),
                            title: 'DrawControl',
                            stealth: true,
                            type: TC.Consts.layerType.VECTOR,
                            styles: {
                                point: $.extend({}, map.options.styles.point, { fillOpacity: 0 }),
                                line: map.options.styles.line,
                                polygon: map.options.styles.polygon
                            }
                        });

                        $.when(self.layerPromise).then(function (layer) {
                            self.layer = layer;
                            map.putLayerOnTop(self.layer);
                        });
                    });
                }
            }
        });
    };

    ctlProto.new = function () {
        var self = this;
        if (self.layer) {
            self.layer.clearFeatures();
        }
        self.setMode(self.mode, true);
    };

    ctlProto.undo = function () {
        var self = this;
        var result = self.wrap.undo();
        if (result) {
            self.historyIndex--;
            setDrawState(self);

            if (self.historyIndex <= 0) {
                self.resetValues();
            }
        }

        return result;
    };

    ctlProto.redo = function () {
        var self = this;
        var result = this.wrap.redo();
        if (result) {
            self.historyIndex++;
            setDrawState(self);
        }
        return result;
    };

    ctlProto.cancel = function () {
        var self = this;
        self._cancelClick = true;
        this.setMode(null, false);
        self.resetValues();
        setFeatureAddReadyState(self);
        self.$events.trigger($.Event(TC.Consts.event.DRAWCANCEL, { ctrl: self }));
    };

    ctlProto.activate = function () {
        var self = this;
        self._$newBtn.addClass(TC.Consts.classes.ACTIVE);
        TC.Control.prototype.activate.call(self);
        self.wrap.activate(self.mode);
        self._$div
            .removeClass(self._pointClass)
            .removeClass(self._lineClass)
            .removeClass(self._polygonClass);
        switch (self.mode) {
            case TC.Consts.geom.POINT:
                self._$div.addClass(self._pointClass);
                break;
            case TC.Consts.geom.POLYLINE:
                self._$div.addClass(self._lineClass);
                break;
            case TC.Consts.geom.POLYGON:
                self._$div.addClass(self._polygonClass);
                break;
            default:
                break;
        }

    };

    ctlProto.deactivate = function () {
        var self = this;
        if (self._$newBtn) {
            self._$newBtn.removeClass(TC.Consts.classes.ACTIVE);
        }
        TC.Control.prototype.deactivate.call(self, !self._cancelClick);
        if (self.wrap) {
            self.wrap.deactivate();
        }
        self.resetValues();
        //self.$events.trigger($.Event(TC.Consts.event.DRAWCANCEL, { ctrl: self }));
        self._cancelClick = false;
    };

    ctlProto.isExclusive = function () {
        return true;
    };

    ctlProto.end = function () {
        var self = this;
        self.wrap.end();
        self.resetValues();
    };

    ctlProto.setMode = function (mode, activate) {
        var self = this;

        if (mode)
            self.mode = mode;

        if (activate && mode) {
            if (self.layer) {
                self.layer.map.putLayerOnTop(self.layer);
            }
            self.activate();
        }
        else {
            self.deactivate();
        }

        var event = activate ? TC.Consts.event.CONTROLACTIVATE : TC.Consts.event.CONTROLDEACTIVATE;
        if (self.map) {
            self.map.$events.trigger($.Event(event, { control: self }));
        }
    };

    ctlProto.getLayer = function () {
        var self = this;
        // Se ha instanciado un control sin capa asociada
        if (self.options && typeof self.options.layer === 'boolean' && !self.options.layer) {
            return null;
        }
        return self.layer ? self.layer : self.layerPromise;
    };

    ctlProto.setLayer = function (layer) {
        var self = this;
        if (self.map) {
            if (typeof (layer) === "string") {
                self.layer = self.map.getLayer(layer);
            }
            else {
                self.layer = layer;
            }
        }
    };

    ctlProto.resetValues = function () {
        var self = this;
        self.history.length = 0;
        self.historyIndex = 0;
        setDrawState(self);
    };

})();<|endoftext|>


<commit_before>function focus_code_field() {
    for (let input of document.querySelectorAll('[id^=duo-verify-code-]')) {
        if (input.offsetParent) {
            input.focus();
            break;
        }
    }
}

function on_code_keypressed(event) {
    if (event.keyCode === 13) {
        document.querySelector('#verify_factor').click();
    }
}

self.port.on('init', function(prefs) {
    if (!document.querySelector('#extra-verification-challenge')) {
        return;
    }

    // fix overly long devices
    for (let option of document.querySelectorAll('#factor_selector option')) {
        option.textContent = option.textContent.replace(/ \S+DuoPushPhone\S+ /, ' Phone ');
    }

    // focus the currently visible code field
    document.querySelector('#factor_selector').addEventListener('change', focus_code_field);
    focus_code_field();

    // pressing enter in the code field should submit
    for (let input of document.querySelectorAll('[id^=duo-verify-code-]')) {
        input.addEventListener('keypress', on_code_keypressed);
    }

    // check 'remember device' if required
    if (prefs.rememberDevice) {
        for (let input of document.querySelectorAll('[id^=duo-remember-checkbox]')) {
            input.checked = true;
        }
    }
});
<commit_msg>Focus code field if no #factor_selector, select contents.<commit_after>function focus_code_field() {
    for (let input of document.querySelectorAll('[id^=duo-verify-code-]')) {
        if (input.offsetParent) {
            input.focus();
            break;
        }
    }
}

function on_code_keypressed(event) {
    if (event.keyCode === 13) {
        document.querySelector('#verify_factor').click();
    }
}

self.port.on('init', function(prefs) {
    if (!document.querySelector('#extra-verification-challenge')) {
        return;
    }

    if (document.querySelector('#factor_selector')) {
        // fix overly long devices
        for (let option of document.querySelectorAll('#factor_selector option')) {
            option.textContent = option.textContent.replace(/ \S+DuoPushPhone\S+ /, ' Phone ');
        }

        // focus the currently visible code field after factor selected
        document.querySelector('#factor_selector').addEventListener('change', focus_code_field);
    }

    // focus the currently visible code field
    focus_code_field();

    // pressing enter in the code field should submit
    for (let input of document.querySelectorAll('[id^=duo-verify-code-]')) {
        input.addEventListener('keypress', on_code_keypressed);
    }

    // check 'remember device' if required
    if (prefs.rememberDevice) {
        for (let input of document.querySelectorAll('[id^=duo-remember-checkbox]')) {
            input.checked = true;
        }
    }
});

<|endoftext|>


<commit_before>'use strict';
angular.module('mean.icu.ui.modalcompartmentalization', [])
    .directive('icuCompModal', function($state, $uibModal, circlesService) {

        function link(scope, elem, attrs) {
            circlesService.getmine().then(function(data) {
                scope.mine = data;
                c19n();
            });

            function c19n() {
                if (scope.entity && scope.entity.circles && scope.entity.circles.c19n && scope.entity.circles.c19n.length) {
                    elem[0].classList.add('c19n');
                    scope.c19n = [];

                    var source = scope.mine.sources.find(function(s) {
                        return s._id === scope.entity.sources[0];
                    });

                    var c19n = scope.mine.allowed.c19n.find(function(c) {
                        return c._id === scope.entity.circles.c19n[0];
                    });

                    scope.c19n.push(source.name + '(' + c19n.name + ')');

                    if (scope.entity.circles.c19nGroups1[0])
                        scope.c19n.push(scope.mine.allowed.c19nGroups1.find(function(c) {
                            return c._id === scope.entity.circles.c19nGroups1[0];
                        }).name);

                    if (scope.entity.circles.c19nGroups2[0])
                        scope.c19n.push(scope.mine.allowed.c19nGroups2.find(function(c) {
                            return c._id === scope.entity.circles.c19nGroups2[0];
                        }).name);

                    scope.c19n = scope.c19n.join(', ');
                } else {
                    elem[0].classList.remove('c19n');

                }
            }

            elem.bind('click', function() {
                buildModal();
            });

            function buildModal() {
                var modalInstance = $uibModal.open({
                    animation: true,
                    templateUrl: '/icu/components/modal-compartmentalization/modal.html',
                    controller: CompModalCtrl,
                    resolve: {
                        entity: function() {
                            return scope.entity;
                        },
                        entityName: function() {
                            return scope.entityName;
                        },
                        data: function() {
                            return scope.mine
                        }
                    }

                });

                modalInstance.result.then(function() {

                }, function() {
                    c19n();
                    console.log('Modal dismissed');
                });
            }
        };

        return {
            restrict: 'A',
            scope: {
                entityName: '@',
                entity: '='
            },
            template: '

',
            link: link
        };
    });

function CompModalCtrl($scope, $uibModalInstance, entity, entityName, $injector, data) {

    var serviceMap = {
        project: 'ProjectsService',
        discussion: 'DiscussionsService',
        task: 'TasksService'
    };

    var serviceName = serviceMap[entityName];
    var service = $injector.get(serviceName);

    $scope.c19n = {
        lists: {},
        isShown: {},
        selected: {}
    };

    $scope.c19n.lists.sources = data.sources;
    $scope.c19n.lists.sourcesObj = {};
    for (var i = 0; i < data.sources.length; i++) {
        $scope.c19n.lists.sourcesObj[data.sources[i]._id] = data.sources[i];
    }
    $scope.c19n.lists.c19nGroups1 = data.allowed.c19nGroups1;
    $scope.c19n.lists.c19nGroups1Obj = {};
    for (var i = 0; i < data.allowed.c19nGroups1.length; i++) {
        $scope.c19n.lists.c19nGroups1Obj[data.allowed.c19nGroups1[i]._id] = data.allowed.c19nGroups1[i];
    }
    $scope.c19n.lists.c19nGroups2 = data.allowed.c19nGroups2;
    $scope.c19n.lists.c19nGroups2Obj = {};
    for (var i = 0; i < data.allowed.c19nGroups2.length; i++) {
        $scope.c19n.lists.c19nGroups2Obj[data.allowed.c19nGroups2[i]._id] = data.allowed.c19nGroups2[i];
    }

    $scope.entity = entity;
    $scope.entity.sources = $scope.entity.sources || [];
    $scope.entity.circles = $scope.entity.circles || {};

    $scope.c19n.isShown.sources = !$scope.entity.sources[0];

    var setDeepC19nValue = function(obj, path, item) {
        var path = path.split('.');
        var i = 0;
        for (var len = path.length; i < len - 1; i++) {
            obj = obj[path[i]];
        };
        obj[path[i]] = obj[path[i]] || [];
        if (item) {
            obj[path[i]][0] = item;
        } else {
            obj[path[i]].shift();
        }
    };

    $scope.addC19n = function(path, item, type) {
        $scope.errorMessage = ''
        setDeepC19nValue($scope.entity, path, item);

        service.update($scope.entity).then(function(data) {
            $scope.c19n.isShown.sources = false;
            $scope.c19n.isShown[type] = false;
        }, function(error) {
            setDeepC19nValue($scope.entity, path);

            $scope.errorMessage = error.data && error.data.message ? error.data.message : 'permissions denied';
            $scope.c19n.isShown[type] = true;
        })

    };

    $scope.removeC19n = function(type) {
        if (type === 'sources') {
            $scope.entity.sources = $scope.entity.circles.c19nGroups1 = $scope.entity.circles.c19nGroups2 = [];
            $scope.c19n.isShown = {
                sources: true,
                c19nGroups1: false,
                c19nGroups2: false,
            }
        } else {
            $scope.entity.circles[type] = [];
            $scope.c19n.isShown[type] = true;
        }

        service.update($scope.entity)
    };

    $scope.showSelect = function() {
        if (!$scope.entity.sources[0]) {
            $scope.c19n.isShown.sources = true;
        } else {
            if (!$scope.entity.circles.c19nGroups1 || !$scope.entity.circles.c19nGroups1[0]) {
                $scope.c19n.isShown.c19nGroups1 = true;
            }
            if (!$scope.entity.circles.c19nGroups2 || !$scope.entity.circles.c19nGroups2[0]) {
                $scope.c19n.isShown.c19nGroups2 = true;
            }
        }
    }

    $scope.close = function() {
        $uibModalInstance.close();
    };

    $scope.cancel = function() {
        $uibModalInstance.dismiss('cancel');
    };
}<commit_msg>Handle tooltip for user without circles<commit_after>'use strict';
angular.module('mean.icu.ui.modalcompartmentalization', [])
    .directive('icuCompModal', function($state, $uibModal, circlesService) {

        function link(scope, elem, attrs) {
            circlesService.getmine().then(function(data) {
                scope.mine = data;
                c19n();
            });

            function c19n() {
                if (scope.entity && scope.entity.circles && scope.entity.circles.c19n && scope.entity.circles.c19n.length) {
                    elem[0].classList.add('c19n');
                    scope.c19n = [];

                    var source = scope.mine.sources.find(function(s) {
                        return s._id === scope.entity.sources[0];
                    });

                    var c19n = scope.mine.allowed.c19n.find(function(c) {
                        return c._id === scope.entity.circles.c19n[0];
                    });

                    scope.c19n.push(source.name + '(' + c19n.circleId + ')');

                    if (scope.entity.circles.c19nGroups1.length)
                        scope.c19n.push(scope.mine.allowed.c19nGroups1.find(function(c) {
                            return c._id === scope.entity.circles.c19nGroups1[0];
                        }).name);

                    if (scope.entity.circles.c19nGroups2.length)
                        scope.c19n.push(scope.mine.allowed.c19nGroups2.find(function(c) {
                            return c._id === scope.entity.circles.c19nGroups2[0];
                        }).name);

                    scope.c19n = scope.c19n.join(', ');
                } else {
                    elem[0].classList.remove('c19n');

                }
            }

            elem.bind('click', function() {
                buildModal();
            });

            function buildModal() {
                var modalInstance = $uibModal.open({
                    animation: true,
                    templateUrl: '/icu/components/modal-compartmentalization/modal.html',
                    controller: CompModalCtrl,
                    resolve: {
                        entity: function() {
                            return scope.entity;
                        },
                        entityName: function() {
                            return scope.entityName;
                        },
                        data: function() {
                            return scope.mine
                        }
                    }

                });

                modalInstance.result.then(function() {

                }, function() {
                    c19n();
                    console.log('Modal dismissed');
                });
            }
        };

        return {
            restrict: 'A',
            scope: {
                entityName: '@',
                entity: '='
            },
            template: '

',
            link: link
        };
    });

function CompModalCtrl($scope, $uibModalInstance, entity, entityName, $injector, data) {

    var serviceMap = {
        project: 'ProjectsService',
        discussion: 'DiscussionsService',
        task: 'TasksService'
    };

    var serviceName = serviceMap[entityName];
    var service = $injector.get(serviceName);

    $scope.c19n = {
        lists: {},
        isShown: {},
        selected: {}
    };

    $scope.c19n.lists.sources = data.sources;
    $scope.c19n.lists.sourcesObj = {};
    for (var i = 0; i < data.sources.length; i++) {
        $scope.c19n.lists.sourcesObj[data.sources[i]._id] = data.sources[i];
    }
    $scope.c19n.lists.c19nGroups1 = data.allowed.c19nGroups1;
    $scope.c19n.lists.c19nGroups1Obj = {};
    for (var i = 0; i < data.allowed.c19nGroups1.length; i++) {
        $scope.c19n.lists.c19nGroups1Obj[data.allowed.c19nGroups1[i]._id] = data.allowed.c19nGroups1[i];
    }
    $scope.c19n.lists.c19nGroups2 = data.allowed.c19nGroups2;
    $scope.c19n.lists.c19nGroups2Obj = {};
    for (var i = 0; i < data.allowed.c19nGroups2.length; i++) {
        $scope.c19n.lists.c19nGroups2Obj[data.allowed.c19nGroups2[i]._id] = data.allowed.c19nGroups2[i];
    }

    $scope.entity = entity;
    $scope.entity.sources = $scope.entity.sources || [];
    $scope.entity.circles = $scope.entity.circles || {};

    $scope.c19n.isShown.sources = !$scope.entity.sources[0];

    var setDeepC19nValue = function(obj, path, item) {
        var path = path.split('.');
        var i = 0;
        for (var len = path.length; i < len - 1; i++) {
            obj = obj[path[i]];
        };
        obj[path[i]] = obj[path[i]] || [];
        if (item) {
            obj[path[i]][0] = item;
        } else {
            obj[path[i]].shift();
        }
    };

    $scope.addC19n = function(path, item, type) {
        $scope.errorMessage = ''
        setDeepC19nValue($scope.entity, path, item);

        service.update($scope.entity).then(function(data) {
            $scope.c19n.isShown.sources = false;
            $scope.c19n.isShown[type] = false;
        }, function(error) {
            setDeepC19nValue($scope.entity, path);

            $scope.errorMessage = error.data && error.data.message ? error.data.message : 'permissions denied';
            $scope.c19n.isShown[type] = true;
        })

    };

    $scope.removeC19n = function(type) {
        if (type === 'sources') {
            $scope.entity.sources = $scope.entity.circles.c19nGroups1 = $scope.entity.circles.c19nGroups2 = [];
            $scope.c19n.isShown = {
                sources: true,
                c19nGroups1: false,
                c19nGroups2: false,
            }
        } else {
            $scope.entity.circles[type] = [];
            $scope.c19n.isShown[type] = true;
        }

        service.update($scope.entity)
    };

    $scope.showSelect = function() {
        if (!$scope.entity.sources[0]) {
            $scope.c19n.isShown.sources = true;
        } else {
            if (!$scope.entity.circles.c19nGroups1 || !$scope.entity.circles.c19nGroups1[0]) {
                $scope.c19n.isShown.c19nGroups1 = true;
            }
            if (!$scope.entity.circles.c19nGroups2 || !$scope.entity.circles.c19nGroups2[0]) {
                $scope.c19n.isShown.c19nGroups2 = true;
            }
        }
    }

    $scope.close = function() {
        $uibModalInstance.close();
    };

    $scope.cancel = function() {
        $uibModalInstance.dismiss('cancel');
    };
}<|endoftext|>


<commit_before>import Ember from 'ember';

export default Ember.Mixin.create({

  find: function () {
    return this.preAppFind({
      arguments: arguments,
      super: this._super
    });
  },

  findAll: function () {
    return this.preAppFind({
      arguments: arguments,
      super: this._super
    });
  },

  preAppFind: function (opts) {

    // Grab our global objects as well as our type.
    var typeKey = opts.arguments[1].typeKey;
    var request;

    // Delete the key so no subsequent calls to `find` use it.
    if (window.__ds_adapter_preapp_request)  {
      request = window.__ds_adapter_preapp_request[typeKey];
      delete window.__ds_adapter_preapp_request[typeKey];
    }

    // If no request exists, use super and call it a day.
    if ( !request ) {
      return opts.super.apply(this, opts.arguments);
    } else {

      return new Ember.RSVP.Promise(function (resolve, reject) {

        // If responseText has already been set by the pre-app request,
        // resolve with it.
        if ( request.responseText ) {
          resolve(JSON.parse(request.responseText));

        // If response has not been set by the pre-app request,
        // this likely means that the request is not yet finished.
        // Let's hook into the onload and resolve/reject accordingly.
        } else {

          var onFn = function () {
            var response = JSON.parse(request.responseText);
            if (request.status >= 200 && request.status < 400) {
              resolve(response);
            } else {
              reject(response);
            }
          };

          request.onload = onFn;
          request.onerror = onFn;

        }

      });

    }

  }

});
<commit_msg>Usage of `typeKey` has been deprecated and will be removed in Ember Data 2.0. It has been replaced by `modelName` on the model class.<commit_after>import Ember from 'ember';

export default Ember.Mixin.create({

  find: function () {
    return this.preAppFind({
      arguments: arguments,
      super: this._super
    });
  },

  findAll: function () {
    return this.preAppFind({
      arguments: arguments,
      super: this._super
    });
  },

  preAppFind: function (opts) {

    // Grab our global objects as well as our type.
    var modelName = opts.arguments[1].modelName;
    var request;

    // Delete the key so no subsequent calls to `find` use it.
    if (window.__ds_adapter_preapp_request)  {
      request = window.__ds_adapter_preapp_request[modelName];
      delete window.__ds_adapter_preapp_request[modelName];
    }

    // If no request exists, use super and call it a day.
    if ( !request ) {
      return opts.super.apply(this, opts.arguments);
    } else {

      return new Ember.RSVP.Promise(function (resolve, reject) {

        // If responseText has already been set by the pre-app request,
        // resolve with it.
        if ( request.responseText ) {
          resolve(JSON.parse(request.responseText));

        // If response has not been set by the pre-app request,
        // this likely means that the request is not yet finished.
        // Let's hook into the onload and resolve/reject accordingly.
        } else {

          var onFn = function () {
            var response = JSON.parse(request.responseText);
            if (request.status >= 200 && request.status < 400) {
              resolve(response);
            } else {
              reject(response);
            }
          };

          request.onload = onFn;
          request.onerror = onFn;

        }

      });

    }

  }

});
<|endoftext|>


<commit_before>var ignoredSymbols = "[\\*\\^\\$]"

function has(string, input) {
	if (!input) {
		if (string == "numbers" || string == "digits" || string == "num") return '(?=.*[0-9])'
		if (string == "letters" || string == "char") return '(?=.*[a-zA-Z])'

		if (string == "$numbers" || string == "$digits" || string == "$num" || string == "$letters" || string == "$char") {
			return '(?=.*\\b' + string.substring(1) + '\\b.*)'
		}

		if (string.match(ignoredSymbols)) {
			for (i = 0; i < string.match(new RegExp(ignoredSymbols, 'g')).length; i++) {
				var metaChar = string.match(new RegExp(ignoredSymbols, 'g'))[i]
				    string = string.replace(metaChar, "\\" + metaChar)
			}
			return new RegExp(string)
		} else {
			return '(?=.*\\b' + string + '\\b.*)'
		}
	} else {
		if (string.match(ignoredSymbols)) {
			for (i = 0; i < string.match(new RegExp(ignoredSymbols, 'g')).length; i++) {
				var metaChar = string.match(new RegExp(ignoredSymbols, 'g'))[i]
				    string = string.replace(metaChar, "\\" + metaChar)
			}
		}
		return input.match(new RegExp(string, 'gi')).length
	}
}
function not(string) {
	if (string == "numbers" || string == "digits" || string == "num") return '(?=.*^([^0-9]*)$)'
	if (string == "letters" || string == "char") return '(?=.*^([^a-zA-Z]*)$)'

	if (string == "$numbers" || string == "$digits" || string == "$num" || string == "$letters" || string == "$char") {
		return '(?=.*^(?!.*' + string.substring(1) + ').*$)'
	}

	if (string.match(ignoredSymbols)) {
		for (i = 0; i < string.match(new RegExp(ignoredSymbols, 'g')).length; i++) {
			var metaChar = string.match(new RegExp(ignoredSymbols, 'g'))[i]
				string = string.replace(metaChar, "\\" + metaChar)
		}
	}
	return '(?=.*^(?!.*' + string + ').*$)'
}
function beginsWith(string, input) {
	if (!input) {
		if (string.match(ignoredSymbols)) {
			for (i = 0; i < string.match(new RegExp(ignoredSymbols, 'g')).length; i++) {
				var metaChar = string.match(new RegExp(ignoredSymbols, 'g'))[i]
					string = string.replace(metaChar, "\\" + metaChar)
			}
		}
		return '(?=\\b' + string + ')'
	} else {
		if (string.match(ignoredSymbols)) {
			for (i = 0; i < string.match(new RegExp(ignoredSymbols, 'g')).length; i++) {
				var metaChar = string.match(new RegExp(ignoredSymbols, 'g'))[i]
					string = string.replace(metaChar, "\\" + metaChar)
			}
		}
		return input.match(new RegExp('\\b' + string, 'g')).length
	}
}
function endsWith(string, input) {
	if (!input) {
		if (string.match(ignoredSymbols)) {
			for (i = 0; i < string.match(new RegExp(ignoredSymbols, 'g')).length; i++) {
				var metaChar = string.match(new RegExp(ignoredSymbols, 'g'))[i]
					string = string.replace(metaChar, "\\" + metaChar)
			}
		}
		return '(?=\\B' + string + ')'
	} else {
		if (string.match(ignoredSymbols)) {
			for (i = 0; i < string.match(new RegExp(ignoredSymbols, 'g')).length; i++) {
				var metaChar = string.match(new RegExp(ignoredSymbols, 'g'))[i]
					string = string.replace(metaChar, "\\" + metaChar)
			}
		}
		return input.match(new RegExp('\\B' + string, 'g')).length
	}
}
function wordSize(size, input) {
	if (!input) {
		return '(?=[a-zA-Z0-9]{' + size + '})'
	} else {
		return input.match(new RegExp('[a-z0-9]{' + size + '}', 'gi')).length
	}
}
function or() {
	return '|'
}
// does not work with or() and +
function atLeastOne(string) {
	if (string.match(ignoredSymbols)) {
		for (i = 0; i < string.match(new RegExp(ignoredSymbols, 'g')).length; i++) {
			var metaChar = string.match(new RegExp(ignoredSymbols, 'g'))[i]
				string = string.replace(metaChar, "\\" + metaChar)
		}
	}
	return new RegExp('(?=' + string + '+)', 'g')
}
function showRegex(string) {
	return eval(string)
}
<commit_msg>Update easy-regex.js<commit_after>//meta-characters that bring errors when used in a function's parameter
var ignoredSymbols = "[\\*\\^\\$]"

function has(string, input) {
	if (!input) {
		if (string == "numbers" || string == "digits" || string == "num") return '(?=.*[0-9])'
		if (string == "letters" || string == "char") return '(?=.*[a-zA-Z])'

		if (string == "$numbers" || string == "$digits" || string == "$num" || string == "$letters" || string == "$char") {
			return '(?=.*\\b' + string.substring(1) + '\\b.*)'
		}
		//loop that checks for meta chars and adds a backlash for everyone that is found
		if (string.match(ignoredSymbols)) {
			for (i = 0; i < string.match(new RegExp(ignoredSymbols, 'g')).length; i++) {
				//replaces each meta-char with '\\' to prevent errors
				string = string.replace(string.match(new RegExp(ignoredSymbols, 'g'))[i], "\\" + string.match(new RegExp(ignoredSymbols, 'g'))[i])
			}
		}
		return '(?=.*\\b' + string + '\\b.*)'
	} else {
		if (string.match(ignoredSymbols)) {
			for (i = 0; i < string.match(new RegExp(ignoredSymbols, 'g')).length; i++) {
				string = string.replace(string.match(new RegExp(ignoredSymbols, 'g'))[i], "\\" + string.match(new RegExp(ignoredSymbols, 'g'))[i])
			}
		}
		return input.match(new RegExp(string, 'gi')).length
	}
}
function not(string) {
	if (string == "numbers" || string == "digits" || string == "num") return '(?=.*^([^0-9]*)$)'
	if (string == "letters" || string == "char") return '(?=.*^([^a-zA-Z]*)$)'

	if (string == "$numbers" || string == "$digits" || string == "$num" || string == "$letters" || string == "$char") {
		return '(?=.*^(?!.*' + string.substring(1) + ').*$)'
	}

	if (string.match(ignoredSymbols)) {
		for (i = 0; i < string.match(new RegExp(ignoredSymbols, 'g')).length; i++) {
			string = string.replace(string.match(new RegExp(ignoredSymbols, 'g'))[i], "\\" + string.match(new RegExp(ignoredSymbols, 'g'))[i])
		}
	}
	return '(?=.*^(?!.*' + string + ').*$)'
}
function beginsWith(string, input) {
	if (!input) {
		if (string.match(ignoredSymbols)) {
			for (i = 0; i < string.match(new RegExp(ignoredSymbols, 'g')).length; i++) {
				string = string.replace(string.match(new RegExp(ignoredSymbols, 'g'))[i], "\\" + string.match(new RegExp(ignoredSymbols, 'g'))[i])
			}
		}
		return '(?=\\b' + string + ')'
	} else {
		if (string.match(ignoredSymbols)) {
			for (i = 0; i < string.match(new RegExp(ignoredSymbols, 'g')).length; i++) {
				string = string.replace(string.match(new RegExp(ignoredSymbols, 'g'))[i], "\\" + string.match(new RegExp(ignoredSymbols, 'g'))[i])
			}
		}
		return input.match(new RegExp('\\b' + string, 'g')).length
	}
}
function endsWith(string, input) {
	if (!input) {
		if (string.match(ignoredSymbols)) {
			for (i = 0; i < string.match(new RegExp(ignoredSymbols, 'g')).length; i++) {
				string = string.replace(string.match(new RegExp(ignoredSymbols, 'g'))[i], "\\" + string.match(new RegExp(ignoredSymbols, 'g'))[i])
			}
		}
		return '(?=\\B' + string + ')'
	} else {
		if (string.match(ignoredSymbols)) {
			for (i = 0; i < string.match(new RegExp(ignoredSymbols, 'g')).length; i++) {
				string = string.replace(string.match(new RegExp(ignoredSymbols, 'g'))[i], "\\" + string.match(new RegExp(ignoredSymbols, 'g'))[i])
			}
		}
		return input.match(new RegExp('\\B' + string, 'g')).length
	}
}
function wordSize(size, input) {
	if (!input) {
		return '(?=[a-zA-Z0-9]{' + size + '})'
	} else {
		return input.match(new RegExp('[a-z0-9]{' + size + '}', 'gi')).length
	}
}
function or() {
	return '|'
}
// does not work with or() and +
function atLeastOne(string) {
	if (string.match(ignoredSymbols)) {
		for (i = 0; i < string.match(new RegExp(ignoredSymbols, 'g')).length; i++) {
			string = string.replace(string.match(new RegExp(ignoredSymbols, 'g'))[i], "\\" + string.match(new RegExp(ignoredSymbols, 'g'))[i])
		}
	}
	return new RegExp('(?=' + string + '+)', 'g')
}
function showRegex(string) {
	return eval(string)
}
<|endoftext|>