@react-hive/honey-utils 3.14.0 → 3.16.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 +6 -1
- package/dist/README.md +6 -1
- package/dist/file.d.ts +1 -17
- package/dist/geometry/apply-inertia-step.d.ts +134 -0
- package/dist/geometry/index.d.ts +2 -0
- package/dist/geometry/resolve-bounded-delta.d.ts +79 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.dev.cjs +325 -29
- package/dist/index.dev.cjs.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/string/find-char-indices.d.ts +15 -0
- package/dist/string/for-each-char.d.ts +43 -0
- package/dist/string/index.d.ts +3 -0
- package/dist/string/parse-file-name.d.ts +16 -0
- package/package.json +1 -1
package/dist/index.dev.cjs
CHANGED
|
@@ -230,7 +230,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
230
230
|
/* harmony export */ pipe: () => (/* binding */ pipe),
|
|
231
231
|
/* harmony export */ unique: () => (/* binding */ unique)
|
|
232
232
|
/* harmony export */ });
|
|
233
|
-
/* harmony import */ var _guards__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*!
|
|
233
|
+
/* harmony import */ var _guards__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ~/guards */ "./src/guards.ts");
|
|
234
234
|
|
|
235
235
|
/**
|
|
236
236
|
* Checks if a value is an array.
|
|
@@ -1324,11 +1324,10 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
1324
1324
|
/* harmony export */ blobToFile: () => (/* binding */ blobToFile),
|
|
1325
1325
|
/* harmony export */ fileListToFiles: () => (/* binding */ fileListToFiles),
|
|
1326
1326
|
/* harmony export */ isFile: () => (/* binding */ isFile),
|
|
1327
|
-
/* harmony export */ parseFileName: () => (/* binding */ parseFileName),
|
|
1328
1327
|
/* harmony export */ readFilesFromDataTransfer: () => (/* binding */ readFilesFromDataTransfer),
|
|
1329
1328
|
/* harmony export */ traverseFileSystemDirectory: () => (/* binding */ traverseFileSystemDirectory)
|
|
1330
1329
|
/* harmony export */ });
|
|
1331
|
-
/* harmony import */ var
|
|
1330
|
+
/* harmony import */ var _async__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ~/async */ "./src/async/index.ts");
|
|
1332
1331
|
|
|
1333
1332
|
/**
|
|
1334
1333
|
* Checks if a value is a `File` object.
|
|
@@ -1338,29 +1337,6 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
1338
1337
|
* @returns `true` if the value is a `File` object; otherwise, `false`.
|
|
1339
1338
|
*/
|
|
1340
1339
|
const isFile = (value) => value instanceof File;
|
|
1341
|
-
/**
|
|
1342
|
-
* Splits a file name into its base name and extension.
|
|
1343
|
-
*
|
|
1344
|
-
* Special cases:
|
|
1345
|
-
* - Files without a dot return `[fileName, ""]`
|
|
1346
|
-
* - Hidden files like `.gitignore` return `[".gitignore", ""]`
|
|
1347
|
-
* - Names ending with a trailing dot (e.g., `"file."`) return `["file.", ""]`
|
|
1348
|
-
* - Multi-dot names (e.g., `"archive.tar.gz"`) split on the last dot
|
|
1349
|
-
*
|
|
1350
|
-
* @param fileName - The full file name to parse.
|
|
1351
|
-
*
|
|
1352
|
-
* @returns A tuple where:
|
|
1353
|
-
* - index 0 is the base name
|
|
1354
|
-
* - index 1 is the file extension (lowercased), or an empty string if none exists
|
|
1355
|
-
*/
|
|
1356
|
-
const parseFileName = (fileName) => {
|
|
1357
|
-
const lastDotIndex = fileName.lastIndexOf('.');
|
|
1358
|
-
// No dot or leading dot with no extension (e.g., ".gitignore")
|
|
1359
|
-
if (lastDotIndex <= 0 || lastDotIndex === fileName.length - 1) {
|
|
1360
|
-
return [fileName, ''];
|
|
1361
|
-
}
|
|
1362
|
-
return [fileName.slice(0, lastDotIndex), fileName.slice(lastDotIndex + 1).toLowerCase()];
|
|
1363
|
-
};
|
|
1364
1340
|
/**
|
|
1365
1341
|
* Converts a `FileList` object to an array of `File` objects.
|
|
1366
1342
|
*
|
|
@@ -1450,7 +1426,7 @@ const traverseFileSystemDirectory = async (directoryEntry, { skipFiles = [
|
|
|
1450
1426
|
], } = {}) => {
|
|
1451
1427
|
const skipFilesSet = new Set(skipFiles);
|
|
1452
1428
|
const entries = await readFileSystemDirectoryEntries(directoryEntry);
|
|
1453
|
-
const filePromises = await (0,
|
|
1429
|
+
const filePromises = await (0,_async__WEBPACK_IMPORTED_MODULE_0__.runParallel)(entries, async (entry) => {
|
|
1454
1430
|
if (entry.isDirectory) {
|
|
1455
1431
|
return traverseFileSystemDirectory(entry, {
|
|
1456
1432
|
skipFiles,
|
|
@@ -1640,6 +1616,110 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
1640
1616
|
const invokeIfFunction = (input, ...args) => (typeof input === 'function' ? input(...args) : input);
|
|
1641
1617
|
|
|
1642
1618
|
|
|
1619
|
+
/***/ }),
|
|
1620
|
+
|
|
1621
|
+
/***/ "./src/geometry/apply-inertia-step.ts":
|
|
1622
|
+
/*!********************************************!*\
|
|
1623
|
+
!*** ./src/geometry/apply-inertia-step.ts ***!
|
|
1624
|
+
\********************************************/
|
|
1625
|
+
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
1626
|
+
|
|
1627
|
+
__webpack_require__.r(__webpack_exports__);
|
|
1628
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
1629
|
+
/* harmony export */ applyInertiaStep: () => (/* binding */ applyInertiaStep)
|
|
1630
|
+
/* harmony export */ });
|
|
1631
|
+
/* harmony import */ var _geometry__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ~/geometry */ "./src/geometry/index.ts");
|
|
1632
|
+
|
|
1633
|
+
/**
|
|
1634
|
+
* Advances a value by one inertia step using velocity, friction, and hard bounds.
|
|
1635
|
+
*
|
|
1636
|
+
* This utility models **inertial motion** (momentum + decay) on top of
|
|
1637
|
+
* {@link resolveBoundedDelta}, which acts as the authoritative constraint layer.
|
|
1638
|
+
*
|
|
1639
|
+
* The function:
|
|
1640
|
+
* - Integrates velocity over the elapsed time to produce a movement delta
|
|
1641
|
+
* - Resolves that delta against fixed bounds
|
|
1642
|
+
* - Applies exponential friction to gradually reduce velocity
|
|
1643
|
+
* - Stops immediately when a bound is hit or velocity falls below a threshold
|
|
1644
|
+
*
|
|
1645
|
+
* ⚠️ This function performs **one step only** and is intended to be called
|
|
1646
|
+
* repeatedly from an animation loop (e.g. `requestAnimationFrame`).
|
|
1647
|
+
*
|
|
1648
|
+
* ### Common use cases
|
|
1649
|
+
* - Synthetic scrolling with momentum
|
|
1650
|
+
* - Carousels and sliders
|
|
1651
|
+
* - Timelines and scrubbers
|
|
1652
|
+
* - Drag-to-scroll interactions with inertia
|
|
1653
|
+
*
|
|
1654
|
+
* @param value - Current value before applying inertia (e.g. translate position).
|
|
1655
|
+
* @param min - Minimum allowed value (inclusive).
|
|
1656
|
+
* @param max - Maximum allowed value (inclusive).
|
|
1657
|
+
* @param velocity - Current velocity in units per millisecond (e.g. px/ms).
|
|
1658
|
+
* @param deltaTime - Time elapsed since the previous step, in milliseconds.
|
|
1659
|
+
* @param friction - Exponential friction coefficient controlling decay rate.
|
|
1660
|
+
* @param minVelocity - Minimum velocity below which inertia stops.
|
|
1661
|
+
*
|
|
1662
|
+
* @returns An object containing the updated value and velocity,
|
|
1663
|
+
* or `null` when inertia has completed or movement is no longer possible.
|
|
1664
|
+
*
|
|
1665
|
+
* @example
|
|
1666
|
+
* ```ts
|
|
1667
|
+
* let value = translateX;
|
|
1668
|
+
* let velocity = releaseVelocity; // px/ms from drag end
|
|
1669
|
+
* let lastTime = performance.now();
|
|
1670
|
+
*
|
|
1671
|
+
* const step = (time: number) => {
|
|
1672
|
+
* const deltaTime = time - lastTime;
|
|
1673
|
+
* lastTime = time;
|
|
1674
|
+
*
|
|
1675
|
+
* const result = applyInertiaStep({
|
|
1676
|
+
* value,
|
|
1677
|
+
* velocity,
|
|
1678
|
+
* min: -maxOverflow,
|
|
1679
|
+
* max: 0,
|
|
1680
|
+
* deltaTime,
|
|
1681
|
+
* });
|
|
1682
|
+
*
|
|
1683
|
+
* if (!result) {
|
|
1684
|
+
* return; // inertia finished
|
|
1685
|
+
* }
|
|
1686
|
+
*
|
|
1687
|
+
* value = result.value;
|
|
1688
|
+
* velocity = result.velocity;
|
|
1689
|
+
*
|
|
1690
|
+
* container.style.transform = `translateX(${value}px)`;
|
|
1691
|
+
* requestAnimationFrame(step);
|
|
1692
|
+
* };
|
|
1693
|
+
*
|
|
1694
|
+
* requestAnimationFrame(step);
|
|
1695
|
+
* ```
|
|
1696
|
+
*/
|
|
1697
|
+
const applyInertiaStep = ({ value, min, max, velocity, deltaTime, friction = 0.002, minVelocity = 0.01, }) => {
|
|
1698
|
+
if (Math.abs(velocity) < minVelocity) {
|
|
1699
|
+
return null;
|
|
1700
|
+
}
|
|
1701
|
+
// Distance we want to move this frame
|
|
1702
|
+
const delta = velocity * deltaTime;
|
|
1703
|
+
const nextValue = (0,_geometry__WEBPACK_IMPORTED_MODULE_0__.resolveBoundedDelta)({
|
|
1704
|
+
delta,
|
|
1705
|
+
value,
|
|
1706
|
+
min,
|
|
1707
|
+
max,
|
|
1708
|
+
});
|
|
1709
|
+
// Hit a hard bound → stop inertia immediately
|
|
1710
|
+
if (nextValue === null) {
|
|
1711
|
+
return null;
|
|
1712
|
+
}
|
|
1713
|
+
// Apply exponential friction
|
|
1714
|
+
const decay = Math.exp(-friction * deltaTime);
|
|
1715
|
+
const nextVelocity = velocity * decay;
|
|
1716
|
+
return {
|
|
1717
|
+
value: nextValue,
|
|
1718
|
+
velocity: nextVelocity,
|
|
1719
|
+
};
|
|
1720
|
+
};
|
|
1721
|
+
|
|
1722
|
+
|
|
1643
1723
|
/***/ }),
|
|
1644
1724
|
|
|
1645
1725
|
/***/ "./src/geometry/index.ts":
|
|
@@ -1650,9 +1730,15 @@ const invokeIfFunction = (input, ...args) => (typeof input === 'function' ? inpu
|
|
|
1650
1730
|
|
|
1651
1731
|
__webpack_require__.r(__webpack_exports__);
|
|
1652
1732
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
1653
|
-
/* harmony export */
|
|
1733
|
+
/* harmony export */ applyInertiaStep: () => (/* reexport safe */ _apply_inertia_step__WEBPACK_IMPORTED_MODULE_2__.applyInertiaStep),
|
|
1734
|
+
/* harmony export */ calculateCenterOffset: () => (/* reexport safe */ _layout__WEBPACK_IMPORTED_MODULE_0__.calculateCenterOffset),
|
|
1735
|
+
/* harmony export */ resolveBoundedDelta: () => (/* reexport safe */ _resolve_bounded_delta__WEBPACK_IMPORTED_MODULE_1__.resolveBoundedDelta)
|
|
1654
1736
|
/* harmony export */ });
|
|
1655
1737
|
/* harmony import */ var _layout__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./layout */ "./src/geometry/layout/index.ts");
|
|
1738
|
+
/* harmony import */ var _resolve_bounded_delta__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./resolve-bounded-delta */ "./src/geometry/resolve-bounded-delta.ts");
|
|
1739
|
+
/* harmony import */ var _apply_inertia_step__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./apply-inertia-step */ "./src/geometry/apply-inertia-step.ts");
|
|
1740
|
+
|
|
1741
|
+
|
|
1656
1742
|
|
|
1657
1743
|
|
|
1658
1744
|
|
|
@@ -1706,6 +1792,83 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
1706
1792
|
|
|
1707
1793
|
|
|
1708
1794
|
|
|
1795
|
+
/***/ }),
|
|
1796
|
+
|
|
1797
|
+
/***/ "./src/geometry/resolve-bounded-delta.ts":
|
|
1798
|
+
/*!***********************************************!*\
|
|
1799
|
+
!*** ./src/geometry/resolve-bounded-delta.ts ***!
|
|
1800
|
+
\***********************************************/
|
|
1801
|
+
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
1802
|
+
|
|
1803
|
+
__webpack_require__.r(__webpack_exports__);
|
|
1804
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
1805
|
+
/* harmony export */ resolveBoundedDelta: () => (/* binding */ resolveBoundedDelta)
|
|
1806
|
+
/* harmony export */ });
|
|
1807
|
+
/**
|
|
1808
|
+
* Resolves the next value by consuming a delta within fixed numeric bounds.
|
|
1809
|
+
*
|
|
1810
|
+
* This function applies **bounded delta consumption** rather than naive clamping:
|
|
1811
|
+
*
|
|
1812
|
+
* - The delta is applied in the given direction as long as movement is possible.
|
|
1813
|
+
* - If the delta would overshoot a bound, it is partially consumed so the
|
|
1814
|
+
* resulting value lands exactly on the boundary.
|
|
1815
|
+
* - If movement in the given direction is no longer possible, `null` is returned.
|
|
1816
|
+
*
|
|
1817
|
+
* This behavior mirrors how native scroll engines and drag constraints
|
|
1818
|
+
* handle fast input without jitter or overshoot.
|
|
1819
|
+
*
|
|
1820
|
+
* ### Key characteristics
|
|
1821
|
+
* - Direction-aware (positive and negative deltas behave independently)
|
|
1822
|
+
* - Prevents overshoot while preserving remaining movement
|
|
1823
|
+
* - Does **not** clamp unconditionally
|
|
1824
|
+
* - Side-effect free and fully deterministic
|
|
1825
|
+
*
|
|
1826
|
+
* ### Common use cases
|
|
1827
|
+
* - Synthetic scrolling
|
|
1828
|
+
* - Drag constraints
|
|
1829
|
+
* - Sliders and carousels
|
|
1830
|
+
* - Timelines and scrubbers
|
|
1831
|
+
* - Inertia and momentum systems
|
|
1832
|
+
*
|
|
1833
|
+
* @param delta - Incremental change to apply to the current value.
|
|
1834
|
+
* The sign determines the movement direction.
|
|
1835
|
+
* @param value - Current numeric value before applying the delta.
|
|
1836
|
+
* @param min - Minimum allowed value (inclusive).
|
|
1837
|
+
* @param max - Maximum allowed value (inclusive).
|
|
1838
|
+
*
|
|
1839
|
+
* @returns The next resolved value after applying the delta,
|
|
1840
|
+
* or `null` if movement in the given direction is not possible.
|
|
1841
|
+
*
|
|
1842
|
+
* @example
|
|
1843
|
+
* ```ts
|
|
1844
|
+
* // Simple bounded movement
|
|
1845
|
+
* resolveBoundedDelta({ value: 10, delta: -5, min: 0, max: 100 });
|
|
1846
|
+
* // → 5
|
|
1847
|
+
*
|
|
1848
|
+
* // Overshoot is clamped to the boundary
|
|
1849
|
+
* resolveBoundedDelta({ value: 2, delta: -10, min: 0, max: 100 });
|
|
1850
|
+
* // → 0
|
|
1851
|
+
*
|
|
1852
|
+
* // Movement blocked at the boundary
|
|
1853
|
+
* resolveBoundedDelta({ value: 0, delta: -5, min: 0, max: 100 });
|
|
1854
|
+
* // → null
|
|
1855
|
+
* ```
|
|
1856
|
+
*/
|
|
1857
|
+
const resolveBoundedDelta = ({ delta, value, min, max, }) => {
|
|
1858
|
+
if (delta === 0) {
|
|
1859
|
+
return null;
|
|
1860
|
+
}
|
|
1861
|
+
const candidate = value + delta;
|
|
1862
|
+
if (delta < 0) {
|
|
1863
|
+
return value <= min ? null : Math.max(candidate, min);
|
|
1864
|
+
}
|
|
1865
|
+
if (delta > 0) {
|
|
1866
|
+
return value >= max ? null : Math.min(candidate, max);
|
|
1867
|
+
}
|
|
1868
|
+
return null;
|
|
1869
|
+
};
|
|
1870
|
+
|
|
1871
|
+
|
|
1709
1872
|
/***/ }),
|
|
1710
1873
|
|
|
1711
1874
|
/***/ "./src/guards.ts":
|
|
@@ -2288,6 +2451,89 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
2288
2451
|
const camelToWords = (input) => input.replace(/([a-z0-9])([A-Z])/g, '$1 $2');
|
|
2289
2452
|
|
|
2290
2453
|
|
|
2454
|
+
/***/ }),
|
|
2455
|
+
|
|
2456
|
+
/***/ "./src/string/find-char-indices.ts":
|
|
2457
|
+
/*!*****************************************!*\
|
|
2458
|
+
!*** ./src/string/find-char-indices.ts ***!
|
|
2459
|
+
\*****************************************/
|
|
2460
|
+
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
2461
|
+
|
|
2462
|
+
__webpack_require__.r(__webpack_exports__);
|
|
2463
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
2464
|
+
/* harmony export */ findCharIndices: () => (/* binding */ findCharIndices)
|
|
2465
|
+
/* harmony export */ });
|
|
2466
|
+
/**
|
|
2467
|
+
* Finds all zero-based indices where a given single character occurs in a string.
|
|
2468
|
+
*
|
|
2469
|
+
* The string is scanned once from start to end and each matching character position is collected.
|
|
2470
|
+
*
|
|
2471
|
+
* ⚠️ Character comparison is performed at the UTF-16 code unit level
|
|
2472
|
+
* (`String.charCodeAt`), not by Unicode grapheme clusters.
|
|
2473
|
+
*
|
|
2474
|
+
* @param inputString - The string to scan.
|
|
2475
|
+
* @param targetChar - A single character to search for.
|
|
2476
|
+
*
|
|
2477
|
+
* @returns An array of zero-based indices for each occurrence of `targetChar`.
|
|
2478
|
+
* Returns an empty array if no matches are found.
|
|
2479
|
+
*/
|
|
2480
|
+
const findCharIndices = (inputString, targetChar) => {
|
|
2481
|
+
if (inputString.length === 0) {
|
|
2482
|
+
return [];
|
|
2483
|
+
}
|
|
2484
|
+
const targetCode = targetChar.charCodeAt(0);
|
|
2485
|
+
const indices = [];
|
|
2486
|
+
for (let i = 0; i < inputString.length; i++) {
|
|
2487
|
+
if (inputString.charCodeAt(i) === targetCode) {
|
|
2488
|
+
indices.push(i);
|
|
2489
|
+
}
|
|
2490
|
+
}
|
|
2491
|
+
return indices;
|
|
2492
|
+
};
|
|
2493
|
+
|
|
2494
|
+
|
|
2495
|
+
/***/ }),
|
|
2496
|
+
|
|
2497
|
+
/***/ "./src/string/for-each-char.ts":
|
|
2498
|
+
/*!*************************************!*\
|
|
2499
|
+
!*** ./src/string/for-each-char.ts ***!
|
|
2500
|
+
\*************************************/
|
|
2501
|
+
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
2502
|
+
|
|
2503
|
+
__webpack_require__.r(__webpack_exports__);
|
|
2504
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
2505
|
+
/* harmony export */ forEachChar: () => (/* binding */ forEachChar)
|
|
2506
|
+
/* harmony export */ });
|
|
2507
|
+
/**
|
|
2508
|
+
* Iterates over each character of a string and invokes a callback for each one.
|
|
2509
|
+
*
|
|
2510
|
+
* Iteration is performed over UTF-16 code units (not Unicode grapheme clusters).
|
|
2511
|
+
* Characters may be conditionally skipped using an optional predicate.
|
|
2512
|
+
*
|
|
2513
|
+
* @param input - The string to iterate over.
|
|
2514
|
+
* @param onChar - Invoked for each character that is not skipped.
|
|
2515
|
+
* @param shouldSkipChar - Optional predicate; returning `true` skips the character.
|
|
2516
|
+
*/
|
|
2517
|
+
const forEachChar = (input, onChar, shouldSkipChar) => {
|
|
2518
|
+
if (input.length === 0) {
|
|
2519
|
+
return;
|
|
2520
|
+
}
|
|
2521
|
+
const length = input.length;
|
|
2522
|
+
for (let charIndex = 0; charIndex < length; charIndex++) {
|
|
2523
|
+
const char = input[charIndex];
|
|
2524
|
+
const context = {
|
|
2525
|
+
charIndex,
|
|
2526
|
+
prevChar: charIndex > 0 ? input[charIndex - 1] : null,
|
|
2527
|
+
nextChar: charIndex < length - 1 ? input[charIndex + 1] : null,
|
|
2528
|
+
};
|
|
2529
|
+
if (shouldSkipChar?.(char, context)) {
|
|
2530
|
+
continue;
|
|
2531
|
+
}
|
|
2532
|
+
onChar(char, context);
|
|
2533
|
+
}
|
|
2534
|
+
};
|
|
2535
|
+
|
|
2536
|
+
|
|
2291
2537
|
/***/ }),
|
|
2292
2538
|
|
|
2293
2539
|
/***/ "./src/string/index.ts":
|
|
@@ -2300,8 +2546,11 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
2300
2546
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
2301
2547
|
/* harmony export */ camelToDashCase: () => (/* reexport safe */ _camel_to_dash_case__WEBPACK_IMPORTED_MODULE_2__.camelToDashCase),
|
|
2302
2548
|
/* harmony export */ camelToWords: () => (/* reexport safe */ _camel_to_words__WEBPACK_IMPORTED_MODULE_3__.camelToWords),
|
|
2549
|
+
/* harmony export */ findCharIndices: () => (/* reexport safe */ _find_char_indices__WEBPACK_IMPORTED_MODULE_7__.findCharIndices),
|
|
2550
|
+
/* harmony export */ forEachChar: () => (/* reexport safe */ _for_each_char__WEBPACK_IMPORTED_MODULE_8__.forEachChar),
|
|
2303
2551
|
/* harmony export */ isNilOrEmptyString: () => (/* reexport safe */ _is_nil_or_empty_string__WEBPACK_IMPORTED_MODULE_5__.isNilOrEmptyString),
|
|
2304
2552
|
/* harmony export */ isString: () => (/* reexport safe */ _is_string__WEBPACK_IMPORTED_MODULE_0__.isString),
|
|
2553
|
+
/* harmony export */ parseFileName: () => (/* reexport safe */ _parse_file_name__WEBPACK_IMPORTED_MODULE_6__.parseFileName),
|
|
2305
2554
|
/* harmony export */ splitStringIntoWords: () => (/* reexport safe */ _split_string_into_words__WEBPACK_IMPORTED_MODULE_4__.splitStringIntoWords),
|
|
2306
2555
|
/* harmony export */ toKebabCase: () => (/* reexport safe */ _to_kebab_case__WEBPACK_IMPORTED_MODULE_1__.toKebabCase)
|
|
2307
2556
|
/* harmony export */ });
|
|
@@ -2311,6 +2560,12 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
2311
2560
|
/* harmony import */ var _camel_to_words__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./camel-to-words */ "./src/string/camel-to-words.ts");
|
|
2312
2561
|
/* harmony import */ var _split_string_into_words__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./split-string-into-words */ "./src/string/split-string-into-words.ts");
|
|
2313
2562
|
/* harmony import */ var _is_nil_or_empty_string__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./is-nil-or-empty-string */ "./src/string/is-nil-or-empty-string.ts");
|
|
2563
|
+
/* harmony import */ var _parse_file_name__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./parse-file-name */ "./src/string/parse-file-name.ts");
|
|
2564
|
+
/* harmony import */ var _find_char_indices__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./find-char-indices */ "./src/string/find-char-indices.ts");
|
|
2565
|
+
/* harmony import */ var _for_each_char__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./for-each-char */ "./src/string/for-each-char.ts");
|
|
2566
|
+
|
|
2567
|
+
|
|
2568
|
+
|
|
2314
2569
|
|
|
2315
2570
|
|
|
2316
2571
|
|
|
@@ -2370,6 +2625,43 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
2370
2625
|
const isString = (value) => typeof value === 'string';
|
|
2371
2626
|
|
|
2372
2627
|
|
|
2628
|
+
/***/ }),
|
|
2629
|
+
|
|
2630
|
+
/***/ "./src/string/parse-file-name.ts":
|
|
2631
|
+
/*!***************************************!*\
|
|
2632
|
+
!*** ./src/string/parse-file-name.ts ***!
|
|
2633
|
+
\***************************************/
|
|
2634
|
+
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
2635
|
+
|
|
2636
|
+
__webpack_require__.r(__webpack_exports__);
|
|
2637
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
2638
|
+
/* harmony export */ parseFileName: () => (/* binding */ parseFileName)
|
|
2639
|
+
/* harmony export */ });
|
|
2640
|
+
/**
|
|
2641
|
+
* Splits a file name into its base name and extension.
|
|
2642
|
+
*
|
|
2643
|
+
* Special cases:
|
|
2644
|
+
* - Files without a dot return `[fileName, ""]`
|
|
2645
|
+
* - Hidden files like `.gitignore` return `[".gitignore", ""]`
|
|
2646
|
+
* - Names ending with a trailing dot (e.g., `"file."`) return `["file.", ""]`
|
|
2647
|
+
* - Multi-dot names (e.g., `"archive.tar.gz"`) split on the last dot
|
|
2648
|
+
*
|
|
2649
|
+
* @param fileName - The full file name to parse.
|
|
2650
|
+
*
|
|
2651
|
+
* @returns A tuple where:
|
|
2652
|
+
* - index 0 is the base name
|
|
2653
|
+
* - index 1 is the file extension (lowercased), or an empty string if none exists
|
|
2654
|
+
*/
|
|
2655
|
+
const parseFileName = (fileName) => {
|
|
2656
|
+
const lastDotIndex = fileName.lastIndexOf('.');
|
|
2657
|
+
// No dot or leading dot with no extension (e.g., ".gitignore")
|
|
2658
|
+
if (lastDotIndex <= 0 || lastDotIndex === fileName.length - 1) {
|
|
2659
|
+
return [fileName, ''];
|
|
2660
|
+
}
|
|
2661
|
+
return [fileName.slice(0, lastDotIndex), fileName.slice(lastDotIndex + 1).toLowerCase()];
|
|
2662
|
+
};
|
|
2663
|
+
|
|
2664
|
+
|
|
2373
2665
|
/***/ }),
|
|
2374
2666
|
|
|
2375
2667
|
/***/ "./src/string/split-string-into-words.ts":
|
|
@@ -2491,6 +2783,7 @@ var __webpack_exports__ = {};
|
|
|
2491
2783
|
__webpack_require__.r(__webpack_exports__);
|
|
2492
2784
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
2493
2785
|
/* harmony export */ FOCUSABLE_HTML_TAGS: () => (/* reexport safe */ _a11y__WEBPACK_IMPORTED_MODULE_11__.FOCUSABLE_HTML_TAGS),
|
|
2786
|
+
/* harmony export */ applyInertiaStep: () => (/* reexport safe */ _geometry__WEBPACK_IMPORTED_MODULE_9__.applyInertiaStep),
|
|
2494
2787
|
/* harmony export */ assert: () => (/* reexport safe */ _guards__WEBPACK_IMPORTED_MODULE_4__.assert),
|
|
2495
2788
|
/* harmony export */ blobToFile: () => (/* reexport safe */ _file__WEBPACK_IMPORTED_MODULE_7__.blobToFile),
|
|
2496
2789
|
/* harmony export */ calculateCenterOffset: () => (/* reexport safe */ _geometry__WEBPACK_IMPORTED_MODULE_9__.calculateCenterOffset),
|
|
@@ -2513,6 +2806,8 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
2513
2806
|
/* harmony export */ filterParallel: () => (/* reexport safe */ _async__WEBPACK_IMPORTED_MODULE_0__.filterParallel),
|
|
2514
2807
|
/* harmony export */ filterSequential: () => (/* reexport safe */ _async__WEBPACK_IMPORTED_MODULE_0__.filterSequential),
|
|
2515
2808
|
/* harmony export */ findAsync: () => (/* reexport safe */ _async__WEBPACK_IMPORTED_MODULE_0__.findAsync),
|
|
2809
|
+
/* harmony export */ findCharIndices: () => (/* reexport safe */ _string__WEBPACK_IMPORTED_MODULE_1__.findCharIndices),
|
|
2810
|
+
/* harmony export */ forEachChar: () => (/* reexport safe */ _string__WEBPACK_IMPORTED_MODULE_1__.forEachChar),
|
|
2516
2811
|
/* harmony export */ getDOMRectIntersectionRatio: () => (/* reexport safe */ _intersection__WEBPACK_IMPORTED_MODULE_10__.getDOMRectIntersectionRatio),
|
|
2517
2812
|
/* harmony export */ getElementOffsetRect: () => (/* reexport safe */ _dom__WEBPACK_IMPORTED_MODULE_6__.getElementOffsetRect),
|
|
2518
2813
|
/* harmony export */ getFocusableHtmlElements: () => (/* reexport safe */ _a11y__WEBPACK_IMPORTED_MODULE_11__.getFocusableHtmlElements),
|
|
@@ -2559,11 +2854,12 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
2559
2854
|
/* harmony export */ not: () => (/* reexport safe */ _function__WEBPACK_IMPORTED_MODULE_3__.not),
|
|
2560
2855
|
/* harmony export */ once: () => (/* reexport safe */ _function__WEBPACK_IMPORTED_MODULE_3__.once),
|
|
2561
2856
|
/* harmony export */ parse2DMatrix: () => (/* reexport safe */ _dom__WEBPACK_IMPORTED_MODULE_6__.parse2DMatrix),
|
|
2562
|
-
/* harmony export */ parseFileName: () => (/* reexport safe */
|
|
2857
|
+
/* harmony export */ parseFileName: () => (/* reexport safe */ _string__WEBPACK_IMPORTED_MODULE_1__.parseFileName),
|
|
2563
2858
|
/* harmony export */ pipe: () => (/* reexport safe */ _array__WEBPACK_IMPORTED_MODULE_2__.pipe),
|
|
2564
2859
|
/* harmony export */ readFilesFromDataTransfer: () => (/* reexport safe */ _file__WEBPACK_IMPORTED_MODULE_7__.readFilesFromDataTransfer),
|
|
2565
2860
|
/* harmony export */ reduceAsync: () => (/* reexport safe */ _async__WEBPACK_IMPORTED_MODULE_0__.reduceAsync),
|
|
2566
2861
|
/* harmony export */ resolveAxisDelta: () => (/* reexport safe */ _intersection__WEBPACK_IMPORTED_MODULE_10__.resolveAxisDelta),
|
|
2862
|
+
/* harmony export */ resolveBoundedDelta: () => (/* reexport safe */ _geometry__WEBPACK_IMPORTED_MODULE_9__.resolveBoundedDelta),
|
|
2567
2863
|
/* harmony export */ retry: () => (/* reexport safe */ _async__WEBPACK_IMPORTED_MODULE_0__.retry),
|
|
2568
2864
|
/* harmony export */ runParallel: () => (/* reexport safe */ _async__WEBPACK_IMPORTED_MODULE_0__.runParallel),
|
|
2569
2865
|
/* harmony export */ runSequential: () => (/* reexport safe */ _async__WEBPACK_IMPORTED_MODULE_0__.runSequential),
|