addReviewedCommitId(commentBody: string, commitId: string): string {
    const start = commentBody.indexOf(COMMIT_ID_START_TAG)
    const end = commentBody.indexOf(COMMIT_ID_END_TAG)
    if (start === -1 || end === -1) {
      return `${commentBody}\n${COMMIT_ID_START_TAG}\n<!-- ${commitId} -->\n${COMMIT_ID_END_TAG}`
    }
    const ids = commentBody.substring(start + COMMIT_ID_START_TAG.length, end)
    return `${commentBody.substring(
      0,
      start + COMMIT_ID_START_TAG.length
    )}${ids}<!-- ${commitId} -->\n${commentBody.substring(end)}`
  }


async members(): Promise<User[]> {
    return [new User()];
  }


myField(): string {
    return "Hello World";
  }


const debounced = (): void => {
      // Base64 decode the data
      const data: DataStore = store.data || {};

      // Loop over each stored capability
      for (const name of Object.keys(this.#stores)) {
        // Get the prefix offset for the keys
        const offset = `${name}-`.length;

        // Get any keys that match the capability name prefix
        const filtered: DataStore = {};

        // Loop over each key in the secret
        for (const key of Object.keys(data)) {
          // Match on the capability name as a prefix
          if (startsWith(name, key)) {
            // Strip the prefix and store the value
            filtered[key.slice(offset)] = data[key];
          }
        }

        // Send the data to the receiver callback
        this.#stores[name].receive(filtered);
      }

      // Call the onReady callback if this is the first time the secret has been read
      if (this.#onReady) {
        this.#onReady();
        this.#onReady = undefined;
      }
    };

// Wrap the update in a debounced function


confirmHeight(_i: number, heightGetter: THeightGetter) {
    let i = _i;
    if (i > this.lastI) {
      this.calcHeights(i, heightGetter);
      return;
    }
    const h = heightGetter(i);
    if (h === this.heights[i]) {
      return;
    }
    const chg = h - this.heights[i];
    this.heights[i] = h;
    // shift the y positions by `chg` for all known y positions
    while (++i <= this.lastI) {
      this.ys[i] += chg;
    }
    if (this.ys[this.lastI + 1] != null) {
      this.ys[this.lastI + 1] += chg;
    }
  }

/**
   * Get the latest height for index `_i`. If it's in new terretory
   * (_i > lastI), find the heights (and y-values) leading up to it. If it's in
   * known territory (_i <= lastI) and the height is different than what is
   * known, recalculate subsequent y values, but don't confirm the heights of
   * those items, just update based on the difference.
   */


get transformer_(): Promise<any> {
    if (this._isDisposed) {
      throw new Error(
        'This TransformedTargetRegressor instance has already been disposed'
      )
    }

    if (!this._isInitialized) {
      throw new Error(
        'TransformedTargetRegressor must call init() before accessing transformer_'
      )
    }

    return (async () => {
      // invoke accessor
      await this._py
        .ex`attr_TransformedTargetRegressor_transformer_ = bridgeTransformedTargetRegressor[${this.id}].transformer_`

      // convert the result from python to node.js
      return this
        ._py`attr_TransformedTargetRegressor_transformer_.tolist() if hasattr(attr_TransformedTargetRegressor_transformer_, 'tolist') else attr_TransformedTargetRegressor_transformer_`
    })()
  }

/**
    Transformer used in [`fit`](https://scikit-learn.org/stable/modules/generated/#sklearn.compose.TransformedTargetRegressor.fit "sklearn.compose.TransformedTargetRegressor.fit") and [`predict`](https://scikit-learn.org/stable/modules/generated/#sklearn.compose.TransformedTargetRegressor.predict "sklearn.compose.TransformedTargetRegressor.predict").
   */


async mahalanobis(opts: {
    /**
      The observations, the Mahalanobis distances of the which we compute. Observations are assumed to be drawn from the same distribution than the data used in fit.
     */
    X?: ArrayLike[]
  }): Promise<NDArray> {
    if (this._isDisposed) {
      throw new Error(
        'This EllipticEnvelope instance has already been disposed'
      )
    }

    if (!this._isInitialized) {
      throw new Error('EllipticEnvelope must call init() before mahalanobis()')
    }

    // set up method params
    await this._py
      .ex`pms_EllipticEnvelope_mahalanobis = {'X': np.array(${opts['X'] ?? undefined}) if ${opts['X'] !== undefined} else None}

pms_EllipticEnvelope_mahalanobis = {k: v for k, v in pms_EllipticEnvelope_mahalanobis.items() if v is not None}`

    // invoke method
    await this._py
      .ex`res_EllipticEnvelope_mahalanobis = bridgeEllipticEnvelope[${this.id}].mahalanobis(**pms_EllipticEnvelope_mahalanobis)`

    // convert the result from python to node.js
    return this
      ._py`res_EllipticEnvelope_mahalanobis.tolist() if hasattr(res_EllipticEnvelope_mahalanobis, 'tolist') else res_EllipticEnvelope_mahalanobis`
  }

/**
    Compute the squared Mahalanobis distances of given observations.
   */


async score(opts: {
    /**
      Test data of which we compute the likelihood, where `n_samples` is the number of samples and `n_features` is the number of features. `X_test` is assumed to be drawn from the same distribution than the data used in fit (including centering).
     */
    X_test?: ArrayLike[]

    /**
      Not used, present for API consistency by convention.
     */
    y?: any
  }): Promise<number> {
    if (this._isDisposed) {
      throw new Error(
        'This GraphicalLassoCV instance has already been disposed'
      )
    }

    if (!this._isInitialized) {
      throw new Error('GraphicalLassoCV must call init() before score()')
    }

    // set up method params
    await this._py
      .ex`pms_GraphicalLassoCV_score = {'X_test': np.array(${opts['X_test'] ?? undefined}) if ${opts['X_test'] !== undefined} else None, 'y': ${opts['y'] ?? undefined}}

pms_GraphicalLassoCV_score = {k: v for k, v in pms_GraphicalLassoCV_score.items() if v is not None}`

    // invoke method
    await this._py
      .ex`res_GraphicalLassoCV_score = bridgeGraphicalLassoCV[${this.id}].score(**pms_GraphicalLassoCV_score)`

    // convert the result from python to node.js
    return this
      ._py`res_GraphicalLassoCV_score.tolist() if hasattr(res_GraphicalLassoCV_score, 'tolist') else res_GraphicalLassoCV_score`
  }

/**
    Compute the log-likelihood of `X_test` under the estimated Gaussian model.

    The Gaussian model is defined by its mean and covariance matrix which are represented respectively by `self.location_` and `self.covariance_`.
   */


async get_precision(opts: {
    /**
      The precision matrix associated to the current covariance object.
     */
    precision_?: ArrayLike[]
  }): Promise<any> {
    if (this._isDisposed) {
      throw new Error('This MinCovDet instance has already been disposed')
    }

    if (!this._isInitialized) {
      throw new Error('MinCovDet must call init() before get_precision()')
    }

    // set up method params
    await this._py
      .ex`pms_MinCovDet_get_precision = {'precision_': np.array(${opts['precision_'] ?? undefined}) if ${opts['precision_'] !== undefined} else None}

pms_MinCovDet_get_precision = {k: v for k, v in pms_MinCovDet_get_precision.items() if v is not None}`

    // invoke method
    await this._py
      .ex`res_MinCovDet_get_precision = bridgeMinCovDet[${this.id}].get_precision(**pms_MinCovDet_get_precision)`

    // convert the result from python to node.js
    return this
      ._py`res_MinCovDet_get_precision.tolist() if hasattr(res_MinCovDet_get_precision, 'tolist') else res_MinCovDet_get_precision`
  }

/**
    Getter for the precision matrix.
   */


get location_(): Promise<NDArray> {
    if (this._isDisposed) {
      throw new Error(
        'This ShrunkCovariance instance has already been disposed'
      )
    }

    if (!this._isInitialized) {
      throw new Error(
        'ShrunkCovariance must call init() before accessing location_'
      )
    }

    return (async () => {
      // invoke accessor
      await this._py
        .ex`attr_ShrunkCovariance_location_ = bridgeShrunkCovariance[${this.id}].location_`

      // convert the result from python to node.js
      return this
        ._py`attr_ShrunkCovariance_location_.tolist() if hasattr(attr_ShrunkCovariance_location_, 'tolist') else attr_ShrunkCovariance_location_`
    })()
  }

/**
    Estimated location, i.e. the estimated mean.
   */


get n_components_(): Promise<number> {
    if (this._isDisposed) {
      throw new Error('This IncrementalPCA instance has already been disposed')
    }

    if (!this._isInitialized) {
      throw new Error(
        'IncrementalPCA must call init() before accessing n_components_'
      )
    }

    return (async () => {
      // invoke accessor
      await this._py
        .ex`attr_IncrementalPCA_n_components_ = bridgeIncrementalPCA[${this.id}].n_components_`

      // convert the result from python to node.js
      return this
        ._py`attr_IncrementalPCA_n_components_.tolist() if hasattr(attr_IncrementalPCA_n_components_, 'tolist') else attr_IncrementalPCA_n_components_`
    })()
  }

/**
    The estimated number of components. Relevant when `n_components=None`.
   */


get classes_(): Promise<NDArray> {
    if (this._isDisposed) {
      throw new Error('This DummyClassifier instance has already been disposed')
    }

    if (!this._isInitialized) {
      throw new Error(
        'DummyClassifier must call init() before accessing classes_'
      )
    }

    return (async () => {
      // invoke accessor
      await this._py
        .ex`attr_DummyClassifier_classes_ = bridgeDummyClassifier[${this.id}].classes_`

      // convert the result from python to node.js
      return this
        ._py`attr_DummyClassifier_classes_.tolist() if hasattr(attr_DummyClassifier_classes_, 'tolist') else attr_DummyClassifier_classes_`
    })()
  }

/**
    Unique class labels observed in `y`. For multi-output classification problems, this attribute is a list of arrays as each output has an independent set of possible classes.
   */


async transform(opts: {
    /**
      The input samples.
     */
    X?: any
  }): Promise<any> {
    if (this._isDisposed) {
      throw new Error(
        'This SequentialFeatureSelector instance has already been disposed'
      )
    }

    if (!this._isInitialized) {
      throw new Error(
        'SequentialFeatureSelector must call init() before transform()'
      )
    }

    // set up method params
    await this._py
      .ex`pms_SequentialFeatureSelector_transform = {'X': np.array(${opts['X'] ?? undefined}) if ${opts['X'] !== undefined} else None}

pms_SequentialFeatureSelector_transform = {k: v for k, v in pms_SequentialFeatureSelector_transform.items() if v is not None}`

    // invoke method
    await this._py
      .ex`res_SequentialFeatureSelector_transform = bridgeSequentialFeatureSelector[${this.id}].transform(**pms_SequentialFeatureSelector_transform)`

    // convert the result from python to node.js
    return this
      ._py`res_SequentialFeatureSelector_transform.tolist() if hasattr(res_SequentialFeatureSelector_transform, 'tolist') else res_SequentialFeatureSelector_transform`
  }

/**
    Reduce X to the selected features.
   */


get bars_(): Promise<any> {
    if (this._isDisposed) {
      throw new Error(
        'This PartialDependenceDisplay instance has already been disposed'
      )
    }

    if (!this._isInitialized) {
      throw new Error(
        'PartialDependenceDisplay must call init() before accessing bars_'
      )
    }

    return (async () => {
      // invoke accessor
      await this._py
        .ex`attr_PartialDependenceDisplay_bars_ = bridgePartialDependenceDisplay[${this.id}].bars_`

      // convert the result from python to node.js
      return this
        ._py`attr_PartialDependenceDisplay_bars_.tolist() if hasattr(attr_PartialDependenceDisplay_bars_, 'tolist') else attr_PartialDependenceDisplay_bars_`
    })()
  }

/**
    If `ax` is an axes or `undefined`, `bars_\[i, j\]` is the partial dependence bar plot on the i-th row and j-th column (for a categorical feature). If `ax` is a list of axes, `bars_\[i\]` is the partial dependence bar plot corresponding to the i-th item in `ax`. Elements that are `undefined` correspond to a nonexisting axes or an axes that does not include a bar plot.
   */


async fit_transform(opts: {
    /**
      Input samples.
     */
    X?: ArrayLike[]

    /**
      Target values (`undefined` for unsupervised transformations).
     */
    y?: ArrayLike

    /**
      Additional fit parameters.
     */
    fit_params?: any
  }): Promise<any[]> {
    if (this._isDisposed) {
      throw new Error('This Nystroem instance has already been disposed')
    }

    if (!this._isInitialized) {
      throw new Error('Nystroem must call init() before fit_transform()')
    }

    // set up method params
    await this._py
      .ex`pms_Nystroem_fit_transform = {'X': np.array(${opts['X'] ?? undefined}) if ${opts['X'] !== undefined} else None, 'y': np.array(${opts['y'] ?? undefined}) if ${opts['y'] !== undefined} else None, 'fit_params': ${opts['fit_params'] ?? undefined}}

pms_Nystroem_fit_transform = {k: v for k, v in pms_Nystroem_fit_transform.items() if v is not None}`

    // invoke method
    await this._py
      .ex`res_Nystroem_fit_transform = bridgeNystroem[${this.id}].fit_transform(**pms_Nystroem_fit_transform)`

    // convert the result from python to node.js
    return this
      ._py`res_Nystroem_fit_transform.tolist() if hasattr(res_Nystroem_fit_transform, 'tolist') else res_Nystroem_fit_transform`
  }

/**
    Fit to data, then transform it.

    Fits transformer to `X` and `y` with optional parameters `fit_params` and returns a transformed version of `X`.
   */


async set_score_request(opts: {
    /**
      Metadata routing for `sample_weight` parameter in `score`.
     */
    sample_weight?: string | boolean
  }): Promise<any> {
    if (this._isDisposed) {
      throw new Error('This ElasticNet instance has already been disposed')
    }

    if (!this._isInitialized) {
      throw new Error('ElasticNet must call init() before set_score_request()')
    }

    // set up method params
    await this._py
      .ex`pms_ElasticNet_set_score_request = {'sample_weight': ${opts['sample_weight'] ?? undefined}}

pms_ElasticNet_set_score_request = {k: v for k, v in pms_ElasticNet_set_score_request.items() if v is not None}`

    // invoke method
    await this._py
      .ex`res_ElasticNet_set_score_request = bridgeElasticNet[${this.id}].set_score_request(**pms_ElasticNet_set_score_request)`

    // convert the result from python to node.js
    return this
      ._py`res_ElasticNet_set_score_request.tolist() if hasattr(res_ElasticNet_set_score_request, 'tolist') else res_ElasticNet_set_score_request`
  }

/**
    Request metadata passed to the `score` method.

    Note that this method is only relevant if `enable_metadata_routing=True` (see [`sklearn.set_config`](https://scikit-learn.org/stable/modules/generated/sklearn.set_config.html#sklearn.set_config "sklearn.set_config")). Please see [User Guide](https://scikit-learn.org/stable/modules/generated/../../metadata_routing.html#metadata-routing) on how the routing mechanism works.

    The options for each parameter are:
   */


get alpha_(): Promise<number> {
    if (this._isDisposed) {
      throw new Error('This LarsCV instance has already been disposed')
    }

    if (!this._isInitialized) {
      throw new Error('LarsCV must call init() before accessing alpha_')
    }

    return (async () => {
      // invoke accessor
      await this._py.ex`attr_LarsCV_alpha_ = bridgeLarsCV[${this.id}].alpha_`

      // convert the result from python to node.js
      return this
        ._py`attr_LarsCV_alpha_.tolist() if hasattr(attr_LarsCV_alpha_, 'tolist') else attr_LarsCV_alpha_`
    })()
  }

/**
    the estimated regularization parameter alpha
   */


async fit(opts: {
    /**
      Data.

      Note that large sparse matrices and arrays requiring `int64` indices are not accepted.
     */
    X?: SparseMatrix

    /**
      Target. Will be cast to X’s dtype if necessary.
     */
    y?: NDArray

    /**
      Sample weights. Internally, the `sample_weight` vector will be rescaled to sum to `n_samples`.
     */
    sample_weight?: number | ArrayLike

    /**
      Allow to bypass several input checking. Don’t use this parameter unless you know what you do.

      @defaultValue `true`
     */
    check_input?: boolean
  }): Promise<any> {
    if (this._isDisposed) {
      throw new Error('This Lasso instance has already been disposed')
    }

    if (!this._isInitialized) {
      throw new Error('Lasso must call init() before fit()')
    }

    // set up method params
    await this._py
      .ex`pms_Lasso_fit = {'X': ${opts['X'] ?? undefined}, 'y': np.array(${opts['y'] ?? undefined}) if ${opts['y'] !== undefined} else None, 'sample_weight': np.array(${opts['sample_weight'] ?? undefined}) if ${opts['sample_weight'] !== undefined} else None, 'check_input': ${opts['check_input'] ?? undefined}}

pms_Lasso_fit = {k: v for k, v in pms_Lasso_fit.items() if v is not None}`

    // invoke method
    await this._py
      .ex`res_Lasso_fit = bridgeLasso[${this.id}].fit(**pms_Lasso_fit)`

    // convert the result from python to node.js
    return this
      ._py`res_Lasso_fit.tolist() if hasattr(res_Lasso_fit, 'tolist') else res_Lasso_fit`
  }

/**
    Fit model with coordinate descent.
   */


async get_metadata_routing(opts: {
    /**
      A [`MetadataRequest`](https://scikit-learn.org/stable/modules/generated/sklearn.utils.metadata_routing.MetadataRequest.html#sklearn.utils.metadata_routing.MetadataRequest "sklearn.utils.metadata_routing.MetadataRequest") encapsulating routing information.
     */
    routing?: any
  }): Promise<any> {
    if (this._isDisposed) {
      throw new Error(
        'This LinearRegression instance has already been disposed'
      )
    }

    if (!this._isInitialized) {
      throw new Error(
        'LinearRegression must call init() before get_metadata_routing()'
      )
    }

    // set up method params
    await this._py
      .ex`pms_LinearRegression_get_metadata_routing = {'routing': ${opts['routing'] ?? undefined}}

pms_LinearRegression_get_metadata_routing = {k: v for k, v in pms_LinearRegression_get_metadata_routing.items() if v is not None}`

    // invoke method
    await this._py
      .ex`res_LinearRegression_get_metadata_routing = bridgeLinearRegression[${this.id}].get_metadata_routing(**pms_LinearRegression_get_metadata_routing)`

    // convert the result from python to node.js
    return this
      ._py`res_LinearRegression_get_metadata_routing.tolist() if hasattr(res_LinearRegression_get_metadata_routing, 'tolist') else res_LinearRegression_get_metadata_routing`
  }

/**
    Get metadata routing of this object.

    Please check [User Guide](https://scikit-learn.org/stable/modules/generated/../../metadata_routing.html#metadata-routing) on how the routing mechanism works.
   */


async predict(opts: {
    /**
      The data matrix for which we want to get the predictions.
     */
    X?: ArrayLike | SparseMatrix[]
  }): Promise<NDArray> {
    if (this._isDisposed) {
      throw new Error(
        'This LogisticRegression instance has already been disposed'
      )
    }

    if (!this._isInitialized) {
      throw new Error('LogisticRegression must call init() before predict()')
    }

    // set up method params
    await this._py
      .ex`pms_LogisticRegression_predict = {'X': np.array(${opts['X'] ?? undefined}) if ${opts['X'] !== undefined} else None}

pms_LogisticRegression_predict = {k: v for k, v in pms_LogisticRegression_predict.items() if v is not None}`

    // invoke method
    await this._py
      .ex`res_LogisticRegression_predict = bridgeLogisticRegression[${this.id}].predict(**pms_LogisticRegression_predict)`

    // convert the result from python to node.js
    return this
      ._py`res_LogisticRegression_predict.tolist() if hasattr(res_LogisticRegression_predict, 'tolist') else res_LogisticRegression_predict`
  }

/**
    Predict class labels for samples in X.
   */


async set_output(opts: {
    /**
      Configure output of `transform` and `fit_transform`.
     */
    transform?: 'default' | 'pandas' | 'polars'
  }): Promise<any> {
    if (this._isDisposed) {
      throw new Error(
        'This LocallyLinearEmbedding instance has already been disposed'
      )
    }

    if (!this._isInitialized) {
      throw new Error(
        'LocallyLinearEmbedding must call init() before set_output()'
      )
    }

    // set up method params
    await this._py
      .ex`pms_LocallyLinearEmbedding_set_output = {'transform': ${opts['transform'] ?? undefined}}

pms_LocallyLinearEmbedding_set_output = {k: v for k, v in pms_LocallyLinearEmbedding_set_output.items() if v is not None}`

    // invoke method
    await this._py
      .ex`res_LocallyLinearEmbedding_set_output = bridgeLocallyLinearEmbedding[${this.id}].set_output(**pms_LocallyLinearEmbedding_set_output)`

    // convert the result from python to node.js
    return this
      ._py`res_LocallyLinearEmbedding_set_output.tolist() if hasattr(res_LocallyLinearEmbedding_set_output, 'tolist') else res_LocallyLinearEmbedding_set_output`
  }

/**
    Set output container.

    See [Introducing the set_output API](https://scikit-learn.org/stable/modules/generated/../../auto_examples/miscellaneous/plot_set_output.html#sphx-glr-auto-examples-miscellaneous-plot-set-output-py) for an example on how to use the API.
   */


get learning_rate_(): Promise<number> {
    if (this._isDisposed) {
      throw new Error('This TSNE instance has already been disposed')
    }

    if (!this._isInitialized) {
      throw new Error('TSNE must call init() before accessing learning_rate_')
    }

    return (async () => {
      // invoke accessor
      await this._py
        .ex`attr_TSNE_learning_rate_ = bridgeTSNE[${this.id}].learning_rate_`

      // convert the result from python to node.js
      return this
        ._py`attr_TSNE_learning_rate_.tolist() if hasattr(attr_TSNE_learning_rate_, 'tolist') else attr_TSNE_learning_rate_`
    })()
  }


async dispose() {
    if (this._isDisposed) {
      return
    }

    if (!this._isInitialized) {
      return
    }

    await this._py.ex`del bridgeConfusionMatrixDisplay[${this.id}]`

    this._isDisposed = true
  }

/**
    Disposes of the underlying Python resources.

    Once `dispose()` is called, the instance is no longer usable.
   */


get ax_(): Promise<any> {
    if (this._isDisposed) {
      throw new Error(
        'This LearningCurveDisplay instance has already been disposed'
      )
    }

    if (!this._isInitialized) {
      throw new Error(
        'LearningCurveDisplay must call init() before accessing ax_'
      )
    }

    return (async () => {
      // invoke accessor
      await this._py
        .ex`attr_LearningCurveDisplay_ax_ = bridgeLearningCurveDisplay[${this.id}].ax_`

      // convert the result from python to node.js
      return this
        ._py`attr_LearningCurveDisplay_ax_.tolist() if hasattr(attr_LearningCurveDisplay_ax_, 'tolist') else attr_LearningCurveDisplay_ax_`
    })()
  }

/**
    Axes with the learning curve.
   */


async fit(opts: {
    /**
      The data used to compute the median and quantiles used for later scaling along the features axis.
     */
    X?: ArrayLike | SparseMatrix[]

    /**
      Not used, present here for API consistency by convention.
     */
    y?: any
  }): Promise<any> {
    if (this._isDisposed) {
      throw new Error('This RobustScaler instance has already been disposed')
    }

    if (!this._isInitialized) {
      throw new Error('RobustScaler must call init() before fit()')
    }

    // set up method params
    await this._py
      .ex`pms_RobustScaler_fit = {'X': np.array(${opts['X'] ?? undefined}) if ${opts['X'] !== undefined} else None, 'y': ${opts['y'] ?? undefined}}

pms_RobustScaler_fit = {k: v for k, v in pms_RobustScaler_fit.items() if v is not None}`

    // invoke method
    await this._py
      .ex`res_RobustScaler_fit = bridgeRobustScaler[${this.id}].fit(**pms_RobustScaler_fit)`

    // convert the result from python to node.js
    return this
      ._py`res_RobustScaler_fit.tolist() if hasattr(res_RobustScaler_fit, 'tolist') else res_RobustScaler_fit`
  }

/**
    Compute the median and quantiles to be used for scaling.
   */


async decision_function(opts: {
    /**
      Array representing the data.
     */
    X?: ArrayLike | SparseMatrix[]
  }): Promise<NDArray[]> {
    if (this._isDisposed) {
      throw new Error(
        'This SelfTrainingClassifier instance has already been disposed'
      )
    }

    if (!this._isInitialized) {
      throw new Error(
        'SelfTrainingClassifier must call init() before decision_function()'
      )
    }

    // set up method params
    await this._py
      .ex`pms_SelfTrainingClassifier_decision_function = {'X': np.array(${opts['X'] ?? undefined}) if ${opts['X'] !== undefined} else None}

pms_SelfTrainingClassifier_decision_function = {k: v for k, v in pms_SelfTrainingClassifier_decision_function.items() if v is not None}`

    // invoke method
    await this._py
      .ex`res_SelfTrainingClassifier_decision_function = bridgeSelfTrainingClassifier[${this.id}].decision_function(**pms_SelfTrainingClassifier_decision_function)`

    // convert the result from python to node.js
    return this
      ._py`res_SelfTrainingClassifier_decision_function.tolist() if hasattr(res_SelfTrainingClassifier_decision_function, 'tolist') else res_SelfTrainingClassifier_decision_function`
  }

/**
    Call decision function of the `base_estimator`.
   */


async sparsify(opts: {}): Promise<any> {
    if (this._isDisposed) {
      throw new Error('This LinearSVC instance has already been disposed')
    }

    if (!this._isInitialized) {
      throw new Error('LinearSVC must call init() before sparsify()')
    }

    // set up method params
    await this._py.ex`pms_LinearSVC_sparsify = {}

pms_LinearSVC_sparsify = {k: v for k, v in pms_LinearSVC_sparsify.items() if v is not None}`

    // invoke method
    await this._py
      .ex`res_LinearSVC_sparsify = bridgeLinearSVC[${this.id}].sparsify(**pms_LinearSVC_sparsify)`

    // convert the result from python to node.js
    return this
      ._py`res_LinearSVC_sparsify.tolist() if hasattr(res_LinearSVC_sparsify, 'tolist') else res_LinearSVC_sparsify`
  }

/**
    Convert coefficient matrix to sparse format.

    Converts the `coef_` member to a scipy.sparse matrix, which for L1-regularized models can be much more memory- and storage-efficient than the usual numpy.ndarray representation.

    The `intercept_` member is not converted.
   */


async decision_path(opts: {
    /**
      The input samples. Internally, it will be converted to `dtype=np.float32` and if a sparse matrix is provided to a sparse `csr_matrix`.
     */
    X?: ArrayLike | SparseMatrix[]

    /**
      Allow to bypass several input checking. Don’t use this parameter unless you know what you’re doing.

      @defaultValue `true`
     */
    check_input?: boolean
  }): Promise<SparseMatrix[]> {
    if (this._isDisposed) {
      throw new Error(
        'This ExtraTreeClassifier instance has already been disposed'
      )
    }

    if (!this._isInitialized) {
      throw new Error(
        'ExtraTreeClassifier must call init() before decision_path()'
      )
    }

    // set up method params
    await this._py
      .ex`pms_ExtraTreeClassifier_decision_path = {'X': np.array(${opts['X'] ?? undefined}) if ${opts['X'] !== undefined} else None, 'check_input': ${opts['check_input'] ?? undefined}}

pms_ExtraTreeClassifier_decision_path = {k: v for k, v in pms_ExtraTreeClassifier_decision_path.items() if v is not None}`

    // invoke method
    await this._py
      .ex`res_ExtraTreeClassifier_decision_path = bridgeExtraTreeClassifier[${this.id}].decision_path(**pms_ExtraTreeClassifier_decision_path)`

    // convert the result from python to node.js
    return this
      ._py`res_ExtraTreeClassifier_decision_path.tolist() if hasattr(res_ExtraTreeClassifier_decision_path, 'tolist') else res_ExtraTreeClassifier_decision_path`
  }

/**
    Return the decision path in the tree.
   */


async fit(opts: {
    /**
      The training input samples. Internally, it will be converted to `dtype=np.float32` and if a sparse matrix is provided to a sparse `csc_matrix`.
     */
    X?: ArrayLike | SparseMatrix[]

    /**
      The target values (real numbers). Use `dtype=np.float64` and `order='C'` for maximum efficiency.
     */
    y?: ArrayLike

    /**
      Sample weights. If `undefined`, then samples are equally weighted. Splits that would create child nodes with net zero or negative weight are ignored while searching for a split in each node.
     */
    sample_weight?: ArrayLike

    /**
      Allow to bypass several input checking. Don’t use this parameter unless you know what you’re doing.

      @defaultValue `true`
     */
    check_input?: boolean
  }): Promise<any> {
    if (this._isDisposed) {
      throw new Error(
        'This ExtraTreeRegressor instance has already been disposed'
      )
    }

    if (!this._isInitialized) {
      throw new Error('ExtraTreeRegressor must call init() before fit()')
    }

    // set up method params
    await this._py
      .ex`pms_ExtraTreeRegressor_fit = {'X': np.array(${opts['X'] ?? undefined}) if ${opts['X'] !== undefined} else None, 'y': np.array(${opts['y'] ?? undefined}) if ${opts['y'] !== undefined} else None, 'sample_weight': np.array(${opts['sample_weight'] ?? undefined}) if ${opts['sample_weight'] !== undefined} else None, 'check_input': ${opts['check_input'] ?? undefined}}

pms_ExtraTreeRegressor_fit = {k: v for k, v in pms_ExtraTreeRegressor_fit.items() if v is not None}`

    // invoke method
    await this._py
      .ex`res_ExtraTreeRegressor_fit = bridgeExtraTreeRegressor[${this.id}].fit(**pms_ExtraTreeRegressor_fit)`

    // convert the result from python to node.js
    return this
      ._py`res_ExtraTreeRegressor_fit.tolist() if hasattr(res_ExtraTreeRegressor_fit, 'tolist') else res_ExtraTreeRegressor_fit`
  }

/**
    Build a decision tree regressor from the training set (X, y).
   */


public async set(didUri: string, resolutionResult: DidResolutionResult): Promise<void> {
    this.cache.set(didUri, resolutionResult);
  }

/**
   * Stores a DID resolution result in the cache with a TTL.
   *
   * @param didUri - The DID string used as the key for storing the result.
   * @param resolutionResult - The DID resolution result to be cached.
   * @returns A promise that resolves when the operation is complete.
   */


get contextId() { return this.deleted ? this._initialWrite.contextId : this._contextId; }

/** Record's context ID. If the record is deleted, the context Id comes from the initial write */


public static async consumeToArrayBuffer({ readableStream }: { readableStream: ReadableStream}): Promise<ArrayBuffer> {
    const iterableStream = Stream.asAsyncIterator(readableStream);
    const arrayBuffer = await Convert.asyncIterable(iterableStream).toArrayBufferAsync();

    return arrayBuffer;
  }

/**
   * Consumes a `ReadableStream` and returns its contents as an `ArrayBuffer`.
   *
   * This method reads all data from a `ReadableStream`, collects it, and converts it into an
   * `ArrayBuffer`.
   *
   * @example
   * ```ts
   * const readableStream = new ReadableStream({ ... });
   * const arrayBuffer = await Stream.consumeToArrayBuffer({ readableStream });
   * ```
   *
   * @param readableStream - The Web `ReadableStream` whose data will be consumed.
   * @returns A Promise that resolves to an `ArrayBuffer` containing all the data from the stream.
   */


public static async decompressPublicKey({ publicKeyBytes }: {
    publicKeyBytes: Uint8Array;
  }): Promise<Uint8Array> {
    // Decode Weierstrass points from the public key byte array.
    const point = secp256k1.ProjectivePoint.fromHex(publicKeyBytes);

    // Return the uncompressed form of the public key.
    return point.toRawBytes(false);
  }

/**
   * Converts a public key to its uncompressed form.
   *
   * @remarks
   * This method takes a compressed public key represented as a byte array and decompresses it.
   * Public key decompression involves reconstructing the y-coordinate from the x-coordinate,
   * resulting in the full public key. This method is used when the uncompressed key format is
   * required for certain cryptographic operations or interoperability.
   *
   * @example
   * ```ts
   * const compressedPublicKeyBytes = new Uint8Array([...]); // Replace with actual compressed public key bytes
   * const decompressedPublicKey = await Secp256k1.decompressPublicKey({
   *   publicKeyBytes: compressedPublicKeyBytes
   * });
   * ```
   *
   * @param params - The parameters for the public key decompression.
   * @param params.publicKeyBytes - The public key as a Uint8Array.
   *
   * @returns A Promise that resolves to the uncompressed public key as a Uint8Array.
   */


public static async digest({ data }: {
    data: Uint8Array;
  }): Promise<Uint8Array> {
    const hash = sha256(data);

    return hash;
  }

/**
   * Generates a SHA-256 hash digest for the given data.
   *
   * @remarks
   * This method produces a hash digest using the SHA-256 algorithm. The resultant digest
   * is deterministic, meaning the same data will always produce the same hash, but
   * is computationally infeasible to regenerate the original data from the hash.
   *
   * @example
   * ```ts
   * const data = new Uint8Array([...]);
   * const hash = await Sha256.digest({ data });
   * ```
   *
   * @param params - The parameters for the hashing operation.
   * @param params.data - The data to hash, represented as a Uint8Array.
   *
   * @returns A Promise that resolves to the SHA-256 hash digest of the provided data as a Uint8Array.
   */


public static async resolve(didUri: string, _options?: DidResolutionOptions): Promise<DidResolutionResult> {
    // Attempt to parse the DID URI.
    const parsedDid = Did.parse(didUri);

    // If parsing failed, the DID is invalid.
    if (!parsedDid) {
      return {
        ...EMPTY_DID_RESOLUTION_RESULT,
        didResolutionMetadata: { error: 'invalidDid' }
      };
    }

    // If the DID method is not "web", return an error.
    if (parsedDid.method !== DidWeb.methodName) {
      return {
        ...EMPTY_DID_RESOLUTION_RESULT,
        didResolutionMetadata: { error: 'methodNotSupported' }
      };
    }

    // Replace ":" with "/" in the identifier and prepend "https://" to obtain the fully qualified
    // domain name and optional path.
    let baseUrl = `https://${parsedDid.id.replace(/:/g, '/')}`;

    // If the domain contains a percent encoded port value, decode the colon.
    baseUrl = decodeURIComponent(baseUrl);

    // Append the expected location of the DID document depending on whether a path was specified.
    const didDocumentUrl = parsedDid.id.includes(':') ?
      `${baseUrl}/did.json` :
      `${baseUrl}/.well-known/did.json`;

    try {
      // Perform an HTTP GET request to obtain the DID document.
      const response = await fetch(didDocumentUrl);

      // If the response status code is not 200, return an error.
      if (!response.ok) throw new Error('HTTP error status code returned');

      // Parse the DID document.
      const didDocument = await response.json() as DidDocument;

      return {
        ...EMPTY_DID_RESOLUTION_RESULT,
        didDocument,
      };

    } catch (error: any) {
      // If the DID document could not be retrieved, return an error.
      return {
        ...EMPTY_DID_RESOLUTION_RESULT,
        didResolutionMetadata: { error: 'notFound' }
      };
    }
  }

/**
   * Resolves a `did:web` identifier to a DID Document.
   *
   * @param didUri - The DID to be resolved.
   * @param _options - Optional parameters for resolving the DID. Unused by this DID method.
   * @returns A Promise resolving to a {@link DidResolutionResult} object representing the result of the resolution.
   */


softDelete = (
    query?: {
      /** @format int64 */
      id?: number
    },
    params: RequestParams = {}
  ) =>
    this.request<AxiosResponse, any>({
      path: `/api/admin/view/soft-delete`,
      method: 'DELETE',
      query: query,
      secure: true,
      ...params,
    })

/**
   * No description
   *
   * @tags view
   * @name SoftDelete
   * @summary 删除
   * @request DELETE:/api/admin/view/soft-delete
   * @secure
   */


function svgFind(e: any) {
  const arr = []
  const dirents = readdirSync(e, { withFileTypes: true })
  for (const dirent of dirents) {
    if (dirent.isDirectory()) arr.push(...svgFind(e + dirent.name + '/'))
    else {
      const svg = readFileSync(e + dirent.name)
        .toString()
        .replace(clearReturn, '')
        .replace(svgTitle, ($1: any, $2: any) => {
          let width = 0,
            height = 0,
            content = $2.replace(clearHeightWidth, (s1: any, s2: any, s3: any) => {
              if (s2 === 'width') width = s3
              else if (s2 === 'height') height = s3
              return ''
            })
          if (!hasViewBox.test($2)) content += `viewBox="0 0 ${width} ${height}"`
          return `<symbol id="${idPerfix}-${dirent.name.replace('.svg', '')}" ${content}>`
        }).replace('</svg>', '</symbol>')
      arr.push(svg)
    }
  }
  return arr
}


const getTablesByDatabase = async (params: any) => {
  const result = await apiRequest(
    'get',
    'catalog/get-tables-by-database',
    params
  );
  return result;
};


async function getPostCollect(
  postId: string,
): Promise<TGApp.Sqlite.UserCollection.UFMap[] | boolean> {
  const db = await TGSqlite.getDB();
  const sql = "SELECT * FROM UFMap WHERE postId = ?";
  const res: TGApp.Sqlite.UserCollection.UFMap[] = await db.select(sql, [postId]);
  if (res.length > 0) return res;
  const unclassifiedSql = "SELECT * FROM UFPost WHERE id = ?";
  const unclassifiedRes: TGApp.Sqlite.UserCollection.UFPost[] = await db.select(unclassifiedSql, [
    postId,
  ]);
  return unclassifiedRes.length > 0;
}

/**
 * @description 获取单个帖子的收藏信息
 * @since Beta v0.4.5
 * @param {string} postId 文章 id
 * @return {Promise<TGApp.Sqlite.UserCollection.UFMap[]|boolean>} 返回收藏信息
 */


function animateResponseText() {
          if (finished || controller.signal.aborted) {
            responseText += remainText;
            console.log("[Response Animation] finished");
            if (responseText?.length === 0) {
              options.onError?.(new Error("empty response from server"));
            }
            return;
          }

          if (remainText.length > 0) {
            const fetchCount = Math.max(1, Math.round(remainText.length / 60));
            const fetchText = remainText.slice(0, fetchCount);
            responseText += fetchText;
            remainText = remainText.slice(fetchCount);
            options.onUpdate?.(responseText, fetchText);
          }

          requestAnimationFrame(animateResponseText);
        }

// animate response to make it looks smooth


async function updateMcpConfig(config: McpConfigData): Promise<void> {
  try {
    // 确保目录存在
    await fs.mkdir(path.dirname(CONFIG_PATH), { recursive: true });
    await fs.writeFile(CONFIG_PATH, JSON.stringify(config, null, 2));
  } catch (error) {
    throw error;
  }
}

// 更新 MCP 配置文件


function createSign(apiUrl: string, timestamp: number, nonceStr: string) {
  const method = 'GET'
  const signStr = `${method}\n${apiUrl}\n${timestamp}\n${nonceStr}\n\n`
  const cert = WechatPaySpec.privateKey
  const sign = crypto.createSign('RSA-SHA256')
  sign.update(signStr)
  return sign.sign(cert, 'base64')
}


public drawCameraFrustum(camera: Camera3D, color: Color = Color.COLOR_WHITE) {
        if (camera.type == CameraType.perspective) {
            let y = Math.tan(camera.fov / 2 * DEGREES_TO_RADIANS);
            let x = y * camera.aspect;
            let worldMatrix = camera.transform._worldMatrix;

            let f0 = worldMatrix.transformVector(new Vector3(-x, -y, 1));
            let f1 = worldMatrix.transformVector(new Vector3(-x, y, 1));
            let f2 = worldMatrix.transformVector(new Vector3(x, -y, 1));
            let f3 = worldMatrix.transformVector(new Vector3(x, y, 1));

            let far = camera.far;
            let near = camera.near;
            let pos = camera.transform.worldPosition;

            let farLB = new Vector3().copyFrom(f0).multiplyScalar(far).add(pos);
            let farLT = new Vector3().copyFrom(f1).multiplyScalar(far).add(pos);
            let farRB = new Vector3().copyFrom(f2).multiplyScalar(far).add(pos);
            let farRT = new Vector3().copyFrom(f3).multiplyScalar(far).add(pos);

            let nearLB = new Vector3().copyFrom(f0).multiplyScalar(near).add(pos);
            let nearLT = new Vector3().copyFrom(f1).multiplyScalar(near).add(pos);
            let nearRB = new Vector3().copyFrom(f2).multiplyScalar(near).add(pos);
            let nearRT = new Vector3().copyFrom(f3).multiplyScalar(near).add(pos);

            let custom = this.createCustomShape(`CameraFrustum_${camera.object3D.instanceID}`);
            custom.buildLines([nearLT, farLT], color);
            custom.buildLines([nearLB, farLB], color);
            custom.buildLines([nearRT, farRT], color);
            custom.buildLines([nearRB, farRB], color);
            custom.buildLines([farLT, farRT, farRB, farLB, farLT], color);
            custom.buildLines([nearLT, nearRT, nearRB, nearLB, nearLT], color);
        } else if (camera.type == CameraType.ortho) {
            camera.viewPort;
            camera.viewPort.height;
            let worldMatrix = camera.transform.worldMatrix;
            let farLT = worldMatrix.transformVector(new Vector3(camera.viewPort.width * -0.5, camera.viewPort.height * 0.5, camera.far));
            let farLB = worldMatrix.transformVector(new Vector3(camera.viewPort.width * -0.5, camera.viewPort.height * -0.5, camera.far));
            let farRT = worldMatrix.transformVector(new Vector3(camera.viewPort.width * 0.5, camera.viewPort.height * 0.5, camera.far));
            let farRB = worldMatrix.transformVector(new Vector3(camera.viewPort.width * 0.5, camera.viewPort.height * -0.5, camera.far));

            let nearLT = worldMatrix.transformVector(new Vector3(camera.viewPort.width * -0.5, camera.viewPort.height * 0.5, camera.near));
            let nearLB = worldMatrix.transformVector(new Vector3(camera.viewPort.width * -0.5, camera.viewPort.height * -0.5, camera.near));
            let nearRT = worldMatrix.transformVector(new Vector3(camera.viewPort.width * 0.5, camera.viewPort.height * 0.5, camera.near));
            let nearRB = worldMatrix.transformVector(new Vector3(camera.viewPort.width * 0.5, camera.viewPort.height * -0.5, camera.near));

            let custom = this.createCustomShape(`CameraFrustum_${camera.object3D.instanceID}`);
            custom.buildLines([nearLT, farLT], color);
            custom.buildLines([nearLB, farLB], color);
            custom.buildLines([nearRT, farRT], color);
            custom.buildLines([nearRB, farRB], color);
            custom.buildLines([farLT, farRT, farRB, farLB, farLT], color);
            custom.buildLines([nearLT, nearRT, nearRB, nearLB, nearLT], color);
        }
    }

/**
     * Draw the camera cone
     * @param camera The camera to display the cone
     * @param color The color of the camera cone
     */


public enableSpring(index: number, onOff: boolean): void {
        if (this._constraint) {
            this._constraint.enableSpring(index, onOff);
        } else {
            this._springParams.push({ index, onOff });
        }
    }

/**
     * 启用或禁用弹簧功能。
     * @param index 弹簧的索引
     * @param onOff 是否启用
     */


public set enable(value: boolean) {
        if (this._enable === value) return;
        this._enable = value;
        value ? this.registerEvents() : this.unregisterEvents();
    }

/**
     * 是否启用拖拽功能
     */


public set target(val: Object3D | null) {
        if (this._target == val) return;
        this._target = val;
    }

/**
     *
     * Set the control object3D
     * @param val Object3D
     */


public get lightColor(): Color {
        return this.lightData.lightColor;
    }

/**
     * Get light source color
     * @return Color
     */


public get radius(): number {
        return this.lightData.radius as number;
    }

/**
     *
     * Get the radius of the light source
     * @return number
     */


public notifyChange(): void {
        this.transform.notifyChange();
    }

/**
     * Notify transformation attribute updates
     */


public set rotationY(value: number) {
        this.transform.rotationY = value;
    }

/**
     *
     * Set the y rotation relative to the local coordinates of the parent container.
     */


public get topology(): GPUPrimitiveTopology {
        return this.shaderState.topology;
    }


public pause() {
        this.pauseRender = true;
    }


public get baseColor() {
        return this.shader.getUniformColor("baseColor");
    }

/**
     * get base color (tint color)
     */


public prepend(a: number, b: number, c: number, d: number, tx: number, ty: number): Matrix3 {
        let tx1 = this.tx;
        if (a != 1 || b != 0 || c != 0 || d != 1) {
            let a1 = this.a;
            let c1 = this.c;
            this.a = a1 * a + this.b * c;
            this.b = a1 * b + this.b * d;
            this.c = c1 * a + this.d * c;
            this.d = c1 * b + this.d * d;
        }
        this.tx = tx1 * a + this.ty * c + tx;
        this.ty = tx1 * b + this.ty * d + ty;
        return this;
    }

/**
     * get a front matrix by multiplication
     * @param a Multiply by a
     * @param b Multiply by b
     * @param c Multiply by c
     * @param d Multiply by d
     * @param tx Multiply by tx
     * @param ty Multiply by ty
     * @returns prematrix
     */


public decompose(orientationStyle: string = 'eulerAngles', target?: Vector3[]): Vector3[] {
        let q: Quaternion = Quaternion.CALCULATION_QUATERNION;
        let vec: Vector3[] = target ? target : Matrix4._prs;
        this.copyRawDataTo(Matrix4.decomposeRawData);
        let mr = Matrix4.decomposeRawData;

        let pos: Vector3 = vec[0];
        pos.x = mr[12];
        pos.y = mr[13];
        pos.z = mr[14];
        mr[12] = 0;
        mr[13] = 0;
        mr[14] = 0;

        let scale: Vector3 = vec[2];

        scale.x = Math.sqrt(mr[0] * mr[0] + mr[1] * mr[1] + mr[2] * mr[2]);
        scale.y = Math.sqrt(mr[4] * mr[4] + mr[5] * mr[5] + mr[6] * mr[6]);
        scale.z = Math.sqrt(mr[8] * mr[8] + mr[9] * mr[9] + mr[10] * mr[10]);

        if (mr[0] * (mr[5] * mr[10] - mr[6] * mr[9])
            - mr[1] * (mr[4] * mr[10] - mr[6] * mr[8])
            + mr[2] * (mr[4] * mr[9] - mr[5] * mr[8]) < 0) {
            scale.z = -scale.z;
        }

        mr[0] /= scale.x;
        mr[1] /= scale.x;
        mr[2] /= scale.x;
        mr[4] /= scale.y;
        mr[5] /= scale.y;
        mr[6] /= scale.y;
        mr[8] /= scale.z;
        mr[9] /= scale.z;
        mr[10] /= scale.z;

        let rot = vec[1];
        let tr: number;
        switch (orientationStyle) {
            case Orientation3D.AXIS_ANGLE:
                rot.w = Math.acos((mr[0] + mr[5] + mr[10] - 1) / 2);

                let len: number = Math.sqrt((mr[6] - mr[9]) * (mr[6] - mr[9]) + (mr[8] - mr[2]) * (mr[8] - mr[2]) + (mr[1] - mr[4]) * (mr[1] - mr[4]));
                rot.x = (mr[6] - mr[9]) / len;
                rot.y = (mr[8] - mr[2]) / len;
                rot.z = (mr[1] - mr[4]) / len;

                break;
            case Orientation3D.QUATERNION:
                tr = mr[0] + mr[5] + mr[10];

                if (tr > 0) {
                    rot.w = Math.sqrt(1 + tr) / 2;

                    rot.x = (mr[6] - mr[9]) / (4 * rot.w);
                    rot.y = (mr[8] - mr[2]) / (4 * rot.w);
                    rot.z = (mr[1] - mr[4]) / (4 * rot.w);
                } else if (mr[0] > mr[5] && mr[0] > mr[10]) {
                    rot.x = Math.sqrt(1 + mr[0] - mr[5] - mr[10]) / 2;

                    rot.w = (mr[6] - mr[9]) / (4 * rot.x);
                    rot.y = (mr[1] + mr[4]) / (4 * rot.x);
                    rot.z = (mr[8] + mr[2]) / (4 * rot.x);
                } else if (mr[5] > mr[10]) {
                    rot.y = Math.sqrt(1 + mr[5] - mr[0] - mr[10]) / 2;

                    rot.x = (mr[1] + mr[4]) / (4 * rot.y);
                    rot.w = (mr[8] - mr[2]) / (4 * rot.y);
                    rot.z = (mr[6] + mr[9]) / (4 * rot.y);
                } else {
                    rot.z = Math.sqrt(1 + mr[10] - mr[0] - mr[5]) / 2;

                    rot.x = (mr[8] + mr[2]) / (4 * rot.z);
                    rot.y = (mr[6] + mr[9]) / (4 * rot.z);
                    rot.w = (mr[1] - mr[4]) / (4 * rot.z);
                }

                break;
            case Orientation3D.EULER_ANGLES:
                tr = mr[0] + mr[5] + mr[10];

                if (tr > 0) {
                    q.w = Math.sqrt(1 + tr) / 2;

                    q.x = (mr[6] - mr[9]) / (4 * q.w);
                    q.y = (mr[8] - mr[2]) / (4 * q.w);
                    q.z = (mr[1] - mr[4]) / (4 * q.w);
                } else if (mr[0] > mr[5] && mr[0] > mr[10]) {
                    q.x = Math.sqrt(1 + mr[0] - mr[5] - mr[10]) / 2;

                    q.w = (mr[6] - mr[9]) / (4 * q.x);
                    q.y = (mr[1] + mr[4]) / (4 * q.x);
                    q.z = (mr[8] + mr[2]) / (4 * q.x);
                } else if (mr[5] > mr[10]) {
                    rot.y = Math.sqrt(1 + mr[5] - mr[0] - mr[10]) / 2;

                    q.x = (mr[1] + mr[4]) / (4 * q.y);
                    q.w = (mr[8] - mr[2]) / (4 * q.y);
                    q.z = (mr[6] + mr[9]) / (4 * q.y);
                } else {
                    q.z = Math.sqrt(1 + mr[10] - mr[0] - mr[5]) / 2;

                    q.x = (mr[8] + mr[2]) / (4 * q.z);
                    q.y = (mr[6] + mr[9]) / (4 * q.z);
                    q.w = (mr[1] - mr[4]) / (4 * q.z);
                }
                q.getEulerAngles(rot);

                break;
        }

        vec[0] = pos;
        vec[1] = rot;
        vec[2] = scale;

        return vec;
    }

/**
     * Decompose the current matrix
     * @param orientationStyle The default decomposition type is Orientation3D.EULER_ANGLES
     * @see Orientation3D.AXIS_ANGLE
     * @see Orientation3D.EULER_ANGLES
     * @see Orientation3D.QUATERNION
     * @returns Vector3[3] pos rot scale
     */


public makeBasis(xAxis: Vector3, yAxis: Vector3, zAxis: Vector3) {
        this.setElements(
            xAxis.x, yAxis.x, zAxis.x, 0,
            xAxis.y, yAxis.y, zAxis.y, 0,
            xAxis.z, yAxis.z, zAxis.z, 0,
            0, 0, 0, 1
        );
        return this;
    }

/**
     * Generate the matrix according to the three axes
     * @param xAxis
     * @param yAxis
     * @param zAxis
     */


public static identity() {
        return Quaternion._zero;
    }

/**
     * Identity quaternion
     * @returns
     */


public sqrDistToPoint(P: Vector3): number {
        let v = this._dir;
        let w = P.subtract(this.origin);

        let c1 = dot(w, v);
        let c2 = dot(v, v);
        let b = c1 / c2;

        let Pb = this.getPoint(b);
        return sqrMagnitude(P.subtract(Pb));
    }

/**
     * Calculate the distance from a point
     * @param P Specify Point
     * @returns result
     */


private generateMipmap(texture: Texture) {
        let mipmap: number = 1;
        while (mipmap < this._texture.mipmapCount) {
            this.generateMipmapAtLevel(mipmap, texture);
            mipmap++;
        }
    }

/**
     * @private generateMipmap
     * @param texture texture reference
     */


private byTags(filter: NDKFilter, subscription: NDKSubscription): boolean {
        const tagFilters = Object.entries(filter)
            .filter(([filter]) => filter.startsWith("#") && filter.length === 2)
            .map(([filter, values]) => [filter[1], values]);
        if (tagFilters.length === 0) return false;

        // Go through all the tags (#e, #p, etc)
        for (const [tag, values] of tagFilters) {
            // Go throgh each value in the filter
            for (const value of values as string[]) {
                const tagValue = tag + value;

                // Get all events with this tag
                const eventIds = this.eventTags.getSet(tagValue);
                if (!eventIds) continue;

                // Go through each event that came back
                eventIds.forEach((id) => {
                    const event = this.events.get(id);
                    if (!event) return;

                    if (!filter.kinds || filter.kinds.includes(event.kind!)) {
                        foundEvent(subscription, event, event.relay, filter);
                    }
                });
            }
        }

        return true;
    }

/**
     * Searches by tags and optionally filters by tags
     */


private cleanProof(proof: Proof): Proof {
        return {
            id: proof.id,
            amount: proof.amount,
            C: proof.C,
            secret: proof.secret
        };
    }

/**
     * Returns a minimal proof object with only essential properties
     */


findAll() {
    return this.levelRepository.find();
  }

/* 不分页查询所有家长引导 */


public get ruleNames(): string[] { return SolidityParser.ruleNames; }


public customErrorDefinition(): CustomErrorDefinitionContext {
		let _localctx: CustomErrorDefinitionContext = new CustomErrorDefinitionContext(this._ctx, this.state);
		this.enterRule(_localctx, 30, SolidityParser.RULE_customErrorDefinition);
		try {
			this.enterOuterAlt(_localctx, 1);
			{
			this.state = 364;
			this.match(SolidityParser.T__24);
			this.state = 365;
			this.identifier();
			this.state = 366;
			this.parameterList();
			this.state = 367;
			this.match(SolidityParser.T__1);
			}
		}
		catch (re) {
			if (re instanceof RecognitionException) {
				_localctx.exception = re;
				this._errHandler.reportError(this, re);
				this._errHandler.recover(this, re);
			} else {
				throw re;
			}
		}
		finally {
			this.exitRule();
		}
		return _localctx;
	}


public assemblyFunctionDefinition(): AssemblyFunctionDefinitionContext {
		let _localctx: AssemblyFunctionDefinitionContext = new AssemblyFunctionDefinitionContext(this._ctx, this.state);
		this.enterRule(_localctx, 176, SolidityParser.RULE_assemblyFunctionDefinition);
		let _la: number;
		try {
			this.enterOuterAlt(_localctx, 1);
			{
			this.state = 1061;
			this.match(SolidityParser.T__29);
			this.state = 1062;
			this.identifier();
			this.state = 1063;
			this.match(SolidityParser.T__22);
			this.state = 1065;
			this._errHandler.sync(this);
			_la = this._input.LA(1);
			if (_la === SolidityParser.T__13 || _la === SolidityParser.T__24 || ((((_la - 36)) & ~0x1F) === 0 && ((1 << (_la - 36)) & ((1 << (SolidityParser.T__35 - 36)) | (1 << (SolidityParser.T__41 - 36)) | (1 << (SolidityParser.T__53 - 36)))) !== 0) || ((((_la - 95)) & ~0x1F) === 0 && ((1 << (_la - 95)) & ((1 << (SolidityParser.T__94 - 95)) | (1 << (SolidityParser.LeaveKeyword - 95)) | (1 << (SolidityParser.PayableKeyword - 95)) | (1 << (SolidityParser.ConstructorKeyword - 95)))) !== 0) || _la === SolidityParser.ReceiveKeyword || _la === SolidityParser.Identifier) {
				{
				this.state = 1064;
				this.assemblyIdentifierList();
				}
			}

			this.state = 1067;
			this.match(SolidityParser.T__23);
			this.state = 1069;
			this._errHandler.sync(this);
			_la = this._input.LA(1);
			if (_la === SolidityParser.T__93) {
				{
				this.state = 1068;
				this.assemblyFunctionReturns();
				}
			}

			this.state = 1071;
			this.assemblyBlock();
			}
		}
		catch (re) {
			if (re instanceof RecognitionException) {
				_localctx.exception = re;
				this._errHandler.reportError(this, re);
				this._errHandler.recover(this, re);
			} else {
				throw re;
			}
		}
		finally {
			this.exitRule();
		}
		return _localctx;
	}


public accept<Result>(visitor: SolidityVisitor<Result>): Result {
		if (visitor.visitIdentifierList) {
			return visitor.visitIdentifierList(this);
		} else {
			return visitor.visitChildren(this);
		}
	}


public enterRule(listener: SolidityListener): void {
		if (listener.enterInlineAssemblyStatement) {
			listener.enterInlineAssemblyStatement(this);
		}
	}


public accept<Result>(visitor: SolidityVisitor<Result>): Result {
		if (visitor.visitAssemblyCase) {
			return visitor.visitAssemblyCase(this);
		} else {
			return visitor.visitChildren(this);
		}
	}


isZero(): boolean {
    return this.equals(Address.zero())
  }


private _hardhatSetPrevRandaoParams(params: any[]): [Buffer] {
    // using rpcHash because it's also 32 bytes long
    return validateParams(params, rpcHash);
  }


function B2B_G(
  v: Uint32Array,
  mw: Uint32Array,
  a: number,
  b: number,
  c: number,
  d: number,
  ix: number,
  iy: number
) {
  const x0 = mw[ix]
  const x1 = mw[ix + 1]
  const y0 = mw[iy]
  const y1 = mw[iy + 1]

  ADD64AA(v, a, b) // v[a,a+1] += v[b,b+1] ... in JS we must store a uint64 as two uint32s
  ADD64AC(v, a, x0, x1) // v[a, a+1] += x ... x0 is the low 32 bits of x, x1 is the high 32 bits

  // v[d,d+1] = (v[d,d+1] xor v[a,a+1]) rotated to the right by 32 bits
  let xor0 = v[d] ^ v[a]
  let xor1 = v[d + 1] ^ v[a + 1]
  v[d] = xor1
  v[d + 1] = xor0

  ADD64AA(v, c, d)

  // v[b,b+1] = (v[b,b+1] xor v[c,c+1]) rotated right by 24 bits
  xor0 = v[b] ^ v[c]
  xor1 = v[b + 1] ^ v[c + 1]
  v[b] = (xor0 >>> 24) ^ (xor1 << 8)
  v[b + 1] = (xor1 >>> 24) ^ (xor0 << 8)

  ADD64AA(v, a, b)
  ADD64AC(v, a, y0, y1)

  // v[d,d+1] = (v[d,d+1] xor v[a,a+1]) rotated right by 16 bits
  xor0 = v[d] ^ v[a]
  xor1 = v[d + 1] ^ v[a + 1]
  v[d] = (xor0 >>> 16) ^ (xor1 << 16)
  v[d + 1] = (xor1 >>> 16) ^ (xor0 << 16)

  ADD64AA(v, c, d)

  // v[b,b+1] = (v[b,b+1] xor v[c,c+1]) rotated right by 63 bits
  xor0 = v[b] ^ v[c]
  xor1 = v[b + 1] ^ v[c + 1]
  v[b] = (xor1 >>> 31) ^ (xor0 << 1)
  v[b + 1] = (xor0 >>> 31) ^ (xor1 << 1)
}


function safeSlice(input: Uint8Array, start: number, end: number) {
  if (end > input.length) {
    throw new Error('invalid RLP (safeSlice): end slice of Uint8Array out-of-bounds')
  }
  return input.slice(start, end)
}

/**
 * Slices a Uint8Array, throws if the slice goes out-of-bounds of the Uint8Array.
 * E.g. `safeSlice(hexToBytes('aa'), 1, 2)` will throw.
 * @param input
 * @param start
 * @param end
 */


const updateMarkCount = (markList: MarkItemType[]) => {
    markList.forEach((mark: MarkItemType) => {
      const { msgId, markType, markCount } = mark

      const msgItem = currentMessageMap.value?.get(msgId)
      if (msgItem) {
        if (markType === MarkEnum.LIKE) {
          msgItem.message.messageMark.likeCount = markCount
        } else if (markType === MarkEnum.DISLIKE) {
          msgItem.message.messageMark.dislikeCount = markCount
        }
      }
    })
  }


async getBill(): Promise<OutputOptions> {
    // throw new Error('Method not implemented.');
    return output({ code: 0, data: null });
  }


const csrf = async () => {
  /**
   * 1，验证referer
   * 2，验证origin
   */
};

// import { ParameterizedContext } from 'koa';


public static getConceptModels(
        namespace: string,
        conceptName: string,
    ): CancelablePromise<Array<ConceptModelInfo>> {
        return __request(OpenAPI, {
            method: 'GET',
            url: '/api/v1/concepts/{namespace}/{concept_name}/model',
            path: {
                'namespace': namespace,
                'concept_name': conceptName,
            },
            errors: {
                422: `Validation Error`,
            },
        });
    }

/**
     * Get Concept Models
     * Get a concept model from a database.
     * @param namespace
     * @param conceptName
     * @returns ConceptModelInfo Successful Response
     * @throws ApiError
     */


public node(node: M['NodeOrId']): NodeModel<M, V> {
    const nodeId = getId(node)
    return nonNullable(this.#nodes.get(nodeId), `Node ${nodeId} not found in view ${this.$view.id}`)
  }

/**
   * Get node by id.
   * @throws Error if node is not found.
   */


const printEdge = (edge: ComputedEdge): CompositeGeneratorNode => {
    return new CompositeGeneratorNode().append(
      names.get(edge.source),
      ' -.',
      edge.label ? ' "' + edge.label.replaceAll('\n', '\\n') + '" .-' : '-',
      '> ',
      names.get(edge.target)
    )
  }

//     return `${names.get(edge.source)} -> ${names.get(edge.target)}${edge.label ? ': ' + edge.label : ''}`


private uniqueDescedants(of: () => ast.Element | undefined): Stream<AstNodeDescription> {
    return new StreamImpl(
      () => {
        const element = of()
        const fqn = element && this.fqnIndex.getFqn(element)
        if (fqn) {
          return this.fqnIndex.uniqueDescedants(fqn).iterator()
        }
        return null
      },
      iterator => {
        if (iterator) {
          return iterator.next()
        }
        return DONE_RESULT
      },
    )
  }


public get camera(): Nullable<MmdCamera> {
        return this._camera;
    }


public static Create(animation: MmdWasmAnimation, model: MmdWasmModel, onDispose: () => void, retargetingMap?: { [key: string]: string }, logger?: ILogger): MmdWasmRuntimeModelAnimation {
        const wasmInstance = animation._poolWrapper.instance;
        const animationPool = animation._poolWrapper.pool;

        const skeleton = model.skeleton;
        const bones = skeleton.bones;

        const boneIndexMap = new Map<string, number>();
        if (retargetingMap === undefined) {
            for (let i = 0; i < bones.length; ++i) {
                boneIndexMap.set(bones[i].name, i);
            }
        } else {
            for (let i = 0; i < bones.length; ++i) {
                boneIndexMap.set(retargetingMap[bones[i].name] ?? bones[i].name, i);
            }
        }

        const boneBindIndexMapPtr = animationPool.createBoneBindIndexMap(animation.ptr);
        const boneBindIndexMap = wasmInstance.createTypedArray(Int32Array, boneBindIndexMapPtr, animation.boneTracks.length);
        {
            const boneTracks = animation.boneTracks;
            const boneBindIndexMapArray = boneBindIndexMap.array;
            for (let i = 0; i < boneTracks.length; ++i) {
                const boneTrack = boneTracks[i];
                const boneIndex = boneIndexMap.get(boneTrack.name);
                if (boneIndex === undefined) {
                    logger?.warn(`Binding failed: bone ${boneTrack.name} not found`);
                    boneBindIndexMapArray[i] = -1;
                } else {
                    boneBindIndexMapArray[i] = boneIndex;
                }
            }
        }

        const movableBoneBindIndexMapPtr = animationPool.createMovableBoneBindIndexMap(animation.ptr);
        const movableBoneBindIndexMap = wasmInstance.createTypedArray(Int32Array, movableBoneBindIndexMapPtr, animation.movableBoneTracks.length);
        {
            const movableBoneBindIndexMapArray = movableBoneBindIndexMap.array;
            const movableBoneTracks = animation.movableBoneTracks;
            for (let i = 0; i < movableBoneTracks.length; ++i) {
                const movableBoneTrack = movableBoneTracks[i];
                const boneIndex = boneIndexMap.get(movableBoneTrack.name);
                if (boneIndex === undefined) {
                    logger?.warn(`Binding failed: bone ${movableBoneTrack.name} not found`);
                    movableBoneBindIndexMapArray[i] = -1;
                } else {
                    movableBoneBindIndexMapArray[i] = boneIndex;
                }
            }
        }

        const morphBindIndexMap: Nullable<MorphIndices>[] = new Array(animation.morphTracks.length);
        const morphController = model.morph;
        const morphTracks = animation.morphTracks;
        for (let i = 0; i < morphTracks.length; ++i) {
            const morphTrack = morphTracks[i];
            const mappedName = retargetingMap?.[morphTrack.name] ?? morphTrack.name;
            const morphIndices = morphController.getMorphIndices(mappedName);
            if (morphIndices === undefined) {
                logger?.warn(`Binding failed: morph ${mappedName} not found`);
                morphBindIndexMap[i] = null;
            } else {
                morphBindIndexMap[i] = morphIndices;
            }
        }

        const morphLengthBufferPtr = animationPool.allocateLengthsBuffer(morphTracks.length);
        const morphLengthBuffer = wasmInstance.createTypedArray(Uint32Array, morphLengthBufferPtr, morphTracks.length);
        {
            const morphLengthBufferArray = morphLengthBuffer.array;
            const wasmMorphIndexMap = morphController.wasmMorphIndexMap;
            for (let i = 0; i < morphTracks.length; ++i) {
                let indicesCount = 0;
                const morphIndices = morphBindIndexMap[i];
                if (morphIndices !== null) {
                    for (let j = 0; j < morphIndices.length; ++j) {
                        const remappedIndex = wasmMorphIndexMap[morphIndices[j]];
                        if (remappedIndex !== undefined && remappedIndex !== -1) indicesCount += 1;
                    }
                }
                morphLengthBufferArray[i] = indicesCount;
            }
        }
        const morphBindIndexMapPtr = animationPool.createMorphBindIndexMap(animation.ptr, morphLengthBufferPtr);
        {
            const wasmMorphIndexMap = morphController.wasmMorphIndexMap;
            for (let i = 0; i < morphTracks.length; ++i) {
                const nthMorphIndicesPtr = animationPool.getNthMorphBindIndexMap(morphBindIndexMapPtr, i);
                const nthMorphIndices = wasmInstance.createTypedArray(Int32Array, nthMorphIndicesPtr, morphLengthBuffer.array[i]).array;

                let indicesCount = 0;
                const morphIndices = morphBindIndexMap[i];
                if (morphIndices !== null) {
                    for (let j = 0; j < morphIndices.length; ++j) {
                        const remappedIndex = wasmMorphIndexMap[morphIndices[j]];
                        if (remappedIndex !== undefined && remappedIndex !== -1) {
                            nthMorphIndices[indicesCount] = remappedIndex;
                            indicesCount += 1;
                        }
                    }
                }
            }
        }
        animationPool.deallocateLengthsBuffer(morphLengthBufferPtr, morphTracks.length);

        const ikSolverBindIndexMapPtr = animationPool.createIkSolverBindIndexMap(animation.ptr);
        const ikSolverBindIndexMap = wasmInstance.createTypedArray(Int32Array, ikSolverBindIndexMapPtr, animation.propertyTrack.ikBoneNames.length);
        {
            const ikSolverBindIndexMapArray = ikSolverBindIndexMap.array;
            const runtimeBones = model.runtimeBones;
            const propertyTrackIkBoneNames = animation.propertyTrack.ikBoneNames;
            for (let i = 0; i < propertyTrackIkBoneNames.length; ++i) {
                const ikBoneName = propertyTrackIkBoneNames[i];
                const ikBoneIndex = boneIndexMap.get(ikBoneName);
                if (ikBoneIndex === undefined) {
                    logger?.warn(`Binding failed: IK bone ${ikBoneName} not found`);
                    ikSolverBindIndexMapArray[i] = -1;
                } else {
                    const ikSolverIndex = runtimeBones[ikBoneIndex].ikSolverIndex;
                    if (ikSolverIndex === -1) {
                        logger?.warn(`Binding failed: IK solver for bone ${ikBoneName} not found`);
                        ikSolverBindIndexMapArray[i] = -1;
                    } else {
                        ikSolverBindIndexMapArray[i] = ikSolverIndex;
                    }
                }
            }
        }

        const runtimeAnimationPtr = animationPool.createRuntimeAnimation(
            animation.ptr,
            boneBindIndexMapPtr,
            movableBoneBindIndexMapPtr,
            morphBindIndexMapPtr,
            ikSolverBindIndexMapPtr
        );

        return new MmdWasmRuntimeModelAnimation(
            runtimeAnimationPtr,
            model.ptr,
            animation,
            boneBindIndexMap,
            movableBoneBindIndexMap,
            morphController,
            morphBindIndexMap,
            model.mesh.metadata.meshes,
            ikSolverBindIndexMap,
            model.mesh.metadata.materials,
            onDispose
        );
    }

/**
     * @internal
     * Bind animation to model and prepare material for morph animation
     * @param animation Animation to bind
     * @param model Bind target
     * @param onDispose Callback when this instance is disposed
     * @param retargetingMap Animation bone name to model bone name map
     * @param logger Logger
     * @return MmdRuntimeModelAnimation instance
     */


verifyToken(token: string): JWTObject {
    return jwt.verify(token, this.configuration.secret) as JWTObject;
  }


function entriesApi(
      items: DataTransferItemList,
      cb: (files?: File[], paths?: string[]) => void,
    ) {
      const fd: any[] = [],
        files: any[] = [],
        rootPromises: any[] = [];

      function readEntries(entry: any, reader: any, oldEntries: any, cb: any) {
        const dirReader = reader || entry.createReader();
        dirReader.readEntries(function (entries: any) {
          const newEntries = oldEntries ? oldEntries.concat(entries) : entries;
          if (entries.length) {
            setTimeout(readEntries.bind(null, entry, dirReader, newEntries, cb), 0);
          } else {
            cb(newEntries);
          }
        });
      }

      function readDirectory(entry: any, path: null | string, resolve: (v: any) => void) {
        if (!path) path = entry.name;
        readEntries(entry, 0, 0, function (entries: any[]) {
          const promises: Promise<any>[] = [];
          entries.forEach(function (entry: any) {
            promises.push(
              new Promise(function (resolve) {
                if (entry.isFile) {
                  entry.file(function (file: File) {
                    const p = path + '/' + file.name;
                    fd.push(file);
                    files.push(p);
                    if (files.length > 1000000) {
                      return false;
                    }
                    resolve(true);
                  }, resolve.bind(null, true));
                } else readDirectory(entry, path + '/' + entry.name, resolve);
              }),
            );
          });
          Promise.all(promises).then(resolve.bind(null, true));
        });
      }

      let timeBegin = Date.now();
      [].slice.call(items).forEach(function (entry: any) {
        entry = entry.webkitGetAsEntry();
        if (entry) {
          rootPromises.push(
            new Promise(function (resolve) {
              if (entry.isFile) {
                entry.file(function (file: File) {
                  fd.push(file);
                  files.push(file.name);
                  if (files.length > 1000000) {
                    return false;
                  }
                  resolve(true);
                }, resolve.bind(null, true));
              } else if (entry.isDirectory) {
                const timeToRead = Date.now();
                readDirectory(entry, null, resolve);
              }
            }),
          );
        }
      });

      if (files.length > 1000000) {
        return false;
      }

      timeBegin = Date.now();
      Promise.all(rootPromises).then(cb.bind(null, fd, files));
    }

// old drag and drop API implemented in Chrome 11+


public mount(path: string, other: Server) {
        hpx.hpxServerMount(this.serverId, path, other.serverId);
    }

/**
    * Defines a WebSocket route on the server.
     * @param {string} path - The route path.
     * @param {(wsClient: WebSocketClient) => any} callback -
     *        The callback function to handle WebSocket connections.
     *
     * @example
     *  asdasdasdasdasdsa;
     *
     */


async updateVectors(
        collection_name: string,
        {
            wait = true,
            ordering,
            points,
            shard_key,
        }: {wait?: boolean; ordering?: SchemaFor<'WriteOrdering'>} & SchemaFor<'UpdateVectors'>,
    ) {
        const response = await this._openApiClient.points.updateVectors({
            collection_name,
            wait,
            ordering,
            points,
            shard_key,
        });
        return maybe(response.data.result).orThrow('Update vectors returned empty');
    }

/**
     * Update vectors
     * @param collection_name
     * @param {object} args
     *     - wait: Await for the results to be processed.
     *         - If `true`, result will be returned only when all changes are applied
     *         - If `false`, result will be returned immediately after the confirmation of receiving.
     *         - Default: `true`
     *     - ordering: Define strategy for ordering of the points. Possible values:
     *          - 'weak'   - write operations may be reordered, works faster, default
     *          - 'medium' - write operations go through dynamically selected leader,
     *                      may be inconsistent for a short period of time in case of leader change
     *          - 'strong' - Write operations go through the permanent leader,
     *                      consistent, but may be unavailable if leader is down
     *     - points: Points with named vectors
     *     - shard_key: Specify in which shards to look for the points, if not specified - look in all shards
     * @returns Operation result
     */


init(init_?: typeof this.init_data): void {
		// 不存在多语言则删除组件
		if (!mk.language_manage.label_data_tab[cc.js.getClassName(main_main)]?.[this.init_data.label_s]) {
			this.nodes.label.getComponent(mk.language.label)?.destroy();
		}

		Object.assign(this.data, this.init_data);
	}


clear(): void {
		for (const k_s in this._cache) {
			this._cache[k_s] = undefined!;
		}

		if (!this._init_config.name_s) {
			return;
		}

		Object.keys(this._init_config.data).forEach((v_s) => {
			const key_s = `${this._init_config.name_s}-${String(v_s)}`;

			this._write_pipeline.add(() => {
				cc.sys.localStorage.removeItem(key_s);
			});
		});
	}

/** 清空当前存储器数据 */


release(asset_: cc.Asset | cc.Asset[]): void {
		const asset_as: cc.Asset[] = Array.isArray(asset_) ? asset_ : [asset_];

		asset_as.forEach((v) => {
			if (!v.isValid) {
				return;
			}

			// 释放动态图集中的资源
			if (cc.dynamicAtlasManager?.enabled) {
				if (v instanceof cc.SpriteFrame) {
					cc.dynamicAtlasManager.deleteAtlasSpriteFrame(v);
				} else if (v instanceof cc.Texture2D) {
					cc.dynamicAtlasManager.deleteAtlasTexture(v);
				}
			}

			// 更新引用计数
			for (let k_n = 0; k_n < v.refCount; k_n++) {
				v.decRef(false);
			}

			// 释放资源，禁止自动释放，否则会出现释放后立即加载当前资源导致加载返回资源是已释放后的
			cc.assetManager.releaseAsset(v);
			// 更新资源管理表
			this._asset_manage_map.delete(v.nativeUrl || v._uuid);

			this._log.debug("释放资源", v.name, v.nativeUrl, v._uuid);
		});
	}

/**
	 * 释放资源
	 * @param asset_ 释放的资源
	 */


function getTagToFindSuggestion(
	app: App,
	settings: AutoTimelineSettings,
	query: string
): string[] {
	const unfilteredRestults = app.vault
		.getMarkdownFiles()
		.reduce<string[]>((accumulator, file) => {
			const cachedMetadata = app.metadataCache.getFileCache(file);

			if (!cachedMetadata || !cachedMetadata.frontmatter)
				return accumulator;
			accumulator.push(
				...getTagsFromMetadataOrTagObject(
					settings,
					cachedMetadata.frontmatter,
					cachedMetadata.tags
				)
			);
			return accumulator;
		}, []);

	const allQueries = query.split(settings.markdownBlockTagsToFindSeparator);
	const currentQuery = allQueries[allQueries.length - 1];
	const allreadyUsedQueries = allQueries.slice(0, -1);

	return filterAndSortSuggestionResults(
		unfilteredRestults,
		currentQuery,
		allreadyUsedQueries
	);
}

/**
 * Given a query get all the `TagToFind` typed suggestions.
 * This will go trough every cached file and retrieve all timeline metadata + tags.
 *
 * @param app - The obsidian app object.
 * @param settings - The plugin settings.
 * @param query - The query that the user just typed.
 * @returns the suggestions set.
 */


protected async _call(
        arg: z.infer<typeof this.schema>,
        _?: CallbackManagerForToolRun,
        flowConfig?: { sessionId?: string; chatId?: string; input?: string }
    ): Promise<string> {
        const inputQuestion = this.input || arg.input

        const body = {
            question: inputQuestion,
            chatId: this.startNewSession ? uuidv4() : flowConfig?.chatId,
            overrideConfig: {
                sessionId: this.startNewSession ? uuidv4() : flowConfig?.sessionId,
                ...(this.overrideConfig ?? {}),
                ...(arg.overrideConfig ?? {})
            }
        }

        const options = {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                ...this.headers
            },
            body: JSON.stringify(body)
        }

        let sandbox = {
            $callOptions: options,
            $callBody: body,
            util: undefined,
            Symbol: undefined,
            child_process: undefined,
            fs: undefined,
            process: undefined
        }

        const code = `
const fetch = require('node-fetch');
const url = "${this.baseURL}/api/v1/prediction/${this.chatflowid}";

const body = $callBody;

const options = $callOptions;

try {
	const response = await fetch(url, options);
	const resp = await response.json();
	return resp.text;
} catch (error) {
	console.error(error);
	return '';
}
`
        const builtinDeps = process.env.TOOL_FUNCTION_BUILTIN_DEP
            ? defaultAllowBuiltInDep.concat(process.env.TOOL_FUNCTION_BUILTIN_DEP.split(','))
            : defaultAllowBuiltInDep
        const externalDeps = process.env.TOOL_FUNCTION_EXTERNAL_DEP ? process.env.TOOL_FUNCTION_EXTERNAL_DEP.split(',') : []
        const deps = availableDependencies.concat(externalDeps)

        const vmOptions = {
            console: 'inherit',
            sandbox,
            require: {
                external: { modules: deps },
                builtin: builtinDeps
            },
            eval: false,
            wasm: false,
            timeout: 10000
        } as any

        const vm = new NodeVM(vmOptions)
        const response = await vm.run(`module.exports = async function() {${code}}()`, __dirname)

        return response
    }


const currentAgentMeta = (s: SessionStore): MetaData => {
  const isInbox = sessionSelectors.isInboxSession(s);

  const defaultMeta = {
    avatar: isInbox ? DEFAULT_INBOX_AVATAR : DEFAULT_AVATAR,
    backgroundColor: DEFAULT_BACKGROUND_COLOR,
    description: isInbox
      ? t('inbox.desc', { ns: 'chat' })
      : currentAgentSystemRole(s) || t('noDescription'),
    title: isInbox ? t('inbox.title', { ns: 'chat' }) : t('defaultSession'),
  };

  const session = sessionSelectors.currentSession(s);

  return merge(defaultMeta, session?.meta);
};


private fillExecutedBddStep(bddStep: BddStepData, possiblePwSteps: pw.TestStep[]) {
    const pwStep = this.findPlaywrightStep(possiblePwSteps, bddStep);
    if (pwStep?.error) {
      this.registerErrorStep(pwStep, pwStep.error);
    }
    if (this.isTimeouted() && pwStep && isUnknownDuration(pwStep)) {
      this.registerTimeoutedStep(pwStep);
    }
    if (pwStep?.parent && bddStep.isBg) {
      this.bgRoots.add(pwStep.parent);
    }
    if (pwStep) {
      this.attachmentMapper.populateStepAttachments(pwStep);
    }

    return { bddStep, pwStep };
  }


graphToPrompt(workflow: ComfyBoxWorkflow, tag: string | null = null): SerializedPrompt {
        return this.promptSerializer.serialize(workflow.graph, tag)
    }

/**
     * Converts the current graph workflow for sending to the API
     * @returns The workflow and node links
     */


function insertTemplate(template: SerializedComfyBoxTemplate, graph: LGraph, templateNodeIDToNode: Record<NodeID, LGraphNode>, container: ContainerLayout, childIndex: number): IDragItem {
        const idMapping: Record<DragItemID, DragItemID> = {};

        const getDragItemID = (id: DragItemID): DragItemID => {
            idMapping[id] ||= uuidv4();
            return idMapping[id];
        }

        // Ensure all IDs are unique, and rewrite node IDs in widgets to point
        // to newly created nodes
        for (const [id, entry] of Object.entries(template.layout.allItems)) {
            const newId = getDragItemID(id);
            template.layout.allItems[newId] = entry;
            entry.dragItem.id = newId;

            if (entry.parent)
                entry.parent = getDragItemID(entry.parent)
            entry.children = entry.children.map(getDragItemID);

            if (entry.dragItem.type === "widget") {
                entry.dragItem.nodeId = templateNodeIDToNode[entry.dragItem.nodeId].id;
            }
        }

        if (template.layout.root) {
            template.layout.root = getDragItemID(template.layout.root)

            // make sure the new root doesn't have a parent since that parent
            // was detached from the serialized layout and won't be found in
            // template.layout.allItems
            template.layout.allItems[template.layout.root].parent = null;
        }

        const raw = deserializeRaw(template.layout, graph);

        // merge the template's detached layout tree into this layout
        store.update(s => {
            s.allItems = { ...s.allItems, ...raw.allItems }
            s.allItemsByNode = { ...s.allItemsByNode, ...raw.allItemsByNode }
            return s;
        })

        moveItem(raw.root, container, childIndex);

        return raw.root
    }

/*
     * NOTE: Modifies the template in-place, be sure you cloned it beforehand!
     */


async handleChangeDirectory (uri: vscode.Uri): Promise<void> {
        this._telemetryLogger.logEvent({
            eventKey: 'ML_VS_CODE_ACTIONS',
            data: {
                action_type: 'changeDirectory',
                result: ''
            }
        });

        await this._terminalService.openTerminalOrBringToFront();

        try {
            await this._mvm.getReadyPromise();
        } catch (e) {
            return;
        }

        void this._mvm.feval('cd', 0, [uri.fsPath]);
    }

/**
     * Implements the MATLAB change directory action
     * @param uri The file path that MATLAB should "cd" to
     * @returns
     */


function _convertAgentStepToMessages(
    action: AgentAction | FunctionsAgentAction | ToolsAgentAction,
    observation: string
) {
    if (isToolsAgentAction(action) && action.toolCallId !== undefined) {
        const log = action.messageLog as BaseMessage[]
        if (observation.length < 1) {
            observation = `The tool ${action.tool} returned no output.`
        }
        return log.concat(
            new ToolMessage({
                content: observation,
                name: action.tool,
                tool_call_id: action.toolCallId
            })
        )
    } else if (
        isFunctionsAgentAction(action) &&
        action.messageLog !== undefined
    ) {
        return action.messageLog?.concat(
            new FunctionMessage(observation, action.tool)
        )
    } else {
        return [new AIMessage(action.log)]
    }
}


async configure() {
    const adapter = await navigator.gpu.requestAdapter();
    if (adapter === null) {
      throw new VisualizerError('Unable to request webgpu adapter');
    }

    this.device = await adapter.requestDevice();
    if (this.device === null) {
      throw new VisualizerError('Unable to get WebGPU device');
    }
  }

/**
   * @inheritDoc VisualizationBuilder.configure
   */


public static getNorthByPointAB(point_a: Point, point_b: Point): number {
		let point_c = new Point(point_a.lng, point_b.lat);
		let ab = this.getDistance(point_a, point_b);
		let bc = this.getDistance(point_b, point_c);
		// 0
		if (point_a.lng == point_b.lng && point_a.lat == point_b.lat) {
			return 0;
		}
		// 0 <= n <= 90
		if (point_a.lng <= point_b.lng && point_a.lat <= point_b.lat) {
			if (bc < ab) {
				let BAC = Math.asin(bc / ab);
				return this.radToDeg(BAC);
			} else {
				return 90;
			}
		}
		// 90 < n <= 180
		if (point_a.lng <= point_b.lng && point_a.lat > point_b.lat) {
			if (bc < ab) {
				let BAC = Math.asin(bc / ab);
				return 180 - this.radToDeg(BAC);
			} else {
				return 90;
			}
		}
		// 180 < n <= 270
		if (point_a.lng >= point_b.lng && point_a.lat >= point_b.lat) {
			if (bc < ab) {
				let BAC = Math.asin(bc / ab);
				return 180 + this.radToDeg(BAC);
			} else {
				return 270;
			}
		}
		// 270 < n <= 360
		if (point_a.lng >= point_b.lng && point_a.lat < point_b.lat) {
			if (bc < ab) {
				let BAC = Math.asin(bc / ab);
				return 360 - this.radToDeg(BAC);
			} else {
				return 270;
			}
		}
		return 0;
	}

/** 根据一点的经纬度求另一点与其相对的北向夹角 */


private async asyncGenerate() {
    await this.asyncInitChat();
    this.requestInProgress = true;
    const prompt = this.uiChatInput.value;
    if (prompt == "") {
      this.requestInProgress = false;
      return;
    }

    this.appendMessage("right", prompt);
    this.uiChatInput.value = "";
    this.uiChatInput.setAttribute("placeholder", "Generating...");

    this.appendMessage("left", "");
    this.chatHistory.push({ role: "user", content: prompt });

    try {
      let curMessage = "";
      let usage: webllm.CompletionUsage | undefined = undefined;
      const completion = await this.engine.chat.completions.create({
        stream: true,
        messages: this.chatHistory,
        stream_options: { include_usage: true },
      });
      // TODO(Charlie): Processing of � requires changes
      for await (const chunk of completion) {
        const curDelta = chunk.choices[0]?.delta.content;
        if (curDelta) {
          curMessage += curDelta;
        }
        this.updateLastMessage("left", curMessage);
        if (chunk.usage) {
          usage = chunk.usage;
        }
      }
      if (usage) {
        this.uiChatInfoLabel.innerHTML =
          `prompt_tokens: ${usage.prompt_tokens}, ` +
          `completion_tokens: ${usage.completion_tokens}, ` +
          `prefill: ${usage.extra.prefill_tokens_per_s.toFixed(4)} tokens/sec, ` +
          `decoding: ${usage.extra.decode_tokens_per_s.toFixed(4)} tokens/sec`;
      }
      const finalMessage = await this.engine.getMessage();
      this.updateLastMessage("left", finalMessage); // TODO: Remove this after � issue is fixed
      this.chatHistory.push({ role: "assistant", content: finalMessage });
    } catch (err) {
      this.appendMessage("error", "Generate error, " + err.toString());
      console.log(err.stack);
      await this.unloadChat();
    }
    this.uiChatInput.setAttribute("placeholder", "Enter your message...");
    this.requestInProgress = false;
  }


const resolveConstrainedBigint = (
  number: bigint,
  constraint: TypeConstraint<bigint>
) => {
  const min = constraint.min && constraint.min + BigInt(constraint.minExclusive ? 1 : 0)
  const max = constraint.max && constraint.max - BigInt(constraint.maxExclusive ? 1 : 0)

  let result: number | bigint = number

  if (min && number < min) {
    result = min
  }
  if (max && number > max) {
    result = max
  }

  return result
}


const createParameters = (
  type: "query" | "header" | "path",
  schema: Schema.Schema<any, any, any>,
  componentSchemaCallback: ComponentSchemaCallback
): Array<OpenApiTypes.OpenAPISpecParameter> => {
  return getPropertySignatures(type, schema.ast).map((ps) => {
    if (typeof ps.name !== "string") {
      throw new Error(`${type} parameter struct fields must be strings`)
    }

    const ast = (ps.type._tag === "Union" && ps.type.types.some(AST.isUndefinedKeyword)) ?
      AST.Union.make(
        ps.type.types.filter((ast) => !AST.isUndefinedKeyword(ast)),
        ps.type.annotations
      ) :
      ps.type

    const schema = Schema.make<unknown, unknown, never>(ast)

    const parameter: OpenApiTypes.OpenAPISpecParameter = {
      name: ps.name,
      in: type,
      schema: makeSchema(schema, componentSchemaCallback)
    }

    if (!ps.isOptional) {
      parameter["required"] = true
    }

    const description = AST.getDescriptionAnnotation(schema.ast)
    if (Option.isSome(description)) {
      parameter["description"] = description.value
    }

    return parameter
  })
}


function stopAudio(): void {
    // stop the audio playback
    currentAudio?.pause();
    currentAudio = null;

    // update audio playback state
    isPlaying = false;

    // clear the audioQueue
    audioQueue.length = 0;
  }

/**
   * stops audio playback, clears audio playback queue, and updates audio playback state
   */


public static getInstance(): MD5Hashing {
    if (!MD5Hashing.instance)
      MD5Hashing.instance = new MD5Hashing()

    return MD5Hashing.instance
  }


const getEnvProviderSsmParams = async ()
        : Promise<{ [key: string]: string; }> => {
        const params = (await Promise.all(
          paramKeys.map(async (paramKey): Promise<{ [key: string]: string; }> => {
            const val = await getPlatformAccountSSMParameterValue(paramKey, region, ctx.logger);
            return {
              [paramKey]: val
            };
          })
        )).reduce((acc, paramKeyValMap) => {
          const typedAcc: { [key: string]: string; } = acc;
          const key = Object.keys(paramKeyValMap)[0];
          return {
            ...typedAcc, [key]: paramKeyValMap[key]
          };
        }, {});

        return params;

      };

// Get a key/value map of SSM parameters


static inline void put_bits(limb_t *tab, limb_t len, slimb_t pos, limb_t val)
{
    limb_t i;
    int p;

    i = pos >> LIMB_LOG2_BITS;
    p = pos & (LIMB_BITS - 1);
    if (i < len)
        tab[i] |= val << p;
    if (p != 0) {
        i++;
        if (i < len) {
            tab[i] |= val >> (LIMB_BITS - p);
        }
    }
}


ZyanStatus ZyanBitsetPerformByteOperation(ZyanBitset* destination, const ZyanBitset* source,
    ZyanBitsetByteOperation operation)
{
    if (!destination || !source || !operation)
    {
        return ZYAN_STATUS_INVALID_ARGUMENT;
    }

    ZyanUSize s1;
    ZyanUSize s2;
    ZYAN_CHECK(ZyanVectorGetSize(&destination->bits, &s1));
    ZYAN_CHECK(ZyanVectorGetSize(&source->bits, &s2));

    const ZyanUSize min = ZYAN_MIN(s1, s2);
    for (ZyanUSize i = 0; i < min; ++i)
    {
        ZyanU8* v1;
        const ZyanU8* v2;
        ZYAN_CHECK(ZyanVectorGetPointerMutable(&destination->bits, i, (void**)&v1));
        ZYAN_CHECK(ZyanVectorGetPointer(&source->bits, i, (const void**)&v2));

        ZYAN_ASSERT(v1);
        ZYAN_ASSERT(v2);

        ZYAN_CHECK(operation(v1, v2));
    }

    return ZYAN_STATUS_SUCCESS;
}


static int eval_gbmd(acpi_handle handle, unsigned long *res)
{
	return eval_int(handle, "VPC0.GBMD", res);
}

//static int eval_qcho(acpi_handle handle, unsigned long *res)
//{
//	// \_SB.PCI0.LPC0.EC0.QCHO
//	return eval_int(handle, "QCHO", res);
//}


FRESULT f_sync (
	FIL* fp		/* Open file to be synced */
)
{
	FRESULT res;
	FATFS *fs;
	DWORD tm;
	BYTE *dir;

	res = validate(&fp->obj, &fs);	/* Check validity of the file object */
	if (res == FR_OK) {
		if (fp->flag & FA_MODIFIED) {	/* Is there any change to the file? */
#if !FF_FS_TINY
			if (fp->flag & FA_DIRTY) {	/* Write-back cached data if needed */
				if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) LEAVE_FF(fs, FR_DISK_ERR);
				fp->flag &= (BYTE)~FA_DIRTY;
			}
#endif
			/* Update the directory entry */
			tm = GET_FATTIME();				/* Modified time */
#if FF_FS_EXFAT
			if (fs->fs_type == FS_EXFAT) {
				res = fill_first_frag(&fp->obj);	/* Fill first fragment on the FAT if needed */
				if (res == FR_OK) {
					res = fill_last_frag(&fp->obj, fp->clust, 0xFFFFFFFF);	/* Fill last fragment on the FAT if needed */
				}
				if (res == FR_OK) {
					DIR dj;
					DEF_NAMBUF

					INIT_NAMBUF(fs);
					res = load_obj_xdir(&dj, &fp->obj);	/* Load directory entry block */
					if (res == FR_OK) {
						fs->dirbuf[XDIR_Attr] |= AM_ARC;				/* Set archive attribute to indicate that the file has been changed */
						fs->dirbuf[XDIR_GenFlags] = fp->obj.stat | 1;	/* Update file allocation information */
						st_dword(fs->dirbuf + XDIR_FstClus, fp->obj.sclust);		/* Update start cluster */
						st_qword(fs->dirbuf + XDIR_FileSize, fp->obj.objsize);		/* Update file size */
						st_qword(fs->dirbuf + XDIR_ValidFileSize, fp->obj.objsize);	/* (FatFs does not support Valid File Size feature) */
						st_dword(fs->dirbuf + XDIR_ModTime, tm);		/* Update modified time */
						fs->dirbuf[XDIR_ModTime10] = 0;
						st_dword(fs->dirbuf + XDIR_AccTime, 0);
						res = store_xdir(&dj);	/* Restore it to the directory */
						if (res == FR_OK) {
							res = sync_fs(fs);
							fp->flag &= (BYTE)~FA_MODIFIED;
						}
					}
					FREE_NAMBUF();
				}
			} else
#endif
			{
				res = move_window(fs, fp->dir_sect);
				if (res == FR_OK) {
					dir = fp->dir_ptr;
					dir[DIR_Attr] |= AM_ARC;						/* Set archive attribute to indicate that the file has been changed */
					st_clust(fp->obj.fs, dir, fp->obj.sclust);		/* Update file allocation information  */
					st_dword(dir + DIR_FileSize, (DWORD)fp->obj.objsize);	/* Update file size */
					st_dword(dir + DIR_ModTime, tm);				/* Update modified time */
					st_word(dir + DIR_LstAccDate, 0);
					fs->wflag = 1;
					res = sync_fs(fs);					/* Restore it to the directory */
					fp->flag &= (BYTE)~FA_MODIFIED;
				}
			}
		}
	}

	LEAVE_FF(fs, res);
}


static void putc_bfd (putbuff* pb, TCHAR c)
{
	UINT n;
	int i, nc;
#if FF_USE_LFN && FF_LFN_UNICODE
	WCHAR hs, wc;
#if FF_LFN_UNICODE == 2
	DWORD dc;
	const TCHAR* tp;
#endif
#endif

	if (FF_USE_STRFUNC == 2 && c == '\n') {	 /* LF -> CRLF conversion */
		putc_bfd(pb, '\r');
	}

	i = pb->idx;			/* Write index of pb->buf[] */
	if (i < 0) return;		/* In write error? */
	nc = pb->nchr;			/* Write unit counter */

#if FF_USE_LFN && FF_LFN_UNICODE
#if FF_LFN_UNICODE == 1		/* UTF-16 input */
	if (IsSurrogateH(c)) {	/* Is this a high-surrogate? */
		pb->hs = c; return;	/* Save it for next */
	}
	hs = pb->hs; pb->hs = 0;
	if (hs != 0) {			/* Is there a leading high-surrogate? */
		if (!IsSurrogateL(c)) hs = 0;	/* Discard high-surrogate if not a surrogate pair */
	} else {
		if (IsSurrogateL(c)) return;	/* Discard stray low-surrogate */
	}
	wc = c;
#elif FF_LFN_UNICODE == 2	/* UTF-8 input */
	for (;;) {
		if (pb->ct == 0) {	/* Out of multi-byte sequence? */
			pb->bs[pb->wi = 0] = (BYTE)c;	/* Save 1st byte */
			if ((BYTE)c < 0x80) break;					/* Single byte code? */
			if (((BYTE)c & 0xE0) == 0xC0) pb->ct = 1;	/* 2-byte sequence? */
			if (((BYTE)c & 0xF0) == 0xE0) pb->ct = 2;	/* 3-byte sequence? */
			if (((BYTE)c & 0xF8) == 0xF0) pb->ct = 3;	/* 4-byte sequence? */
			return;										/* Wrong leading byte (discard it) */
		} else {				/* In the multi-byte sequence */
			if (((BYTE)c & 0xC0) != 0x80) {	/* Broken sequence? */
				pb->ct = 0; continue;		/* Discard the sequense */
			}
			pb->bs[++pb->wi] = (BYTE)c;	/* Save the trailing byte */
			if (--pb->ct == 0) break;	/* End of the sequence? */
			return;
		}
	}
	tp = (const TCHAR*)pb->bs;
	dc = tchar2uni(&tp);			/* UTF-8 ==> UTF-16 */
	if (dc == 0xFFFFFFFF) return;	/* Wrong code? */
	hs = (WCHAR)(dc >> 16);
	wc = (WCHAR)dc;
#elif FF_LFN_UNICODE == 3	/* UTF-32 input */
	if (IsSurrogate(c) || c >= 0x110000) return;	/* Discard invalid code */
	if (c >= 0x10000) {		/* Out of BMP? */
		hs = (WCHAR)(0xD800 | ((c >> 10) - 0x40)); 	/* Make high surrogate */
		wc = 0xDC00 | (c & 0x3FF);					/* Make low surrogate */
	} else {
		hs = 0;
		wc = (WCHAR)c;
	}
#endif
	/* A code point in UTF-16 is available in hs and wc */

#if FF_STRF_ENCODE == 1		/* Write a code point in UTF-16LE */
	if (hs != 0) {	/* Surrogate pair? */
		st_word(&pb->buf[i], hs);
		i += 2;
		nc++;
	}
	st_word(&pb->buf[i], wc);
	i += 2;
#elif FF_STRF_ENCODE == 2	/* Write a code point in UTF-16BE */
	if (hs != 0) {	/* Surrogate pair? */
		pb->buf[i++] = (BYTE)(hs >> 8);
		pb->buf[i++] = (BYTE)hs;
		nc++;
	}
	pb->buf[i++] = (BYTE)(wc >> 8);
	pb->buf[i++] = (BYTE)wc;
#elif FF_STRF_ENCODE == 3	/* Write a code point in UTF-8 */
	if (hs != 0) {	/* 4-byte sequence? */
		nc += 3;
		hs = (hs & 0x3FF) + 0x40;
		pb->buf[i++] = (BYTE)(0xF0 | hs >> 8);
		pb->buf[i++] = (BYTE)(0x80 | (hs >> 2 & 0x3F));
		pb->buf[i++] = (BYTE)(0x80 | (hs & 3) << 4 | (wc >> 6 & 0x0F));
		pb->buf[i++] = (BYTE)(0x80 | (wc & 0x3F));
	} else {
		if (wc < 0x80) {	/* Single byte? */
			pb->buf[i++] = (BYTE)wc;
		} else {
			if (wc < 0x800) {	/* 2-byte sequence? */
				nc += 1;
				pb->buf[i++] = (BYTE)(0xC0 | wc >> 6);
			} else {			/* 3-byte sequence */
				nc += 2;
				pb->buf[i++] = (BYTE)(0xE0 | wc >> 12);
				pb->buf[i++] = (BYTE)(0x80 | (wc >> 6 & 0x3F));
			}
			pb->buf[i++] = (BYTE)(0x80 | (wc & 0x3F));
		}
	}
#else						/* Write a code point in ANSI/OEM */
	if (hs != 0) return;
	wc = ff_uni2oem(wc, CODEPAGE);	/* UTF-16 ==> ANSI/OEM */
	if (wc == 0) return;
	if (wc >= 0x100) {
		pb->buf[i++] = (BYTE)(wc >> 8); nc++;
	}
	pb->buf[i++] = (BYTE)wc;
#endif

#else							/* ANSI/OEM input (without re-encoding) */
	pb->buf[i++] = (BYTE)c;
#endif

	if (i >= (int)(sizeof pb->buf) - 4) {	/* Write buffered characters to the file */
		f_write(pb->fp, pb->buf, (UINT)i, &n);
		i = (n == (UINT)i) ? 0 : -1;
	}
	pb->idx = i;
	pb->nchr = nc + 1;
}

/* Buffered file write with code conversion */


void gpio_7segment_disconnect_pin(const GpioPin* pin) {
    furi_hal_gpio_init(pin, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedLow);
    furi_hal_gpio_write(pin, true);
}

// Disconnects a GpioPin via OutputOpenDrive, PushPullNo, output true.
// @pin pointer to GpioPin to disconnect.


void rgbleds_reset(RgbLeds* leds) {
    for(int i = 0; i < leds->num_leds; i++) {
        leds->color[i] = 0x000000;
    }
}

/**
 * @brief Resets the LEDs to their default color pattern (off).
 * @details This method resets the LEDs data to their default color pattern (off).
 * You must still call rgbleds_update to update the LEDs.
 * @param leds The RgbLeds struct to reset.
*/


static void ct_timer_interrupt(void *data, unsigned int status)
{
	struct ct_timer *timer = data;

	/* Interval timer interrupt */
	if ((status & IT_INT) && timer->ops->interrupt)
		timer->ops->interrupt(timer);
}


int curlx_uztosi(size_t uznum)
{
#ifdef __INTEL_COMPILER
#  pragma warning(push)
#  pragma warning(disable:810) /* conversion may lose significant bits */
#endif

  DEBUGASSERT(uznum <= (size_t) CURL_MASK_SINT);
  return (int)(uznum & (size_t) CURL_MASK_SINT);

#ifdef __INTEL_COMPILER
#  pragma warning(pop)
#endif
}


bool Curl_ipvalid(struct connectdata *conn)
{
  if(conn->ip_version == CURL_IPRESOLVE_V6)
    return Curl_ipv6works();
  return TRUE;
}

/*
 * Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've
 * been set and returns TRUE if they are OK.
 */


void Curl_infof(struct SessionHandle *data, const char *fmt, ...)
{
  if(data && data->set.verbose) {
    va_list ap;
    size_t len;
    char print_buffer[2048 + 1];
    va_start(ap, fmt);
    vsnprintf(print_buffer, sizeof(print_buffer), fmt, ap);
    va_end(ap);
    len = strlen(print_buffer);
    Curl_debug(data, CURLINFO_TEXT, print_buffer, len, NULL);
  }
}

/* CURL_DO_LINEEND_CONV */
/* Curl_infof() is for info message along the way */