puzzle-lib 1.3.0 → 1.6.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/LICENSE +21 -21
- package/README.md +38 -39
- package/build/src/Braille/BrailleCharacter.d.ts +15 -15
- package/build/src/Braille/BrailleCharacter.js +38 -37
- package/build/src/Braille/BrailleCharacter.js.map +1 -1
- package/build/src/Braille/BrailleData.d.ts +6 -6
- package/build/src/Braille/BrailleData.js +65 -64
- package/build/src/Braille/BrailleData.js.map +1 -1
- package/build/src/Braille/BrailleDot.d.ts +9 -9
- package/build/src/Braille/BrailleDot.js +13 -12
- package/build/src/Braille/BrailleDot.js.map +1 -1
- package/build/src/Braille/BrailleEncoding.d.ts +54 -54
- package/build/src/Braille/BrailleEncoding.js +65 -64
- package/build/src/Braille/BrailleEncoding.js.map +1 -1
- package/build/src/Braille/BrailleStream.d.ts +18 -18
- package/build/src/Braille/BrailleStream.js +75 -74
- package/build/src/Braille/BrailleStream.js.map +1 -1
- package/build/src/Cipher/AutoKeyString.d.ts +4 -4
- package/build/src/Cipher/AutoKeyString.js +34 -33
- package/build/src/Cipher/AutoKeyString.js.map +1 -1
- package/build/src/Cipher/CaesarString.d.ts +8 -8
- package/build/src/Cipher/CaesarString.js +31 -30
- package/build/src/Cipher/CaesarString.js.map +1 -1
- package/build/src/Cipher/CaesarUtils.d.ts +13 -13
- package/build/src/Cipher/CaesarUtils.js +57 -56
- package/build/src/Cipher/CaesarUtils.js.map +1 -1
- package/build/src/Cipher/KeyedCipherStringBase.d.ts +12 -12
- package/build/src/Cipher/KeyedCipherStringBase.js +28 -27
- package/build/src/Cipher/KeyedCipherStringBase.js.map +1 -1
- package/build/src/Cipher/VigenereString.d.ts +4 -4
- package/build/src/Cipher/VigenereString.js +21 -20
- package/build/src/Cipher/VigenereString.js.map +1 -1
- package/build/src/Common/CharacterImage.d.ts +6 -6
- package/build/src/Common/CharacterImage.js +10 -9
- package/build/src/Common/CharacterImage.js.map +1 -1
- package/build/src/Common/EncodingCategory.d.ts +8 -8
- package/build/src/Common/EncodingCategory.js +12 -11
- package/build/src/Common/EncodingCategory.js.map +1 -1
- package/build/src/Common/EncodingCharacterBase.d.ts +23 -23
- package/build/src/Common/EncodingCharacterBase.js +52 -51
- package/build/src/Common/EncodingCharacterBase.js.map +1 -1
- package/build/src/Common/EncodingDataBase.d.ts +7 -7
- package/build/src/Common/EncodingDataBase.js +29 -28
- package/build/src/Common/EncodingDataBase.js.map +1 -1
- package/build/src/Common/EncodingEntry.d.ts +8 -8
- package/build/src/Common/EncodingEntry.js +14 -13
- package/build/src/Common/EncodingEntry.js.map +1 -1
- package/build/src/Common/EncodingLookupResult.d.ts +6 -6
- package/build/src/Common/EncodingLookupResult.js +13 -12
- package/build/src/Common/EncodingLookupResult.js.map +1 -1
- package/build/src/Common/Helpers.d.ts +4 -4
- package/build/src/Common/Helpers.js +16 -15
- package/build/src/Common/Helpers.js.map +1 -1
- package/build/src/Common/InlineSvg.d.ts +7 -7
- package/build/src/Common/InlineSvg.js +14 -13
- package/build/src/Common/InlineSvg.js.map +1 -1
- package/build/src/Conversion/CharacterAutoConvert.d.ts +10 -7
- package/build/src/Conversion/CharacterAutoConvert.js +88 -80
- package/build/src/Conversion/CharacterAutoConvert.js.map +1 -1
- package/build/src/Conversion/CharacterConversion.d.ts +8 -8
- package/build/src/Conversion/CharacterConversion.js +50 -49
- package/build/src/Conversion/CharacterConversion.js.map +1 -1
- package/build/src/Conversion/CharacterEncoding.d.ts +9 -8
- package/build/src/Conversion/CharacterEncoding.js +13 -11
- package/build/src/Conversion/CharacterEncoding.js.map +1 -1
- package/build/src/Conversion/CharacterTableEntry.d.ts +10 -10
- package/build/src/Conversion/CharacterTableEntry.js +19 -18
- package/build/src/Conversion/CharacterTableEntry.js.map +1 -1
- package/build/src/Conversion/SignificantFigures.d.ts +7 -7
- package/build/src/Conversion/SignificantFigures.js +50 -49
- package/build/src/Conversion/SignificantFigures.js.map +1 -1
- package/build/src/Conversion/StringAutoConvert.d.ts +6 -6
- package/build/src/Conversion/StringAutoConvert.js +46 -45
- package/build/src/Conversion/StringAutoConvert.js.map +1 -1
- package/build/src/Morse/MorseCharacter.d.ts +22 -22
- package/build/src/Morse/MorseCharacter.js +96 -95
- package/build/src/Morse/MorseCharacter.js.map +1 -1
- package/build/src/Morse/MorseData.d.ts +6 -6
- package/build/src/Morse/MorseData.js +70 -69
- package/build/src/Morse/MorseData.js.map +1 -1
- package/build/src/Morse/MorseEncoding.d.ts +59 -59
- package/build/src/Morse/MorseEncoding.js +94 -93
- package/build/src/Morse/MorseEncoding.js.map +1 -1
- package/build/src/Morse/MorseString.d.ts +10 -10
- package/build/src/Morse/MorseString.js +66 -65
- package/build/src/Morse/MorseString.js.map +1 -1
- package/build/src/Nato/NatoCharacter.d.ts +5 -5
- package/build/src/Nato/NatoCharacter.js +10 -9
- package/build/src/Nato/NatoCharacter.js.map +1 -1
- package/build/src/Nato/NatoData.d.ts +7 -7
- package/build/src/Nato/NatoData.js +51 -50
- package/build/src/Nato/NatoData.js.map +1 -1
- package/build/src/NavalFlags/NavalFlags.d.ts +7 -7
- package/build/src/NavalFlags/NavalFlags.js +52 -50
- package/build/src/NavalFlags/NavalFlags.js.map +1 -1
- package/build/src/Resistor/Resistor.d.ts +24 -24
- package/build/src/Resistor/Resistor.js +86 -85
- package/build/src/Resistor/Resistor.js.map +1 -1
- package/build/src/Resistor/ResistorColorEntry.d.ts +12 -12
- package/build/src/Resistor/ResistorColorEntry.js +31 -30
- package/build/src/Resistor/ResistorColorEntry.js.map +1 -1
- package/build/src/Semaphore/SemaphoreCharacter.d.ts +20 -20
- package/build/src/Semaphore/SemaphoreCharacter.js +75 -74
- package/build/src/Semaphore/SemaphoreCharacter.js.map +1 -1
- package/build/src/Semaphore/SemaphoreData.d.ts +6 -6
- package/build/src/Semaphore/SemaphoreData.js +53 -52
- package/build/src/Semaphore/SemaphoreData.js.map +1 -1
- package/build/src/Semaphore/SemaphoreDegrees.d.ts +5 -5
- package/build/src/Semaphore/SemaphoreDegrees.js +26 -25
- package/build/src/Semaphore/SemaphoreDegrees.js.map +1 -1
- package/build/src/Semaphore/SemaphoreDirection.d.ts +11 -11
- package/build/src/Semaphore/SemaphoreDirection.js +15 -14
- package/build/src/Semaphore/SemaphoreDirection.js.map +1 -1
- package/build/src/Semaphore/SemaphoreEncoding.d.ts +40 -40
- package/build/src/Semaphore/SemaphoreEncoding.js +47 -46
- package/build/src/Semaphore/SemaphoreEncoding.js.map +1 -1
- package/build/src/Semaphore/SemaphoreStream.d.ts +17 -17
- package/build/src/Semaphore/SemaphoreStream.js +72 -71
- package/build/src/Semaphore/SemaphoreStream.js.map +1 -1
- package/build/src/WordSearch/Point.d.ts +4 -4
- package/build/src/WordSearch/Point.js +2 -2
- package/build/src/WordSearch/Result.d.ts +6 -6
- package/build/src/WordSearch/Result.js +10 -9
- package/build/src/WordSearch/Result.js.map +1 -1
- package/build/src/WordSearch/WordSearchDirection.d.ts +6 -6
- package/build/src/WordSearch/WordSearchDirection.js +10 -9
- package/build/src/WordSearch/WordSearchDirection.js.map +1 -1
- package/build/src/WordSearch/WordSearchSolver.d.ts +27 -18
- package/build/src/WordSearch/WordSearchSolver.js +222 -171
- package/build/src/WordSearch/WordSearchSolver.js.map +1 -1
- package/build/src/index.d.ts +35 -35
- package/build/src/index.js +72 -70
- package/build/src/index.js.map +1 -1
- package/package.json +40 -39
- package/src/Braille/BrailleCharacter.ts +49 -0
- package/src/Braille/BrailleData.ts +131 -0
- package/src/Braille/BrailleDot.ts +9 -0
- package/src/Braille/BrailleEncoding.ts +144 -0
- package/src/Braille/BrailleStream.ts +87 -0
- package/src/Cipher/AutoKeyString.ts +35 -0
- package/src/Cipher/CaesarString.ts +38 -0
- package/src/Cipher/CaesarUtils.ts +69 -0
- package/src/Cipher/KeyedCipherStringBase.ts +35 -0
- package/src/Cipher/VigenereString.ts +21 -0
- package/src/Common/CharacterImage.ts +11 -0
- package/src/Common/EncodingCategory.ts +10 -0
- package/src/Common/EncodingCharacterBase.ts +72 -0
- package/src/Common/EncodingDataBase.ts +31 -0
- package/src/Common/EncodingEntry.ts +17 -0
- package/src/Common/EncodingLookupResult.ts +10 -0
- package/src/Common/Helpers.ts +13 -0
- package/src/Common/InlineSvg.ts +15 -0
- package/src/Conversion/CharacterAutoConvert.ts +108 -0
- package/src/Conversion/CharacterConversion.ts +89 -0
- package/src/Conversion/CharacterEncoding.ts +9 -0
- package/src/Conversion/CharacterTableEntry.ts +23 -0
- package/src/Conversion/SignificantFigures.ts +55 -0
- package/src/Conversion/StringAutoConvert.ts +56 -0
- package/src/Morse/MorseCharacter.ts +112 -0
- package/src/Morse/MorseData.ts +143 -0
- package/src/Morse/MorseEncoding.ts +98 -0
- package/src/Morse/MorseString.ts +106 -0
- package/src/Nato/NatoCharacter.ts +9 -0
- package/src/Nato/NatoData.ts +49 -0
- package/src/NavalFlags/LICENSE +7 -0
- package/src/NavalFlags/NavalFlags.ts +293 -0
- package/src/Resistor/Resistor.ts +135 -0
- package/src/Resistor/ResistorColorEntry.ts +43 -0
- package/src/Semaphore/SemaphoreCharacter.ts +107 -0
- package/src/Semaphore/SemaphoreData.ts +58 -0
- package/src/Semaphore/SemaphoreDegrees.ts +26 -0
- package/src/Semaphore/SemaphoreDirection.ts +11 -0
- package/src/Semaphore/SemaphoreEncoding.ts +48 -0
- package/src/Semaphore/SemaphoreStream.ts +89 -0
- package/src/WordSearch/Point.ts +4 -0
- package/src/WordSearch/Result.ts +10 -0
- package/src/WordSearch/WordSearchDirection.ts +6 -0
- package/src/WordSearch/WordSearchSolver.ts +271 -0
- package/src/index.ts +38 -0
- package/src/trie-prefix-tree.d.ts +70 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export class CharacterTableEntry {
|
|
2
|
+
private static getValue(value: number, base: number, maxValue: number) {
|
|
3
|
+
return value
|
|
4
|
+
.toString(base)
|
|
5
|
+
.padStart(Math.ceil(Math.log(maxValue) / Math.log(base)), '0');
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
readonly character: string;
|
|
9
|
+
readonly binary: string;
|
|
10
|
+
readonly ternary: string;
|
|
11
|
+
readonly octal: string;
|
|
12
|
+
readonly decimal: string;
|
|
13
|
+
readonly hexadecimal: string;
|
|
14
|
+
|
|
15
|
+
constructor(character: string, value: number, maxValue: number) {
|
|
16
|
+
this.character = character;
|
|
17
|
+
this.binary = CharacterTableEntry.getValue(value, 2, maxValue);
|
|
18
|
+
this.ternary = CharacterTableEntry.getValue(value, 3, maxValue);
|
|
19
|
+
this.octal = CharacterTableEntry.getValue(value, 8, maxValue);
|
|
20
|
+
this.decimal = CharacterTableEntry.getValue(value, 10, maxValue);
|
|
21
|
+
this.hexadecimal = CharacterTableEntry.getValue(value, 16, maxValue);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export class SignificantFigures {
|
|
2
|
+
static ceil(num: number, sigFigs: number) {
|
|
3
|
+
return this.roundInternal(Math.ceil, num, sigFigs);
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
static floor(num: number, sigFigs: number) {
|
|
7
|
+
return this.roundInternal(Math.floor, num, sigFigs);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
static round(num: number, sigFigs: number) {
|
|
11
|
+
return this.roundInternal(Math.round, num, sigFigs);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
private static roundInternal(
|
|
15
|
+
func: (num: number) => number,
|
|
16
|
+
num: number,
|
|
17
|
+
sigFigs: number
|
|
18
|
+
) {
|
|
19
|
+
if (num === 0) {
|
|
20
|
+
return num;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (sigFigs <= 0) {
|
|
24
|
+
throw new RangeError('sigFigs value must be positive');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const factor = this.getFactor(num, sigFigs);
|
|
28
|
+
|
|
29
|
+
if (factor > 0) {
|
|
30
|
+
return func(num / factor) * factor;
|
|
31
|
+
} else if (factor < 0) {
|
|
32
|
+
const absFactor = Math.abs(factor);
|
|
33
|
+
return func(num * absFactor) / absFactor;
|
|
34
|
+
} else {
|
|
35
|
+
return num;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
private static getFactor(num: number, sigFigs: number) {
|
|
40
|
+
const absNum = Math.abs(num);
|
|
41
|
+
let digits = 0;
|
|
42
|
+
|
|
43
|
+
if (absNum < 1) {
|
|
44
|
+
digits = -sigFigs;
|
|
45
|
+
} else {
|
|
46
|
+
digits = Math.ceil(Math.log(absNum) / Math.log(10)) - sigFigs;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (digits < 0) {
|
|
50
|
+
return -Math.pow(10, Math.abs(digits));
|
|
51
|
+
} else {
|
|
52
|
+
return Math.pow(10, digits);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import {CharacterAutoConvert} from './CharacterAutoConvert';
|
|
2
|
+
import {CharacterEncoding} from './CharacterEncoding';
|
|
3
|
+
|
|
4
|
+
export class StringAutoConvert {
|
|
5
|
+
static convertString(input: string, homogeneous: boolean) {
|
|
6
|
+
const split = this.splitString(input);
|
|
7
|
+
|
|
8
|
+
if (homogeneous) {
|
|
9
|
+
const encoding = this.determineStringEncoding(input);
|
|
10
|
+
return split.reduce(
|
|
11
|
+
(result, letter) =>
|
|
12
|
+
result + CharacterAutoConvert.convertCharacter(letter, encoding),
|
|
13
|
+
''
|
|
14
|
+
);
|
|
15
|
+
} else {
|
|
16
|
+
return split.reduce(
|
|
17
|
+
(result, letter) =>
|
|
18
|
+
result + CharacterAutoConvert.convertCharacter(letter),
|
|
19
|
+
''
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
static determineStringEncoding(input: string): CharacterEncoding {
|
|
25
|
+
const encodingCount: {[index: number]: number} = {};
|
|
26
|
+
const parsed = this.splitString(input);
|
|
27
|
+
const encodingKeys: number[] = [];
|
|
28
|
+
|
|
29
|
+
for (const letter of parsed) {
|
|
30
|
+
const charEncoding =
|
|
31
|
+
CharacterAutoConvert.determineCharacterEncoding(letter);
|
|
32
|
+
if (!encodingCount[charEncoding]) {
|
|
33
|
+
encodingCount[charEncoding] = 1;
|
|
34
|
+
encodingKeys.push(charEncoding);
|
|
35
|
+
} else {
|
|
36
|
+
encodingCount[charEncoding] = encodingCount[charEncoding] + 1;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
let maxCount = 0;
|
|
41
|
+
let maxEncoding: number;
|
|
42
|
+
maxEncoding = CharacterEncoding.None;
|
|
43
|
+
|
|
44
|
+
for (const encoding of encodingKeys) {
|
|
45
|
+
if (encodingCount[encoding] > maxCount) {
|
|
46
|
+
maxCount = encodingCount[encoding];
|
|
47
|
+
maxEncoding = encoding;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return maxEncoding;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
static splitString(input: string): string[] {
|
|
54
|
+
return input.split(' ').filter(item => item !== '');
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import {EncodingCategory} from '../Common/EncodingCategory';
|
|
2
|
+
import {EncodingCharacterBase} from '../Common/EncodingCharacterBase';
|
|
3
|
+
import {Helpers} from '../Common/Helpers';
|
|
4
|
+
import {MorseData} from './MorseData';
|
|
5
|
+
import {MorseEncoding} from './MorseEncoding';
|
|
6
|
+
|
|
7
|
+
const MORSE_BITMASK = MorseEncoding.Dot | MorseEncoding.Dash;
|
|
8
|
+
|
|
9
|
+
export class MorseCharacter extends EncodingCharacterBase<MorseEncoding> {
|
|
10
|
+
static readonly DOT: string = '.';
|
|
11
|
+
static readonly DASH: string = '-';
|
|
12
|
+
// Character which may not appear in morse and is reserved for use by this class
|
|
13
|
+
static readonly RESERVED_DIVIDER: string = 'A';
|
|
14
|
+
|
|
15
|
+
static toMorseString(encoding: MorseEncoding) {
|
|
16
|
+
let morseChars = '';
|
|
17
|
+
|
|
18
|
+
while (encoding !== MorseEncoding.None) {
|
|
19
|
+
if ((encoding & MORSE_BITMASK) === MorseEncoding.Dot) {
|
|
20
|
+
morseChars += MorseCharacter.DOT;
|
|
21
|
+
} else if ((encoding & MORSE_BITMASK) === MorseEncoding.Dash) {
|
|
22
|
+
morseChars += MorseCharacter.DASH;
|
|
23
|
+
} else {
|
|
24
|
+
throw new Error('Invalid morse bits');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
encoding >>>= 2;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return morseChars;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
static parseMorseString(morse: string): MorseEncoding {
|
|
34
|
+
let bits = MorseEncoding.None;
|
|
35
|
+
|
|
36
|
+
for (let i = morse.length - 1; i >= 0; i--) {
|
|
37
|
+
const ch = morse[i];
|
|
38
|
+
if (ch === MorseCharacter.DOT) {
|
|
39
|
+
bits |= MorseEncoding.Dot;
|
|
40
|
+
} else if (ch === MorseCharacter.DASH) {
|
|
41
|
+
bits |= MorseEncoding.Dash;
|
|
42
|
+
} else {
|
|
43
|
+
throw new Error('Invalid morse character');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
bits <<= 2;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
bits >>>= 2;
|
|
50
|
+
return bits;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
private _morse: string;
|
|
54
|
+
|
|
55
|
+
constructor(str = '', category: EncodingCategory = EncodingCategory.All) {
|
|
56
|
+
super(MorseData.instance, category);
|
|
57
|
+
|
|
58
|
+
this._morse = str;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
get morseString() {
|
|
62
|
+
return this._morse;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
set morseString(value: string) {
|
|
66
|
+
this._morse = value;
|
|
67
|
+
this.invalidateLookup();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
backspace() {
|
|
71
|
+
if (this._morse.length > 0) {
|
|
72
|
+
this._morse = this._morse.substring(0, this._morse.length - 1);
|
|
73
|
+
this.invalidateLookup();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
dot() {
|
|
78
|
+
this._morse += MorseCharacter.DOT;
|
|
79
|
+
this.invalidateLookup();
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
dash() {
|
|
83
|
+
this._morse += MorseCharacter.DASH;
|
|
84
|
+
this.invalidateLookup();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
invertDotsAndDashes() {
|
|
88
|
+
// Replace dots with a placeholder, dashes with dots, then placeholders with dashes
|
|
89
|
+
Helpers.assert(this._morse.indexOf(MorseCharacter.RESERVED_DIVIDER) < 0);
|
|
90
|
+
this._morse = this._morse
|
|
91
|
+
.replace(/\./g, 'A')
|
|
92
|
+
.replace(/-/g, MorseCharacter.DOT)
|
|
93
|
+
.replace(/A/g, MorseCharacter.DASH);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
reverse() {
|
|
97
|
+
this._morse = this._morse.split('').reverse().join('');
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
protected onClear() {
|
|
101
|
+
this._morse = '';
|
|
102
|
+
this.invalidateLookup();
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
protected onEmpty() {
|
|
106
|
+
return this._morse.length === 0;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
protected getEncoding() {
|
|
110
|
+
return MorseCharacter.parseMorseString(this._morse);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import {EncodingCategory} from '../Common/EncodingCategory';
|
|
2
|
+
import {EncodingDataBase} from '../Common/EncodingDataBase';
|
|
3
|
+
import {MorseEncoding} from './MorseEncoding';
|
|
4
|
+
|
|
5
|
+
export class MorseData extends EncodingDataBase<MorseEncoding> {
|
|
6
|
+
static readonly instance: MorseData = new MorseData();
|
|
7
|
+
|
|
8
|
+
constructor() {
|
|
9
|
+
super();
|
|
10
|
+
|
|
11
|
+
// Letters
|
|
12
|
+
this.addToList(MorseEncoding.LetterA, EncodingCategory.Letter, 'A');
|
|
13
|
+
this.addToList(MorseEncoding.LetterB, EncodingCategory.Letter, 'B');
|
|
14
|
+
this.addToList(MorseEncoding.LetterC, EncodingCategory.Letter, 'C');
|
|
15
|
+
this.addToList(MorseEncoding.LetterD, EncodingCategory.Letter, 'D');
|
|
16
|
+
this.addToList(MorseEncoding.LetterE, EncodingCategory.Letter, 'E');
|
|
17
|
+
this.addToList(MorseEncoding.LetterF, EncodingCategory.Letter, 'F');
|
|
18
|
+
this.addToList(MorseEncoding.LetterG, EncodingCategory.Letter, 'G');
|
|
19
|
+
this.addToList(MorseEncoding.LetterH, EncodingCategory.Letter, 'H');
|
|
20
|
+
this.addToList(MorseEncoding.LetterI, EncodingCategory.Letter, 'I');
|
|
21
|
+
this.addToList(MorseEncoding.LetterJ, EncodingCategory.Letter, 'J');
|
|
22
|
+
this.addToList(MorseEncoding.LetterK, EncodingCategory.Letter, 'K');
|
|
23
|
+
this.addToList(MorseEncoding.LetterL, EncodingCategory.Letter, 'L');
|
|
24
|
+
this.addToList(MorseEncoding.LetterM, EncodingCategory.Letter, 'M');
|
|
25
|
+
this.addToList(MorseEncoding.LetterN, EncodingCategory.Letter, 'N');
|
|
26
|
+
this.addToList(MorseEncoding.LetterO, EncodingCategory.Letter, 'O');
|
|
27
|
+
this.addToList(MorseEncoding.LetterP, EncodingCategory.Letter, 'P');
|
|
28
|
+
this.addToList(MorseEncoding.LetterQ, EncodingCategory.Letter, 'Q');
|
|
29
|
+
this.addToList(MorseEncoding.LetterR, EncodingCategory.Letter, 'R');
|
|
30
|
+
this.addToList(MorseEncoding.LetterS, EncodingCategory.Letter, 'S');
|
|
31
|
+
this.addToList(MorseEncoding.LetterT, EncodingCategory.Letter, 'T');
|
|
32
|
+
this.addToList(MorseEncoding.LetterU, EncodingCategory.Letter, 'U');
|
|
33
|
+
this.addToList(MorseEncoding.LetterV, EncodingCategory.Letter, 'V');
|
|
34
|
+
this.addToList(MorseEncoding.LetterW, EncodingCategory.Letter, 'W');
|
|
35
|
+
this.addToList(MorseEncoding.LetterX, EncodingCategory.Letter, 'X');
|
|
36
|
+
this.addToList(MorseEncoding.LetterY, EncodingCategory.Letter, 'Y');
|
|
37
|
+
this.addToList(MorseEncoding.LetterZ, EncodingCategory.Letter, 'Z');
|
|
38
|
+
|
|
39
|
+
// Numbers
|
|
40
|
+
this.addToList(MorseEncoding.Number0, EncodingCategory.Number, '0');
|
|
41
|
+
this.addToList(MorseEncoding.Number1, EncodingCategory.Number, '1');
|
|
42
|
+
this.addToList(MorseEncoding.Number2, EncodingCategory.Number, '2');
|
|
43
|
+
this.addToList(MorseEncoding.Number3, EncodingCategory.Number, '3');
|
|
44
|
+
this.addToList(MorseEncoding.Number4, EncodingCategory.Number, '4');
|
|
45
|
+
this.addToList(MorseEncoding.Number5, EncodingCategory.Number, '5');
|
|
46
|
+
this.addToList(MorseEncoding.Number6, EncodingCategory.Number, '6');
|
|
47
|
+
this.addToList(MorseEncoding.Number7, EncodingCategory.Number, '7');
|
|
48
|
+
this.addToList(MorseEncoding.Number8, EncodingCategory.Number, '8');
|
|
49
|
+
this.addToList(MorseEncoding.Number9, EncodingCategory.Number, '9');
|
|
50
|
+
|
|
51
|
+
// Punctuation
|
|
52
|
+
this.addToList(
|
|
53
|
+
MorseEncoding.PunctuationPeriod,
|
|
54
|
+
EncodingCategory.Punctuation,
|
|
55
|
+
'.'
|
|
56
|
+
);
|
|
57
|
+
this.addToList(
|
|
58
|
+
MorseEncoding.PunctuationComma,
|
|
59
|
+
EncodingCategory.Punctuation,
|
|
60
|
+
','
|
|
61
|
+
);
|
|
62
|
+
this.addToList(
|
|
63
|
+
MorseEncoding.PunctuationQuestionMark,
|
|
64
|
+
EncodingCategory.Punctuation,
|
|
65
|
+
'?'
|
|
66
|
+
);
|
|
67
|
+
this.addToList(
|
|
68
|
+
MorseEncoding.PunctuationApostrophe,
|
|
69
|
+
EncodingCategory.Punctuation,
|
|
70
|
+
"'"
|
|
71
|
+
);
|
|
72
|
+
this.addToList(
|
|
73
|
+
MorseEncoding.PunctuationExclamationPoint,
|
|
74
|
+
EncodingCategory.Punctuation,
|
|
75
|
+
'!'
|
|
76
|
+
);
|
|
77
|
+
this.addToList(
|
|
78
|
+
MorseEncoding.PunctuationForwardSlash,
|
|
79
|
+
EncodingCategory.Punctuation,
|
|
80
|
+
'/'
|
|
81
|
+
);
|
|
82
|
+
this.addToList(
|
|
83
|
+
MorseEncoding.PunctuationOpenParenthesis,
|
|
84
|
+
EncodingCategory.Punctuation,
|
|
85
|
+
'('
|
|
86
|
+
);
|
|
87
|
+
this.addToList(
|
|
88
|
+
MorseEncoding.PunctuationCloseParenthesis,
|
|
89
|
+
EncodingCategory.Punctuation,
|
|
90
|
+
')'
|
|
91
|
+
);
|
|
92
|
+
this.addToList(
|
|
93
|
+
MorseEncoding.PunctuationAmpersand,
|
|
94
|
+
EncodingCategory.Punctuation,
|
|
95
|
+
'&'
|
|
96
|
+
);
|
|
97
|
+
this.addToList(
|
|
98
|
+
MorseEncoding.PunctuationColon,
|
|
99
|
+
EncodingCategory.Punctuation,
|
|
100
|
+
':'
|
|
101
|
+
);
|
|
102
|
+
this.addToList(
|
|
103
|
+
MorseEncoding.PunctuationSemicolon,
|
|
104
|
+
EncodingCategory.Punctuation,
|
|
105
|
+
';'
|
|
106
|
+
);
|
|
107
|
+
this.addToList(
|
|
108
|
+
MorseEncoding.PunctuationDoubleDash,
|
|
109
|
+
EncodingCategory.Punctuation,
|
|
110
|
+
'='
|
|
111
|
+
);
|
|
112
|
+
this.addToList(
|
|
113
|
+
MorseEncoding.PunctuationPlusSign,
|
|
114
|
+
EncodingCategory.Punctuation,
|
|
115
|
+
'+'
|
|
116
|
+
);
|
|
117
|
+
this.addToList(
|
|
118
|
+
MorseEncoding.PunctuationHyphen,
|
|
119
|
+
EncodingCategory.Punctuation,
|
|
120
|
+
'-'
|
|
121
|
+
);
|
|
122
|
+
this.addToList(
|
|
123
|
+
MorseEncoding.PunctuationUnderscore,
|
|
124
|
+
EncodingCategory.Punctuation,
|
|
125
|
+
'_'
|
|
126
|
+
);
|
|
127
|
+
this.addToList(
|
|
128
|
+
MorseEncoding.PunctuationQuotationMark,
|
|
129
|
+
EncodingCategory.Punctuation,
|
|
130
|
+
'"'
|
|
131
|
+
);
|
|
132
|
+
this.addToList(
|
|
133
|
+
MorseEncoding.PunctuationDollarSign,
|
|
134
|
+
EncodingCategory.Punctuation,
|
|
135
|
+
'$'
|
|
136
|
+
);
|
|
137
|
+
this.addToList(
|
|
138
|
+
MorseEncoding.PunctuationAtSign,
|
|
139
|
+
EncodingCategory.Punctuation,
|
|
140
|
+
'@'
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// The encoding for morse is much less straightforward than the others. The dots
|
|
2
|
+
// and dashes each use two bits of the integer starting with the least-
|
|
3
|
+
// significant bit.
|
|
4
|
+
//
|
|
5
|
+
// Example:
|
|
6
|
+
//
|
|
7
|
+
// 'F' -> ..-.
|
|
8
|
+
//
|
|
9
|
+
// Which encodes as:
|
|
10
|
+
//
|
|
11
|
+
// 01 01 10 01
|
|
12
|
+
// . . - .
|
|
13
|
+
//
|
|
14
|
+
// Since it's packed starting with the LSB, the resulting number is reversed:
|
|
15
|
+
//
|
|
16
|
+
// 01100101 -> 0x65
|
|
17
|
+
//
|
|
18
|
+
|
|
19
|
+
function packMorse(...args: MorseEncoding[]) {
|
|
20
|
+
let value = MorseEncoding.None;
|
|
21
|
+
let shift = 0;
|
|
22
|
+
|
|
23
|
+
for (let arg of args) {
|
|
24
|
+
arg <<= shift;
|
|
25
|
+
value |= arg;
|
|
26
|
+
shift += 2;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return value;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export enum MorseEncoding {
|
|
33
|
+
None = 0,
|
|
34
|
+
|
|
35
|
+
// Primitives
|
|
36
|
+
Dot = 0x1,
|
|
37
|
+
Dash = 0x2,
|
|
38
|
+
|
|
39
|
+
// Letters
|
|
40
|
+
LetterA = packMorse(Dot, Dash),
|
|
41
|
+
LetterB = packMorse(Dash, Dot, Dot, Dot),
|
|
42
|
+
LetterC = packMorse(Dash, Dot, Dash, Dot),
|
|
43
|
+
LetterD = packMorse(Dash, Dot, Dot),
|
|
44
|
+
LetterE = packMorse(Dot),
|
|
45
|
+
LetterF = packMorse(Dot, Dot, Dash, Dot),
|
|
46
|
+
LetterG = packMorse(Dash, Dash, Dot),
|
|
47
|
+
LetterH = packMorse(Dot, Dot, Dot, Dot),
|
|
48
|
+
LetterI = packMorse(Dot, Dot),
|
|
49
|
+
LetterJ = packMorse(Dot, Dash, Dash, Dash),
|
|
50
|
+
LetterK = packMorse(Dash, Dot, Dash),
|
|
51
|
+
LetterL = packMorse(Dot, Dash, Dot, Dot),
|
|
52
|
+
LetterM = packMorse(Dash, Dash),
|
|
53
|
+
LetterN = packMorse(Dash, Dot),
|
|
54
|
+
LetterO = packMorse(Dash, Dash, Dash),
|
|
55
|
+
LetterP = packMorse(Dot, Dash, Dash, Dot),
|
|
56
|
+
LetterQ = packMorse(Dash, Dash, Dot, Dash),
|
|
57
|
+
LetterR = packMorse(Dot, Dash, Dot),
|
|
58
|
+
LetterS = packMorse(Dot, Dot, Dot),
|
|
59
|
+
LetterT = packMorse(Dash),
|
|
60
|
+
LetterU = packMorse(Dot, Dot, Dash),
|
|
61
|
+
LetterV = packMorse(Dot, Dot, Dot, Dash),
|
|
62
|
+
LetterW = packMorse(Dot, Dash, Dash),
|
|
63
|
+
LetterX = packMorse(Dash, Dot, Dot, Dash),
|
|
64
|
+
LetterY = packMorse(Dash, Dot, Dash, Dash),
|
|
65
|
+
LetterZ = packMorse(Dash, Dash, Dot, Dot),
|
|
66
|
+
|
|
67
|
+
// Numbers
|
|
68
|
+
Number0 = packMorse(Dash, Dash, Dash, Dash, Dash),
|
|
69
|
+
Number1 = packMorse(Dot, Dash, Dash, Dash, Dash),
|
|
70
|
+
Number2 = packMorse(Dot, Dot, Dash, Dash, Dash),
|
|
71
|
+
Number3 = packMorse(Dot, Dot, Dot, Dash, Dash),
|
|
72
|
+
Number4 = packMorse(Dot, Dot, Dot, Dot, Dash),
|
|
73
|
+
Number5 = packMorse(Dot, Dot, Dot, Dot, Dot),
|
|
74
|
+
Number6 = packMorse(Dash, Dot, Dot, Dot, Dot),
|
|
75
|
+
Number7 = packMorse(Dash, Dash, Dot, Dot, Dot),
|
|
76
|
+
Number8 = packMorse(Dash, Dash, Dash, Dot, Dot),
|
|
77
|
+
Number9 = packMorse(Dash, Dash, Dash, Dash, Dot),
|
|
78
|
+
|
|
79
|
+
// Punctuation
|
|
80
|
+
PunctuationPeriod = packMorse(Dot, Dash, Dot, Dash, Dot, Dash),
|
|
81
|
+
PunctuationComma = packMorse(Dash, Dash, Dot, Dot, Dash, Dash),
|
|
82
|
+
PunctuationQuestionMark = packMorse(Dot, Dot, Dash, Dash, Dot, Dot),
|
|
83
|
+
PunctuationApostrophe = packMorse(Dot, Dash, Dash, Dash, Dash, Dot),
|
|
84
|
+
PunctuationExclamationPoint = packMorse(Dash, Dot, Dash, Dot, Dash, Dash),
|
|
85
|
+
PunctuationForwardSlash = packMorse(Dash, Dot, Dot, Dash, Dot),
|
|
86
|
+
PunctuationOpenParenthesis = packMorse(Dash, Dot, Dash, Dash, Dot),
|
|
87
|
+
PunctuationCloseParenthesis = packMorse(Dash, Dot, Dash, Dash, Dot, Dash),
|
|
88
|
+
PunctuationAmpersand = packMorse(Dot, Dash, Dot, Dot, Dot),
|
|
89
|
+
PunctuationColon = packMorse(Dash, Dash, Dash, Dot, Dot, Dot),
|
|
90
|
+
PunctuationSemicolon = packMorse(Dash, Dot, Dash, Dot, Dash, Dot),
|
|
91
|
+
PunctuationDoubleDash = packMorse(Dash, Dot, Dot, Dot, Dash),
|
|
92
|
+
PunctuationPlusSign = packMorse(Dot, Dash, Dot, Dash, Dot),
|
|
93
|
+
PunctuationHyphen = packMorse(Dash, Dot, Dot, Dot, Dot, Dash),
|
|
94
|
+
PunctuationUnderscore = packMorse(Dot, Dot, Dash, Dash, Dot, Dash),
|
|
95
|
+
PunctuationQuotationMark = packMorse(Dot, Dash, Dot, Dot, Dash, Dot),
|
|
96
|
+
PunctuationDollarSign = packMorse(Dot, Dot, Dot, Dash, Dot, Dot, Dash),
|
|
97
|
+
PunctuationAtSign = packMorse(Dot, Dash, Dash, Dot, Dash, Dot),
|
|
98
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import {Helpers} from '../Common/Helpers';
|
|
2
|
+
import {MorseCharacter} from './MorseCharacter';
|
|
3
|
+
|
|
4
|
+
// MorseString represents a string of multiple morse characters. It allows for a longer representation
|
|
5
|
+
// to be converted to a single string and allows for sentence-level transforms such as reversing
|
|
6
|
+
// the order of tokens.
|
|
7
|
+
export class MorseString {
|
|
8
|
+
static readonly CHARACTER_DIVIDER: string = '/';
|
|
9
|
+
static readonly WORD_DIVIDER = ' ';
|
|
10
|
+
|
|
11
|
+
constructor(
|
|
12
|
+
morse = '',
|
|
13
|
+
characterDivider = MorseString.CHARACTER_DIVIDER,
|
|
14
|
+
wordDivider = MorseString.WORD_DIVIDER
|
|
15
|
+
) {
|
|
16
|
+
// The dividers should be single characters which don't clash with the other string content
|
|
17
|
+
Helpers.assertMsg(
|
|
18
|
+
characterDivider.length === 1,
|
|
19
|
+
'Divider must be a single character'
|
|
20
|
+
);
|
|
21
|
+
Helpers.assertMsg(
|
|
22
|
+
wordDivider.length === 1,
|
|
23
|
+
'Divider must be a single character'
|
|
24
|
+
);
|
|
25
|
+
Helpers.assertMsg(
|
|
26
|
+
characterDivider !== wordDivider,
|
|
27
|
+
'Dividers must be different from each other'
|
|
28
|
+
);
|
|
29
|
+
Helpers.assertMsg(
|
|
30
|
+
characterDivider !== MorseCharacter.DASH,
|
|
31
|
+
'Character divider must not be a reserved value'
|
|
32
|
+
);
|
|
33
|
+
Helpers.assertMsg(
|
|
34
|
+
characterDivider !== MorseCharacter.DOT,
|
|
35
|
+
'Character divider must not be a reserved value'
|
|
36
|
+
);
|
|
37
|
+
Helpers.assertMsg(
|
|
38
|
+
characterDivider !== MorseCharacter.RESERVED_DIVIDER,
|
|
39
|
+
'Character divider must not be a reserved value'
|
|
40
|
+
);
|
|
41
|
+
Helpers.assertMsg(
|
|
42
|
+
wordDivider !== MorseCharacter.DASH,
|
|
43
|
+
'Word divider must not be a reserved value'
|
|
44
|
+
);
|
|
45
|
+
Helpers.assertMsg(
|
|
46
|
+
wordDivider !== MorseCharacter.DOT,
|
|
47
|
+
'Word divider must not be a reserved value'
|
|
48
|
+
);
|
|
49
|
+
Helpers.assertMsg(
|
|
50
|
+
wordDivider !== MorseCharacter.RESERVED_DIVIDER,
|
|
51
|
+
'Word divider must not be a reserved value'
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
const words = morse.split(wordDivider).filter(w => w.length > 0);
|
|
55
|
+
// Discard any empty characters (caused by trailing separator)
|
|
56
|
+
const wordCharacters = words.map(w =>
|
|
57
|
+
w.split(characterDivider).filter(wc => wc.length > 0)
|
|
58
|
+
);
|
|
59
|
+
this._words = wordCharacters.map(subarray =>
|
|
60
|
+
subarray.map(wc => new MorseCharacter(wc))
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// reverse reverses the order of all tokens in the string (including separators), such as would be
|
|
65
|
+
// the case if you were reading the data for a puzzle backwards.
|
|
66
|
+
reverse(): MorseString {
|
|
67
|
+
for (let i = 0; i < this._words.length; i++) {
|
|
68
|
+
for (const c of this._words[i]) {
|
|
69
|
+
// Reverse the dots/dashes in each letter
|
|
70
|
+
c.reverse();
|
|
71
|
+
}
|
|
72
|
+
// Reverse the letters in each word
|
|
73
|
+
this._words[i] = this._words[i].reverse();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Reverse the order of the words
|
|
77
|
+
this._words = this._words.reverse();
|
|
78
|
+
return this;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// invertDotsAndDashes switches all dots and dashes in the input, such as would be the case if
|
|
82
|
+
// you had two ambiguous symbols for dot/dash and selected the wrong mapping.
|
|
83
|
+
invertDotsAndDashes(): MorseString {
|
|
84
|
+
for (const word of this._words) {
|
|
85
|
+
for (const c of word) {
|
|
86
|
+
c.invertDotsAndDashes();
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return this;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
toString(): string {
|
|
93
|
+
let s = '';
|
|
94
|
+
for (let i = 0; i < this._words.length; i++) {
|
|
95
|
+
if (i > 0) {
|
|
96
|
+
s += ' '; // This is a new word
|
|
97
|
+
}
|
|
98
|
+
for (const c of this._words[i]) {
|
|
99
|
+
s += c.toString() || '?';
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return s;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
protected _words: MorseCharacter[][];
|
|
106
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import {NatoCharacter} from './NatoCharacter';
|
|
2
|
+
|
|
3
|
+
// There's no concept of a 'partial match' for a NATO letter, so there's no
|
|
4
|
+
// reason to derive from EncodingDataBase.
|
|
5
|
+
export class NatoData {
|
|
6
|
+
static readonly instance: NatoData = new NatoData();
|
|
7
|
+
|
|
8
|
+
private readonly _entries: NatoCharacter[] = [
|
|
9
|
+
new NatoCharacter('A', 'Alfa'),
|
|
10
|
+
new NatoCharacter('B', 'Bravo'),
|
|
11
|
+
new NatoCharacter('C', 'Charlie'),
|
|
12
|
+
new NatoCharacter('D', 'Delta'),
|
|
13
|
+
new NatoCharacter('E', 'Echo'),
|
|
14
|
+
new NatoCharacter('F', 'Foxtrot'),
|
|
15
|
+
new NatoCharacter('G', 'Golf'),
|
|
16
|
+
new NatoCharacter('H', 'Hotel'),
|
|
17
|
+
new NatoCharacter('I', 'India'),
|
|
18
|
+
new NatoCharacter('J', 'Juliet'),
|
|
19
|
+
new NatoCharacter('K', 'Kilo'),
|
|
20
|
+
new NatoCharacter('L', 'Lima'),
|
|
21
|
+
new NatoCharacter('M', 'Mike'),
|
|
22
|
+
new NatoCharacter('N', 'November'),
|
|
23
|
+
new NatoCharacter('O', 'Oscar'),
|
|
24
|
+
new NatoCharacter('P', 'Papa'),
|
|
25
|
+
new NatoCharacter('Q', 'Quebec'),
|
|
26
|
+
new NatoCharacter('R', 'Romeo'),
|
|
27
|
+
new NatoCharacter('S', 'Sierra'),
|
|
28
|
+
new NatoCharacter('T', 'Tango'),
|
|
29
|
+
new NatoCharacter('U', 'Uniform'),
|
|
30
|
+
new NatoCharacter('V', 'Victor'),
|
|
31
|
+
new NatoCharacter('W', 'Whiskey'),
|
|
32
|
+
new NatoCharacter('X', 'X-ray'),
|
|
33
|
+
new NatoCharacter('Y', 'Yankee'),
|
|
34
|
+
new NatoCharacter('Z', 'Zulu'),
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
get entries(): NatoCharacter[] {
|
|
38
|
+
return this._entries;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
lookup(letter: string): NatoCharacter | null {
|
|
42
|
+
for (const ch of this._entries) {
|
|
43
|
+
if (ch.character.toUpperCase() === letter.toUpperCase()) {
|
|
44
|
+
return ch;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
The SVG images used in this directory are of simple geometry is ineligible for copyright
|
|
2
|
+
and therefore in the public domain, because it consists entirely of information that is
|
|
3
|
+
common property and contains no original authorship. With the exception of the image
|
|
4
|
+
for 'U'/'Uniform', they were obtained from the Wikimedia Commons project at
|
|
5
|
+
https://commons.wikimedia.org/wiki/Category:SVG_signal_flags on 2018-10-17. The SVG
|
|
6
|
+
for Uniform is also ineligible for copyright and in the public domain, but did not come
|
|
7
|
+
from Wikimedia.
|