UNPKG

@parischap/pretty-print

Version:
487 lines 24.1 kB
/** * This module implements the options for pretty-printing. * * With the make function, you can define your own instances if the provided ones don't suit your * needs. */ import { ASText } from '@parischap/ansi-styles'; import { MCache, MFunction, MMatch, MString, MStruct, MTree, MTypes } from '@parischap/effect-lib'; import { Array, Either, flow, Function, HashMap, HashSet, MutableHashMap, Number, Option, pipe, SortedMap, SortedSet, Struct, Tuple } from 'effect'; import { MInspectable, MPipeable } from '@parischap/effect-lib'; import { Equal, Hash, Predicate } from 'effect'; import * as PPByPasser from './ByPasser.js'; import * as PPByPassers from './ByPassers.js'; import * as PPMarkMap from './MarkMap.js'; import * as PPMarkShowerConstructor from './MarkShowerConstructor.js'; import * as PPNonPrimitiveFormatter from './NonPrimitiveFormatter.js'; import * as PPPrimitiveFormatter from './PrimitiveFormatter.js'; import * as PPPropertyFilters from './PropertyFilters.js'; import * as PPPropertyFormatter from './PropertyFormatter.js'; import * as PPStringifiedValue from './StringifiedValue.js'; import * as PPStyleMap from './StyleMap.js'; import * as PPValue from './Value.js'; import * as PPValueBasedStylerConstructor from './ValueBasedStylerConstructor.js'; import * as PPValues from './Values.js'; /** * Module tag * * @category Models */ export const moduleTag = '@parischap/pretty-print/Option/'; const _TypeId = /*#__PURE__*/Symbol.for(moduleTag); /** * Namespace for the possible sources of properties for non-primitive values * * @category Models */ export var PropertySource; (function (PropertySource) { /** * Type of a PropertySource * * @category Models */ let Type; (function (Type) { /** * Properties are obtained by calling Reflect.getOwnProperties on the non-primitive-value and * its prototypes (until maxPrototypeDepth is reached). This is usually a good choice for * records */ Type[Type["FromProperties"] = 0] = "FromProperties"; /** * Properties are obtained by iterating over the non-primitive-value that must implement the * Iterable protocol. Each value returned by the iterator is used to create a property with an * auto-incremented numerical key (converted to a string). This is usually a good choice for * arrays and sets. */ Type[Type["FromValueIterable"] = 1] = "FromValueIterable"; /** * Properties are obtained by iterating over the non-primitive-value that must implement the * Iterable protocol. The iterator must return a key/value pair. Otherwise, the returned value * is ignored. This is usually a good choice for maps,... */ Type[Type["FromKeyValueIterable"] = 2] = "FromKeyValueIterable"; })(Type = PropertySource.Type || (PropertySource.Type = {})); })(PropertySource || (PropertySource = {})); /** * Namespace for the options regarding the display of the number of properties of a non-primitive * value. The number of properties is shown in between parentheses just after the non-primitive * value id. * * @category Models */ export var PropertyNumberDisplayOption; (function (PropertyNumberDisplayOption) { /** * Type of a PropertyNumberDisplayOption * * @category Models */ let Type; (function (Type) { /** The number of properties is not shown */ Type[Type["None"] = 0] = "None"; /** Shows the number of properties retrieved from the property source */ Type[Type["All"] = 1] = "All"; /** * Shows the number of properties actually displayed, i.e. these remaining after filtering, * deduping and applying `maxPropertyNumber` */ Type[Type["Actual"] = 2] = "Actual"; /** * Shows both the number of properties retrieved from the property source and the number of * properties actually displayed (after filtering, deduping and applying `maxPropertyNumber`) */ Type[Type["AllAndActual"] = 3] = "AllAndActual"; /** * Shows both the number of properties retrieved from the property source and the number of * properties actually displayed (after filtering, deduping and applying `maxPropertyNumber`) * only if these two numbers are different. Otherwise, does not show anything */ Type[Type["AllAndActualIfDifferent"] = 4] = "AllAndActualIfDifferent"; })(Type = PropertyNumberDisplayOption.Type || (PropertyNumberDisplayOption.Type = {})); })(PropertyNumberDisplayOption || (PropertyNumberDisplayOption = {})); /** * Namespace for the options for pretty printing non-primitive values * * @category Models */ export var NonPrimitive; (function (NonPrimitive) { const namespaceTag = moduleTag + 'NonPrimitive/'; const _TypeId = /*#__PURE__*/Symbol.for(namespaceTag); /** * Type guard * * @category Guards */ NonPrimitive.has = u => Predicate.hasProperty(u, _TypeId); /** * Equivalence * * @category Equivalences */ NonPrimitive.equivalence = (self, that) => that.id === self.id; /** Prototype */ const _TypeIdHash = /*#__PURE__*/Hash.hash(_TypeId); const proto = { [_TypeId]: _TypeId, [Equal.symbol](that) { return NonPrimitive.has(that) && NonPrimitive.equivalence(this, that); }, [Hash.symbol]() { return pipe(this.id, Hash.hash, Hash.combine(_TypeIdHash), Hash.cached(this)); }, [MInspectable.IdSymbol]() { return this.id; }, ... /*#__PURE__*/MInspectable.BaseProto(namespaceTag), ...MPipeable.BaseProto }; /** * Constructor without an id * * @category Constructors */ NonPrimitive.make = params => MTypes.objectFromDataAndProto(proto, params); /** * Returns the `id` property of `self` * * @category Destructors */ NonPrimitive.id = /*#__PURE__*/Struct.get('id'); /** * Defaults NonPrimitive Option instance * * @category Instances */ NonPrimitive.record = /*#__PURE__*/NonPrimitive.make({ id: 'Object', showId: false, propertyNumberDisplayOption: PropertyNumberDisplayOption.Type.None, keyValueSeparatorMark: ': ', singleLineStartDelimiterMark: '{ ', singleLineEndDelimiterMark: ' }', multiLineStartDelimiterMark: '{', multiLineEndDelimiterMark: '}', prototypeStartDelimiterMark: '', prototypeEndDelimiterMark: '@', singleLineInBetweenPropertySeparatorMark: ', ', multiLineInBetweenPropertySeparatorMark: ',', idSeparatorMark: ' ', propertyNumberSeparatorMark: ',', propertyNumberStartDelimiterMark: '(', propertyNumberEndDelimiterMark: ')', propertySource: PropertySource.Type.FromProperties, maxPrototypeDepth: 0, propertyFilters: PPPropertyFilters.utilInspectLike, propertySortOrder: /*#__PURE__*/Option.none(), dedupeProperties: false, maxPropertyNumber: 100, propertyFormatter: PPPropertyFormatter.keyAndValue, nonPrimitiveFormatter: /*#__PURE__*/PPNonPrimitiveFormatter.splitOnTotalLengthMaker(80) }); /** * NonPrimitive Option instance for arrays * * @category Instances */ NonPrimitive.array = /*#__PURE__*/NonPrimitive.make({ ...NonPrimitive.record, id: 'Array', propertyNumberDisplayOption: PropertyNumberDisplayOption.Type.AllAndActualIfDifferent, singleLineStartDelimiterMark: '[ ', singleLineEndDelimiterMark: ' ]', multiLineStartDelimiterMark: '[', multiLineEndDelimiterMark: ']', propertySource: PropertySource.Type.FromValueIterable, propertyFilters: PPPropertyFilters.empty, propertyFormatter: PPPropertyFormatter.valueOnly }); /** * Constructor that generates a NonPrimitive Option instance suitable for maps * * @category Constructors */ NonPrimitive.maps = id => NonPrimitive.make({ ...NonPrimitive.record, id, showId: true, propertyNumberDisplayOption: PropertyNumberDisplayOption.Type.AllAndActualIfDifferent, keyValueSeparatorMark: ' => ', propertySource: PropertySource.Type.FromKeyValueIterable, propertyFilters: PPPropertyFilters.empty, propertyFormatter: PPPropertyFormatter.keyAndValue }); /** * Constructor that generates a NonPrimitive Option instance suitable for sets and arrays other * than Array * * @category Constructors */ NonPrimitive.setsAndArrays = id => NonPrimitive.make({ ...NonPrimitive.record, id, showId: true, propertyNumberDisplayOption: PropertyNumberDisplayOption.Type.AllAndActualIfDifferent, propertySource: PropertySource.Type.FromValueIterable, propertyFilters: PPPropertyFilters.empty, propertyFormatter: PPPropertyFormatter.valueOnly }); /** * Namespace of an initialized NonPrimitive Option * * @category Models */ let Initialized; (function (Initialized) { /** * Builds an Initialized from a NonPrimitive * * @category Constructors */ Initialized.fromNonPrimitive = params => { const valueBasedStylerConstructor = params.valueBasedStylerConstructor; const nonPrimitiveValueIdTextFormatter = valueBasedStylerConstructor('NonPrimitiveValueId'); const nonPrimitiveValueIdSeparatorTextFormatter = valueBasedStylerConstructor('NonPrimitiveValueIdSeparator'); const propertyNumberDelimitersTextFormatter = valueBasedStylerConstructor('PropertyNumberDelimiters'); const propertyNumberSeparatorTextFormatter = valueBasedStylerConstructor('PropertyNumberSeparator'); const PropertyNumbersTextFormatter = valueBasedStylerConstructor('PropertyNumbers'); return flow(MStruct.enrichWith({ syntheticPropertyFilter: nonPrimitiveOption => PPPropertyFilters.toSyntheticPropertyFilter(nonPrimitiveOption.propertyFilters), initializedPropertyFormatter: nonPrimitiveOption => nonPrimitiveOption.propertyFormatter(params), initializedNonPrimitiveFormatter: nonPrimitiveOption => nonPrimitiveOption.nonPrimitiveFormatter(params), toHeaderMarkShower: nonPrimitiveOption => { const emptyText = Function.constant(ASText.empty); const propertyNumberDisplayOption = nonPrimitiveOption.propertyNumberDisplayOption; const isNone = propertyNumberDisplayOption === PropertyNumberDisplayOption.Type.None; const isAll = propertyNumberDisplayOption === PropertyNumberDisplayOption.Type.All; const isActual = propertyNumberDisplayOption === PropertyNumberDisplayOption.Type.Actual; const isAllAndActual = propertyNumberDisplayOption === PropertyNumberDisplayOption.Type.AllAndActual; const isAllAndActualIfDifferent = propertyNumberDisplayOption === PropertyNumberDisplayOption.Type.AllAndActualIfDifferent; const showId = nonPrimitiveOption.showId; const [propertyNumberStartDelimiter, propertyNumberEndDelimiter] = isNone ? Tuple.make(emptyText, emptyText) : Tuple.make(propertyNumberDelimitersTextFormatter.withContextLast(nonPrimitiveOption.propertyNumberStartDelimiterMark), propertyNumberDelimitersTextFormatter.withContextLast(nonPrimitiveOption.propertyNumberEndDelimiterMark)); const propertyNumberSeparator = isAllAndActual || isAllAndActualIfDifferent ? propertyNumberSeparatorTextFormatter.withContextLast(nonPrimitiveOption.propertyNumberSeparatorMark) : emptyText; const idSeparator = showId || !isNone ? nonPrimitiveValueIdSeparatorTextFormatter.withContextLast(nonPrimitiveOption.idSeparatorMark) : emptyText; const id = showId ? nonPrimitiveValueIdTextFormatter.withContextLast(nonPrimitiveOption.id) : emptyText; return ({ allPropertyNumber, actualPropertyNumber }) => value => { const showAllAndActual = isAllAndActual || isAllAndActualIfDifferent && allPropertyNumber !== actualPropertyNumber; const styledTotalPropertyNumber = isAll || showAllAndActual ? pipe(allPropertyNumber, MString.fromNonNullablePrimitive, PropertyNumbersTextFormatter.withContextLast, Function.apply(value)) : ASText.empty; const styledActualPropertyNumber = isActual || showAllAndActual ? pipe(actualPropertyNumber, MString.fromNonNullablePrimitive, PropertyNumbersTextFormatter.withContextLast, Function.apply(value)) : ASText.empty; const [inContextPropertyNumberStartDelimiter, inContextPropertyNumberSeparator, inContextPropertyNumberEndDelimiter, inContextIdSeparator] = isAllAndActualIfDifferent && allPropertyNumber === actualPropertyNumber ? [ASText.empty, ASText.empty, ASText.empty, showId ? idSeparator(value) : ASText.empty] : [propertyNumberStartDelimiter(value), propertyNumberSeparator(value), propertyNumberEndDelimiter(value), idSeparator(value)]; return ASText.concat(id(value), inContextPropertyNumberStartDelimiter, styledTotalPropertyNumber, inContextPropertyNumberSeparator, styledActualPropertyNumber, inContextPropertyNumberEndDelimiter, inContextIdSeparator); }; } })); }; })(Initialized = NonPrimitive.Initialized || (NonPrimitive.Initialized = {})); })(NonPrimitive || (NonPrimitive = {})); /** * Type guard * * @category Guards */ export const has = u => Predicate.hasProperty(u, _TypeId); /** * Equivalence * * @category Equivalences */ export const equivalence = (self, that) => that.id === self.id; /** Prototype */ const _TypeIdHash = /*#__PURE__*/Hash.hash(_TypeId); const proto = { [_TypeId]: _TypeId, [Equal.symbol](that) { return has(that) && equivalence(this, that); }, [Hash.symbol]() { return pipe(this.id, Hash.hash, Hash.combine(_TypeIdHash), Hash.cached(this)); }, [MInspectable.IdSymbol]() { return this.id; }, ... /*#__PURE__*/MInspectable.BaseProto(moduleTag), ...MPipeable.BaseProto }; /** * Constructor without a id * * @category Constructors */ export const make = params => MTypes.objectFromDataAndProto(proto, params); /** * Returns the `id` property of `self` * * @category Destructors */ export const id = /*#__PURE__*/Struct.get('id'); /** * `Option` instance that pretty-prints a value in a way very similar to util.inspect. * * @category Instances */ export const utilInspectLike = /*#__PURE__*/make({ id: 'UtilInspectLike', styleMap: PPStyleMap.none, markMap: PPMarkMap.utilInspectLike, byPassers: /*#__PURE__*/Array.make(PPByPasser.functionToName, PPByPasser.objectToString), primitiveFormatter: /*#__PURE__*/PPPrimitiveFormatter.utilInspectLikeMaker(), maxDepth: 2, generalNonPrimitiveOption: NonPrimitive.record, specificNonPrimitiveOption: value => { const content = value.content; if (MTypes.isArray(content)) return Option.some(NonPrimitive.array); if (content instanceof Map) return Option.some(NonPrimitive.maps('Map')); if (content instanceof Set) return Option.some(NonPrimitive.setsAndArrays('Set')); if (content instanceof WeakMap) return Option.some(NonPrimitive.maps('WeakMap')); if (content instanceof WeakSet) return Option.some(NonPrimitive.setsAndArrays('WeakSet')); if (HashMap.isHashMap(content)) return Option.some(NonPrimitive.maps('EffectHashMap')); if (SortedMap.isSortedMap(content)) return Option.some(NonPrimitive.maps('EffectSortedMap')); if (HashSet.isHashSet(content)) return Option.some(NonPrimitive.setsAndArrays('EffectHashSet')); if (SortedSet.isSortedSet(content)) return Option.some(NonPrimitive.setsAndArrays('EffectSortedSet')); return pipe(content, MTypes.typedArrayName, Option.map(NonPrimitive.setsAndArrays)); } }); /** * `Option` instance that pretty-prints a value in a way very similar to util.inspect with colors * adapted to a terminal in dark mode. * * @category Instances */ export const darkModeUtilInspectLike = /*#__PURE__*/make({ ...utilInspectLike, id: 'DarkModeUtilInspectLike', styleMap: PPStyleMap.darkMode }); /** * `Option` instance that treeifies a value * * @category Instances */ export const treeify = /*#__PURE__*/make({ id: 'Treeify', styleMap: PPStyleMap.none, markMap: PPMarkMap.utilInspectLike, byPassers: /*#__PURE__*/Array.empty(), primitiveFormatter: /*#__PURE__*/PPPrimitiveFormatter.utilInspectLikeMaker(), maxDepth: +Infinity, generalNonPrimitiveOption: /*#__PURE__*/NonPrimitive.make({ ...NonPrimitive.record, propertyFilters: /*#__PURE__*/Array.empty(), propertySortOrder: /*#__PURE__*/Option.none(), dedupeProperties: false, maxPropertyNumber: +Infinity, propertyFormatter: PPPropertyFormatter.treeify, nonPrimitiveFormatter: PPNonPrimitiveFormatter.treeify }), specificNonPrimitiveOption: /*#__PURE__*/flow(utilInspectLike.specificNonPrimitiveOption, /*#__PURE__*/Option.map(/*#__PURE__*/flow(/*#__PURE__*/MStruct.set({ nonPrimitiveFormatter: PPNonPrimitiveFormatter.treeify, propertyFormatter: PPPropertyFormatter.treeify }), NonPrimitive.make))) }); /** * `Option` instance that treeifies a value with colors adapted to dark mode * * @category Instances */ export const darkModeTreeify = /*#__PURE__*/make({ ...treeify, id: 'DarkModeTreeify', styleMap: PPStyleMap.darkMode }); /** * `Option` instance that treeifies a value and hides the leaves * * @category Instances */ export const treeifyHideLeaves = /*#__PURE__*/make({ ...treeify, id: 'TreeifyHideLeaves', generalNonPrimitiveOption: /*#__PURE__*/NonPrimitive.make({ ...treeify.generalNonPrimitiveOption, propertyFormatter: PPPropertyFormatter.treeifyHideLeafValues }), specificNonPrimitiveOption: /*#__PURE__*/flow(treeify.specificNonPrimitiveOption, /*#__PURE__*/Option.map(/*#__PURE__*/flow(/*#__PURE__*/MStruct.set({ propertyFormatter: PPPropertyFormatter.treeifyHideLeafValues }), NonPrimitive.make))) }); /** * `Option` instance that treeifies a value and hides the leaves with colors adapted to dark mode * * @category Instances */ export const darkModeTreeifyHideLeaves = /*#__PURE__*/make({ ...treeifyHideLeaves, id: 'DarkModeTreeifyHideLeaves', styleMap: PPStyleMap.darkMode }); /** * Builds a Stringifier from an Option * * @category Destructors */ export const toStringifier = self => { const valueBasedStylerConstructor = PPValueBasedStylerConstructor.fromOption(self); const markShowerConstructor = PPMarkShowerConstructor.fromOption(self); const constructors = { markShowerConstructor, valueBasedStylerConstructor }; const primitiveValueTextFormatter = valueBasedStylerConstructor('PrimitiveValue'); const messageTextFormatter = valueBasedStylerConstructor('Message'); const circularObjectMarkShower = markShowerConstructor('CircularObject'); const circularReferenceStartDelimiterMarkShower = markShowerConstructor('CircularReferenceStartDelimiter'); const circularReferenceEndDelimiterMarkShower = markShowerConstructor('CircularReferenceEndDelimiter'); const messageStartDelimiterMarkShower = markShowerConstructor('MessageStartDelimiter'); const messageEndDelimiterMarkShower = markShowerConstructor('MessageEndDelimiter'); const initializedByPasser = PPByPassers.toSyntheticByPasser(self.byPassers).call(self, constructors); const toInitializedNonPrimitiveOption = NonPrimitive.Initialized.fromNonPrimitive(constructors); const initializedNonPrimitiveOptionCache = MCache.make({ lookUp: ({ key }) => Tuple.make(toInitializedNonPrimitiveOption(key), true) }); const initializedNonPrimitiveOptionGetter = MCache.toGetter(initializedNonPrimitiveOptionCache); const initializedGeneralNonPrimitiveOption = initializedNonPrimitiveOptionGetter(self.generalNonPrimitiveOption); const functionToNameByPasser = PPByPasser.functionToName.call(self, constructors); let lastCyclicalIndex = 1; const cyclicalMap = MutableHashMap.empty(); const stringifier = flow(PPValue.fromTopValue, MTree.unfoldAndFold({ unfold: (seed, cyclicalRef) => pipe(Either.gen(function* () { const notByPassed = yield* pipe(seed, initializedByPasser, Either.fromOption(Function.constant(seed)), Either.flip); const unBypassedNonPrimitive = yield* pipe(notByPassed, Either.liftPredicate(PPValue.isNonPrimitive, Function.unsafeCoerce), Either.mapLeft(flow(self.primitiveFormatter, primitiveValueTextFormatter(notByPassed), PPStringifiedValue.fromText))); const initializedNonPrimitiveOption = pipe(unBypassedNonPrimitive, self.specificNonPrimitiveOption, Option.map(initializedNonPrimitiveOptionGetter), Option.getOrElse(Function.constant(initializedGeneralNonPrimitiveOption))); const unBypassedNonPrimitiveUnderMaxDepth = yield* pipe(unBypassedNonPrimitive, Either.liftPredicate(flow(PPValue.depth, Number.lessThan(self.maxDepth)), flow(functionToNameByPasser, Option.getOrElse(pipe(initializedNonPrimitiveOption.id, messageTextFormatter(unBypassedNonPrimitive), ASText.surround(messageStartDelimiterMarkShower(unBypassedNonPrimitive), messageEndDelimiterMarkShower(unBypassedNonPrimitive)), PPStringifiedValue.fromText, Function.constant))))); const unCyclicalUnBypassedNonPrimitiveUnderMaxDepth = yield* pipe(cyclicalRef, Option.map(([cyclicalValue]) => pipe(cyclicalMap, MutableHashMap.get(cyclicalValue), Option.getOrElse(() => { /* eslint-disable-next-line functional/no-expression-statements */ MutableHashMap.set(cyclicalMap, cyclicalValue, lastCyclicalIndex); return lastCyclicalIndex++; }), MString.fromNonNullablePrimitive, messageTextFormatter(unBypassedNonPrimitiveUnderMaxDepth), ASText.prepend(circularObjectMarkShower(unBypassedNonPrimitiveUnderMaxDepth)), ASText.surround(messageStartDelimiterMarkShower(unBypassedNonPrimitiveUnderMaxDepth), messageEndDelimiterMarkShower(unBypassedNonPrimitiveUnderMaxDepth)), PPStringifiedValue.fromText)), Either.fromOption(Function.constant(unBypassedNonPrimitiveUnderMaxDepth)), Either.flip); const properties = pipe(initializedNonPrimitiveOption.propertySource, MMatch.make, MMatch.whenIs(PropertySource.Type.FromProperties, pipe(initializedNonPrimitiveOption.maxPrototypeDepth, PPValues.fromProperties, Function.constant)), MMatch.whenIs(PropertySource.Type.FromValueIterable, Function.constant(PPValues.fromValueIterable)), MMatch.whenIs(PropertySource.Type.FromKeyValueIterable, Function.constant(PPValues.fromKeyValueIterable(stringifier))), MMatch.exhaustive, Function.apply(unCyclicalUnBypassedNonPrimitiveUnderMaxDepth)); const sort = pipe(initializedNonPrimitiveOption.propertySortOrder, Option.map(order => Array.sort(order)), Option.getOrElse(Function.constant(Function.identity))); const filteredAndSortedProperties = pipe(properties, initializedNonPrimitiveOption.syntheticPropertyFilter, sort, MFunction.fIfTrue({ condition: initializedNonPrimitiveOption.dedupeProperties, f: Array.dedupeWith((self, that) => self.oneLineStringKey === that.oneLineStringKey) }), Array.take(initializedNonPrimitiveOption.maxPropertyNumber)); return Tuple.make(Tuple.make(unCyclicalUnBypassedNonPrimitiveUnderMaxDepth, initializedNonPrimitiveOption, properties.length), filteredAndSortedProperties); }), Either.mapLeft(flow(Tuple.make, Tuple.appendElement(seed), Tuple.appendElement(true)))), foldNonLeaf: ([nonPrimitive, initializedNonPrimitiveOption, allPropertyNumber], children) => pipe(children, Array.map(([stringified, value, isLeaf]) => pipe(stringified, initializedNonPrimitiveOption.initializedPropertyFormatter({ value, isLeaf }))), initializedNonPrimitiveOption.initializedNonPrimitiveFormatter({ value: nonPrimitive, header: pipe(cyclicalMap, MutableHashMap.get(nonPrimitive), Option.map(flow(MString.fromNonNullablePrimitive, messageTextFormatter(nonPrimitive), ASText.prepend(circularReferenceStartDelimiterMarkShower(nonPrimitive)), ASText.append(circularReferenceEndDelimiterMarkShower(nonPrimitive)))), Option.getOrElse(Function.constant(ASText.empty)), ASText.append(pipe(nonPrimitive, initializedNonPrimitiveOption.toHeaderMarkShower({ allPropertyNumber, actualPropertyNumber: children.length })))) }), Tuple.make, Tuple.appendElement(nonPrimitive), Tuple.appendElement(false)), foldLeaf: Function.identity }), ([first]) => first); return stringifier; }; //# sourceMappingURL=Option.js.map