@jsenv/terminal-recorder 1.5.44 → 1.5.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/jsenv_terminal_recorder_node_modules.js +14 -22
- package/dist/terminal_recorder_browser.js +135 -52
- package/package.json +6 -6
- package/src/.jsenv/chrome@145.0.0/@fs/Users/dmail/Documents/dev/jsenv/core/node_modules/@xterm/addon-fit/lib/addon-fit.mjs +18 -0
- package/src/.jsenv/chrome@145.0.0/@fs/Users/dmail/Documents/dev/jsenv/core/node_modules/@xterm/addon-fit/lib/addon-fit.mjs.map +28 -0
- package/src/.jsenv/chrome@145.0.0/@fs/Users/dmail/Documents/dev/jsenv/core/node_modules/@xterm/addon-serialize/lib/addon-serialize.mjs +19 -0
- package/src/.jsenv/chrome@145.0.0/@fs/Users/dmail/Documents/dev/jsenv/core/node_modules/@xterm/addon-serialize/lib/addon-serialize.mjs.map +176 -0
- package/src/.jsenv/chrome@145.0.0/@fs/Users/dmail/Documents/dev/jsenv/core/node_modules/@xterm/addon-webgl/lib/addon-webgl.mjs +101 -0
- package/src/.jsenv/chrome@145.0.0/@fs/Users/dmail/Documents/dev/jsenv/core/node_modules/@xterm/addon-webgl/lib/addon-webgl.mjs.map +1623 -0
- package/src/.jsenv/chrome@145.0.0/@fs/Users/dmail/Documents/dev/jsenv/core/node_modules/@xterm/xterm/css/xterm.css +267 -0
- package/src/.jsenv/chrome@145.0.0/@fs/Users/dmail/Documents/dev/jsenv/core/node_modules/@xterm/xterm/lib/xterm.mjs +53 -0
- package/src/.jsenv/chrome@145.0.0/@fs/Users/dmail/Documents/dev/jsenv/core/node_modules/@xterm/xterm/lib/xterm.mjs.map +3592 -0
- package/src/.jsenv/chrome@145.0.0/@fs/Users/dmail/Documents/dev/jsenv/core/packages/backend/server/src/plugins/autoreload_on_server_restart/client/autoreload_on_server_restart.js +133 -0
- package/src/.jsenv/chrome@145.0.0/@fs/Users/dmail/Documents/dev/jsenv/core/packages/frontend/custom-elements-redefine/src/main.js +217 -0
- package/src/.jsenv/chrome@145.0.0/@fs/Users/dmail/Documents/dev/jsenv/core/packages/internal/plugin-supervisor/src/client/supervisor.js +1418 -0
- package/src/.jsenv/chrome@145.0.0/@fs/Users/dmail/Documents/dev/jsenv/core/src/plugins/drop_to_open/client/drop_to_open.js +49 -0
- package/src/.jsenv/chrome@145.0.0/gif_encoder.js +400 -0
- package/src/.jsenv/chrome@145.0.0/gif_encoder.js.map +11 -0
- package/src/.jsenv/chrome@145.0.0/lzw_encoder.js +253 -0
- package/src/.jsenv/chrome@145.0.0/neuquant.js +498 -0
- package/src/.jsenv/chrome@145.0.0/terminal_recorder.js +384 -0
- package/src/.jsenv/chrome@145.0.0/terminal_recorder.js.map +11 -0
- package/src/.jsenv/chrome@145.0.0/xterm.html +64 -0
- package/src/.jsenv/chrome@145.0.0/xterm.html@L14C5-L18C14.js +5 -0
- package/src/.jsenv/chrome@145.0.0/xterm.html@L19C5-L24C14.js +7 -0
- package/src/.jsenv/chrome@145.0.0/xterm.html@L19C5-L24C14.js.map +11 -0
|
@@ -31,19 +31,18 @@ function stripAnsi(string) {
|
|
|
31
31
|
return string.replace(regex, '');
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
const r = String.raw,
|
|
35
|
-
e = r`\p{Emoji}(?:\p{EMod}|[\u{E0020}-\u{E007E}]+\u{E007F}|\uFE0F?\u20E3?)`;
|
|
36
|
-
const emojiRegex = () => new RegExp(r`\p{RI}{2}|(?)${e}(?:\u200D${e})*`, 'gu');
|
|
37
|
-
|
|
38
34
|
// Generated by scripts/build.js
|
|
39
35
|
|
|
40
|
-
|
|
36
|
+
const ambiguousMinimalCodePoint = 161;
|
|
37
|
+
const ambiguousMaximumCodePoint = 1114109;
|
|
41
38
|
const ambiguousRanges = [161, 161, 164, 164, 167, 168, 170, 170, 173, 174, 176, 180, 182, 186, 188, 191, 198, 198, 208, 208, 215, 216, 222, 225, 230, 230, 232, 234, 236, 237, 240, 240, 242, 243, 247, 250, 252, 252, 254, 254, 257, 257, 273, 273, 275, 275, 283, 283, 294, 295, 299, 299, 305, 307, 312, 312, 319, 322, 324, 324, 328, 331, 333, 333, 338, 339, 358, 359, 363, 363, 462, 462, 464, 464, 466, 466, 468, 468, 470, 470, 472, 472, 474, 474, 476, 476, 593, 593, 609, 609, 708, 708, 711, 711, 713, 715, 717, 717, 720, 720, 728, 731, 733, 733, 735, 735, 768, 879, 913, 929, 931, 937, 945, 961, 963, 969, 1025, 1025, 1040, 1103, 1105, 1105, 8208, 8208, 8211, 8214, 8216, 8217, 8220, 8221, 8224, 8226, 8228, 8231, 8240, 8240, 8242, 8243, 8245, 8245, 8251, 8251, 8254, 8254, 8308, 8308, 8319, 8319, 8321, 8324, 8364, 8364, 8451, 8451, 8453, 8453, 8457, 8457, 8467, 8467, 8470, 8470, 8481, 8482, 8486, 8486, 8491, 8491, 8531, 8532, 8539, 8542, 8544, 8555, 8560, 8569, 8585, 8585, 8592, 8601, 8632, 8633, 8658, 8658, 8660, 8660, 8679, 8679, 8704, 8704, 8706, 8707, 8711, 8712, 8715, 8715, 8719, 8719, 8721, 8721, 8725, 8725, 8730, 8730, 8733, 8736, 8739, 8739, 8741, 8741, 8743, 8748, 8750, 8750, 8756, 8759, 8764, 8765, 8776, 8776, 8780, 8780, 8786, 8786, 8800, 8801, 8804, 8807, 8810, 8811, 8814, 8815, 8834, 8835, 8838, 8839, 8853, 8853, 8857, 8857, 8869, 8869, 8895, 8895, 8978, 8978, 9312, 9449, 9451, 9547, 9552, 9587, 9600, 9615, 9618, 9621, 9632, 9633, 9635, 9641, 9650, 9651, 9654, 9655, 9660, 9661, 9664, 9665, 9670, 9672, 9675, 9675, 9678, 9681, 9698, 9701, 9711, 9711, 9733, 9734, 9737, 9737, 9742, 9743, 9756, 9756, 9758, 9758, 9792, 9792, 9794, 9794, 9824, 9825, 9827, 9829, 9831, 9834, 9836, 9837, 9839, 9839, 9886, 9887, 9919, 9919, 9926, 9933, 9935, 9939, 9941, 9953, 9955, 9955, 9960, 9961, 9963, 9969, 9972, 9972, 9974, 9977, 9979, 9980, 9982, 9983, 10045, 10045, 10102, 10111, 11094, 11097, 12872, 12879, 57344, 63743, 65024, 65039, 65533, 65533, 127232, 127242, 127248, 127277, 127280, 127337, 127344, 127373, 127375, 127376, 127387, 127404, 917760, 917999, 983040, 1048573, 1048576, 1114109];
|
|
42
39
|
|
|
43
|
-
|
|
40
|
+
const fullwidthMinimalCodePoint = 12288;
|
|
41
|
+
const fullwidthMaximumCodePoint = 65510;
|
|
44
42
|
const fullwidthRanges = [12288, 12288, 65281, 65376, 65504, 65510];
|
|
45
43
|
|
|
46
|
-
|
|
44
|
+
const wideMinimalCodePoint = 4352;
|
|
45
|
+
const wideMaximumCodePoint = 262141;
|
|
47
46
|
const wideRanges = [4352, 4447, 8986, 8987, 9001, 9002, 9193, 9196, 9200, 9200, 9203, 9203, 9725, 9726, 9748, 9749, 9776, 9783, 9800, 9811, 9855, 9855, 9866, 9871, 9875, 9875, 9889, 9889, 9898, 9899, 9917, 9918, 9924, 9925, 9934, 9934, 9940, 9940, 9962, 9962, 9970, 9971, 9973, 9973, 9978, 9978, 9981, 9981, 9989, 9989, 9994, 9995, 10024, 10024, 10060, 10060, 10062, 10062, 10067, 10069, 10071, 10071, 10133, 10135, 10160, 10160, 10175, 10175, 11035, 11036, 11088, 11088, 11093, 11093, 11904, 11929, 11931, 12019, 12032, 12245, 12272, 12287, 12289, 12350, 12353, 12438, 12441, 12543, 12549, 12591, 12593, 12686, 12688, 12773, 12783, 12830, 12832, 12871, 12880, 42124, 42128, 42182, 43360, 43388, 44032, 55203, 63744, 64255, 65040, 65049, 65072, 65106, 65108, 65126, 65128, 65131, 94176, 94180, 94192, 94198, 94208, 101589, 101631, 101662, 101760, 101874, 110576, 110579, 110581, 110587, 110589, 110590, 110592, 110882, 110898, 110898, 110928, 110930, 110933, 110933, 110948, 110951, 110960, 111355, 119552, 119638, 119648, 119670, 126980, 126980, 127183, 127183, 127374, 127374, 127377, 127386, 127488, 127490, 127504, 127547, 127552, 127560, 127568, 127569, 127584, 127589, 127744, 127776, 127789, 127797, 127799, 127868, 127870, 127891, 127904, 127946, 127951, 127955, 127968, 127984, 127988, 127988, 127992, 128062, 128064, 128064, 128066, 128252, 128255, 128317, 128331, 128334, 128336, 128359, 128378, 128378, 128405, 128406, 128420, 128420, 128507, 128591, 128640, 128709, 128716, 128716, 128720, 128722, 128725, 128728, 128732, 128735, 128747, 128748, 128756, 128764, 128992, 129003, 129008, 129008, 129292, 129338, 129340, 129349, 129351, 129535, 129648, 129660, 129664, 129674, 129678, 129734, 129736, 129736, 129741, 129756, 129759, 129770, 129775, 129784, 131072, 196605, 196608, 262141];
|
|
48
47
|
|
|
49
48
|
/**
|
|
@@ -71,15 +70,8 @@ const isInRange = (ranges, codePoint) => {
|
|
|
71
70
|
return false;
|
|
72
71
|
};
|
|
73
72
|
|
|
74
|
-
const minimumAmbiguousCodePoint = ambiguousRanges[0];
|
|
75
|
-
const maximumAmbiguousCodePoint = ambiguousRanges.at(-1);
|
|
76
|
-
const minimumFullWidthCodePoint = fullwidthRanges[0];
|
|
77
|
-
const maximumFullWidthCodePoint = fullwidthRanges.at(-1);
|
|
78
|
-
const minimumWideCodePoint = wideRanges[0];
|
|
79
|
-
const maximumWideCodePoint = wideRanges.at(-1);
|
|
80
|
-
|
|
81
73
|
const commonCjkCodePoint = 0x4E_00;
|
|
82
|
-
const [wideFastPathStart, wideFastPathEnd] = findWideFastPathRange(wideRanges);
|
|
74
|
+
const [wideFastPathStart, wideFastPathEnd] = /* #__PURE__ */ findWideFastPathRange(wideRanges);
|
|
83
75
|
|
|
84
76
|
// Use a hot-path range so common `isWide` calls can skip binary search.
|
|
85
77
|
// The range containing U+4E00 covers common CJK ideographs;
|
|
@@ -110,8 +102,8 @@ function findWideFastPathRange(ranges) {
|
|
|
110
102
|
|
|
111
103
|
const isAmbiguous = codePoint => {
|
|
112
104
|
if (
|
|
113
|
-
codePoint <
|
|
114
|
-
|| codePoint >
|
|
105
|
+
codePoint < ambiguousMinimalCodePoint
|
|
106
|
+
|| codePoint > ambiguousMaximumCodePoint
|
|
115
107
|
) {
|
|
116
108
|
return false;
|
|
117
109
|
}
|
|
@@ -121,8 +113,8 @@ const isAmbiguous = codePoint => {
|
|
|
121
113
|
|
|
122
114
|
const isFullWidth = codePoint => {
|
|
123
115
|
if (
|
|
124
|
-
codePoint <
|
|
125
|
-
|| codePoint >
|
|
116
|
+
codePoint < fullwidthMinimalCodePoint
|
|
117
|
+
|| codePoint > fullwidthMaximumCodePoint
|
|
126
118
|
) {
|
|
127
119
|
return false;
|
|
128
120
|
}
|
|
@@ -139,8 +131,8 @@ const isWide = codePoint => {
|
|
|
139
131
|
}
|
|
140
132
|
|
|
141
133
|
if (
|
|
142
|
-
codePoint <
|
|
143
|
-
|| codePoint >
|
|
134
|
+
codePoint < wideMinimalCodePoint
|
|
135
|
+
|| codePoint > wideMaximumCodePoint
|
|
144
136
|
) {
|
|
145
137
|
return false;
|
|
146
138
|
}
|
|
@@ -528,4 +520,4 @@ function requireHe () {
|
|
|
528
520
|
var heExports = requireHe();
|
|
529
521
|
var __jsenv_default_import__ = /*@__PURE__*/getDefaultExportFromCjs(heExports);
|
|
530
522
|
|
|
531
|
-
export { __jsenv_default_import__, ansiRegex, eastAsianWidth,
|
|
523
|
+
export { __jsenv_default_import__, ansiRegex, eastAsianWidth, stripAnsi };
|
|
@@ -1,22 +1,121 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { eastAsianWidth, stripAnsi, ansiRegex, __jsenv_default_import__ } from "./jsenv_terminal_recorder_node_modules.js";
|
|
2
|
+
|
|
3
|
+
// Whole-cluster zero-width: Default_Ignorable, Control, Format, Mark, Surrogate
|
|
4
|
+
const zeroWidthClusterRegex =
|
|
5
|
+
/^[\p{Default_Ignorable_Code_Point}\p{Control}\p{Format}\p{Mark}\p{Surrogate}]+$/v;
|
|
6
|
+
|
|
7
|
+
// Strip leading non-printing chars to get the first visible scalar of a cluster
|
|
8
|
+
const leadingNonPrintingRegex =
|
|
9
|
+
/^[\p{Default_Ignorable_Code_Point}\p{Control}\p{Format}\p{Mark}\p{Surrogate}]+/v;
|
|
10
|
+
|
|
11
|
+
// RGI emoji sequences (e.g. flag sequences, ZWJ families, keycap+VS16)
|
|
12
|
+
const rgiEmojiRegex = /^\p{RGI_Emoji}$/v;
|
|
13
|
+
|
|
14
|
+
// Unqualified keycap: digit/# /* + combining enclosing keycap (no VS16)
|
|
15
|
+
const unqualifiedKeycapRegex = /^[\d#*]\u20E3$/;
|
|
16
|
+
const extendedPictographicRegex = /\p{Extended_Pictographic}/gv;
|
|
17
|
+
|
|
18
|
+
const isDoubleWidthNonRgiEmojiSequence = (segment) => {
|
|
19
|
+
if (segment.length > 50) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
if (unqualifiedKeycapRegex.test(segment)) {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
// ZWJ sequences with 2+ Extended_Pictographic
|
|
26
|
+
if (segment.includes("\u200D")) {
|
|
27
|
+
const pictographics = segment.match(extendedPictographicRegex);
|
|
28
|
+
return pictographics !== null && pictographics.length >= 2;
|
|
29
|
+
}
|
|
30
|
+
return false;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const baseVisible = (segment) => {
|
|
34
|
+
return segment.replace(leadingNonPrintingRegex, "");
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const isHangulLeadingJamo = (cp) => {
|
|
38
|
+
return (cp >= 0x11_00 && cp <= 0x11_5f) || (cp >= 0xa9_60 && cp <= 0xa9_7c);
|
|
39
|
+
};
|
|
40
|
+
const isHangulVowelJamo = (cp) => {
|
|
41
|
+
return (cp >= 0x11_60 && cp <= 0x11_a7) || (cp >= 0xd7_b0 && cp <= 0xd7_c6);
|
|
42
|
+
};
|
|
43
|
+
const isHangulTrailingJamo = (cp) => {
|
|
44
|
+
return (cp >= 0x11_a8 && cp <= 0x11_ff) || (cp >= 0xd7_cb && cp <= 0xd7_fb);
|
|
45
|
+
};
|
|
46
|
+
const isHangulJamo = (cp) => {
|
|
47
|
+
return (
|
|
48
|
+
isHangulLeadingJamo(cp) || isHangulVowelJamo(cp) || isHangulTrailingJamo(cp)
|
|
49
|
+
);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const hangulClusterWidth = (visibleSegment, eastAsianWidthOptions) => {
|
|
53
|
+
const codePoints = [];
|
|
54
|
+
for (const character of visibleSegment) {
|
|
55
|
+
if (zeroWidthClusterRegex.test(character)) {
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
codePoints.push(character.codePointAt(0));
|
|
59
|
+
}
|
|
60
|
+
if (codePoints.length === 0) {
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
let width = 0;
|
|
64
|
+
for (let index = 0; index < codePoints.length; index++) {
|
|
65
|
+
const codePoint = codePoints[index];
|
|
66
|
+
if (!isHangulJamo(codePoint)) {
|
|
67
|
+
if (width === 0) {
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
for (let remaining = index; remaining < codePoints.length; remaining++) {
|
|
71
|
+
width += eastAsianWidth(codePoints[remaining], eastAsianWidthOptions);
|
|
72
|
+
}
|
|
73
|
+
return width;
|
|
74
|
+
}
|
|
75
|
+
if (
|
|
76
|
+
isHangulLeadingJamo(codePoint) &&
|
|
77
|
+
isHangulVowelJamo(codePoints[index + 1])
|
|
78
|
+
) {
|
|
79
|
+
width += 2;
|
|
80
|
+
index += isHangulTrailingJamo(codePoints[index + 2]) ? 2 : 1;
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
width += eastAsianWidth(codePoint, eastAsianWidthOptions);
|
|
84
|
+
}
|
|
85
|
+
return width;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const trailingHalfwidthWidth = (visibleSegment, eastAsianWidthOptions) => {
|
|
89
|
+
let extra = 0;
|
|
90
|
+
let first = true;
|
|
91
|
+
for (const character of visibleSegment) {
|
|
92
|
+
if (first) {
|
|
93
|
+
first = false;
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
if (character >= "\uFF00" && character <= "\uFFEF") {
|
|
97
|
+
extra += eastAsianWidth(character.codePointAt(0), eastAsianWidthOptions);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return extra;
|
|
101
|
+
};
|
|
2
102
|
|
|
3
103
|
const createMeasureTextWidth = ({ stripAnsi }) => {
|
|
4
104
|
const segmenter = new Intl.Segmenter();
|
|
5
|
-
const defaultIgnorableCodePointRegex = /^\p{Default_Ignorable_Code_Point}$/u;
|
|
6
105
|
|
|
7
106
|
const measureTextWidth = (
|
|
8
107
|
string,
|
|
9
|
-
{
|
|
10
|
-
ambiguousIsNarrow = true,
|
|
11
|
-
countAnsiEscapeCodes = false,
|
|
12
|
-
skipEmojis = false,
|
|
13
|
-
} = {},
|
|
108
|
+
{ ambiguousIsNarrow = true, countAnsiEscapeCodes = false } = {},
|
|
14
109
|
) => {
|
|
15
110
|
if (typeof string !== "string" || string.length === 0) {
|
|
16
111
|
return 0;
|
|
17
112
|
}
|
|
18
113
|
|
|
19
|
-
|
|
114
|
+
// Only strip ANSI when escape codes are actually present
|
|
115
|
+
if (
|
|
116
|
+
!countAnsiEscapeCodes &&
|
|
117
|
+
(string.includes("\u001B") || string.includes("\u009B"))
|
|
118
|
+
) {
|
|
20
119
|
string = stripAnsi(string);
|
|
21
120
|
}
|
|
22
121
|
|
|
@@ -24,70 +123,54 @@ const createMeasureTextWidth = ({ stripAnsi }) => {
|
|
|
24
123
|
return 0;
|
|
25
124
|
}
|
|
26
125
|
|
|
126
|
+
// Fast path: printable ASCII needs no segmenter or EAW lookup
|
|
127
|
+
if (/^[\u0020-\u007E]*$/.test(string)) {
|
|
128
|
+
return string.length;
|
|
129
|
+
}
|
|
130
|
+
|
|
27
131
|
let width = 0;
|
|
28
132
|
const eastAsianWidthOptions = { ambiguousAsWide: !ambiguousIsNarrow };
|
|
29
133
|
|
|
30
|
-
for (const { segment
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
// Ignore control characters
|
|
34
|
-
if (codePoint <= 0x1f || (codePoint >= 0x7f && codePoint <= 0x9f)) {
|
|
35
|
-
continue;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// Ignore zero-width characters
|
|
39
|
-
if (
|
|
40
|
-
(codePoint >= 0x20_0b && codePoint <= 0x20_0f) || // Zero-width space, non-joiner, joiner, left-to-right mark, right-to-left mark
|
|
41
|
-
codePoint === 0xfe_ff // Zero-width no-break space
|
|
42
|
-
) {
|
|
134
|
+
for (const { segment } of segmenter.segment(string)) {
|
|
135
|
+
if (zeroWidthClusterRegex.test(segment)) {
|
|
43
136
|
continue;
|
|
44
137
|
}
|
|
45
138
|
|
|
46
|
-
//
|
|
139
|
+
// RGI emoji + unqualified emoji sequences are double-width
|
|
47
140
|
if (
|
|
48
|
-
(
|
|
49
|
-
(
|
|
50
|
-
(codePoint >= 0x1d_c0 && codePoint <= 0x1d_ff) || // Combining diacritical marks supplement
|
|
51
|
-
(codePoint >= 0x20_d0 && codePoint <= 0x20_ff) || // Combining diacritical marks for symbols
|
|
52
|
-
(codePoint >= 0xfe_20 && codePoint <= 0xfe_2f) // Combining half marks
|
|
141
|
+
rgiEmojiRegex.test(segment) ||
|
|
142
|
+
isDoubleWidthNonRgiEmojiSequence(segment)
|
|
53
143
|
) {
|
|
144
|
+
if (process.env.CAPTURING_SIDE_EFFECTS && segment === "✔️") {
|
|
145
|
+
width += 2;
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
width += 2;
|
|
54
149
|
continue;
|
|
55
150
|
}
|
|
56
151
|
|
|
57
|
-
|
|
58
|
-
if (codePoint >= 0xd8_00 && codePoint <= 0xdf_ff) {
|
|
59
|
-
continue;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Ignore variation selectors
|
|
63
|
-
if (codePoint >= 0xfe_00 && codePoint <= 0xfe_0f) {
|
|
64
|
-
continue;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// This covers some of the above cases, but we still keep them for performance reasons.
|
|
68
|
-
if (defaultIgnorableCodePointRegex.test(character)) {
|
|
69
|
-
continue;
|
|
70
|
-
}
|
|
152
|
+
const visibleSegment = baseVisible(segment);
|
|
71
153
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
width += measureTextWidth(character, {
|
|
80
|
-
skipEmojis: true,
|
|
81
|
-
countAnsiEscapeCodes: true, // to skip call to stripAnsi
|
|
82
|
-
});
|
|
154
|
+
const hangulWidth = hangulClusterWidth(
|
|
155
|
+
visibleSegment,
|
|
156
|
+
eastAsianWidthOptions,
|
|
157
|
+
);
|
|
158
|
+
if (hangulWidth !== undefined) {
|
|
159
|
+
width += hangulWidth;
|
|
83
160
|
continue;
|
|
84
161
|
}
|
|
85
162
|
|
|
163
|
+
// EAW of the cluster's first visible scalar
|
|
164
|
+
const codePoint = visibleSegment.codePointAt(0);
|
|
86
165
|
width += eastAsianWidth(codePoint, eastAsianWidthOptions);
|
|
166
|
+
|
|
167
|
+
// Add width for trailing Halfwidth/Fullwidth Forms (e.g. ゙, ゚, ー)
|
|
168
|
+
width += trailingHalfwidthWidth(visibleSegment, eastAsianWidthOptions);
|
|
87
169
|
}
|
|
88
170
|
|
|
89
171
|
return width;
|
|
90
172
|
};
|
|
173
|
+
|
|
91
174
|
return measureTextWidth;
|
|
92
175
|
};
|
|
93
176
|
|
package/package.json
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsenv/terminal-recorder",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.46",
|
|
4
|
+
"type": "module",
|
|
4
5
|
"description": "Record terminal output as .svg, .gif, .webm, .mp4",
|
|
5
6
|
"repository": {
|
|
6
7
|
"type": "git",
|
|
7
8
|
"url": "https://github.com/jsenv/core",
|
|
8
9
|
"directory": "packages/tooling/terminal-recorder"
|
|
9
10
|
},
|
|
10
|
-
"license": "MIT",
|
|
11
11
|
"author": {
|
|
12
12
|
"name": "dmail",
|
|
13
13
|
"email": "dmaillard06@gmail.com"
|
|
14
14
|
},
|
|
15
|
-
"
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"main": "./dist/terminal_recorder_browser.js",
|
|
16
17
|
"exports": {
|
|
17
18
|
".": {
|
|
18
19
|
"node": "./src/main.js",
|
|
@@ -23,7 +24,6 @@
|
|
|
23
24
|
},
|
|
24
25
|
"./*": "./*"
|
|
25
26
|
},
|
|
26
|
-
"main": "./dist/terminal_recorder_browser.js",
|
|
27
27
|
"files": [
|
|
28
28
|
"/dist/",
|
|
29
29
|
"/src/"
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"@jsenv/humanize": "1.7.6",
|
|
38
|
-
"@jsenv/server": "17.
|
|
39
|
-
"@jsenv/terminal-text-size": "0.0.
|
|
38
|
+
"@jsenv/server": "17.3.0",
|
|
39
|
+
"@jsenv/terminal-text-size": "0.0.4",
|
|
40
40
|
"@playwright/browser-chromium": "1.58.1",
|
|
41
41
|
"ansi-regex": "6.2.2",
|
|
42
42
|
"eastasianwidth": "0.3.0",
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2014-2024 The xterm.js authors. All rights reserved.
|
|
3
|
+
* @license MIT
|
|
4
|
+
*
|
|
5
|
+
* Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)
|
|
6
|
+
* @license MIT
|
|
7
|
+
*
|
|
8
|
+
* Originally forked from (with the author's permission):
|
|
9
|
+
* Fabrice Bellard's javascript vt100 for jslinux:
|
|
10
|
+
* http://bellard.org/jslinux/
|
|
11
|
+
* Copyright (c) 2011 Fabrice Bellard
|
|
12
|
+
*/
|
|
13
|
+
/*---------------------------------------------------------------------------------------------
|
|
14
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
15
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
16
|
+
*--------------------------------------------------------------------------------------------*/
|
|
17
|
+
var h=2,_=1,o=class{activate(e){this._terminal=e}dispose(){}fit(){let e=this.proposeDimensions();if(!e||!this._terminal||isNaN(e.cols)||isNaN(e.rows))return;let t=this._terminal._core;(this._terminal.rows!==e.rows||this._terminal.cols!==e.cols)&&(t._renderService.clear(),this._terminal.resize(e.cols,e.rows))}proposeDimensions(){if(!this._terminal||!this._terminal.element||!this._terminal.element.parentElement)return;let t=this._terminal._core._renderService.dimensions;if(t.css.cell.width===0||t.css.cell.height===0)return;let s=this._terminal.options.scrollback===0?0:this._terminal.options.overviewRuler?.width||14,r=window.getComputedStyle(this._terminal.element.parentElement),l=parseInt(r.getPropertyValue("height")),a=Math.max(0,parseInt(r.getPropertyValue("width"))),i=window.getComputedStyle(this._terminal.element),n={top:parseInt(i.getPropertyValue("padding-top")),bottom:parseInt(i.getPropertyValue("padding-bottom")),right:parseInt(i.getPropertyValue("padding-right")),left:parseInt(i.getPropertyValue("padding-left"))},m=n.top+n.bottom,d=n.right+n.left,c=l-m,p=a-d-s;return{cols:Math.max(h,Math.floor(p/t.css.cell.width)),rows:Math.max(_,Math.floor(c/t.css.cell.height))}}};export{o as FitAddon};
|
|
18
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vVXNlcnMvZG1haWwvRG9jdW1lbnRzL2Rldi9qc2Vudi9jb3JlL25vZGVfbW9kdWxlcy9AeHRlcm0vYWRkb24tZml0L2xpYi9hZGRvbi1maXQubWpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ29weXJpZ2h0IChjKSAyMDE0LTIwMjQgVGhlIHh0ZXJtLmpzIGF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKiBAbGljZW5zZSBNSVRcbiAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTItMjAxMywgQ2hyaXN0b3BoZXIgSmVmZnJleSAoTUlUIExpY2Vuc2UpXG4gKiBAbGljZW5zZSBNSVRcbiAqXG4gKiBPcmlnaW5hbGx5IGZvcmtlZCBmcm9tICh3aXRoIHRoZSBhdXRob3IncyBwZXJtaXNzaW9uKTpcbiAqICAgRmFicmljZSBCZWxsYXJkJ3MgamF2YXNjcmlwdCB2dDEwMCBmb3IganNsaW51eDpcbiAqICAgaHR0cDovL2JlbGxhcmQub3JnL2pzbGludXgvXG4gKiAgIENvcHlyaWdodCAoYykgMjAxMSBGYWJyaWNlIEJlbGxhcmRcbiAqL1xuLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqICBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqICBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuIFNlZSBMaWNlbnNlLnR4dCBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxuICotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG52YXIgaD0yLF89MSxvPWNsYXNze2FjdGl2YXRlKGUpe3RoaXMuX3Rlcm1pbmFsPWV9ZGlzcG9zZSgpe31maXQoKXtsZXQgZT10aGlzLnByb3Bvc2VEaW1lbnNpb25zKCk7aWYoIWV8fCF0aGlzLl90ZXJtaW5hbHx8aXNOYU4oZS5jb2xzKXx8aXNOYU4oZS5yb3dzKSlyZXR1cm47bGV0IHQ9dGhpcy5fdGVybWluYWwuX2NvcmU7KHRoaXMuX3Rlcm1pbmFsLnJvd3MhPT1lLnJvd3N8fHRoaXMuX3Rlcm1pbmFsLmNvbHMhPT1lLmNvbHMpJiYodC5fcmVuZGVyU2VydmljZS5jbGVhcigpLHRoaXMuX3Rlcm1pbmFsLnJlc2l6ZShlLmNvbHMsZS5yb3dzKSl9cHJvcG9zZURpbWVuc2lvbnMoKXtpZighdGhpcy5fdGVybWluYWx8fCF0aGlzLl90ZXJtaW5hbC5lbGVtZW50fHwhdGhpcy5fdGVybWluYWwuZWxlbWVudC5wYXJlbnRFbGVtZW50KXJldHVybjtsZXQgdD10aGlzLl90ZXJtaW5hbC5fY29yZS5fcmVuZGVyU2VydmljZS5kaW1lbnNpb25zO2lmKHQuY3NzLmNlbGwud2lkdGg9PT0wfHx0LmNzcy5jZWxsLmhlaWdodD09PTApcmV0dXJuO2xldCBzPXRoaXMuX3Rlcm1pbmFsLm9wdGlvbnMuc2Nyb2xsYmFjaz09PTA/MDp0aGlzLl90ZXJtaW5hbC5vcHRpb25zLm92ZXJ2aWV3UnVsZXI/LndpZHRofHwxNCxyPXdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHRoaXMuX3Rlcm1pbmFsLmVsZW1lbnQucGFyZW50RWxlbWVudCksbD1wYXJzZUludChyLmdldFByb3BlcnR5VmFsdWUoXCJoZWlnaHRcIikpLGE9TWF0aC5tYXgoMCxwYXJzZUludChyLmdldFByb3BlcnR5VmFsdWUoXCJ3aWR0aFwiKSkpLGk9d2luZG93LmdldENvbXB1dGVkU3R5bGUodGhpcy5fdGVybWluYWwuZWxlbWVudCksbj17dG9wOnBhcnNlSW50KGkuZ2V0UHJvcGVydHlWYWx1ZShcInBhZGRpbmctdG9wXCIpKSxib3R0b206cGFyc2VJbnQoaS5nZXRQcm9wZXJ0eVZhbHVlKFwicGFkZGluZy1ib3R0b21cIikpLHJpZ2h0OnBhcnNlSW50KGkuZ2V0UHJvcGVydHlWYWx1ZShcInBhZGRpbmctcmlnaHRcIikpLGxlZnQ6cGFyc2VJbnQoaS5nZXRQcm9wZXJ0eVZhbHVlKFwicGFkZGluZy1sZWZ0XCIpKX0sbT1uLnRvcCtuLmJvdHRvbSxkPW4ucmlnaHQrbi5sZWZ0LGM9bC1tLHA9YS1kLXM7cmV0dXJue2NvbHM6TWF0aC5tYXgoaCxNYXRoLmZsb29yKHAvdC5jc3MuY2VsbC53aWR0aCkpLHJvd3M6TWF0aC5tYXgoXyxNYXRoLmZsb29yKGMvdC5jc3MuY2VsbC5oZWlnaHQpKX19fTtleHBvcnR7byBhcyBGaXRBZGRvbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hZGRvbi1maXQubWpzLm1hcFxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7O0FBc0JBLElBQU1BLEVBQWUsRUFDZkMsRUFBZSxFQUVSQyxFQUFOLEtBQW1ELENBR2pELFNBQVNDLEVBQTBCLENBQ3hDLEtBQUssVUFBWUEsQ0FDbkIsQ0FFTyxTQUFnQixDQUFDLENBRWpCLEtBQVksQ0FDakIsSUFBTUMsRUFBTyxLQUFLLGtCQUFrQixFQUNwQyxHQUFJLENBQUNBLEdBQVEsQ0FBQyxLQUFLLFdBQWEsTUFBTUEsRUFBSyxJQUFJLEdBQUssTUFBTUEsRUFBSyxJQUFJLEVBQ2pFLE9BSUYsSUFBTUMsRUFBUSxLQUFLLFVBQWtCLE9BR2pDLEtBQUssVUFBVSxPQUFTRCxFQUFLLE1BQVEsS0FBSyxVQUFVLE9BQVNBLEVBQUssUUFDcEVDLEVBQUssZUFBZSxNQUFNLEVBQzFCLEtBQUssVUFBVSxPQUFPRCxFQUFLLEtBQU1BLEVBQUssSUFBSSxFQUU5QyxDQUVPLG1CQUFxRCxDQUsxRCxHQUpJLENBQUMsS0FBSyxXQUlOLENBQUMsS0FBSyxVQUFVLFNBQVcsQ0FBQyxLQUFLLFVBQVUsUUFBUSxjQUNyRCxPQUtGLElBQU1BLEVBRFEsS0FBSyxVQUFrQixNQUNBLGVBQWUsV0FFcEQsR0FBSUEsRUFBSyxJQUFJLEtBQUssUUFBVSxHQUFLQSxFQUFLLElBQUksS0FBSyxTQUFXLEVBQ3hELE9BR0YsSUFBTUUsRUFBa0IsS0FBSyxVQUFVLFFBQVEsYUFBZSxFQUMxRCxFQUNDLEtBQUssVUFBVSxRQUFRLGVBQWUsT0FBUyxHQUU5Q0MsRUFBcUIsT0FBTyxpQkFBaUIsS0FBSyxVQUFVLFFBQVEsYUFBYSxFQUNqRkMsRUFBc0IsU0FBU0QsRUFBbUIsaUJBQWlCLFFBQVEsQ0FBQyxFQUM1RUUsRUFBcUIsS0FBSyxJQUFJLEVBQUcsU0FBU0YsRUFBbUIsaUJBQWlCLE9BQU8sQ0FBQyxDQUFDLEVBQ3ZGRyxFQUFlLE9BQU8saUJBQWlCLEtBQUssVUFBVSxPQUFPLEVBQzdEQyxFQUFpQixDQUNyQixJQUFLLFNBQVNELEVBQWEsaUJBQWlCLGFBQWEsQ0FBQyxFQUMxRCxPQUFRLFNBQVNBLEVBQWEsaUJBQWlCLGdCQUFnQixDQUFDLEVBQ2hFLE1BQU8sU0FBU0EsRUFBYSxpQkFBaUIsZUFBZSxDQUFDLEVBQzlELEtBQU0sU0FBU0EsRUFBYSxpQkFBaUIsY0FBYyxDQUFDLENBQzlELEVBQ01FLEVBQW9CRCxFQUFlLElBQU1BLEVBQWUsT0FDeERFLEVBQW9CRixFQUFlLE1BQVFBLEVBQWUsS0FDMURHLEVBQWtCTixFQUFzQkksRUFDeENHLEVBQWlCTixFQUFxQkksRUFBb0JQLEVBS2hFLE1BSmlCLENBQ2YsS0FBTSxLQUFLLElBQUlOLEVBQWMsS0FBSyxNQUFNZSxFQUFpQlgsRUFBSyxJQUFJLEtBQUssS0FBSyxDQUFDLEVBQzdFLEtBQU0sS0FBSyxJQUFJSCxFQUFjLEtBQUssTUFBTWEsRUFBa0JWLEVBQUssSUFBSSxLQUFLLE1BQU0sQ0FBQyxDQUNqRixDQUVGLENBQ0YiLCJuYW1lcyI6WyJNSU5JTVVNX0NPTFMiLCJNSU5JTVVNX1JPV1MiLCJGaXRBZGRvbiIsInRlcm1pbmFsIiwiZGltcyIsImNvcmUiLCJzY3JvbGxiYXJXaWR0aCIsInBhcmVudEVsZW1lbnRTdHlsZSIsInBhcmVudEVsZW1lbnRIZWlnaHQiLCJwYXJlbnRFbGVtZW50V2lkdGgiLCJlbGVtZW50U3R5bGUiLCJlbGVtZW50UGFkZGluZyIsImVsZW1lbnRQYWRkaW5nVmVyIiwiZWxlbWVudFBhZGRpbmdIb3IiLCJhdmFpbGFibGVIZWlnaHQiLCJhdmFpbGFibGVXaWR0aCJdfQ==
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": [
|
|
4
|
+
"file:///Users/dmail/Documents/dev/jsenv/core/node_modules/@xterm/addon-fit/lib/addon-fit.mjs"
|
|
5
|
+
],
|
|
6
|
+
"sourcesContent": [
|
|
7
|
+
"/**\n * Copyright (c) 2014-2024 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)\n * @license MIT\n *\n * Originally forked from (with the author's permission):\n * Fabrice Bellard's javascript vt100 for jslinux:\n * http://bellard.org/jslinux/\n * Copyright (c) 2011 Fabrice Bellard\n */\n/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nvar h=2,_=1,o=class{activate(e){this._terminal=e}dispose(){}fit(){let e=this.proposeDimensions();if(!e||!this._terminal||isNaN(e.cols)||isNaN(e.rows))return;let t=this._terminal._core;(this._terminal.rows!==e.rows||this._terminal.cols!==e.cols)&&(t._renderService.clear(),this._terminal.resize(e.cols,e.rows))}proposeDimensions(){if(!this._terminal||!this._terminal.element||!this._terminal.element.parentElement)return;let t=this._terminal._core._renderService.dimensions;if(t.css.cell.width===0||t.css.cell.height===0)return;let s=this._terminal.options.scrollback===0?0:this._terminal.options.overviewRuler?.width||14,r=window.getComputedStyle(this._terminal.element.parentElement),l=parseInt(r.getPropertyValue(\"height\")),a=Math.max(0,parseInt(r.getPropertyValue(\"width\"))),i=window.getComputedStyle(this._terminal.element),n={top:parseInt(i.getPropertyValue(\"padding-top\")),bottom:parseInt(i.getPropertyValue(\"padding-bottom\")),right:parseInt(i.getPropertyValue(\"padding-right\")),left:parseInt(i.getPropertyValue(\"padding-left\"))},m=n.top+n.bottom,d=n.right+n.left,c=l-m,p=a-d-s;return{cols:Math.max(h,Math.floor(p/t.css.cell.width)),rows:Math.max(_,Math.floor(c/t.css.cell.height))}}};export{o as FitAddon};\n//# sourceMappingURL=addon-fit.mjs.map\n"
|
|
8
|
+
],
|
|
9
|
+
"mappings": ";;;;;;;;;;;;;;;;AAsBA,IAAMA,EAAe,EACfC,EAAe,EAERC,EAAN,KAAmD,CAGjD,SAASC,EAA0B,CACxC,KAAK,UAAYA,CACnB,CAEO,SAAgB,CAAC,CAEjB,KAAY,CACjB,IAAMC,EAAO,KAAK,kBAAkB,EACpC,GAAI,CAACA,GAAQ,CAAC,KAAK,WAAa,MAAMA,EAAK,IAAI,GAAK,MAAMA,EAAK,IAAI,EACjE,OAIF,IAAMC,EAAQ,KAAK,UAAkB,OAGjC,KAAK,UAAU,OAASD,EAAK,MAAQ,KAAK,UAAU,OAASA,EAAK,QACpEC,EAAK,eAAe,MAAM,EAC1B,KAAK,UAAU,OAAOD,EAAK,KAAMA,EAAK,IAAI,EAE9C,CAEO,mBAAqD,CAK1D,GAJI,CAAC,KAAK,WAIN,CAAC,KAAK,UAAU,SAAW,CAAC,KAAK,UAAU,QAAQ,cACrD,OAKF,IAAMA,EADQ,KAAK,UAAkB,MACA,eAAe,WAEpD,GAAIA,EAAK,IAAI,KAAK,QAAU,GAAKA,EAAK,IAAI,KAAK,SAAW,EACxD,OAGF,IAAME,EAAkB,KAAK,UAAU,QAAQ,aAAe,EAC1D,EACC,KAAK,UAAU,QAAQ,eAAe,OAAS,GAE9CC,EAAqB,OAAO,iBAAiB,KAAK,UAAU,QAAQ,aAAa,EACjFC,EAAsB,SAASD,EAAmB,iBAAiB,QAAQ,CAAC,EAC5EE,EAAqB,KAAK,IAAI,EAAG,SAASF,EAAmB,iBAAiB,OAAO,CAAC,CAAC,EACvFG,EAAe,OAAO,iBAAiB,KAAK,UAAU,OAAO,EAC7DC,EAAiB,CACrB,IAAK,SAASD,EAAa,iBAAiB,aAAa,CAAC,EAC1D,OAAQ,SAASA,EAAa,iBAAiB,gBAAgB,CAAC,EAChE,MAAO,SAASA,EAAa,iBAAiB,eAAe,CAAC,EAC9D,KAAM,SAASA,EAAa,iBAAiB,cAAc,CAAC,CAC9D,EACME,EAAoBD,EAAe,IAAMA,EAAe,OACxDE,EAAoBF,EAAe,MAAQA,EAAe,KAC1DG,EAAkBN,EAAsBI,EACxCG,EAAiBN,EAAqBI,EAAoBP,EAKhE,MAJiB,CACf,KAAM,KAAK,IAAIN,EAAc,KAAK,MAAMe,EAAiBX,EAAK,IAAI,KAAK,KAAK,CAAC,EAC7E,KAAM,KAAK,IAAIH,EAAc,KAAK,MAAMa,EAAkBV,EAAK,IAAI,KAAK,MAAM,CAAC,CACjF,CAEF,CACF",
|
|
10
|
+
"names": [
|
|
11
|
+
"MINIMUM_COLS",
|
|
12
|
+
"MINIMUM_ROWS",
|
|
13
|
+
"FitAddon",
|
|
14
|
+
"terminal",
|
|
15
|
+
"dims",
|
|
16
|
+
"core",
|
|
17
|
+
"scrollbarWidth",
|
|
18
|
+
"parentElementStyle",
|
|
19
|
+
"parentElementHeight",
|
|
20
|
+
"parentElementWidth",
|
|
21
|
+
"elementStyle",
|
|
22
|
+
"elementPadding",
|
|
23
|
+
"elementPaddingVer",
|
|
24
|
+
"elementPaddingHor",
|
|
25
|
+
"availableHeight",
|
|
26
|
+
"availableWidth"
|
|
27
|
+
]
|
|
28
|
+
}
|