@ca-plant-list/ca-plant-list 0.3.2 → 0.3.4

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.
Files changed (70) hide show
  1. package/.vscode/settings.json +4 -2
  2. package/data/exceptions.json +0 -3
  3. package/data/glossary/calyx.md +1 -0
  4. package/data/glossary/ovary.md +3 -0
  5. package/data/glossary/pedicel.md +1 -0
  6. package/data/glossary/pistil.md +3 -0
  7. package/data/glossary/sepal.md +1 -0
  8. package/data/glossary/stigma.md +3 -0
  9. package/data/glossary/style.md +3 -0
  10. package/data/illustrations/inkscape/pistil.svg +156 -0
  11. package/data/synonyms.csv +8 -3
  12. package/data/taxa.csv +77 -72
  13. package/data/text/Calochortus-argillosus.md +1 -0
  14. package/data/text/Calochortus-luteus.md +1 -0
  15. package/data/text/Calochortus-venustus.md +1 -0
  16. package/data/text/Ceanothus-cuneatus-var-cuneatus.md +1 -0
  17. package/data/text/Ceanothus-leucodermis.md +1 -0
  18. package/data/text/Claytonia-parviflora.md +1 -0
  19. package/data/text/Claytonia-perfoliata.md +1 -0
  20. package/data/text/Collinsia-heterophylla-var-heterophylla.md +1 -0
  21. package/data/text/Delphinium-californicum-subsp-californicum.md +1 -0
  22. package/data/text/Delphinium-decorum-subsp-decorum.md +1 -0
  23. package/data/text/Delphinium-hesperium-subsp-hesperium.md +1 -0
  24. package/data/text/Delphinium-patens-subsp-patens.md +1 -0
  25. package/data/text/Galium-andrewsii-subsp-gatense.md +1 -0
  26. package/data/text/Helianthella-californica-var-californica.md +1 -0
  27. package/data/text/Helianthella-castanea.md +1 -0
  28. package/data/text/Iris-macrosiphon.md +1 -0
  29. package/data/text/Lasthenia-californica-subsp-californica.md +1 -0
  30. package/data/text/Lasthenia-gracilis.md +1 -0
  31. package/data/text/Leptosiphon-ambiguus.md +1 -0
  32. package/data/text/Leptosiphon-androsaceus.md +1 -0
  33. package/data/text/Leptosiphon-bicolor.md +1 -1
  34. package/data/text/Leptosiphon-parviflorus.md +1 -0
  35. package/data/text/Lithophragma-affine.md +1 -1
  36. package/data/text/Lithophragma-parviflorum-var-parviflorum.md +1 -1
  37. package/data/text/Lomatium-californicum.md +0 -0
  38. package/data/text/Lomatium-dasycarpum-subsp-dasycarpum.md +1 -0
  39. package/data/text/Lomatium-utriculatum.md +1 -0
  40. package/data/text/Nemophila-heterophylla.md +1 -0
  41. package/data/text/Nemophila-parviflora-var-parviflora.md +1 -0
  42. package/data/text/Plectritis-ciliosa.md +1 -0
  43. package/data/text/Plectritis-macrocera.md +1 -0
  44. package/data/text/Primula-clevelandii-var-patula.md +1 -0
  45. package/data/text/Primula-hendersonii.md +1 -0
  46. package/data/text/Sidalcea-diploscypha.md +1 -0
  47. package/data/text/Thysanocarpus-curvipes.md +1 -0
  48. package/data/text/Thysanocarpus-laciniatus.md +1 -0
  49. package/data/text/Viola-douglasii.md +1 -0
  50. package/data/text/Viola-pedunculata.md +1 -0
  51. package/data/text/Viola-purpurea-subsp-quercetorum.md +1 -0
  52. package/ebook/css/main.css +5 -0
  53. package/lib/basepagerenderer.js +30 -29
  54. package/lib/dateutils.js +36 -16
  55. package/lib/ebook/pages/page_list_families.js +15 -9
  56. package/lib/ebook/pages/taxonpage.js +63 -36
  57. package/lib/ebook/plantbook.js +82 -48
  58. package/lib/errorlog.js +16 -11
  59. package/lib/families.js +109 -74
  60. package/lib/files.js +103 -45
  61. package/lib/genera.js +40 -26
  62. package/lib/generictaxaloader.js +15 -7
  63. package/lib/index.js +38 -3
  64. package/lib/taxa.js +174 -87
  65. package/lib/taxaloader.js +28 -15
  66. package/lib/taxaprocessor.js +6 -8
  67. package/lib/taxon.js +115 -57
  68. package/package.json +4 -6
  69. package/scripts/build-ebook.js +33 -25
  70. package/lib/index.d.ts +0 -345
package/lib/families.js CHANGED
@@ -4,30 +4,38 @@ import { Jepson } from "./jepson.js";
4
4
  import { Taxa } from "./taxa.js";
5
5
  import { Files } from "./files.js";
6
6
  import { Config } from "./config.js";
7
+ // eslint-disable-next-line no-unused-vars
8
+ import { Taxon } from "./index.js";
7
9
 
8
10
  class Family {
9
-
10
11
  #name;
11
12
  #data;
12
13
 
13
- constructor( name, data ) {
14
+ /**
15
+ * @param {string} name
16
+ * @param {*} data
17
+ */
18
+ constructor(name, data) {
14
19
  this.#name = name;
15
20
  this.#data = data;
16
21
  }
17
22
 
18
- addTaxon( taxon ) {
19
- if ( !this.#data.taxa ) {
23
+ /**
24
+ * @param {Taxon} taxon
25
+ */
26
+ addTaxon(taxon) {
27
+ if (!this.#data.taxa) {
20
28
  this.#data.taxa = [];
21
29
  }
22
- this.#data.taxa.push( taxon );
23
- Sections.addTaxon( this.getSectionName(), taxon );
30
+ this.#data.taxa.push(taxon);
31
+ Sections.addTaxon(this.getSectionName(), taxon);
24
32
  }
25
33
 
26
34
  getBaseFileName() {
27
35
  return this.getName();
28
36
  }
29
37
 
30
- getFileName( ext = "html" ) {
38
+ getFileName(ext = "html") {
31
39
  return this.getBaseFileName() + "." + ext;
32
40
  }
33
41
 
@@ -46,163 +54,190 @@ class Family {
46
54
  getTaxa() {
47
55
  return this.#data.taxa;
48
56
  }
49
-
50
57
  }
51
58
 
52
59
  class Families {
60
+ #families;
53
61
 
54
- static #families;
55
-
56
- static {
57
-
62
+ constructor() {
58
63
  const dataDir = Config.getPackageDir() + "/data";
59
64
 
60
- this.#families = JSON.parse( Files.read( dataDir + "/families.json" ) );
61
- for ( const [ k, v ] of Object.entries( this.#families ) ) {
62
- this.#families[ k ] = new Family( k, v );
65
+ this.#families = JSON.parse(Files.read(dataDir + "/families.json"));
66
+ for (const [k, v] of Object.entries(this.#families)) {
67
+ this.#families[k] = new Family(k, v);
63
68
  }
64
-
65
69
  }
66
70
 
67
- static getFamilies() {
68
- return Object.values( this.#families ).sort( ( a, b ) => a.getName().localeCompare( b.getName() ) );
71
+ getFamilies() {
72
+ return Object.values(this.#families).sort((a, b) =>
73
+ a.getName().localeCompare(b.getName())
74
+ );
69
75
  }
70
76
 
71
- static getFamily( familyName ) {
72
- return this.#families[ familyName ];
77
+ /**
78
+ * @param {string} familyName
79
+ */
80
+ getFamily(familyName) {
81
+ return this.#families[familyName];
73
82
  }
74
83
 
75
- static renderPages( outputDir, taxaColumns ) {
76
- new PageFamilyList( outputDir, this.#families ).render( taxaColumns );
84
+ /**
85
+ * @param {string} outputDir
86
+ * @param {import("./index.js").TaxaCol[]} taxaColumns
87
+ */
88
+ renderPages(outputDir, taxaColumns) {
89
+ new PageFamilyList(outputDir, this.#families).render(taxaColumns);
77
90
 
78
- const names = Object.keys( this.#families );
79
- for ( const name of names.sort() ) {
80
- const family = this.#families[ name ];
81
- if ( family.getTaxa() ) {
82
- new PageFamily( outputDir, family ).render( taxaColumns );
91
+ const names = Object.keys(this.#families);
92
+ for (const name of names.sort()) {
93
+ const family = this.#families[name];
94
+ if (family.getTaxa()) {
95
+ new PageFamily(outputDir, family).render(taxaColumns);
83
96
  }
84
97
  }
85
98
  }
86
-
87
99
  }
88
100
 
89
101
  class PageFamilyList extends GenericPage {
90
-
91
102
  #families;
92
103
 
93
- constructor( outputDir, families ) {
94
- super( outputDir, "Families", "list_families" );
104
+ /**
105
+ * @param {string} outputDir
106
+ * @param {Object<string,Family>} families
107
+ */
108
+ constructor(outputDir, families) {
109
+ super(outputDir, "Families", "list_families");
95
110
  this.#families = families;
96
111
  }
97
112
 
98
- render( taxaColumns ) {
99
-
113
+ /**
114
+ * @param {import("./index.js").TaxaCol[]} taxaColumns
115
+ */
116
+ render(taxaColumns) {
100
117
  let html = this.getDefaultIntro();
101
118
 
102
119
  const sections = Sections.getSections();
103
120
  const sectionLinks = [];
104
- for ( const name of Object.keys( sections ).sort() ) {
105
-
106
- const taxa = sections[ name ];
121
+ for (const name of Object.keys(sections).sort()) {
122
+ const taxa = sections[name];
107
123
 
108
124
  // Render the section page.
109
- new PageSection( this.getOutputDir(), name, taxa ).render( taxaColumns );
125
+ new PageSection(this.getOutputDir(), name, taxa).render(
126
+ taxaColumns
127
+ );
110
128
 
111
129
  // Render the link.
112
130
  const href = "./" + name + ".html";
113
- sectionLinks.push( HTML.getLink( href, name ) + " (" + taxa.length + ")" );
131
+ sectionLinks.push(
132
+ HTML.getLink(href, name) + " (" + taxa.length + ")"
133
+ );
114
134
  }
115
- html += HTML.wrap( "ul", HTML.arrayToLI( sectionLinks ), { class: "listmenu" } );
135
+ html += HTML.wrap("ul", HTML.arrayToLI(sectionLinks), {
136
+ class: "listmenu",
137
+ });
116
138
 
117
139
  html += "<table>";
118
140
  html += "<thead>";
119
- html += HTML.textElement( "th", "Family" );
120
- html += HTML.textElement( "th", "Number of Species", { class: "right" } );
141
+ html += HTML.textElement("th", "Family");
142
+ html += HTML.textElement("th", "Number of Species", { class: "right" });
121
143
  html += "</thead>";
122
144
 
123
145
  html += "<tbody>";
124
- const names = Object.keys( this.#families ).sort();
125
- for ( const name of names ) {
126
- const family = this.#families[ name ];
146
+ const names = Object.keys(this.#families).sort();
147
+ for (const name of names) {
148
+ const family = this.#families[name];
127
149
  const taxa = family.getTaxa();
128
- if ( !taxa ) {
150
+ if (!taxa) {
129
151
  continue;
130
152
  }
131
- let cols = HTML.wrap( "td", HTML.getLink( "./" + family.getFileName(), family.getName() ) );
132
- cols += HTML.wrap( "td", taxa.length, { class: "right" } );
133
- html += HTML.wrap( "tr", cols );
153
+ let cols = HTML.wrap(
154
+ "td",
155
+ HTML.getLink("./" + family.getFileName(), family.getName())
156
+ );
157
+ cols += HTML.wrap("td", taxa.length, { class: "right" });
158
+ html += HTML.wrap("tr", cols);
134
159
  }
135
160
  html += "</tbody>";
136
161
 
137
162
  html += "</table>";
138
163
 
139
- this.writeFile( html );
164
+ this.writeFile(html);
140
165
  }
141
166
  }
142
167
 
143
168
  class PageFamily extends GenericPage {
144
-
145
169
  #family;
146
170
 
147
- constructor( outputDir, family ) {
148
- super( outputDir, family.getName(), family.getBaseFileName() );
171
+ /**
172
+ * @param {string} outputDir
173
+ * @param {Family} family
174
+ */
175
+ constructor(outputDir, family) {
176
+ super(outputDir, family.getName(), family.getBaseFileName());
149
177
  this.#family = family;
150
178
  }
151
179
 
152
- render( columns ) {
153
-
180
+ /**
181
+ *
182
+ * @param {import("./index.js").TaxaCol[]} columns
183
+ */
184
+ render(columns) {
154
185
  let html = this.getDefaultIntro();
155
186
 
156
187
  html += HTML.wrap(
157
188
  "div",
158
- Jepson.getEFloraLink( this.#family.getJepsonID() ),
189
+ Jepson.getEFloraLink(this.#family.getJepsonID()),
159
190
  { class: "section" }
160
191
  );
161
192
 
162
- html += Taxa.getHTMLTable( this.#family.getTaxa(), columns );
163
-
164
- this.writeFile( html );
193
+ html += Taxa.getHTMLTable(this.#family.getTaxa(), columns);
165
194
 
195
+ this.writeFile(html);
166
196
  }
167
197
  }
168
198
 
169
199
  class PageSection extends GenericPage {
170
-
171
200
  #taxa;
172
201
 
173
- constructor( outputDir, name, taxa ) {
174
- super( outputDir, name, name );
202
+ /**
203
+ * @param {string} outputDir
204
+ * @param {string} name
205
+ * @param {Taxon[]} taxa
206
+ */
207
+ constructor(outputDir, name, taxa) {
208
+ super(outputDir, name, name);
175
209
  this.#taxa = taxa;
176
210
  }
177
211
 
178
- render( columns ) {
179
-
212
+ render(columns) {
180
213
  let html = this.getDefaultIntro();
181
214
 
182
- html += Taxa.getHTMLTable( this.#taxa, columns );
183
-
184
- this.writeFile( html );
215
+ html += Taxa.getHTMLTable(this.#taxa, columns);
185
216
 
217
+ this.writeFile(html);
186
218
  }
187
219
  }
188
220
 
189
221
  class Sections {
190
-
222
+ /** @type {Object<string,Taxon[]} */
191
223
  static #sections = {};
192
224
 
193
- static addTaxon( name, taxon ) {
194
- let section = this.#sections[ name ];
195
- if ( !section ) {
225
+ /**
226
+ * @param {string} name
227
+ * @param {Taxon} taxon
228
+ */
229
+ static addTaxon(name, taxon) {
230
+ let section = this.#sections[name];
231
+ if (!section) {
196
232
  section = [];
197
- this.#sections[ name ] = section;
233
+ this.#sections[name] = section;
198
234
  }
199
- section.push( taxon );
235
+ section.push(taxon);
200
236
  }
201
237
 
202
238
  static getSections() {
203
239
  return this.#sections;
204
240
  }
205
-
206
241
  }
207
242
 
208
- export { Families };
243
+ export { Families };
package/lib/files.js CHANGED
@@ -3,91 +3,149 @@ import * as path from "node:path";
3
3
  import { default as unzipper } from "unzipper";
4
4
 
5
5
  class Files {
6
-
7
- static copyDir( srcDir, targetDir ) {
8
- fs.cpSync( srcDir, targetDir, { recursive: true } );
6
+ /**
7
+ * @param {string} srcDir
8
+ * @param {string} targetDir
9
+ */
10
+ static copyDir(srcDir, targetDir) {
11
+ fs.cpSync(srcDir, targetDir, { recursive: true });
9
12
  }
10
13
 
11
- static createFileFromStream( fileName, inStream ) {
12
-
13
- function implementation( fileName, inStream, resolve ) {
14
- const outStream = fs.createWriteStream( fileName );
15
- outStream.on( "finish", () => { resolve( true ); } );
16
- inStream.pipe( outStream );
14
+ /**
15
+ * @param {string} fileName
16
+ * @param {*} inStream
17
+ * @access private
18
+ */
19
+ static #createFileFromStream(fileName, inStream) {
20
+ /**
21
+ *
22
+ * @param {string} fileName
23
+ * @param {*} inStream
24
+ * @param {*} resolve
25
+ */
26
+ function implementation(fileName, inStream, resolve) {
27
+ const outStream = fs.createWriteStream(fileName);
28
+ outStream.on("finish", () => {
29
+ resolve(true);
30
+ });
31
+ inStream.pipe(outStream);
17
32
  }
18
33
 
19
- return new Promise( ( resolve ) => { implementation( fileName, inStream, resolve ); } );
34
+ return new Promise((resolve) => {
35
+ implementation(fileName, inStream, resolve);
36
+ });
20
37
  }
21
38
 
22
- static exists( path ) {
23
- return fs.existsSync( path );
39
+ /**
40
+ * @param {string} path
41
+ * @returns {boolean}
42
+ */
43
+ static exists(path) {
44
+ return fs.existsSync(path);
24
45
  }
25
46
 
26
47
  /**
27
48
  * Retrieve data from a URL and write it to a file. If the response status is anything other than 200, an Error is thrown.
28
- * @param {string|URL} url
49
+ * @param {string|URL} url
29
50
  * @param {string|undefined} targetFileName If targetFileName is undefined, the data will be retrieved but not written to a file.
30
51
  * @param {Object} [headers={}] Request Headers.
31
52
  * @returns {Promise<Headers>} The Response headers.
32
53
  */
33
- static async fetch( url, targetFileName, headers = {} ) {
34
- const response = await fetch( url, headers );
35
- if ( response.status !== 200 ) {
36
- throw new Error( response.status + " retrieving " + url );
54
+ static async fetch(url, targetFileName, headers = {}) {
55
+ const response = await fetch(url, headers);
56
+ if (response.status !== 200) {
57
+ throw new Error(response.status + " retrieving " + url);
37
58
  }
38
59
  const data = await response.blob();
39
60
  const arrayBuffer = await data.arrayBuffer();
40
- const buffer = Buffer.from( arrayBuffer );
41
- if ( targetFileName ) {
42
- fs.writeFileSync( targetFileName, buffer );
61
+ const buffer = Buffer.from(arrayBuffer);
62
+ if (targetFileName) {
63
+ fs.writeFileSync(targetFileName, buffer);
43
64
  }
44
65
  return response.headers;
45
66
  }
46
67
 
47
- static getDirEntries( path ) {
48
- return fs.readdirSync( path );
68
+ /**
69
+ * @param {string} path
70
+ * @returns {string[]}
71
+ */
72
+ static getDirEntries(path) {
73
+ return fs.readdirSync(path);
49
74
  }
50
75
 
51
- static isDir( path ) {
52
- const stats = fs.statSync( path, { throwIfNoEntry: false } );
76
+ /**
77
+ * @param {string} path
78
+ * @returns {boolean}
79
+ */
80
+ static isDir(path) {
81
+ const stats = fs.statSync(path, { throwIfNoEntry: false });
53
82
  return stats !== undefined && stats.isDirectory();
54
83
  }
55
84
 
56
- static join( ...paths ) {
57
- return path.join( ...paths ).replaceAll( "\\", "/" );
85
+ /**
86
+ * @param {string[]} paths
87
+ * @returns {string}
88
+ */
89
+ static join(...paths) {
90
+ return path.join(...paths).replaceAll("\\", "/");
58
91
  }
59
92
 
60
- static mkdir( path ) {
61
- fs.mkdirSync( path, { recursive: true } );
93
+ /**
94
+ * @param {string} path
95
+ */
96
+ static mkdir(path) {
97
+ fs.mkdirSync(path, { recursive: true });
62
98
  }
63
99
 
64
- static read( path ) {
65
- return fs.readFileSync( path, "utf8" );
100
+ /**
101
+ * @param {string} path
102
+ * @returns {string}
103
+ */
104
+ static read(path) {
105
+ return fs.readFileSync(path, "utf8");
66
106
  }
67
107
 
68
- static rmDir( dir ) {
69
- fs.rmSync( dir, { force: true, recursive: true, maxRetries: 2, retryDelay: 1000 } );
108
+ /**
109
+ * @param {string} dir
110
+ */
111
+ static rmDir(dir) {
112
+ fs.rmSync(dir, {
113
+ force: true,
114
+ recursive: true,
115
+ maxRetries: 2,
116
+ retryDelay: 1000,
117
+ });
70
118
  }
71
119
 
72
- static write( path, data, overwrite = false ) {
73
- if ( !overwrite && this.exists( path ) ) {
74
- throw new Error( path + " already exists" );
120
+ /**
121
+ * @param {string} path
122
+ * @param {string} data
123
+ * @param {boolean} overwrite
124
+ */
125
+ static write(path, data, overwrite = false) {
126
+ if (!overwrite && this.exists(path)) {
127
+ throw new Error(path + " already exists");
75
128
  }
76
- fs.writeFileSync( path, data );
129
+ fs.writeFileSync(path, data);
77
130
  }
78
131
 
79
- static async zipFileExtract( zipFilePath, fileNameToUnzip, targetFilePath ) {
80
-
81
- const zipDir = await unzipper.Open.file( zipFilePath );
82
- for ( const entry of zipDir.files ) {
83
- if ( entry.path === fileNameToUnzip ) {
84
- await this.createFileFromStream( targetFilePath, entry.stream() );
132
+ /**
133
+ * @param {string} zipFilePath
134
+ * @param {string} fileNameToUnzip
135
+ * @param {string} targetFilePath
136
+ */
137
+ static async zipFileExtract(zipFilePath, fileNameToUnzip, targetFilePath) {
138
+ const zipDir = await unzipper.Open.file(zipFilePath);
139
+ for (const entry of zipDir.files) {
140
+ if (entry.path === fileNameToUnzip) {
141
+ await this.#createFileFromStream(
142
+ targetFilePath,
143
+ entry.stream()
144
+ );
85
145
  break;
86
146
  }
87
147
  }
88
-
89
148
  }
90
-
91
149
  }
92
150
 
93
- export { Files };
151
+ export { Files };
package/lib/genera.js CHANGED
@@ -1,62 +1,76 @@
1
1
  import { Config } from "./config.js";
2
2
  import { Families } from "./families.js";
3
3
  import { Files } from "./files.js";
4
+ // eslint-disable-next-line no-unused-vars
5
+ import { Taxon } from "./taxon.js";
4
6
 
5
7
  class Genera {
8
+ #families;
9
+ #genera;
6
10
 
7
- static #genera;
8
-
9
- static {
11
+ /**
12
+ * @param {Families} families
13
+ */
14
+ constructor(families) {
10
15
  const dataDir = Config.getPackageDir() + "/data";
11
- this.#genera = JSON.parse( Files.read( dataDir + "/genera.json" ) );
16
+ this.#genera = JSON.parse(Files.read(dataDir + "/genera.json"));
17
+ this.#families = families;
12
18
  }
13
19
 
14
- static addTaxon( taxon ) {
15
-
20
+ /**
21
+ * @param {Taxon} taxon
22
+ */
23
+ addTaxon(taxon) {
16
24
  const genusName = taxon.getGenusName();
17
- const genusData = this.#genera[ genusName ];
18
- if ( !genusData ) {
19
- console.log( taxon.getName() + " genus not found" );
25
+ const genusData = this.#genera[genusName];
26
+ if (!genusData) {
27
+ console.log(taxon.getName() + " genus not found");
20
28
  return;
21
29
  }
22
30
 
23
- if ( genusData.taxa === undefined ) {
31
+ if (genusData.taxa === undefined) {
24
32
  genusData.taxa = [];
25
33
  }
26
- genusData.taxa.push( taxon );
34
+ genusData.taxa.push(taxon);
27
35
 
28
- const family = this.getFamily( genusName );
29
- if ( !family ) {
30
- console.log( taxon.getName() + " family not found" );
36
+ const family = this.getFamily(genusName);
37
+ if (!family) {
38
+ console.log(taxon.getName() + " family not found");
31
39
  return;
32
40
  }
33
- family.addTaxon( taxon );
41
+ family.addTaxon(taxon);
34
42
  }
35
43
 
36
- static getGenus( genusName ) {
37
- return new Genus( this.#genera[ genusName ] );
44
+ /**
45
+ * @param {string} genusName
46
+ */
47
+ getGenus(genusName) {
48
+ return new Genus(this.#genera[genusName]);
38
49
  }
39
50
 
40
- static getFamily( genusName ) {
41
- const genus = this.#genera[ genusName ];
42
- if ( genus ) {
43
- return Families.getFamily( genus.family );
51
+ /**
52
+ * @param {string} genusName
53
+ */
54
+ getFamily(genusName) {
55
+ const genus = this.#genera[genusName];
56
+ if (genus) {
57
+ return this.#families.getFamily(genus.family);
44
58
  }
45
59
  }
46
-
47
60
  }
48
61
 
49
62
  class Genus {
50
-
51
63
  #data;
52
64
 
53
- constructor( data ) {
65
+ constructor(data) {
54
66
  this.#data = data;
55
67
  }
56
68
 
57
69
  getTaxa() {
58
- return this.#data.taxa.sort( ( a, b ) => a.getName().localeCompare( b.getName() ) );
70
+ return this.#data.taxa.sort((a, b) =>
71
+ a.getName().localeCompare(b.getName())
72
+ );
59
73
  }
60
74
  }
61
75
 
62
- export { Genera };
76
+ export { Genera };
@@ -1,16 +1,22 @@
1
- import { ErrorLog } from "./errorlog.js";
1
+ import { ErrorLog } from "./index.js";
2
2
 
3
3
  class GenericTaxaLoader {
4
-
5
4
  #options;
6
5
  #errorLog;
6
+ /** @type {import("./index.js").Taxa|undefined}*/
7
7
  #taxa;
8
8
 
9
- constructor( options ) {
9
+ /**
10
+ * @param {*} options
11
+ */
12
+ constructor(options) {
10
13
  this.#options = options;
11
- this.#errorLog = new ErrorLog( options.outputdir + "/errors.tsv" );
14
+ this.#errorLog = new ErrorLog(options.outputdir + "/errors.tsv");
12
15
  }
13
16
 
17
+ /**
18
+ * @returns {ErrorLog}
19
+ */
14
20
  getErrorLog() {
15
21
  return this.#errorLog;
16
22
  }
@@ -27,14 +33,16 @@ class GenericTaxaLoader {
27
33
  this.#taxa = await this.loadTaxa();
28
34
  }
29
35
 
36
+ /**
37
+ * @return {Promise<import("./index.js").Taxa>}
38
+ */
30
39
  async loadTaxa() {
31
- throw new Error( "must be implemented by subclass" );
40
+ throw new Error("must be implemented by subclass");
32
41
  }
33
42
 
34
43
  writeErrorLog() {
35
44
  this.#errorLog.write();
36
45
  }
37
-
38
46
  }
39
47
 
40
- export { GenericTaxaLoader };
48
+ export { GenericTaxaLoader };