@jsprismarine/prismarine
Version:
Dedicated Minecraft Bedrock Edition server written in TypeScript
184 lines (183 loc) • 23 kB
JavaScript
import { NetworkUtil } from "../../network/NetworkUtil.es.js";
import SkinAnimation from "./SkinAnimation.es.js";
import SkinCape from "./SkinCape.es.js";
import SkinImage from "./SkinImage.es.js";
import SkinPersona from "./skin-persona/SkinPersona.es.js";
import SkinPersonaPiece from "./skin-persona/SkinPersonaPiece.es.js";
import SkinPersonaPieceTintColor from "./skin-persona/SkinPersonaPieceTintColor.es.js";
//#region src/utils/skin/Skin.ts
var Skin = class Skin {
id;
playFabId;
resourcePatch;
image;
animations = /* @__PURE__ */ new Set();
cape;
geometry;
animationData;
premium;
persona;
capeOnClassicSkin;
color = "#0";
armSize = "wide";
personaData;
/**
* Full skin ID, computed because
* not sent on JWT.
*/
fullId;
isTrusted = true;
/**
* Loads a skin from a JSON file containing skin data
* using minecraft bedrock login fields.
*
* (loads the skin persona)
*/
static fromJWT(jwt) {
const skin = new Skin();
skin.id = jwt.SkinId;
skin.resourcePatch = Buffer.from(jwt.SkinResourcePatch, "base64").toString();
skin.image = new SkinImage({
width: jwt.SkinImageWidth,
height: jwt.SkinImageHeight,
data: Buffer.from(jwt.SkinData, "base64")
});
skin.playFabId = jwt.PlayFabId;
skin.color = jwt.SkinColor;
skin.armSize = jwt.ArmSize;
for (const animation of jwt.AnimatedImageData) skin.animations.add(new SkinAnimation({
image: new SkinImage({
width: animation.ImageWidth,
height: animation.ImageHeight,
data: Buffer.from(animation.Image, "base64")
}),
frames: animation.Frames,
type: animation.Type,
expression: animation.AnimationExpression
}));
skin.cape = new SkinCape({
id: jwt.CapeId,
image: new SkinImage({
width: jwt.CapeImageWidth,
height: jwt.CapeImageHeight,
data: Buffer.from(jwt.CapeData, "base64")
})
});
skin.geometry = Buffer.from(jwt.SkinGeometryData, "base64").toString();
skin.animationData = Buffer.from(jwt.SkinAnimationData, "base64").toString();
skin.premium = jwt.PremiumSkin;
skin.persona = jwt.PersonaSkin;
skin.capeOnClassicSkin = jwt.CapeOnClassicSkin;
if (skin.persona) {
skin.personaData = new SkinPersona();
for (const personaPiece of jwt.PersonaPieces) skin.personaData.getPieces().add(new SkinPersonaPiece({
def: personaPiece.IsDefault,
packId: personaPiece.PackId,
pieceId: personaPiece.PieceId,
pieceType: personaPiece.PieceType,
productId: personaPiece.ProductId
}));
for (const pieceTintColor of jwt.PieceTintColors) {
const tintColor = new SkinPersonaPieceTintColor();
tintColor.getColors().push(...pieceTintColor.Colors);
tintColor.setPieceType(pieceTintColor.PieceType);
skin.personaData.getTintColors().add(tintColor);
}
}
skin.fullId = skin.id + skin.getCape().getId();
return skin;
}
networkSerialize(stream) {
NetworkUtil.writeString(stream, this.getId());
NetworkUtil.writeString(stream, this.getPlayFabId());
NetworkUtil.writeString(stream, this.getResourcePatch());
this.getImage().networkSerialize(stream);
stream.writeUnsignedIntLE(this.getAnimations().size);
for (const animation of this.getAnimations()) {
animation.getImage().networkSerialize(stream);
stream.writeUnsignedIntLE(animation.getType());
stream.writeFloatLE(animation.getFrames());
stream.writeUnsignedIntLE(animation.getExpression());
}
this.getCape().getImage().networkSerialize(stream);
NetworkUtil.writeString(stream, this.getGeometry());
NetworkUtil.writeString(stream, "0.0.0");
NetworkUtil.writeString(stream, this.getAnimationData());
NetworkUtil.writeString(stream, this.getCape().getId());
NetworkUtil.writeString(stream, this.getFullId());
NetworkUtil.writeString(stream, this.getArmSize());
NetworkUtil.writeString(stream, this.getColor());
if (this.isPersona()) {
stream.writeUnsignedIntLE(this.getPersonaData().getPieces().size);
for (const personaPiece of this.getPersonaData().getPieces()) {
NetworkUtil.writeString(stream, personaPiece.getPieceId());
NetworkUtil.writeString(stream, personaPiece.getPieceType());
NetworkUtil.writeString(stream, personaPiece.getPackId());
stream.writeBoolean(personaPiece.isDefault());
NetworkUtil.writeString(stream, personaPiece.getProductId());
}
stream.writeUnsignedIntLE(this.getPersonaData().getTintColors().size);
for (const tint of this.getPersonaData().getTintColors()) {
NetworkUtil.writeString(stream, tint.getPieceType());
stream.writeUnsignedIntLE(tint.getColors().length);
for (const color of tint.getColors()) NetworkUtil.writeString(stream, color);
}
} else {
stream.writeUnsignedIntLE(0);
stream.writeUnsignedIntLE(0);
}
stream.writeBoolean(this.isPremium());
stream.writeBoolean(this.isPersona());
stream.writeBoolean(this.isCapeOnClassicSkin());
stream.writeBoolean(false);
stream.writeBoolean(true);
}
getId() {
return this.id;
}
getFullId() {
return this.fullId || this.getId() + this.getCape().getId();
}
getPlayFabId() {
return this.playFabId;
}
getResourcePatch() {
return this.resourcePatch;
}
getImage() {
return this.image;
}
getAnimations() {
return this.animations;
}
getAnimationData() {
return this.animationData;
}
isPersona() {
return this.persona;
}
isPremium() {
return this.premium;
}
isCapeOnClassicSkin() {
return this.capeOnClassicSkin;
}
getColor() {
return this.color;
}
getArmSize() {
return this.armSize;
}
getPersonaData() {
return this.personaData;
}
getGeometry() {
return this.geometry;
}
getCape() {
return this.cape;
}
};
//#endregion
export { Skin as default };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2tpbi5lcy5qcyIsIm5hbWVzIjpbXSwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdXRpbHMvc2tpbi9Ta2luLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIEJpbmFyeVN0cmVhbSBmcm9tICdAanNwcmlzbWFyaW5lL2pzYmluYXJ5dXRpbHMnO1xuaW1wb3J0IHsgTmV0d29ya1V0aWwgfSBmcm9tICcuLi8uLi9uZXR3b3JrL05ldHdvcmtVdGlsJztcbmltcG9ydCBTa2luQW5pbWF0aW9uIGZyb20gJy4vU2tpbkFuaW1hdGlvbic7XG5pbXBvcnQgU2tpbkNhcGUgZnJvbSAnLi9Ta2luQ2FwZSc7XG5pbXBvcnQgU2tpbkltYWdlIGZyb20gJy4vU2tpbkltYWdlJztcbmltcG9ydCBTa2luUGVyc29uYSBmcm9tICcuL3NraW4tcGVyc29uYS9Ta2luUGVyc29uYSc7XG5pbXBvcnQgU2tpblBlcnNvbmFQaWVjZSBmcm9tICcuL3NraW4tcGVyc29uYS9Ta2luUGVyc29uYVBpZWNlJztcbmltcG9ydCBTa2luUGVyc29uYVBpZWNlVGludENvbG9yIGZyb20gJy4vc2tpbi1wZXJzb25hL1NraW5QZXJzb25hUGllY2VUaW50Q29sb3InO1xuXG5pbnRlcmZhY2UgSW1hZ2Uge1xuICAgIEltYWdlV2lkdGg6IG51bWJlcjtcbiAgICBJbWFnZUhlaWdodDogbnVtYmVyO1xuICAgIEltYWdlOiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBBbmltYXRlZEltYWdlRGF0YSBleHRlbmRzIEltYWdlIHtcbiAgICBGcmFtZXM6IG51bWJlcjtcbiAgICBUeXBlOiBudW1iZXI7XG4gICAgQW5pbWF0aW9uRXhwcmVzc2lvbjogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgUGVyc29uYVBpZWNlIHtcbiAgICBJc0RlZmF1bHQ6IGJvb2xlYW47XG4gICAgUGFja0lkOiBzdHJpbmc7XG4gICAgUGllY2VJZDogc3RyaW5nO1xuICAgIFBpZWNlVHlwZTogc3RyaW5nO1xuICAgIFByb2R1Y3RJZDogc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgUGllY2VUaW50Q29sb3Ige1xuICAgIENvbG9yczogc3RyaW5nW107XG4gICAgUGllY2VUeXBlOiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBKV1Qge1xuICAgIFNraW5JZDogc3RyaW5nO1xuICAgIENhcGVJZDogc3RyaW5nO1xuICAgIFNraW5SZXNvdXJjZVBhdGNoOiBzdHJpbmc7XG4gICAgUGxheUZhYklkOiBzdHJpbmc7XG4gICAgU2tpbkltYWdlSGVpZ2h0OiBudW1iZXI7XG4gICAgU2tpbkltYWdlV2lkdGg6IG51bWJlcjtcbiAgICBTa2luR2VvbWV0cnlEYXRhOiBzdHJpbmc7XG4gICAgU2tpbkFuaW1hdGlvbkRhdGE6IHN0cmluZztcbiAgICBDYXBlSW1hZ2VIZWlnaHQ6IG51bWJlcjtcbiAgICBDYXBlSW1hZ2VXaWR0aDogbnVtYmVyO1xuICAgIENhcGVPbkNsYXNzaWNTa2luOiBib29sZWFuO1xuICAgIFNraW5EYXRhOiBzdHJpbmc7XG4gICAgQ2FwZURhdGE6IHN0cmluZztcbiAgICBQcmVtaXVtU2tpbjogYm9vbGVhbjtcbiAgICBQZXJzb25hU2tpbjogYm9vbGVhbjtcbiAgICBTa2luQ29sb3I6IHN0cmluZztcbiAgICBBcm1TaXplOiBzdHJpbmc7XG4gICAgQW5pbWF0ZWRJbWFnZURhdGE6IEFuaW1hdGVkSW1hZ2VEYXRhW107XG4gICAgUGVyc29uYVBpZWNlczogUGVyc29uYVBpZWNlW107XG4gICAgUGllY2VUaW50Q29sb3JzOiBQaWVjZVRpbnRDb2xvcltdO1xufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTa2luIHtcbiAgICBwcml2YXRlIGlkITogc3RyaW5nO1xuICAgIHByaXZhdGUgcGxheUZhYklkITogc3RyaW5nO1xuICAgIHByaXZhdGUgcmVzb3VyY2VQYXRjaCE6IHN0cmluZztcbiAgICBwcml2YXRlIGltYWdlITogU2tpbkltYWdlO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgYW5pbWF0aW9uczogU2V0PFNraW5BbmltYXRpb24+ID0gbmV3IFNldCgpO1xuICAgIHByaXZhdGUgY2FwZSE6IFNraW5DYXBlO1xuICAgIHByaXZhdGUgZ2VvbWV0cnkhOiBzdHJpbmc7XG4gICAgcHJpdmF0ZSBhbmltYXRpb25EYXRhITogc3RyaW5nO1xuICAgIHByaXZhdGUgcHJlbWl1bSE6IGJvb2xlYW47XG4gICAgcHJpdmF0ZSBwZXJzb25hITogYm9vbGVhbjtcbiAgICBwcml2YXRlIGNhcGVPbkNsYXNzaWNTa2luITogYm9vbGVhbjtcbiAgICBwcml2YXRlIGNvbG9yID0gJyMwJztcbiAgICBwcml2YXRlIGFybVNpemUgPSAnd2lkZSc7XG4gICAgcHJpdmF0ZSBwZXJzb25hRGF0YSE6IFNraW5QZXJzb25hO1xuXG4gICAgLyoqXG4gICAgICogRnVsbCBza2luIElELCBjb21wdXRlZCBiZWNhdXNlXG4gICAgICogbm90IHNlbnQgb24gSldULlxuICAgICAqL1xuICAgIHB1YmxpYyBmdWxsSWQhOiBzdHJpbmc7XG4gICAgcHVibGljIGlzVHJ1c3RlZCA9IHRydWU7XG5cbiAgICAvKipcbiAgICAgKiBMb2FkcyBhIHNraW4gZnJvbSBhIEpTT04gZmlsZSBjb250YWluaW5nIHNraW4gZGF0YVxuICAgICAqIHVzaW5nIG1pbmVjcmFmdCBiZWRyb2NrIGxvZ2luIGZpZWxkcy5cbiAgICAgKlxuICAgICAqIChsb2FkcyB0aGUgc2tpbiBwZXJzb25hKVxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgZnJvbUpXVChqd3Q6IEpXVCk6IFNraW4ge1xuICAgICAgICBjb25zdCBza2luID0gbmV3IFNraW4oKTtcblxuICAgICAgICAvLyBSZWFkIHNraW5cbiAgICAgICAgc2tpbi5pZCA9IGp3dC5Ta2luSWQ7XG4gICAgICAgIHNraW4ucmVzb3VyY2VQYXRjaCA9IEJ1ZmZlci5mcm9tKGp3dC5Ta2luUmVzb3VyY2VQYXRjaCwgJ2Jhc2U2NCcpLnRvU3RyaW5nKCk7XG4gICAgICAgIHNraW4uaW1hZ2UgPSBuZXcgU2tpbkltYWdlKHtcbiAgICAgICAgICAgIHdpZHRoOiBqd3QuU2tpbkltYWdlV2lkdGgsXG4gICAgICAgICAgICBoZWlnaHQ6IGp3dC5Ta2luSW1hZ2VIZWlnaHQsXG4gICAgICAgICAgICBkYXRhOiBCdWZmZXIuZnJvbShqd3QuU2tpbkRhdGEsICdiYXNlNjQnKVxuICAgICAgICB9KTtcbiAgICAgICAgc2tpbi5wbGF5RmFiSWQgPSBqd3QuUGxheUZhYklkO1xuICAgICAgICBza2luLmNvbG9yID0gand0LlNraW5Db2xvcjtcbiAgICAgICAgc2tpbi5hcm1TaXplID0gand0LkFybVNpemU7XG5cbiAgICAgICAgLy8gUmVhZCBhbmltYXRpb25zXG4gICAgICAgIGZvciAoY29uc3QgYW5pbWF0aW9uIG9mIGp3dC5BbmltYXRlZEltYWdlRGF0YSkge1xuICAgICAgICAgICAgc2tpbi5hbmltYXRpb25zLmFkZChcbiAgICAgICAgICAgICAgICBuZXcgU2tpbkFuaW1hdGlvbih7XG4gICAgICAgICAgICAgICAgICAgIGltYWdlOiBuZXcgU2tpbkltYWdlKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoOiBhbmltYXRpb24uSW1hZ2VXaWR0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodDogYW5pbWF0aW9uLkltYWdlSGVpZ2h0LFxuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YTogQnVmZmVyLmZyb20oYW5pbWF0aW9uLkltYWdlLCAnYmFzZTY0JylcbiAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICAgIGZyYW1lczogYW5pbWF0aW9uLkZyYW1lcyxcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogYW5pbWF0aW9uLlR5cGUsXG4gICAgICAgICAgICAgICAgICAgIGV4cHJlc3Npb246IGFuaW1hdGlvbi5BbmltYXRpb25FeHByZXNzaW9uXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBSZWFkIGNhcGVcbiAgICAgICAgc2tpbi5jYXBlID0gbmV3IFNraW5DYXBlKHtcbiAgICAgICAgICAgIGlkOiBqd3QuQ2FwZUlkLFxuICAgICAgICAgICAgaW1hZ2U6IG5ldyBTa2luSW1hZ2Uoe1xuICAgICAgICAgICAgICAgIHdpZHRoOiBqd3QuQ2FwZUltYWdlV2lkdGgsXG4gICAgICAgICAgICAgICAgaGVpZ2h0OiBqd3QuQ2FwZUltYWdlSGVpZ2h0LFxuICAgICAgICAgICAgICAgIGRhdGE6IEJ1ZmZlci5mcm9tKGp3dC5DYXBlRGF0YSwgJ2Jhc2U2NCcpXG4gICAgICAgICAgICB9KVxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBUT0RPOiBtYWtlIGEgY2xhc3MgdG8gbWFuYWdlIGdlb21ldHJ5XG4gICAgICAgIHNraW4uZ2VvbWV0cnkgPSBCdWZmZXIuZnJvbShqd3QuU2tpbkdlb21ldHJ5RGF0YSwgJ2Jhc2U2NCcpLnRvU3RyaW5nKCk7XG5cbiAgICAgICAgLy8gVE9ETzogTW9zdCBvZiB0aGUgdGltZXMgaXMgZW1wdHksIGZpZ3VyZSBvdXQgd2hhdCBpcyBpdFxuICAgICAgICBza2luLmFuaW1hdGlvbkRhdGEgPSBCdWZmZXIuZnJvbShqd3QuU2tpbkFuaW1hdGlvbkRhdGEsICdiYXNlNjQnKS50b1N0cmluZygpO1xuXG4gICAgICAgIC8vIFJlYWQgc2tpbiBib29sZWFuIHByb3BlcnRpZXNcbiAgICAgICAgc2tpbi5wcmVtaXVtID0gand0LlByZW1pdW1Ta2luO1xuICAgICAgICBza2luLnBlcnNvbmEgPSBqd3QuUGVyc29uYVNraW47XG4gICAgICAgIHNraW4uY2FwZU9uQ2xhc3NpY1NraW4gPSBqd3QuQ2FwZU9uQ2xhc3NpY1NraW47XG5cbiAgICAgICAgLy8gQXZvaWQgcmVhZGluZyB3aGVuIHNraW4gaXMgbm90IHBlcnNvbmEgdHlwZVxuICAgICAgICBpZiAoc2tpbi5wZXJzb25hKSB7XG4gICAgICAgICAgICBza2luLnBlcnNvbmFEYXRhID0gbmV3IFNraW5QZXJzb25hKCk7XG5cbiAgICAgICAgICAgIC8vIFJlYWQgcGVyc29uYSBwaWVjZXNcbiAgICAgICAgICAgIGZvciAoY29uc3QgcGVyc29uYVBpZWNlIG9mIGp3dC5QZXJzb25hUGllY2VzKSB7XG4gICAgICAgICAgICAgICAgc2tpbi5wZXJzb25hRGF0YS5nZXRQaWVjZXMoKS5hZGQoXG4gICAgICAgICAgICAgICAgICAgIG5ldyBTa2luUGVyc29uYVBpZWNlKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlZjogcGVyc29uYVBpZWNlLklzRGVmYXVsdCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tJZDogcGVyc29uYVBpZWNlLlBhY2tJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBpZWNlSWQ6IHBlcnNvbmFQaWVjZS5QaWVjZUlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGllY2VUeXBlOiBwZXJzb25hUGllY2UuUGllY2VUeXBlLFxuICAgICAgICAgICAgICAgICAgICAgICAgcHJvZHVjdElkOiBwZXJzb25hUGllY2UuUHJvZHVjdElkXG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gUmVhZCBwaWVjZSB0aW50IGNvbG9yc1xuICAgICAgICAgICAgZm9yIChjb25zdCBwaWVjZVRpbnRDb2xvciBvZiBqd3QuUGllY2VUaW50Q29sb3JzKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdGludENvbG9yID0gbmV3IFNraW5QZXJzb25hUGllY2VUaW50Q29sb3IoKTtcbiAgICAgICAgICAgICAgICB0aW50Q29sb3IuZ2V0Q29sb3JzKCkucHVzaCguLi5waWVjZVRpbnRDb2xvci5Db2xvcnMpO1xuICAgICAgICAgICAgICAgIHRpbnRDb2xvci5zZXRQaWVjZVR5cGUocGllY2VUaW50Q29sb3IuUGllY2VUeXBlKTtcbiAgICAgICAgICAgICAgICBza2luLnBlcnNvbmFEYXRhLmdldFRpbnRDb2xvcnMoKS5hZGQodGludENvbG9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENvbXB1dGUgYSBmdWxsIGlkXG4gICAgICAgIHNraW4uZnVsbElkID0gc2tpbi5pZCArIHNraW4uZ2V0Q2FwZSgpLmdldElkKCk7XG4gICAgICAgIHJldHVybiBza2luO1xuICAgIH1cblxuICAgIHB1YmxpYyBuZXR3b3JrU2VyaWFsaXplKHN0cmVhbTogQmluYXJ5U3RyZWFtKTogdm9pZCB7XG4gICAgICAgIE5ldHdvcmtVdGlsLndyaXRlU3RyaW5nKHN0cmVhbSwgdGhpcy5nZXRJZCgpKTtcbiAgICAgICAgTmV0d29ya1V0aWwud3JpdGVTdHJpbmcoc3RyZWFtLCB0aGlzLmdldFBsYXlGYWJJZCgpKTtcbiAgICAgICAgTmV0d29ya1V0aWwud3JpdGVTdHJpbmcoc3RyZWFtLCB0aGlzLmdldFJlc291cmNlUGF0Y2goKSk7XG5cbiAgICAgICAgLy8gU2tpbiBpbWFnZVxuICAgICAgICB0aGlzLmdldEltYWdlKCkubmV0d29ya1NlcmlhbGl6ZShzdHJlYW0pO1xuXG4gICAgICAgIC8vIEFuaW1hdGlvbnNcbiAgICAgICAgc3RyZWFtLndyaXRlVW5zaWduZWRJbnRMRSh0aGlzLmdldEFuaW1hdGlvbnMoKS5zaXplKTtcbiAgICAgICAgZm9yIChjb25zdCBhbmltYXRpb24gb2YgdGhpcy5nZXRBbmltYXRpb25zKCkpIHtcbiAgICAgICAgICAgIGFuaW1hdGlvbi5nZXRJbWFnZSgpLm5ldHdvcmtTZXJpYWxpemUoc3RyZWFtKTtcbiAgICAgICAgICAgIHN0cmVhbS53cml0ZVVuc2lnbmVkSW50TEUoYW5pbWF0aW9uLmdldFR5cGUoKSk7XG4gICAgICAgICAgICBzdHJlYW0ud3JpdGVGbG9hdExFKGFuaW1hdGlvbi5nZXRGcmFtZXMoKSk7XG4gICAgICAgICAgICBzdHJlYW0ud3JpdGVVbnNpZ25lZEludExFKGFuaW1hdGlvbi5nZXRFeHByZXNzaW9uKCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ2FwZSBpbWFnZVxuICAgICAgICB0aGlzLmdldENhcGUoKS5nZXRJbWFnZSgpLm5ldHdvcmtTZXJpYWxpemUoc3RyZWFtKTtcblxuICAgICAgICAvLyBNaXNjZWxsYW5lb3VzXG4gICAgICAgIE5ldHdvcmtVdGlsLndyaXRlU3RyaW5nKHN0cmVhbSwgdGhpcy5nZXRHZW9tZXRyeSgpKTtcbiAgICAgICAgTmV0d29ya1V0aWwud3JpdGVTdHJpbmcoc3RyZWFtLCAnMC4wLjAnKTsgLy8gZ2VvbWV0cnkgZGF0YSBlbmdpbmUgdmVyc2lvblxuICAgICAgICBOZXR3b3JrVXRpbC53cml0ZVN0cmluZyhzdHJlYW0sIHRoaXMuZ2V0QW5pbWF0aW9uRGF0YSgpKTtcbiAgICAgICAgTmV0d29ya1V0aWwud3JpdGVTdHJpbmcoc3RyZWFtLCB0aGlzLmdldENhcGUoKS5nZXRJZCgpKTtcbiAgICAgICAgTmV0d29ya1V0aWwud3JpdGVTdHJpbmcoc3RyZWFtLCB0aGlzLmdldEZ1bGxJZCgpKTtcbiAgICAgICAgTmV0d29ya1V0aWwud3JpdGVTdHJpbmcoc3RyZWFtLCB0aGlzLmdldEFybVNpemUoKSk7XG4gICAgICAgIE5ldHdvcmtVdGlsLndyaXRlU3RyaW5nKHN0cmVhbSwgdGhpcy5nZXRDb2xvcigpKTtcblxuICAgICAgICAvLyBIYWNrIHRvIGtlZXAgbGVzcyB1c2VsZXNzIGRhdGEgaW4gc29mdHdhcmVcbiAgICAgICAgaWYgKHRoaXMuaXNQZXJzb25hKCkpIHtcbiAgICAgICAgICAgIHN0cmVhbS53cml0ZVVuc2lnbmVkSW50TEUodGhpcy5nZXRQZXJzb25hRGF0YSgpLmdldFBpZWNlcygpLnNpemUpO1xuICAgICAgICAgICAgZm9yIChjb25zdCBwZXJzb25hUGllY2Ugb2YgdGhpcy5nZXRQZXJzb25hRGF0YSgpLmdldFBpZWNlcygpKSB7XG4gICAgICAgICAgICAgICAgTmV0d29ya1V0aWwud3JpdGVTdHJpbmcoc3RyZWFtLCBwZXJzb25hUGllY2UuZ2V0UGllY2VJZCgpKTtcbiAgICAgICAgICAgICAgICBOZXR3b3JrVXRpbC53cml0ZVN0cmluZyhzdHJlYW0sIHBlcnNvbmFQaWVjZS5nZXRQaWVjZVR5cGUoKSk7XG4gICAgICAgICAgICAgICAgTmV0d29ya1V0aWwud3JpdGVTdHJpbmcoc3RyZWFtLCBwZXJzb25hUGllY2UuZ2V0UGFja0lkKCkpO1xuICAgICAgICAgICAgICAgIHN0cmVhbS53cml0ZUJvb2xlYW4ocGVyc29uYVBpZWNlLmlzRGVmYXVsdCgpKTtcbiAgICAgICAgICAgICAgICBOZXR3b3JrVXRpbC53cml0ZVN0cmluZyhzdHJlYW0sIHBlcnNvbmFQaWVjZS5nZXRQcm9kdWN0SWQoKSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHN0cmVhbS53cml0ZVVuc2lnbmVkSW50TEUodGhpcy5nZXRQZXJzb25hRGF0YSgpLmdldFRpbnRDb2xvcnMoKS5zaXplKTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgdGludCBvZiB0aGlzLmdldFBlcnNvbmFEYXRhKCkuZ2V0VGludENvbG9ycygpKSB7XG4gICAgICAgICAgICAgICAgTmV0d29ya1V0aWwud3JpdGVTdHJpbmcoc3RyZWFtLCB0aW50LmdldFBpZWNlVHlwZSgpKTtcbiAgICAgICAgICAgICAgICBzdHJlYW0ud3JpdGVVbnNpZ25lZEludExFKHRpbnQuZ2V0Q29sb3JzKCkubGVuZ3RoKTtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGNvbG9yIG9mIHRpbnQuZ2V0Q29sb3JzKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgTmV0d29ya1V0aWwud3JpdGVTdHJpbmcoc3RyZWFtLCBjb2xvcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc3RyZWFtLndyaXRlVW5zaWduZWRJbnRMRSgwKTsgLy8gUGVyc29uYSBwaWVjZXNcbiAgICAgICAgICAgIHN0cmVhbS53cml0ZVVuc2lnbmVkSW50TEUoMCk7IC8vIFRpbnQgY29sb3JzXG4gICAgICAgIH1cblxuICAgICAgICBzdHJlYW0ud3JpdGVCb29sZWFuKHRoaXMuaXNQcmVtaXVtKCkpO1xuICAgICAgICBzdHJlYW0ud3JpdGVCb29sZWFuKHRoaXMuaXNQZXJzb25hKCkpO1xuICAgICAgICBzdHJlYW0ud3JpdGVCb29sZWFuKHRoaXMuaXNDYXBlT25DbGFzc2ljU2tpbigpKTtcbiAgICAgICAgc3RyZWFtLndyaXRlQm9vbGVhbihmYWxzZSk7IC8vIElzIHByaW1hcnkgdXNlclxuICAgICAgICBzdHJlYW0ud3JpdGVCb29sZWFuKHRydWUpOyAvLyBJcyBvdmVycmlkZVxuICAgIH1cblxuICAgIHB1YmxpYyBnZXRJZCgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5pZDtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0RnVsbElkKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLmZ1bGxJZCB8fCB0aGlzLmdldElkKCkgKyB0aGlzLmdldENhcGUoKS5nZXRJZCgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRQbGF5RmFiSWQoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGxheUZhYklkO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRSZXNvdXJjZVBhdGNoKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLnJlc291cmNlUGF0Y2g7XG4gICAgfVxuXG4gICAgcHVibGljIGdldEltYWdlKCk6IFNraW5JbWFnZSB7XG4gICAgICAgIHJldHVybiB0aGlzLmltYWdlO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRBbmltYXRpb25zKCk6IFNldDxTa2luQW5pbWF0aW9uPiB7XG4gICAgICAgIHJldHVybiB0aGlzLmFuaW1hdGlvbnM7XG4gICAgfVxuXG4gICAgcHVibGljIGdldEFuaW1hdGlvbkRhdGEoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYW5pbWF0aW9uRGF0YTtcbiAgICB9XG5cbiAgICBwdWJsaWMgaXNQZXJzb25hKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5wZXJzb25hO1xuICAgIH1cblxuICAgIHB1YmxpYyBpc1ByZW1pdW0oKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLnByZW1pdW07XG4gICAgfVxuXG4gICAgcHVibGljIGlzQ2FwZU9uQ2xhc3NpY1NraW4oKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLmNhcGVPbkNsYXNzaWNTa2luO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRDb2xvcigpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5jb2xvcjtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0QXJtU2l6ZSgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5hcm1TaXplO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRQZXJzb25hRGF0YSgpOiBTa2luUGVyc29uYSB7XG4gICAgICAgIHJldHVybiB0aGlzLnBlcnNvbmFEYXRhO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRHZW9tZXRyeSgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5nZW9tZXRyeTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0Q2FwZSgpOiBTa2luQ2FwZSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNhcGU7XG4gICAgfVxufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQXlEQSxJQUFxQixPQUFyQixNQUFxQixLQUFLO0NBQ3RCO0NBQ0E7Q0FDQTtDQUNBO0NBQ0EsNkJBQWtELElBQUksSUFBSTtDQUMxRDtDQUNBO0NBQ0E7Q0FDQTtDQUNBO0NBQ0E7Q0FDQSxRQUFnQjtDQUNoQixVQUFrQjtDQUNsQjs7Ozs7Q0FNQTtDQUNBLFlBQW1COzs7Ozs7O0NBUW5CLE9BQWMsUUFBUSxLQUFnQjtFQUNsQyxNQUFNLE9BQU8sSUFBSSxLQUFLO0VBR3RCLEtBQUssS0FBSyxJQUFJO0VBQ2QsS0FBSyxnQkFBZ0IsT0FBTyxLQUFLLElBQUksbUJBQW1CLFFBQVEsRUFBRSxTQUFTO0VBQzNFLEtBQUssUUFBUSxJQUFJLFVBQVU7R0FDdkIsT0FBTyxJQUFJ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