UNPKG

loopey

Version:

A React UI component library for chat widgets.

1,955 lines (1,821 loc) 1.11 MB
import React, { useState, useEffect, useRef, useCallback, memo, useMemo } from 'react'; const Button = ({ children, ...props }) => (React.createElement("button", { ...props, style: { padding: '0.75em 2em', background: 'linear-gradient(90deg, #6a11cb 0%, #2575fc 100%)', color: '#fff', border: 'none', borderRadius: '2em', fontSize: '1rem', fontWeight: 600, boxShadow: '0 4px 16px rgba(38, 50, 56, 0.15)', cursor: 'pointer', transition: 'transform 0.1s, box-shadow 0.1s', outline: 'none', }, onMouseDown: e => (e.currentTarget.style.transform = 'scale(0.97)'), onMouseUp: e => (e.currentTarget.style.transform = 'scale(1)'), onMouseLeave: e => (e.currentTarget.style.transform = 'scale(1)') }, children)); const ChatWidget = ({ title = "Chat", primaryColor = "#2563eb", // Default blue onSendMessage, }) => { const [isOpen, setIsOpen] = useState(false); const [message, setMessage] = useState(""); const handleSend = () => { if (message.trim() && onSendMessage) { onSendMessage(message); setMessage(""); } }; return (React.createElement("div", { className: "chat-widget" }, isOpen && (React.createElement("div", { className: "chat-box", style: { boxShadow: "0 8px 32px rgba(0, 0, 0, 0.08)", border: "none", backgroundColor: "#ffffff", } }, React.createElement("div", { className: "chat-header", style: { color: primaryColor } }, title, React.createElement("button", { onClick: () => setIsOpen(false), className: "chat-close", "aria-label": "Close chat" }, React.createElement("span", { style: { color: "#9ca3af" } }, "\u00D7"))), React.createElement("div", { className: "chat-messages" }, React.createElement("p", { className: "chat-placeholder" }, "Start the conversation...")), React.createElement("div", { className: "chat-input" }, React.createElement("input", { className: "chat-text", placeholder: "Type a message...", value: message, onChange: (e) => setMessage(e.target.value), onKeyDown: (e) => e.key === "Enter" && handleSend() }), React.createElement("button", { onClick: handleSend, className: "chat-send", style: { backgroundColor: primaryColor }, "aria-label": "Send message" }, React.createElement("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, React.createElement("path", { d: "M22 2L11 13", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }), React.createElement("path", { d: "M22 2L15 22L11 13L2 9L22 2Z", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" })))))), React.createElement("button", { onClick: () => setIsOpen(!isOpen), className: "chat-toggle", style: { backgroundColor: primaryColor }, "aria-label": isOpen ? "Close chat" : "Open chat" }, isOpen ? "×" : "💬"))); }; function ok$1() {} function unreachable() {} /** * @typedef Options * Configuration for `stringify`. * @property {boolean} [padLeft=true] * Whether to pad a space before a token. * @property {boolean} [padRight=false] * Whether to pad a space after a token. */ /** * Serialize an array of strings or numbers to comma-separated tokens. * * @param {Array<string|number>} values * List of tokens. * @param {Options} [options] * Configuration for `stringify` (optional). * @returns {string} * Comma-separated tokens. */ function stringify$1(values, options) { const settings = {}; // Ensure the last empty entry is seen. const input = values[values.length - 1] === '' ? [...values, ''] : values; return input .join( (settings.padRight ? ' ' : '') + ',' + (settings.padLeft === false ? '' : ' ') ) .trim() } /** * @typedef Options * Configuration. * @property {boolean | null | undefined} [jsx=false] * Support JSX identifiers (default: `false`). */ const nameRe = /^[$_\p{ID_Start}][$_\u{200C}\u{200D}\p{ID_Continue}]*$/u; const nameReJsx = /^[$_\p{ID_Start}][-$_\u{200C}\u{200D}\p{ID_Continue}]*$/u; /** @type {Options} */ const emptyOptions$5 = {}; /** * Checks if the given value is a valid identifier name. * * @param {string} name * Identifier to check. * @param {Options | null | undefined} [options] * Configuration (optional). * @returns {boolean} * Whether `name` can be an identifier. */ function name(name, options) { const settings = emptyOptions$5; const re = settings.jsx ? nameReJsx : nameRe; return re.test(name) } /** * @typedef {import('hast').Nodes} Nodes */ // HTML whitespace expression. // See <https://infra.spec.whatwg.org/#ascii-whitespace>. const re = /[ \t\n\f\r]/g; /** * Check if the given value is *inter-element whitespace*. * * @param {Nodes | string} thing * Thing to check (`Node` or `string`). * @returns {boolean} * Whether the `value` is inter-element whitespace (`boolean`): consisting of * zero or more of space, tab (`\t`), line feed (`\n`), carriage return * (`\r`), or form feed (`\f`); if a node is passed it must be a `Text` node, * whose `value` field is checked. */ function whitespace(thing) { return typeof thing === 'object' ? thing.type === 'text' ? empty$1(thing.value) : false : empty$1(thing) } /** * @param {string} value * @returns {boolean} */ function empty$1(value) { return value.replace(re, '') === '' } /** * @import {Schema as SchemaType, Space} from 'property-information' */ /** @type {SchemaType} */ class Schema { /** * @param {SchemaType['property']} property * Property. * @param {SchemaType['normal']} normal * Normal. * @param {Space | undefined} [space] * Space. * @returns * Schema. */ constructor(property, normal, space) { this.normal = normal; this.property = property; if (space) { this.space = space; } } } Schema.prototype.normal = {}; Schema.prototype.property = {}; Schema.prototype.space = undefined; /** * @import {Info, Space} from 'property-information' */ /** * @param {ReadonlyArray<Schema>} definitions * Definitions. * @param {Space | undefined} [space] * Space. * @returns {Schema} * Schema. */ function merge(definitions, space) { /** @type {Record<string, Info>} */ const property = {}; /** @type {Record<string, string>} */ const normal = {}; for (const definition of definitions) { Object.assign(property, definition.property); Object.assign(normal, definition.normal); } return new Schema(property, normal, space) } /** * Get the cleaned case insensitive form of an attribute or property. * * @param {string} value * An attribute-like or property-like name. * @returns {string} * Value that can be used to look up the properly cased property on a * `Schema`. */ function normalize$1(value) { return value.toLowerCase() } /** * @import {Info as InfoType} from 'property-information' */ /** @type {InfoType} */ class Info { /** * @param {string} property * Property. * @param {string} attribute * Attribute. * @returns * Info. */ constructor(property, attribute) { this.attribute = attribute; this.property = property; } } Info.prototype.attribute = ''; Info.prototype.booleanish = false; Info.prototype.boolean = false; Info.prototype.commaOrSpaceSeparated = false; Info.prototype.commaSeparated = false; Info.prototype.defined = false; Info.prototype.mustUseProperty = false; Info.prototype.number = false; Info.prototype.overloadedBoolean = false; Info.prototype.property = ''; Info.prototype.spaceSeparated = false; Info.prototype.space = undefined; let powers = 0; const boolean = increment(); const booleanish = increment(); const overloadedBoolean = increment(); const number = increment(); const spaceSeparated = increment(); const commaSeparated = increment(); const commaOrSpaceSeparated = increment(); function increment() { return 2 ** ++powers } var types = /*#__PURE__*/Object.freeze({ __proto__: null, boolean: boolean, booleanish: booleanish, commaOrSpaceSeparated: commaOrSpaceSeparated, commaSeparated: commaSeparated, number: number, overloadedBoolean: overloadedBoolean, spaceSeparated: spaceSeparated }); /** * @import {Space} from 'property-information' */ const checks = /** @type {ReadonlyArray<keyof typeof types>} */ ( Object.keys(types) ); class DefinedInfo extends Info { /** * @constructor * @param {string} property * Property. * @param {string} attribute * Attribute. * @param {number | null | undefined} [mask] * Mask. * @param {Space | undefined} [space] * Space. * @returns * Info. */ constructor(property, attribute, mask, space) { let index = -1; super(property, attribute); mark(this, 'space', space); if (typeof mask === 'number') { while (++index < checks.length) { const check = checks[index]; mark(this, checks[index], (mask & types[check]) === types[check]); } } } } DefinedInfo.prototype.defined = true; /** * @template {keyof DefinedInfo} Key * Key type. * @param {DefinedInfo} values * Info. * @param {Key} key * Key. * @param {DefinedInfo[Key]} value * Value. * @returns {undefined} * Nothing. */ function mark(values, key, value) { if (value) { values[key] = value; } } /** * @import {Info, Space} from 'property-information' */ /** * @param {Definition} definition * Definition. * @returns {Schema} * Schema. */ function create(definition) { /** @type {Record<string, Info>} */ const properties = {}; /** @type {Record<string, string>} */ const normals = {}; for (const [property, value] of Object.entries(definition.properties)) { const info = new DefinedInfo( property, definition.transform(definition.attributes || {}, property), value, definition.space ); if ( definition.mustUseProperty && definition.mustUseProperty.includes(property) ) { info.mustUseProperty = true; } properties[property] = info; normals[normalize$1(property)] = property; normals[normalize$1(info.attribute)] = property; } return new Schema(properties, normals, definition.space) } const aria = create({ properties: { ariaActiveDescendant: null, ariaAtomic: booleanish, ariaAutoComplete: null, ariaBusy: booleanish, ariaChecked: booleanish, ariaColCount: number, ariaColIndex: number, ariaColSpan: number, ariaControls: spaceSeparated, ariaCurrent: null, ariaDescribedBy: spaceSeparated, ariaDetails: null, ariaDisabled: booleanish, ariaDropEffect: spaceSeparated, ariaErrorMessage: null, ariaExpanded: booleanish, ariaFlowTo: spaceSeparated, ariaGrabbed: booleanish, ariaHasPopup: null, ariaHidden: booleanish, ariaInvalid: null, ariaKeyShortcuts: null, ariaLabel: null, ariaLabelledBy: spaceSeparated, ariaLevel: number, ariaLive: null, ariaModal: booleanish, ariaMultiLine: booleanish, ariaMultiSelectable: booleanish, ariaOrientation: null, ariaOwns: spaceSeparated, ariaPlaceholder: null, ariaPosInSet: number, ariaPressed: booleanish, ariaReadOnly: booleanish, ariaRelevant: null, ariaRequired: booleanish, ariaRoleDescription: spaceSeparated, ariaRowCount: number, ariaRowIndex: number, ariaRowSpan: number, ariaSelected: booleanish, ariaSetSize: number, ariaSort: null, ariaValueMax: number, ariaValueMin: number, ariaValueNow: number, ariaValueText: null, role: null }, transform(_, property) { return property === 'role' ? property : 'aria-' + property.slice(4).toLowerCase() } }); /** * @param {Record<string, string>} attributes * Attributes. * @param {string} attribute * Attribute. * @returns {string} * Transformed attribute. */ function caseSensitiveTransform(attributes, attribute) { return attribute in attributes ? attributes[attribute] : attribute } /** * @param {Record<string, string>} attributes * Attributes. * @param {string} property * Property. * @returns {string} * Transformed property. */ function caseInsensitiveTransform(attributes, property) { return caseSensitiveTransform(attributes, property.toLowerCase()) } const html$3 = create({ attributes: { acceptcharset: 'accept-charset', classname: 'class', htmlfor: 'for', httpequiv: 'http-equiv' }, mustUseProperty: ['checked', 'multiple', 'muted', 'selected'], properties: { // Standard Properties. abbr: null, accept: commaSeparated, acceptCharset: spaceSeparated, accessKey: spaceSeparated, action: null, allow: null, allowFullScreen: boolean, allowPaymentRequest: boolean, allowUserMedia: boolean, alt: null, as: null, async: boolean, autoCapitalize: null, autoComplete: spaceSeparated, autoFocus: boolean, autoPlay: boolean, blocking: spaceSeparated, capture: null, charSet: null, checked: boolean, cite: null, className: spaceSeparated, cols: number, colSpan: null, content: null, contentEditable: booleanish, controls: boolean, controlsList: spaceSeparated, coords: number | commaSeparated, crossOrigin: null, data: null, dateTime: null, decoding: null, default: boolean, defer: boolean, dir: null, dirName: null, disabled: boolean, download: overloadedBoolean, draggable: booleanish, encType: null, enterKeyHint: null, fetchPriority: null, form: null, formAction: null, formEncType: null, formMethod: null, formNoValidate: boolean, formTarget: null, headers: spaceSeparated, height: number, hidden: overloadedBoolean, high: number, href: null, hrefLang: null, htmlFor: spaceSeparated, httpEquiv: spaceSeparated, id: null, imageSizes: null, imageSrcSet: null, inert: boolean, inputMode: null, integrity: null, is: null, isMap: boolean, itemId: null, itemProp: spaceSeparated, itemRef: spaceSeparated, itemScope: boolean, itemType: spaceSeparated, kind: null, label: null, lang: null, language: null, list: null, loading: null, loop: boolean, low: number, manifest: null, max: null, maxLength: number, media: null, method: null, min: null, minLength: number, multiple: boolean, muted: boolean, name: null, nonce: null, noModule: boolean, noValidate: boolean, onAbort: null, onAfterPrint: null, onAuxClick: null, onBeforeMatch: null, onBeforePrint: null, onBeforeToggle: null, onBeforeUnload: null, onBlur: null, onCancel: null, onCanPlay: null, onCanPlayThrough: null, onChange: null, onClick: null, onClose: null, onContextLost: null, onContextMenu: null, onContextRestored: null, onCopy: null, onCueChange: null, onCut: null, onDblClick: null, onDrag: null, onDragEnd: null, onDragEnter: null, onDragExit: null, onDragLeave: null, onDragOver: null, onDragStart: null, onDrop: null, onDurationChange: null, onEmptied: null, onEnded: null, onError: null, onFocus: null, onFormData: null, onHashChange: null, onInput: null, onInvalid: null, onKeyDown: null, onKeyPress: null, onKeyUp: null, onLanguageChange: null, onLoad: null, onLoadedData: null, onLoadedMetadata: null, onLoadEnd: null, onLoadStart: null, onMessage: null, onMessageError: null, onMouseDown: null, onMouseEnter: null, onMouseLeave: null, onMouseMove: null, onMouseOut: null, onMouseOver: null, onMouseUp: null, onOffline: null, onOnline: null, onPageHide: null, onPageShow: null, onPaste: null, onPause: null, onPlay: null, onPlaying: null, onPopState: null, onProgress: null, onRateChange: null, onRejectionHandled: null, onReset: null, onResize: null, onScroll: null, onScrollEnd: null, onSecurityPolicyViolation: null, onSeeked: null, onSeeking: null, onSelect: null, onSlotChange: null, onStalled: null, onStorage: null, onSubmit: null, onSuspend: null, onTimeUpdate: null, onToggle: null, onUnhandledRejection: null, onUnload: null, onVolumeChange: null, onWaiting: null, onWheel: null, open: boolean, optimum: number, pattern: null, ping: spaceSeparated, placeholder: null, playsInline: boolean, popover: null, popoverTarget: null, popoverTargetAction: null, poster: null, preload: null, readOnly: boolean, referrerPolicy: null, rel: spaceSeparated, required: boolean, reversed: boolean, rows: number, rowSpan: number, sandbox: spaceSeparated, scope: null, scoped: boolean, seamless: boolean, selected: boolean, shadowRootClonable: boolean, shadowRootDelegatesFocus: boolean, shadowRootMode: null, shape: null, size: number, sizes: null, slot: null, span: number, spellCheck: booleanish, src: null, srcDoc: null, srcLang: null, srcSet: null, start: number, step: null, style: null, tabIndex: number, target: null, title: null, translate: null, type: null, typeMustMatch: boolean, useMap: null, value: booleanish, width: number, wrap: null, writingSuggestions: null, // Legacy. // See: https://html.spec.whatwg.org/#other-elements,-attributes-and-apis align: null, // Several. Use CSS `text-align` instead, aLink: null, // `<body>`. Use CSS `a:active {color}` instead archive: spaceSeparated, // `<object>`. List of URIs to archives axis: null, // `<td>` and `<th>`. Use `scope` on `<th>` background: null, // `<body>`. Use CSS `background-image` instead bgColor: null, // `<body>` and table elements. Use CSS `background-color` instead border: number, // `<table>`. Use CSS `border-width` instead, borderColor: null, // `<table>`. Use CSS `border-color` instead, bottomMargin: number, // `<body>` cellPadding: null, // `<table>` cellSpacing: null, // `<table>` char: null, // Several table elements. When `align=char`, sets the character to align on charOff: null, // Several table elements. When `char`, offsets the alignment classId: null, // `<object>` clear: null, // `<br>`. Use CSS `clear` instead code: null, // `<object>` codeBase: null, // `<object>` codeType: null, // `<object>` color: null, // `<font>` and `<hr>`. Use CSS instead compact: boolean, // Lists. Use CSS to reduce space between items instead declare: boolean, // `<object>` event: null, // `<script>` face: null, // `<font>`. Use CSS instead frame: null, // `<table>` frameBorder: null, // `<iframe>`. Use CSS `border` instead hSpace: number, // `<img>` and `<object>` leftMargin: number, // `<body>` link: null, // `<body>`. Use CSS `a:link {color: *}` instead longDesc: null, // `<frame>`, `<iframe>`, and `<img>`. Use an `<a>` lowSrc: null, // `<img>`. Use a `<picture>` marginHeight: number, // `<body>` marginWidth: number, // `<body>` noResize: boolean, // `<frame>` noHref: boolean, // `<area>`. Use no href instead of an explicit `nohref` noShade: boolean, // `<hr>`. Use background-color and height instead of borders noWrap: boolean, // `<td>` and `<th>` object: null, // `<applet>` profile: null, // `<head>` prompt: null, // `<isindex>` rev: null, // `<link>` rightMargin: number, // `<body>` rules: null, // `<table>` scheme: null, // `<meta>` scrolling: booleanish, // `<frame>`. Use overflow in the child context standby: null, // `<object>` summary: null, // `<table>` text: null, // `<body>`. Use CSS `color` instead topMargin: number, // `<body>` valueType: null, // `<param>` version: null, // `<html>`. Use a doctype. vAlign: null, // Several. Use CSS `vertical-align` instead vLink: null, // `<body>`. Use CSS `a:visited {color}` instead vSpace: number, // `<img>` and `<object>` // Non-standard Properties. allowTransparency: null, autoCorrect: null, autoSave: null, disablePictureInPicture: boolean, disableRemotePlayback: boolean, prefix: null, property: null, results: number, security: null, unselectable: null }, space: 'html', transform: caseInsensitiveTransform }); const svg$1 = create({ attributes: { accentHeight: 'accent-height', alignmentBaseline: 'alignment-baseline', arabicForm: 'arabic-form', baselineShift: 'baseline-shift', capHeight: 'cap-height', className: 'class', clipPath: 'clip-path', clipRule: 'clip-rule', colorInterpolation: 'color-interpolation', colorInterpolationFilters: 'color-interpolation-filters', colorProfile: 'color-profile', colorRendering: 'color-rendering', crossOrigin: 'crossorigin', dataType: 'datatype', dominantBaseline: 'dominant-baseline', enableBackground: 'enable-background', fillOpacity: 'fill-opacity', fillRule: 'fill-rule', floodColor: 'flood-color', floodOpacity: 'flood-opacity', fontFamily: 'font-family', fontSize: 'font-size', fontSizeAdjust: 'font-size-adjust', fontStretch: 'font-stretch', fontStyle: 'font-style', fontVariant: 'font-variant', fontWeight: 'font-weight', glyphName: 'glyph-name', glyphOrientationHorizontal: 'glyph-orientation-horizontal', glyphOrientationVertical: 'glyph-orientation-vertical', hrefLang: 'hreflang', horizAdvX: 'horiz-adv-x', horizOriginX: 'horiz-origin-x', horizOriginY: 'horiz-origin-y', imageRendering: 'image-rendering', letterSpacing: 'letter-spacing', lightingColor: 'lighting-color', markerEnd: 'marker-end', markerMid: 'marker-mid', markerStart: 'marker-start', navDown: 'nav-down', navDownLeft: 'nav-down-left', navDownRight: 'nav-down-right', navLeft: 'nav-left', navNext: 'nav-next', navPrev: 'nav-prev', navRight: 'nav-right', navUp: 'nav-up', navUpLeft: 'nav-up-left', navUpRight: 'nav-up-right', onAbort: 'onabort', onActivate: 'onactivate', onAfterPrint: 'onafterprint', onBeforePrint: 'onbeforeprint', onBegin: 'onbegin', onCancel: 'oncancel', onCanPlay: 'oncanplay', onCanPlayThrough: 'oncanplaythrough', onChange: 'onchange', onClick: 'onclick', onClose: 'onclose', onCopy: 'oncopy', onCueChange: 'oncuechange', onCut: 'oncut', onDblClick: 'ondblclick', onDrag: 'ondrag', onDragEnd: 'ondragend', onDragEnter: 'ondragenter', onDragExit: 'ondragexit', onDragLeave: 'ondragleave', onDragOver: 'ondragover', onDragStart: 'ondragstart', onDrop: 'ondrop', onDurationChange: 'ondurationchange', onEmptied: 'onemptied', onEnd: 'onend', onEnded: 'onended', onError: 'onerror', onFocus: 'onfocus', onFocusIn: 'onfocusin', onFocusOut: 'onfocusout', onHashChange: 'onhashchange', onInput: 'oninput', onInvalid: 'oninvalid', onKeyDown: 'onkeydown', onKeyPress: 'onkeypress', onKeyUp: 'onkeyup', onLoad: 'onload', onLoadedData: 'onloadeddata', onLoadedMetadata: 'onloadedmetadata', onLoadStart: 'onloadstart', onMessage: 'onmessage', onMouseDown: 'onmousedown', onMouseEnter: 'onmouseenter', onMouseLeave: 'onmouseleave', onMouseMove: 'onmousemove', onMouseOut: 'onmouseout', onMouseOver: 'onmouseover', onMouseUp: 'onmouseup', onMouseWheel: 'onmousewheel', onOffline: 'onoffline', onOnline: 'ononline', onPageHide: 'onpagehide', onPageShow: 'onpageshow', onPaste: 'onpaste', onPause: 'onpause', onPlay: 'onplay', onPlaying: 'onplaying', onPopState: 'onpopstate', onProgress: 'onprogress', onRateChange: 'onratechange', onRepeat: 'onrepeat', onReset: 'onreset', onResize: 'onresize', onScroll: 'onscroll', onSeeked: 'onseeked', onSeeking: 'onseeking', onSelect: 'onselect', onShow: 'onshow', onStalled: 'onstalled', onStorage: 'onstorage', onSubmit: 'onsubmit', onSuspend: 'onsuspend', onTimeUpdate: 'ontimeupdate', onToggle: 'ontoggle', onUnload: 'onunload', onVolumeChange: 'onvolumechange', onWaiting: 'onwaiting', onZoom: 'onzoom', overlinePosition: 'overline-position', overlineThickness: 'overline-thickness', paintOrder: 'paint-order', panose1: 'panose-1', pointerEvents: 'pointer-events', referrerPolicy: 'referrerpolicy', renderingIntent: 'rendering-intent', shapeRendering: 'shape-rendering', stopColor: 'stop-color', stopOpacity: 'stop-opacity', strikethroughPosition: 'strikethrough-position', strikethroughThickness: 'strikethrough-thickness', strokeDashArray: 'stroke-dasharray', strokeDashOffset: 'stroke-dashoffset', strokeLineCap: 'stroke-linecap', strokeLineJoin: 'stroke-linejoin', strokeMiterLimit: 'stroke-miterlimit', strokeOpacity: 'stroke-opacity', strokeWidth: 'stroke-width', tabIndex: 'tabindex', textAnchor: 'text-anchor', textDecoration: 'text-decoration', textRendering: 'text-rendering', transformOrigin: 'transform-origin', typeOf: 'typeof', underlinePosition: 'underline-position', underlineThickness: 'underline-thickness', unicodeBidi: 'unicode-bidi', unicodeRange: 'unicode-range', unitsPerEm: 'units-per-em', vAlphabetic: 'v-alphabetic', vHanging: 'v-hanging', vIdeographic: 'v-ideographic', vMathematical: 'v-mathematical', vectorEffect: 'vector-effect', vertAdvY: 'vert-adv-y', vertOriginX: 'vert-origin-x', vertOriginY: 'vert-origin-y', wordSpacing: 'word-spacing', writingMode: 'writing-mode', xHeight: 'x-height', // These were camelcased in Tiny. Now lowercased in SVG 2 playbackOrder: 'playbackorder', timelineBegin: 'timelinebegin' }, properties: { about: commaOrSpaceSeparated, accentHeight: number, accumulate: null, additive: null, alignmentBaseline: null, alphabetic: number, amplitude: number, arabicForm: null, ascent: number, attributeName: null, attributeType: null, azimuth: number, bandwidth: null, baselineShift: null, baseFrequency: null, baseProfile: null, bbox: null, begin: null, bias: number, by: null, calcMode: null, capHeight: number, className: spaceSeparated, clip: null, clipPath: null, clipPathUnits: null, clipRule: null, color: null, colorInterpolation: null, colorInterpolationFilters: null, colorProfile: null, colorRendering: null, content: null, contentScriptType: null, contentStyleType: null, crossOrigin: null, cursor: null, cx: null, cy: null, d: null, dataType: null, defaultAction: null, descent: number, diffuseConstant: number, direction: null, display: null, dur: null, divisor: number, dominantBaseline: null, download: boolean, dx: null, dy: null, edgeMode: null, editable: null, elevation: number, enableBackground: null, end: null, event: null, exponent: number, externalResourcesRequired: null, fill: null, fillOpacity: number, fillRule: null, filter: null, filterRes: null, filterUnits: null, floodColor: null, floodOpacity: null, focusable: null, focusHighlight: null, fontFamily: null, fontSize: null, fontSizeAdjust: null, fontStretch: null, fontStyle: null, fontVariant: null, fontWeight: null, format: null, fr: null, from: null, fx: null, fy: null, g1: commaSeparated, g2: commaSeparated, glyphName: commaSeparated, glyphOrientationHorizontal: null, glyphOrientationVertical: null, glyphRef: null, gradientTransform: null, gradientUnits: null, handler: null, hanging: number, hatchContentUnits: null, hatchUnits: null, height: null, href: null, hrefLang: null, horizAdvX: number, horizOriginX: number, horizOriginY: number, id: null, ideographic: number, imageRendering: null, initialVisibility: null, in: null, in2: null, intercept: number, k: number, k1: number, k2: number, k3: number, k4: number, kernelMatrix: commaOrSpaceSeparated, kernelUnitLength: null, keyPoints: null, // SEMI_COLON_SEPARATED keySplines: null, // SEMI_COLON_SEPARATED keyTimes: null, // SEMI_COLON_SEPARATED kerning: null, lang: null, lengthAdjust: null, letterSpacing: null, lightingColor: null, limitingConeAngle: number, local: null, markerEnd: null, markerMid: null, markerStart: null, markerHeight: null, markerUnits: null, markerWidth: null, mask: null, maskContentUnits: null, maskUnits: null, mathematical: null, max: null, media: null, mediaCharacterEncoding: null, mediaContentEncodings: null, mediaSize: number, mediaTime: null, method: null, min: null, mode: null, name: null, navDown: null, navDownLeft: null, navDownRight: null, navLeft: null, navNext: null, navPrev: null, navRight: null, navUp: null, navUpLeft: null, navUpRight: null, numOctaves: null, observer: null, offset: null, onAbort: null, onActivate: null, onAfterPrint: null, onBeforePrint: null, onBegin: null, onCancel: null, onCanPlay: null, onCanPlayThrough: null, onChange: null, onClick: null, onClose: null, onCopy: null, onCueChange: null, onCut: null, onDblClick: null, onDrag: null, onDragEnd: null, onDragEnter: null, onDragExit: null, onDragLeave: null, onDragOver: null, onDragStart: null, onDrop: null, onDurationChange: null, onEmptied: null, onEnd: null, onEnded: null, onError: null, onFocus: null, onFocusIn: null, onFocusOut: null, onHashChange: null, onInput: null, onInvalid: null, onKeyDown: null, onKeyPress: null, onKeyUp: null, onLoad: null, onLoadedData: null, onLoadedMetadata: null, onLoadStart: null, onMessage: null, onMouseDown: null, onMouseEnter: null, onMouseLeave: null, onMouseMove: null, onMouseOut: null, onMouseOver: null, onMouseUp: null, onMouseWheel: null, onOffline: null, onOnline: null, onPageHide: null, onPageShow: null, onPaste: null, onPause: null, onPlay: null, onPlaying: null, onPopState: null, onProgress: null, onRateChange: null, onRepeat: null, onReset: null, onResize: null, onScroll: null, onSeeked: null, onSeeking: null, onSelect: null, onShow: null, onStalled: null, onStorage: null, onSubmit: null, onSuspend: null, onTimeUpdate: null, onToggle: null, onUnload: null, onVolumeChange: null, onWaiting: null, onZoom: null, opacity: null, operator: null, order: null, orient: null, orientation: null, origin: null, overflow: null, overlay: null, overlinePosition: number, overlineThickness: number, paintOrder: null, panose1: null, path: null, pathLength: number, patternContentUnits: null, patternTransform: null, patternUnits: null, phase: null, ping: spaceSeparated, pitch: null, playbackOrder: null, pointerEvents: null, points: null, pointsAtX: number, pointsAtY: number, pointsAtZ: number, preserveAlpha: null, preserveAspectRatio: null, primitiveUnits: null, propagate: null, property: commaOrSpaceSeparated, r: null, radius: null, referrerPolicy: null, refX: null, refY: null, rel: commaOrSpaceSeparated, rev: commaOrSpaceSeparated, renderingIntent: null, repeatCount: null, repeatDur: null, requiredExtensions: commaOrSpaceSeparated, requiredFeatures: commaOrSpaceSeparated, requiredFonts: commaOrSpaceSeparated, requiredFormats: commaOrSpaceSeparated, resource: null, restart: null, result: null, rotate: null, rx: null, ry: null, scale: null, seed: null, shapeRendering: null, side: null, slope: null, snapshotTime: null, specularConstant: number, specularExponent: number, spreadMethod: null, spacing: null, startOffset: null, stdDeviation: null, stemh: null, stemv: null, stitchTiles: null, stopColor: null, stopOpacity: null, strikethroughPosition: number, strikethroughThickness: number, string: null, stroke: null, strokeDashArray: commaOrSpaceSeparated, strokeDashOffset: null, strokeLineCap: null, strokeLineJoin: null, strokeMiterLimit: number, strokeOpacity: number, strokeWidth: null, style: null, surfaceScale: number, syncBehavior: null, syncBehaviorDefault: null, syncMaster: null, syncTolerance: null, syncToleranceDefault: null, systemLanguage: commaOrSpaceSeparated, tabIndex: number, tableValues: null, target: null, targetX: number, targetY: number, textAnchor: null, textDecoration: null, textRendering: null, textLength: null, timelineBegin: null, title: null, transformBehavior: null, type: null, typeOf: commaOrSpaceSeparated, to: null, transform: null, transformOrigin: null, u1: null, u2: null, underlinePosition: number, underlineThickness: number, unicode: null, unicodeBidi: null, unicodeRange: null, unitsPerEm: number, values: null, vAlphabetic: number, vMathematical: number, vectorEffect: null, vHanging: number, vIdeographic: number, version: null, vertAdvY: number, vertOriginX: number, vertOriginY: number, viewBox: null, viewTarget: null, visibility: null, width: null, widths: null, wordSpacing: null, writingMode: null, x: null, x1: null, x2: null, xChannelSelector: null, xHeight: number, y: null, y1: null, y2: null, yChannelSelector: null, z: null, zoomAndPan: null }, space: 'svg', transform: caseSensitiveTransform }); const xlink = create({ properties: { xLinkActuate: null, xLinkArcRole: null, xLinkHref: null, xLinkRole: null, xLinkShow: null, xLinkTitle: null, xLinkType: null }, space: 'xlink', transform(_, property) { return 'xlink:' + property.slice(5).toLowerCase() } }); const xmlns = create({ attributes: {xmlnsxlink: 'xmlns:xlink'}, properties: {xmlnsXLink: null, xmlns: null}, space: 'xmlns', transform: caseInsensitiveTransform }); const xml$1 = create({ properties: {xmlBase: null, xmlLang: null, xmlSpace: null}, space: 'xml', transform(_, property) { return 'xml:' + property.slice(3).toLowerCase() } }); /** * Special cases for React (`Record<string, string>`). * * `hast` is close to `React` but differs in a couple of cases. * To get a React property from a hast property, * check if it is in `hastToReact`. * If it is, use the corresponding value; * otherwise, use the hast property. * * @type {Record<string, string>} */ const hastToReact = { classId: 'classID', dataType: 'datatype', itemId: 'itemID', strokeDashArray: 'strokeDasharray', strokeDashOffset: 'strokeDashoffset', strokeLineCap: 'strokeLinecap', strokeLineJoin: 'strokeLinejoin', strokeMiterLimit: 'strokeMiterlimit', typeOf: 'typeof', xLinkActuate: 'xlinkActuate', xLinkArcRole: 'xlinkArcrole', xLinkHref: 'xlinkHref', xLinkRole: 'xlinkRole', xLinkShow: 'xlinkShow', xLinkTitle: 'xlinkTitle', xLinkType: 'xlinkType', xmlnsXLink: 'xmlnsXlink' }; /** * @import {Schema} from 'property-information' */ const cap$1 = /[A-Z]/g; const dash = /-[a-z]/g; const valid = /^data[-\w.:]+$/i; /** * Look up info on a property. * * In most cases the given `schema` contains info on the property. * All standard, * most legacy, * and some non-standard properties are supported. * For these cases, * the returned `Info` has hints about the value of the property. * * `name` can also be a valid data attribute or property, * in which case an `Info` object with the correctly cased `attribute` and * `property` is returned. * * `name` can be an unknown attribute, * in which case an `Info` object with `attribute` and `property` set to the * given name is returned. * It is not recommended to provide unsupported legacy or recently specced * properties. * * * @param {Schema} schema * Schema; * either the `html` or `svg` export. * @param {string} value * An attribute-like or property-like name; * it will be passed through `normalize` to hopefully find the correct info. * @returns {Info} * Info. */ function find(schema, value) { const normal = normalize$1(value); let property = value; let Type = Info; if (normal in schema.normal) { return schema.property[schema.normal[normal]] } if (normal.length > 4 && normal.slice(0, 4) === 'data' && valid.test(value)) { // Attribute or property. if (value.charAt(4) === '-') { // Turn it into a property. const rest = value.slice(5).replace(dash, camelcase); property = 'data' + rest.charAt(0).toUpperCase() + rest.slice(1); } else { // Turn it into an attribute. const rest = value.slice(4); if (!dash.test(rest)) { let dashes = rest.replace(cap$1, kebab); if (dashes.charAt(0) !== '-') { dashes = '-' + dashes; } value = 'data' + dashes; } } Type = DefinedInfo; } return new Type(property, value) } /** * @param {string} $0 * Value. * @returns {string} * Kebab. */ function kebab($0) { return '-' + $0.toLowerCase() } /** * @param {string} $0 * Value. * @returns {string} * Camel. */ function camelcase($0) { return $0.charAt(1).toUpperCase() } // Note: types exposed from `index.d.ts`. const html$2 = merge([aria, html$3, xlink, xmlns, xml$1], 'html'); const svg = merge([aria, svg$1, xlink, xmlns, xml$1], 'svg'); /** * Parse space-separated tokens to an array of strings. * * @param {string} value * Space-separated tokens. * @returns {Array<string>} * List of tokens. */ /** * Serialize an array of strings as space separated-tokens. * * @param {Array<string|number>} values * List of tokens. * @returns {string} * Space-separated tokens. */ function stringify(values) { return values.join(' ').trim() } function getDefaultExportFromCjs (x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; } var cjs$1 = {}; var inlineStyleParser; var hasRequiredInlineStyleParser; function requireInlineStyleParser () { if (hasRequiredInlineStyleParser) return inlineStyleParser; hasRequiredInlineStyleParser = 1; // http://www.w3.org/TR/CSS21/grammar.html // https://github.com/visionmedia/css-parse/pull/49#issuecomment-30088027 var COMMENT_REGEX = /\/\*[^*]*\*+([^/*][^*]*\*+)*\//g; var NEWLINE_REGEX = /\n/g; var WHITESPACE_REGEX = /^\s*/; // declaration var PROPERTY_REGEX = /^(\*?[-#/*\\\w]+(\[[0-9a-z_-]+\])?)\s*/; var COLON_REGEX = /^:\s*/; var VALUE_REGEX = /^((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^)]*?\)|[^};])+)/; var SEMICOLON_REGEX = /^[;\s]*/; // https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String/Trim#Polyfill var TRIM_REGEX = /^\s+|\s+$/g; // strings var NEWLINE = '\n'; var FORWARD_SLASH = '/'; var ASTERISK = '*'; var EMPTY_STRING = ''; // types var TYPE_COMMENT = 'comment'; var TYPE_DECLARATION = 'declaration'; /** * @param {String} style * @param {Object} [options] * @return {Object[]} * @throws {TypeError} * @throws {Error} */ inlineStyleParser = function (style, options) { if (typeof style !== 'string') { throw new TypeError('First argument must be a string'); } if (!style) return []; options = options || {}; /** * Positional. */ var lineno = 1; var column = 1; /** * Update lineno and column based on `str`. * * @param {String} str */ function updatePosition(str) { var lines = str.match(NEWLINE_REGEX); if (lines) lineno += lines.length; var i = str.lastIndexOf(NEWLINE); column = ~i ? str.length - i : column + str.length; } /** * Mark position and patch `node.position`. * * @return {Function} */ function position() { var start = { line: lineno, column: column }; return function (node) { node.position = new Position(start); whitespace(); return node; }; } /** * Store position information for a node. * * @constructor * @property {Object} start * @property {Object} end * @property {undefined|String} source */ function Position(start) { this.start = start; this.end = { line: lineno, column: column }; this.source = options.source; } /** * Non-enumerable source string. */ Position.prototype.content = style; /** * Error `msg`. * * @param {String} msg * @throws {Error} */ function error(msg) { var err = new Error( options.source + ':' + lineno + ':' + column + ': ' + msg ); err.reason = msg; err.filename = options.source; err.line = lineno; err.column = column; err.source = style; if (options.silent) ; else { throw err; } } /** * Match `re` and return captures. * * @param {RegExp} re * @return {undefined|Array} */ function match(re) { var m = re.exec(style); if (!m) return; var str = m[0]; updatePosition(str); style = style.slice(str.length); return m; } /** * Parse whitespace. */ function whitespace() { match(WHITESPACE_REGEX); } /** * Parse comments. * * @param {Object[]} [rules] * @return {Object[]} */ function comments(rules) { var c; rules = rules || []; while ((c = comment())) { if (c !== false) { rules.push(c); } } return rules; } /** * Parse comment. * * @return {Object} * @throws {Error} */ function comment() { var pos = position(); if (FORWARD_SLASH != style.charAt(0) || ASTERISK != style.charAt(1)) return; var i = 2; while ( EMPTY_STRING != style.charAt(i) && (ASTERISK != style.charAt(i) || FORWARD_SLASH != style.charAt(i + 1)) ) { ++i; } i += 2; if (EMPTY_STRING === style.charAt(i - 1)) { return error('End of comment missing'); } var str = style.slice(2, i - 2); column += 2; updatePosition(str); style = style.slice(i); column += 2; return pos({ type: TYPE_COMMENT, comment: str }); } /** * Parse declaration. * * @return {Object} * @throws {Error} */ function declaration() { var pos = position(); // prop var prop = match(PROPERTY_REGEX); if (!prop) return; comment(); // : if (!match(COLON_REGEX)) return error("property missing ':'"); // val var val = match(VALUE_REGEX); var ret = pos({ type: TYPE_DECLARATION, property: trim(prop[0].replace(COMMENT_REGEX, EMPTY_STRING)), value: val ? trim(val[0].replace(COMMENT_REGEX, EMPTY_STRING)) : EMPTY_STRING }); // ; match(SEMICOLON_REGEX); return ret; } /** * Parse declarations. * * @return {Object[]} */ function declarations() { var decls = []; comments(decls); // declarations var decl; while ((decl = declaration())) { if (decl !== false) { decls.push(decl); comments(decls); } } return decls; } whitespace(); return declarations(); }; /** * Trim `str`. * * @param {String} str * @return {String} */ function trim(str) { return str ? str.replace(TRIM_REGEX, EMPTY_STRING) : EMPTY_STRING; } return inlineStyleParser; } var hasRequiredCjs$1; function requireCjs$1 () { if (hasRequiredCjs$1) return cjs$1; hasRequiredCjs$1 = 1; var __importDefault = (cjs$1 && cjs$1.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(cjs$1, "__esModule", { value: true }); cjs$1.default = StyleToObject; var inline_style_parser_1 = __importDefault(requireInlineStyleParser()); /** * Parses inline style to object. * * @param style - Inline style. * @param iterator - Iterator. * @returns - Style object or null. * * @example Parsing inline style to object: * * ```js * import parse from 'style-to-object'; * parse('line-height: 42;'); // { 'line-height': '42' } * ``` */ function StyleToObject(style, iterator) { var styleObject = null; if (!style || typeof style !== 'string') { return styleObject; } var declarations = (0, inline_style_parser_1.default)(style); var hasIterator = typeof iterator === 'function'; declarations.forEach(function (declaration) { if (declaration.type !== 'declaration') { return; } var property = declaration.property, value = declaration.value; if (hasIterator) { iterator(property, value, declaration); } else if (value) { styleObject = styleObject || {}; styleObject[property] = value; } }); return styleObject; } return cjs$1; } var utilities = {}; var hasRequiredUtilities; function requireUtilities () { if (hasRequiredUtilities) return utilities; hasRequiredUtilities = 1; Object.defineProperty(utilities, "__esModule", { value: true }); utilities.camelCase = void 0; var CUSTOM_PROPERTY_REGEX = /^--[a-zA-Z0-9_-]+$/; var HYPHEN_REGEX = /-([a-z])/g; var NO_HYPHEN_REGEX = /^[^-]+$/; var VENDOR_PREFIX_REGEX = /^-(webkit|moz|ms|o|khtml)-/; var MS_VENDOR_PREFIX_REGEX = /^-(ms)-/; /** * Checks whether to skip camelCase. */ var skipCamelCase = function (property) { return !property || NO_HYPHEN_REGEX.test(property) || CUSTOM_PROPERTY_REGEX.test(property); }; /** * Replacer that capitalizes first character. */ var capitalize = function (match, character) { return character.toUpperCase(); }; /** * Replacer that removes beginning hyphen of vendor prefix property. */ var trimHyphen = function (match, prefix) { return "".concat(prefix, "-"); }; /** * CamelCases a CSS property. */ var camelCase = function (property, options) { if (options === void 0) { options = {}; } if (skipCamelCase(property)) { return property; } property = property.toLowerCase(); if (options.reactCompat) { // `-ms` vendor prefix should not be capitalized property = property.replace(MS_VENDOR_PREFIX_REGEX, trimHyphen); } else { // for non-React, remove first hyphen so vendor prefix is not capitalized property = property.replace(VENDOR_PREFIX_REGEX, trimHyphen); } return property.replace(HYPHEN_REGEX, capitalize); }; utilities.camelCase = camelCase; return utilities; } var cjs; var hasRequiredCjs; function requireCjs () { if (hasRequiredCjs) return cjs; hasRequiredCjs = 1; var __importDefault = (cjs && cjs.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; var style_to_object_1 = __importDefault(requireCjs$1()); var utilities_1 = requireUtilities(); /** * Parses CSS inline style to JavaScript object (camelCased). */ function StyleToJS(style, options) { var output = {}; if (!style || typeof style !== 'string') { return output; } (0, style_to_object_1.default)(style, function (property, value) { // skip CSS comment if (property && value) { output[(0, utilities_1.camelCase)(property, options)] = value; } }); return output; } StyleToJS.default = StyleToJS; cjs = StyleToJS; return cjs; } var cjsExports = requireCjs(); var styleToJs = /*@__PURE__*/getDefaultExportFromCjs(cjsExports); /** * @typedef {import('unist').Node} Node * @typedef {import('unist').Point} Point * @typedef {import('unist').Position} Position */ /** * @typedef NodeLike * @property {string} type * @property {PositionLike | null | undefined} [position] * * @typedef PositionLike * @property {PointLike | null | undefined} [start] * @property {PointLike | null | undefined} [end] * * @typedef PointLike * @property {number | null | undefined} [line] * @property {number | null | undefined} [column] * @property {number | null | undefined} [offset] */ /** * Get the ending point of `node`. * * @param node