rlint 0.4.0 → 0.5.0

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/README.md CHANGED
@@ -37,7 +37,14 @@ These aren't styling issues — they're **structural bugs** that can be detected
37
37
  ## Installation
38
38
 
39
39
  ```bash
40
- npm install rlint
40
+ # Install globally (recommended — makes `rlint` available everywhere)
41
+ npm install -g rlint
42
+
43
+ # Or use without installing
44
+ npx rlint check https://example.com
45
+
46
+ # Or install as a dev dependency
47
+ npm install --save-dev rlint
41
48
  ```
42
49
 
43
50
  No extra setup. Renderlint uses your system Chrome — no 150MB Chromium download. If Chrome isn't installed, Chromium is downloaded automatically on first run.
@@ -48,16 +55,19 @@ No extra setup. Renderlint uses your system Chrome — no 150MB Chromium downloa
48
55
 
49
56
  ```bash
50
57
  # Check any URL
51
- npx rlint check https://example.com
58
+ rlint check https://example.com
52
59
 
53
60
  # Check your dev server
54
- npx rlint check http://localhost:3000
61
+ rlint check http://localhost:3000
62
+
63
+ # Mobile testing (portrait + landscape at 375x667)
64
+ rlint check --mobile http://localhost:3000
55
65
 
56
66
  # Check multiple viewports (mobile + desktop)
57
- npx rlint check --viewport 375x667,1920x1080 http://localhost:3000
67
+ rlint check --viewport 375x667,1920x1080 http://localhost:3000
58
68
 
59
69
  # Auto-detect framework and start dev server
60
- npx rlint dev
70
+ rlint dev
61
71
  ```
62
72
 
63
73
  ## Checks
@@ -65,10 +75,11 @@ npx rlint dev
65
75
  | Check | Severity | What it catches |
66
76
  |-------|----------|-----------------|
67
77
  | `overflow` | error | Horizontal scrollbars from content wider than viewport |
68
- | `clickability` | error | Buttons/links covered by other elements (z-index bugs) |
69
- | `touch-targets` | warning | Elements smaller than 44×44px (WCAG 2.5.5) |
78
+ | `clickability` | error | Buttons/links covered by other elements checks center + all 4 corners |
79
+ | `touch-targets` | warning | Elements smaller than 44×44px (WCAG 2.5.5) + adjacent targets with <8px gap |
70
80
  | `visibility` | warning | Interactive elements that are invisible or off-screen |
71
81
  | `text-overflow` | warning | Text clipped without proper ellipsis handling |
82
+ | `viewport-meta` | warning | Missing or misconfigured viewport meta tag (mobile rendering) |
72
83
 
73
84
  ## Framework Support
74
85
 
@@ -76,10 +87,10 @@ Renderlint auto-detects your framework and handles hydration:
76
87
 
77
88
  ```bash
78
89
  # Auto-detect and start dev server
79
- npx rlint dev --routes /,/about,/contact
90
+ rlint dev --routes /,/about,/contact
80
91
 
81
92
  # Specify framework manually
82
- npx rlint dev --framework nextjs --routes /,/api/health
93
+ rlint dev --framework nextjs --routes /,/api/health
83
94
  ```
84
95
 
85
96
  Supported: **Next.js**, **SvelteKit**, **Vite**, **Remix**, **Astro**, **Nuxt**, **Create React App**
@@ -103,7 +114,15 @@ await browser.close();
103
114
 
104
115
  ## MCP Server (for AI Agents)
105
116
 
106
- Renderlint includes an MCP server for integration with Claude Code and other AI tools:
117
+ Renderlint includes an MCP server so AI agents can check pages for layout bugs programmatically.
118
+
119
+ ### Claude Code
120
+
121
+ ```bash
122
+ claude mcp add rlint -- npx rlint-mcp
123
+ ```
124
+
125
+ Or add to your project's `.mcp.json`:
107
126
 
108
127
  ```json
109
128
  {
@@ -116,11 +135,117 @@ Renderlint includes an MCP server for integration with Claude Code and other AI
116
135
  }
117
136
  ```
118
137
 
119
- Available tools:
120
- - `check_page` — Check a URL for layout issues
121
- - `check_html` Check raw HTML content
122
- - `check_file` — Check a local HTML file
123
- - `screenshot` — Take a screenshot (returns image for visual debugging)
138
+ ### Claude Desktop
139
+
140
+ Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS, `%APPDATA%\Claude\claude_desktop_config.json` on Windows):
141
+
142
+ ```json
143
+ {
144
+ "mcpServers": {
145
+ "rlint": {
146
+ "command": "npx",
147
+ "args": ["rlint-mcp"]
148
+ }
149
+ }
150
+ }
151
+ ```
152
+
153
+ ### Cursor
154
+
155
+ Add to `.cursor/mcp.json` in your project:
156
+
157
+ ```json
158
+ {
159
+ "mcpServers": {
160
+ "rlint": {
161
+ "command": "npx",
162
+ "args": ["rlint-mcp"]
163
+ }
164
+ }
165
+ }
166
+ ```
167
+
168
+ ### Available MCP Tools
169
+
170
+ | Tool | Description |
171
+ |------|-------------|
172
+ | `check_page` | Check a URL for layout issues (overflow, covered buttons, touch targets, etc.) |
173
+ | `check_html` | Check raw HTML content directly |
174
+ | `check_file` | Check a local HTML file by path |
175
+ | `screenshot` | Take a screenshot of a URL or element (returns base64 PNG) |
176
+
177
+ All check tools accept optional parameters:
178
+ - `viewport` (`{ width, height }`) — custom viewport size
179
+ - `checks` (array) — specific checks to run: `overflow`, `clickability`, `touch-targets`, `text-overflow`, `visibility`, `viewport-meta`
180
+ - `mobile` (boolean) — test at mobile viewports (375x667 portrait + 667x375 landscape)
181
+
182
+ Results include element selectors, dimensions, and fix hints.
183
+
184
+ ## For LLMs: Using rlint as a CLI Tool
185
+
186
+ If you're an LLM/AI agent with shell access, you can use rlint directly from the command line to validate UI you've built or modified.
187
+
188
+ ### Quick reference
189
+
190
+ ```bash
191
+ # Install globally (one-time setup)
192
+ npm install -g rlint
193
+
194
+ # Check a running dev server
195
+ rlint check http://localhost:3000 --format json
196
+
197
+ # Mobile testing (portrait + landscape, recommended after UI changes)
198
+ rlint check --mobile --format json http://localhost:3000
199
+
200
+ # Check specific routes at mobile viewport
201
+ rlint check --viewport 375x667 http://localhost:3000 http://localhost:3000/about
202
+
203
+ # Check with JSON output (easiest to parse)
204
+ rlint check --format json http://localhost:3000
205
+
206
+ # Run only specific checks
207
+ rlint check --only overflow,clickability http://localhost:3000
208
+
209
+ # Auto-detect framework, start dev server, check routes
210
+ rlint dev --routes /,/about,/settings --format json
211
+ ```
212
+
213
+ ### Interpreting results
214
+
215
+ rlint exits with code **1** if errors are found (code **0** if clean). Use `--format json` for structured output:
216
+
217
+ ```json
218
+ {
219
+ "url": "http://localhost:3000",
220
+ "summary": { "passed": 47, "errors": 1, "warnings": 2 },
221
+ "issues": [
222
+ {
223
+ "check": "overflow",
224
+ "severity": "error",
225
+ "message": "Horizontal overflow detected",
226
+ "element": { "selector": "div.hero-banner" },
227
+ "fixHint": "Add overflow-x: hidden or check for elements with fixed widths"
228
+ }
229
+ ]
230
+ }
231
+ ```
232
+
233
+ ### Recommended workflow for LLMs
234
+
235
+ 1. Make your UI changes
236
+ 2. Ensure the dev server is running
237
+ 3. Run `rlint check --format json http://localhost:3000` on affected routes
238
+ 4. Parse the JSON output — fix any issues using the `fixHint` and `element.selector` fields
239
+ 5. Re-run to verify fixes
240
+
241
+ ### Available checks
242
+
243
+ - **overflow** — Horizontal scrollbars from content wider than viewport
244
+ - **clickability** — Buttons/links covered by other elements (checks center + 4 corners)
245
+ - **touch-targets** — Elements smaller than 44x44px + adjacent targets with <8px gap
246
+ - **text-overflow** — Text clipped without ellipsis handling
247
+ - **visibility** — Interactive elements that are invisible or off-screen
248
+ - **viewport-meta** — Missing or misconfigured viewport meta tag
124
249
 
125
250
  ## Configuration
126
251
 
@@ -159,8 +284,9 @@ jobs:
159
284
  - uses: actions/setup-node@v4
160
285
  - run: npm ci
161
286
  - run: npm run build
287
+ - run: npm install -g rlint
162
288
  - run: npm start & npx wait-on http://localhost:3000
163
- - run: npx rlint check --fail-on warning http://localhost:3000
289
+ - run: rlint check --fail-on warning http://localhost:3000
164
290
  ```
165
291
 
166
292
  > **Tip:** Renderlint uses system Chrome. If unavailable, Chromium is downloaded to `~/.cache/rlint` on first run. Cache this directory in CI for faster builds.
@@ -175,6 +301,7 @@ rlint check <urls...>
175
301
  -i, --ignore <selectors> Ignore matching elements
176
302
  -c, --config <path> Config file path
177
303
  --fail-on <severity> Exit code 1 on: error, warning
304
+ --mobile Test mobile viewports (375x667 + 667x375)
178
305
  --headed Show browser window
179
306
  --wait-for-hydration Wait for SPA hydration
180
307
 
@@ -182,6 +309,7 @@ rlint dev
182
309
  -r, --routes <routes> Routes to check (default: /)
183
310
  -p, --port <port> Dev server port
184
311
  --framework <name> Framework override
312
+ --mobile Test mobile viewports (375x667 + 667x375)
185
313
  --no-start-server Use existing dev server
186
314
  ```
187
315
 
@@ -1 +1 @@
1
- {"version":3,"file":"clickability.d.ts","sourceRoot":"","sources":["../../src/checks/clickability.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAuB,MAAM,aAAa,CAAC;AAuB9D,eAAO,MAAM,iBAAiB,EAAE,KA6I/B,CAAC"}
1
+ {"version":3,"file":"clickability.d.ts","sourceRoot":"","sources":["../../src/checks/clickability.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAuB,MAAM,aAAa,CAAC;AAyB9D,eAAO,MAAM,iBAAiB,EAAE,KAmL/B,CAAC"}
@@ -26,6 +26,18 @@ export const clickabilityCheck = {
26
26
  const results = [];
27
27
  const selectorString = selectors.join(', ');
28
28
  const elements = document.querySelectorAll(selectorString);
29
+ // Small inset to avoid hitting borders/edges where elementFromPoint is ambiguous
30
+ const EDGE_INSET = 2;
31
+ function isCovered(el, x, y) {
32
+ // Clamp to viewport
33
+ if (x < 0 || y < 0 || x > window.innerWidth || y > window.innerHeight)
34
+ return null;
35
+ const topEl = document.elementFromPoint(x, y);
36
+ if (topEl && topEl !== el && !el.contains(topEl) && !topEl.contains(el)) {
37
+ return topEl;
38
+ }
39
+ return null;
40
+ }
29
41
  for (const el of elements) {
30
42
  // Skip ignored elements
31
43
  const shouldIgnore = ignoreSelectors.some(sel => {
@@ -56,23 +68,36 @@ export const clickabilityCheck = {
56
68
  rect.top > window.innerHeight) {
57
69
  continue;
58
70
  }
59
- // Check center point
60
- const centerX = rect.left + rect.width / 2;
61
- const centerY = rect.top + rect.height / 2;
62
- const topElement = document.elementFromPoint(centerX, centerY);
63
- if (topElement && topElement !== el && !el.contains(topElement) && !topElement.contains(el)) {
64
- // Element is covered!
71
+ // Check 5 points: center + 4 corners (inset slightly to avoid border ambiguity)
72
+ const points = [
73
+ { name: 'center', x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 },
74
+ { name: 'top-left', x: rect.left + EDGE_INSET, y: rect.top + EDGE_INSET },
75
+ { name: 'top-right', x: rect.right - EDGE_INSET, y: rect.top + EDGE_INSET },
76
+ { name: 'bottom-left', x: rect.left + EDGE_INSET, y: rect.bottom - EDGE_INSET },
77
+ { name: 'bottom-right', x: rect.right - EDGE_INSET, y: rect.bottom - EDGE_INSET },
78
+ ];
79
+ const coveredPoints = [];
80
+ let firstCoverer = null;
81
+ for (const point of points) {
82
+ const coverer = isCovered(el, point.x, point.y);
83
+ if (coverer) {
84
+ coveredPoints.push(point.name);
85
+ if (!firstCoverer)
86
+ firstCoverer = coverer;
87
+ }
88
+ }
89
+ if (coveredPoints.length > 0 && firstCoverer) {
65
90
  let selector = el.tagName.toLowerCase();
66
91
  if (el.id)
67
92
  selector += `#${el.id}`;
68
93
  if (el.className && typeof el.className === 'string') {
69
94
  selector += '.' + el.className.trim().split(/\s+/).join('.');
70
95
  }
71
- let coverSelector = topElement.tagName.toLowerCase();
72
- if (topElement.id)
73
- coverSelector += `#${topElement.id}`;
74
- if (topElement.className && typeof topElement.className === 'string') {
75
- coverSelector += '.' + topElement.className.trim().split(/\s+/).join('.');
96
+ let coverSelector = firstCoverer.tagName.toLowerCase();
97
+ if (firstCoverer.id)
98
+ coverSelector += `#${firstCoverer.id}`;
99
+ if (firstCoverer.className && typeof firstCoverer.className === 'string') {
100
+ coverSelector += '.' + firstCoverer.className.trim().split(/\s+/).join('.');
76
101
  }
77
102
  results.push({
78
103
  selector,
@@ -90,31 +115,41 @@ export const clickabilityCheck = {
90
115
  },
91
116
  coveredBy: {
92
117
  selector: coverSelector,
93
- tagName: topElement.tagName,
94
- className: typeof topElement.className === 'string' ? topElement.className : '',
118
+ tagName: firstCoverer.tagName,
119
+ className: typeof firstCoverer.className === 'string' ? firstCoverer.className : '',
95
120
  },
121
+ coveredPoints,
122
+ totalPoints: points.length,
96
123
  });
97
124
  }
98
125
  }
99
126
  return results;
100
127
  }, { selectors, ignoreSelectors });
101
- const issues = coveredElements.map(el => ({
102
- check: 'clickability',
103
- severity: 'error',
104
- message: `Interactive element is covered by another element`,
105
- element: {
106
- selector: el.selector,
107
- tagName: el.tagName,
108
- className: el.className,
109
- id: el.id,
110
- textContent: el.textContent,
111
- rect: el.rect,
112
- },
113
- details: {
114
- coveredBy: el.coveredBy.selector,
115
- },
116
- fixHint: `Check z-index of ${el.selector} and ${el.coveredBy.selector}, or remove/reposition the covering element`,
117
- }));
128
+ const issues = coveredElements.map(el => {
129
+ const allCovered = el.coveredPoints.length === el.totalPoints;
130
+ const coverageDesc = allCovered
131
+ ? 'fully covered'
132
+ : `partially covered (${el.coveredPoints.join(', ')})`;
133
+ return {
134
+ check: 'clickability',
135
+ severity: 'error',
136
+ message: `Interactive element is ${coverageDesc} by another element`,
137
+ element: {
138
+ selector: el.selector,
139
+ tagName: el.tagName,
140
+ className: el.className,
141
+ id: el.id,
142
+ textContent: el.textContent,
143
+ rect: el.rect,
144
+ },
145
+ details: {
146
+ coveredBy: el.coveredBy.selector,
147
+ coveredPoints: el.coveredPoints,
148
+ totalPoints: el.totalPoints,
149
+ },
150
+ fixHint: `Check z-index of ${el.selector} and ${el.coveredBy.selector}, or remove/reposition the covering element`,
151
+ };
152
+ });
118
153
  return {
119
154
  check: 'clickability',
120
155
  passed: Math.max(0, (await page.$$(selectors.join(', '))).length - issues.length),
@@ -1 +1 @@
1
- {"version":3,"file":"clickability.js","sourceRoot":"","sources":["../../src/checks/clickability.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"clickability.js","sourceRoot":"","sources":["../../src/checks/clickability.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,7 @@ export { clickabilityCheck } from './clickability.js';
3
3
  export { touchTargetsCheck } from './touch-targets.js';
4
4
  export { visibilityCheck } from './visibility.js';
5
5
  export { textOverflowCheck } from './text-overflow.js';
6
+ export { viewportMetaCheck } from './viewport-meta.js';
6
7
  import type { Check } from '../types.js';
7
8
  export declare const allChecks: Check[];
8
9
  export declare const checksByName: Record<string, Check>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/checks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAOvD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzC,eAAO,MAAM,SAAS,EAAE,KAAK,EAM5B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAQ9C,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/checks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAQvD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzC,eAAO,MAAM,SAAS,EAAE,KAAK,EAO5B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAU9C,CAAC"}
@@ -3,17 +3,20 @@ export { clickabilityCheck } from './clickability.js';
3
3
  export { touchTargetsCheck } from './touch-targets.js';
4
4
  export { visibilityCheck } from './visibility.js';
5
5
  export { textOverflowCheck } from './text-overflow.js';
6
+ export { viewportMetaCheck } from './viewport-meta.js';
6
7
  import { overflowCheck } from './overflow.js';
7
8
  import { clickabilityCheck } from './clickability.js';
8
9
  import { touchTargetsCheck } from './touch-targets.js';
9
10
  import { visibilityCheck } from './visibility.js';
10
11
  import { textOverflowCheck } from './text-overflow.js';
12
+ import { viewportMetaCheck } from './viewport-meta.js';
11
13
  export const allChecks = [
12
14
  overflowCheck,
13
15
  clickabilityCheck,
14
16
  touchTargetsCheck,
15
17
  visibilityCheck,
16
18
  textOverflowCheck,
19
+ viewportMetaCheck,
17
20
  ];
18
21
  export const checksByName = {
19
22
  overflow: overflowCheck,
@@ -23,5 +26,7 @@ export const checksByName = {
23
26
  visibility: visibilityCheck,
24
27
  'text-overflow': textOverflowCheck,
25
28
  textOverflow: textOverflowCheck,
29
+ 'viewport-meta': viewportMetaCheck,
30
+ viewportMeta: viewportMetaCheck,
26
31
  };
27
32
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/checks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAGvD,MAAM,CAAC,MAAM,SAAS,GAAY;IAChC,aAAa;IACb,iBAAiB;IACjB,iBAAiB;IACjB,eAAe;IACf,iBAAiB;CAClB,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAA0B;IACjD,QAAQ,EAAE,aAAa;IACvB,YAAY,EAAE,iBAAiB;IAC/B,eAAe,EAAE,iBAAiB;IAClC,YAAY,EAAE,iBAAiB;IAC/B,UAAU,EAAE,eAAe;IAC3B,eAAe,EAAE,iBAAiB;IAClC,YAAY,EAAE,iBAAiB;CAChC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/checks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAGvD,MAAM,CAAC,MAAM,SAAS,GAAY;IAChC,aAAa;IACb,iBAAiB;IACjB,iBAAiB;IACjB,eAAe;IACf,iBAAiB;IACjB,iBAAiB;CAClB,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAA0B;IACjD,QAAQ,EAAE,aAAa;IACvB,YAAY,EAAE,iBAAiB;IAC/B,eAAe,EAAE,iBAAiB;IAClC,YAAY,EAAE,iBAAiB;IAC/B,UAAU,EAAE,eAAe;IAC3B,eAAe,EAAE,iBAAiB;IAClC,YAAY,EAAE,iBAAiB;IAC/B,eAAe,EAAE,iBAAiB;IAClC,YAAY,EAAE,iBAAiB;CAChC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"touch-targets.d.ts","sourceRoot":"","sources":["../../src/checks/touch-targets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAuB,MAAM,aAAa,CAAC;AAoB9D,eAAO,MAAM,iBAAiB,EAAE,KAsI/B,CAAC"}
1
+ {"version":3,"file":"touch-targets.d.ts","sourceRoot":"","sources":["../../src/checks/touch-targets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAuB,MAAM,aAAa,CAAC;AAwC9D,eAAO,MAAM,iBAAiB,EAAE,KAoO/B,CAAC"}