@ultipa-graph/ultipa-driver
Version:
NodeJS SDK for Ultipa GQL
257 lines • 31.4 kB
JavaScript
;
/**
* Type conversion utilities between gRPC proto types and JavaScript types.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildGqlRequest = buildGqlRequest;
exports.buildParameters = buildParameters;
exports.convertGqlResponse = convertGqlResponse;
exports.convertTypedValue = convertTypedValue;
exports.convertProtoProperties = convertProtoProperties;
exports.convertGraphInfo = convertGraphInfo;
exports.graphTypeToProto = graphTypeToProto;
exports.protoToGraphType = protoToGraphType;
exports.protoToHealthStatus = protoToHealthStatus;
exports.cacheTypeToProto = cacheTypeToProto;
exports.nodeDataToProto = nodeDataToProto;
exports.edgeDataToProto = edgeDataToProto;
const response_1 = require("../response");
const types_1 = require("../types");
/**
* Build a GQL request from config.
*/
function buildGqlRequest(query, session, config, queryConfig) {
return {
gql: query,
graph_name: queryConfig?.graphName || session?.defaultGraph || config.defaultGraph || '',
parameters: buildParameters(queryConfig?.parameters),
session_id: session?.id?.toString() || '0',
transaction_id: queryConfig?.transactionId?.toString() || '0',
timeout: Math.floor((queryConfig?.timeout || config.timeout || 30000) / 1000), // Convert ms to seconds for gRPC
read_only: queryConfig?.readOnly || false,
max_path_results: queryConfig?.maxPathResults || 0,
};
}
/**
* Build parameters array for gRPC.
*/
function buildParameters(params) {
if (!params)
return [];
return Object.entries(params).map(([name, value]) => ({
name,
value: (0, types_1.createTypedValue)(value),
}));
}
/**
* Convert gRPC response to Response object.
*/
function convertGqlResponse(grpcResponse) {
const columns = grpcResponse.columns || [];
const rows = (grpcResponse.rows || []).map((row) => {
const rawValues = row.values || [];
const values = rawValues.map((tv) => convertTypedValue(tv));
const types = rawValues.map((tv) => protoTypeToEnum(tv?.type));
return new response_1.Row(values, types);
});
return new response_1.Response(columns, rows, parseInt(grpcResponse.row_count || '0', 10), grpcResponse.has_more || false, grpcResponse.warnings || [], parseInt(grpcResponse.rows_affected || '0', 10), grpcResponse.current_graph || '',
// Old servers omit these proto3 fields → 0 means "not reported".
parseInt(grpcResponse.time_cost_ns || '0', 10), parseInt(grpcResponse.disk_cost_ns || '0', 10), parseInt(grpcResponse.compute_cost_ns || '0', 10));
}
/**
* Map proto type string or number to PropertyType enum.
* Handles both string enum names (e.g., 'PROPERTY_TYPE_STRING') and numeric values.
*/
function protoTypeToEnum(protoType) {
// Handle numeric enum values directly
if (typeof protoType === 'number') {
// If it's already a valid PropertyType number, return it directly
// PropertyType ranges from UNSET(0) to EDGE(33)
if (protoType >= types_1.PropertyType.UNSET && protoType <= types_1.PropertyType.EDGE) {
return protoType;
}
return types_1.PropertyType.NULL;
}
const typeMap = {
'PROPERTY_TYPE_NULL': types_1.PropertyType.NULL,
'PROPERTY_TYPE_UNSET': types_1.PropertyType.UNSET,
'PROPERTY_TYPE_BOOL': types_1.PropertyType.BOOL,
'PROPERTY_TYPE_INT32': types_1.PropertyType.INT32,
'PROPERTY_TYPE_UINT32': types_1.PropertyType.UINT32,
'PROPERTY_TYPE_INT64': types_1.PropertyType.INT64,
'PROPERTY_TYPE_UINT64': types_1.PropertyType.UINT64,
'PROPERTY_TYPE_FLOAT': types_1.PropertyType.FLOAT,
'PROPERTY_TYPE_DOUBLE': types_1.PropertyType.DOUBLE,
'PROPERTY_TYPE_STRING': types_1.PropertyType.STRING,
'PROPERTY_TYPE_TEXT': types_1.PropertyType.TEXT,
'PROPERTY_TYPE_BLOB': types_1.PropertyType.BLOB,
'PROPERTY_TYPE_TIMESTAMP': types_1.PropertyType.TIMESTAMP,
'PROPERTY_TYPE_DATETIME': types_1.PropertyType.DATETIME,
'PROPERTY_TYPE_DATE': types_1.PropertyType.DATE,
'PROPERTY_TYPE_LOCAL_DATETIME': types_1.PropertyType.LOCAL_DATETIME,
'PROPERTY_TYPE_ZONED_DATETIME': types_1.PropertyType.ZONED_DATETIME,
'PROPERTY_TYPE_LOCAL_TIME': types_1.PropertyType.LOCAL_TIME,
'PROPERTY_TYPE_ZONED_TIME': types_1.PropertyType.ZONED_TIME,
'PROPERTY_TYPE_YEAR_TO_MONTH': types_1.PropertyType.YEAR_TO_MONTH,
'PROPERTY_TYPE_DAY_TO_SECOND': types_1.PropertyType.DAY_TO_SECOND,
'PROPERTY_TYPE_DECIMAL': types_1.PropertyType.DECIMAL,
'PROPERTY_TYPE_POINT': types_1.PropertyType.POINT,
'PROPERTY_TYPE_POINT3D': types_1.PropertyType.POINT3D,
'PROPERTY_TYPE_VECTOR': types_1.PropertyType.VECTOR,
'PROPERTY_TYPE_LIST': types_1.PropertyType.LIST,
'PROPERTY_TYPE_SET': types_1.PropertyType.SET,
'PROPERTY_TYPE_MAP': types_1.PropertyType.MAP,
'PROPERTY_TYPE_NODE': types_1.PropertyType.NODE,
'PROPERTY_TYPE_EDGE': types_1.PropertyType.EDGE,
'PROPERTY_TYPE_PATH': types_1.PropertyType.PATH,
'PROPERTY_TYPE_RECORD': types_1.PropertyType.RECORD,
'PROPERTY_TYPE_TABLE': types_1.PropertyType.TABLE,
'PROPERTY_TYPE_ERROR': types_1.PropertyType.ERROR,
};
return typeMap[protoType] ?? types_1.PropertyType.NULL;
}
/**
* Convert gRPC TypedValue to JS value.
* Uses the same decoding logic as typedValueToJS for consistency.
*/
function convertTypedValue(tv) {
if (!tv || tv.is_null || tv.isNull)
return null;
const data = tv.data;
const protoType = tv.type;
// Handle null types (both string and numeric enum values)
if (protoType === 'PROPERTY_TYPE_NULL' || protoType === 'PROPERTY_TYPE_UNSET' ||
protoType === types_1.PropertyType.NULL || protoType === types_1.PropertyType.UNSET) {
return null;
}
// Handle empty data - but STRING type with empty data should return ""
if (!data || data.length === 0) {
const isStringType = protoType === 'PROPERTY_TYPE_STRING' || protoType === 'PROPERTY_TYPE_TEXT' ||
protoType === types_1.PropertyType.STRING || protoType === types_1.PropertyType.TEXT;
const isBlobType = protoType === 'PROPERTY_TYPE_BLOB' || protoType === types_1.PropertyType.BLOB;
if (isStringType) {
return '';
}
if (isBlobType) {
return Buffer.alloc(0);
}
return null;
}
const buf = Buffer.from(data);
const enumType = protoTypeToEnum(protoType);
// Use typedValueToJS for consistent decoding
return (0, types_1.typedValueToJS)({ type: enumType, data: buf, isNull: false });
}
/**
* Convert proto properties map to JS object.
*/
function convertProtoProperties(protoProps) {
const result = {};
for (const [key, tv] of Object.entries(protoProps)) {
result[key] = convertTypedValue(tv);
}
return result;
}
/**
* Convert GraphInfo from proto to JS object.
*/
function convertGraphInfo(g) {
return {
name: g.name || '',
graphType: protoToGraphType(g.graph_type),
nodeCount: parseInt(g.node_count || '0', 10),
edgeCount: parseInt(g.edge_count || '0', 10),
description: g.description || '',
};
}
/**
* Map GraphType enum to proto string.
*/
function graphTypeToProto(graphType) {
switch (graphType) {
case types_1.GraphType.OPEN:
return 'GRAPH_TYPE_OPEN';
case types_1.GraphType.CLOSED:
return 'GRAPH_TYPE_CLOSED';
case types_1.GraphType.ONTOLOGY:
return 'GRAPH_TYPE_ONTOLOGY';
default:
return 'GRAPH_TYPE_OPEN';
}
}
/**
* Map proto string to GraphType enum.
*/
function protoToGraphType(proto) {
switch (proto) {
case 'GRAPH_TYPE_CLOSED':
return types_1.GraphType.CLOSED;
case 'GRAPH_TYPE_ONTOLOGY':
return types_1.GraphType.ONTOLOGY;
default:
return types_1.GraphType.OPEN;
}
}
/**
* Map proto HealthStatus to enum.
*/
function protoToHealthStatus(proto) {
switch (proto) {
case 'HEALTH_STATUS_SERVING':
return types_1.HealthStatus.SERVING;
case 'HEALTH_STATUS_NOT_SERVING':
return types_1.HealthStatus.NOT_SERVING;
case 'HEALTH_STATUS_SERVICE_UNKNOWN':
return types_1.HealthStatus.SERVICE_UNKNOWN;
default:
return types_1.HealthStatus.UNKNOWN;
}
}
/**
* Map CacheType to proto string.
*/
function cacheTypeToProto(cacheType) {
switch (cacheType) {
case types_1.CacheType.AST:
return 'CACHE_TYPE_AST';
case types_1.CacheType.PLAN:
return 'CACHE_TYPE_PLAN';
default:
return 'CACHE_TYPE_ALL';
}
}
/**
* Convert NodeData to proto format.
*/
function nodeDataToProto(node) {
const properties = {};
if (node.properties) {
for (const [key, value] of Object.entries(node.properties)) {
properties[key] = (0, types_1.createTypedValue)(value);
}
}
return {
id: node.id || '',
labels: node.labels || [],
properties,
};
}
/**
* Convert EdgeData to proto format.
*/
function edgeDataToProto(edge) {
const properties = {};
if (edge.properties) {
for (const [key, value] of Object.entries(edge.properties)) {
properties[key] = (0, types_1.createTypedValue)(value);
}
}
return {
id: edge.id || '',
label: edge.label || '',
from_node_id: edge.fromNodeId || '',
to_node_id: edge.toNodeId || '',
properties,
};
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udmVydGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXJ2aWNlcy9jb252ZXJ0ZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7R0FFRzs7QUFtQkgsMENBZ0JDO0FBS0QsMENBTUM7QUFLRCxnREFxQkM7QUE0REQsOENBZ0NDO0FBS0Qsd0RBTUM7QUFLRCw0Q0FRQztBQUtELDRDQVdDO0FBS0QsNENBU0M7QUFLRCxrREFXQztBQUtELDRDQVNDO0FBS0QsMENBWUM7QUFLRCwwQ0FjQztBQTFSRCwwQ0FBNEM7QUFDNUMsb0NBUWtCO0FBS2xCOztHQUVHO0FBQ0gsU0FBZ0IsZUFBZSxDQUM3QixLQUFhLEVBQ2IsT0FBdUIsRUFDdkIsTUFBbUIsRUFDbkIsV0FBeUI7SUFFekIsT0FBTztRQUNMLEdBQUcsRUFBRSxLQUFLO1FBQ1YsVUFBVSxFQUFFLFdBQVcsRUFBRSxTQUFTLElBQUksT0FBTyxFQUFFLFlBQVksSUFBSSxNQUFNLENBQUMsWUFBWSxJQUFJLEVBQUU7UUFDeEYsVUFBVSxFQUFFLGVBQWUsQ0FBQyxXQUFXLEVBQUUsVUFBVSxDQUFDO1FBQ3BELFVBQVUsRUFBRSxPQUFPLEVBQUUsRUFBRSxFQUFFLFFBQVEsRUFBRSxJQUFJLEdBQUc7UUFDMUMsY0FBYyxFQUFFLFdBQVcsRUFBRSxhQUFhLEVBQUUsUUFBUSxFQUFFLElBQUksR0FBRztRQUM3RCxPQUFPLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLFdBQVcsRUFBRSxPQUFPLElBQUksTUFBTSxDQUFDLE9BQU8sSUFBSSxLQUFLLENBQUMsR0FBRyxJQUFJLENBQUMsRUFBRSxpQ0FBaUM7UUFDaEgsU0FBUyxFQUFFLFdBQVcsRUFBRSxRQUFRLElBQUksS0FBSztRQUN6QyxnQkFBZ0IsRUFBRSxXQUFXLEVBQUUsY0FBYyxJQUFJLENBQUM7S0FDbkQsQ0FBQztBQUNKLENBQUM7QUFFRDs7R0FFRztBQUNILFNBQWdCLGVBQWUsQ0FBQyxNQUE0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SUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ3BCLEtBQUssTUFBTSxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO1lBQzNELFVBQVUsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFBLHdCQUFnQixFQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzVDLENBQUM7SUFDSCxDQUFDO0lBQ0QsT0FBTztRQUNMLEVBQUUsRUFBRSxJQUFJLENBQUMsRUFBRSxJQUFJLEVBQUU7UUFDakIsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNLElBQUksRUFBRTtRQUN6QixVQUFVO0tBQ1gsQ0FBQztBQUNKLENBQUM7QUFFRDs7R0FFRztBQUNILFNBQWdCLGVBQWUsQ0FBQyxJQUFTO0lBQ3ZDLE1BQU0sVUFBVSxHQUF3QixFQUFFLENBQUM7SUFDM0MsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDcEIsS0FBSyxNQUFNLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7WUFDM0QsVUFBVSxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUEsd0JBQWdCLEVBQUMsS0FBSyxDQUFDLENBQUM7UUFDNUMsQ0FBQztJQUNILENBQUM7SUFDRCxPQUFPO1FBQ0wsRUFBRSxFQUFFLElBQUksQ0FBQyxFQUFFLElBQUksRUFBRTtRQUNqQixLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssSUFBSSxFQUFFO1FBQ3ZCLFlBQVksRUFBRSxJQUFJLENBQUMsVUFBVSxJQUFJLEVBQUU7UUFDbkMsVUFBVSxFQUFFLElBQUksQ0FBQyxRQUFRLElBQUksRUFBRTtRQUMvQixVQUFVO0tBQ1gsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFR5cGUgY29udmVyc2lvbiB1dGlsaXRpZXMgYmV0d2VlbiBnUlBDIHByb3RvIHR5cGVzIGFuZCBKYXZhU2NyaXB0IHR5cGVzLlxuICovXG5cbmltcG9ydCB7IFJlc3BvbnNlLCBSb3cgfSBmcm9tICcuLi9yZXNwb25zZSc7XG5pbXBvcnQge1xuICBHcmFwaFR5cGUsXG4gIEhlYWx0aFN0YXR1cyxcbiAgQ2FjaGVUeXBlLFxuICBHcmFwaEluZm8sXG4gIGNyZWF0ZVR5cGVkVmFsdWUsXG4gIFByb3BlcnR5VHlwZSxcbiAgdHlwZWRWYWx1ZVRvSlMsXG59IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7IEdxbGRiQ29uZmlnIH0gZnJvbSAnLi4vY29uZmlnJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi9zZXNzaW9uJztcbmltcG9ydCB7IFF1ZXJ5Q29uZmlnIH0gZnJvbSAnLi4vY2xpZW50JztcblxuLyoqXG4gKiBCdWlsZCBhIEdRTCByZXF1ZXN0IGZyb20gY29uZmlnLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRHcWxSZXF1ZXN0KFxuICBxdWVyeTogc3RyaW5nLFxuICBzZXNzaW9uOiBTZXNzaW9uIHwgbnVsbCxcbiAgY29uZmlnOiBHcWxkYkNvbmZpZyxcbiAgcXVlcnlDb25maWc/OiBRdWVyeUNvbmZpZ1xuKTogYW55IHtcbiAgcmV0dXJuIHtcbiAgICBncWw6IHF1ZXJ5LFxuICAgIGdyYXBoX25hbWU6IHF1ZXJ5Q29uZmlnPy5ncmFwaE5hbWUgfHwgc2Vzc2lvbj8uZGVmYXVsdEdyYXBoIHx8IGNvbmZpZy5kZWZhdWx0R3JhcGggfHwgJycsXG4gICAgcGFyYW1ldGVyczogYnVpbGRQYXJhbWV0ZXJzKHF1ZXJ5Q29uZmlnPy5wYXJhbWV0ZXJzKSxcbiAgICBzZXNzaW9uX2lkOiBzZXNzaW9uPy5pZD8udG9TdHJpbmcoKSB8fCAnMCcsXG4gICAgdHJhbnNhY3Rpb25faWQ6IHF1ZXJ5Q29uZmlnPy50cmFuc2FjdGlvbklkPy50b1N0cmluZygpIHx8ICcwJyxcbiAgICB0aW1lb3V0OiBNYXRoLmZsb29yKChxdWVyeUNvbmZpZz8udGltZW91dCB8fCBjb25maWcudGltZW91dCB8fCAzMDAwMCkgLyAxMDAwKSwgLy8gQ29udmVydCBtcyB0byBzZWNvbmRzIGZvciBnUlBDXG4gICAgcmVhZF9vbmx5OiBxdWVyeUNvbmZpZz8ucmVhZE9ubHkgfHwgZmFsc2UsXG4gICAgbWF4X3BhdGhfcmVzdWx0czogcXVlcnlDb25maWc/Lm1heFBhdGhSZXN1bHRzIHx8IDAsXG4gIH07XG59XG5cbi8qKlxuICogQnVpbGQgcGFyYW1ldGVycyBhcnJheSBmb3IgZ1JQQy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkUGFyYW1ldGVycyhwYXJhbXM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+KTogYW55W10ge1xuICBpZiAoIXBhcmFtcykgcmV0dXJuIFtdO1xuICByZXR1cm4gT2JqZWN0LmVudHJpZXMocGFyYW1zKS5tYXAoKFtuYW1lLCB2YWx1ZV0pID0+ICh7XG4gICAgbmFtZSxcbiAgICB2YWx1ZTogY3JlYXRlVHlwZWRWYWx1ZSh2YWx1ZSksXG4gIH0pKTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0IGdSUEMgcmVzcG9uc2UgdG8gUmVzcG9uc2Ugb2JqZWN0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gY29udmVydEdxbFJlc3BvbnNlKGdycGNSZXNwb25zZTogYW55KTogUmVzcG9uc2Uge1xuICBjb25zdCBjb2x1bW5zID0gZ3JwY1Jlc3BvbnNlLmNvbHVtbnMgfHwgW107XG4gIGNvbnN0IHJvd3M6IFJvd1tdID0gKGdycGNSZXNwb25zZS5yb3dzIHx8IFtdKS5tYXAoKHJvdzogYW55KSA9PiB7XG4gICAgY29uc3QgcmF3VmFsdWVzID0gcm93LnZhbHVlcyB8fCBbXTtcbiAgICBjb25zdCB2YWx1ZXMgPSByYXdWYWx1ZXMubWFwKCh0djogYW55KSA9PiBjb252ZXJ0VHlwZWRWYWx1ZSh0dikpO1xuICAgIGNvbnN0IHR5cGVzID0gcmF3VmFsdWVzLm1hcCgodHY6IGFueSkgPT4gcHJvdG9UeXBlVG9FbnVtKHR2Py50eXBlKSk7XG4gICAgcmV0dXJuIG5ldyBSb3codmFsdWVzLCB0eXBlcyk7XG4gIH0pO1xuICByZXR1cm4gbmV3IFJlc3BvbnNlKFxuICAgIGNvbHVtbnMsXG4gICAgcm93cyxcbiAgICBwYXJzZUludChncnBjUmVzcG9uc2Uucm93X2NvdW50IHx8ICcwJywgMTApLFxuICAgIGdycGNSZXNwb25zZS5oYXNfbW9yZSB8fCBmYWxzZSxcbiAgICBncnBjUmVzcG9uc2Uud2FybmluZ3MgfHwgW10sXG4gICAgcGFyc2VJbnQoZ3JwY1Jlc3BvbnNlLnJvd3NfYWZmZWN0ZWQgfHwgJzAnLCAxMCksXG4gICAgZ3JwY1Jlc3BvbnNlLmN1cnJlbnRfZ3JhcGggfHwgJycsXG4gICAgLy8gT2xkIHNlcnZlcnMgb21pdCB0aGVzZSBwcm90bzMgZmllbGRzIOKGkiAwIG1lYW5zIFwibm90IHJlcG9ydGVkXCIuXG4gICAgcGFyc2VJbnQoZ3JwY1Jlc3BvbnNlLnRpbWVfY29zdF9ucyB8fCAnMCcsIDEwKSxcbiAgICBwYXJzZUludChncnBjUmVzcG9uc2UuZGlza19jb3N0X25zIHx8ICcwJywgMTApLFxuICAgIHBhcnNlSW50KGdycGNSZXNwb25zZS5jb21wdXRlX2Nvc3RfbnMgfHwgJzAnLCAxMClcbiAgKTtcbn1cblxuLyoqXG4gKiBNYXAgcHJvdG8gdHlwZSBzdHJpbmcgb3IgbnVtYmVyIHRvIFByb3BlcnR5VHlwZSBlbnVtLlxuICogSGFuZGxlcyBib3RoIHN0cmluZyBlbnVtIG5hbWVzIChlLmcuLCAnUFJPUEVSVFlfVFlQRV9TVFJJTkcnKSBhbmQgbnVtZXJpYyB2YWx1ZXMuXG4gKi9cbmZ1bmN0aW9uIHByb3RvVHlwZVRvRW51bShwcm90b1R5cGU6IHN0cmluZyB8IG51bWJlcik6IFByb3BlcnR5VHlwZSB7XG4gIC8vIEhhbmRsZSBudW1lcmljIGVudW0gdmFsdWVzIGRpcmVjdGx5XG4gIGlmICh0eXBlb2YgcHJvdG9UeXBlID09PSAnbnVtYmVyJykge1xuICAgIC8vIElmIGl0J3MgYWxyZWFkeSBhIHZhbGlkIFByb3BlcnR5VHlwZSBudW1iZXIsIHJldHVybiBpdCBkaXJlY3RseVxuICAgIC8vIFByb3BlcnR5VHlwZSByYW5nZXMgZnJvbSBVTlNFVCgwKSB0byBFREdFKDMzKVxuICAgIGlmIChwcm90b1R5cGUgPj0gUHJvcGVydHlUeXBlLlVOU0VUICYmIHByb3RvVHlwZSA8PSBQcm9wZXJ0eVR5cGUuRURHRSkge1xuICAgICAgcmV0dXJuIHByb3RvVHlwZSBhcyBQcm9wZXJ0eVR5cGU7XG4gICAgfVxuICAgIHJldHVybiBQcm9wZXJ0eVR5cGUuTlVMTDtcbiAgfVxuXG4gIGNvbnN0IHR5cGVNYXA6IFJlY29yZDxzdHJpbmcsIFByb3BlcnR5VHlwZT4gPSB7XG4gICAgJ1BST1BFUlRZX1RZUEVfTlVMTCc6IFByb3BlcnR5VHlwZS5OVUxMLFxuICAgICdQUk9QRVJUWV9UWVBFX1VOU0VUJzogUHJvcGVydHlUeXBlLlVOU0VULFxuICAgICdQUk9QRVJUWV9UWVBFX0JPT0wnOiBQcm9wZXJ0eVR5cGUuQk9PTCxcbiAgICAnUFJPUEVSVFlfVFlQRV9JTlQzMic6IFByb3BlcnR5VHlwZS5JTlQzMixcbiAgICAnUFJPUEVSVFlfVFlQRV9VSU5UMzInOiBQcm9wZXJ0eVR5cGUuVUlOVDMyLFxuICAgICdQUk9QRVJUWV9UWVBFX0lOVDY0JzogUHJvcGVydHlUeXBlLklOVDY0LFxuICAgICdQUk9QRVJUWV9UWVBFX1VJTlQ2NCc6IFByb3BlcnR5VHlwZS5VSU5UNjQsXG4gICAgJ1BST1BFUlRZX1RZUEVfRkxPQVQnOiBQcm9wZXJ0eVR5cGUuRkxPQVQsXG4gICAgJ1BST1BFUlRZX1RZUEVfRE9VQkxFJzogUHJvcGVydHlUeXBlLkRPVUJMRSxcbiAgICAnUFJPUEVSVFlfVFlQRV9TVFJJTkcnOiBQcm9wZXJ0eVR5cGUuU1RSSU5HLFxuICAgICdQUk9QRVJUWV9UWVBFX1RFWFQnOiBQcm9wZXJ0eVR5cGUuVEVYVCxcbiAgICAnUFJPUEVSVFlfVFlQRV9CTE9CJzogUHJvcGVydHlUeXBlLkJMT0IsXG4gICAgJ1BST1BFUlRZX1RZUEVfVElNRVNUQU1QJzogUHJvcGVydHlUeXBlLlRJTUVTVEFNUCxcbiAgICAnUFJPUEVSVFlfVFlQRV9EQVRFVElNRSc6IFByb3BlcnR5VHlwZS5EQVRFVElNRSxcbiAgICAnUFJPUEVSVFlfVFlQRV9EQVRFJzogUHJvcGVydHlUeXBlLkRBVEUsXG4gICAgJ1BST1BFUlRZX1RZUEVfTE9DQUxfREFURVRJTUUnOiBQcm9wZXJ0eVR5cGUuTE9DQUxfREFURVRJTUUsXG4gICAgJ1BST1BFUlRZX1RZUEVfWk9ORURfREFURVRJTUUnOiBQcm9wZXJ0eVR5cGUuWk9ORURfREFURVRJTUUsXG4gICAgJ1BST1BFUlRZX1RZUEVfTE9DQUxfVElNRSc6IFByb3BlcnR5VHlwZS5MT0NBTF9USU1FLFxuICAgICdQUk9QRVJUWV9UWVBFX1pPTkVEX1RJTUUnOiBQcm9wZXJ0eVR5cGUuWk9ORURfVElNRSxcbiAgICAnUFJPUEVSVFlfVFlQRV9ZRUFSX1RPX01PTlRIJzogUHJvcGVydHlUeXBlLllFQVJfVE9fTU9OVEgsXG4gICAgJ1BST1BFUlRZX1RZUEVfREFZX1RPX1NFQ09ORCc6IFByb3BlcnR5VHlwZS5EQVlfVE9fU0VDT05ELFxuICAgICdQUk9QRVJUWV9UWVBFX0RFQ0lNQUwnOiBQcm9wZXJ0eVR5cGUuREVDSU1BTCxcbiAgICAnUFJPUEVSVFlfVFlQRV9QT0lOVCc6IFByb3BlcnR5VHlwZS5QT0lOVCxcbiAgICAnUFJPUEVSVFlfVFlQRV9QT0lOVDNEJzogUHJvcGVydHlUeXBlLlBPSU5UM0QsXG4gICAgJ1BST1BFUlRZX1RZUEVfVkVDVE9SJzogUHJvcGVydHlUeXBlLlZFQ1RPUixcbiAgICAnUFJPUEVSVFlfVFlQRV9MSVNUJzogUHJvcGVydHlUeXBlLkxJU1QsXG4gICAgJ1BST1BFUlRZX1RZUEVfU0VUJzogUHJvcGVydHlUeXBlLlNFVCxcbiAgICAnUFJPUEVSVFlfVFlQRV9NQVAnOiBQcm9wZXJ0eVR5cGUuTUFQLFxuICAgICdQUk9QRVJUWV9UWVBFX05PREUnOiBQcm9wZXJ0eVR5cGUuTk9ERSxcbiAgICAnUFJPUEVSVFlfVFlQRV9FREdFJzogUHJvcGVydHlUeXBlLkVER0UsXG4gICAgJ1BST1BFUlRZX1RZUEVfUEFUSCc6IFByb3BlcnR5VHlwZS5QQVRILFxuICAgICdQUk9QRVJUWV9UWVBFX1JFQ09SRCc6IFByb3BlcnR5VHlwZS5SRUNPUkQsXG4gICAgJ1BST1BFUlRZX1RZUEVfVEFCTEUnOiBQcm9wZXJ0eVR5cGUuVEFCTEUsXG4gICAgJ1BST1BFUlRZX1RZUEVfRVJST1InOiBQcm9wZXJ0eVR5cGUuRVJST1IsXG4gIH07XG4gIHJldHVybiB0eXBlTWFwW3Byb3RvVHlwZV0gPz8gUHJvcGVydHlUeXBlLk5VTEw7XG59XG5cbi8qKlxuICogQ29udmVydCBnUlBDIFR5cGVkVmFsdWUgdG8gSlMgdmFsdWUuXG4gKiBVc2VzIHRoZSBzYW1lIGRlY29kaW5nIGxvZ2ljIGFzIHR5cGVkVmFsdWVUb0pTIGZvciBjb25zaXN0ZW5jeS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbnZlcnRUeXBlZFZhbHVlKHR2OiBhbnkpOiBhbnkge1xuICBpZiAoIXR2IHx8IHR2LmlzX251bGwgfHwgdHYuaXNOdWxsKSByZXR1cm4gbnVsbDtcblxuICBjb25zdCBkYXRhID0gdHYuZGF0YTtcbiAgY29uc3QgcHJvdG9UeXBlID0gdHYudHlwZTtcblxuICAvLyBIYW5kbGUgbnVsbCB0eXBlcyAoYm90aCBzdHJpbmcgYW5kIG51bWVyaWMgZW51bSB2YWx1ZXMpXG4gIGlmIChwcm90b1R5cGUgPT09ICdQUk9QRVJUWV9UWVBFX05VTEwnIHx8IHByb3RvVHlwZSA9PT0gJ1BST1BFUlRZX1RZUEVfVU5TRVQnIHx8XG4gICAgICBwcm90b1R5cGUgPT09IFByb3BlcnR5VHlwZS5OVUxMIHx8IHByb3RvVHlwZSA9PT0gUHJvcGVydHlUeXBlLlVOU0VUKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvLyBIYW5kbGUgZW1wdHkgZGF0YSAtIGJ1dCBTVFJJTkcgdHlwZSB3aXRoIGVtcHR5IGRhdGEgc2hvdWxkIHJldHVybiBcIlwiXG4gIGlmICghZGF0YSB8fCBkYXRhLmxlbmd0aCA9PT0gMCkge1xuICAgIGNvbnN0IGlzU3RyaW5nVHlwZSA9IHByb3RvVHlwZSA9PT0gJ1BST1BFUlRZX1RZUEVfU1RSSU5HJyB8fCBwcm90b1R5cGUgPT09ICdQUk9QRVJUWV9UWVBFX1RFWFQnIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgcHJvdG9UeXBlID09PSBQcm9wZXJ0eVR5cGUuU1RSSU5HIHx8IHByb3RvVHlwZSA9PT0gUHJvcGVydHlUeXBlLlRFWFQ7XG4gICAgY29uc3QgaXNCbG9iVHlwZSA9IHByb3RvVHlwZSA9PT0gJ1BST1BFUlRZX1RZUEVfQkxPQicgfHwgcHJvdG9UeXBlID09PSBQcm9wZXJ0eVR5cGUuQkxPQjtcblxuICAgIGlmIChpc1N0cmluZ1R5cGUpIHtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG4gICAgaWYgKGlzQmxvYlR5cGUpIHtcbiAgICAgIHJldHVybiBCdWZmZXIuYWxsb2MoMCk7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3QgYnVmID0gQnVmZmVyLmZyb20oZGF0YSk7XG4gIGNvbnN0IGVudW1UeXBlID0gcHJvdG9UeXBlVG9FbnVtKHByb3RvVHlwZSk7XG5cbiAgLy8gVXNlIHR5cGVkVmFsdWVUb0pTIGZvciBjb25zaXN0ZW50IGRlY29kaW5nXG4gIHJldHVybiB0eXBlZFZhbHVlVG9KUyh7IHR5cGU6IGVudW1UeXBlLCBkYXRhOiBidWYsIGlzTnVsbDogZmFsc2UgfSk7XG59XG5cbi8qKlxuICogQ29udmVydCBwcm90byBwcm9wZXJ0aWVzIG1hcCB0byBKUyBvYmplY3QuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb252ZXJ0UHJvdG9Qcm9wZXJ0aWVzKHByb3RvUHJvcHM6IFJlY29yZDxzdHJpbmcsIGFueT4pOiBSZWNvcmQ8c3RyaW5nLCBhbnk+IHtcbiAgY29uc3QgcmVzdWx0OiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge307XG4gIGZvciAoY29uc3QgW2tleSwgdHZdIG9mIE9iamVjdC5lbnRyaWVzKHByb3RvUHJvcHMpKSB7XG4gICAgcmVzdWx0W2tleV0gPSBjb252ZXJ0VHlwZWRWYWx1ZSh0dik7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBDb252ZXJ0IEdyYXBoSW5mbyBmcm9tIHByb3RvIHRvIEpTIG9iamVjdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbnZlcnRHcmFwaEluZm8oZzogYW55KTogR3JhcGhJbmZvIHtcbiAgcmV0dXJuIHtcbiAgICBuYW1lOiBnLm5hbWUgfHwgJycsXG4gICAgZ3JhcGhUeXBlOiBwcm90b1RvR3JhcGhUeXBlKGcuZ3JhcGhfdHlwZSksXG4gICAgbm9kZUNvdW50OiBwYXJzZUludChnLm5vZGVfY291bnQgfHwgJzAnLCAxMCksXG4gICAgZWRnZUNvdW50OiBwYXJzZUludChnLmVkZ2VfY291bnQgfHwgJzAnLCAxMCksXG4gICAgZGVzY3JpcHRpb246IGcuZGVzY3JpcHRpb24gfHwgJycsXG4gIH07XG59XG5cbi8qKlxuICogTWFwIEdyYXBoVHlwZSBlbnVtIHRvIHByb3RvIHN0cmluZy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdyYXBoVHlwZVRvUHJvdG8oZ3JhcGhUeXBlOiBHcmFwaFR5cGUpOiBzdHJpbmcge1xuICBzd2l0Y2ggKGdyYXBoVHlwZSkge1xuICAgIGNhc2UgR3JhcGhUeXBlLk9QRU46XG4gICAgICByZXR1cm4gJ0dSQVBIX1RZUEVfT1BFTic7XG4gICAgY2FzZSBHcmFwaFR5cGUuQ0xPU0VEOlxuICAgICAgcmV0dXJuICdHUkFQSF9UWVBFX0NMT1NFRCc7XG4gICAgY2FzZSBHcmFwaFR5cGUuT05UT0xPR1k6XG4gICAgICByZXR1cm4gJ0dSQVBIX1RZUEVfT05UT0xPR1knO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gJ0dSQVBIX1RZUEVfT1BFTic7XG4gIH1cbn1cblxuLyoqXG4gKiBNYXAgcHJvdG8gc3RyaW5nIHRvIEdyYXBoVHlwZSBlbnVtLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcHJvdG9Ub0dyYXBoVHlwZShwcm90bzogc3RyaW5nKTogR3JhcGhUeXBlIHtcbiAgc3dpdGNoIChwcm90bykge1xuICAgIGNhc2UgJ0dSQVBIX1RZUEVfQ0xPU0VEJzpcbiAgICAgIHJldHVybiBHcmFwaFR5cGUuQ0xPU0VEO1xuICAgIGNhc2UgJ0dSQVBIX1RZUEVfT05UT0xPR1knOlxuICAgICAgcmV0dXJuIEdyYXBoVHlwZS5PTlRPTE9HWTtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIEdyYXBoVHlwZS5PUEVOO1xuICB9XG59XG5cbi8qKlxuICogTWFwIHByb3RvIEhlYWx0aFN0YXR1cyB0byBlbnVtLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcHJvdG9Ub0hlYWx0aFN0YXR1cyhwcm90bzogc3RyaW5nKTogSGVhbHRoU3RhdHVzIHtcbiAgc3dpdGNoIChwcm90bykge1xuICAgIGNhc2UgJ0hFQUxUSF9TVEFUVVNfU0VSVklORyc6XG4gICAgICByZXR1cm4gSGVhbHRoU3RhdHVzLlNFUlZJTkc7XG4gICAgY2FzZSAnSEVBTFRIX1NUQVRVU19OT1RfU0VSVklORyc6XG4gICAgICByZXR1cm4gSGVhbHRoU3RhdHVzLk5PVF9TRVJWSU5HO1xuICAgIGNhc2UgJ0hFQUxUSF9TVEFUVVNfU0VSVklDRV9VTktOT1dOJzpcbiAgICAgIHJldHVybiBIZWFsdGhTdGF0dXMuU0VSVklDRV9VTktOT1dOO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gSGVhbHRoU3RhdHVzLlVOS05PV047XG4gIH1cbn1cblxuLyoqXG4gKiBNYXAgQ2FjaGVUeXBlIHRvIHByb3RvIHN0cmluZy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNhY2hlVHlwZVRvUHJvdG8oY2FjaGVUeXBlOiBDYWNoZVR5cGUpOiBzdHJpbmcge1xuICBzd2l0Y2ggKGNhY2hlVHlwZSkge1xuICAgIGNhc2UgQ2FjaGVUeXBlLkFTVDpcbiAgICAgIHJldHVybiAnQ0FDSEVfVFlQRV9BU1QnO1xuICAgIGNhc2UgQ2FjaGVUeXBlLlBMQU46XG4gICAgICByZXR1cm4gJ0NBQ0hFX1RZUEVfUExBTic7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiAnQ0FDSEVfVFlQRV9BTEwnO1xuICB9XG59XG5cbi8qKlxuICogQ29udmVydCBOb2RlRGF0YSB0byBwcm90byBmb3JtYXQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub2RlRGF0YVRvUHJvdG8obm9kZTogYW55KTogYW55IHtcbiAgY29uc3QgcHJvcGVydGllczogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9O1xuICBpZiAobm9kZS5wcm9wZXJ0aWVzKSB7XG4gICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMobm9kZS5wcm9wZXJ0aWVzKSkge1xuICAgICAgcHJvcGVydGllc1trZXldID0gY3JlYXRlVHlwZWRWYWx1ZSh2YWx1ZSk7XG4gICAgfVxuICB9XG4gIHJldHVybiB7XG4gICAgaWQ6IG5vZGUuaWQgfHwgJycsXG4gICAgbGFiZWxzOiBub2RlLmxhYmVscyB8fCBbXSxcbiAgICBwcm9wZXJ0aWVzLFxuICB9O1xufVxuXG4vKipcbiAqIENvbnZlcnQgRWRnZURhdGEgdG8gcHJvdG8gZm9ybWF0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZWRnZURhdGFUb1Byb3RvKGVkZ2U6IGFueSk6IGFueSB7XG4gIGNvbnN0IHByb3BlcnRpZXM6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fTtcbiAgaWYgKGVkZ2UucHJvcGVydGllcykge1xuICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKGVkZ2UucHJvcGVydGllcykpIHtcbiAgICAgIHByb3BlcnRpZXNba2V5XSA9IGNyZWF0ZVR5cGVkVmFsdWUodmFsdWUpO1xuICAgIH1cbiAgfVxuICByZXR1cm4ge1xuICAgIGlkOiBlZGdlLmlkIHx8ICcnLFxuICAgIGxhYmVsOiBlZGdlLmxhYmVsIHx8ICcnLFxuICAgIGZyb21fbm9kZV9pZDogZWRnZS5mcm9tTm9kZUlkIHx8ICcnLFxuICAgIHRvX25vZGVfaWQ6IGVkZ2UudG9Ob2RlSWQgfHwgJycsXG4gICAgcHJvcGVydGllcyxcbiAgfTtcbn1cbiJdfQ==