PageSourceSearch

https://odoo.pantalytics.com/web/static/lib/signature_pad/signature_pad.umd.js

js pantalytics.com collected 2026-09-25 21:11:59 UTC 27,531 bytes, 644 lines download raw bytes

vendor: 5,888 bytes, lines 1-163
1/*!
2 * Signature Pad v5.0.4 | https://github.com/szimek/signature_pad
3 * (c) 2024 Szymon Nowak | Released under the MIT license
4 */
5
6(function (global, factory) {
7    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
8    typeof define === 'function' && define.amd ? define(factory) :
9    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.SignaturePad = factory());
10})(this, (function () { 'use strict';
11
12    class Point {
13        constructor(x, y, pressure, time) {
14            if (isNaN(x) || isNaN(y)) {
15                throw new Error(`Point is invalid: (${x}, ${y})`);
16            }
17            this.x = +x;
18            this.y = +y;
19            this.pressure = pressure || 0;
20            this.time = time || Date.now();
21        }
22        distanceTo(start) {
23            return Math.sqrt(Math.pow(this.x - start.x, 2) + Math.pow(this.y - start.y, 2));
24        }
25        equals(other) {
26            return (this.x === other.x &&
27                this.y === other.y &&
28                this.pressure === other.pressure &&
29                this.time === other.time);
30        }
31        velocityFrom(start) {
32            return this.time !== start.time
33                ? this.distanceTo(start) / (this.time - start.time)
34                : 0;
35        }
36    }
37
38    class Bezier {
39        static fromPoints(points, widths) {
40            const c2 = this.calculateControlPoints(points[0], points[1], points[2]).c2;
41            const c3 = this.calculateControlPoints(points[1], points[2], points[3]).c1;
42            return new Bezier(points[1], c2, c3, points[2], widths.start, widths.end);
43        }
44        static calculateControlPoints(s1, s2, s3) {
45            const dx1 = s1.x - s2.x;
46            const dy1 = s1.y - s2.y;
47            const dx2 = s2.x - s3.x;
48            const dy2 = s2.y - s3.y;
49            const m1 = { x: (s1.x + s2.x) / 2.0, y: (s1.y + s2.y) / 2.0 };
50            const m2 = { x: (s2.x + s3.x) / 2.0, y: (s2.y + s3.y) / 2.0 };
51            const l1 = Math.sqrt(dx1 * dx1 + dy1 * dy1);
52            const l2 = Math.sqrt(dx2 * dx2 + dy2 * dy2);
53            const dxm = m1.x - m2.x;
54            const dym = m1.y - m2.y;
55            const k = l1 + l2 == 0 ? 0 : l2 / (l1 + l2);
56            const cm = { x: m2.x + dxm * k, y: m2.y + dym * k };
57            const tx = s2.x - cm.x;
58            const ty = s2.y - cm.y;
59            return {
60                c1: new Point(m1.x + tx, m1.y + ty),
61                c2: new Point(m2.x + tx, m2.y + ty),
62            };
63        }
64        constructor(startPoint, control2, control1, endPoint, startWidth, endWidth) {
65            this.startPoint = startPoint;
66            this.control2 = control2;
67            this.control1 = control1;
68            this.endPoint = endPoint;
69            this.startWidth = startWidth;
70            this.endWidth = endWidth;
71        }
72        length() {
73            const steps = 10;
74            let length = 0;
75            let px;
76            let py;
77            for (let i = 0; i <= steps; i += 1) {
78                const t = i / steps;
79                const cx = this.point(t, this.startPoint.x, this.control1.x, this.control2.x, this.endPoint.x);
80                const cy = this.point(t, this.startPoint.y, this.control1.y, this.control2.y, this.endPoint.y);
81                if (i > 0) {
82                    const xdiff = cx - px;
83                    const ydiff = cy - py;
84                    length += Math.sqrt(xdiff * xdiff + ydiff * ydiff);
85                }
86                px = cx;
87                py = cy;
88            }
89            return length;
90        }
91        point(t, start, c1, c2, end) {
92            return (start * (1.0 - t) * (1.0 - t) * (1.0 - t))
93                + (3.0 * c1 * (1.0 - t) * (1.0 - t) * t)
94                + (3.0 * c2 * (1.0 - t) * t * t)
95                + (end * t * t * t);
96        }
97    }
98
99    class SignatureEventTarget {
100        constructor() {
101            try {
102                this._et = new EventTarget();
103            }
104            catch (_a) {
105                this._et = document;
106            }
107        }
108        addEventListener(type, listener, options) {
109            this._et.addEventListener(type, listener, options);
110        }
111        dispatchEvent(event) {
112            return this._et.dispatchEvent(event);
113        }
114        removeEventListener(type, callback, options) {
115            this._et.removeEventListener(type, callback, options);
116        }
117    }
118
119    function throttle(fn, wait = 250) {
120        let previous = 0;
121        let timeout = null;
122        let result;
123        let storedContext;
124        let storedArgs;
125        const later = () => {
126            previous = Date.now();
127            timeout = null;
128            result = fn.apply(storedContext, storedArgs);
129            if (!timeout) {
130                storedContext = null;
131                storedArgs = [];
132            }
133        };
134        return function wrapper(...args) {
135            const now = Date.now();
136            const remaining = wait - (now - previous);
137            storedContext = this;
138            storedArgs = args;
139            if (remaining <= 0 || remaining > wait) {
140                if (timeout) {
141                    clearTimeout(timeout);
142                    timeout = null;
143                }
144                previous = now;
145                result = fn.apply(storedContext, storedArgs);
146                if (!timeout) {
147                    storedContext = null;
148                    storedArgs = [];
149                }
150            }
151            else if (!timeout) {
152                timeout = window.setTimeout(later, remaining);
153            }
154            return result;
155        };
156    }
157
158    class SignaturePad extends SignatureEventTarget {
159        constructor(canvas, options = {}) {
160            var _a, _b, _c;
161            super();
162            this.canvas = canvas;
163            this._drawingStroke = false;
164            this._isEmpty = true;
165            this._lastPoints = [];
166            this._data = [];
167            this._lastVelocity = 0;
168            this._lastWidth = 0;
169            this._handleMouseDown = (event) => {
170                if (!this._isLeftButtonPressed(event, true) || this._drawingStroke) {
171                    return;
172                }
173                this._strokeBegin(this._pointerEventToSignatureEvent(event));
174            };
175            this._handleMouseMove = (event) => {
176                if (!this._isLeftButtonPressed(event, true) || !this._drawingStroke) {
177                    this._strokeEnd(this._pointerEventToSignatureEvent(event), false);
178                    return;
179                }
180                this._strokeMoveUpdate(this._pointerEventToSignatureEvent(event));
181            };
182            this._handleMouseUp = (event) => {
183                if (this._isLeftButtonPressed(event)) {
184                    return;
185                }
186                this._strokeEnd(this._pointerEventToSignatureEvent(event));
187            };
188            this._handleTouchStart = (event) => {
189                if (event.targetTouches.length !== 1 || this._drawingStroke) {
190                    return;
191                }
192                if (event.cancelable) {
193                    event.preventDefault();
194                }
195                this._strokeBegin(this._touchEventToSignatureEvent(event));
196            };
197            this._handleTouchMove = (event) => {
198                if (event.targetTouches.length !== 1) {
199                    return;
200                }
201                if (event.cancelable) {
202                    event.preventDefault();
203                }
204                if (!this._drawingStroke) {
205                    this._strokeEnd(this._touchEventToSignatureEvent(event), false);
206                    return;
207                }
208                this._strokeMoveUpdate(this._touchEventToSignatureEvent(event));
209            };
210            this._handleTouchEnd = (event) => {
211                if (event.targetTouches.length !== 0) {
212                    return;
213                }
214                if (event.cancelable) {
215                    event.preventDefault();
216                }
217                this.canvas.removeEventListener('touchmove', this._handleTouchMove);
218                this._strokeEnd(this._touchEventToSignatureEvent(event));
219            };
220            this._handlePointerDown = (event) => {
221                if (!event.isPrimary || !this._isLeftButtonPressed(event) || this._drawingStroke) {
222                    return;
223                }
224                event.preventDefault();
225                this._strokeBegin(this._pointerEventToSignatureEvent(event));
226            };
227            this._handlePointerMove = (event) => {
228                if (!event.isPrimary) {
229                    return;
230                }
231                if (!this._isLeftButtonPressed(event, true) || !this._drawingStroke) {
232                    this._strokeEnd(this._pointerEventToSignatureEvent(event), false);
233                    return;
234                }
235                event.preventDefault();
236                this._strokeMoveUpdate(this._pointerEventToSignatureEvent(event));
237            };
238            this._handlePointerUp = (event) => {
239                if (!event.isPrimary || this._isLeftButtonPressed(event)) {
240                    return;
241                }
242                event.preventDefault();
243                this._strokeEnd(this._pointerEventToSignatureEvent(event));
244            };
245            this.velocityFilterWeight = options.velocityFilterWeight || 0.7;
246            this.minWidth = options.minWidth || 0.5;
247            this.maxWidth = options.maxWidth || 2.5;
248            this.throttle = (_a = options.throttle) !== null && _a !== void 0 ? _a : 16;
249            this.minDistance = (_b = options.minDistance) !== null && _b !== void 0 ? _b : 5;
250            this.dotSize = options.dotSize || 0;
251            this.penColor = options.penColor || 'black';
252            this.backgroundColor = options.backgroundColor || 'rgba(0,0,0,0)';
253            this.compositeOperation = options.compositeOperation || 'source-over';
254            this.canvasContextOptions = (_c = options.canvasContextOptions) !== null && _c !== void 0 ? _c : {};
255            this._strokeMoveUpdate = this.throttle
256                ? throttle(SignaturePad.prototype._strokeUpdate, this.throttle)
257                : SignaturePad.prototype._strokeUpdate;
258            this._ctx = canvas.getContext('2d', this.canvasContextOptions);
259            this.clear();
260            this.on();
261        }
262        clear() {
263            const { _ctx: ctx, canvas } = this;
264            ctx.fillStyle = this.backgroundColor;
265            ctx.clearRect(0, 0, canvas.width, canvas.height);
266            ctx.fillRect(0, 0, canvas.width, canvas.height);
267            this._data = [];
268            this._reset(this._getPointGroupOptions());
269            this._isEmpty = true;
270        }
271        fromDataURL(dataUrl, options = {}) {
272            return new Promise((resolve, reject) => {
273                const image = new Image();
274                const ratio = options.ratio || window.devicePixelRatio || 1;
275                const width = options.width || this.canvas.width / ratio;
276                const height = options.height || this.canvas.height / ratio;
277                const xOffset = options.xOffset || 0;
278                const yOffset = options.yOffset || 0;
279                this._reset(this._getPointGroupOptions());
280                image.onload = () => {
281                    this._ctx.drawImage(image, xOffset, yOffset, width, height);
282                    resolve();
283                };
284                image.onerror = (error) => {
285                    reject(error);
286                };
287                image.crossOrigin = 'anonymous';
288                image.src = dataUrl;
289                this._isEmpty = false;
290            });
291        }
292        toDataURL(type = 'image/png', encoderOptions) {
293            switch (type) {
294                case 'image/svg+xml':
295                    if (typeof encoderOptions !== 'object') {
296                        encoderOptions = undefined;
297                    }
298                    return `data:image/svg+xml;base64,${btoa(this.toSVG(encoderOptions))}`;
299                default:
300                    if (typeof encoderOptions !== 'number') {
301                        encoderOptions = undefined;
302                    }
303                    return this.canvas.toDataURL(type, encoderOptions);
304            }
305        }
306        on() {
307            this.canvas.style.touchAction = 'none';
308            this.canvas.style.msTouchAction = 'none';
309            this.canvas.style.userSelect = 'none';
310            const isIOS = /Macintosh/.test(navigator.userAgent) && 'ontouchstart' in document;
311            if (window.PointerEvent && !isIOS) {
312                this._handlePointerEvents();
313            }
314            else {
315                this._handleMouseEvents();
316                if ('ontouchstart' in window) {
317                    this._handleTouchEvents();
318                }
319            }
320        }
321        off() {
322            this.canvas.style.touchAction = 'auto';
323            this.canvas.style.msTouchAction = 'auto';
324            this.canvas.style.userSelect = 'auto';
325            this.canvas.removeEventListener('pointerdown', this._handlePointerDown);
326            this.canvas.removeEventListener('mousedown', this._handleMouseDown);
327            this.canvas.removeEventListener('touchstart', this._handleTouchStart);
328            this._removeMoveUpEventListeners();
329        }
330        _getListenerFunctions() {
331            var _a;
332            const canvasWindow = window.document === this.canvas.ownerDocument
333                ? window
334                : (_a = this.canvas.ownerDocument.defaultView) !== null && _a !== void 0 ? _a : this.canvas.ownerDocument;
335            return {
336                addEventListener: canvasWindow.addEventListener.bind(canvasWindow),
337                removeEventListener: canvasWindow.removeEventListener.bind(canvasWindow),
338            };
339        }
340        _removeMoveUpEventListeners() {
341            const { removeEventListener } = this._getListenerFunctions();
342            removeEventListener('pointermove', this._handlePointerMove);
343            removeEventListener('pointerup', this._handlePointerUp);
344            removeEventListener('mousemove', this._handleMouseMove);
345            removeEventListener('mouseup', this._handleMouseUp);
346            removeEventListener('touchmove', this._handleTouchMove);
347            removeEventListener('touchend', this._handleTouchEnd);
348        }
349        isEmpty() {
350            return this._isEmpty;
351        }
352        fromData(pointGroups, { clear = true } = {}) {
353            if (clear) {
354                this.clear();
355            }
356            this._fromData(pointGroups, this._drawCurve.bind(this), this._drawDot.bind(this));
357            this._data = this._data.concat(pointGroups);
358        }
359        toData() {
360            return this._data;
361        }
362        _isLeftButtonPressed(event, only) {
363            if (only) {
364                return event.buttons === 1;
365            }
366            return (event.buttons & 1) === 1;
367        }
368        _pointerEventToSignatureEvent(event) {
369            return {
370                event: event,
371                type: event.type,
372                x: event.clientX,
373                y: event.clientY,
374                pressure: 'pressure' in event ? event.pressure : 0,
375            };
376        }
377        _touchEventToSignatureEvent(event) {
378            const touch = event.changedTouches[0];
379            return {
380                event: event,
381                type: event.type,
382                x: touch.clientX,
383                y: touch.clientY,
384                pressure: touch.force,
385            };
386        }
387        _getPointGroupOptions(group) {
388            return {
389                penColor: group && 'penColor' in group ? group.penColor : this.penColor,
390                dotSize: group && 'dotSize' in group ? group.dotSize : this.dotSize,
391                minWidth: group && 'minWidth' in group ? group.minWidth : this.minWidth,
392                maxWidth: group && 'maxWidth' in group ? group.maxWidth : this.maxWidth,
393                velocityFilterWeight: group && 'velocityFilterWeight' in group
394                    ? group.velocityFilterWeight
395                    : this.velocityFilterWeight,
396                compositeOperation: group && 'compositeOperation' in group
397                    ? group.compositeOperation
398                    : this.compositeOperation,
399            };
400        }
401        _strokeBegin(event) {
402            const cancelled = !this.dispatchEvent(new CustomEvent('beginStroke', { detail: event, cancelable: true }));
403            if (cancelled) {
404                return;
405            }
406            const { addEventListener } = this._getListenerFunctions();
407            switch (event.event.type) {
408                case 'mousedown':
409                    addEventListener('mousemove', this._handleMouseMove);
410                    addEventListener('mouseup', this._handleMouseUp);
411                    break;
412                case 'touchstart':
413                    addEventListener('touchmove', this._handleTouchMove);
414                    addEventListener('touchend', this._handleTouchEnd);
415                    break;
416                case 'pointerdown':
417                    addEventListener('pointermove', this._handlePointerMove);
418                    addEventListener('pointerup', this._handlePointerUp);
419                    break;
420            }
421            this._drawingStroke = true;
422            const pointGroupOptions = this._getPointGroupOptions();
423            const newPointGroup = Object.assign(Object.assign({}, pointGroupOptions), { points: [] });
424            this._data.push(newPointGroup);
425            this._reset(pointGroupOptions);
426            this._strokeUpdate(event);
427        }
428        _strokeUpdate(event) {
429            if (!this._drawingStroke) {
430                return;
431            }
432            if (this._data.length === 0) {
433                this._strokeBegin(event);
434                return;
435            }
436            this.dispatchEvent(new CustomEvent('beforeUpdateStroke', { detail: event }));
437            const point = this._createPoint(event.x, event.y, event.pressure);
438            const lastPointGroup = this._data[this._data.length - 1];
439            const lastPoints = lastPointGroup.points;
440            const lastPoint = lastPoints.length > 0 && lastPoints[lastPoints.length - 1];
441            const isLastPointTooClose = lastPoint
442                ? point.distanceTo(lastPoint) <= this.minDistance
443                : false;
vendor: 9,004 bytes, lines 444-644
444            const pointGroupOptions = this._getPointGroupOptions(lastPointGroup);
445            if (!lastPoint || !(lastPoint && isLastPointTooClose)) {
446                const curve = this._addPoint(point, pointGroupOptions);
447                if (!lastPoint) {
448                    this._drawDot(point, pointGroupOptions);
449                }
450                else if (curve) {
451                    this._drawCurve(curve, pointGroupOptions);
452                }
453                lastPoints.push({
454                    time: point.time,
455                    x: point.x,
456                    y: point.y,
457                    pressure: point.pressure,
458                });
459            }
460            this.dispatchEvent(new CustomEvent('afterUpdateStroke', { detail: event }));
461        }
462        _strokeEnd(event, shouldUpdate = true) {
463            this._removeMoveUpEventListeners();
464            if (!this._drawingStroke) {
465                return;
466            }
467            if (shouldUpdate) {
468                this._strokeUpdate(event);
469            }
470            this._drawingStroke = false;
471            this.dispatchEvent(new CustomEvent('endStroke', { detail: event }));
472        }
473        _handlePointerEvents() {
474            this._drawingStroke = false;
475            this.canvas.addEventListener('pointerdown', this._handlePointerDown);
476        }
477        _handleMouseEvents() {
478            this._drawingStroke = false;
479            this.canvas.addEventListener('mousedown', this._handleMouseDown);
480        }
481        _handleTouchEvents() {
482            this.canvas.addEventListener('touchstart', this._handleTouchStart);
483        }
484        _reset(options) {
485            this._lastPoints = [];
486            this._lastVelocity = 0;
487            this._lastWidth = (options.minWidth + options.maxWidth) / 2;
488            this._ctx.fillStyle = options.penColor;
489            this._ctx.globalCompositeOperation = options.compositeOperation;
490        }
491        _createPoint(x, y, pressure) {
492            const rect = this.canvas.getBoundingClientRect();
493            return new Point(x - rect.left, y - rect.top, pressure, new Date().getTime());
494        }
495        _addPoint(point, options) {
496            const { _lastPoints } = this;
497            _lastPoints.push(point);
498            if (_lastPoints.length > 2) {
499                if (_lastPoints.length === 3) {
500                    _lastPoints.unshift(_lastPoints[0]);
501                }
502                const widths = this._calculateCurveWidths(_lastPoints[1], _lastPoints[2], options);
503                const curve = Bezier.fromPoints(_lastPoints, widths);
504                _lastPoints.shift();
505                return curve;
506            }
507            return null;
508        }
509        _calculateCurveWidths(startPoint, endPoint, options) {
510            const velocity = options.velocityFilterWeight * endPoint.velocityFrom(startPoint) +
511                (1 - options.velocityFilterWeight) * this._lastVelocity;
512            const newWidth = this._strokeWidth(velocity, options);
513            const widths = {
514                end: newWidth,
515                start: this._lastWidth,
516            };
517            this._lastVelocity = velocity;
518            this._lastWidth = newWidth;
519            return widths;
520        }
521        _strokeWidth(velocity, options) {
522            return Math.max(options.maxWidth / (velocity + 1), options.minWidth);
523        }
524        _drawCurveSegment(x, y, width) {
525            const ctx = this._ctx;
526            ctx.moveTo(x, y);
527            ctx.arc(x, y, width, 0, 2 * Math.PI, false);
528            this._isEmpty = false;
529        }
530        _drawCurve(curve, options) {
531            const ctx = this._ctx;
532            const widthDelta = curve.endWidth - curve.startWidth;
533            const drawSteps = Math.ceil(curve.length()) * 2;
534            ctx.beginPath();
535            ctx.fillStyle = options.penColor;
536            for (let i = 0; i < drawSteps; i += 1) {
537                const t = i / drawSteps;
538                const tt = t * t;
539                const ttt = tt * t;
540                const u = 1 - t;
541                const uu = u * u;
542                const uuu = uu * u;
543                let x = uuu * curve.startPoint.x;
544                x += 3 * uu * t * curve.control1.x;
545                x += 3 * u * tt * curve.control2.x;
546                x += ttt * curve.endPoint.x;
547                let y = uuu * curve.startPoint.y;
548                y += 3 * uu * t * curve.control1.y;
549                y += 3 * u * tt * curve.control2.y;
550                y += ttt * curve.endPoint.y;
551                const width = Math.min(curve.startWidth + ttt * widthDelta, options.maxWidth);
552                this._drawCurveSegment(x, y, width);
553            }
554            ctx.closePath();
555            ctx.fill();
556        }
557        _drawDot(point, options) {
558            const ctx = this._ctx;
559            const width = options.dotSize > 0
560                ? options.dotSize
561                : (options.minWidth + options.maxWidth) / 2;
562            ctx.beginPath();
563            this._drawCurveSegment(point.x, point.y, width);
564            ctx.closePath();
565            ctx.fillStyle = options.penColor;
566            ctx.fill();
567        }
568        _fromData(pointGroups, drawCurve, drawDot) {
569            for (const group of pointGroups) {
570                const { points } = group;
571                const pointGroupOptions = this._getPointGroupOptions(group);
572                if (points.length > 1) {
573                    for (let j = 0; j < points.length; j += 1) {
574                        const basicPoint = points[j];
575                        const point = new Point(basicPoint.x, basicPoint.y, basicPoint.pressure, basicPoint.time);
576                        if (j === 0) {
577                            this._reset(pointGroupOptions);
578                        }
579                        const curve = this._addPoint(point, pointGroupOptions);
580                        if (curve) {
581                            drawCurve(curve, pointGroupOptions);
582                        }
583                    }
584                }
585                else {
586                    this._reset(pointGroupOptions);
587                    drawDot(points[0], pointGroupOptions);
588                }
589            }
590        }
591        toSVG({ includeBackgroundColor = false } = {}) {
592            const pointGroups = this._data;
593            const ratio = Math.max(window.devicePixelRatio || 1, 1);
594            const minX = 0;
595            const minY = 0;
596            const maxX = this.canvas.width / ratio;
597            const maxY = this.canvas.height / ratio;
598            const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
599            svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
600            svg.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
601            svg.setAttribute('viewBox', `${minX} ${minY} ${maxX} ${maxY}`);
602            svg.setAttribute('width', maxX.toString());
603            svg.setAttribute('height', maxY.toString());
604            if (includeBackgroundColor && this.backgroundColor) {
605                const rect = document.createElement('rect');
606                rect.setAttribute('width', '100%');
607                rect.setAttribute('height', '100%');
608                rect.setAttribute('fill', this.backgroundColor);
609                svg.appendChild(rect);
610            }
611            this._fromData(pointGroups, (curve, { penColor }) => {
612                const path = document.createElement('path');
613                if (!isNaN(curve.control1.x) &&
614                    !isNaN(curve.control1.y) &&
615                    !isNaN(curve.control2.x) &&
616                    !isNaN(curve.control2.y)) {
617                    const attr = `M ${curve.startPoint.x.toFixed(3)},${curve.startPoint.y.toFixed(3)} ` +
618                        `C ${curve.control1.x.toFixed(3)},${curve.control1.y.toFixed(3)} ` +
619                        `${curve.control2.x.toFixed(3)},${curve.control2.y.toFixed(3)} ` +
620                        `${curve.endPoint.x.toFixed(3)},${curve.endPoint.y.toFixed(3)}`;
621                    path.setAttribute('d', attr);
622                    path.setAttribute('stroke-width', (curve.endWidth * 2.25).toFixed(3));
623                    path.setAttribute('stroke', penColor);
624                    path.setAttribute('fill', 'none');
625                    path.setAttribute('stroke-linecap', 'round');
626                    svg.appendChild(path);
627                }
628            }, (point, { penColor, dotSize, minWidth, maxWidth }) => {
629                const circle = document.createElement('circle');
630                const size = dotSize > 0 ? dotSize : (minWidth + maxWidth) / 2;
631                circle.setAttribute('r', size.toString());
632                circle.setAttribute('cx', point.x.toString());
633                circle.setAttribute('cy', point.y.toString());
634                circle.setAttribute('fill', penColor);
635                svg.appendChild(circle);
636            });
637            return svg.outerHTML;
638        }
639    }
640
641    return SignaturePad;
642
643}));
644//# sourceMappingURL=signature_pad.umd.js.map

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.