@cute-dw/core
Version:
This TypeScript library is the main part of a more powerfull package designed for the fast WEB software development. The cornerstone of the library is the **DataStore** class, which might be useful when you need a full control of the data, but do not need
147 lines • 22.4 kB
JavaScript
import { HttpParams } from "@angular/common/http";
import { Ciphers } from "../Ciphers";
import { Objects } from "../Objects";
export const JSONRPC_VERSION_2 = "2.0";
export const JSONRPC_VERSION = JSONRPC_VERSION_2;
/**
* This class consists exclusively of the static methods that operate on or return Request/Response objects that follow [JSON-RPC 2.0 Specification](https://www.jsonrpc.org/specification)
* @since 0.5.0
*/
export class JsonRpc {
/**
* Creates a `Request` object to a Server that follows JSON-RPC protocol
* @param method A String containing the name of the method to be invoked. Method names that begin with the word rpc followed by a period character (U+002E or ASCII 46) are reserved for rpc-internal methods and extensions and MUST NOT be used for anything else.
* @param params A Structured value that holds the parameter values to be used during the invocation of the method. This member MAY be omitted.
* @param id An identifier established by the Client that MUST contain a String, Number, or NULL value if included.
* @returns `Request` object in JSON-RPC 2.0 specification
*/
static createRequest(method, params, id) {
let args = undefined;
id = id ?? Ciphers.hashCode(Ciphers.uuid_v4());
if (params) {
args = {};
if (typeof params === "string") {
params = new HttpParams({ fromString: params });
}
if (params instanceof HttpParams) {
let arr;
params.keys().forEach(key => {
arr = params.getAll(key);
if (arr) {
args[key] = arr.length > 1 ? [...arr] : arr[0];
}
else {
args[key] = null;
}
});
}
else {
args = { ...params };
}
}
return { jsonrpc: JSONRPC_VERSION_2, method, params: args, id };
}
/**
* Creates a `Notification` object to a Server that follows JSON-RPC protocol
* @param method A String containing the name of the method to be invoked. Method names that begin with the word rpc followed by a period character (U+002E or ASCII 46) are reserved for rpc-internal methods and extensions and MUST NOT be used for anything else.
* @param params A Structured value that holds the parameter values to be used during the invocation of the method. This member MAY be omitted.
* @returns `Notification` object in JSON-RPC 2.0 specification
*/
static createNotification(method, params) {
let args = undefined;
if (params) {
args = {};
if (typeof params === "string") {
params = new HttpParams({ fromString: params });
}
if (params instanceof HttpParams) {
let arr;
params.keys().forEach(key => {
arr = params.getAll(key);
if (arr) {
args[key] = arr.length > 1 ? [...arr] : arr[0];
}
else {
args[key] = null;
}
});
}
else {
args = { ...params };
}
}
return { jsonrpc: JSONRPC_VERSION_2, method, params: args };
}
/**
* Creates a `Response` object to a Server that follows JSON-RPC protocol
* @param id An identifier established by the Client that MUST contain a String, Number, or NULL value if included.
* @param data A value that is applied to a _result_ or an _error_ property depending on the `success` value
* @param success A boolean value that determines the type of the `Response` object
* @returns `Response` object in JSON-RPC 2.0 specification
*/
static createResponse(id, data, success = true) {
return { jsonrpc: JSONRPC_VERSION_2, id, result: (success ? data : undefined), error: (!success ? data : undefined) };
}
static toResultResponse(obj) {
return JsonRpc.createResponse(obj.id, obj.result, true);
}
static toErrorResponse(obj) {
return JsonRpc.createResponse(obj.id, obj.error, false);
}
/**
* Converts a specified object to a valid JSON-RPC `Response` object
* @param obj Object to transform
* @returns `Response` object in JSON-RPC 2.0 specification
*/
static toResponse(obj) {
if (JsonRpc.isResponseObject(obj)) {
return obj;
}
if (obj.error !== undefined) {
return JsonRpc.toErrorResponse(obj);
}
return JsonRpc.toResultResponse(obj);
}
/**
* Checks if the specified object `obj` is a valid `Request` object of the JSON-RPC 2.0 specification
* @param obj Object to test
* @returns _true_ if the object `obj` is a valid JSON-RPC 2.0 `Request` object, else _false_
*/
static isRequestObject(obj) {
return Objects.isObject(obj)
&& obj.jsonrpc === JSONRPC_VERSION_2
&& obj.method
&& obj.id != null;
//&& obj.id !== undefined;
}
/**
* Checks if the specified object `obj` is a valid `Notification` object of the JSON-RPC 2.0 specification
* @param obj Object to test
* @returns _true_ if the object `obj` is a valid JSON-RPC 2.0 `Notification` object, else _false_
*/
static isNotificationObject(obj) {
return Objects.isObject(obj)
&& obj.jsonrpc === JSONRPC_VERSION_2
&& obj.method
&& obj.id == null;
//&& obj.id === undefined;
}
/**
* Checks if the specified object `obj` is a valid `Response` object of the JSON-RPC 2.0 specification
* @param obj Object to test
* @returns _true_ if the object `obj` is a valid JSON-RPC 2.0 `Response` object, else _false_
*/
static isResponseObject(obj) {
return Objects.isObject(obj)
&& obj.jsonrpc === JSONRPC_VERSION_2
&& obj.id !== undefined
&& (obj.result !== undefined || obj.error !== undefined);
}
static isResultResponse(obj) {
return JsonRpc.isResponseObject(obj) && (obj.result !== undefined && obj.error === undefined);
}
static isErrorResponse(obj) {
return JsonRpc.isResponseObject(obj) && (obj.error !== undefined);
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSnNvblJwYy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2N1dGUtY29yZS9zcmMvbGliL3V0aWwvbmV0L0pzb25ScGMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDckMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFlBQVksQ0FBQztBQUVyQyxNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBVyxLQUFLLENBQUM7QUFDL0MsTUFBTSxDQUFDLE1BQU0sZUFBZSxHQUFHLGlCQUFpQixDQUFDO0FBa0JqRDs7O0dBR0c7QUFDSCxNQUFNLE9BQU8sT0FBTztJQUVsQjs7Ozs7O09BTUc7SUFDSCxNQUFNLENBQUMsYUFBYSxDQUEyQixNQUFjLEVBQUUsTUFBNEMsRUFBRSxFQUFjO1FBQ3pILElBQUksSUFBSSxHQUFRLFNBQVMsQ0FBQztRQUMxQixFQUFFLEdBQUcsRUFBRSxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUUsT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFFLENBQUM7UUFDakQsSUFBSSxNQUFNLEVBQUU7WUFDVixJQUFJLEdBQUcsRUFBRSxDQUFDO1lBQ1YsSUFBSSxPQUFPLE1BQU0sS0FBSyxRQUFRLEVBQUU7Z0JBQzlCLE1BQU0sR0FBRyxJQUFJLFVBQVUsQ0FBQyxFQUFDLFVBQVUsRUFBRSxNQUFNLEVBQUMsQ0FBQyxDQUFDO2FBQy9DO1lBQ0QsSUFBSSxNQUFNLFlBQVksVUFBVSxFQUFFO2dCQUNoQyxJQUFJLEdBQUcsQ0FBQztnQkFDUixNQUFNLENBQUMsSUFBSSxFQUFFLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQSxFQUFFO29CQUN6QixHQUFHLEdBQWdCLE1BQU8sQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7b0JBQ3ZDLElBQUksR0FB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QU0sS0FBSyxTQUFTLElBQUksR0FBRyxDQUFDLEtBQUssS0FBSyxTQUFTLENBQUMsQ0FBQztJQUNoRyxDQUFDO0lBRUQsTUFBTSxDQUFDLGVBQWUsQ0FBQyxHQUFRO1FBQzdCLE9BQU8sT0FBTyxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssS0FBSyxTQUFTLENBQUMsQ0FBQztJQUNwRSxDQUFDO0NBRUYiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBIdHRwUGFyYW1zIH0gZnJvbSBcIkBhbmd1bGFyL2NvbW1vbi9odHRwXCI7XG5pbXBvcnQgeyBDaXBoZXJzIH0gZnJvbSBcIi4uL0NpcGhlcnNcIjtcbmltcG9ydCB7IE9iamVjdHMgfSBmcm9tIFwiLi4vT2JqZWN0c1wiO1xuXG5leHBvcnQgY29uc3QgSlNPTlJQQ19WRVJTSU9OXzI6IHN0cmluZyA9IFwiMi4wXCI7XG5leHBvcnQgY29uc3QgSlNPTlJQQ19WRVJTSU9OID0gSlNPTlJQQ19WRVJTSU9OXzI7XG4vKiogVHlwZSBvZiBgaWRgIHByb3BlcnR5LiBUaGUgdmFsdWUgU0hPVUxEIG5vcm1hbGx5IG5vdCBiZSBOdWxsIGFuZCBOdW1iZXJzIFNIT1VMRCBOT1QgY29udGFpbiBmcmFjdGlvbmFsIHBhcnRzICovXG5leHBvcnQgdHlwZSBKc29uUnBjSWQgPSBudW1iZXIgfCBzdHJpbmcgfCBudWxsOyAgLy8gbnVsbCAtIGNhbiBiZSBpbnRlcnByZXRlZCBieSB0aGUgc2VydmVyIHNpZGUgYXMgYSBub3RpZmljYXRpb24gY2FsbFxuLyoqIFBhcmFtZXRlcnMgZm9yIHRoZSBycGMgY2FsbCBNVVNUIGJlIHByb3ZpZGVkIGFzIGEgU3RydWN0dXJlZCB2YWx1ZS4gRWl0aGVyIGJ5LXBvc2l0aW9uIHRocm91Z2ggYW4gQXJyYXkgb3IgYnktbmFtZSB0aHJvdWdoIGFuIE9iamVjdC4gKi9cbmV4cG9ydCB0eXBlIEpzb25ScGNQYXJhbXMgPSB7W2tleTpzdHJpbmddOiBhbnl9IHwgW107XG4vKiogVHlwZSBvZiBKU09OLVJQQyBgUmVxdWVzdGAgb2JqZWN0ICovXG5leHBvcnQgdHlwZSBKc29uUnBjUmVxdWVzdCA9IHsganNvbnJwYzogdHlwZW9mIEpTT05SUENfVkVSU0lPTl8yLCBtZXRob2Q6IHN0cmluZywgaWQ6IEpzb25ScGNJZCwgcGFyYW1zPzogSnNvblJwY1BhcmFtc307XG4vKiogVHlwZSBvZiBKU09OLVJQQyBgTm90aWZpY2F0aW9uYCBvYmplY3QgKi9cbmV4cG9ydCB0eXBlIEpzb25ScGNOb3RpZmljYXRpb24gPSBPbWl0PEpzb25ScGNSZXF1ZXN0LCBcImlkXCI+O1xuLyoqIFdoZW4gYSBycGMgY2FsbCBlbmNvdW50ZXJzIGFuIGVycm9yLCB0aGUgUmVzcG9uc2UgT2JqZWN0IE1VU1QgY29udGFpbiB0aGUgZXJyb3IgbWVtYmVyIHdpdGggYSB2YWx1ZSB0aGF0IGlzIGFuIE9iamVjdCAqL1xuZXhwb3J0IHR5cGUgSnNvblJwY0Vycm9yID0ge2NvZGU6IG51bWJlciwgbWVzc2FnZTogc3RyaW5nLCBkYXRhPzogYW55fTtcbi8qKiBUeXBlIG9mIEpTT04tUlBDIGBSZXNwb25zZWAgb2JqZWN0LiBgcmVzdWx0YCBtZW1iZXIgaXMgUkVRVUlSRUQgb24gc3VjY2Vzcy4gYGVycm9yYCBtZW1iZXIgaXMgUkVRVUlSRUQgb24gZXJyb3IuICovXG5leHBvcnQgdHlwZSBKc29uUnBjUmVzcG9uc2UgPSB7IGpzb25ycGM6IHR5cGVvZiBKU09OUlBDX1ZFUlNJT05fMiwgaWQ6IEpzb25ScGNJZCwgcmVzdWx0PzogYW55LCBlcnJvcj86IEpzb25ScGNFcnJvciB9O1xuLyoqIFR5cGUgb2YgSlNPTi1SUEMgYFJlc3VsdGAgUmVzcG9uc2Ugb2JqZWN0ICovXG5leHBvcnQgdHlwZSBKc29uUnBjUmVzdWx0UmVzcG9uc2UgPSBPbWl0PEpzb25ScGNSZXNwb25zZSwgXCJlcnJvclwiPjtcbi8qKiBUeXBlIG9mIEpTT04tUlBDIGBFcnJvcmAgUmVzcG9uc2Ugb2JqZWN0ICovXG5leHBvcnQgdHlwZSBKc29uUnBjRXJyb3JSZXNwb25zZSA9IE9taXQ8SnNvblJwY1Jlc3BvbnNlLCBcInJlc3VsdFwiPjtcblxuLyoqXG4gKiBUaGlzIGNsYXNzIGNvbnNpc3RzIGV4Y2x1c2l2ZWx5IG9mIHRoZSBzdGF0aWMgbWV0aG9kcyB0aGF0IG9wZXJhdGUgb24gb3IgcmV0dXJuIFJlcXVlc3QvUmVzcG9uc2Ugb2JqZWN0cyB0aGF0IGZvbGxvdyBbSlNPTi1SUEMgMi4wIFNwZWNpZmljYXRpb25dKGh0dHBzOi8vd3d3Lmpzb25ycGMub3JnL3NwZWNpZmljYXRpb24pXG4gKiBAc2luY2UgMC41LjBcbiAqL1xuZXhwb3J0IGNsYXNzIEpzb25ScGMge1xuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgYFJlcXVlc3RgIG9iamVjdCB0byBhIFNlcnZlciB0aGF0IGZvbGxvd3MgSlNPTi1SUEMgcHJvdG9jb2xcbiAgICogQHBhcmFtIG1ldGhvZCBBIFN0cmluZyBjb250YWluaW5nIHRoZSBuYW1lIG9mIHRoZSBtZXRob2QgdG8gYmUgaW52b2tlZC4gTWV0aG9kIG5hbWVzIHRoYXQgYmVnaW4gd2l0aCB0aGUgd29yZCBycGMgZm9sbG93ZWQgYnkgYSBwZXJpb2QgY2hhcmFjdGVyIChVKzAwMkUgb3IgQVNDSUkgNDYpIGFyZSByZXNlcnZlZCBmb3IgcnBjLWludGVybmFsIG1ldGhvZHMgYW5kIGV4dGVuc2lvbnMgYW5kIE1VU1QgTk9UIGJlIHVzZWQgZm9yIGFueXRoaW5nIGVsc2UuXG4gICAqIEBwYXJhbSBwYXJhbXMgQSBTdHJ1Y3R1cmVkIHZhbHVlIHRoYXQgaG9sZHMgdGhlIHBhcmFtZXRlciB2YWx1ZXMgdG8gYmUgdXNlZCBkdXJpbmcgdGhlIGludm9jYXRpb24gb2YgdGhlIG1ldGhvZC4gVGhpcyBtZW1iZXIgTUFZIGJlIG9taXR0ZWQuXG4gICAqIEBwYXJhbSBpZCBBbiBpZGVudGlmaWVyIGVzdGFibGlzaGVkIGJ5IHRoZSBDbGllbnQgdGhhdCBNVVNUIGNvbnRhaW4gYSBTdHJpbmcsIE51bWJlciwgb3IgTlVMTCB2YWx1ZSBpZiBpbmNsdWRlZC5cbiAgICogQHJldHVybnMgYFJlcXVlc3RgIG9iamVjdCBpbiBKU09OLVJQQyAyLjAgc3BlY2lmaWNhdGlvblxuICAgKi9cbiAgc3RhdGljIGNyZWF0ZVJlcXVlc3Q8VCBleHRlbmRzIEpzb25ScGNSZXF1ZXN0PihtZXRob2Q6IHN0cmluZywgcGFyYW1zPzogSnNvblJwY1BhcmFtcyB8IEh0dHBQYXJhbXMgfCBzdHJpbmcsIGlkPzogSnNvblJwY0lkKTogVCB7XG4gICAgbGV0IGFyZ3M6IGFueSA9IHVuZGVmaW5lZDtcbiAgICBpZCA9IGlkID8/IENpcGhlcnMuaGFzaENvZGUoIENpcGhlcnMudXVpZF92NCgpICk7XG4gICAgaWYgKHBhcmFtcykge1xuICAgICAgYXJncyA9IHt9O1xuICAgICAgaWYgKHR5cGVvZiBwYXJhbXMgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgcGFyYW1zID0gbmV3IEh0dHBQYXJhbXMoe2Zyb21TdHJpbmc6IHBhcmFtc30pO1xuICAgICAgfVxuICAgICAgaWYgKHBhcmFtcyBpbnN0YW5jZW9mIEh0dHBQYXJhbXMpIHtcbiAgICAgICAgbGV0IGFycjtcbiAgICAgICAgcGFyYW1zLmtleXMoKS5mb3JFYWNoKGtleT0+e1xuICAgICAgICAgIGFyciA9ICg8SHR0cFBhcmFtcz5wYXJhbXMpLmdldEFsbChrZXkpO1xuICAgICAgICAgIGlmIChhcnIpIHtcbiAgICAgICAgICAgIGFyZ3Nba2V5XSA9IGFyci5sZW5ndGggPiAxID8gWy4uLmFycl0gOiBhcnJbMF07XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFyZ3Nba2V5XSA9IG51bGw7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFyZ3MgPSB7Li4ucGFyYW1zfTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHsganNvbnJwYzogSlNPTlJQQ19WRVJTSU9OXzIsIG1ldGhvZCwgcGFyYW1zOiBhcmdzLCBpZCB9IGFzIFQ7XG4gIH1cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBgTm90aWZpY2F0aW9uYCBvYmplY3QgdG8gYSBTZXJ2ZXIgdGhhdCBmb2xsb3dzIEpTT04tUlBDIHByb3RvY29sXG4gICAqIEBwYXJhbSBtZXRob2QgQSBTdHJpbmcgY29udGFpbmluZyB0aGUgbmFtZSBvZiB0aGUgbWV0aG9kIHRvIGJlIGludm9rZWQuIE1ldGhvZCBuYW1lcyB0aGF0IGJlZ2luIHdpdGggdGhlIHdvcmQgcnBjIGZvbGxvd2VkIGJ5IGEgcGVyaW9kIGNoYXJhY3RlciAoVSswMDJFIG9yIEFTQ0lJIDQ2KSBhcmUgcmVzZXJ2ZWQgZm9yIHJwYy1pbnRlcm5hbCBtZXRob2RzIGFuZCBleHRlbnNpb25zIGFuZCBNVVNUIE5PVCBiZSB1c2VkIGZvciBhbnl0aGluZyBlbHNlLlxuICAgKiBAcGFyYW0gcGFyYW1zIEEgU3RydWN0dXJlZCB2YWx1ZSB0aGF0IGhvbGRzIHRoZSBwYXJhbWV0ZXIgdmFsdWVzIHRvIGJlIHVzZWQgZHVyaW5nIHRoZSBpbnZvY2F0aW9uIG9mIHRoZSBtZXRob2QuIFRoaXMgbWVtYmVyIE1BWSBiZSBvbWl0dGVkLlxuICAgKiBAcmV0dXJucyBgTm90aWZpY2F0aW9uYCBvYmplY3QgaW4gSlNPTi1SUEMgMi4wIHNwZWNpZmljYXRpb25cbiAgICovXG4gIHN0YXRpYyBjcmVhdGVOb3RpZmljYXRpb248VCBleHRlbmRzIEpzb25ScGNOb3RpZmljYXRpb24+KG1ldGhvZDogc3RyaW5nLCBwYXJhbXM/OiBKc29uUnBjUGFyYW1zIHwgSHR0cFBhcmFtcyB8IHN0cmluZyk6IFQge1xuICAgIGxldCBhcmdzOiBhbnkgPSB1bmRlZmluZWQ7XG4gICAgaWYgKHBhcmFtcykge1xuICAgICAgYXJncyA9IHt9O1xuICAgICAgaWYgKHR5cGVvZiBwYXJhbXMgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgcGFyYW1zID0gbmV3IEh0dHBQYXJhbXMoe2Zyb21TdHJpbmc6IHBhcmFtc30pO1xuICAgICAgfVxuICAgICAgaWYgKHBhcmFtcyBpbnN0YW5jZW9mIEh0dHBQYXJhbXMpIHtcbiAgICAgICAgbGV0IGFycjtcbiAgICAgICAgcGFyYW1zLmtleXMoKS5mb3JFYWNoKGtleT0+e1xuICAgICAgICAgIGFyciA9ICg8SHR0cFBhcmFtcz5wYXJhbXMpLmdldEFsbChrZXkpO1xuICAgICAgICAgIGlmIChhcnIpIHtcbiAgICAgICAgICAgIGFyZ3Nba2V5XSA9IGFyci5sZW5ndGggPiAxID8gWy4uLmFycl0gOiBhcnJbMF07XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFyZ3Nba2V5XSA9IG51bGw7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFyZ3MgPSB7Li4ucGFyYW1zfTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHsganNvbnJwYzogSlNPTlJQQ19WRVJTSU9OXzIsIG1ldGhvZCwgcGFyYW1zOiBhcmdzIH0gYXMgVDtcbiAgfVxuICAvKipcbiAgICogQ3JlYXRlcyBhIGBSZXNwb25zZWAgb2JqZWN0IHRvIGEgU2VydmVyIHRoYXQgZm9sbG93cyBKU09OLVJQQyBwcm90b2NvbFxuICAgKiBAcGFyYW0gaWQgQW4gaWRlbnRpZmllciBlc3RhYmxpc2hlZCBieSB0aGUgQ2xpZW50IHRoYXQgTVVTVCBjb250YWluIGEgU3RyaW5nLCBOdW1iZXIsIG9yIE5VTEwgdmFsdWUgaWYgaW5jbHVkZWQuXG4gICAqIEBwYXJhbSBkYXRhIEEgdmFsdWUgdGhhdCBpcyBhcHBsaWVkIHRvIGEgX3Jlc3VsdF8gb3IgYW4gX2Vycm9yXyBwcm9wZXJ0eSBkZXBlbmRpbmcgb24gdGhlIGBzdWNjZXNzYCB2YWx1ZVxuICAgKiBAcGFyYW0gc3VjY2VzcyBBIGJvb2xlYW4gdmFsdWUgdGhhdCBkZXRlcm1pbmVzIHRoZSB0eXBlIG9mIHRoZSBgUmVzcG9uc2VgIG9iamVjdFxuICAgKiBAcmV0dXJucyBgUmVzcG9uc2VgIG9iamVjdCBpbiBKU09OLVJQQyAyLjAgc3BlY2lmaWNhdGlvblxuICAgKi9cbiAgc3RhdGljIGNyZWF0ZVJlc3BvbnNlPFQgZXh0ZW5kcyBKc29uUnBjUmVzcG9uc2U+KGlkOiBKc29uUnBjSWQsIGRhdGE/OiBhbnksIHN1Y2Nlc3M6IGJvb2xlYW4gPSB0cnVlKTogVCB7XG4gICAgcmV0dXJuIHsganNvbnJwYzogSlNPTlJQQ19WRVJTSU9OXzIsIGlkLCByZXN1bHQ6IChzdWNjZXNzID8gZGF0YSA6IHVuZGVmaW5lZCksIGVycm9yOiAoIXN1Y2Nlc3MgPyBkYXRhIDogdW5kZWZpbmVkKSB9IGFzIFQ7XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyB0b1Jlc3VsdFJlc3BvbnNlKG9iajogeyBpZDogSnNvblJwY0lkLCByZXN1bHQ/OiBhbnkgfSk6IEpzb25ScGNSZXN1bHRSZXNwb25zZSB7XG4gICAgcmV0dXJuIEpzb25ScGMuY3JlYXRlUmVzcG9uc2Uob2JqLmlkLCBvYmoucmVzdWx0LCB0cnVlKTtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIHRvRXJyb3JSZXNwb25zZShvYmo6IHsgaWQ6IEpzb25ScGNJZCwgZXJyb3I/OiBhbnkgfSk6IEpzb25ScGNFcnJvclJlc3BvbnNlIHtcbiAgICByZXR1cm4gSnNvblJwYy5jcmVhdGVSZXNwb25zZShvYmouaWQsIG9iai5lcnJvciwgZmFsc2UpO1xuICB9XG4gIC8qKlxuICAgKiBDb252ZXJ0cyBhIHNwZWNpZmllZCBvYmplY3QgdG8gYSB2YWxpZCBKU09OLVJQQyBgUmVzcG9uc2VgIG9iamVjdFxuICAgKiBAcGFyYW0gb2JqICBPYmplY3QgdG8gdHJhbnNmb3JtXG4gICAqIEByZXR1cm5zIGBSZXNwb25zZWAgb2JqZWN0IGluIEpTT04tUlBDIDIuMCBzcGVjaWZpY2F0aW9uXG4gICAqL1xuICBzdGF0aWMgdG9SZXNwb25zZTxUIGV4dGVuZHMgSnNvblJwY1Jlc3BvbnNlPihvYmo6IHsgaWQ6IEpzb25ScGNJZCwgcmVzdWx0PzogYW55LCBlcnJvcj86IGFueSB9KTogVCB7XG4gICAgaWYgKEpzb25ScGMuaXNSZXNwb25zZU9iamVjdChvYmopKSB7XG4gICAgICByZXR1cm4gb2JqIGFzIFQ7XG4gICAgfSBpZiAob2JqLmVycm9yICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBKc29uUnBjLnRvRXJyb3JSZXNwb25zZShvYmopIGFzIFQ7XG4gICAgfVxuICAgIHJldHVybiBKc29uUnBjLnRvUmVzdWx0UmVzcG9uc2Uob2JqKSBhcyBUO1xuICB9XG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIHNwZWNpZmllZCBvYmplY3QgYG9iamAgaXMgYSB2YWxpZCBgUmVxdWVzdGAgb2JqZWN0IG9mIHRoZSBKU09OLVJQQyAyLjAgc3BlY2lmaWNhdGlvblxuICAgKiBAcGFyYW0gb2JqIE9iamVjdCB0byB0ZXN0XG4gICAqIEByZXR1cm5zIF90cnVlXyBpZiB0aGUgb2JqZWN0IGBvYmpgIGlzIGEgdmFsaWQgSlNPTi1SUEMgMi4wIGBSZXF1ZXN0YCBvYmplY3QsIGVsc2UgX2ZhbHNlX1xuICAgKi9cbiAgc3RhdGljIGlzUmVxdWVzdE9iamVjdChvYmo6IGFueSk6IG9iaiBpcyBKc29uUnBjUmVxdWVzdCB7XG4gICAgcmV0dXJuIE9iamVjdHMuaXNPYmplY3Qob2JqKVxuICAgICAgJiYgb2JqLmpzb25ycGMgPT09IEpTT05SUENfVkVSU0lPTl8yXG4gICAgICAmJiBvYmoubWV0aG9kXG4gICAgICAmJiBvYmouaWQgIT0gbnVsbDtcbiAgICAgIC8vJiYgb2JqLmlkICE9PSB1bmRlZmluZWQ7XG4gIH1cbiAgLyoqXG4gICAqIENoZWNrcyBpZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBgb2JqYCBpcyBhIHZhbGlkIGBOb3RpZmljYXRpb25gIG9iamVjdCBvZiB0aGUgSlNPTi1SUEMgMi4wIHNwZWNpZmljYXRpb25cbiAgICogQHBhcmFtIG9iaiBPYmplY3QgdG8gdGVzdFxuICAgKiBAcmV0dXJucyBfdHJ1ZV8gaWYgdGhlIG9iamVjdCBgb2JqYCBpcyBhIHZhbGlkIEpTT04tUlBDIDIuMCBgTm90aWZpY2F0aW9uYCBvYmplY3QsIGVsc2UgX2ZhbHNlX1xuICAgKi9cbiAgc3RhdGljIGlzTm90aWZpY2F0aW9uT2JqZWN0KG9iajogYW55KTogb2JqIGlzIEpzb25ScGNOb3RpZmljYXRpb24ge1xuICAgIHJldHVybiBPYmplY3RzLmlzT2JqZWN0KG9iailcbiAgICAgICYmIG9iai5qc29ucnBjID09PSBKU09OUlBDX1ZFUlNJT05fMlxuICAgICAgJiYgb2JqLm1ldGhvZFxuICAgICAgJiYgb2JqLmlkID09IG51bGw7XG4gICAgICAvLyYmIG9iai5pZCA9PT0gdW5kZWZpbmVkO1xuICB9XG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIHNwZWNpZmllZCBvYmplY3QgYG9iamAgaXMgYSB2YWxpZCBgUmVzcG9uc2VgIG9iamVjdCBvZiB0aGUgSlNPTi1SUEMgMi4wIHNwZWNpZmljYXRpb25cbiAgICogQHBhcmFtIG9iaiBPYmplY3QgdG8gdGVzdFxuICAgKiBAcmV0dXJucyBfdHJ1ZV8gaWYgdGhlIG9iamVjdCBgb2JqYCBpcyBhIHZhbGlkIEpTT04tUlBDIDIuMCBgUmVzcG9uc2VgIG9iamVjdCwgZWxzZSBfZmFsc2VfXG4gICAqL1xuICBzdGF0aWMgaXNSZXNwb25zZU9iamVjdChvYmo6IGFueSk6IG9iaiBpcyBKc29uUnBjUmVzcG9uc2Uge1xuICAgIHJldHVybiBPYmplY3RzLmlzT2JqZWN0KG9iailcbiAgICAgICYmIG9iai5qc29ucnBjID09PSBKU09OUlBDX1ZFUlNJT05fMlxuICAgICAgJiYgb2JqLmlkICE9PSB1bmRlZmluZWRcbiAgICAgICYmIChvYmoucmVzdWx0ICE9PSB1bmRlZmluZWQgfHwgb2JqLmVycm9yICE9PSB1bmRlZmluZWQpO1xuICB9XG5cbiAgc3RhdGljIGlzUmVzdWx0UmVzcG9uc2Uob2JqOiBhbnkpOiBib29sZWFuIHtcbiAgICByZXR1cm4gSnNvblJwYy5pc1Jlc3BvbnNlT2JqZWN0KG9iaikgJiYgKG9iai5yZXN1bHQgIT09IHVuZGVmaW5lZCAmJiBvYmouZXJyb3IgPT09IHVuZGVmaW5lZCk7XG4gIH1cblxuICBzdGF0aWMgaXNFcnJvclJlc3BvbnNlKG9iajogYW55KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIEpzb25ScGMuaXNSZXNwb25zZU9iamVjdChvYmopICYmIChvYmouZXJyb3IgIT09IHVuZGVmaW5lZCk7XG4gIH1cblxufVxuIl19