UNPKG

tsshogi

Version:

TypeScript library for Shogi (Japanese chess)

634 lines 51.8 kB
// CSA file format (.csa)
// See http://www2.computer-shogi.org/protocol/record_v22.html
import { appendLine } from "./helpers/string.mjs";
import { InvalidLineError, InvalidMoveError, InvalidPieceNameError, InvalidTurnError, PieceNotExistsError, } from "./errors.mjs";
import { Color, reverseColor } from "./color.mjs";
import { anySpecialMove, Move, specialMove, SpecialMoveType } from "./move.mjs";
import { Piece, PieceType, promotedPieceType } from "./piece.mjs";
import { Position, countNotExistingPieces, InitialPositionSFEN, } from "./position.mjs";
import { Record, RecordMetadata, RecordMetadataKey, getBlackPlayerName, getWhitePlayerName, } from "./record.mjs";
import { Square } from "./square.mjs";
var LineType;
(function (LineType) {
    LineType[LineType["VERSION"] = 0] = "VERSION";
    LineType[LineType["EXTENDED_COMMENT"] = 1] = "EXTENDED_COMMENT";
    LineType[LineType["COMMENT"] = 2] = "COMMENT";
    LineType[LineType["BLACK_NAME"] = 3] = "BLACK_NAME";
    LineType[LineType["WHITE_NAME"] = 4] = "WHITE_NAME";
    LineType[LineType["METADATA"] = 5] = "METADATA";
    LineType[LineType["POSITION"] = 6] = "POSITION";
    LineType[LineType["RANK"] = 7] = "RANK";
    LineType[LineType["PIECES"] = 8] = "PIECES";
    LineType[LineType["FIRST_TURN"] = 9] = "FIRST_TURN";
    LineType[LineType["MOVE"] = 10] = "MOVE";
    LineType[LineType["SPECIAL_MOVE"] = 11] = "SPECIAL_MOVE";
    LineType[LineType["ELAPSED"] = 12] = "ELAPSED";
})(LineType || (LineType = {}));
var SectionType;
(function (SectionType) {
    SectionType[SectionType["HEADER"] = 0] = "HEADER";
    SectionType[SectionType["MOVE"] = 1] = "MOVE";
    SectionType[SectionType["NEUTRAL"] = 2] = "NEUTRAL";
})(SectionType || (SectionType = {}));
const linePatterns = [
    {
        pattern: /^V/,
        type: LineType.VERSION,
        sectionType: SectionType.HEADER,
    },
    {
        pattern: /^'\*(.+)$/,
        type: LineType.EXTENDED_COMMENT,
        sectionType: SectionType.NEUTRAL,
    },
    {
        pattern: /^'(.+)$/,
        type: LineType.COMMENT,
        sectionType: SectionType.NEUTRAL,
    },
    {
        pattern: /^N\+(.+)$/,
        type: LineType.BLACK_NAME,
        sectionType: SectionType.HEADER,
    },
    {
        pattern: /^N-(.+)$/,
        type: LineType.WHITE_NAME,
        sectionType: SectionType.HEADER,
    },
    {
        pattern: /^\$([^:]+):(.+)$/,
        type: LineType.METADATA,
        sectionType: SectionType.HEADER,
    },
    {
        pattern: /^PI([1-9]{2}[A-Z]{2})*$/,
        type: LineType.POSITION,
        sectionType: SectionType.HEADER,
    },
    {
        pattern: /^P[1-9]( \* ?|[-+][A-Z][A-Z]){9}$/,
        type: LineType.RANK,
        sectionType: SectionType.HEADER,
    },
    {
        pattern: /^P[-+]([0-9]{2}[A-Z]{2})*/,
        type: LineType.PIECES,
        sectionType: SectionType.HEADER,
    },
    {
        pattern: /^[-+]$/,
        type: LineType.FIRST_TURN,
        sectionType: SectionType.HEADER,
    },
    {
        pattern: /^[-+][0-9]{4}[A-Z]{2}/,
        type: LineType.MOVE,
        sectionType: SectionType.MOVE,
    },
    {
        pattern: /^%[-+A-Z_]+/,
        type: LineType.SPECIAL_MOVE,
        sectionType: SectionType.MOVE,
    },
    {
        pattern: /^T([0-9]+(?:\.[0-9]*)?)/,
        type: LineType.ELAPSED,
        sectionType: SectionType.MOVE,
    },
];
function parseLine(line) {
    const results = [];
    const lines = /^['N$]/.test(line) ? [line] : line.split(",");
    for (const line of lines) {
        for (let i = 0; i < linePatterns.length; i++) {
            const matched = linePatterns[i].pattern.exec(line);
            if (matched) {
                results.push({
                    type: linePatterns[i].type,
                    line: line,
                    args: matched.slice(1),
                    sectionType: linePatterns[i].sectionType,
                });
                break;
            }
        }
    }
    return results;
}
const csaNameToRecordMetadataKey = {
    EVENT: RecordMetadataKey.TITLE,
    SITE: RecordMetadataKey.PLACE,
    START_TIME: RecordMetadataKey.START_DATETIME,
    END_TIME: RecordMetadataKey.END_DATETIME,
    TIME_LIMIT: RecordMetadataKey.TIME_LIMIT,
    TIME: RecordMetadataKey.TIME_LIMIT,
    "TIME+": RecordMetadataKey.BLACK_TIME_LIMIT,
    "TIME-": RecordMetadataKey.WHITE_TIME_LIMIT,
    OPENING: RecordMetadataKey.STRATEGY,
    MAX_MOVES: RecordMetadataKey.MAX_MOVES,
    JISHOGI: RecordMetadataKey.JISHOGI,
    NOTE: RecordMetadataKey.NOTE,
};
const csaNameToPieceType = {
    FU: PieceType.PAWN,
    KY: PieceType.LANCE,
    KE: PieceType.KNIGHT,
    GI: PieceType.SILVER,
    KI: PieceType.GOLD,
    KA: PieceType.BISHOP,
    HI: PieceType.ROOK,
    OU: PieceType.KING,
    TO: PieceType.PROM_PAWN,
    NY: PieceType.PROM_LANCE,
    NK: PieceType.PROM_KNIGHT,
    NG: PieceType.PROM_SILVER,
    UM: PieceType.HORSE,
    RY: PieceType.DRAGON,
};
function parsePosition(line, position) {
    position.resetBySFEN(InitialPositionSFEN.STANDARD);
    for (let i = 2; i + 4 <= line.length; i += 4) {
        const file = Number(line[i]);
        const rank = Number(line[i + 1]);
        position.board.remove(new Square(file, rank));
    }
}
function parseRank(line, position) {
    const rank = Number(line[1]);
    let begin = 2;
    for (let x = 0; x < 9; x += 1) {
        const file = 9 - x;
        const section = line.slice(begin, begin + 3);
        // 次のマス目は通常3文字先になる。
        // ただし " *  * " のように空きマスが続いた時にメールやHTML上で連続する空白がまとめられて " * * " となることがある。
        // これはCSAの仕様といては正しいデータではないが、現実に存在するので配慮する。
        // 3文字先へ進めるが、次の文字が "*" であれば1文字戻る。
        begin += 3;
        if (line[begin] === "*") {
            begin -= 1;
        }
        if (section[0] === " ") {
            continue;
        }
        const color = section[0] === "+" ? Color.BLACK : Color.WHITE;
        const pieceType = csaNameToPieceType[section.slice(1)];
        if (!pieceType) {
            return new InvalidPieceNameError(section);
        }
        position.board.set(new Square(file, rank), new Piece(color, pieceType));
    }
}
function parsePieces(line, position) {
    const color = line[1] === "+" ? Color.BLACK : Color.WHITE;
    for (let begin = 2; begin + 4 <= line.length; begin += 4) {
        const section = line.slice(begin, begin + 4);
        if (section === "00AL") {
            const counts = countNotExistingPieces(position);
            if (color === Color.BLACK) {
                position.blackHand.forEach((pieceType) => {
                    position.blackHand.add(pieceType, counts[pieceType]);
                });
            }
            else {
                position.whiteHand.forEach((pieceType) => {
                    position.whiteHand.add(pieceType, counts[pieceType]);
                });
            }
            return;
        }
        const file = Number(section[0]);
        const rank = Number(section[1]);
        const pieceType = csaNameToPieceType[section.slice(2)];
        if (!pieceType) {
            return new InvalidPieceNameError(section);
        }
        if (file !== 0 && rank !== 0) {
            position.board.set(new Square(file, rank), new Piece(color, pieceType));
        }
        else if (color === Color.BLACK) {
            position.blackHand.add(pieceType, 1);
        }
        else {
            position.whiteHand.add(pieceType, 1);
        }
    }
}
function parseMove(line, position) {
    const color = line[0] === "+" ? Color.BLACK : Color.WHITE;
    if (color != position.color) {
        return new InvalidTurnError(line);
    }
    const fromFile = Number(line[1]);
    const fromRank = Number(line[2]);
    const toFile = Number(line[3]);
    const toRank = Number(line[4]);
    const pieceType = csaNameToPieceType[line.slice(5, 7)];
    if (!pieceType) {
        return new InvalidPieceNameError(line);
    }
    const from = fromFile === 0 && fromRank === 0 ? pieceType : new Square(fromFile, fromRank);
    const to = new Square(toFile, toRank);
    let move = position.createMove(from, to);
    if (!move) {
        return new InvalidMoveError(line);
    }
    if (from instanceof Square) {
        const basePiece = position.board.at(from);
        if (!basePiece) {
            return new PieceNotExistsError(line);
        }
        if (basePiece.type !== pieceType) {
            if (basePiece.promoted().type === pieceType) {
                move = move.withPromote();
            }
            else {
                return new PieceNotExistsError(line);
            }
        }
    }
    return move;
}
/**
 * CSA形式の特殊な指し手の名前をSpecialMoveTypeに変換します。
 * @param name 先頭の % 記号を含めない名前をしていします。
 * @param color 手番を指定します。 +ILLEGAL_ACTION や -ILLEGAL_ACTION の読み取りに使用します。
 */
export function getSpecialMoveByName(name, color) {
    switch (name) {
        case "CHUDAN":
            return specialMove(SpecialMoveType.INTERRUPT);
        case "TORYO":
            return specialMove(SpecialMoveType.RESIGN);
        case "MAX_MOVES":
            return specialMove(SpecialMoveType.MAX_MOVES);
        case "JISHOGI":
            return specialMove(SpecialMoveType.IMPASS);
        case "HIKIWAKE":
            return specialMove(SpecialMoveType.DRAW);
        case "SENNICHITE":
            return specialMove(SpecialMoveType.REPETITION_DRAW);
        case "TSUMI":
            return specialMove(SpecialMoveType.MATE);
        case "FUZUMI":
            return specialMove(SpecialMoveType.NO_MATE);
        case "TIME_UP":
            return specialMove(SpecialMoveType.TIMEOUT);
        case "ILLEGAL_MOVE":
            return specialMove(SpecialMoveType.FOUL_LOSE);
        case "+ILLEGAL_ACTION":
            return specialMove(color == Color.BLACK ? SpecialMoveType.FOUL_WIN : SpecialMoveType.FOUL_LOSE);
        case "-ILLEGAL_ACTION":
            return specialMove(color == Color.WHITE ? SpecialMoveType.FOUL_WIN : SpecialMoveType.FOUL_LOSE);
        case "KACHI":
            return specialMove(SpecialMoveType.ENTERING_OF_KING);
    }
    return anySpecialMove(name);
}
/**
 * CSA形式の指し手を読み取ります。
 * @param position
 * @param line
 */
export function parseCSAMove(position, line) {
    return parseMove(line, position);
}
/**
 * CSA形式の棋譜を読み取ります。
 * @param data
 */
export function importCSA(data) {
    const metadata = new RecordMetadata();
    const record = new Record();
    const position = new Position();
    position.resetBySFEN(InitialPositionSFEN.EMPTY);
    let preMoveComment = "";
    let inMoveSection = false;
    const lines = data.replace(/\r?\n\/(\r?\n[\s\S]*)?$/, "").split(/\r?\n/);
    for (const line of lines) {
        for (const parsed of parseLine(line)) {
            if (parsed.sectionType === SectionType.MOVE && !inMoveSection) {
                return new InvalidLineError(parsed.line);
            }
            // NOTE:
            //   WCSC の棋譜中継ではファイルの末尾に $END_TIME が書かれる。
            //   V2.2 の仕様上は認められないはずだが、エラーにすると実用上困るので無視する。
            if (parsed.sectionType === SectionType.HEADER && inMoveSection) {
                continue;
            }
            switch (parsed.type) {
                case LineType.VERSION:
                    break;
                case LineType.EXTENDED_COMMENT:
                    if (inMoveSection) {
                        record.current.comment = appendLine(record.current.comment, parsed.args[0]);
                    }
                    else {
                        preMoveComment = appendLine(preMoveComment, parsed.args[0]);
                    }
                    break;
                case LineType.COMMENT:
                    break;
                case LineType.BLACK_NAME:
                    metadata.setStandardMetadata(RecordMetadataKey.BLACK_NAME, parsed.args[0]);
                    break;
                case LineType.WHITE_NAME:
                    metadata.setStandardMetadata(RecordMetadataKey.WHITE_NAME, parsed.args[0]);
                    break;
                case LineType.METADATA: {
                    const key = csaNameToRecordMetadataKey[parsed.args[0]];
                    if (key) {
                        metadata.setStandardMetadata(key, parsed.args[1]);
                    }
                    else {
                        metadata.setCustomMetadata(parsed.args[0], parsed.args[1]);
                    }
                    break;
                }
                case LineType.POSITION:
                    parsePosition(parsed.line, position);
                    break;
                case LineType.RANK: {
                    const error = parseRank(parsed.line, position);
                    if (error) {
                        return error;
                    }
                    break;
                }
                case LineType.PIECES: {
                    const error = parsePieces(parsed.line, position);
                    if (error) {
                        return error;
                    }
                    break;
                }
                case LineType.FIRST_TURN:
                    if (parsed.line[0] === "+") {
                        position.setColor(Color.BLACK);
                    }
                    else {
                        position.setColor(Color.WHITE);
                    }
                    record.clear(position);
                    record.first.comment = preMoveComment;
                    inMoveSection = true;
                    break;
                case LineType.MOVE: {
                    const moveOrError = parseMove(parsed.line, record.position);
                    if (moveOrError instanceof Error) {
                        return moveOrError;
                    }
                    record.append(moveOrError, { ignoreValidation: true });
                    break;
                }
                case LineType.SPECIAL_MOVE: {
                    const specialMove = getSpecialMoveByName(parsed.line.slice(1), record.position.color);
                    record.append(specialMove, { ignoreValidation: true });
                    break;
                }
                case LineType.ELAPSED:
                    record.current.setElapsedMs(Number(parsed.args[0]) * 1e3);
                    break;
            }
        }
    }
    if (!inMoveSection) {
        record.clear(position);
        record.first.comment = preMoveComment;
    }
    record.goto(0);
    record.resetAllBranchSelection();
    record.metadata = metadata;
    return record;
}
const timeRegExpV2 = /^[0-9]+:[0-9]{2}\+[0-9]+$/;
const timeRegExpV3 = /^[0-9.]+\+[0-9.]+\+[0-9.]+$/;
function formatMetadata(metadata, options) {
    let ret = "";
    const returnCode = options?.returnCode || "\n";
    const blackName = getBlackPlayerName(metadata);
    if (blackName) {
        ret += "N+" + blackName + returnCode;
    }
    const whiteName = getWhitePlayerName(metadata);
    if (whiteName) {
        ret += "N-" + whiteName + returnCode;
    }
    const event = metadata.getStandardMetadata(RecordMetadataKey.TOURNAMENT) ||
        metadata.getStandardMetadata(RecordMetadataKey.TITLE) ||
        metadata.getStandardMetadata(RecordMetadataKey.OPUS_NAME) ||
        metadata.getStandardMetadata(RecordMetadataKey.PUBLISHED_BY);
    if (event) {
        ret += "$EVENT:" + event + returnCode;
    }
    const site = metadata.getStandardMetadata(RecordMetadataKey.PLACE);
    if (site) {
        ret += "$SITE:" + site + returnCode;
    }
    const startTime = metadata.getStandardMetadata(RecordMetadataKey.START_DATETIME) ||
        metadata.getStandardMetadata(RecordMetadataKey.DATE);
    if (startTime) {
        // 年月日 YYYY/MM/DD (10文字) については KIF 形式と共通
        ret += "$START_TIME:" + startTime.slice(10) + returnCode;
    }
    const endTime = metadata.getStandardMetadata(RecordMetadataKey.DATE);
    if (endTime) {
        ret += "$END_TIME:" + endTime.slice(10) + returnCode;
    }
    const opening = metadata.getStandardMetadata(RecordMetadataKey.STRATEGY);
    if (opening) {
        ret += "$OPENING:" + opening + returnCode;
    }
    const timeLimit = metadata.getStandardMetadata(RecordMetadataKey.TIME_LIMIT);
    if (timeLimit && timeRegExpV2.test(timeLimit)) {
        ret += "$TIME_LIMIT:" + timeLimit + returnCode;
    }
    else if (timeLimit && timeRegExpV3.test(timeLimit)) {
        ret += "$TIME:" + timeLimit + returnCode;
    }
    const blackTimeLimit = metadata.getStandardMetadata(RecordMetadataKey.BLACK_TIME_LIMIT);
    if (blackTimeLimit && timeRegExpV3.test(blackTimeLimit)) {
        ret += "$TIME+:" + blackTimeLimit + returnCode;
    }
    const whiteTimeLimit = metadata.getStandardMetadata(RecordMetadataKey.WHITE_TIME_LIMIT);
    if (whiteTimeLimit && timeRegExpV3.test(whiteTimeLimit)) {
        ret += "$TIME-:" + whiteTimeLimit + returnCode;
    }
    const maxMoves = metadata.getStandardMetadata(RecordMetadataKey.MAX_MOVES);
    if (maxMoves) {
        ret += "$MAX_MOVES:" + maxMoves + returnCode;
    }
    const jishogi = metadata.getStandardMetadata(RecordMetadataKey.JISHOGI);
    if (jishogi) {
        ret += "$JISHOGI:" + jishogi + returnCode;
    }
    const note = metadata.getStandardMetadata(RecordMetadataKey.NOTE);
    if (note) {
        ret += "$NOTE:" + note + returnCode;
    }
    return ret;
}
const pieceTypeToString = {
    king: "OU",
    rook: "HI",
    dragon: "RY",
    bishop: "KA",
    horse: "UM",
    gold: "KI",
    silver: "GI",
    promSilver: "NG",
    knight: "KE",
    promKnight: "NK",
    lance: "KY",
    promLance: "NY",
    pawn: "FU",
    promPawn: "TO",
};
function formatHand(hand) {
    let ret = "";
    hand.forEach((pieceType, n) => {
        for (let i = 0; i < n; i++) {
            ret += "00" + pieceTypeToString[pieceType];
        }
    });
    return ret;
}
const sfenToPCommand = {
    [InitialPositionSFEN.STANDARD]: ["PI", "+"],
    [InitialPositionSFEN.HANDICAP_LANCE]: ["PI11KY", "-"],
    [InitialPositionSFEN.HANDICAP_RIGHT_LANCE]: ["PI91KY", "-"],
    [InitialPositionSFEN.HANDICAP_BISHOP]: ["PI22KA", "-"],
    [InitialPositionSFEN.HANDICAP_ROOK]: ["PI82HI", "-"],
    [InitialPositionSFEN.HANDICAP_ROOK_LANCE]: ["PI82HI11KY", "-"],
    [InitialPositionSFEN.HANDICAP_2PIECES]: ["PI82HI22KA", "-"],
    [InitialPositionSFEN.HANDICAP_4PIECES]: ["PI82HI22KA11KY91KY", "-"],
    [InitialPositionSFEN.HANDICAP_6PIECES]: ["PI82HI22KA21KE81KE11KY91KY", "-"],
    [InitialPositionSFEN.HANDICAP_8PIECES]: ["PI82HI22KA31GI71GI21KE81KE11KY91KY", "-"],
    [InitialPositionSFEN.HANDICAP_10PIECES]: ["PI82HI22KA41KI61KI31GI71GI21KE81KE11KY91KY", "-"],
};
function formatPosition(position, options) {
    const returnCode = options?.returnCode || "\n";
    const p = sfenToPCommand[position.sfen];
    if (p) {
        return p[0] + returnCode + p[1] + returnCode;
    }
    let ret = "";
    for (let rank = 1; rank <= 9; rank += 1) {
        ret += "P" + rank;
        for (let file = 9; file >= 1; file -= 1) {
            const piece = position.board.at(new Square(file, rank));
            if (!piece) {
                ret += " * ";
            }
            else if (piece.color === Color.BLACK) {
                ret += "+" + pieceTypeToString[piece.type];
            }
            else {
                ret += "-" + pieceTypeToString[piece.type];
            }
        }
        ret += returnCode;
    }
    ret += "P+" + formatHand(position.blackHand) + returnCode;
    ret += "P-" + formatHand(position.whiteHand) + returnCode;
    ret += (position.color === Color.BLACK ? "+" : "-") + returnCode;
    return ret;
}
function formatSquare(square) {
    return square instanceof Square ? `${square.file}${square.rank}` : "00";
}
/**
 * 特殊な指し手のCSA形式文字列を取得します。
 * 先頭の % は含みません。
 * @param move
 * @param color 手番を指定します。 +ILLEGAL_ACTION や -ILLEGAL_ACTION の出力に使用します。
 */
export function getCSASpecialMoveName(move, color) {
    switch (move.type) {
        case SpecialMoveType.INTERRUPT:
            return "CHUDAN";
        case SpecialMoveType.RESIGN:
            return "TORYO";
        case SpecialMoveType.MAX_MOVES:
            return "MAX_MOVES";
        case SpecialMoveType.IMPASS:
            return "JISHOGI";
        case SpecialMoveType.DRAW:
            return "HIKIWAKE";
        case SpecialMoveType.REPETITION_DRAW:
            return "SENNICHITE";
        case SpecialMoveType.MATE:
            return "TSUMI";
        case SpecialMoveType.NO_MATE:
            return "FUZUMI";
        case SpecialMoveType.TIMEOUT:
            return "TIME_UP";
        case SpecialMoveType.FOUL_LOSE:
            return "ILLEGAL_MOVE";
        case SpecialMoveType.FOUL_WIN:
            return color == Color.BLACK ? "+ILLEGAL_ACTION" : "-ILLEGAL_ACTION";
        case SpecialMoveType.ENTERING_OF_KING:
            return "KACHI";
    }
}
/**
 * CSA形式の指し手を出力します。
 * @param move
 */
export function formatCSAMove(move) {
    return ((move.color === Color.BLACK ? "+" : "-") +
        formatSquare(move.from) +
        formatSquare(move.to) +
        pieceTypeToString[move.promote ? promotedPieceType(move.pieceType) : move.pieceType]);
}
/**
 * CSA形式の棋譜を出力します。
 * @param record
 * @param options
 */
export function exportCSA(record, options) {
    const returnCode = options?.returnCode || "\n";
    let ret = "";
    if (options?.v3) {
        ret += "'CSA encoding=" + (options.v3.encoding || "UTF-8") + returnCode;
    }
    if (options?.comment) {
        for (const line of options.comment.split("\n")) {
            ret += "'" + line + returnCode;
        }
    }
    ret += (options?.v3 ? "V3.0" : "V2.2") + returnCode;
    ret += formatMetadata(record.metadata, options);
    ret += formatPosition(record.initialPosition, options);
    record.moves.forEach((node) => {
        if (node.ply !== 0) {
            let move;
            if (node.move instanceof Move) {
                move = formatCSAMove(node.move);
            }
            else {
                const name = getCSASpecialMoveName(node.move, reverseColor(node.nextColor));
                if (name) {
                    move = "%" + name;
                }
            }
            if (move) {
                ret += move + returnCode;
                if (options?.v3?.milliseconds && node.elapsedMs % 1e3 !== 0) {
                    ret += "T" + node.elapsedMs / 1e3 + returnCode;
                }
                else {
                    ret += "T" + Math.floor(node.elapsedMs / 1e3) + returnCode;
                }
            }
        }
        if (node.comment) {
            const comment = node.comment.endsWith("\n") ? node.comment.slice(0, -1) : node.comment;
            comment.split("\n").forEach((line) => {
                ret += "'*" + line + returnCode;
            });
        }
    });
    return ret;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3NhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NzYS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSx5QkFBeUI7QUFDekIsOERBQThEO0FBRTlELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUM5QyxPQUFPLEVBQ0wsZ0JBQWdCLEVBQ2hCLGdCQUFnQixFQUNoQixxQkFBcUIsRUFDckIsZ0JBQWdCLEVBQ2hCLG1CQUFtQixHQUNwQixNQUFNLFVBQVUsQ0FBQztBQUNsQixPQUFPLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUU5QyxPQUFPLEVBQUUsY0FBYyxFQUFFLElBQUksRUFBRSxXQUFXLEVBQWUsZUFBZSxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBQ3pGLE9BQU8sRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQzlELE9BQU8sRUFDTCxRQUFRLEVBQ1Isc0JBQXNCLEVBRXRCLG1CQUFtQixHQUNwQixNQUFNLFlBQVksQ0FBQztBQUNwQixPQUFPLEVBR0wsTUFBTSxFQUNOLGNBQWMsRUFDZCxpQkFBaUIsRUFDakIsa0JBQWtCLEVBQ2xCLGtCQUFrQixHQUNuQixNQUFNLFVBQVUsQ0FBQztBQUNsQixPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBRWxDLElBQUssUUFjSjtBQWRELFdBQUssUUFBUTtJQUNYLDZDQUFPLENBQUE7SUFDUCwrREFBZ0IsQ0FBQTtJQUNoQiw2Q0FBTyxDQUFBO0lBQ1AsbURBQVUsQ0FBQTtJQUNWLG1EQUFVLENBQUE7SUFDViwrQ0FBUSxDQUFBO0lBQ1IsK0NBQVEsQ0FBQTtJQUNSLHVDQUFJLENBQUE7SUFDSiwyQ0FBTSxDQUFBO0lBQ04sbURBQVUsQ0FBQTtJQUNWLHdDQUFJLENBQUE7SUFDSix3REFBWSxDQUFBO0lBQ1osOENBQU8sQ0FBQTtBQUNULENBQUMsRUFk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