"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var AccessControl_exports = {};
__export(AccessControl_exports, {
  AccessControlAPI: () => AccessControlAPI,
  AssignCredentialResult: () => AssignCredentialResult,
  SetCredentialResult: () => SetCredentialResult,
  SetUserResult: () => SetUserResult
});
module.exports = __toCommonJS(AccessControl_exports);
var import_cc = require("@zwave-js/cc");
var import_UserCodeCC = require("@zwave-js/cc/UserCodeCC");
var import_UserCredentialCC = require("@zwave-js/cc/UserCredentialCC");
var import_core = require("@zwave-js/core");
var import_shared = require("@zwave-js/shared");
var import_FeatureAPI = require("./FeatureAPI.js");
var SetUserResult;
(function(SetUserResult2) {
  SetUserResult2[SetUserResult2["OK"] = 0] = "OK";
  SetUserResult2[SetUserResult2["Error_AddRejectedLocationOccupied"] = 1] = "Error_AddRejectedLocationOccupied";
  SetUserResult2[SetUserResult2["Error_ModifyRejectedLocationEmpty"] = 2] = "Error_ModifyRejectedLocationEmpty";
  SetUserResult2[SetUserResult2["Error_Unknown"] = 255] = "Error_Unknown";
})(SetUserResult || (SetUserResult = {}));
var SetCredentialResult;
(function(SetCredentialResult2) {
  SetCredentialResult2[SetCredentialResult2["OK"] = 0] = "OK";
  SetCredentialResult2[SetCredentialResult2["Error_AddRejectedLocationOccupied"] = 1] = "Error_AddRejectedLocationOccupied";
  SetCredentialResult2[SetCredentialResult2["Error_ModifyRejectedLocationEmpty"] = 2] = "Error_ModifyRejectedLocationEmpty";
  SetCredentialResult2[SetCredentialResult2["Error_DuplicateCredential"] = 3] = "Error_DuplicateCredential";
  SetCredentialResult2[SetCredentialResult2["Error_ManufacturerSecurityRules"] = 4] = "Error_ManufacturerSecurityRules";
  SetCredentialResult2[SetCredentialResult2["Error_DuplicateAdminPINCode"] = 5] = "Error_DuplicateAdminPINCode";
  SetCredentialResult2[SetCredentialResult2["Error_WrongUserUniqueIdentifier"] = 6] = "Error_WrongUserUniqueIdentifier";
  SetCredentialResult2[SetCredentialResult2["Error_Unknown"] = 255] = "Error_Unknown";
})(SetCredentialResult || (SetCredentialResult = {}));
var AssignCredentialResult;
(function(AssignCredentialResult2) {
  AssignCredentialResult2[AssignCredentialResult2["OK"] = 0] = "OK";
  AssignCredentialResult2[AssignCredentialResult2["Error_InvalidCredential"] = 1] = "Error_InvalidCredential";
  AssignCredentialResult2[AssignCredentialResult2["Error_InvalidUser"] = 2] = "Error_InvalidUser";
  AssignCredentialResult2[AssignCredentialResult2["Error_Unknown"] = 255] = "Error_Unknown";
})(AssignCredentialResult || (AssignCredentialResult = {}));
function u3cUserReportTypeToSetUserResult(reportType) {
  if (reportType == void 0)
    return SetUserResult.Error_Unknown;
  switch (reportType) {
    case import_cc.UserCredentialUserReportType.UserAdded:
    case import_cc.UserCredentialUserReportType.UserModified:
    case import_cc.UserCredentialUserReportType.UserDeleted:
    case import_cc.UserCredentialUserReportType.UserUnchanged:
      return SetUserResult.OK;
    case import_cc.UserCredentialUserReportType.UserAddRejectedLocationOccupied:
      return SetUserResult.Error_AddRejectedLocationOccupied;
    case import_cc.UserCredentialUserReportType.UserModifyRejectedLocationEmpty:
      return SetUserResult.Error_ModifyRejectedLocationEmpty;
    default:
      return SetUserResult.Error_Unknown;
  }
}
__name(u3cUserReportTypeToSetUserResult, "u3cUserReportTypeToSetUserResult");
function u3cCredentialReportTypeToSetCredentialResult(reportType) {
  if (reportType == void 0)
    return SetCredentialResult.Error_Unknown;
  switch (reportType) {
    case import_cc.UserCredentialCredentialReportType.CredentialAdded:
    case import_cc.UserCredentialCredentialReportType.CredentialModified:
    case import_cc.UserCredentialCredentialReportType.CredentialDeleted:
    case import_cc.UserCredentialCredentialReportType.CredentialUnchanged:
      return SetCredentialResult.OK;
    case import_cc.UserCredentialCredentialReportType.CredentialAddRejectedLocationOccupied:
      return SetCredentialResult.Error_AddRejectedLocationOccupied;
    case import_cc.UserCredentialCredentialReportType.CredentialModifyRejectedLocationEmpty:
      return SetCredentialResult.Error_ModifyRejectedLocationEmpty;
    case import_cc.UserCredentialCredentialReportType.DuplicateCredential:
      return SetCredentialResult.Error_DuplicateCredential;
    case import_cc.UserCredentialCredentialReportType.ManufacturerSecurityRules:
      return SetCredentialResult.Error_ManufacturerSecurityRules;
    case import_cc.UserCredentialCredentialReportType.DuplicateAdminPINCode:
      return SetCredentialResult.Error_DuplicateAdminPINCode;
    case import_cc.UserCredentialCredentialReportType.WrongUserUniqueIdentifier:
      return SetCredentialResult.Error_WrongUserUniqueIdentifier;
    default:
      return SetCredentialResult.Error_Unknown;
  }
}
__name(u3cCredentialReportTypeToSetCredentialResult, "u3cCredentialReportTypeToSetCredentialResult");
function u3cAssociationStatusToAssignCredentialResult(status) {
  if (status == void 0)
    return AssignCredentialResult.Error_Unknown;
  switch (status) {
    case 0:
      return AssignCredentialResult.OK;
    case 1:
    case 2:
    case 3:
      return AssignCredentialResult.Error_InvalidCredential;
    case 4:
    case 5:
      return AssignCredentialResult.Error_InvalidUser;
    default:
      return AssignCredentialResult.Error_Unknown;
  }
}
__name(u3cAssociationStatusToAssignCredentialResult, "u3cAssociationStatusToAssignCredentialResult");
const NON_PIN_CHARS = /[^0-9]/;
function supportsNonPINChars(supportedASCIIChars) {
  return supportedASCIIChars != void 0 && NON_PIN_CHARS.test(supportedASCIIChars);
}
__name(supportsNonPINChars, "supportsNonPINChars");
const USER_CODE_OBFUSCATION_CHARS = ["*"];
function userCodeReadBackConfirmsSet(expected, actual, version) {
  if (actual == void 0)
    return false;
  if (typeof expected !== "string" || typeof actual !== "string") {
    const toBytes = /* @__PURE__ */ __name((v) => typeof v === "string" ? import_shared.Bytes.from(v, "ascii") : import_shared.Bytes.view(v), "toBytes");
    if (toBytes(actual).equals(toBytes(expected)))
      return true;
  } else if (actual === expected) {
    return true;
  }
  if (version === 1 && typeof actual === "string" && actual.length > 0) {
    return USER_CODE_OBFUSCATION_CHARS.some((char) => actual === char.repeat(actual.length));
  }
  return false;
}
__name(userCodeReadBackConfirmsSet, "userCodeReadBackConfirmsSet");
class AccessControlAPI extends import_FeatureAPI.FeatureAPI {
  static {
    __name(this, "AccessControlAPI");
  }
  get #usesUserCredentialCC() {
    if (!this.endpoint.supportsCC(import_core.CommandClasses["User Credential"])) {
      return false;
    }
    if (!this.endpoint.supportsCC(import_core.CommandClasses["User Code"])) {
      return true;
    }
    return this.getValue(import_UserCredentialCC.UserCredentialCCValues.supportedUsers.endpoint(this.endpoint.index)) !== 0;
  }
  /**
   * Returns the user-related capabilities of this endpoint.
   * This method uses cached information from the most recent interview.
   */
  getUserCapabilitiesCached() {
    if (this.#usesUserCredentialCC) {
      return {
        maxUsers: this.getValue(import_UserCredentialCC.UserCredentialCCValues.supportedUsers.endpoint(this.endpoint.index)) ?? 0,
        supportedUserTypes: this.getValue(import_UserCredentialCC.UserCredentialCCValues.supportedUserTypes.endpoint(this.endpoint.index)) ?? [],
        maxUserNameLength: this.getValue(import_UserCredentialCC.UserCredentialCCValues.maxUserNameLength.endpoint(this.endpoint.index)) ?? void 0,
        supportedCredentialRules: this.getValue(import_UserCredentialCC.UserCredentialCCValues.supportedCredentialRules.endpoint(this.endpoint.index)) ?? [],
        supportsUsersWithoutCredentials: true
      };
    } else {
      const supportedStatuses = this.getValue(import_UserCodeCC.UserCodeCCValues.supportedUserIDStatuses.endpoint(this.endpoint.index)) ?? [];
      const supportedUserTypes = [
        import_cc.UserCredentialUserType.General
      ];
      if (supportedStatuses.includes(import_cc.UserIDStatus.Messaging)) {
        supportedUserTypes.push(import_cc.UserCredentialUserType.NonAccess);
      }
      return {
        maxUsers: this.getValue(import_UserCodeCC.UserCodeCCValues.supportedUsers.endpoint(this.endpoint.index)) ?? 0,
        supportedUserTypes,
        // User Code CC does not support user names or credential rules
        maxUserNameLength: void 0,
        supportedCredentialRules: [import_cc.UserCredentialRule.Single],
        supportsUsersWithoutCredentials: false
      };
    }
  }
  /**
   * Returns the credential-related capabilities of this endpoint.
   * This method uses cached information from the most recent interview.
   */
  getCredentialCapabilitiesCached() {
    if (this.#usesUserCredentialCC) {
      const supportedTypes = this.getValue(import_UserCredentialCC.UserCredentialCCValues.supportedCredentialTypes.endpoint(this.endpoint.index)) ?? [];
      const credentialTypes = /* @__PURE__ */ new Map();
      for (const type of supportedTypes) {
        const cap = this.getValue(import_UserCredentialCC.UserCredentialCCValues.credentialCapabilities(type).endpoint(this.endpoint.index));
        if (cap)
          credentialTypes.set(type, cap);
      }
      return {
        supportedCredentialTypes: credentialTypes,
        supportsAdminCode: this.getValue(import_UserCredentialCC.UserCredentialCCValues.supportsAdminCode.endpoint(this.endpoint.index)) ?? false,
        supportsAdminCodeDeactivation: this.getValue(import_UserCredentialCC.UserCredentialCCValues.supportsAdminCodeDeactivation.endpoint(this.endpoint.index)) ?? false,
        supportsCredentialAssignment: this.#u3cAPI().supportsCommand(import_cc.UserCredentialCommand.UserCredentialAssociationSet) === true
      };
    } else {
      const maxUsers = this.getValue(import_UserCodeCC.UserCodeCCValues.supportedUsers.endpoint(this.endpoint.index)) ?? 0;
      const credentialTypes = /* @__PURE__ */ new Map();
      credentialTypes.set(this.#ucCredentialType, {
        // For User Code CC, credential slots and users are identical
        numberOfCredentialSlots: maxUsers,
        minCredentialLength: 4,
        maxCredentialLength: 10,
        maxCredentialHashLength: 0,
        supportsCredentialLearn: false
      });
      return {
        supportedCredentialTypes: credentialTypes,
        supportsAdminCode: this.getValue(import_UserCodeCC.UserCodeCCValues.supportsAdminCode.endpoint(this.endpoint.index)) ?? false,
        supportsAdminCodeDeactivation: this.getValue(import_UserCodeCC.UserCodeCCValues.supportsAdminCodeDeactivation.endpoint(this.endpoint.index)) ?? false,
        // User Code CC has no equivalent to credential reassignment
        supportsCredentialAssignment: false
      };
    }
  }
  /**
   * Returns the data for the user with the given ID.
   * This communicates with the node to retrieve fresh information.
   */
  async getUser(userId) {
    if (this.#usesUserCredentialCC) {
      const api = this.#u3cAPI();
      const result = await api.getUser(userId);
      if (result)
        await this.endpoint.tryGetNode()?.handleCommand(result);
      if (!result?.userId)
        return void 0;
      return {
        userId: result.userId,
        active: result.active ?? false,
        userType: result.userType ?? import_cc.UserCredentialUserType.General,
        userName: result.userName ?? void 0,
        credentialRule: result.credentialRule ?? void 0,
        expiringTimeoutMinutes: result.expiringTimeoutMinutes || void 0
      };
    } else {
      const api = this.#ucAPI();
      const result = await api.get(userId);
      if (!result)
        return void 0;
      return this.#mapUserCodeStatusToUserData(userId, result.userIdStatus);
    }
  }
  /**
   * Returns the data for the user with the given ID.
   * This method uses cached information from the most recent interview.
   */
  getUserCached(userId) {
    if (this.#usesUserCredentialCC) {
      return this.#getUserCached_U3C(userId);
    } else {
      return this.#getUserCached_UC(userId);
    }
  }
  /**
   * Returns the data for all configured users.
   * This communicates with the node to retrieve fresh information.
   */
  async getUsers() {
    if (this.#usesUserCredentialCC) {
      const api = this.#u3cAPI();
      const users = [];
      let nextUserId = 0;
      do {
        const result = await api.getUser(nextUserId);
        if (result) {
          await this.endpoint.tryGetNode()?.handleCommand(result);
        }
        if (!result?.userId)
          break;
        users.push({
          userId: result.userId,
          active: result.active ?? false,
          userType: result.userType ?? import_cc.UserCredentialUserType.General,
          userName: result.userName ?? void 0,
          credentialRule: result.credentialRule ?? void 0,
          expiringTimeoutMinutes: result.expiringTimeoutMinutes || void 0
        });
        nextUserId = result.nextUserId ?? 0;
      } while (nextUserId > 0);
      return users;
    } else {
      const api = this.#ucAPI();
      const maxUsers = await api.getUsersCount();
      if (!maxUsers)
        return [];
      const users = [];
      const supportsBulk = !!this.getValue(import_UserCodeCC.UserCodeCCValues.supportsMultipleUserCodeReport.endpoint(this.endpoint.index));
      if (supportsBulk) {
        let nextUserId = 1;
        while (nextUserId > 0 && nextUserId <= maxUsers) {
          const response = await api.get(nextUserId, true);
          if (!response)
            break;
          users.push(...response.userCodes.map((entry) => this.#mapUserCodeStatusToUserData(entry.userId, entry.userIdStatus)).filter((u) => u != void 0));
          nextUserId = response.nextUserId;
        }
      } else {
        for (let userId = 1; userId <= maxUsers; userId++) {
          const result = await api.get(userId);
          if (!result)
            continue;
          const user = this.#mapUserCodeStatusToUserData(userId, result.userIdStatus);
          if (user)
            users.push(user);
        }
      }
      return users;
    }
  }
  /**
   * Returns the data for all configured users.
   * This method uses cached information from the most recent interview.
   */
  getUsersCached() {
    if (this.#usesUserCredentialCC) {
      const maxUsers = this.getValue(import_UserCredentialCC.UserCredentialCCValues.supportedUsers.endpoint(this.endpoint.index)) ?? 0;
      const users = [];
      for (let userId = 1; userId <= maxUsers; userId++) {
        const user = this.#getUserCached_U3C(userId);
        if (user)
          users.push(user);
      }
      return users;
    } else {
      const maxUsers = this.getValue(import_UserCodeCC.UserCodeCCValues.supportedUsers.endpoint(this.endpoint.index)) ?? 0;
      const users = [];
      for (let userId = 1; userId <= maxUsers; userId++) {
        const user = this.#getUserCached_UC(userId);
        if (user)
          users.push(user);
      }
      return users;
    }
  }
  /**
   * Creates a new user with the given ID, optionally writing a credential at
   * the same time.
   *
   * This communicates with the node.
   *
   * @param credential - The credential to set for this user. On devices where `supportsUsersWithoutCredentials` is `false`, this field is required.
   */
  async addUser(userId, options, credential) {
    if (this.#usesUserCredentialCC) {
      const api = this.#u3cAPI();
      const userType = options.userType ?? import_cc.UserCredentialUserType.General;
      let result;
      if (userType === import_cc.UserCredentialUserType.Expiring) {
        result = await api.setUser({
          operationType: import_cc.UserCredentialOperationType.Add,
          userId,
          active: options.active ?? true,
          userType,
          expiringTimeoutMinutes: options.expiringTimeoutMinutes ?? 0,
          credentialRule: options.credentialRule,
          userName: options.userName
        });
      } else {
        result = await api.setUser({
          operationType: import_cc.UserCredentialOperationType.Add,
          userId,
          active: options.active ?? true,
          userType,
          credentialRule: options.credentialRule,
          userName: options.userName
        });
      }
      if (result)
        await this.endpoint.tryGetNode()?.handleCommand(result);
      const userResult = u3cUserReportTypeToSetUserResult(result?.reportType);
      if (userResult !== SetUserResult.OK || !credential) {
        return credential ? { user: userResult, credential: void 0 } : { user: userResult };
      }
      const credentialResult = await this.setCredential(userId, credential.type, credential.slot, credential.data);
      return { user: userResult, credential: credentialResult };
    } else {
      if (!credential) {
        throw new import_core.ZWaveError("On this device, users and codes must be stored together. addUser() requires a credential.", import_core.ZWaveErrorCodes.Argument_Invalid);
      }
      if (credential.slot !== userId) {
        throw new import_core.ZWaveError("On this device, users and codes share the same slot. The credential slot must equal the user ID.", import_core.ZWaveErrorCodes.Argument_Invalid);
      }
      this.#assertValidSlot(credential.type, userId);
      const active = options.active ?? true;
      const userType = options.userType ?? import_cc.UserCredentialUserType.General;
      let status;
      if (!active) {
        status = import_cc.UserIDStatus.Disabled;
      } else if (userType === import_cc.UserCredentialUserType.NonAccess) {
        status = import_cc.UserIDStatus.Messaging;
      } else {
        status = import_cc.UserIDStatus.Enabled;
      }
      const api = this.#ucAPI();
      const codeData = typeof credential.data === "string" ? credential.data : import_shared.Bytes.from(credential.data);
      const result = await api.set(userId, status, codeData);
      let succeeded;
      if (result == void 0) {
        const verified = await api.get(userId);
        succeeded = verified?.userIdStatus === status && userCodeReadBackConfirmsSet(codeData, verified?.userCode, api.version);
      } else {
        succeeded = (0, import_core.supervisedCommandSucceeded)(result);
      }
      if (succeeded) {
        const node = this.endpoint.tryGetNode();
        if (node) {
          const userData = { userId, active, userType };
          node.emit("user added", this.endpoint, userData);
          node.emit("credential added", this.endpoint, {
            userId,
            credentialType: credential.type,
            credentialSlot: userId,
            data: credential.data
          });
        }
      }
      return succeeded ? { user: SetUserResult.OK, credential: SetCredentialResult.OK } : {
        user: SetUserResult.Error_Unknown,
        credential: SetCredentialResult.Error_Unknown
      };
    }
  }
  /**
   * Creates or updates the user with the given ID.
   * This communicates with the node.
   */
  async setUser(userId, options) {
    if (this.#usesUserCredentialCC) {
      const api = this.#u3cAPI();
      const existing = this.#getUserCached_U3C(userId);
      const operationType = existing ? import_cc.UserCredentialOperationType.Modify : import_cc.UserCredentialOperationType.Add;
      const userType = options.userType ?? existing?.userType ?? import_cc.UserCredentialUserType.General;
      let result;
      if (userType === import_cc.UserCredentialUserType.Expiring) {
        result = await api.setUser({
          operationType,
          userId,
          active: options.active ?? existing?.active ?? true,
          userType,
          expiringTimeoutMinutes: options.expiringTimeoutMinutes ?? existing?.expiringTimeoutMinutes ?? 0,
          credentialRule: options.credentialRule ?? existing?.credentialRule,
          userName: options.userName ?? existing?.userName
        });
      } else {
        result = await api.setUser({
          operationType,
          userId,
          active: options.active ?? existing?.active ?? true,
          userType,
          credentialRule: options.credentialRule ?? existing?.credentialRule,
          userName: options.userName ?? existing?.userName
        });
      }
      if (result)
        await this.endpoint.tryGetNode()?.handleCommand(result);
      return u3cUserReportTypeToSetUserResult(result?.reportType);
    } else {
      const api = this.#ucAPI();
      const existing = this.#getUserCached_UC(userId);
      const existingStatus = this.getValue(import_UserCodeCC.UserCodeCCValues.userIdStatus(userId).endpoint(this.endpoint.index));
      const active = options.active ?? existing?.active ?? true;
      const userType = options.userType ?? existing?.userType ?? import_cc.UserCredentialUserType.General;
      let status;
      if (!active) {
        status = import_cc.UserIDStatus.Disabled;
      } else if (userType === import_cc.UserCredentialUserType.NonAccess) {
        status = import_cc.UserIDStatus.Messaging;
      } else {
        status = import_cc.UserIDStatus.Enabled;
      }
      const existingCode = this.getValue(import_UserCodeCC.UserCodeCCValues.userCode(userId).endpoint(this.endpoint.index));
      if (!existingCode) {
        throw new import_core.ZWaveError("On this device, users and codes must be stored together. To add a new user, use the addUser() method and provide a credential.", import_core.ZWaveErrorCodes.Argument_Invalid);
      }
      const result = await api.set(userId, status, existingCode);
      let succeeded;
      if (result == void 0) {
        const verified = await api.get(userId);
        const verifiedStatus = verified?.userIdStatus;
        succeeded = verifiedStatus != void 0 && verifiedStatus !== existingStatus && verifiedStatus !== import_cc.UserIDStatus.Available;
      } else {
        succeeded = (0, import_core.supervisedCommandSucceeded)(result);
      }
      if (succeeded) {
        const node = this.endpoint.tryGetNode();
        if (node) {
          const userData = { userId, active, userType };
          node.emit(existing ? "user modified" : "user added", this.endpoint, userData);
        }
      }
      return succeeded ? SetUserResult.OK : SetUserResult.Error_Unknown;
    }
  }
  /**
   * Deletes the user with the given ID and all of their credentials.
   * This communicates with the node.
   */
  async deleteUser(userId) {
    if (this.#usesUserCredentialCC) {
      const api = this.#u3cAPI();
      const raw = await api.setUser({
        operationType: import_cc.UserCredentialOperationType.Delete,
        userId
      });
      if (raw)
        await this.endpoint.tryGetNode()?.handleCommand(raw);
      const status = u3cUserReportTypeToSetUserResult(raw?.reportType);
      if (status === SetUserResult.OK) {
        this.#purgeCachedCredentials(userId);
      }
      return status;
    } else {
      const existed = this.#getUserCached_UC(userId) != void 0;
      const api = this.#ucAPI();
      const result = await api.clear(userId);
      let succeeded;
      if (result == void 0) {
        const verified = await api.get(userId);
        succeeded = verified?.userIdStatus === import_cc.UserIDStatus.Available;
      } else {
        succeeded = (0, import_core.supervisedCommandSucceeded)(result);
      }
      if (succeeded) {
        this.#clearCachedUserCodes(userId);
      }
      if (succeeded && existed) {
        const node = this.endpoint.tryGetNode();
        if (node) {
          node.emit("user deleted", this.endpoint, { userId });
          node.emit("credential deleted", this.endpoint, {
            userId,
            credentialType: this.#ucCredentialType,
            // For User Code CC, credential slots and users are identical
            credentialSlot: userId
          });
        }
      }
      return succeeded ? SetUserResult.OK : SetUserResult.Error_Unknown;
    }
  }
  /**
   * Deletes all users and their credentials.
   * This communicates with the node.
   */
  async deleteAllUsers() {
    if (this.#usesUserCredentialCC) {
      const api = this.#u3cAPI();
      const raw = await api.setUser({
        operationType: import_cc.UserCredentialOperationType.Delete,
        userId: 0
      });
      const status = u3cUserReportTypeToSetUserResult(raw?.reportType);
      if (status === SetUserResult.OK) {
        this.#purgeAllCachedUsersAndCredentials();
      }
      if (raw)
        await this.endpoint.tryGetNode()?.handleCommand(raw);
      return status;
    } else {
      const api = this.#ucAPI();
      const result = await api.clear(0);
      const succeeded = result == void 0 || (0, import_core.supervisedCommandSucceeded)(result);
      if (succeeded) {
        this.#clearCachedUserCodes();
      }
      return succeeded ? SetUserResult.OK : SetUserResult.Error_Unknown;
    }
  }
  /**
   * Returns the data for a specific credential type and slot.
   * This communicates with the node to retrieve fresh information.
   */
  async getCredential(type, slot) {
    this.#assertValidSlot(type, slot);
    if (this.#usesUserCredentialCC) {
      const result = await this.#u3cAPI().getCredential(0, type, slot);
      if (result)
        await this.endpoint.tryGetNode()?.handleCommand(result);
      return this.#mapCredentialData(result);
    } else {
      const api = this.#ucAPI();
      const result = await api.get(slot);
      if (!result)
        return void 0;
      if (result.userIdStatus === import_cc.UserIDStatus.Available || result.userIdStatus === import_cc.UserIDStatus.StatusNotAvailable) {
        return void 0;
      }
      return { userId: slot, type, slot, data: result.userCode };
    }
  }
  /**
   * Returns the data for a specific credential type and slot.
   * This method uses cached information from the most recent interview.
   */
  getCredentialCached(type, slot) {
    this.#assertValidSlot(type, slot);
    if (this.#usesUserCredentialCC) {
      return this.#getCredentialCached_U3C(type, slot);
    } else {
      return this.#getCredentialCached_UC(type, slot);
    }
  }
  /**
   * Returns all credentials for the given user and optional type.
   * This communicates with the node to retrieve fresh information.
   */
  async getCredentialsForUser(userId, type) {
    if (this.#usesUserCredentialCC) {
      if (type != void 0 && !this.#supportsCredentialType(type)) {
        return [];
      }
      return this.#queryCredentials_U3C(userId, type ?? import_cc.UserCredentialType.None, 0, type);
    } else {
      if (type != void 0 && type !== this.#ucCredentialType) {
        return [];
      }
      const cred = await this.getCredential(
        this.#ucCredentialType,
        // For User Code CC, credential slots and users are identical
        userId
      );
      return cred ? [cred] : [];
    }
  }
  /**
   * Returns all credentials for the given user and optional type.
   * This method uses cached information from the most recent interview.
   */
  getCredentialsForUserCached(userId, type) {
    if (this.#usesUserCredentialCC) {
      if (type != void 0 && !this.#supportsCredentialType(type)) {
        return [];
      }
      return this.#getAllCredentialsCached_U3C().filter((credential) => credential.userId === userId && (type == void 0 || credential.type === type));
    } else {
      if (type != void 0 && type !== this.#ucCredentialType) {
        return [];
      }
      const cred = this.#getCredentialCached_UC(
        this.#ucCredentialType,
        // For User Code CC, credential slots and users are identical
        userId
      );
      return cred ? [cred] : [];
    }
  }
  /**
   * Returns all credentials of the given type, regardless of ownership.
   * This communicates with the node to retrieve fresh information.
   */
  async getCredentialsByType(type) {
    if (!this.#supportsCredentialType(type)) {
      return [];
    }
    if (this.#usesUserCredentialCC) {
      return this.#queryCredentials_U3C(0, type, 0, type);
    } else {
      return this.#getAllCredentials_UC();
    }
  }
  /**
   * Returns all credentials of the given type, regardless of ownership.
   * This method uses cached information from the most recent interview.
   */
  getCredentialsByTypeCached(type) {
    if (!this.#supportsCredentialType(type)) {
      return [];
    }
    if (this.#usesUserCredentialCC) {
      return this.#getAllCredentialsCached_U3C().filter((credential) => credential.type === type);
    } else {
      return this.#getAllCredentialsCached_UC();
    }
  }
  /**
   * Returns all credentials, regardless of ownership or type.
   * This communicates with the node to retrieve fresh information.
   */
  async getAllCredentials() {
    if (this.#usesUserCredentialCC) {
      return this.#queryCredentials_U3C(0, import_cc.UserCredentialType.None, 0);
    } else {
      return this.#getAllCredentials_UC();
    }
  }
  /**
   * Returns all credentials, regardless of ownership or type.
   * This method uses cached information from the most recent interview.
   */
  getAllCredentialsCached() {
    if (this.#usesUserCredentialCC) {
      return this.#getAllCredentialsCached_U3C();
    } else {
      return this.#getAllCredentialsCached_UC();
    }
  }
  /**
   * Creates or updates a credential for the given user.
   * This communicates with the node.
   */
  async setCredential(userId, type, slot, data) {
    if (this.#usesUserCredentialCC) {
      this.#assertValidSlot(type, slot);
      const api = this.#u3cAPI();
      const existing = this.#getCredentialCachedForUser_U3C(userId, type, slot);
      const credentialData = typeof data === "string" ? import_shared.Bytes.from(data, "utf-8") : import_shared.Bytes.from(data);
      const raw = await api.setCredential({
        operationType: existing ? import_cc.UserCredentialOperationType.Modify : import_cc.UserCredentialOperationType.Add,
        userId,
        credentialType: type,
        credentialSlot: slot,
        credentialData
      });
      if (raw)
        await this.endpoint.tryGetNode()?.handleCommand(raw);
      return u3cCredentialReportTypeToSetCredentialResult(raw?.reportType);
    } else {
      this.#assertValidSlot(type, userId);
      const api = this.#ucAPI();
      const existingStatus = this.getValue(import_UserCodeCC.UserCodeCCValues.userIdStatus(userId).endpoint(this.endpoint.index));
      const status = existingStatus == void 0 || existingStatus === import_cc.UserIDStatus.Available ? import_cc.UserIDStatus.Enabled : existingStatus;
      const existingCred = this.#getCredentialCached_UC(type, userId);
      const codeData = typeof data === "string" ? data : import_shared.Bytes.from(data);
      const result = await api.set(userId, status, codeData);
      let succeeded;
      if (result == void 0) {
        const verified = await api.get(userId);
        succeeded = verified?.userIdStatus === status && userCodeReadBackConfirmsSet(codeData, verified?.userCode, api.version);
      } else {
        succeeded = (0, import_core.supervisedCommandSucceeded)(result);
      }
      if (succeeded) {
        const node = this.endpoint.tryGetNode();
        if (node) {
          node.emit(existingCred ? "credential modified" : "credential added", this.endpoint, {
            userId,
            credentialType: type,
            credentialSlot: userId,
            data
          });
        }
      }
      return succeeded ? SetCredentialResult.OK : SetCredentialResult.Error_Unknown;
    }
  }
  async deleteCredential(userIdOrType, typeOrSlot, slot) {
    if (slot == void 0) {
      return this.deleteCredential(0, userIdOrType, typeOrSlot);
    }
    const userId = userIdOrType ?? 0;
    const type = typeOrSlot;
    if (this.#usesUserCredentialCC) {
      this.#assertValidSlot(type, slot);
      const api = this.#u3cAPI();
      const raw = await api.setCredential({
        operationType: import_cc.UserCredentialOperationType.Delete,
        userId,
        credentialType: type,
        credentialSlot: slot
      });
      if (raw)
        await this.endpoint.tryGetNode()?.handleCommand(raw);
      return u3cCredentialReportTypeToSetCredentialResult(raw?.reportType);
    } else {
      if (userId !== 0 && userId !== slot) {
        return SetCredentialResult.Error_ModifyRejectedLocationEmpty;
      }
      const targetUserId = userId === 0 ? slot : userId;
      this.#assertValidSlot(type, targetUserId);
      const existed = this.#getCredentialCached_UC(type, targetUserId) != void 0;
      const api = this.#ucAPI();
      const result = await api.clear(targetUserId);
      let succeeded;
      if (result == void 0) {
        const verified = await api.get(targetUserId);
        succeeded = verified?.userIdStatus === import_cc.UserIDStatus.Available;
      } else {
        succeeded = (0, import_core.supervisedCommandSucceeded)(result);
      }
      if (succeeded) {
        this.#clearCachedUserCodes(targetUserId);
      }
      if (succeeded && existed) {
        const node = this.endpoint.tryGetNode();
        if (node) {
          node.emit("credential deleted", this.endpoint, {
            userId: targetUserId,
            credentialType: type,
            credentialSlot: targetUserId
          });
          node.emit("user deleted", this.endpoint, {
            userId: targetUserId
          });
        }
      }
      return succeeded ? SetCredentialResult.OK : SetCredentialResult.Error_Unknown;
    }
  }
  /**
   * Deletes credentials matching the given filters.
   */
  async deleteCredentials(options = {}) {
    const userId = options.userId ?? 0;
    const credentialType = options.credentialType ?? import_cc.UserCredentialType.None;
    if (this.#usesUserCredentialCC) {
      const api = this.#u3cAPI();
      const raw = await api.setCredential({
        operationType: import_cc.UserCredentialOperationType.Delete,
        userId,
        credentialType,
        credentialSlot: 0
      });
      const status = u3cCredentialReportTypeToSetCredentialResult(raw?.reportType);
      if (status === SetCredentialResult.OK) {
        this.#purgeCachedCredentials(userId, credentialType);
      }
      if (raw)
        await this.endpoint.tryGetNode()?.handleCommand(raw);
      return status;
    } else {
      if (credentialType !== import_cc.UserCredentialType.None && credentialType !== this.#ucCredentialType) {
        throw new import_core.ZWaveError(`Credential type ${(0, import_shared.getEnumMemberName)(import_cc.UserCredentialType, credentialType)} is not supported by this node`, import_core.ZWaveErrorCodes.Argument_Invalid);
      }
      const existed = userId !== 0 ? this.#getUserCached_UC(userId) != void 0 : true;
      const api = this.#ucAPI();
      const result = await api.clear(userId);
      let succeeded;
      if (userId !== 0 && result == void 0) {
        const verified = await api.get(userId);
        succeeded = verified?.userIdStatus === import_cc.UserIDStatus.Available;
      } else {
        succeeded = result == void 0 || (0, import_core.supervisedCommandSucceeded)(result);
      }
      if (succeeded) {
        this.#clearCachedUserCodes(userId);
      }
      if (succeeded && existed) {
        const node = this.endpoint.tryGetNode();
        if (node) {
          node.emit("credential deleted", this.endpoint, {
            userId,
            credentialType: this.#ucCredentialType,
            credentialSlot: userId
          });
          node.emit("user deleted", this.endpoint, { userId });
        }
      }
      return succeeded ? SetCredentialResult.OK : SetCredentialResult.Error_Unknown;
    }
  }
  /**
   * Assigns an existing credential to a different user, without re-enrolling
   * it. Useful for credentials that were added locally on the device (e.g. a
   * biometric auto-assigned to a fresh user) that need to be attached to an
   * existing user which already has other credentials.
   *
   * Only supported on nodes using the User Credential CC. Use
   * {@link getCredentialCapabilitiesCached} to check for support via the
   * `supportsCredentialAssignment` property.
   *
   * This communicates with the node.
   */
  async assignCredential(type, slot, destinationUserId) {
    if (!this.#usesUserCredentialCC) {
      throw new import_core.ZWaveError("This node does not support assigning a credential to a different user", import_core.ZWaveErrorCodes.CC_NotSupported);
    }
    this.#assertValidSlot(type, slot);
    const api = this.#u3cAPI();
    const response = await api.setUserCredentialAssociation({
      credentialType: type,
      credentialSlot: slot,
      destinationUserId
    });
    if (response) {
      await this.endpoint.tryGetNode()?.handleCommand(response);
    }
    return u3cAssociationStatusToAssignCredentialResult(response?.status);
  }
  /**
   * Starts a learn process for the given credential slot, allowing a user
   * to input a credential directly on the device.
   * Only supported on nodes using the User Credential CC.
   * This communicates with the node.
   */
  async startCredentialLearn(userId, type, slot, timeout) {
    if (!this.#usesUserCredentialCC) {
      throw new import_core.ZWaveError("This node does not support learning credentials", import_core.ZWaveErrorCodes.CC_NotSupported);
    }
    this.#assertValidSlot(type, slot);
    const existing = this.#getCredentialCachedForUser_U3C(userId, type, slot);
    const operationType = existing ? import_cc.UserCredentialOperationType.Modify : import_cc.UserCredentialOperationType.Add;
    timeout ??= this.getCredentialCapabilitiesCached().supportedCredentialTypes.get(type)?.credentialLearnRecommendedTimeout;
    if (timeout == void 0) {
      throw new import_core.ZWaveError(`Credential learning is not supported for credential type ${(0, import_shared.getEnumMemberName)(import_cc.UserCredentialType, type)}`, import_core.ZWaveErrorCodes.CC_NotSupported);
    }
    const api = this.#u3cAPI();
    return api.startCredentialLearn({
      userId,
      credentialType: type,
      credentialSlot: slot,
      operationType,
      learnTimeout: timeout
    });
  }
  /**
   * Cancels an ongoing credential learn process.
   * Only supported on nodes using the User Credential CC.
   * This communicates with the node.
   */
  async cancelCredentialLearn() {
    if (!this.#usesUserCredentialCC) {
      throw new import_core.ZWaveError("This node does not support learning credentials", import_core.ZWaveErrorCodes.CC_NotSupported);
    }
    const api = this.#u3cAPI();
    return api.cancelCredentialLearn();
  }
  /**
   * Retrieves the admin code from the node.
   * This communicates with the node to retrieve fresh information.
   */
  async getAdminCode() {
    if (this.#usesUserCredentialCC) {
      const api = this.#u3cAPI();
      return api.getAdminPinCode();
    } else {
      const api = this.#ucAPI();
      return api.getAdminCode();
    }
  }
  /**
   * Sets the admin code on the node.
   * This communicates with the node.
   */
  async setAdminCode(code) {
    if (this.#usesUserCredentialCC) {
      const api = this.#u3cAPI();
      return api.setAdminPinCode({ pinCode: code });
    } else {
      const api = this.#ucAPI();
      return api.setAdminCode(code);
    }
  }
  #ucAPI() {
    return this.endpoint.commandClasses["User Code"];
  }
  #u3cAPI() {
    return this.endpoint.commandClasses["User Credential"];
  }
  #supportsCredentialType(type) {
    return this.getCredentialCapabilitiesCached().supportedCredentialTypes.has(type);
  }
  /** The ASCII characters the node accepts in user codes, if known */
  get #supportedASCIIChars() {
    return this.getValue(import_UserCodeCC.UserCodeCCValues.supportedASCIIChars.endpoint(this.endpoint.index));
  }
  /** Returns the credential type to use for User Code CC based on supported characters */
  get #ucCredentialType() {
    return supportsNonPINChars(this.#supportedASCIIChars) ? import_cc.UserCredentialType.Password : import_cc.UserCredentialType.PINCode;
  }
  /** Maps User Code CC's UserIDStatus to the unified active/userType model */
  #mapUserCodeStatusToUserData(userId, status) {
    if (status === import_cc.UserIDStatus.Available || status === import_cc.UserIDStatus.StatusNotAvailable || status === import_cc.UserIDStatus.PassageMode) {
      return void 0;
    }
    let active;
    let userType;
    switch (status) {
      case import_cc.UserIDStatus.Enabled:
        active = true;
        userType = import_cc.UserCredentialUserType.General;
        break;
      case import_cc.UserIDStatus.Disabled:
        active = false;
        userType = import_cc.UserCredentialUserType.General;
        break;
      // Messaging is the closest User Code CC equivalent to NonAccess
      case import_cc.UserIDStatus.Messaging:
        active = true;
        userType = import_cc.UserCredentialUserType.NonAccess;
        break;
      default:
        active = true;
        userType = import_cc.UserCredentialUserType.General;
        break;
    }
    return { userId, active, userType };
  }
  /**
   * Removes cached credential values from the value DB for the given filters.
   * Use userId 0 to match all users, and UserCredentialType.None to match all
   * credential types.
   */
  #purgeCachedCredentials(userId, credentialType = import_cc.UserCredentialType.None) {
    const valueDB = this.endpoint.tryGetNode()?.valueDB;
    if (!valueDB)
      return;
    const credentialOwners = valueDB.findValues((vid) => import_UserCredentialCC.UserCredentialCCValues.credentialOwner.is(vid) && vid.endpoint === this.endpoint.index);
    for (const { endpoint, propertyKey, value } of credentialOwners) {
      if (userId !== 0 && value !== userId)
        continue;
      const key = propertyKey;
      const type = key >>> 16;
      const slot = key & 65535;
      if (credentialType !== import_cc.UserCredentialType.None && type !== credentialType) {
        continue;
      }
      for (const valueId of [
        import_UserCredentialCC.UserCredentialCCValues.credential(type, slot),
        import_UserCredentialCC.UserCredentialCCValues.credentialOwner(type, slot),
        import_UserCredentialCC.UserCredentialCCValues.credentialModifierType(type, slot),
        import_UserCredentialCC.UserCredentialCCValues.credentialModifierNodeId(type, slot)
      ]) {
        valueDB.removeValue(valueId.endpoint(endpoint));
      }
    }
  }
  /** Removes all cached user and credential values from the value DB */
  #purgeAllCachedUsersAndCredentials() {
    const valueDB = this.endpoint.tryGetNode()?.valueDB;
    if (!valueDB)
      return;
    const maxUsers = this.getValue(import_UserCredentialCC.UserCredentialCCValues.supportedUsers.endpoint(this.endpoint.index)) ?? 0;
    for (let userId = 1; userId <= maxUsers; userId++) {
      for (const value of [
        import_UserCredentialCC.UserCredentialCCValues.userType(userId),
        import_UserCredentialCC.UserCredentialCCValues.userActive(userId),
        import_UserCredentialCC.UserCredentialCCValues.credentialRule(userId),
        import_UserCredentialCC.UserCredentialCCValues.expiringTimeoutMinutes(userId),
        import_UserCredentialCC.UserCredentialCCValues.userName(userId),
        import_UserCredentialCC.UserCredentialCCValues.userModifierType(userId),
        import_UserCredentialCC.UserCredentialCCValues.userModifierNodeId(userId),
        import_UserCredentialCC.UserCredentialCCValues.userChecksum(userId)
      ]) {
        valueDB.removeValue(value.endpoint(this.endpoint.index));
      }
    }
    const credentialValues = valueDB.findValues((vid) => import_UserCredentialCC.UserCredentialCCValues.credential.is(vid) || import_UserCredentialCC.UserCredentialCCValues.credentialOwner.is(vid) || import_UserCredentialCC.UserCredentialCCValues.credentialModifierType.is(vid) || import_UserCredentialCC.UserCredentialCCValues.credentialModifierNodeId.is(vid));
    for (const vid of credentialValues) {
      valueDB.removeValue(vid);
    }
  }
  /**
   * Resets cached User Code CC slots in the value DB to the cleared state
   * (`userIdStatus = Available`, `userCode = ""`).
   * If `userId` is given, only that slot is reset; otherwise all cached slots are reset.
   */
  #clearCachedUserCodes(userId) {
    const valueDB = this.endpoint.tryGetNode()?.valueDB;
    if (!valueDB)
      return;
    let values = valueDB.findValues((vid) => vid.endpoint === this.endpoint.index && (import_UserCodeCC.UserCodeCCValues.userIdStatus.is(vid) || import_UserCodeCC.UserCodeCCValues.userCode.is(vid)));
    if (userId) {
      values = values.filter((vid) => vid.propertyKey === userId);
    }
    for (const vid of values) {
      if (import_UserCodeCC.UserCodeCCValues.userIdStatus.is(vid)) {
        valueDB.setValue(vid, import_cc.UserIDStatus.Available);
      } else {
        valueDB.setValue(vid, "");
      }
    }
  }
  #mapCredentialData(result) {
    if (!result?.credentialSlot)
      return void 0;
    return {
      userId: result.userId,
      type: result.credentialType,
      slot: result.credentialSlot,
      data: result.credentialData != void 0 ? (0, import_UserCredentialCC.normalizeCredentialData)(result.credentialType, result.credentialData) : void 0
    };
  }
  async #queryCredentials_U3C(userId, startType, startSlot, filterType) {
    const api = this.#u3cAPI();
    const credentials = [];
    let queryType = startType;
    let querySlot = startSlot;
    while (true) {
      const result = await api.getCredential(userId, queryType, querySlot);
      if (result)
        await this.endpoint.tryGetNode()?.handleCommand(result);
      const credential = this.#mapCredentialData(result);
      if (!result || !credential)
        break;
      if (filterType != void 0 && credential.type !== filterType) {
        break;
      }
      credentials.push(credential);
      const nextType = result.nextCredentialType ?? import_cc.UserCredentialType.None;
      const nextSlot = result.nextCredentialSlot ?? 0;
      if (nextType === import_cc.UserCredentialType.None && nextSlot === 0) {
        break;
      }
      if (filterType != void 0 && nextType !== filterType) {
        break;
      }
      if (nextType === queryType && nextSlot === querySlot) {
        break;
      }
      queryType = nextType;
      querySlot = nextSlot;
    }
    return credentials;
  }
  async #getAllCredentials_UC() {
    const api = this.#ucAPI();
    const maxUsers = await api.getUsersCount();
    if (!maxUsers)
      return [];
    const credentials = [];
    const supportsBulk = !!this.getValue(import_UserCodeCC.UserCodeCCValues.supportsMultipleUserCodeReport.endpoint(this.endpoint.index));
    if (supportsBulk) {
      let nextUserId = 1;
      while (nextUserId > 0 && nextUserId <= maxUsers) {
        const response = await api.get(nextUserId, true);
        if (!response)
          break;
        for (const entry of response.userCodes) {
          if (entry.userIdStatus === import_cc.UserIDStatus.Available || entry.userIdStatus === import_cc.UserIDStatus.StatusNotAvailable) {
            continue;
          }
          credentials.push({
            userId: entry.userId,
            type: this.#ucCredentialType,
            slot: entry.userId,
            data: entry.userCode
          });
        }
        nextUserId = response.nextUserId;
      }
    } else {
      for (let userId = 1; userId <= maxUsers; userId++) {
        const credential = await this.getCredential(this.#ucCredentialType, userId);
        if (credential)
          credentials.push(credential);
      }
    }
    return credentials;
  }
  #getAllCredentialsCached_U3C() {
    const valueDB = this.endpoint.tryGetNode()?.valueDB;
    if (!valueDB)
      return [];
    return valueDB.findValues((vid) => import_UserCredentialCC.UserCredentialCCValues.credentialOwner.is(vid) && vid.endpoint === this.endpoint.index).filter(({ propertyKey }) => typeof propertyKey === "number").toSorted((a, b) => a.propertyKey - b.propertyKey).flatMap(({ propertyKey }) => {
      const key = propertyKey;
      const type = key >>> 16;
      const slot = key & 65535;
      const credential = this.#getCredentialCached_U3C(type, slot);
      return credential ? [credential] : [];
    });
  }
  #getAllCredentialsCached_UC() {
    const maxUsers = this.getValue(import_UserCodeCC.UserCodeCCValues.supportedUsers.endpoint(this.endpoint.index)) ?? 0;
    const credentials = [];
    for (let userId = 1; userId <= maxUsers; userId++) {
      const credential = this.#getCredentialCached_UC(this.#ucCredentialType, userId);
      if (credential)
        credentials.push(credential);
    }
    return credentials;
  }
  #assertValidSlot(type, slot) {
    const caps = this.getCredentialCapabilitiesCached().supportedCredentialTypes.get(type);
    if (!caps || slot < 1 || slot > caps.numberOfCredentialSlots) {
      throw new import_core.ZWaveError(`Credential slot ${slot} is out of range for credential type ${(0, import_shared.getEnumMemberName)(import_cc.UserCredentialType, type)}`, import_core.ZWaveErrorCodes.Argument_Invalid);
    }
  }
  #getUserCached_U3C(userId) {
    const userType = this.getValue(import_UserCredentialCC.UserCredentialCCValues.userType(userId).endpoint(this.endpoint.index));
    if (userType == void 0)
      return void 0;
    return {
      userId,
      active: this.getValue(import_UserCredentialCC.UserCredentialCCValues.userActive(userId).endpoint(this.endpoint.index)) ?? false,
      userType,
      userName: this.getValue(import_UserCredentialCC.UserCredentialCCValues.userName(userId).endpoint(this.endpoint.index)) ?? void 0,
      credentialRule: this.getValue(import_UserCredentialCC.UserCredentialCCValues.credentialRule(userId).endpoint(this.endpoint.index)) ?? void 0,
      expiringTimeoutMinutes: this.getValue(import_UserCredentialCC.UserCredentialCCValues.expiringTimeoutMinutes(userId).endpoint(this.endpoint.index)) || void 0
    };
  }
  #getCredentialOwner_U3C(type, slot) {
    return this.getValue(import_UserCredentialCC.UserCredentialCCValues.credentialOwner(type, slot).endpoint(this.endpoint.index));
  }
  #getCredentialCached_U3C(type, slot) {
    const owner = this.#getCredentialOwner_U3C(type, slot);
    if (owner == void 0)
      return void 0;
    const data = this.getValue(import_UserCredentialCC.UserCredentialCCValues.credential(type, slot).endpoint(this.endpoint.index));
    return { userId: owner, type, slot, data };
  }
  #getCredentialCachedForUser_U3C(userId, type, slot) {
    const credential = this.#getCredentialCached_U3C(type, slot);
    if (credential?.userId !== userId)
      return void 0;
    return credential;
  }
  #getUserCached_UC(userId) {
    const status = this.getValue(import_UserCodeCC.UserCodeCCValues.userIdStatus(userId).endpoint(this.endpoint.index));
    if (status == void 0)
      return void 0;
    return this.#mapUserCodeStatusToUserData(userId, status);
  }
  #getCredentialCached_UC(type, slot) {
    if (type !== this.#ucCredentialType)
      return void 0;
    const status = this.getValue(import_UserCodeCC.UserCodeCCValues.userIdStatus(slot).endpoint(this.endpoint.index));
    if (status == void 0 || status === import_cc.UserIDStatus.Available || status === import_cc.UserIDStatus.StatusNotAvailable) {
      return void 0;
    }
    const data = this.getValue(import_UserCodeCC.UserCodeCCValues.userCode(slot).endpoint(this.endpoint.index));
    if (data == void 0)
      return void 0;
    return { userId: slot, type, slot, data };
  }
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  AccessControlAPI,
  AssignCredentialResult,
  SetCredentialResult,
  SetUserResult
});
//# sourceMappingURL=AccessControl.js.map
