import { __esDecorate, __runInitializers } from "tslib";
import * as __validateArgs from "./UserCredentialCC._validateArgs.js";
const { validateArgs_UserCredentialCCAPI_setUser, validateArgs_UserCredentialCCAPI_getUser, validateArgs_UserCredentialCCAPI_setCredential, validateArgs_UserCredentialCCAPI_getCredential, validateArgs_UserCredentialCCAPI_startCredentialLearn, validateArgs_UserCredentialCCAPI_setUserCredentialAssociation, validateArgs_UserCredentialCCAPI_getUserChecksum, validateArgs_UserCredentialCCAPI_getCredentialChecksum, validateArgs_UserCredentialCCAPI_setAdminPinCode, validateArgs_UserCredentialCCAPI_setKeyLockerEntry, validateArgs_UserCredentialCCAPI_getKeyLockerEntry, validateArgs_UserCredentialCCAPI_sendUserCapabilitiesReport, validateArgs_UserCredentialCCAPI_sendCredentialCapabilitiesReport, validateArgs_UserCredentialCCAPI_sendKeyLockerCapabilitiesReport, validateArgs_UserCredentialCCAPI_sendUserReport, validateArgs_UserCredentialCCAPI_sendCredentialReport, validateArgs_UserCredentialCCAPI_sendCredentialLearnReport, validateArgs_UserCredentialCCAPI_sendUserCredentialAssociationReport, validateArgs_UserCredentialCCAPI_sendAllUsersChecksumReport, validateArgs_UserCredentialCCAPI_sendUserChecksumReport, validateArgs_UserCredentialCCAPI_sendCredentialChecksumReport, validateArgs_UserCredentialCCAPI_sendAdminPinCodeReport, validateArgs_UserCredentialCCAPI_sendKeyLockerEntryReport } = __validateArgs;
import { CommandClasses, MessagePriority, ZWaveError, ZWaveErrorCodes, encodeBitMask, parseBitMask, validatePayload, } from "@zwave-js/core";
import { Bytes, getEnumMemberName, pick, stringToUint8ArrayUTF16BE, uint8ArrayToStringUTF16BE, } from "@zwave-js/shared";
import { CCAPI, PhysicalCCAPI } from "../lib/API.js";
import { CommandClass, } from "../lib/CommandClass.js";
import { API, CCCommand, ccValueProperty, ccValues, commandClass, expectedCCResponse, implementedVersion, useSupervision, } from "../lib/CommandClassDecorators.js";
import { UserCredentialAdminCodeOperationResult, UserCredentialCommand, UserCredentialCredentialReportType, UserCredentialKeyLockerEntryType, UserCredentialLearnStatus, UserCredentialModifierType, UserCredentialNameEncoding, UserCredentialOperationType, UserCredentialRule, UserCredentialType, UserCredentialUserReportType, UserCredentialUserType, } from "../lib/_Types.js";
function credentialToLogString(credential) {
    if (credential.length === 0)
        return "(empty)";
    return "*".repeat(credential.length);
}
/**
 * Returns the canonical form of a credential for storage and reporting:
 * text credentials (PIN codes, passwords) are returned as strings, binary
 * credentials (biometric data, BLE/NFC/RFID identifiers, ...) as raw bytes.
 */
export function normalizeCredentialData(credentialType, credentialData) {
    if (credentialType === UserCredentialType.PINCode
        || credentialType === UserCredentialType.Password) {
        return credentialData.toString("utf8");
    }
    return credentialData;
}
import { UserCredentialCCValues } from "./_CCValues.generated.js";
export { UserCredentialCCValues };
// API class
let UserCredentialCCAPI = (() => {
    let _classDecorators = [API(CommandClasses["User Credential"])];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = PhysicalCCAPI;
    let _instanceExtraInitializers = [];
    let _setUser_decorators;
    let _getUser_decorators;
    let _setCredential_decorators;
    let _getCredential_decorators;
    let _startCredentialLearn_decorators;
    let _setUserCredentialAssociation_decorators;
    let _getUserChecksum_decorators;
    let _getCredentialChecksum_decorators;
    let _setAdminPinCode_decorators;
    let _setKeyLockerEntry_decorators;
    let _getKeyLockerEntry_decorators;
    let _sendUserCapabilitiesReport_decorators;
    let _sendCredentialCapabilitiesReport_decorators;
    let _sendKeyLockerCapabilitiesReport_decorators;
    let _sendUserReport_decorators;
    let _sendCredentialReport_decorators;
    let _sendCredentialLearnReport_decorators;
    let _sendUserCredentialAssociationReport_decorators;
    let _sendAllUsersChecksumReport_decorators;
    let _sendUserChecksumReport_decorators;
    let _sendCredentialChecksumReport_decorators;
    let _sendAdminPinCodeReport_decorators;
    let _sendKeyLockerEntryReport_decorators;
    var UserCredentialCCAPI = class extends _classSuper {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            _setUser_decorators = [validateArgs_UserCredentialCCAPI_setUser()];
            _getUser_decorators = [validateArgs_UserCredentialCCAPI_getUser()];
            _setCredential_decorators = [validateArgs_UserCredentialCCAPI_setCredential()];
            _getCredential_decorators = [validateArgs_UserCredentialCCAPI_getCredential()];
            _startCredentialLearn_decorators = [validateArgs_UserCredentialCCAPI_startCredentialLearn()];
            _setUserCredentialAssociation_decorators = [validateArgs_UserCredentialCCAPI_setUserCredentialAssociation()];
            _getUserChecksum_decorators = [validateArgs_UserCredentialCCAPI_getUserChecksum()];
            _getCredentialChecksum_decorators = [validateArgs_UserCredentialCCAPI_getCredentialChecksum()];
            _setAdminPinCode_decorators = [validateArgs_UserCredentialCCAPI_setAdminPinCode()];
            _setKeyLockerEntry_decorators = [validateArgs_UserCredentialCCAPI_setKeyLockerEntry()];
            _getKeyLockerEntry_decorators = [validateArgs_UserCredentialCCAPI_getKeyLockerEntry()];
            _sendUserCapabilitiesReport_decorators = [validateArgs_UserCredentialCCAPI_sendUserCapabilitiesReport()];
            _sendCredentialCapabilitiesReport_decorators = [validateArgs_UserCredentialCCAPI_sendCredentialCapabilitiesReport()];
            _sendKeyLockerCapabilitiesReport_decorators = [validateArgs_UserCredentialCCAPI_sendKeyLockerCapabilitiesReport()];
            _sendUserReport_decorators = [validateArgs_UserCredentialCCAPI_sendUserReport()];
            _sendCredentialReport_decorators = [validateArgs_UserCredentialCCAPI_sendCredentialReport()];
            _sendCredentialLearnReport_decorators = [validateArgs_UserCredentialCCAPI_sendCredentialLearnReport()];
            _sendUserCredentialAssociationReport_decorators = [validateArgs_UserCredentialCCAPI_sendUserCredentialAssociationReport()];
            _sendAllUsersChecksumReport_decorators = [validateArgs_UserCredentialCCAPI_sendAllUsersChecksumReport()];
            _sendUserChecksumReport_decorators = [validateArgs_UserCredentialCCAPI_sendUserChecksumReport()];
            _sendCredentialChecksumReport_decorators = [validateArgs_UserCredentialCCAPI_sendCredentialChecksumReport()];
            _sendAdminPinCodeReport_decorators = [validateArgs_UserCredentialCCAPI_sendAdminPinCodeReport()];
            _sendKeyLockerEntryReport_decorators = [validateArgs_UserCredentialCCAPI_sendKeyLockerEntryReport()];
            __esDecorate(this, null, _setUser_decorators, { kind: "method", name: "setUser", static: false, private: false, access: { has: obj => "setUser" in obj, get: obj => obj.setUser }, metadata: _metadata }, null, _instanceExtraInitializers);
            __esDecorate(this, null, _getUser_decorators, { kind: "method", name: "getUser", static: false, private: false, access: { has: obj => "getUser" in obj, get: obj => obj.getUser }, metadata: _metadata }, null, _instanceExtraInitializers);
            __esDecorate(this, null, _setCredential_decorators, { kind: "method", name: "setCredential", static: false, private: false, access: { has: obj => "setCredential" in obj, get: obj => obj.setCredential }, metadata: _metadata }, null, _instanceExtraInitializers);
            __esDecorate(this, null, _getCredential_decorators, { kind: "method", name: "getCredential", static: false, private: false, access: { has: obj => "getCredential" in obj, get: obj => obj.getCredential }, metadata: _metadata }, null, _instanceExtraInitializers);
            __esDecorate(this, null, _startCredentialLearn_decorators, { kind: "method", name: "startCredentialLearn", static: false, private: false, access: { has: obj => "startCredentialLearn" in obj, get: obj => obj.startCredentialLearn }, metadata: _metadata }, null, _instanceExtraInitializers);
            __esDecorate(this, null, _setUserCredentialAssociation_decorators, { kind: "method", name: "setUserCredentialAssociation", static: false, private: false, access: { has: obj => "setUserCredentialAssociation" in obj, get: obj => obj.setUserCredentialAssociation }, metadata: _metadata }, null, _instanceExtraInitializers);
            __esDecorate(this, null, _getUserChecksum_decorators, { kind: "method", name: "getUserChecksum", static: false, private: false, access: { has: obj => "getUserChecksum" in obj, get: obj => obj.getUserChecksum }, metadata: _metadata }, null, _instanceExtraInitializers);
            __esDecorate(this, null, _getCredentialChecksum_decorators, { kind: "method", name: "getCredentialChecksum", static: false, private: false, access: { has: obj => "getCredentialChecksum" in obj, get: obj => obj.getCredentialChecksum }, metadata: _metadata }, null, _instanceExtraInitializers);
            __esDecorate(this, null, _setAdminPinCode_decorators, { kind: "method", name: "setAdminPinCode", static: false, private: false, access: { has: obj => "setAdminPinCode" in obj, get: obj => obj.setAdminPinCode }, metadata: _metadata }, null, _instanceExtraInitializers);
            __esDecorate(this, null, _setKeyLockerEntry_decorators, { kind: "method", name: "setKeyLockerEntry", static: false, private: false, access: { has: obj => "setKeyLockerEntry" in obj, get: obj => obj.setKeyLockerEntry }, metadata: _metadata }, null, _instanceExtraInitializers);
            __esDecorate(this, null, _getKeyLockerEntry_decorators, { kind: "method", name: "getKeyLockerEntry", static: false, private: false, access: { has: obj => "getKeyLockerEntry" in obj, get: obj => obj.getKeyLockerEntry }, metadata: _metadata }, null, _instanceExtraInitializers);
            __esDecorate(this, null, _sendUserCapabilitiesReport_decorators, { kind: "method", name: "sendUserCapabilitiesReport", static: false, private: false, access: { has: obj => "sendUserCapabilitiesReport" in obj, get: obj => obj.sendUserCapabilitiesReport }, metadata: _metadata }, null, _instanceExtraInitializers);
            __esDecorate(this, null, _sendCredentialCapabilitiesReport_decorators, { kind: "method", name: "sendCredentialCapabilitiesReport", static: false, private: false, access: { has: obj => "sendCredentialCapabilitiesReport" in obj, get: obj => obj.sendCredentialCapabilitiesReport }, metadata: _metadata }, null, _instanceExtraInitializers);
            __esDecorate(this, null, _sendKeyLockerCapabilitiesReport_decorators, { kind: "method", name: "sendKeyLockerCapabilitiesReport", static: false, private: false, access: { has: obj => "sendKeyLockerCapabilitiesReport" in obj, get: obj => obj.sendKeyLockerCapabilitiesReport }, metadata: _metadata }, null, _instanceExtraInitializers);
            __esDecorate(this, null, _sendUserReport_decorators, { kind: "method", name: "sendUserReport", static: false, private: false, access: { has: obj => "sendUserReport" in obj, get: obj => obj.sendUserReport }, metadata: _metadata }, null, _instanceExtraInitializers);
            __esDecorate(this, null, _sendCredentialReport_decorators, { kind: "method", name: "sendCredentialReport", static: false, private: false, access: { has: obj => "sendCredentialReport" in obj, get: obj => obj.sendCredentialReport }, metadata: _metadata }, null, _instanceExtraInitializers);
            __esDecorate(this, null, _sendCredentialLearnReport_decorators, { kind: "method", name: "sendCredentialLearnReport", static: false, private: false, access: { has: obj => "sendCredentialLearnReport" in obj, get: obj => obj.sendCredentialLearnReport }, metadata: _metadata }, null, _instanceExtraInitializers);
            __esDecorate(this, null, _sendUserCredentialAssociationReport_decorators, { kind: "method", name: "sendUserCredentialAssociationReport", static: false, private: false, access: { has: obj => "sendUserCredentialAssociationReport" in obj, get: obj => obj.sendUserCredentialAssociationReport }, metadata: _metadata }, null, _instanceExtraInitializers);
            __esDecorate(this, null, _sendAllUsersChecksumReport_decorators, { kind: "method", name: "sendAllUsersChecksumReport", static: false, private: false, access: { has: obj => "sendAllUsersChecksumReport" in obj, get: obj => obj.sendAllUsersChecksumReport }, metadata: _metadata }, null, _instanceExtraInitializers);
            __esDecorate(this, null, _sendUserChecksumReport_decorators, { kind: "method", name: "sendUserChecksumReport", static: false, private: false, access: { has: obj => "sendUserChecksumReport" in obj, get: obj => obj.sendUserChecksumReport }, metadata: _metadata }, null, _instanceExtraInitializers);
            __esDecorate(this, null, _sendCredentialChecksumReport_decorators, { kind: "method", name: "sendCredentialChecksumReport", static: false, private: false, access: { has: obj => "sendCredentialChecksumReport" in obj, get: obj => obj.sendCredentialChecksumReport }, metadata: _metadata }, null, _instanceExtraInitializers);
            __esDecorate(this, null, _sendAdminPinCodeReport_decorators, { kind: "method", name: "sendAdminPinCodeReport", static: false, private: false, access: { has: obj => "sendAdminPinCodeReport" in obj, get: obj => obj.sendAdminPinCodeReport }, metadata: _metadata }, null, _instanceExtraInitializers);
            __esDecorate(this, null, _sendKeyLockerEntryReport_decorators, { kind: "method", name: "sendKeyLockerEntryReport", static: false, private: false, access: { has: obj => "sendKeyLockerEntryReport" in obj, get: obj => obj.sendKeyLockerEntryReport }, metadata: _metadata }, null, _instanceExtraInitializers);
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            UserCredentialCCAPI = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
            __runInitializers(_classThis, _classExtraInitializers);
        }
        supportsCommand(cmd) {
            switch (cmd) {
                // Mandatory v1 commands
                case UserCredentialCommand.UserCapabilitiesGet:
                case UserCredentialCommand.UserCapabilitiesReport:
                case UserCredentialCommand.CredentialCapabilitiesGet:
                case UserCredentialCommand.CredentialCapabilitiesReport:
                case UserCredentialCommand.UserSet:
                case UserCredentialCommand.UserGet:
                case UserCredentialCommand.UserReport:
                case UserCredentialCommand.CredentialSet:
                case UserCredentialCommand.CredentialGet:
                case UserCredentialCommand.CredentialReport:
                case UserCredentialCommand.CredentialLearnStart:
                case UserCredentialCommand.CredentialLearnCancel:
                case UserCredentialCommand.CredentialLearnReport:
                case UserCredentialCommand.UserCredentialAssociationSet:
                case UserCredentialCommand.UserCredentialAssociationReport:
                    return true;
                case UserCredentialCommand.AllUsersChecksumGet:
                case UserCredentialCommand.AllUsersChecksumReport: {
                    return this.tryGetValueDB()?.getValue(UserCredentialCCValues.supportsAllUsersChecksum.endpoint(this.endpoint.index));
                }
                case UserCredentialCommand.UserChecksumGet:
                case UserCredentialCommand.UserChecksumReport: {
                    return this.tryGetValueDB()?.getValue(UserCredentialCCValues.supportsUserChecksum.endpoint(this.endpoint.index));
                }
                case UserCredentialCommand.CredentialChecksumGet:
                case UserCredentialCommand.CredentialChecksumReport: {
                    return this.tryGetValueDB()?.getValue(UserCredentialCCValues.supportsCredentialChecksum
                        .endpoint(this.endpoint.index));
                }
                case UserCredentialCommand.AdminPinCodeSet:
                case UserCredentialCommand.AdminPinCodeGet:
                case UserCredentialCommand.AdminPinCodeReport: {
                    return this.tryGetValueDB()?.getValue(UserCredentialCCValues.supportsAdminCode.endpoint(this.endpoint.index));
                }
                // V2 commands
                case UserCredentialCommand.KeyLockerCapabilitiesGet:
                case UserCredentialCommand.KeyLockerCapabilitiesReport:
                case UserCredentialCommand.KeyLockerEntrySet:
                case UserCredentialCommand.KeyLockerEntryGet:
                case UserCredentialCommand.KeyLockerEntryReport:
                    return this.version >= 2;
            }
            return super.supportsCommand(cmd);
        }
        // oxlint-disable-next-line typescript/explicit-module-boundary-types
        async getUserCapabilities() {
            this.assertSupportsCommand(UserCredentialCommand, UserCredentialCommand.UserCapabilitiesGet);
            const cc = new UserCredentialCCUserCapabilitiesGet({
                nodeId: this.endpoint.nodeId,
                endpointIndex: this.endpoint.index,
            });
            const response = await this.host.sendCommand(cc, this.commandOptions);
            if (response) {
                return pick(response, [
                    "numberOfSupportedUsers",
                    "supportedCredentialRules",
                    "maxUserNameLength",
                    "supportsUserSchedule",
                    "supportsAllUsersChecksum",
                    "supportsUserChecksum",
                    "supportedUserNameEncodings",
                    "supportedUserTypes",
                ]);
            }
        }
        // oxlint-disable-next-line typescript/explicit-module-boundary-types
        async getCredentialCapabilities() {
            this.assertSupportsCommand(UserCredentialCommand, UserCredentialCommand.CredentialCapabilitiesGet);
            const cc = new UserCredentialCCCredentialCapabilitiesGet({
                nodeId: this.endpoint.nodeId,
                endpointIndex: this.endpoint.index,
            });
            const response = await this.host.sendCommand(cc, this.commandOptions);
            if (response) {
                return pick(response, [
                    "supportsCredentialChecksum",
                    "supportsAdminCode",
                    "supportsAdminCodeDeactivation",
                    "credentialTypes",
                ]);
            }
        }
        // oxlint-disable-next-line typescript/explicit-module-boundary-types
        async getKeyLockerCapabilities() {
            this.assertSupportsCommand(UserCredentialCommand, UserCredentialCommand.KeyLockerCapabilitiesGet);
            const cc = new UserCredentialCCKeyLockerCapabilitiesGet({
                nodeId: this.endpoint.nodeId,
                endpointIndex: this.endpoint.index,
            });
            const response = await this.host.sendCommand(cc, this.commandOptions);
            return response?.keyLockerCapabilities;
        }
        // User Management
        /**
         * Applications should not use this method directly. Prefer the
         * `endpoint.accessControl` API for managing users.
         */
        async setUser(options) {
            this.assertSupportsCommand(UserCredentialCommand, UserCredentialCommand.UserSet);
            const cc = new UserCredentialCCUserSet({
                nodeId: this.endpoint.nodeId,
                endpointIndex: this.endpoint.index,
                ...options,
            });
            return this.host.sendCommand(cc, this.commandOptions);
        }
        /**
         * Applications should not use this method directly. Prefer the
         * `endpoint.accessControl` API for querying users.
         */
        async getUser(userId) {
            this.assertSupportsCommand(UserCredentialCommand, UserCredentialCommand.UserGet);
            const cc = new UserCredentialCCUserGet({
                nodeId: this.endpoint.nodeId,
                endpointIndex: this.endpoint.index,
                userId,
            });
            return this.host.sendCommand(cc, this.commandOptions);
        }
        // Credential Management
        /**
         * Applications should not use this method directly. Prefer the
         * `endpoint.accessControl` API for managing credentials.
         */
        async setCredential(options) {
            this.assertSupportsCommand(UserCredentialCommand, UserCredentialCommand.CredentialSet);
            const cc = new UserCredentialCCCredentialSet({
                nodeId: this.endpoint.nodeId,
                endpointIndex: this.endpoint.index,
                ...options,
            });
            return this.host.sendCommand(cc, this.commandOptions);
        }
        /**
         * Applications should not use this method directly. Prefer the
         * `endpoint.accessControl` API for querying credentials.
         */
        async getCredential(userId, credentialType, credentialSlot) {
            this.assertSupportsCommand(UserCredentialCommand, UserCredentialCommand.CredentialGet);
            const cc = new UserCredentialCCCredentialGet({
                nodeId: this.endpoint.nodeId,
                endpointIndex: this.endpoint.index,
                userId,
                credentialType,
                credentialSlot,
            });
            return this.host.sendCommand(cc, this.commandOptions);
        }
        async startCredentialLearn(options) {
            this.assertSupportsCommand(UserCredentialCommand, UserCredentialCommand.CredentialLearnStart);
            // The node will ignore the command if credential learning is not
            // supported for this credential type (CC:0083.01.0F.11.004)
            const caps = UserCredentialCC.getCredentialCapabilitiesCached(this.host, this.endpoint, options.credentialType);
            if (caps && !caps.supportsCredentialLearn) {
                throw new ZWaveError(`Credential learning is not supported for credential type ${getEnumMemberName(UserCredentialType, options.credentialType)}`, ZWaveErrorCodes.CC_NotSupported);
            }
            const cc = new UserCredentialCCCredentialLearnStart({
                nodeId: this.endpoint.nodeId,
                endpointIndex: this.endpoint.index,
                ...options,
            });
            return this.host.sendCommand(cc, this.commandOptions);
        }
        async cancelCredentialLearn() {
            this.assertSupportsCommand(UserCredentialCommand, UserCredentialCommand.CredentialLearnCancel);
            const cc = new UserCredentialCCCredentialLearnCancel({
                nodeId: this.endpoint.nodeId,
                endpointIndex: this.endpoint.index,
            });
            return this.host.sendCommand(cc, this.commandOptions);
        }
        /**
         * Applications should not use this method directly. Prefer the
         * `endpoint.accessControl` API for reassigning credentials between users.
         */
        async setUserCredentialAssociation(options) {
            this.assertSupportsCommand(UserCredentialCommand, UserCredentialCommand.UserCredentialAssociationSet);
            const cc = new UserCredentialCCAssociationSet({
                nodeId: this.endpoint.nodeId,
                endpointIndex: this.endpoint.index,
                ...options,
            });
            return this.host.sendCommand(cc, this.commandOptions);
        }
        // oxlint-disable-next-line typescript/explicit-module-boundary-types
        async getAllUsersChecksum() {
            this.assertSupportsCommand(UserCredentialCommand, UserCredentialCommand.AllUsersChecksumGet);
            const cc = new UserCredentialCCAllUsersChecksumGet({
                nodeId: this.endpoint.nodeId,
                endpointIndex: this.endpoint.index,
            });
            const response = await this.host.sendCommand(cc, this.commandOptions);
            return response?.checksum;
        }
        async getUserChecksum(userId) {
            this.assertSupportsCommand(UserCredentialCommand, UserCredentialCommand.UserChecksumGet);
            const cc = new UserCredentialCCUserChecksumGet({
                nodeId: this.endpoint.nodeId,
                endpointIndex: this.endpoint.index,
                userId,
            });
            const response = await this.host.sendCommand(cc, this.commandOptions);
            return response?.checksum;
        }
        async getCredentialChecksum(credentialType) {
            this.assertSupportsCommand(UserCredentialCommand, UserCredentialCommand.CredentialChecksumGet);
            const cc = new UserCredentialCCCredentialChecksumGet({
                nodeId: this.endpoint.nodeId,
                endpointIndex: this.endpoint.index,
                credentialType,
            });
            const response = await this.host.sendCommand(cc, this.commandOptions);
            return response?.checksum;
        }
        async setAdminPinCode(options) {
            this.assertSupportsCommand(UserCredentialCommand, UserCredentialCommand.AdminPinCodeSet);
            // Deactivating the admin code (empty string) requires ACD support,
            // otherwise the node may ignore the command (CC:0083.01.1A.13.003)
            if (options.pinCode.length === 0) {
                const supportsDeactivation = this.tryGetValueDB()?.getValue(UserCredentialCCValues.supportsAdminCodeDeactivation.endpoint(this.endpoint.index));
                if (supportsDeactivation === false) {
                    throw new ZWaveError("This node does not support deactivating the Admin Code", ZWaveErrorCodes.CC_NotSupported);
                }
            }
            const cc = new UserCredentialCCAdminPinCodeSet({
                nodeId: this.endpoint.nodeId,
                endpointIndex: this.endpoint.index,
                ...options,
            });
            return this.host.sendCommand(cc, this.commandOptions);
        }
        // oxlint-disable-next-line typescript/explicit-module-boundary-types
        async getAdminPinCode() {
            this.assertSupportsCommand(UserCredentialCommand, UserCredentialCommand.AdminPinCodeGet);
            const cc = new UserCredentialCCAdminPinCodeGet({
                nodeId: this.endpoint.nodeId,
                endpointIndex: this.endpoint.index,
            });
            const response = await this.host.sendCommand(cc, this.commandOptions);
            return response?.pinCode;
        }
        async setKeyLockerEntry(options) {
            this.assertSupportsCommand(UserCredentialCommand, UserCredentialCommand.KeyLockerEntrySet);
            const cc = new UserCredentialCCKeyLockerEntrySet({
                nodeId: this.endpoint.nodeId,
                endpointIndex: this.endpoint.index,
                ...options,
            });
            return this.host.sendCommand(cc, this.commandOptions);
        }
        async getKeyLockerEntry(entryType, entrySlot) {
            this.assertSupportsCommand(UserCredentialCommand, UserCredentialCommand.KeyLockerEntryGet);
            const cc = new UserCredentialCCKeyLockerEntryGet({
                nodeId: this.endpoint.nodeId,
                endpointIndex: this.endpoint.index,
                entryType,
                entrySlot,
            });
            const response = await this.host.sendCommand(cc, this.commandOptions);
            if (response) {
                return pick(response, [
                    "occupied",
                    "entryType",
                    "entrySlot",
                ]);
            }
        }
        async sendUserCapabilitiesReport(options) {
            this.assertSupportsCommand(UserCredentialCommand, UserCredentialCommand.UserCapabilitiesReport);
            const cc = new UserCredentialCCUserCapabilitiesReport({
                nodeId: this.endpoint.nodeId,
                endpointIndex: this.endpoint.index,
                ...options,
            });
            return this.host.sendCommand(cc, this.commandOptions);
        }
        async sendCredentialCapabilitiesReport(options) {
            this.assertSupportsCommand(UserCredentialCommand, UserCredentialCommand.CredentialCapabilitiesReport);
            const cc = new UserCredentialCCCredentialCapabilitiesReport({
                nodeId: this.endpoint.nodeId,
                endpointIndex: this.endpoint.index,
                ...options,
            });
            return this.host.sendCommand(cc, this.commandOptions);
        }
        async sendKeyLockerCapabilitiesReport(options) {
            this.assertSupportsCommand(UserCredentialCommand, UserCredentialCommand.KeyLockerCapabilitiesReport);
            const cc = new UserCredentialCCKeyLockerCapabilitiesReport({
                nodeId: this.endpoint.nodeId,
                endpointIndex: this.endpoint.index,
                ...options,
            });
            return this.host.sendCommand(cc, this.commandOptions);
        }
        async sendUserReport(options) {
            this.assertSupportsCommand(UserCredentialCommand, UserCredentialCommand.UserReport);
            const cc = new UserCredentialCCUserReport({
                nodeId: this.endpoint.nodeId,
                endpointIndex: this.endpoint.index,
                ...options,
            });
            return this.host.sendCommand(cc, this.commandOptions);
        }
        async sendCredentialReport(options) {
            this.assertSupportsCommand(UserCredentialCommand, UserCredentialCommand.CredentialReport);
            const cc = new UserCredentialCCCredentialReport({
                nodeId: this.endpoint.nodeId,
                endpointIndex: this.endpoint.index,
                ...options,
            });
            return this.host.sendCommand(cc, this.commandOptions);
        }
        async sendCredentialLearnReport(options) {
            this.assertSupportsCommand(UserCredentialCommand, UserCredentialCommand.CredentialLearnReport);
            const cc = new UserCredentialCCCredentialLearnReport({
                nodeId: this.endpoint.nodeId,
                endpointIndex: this.endpoint.index,
                ...options,
            });
            return this.host.sendCommand(cc, this.commandOptions);
        }
        async sendUserCredentialAssociationReport(options) {
            this.assertSupportsCommand(UserCredentialCommand, UserCredentialCommand.UserCredentialAssociationReport);
            const cc = new UserCredentialCCAssociationReport({
                nodeId: this.endpoint.nodeId,
                endpointIndex: this.endpoint.index,
                ...options,
            });
            return this.host.sendCommand(cc, this.commandOptions);
        }
        async sendAllUsersChecksumReport(options) {
            this.assertSupportsCommand(UserCredentialCommand, UserCredentialCommand.AllUsersChecksumReport);
            const cc = new UserCredentialCCAllUsersChecksumReport({
                nodeId: this.endpoint.nodeId,
                endpointIndex: this.endpoint.index,
                ...options,
            });
            return this.host.sendCommand(cc, this.commandOptions);
        }
        async sendUserChecksumReport(options) {
            this.assertSupportsCommand(UserCredentialCommand, UserCredentialCommand.UserChecksumReport);
            const cc = new UserCredentialCCUserChecksumReport({
                nodeId: this.endpoint.nodeId,
                endpointIndex: this.endpoint.index,
                ...options,
            });
            return this.host.sendCommand(cc, this.commandOptions);
        }
        async sendCredentialChecksumReport(options) {
            this.assertSupportsCommand(UserCredentialCommand, UserCredentialCommand.CredentialChecksumReport);
            const cc = new UserCredentialCCCredentialChecksumReport({
                nodeId: this.endpoint.nodeId,
                endpointIndex: this.endpoint.index,
                ...options,
            });
            return this.host.sendCommand(cc, this.commandOptions);
        }
        async sendAdminPinCodeReport(options) {
            this.assertSupportsCommand(UserCredentialCommand, UserCredentialCommand.AdminPinCodeReport);
            const cc = new UserCredentialCCAdminPinCodeReport({
                nodeId: this.endpoint.nodeId,
                endpointIndex: this.endpoint.index,
                ...options,
            });
            return this.host.sendCommand(cc, this.commandOptions);
        }
        async sendKeyLockerEntryReport(options) {
            this.assertSupportsCommand(UserCredentialCommand, UserCredentialCommand.KeyLockerEntryReport);
            const cc = new UserCredentialCCKeyLockerEntryReport({
                nodeId: this.endpoint.nodeId,
                endpointIndex: this.endpoint.index,
                ...options,
            });
            return this.host.sendCommand(cc, this.commandOptions);
        }
        constructor() {
            super(...arguments);
            __runInitializers(this, _instanceExtraInitializers);
        }
    };
    return UserCredentialCCAPI = _classThis;
})();
export { UserCredentialCCAPI };
let UserCredentialCC = (() => {
    let _classDecorators = [commandClass(CommandClasses["User Credential"]), implementedVersion(2), ccValues(UserCredentialCCValues)];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = CommandClass;
    var UserCredentialCC = class extends _classSuper {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            UserCredentialCC = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
            __runInitializers(_classThis, _classExtraInitializers);
        }
        async interview(ctx) {
            const node = this.getNode(ctx);
            const endpoint = this.getEndpoint(ctx);
            const api = CCAPI.create(CommandClasses["User Credential"], ctx, endpoint).withOptions({
                priority: MessagePriority.NodeQuery,
            });
            ctx.logNode(node.id, {
                endpoint: this.endpointIndex,
                message: "querying user capabilities...",
                direction: "outbound",
            });
            const userCaps = await api.getUserCapabilities();
            if (!userCaps) {
                ctx.logNode(node.id, {
                    endpoint: this.endpointIndex,
                    message: "User capabilities query timed out - skipping interview",
                    level: "warn",
                });
                return;
            }
            ctx.logNode(node.id, {
                endpoint: this.endpointIndex,
                message: "querying credential capabilities...",
                direction: "outbound",
            });
            const credCaps = await api.getCredentialCapabilities();
            if (!credCaps) {
                ctx.logNode(node.id, {
                    endpoint: this.endpointIndex,
                    message: "Credential capabilities query timed out - skipping interview",
                    level: "warn",
                });
                return;
            }
            if (api.version >= 2) {
                ctx.logNode(node.id, {
                    endpoint: this.endpointIndex,
                    message: "querying key locker capabilities...",
                    direction: "outbound",
                });
                await api.getKeyLockerCapabilities();
            }
            await this.refreshValues(ctx);
            this.setInterviewComplete(ctx, true);
        }
        async refreshValues(ctx) {
            const node = this.getNode(ctx);
            const endpoint = this.getEndpoint(ctx);
            const api = CCAPI.create(CommandClasses["User Credential"], ctx, endpoint).withOptions({
                priority: MessagePriority.NodeQuery,
            });
            const supportsAllUsersChecksum = this.getValue(ctx, UserCredentialCCValues.supportsAllUsersChecksum);
            const supportsUserChecksum = this.getValue(ctx, UserCredentialCCValues.supportsUserChecksum);
            const supportsAdminCode = this.getValue(ctx, UserCredentialCCValues.supportsAdminCode);
            const supportedKeyLockerEntryTypes = this.getValue(ctx, UserCredentialCCValues.supportedKeyLockerEntryTypes);
            // If possible use the all-users checksum to determine whether to
            // skip full sync of all users and credentials
            let skipFullSync = false;
            let allUsersChecksum;
            if (supportsAllUsersChecksum) {
                allUsersChecksum = await api.getAllUsersChecksum();
                const cachedChecksum = this.getValue(ctx, UserCredentialCCValues.allUsersChecksum);
                if (allUsersChecksum != undefined
                    && cachedChecksum != undefined
                    && allUsersChecksum === cachedChecksum) {
                    ctx.logNode(node.id, {
                        endpoint: this.endpointIndex,
                        message: "all-users checksum unchanged, skipping full sync",
                        direction: "none",
                    });
                    skipFullSync = true;
                }
            }
            if (!skipFullSync) {
                // Iterate all users starting from UUID 0
                let nextUserId = 0;
                let previousUserId = 0;
                do {
                    ctx.logNode(node.id, {
                        endpoint: this.endpointIndex,
                        message: `querying user with UUID ${nextUserId}...`,
                        direction: "outbound",
                    });
                    const user = await api.getUser(nextUserId);
                    if (!user?.userId)
                        break; // No user found, stop iterating
                    const currentUserId = user.userId;
                    // Purge cached data for any users in the gap between the
                    // last reported user and this one
                    for (let gapUserId = previousUserId + 1; gapUserId < currentUserId; gapUserId++) {
                        this.purgeUserFromCache(ctx, gapUserId);
                    }
                    // If possible use the checksum to determine whether to sync
                    // credentials for this user
                    let userChecksum;
                    let syncCredentials = true;
                    if (supportsUserChecksum) {
                        userChecksum = await api.getUserChecksum(currentUserId);
                        const cachedUserChecksum = this.getValue(ctx, UserCredentialCCValues.userChecksum(currentUserId));
                        if (userChecksum != undefined
                            && cachedUserChecksum != undefined
                            && userChecksum === cachedUserChecksum) {
                            ctx.logNode(node.id, {
                                endpoint: this.endpointIndex,
                                message: `user ${currentUserId} checksum unchanged, skipping credential sync`,
                                direction: "none",
                            });
                            syncCredentials = false;
                        }
                    }
                    if (syncCredentials) {
                        await this.queryCredentialsForUser(ctx, api, node.id, currentUserId);
                        if (userChecksum != undefined) {
                            this.setValue(ctx, UserCredentialCCValues.userChecksum(currentUserId), userChecksum);
                        }
                    }
                    previousUserId = currentUserId;
                    nextUserId = user.nextUserId ?? 0;
                } while (nextUserId > 0);
            }
            // After querying all users, save the checksum for the next refresh.
            if (allUsersChecksum != undefined) {
                this.setValue(ctx, UserCredentialCCValues.allUsersChecksum, allUsersChecksum);
            }
            // Query admin PIN code if supported
            if (supportsAdminCode) {
                ctx.logNode(node.id, {
                    endpoint: this.endpointIndex,
                    message: "querying admin PIN code...",
                    direction: "outbound",
                });
                await api.getAdminPinCode();
            }
            // Query key locker entries (V2)
            if (api.version >= 2 && supportedKeyLockerEntryTypes?.length) {
                for (const entryType of supportedKeyLockerEntryTypes) {
                    const entry = this.getValue(ctx, UserCredentialCCValues.keyLockerCapabilities(entryType));
                    if (!entry)
                        continue;
                    for (let slot = 1; slot <= entry.numberOfEntrySlots; slot++) {
                        ctx.logNode(node.id, {
                            endpoint: this.endpointIndex,
                            message: `querying key locker entry type ${entryType}, slot ${slot}...`,
                            direction: "outbound",
                        });
                        await api.getKeyLockerEntry(entryType, slot);
                    }
                }
            }
        }
        purgeUserFromCache(ctx, userId) {
            // Remove all per-user values
            this.removeValue(ctx, UserCredentialCCValues.userType(userId));
            this.removeValue(ctx, UserCredentialCCValues.userActive(userId));
            this.removeValue(ctx, UserCredentialCCValues.credentialRule(userId));
            this.removeValue(ctx, UserCredentialCCValues.expiringTimeoutMinutes(userId));
            this.removeValue(ctx, UserCredentialCCValues.userName(userId));
            this.removeValue(ctx, UserCredentialCCValues.userModifierType(userId));
            this.removeValue(ctx, UserCredentialCCValues.userModifierNodeId(userId));
            this.removeValue(ctx, UserCredentialCCValues.userChecksum(userId));
            // Remove all credential values for this user
            const valueDB = this.getValueDB(ctx);
            const credentialOwners = valueDB.findValues((vid) => UserCredentialCCValues.credentialOwner.is(vid)
                && vid.endpoint === this.endpointIndex);
            for (const { endpoint, propertyKey, value } of credentialOwners) {
                if (value !== userId)
                    continue;
                const key = propertyKey;
                const credentialType = key >>> 16;
                const credentialSlot = key & 0xffff;
                valueDB.removeValue(UserCredentialCCValues.credential(credentialType, credentialSlot).endpoint(endpoint));
                valueDB.removeValue(UserCredentialCCValues.credentialOwner(credentialType, credentialSlot).endpoint(endpoint));
                valueDB.removeValue(UserCredentialCCValues.credentialModifierType(credentialType, credentialSlot).endpoint(endpoint));
                valueDB.removeValue(UserCredentialCCValues.credentialModifierNodeId(credentialType, credentialSlot).endpoint(endpoint));
            }
        }
        async queryCredentialsForUser(ctx, api, nodeId, userId) {
            // Start with credential type 0, slot 0 to get the first credential for this user
            let nextCredType = UserCredentialType.None;
            let nextCredSlot = 0;
            do {
                ctx.logNode(nodeId, {
                    endpoint: this.endpointIndex,
                    message: `querying credential for user ${userId}, type ${nextCredType}, slot ${nextCredSlot}...`,
                    direction: "outbound",
                });
                const cred = await api.getCredential(userId, nextCredType, nextCredSlot);
                if (!cred?.credentialSlot)
                    break; // No credential found, stop iterating
                nextCredType = cred.nextCredentialType ?? UserCredentialType.None;
                nextCredSlot = cred.nextCredentialSlot ?? 0;
            } while (nextCredType !== UserCredentialType.None || nextCredSlot !== 0);
        }
        static getSupportedUsersCached(ctx, endpoint) {
            return ctx
                .getValueDB(endpoint.nodeId)
                .getValue(UserCredentialCCValues.supportedUsers.endpoint(endpoint.index));
        }
        static getSupportedCredentialTypesCached(ctx, endpoint) {
            return ctx
                .getValueDB(endpoint.nodeId)
                .getValue(UserCredentialCCValues.supportedCredentialTypes.endpoint(endpoint.index));
        }
        static getCredentialCapabilitiesCached(ctx, endpoint, credentialType) {
            return ctx
                .getValueDB(endpoint.nodeId)
                .getValue(UserCredentialCCValues.credentialCapabilities(credentialType).endpoint(endpoint.index));
        }
        static supportsAdminCodeCached(ctx, endpoint) {
            return (ctx
                .getValueDB(endpoint.nodeId)
                .getValue(UserCredentialCCValues.supportsAdminCode.endpoint(endpoint.index)) ?? false);
        }
    };
    return UserCredentialCC = _classThis;
})();
export { UserCredentialCC };
let UserCredentialCCUserCapabilitiesReport = (() => {
    let _classDecorators = [CCCommand(UserCredentialCommand.UserCapabilitiesReport), ccValueProperty("numberOfSupportedUsers", UserCredentialCCValues.supportedUsers), ccValueProperty("supportedCredentialRules", UserCredentialCCValues.supportedCredentialRules), ccValueProperty("maxUserNameLength", UserCredentialCCValues.maxUserNameLength), ccValueProperty("supportsUserSchedule", UserCredentialCCValues.supportsUserSchedule), ccValueProperty("supportsAllUsersChecksum", UserCredentialCCValues.supportsAllUsersChecksum), ccValueProperty("supportsUserChecksum", UserCredentialCCValues.supportsUserChecksum), ccValueProperty("supportedUserNameEncodings", UserCredentialCCValues.supportedUserNameEncodings), ccValueProperty("supportedUserTypes", UserCredentialCCValues.supportedUserTypes)];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = UserCredentialCC;
    var UserCredentialCCUserCapabilitiesReport = class extends _classSuper {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            UserCredentialCCUserCapabilitiesReport = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
            __runInitializers(_classThis, _classExtraInitializers);
        }
        constructor(options) {
            super(options);
            this.numberOfSupportedUsers = options.numberOfSupportedUsers;
            this.supportedCredentialRules = options.supportedCredentialRules;
            this.maxUserNameLength = options.maxUserNameLength;
            this.supportsUserSchedule = options.supportsUserSchedule;
            this.supportsAllUsersChecksum = options.supportsAllUsersChecksum;
            this.supportsUserChecksum = options.supportsUserChecksum;
            this.supportedUserNameEncodings = options.supportedUserNameEncodings;
            this.supportedUserTypes = options.supportedUserTypes;
        }
        static from(raw, ctx) {
            validatePayload(raw.payload.length >= 4);
            const numberOfSupportedUsers = raw.payload.readUInt16BE(0);
            const credentialRulesBitmask = raw.payload[2];
            const supportedCredentialRules = parseBitMask(Bytes.from([credentialRulesBitmask]), 0).filter((v) => v in UserCredentialRule);
            const maxUserNameLength = raw.payload[3];
            validatePayload(raw.payload.length >= 5);
            const flagsByte = raw.payload[4];
            const supportsUserSchedule = !!(flagsByte & 128);
            const supportsAllUsersChecksum = !!(flagsByte & 64);
            const supportsUserChecksum = !!(flagsByte & 32);
            // Name encoding bitmask in bits 4:2
            const nameEncodingBitmask = (flagsByte >> 2) & 0b111;
            let supportedUserNameEncodings;
            if (nameEncodingBitmask === 0) {
                // All encodings assumed supported per spec
                supportedUserNameEncodings = [
                    UserCredentialNameEncoding.ASCII,
                    UserCredentialNameEncoding.ExtendedASCII,
                    UserCredentialNameEncoding.UTF16BE,
                ];
            }
            else {
                supportedUserNameEncodings = parseBitMask(Bytes.from([nameEncodingBitmask]), 0).filter((v) => v in UserCredentialNameEncoding);
            }
            validatePayload(raw.payload.length >= 6);
            const userTypesBitmaskLength = raw.payload[5];
            validatePayload(raw.payload.length >= 6 + userTypesBitmaskLength);
            const supportedUserTypes = parseBitMask(raw.payload.subarray(6, 6 + userTypesBitmaskLength), 0).filter((v) => v in UserCredentialUserType);
            return new this({
                nodeId: ctx.sourceNodeId,
                numberOfSupportedUsers,
                supportedCredentialRules,
                maxUserNameLength,
                supportsUserSchedule,
                supportsAllUsersChecksum,
                supportsUserChecksum,
                supportedUserNameEncodings,
                supportedUserTypes,
            });
        }
        numberOfSupportedUsers;
        supportedCredentialRules;
        maxUserNameLength;
        supportsUserSchedule;
        supportsAllUsersChecksum;
        supportsUserChecksum;
        supportedUserNameEncodings;
        supportedUserTypes;
        serialize(ctx) {
            const credentialRulesBitmask = encodeBitMask(this.supportedCredentialRules, UserCredentialRule.Triple, 0);
            const nameEncodingBitmask = encodeBitMask(this.supportedUserNameEncodings, UserCredentialNameEncoding.UTF16BE, UserCredentialNameEncoding.ASCII);
            const flagsByte = (this.supportsUserSchedule ? 0x80 : 0)
                | (this.supportsAllUsersChecksum ? 0x40 : 0)
                | (this.supportsUserChecksum ? 0x20 : 0)
                | ((nameEncodingBitmask[0] & 0b111) << 2);
            const userTypesBitmask = encodeBitMask(this.supportedUserTypes, UserCredentialUserType.RemoteOnly, UserCredentialUserType.General);
            this.payload = Bytes.alloc(6 + userTypesBitmask.length);
            this.payload.writeUInt16BE(this.numberOfSupportedUsers, 0);
            this.payload[2] = credentialRulesBitmask[0];
            this.payload[3] = this.maxUserNameLength;
            this.payload[4] = flagsByte;
            this.payload[5] = userTypesBitmask.length;
            this.payload.set(userTypesBitmask, 6);
            return super.serialize(ctx);
        }
        toLogEntry(ctx) {
            return {
                ...super.toLogEntry(ctx),
                message: {
                    "supported users": this.numberOfSupportedUsers,
                    "supported credential rules": this.supportedCredentialRules
                        .map((r) => getEnumMemberName(UserCredentialRule, r))
                        .join(", "),
                    "max user name length": this.maxUserNameLength,
                    "user schedule support": this.supportsUserSchedule,
                    "all users checksum support": this.supportsAllUsersChecksum,
                    "user checksum support": this.supportsUserChecksum,
                    "supported name encodings": this.supportedUserNameEncodings
                        .map((e) => getEnumMemberName(UserCredentialNameEncoding, e))
                        .join(", "),
                    "supported user types": this.supportedUserTypes
                        .map((t) => getEnumMemberName(UserCredentialUserType, t))
                        .join(", "),
                },
            };
        }
    };
    return UserCredentialCCUserCapabilitiesReport = _classThis;
})();
export { UserCredentialCCUserCapabilitiesReport };
let UserCredentialCCUserCapabilitiesGet = (() => {
    let _classDecorators = [CCCommand(UserCredentialCommand.UserCapabilitiesGet), expectedCCResponse(UserCredentialCCUserCapabilitiesReport)];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = UserCredentialCC;
    var UserCredentialCCUserCapabilitiesGet = class extends _classSuper {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            UserCredentialCCUserCapabilitiesGet = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
            __runInitializers(_classThis, _classExtraInitializers);
        }
    };
    return UserCredentialCCUserCapabilitiesGet = _classThis;
})();
export { UserCredentialCCUserCapabilitiesGet };
let UserCredentialCCCredentialCapabilitiesReport = (() => {
    let _classDecorators = [CCCommand(UserCredentialCommand.CredentialCapabilitiesReport), ccValueProperty("supportsCredentialChecksum", UserCredentialCCValues.supportsCredentialChecksum), ccValueProperty("supportsAdminCode", UserCredentialCCValues.supportsAdminCode), ccValueProperty("supportsAdminCodeDeactivation", UserCredentialCCValues.supportsAdminCodeDeactivation)];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = UserCredentialCC;
    var UserCredentialCCCredentialCapabilitiesReport = class extends _classSuper {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            UserCredentialCCCredentialCapabilitiesReport = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
            __runInitializers(_classThis, _classExtraInitializers);
        }
        constructor(options) {
            super(options);
            this.supportsCredentialChecksum = options.supportsCredentialChecksum;
            this.supportsAdminCode = options.supportsAdminCode;
            this.supportsAdminCodeDeactivation =
                options.supportsAdminCodeDeactivation;
            this.credentialTypes = options.credentialTypes;
        }
        static from(raw, ctx) {
            validatePayload(raw.payload.length >= 2);
            const flagsByte = raw.payload[0];
            const supportsCredentialChecksum = !!(flagsByte & 128);
            const supportsAdminCode = !!(flagsByte & 64);
            const supportsAdminCodeDeactivation = !!(flagsByte & 32);
            const numberOfCredentialTypes = raw.payload[1];
            const n = numberOfCredentialTypes;
            validatePayload(raw.payload.length >= 2 + n * 9);
            const credentialTypes = new Map();
            // Grouped block offsets
            const credTypeOff = 2;
            const clSupportOff = credTypeOff + n;
            const numSlotsOff = clSupportOff + n;
            const minLenOff = numSlotsOff + n * 2;
            const maxLenOff = minLenOff + n;
            const clTimeoutOff = maxLenOff + n;
            const clStepsOff = clTimeoutOff + n;
            const maxHashLenOff = clStepsOff + n;
            for (let i = 0; i < n; i++) {
                const credentialType = raw.payload[credTypeOff + i];
                const clByte = raw.payload[clSupportOff + i];
                const supportsCredentialLearn = !!(clByte & 128);
                const numberOfCredentialSlots = raw.payload.readUInt16BE(numSlotsOff + i * 2);
                const minCredentialLength = raw.payload[minLenOff + i];
                const maxCredentialLength = raw.payload[maxLenOff + i];
                const credentialLearnRecommendedTimeout = raw.payload[clTimeoutOff + i];
                const credentialLearnNumberOfSteps = raw.payload[clStepsOff + i];
                const maxCredentialHashLength = raw.payload[maxHashLenOff + i];
                if (supportsCredentialLearn) {
                    validatePayload(credentialLearnRecommendedTimeout > 0);
                    validatePayload(credentialLearnNumberOfSteps > 0);
                    credentialTypes.set(credentialType, {
                        supportsCredentialLearn,
                        numberOfCredentialSlots,
                        minCredentialLength,
                        maxCredentialLength,
                        credentialLearnRecommendedTimeout,
                        credentialLearnNumberOfSteps,
                        maxCredentialHashLength,
                    });
                }
                else {
                    validatePayload(credentialLearnRecommendedTimeout === 0);
                    validatePayload(credentialLearnNumberOfSteps === 0);
                    credentialTypes.set(credentialType, {
                        supportsCredentialLearn,
                        numberOfCredentialSlots,
                        minCredentialLength,
                        maxCredentialLength,
                        maxCredentialHashLength,
                    });
                }
            }
            return new this({
                nodeId: ctx.sourceNodeId,
                supportsCredentialChecksum,
                supportsAdminCode,
                supportsAdminCodeDeactivation,
                credentialTypes: credentialTypes,
            });
        }
        supportsCredentialChecksum;
        supportsAdminCode;
        supportsAdminCodeDeactivation;
        credentialTypes;
        persistValues(ctx) {
            if (!super.persistValues(ctx))
                return false;
            this.setValue(ctx, UserCredentialCCValues.supportedCredentialTypes, [...this.credentialTypes.keys()]);
            for (const [credentialType, capability] of this.credentialTypes) {
                this.setValue(ctx, UserCredentialCCValues.credentialCapabilities(credentialType), capability);
            }
            return true;
        }
        serialize(ctx) {
            const n = this.credentialTypes.size;
            this.payload = Bytes.alloc(2 + n * 9);
            this.payload[0] = (this.supportsCredentialChecksum ? 0x80 : 0)
                | (this.supportsAdminCode ? 0x40 : 0)
                | (this.supportsAdminCodeDeactivation ? 0x20 : 0);
            this.payload[1] = n;
            const credTypeOff = 2;
            const clSupportOff = credTypeOff + n;
            const numSlotsOff = clSupportOff + n;
            const minLenOff = numSlotsOff + n * 2;
            const maxLenOff = minLenOff + n;
            const clTimeoutOff = maxLenOff + n;
            const clStepsOff = clTimeoutOff + n;
            const maxHashLenOff = clStepsOff + n;
            let i = 0;
            for (const [credentialType, ct] of this.credentialTypes) {
                this.payload[credTypeOff + i] = credentialType;
                this.payload[clSupportOff + i] = ct.supportsCredentialLearn
                    ? 0x80
                    : 0;
                this.payload.writeUInt16BE(ct.numberOfCredentialSlots, numSlotsOff + i * 2);
                this.payload[minLenOff + i] = ct.minCredentialLength;
                this.payload[maxLenOff + i] = ct.maxCredentialLength;
                this.payload[clTimeoutOff + i] =
                    ct.credentialLearnRecommendedTimeout ?? 0;
                this.payload[clStepsOff + i] = ct.credentialLearnNumberOfSteps ?? 0;
                this.payload[maxHashLenOff + i] = ct.maxCredentialHashLength;
                i++;
            }
            return super.serialize(ctx);
        }
        toLogEntry(ctx) {
            const message = {
                "credential checksum support": this.supportsCredentialChecksum,
                "admin code support": this.supportsAdminCode,
                "admin code deactivation support": this.supportsAdminCodeDeactivation,
            };
            for (const [credentialType, ct] of this.credentialTypes) {
                message[`credential type ${getEnumMemberName(UserCredentialType, credentialType)}`] = `slots: ${ct.numberOfCredentialSlots}, length: ${ct.minCredentialLength}-${ct.maxCredentialLength}`;
            }
            return {
                ...super.toLogEntry(ctx),
                message,
            };
        }
    };
    return UserCredentialCCCredentialCapabilitiesReport = _classThis;
})();
export { UserCredentialCCCredentialCapabilitiesReport };
let UserCredentialCCCredentialCapabilitiesGet = (() => {
    let _classDecorators = [CCCommand(UserCredentialCommand.CredentialCapabilitiesGet), expectedCCResponse(UserCredentialCCCredentialCapabilitiesReport)];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = UserCredentialCC;
    var UserCredentialCCCredentialCapabilitiesGet = class extends _classSuper {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            UserCredentialCCCredentialCapabilitiesGet = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
            __runInitializers(_classThis, _classExtraInitializers);
        }
    };
    return UserCredentialCCCredentialCapabilitiesGet = _classThis;
})();
export { UserCredentialCCCredentialCapabilitiesGet };
let UserCredentialCCKeyLockerCapabilitiesReport = (() => {
    let _classDecorators = [CCCommand(UserCredentialCommand.KeyLockerCapabilitiesReport)];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = UserCredentialCC;
    var UserCredentialCCKeyLockerCapabilitiesReport = class extends _classSuper {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            UserCredentialCCKeyLockerCapabilitiesReport = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
            __runInitializers(_classThis, _classExtraInitializers);
        }
        constructor(options) {
            super(options);
            this.keyLockerCapabilities = options.keyLockerCapabilities;
        }
        static from(raw, ctx) {
            validatePayload(raw.payload.length >= 1);
            const numberOfEntryTypes = raw.payload[0];
            const n = numberOfEntryTypes;
            validatePayload(raw.payload.length >= 1 + n * 7);
            const keyLockerCapabilities = new Map();
            // Grouped block offsets
            const entryTypeOff = 1;
            const numSlotsOff = entryTypeOff + n;
            const minLenOff = numSlotsOff + n * 2;
            const maxLenOff = minLenOff + n * 2;
            for (let i = 0; i < n; i++) {
                const entryType = raw.payload[entryTypeOff + i];
                const numberOfEntrySlots = raw.payload.readUInt16BE(numSlotsOff + i * 2);
                const minEntryDataLength = raw.payload.readUInt16BE(minLenOff + i * 2);
                const maxEntryDataLength = raw.payload.readUInt16BE(maxLenOff + i * 2);
                keyLockerCapabilities.set(entryType, {
                    numberOfEntrySlots,
                    minEntryDataLength,
                    maxEntryDataLength,
                });
            }
            return new this({
                nodeId: ctx.sourceNodeId,
                keyLockerCapabilities,
            });
        }
        keyLockerCapabilities;
        persistValues(ctx) {
            if (!super.persistValues(ctx))
                return false;
            this.setValue(ctx, UserCredentialCCValues.supportedKeyLockerEntryTypes, [...this.keyLockerCapabilities.keys()]);
            for (const [entryType, capability] of this.keyLockerCapabilities) {
                this.setValue(ctx, UserCredentialCCValues.keyLockerCapabilities(entryType), capability);
            }
            return true;
        }
        serialize(ctx) {
            const n = this.keyLockerCapabilities.size;
            this.payload = Bytes.alloc(1 + n * 7);
            this.payload[0] = n;
            const entryTypeOff = 1;
            const numSlotsOff = entryTypeOff + n;
            const minLenOff = numSlotsOff + n * 2;
            const maxLenOff = minLenOff + n * 2;
            let i = 0;
            for (const [entryType, capability] of this.keyLockerCapabilities) {
                this.payload[entryTypeOff + i] = entryType;
                this.payload.writeUInt16BE(capability.numberOfEntrySlots, numSlotsOff + i * 2);
                this.payload.writeUInt16BE(capability.minEntryDataLength, minLenOff + i * 2);
                this.payload.writeUInt16BE(capability.maxEntryDataLength, maxLenOff + i * 2);
                i++;
            }
            return super.serialize(ctx);
        }
        toLogEntry(ctx) {
            const message = {};
            for (const [entryType, capability] of this.keyLockerCapabilities) {
                message[`entry type ${getEnumMemberName(UserCredentialKeyLockerEntryType, entryType)}`] = `slots: ${capability.numberOfEntrySlots}, length: ${capability.minEntryDataLength}-${capability.maxEntryDataLength}`;
            }
            return {
                ...super.toLogEntry(ctx),
                message,
            };
        }
    };
    return UserCredentialCCKeyLockerCapabilitiesReport = _classThis;
})();
export { UserCredentialCCKeyLockerCapabilitiesReport };
let UserCredentialCCKeyLockerCapabilitiesGet = (() => {
    let _classDecorators = [CCCommand(UserCredentialCommand.KeyLockerCapabilitiesGet), expectedCCResponse(UserCredentialCCKeyLockerCapabilitiesReport)];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = UserCredentialCC;
    var UserCredentialCCKeyLockerCapabilitiesGet = class extends _classSuper {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            UserCredentialCCKeyLockerCapabilitiesGet = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
            __runInitializers(_classThis, _classExtraInitializers);
        }
    };
    return UserCredentialCCKeyLockerCapabilitiesGet = _classThis;
})();
export { UserCredentialCCKeyLockerCapabilitiesGet };
function testResponseForUserCredentialUserSet(sent, received) {
    // CC:0083.01.05.11.010, CC:0083.01.05.11.011, CC:0083.01.05.11.012,
    // CC:0083.01.05.11.013: UserSet MUST be answered by a UserReport.
    // Match any report type other than ResponseToGet. For Add/Modify/Delete
    // the report echoes the requested userId; for DeleteAll (userId 0) the
    // report contains userId 0.
    return (received.reportType !== UserCredentialUserReportType.ResponseToGet
        && received.userId === sent.userId);
}
let UserCredentialCCUserSet = (() => {
    let _classDecorators = [CCCommand(UserCredentialCommand.UserSet), expectedCCResponse(() => UserCredentialCCUserReport, testResponseForUserCredentialUserSet)];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = UserCredentialCC;
    var UserCredentialCCUserSet = class extends _classSuper {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            UserCredentialCCUserSet = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
            __runInitializers(_classThis, _classExtraInitializers);
        }
        constructor(options) {
            super(options);
            this.operationType = options.operationType;
            this.userId = options.userId;
            if (options.operationType !== UserCredentialOperationType.Delete) {
                this.userType = options.userType;
                this.active = options.active;
                this.credentialRule = options.credentialRule;
                this.expiringTimeoutMinutes = options.expiringTimeoutMinutes;
                this.nameEncoding = options.nameEncoding;
                this.userName = options.userName;
            }
        }
        operationType;
        userId;
        userType;
        active;
        credentialRule;
        expiringTimeoutMinutes;
        nameEncoding;
        userName;
        static from(raw, ctx) {
            validatePayload(raw.payload.length >= 3);
            const operationType = raw.payload[0]
                & 0b11;
            const userId = raw.payload.readUInt16BE(1);
            if (operationType === UserCredentialOperationType.Delete) {
                return new this({
                    nodeId: ctx.sourceNodeId,
                    operationType,
                    userId,
                });
            }
            // For Delete, the remaining fields MAY be omitted
            if (raw.payload.length < 10) {
                return new this({
                    nodeId: ctx.sourceNodeId,
                    operationType,
                    userId,
                });
            }
            const userType = raw.payload[3];
            const active = !!(raw.payload[4] & 0b1);
            const credentialRule = raw.payload[5];
            const expiringTimeoutMinutes = raw.payload.readUInt16BE(6);
            const nameEncoding = raw.payload[8] & 0b111;
            const nameLength = raw.payload[9];
            validatePayload(raw.payload.length >= 10 + nameLength);
            let userName;
            if (nameEncoding === UserCredentialNameEncoding.UTF16BE) {
                userName = uint8ArrayToStringUTF16BE(raw.payload.subarray(10, 10 + nameLength));
            }
            else {
                userName = raw.payload
                    .subarray(10, 10 + nameLength)
                    .toString("ascii");
            }
            if (userType === UserCredentialUserType.Expiring) {
                return new this({
                    nodeId: ctx.sourceNodeId,
                    operationType,
                    userId,
                    userType,
                    expiringTimeoutMinutes,
                    active,
                    credentialRule,
                    nameEncoding,
                    userName,
                });
            }
            return new this({
                nodeId: ctx.sourceNodeId,
                operationType,
                userId,
                userType,
                active,
                credentialRule,
                nameEncoding,
                userName,
            });
        }
        serialize(ctx) {
            // For Delete, remaining user-detail fields MAY be omitted
            if (this.operationType === UserCredentialOperationType.Delete) {
                this.payload = Bytes.alloc(3);
                this.payload[0] = this.operationType & 0b11;
                this.payload.writeUInt16BE(this.userId, 1);
                return super.serialize(ctx);
            }
            if (this.userType == undefined) {
                throw new ZWaveError(`${this.constructor.name}: user type must be set for Add/Modify operations`, ZWaveErrorCodes.Argument_Invalid);
            }
            if (this.active == undefined) {
                throw new ZWaveError(`${this.constructor.name}: The active flag must be set for Add/Modify operations`, ZWaveErrorCodes.Argument_Invalid);
            }
            // Credential rule defaults to Single
            const credentialRule = this.credentialRule ?? UserCredentialRule.Single;
            // Expiring timeout MUST be 0 for non-Expiring user types
            let expiringTimeoutMinutes;
            if (this.userType === UserCredentialUserType.Expiring) {
                if (this.expiringTimeoutMinutes == undefined) {
                    throw new ZWaveError(`${this.constructor.name}: expiring timeout minutes must be set for Expiring user type`, ZWaveErrorCodes.Argument_Invalid);
                }
                expiringTimeoutMinutes = this.expiringTimeoutMinutes;
            }
            else {
                expiringTimeoutMinutes = 0;
            }
            // Name encoding defaults to ASCII
            const nameEncoding = this.nameEncoding
                ?? UserCredentialNameEncoding.ASCII;
            // User name defaults to empty string
            const userName = this.userName ?? "";
            let nameBuffer;
            if (nameEncoding === UserCredentialNameEncoding.UTF16BE) {
                nameBuffer = stringToUint8ArrayUTF16BE(userName);
            }
            else {
                nameBuffer = Bytes.from(userName, "ascii");
            }
            this.payload = Bytes.alloc(10 + nameBuffer.length);
            this.payload[0] = this.operationType & 0b11;
            this.payload.writeUInt16BE(this.userId, 1);
            this.payload[3] = this.userType;
            this.payload[4] = this.active ? 0b1 : 0;
            this.payload[5] = credentialRule;
            this.payload.writeUInt16BE(expiringTimeoutMinutes, 6);
            this.payload[8] = nameEncoding & 0b111;
            this.payload[9] = nameBuffer.length;
            if (nameBuffer.length > 0) {
                this.payload.set(nameBuffer, 10);
            }
            return super.serialize(ctx);
        }
        toLogEntry(ctx) {
            const message = {
                "operation type": getEnumMemberName(UserCredentialOperationType, this.operationType),
                "user ID": this.userId,
            };
            if (this.userType != undefined) {
                message["user type"] = getEnumMemberName(UserCredentialUserType, this.userType);
            }
            if (this.active != undefined) {
                message["active"] = this.active;
            }
            if (this.credentialRule != undefined) {
                message["credential rule"] = getEnumMemberName(UserCredentialRule, this.credentialRule);
            }
            if (this.expiringTimeoutMinutes != undefined) {
                message["expiring timeout (minutes)"] = this.expiringTimeoutMinutes;
            }
            if (this.nameEncoding != undefined) {
                message["name encoding"] = getEnumMemberName(UserCredentialNameEncoding, this.nameEncoding);
            }
            if (this.userName != undefined) {
                message["user name"] = this.userName;
            }
            return { ...super.toLogEntry(ctx), message };
        }
    };
    return UserCredentialCCUserSet = _classThis;
})();
export { UserCredentialCCUserSet };
let UserCredentialCCUserReport = (() => {
    let _classDecorators = [CCCommand(UserCredentialCommand.UserReport)];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = UserCredentialCC;
    var UserCredentialCCUserReport = class extends _classSuper {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            UserCredentialCCUserReport = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
            __runInitializers(_classThis, _classExtraInitializers);
        }
        constructor(options) {
            super(options);
            this.reportType = options.reportType;
            if (options.reportType === UserCredentialUserReportType.ResponseToGet) {
                this.nextUserId = options.nextUserId;
            }
            this.modifierType = options.modifierType;
            this.modifierNodeId = options.modifierNodeId;
            this.userId = options.userId;
            this.userType = options.userType;
            this.active = options.active;
            this.credentialRule = options.credentialRule;
            this.expiringTimeoutMinutes = options.expiringTimeoutMinutes;
            this.nameEncoding = options.nameEncoding;
            this.userName = options.userName;
        }
        static from(raw, ctx) {
            validatePayload(raw.payload.length >= 13);
            const reportType = raw.payload[0];
            const nextUserId = raw.payload.readUInt16BE(1);
            const modifierType = raw.payload[3];
            const modifierNodeId = raw.payload.readUInt16BE(4);
            const userId = raw.payload.readUInt16BE(6);
            const userType = raw.payload[8];
            const active = !!(raw.payload[9] & 0b1);
            const credentialRule = raw.payload[10];
            const expiringTimeoutMinutes = raw.payload.readUInt16BE(11);
            validatePayload(raw.payload.length >= 15);
            const nameEncoding = raw.payload[13]
                & 0b111;
            const nameLength = raw.payload[14];
            validatePayload(raw.payload.length >= 15 + nameLength);
            let userName;
            if (nameEncoding === UserCredentialNameEncoding.UTF16BE) {
                userName = uint8ArrayToStringUTF16BE(raw.payload.subarray(15, 15 + nameLength));
            }
            else {
                userName = raw.payload
                    .subarray(15, 15 + nameLength)
                    .toString("ascii");
            }
            const common = {
                nodeId: ctx.sourceNodeId,
                modifierType,
                modifierNodeId,
                userId,
                userType,
                active,
                credentialRule,
                expiringTimeoutMinutes,
                nameEncoding,
                userName,
            };
            if (reportType === UserCredentialUserReportType.ResponseToGet) {
                return new this({ ...common, reportType, nextUserId });
            }
            return new this({ ...common, reportType });
        }
        reportType;
        nextUserId;
        modifierType;
        modifierNodeId;
        userId;
        userType;
        active;
        credentialRule;
        expiringTimeoutMinutes;
        nameEncoding;
        userName;
        serialize(ctx) {
            let nameBuffer;
            if (this.nameEncoding === UserCredentialNameEncoding.UTF16BE) {
                nameBuffer = stringToUint8ArrayUTF16BE(this.userName);
            }
            else {
                nameBuffer = Bytes.from(this.userName, "ascii");
            }
            this.payload = Bytes.alloc(15 + nameBuffer.length);
            this.payload[0] = this.reportType;
            this.payload.writeUInt16BE(this.nextUserId ?? 0, 1);
            this.payload[3] = this.modifierType;
            this.payload.writeUInt16BE(this.modifierNodeId, 4);
            this.payload.writeUInt16BE(this.userId, 6);
            this.payload[8] = this.userType;
            this.payload[9] = this.active ? 0b1 : 0;
            this.payload[10] = this.credentialRule;
            this.payload.writeUInt16BE(this.expiringTimeoutMinutes, 11);
            this.payload[13] = this.nameEncoding & 0b111;
            this.payload[14] = nameBuffer.length;
            if (nameBuffer.length > 0) {
                this.payload.set(nameBuffer, 15);
            }
            return super.serialize(ctx);
        }
        persistValues(ctx) {
            if (!super.persistValues(ctx))
                return false;
            if (this.userId === 0)
                return true;
            // A UserModifyRejectedLocationEmpty report means we have a stale cache
            // entry for a user that no longer exists on the device.
            if (this.reportType
                === UserCredentialUserReportType.UserDeleted
                || this.reportType
                    === UserCredentialUserReportType.UserModifyRejectedLocationEmpty) {
                // Remove all values for this user
                const userId = this.userId;
                this.removeValue(ctx, UserCredentialCCValues.userType(userId));
                this.removeValue(ctx, UserCredentialCCValues.userActive(userId));
                this.removeValue(ctx, UserCredentialCCValues.credentialRule(userId));
                this.removeValue(ctx, UserCredentialCCValues.expiringTimeoutMinutes(userId));
                this.removeValue(ctx, UserCredentialCCValues.userName(userId));
                this.removeValue(ctx, UserCredentialCCValues.userModifierType(userId));
                this.removeValue(ctx, UserCredentialCCValues.userModifierNodeId(userId));
                return true;
            }
            // A UserAddRejectedLocationOccupied report contains the data for the
            // existing user, so we can update our cache with the actual state.
            if (this.reportType
                !== UserCredentialUserReportType.ResponseToGet
                && this.reportType
                    !== UserCredentialUserReportType.UserAdded
                && this.reportType
                    !== UserCredentialUserReportType.UserModified
                && this.reportType
                    !== UserCredentialUserReportType.UserAddRejectedLocationOccupied) {
                return true;
            }
            const userId = this.userId;
            this.ensureMetadata(ctx, UserCredentialCCValues.userType(userId));
            this.setValue(ctx, UserCredentialCCValues.userType(userId), this.userType);
            this.ensureMetadata(ctx, UserCredentialCCValues.userActive(userId));
            this.setValue(ctx, UserCredentialCCValues.userActive(userId), this.active);
            this.ensureMetadata(ctx, UserCredentialCCValues.credentialRule(userId));
            this.setValue(ctx, UserCredentialCCValues.credentialRule(userId), this.credentialRule);
            this.ensureMetadata(ctx, UserCredentialCCValues.expiringTimeoutMinutes(userId));
            this.setValue(ctx, UserCredentialCCValues.expiringTimeoutMinutes(userId), this.expiringTimeoutMinutes);
            this.ensureMetadata(ctx, UserCredentialCCValues.userName(userId));
            this.setValue(ctx, UserCredentialCCValues.userName(userId), this.userName);
            this.setValue(ctx, UserCredentialCCValues.userModifierType(userId), this.modifierType);
            this.setValue(ctx, UserCredentialCCValues.userModifierNodeId(userId), this.modifierNodeId);
            return true;
        }
        toLogEntry(ctx) {
            const message = {
                "report type": getEnumMemberName(UserCredentialUserReportType, this.reportType),
            };
            if (this.nextUserId != undefined) {
                message["next user ID"] = this.nextUserId;
            }
            message["modifier type"] = getEnumMemberName(UserCredentialModifierType, this.modifierType);
            message["modifier node id"] = this.modifierNodeId;
            message["user ID"] = this.userId;
            message["user type"] = getEnumMemberName(UserCredentialUserType, this.userType);
            message.active = this.active;
            message["credential rule"] = getEnumMemberName(UserCredentialRule, this.credentialRule);
            message["expiring timeout (minutes)"] = this.expiringTimeoutMinutes;
            message["name encoding"] = getEnumMemberName(UserCredentialNameEncoding, this.nameEncoding);
            message["user name"] = this.userName;
            return { ...super.toLogEntry(ctx), message };
        }
    };
    return UserCredentialCCUserReport = _classThis;
})();
export { UserCredentialCCUserReport };
function testResponseForUserCredentialUserGet(sent, received) {
    return (received.reportType
        === UserCredentialUserReportType.ResponseToGet);
}
let UserCredentialCCUserGet = (() => {
    let _classDecorators = [CCCommand(UserCredentialCommand.UserGet), expectedCCResponse(UserCredentialCCUserReport, testResponseForUserCredentialUserGet)];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = UserCredentialCC;
    var UserCredentialCCUserGet = class extends _classSuper {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            UserCredentialCCUserGet = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
            __runInitializers(_classThis, _classExtraInitializers);
        }
        constructor(options) {
            super(options);
            this.userId = options.userId;
        }
        userId;
        static from(raw, ctx) {
            validatePayload(raw.payload.length >= 2);
            const userId = raw.payload.readUInt16BE(0);
            return new this({
                nodeId: ctx.sourceNodeId,
                userId,
            });
        }
        serialize(ctx) {
            this.payload = Bytes.alloc(2);
            this.payload.writeUInt16BE(this.userId, 0);
            return super.serialize(ctx);
        }
        toLogEntry(ctx) {
            return {
                ...super.toLogEntry(ctx),
                message: {
                    "user ID": this.userId,
                },
            };
        }
    };
    return UserCredentialCCUserGet = _classThis;
})();
export { UserCredentialCCUserGet };
function testResponseForUserCredentialCredentialSet(sent, received) {
    // CC:0083.01.0A.11.010, CC:0083.01.0A.11.011, CC:0083.01.0A.11.012,
    // CC:0083.01.0A.11.013: CredentialSet MUST be answered by a
    // CredentialReport. The credentialType is always echoed, so we use it
    // as the primary correlation. DuplicateCredential and DuplicateAdminPINCode
    // reports reference the EXISTING duplicate's (userId, slot) rather than
    // the requested location, so we cannot correlate them on slot.
    if (received.reportType
        === UserCredentialCredentialReportType.ResponseToGet) {
        return false;
    }
    if (received.credentialType !== sent.credentialType) {
        return false;
    }
    if (received.reportType
        === UserCredentialCredentialReportType.DuplicateCredential
        || received.reportType
            === UserCredentialCredentialReportType.DuplicateAdminPINCode) {
        return true;
    }
    return received.credentialSlot === sent.credentialSlot;
}
let UserCredentialCCCredentialSet = (() => {
    let _classDecorators = [CCCommand(UserCredentialCommand.CredentialSet), expectedCCResponse(() => UserCredentialCCCredentialReport, testResponseForUserCredentialCredentialSet)];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = UserCredentialCC;
    var UserCredentialCCCredentialSet = class extends _classSuper {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            UserCredentialCCCredentialSet = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
            __runInitializers(_classThis, _classExtraInitializers);
        }
        constructor(options) {
            super(options);
            this.userId = options.userId;
            this.credentialType = options.credentialType;
            this.credentialSlot = options.credentialSlot;
            this.operationType = options.operationType;
            if (options.operationType !== UserCredentialOperationType.Delete) {
                this.credentialData = options.credentialData;
            }
        }
        userId;
        credentialType;
        credentialSlot;
        operationType;
        credentialData;
        static from(raw, ctx) {
            validatePayload(raw.payload.length >= 6);
            const userId = raw.payload.readUInt16BE(0);
            const credentialType = raw.payload[2];
            const credentialSlot = raw.payload.readUInt16BE(3);
            const operationType = raw.payload[5]
                & 0b11;
            if (operationType === UserCredentialOperationType.Delete) {
                return new this({
                    nodeId: ctx.sourceNodeId,
                    userId,
                    credentialType,
                    credentialSlot,
                    operationType,
                });
            }
            let credentialData = new Bytes();
            if (raw.payload.length >= 7) {
                const credentialLength = raw.payload[6];
                validatePayload(raw.payload.length >= 7 + credentialLength);
                credentialData = Bytes.from(raw.payload.subarray(7, 7 + credentialLength));
            }
            return new this({
                nodeId: ctx.sourceNodeId,
                userId,
                credentialType,
                credentialSlot,
                operationType,
                credentialData,
            });
        }
        serialize(ctx) {
            // For Delete, credential data MAY be omitted
            if (this.operationType === UserCredentialOperationType.Delete) {
                this.payload = Bytes.alloc(6);
                this.payload.writeUInt16BE(this.userId, 0);
                this.payload[2] = this.credentialType;
                this.payload.writeUInt16BE(this.credentialSlot, 3);
                this.payload[5] = this.operationType & 0b11;
                return super.serialize(ctx);
            }
            if (this.credentialData == undefined) {
                throw new ZWaveError(`${this.constructor.name}: credential data must be set for Add/Modify operations`, ZWaveErrorCodes.Argument_Invalid);
            }
            this.payload = Bytes.alloc(7 + this.credentialData.length);
            this.payload.writeUInt16BE(this.userId, 0);
            this.payload[2] = this.credentialType;
            this.payload.writeUInt16BE(this.credentialSlot, 3);
            this.payload[5] = this.operationType & 0b11;
            this.payload[6] = this.credentialData.length;
            if (this.credentialData.length > 0) {
                this.payload.set(this.credentialData, 7);
            }
            return super.serialize(ctx);
        }
        toLogEntry(ctx) {
            const message = {
                "user ID": this.userId,
                "credential type": getEnumMemberName(UserCredentialType, this.credentialType),
                "credential slot": this.credentialSlot,
                "operation type": getEnumMemberName(UserCredentialOperationType, this.operationType),
            };
            if (this.credentialData != undefined) {
                message["credential data"] = credentialToLogString(this.credentialData);
            }
            return { ...super.toLogEntry(ctx), message };
        }
    };
    return UserCredentialCCCredentialSet = _classThis;
})();
export { UserCredentialCCCredentialSet };
let UserCredentialCCCredentialReport = (() => {
    let _classDecorators = [CCCommand(UserCredentialCommand.CredentialReport)];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = UserCredentialCC;
    var UserCredentialCCCredentialReport = class extends _classSuper {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            UserCredentialCCCredentialReport = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
            __runInitializers(_classThis, _classExtraInitializers);
        }
        constructor(options) {
            super(options);
            this.reportType = options.reportType;
            this.userId = options.userId;
            this.credentialType = options.credentialType;
            this.credentialSlot = options.credentialSlot;
            this.credentialReadBack = options.credentialReadBack;
            if (options.credentialReadBack) {
                this.credentialData = options.credentialData;
            }
            this.modifierType = options.modifierType;
            this.modifierNodeId = options.modifierNodeId;
            if (options.reportType
                === UserCredentialCredentialReportType.ResponseToGet) {
                this.nextCredentialType = options.nextCredentialType;
                this.nextCredentialSlot = options.nextCredentialSlot;
            }
        }
        static from(raw, ctx) {
            validatePayload(raw.payload.length >= 8);
            const reportType = raw.payload[0];
            const userId = raw.payload.readUInt16BE(1);
            const credentialType = raw.payload[3];
            const credentialSlot = raw.payload.readUInt16BE(4);
            const credentialReadBack = !!(raw.payload[6] & 128);
            const credentialLength = raw.payload[7];
            validatePayload(raw.payload.length >= 8 + credentialLength + 6);
            const offset = 8 + credentialLength;
            const modifierType = raw.payload[offset];
            const modifierNodeId = raw.payload.readUInt16BE(offset + 1);
            const common = {
                nodeId: ctx.sourceNodeId,
                userId,
                credentialType,
                credentialSlot,
                modifierType,
                modifierNodeId,
            };
            const dataOptions = credentialReadBack
                ? {
                    credentialReadBack: true,
                    credentialData: Bytes.from(raw.payload.subarray(8, 8 + credentialLength)),
                }
                : { credentialReadBack: false };
            if (reportType === UserCredentialCredentialReportType.ResponseToGet) {
                return new this({
                    ...common,
                    ...dataOptions,
                    reportType,
                    nextCredentialType: raw.payload[offset + 3],
                    nextCredentialSlot: raw.payload.readUInt16BE(offset + 4),
                });
            }
            return new this({
                ...common,
                ...dataOptions,
                reportType,
            });
        }
        reportType;
        userId;
        credentialType;
        credentialSlot;
        credentialReadBack;
        credentialData;
        modifierType;
        modifierNodeId;
        nextCredentialType;
        nextCredentialSlot;
        serialize(ctx) {
            const credentialData = this.credentialData ?? new Bytes();
            this.payload = Bytes.alloc(14 + credentialData.length);
            this.payload[0] = this.reportType;
            this.payload.writeUInt16BE(this.userId, 1);
            this.payload[3] = this.credentialType;
            this.payload.writeUInt16BE(this.credentialSlot, 4);
            this.payload[6] = this.credentialReadBack ? 0x80 : 0x00;
            this.payload[7] = credentialData.length;
            if (credentialData.length > 0) {
                this.payload.set(credentialData, 8);
            }
            const offset = 8 + credentialData.length;
            this.payload[offset] = this.modifierType;
            this.payload.writeUInt16BE(this.modifierNodeId, offset + 1);
            this.payload[offset + 3] = this.nextCredentialType
                ?? UserCredentialType.None;
            this.payload.writeUInt16BE(this.nextCredentialSlot ?? 0, offset + 4);
            return super.serialize(ctx);
        }
        persistValues(ctx) {
            if (!super.persistValues(ctx))
                return false;
            // A CredentialModifyRejectedLocationEmpty report means we have a stale
            // cache entry for a credential that no longer exists on the device.
            // CredentialDeleted reports may echo the request fields, including the
            // wildcard zeros used to trigger bulk deletes per CC:0083.01.0A.
            if (this.reportType
                === UserCredentialCredentialReportType.CredentialDeleted
                || this.reportType
                    === UserCredentialCredentialReportType
                        .CredentialModifyRejectedLocationEmpty) {
                if (this.credentialType !== UserCredentialType.None
                    && this.credentialSlot !== 0) {
                    // Single credential. The (type, slot) tuple uniquely identifies
                    // the entry in the value DB, so the userId is not needed.
                    this.removeValue(ctx, UserCredentialCCValues.credential(this.credentialType, this.credentialSlot));
                    this.removeValue(ctx, UserCredentialCCValues.credentialOwner(this.credentialType, this.credentialSlot));
                    this.removeValue(ctx, UserCredentialCCValues.credentialModifierType(this.credentialType, this.credentialSlot));
                    this.removeValue(ctx, UserCredentialCCValues.credentialModifierNodeId(this.credentialType, this.credentialSlot));
                }
                else {
                    // Bulk delete. Walk all cached credentials and remove those
                    // matching the (userId, type) filter (zero means wildcard).
                    const valueDB = this.getValueDB(ctx);
                    const credentialOwners = valueDB.findValues((vid) => UserCredentialCCValues.credentialOwner.is(vid)
                        && vid.endpoint === this.endpointIndex);
                    for (const { endpoint, propertyKey, value } of credentialOwners) {
                        // If a user ID is given, only delete credentials owned by that user
                        if (this.userId !== 0 && value !== this.userId)
                            continue;
                        const key = propertyKey;
                        const cType = key >>> 16;
                        const cSlot = key & 0xffff;
                        // If a credential type is given, only delete credentials of that type
                        if (this.credentialType !== UserCredentialType.None
                            && cType !== this.credentialType) {
                            continue;
                        }
                        valueDB.removeValue(UserCredentialCCValues.credential(cType, cSlot)
                            .endpoint(endpoint));
                        valueDB.removeValue(UserCredentialCCValues.credentialOwner(cType, cSlot)
                            .endpoint(endpoint));
                        valueDB.removeValue(UserCredentialCCValues.credentialModifierType(cType, cSlot).endpoint(endpoint));
                        valueDB.removeValue(UserCredentialCCValues.credentialModifierNodeId(cType, cSlot).endpoint(endpoint));
                    }
                }
                return true;
            }
            // Non-delete reports may carry (None, 0) as a sentinel for "no credential
            // at this location" — e.g. the end-of-walk marker in nextCredential* of
            // a ResponseToGet. Bail out so we don't write bogus cache entries.
            if (this.credentialType === UserCredentialType.None
                || this.credentialSlot === 0) {
                return true;
            }
            // A CredentialAddRejectedLocationOccupied report includes the actual
            // credential data in the read-back field when the device chooses to
            // reveal it, so we can update our cache with the real state.
            const isRejectionWithReadback = this.reportType
                === UserCredentialCredentialReportType
                    .CredentialAddRejectedLocationOccupied
                && this.credentialReadBack;
            if (this.reportType
                !== UserCredentialCredentialReportType.ResponseToGet
                && this.reportType
                    !== UserCredentialCredentialReportType.CredentialAdded
                && this.reportType
                    !== UserCredentialCredentialReportType.CredentialModified
                && !isRejectionWithReadback) {
                return true;
            }
            if (this.credentialData != undefined) {
                this.ensureMetadata(ctx, UserCredentialCCValues.credential(this.credentialType, this.credentialSlot));
                this.setValue(ctx, UserCredentialCCValues.credential(this.credentialType, this.credentialSlot), normalizeCredentialData(this.credentialType, this.credentialData));
            }
            this.setValue(ctx, UserCredentialCCValues.credentialOwner(this.credentialType, this.credentialSlot), this.userId);
            this.setValue(ctx, UserCredentialCCValues.credentialModifierType(this.credentialType, this.credentialSlot), this.modifierType);
            this.setValue(ctx, UserCredentialCCValues.credentialModifierNodeId(this.credentialType, this.credentialSlot), this.modifierNodeId);
            return true;
        }
        toLogEntry(ctx) {
            const message = {
                "report type": getEnumMemberName(UserCredentialCredentialReportType, this.reportType),
                "user ID": this.userId,
                "credential type": getEnumMemberName(UserCredentialType, this.credentialType),
                "credential slot": this.credentialSlot,
                "credential read-back": this.credentialReadBack,
            };
            if (this.credentialData != undefined) {
                message["credential data"] = credentialToLogString(this.credentialData);
            }
            message["modifier type"] = getEnumMemberName(UserCredentialModifierType, this.modifierType);
            message["modifier node id"] = this.modifierNodeId;
            if (this.nextCredentialType != undefined) {
                message["next credential type"] = getEnumMemberName(UserCredentialType, this.nextCredentialType);
            }
            if (this.nextCredentialSlot != undefined) {
                message["next credential slot"] = this.nextCredentialSlot;
            }
            return { ...super.toLogEntry(ctx), message };
        }
    };
    return UserCredentialCCCredentialReport = _classThis;
})();
export { UserCredentialCCCredentialReport };
function testResponseForUserCredentialCredentialGet(_sent, received) {
    return (received.reportType
        === UserCredentialCredentialReportType.ResponseToGet);
}
let UserCredentialCCCredentialGet = (() => {
    let _classDecorators = [CCCommand(UserCredentialCommand.CredentialGet), expectedCCResponse(UserCredentialCCCredentialReport, testResponseForUserCredentialCredentialGet)];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = UserCredentialCC;
    var UserCredentialCCCredentialGet = class extends _classSuper {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            UserCredentialCCCredentialGet = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
            __runInitializers(_classThis, _classExtraInitializers);
        }
        constructor(options) {
            super(options);
            this.userId = options.userId;
            this.credentialType = options.credentialType;
            this.credentialSlot = options.credentialSlot;
        }
        userId;
        credentialType;
        credentialSlot;
        static from(raw, ctx) {
            validatePayload(raw.payload.length >= 5);
            const userId = raw.payload.readUInt16BE(0);
            const credentialType = raw.payload[2];
            const credentialSlot = raw.payload.readUInt16BE(3);
            return new this({
                nodeId: ctx.sourceNodeId,
                userId,
                credentialType,
                credentialSlot,
            });
        }
        serialize(ctx) {
            this.payload = Bytes.alloc(5);
            this.payload.writeUInt16BE(this.userId, 0);
            this.payload[2] = this.credentialType;
            this.payload.writeUInt16BE(this.credentialSlot, 3);
            return super.serialize(ctx);
        }
        toLogEntry(ctx) {
            return {
                ...super.toLogEntry(ctx),
                message: {
                    "user ID": this.userId,
                    "credential type": getEnumMemberName(UserCredentialType, this.credentialType),
                    "credential slot": this.credentialSlot,
                },
            };
        }
    };
    return UserCredentialCCCredentialGet = _classThis;
})();
export { UserCredentialCCCredentialGet };
let UserCredentialCCCredentialLearnStart = (() => {
    let _classDecorators = [CCCommand(UserCredentialCommand.CredentialLearnStart), useSupervision()];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = UserCredentialCC;
    var UserCredentialCCCredentialLearnStart = class extends _classSuper {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            UserCredentialCCCredentialLearnStart = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
            __runInitializers(_classThis, _classExtraInitializers);
        }
        constructor(options) {
            super(options);
            this.userId = options.userId;
            this.credentialType = options.credentialType;
            this.credentialSlot = options.credentialSlot;
            this.operationType = options.operationType;
            this.learnTimeout = options.learnTimeout;
        }
        userId;
        credentialType;
        credentialSlot;
        operationType;
        learnTimeout;
        static from(raw, ctx) {
            validatePayload(raw.payload.length >= 7);
            const userId = raw.payload.readUInt16BE(0);
            const credentialType = raw.payload[2];
            const credentialSlot = raw.payload.readUInt16BE(3);
            const operationType = raw.payload[5]
                & 0b11;
            const learnTimeout = raw.payload[6];
            return new this({
                nodeId: ctx.sourceNodeId,
                userId,
                credentialType,
                credentialSlot,
                operationType,
                learnTimeout,
            });
        }
        serialize(ctx) {
            this.payload = Bytes.alloc(7);
            this.payload.writeUInt16BE(this.userId, 0);
            this.payload[2] = this.credentialType;
            this.payload.writeUInt16BE(this.credentialSlot, 3);
            this.payload[5] = this.operationType & 0b11;
            this.payload[6] = this.learnTimeout;
            return super.serialize(ctx);
        }
        toLogEntry(ctx) {
            return {
                ...super.toLogEntry(ctx),
                message: {
                    "user ID": this.userId,
                    "credential type": getEnumMemberName(UserCredentialType, this.credentialType),
                    "credential slot": this.credentialSlot,
                    "operation type": getEnumMemberName(UserCredentialOperationType, this.operationType),
                    "learn timeout": this.learnTimeout,
                },
            };
        }
    };
    return UserCredentialCCCredentialLearnStart = _classThis;
})();
export { UserCredentialCCCredentialLearnStart };
let UserCredentialCCCredentialLearnCancel = (() => {
    let _classDecorators = [CCCommand(UserCredentialCommand.CredentialLearnCancel), useSupervision()];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = UserCredentialCC;
    var UserCredentialCCCredentialLearnCancel = class extends _classSuper {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            UserCredentialCCCredentialLearnCancel = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
            __runInitializers(_classThis, _classExtraInitializers);
        }
    };
    return UserCredentialCCCredentialLearnCancel = _classThis;
})();
export { UserCredentialCCCredentialLearnCancel };
let UserCredentialCCCredentialLearnReport = (() => {
    let _classDecorators = [CCCommand(UserCredentialCommand.CredentialLearnReport)];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = UserCredentialCC;
    var UserCredentialCCCredentialLearnReport = class extends _classSuper {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            UserCredentialCCCredentialLearnReport = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
            __runInitializers(_classThis, _classExtraInitializers);
        }
        constructor(options) {
            super(options);
            this.learnStatus = options.learnStatus;
            this.userId = options.userId;
            this.credentialType = options.credentialType;
            this.credentialSlot = options.credentialSlot;
            this.stepsRemaining = options.stepsRemaining;
        }
        static from(raw, ctx) {
            validatePayload(raw.payload.length >= 7);
            const learnStatus = raw.payload[0];
            const userId = raw.payload.readUInt16BE(1);
            const credentialType = raw.payload[3];
            const credentialSlot = raw.payload.readUInt16BE(4);
            const stepsRemaining = raw.payload[6];
            return new this({
                nodeId: ctx.sourceNodeId,
                learnStatus,
                userId,
                credentialType,
                credentialSlot,
                stepsRemaining,
            });
        }
        learnStatus;
        userId;
        credentialType;
        credentialSlot;
        stepsRemaining;
        serialize(ctx) {
            this.payload = Bytes.alloc(7);
            this.payload[0] = this.learnStatus;
            this.payload.writeUInt16BE(this.userId, 1);
            this.payload[3] = this.credentialType;
            this.payload.writeUInt16BE(this.credentialSlot, 4);
            this.payload[6] = this.stepsRemaining;
            return super.serialize(ctx);
        }
        toLogEntry(ctx) {
            return {
                ...super.toLogEntry(ctx),
                message: {
                    "learn status": getEnumMemberName(UserCredentialLearnStatus, this.learnStatus),
                    "user ID": this.userId,
                    "credential type": getEnumMemberName(UserCredentialType, this.credentialType),
                    "credential slot": this.credentialSlot,
                    "steps remaining": this.stepsRemaining,
                },
            };
        }
    };
    return UserCredentialCCCredentialLearnReport = _classThis;
})();
export { UserCredentialCCCredentialLearnReport };
let UserCredentialCCAssociationReport = (() => {
    let _classDecorators = [CCCommand(UserCredentialCommand.UserCredentialAssociationReport)];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = UserCredentialCC;
    var UserCredentialCCAssociationReport = class extends _classSuper {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            UserCredentialCCAssociationReport = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
            __runInitializers(_classThis, _classExtraInitializers);
        }
        constructor(options) {
            super(options);
            this.credentialType = options.credentialType;
            this.credentialSlot = options.credentialSlot;
            this.destinationUserId = options.destinationUserId;
            this.status = options.status;
        }
        static from(raw, ctx) {
            validatePayload(raw.payload.length >= 6);
            const credentialType = raw.payload[0];
            const credentialSlot = raw.payload.readUInt16BE(1);
            const destinationUserId = raw.payload.readUInt16BE(3);
            const status = raw.payload[5];
            return new this({
                nodeId: ctx.sourceNodeId,
                credentialType,
                credentialSlot,
                destinationUserId: destinationUserId,
                status,
            });
        }
        credentialType;
        credentialSlot;
        destinationUserId;
        status;
        serialize(ctx) {
            this.payload = Bytes.alloc(6);
            this.payload[0] = this.credentialType;
            this.payload.writeUInt16BE(this.credentialSlot, 1);
            this.payload.writeUInt16BE(this.destinationUserId, 3);
            this.payload[5] = this.status;
            return super.serialize(ctx);
        }
        persistValues(ctx) {
            if (!super.persistValues(ctx))
                return false;
            if (this.status !== 0
                || this.credentialType === UserCredentialType.None
                || this.credentialSlot === 0) {
                return true;
            }
            this.setValue(ctx, UserCredentialCCValues.credentialOwner(this.credentialType, this.credentialSlot), this.destinationUserId);
            return true;
        }
        toLogEntry(ctx) {
            return {
                ...super.toLogEntry(ctx),
                message: {
                    "credential type": getEnumMemberName(UserCredentialType, this.credentialType),
                    "credential slot": this.credentialSlot,
                    "destination user ID": this.destinationUserId,
                    status: this.status,
                },
            };
        }
    };
    return UserCredentialCCAssociationReport = _classThis;
})();
export { UserCredentialCCAssociationReport };
function testResponseForUserCredentialAssociationSet(sent, received) {
    return (sent.credentialType === received.credentialType
        && sent.credentialSlot === received.credentialSlot);
}
let UserCredentialCCAssociationSet = (() => {
    let _classDecorators = [CCCommand(UserCredentialCommand.UserCredentialAssociationSet), expectedCCResponse(UserCredentialCCAssociationReport, testResponseForUserCredentialAssociationSet)];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = UserCredentialCC;
    var UserCredentialCCAssociationSet = class extends _classSuper {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            UserCredentialCCAssociationSet = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
            __runInitializers(_classThis, _classExtraInitializers);
        }
        constructor(options) {
            super(options);
            this.credentialType = options.credentialType;
            this.credentialSlot = options.credentialSlot;
            this.destinationUserId = options.destinationUserId;
        }
        credentialType;
        credentialSlot;
        destinationUserId;
        static from(raw, ctx) {
            validatePayload(raw.payload.length >= 5);
            const credentialType = raw.payload[0];
            const credentialSlot = raw.payload.readUInt16BE(1);
            const destinationUserId = raw.payload.readUInt16BE(3);
            return new this({
                nodeId: ctx.sourceNodeId,
                credentialType,
                credentialSlot,
                destinationUserId,
            });
        }
        serialize(ctx) {
            this.payload = Bytes.alloc(5);
            this.payload[0] = this.credentialType;
            this.payload.writeUInt16BE(this.credentialSlot, 1);
            this.payload.writeUInt16BE(this.destinationUserId, 3);
            return super.serialize(ctx);
        }
        toLogEntry(ctx) {
            return {
                ...super.toLogEntry(ctx),
                message: {
                    "credential type": getEnumMemberName(UserCredentialType, this.credentialType),
                    "credential slot": this.credentialSlot,
                    "destination user ID": this.destinationUserId,
                },
            };
        }
    };
    return UserCredentialCCAssociationSet = _classThis;
})();
export { UserCredentialCCAssociationSet };
let UserCredentialCCAllUsersChecksumReport = (() => {
    let _classDecorators = [CCCommand(UserCredentialCommand.AllUsersChecksumReport)];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = UserCredentialCC;
    var UserCredentialCCAllUsersChecksumReport = class extends _classSuper {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            UserCredentialCCAllUsersChecksumReport = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
            __runInitializers(_classThis, _classExtraInitializers);
        }
        constructor(options) {
            super(options);
            this.checksum = options.checksum;
        }
        static from(raw, ctx) {
            validatePayload(raw.payload.length >= 2);
            const checksum = raw.payload.readUInt16BE(0);
            return new this({
                nodeId: ctx.sourceNodeId,
                checksum,
            });
        }
        checksum;
        serialize(ctx) {
            this.payload = Bytes.alloc(2);
            this.payload.writeUInt16BE(this.checksum, 0);
            return super.serialize(ctx);
        }
        toLogEntry(ctx) {
            return {
                ...super.toLogEntry(ctx),
                message: { checksum: this.checksum },
            };
        }
    };
    return UserCredentialCCAllUsersChecksumReport = _classThis;
})();
export { UserCredentialCCAllUsersChecksumReport };
let UserCredentialCCAllUsersChecksumGet = (() => {
    let _classDecorators = [CCCommand(UserCredentialCommand.AllUsersChecksumGet), expectedCCResponse(UserCredentialCCAllUsersChecksumReport)];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = UserCredentialCC;
    var UserCredentialCCAllUsersChecksumGet = class extends _classSuper {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            UserCredentialCCAllUsersChecksumGet = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
            __runInitializers(_classThis, _classExtraInitializers);
        }
    };
    return UserCredentialCCAllUsersChecksumGet = _classThis;
})();
export { UserCredentialCCAllUsersChecksumGet };
let UserCredentialCCUserChecksumReport = (() => {
    let _classDecorators = [CCCommand(UserCredentialCommand.UserChecksumReport)];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = UserCredentialCC;
    var UserCredentialCCUserChecksumReport = class extends _classSuper {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            UserCredentialCCUserChecksumReport = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
            __runInitializers(_classThis, _classExtraInitializers);
        }
        constructor(options) {
            super(options);
            this.userId = options.userId;
            this.checksum = options.checksum;
        }
        static from(raw, ctx) {
            validatePayload(raw.payload.length >= 4);
            const userId = raw.payload.readUInt16BE(0);
            const checksum = raw.payload.readUInt16BE(2);
            return new this({
                nodeId: ctx.sourceNodeId,
                userId,
                checksum,
            });
        }
        userId;
        checksum;
        serialize(ctx) {
            this.payload = Bytes.alloc(4);
            this.payload.writeUInt16BE(this.userId, 0);
            this.payload.writeUInt16BE(this.checksum, 2);
            return super.serialize(ctx);
        }
        toLogEntry(ctx) {
            return {
                ...super.toLogEntry(ctx),
                message: {
                    "user ID": this.userId,
                    checksum: this.checksum,
                },
            };
        }
    };
    return UserCredentialCCUserChecksumReport = _classThis;
})();
export { UserCredentialCCUserChecksumReport };
function testResponseForUserCredentialUserChecksumGet(sent, received) {
    return received.userId === sent.userId;
}
let UserCredentialCCUserChecksumGet = (() => {
    let _classDecorators = [CCCommand(UserCredentialCommand.UserChecksumGet), expectedCCResponse(UserCredentialCCUserChecksumReport, testResponseForUserCredentialUserChecksumGet)];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = UserCredentialCC;
    var UserCredentialCCUserChecksumGet = class extends _classSuper {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            UserCredentialCCUserChecksumGet = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
            __runInitializers(_classThis, _classExtraInitializers);
        }
        constructor(options) {
            super(options);
            this.userId = options.userId;
        }
        userId;
        static from(raw, ctx) {
            validatePayload(raw.payload.length >= 2);
            const userId = raw.payload.readUInt16BE(0);
            return new this({
                nodeId: ctx.sourceNodeId,
                userId,
            });
        }
        serialize(ctx) {
            this.payload = Bytes.alloc(2);
            this.payload.writeUInt16BE(this.userId, 0);
            return super.serialize(ctx);
        }
        toLogEntry(ctx) {
            return {
                ...super.toLogEntry(ctx),
                message: {
                    "user ID": this.userId,
                },
            };
        }
    };
    return UserCredentialCCUserChecksumGet = _classThis;
})();
export { UserCredentialCCUserChecksumGet };
let UserCredentialCCCredentialChecksumReport = (() => {
    let _classDecorators = [CCCommand(UserCredentialCommand.CredentialChecksumReport)];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = UserCredentialCC;
    var UserCredentialCCCredentialChecksumReport = class extends _classSuper {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            UserCredentialCCCredentialChecksumReport = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
            __runInitializers(_classThis, _classExtraInitializers);
        }
        constructor(options) {
            super(options);
            this.credentialType = options.credentialType;
            this.checksum = options.checksum;
        }
        static from(raw, ctx) {
            validatePayload(raw.payload.length >= 3);
            const credentialType = raw.payload[0];
            const checksum = raw.payload.readUInt16BE(1);
            return new this({
                nodeId: ctx.sourceNodeId,
                credentialType,
                checksum,
            });
        }
        credentialType;
        checksum;
        serialize(ctx) {
            this.payload = Bytes.alloc(3);
            this.payload[0] = this.credentialType;
            this.payload.writeUInt16BE(this.checksum, 1);
            return super.serialize(ctx);
        }
        toLogEntry(ctx) {
            return {
                ...super.toLogEntry(ctx),
                message: {
                    "credential type": getEnumMemberName(UserCredentialType, this.credentialType),
                    checksum: this.checksum,
                },
            };
        }
    };
    return UserCredentialCCCredentialChecksumReport = _classThis;
})();
export { UserCredentialCCCredentialChecksumReport };
function testResponseForUserCredentialCredentialChecksumGet(sent, received) {
    return received.credentialType === sent.credentialType;
}
let UserCredentialCCCredentialChecksumGet = (() => {
    let _classDecorators = [CCCommand(UserCredentialCommand.CredentialChecksumGet), expectedCCResponse(UserCredentialCCCredentialChecksumReport, testResponseForUserCredentialCredentialChecksumGet)];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = UserCredentialCC;
    var UserCredentialCCCredentialChecksumGet = class extends _classSuper {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            UserCredentialCCCredentialChecksumGet = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
            __runInitializers(_classThis, _classExtraInitializers);
        }
        constructor(options) {
            super(options);
            this.credentialType = options.credentialType;
        }
        credentialType;
        static from(raw, ctx) {
            validatePayload(raw.payload.length >= 1);
            const credentialType = raw.payload[0];
            return new this({
                nodeId: ctx.sourceNodeId,
                credentialType,
            });
        }
        serialize(ctx) {
            this.payload = Bytes.alloc(1);
            this.payload[0] = this.credentialType;
            return super.serialize(ctx);
        }
        toLogEntry(ctx) {
            return {
                ...super.toLogEntry(ctx),
                message: {
                    "credential type": getEnumMemberName(UserCredentialType, this.credentialType),
                },
            };
        }
    };
    return UserCredentialCCCredentialChecksumGet = _classThis;
})();
export { UserCredentialCCCredentialChecksumGet };
let UserCredentialCCAdminPinCodeSet = (() => {
    let _classDecorators = [CCCommand(UserCredentialCommand.AdminPinCodeSet), useSupervision()];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = UserCredentialCC;
    var UserCredentialCCAdminPinCodeSet = class extends _classSuper {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            UserCredentialCCAdminPinCodeSet = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
            __runInitializers(_classThis, _classExtraInitializers);
        }
        constructor(options) {
            super(options);
            this.pinCode = options.pinCode;
        }
        pinCode;
        static from(raw, ctx) {
            validatePayload(raw.payload.length >= 1);
            const pinLength = raw.payload[0] & 0b1111;
            validatePayload(raw.payload.length >= 1 + pinLength);
            const pinCode = raw.payload
                .subarray(1, 1 + pinLength)
                .toString("ascii");
            return new this({
                nodeId: ctx.sourceNodeId,
                pinCode,
            });
        }
        serialize(ctx) {
            const pinCode = this.pinCode.slice(0, 15);
            this.payload = Bytes.concat([
                [pinCode.length & 0b1111],
                Bytes.from(pinCode, "ascii"),
            ]);
            return super.serialize(ctx);
        }
        toLogEntry(ctx) {
            return {
                ...super.toLogEntry(ctx),
                message: {
                    "PIN code": credentialToLogString(this.pinCode),
                },
            };
        }
    };
    return UserCredentialCCAdminPinCodeSet = _classThis;
})();
export { UserCredentialCCAdminPinCodeSet };
let UserCredentialCCAdminPinCodeReport = (() => {
    let _classDecorators = [CCCommand(UserCredentialCommand.AdminPinCodeReport)];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = UserCredentialCC;
    var UserCredentialCCAdminPinCodeReport = class extends _classSuper {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            UserCredentialCCAdminPinCodeReport = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
            __runInitializers(_classThis, _classExtraInitializers);
        }
        constructor(options) {
            super(options);
            this.operationResult = options.operationResult;
            this.pinCode = options.pinCode;
        }
        static from(raw, ctx) {
            validatePayload(raw.payload.length >= 1);
            const operationResult = (raw.payload[0] >> 4) & 0b1111;
            const pinLength = raw.payload[0] & 0b1111;
            validatePayload(raw.payload.length >= 1 + pinLength);
            const pinCode = raw.payload
                .subarray(1, 1 + pinLength)
                .toString("ascii");
            return new this({
                nodeId: ctx.sourceNodeId,
                operationResult,
                pinCode,
            });
        }
        operationResult;
        pinCode;
        serialize(ctx) {
            const pinBuffer = Bytes.from(this.pinCode, "ascii");
            this.payload = Bytes.alloc(1 + pinBuffer.length);
            this.payload[0] = ((this.operationResult & 0b1111) << 4)
                | (pinBuffer.length & 0b1111);
            if (pinBuffer.length > 0) {
                this.payload.set(pinBuffer, 1);
            }
            return super.serialize(ctx);
        }
        persistValues(ctx) {
            if (!super.persistValues(ctx))
                return false;
            if (this.operationResult
                === UserCredentialAdminCodeOperationResult.Modified
                || this.operationResult
                    === UserCredentialAdminCodeOperationResult.ResponseToGet) {
                this.setValue(ctx, UserCredentialCCValues.adminPinCode, this.pinCode);
            }
            return true;
        }
        toLogEntry(ctx) {
            return {
                ...super.toLogEntry(ctx),
                message: {
                    "operation result": getEnumMemberName(UserCredentialAdminCodeOperationResult, this.operationResult),
                    "PIN code": credentialToLogString(this.pinCode),
                },
            };
        }
    };
    return UserCredentialCCAdminPinCodeReport = _classThis;
})();
export { UserCredentialCCAdminPinCodeReport };
function testResponseForUserCredentialAdminPinCodeGet(_sent, received) {
    return (received.operationResult
        === UserCredentialAdminCodeOperationResult.ResponseToGet);
}
let UserCredentialCCAdminPinCodeGet = (() => {
    let _classDecorators = [CCCommand(UserCredentialCommand.AdminPinCodeGet), expectedCCResponse(UserCredentialCCAdminPinCodeReport, testResponseForUserCredentialAdminPinCodeGet)];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = UserCredentialCC;
    var UserCredentialCCAdminPinCodeGet = class extends _classSuper {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            UserCredentialCCAdminPinCodeGet = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
            __runInitializers(_classThis, _classExtraInitializers);
        }
    };
    return UserCredentialCCAdminPinCodeGet = _classThis;
})();
export { UserCredentialCCAdminPinCodeGet };
let UserCredentialCCKeyLockerEntrySet = (() => {
    let _classDecorators = [CCCommand(UserCredentialCommand.KeyLockerEntrySet), useSupervision()];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = UserCredentialCC;
    var UserCredentialCCKeyLockerEntrySet = class extends _classSuper {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            UserCredentialCCKeyLockerEntrySet = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
            __runInitializers(_classThis, _classExtraInitializers);
        }
        constructor(options) {
            super(options);
            this.entryType = options.entryType;
            this.entrySlot = options.entrySlot;
            this.operationType = options.operationType;
            if (options.operationType !== UserCredentialOperationType.Delete) {
                this.entryData = options.entryData;
            }
        }
        entryType;
        entrySlot;
        operationType;
        entryData;
        static from(raw, ctx) {
            validatePayload(raw.payload.length >= 4);
            const entryType = raw.payload[0];
            const entrySlot = raw.payload.readUInt16BE(1);
            const operationType = raw.payload[3]
                & 0b11;
            if (operationType === UserCredentialOperationType.Delete) {
                return new this({
                    nodeId: ctx.sourceNodeId,
                    entryType,
                    entrySlot,
                    operationType,
                });
            }
            let entryData = new Bytes();
            if (raw.payload.length >= 6) {
                const entryDataLength = raw.payload.readUInt16BE(4);
                validatePayload(raw.payload.length >= 6 + entryDataLength);
                entryData = Bytes.from(raw.payload.subarray(6, 6 + entryDataLength));
            }
            return new this({
                nodeId: ctx.sourceNodeId,
                entryType,
                entrySlot,
                operationType,
                entryData,
            });
        }
        serialize(ctx) {
            // For Delete, entry data MAY be omitted
            if (this.operationType === UserCredentialOperationType.Delete) {
                this.payload = Bytes.alloc(4);
                this.payload[0] = this.entryType;
                this.payload.writeUInt16BE(this.entrySlot, 1);
                this.payload[3] = this.operationType & 0b11;
                return super.serialize(ctx);
            }
            if (this.entryData == undefined) {
                throw new ZWaveError(`${this.constructor.name}: entry data must be set for Add/Modify operations`, ZWaveErrorCodes.Argument_Invalid);
            }
            this.payload = Bytes.alloc(6 + this.entryData.length);
            this.payload[0] = this.entryType;
            this.payload.writeUInt16BE(this.entrySlot, 1);
            this.payload[3] = this.operationType & 0b11;
            this.payload.writeUInt16BE(this.entryData.length, 4);
            if (this.entryData.length > 0) {
                this.payload.set(this.entryData, 6);
            }
            return super.serialize(ctx);
        }
        toLogEntry(ctx) {
            const message = {
                "entry type": getEnumMemberName(UserCredentialKeyLockerEntryType, this.entryType),
                "entry slot": this.entrySlot,
                "operation type": getEnumMemberName(UserCredentialOperationType, this.operationType),
            };
            if (this.entryData != undefined) {
                message["entry data length"] = this.entryData.length;
            }
            return { ...super.toLogEntry(ctx), message };
        }
    };
    return UserCredentialCCKeyLockerEntrySet = _classThis;
})();
export { UserCredentialCCKeyLockerEntrySet };
let UserCredentialCCKeyLockerEntryReport = (() => {
    let _classDecorators = [CCCommand(UserCredentialCommand.KeyLockerEntryReport)];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = UserCredentialCC;
    var UserCredentialCCKeyLockerEntryReport = class extends _classSuper {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            UserCredentialCCKeyLockerEntryReport = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
            __runInitializers(_classThis, _classExtraInitializers);
        }
        constructor(options) {
            super(options);
            this.occupied = options.occupied;
            this.entryType = options.entryType;
            this.entrySlot = options.entrySlot;
        }
        static from(raw, ctx) {
            validatePayload(raw.payload.length >= 4);
            const occupied = !!(raw.payload[0] & 0x01);
            const entryType = raw.payload[1];
            const entrySlot = raw.payload.readUInt16BE(2);
            return new this({
                nodeId: ctx.sourceNodeId,
                occupied,
                entryType,
                entrySlot,
            });
        }
        occupied;
        entryType;
        entrySlot;
        serialize(ctx) {
            this.payload = Bytes.alloc(4);
            this.payload[0] = this.occupied ? 0x01 : 0x00;
            this.payload[1] = this.entryType;
            this.payload.writeUInt16BE(this.entrySlot, 2);
            return super.serialize(ctx);
        }
        persistValues(ctx) {
            if (!super.persistValues(ctx))
                return false;
            this.setValue(ctx, UserCredentialCCValues.keyLockerEntry(this.entryType, this.entrySlot), this.occupied);
            return true;
        }
        toLogEntry(ctx) {
            return {
                ...super.toLogEntry(ctx),
                message: {
                    occupied: this.occupied,
                    "entry type": getEnumMemberName(UserCredentialKeyLockerEntryType, this.entryType),
                    "entry slot": this.entrySlot,
                },
            };
        }
    };
    return UserCredentialCCKeyLockerEntryReport = _classThis;
})();
export { UserCredentialCCKeyLockerEntryReport };
function testResponseForUserCredentialKeyLockerEntryGet(sent, received) {
    return received.entryType === sent.entryType
        && received.entrySlot === sent.entrySlot;
}
let UserCredentialCCKeyLockerEntryGet = (() => {
    let _classDecorators = [CCCommand(UserCredentialCommand.KeyLockerEntryGet), expectedCCResponse(UserCredentialCCKeyLockerEntryReport, testResponseForUserCredentialKeyLockerEntryGet)];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = UserCredentialCC;
    var UserCredentialCCKeyLockerEntryGet = class extends _classSuper {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            UserCredentialCCKeyLockerEntryGet = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
            __runInitializers(_classThis, _classExtraInitializers);
        }
        constructor(options) {
            super(options);
            this.entryType = options.entryType;
            this.entrySlot = options.entrySlot;
        }
        entryType;
        entrySlot;
        static from(raw, ctx) {
            validatePayload(raw.payload.length >= 3);
            const entryType = raw.payload[0];
            const entrySlot = raw.payload.readUInt16BE(1);
            return new this({
                nodeId: ctx.sourceNodeId,
                entryType,
                entrySlot,
            });
        }
        serialize(ctx) {
            this.payload = Bytes.alloc(3);
            this.payload[0] = this.entryType;
            this.payload.writeUInt16BE(this.entrySlot, 1);
            return super.serialize(ctx);
        }
        toLogEntry(ctx) {
            return {
                ...super.toLogEntry(ctx),
                message: {
                    "entry type": getEnumMemberName(UserCredentialKeyLockerEntryType, this.entryType),
                    "entry slot": this.entrySlot,
                },
            };
        }
    };
    return UserCredentialCCKeyLockerEntryGet = _classThis;
})();
export { UserCredentialCCKeyLockerEntryGet };
//# sourceMappingURL=UserCredentialCC.js.map