0.2.0 - Mid migration

This commit is contained in:
Daniel Mason 2022-04-25 14:47:15 +12:00
parent 139e6a915e
commit 7e38fdbd7d
42393 changed files with 5358157 additions and 62 deletions

22
web/node_modules/string-natural-compare/LICENSE.txt generated vendored Normal file
View file

@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2015-2016 Nathan Woltman
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

109
web/node_modules/string-natural-compare/README.md generated vendored Normal file
View file

@ -0,0 +1,109 @@
# String Natural Compare
[![NPM Version](https://img.shields.io/npm/v/string-natural-compare.svg)](https://www.npmjs.com/package/string-natural-compare)
[![Build Status](https://travis-ci.org/nwoltman/string-natural-compare.svg?branch=master)](https://travis-ci.org/nwoltman/string-natural-compare)
[![Coverage Status](https://coveralls.io/repos/nwoltman/string-natural-compare/badge.svg?branch=master)](https://coveralls.io/r/nwoltman/string-natural-compare?branch=master)
[![Dependencies Status](https://img.shields.io/david/nwoltman/string-natural-compare)](https://david-dm.org/nwoltman/string-natural-compare)
Compare alphanumeric strings the same way a human would, using a natural order algorithm (originally known as the [alphanum algorithm](http://davekoelle.com/alphanum.html)) where numeric characters are sorted based on their numeric values rather than their ASCII values.
```
Standard sorting: Natural order sorting:
img1.png img1.png
img10.png img2.png
img12.png img10.png
img2.png img12.png
```
This module exports a function that returns a number indicating whether one string should come before, after, or is the same as another string.
It can be used directly with the native [`.sort()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) array method.
### Fast and Robust
This module can compare strings containing any size of number and is heavily tested with a custom [benchmark suite](https://github.com/nwoltman/string-natural-compare/tree/master/benchmark) to make sure that it is as fast as possible.
## Installation
```sh
npm install string-natural-compare --save
# or
yarn add string-natural-compare
```
## Usage
#### `naturalCompare(strA, strB[, options])`
+ `strA` (_string_)
+ `strB` (_string_)
+ `options` (_object_) - Optional options object with the following options:
+ `caseInsensitive` (_boolean_) - Set to `true` to compare strings case-insensitively. Default: `false`.
+ `alphabet` (_string_) - A string of characters that define a custom character ordering. Default: `undefined`.
```js
const naturalCompare = require('string-natural-compare');
// Simple, case-sensitive sorting
const files = ['z1.doc', 'z10.doc', 'z17.doc', 'z2.doc', 'z23.doc', 'z3.doc'];
files.sort(naturalCompare);
// -> ['z1.doc', 'z2.doc', 'z3.doc', 'z10.doc', 'z17.doc', 'z23.doc']
// Case-insensitive sorting
const chars = ['B', 'C', 'a', 'd'];
const naturalCompareCI = (a, b) => naturalCompare(a, b, {caseInsensitive: true});
chars.sort(naturalCompareCI);
// -> ['a', 'B', 'C', 'd']
// Note:
['a', 'A'].sort(naturalCompareCI); // -> ['a', 'A']
['A', 'a'].sort(naturalCompareCI); // -> ['A', 'a']
// Compare strings containing large numbers
naturalCompare(
'1165874568735487968325787328996865',
'265812277985321589735871687040841'
);
// -> 1
// (Other inputs with the same ordering as this example may yield a different number > 0)
// Sorting an array of objects
const hotelRooms = [
{street: '350 5th Ave', room: 'A-1021'},
{street: '350 5th Ave', room: 'A-21046-b'}
];
// Sort by street (case-insensitive), then by room (case-sensitive)
hotelRooms.sort((a, b) => (
naturalCompare(a.street, b.street, {caseInsensitive: true}) ||
naturalCompare(a.room, b.room)
));
// When text transformation is needed or when doing a case-insensitive sort on a
// large array of objects, it is best for performance to pre-compute the
// transformed text and store it on the object. This way, the text will not need
// to be transformed for every comparison while sorting.
const cars = [
{make: 'Audi', model: 'R8'},
{make: 'Porsche', model: '911 Turbo S'}
];
// Sort by make, then by model (both case-insensitive)
for (const car of cars) {
car.sortKey = (car.make + ' ' + car.model).toLowerCase();
}
cars.sort((a, b) => naturalCompare(a.sortKey, b.sortKey));
// Using a custom alphabet (Russian alphabet)
const russianOpts = {
alphabet: 'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюя',
};
['Ё', 'А', 'б', 'Б'].sort((a, b) => naturalCompare(a, b, russianOpts));
// -> ['А', 'Б', 'Ё', 'б']
```
**Note:** Putting numbers in the custom alphabet can cause undefined behaviour.

View file

@ -0,0 +1,139 @@
'use strict';
const defaultAlphabetIndexMap = [];
function isNumberCode(code) {
return code >= 48/* '0' */ && code <= 57/* '9' */;
}
function naturalCompare(a, b, opts) {
if (typeof a !== 'string') {
throw new TypeError(`The first argument must be a string. Received type '${typeof a}'`);
}
if (typeof b !== 'string') {
throw new TypeError(`The second argument must be a string. Received type '${typeof b}'`);
}
const lengthA = a.length;
const lengthB = b.length;
let indexA = 0;
let indexB = 0;
let alphabetIndexMap = defaultAlphabetIndexMap;
let firstDifferenceInLeadingZeros = 0;
if (opts) {
if (opts.caseInsensitive) {
a = a.toLowerCase();
b = b.toLowerCase();
}
if (opts.alphabet) {
alphabetIndexMap = buildAlphabetIndexMap(opts.alphabet);
}
}
while (indexA < lengthA && indexB < lengthB) {
let charCodeA = a.charCodeAt(indexA);
let charCodeB = b.charCodeAt(indexB);
if (isNumberCode(charCodeA)) {
if (!isNumberCode(charCodeB)) {
return charCodeA - charCodeB;
}
let numStartA = indexA;
let numStartB = indexB;
while (charCodeA === 48/* '0' */ && ++numStartA < lengthA) {
charCodeA = a.charCodeAt(numStartA);
}
while (charCodeB === 48/* '0' */ && ++numStartB < lengthB) {
charCodeB = b.charCodeAt(numStartB);
}
if (numStartA !== numStartB && firstDifferenceInLeadingZeros === 0) {
firstDifferenceInLeadingZeros = numStartA - numStartB;
}
let numEndA = numStartA;
let numEndB = numStartB;
while (numEndA < lengthA && isNumberCode(a.charCodeAt(numEndA))) {
++numEndA;
}
while (numEndB < lengthB && isNumberCode(b.charCodeAt(numEndB))) {
++numEndB;
}
let difference = numEndA - numStartA - numEndB + numStartB; // numA length - numB length
if (difference !== 0) {
return difference;
}
while (numStartA < numEndA) {
difference = a.charCodeAt(numStartA++) - b.charCodeAt(numStartB++);
if (difference !== 0) {
return difference;
}
}
indexA = numEndA;
indexB = numEndB;
continue;
}
if (charCodeA !== charCodeB) {
if (
charCodeA < alphabetIndexMap.length &&
charCodeB < alphabetIndexMap.length &&
alphabetIndexMap[charCodeA] !== -1 &&
alphabetIndexMap[charCodeB] !== -1
) {
return alphabetIndexMap[charCodeA] - alphabetIndexMap[charCodeB];
}
return charCodeA - charCodeB;
}
++indexA;
++indexB;
}
if (indexA < lengthA) { // `b` is a substring of `a`
return 1;
}
if (indexB < lengthB) { // `a` is a substring of `b`
return -1;
}
return firstDifferenceInLeadingZeros;
}
const alphabetIndexMapCache = {};
function buildAlphabetIndexMap(alphabet) {
const existingMap = alphabetIndexMapCache[alphabet];
if (existingMap !== undefined) {
return existingMap;
}
const indexMap = [];
const maxCharCode = alphabet.split('').reduce((maxCode, char) => {
return Math.max(maxCode, char.charCodeAt(0));
}, 0);
for (let i = 0; i <= maxCharCode; i++) {
indexMap.push(-1);
}
for (let i = 0; i < alphabet.length; i++) {
indexMap[alphabet.charCodeAt(i)] = i;
}
alphabetIndexMapCache[alphabet] = indexMap;
return indexMap;
}
module.exports = naturalCompare;

54
web/node_modules/string-natural-compare/package.json generated vendored Normal file
View file

@ -0,0 +1,54 @@
{
"name": "string-natural-compare",
"version": "3.0.1",
"description": "Compare alphanumeric strings the same way a human would, using a natural order algorithm",
"author": "Nathan Woltman <nwoltman@outlook.com>",
"license": "MIT",
"main": "natural-compare.js",
"files": [
"natural-compare.js"
],
"repository": "github:nwoltman/string-natural-compare",
"homepage": "https://github.com/nwoltman/string-natural-compare",
"bugs": "https://github.com/nwoltman/string-natural-compare/issues",
"keywords": [
"string",
"natural",
"compare",
"comparison",
"order",
"natcmp",
"strnatcmp",
"sort",
"natsort",
"alphanum",
"alphanumeric"
],
"eslintIgnore": [
"benchmark/node_modules/",
"coverage/"
],
"nyc": {
"reporter": [
"html",
"text-summary"
],
"check-coverage": true,
"branches": 100,
"lines": 100,
"statements": 100
},
"devDependencies": {
"@nwoltman/eslint-config": "^0.6.0",
"coveralls": "^3.0.9",
"eslint": "^6.8.0",
"mocha": "^7.0.0",
"nyc": "^15.0.0",
"should": "^13.2.3"
},
"scripts": {
"lint": "eslint .",
"test": "eslint . && nyc mocha",
"coveralls": "nyc report --reporter=text-lcov | coveralls"
}
}