@trademe/ensure
Version:
229 lines (218 loc) • 19.4 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
class EnsureError extends Error {
/**
* @param {?=} message
*/
constructor(message) {
super(dedent(message));
Object.setPrototypeOf(this, new.target.prototype);
}
}
/**
* @param {?} str
* @return {?}
*/
function dedent(str) {
const /** @type {?} */ lines = str.split(/\n/);
const /** @type {?} */ minWhipeSpace = lines.reduce((p, n) => {
const /** @type {?} */ whitespaceCount = n.search(/\S/);
if (whitespaceCount < 0) {
return p;
}
return whitespaceCount < p ? whitespaceCount : p;
}, Infinity);
const /** @type {?} */ newLines = lines.map(l => l.substr(minWhipeSpace));
return newLines.join('\n');
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
// Constants:
const /** @type {?} */ VALUE_KEY = '__value_';
/**
* @param {...?} guards
* @return {?}
*/
function Value(...guards) {
const /** @type {?} */ guardsArray = getGuardsArray(guards);
const /** @type {?} */ getters = guardsArray.filter(c => c.isGetter);
const /** @type {?} */ setters = guardsArray.filter(c => !c.isGetter);
return (target, propertyKey) => {
Object.defineProperty(target, propertyKey, {
get: function () {
const /** @type {?} */ value = (/** @type {?} */ (Reflect)).getMetadata(`${VALUE_KEY}${propertyKey}`, this);
getters.forEach(getter => {
getter.call(this, value, propertyKey);
});
return value;
},
set: function (value) {
let /** @type {?} */ castValue = value;
if (castValue === 'null') {
castValue = null;
}
if (castValue != null) {
setters.forEach(setter => {
castValue = setter.call(this, castValue, propertyKey);
});
}
(/** @type {?} */ (Reflect)).defineMetadata(`${VALUE_KEY}${propertyKey}`, castValue, this);
}
});
};
}
/**
* @param {?} guards
* @return {?}
*/
function getGuardsArray(guards) {
// Handle old @Value([guardOne, guardTwo]) syntax:
const [firstGuard] = guards;
return Array.isArray(firstGuard) ? /** @type {?} */ (firstGuard) : /** @type {?} */ (guards);
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @template T
* @param {?} guard
* @param {?=} config
* @return {?}
*/
function ensure(guard, config) {
Object.defineProperty(guard, 'isGetter', {
get: function () {
return !!config && config.getter;
}
});
return /** @type {?} */ (guard);
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
const /** @type {?} */ isBool = ensure((value, key) => {
if (value === true || value === false) {
return value;
}
if (value === 'true' || value === '') {
return true;
}
if (value === 'false') {
return false;
}
throw new EnsureError(`
"${value}" is not a valid value for '${key}'.
The following values will evaluate to true: true, "true", "".
The following values will evaluate to false: false, "false".
`);
});
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @template T
* @param {?} enumValues
* @return {?}
*/
function isEnum(enumValues) {
// Prepare the enum values so lookups work in both directions,
// with both number and string enums:
const /** @type {?} */ flipped = flipEnum(enumValues);
const /** @type {?} */ stripped = stripEnum(enumValues);
return ensure((value, key) => {
const /** @type {?} */ enumValue = stripped[value] != null ? stripped[value] : stripped[flipped[value]];
if (enumValue == null) {
throw new EnsureError(`
"${value}" is not a valid value for '${key}'. You can use one of the following:
${getValues(enumValues)}
`);
}
return enumValue;
});
}
/**
* @template T
* @param {?} enumT
* @return {?}
*/
function flipEnum(enumT) {
const /** @type {?} */ flipped = {};
Object.keys(enumT).forEach(key => {
flipped[key] = enumT[key];
flipped[enumT[key]] = key;
});
return flipped;
}
/**
* @template T
* @param {?} enumT
* @return {?}
*/
function stripEnum(enumT) {
const /** @type {?} */ stripped = {};
Object.keys(enumT).forEach(key => {
if (isNaN(parseInt(key, 10))) {
stripped[key] = enumT[key];
}
});
return stripped;
}
/**
* @template T
* @param {?} enumT
* @return {?}
*/
function getValues(enumT) {
return Object.keys(enumT)
.filter(key => isNaN(+key))
.map(key => `"${key}"`)
.join(',\n ');
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
const /** @type {?} */ isNotNull = ensure((value, key) => {
if (value == null) {
throw new EnsureError(`
'${key}' must not be "null" or "undefined".
`);
}
return value;
}, {
getter: true
});
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
const /** @type {?} */ isNumber = ensure((value, key) => {
value = +parseFloat(value);
if (isNaN(value)) {
throw new EnsureError(`
'${key}' must be a number.
`);
}
return value;
});
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
export { EnsureError, dedent, Value, ensure, isBool, isEnum, isNotNull, isNumber };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhZGVtZS1lbnN1cmUuanMubWFwIiwic291cmNlcyI6WyJuZzovL0B0cmFkZW1lL2Vuc3VyZS9lbnN1cmUtZXJyb3IudHMiLCJuZzovL0B0cmFkZW1lL2Vuc3VyZS92YWx1ZS92YWx1ZS50cyIsIm5nOi8vQHRyYWRlbWUvZW5zdXJlL2d1YXJkL2d1YXJkLnRzIiwibmc6Ly9AdHJhZGVtZS9lbnN1cmUvZ3VhcmRzL2Jvb2wudHMiLCJuZzovL0B0cmFkZW1lL2Vuc3VyZS9ndWFyZHMvZW51bS50cyIsIm5nOi8vQHRyYWRlbWUvZW5zdXJlL2d1YXJkcy9ub3QtbnVsbC50cyIsIm5nOi8vQHRyYWRlbWUvZW5zdXJlL2d1YXJkcy9udW1iZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGNsYXNzIEVuc3VyZUVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBtZXNzYWdlPzogc3RyaW5nXG4gICAgKSB7XG4gICAgICAgIHN1cGVyKGRlZGVudChtZXNzYWdlKSk7XG4gICAgICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZih0aGlzLCBuZXcudGFyZ2V0LnByb3RvdHlwZSk7XG4gICAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZGVkZW50IChzdHI6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgbGluZXMgPSBzdHIuc3BsaXQoL1xcbi8pO1xuICAgIGNvbnN0IG1pbldoaXBlU3BhY2UgPSBsaW5lcy5yZWR1Y2UoKHAsIG4pID0+IHtcbiAgICAgICAgY29uc3Qgd2hpdGVzcGFjZUNvdW50ID0gbi5zZWFyY2goL1xcUy8pO1xuICAgICAgICBpZiAod2hpdGVzcGFjZUNvdW50IDwgMCkge1xuICAgICAgICAgICAgcmV0dXJuIHA7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHdoaXRlc3BhY2VDb3VudCA8IHAgPyB3aGl0ZXNwYWNlQ291bnQgOiBwO1xuICAgIH0sIEluZmluaXR5KTtcblxuICAgIGNvbnN0IG5ld0xpbmVzID0gbGluZXMubWFwKGwgPT4gbC5zdWJzdHIobWluV2hpcGVTcGFjZSkpO1xuICAgIHJldHVybiBuZXdMaW5lcy5qb2luKCdcXG4nKTtcbn1cbiIsIi8vIERlcGVuZGVuY2llczpcbmltcG9ydCB7IGlzTm90TnVsbCB9IGZyb20gJy4uL2d1YXJkcy9ub3QtbnVsbCc7XG5pbXBvcnQgeyBHdWFyZCB9IGZyb20gJy4uL2d1YXJkL2d1YXJkJztcblxuLy8gQ29uc3RhbnRzOlxuY29uc3QgVkFMVUVfS0VZID0gJ19fdmFsdWVfJztcblxuZXhwb3J0IGZ1bmN0aW9uIFZhbHVlICguLi5ndWFyZHM6IEFycmF5PEd1YXJkPGFueT4gfCBBcnJheTxHdWFyZDxhbnk+Pj4pOiBQcm9wZXJ0eURlY29yYXRvciB7XG4gICAgY29uc3QgZ3VhcmRzQXJyYXkgPSBnZXRHdWFyZHNBcnJheShndWFyZHMpO1xuXG4gICAgY29uc3QgZ2V0dGVycyA9IGd1YXJkc0FycmF5LmZpbHRlcihjID0+IGMuaXNHZXR0ZXIpO1xuICAgIGNvbnN0IHNldHRlcnMgPSBndWFyZHNBcnJheS5maWx0ZXIoYyA9PiAhYy5pc0dldHRlcik7XG5cbiAgICByZXR1cm4gKHRhcmdldDogYW55LCBwcm9wZXJ0eUtleTogc3RyaW5nKSA9PiB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIHByb3BlcnR5S2V5LCB7XG4gICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IChSZWZsZWN0IGFzIGFueSkuZ2V0TWV0YWRhdGEoYCR7VkFMVUVfS0VZfSR7cHJvcGVydHlLZXl9YCwgdGhpcyk7XG4gICAgICAgICAgICAgICAgZ2V0dGVycy5mb3JFYWNoKGdldHRlciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGdldHRlci5jYWxsKHRoaXMsIHZhbHVlLCBwcm9wZXJ0eUtleSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgbGV0IGNhc3RWYWx1ZSA9IHZhbHVlO1xuXG4gICAgICAgICAgICAgICAgaWYgKGNhc3RWYWx1ZSA9PT0gJ251bGwnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhc3RWYWx1ZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKGNhc3RWYWx1ZSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHNldHRlcnMuZm9yRWFjaChzZXR0ZXIgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzdFZhbHVlID0gc2V0dGVyLmNhbGwodGhpcywgY2FzdFZhbHVlLCBwcm9wZXJ0eUtleSk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAoUmVmbGVjdCBhcyBhbnkpLmRlZmluZU1ldGFkYXRhKGAke1ZBTFVFX0tFWX0ke3Byb3BlcnR5S2V5fWAsIGNhc3RWYWx1ZSwgdGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG59XG5cbmZ1bmN0aW9uIGdldEd1YXJkc0FycmF5IChndWFyZHM6IEFycmF5PEd1YXJkPGFueT4gfCBBcnJheTxHdWFyZDxhbnk+Pj4pOiBBcnJheTxHdWFyZDxhbnk+PiB7XG4gICAgLy8gSGFuZGxlIG9sZCBAVmFsdWUoW2d1YXJkT25lLCBndWFyZFR3b10pIHN5bnRheDpcbiAgICBjb25zdCBbZmlyc3RHdWFyZF0gPSBndWFyZHM7XG4gICAgcmV0dXJuIEFycmF5LmlzQXJyYXkoZmlyc3RHdWFyZCkgPyBmaXJzdEd1YXJkIGFzIEFycmF5PEd1YXJkPGFueT4+IDogZ3VhcmRzIGFzIEFycmF5PEd1YXJkPGFueT4+O1xufVxuIiwiLy8gRGVwZW5kZW5jaWVzOlxuaW1wb3J0IHsgR3VhcmRDb25maWcgfSBmcm9tICcuL2d1YXJkLWNvbmZpZyc7XG5cbmV4cG9ydCB0eXBlIEd1YXJkRnVuY3Rpb248VD4gPSAodmFsdWU6IGFueSwga2V5OiBzdHJpbmcpID0+IFQ7XG5leHBvcnQgdHlwZSBHdWFyZDxUPiA9IHsgaXNHZXR0ZXI6IGJvb2xlYW4gfSAmIEd1YXJkRnVuY3Rpb248VD47XG5cbmV4cG9ydCBmdW5jdGlvbiBlbnN1cmUgPFQ+IChndWFyZDogR3VhcmRGdW5jdGlvbjxUPiwgY29uZmlnPzogR3VhcmRDb25maWcpOiBHdWFyZDxUPiB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGd1YXJkLCAnaXNHZXR0ZXInLCB7XG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuICEhY29uZmlnICYmIGNvbmZpZy5nZXR0ZXI7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gZ3VhcmQgYXMgR3VhcmQ8VD47XG59XG4iLCIvLyBEZXBlbmRlbmNpZXM6XG5pbXBvcnQgeyBFbnN1cmVFcnJvciB9IGZyb20gJy4uL2Vuc3VyZS1lcnJvcic7XG5pbXBvcnQgeyBlbnN1cmUgfSBmcm9tICcuLi9ndWFyZC9ndWFyZCc7XG5cbmV4cG9ydCBjb25zdCBpc0Jvb2wgPSBlbnN1cmUoKHZhbHVlOiBhbnksIGtleTogc3RyaW5nKTogYm9vbGVhbiA9PiB7XG4gICAgaWYgKHZhbHVlID09PSB0cnVlIHx8IHZhbHVlID09PSBmYWxzZSkge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuICAgIGlmICh2YWx1ZSA9PT0gJ3RydWUnIHx8IHZhbHVlID09PSAnJykge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKHZhbHVlID09PSAnZmFsc2UnKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgRW5zdXJlRXJyb3IoYFxuICAgICAgICBcIiR7dmFsdWV9XCIgaXMgbm90IGEgdmFsaWQgdmFsdWUgZm9yICcke2tleX0nLlxuICAgICAgICAgICAgVGhlIGZvbGxvd2luZyB2YWx1ZXMgd2lsbCBldmFsdWF0ZSB0byB0cnVlOiB0cnVlLCBcInRydWVcIiwgXCJcIi5cbiAgICAgICAgICAgIFRoZSBmb2xsb3dpbmcgdmFsdWVzIHdpbGwgZXZhbHVhdGUgdG8gZmFsc2U6IGZhbHNlLCBcImZhbHNlXCIuXG4gICAgYCk7XG59KTtcbiIsIi8vIERlcGVuZGVuY2llczpcbmltcG9ydCB7IEVuc3VyZUVycm9yIH0gZnJvbSAnLi4vZW5zdXJlLWVycm9yJztcbmltcG9ydCB7IGVuc3VyZSwgR3VhcmQgfSBmcm9tICcuLi9ndWFyZC9ndWFyZCc7XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0VudW0gPFQ+IChlbnVtVmFsdWVzOiBUKTogR3VhcmQ8VD4ge1xuICAgIC8vIFByZXBhcmUgdGhlIGVudW0gdmFsdWVzIHNvIGxvb2t1cHMgd29yayBpbiBib3RoIGRpcmVjdGlvbnMsXG4gICAgLy8gd2l0aCBib3RoIG51bWJlciBhbmQgc3RyaW5nIGVudW1zOlxuICAgIGNvbnN0IGZsaXBwZWQgPSBmbGlwRW51bShlbnVtVmFsdWVzKTtcbiAgICBjb25zdCBzdHJpcHBlZCA9IHN0cmlwRW51bShlbnVtVmFsdWVzKTtcblxuICAgIHJldHVybiBlbnN1cmUoKHZhbHVlOiBhbnksIGtleTogc3RyaW5nKTogbnVtYmVyIHwgYW55ID0+IHtcbiAgICAgICAgY29uc3QgZW51bVZhbHVlID0gc3RyaXBwZWRbdmFsdWVdICE9IG51bGwgPyBzdHJpcHBlZFt2YWx1ZV0gOiBzdHJpcHBlZFtmbGlwcGVkW3ZhbHVlXV07XG4gICAgICAgIGlmIChlbnVtVmFsdWUgPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVuc3VyZUVycm9yKGBcbiAgICAgICAgICAgICAgICBcIiR7dmFsdWV9XCIgaXMgbm90IGEgdmFsaWQgdmFsdWUgZm9yICcke2tleX0nLiBZb3UgY2FuIHVzZSBvbmUgb2YgdGhlIGZvbGxvd2luZzpcbiAgICAgICAgICAgICAgICAgICAgJHtnZXRWYWx1ZXM8VD4oZW51bVZhbHVlcyl9XG4gICAgICAgICAgICBgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZW51bVZhbHVlO1xuICAgIH0pO1xufVxuXG5mdW5jdGlvbiBmbGlwRW51bSA8VD4gKGVudW1UOiBUKTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSB7XG4gICAgY29uc3QgZmxpcHBlZCA9IHt9O1xuICAgIE9iamVjdC5rZXlzKGVudW1UKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICAgIGZsaXBwZWRba2V5XSA9IGVudW1UW2tleV07XG4gICAgICAgIGZsaXBwZWRbZW51bVRba2V5XV0gPSBrZXk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGZsaXBwZWQ7XG59XG5cbmZ1bmN0aW9uIHN0cmlwRW51bSA8VD4gKGVudW1UOiBUKTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSB7XG4gICAgY29uc3Qgc3RyaXBwZWQgPSB7fTtcbiAgICBPYmplY3Qua2V5cyhlbnVtVCkuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgICBpZiAoaXNOYU4ocGFyc2VJbnQoa2V5LCAxMCkpKSB7XG4gICAgICAgICAgICBzdHJpcHBlZFtrZXldID0gZW51bVRba2V5XTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBzdHJpcHBlZDtcbn1cblxuZnVuY3Rpb24gZ2V0VmFsdWVzPFQ+IChlbnVtVDogVCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKGVudW1UKVxuICAgIC5maWx0ZXIoa2V5ID0+IGlzTmFOKCtrZXkpKVxuICAgIC5tYXAoa2V5ID0+IGBcIiR7a2V5fVwiYClcbiAgICAuam9pbignLFxcbiAgICAgICAgICAgICAgICAgICAgJyk7XG59XG4iLCIvLyBEZXBlbmRlbmNpZXM6XG5pbXBvcnQgeyBFbnN1cmVFcnJvciB9IGZyb20gJy4uL2Vuc3VyZS1lcnJvcic7XG5pbXBvcnQgeyBlbnN1cmUgfSBmcm9tICcuLi9ndWFyZC9ndWFyZCc7XG5cbmV4cG9ydCBjb25zdCBpc05vdE51bGwgPSBlbnN1cmUoKHZhbHVlOiBhbnksIGtleTogYW55KTogYW55ID0+IHtcbiAgICBpZiAodmFsdWUgPT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBuZXcgRW5zdXJlRXJyb3IoYFxuICAgICAgICAgICAgJyR7a2V5fScgbXVzdCBub3QgYmUgXCJudWxsXCIgb3IgXCJ1bmRlZmluZWRcIi5cbiAgICAgICAgYCk7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZTtcbn0sIHtcbiAgICBnZXR0ZXI6IHRydWVcbn0pO1xuIiwiLy8gRGVwZW5kZW5jaWVzOlxuaW1wb3J0IHsgRW5zdXJlRXJyb3IgfSBmcm9tICcuLi9lbnN1cmUtZXJyb3InO1xuaW1wb3J0IHsgZW5zdXJlIH0gZnJvbSAnLi4vZ3VhcmQvZ3VhcmQnO1xuXG5leHBvcnQgY29uc3QgaXNOdW1iZXIgPSBlbnN1cmUoKHZhbHVlOiBhbnksIGtleTogc3RyaW5nKTogbnVtYmVyID0+IHtcbiAgICB2YWx1ZSA9ICtwYXJzZUZsb2F0KHZhbHVlKTtcbiAgICBpZiAoaXNOYU4odmFsdWUpKSB7XG4gICAgICAgIHRocm93IG5ldyBFbnN1cmVFcnJvcihgXG4gICAgICAgICAgICAnJHtrZXl9JyBtdXN0IGJlIGEgbnVtYmVyLlxuICAgICAgICBgKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xufSk7XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLGlCQUF5QixTQUFRLEtBQUs7Ozs7SUFDbEMsWUFDSSxPQUFnQjtRQUVoQixLQUFLLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7UUFDdkIsTUFBTSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztLQUNyRDtDQUNKOzs7OztBQUVELGdCQUF3QixHQUFXO0lBQy9CLHVCQUFNLEtBQUssR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzlCLHVCQUFNLGFBQWEsR0FBRyxLQUFLLENBQUMsTUFB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