@helloao/cli 0.0.9 → 0.0.10

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/dist/cjs/cli.cjs CHANGED
@@ -5172,6 +5172,16 @@ var require_prisma_gen = __commonJS({
5172
5172
  textDirection: "textDirection",
5173
5173
  sha256: "sha256"
5174
5174
  };
5175
+ exports2.Prisma.CommentaryScalarFieldEnum = {
5176
+ id: "id",
5177
+ name: "name",
5178
+ website: "website",
5179
+ licenseUrl: "licenseUrl",
5180
+ englishName: "englishName",
5181
+ language: "language",
5182
+ textDirection: "textDirection",
5183
+ sha256: "sha256"
5184
+ };
5175
5185
  exports2.Prisma.InputFileScalarFieldEnum = {
5176
5186
  translationId: "translationId",
5177
5187
  name: "name",
@@ -5189,6 +5199,16 @@ var require_prisma_gen = __commonJS({
5189
5199
  numberOfChapters: "numberOfChapters",
5190
5200
  sha256: "sha256"
5191
5201
  };
5202
+ exports2.Prisma.CommentaryBookScalarFieldEnum = {
5203
+ id: "id",
5204
+ commentaryId: "commentaryId",
5205
+ name: "name",
5206
+ commonName: "commonName",
5207
+ introduction: "introduction",
5208
+ order: "order",
5209
+ numberOfChapters: "numberOfChapters",
5210
+ sha256: "sha256"
5211
+ };
5192
5212
  exports2.Prisma.ChapterScalarFieldEnum = {
5193
5213
  number: "number",
5194
5214
  bookId: "bookId",
@@ -5196,6 +5216,14 @@ var require_prisma_gen = __commonJS({
5196
5216
  json: "json",
5197
5217
  sha256: "sha256"
5198
5218
  };
5219
+ exports2.Prisma.CommentaryChapterScalarFieldEnum = {
5220
+ number: "number",
5221
+ bookId: "bookId",
5222
+ commentaryId: "commentaryId",
5223
+ introduction: "introduction",
5224
+ json: "json",
5225
+ sha256: "sha256"
5226
+ };
5199
5227
  exports2.Prisma.ChapterAudioUrlScalarFieldEnum = {
5200
5228
  number: "number",
5201
5229
  bookId: "bookId",
@@ -5212,6 +5240,15 @@ var require_prisma_gen = __commonJS({
5212
5240
  contentJson: "contentJson",
5213
5241
  sha256: "sha256"
5214
5242
  };
5243
+ exports2.Prisma.CommentaryChapterVerseScalarFieldEnum = {
5244
+ number: "number",
5245
+ chapterNumber: "chapterNumber",
5246
+ bookId: "bookId",
5247
+ commentaryId: "commentaryId",
5248
+ text: "text",
5249
+ contentJson: "contentJson",
5250
+ sha256: "sha256"
5251
+ };
5215
5252
  exports2.Prisma.ChapterFootnoteScalarFieldEnum = {
5216
5253
  id: "id",
5217
5254
  chapterNumber: "chapterNumber",
@@ -5231,11 +5268,15 @@ var require_prisma_gen = __commonJS({
5231
5268
  };
5232
5269
  exports2.Prisma.ModelName = {
5233
5270
  Translation: "Translation",
5271
+ Commentary: "Commentary",
5234
5272
  InputFile: "InputFile",
5235
5273
  Book: "Book",
5274
+ CommentaryBook: "CommentaryBook",
5236
5275
  Chapter: "Chapter",
5276
+ CommentaryChapter: "CommentaryChapter",
5237
5277
  ChapterAudioUrl: "ChapterAudioUrl",
5238
5278
  ChapterVerse: "ChapterVerse",
5279
+ CommentaryChapterVerse: "CommentaryChapterVerse",
5239
5280
  ChapterFootnote: "ChapterFootnote"
5240
5281
  };
5241
5282
  var config2 = {
@@ -5282,8 +5323,8 @@ var require_prisma_gen = __commonJS({
5282
5323
  }
5283
5324
  }
5284
5325
  },
5285
- "inlineSchema": 'datasource db {\r\n provider = "sqlite"\r\n url = "file:../../bible-api.dev.db"\r\n}\r\n\r\ngenerator client {\r\n provider = "prisma-client-js"\r\n output = "./prisma-gen"\r\n}\r\n\r\nmodel Translation {\r\n id String @id\r\n name String\r\n website String\r\n licenseUrl String\r\n shortName String?\r\n englishName String\r\n language String\r\n textDirection String\r\n\r\n // The SHA-256 hash of the translation\r\n // includes everything about the translation, including the books, chapters, verses, footnotes, etc.\r\n sha256 String?\r\n \r\n books Book[]\r\n chapters Chapter[]\r\n verses ChapterVerse[]\r\n footnotes ChapterFootnote[]\r\n audioUrls ChapterAudioUrl[]\r\n}\r\n\r\nmodel InputFile {\r\n // The ID of the translation that the file is for\r\n translationId String\r\n\r\n // The name of the file\r\n name String\r\n\r\n format String\r\n\r\n // The SHA-256 hash of the file\r\n sha256 String\r\n \r\n sizeInBytes Int\r\n\r\n @@id([translationId, name])\r\n}\r\n\r\nmodel Book {\r\n id String\r\n\r\n translationId String\r\n translation Translation @relation(fields: [translationId], references: [id])\r\n\r\n name String\r\n commonName String\r\n title String?\r\n order Int\r\n\r\n numberOfChapters Int\r\n\r\n // The SHA-256 hash of the book\r\n sha256 String?\r\n\r\n chapters Chapter[]\r\n verses ChapterVerse[]\r\n footnotes ChapterFootnote[]\r\n audioUrls ChapterAudioUrl[]\r\n\r\n @@id([translationId, id])\r\n}\r\n\r\nmodel Chapter {\r\n number Int\r\n\r\n bookId String\r\n book Book @relation(fields: [translationId, bookId], references: [translationId, id])\r\n\r\n translationId String\r\n translation Translation @relation(fields: [translationId], references: [id])\r\n\r\n json String // The JSON of the chapter\r\n\r\n // The SHA-256 hash of the chapter\r\n sha256 String?\r\n\r\n verses ChapterVerse[]\r\n footnotes ChapterFootnote[]\r\n audioUrls ChapterAudioUrl[]\r\n\r\n @@id([translationId, bookId, number])\r\n}\r\n\r\nmodel ChapterAudioUrl {\r\n number Int\r\n bookId String\r\n book Book @relation(fields: [translationId, bookId], references: [translationId, id])\r\n\r\n translationId String\r\n translation Translation @relation(fields: [translationId], references: [id])\r\n\r\n chapter Chapter @relation(fields: [translationId, bookId, number], references: [translationId, bookId, number])\r\n\r\n reader String\r\n url String\r\n\r\n @@id([translationId, bookId, number, reader])\r\n}\r\n\r\nmodel ChapterVerse {\r\n number Int\r\n\r\n chapterNumber Int\r\n chapter Chapter @relation(fields: [translationId, bookId, chapterNumber], references: [translationId, bookId, number])\r\n\r\n bookId String\r\n book Book @relation(fields: [translationId, bookId], references: [translationId, id])\r\n\r\n translationId String\r\n translation Translation @relation(fields: [translationId], references: [id])\r\n\r\n text String // The text of the verse\r\n contentJson String // The JSON of the verse content\r\n\r\n // The SHA-256 hash of the verse\r\n sha256 String?\r\n\r\n footnotes ChapterFootnote[]\r\n\r\n @@id([translationId, bookId, chapterNumber, number])\r\n}\r\n\r\nmodel ChapterFootnote {\r\n id Int\r\n\r\n chapterNumber Int\r\n chapter Chapter @relation(fields: [translationId, bookId, chapterNumber], references: [translationId, bookId, number])\r\n\r\n bookId String\r\n book Book @relation(fields: [translationId, bookId], references: [translationId, id])\r\n\r\n translationId String\r\n translation Translation @relation(fields: [translationId], references: [id])\r\n\r\n text String\r\n\r\n // The SHA-256 hash of the footnote\r\n sha256 String?\r\n\r\n verseNumber Int?\r\n verse ChapterVerse? @relation(fields: [translationId, bookId, chapterNumber, verseNumber], references: [translationId, bookId, chapterNumber, number])\r\n\r\n @@id([translationId, bookId, chapterNumber, id])\r\n}\r\n',
5286
- "inlineSchemaHash": "41764b814e923d5f889dfa978eb00e5b4ed97714ea6987e161972711cbecd4bb",
5326
+ "inlineSchema": 'datasource db {\r\n provider = "sqlite"\r\n url = "file:../../bible-api.dev.db"\r\n}\r\n\r\ngenerator client {\r\n provider = "prisma-client-js"\r\n output = "./prisma-gen"\r\n}\r\n\r\nmodel Translation {\r\n id String @id\r\n name String\r\n website String\r\n licenseUrl String\r\n shortName String?\r\n englishName String\r\n language String\r\n textDirection String\r\n\r\n // The SHA-256 hash of the translation\r\n // includes everything about the translation, including the books, chapters, verses, footnotes, etc.\r\n sha256 String?\r\n \r\n books Book[]\r\n chapters Chapter[]\r\n verses ChapterVerse[]\r\n footnotes ChapterFootnote[]\r\n audioUrls ChapterAudioUrl[]\r\n}\r\n\r\nmodel Commentary {\r\n id String @id\r\n name String\r\n website String\r\n licenseUrl String\r\n englishName String\r\n language String\r\n textDirection String\r\n\r\n // The SHA-256 hash of the translation\r\n // includes everything about the translation, including the books, chapters, verses, footnotes, etc.\r\n sha256 String?\r\n \r\n books CommentaryBook[]\r\n chapters CommentaryChapter[]\r\n verses CommentaryChapterVerse[]\r\n}\r\n\r\nmodel InputFile {\r\n // The ID of the translation that the file is for\r\n translationId String\r\n\r\n // The name of the file\r\n name String\r\n\r\n format String\r\n\r\n // The SHA-256 hash of the file\r\n sha256 String\r\n \r\n sizeInBytes Int\r\n\r\n @@id([translationId, name])\r\n}\r\n\r\nmodel Book {\r\n id String\r\n\r\n translationId String\r\n translation Translation @relation(fields: [translationId], references: [id])\r\n\r\n name String\r\n commonName String\r\n title String?\r\n order Int\r\n\r\n numberOfChapters Int\r\n\r\n // The SHA-256 hash of the book\r\n sha256 String?\r\n\r\n chapters Chapter[]\r\n verses ChapterVerse[]\r\n footnotes ChapterFootnote[]\r\n audioUrls ChapterAudioUrl[]\r\n\r\n @@id([translationId, id])\r\n}\r\n\r\nmodel CommentaryBook {\r\n id String\r\n\r\n commentaryId String\r\n commentary Commentary @relation(fields: [commentaryId], references: [id])\r\n\r\n name String\r\n commonName String\r\n introduction String?\r\n order Int\r\n\r\n numberOfChapters Int\r\n\r\n // The SHA-256 hash of the book\r\n sha256 String?\r\n\r\n chapters CommentaryChapter[]\r\n verses CommentaryChapterVerse[]\r\n\r\n @@id([commentaryId, id])\r\n}\r\n\r\nmodel Chapter {\r\n number Int\r\n\r\n bookId String\r\n book Book @relation(fields: [translationId, bookId], references: [translationId, id])\r\n\r\n translationId String\r\n translation Translation @relation(fields: [translationId], references: [id])\r\n\r\n json String // The JSON of the chapter\r\n\r\n // The SHA-256 hash of the chapter\r\n sha256 String?\r\n\r\n verses ChapterVerse[]\r\n footnotes ChapterFootnote[]\r\n audioUrls ChapterAudioUrl[]\r\n\r\n @@id([translationId, bookId, number])\r\n}\r\n\r\nmodel CommentaryChapter {\r\n number Int\r\n\r\n bookId String\r\n book CommentaryBook @relation(fields: [commentaryId, bookId], references: [commentaryId, id])\r\n\r\n commentaryId String\r\n commentary Commentary @relation(fields: [commentaryId], references: [id])\r\n\r\n introduction String?\r\n json String // The JSON of the chapter\r\n\r\n // The SHA-256 hash of the chapter\r\n sha256 String?\r\n\r\n verses CommentaryChapterVerse[]\r\n\r\n @@id([commentaryId, bookId, number])\r\n}\r\n\r\nmodel ChapterAudioUrl {\r\n number Int\r\n bookId String\r\n book Book @relation(fields: [translationId, bookId], references: [translationId, id])\r\n\r\n translationId String\r\n translation Translation @relation(fields: [translationId], references: [id])\r\n\r\n chapter Chapter @relation(fields: [translationId, bookId, number], references: [translationId, bookId, number])\r\n\r\n reader String\r\n url String\r\n\r\n @@id([translationId, bookId, number, reader])\r\n}\r\n\r\nmodel ChapterVerse {\r\n number Int\r\n\r\n chapterNumber Int\r\n chapter Chapter @relation(fields: [translationId, bookId, chapterNumber], references: [translationId, bookId, number])\r\n\r\n bookId String\r\n book Book @relation(fields: [translationId, bookId], references: [translationId, id])\r\n\r\n translationId String\r\n translation Translation @relation(fields: [translationId], references: [id])\r\n\r\n text String // The text of the verse\r\n contentJson String // The JSON of the verse content\r\n\r\n // The SHA-256 hash of the verse\r\n sha256 String?\r\n\r\n footnotes ChapterFootnote[]\r\n\r\n @@id([translationId, bookId, chapterNumber, number])\r\n}\r\n\r\nmodel CommentaryChapterVerse {\r\n number Int\r\n\r\n chapterNumber Int\r\n chapter CommentaryChapter @relation(fields: [commentaryId, bookId, chapterNumber], references: [commentaryId, bookId, number])\r\n\r\n bookId String\r\n book CommentaryBook @relation(fields: [commentaryId, bookId], references: [commentaryId, id])\r\n\r\n commentaryId String\r\n commentary Commentary @relation(fields: [commentaryId], references: [id])\r\n\r\n text String // The text of the verse\r\n contentJson String // The JSON of the verse content\r\n\r\n // The SHA-256 hash of the verse\r\n sha256 String?\r\n\r\n @@id([commentaryId, bookId, chapterNumber, number])\r\n}\r\n\r\nmodel ChapterFootnote {\r\n id Int\r\n\r\n chapterNumber Int\r\n chapter Chapter @relation(fields: [translationId, bookId, chapterNumber], references: [translationId, bookId, number])\r\n\r\n bookId String\r\n book Book @relation(fields: [translationId, bookId], references: [translationId, id])\r\n\r\n translationId String\r\n translation Translation @relation(fields: [translationId], references: [id])\r\n\r\n text String\r\n\r\n // The SHA-256 hash of the footnote\r\n sha256 String?\r\n\r\n verseNumber Int?\r\n verse ChapterVerse? @relation(fields: [translationId, bookId, chapterNumber, verseNumber], references: [translationId, bookId, chapterNumber, number])\r\n\r\n @@id([translationId, bookId, chapterNumber, id])\r\n}\r\n',
5327
+ "inlineSchemaHash": "e42b9eb867457262455de2d9b486014708f2bf98fc47870045246700b23c4255",
5287
5328
  "copyEngine": true
5288
5329
  };
5289
5330
  var fs2 = require("fs");
@@ -5299,7 +5340,7 @@ var require_prisma_gen = __commonJS({
5299
5340
  config2.dirname = path5.join(process.cwd(), alternativePath);
5300
5341
  config2.isBundled = true;
5301
5342
  }
5302
- config2.runtimeDataModel = JSON.parse('{"models":{"Translation":{"dbName":null,"fields":[{"name":"id","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":true,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"name","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"website","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"licenseUrl","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"shortName","kind":"scalar","isList":false,"isRequired":false,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"englishName","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"language","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"textDirection","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"sha256","kind":"scalar","isList":false,"isRequired":false,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"books","kind":"object","isList":true,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Book","relationName":"BookToTranslation","relationFromFields":[],"relationToFields":[],"isGenerated":false,"isUpdatedAt":false},{"name":"chapters","kind":"object","isList":true,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Chapter","relationName":"ChapterToTranslation","relationFromFields":[],"relationToFields":[],"isGenerated":false,"isUpdatedAt":false},{"name":"verses","kind":"object","isList":true,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"ChapterVerse","relationName":"ChapterVerseToTranslation","relationFromFields":[],"relationToFields":[],"isGenerated":false,"isUpdatedAt":false},{"name":"footnotes","kind":"object","isList":true,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"ChapterFootnote","relationName":"ChapterFootnoteToTranslation","relationFromFields":[],"relationToFields":[],"isGenerated":false,"isUpdatedAt":false},{"name":"audioUrls","kind":"object","isList":true,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"ChapterAudioUrl","relationName":"ChapterAudioUrlToTranslation","relationFromFields":[],"relationToFields":[],"isGenerated":false,"isUpdatedAt":false}],"primaryKey":null,"uniqueFields":[],"uniqueIndexes":[],"isGenerated":false},"InputFile":{"dbName":null,"fields":[{"name":"translationId","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"name","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"format","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"sha256","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"sizeInBytes","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Int","isGenerated":false,"isUpdatedAt":false}],"primaryKey":{"name":null,"fields":["translationId","name"]},"uniqueFields":[],"uniqueIndexes":[],"isGenerated":false},"Book":{"dbName":null,"fields":[{"name":"id","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"translationId","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":true,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"translation","kind":"object","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Translation","relationName":"BookToTranslation","relationFromFields":["translationId"],"relationToFields":["id"],"isGenerated":false,"isUpdatedAt":false},{"name":"name","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"commonName","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"title","kind":"scalar","isList":false,"isRequired":false,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"order","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Int","isGenerated":false,"isUpdatedAt":false},{"name":"numberOfChapters","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Int","isGenerated":false,"isUpdatedAt":false},{"name":"sha256","kind":"scalar","isList":false,"isRequired":false,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"chapters","kind":"object","isList":true,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Chapter","relationName":"BookToChapter","relationFromFields":[],"relationToFields":[],"isGenerated":false,"isUpdatedAt":false},{"name":"verses","kind":"object","isList":true,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"ChapterVerse","relationName":"BookToChapterVerse","relationFromFields":[],"relationToFields":[],"isGenerated":false,"isUpdatedAt":false},{"name":"footnotes","kind":"object","isList":true,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"ChapterFootnote","relationName":"BookToChapterFootnote","relationFromFields":[],"relationToFields":[],"isGenerated":false,"isUpdatedAt":false},{"name":"audioUrls","kind":"object","isList":true,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"ChapterAudioUrl","relationName":"BookToChapterAudioUrl","relationFromFields":[],"relationToFields":[],"isGenerated":false,"isUpdatedAt":false}],"primaryKey":{"name":null,"fields":["translationId","id"]},"uniqueFields":[],"uniqueIndexes":[],"isGenerated":false},"Chapter":{"dbName":null,"fields":[{"name":"number","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Int","isGenerated":false,"isUpdatedAt":false},{"name":"bookId","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":true,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"book","kind":"object","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Book","relationName":"BookToChapter","relationFromFields":["translationId","bookId"],"relationToFields":["translationId","id"],"isGenerated":false,"isUpdatedAt":false},{"name":"translationId","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":true,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"translation","kind":"object","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Translation","relationName":"ChapterToTranslation","relationFromFields":["translationId"],"relationToFields":["id"],"isGenerated":false,"isUpdatedAt":false},{"name":"json","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"sha256","kind":"scalar","isList":false,"isRequired":false,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"verses","kind":"object","isList":true,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"ChapterVerse","relationName":"ChapterToChapterVerse","relationFromFields":[],"relationToFields":[],"isGenerated":false,"isUpdatedAt":false},{"name":"footnotes","kind":"object","isList":true,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"ChapterFootnote","relationName":"ChapterToChapterFootnote","relationFromFields":[],"relationToFields":[],"isGenerated":false,"isUpdatedAt":false},{"name":"audioUrls","kind":"object","isList":true,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"ChapterAudioUrl","relationName":"ChapterToChapterAudioUrl","relationFromFields":[],"relationToFields":[],"isGenerated":false,"isUpdatedAt":false}],"primaryKey":{"name":null,"fields":["translationId","bookId","number"]},"uniqueFields":[],"uniqueIndexes":[],"isGenerated":false},"ChapterAudioUrl":{"dbName":null,"fields":[{"name":"number","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":true,"hasDefaultValue":false,"type":"Int","isGenerated":false,"isUpdatedAt":false},{"name":"bookId","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":true,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"book","kind":"object","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Book","relationName":"BookToChapterAudioUrl","relationFromFields":["translationId","bookId"],"relationToFields":["translationId","id"],"isGenerated":false,"isUpdatedAt":false},{"name":"translationId","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":true,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"translation","kind":"object","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Translation","relationName":"ChapterAudioUrlToTranslation","relationFromFields":["translationId"],"relationToFields":["id"],"isGenerated":false,"isUpdatedAt":false},{"name":"chapter","kind":"object","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Chapter","relationName":"ChapterToChapterAudioUrl","relationFromFields":["translationId","bookId","number"],"relationToFields":["translationId","bookId","number"],"isGenerated":false,"isUpdatedAt":false},{"name":"reader","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"url","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false}],"primaryKey":{"name":null,"fields":["translationId","bookId","number","reader"]},"uniqueFields":[],"uniqueIndexes":[],"isGenerated":false},"ChapterVerse":{"dbName":null,"fields":[{"name":"number","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Int","isGenerated":false,"isUpdatedAt":false},{"name":"chapterNumber","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":true,"hasDefaultValue":false,"type":"Int","isGenerated":false,"isUpdatedAt":false},{"name":"chapter","kind":"object","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Chapter","relationName":"ChapterToChapterVerse","relationFromFields":["translationId","bookId","chapterNumber"],"relationToFields":["translationId","bookId","number"],"isGenerated":false,"isUpdatedAt":false},{"name":"bookId","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":true,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"book","kind":"object","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Book","relationName":"BookToChapterVerse","relationFromFields":["translationId","bookId"],"relationToFields":["translationId","id"],"isGenerated":false,"isUpdatedAt":false},{"name":"translationId","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":true,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"translation","kind":"object","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Translation","relationName":"ChapterVerseToTranslation","relationFromFields":["translationId"],"relationToFields":["id"],"isGenerated":false,"isUpdatedAt":false},{"name":"text","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"contentJson","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"sha256","kind":"scalar","isList":false,"isRequired":false,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"footnotes","kind":"object","isList":true,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"ChapterFootnote","relationName":"ChapterFootnoteToChapterVerse","relationFromFields":[],"relationToFields":[],"isGenerated":false,"isUpdatedAt":false}],"primaryKey":{"name":null,"fields":["translationId","bookId","chapterNumber","number"]},"uniqueFields":[],"uniqueIndexes":[],"isGenerated":false},"ChapterFootnote":{"dbName":null,"fields":[{"name":"id","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Int","isGenerated":false,"isUpdatedAt":false},{"name":"chapterNumber","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":true,"hasDefaultValue":false,"type":"Int","isGenerated":false,"isUpdatedAt":false},{"name":"chapter","kind":"object","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Chapter","relationName":"ChapterToChapterFootnote","relationFromFields":["translationId","bookId","chapterNumber"],"relationToFields":["translationId","bookId","number"],"isGenerated":false,"isUpdatedAt":false},{"name":"bookId","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":true,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"book","kind":"object","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Book","relationName":"BookToChapterFootnote","relationFromFields":["translationId","bookId"],"relationToFields":["translationId","id"],"isGenerated":false,"isUpdatedAt":false},{"name":"translationId","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":true,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"translation","kind":"object","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Translation","relationName":"ChapterFootnoteToTranslation","relationFromFields":["translationId"],"relationToFields":["id"],"isGenerated":false,"isUpdatedAt":false},{"name":"text","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"sha256","kind":"scalar","isList":false,"isRequired":false,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"verseNumber","kind":"scalar","isList":false,"isRequired":false,"isUnique":false,"isId":false,"isReadOnly":true,"hasDefaultValue":false,"type":"Int","isGenerated":false,"isUpdatedAt":false},{"name":"verse","kind":"object","isList":false,"isRequired":false,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"ChapterVerse","relationName":"ChapterFootnoteToChapterVerse","relationFromFields":["translationId","bookId","chapterNumber","verseNumber"],"relationToFields":["translationId","bookId","chapterNumber","number"],"isGenerated":false,"isUpdatedAt":false}],"primaryKey":{"name":null,"fields":["translationId","bookId","chapterNumber","id"]},"uniqueFields":[],"uniqueIndexes":[],"isGenerated":false}},"enums":{},"types":{}}');
5343
+ config2.runtimeDataModel = JSON.parse('{"models":{"Translation":{"dbName":null,"fields":[{"name":"id","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":true,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"name","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"website","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"licenseUrl","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"shortName","kind":"scalar","isList":false,"isRequired":false,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"englishName","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"language","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"textDirection","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"sha256","kind":"scalar","isList":false,"isRequired":false,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"books","kind":"object","isList":true,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Book","relationName":"BookToTranslation","relationFromFields":[],"relationToFields":[],"isGenerated":false,"isUpdatedAt":false},{"name":"chapters","kind":"object","isList":true,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Chapter","relationName":"ChapterToTranslation","relationFromFields":[],"relationToFields":[],"isGenerated":false,"isUpdatedAt":false},{"name":"verses","kind":"object","isList":true,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"ChapterVerse","relationName":"ChapterVerseToTranslation","relationFromFields":[],"relationToFields":[],"isGenerated":false,"isUpdatedAt":false},{"name":"footnotes","kind":"object","isList":true,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"ChapterFootnote","relationName":"ChapterFootnoteToTranslation","relationFromFields":[],"relationToFields":[],"isGenerated":false,"isUpdatedAt":false},{"name":"audioUrls","kind":"object","isList":true,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"ChapterAudioUrl","relationName":"ChapterAudioUrlToTranslation","relationFromFields":[],"relationToFields":[],"isGenerated":false,"isUpdatedAt":false}],"primaryKey":null,"uniqueFields":[],"uniqueIndexes":[],"isGenerated":false},"Commentary":{"dbName":null,"fields":[{"name":"id","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":true,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"name","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"website","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"licenseUrl","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"englishName","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"language","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"textDirection","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"sha256","kind":"scalar","isList":false,"isRequired":false,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"books","kind":"object","isList":true,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"CommentaryBook","relationName":"CommentaryToCommentaryBook","relationFromFields":[],"relationToFields":[],"isGenerated":false,"isUpdatedAt":false},{"name":"chapters","kind":"object","isList":true,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"CommentaryChapter","relationName":"CommentaryToCommentaryChapter","relationFromFields":[],"relationToFields":[],"isGenerated":false,"isUpdatedAt":false},{"name":"verses","kind":"object","isList":true,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"CommentaryChapterVerse","relationName":"CommentaryToCommentaryChapterVerse","relationFromFields":[],"relationToFields":[],"isGenerated":false,"isUpdatedAt":false}],"primaryKey":null,"uniqueFields":[],"uniqueIndexes":[],"isGenerated":false},"InputFile":{"dbName":null,"fields":[{"name":"translationId","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"name","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"format","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"sha256","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"sizeInBytes","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Int","isGenerated":false,"isUpdatedAt":false}],"primaryKey":{"name":null,"fields":["translationId","name"]},"uniqueFields":[],"uniqueIndexes":[],"isGenerated":false},"Book":{"dbName":null,"fields":[{"name":"id","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"translationId","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":true,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"translation","kind":"object","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Translation","relationName":"BookToTranslation","relationFromFields":["translationId"],"relationToFields":["id"],"isGenerated":false,"isUpdatedAt":false},{"name":"name","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"commonName","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"title","kind":"scalar","isList":false,"isRequired":false,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"order","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Int","isGenerated":false,"isUpdatedAt":false},{"name":"numberOfChapters","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Int","isGenerated":false,"isUpdatedAt":false},{"name":"sha256","kind":"scalar","isList":false,"isRequired":false,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"chapters","kind":"object","isList":true,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Chapter","relationName":"BookToChapter","relationFromFields":[],"relationToFields":[],"isGenerated":false,"isUpdatedAt":false},{"name":"verses","kind":"object","isList":true,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"ChapterVerse","relationName":"BookToChapterVerse","relationFromFields":[],"relationToFields":[],"isGenerated":false,"isUpdatedAt":false},{"name":"footnotes","kind":"object","isList":true,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"ChapterFootnote","relationName":"BookToChapterFootnote","relationFromFields":[],"relationToFields":[],"isGenerated":false,"isUpdatedAt":false},{"name":"audioUrls","kind":"object","isList":true,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"ChapterAudioUrl","relationName":"BookToChapterAudioUrl","relationFromFields":[],"relationToFields":[],"isGenerated":false,"isUpdatedAt":false}],"primaryKey":{"name":null,"fields":["translationId","id"]},"uniqueFields":[],"uniqueIndexes":[],"isGenerated":false},"CommentaryBook":{"dbName":null,"fields":[{"name":"id","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"commentaryId","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":true,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"commentary","kind":"object","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Commentary","relationName":"CommentaryToCommentaryBook","relationFromFields":["commentaryId"],"relationToFields":["id"],"isGenerated":false,"isUpdatedAt":false},{"name":"name","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"commonName","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"introduction","kind":"scalar","isList":false,"isRequired":false,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"order","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Int","isGenerated":false,"isUpdatedAt":false},{"name":"numberOfChapters","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Int","isGenerated":false,"isUpdatedAt":false},{"name":"sha256","kind":"scalar","isList":false,"isRequired":false,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"chapters","kind":"object","isList":true,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"CommentaryChapter","relationName":"CommentaryBookToCommentaryChapter","relationFromFields":[],"relationToFields":[],"isGenerated":false,"isUpdatedAt":false},{"name":"verses","kind":"object","isList":true,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"CommentaryChapterVerse","relationName":"CommentaryBookToCommentaryChapterVerse","relationFromFields":[],"relationToFields":[],"isGenerated":false,"isUpdatedAt":false}],"primaryKey":{"name":null,"fields":["commentaryId","id"]},"uniqueFields":[],"uniqueIndexes":[],"isGenerated":false},"Chapter":{"dbName":null,"fields":[{"name":"number","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Int","isGenerated":false,"isUpdatedAt":false},{"name":"bookId","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":true,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"book","kind":"object","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Book","relationName":"BookToChapter","relationFromFields":["translationId","bookId"],"relationToFields":["translationId","id"],"isGenerated":false,"isUpdatedAt":false},{"name":"translationId","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":true,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"translation","kind":"object","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Translation","relationName":"ChapterToTranslation","relationFromFields":["translationId"],"relationToFields":["id"],"isGenerated":false,"isUpdatedAt":false},{"name":"json","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"sha256","kind":"scalar","isList":false,"isRequired":false,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"verses","kind":"object","isList":true,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"ChapterVerse","relationName":"ChapterToChapterVerse","relationFromFields":[],"relationToFields":[],"isGenerated":false,"isUpdatedAt":false},{"name":"footnotes","kind":"object","isList":true,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"ChapterFootnote","relationName":"ChapterToChapterFootnote","relationFromFields":[],"relationToFields":[],"isGenerated":false,"isUpdatedAt":false},{"name":"audioUrls","kind":"object","isList":true,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"ChapterAudioUrl","relationName":"ChapterToChapterAudioUrl","relationFromFields":[],"relationToFields":[],"isGenerated":false,"isUpdatedAt":false}],"primaryKey":{"name":null,"fields":["translationId","bookId","number"]},"uniqueFields":[],"uniqueIndexes":[],"isGenerated":false},"CommentaryChapter":{"dbName":null,"fields":[{"name":"number","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Int","isGenerated":false,"isUpdatedAt":false},{"name":"bookId","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":true,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"book","kind":"object","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"CommentaryBook","relationName":"CommentaryBookToCommentaryChapter","relationFromFields":["commentaryId","bookId"],"relationToFields":["commentaryId","id"],"isGenerated":false,"isUpdatedAt":false},{"name":"commentaryId","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":true,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"commentary","kind":"object","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Commentary","relationName":"CommentaryToCommentaryChapter","relationFromFields":["commentaryId"],"relationToFields":["id"],"isGenerated":false,"isUpdatedAt":false},{"name":"introduction","kind":"scalar","isList":false,"isRequired":false,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"json","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"sha256","kind":"scalar","isList":false,"isRequired":false,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"verses","kind":"object","isList":true,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"CommentaryChapterVerse","relationName":"CommentaryChapterToCommentaryChapterVerse","relationFromFields":[],"relationToFields":[],"isGenerated":false,"isUpdatedAt":false}],"primaryKey":{"name":null,"fields":["commentaryId","bookId","number"]},"uniqueFields":[],"uniqueIndexes":[],"isGenerated":false},"ChapterAudioUrl":{"dbName":null,"fields":[{"name":"number","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":true,"hasDefaultValue":false,"type":"Int","isGenerated":false,"isUpdatedAt":false},{"name":"bookId","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":true,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"book","kind":"object","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Book","relationName":"BookToChapterAudioUrl","relationFromFields":["translationId","bookId"],"relationToFields":["translationId","id"],"isGenerated":false,"isUpdatedAt":false},{"name":"translationId","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":true,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"translation","kind":"object","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Translation","relationName":"ChapterAudioUrlToTranslation","relationFromFields":["translationId"],"relationToFields":["id"],"isGenerated":false,"isUpdatedAt":false},{"name":"chapter","kind":"object","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Chapter","relationName":"ChapterToChapterAudioUrl","relationFromFields":["translationId","bookId","number"],"relationToFields":["translationId","bookId","number"],"isGenerated":false,"isUpdatedAt":false},{"name":"reader","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"url","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false}],"primaryKey":{"name":null,"fields":["translationId","bookId","number","reader"]},"uniqueFields":[],"uniqueIndexes":[],"isGenerated":false},"ChapterVerse":{"dbName":null,"fields":[{"name":"number","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Int","isGenerated":false,"isUpdatedAt":false},{"name":"chapterNumber","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":true,"hasDefaultValue":false,"type":"Int","isGenerated":false,"isUpdatedAt":false},{"name":"chapter","kind":"object","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Chapter","relationName":"ChapterToChapterVerse","relationFromFields":["translationId","bookId","chapterNumber"],"relationToFields":["translationId","bookId","number"],"isGenerated":false,"isUpdatedAt":false},{"name":"bookId","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":true,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"book","kind":"object","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Book","relationName":"BookToChapterVerse","relationFromFields":["translationId","bookId"],"relationToFields":["translationId","id"],"isGenerated":false,"isUpdatedAt":false},{"name":"translationId","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":true,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"translation","kind":"object","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Translation","relationName":"ChapterVerseToTranslation","relationFromFields":["translationId"],"relationToFields":["id"],"isGenerated":false,"isUpdatedAt":false},{"name":"text","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"contentJson","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"sha256","kind":"scalar","isList":false,"isRequired":false,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"footnotes","kind":"object","isList":true,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"ChapterFootnote","relationName":"ChapterFootnoteToChapterVerse","relationFromFields":[],"relationToFields":[],"isGenerated":false,"isUpdatedAt":false}],"primaryKey":{"name":null,"fields":["translationId","bookId","chapterNumber","number"]},"uniqueFields":[],"uniqueIndexes":[],"isGenerated":false},"CommentaryChapterVerse":{"dbName":null,"fields":[{"name":"number","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Int","isGenerated":false,"isUpdatedAt":false},{"name":"chapterNumber","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":true,"hasDefaultValue":false,"type":"Int","isGenerated":false,"isUpdatedAt":false},{"name":"chapter","kind":"object","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"CommentaryChapter","relationName":"CommentaryChapterToCommentaryChapterVerse","relationFromFields":["commentaryId","bookId","chapterNumber"],"relationToFields":["commentaryId","bookId","number"],"isGenerated":false,"isUpdatedAt":false},{"name":"bookId","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":true,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"book","kind":"object","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"CommentaryBook","relationName":"CommentaryBookToCommentaryChapterVerse","relationFromFields":["commentaryId","bookId"],"relationToFields":["commentaryId","id"],"isGenerated":false,"isUpdatedAt":false},{"name":"commentaryId","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":true,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"commentary","kind":"object","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Commentary","relationName":"CommentaryToCommentaryChapterVerse","relationFromFields":["commentaryId"],"relationToFields":["id"],"isGenerated":false,"isUpdatedAt":false},{"name":"text","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"contentJson","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"sha256","kind":"scalar","isList":false,"isRequired":false,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false}],"primaryKey":{"name":null,"fields":["commentaryId","bookId","chapterNumber","number"]},"uniqueFields":[],"uniqueIndexes":[],"isGenerated":false},"ChapterFootnote":{"dbName":null,"fields":[{"name":"id","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Int","isGenerated":false,"isUpdatedAt":false},{"name":"chapterNumber","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":true,"hasDefaultValue":false,"type":"Int","isGenerated":false,"isUpdatedAt":false},{"name":"chapter","kind":"object","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Chapter","relationName":"ChapterToChapterFootnote","relationFromFields":["translationId","bookId","chapterNumber"],"relationToFields":["translationId","bookId","number"],"isGenerated":false,"isUpdatedAt":false},{"name":"bookId","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":true,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"book","kind":"object","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Book","relationName":"BookToChapterFootnote","relationFromFields":["translationId","bookId"],"relationToFields":["translationId","id"],"isGenerated":false,"isUpdatedAt":false},{"name":"translationId","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":true,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"translation","kind":"object","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"Translation","relationName":"ChapterFootnoteToTranslation","relationFromFields":["translationId"],"relationToFields":["id"],"isGenerated":false,"isUpdatedAt":false},{"name":"text","kind":"scalar","isList":false,"isRequired":true,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"sha256","kind":"scalar","isList":false,"isRequired":false,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"String","isGenerated":false,"isUpdatedAt":false},{"name":"verseNumber","kind":"scalar","isList":false,"isRequired":false,"isUnique":false,"isId":false,"isReadOnly":true,"hasDefaultValue":false,"type":"Int","isGenerated":false,"isUpdatedAt":false},{"name":"verse","kind":"object","isList":false,"isRequired":false,"isUnique":false,"isId":false,"isReadOnly":false,"hasDefaultValue":false,"type":"ChapterVerse","relationName":"ChapterFootnoteToChapterVerse","relationFromFields":["translationId","bookId","chapterNumber","verseNumber"],"relationToFields":["translationId","bookId","chapterNumber","number"],"isGenerated":false,"isUpdatedAt":false}],"primaryKey":{"name":null,"fields":["translationId","bookId","chapterNumber","id"]},"uniqueFields":[],"uniqueIndexes":[],"isGenerated":false}},"enums":{},"types":{}}');
5303
5344
  defineDmmfProperty2(exports2.Prisma, config2.runtimeDataModel);
5304
5345
  config2.engineWasm = void 0;
5305
5346
  var { warnEnvConflicts: warnEnvConflicts2 } = require_library();
@@ -5317,6 +5358,1293 @@ var require_prisma_gen = __commonJS({
5317
5358
  }
5318
5359
  });
5319
5360
 
5361
+ // node_modules/.pnpm/papaparse@5.4.1/node_modules/papaparse/papaparse.js
5362
+ var require_papaparse = __commonJS({
5363
+ "node_modules/.pnpm/papaparse@5.4.1/node_modules/papaparse/papaparse.js"(exports2, module2) {
5364
+ (function(root, factory) {
5365
+ if (typeof define === "function" && define.amd) {
5366
+ define([], factory);
5367
+ } else if (typeof module2 === "object" && typeof exports2 !== "undefined") {
5368
+ module2.exports = factory();
5369
+ } else {
5370
+ root.Papa = factory();
5371
+ }
5372
+ })(exports2, function moduleFactory() {
5373
+ "use strict";
5374
+ var global = function() {
5375
+ if (typeof self !== "undefined") {
5376
+ return self;
5377
+ }
5378
+ if (typeof window !== "undefined") {
5379
+ return window;
5380
+ }
5381
+ if (typeof global !== "undefined") {
5382
+ return global;
5383
+ }
5384
+ return {};
5385
+ }();
5386
+ function getWorkerBlob() {
5387
+ var URL2 = global.URL || global.webkitURL || null;
5388
+ var code = moduleFactory.toString();
5389
+ return Papa.BLOB_URL || (Papa.BLOB_URL = URL2.createObjectURL(new Blob(["var global = (function() { if (typeof self !== 'undefined') { return self; } if (typeof window !== 'undefined') { return window; } if (typeof global !== 'undefined') { return global; } return {}; })(); global.IS_PAPA_WORKER=true; ", "(", code, ")();"], { type: "text/javascript" })));
5390
+ }
5391
+ var IS_WORKER = !global.document && !!global.postMessage, IS_PAPA_WORKER = global.IS_PAPA_WORKER || false;
5392
+ var workers = {}, workerIdCounter = 0;
5393
+ var Papa = {};
5394
+ Papa.parse = CsvToJson;
5395
+ Papa.unparse = JsonToCsv;
5396
+ Papa.RECORD_SEP = String.fromCharCode(30);
5397
+ Papa.UNIT_SEP = String.fromCharCode(31);
5398
+ Papa.BYTE_ORDER_MARK = "\uFEFF";
5399
+ Papa.BAD_DELIMITERS = ["\r", "\n", '"', Papa.BYTE_ORDER_MARK];
5400
+ Papa.WORKERS_SUPPORTED = !IS_WORKER && !!global.Worker;
5401
+ Papa.NODE_STREAM_INPUT = 1;
5402
+ Papa.LocalChunkSize = 1024 * 1024 * 10;
5403
+ Papa.RemoteChunkSize = 1024 * 1024 * 5;
5404
+ Papa.DefaultDelimiter = ",";
5405
+ Papa.Parser = Parser;
5406
+ Papa.ParserHandle = ParserHandle;
5407
+ Papa.NetworkStreamer = NetworkStreamer;
5408
+ Papa.FileStreamer = FileStreamer;
5409
+ Papa.StringStreamer = StringStreamer;
5410
+ Papa.ReadableStreamStreamer = ReadableStreamStreamer;
5411
+ if (typeof PAPA_BROWSER_CONTEXT === "undefined") {
5412
+ Papa.DuplexStreamStreamer = DuplexStreamStreamer;
5413
+ }
5414
+ if (global.jQuery) {
5415
+ var $2 = global.jQuery;
5416
+ $2.fn.parse = function(options) {
5417
+ var config2 = options.config || {};
5418
+ var queue = [];
5419
+ this.each(function(idx) {
5420
+ var supported = $2(this).prop("tagName").toUpperCase() === "INPUT" && $2(this).attr("type").toLowerCase() === "file" && global.FileReader;
5421
+ if (!supported || !this.files || this.files.length === 0)
5422
+ return true;
5423
+ for (var i = 0; i < this.files.length; i++) {
5424
+ queue.push({
5425
+ file: this.files[i],
5426
+ inputElem: this,
5427
+ instanceConfig: $2.extend({}, config2)
5428
+ });
5429
+ }
5430
+ });
5431
+ parseNextFile();
5432
+ return this;
5433
+ function parseNextFile() {
5434
+ if (queue.length === 0) {
5435
+ if (isFunction(options.complete))
5436
+ options.complete();
5437
+ return;
5438
+ }
5439
+ var f = queue[0];
5440
+ if (isFunction(options.before)) {
5441
+ var returned = options.before(f.file, f.inputElem);
5442
+ if (typeof returned === "object") {
5443
+ if (returned.action === "abort") {
5444
+ error("AbortError", f.file, f.inputElem, returned.reason);
5445
+ return;
5446
+ } else if (returned.action === "skip") {
5447
+ fileComplete();
5448
+ return;
5449
+ } else if (typeof returned.config === "object")
5450
+ f.instanceConfig = $2.extend(f.instanceConfig, returned.config);
5451
+ } else if (returned === "skip") {
5452
+ fileComplete();
5453
+ return;
5454
+ }
5455
+ }
5456
+ var userCompleteFunc = f.instanceConfig.complete;
5457
+ f.instanceConfig.complete = function(results) {
5458
+ if (isFunction(userCompleteFunc))
5459
+ userCompleteFunc(results, f.file, f.inputElem);
5460
+ fileComplete();
5461
+ };
5462
+ Papa.parse(f.file, f.instanceConfig);
5463
+ }
5464
+ function error(name, file, elem, reason) {
5465
+ if (isFunction(options.error))
5466
+ options.error({ name }, file, elem, reason);
5467
+ }
5468
+ function fileComplete() {
5469
+ queue.splice(0, 1);
5470
+ parseNextFile();
5471
+ }
5472
+ };
5473
+ }
5474
+ if (IS_PAPA_WORKER) {
5475
+ global.onmessage = workerThreadReceivedMessage;
5476
+ }
5477
+ function CsvToJson(_input, _config) {
5478
+ _config = _config || {};
5479
+ var dynamicTyping = _config.dynamicTyping || false;
5480
+ if (isFunction(dynamicTyping)) {
5481
+ _config.dynamicTypingFunction = dynamicTyping;
5482
+ dynamicTyping = {};
5483
+ }
5484
+ _config.dynamicTyping = dynamicTyping;
5485
+ _config.transform = isFunction(_config.transform) ? _config.transform : false;
5486
+ if (_config.worker && Papa.WORKERS_SUPPORTED) {
5487
+ var w2 = newWorker();
5488
+ w2.userStep = _config.step;
5489
+ w2.userChunk = _config.chunk;
5490
+ w2.userComplete = _config.complete;
5491
+ w2.userError = _config.error;
5492
+ _config.step = isFunction(_config.step);
5493
+ _config.chunk = isFunction(_config.chunk);
5494
+ _config.complete = isFunction(_config.complete);
5495
+ _config.error = isFunction(_config.error);
5496
+ delete _config.worker;
5497
+ w2.postMessage({
5498
+ input: _input,
5499
+ config: _config,
5500
+ workerId: w2.id
5501
+ });
5502
+ return;
5503
+ }
5504
+ var streamer = null;
5505
+ if (_input === Papa.NODE_STREAM_INPUT && typeof PAPA_BROWSER_CONTEXT === "undefined") {
5506
+ streamer = new DuplexStreamStreamer(_config);
5507
+ return streamer.getStream();
5508
+ } else if (typeof _input === "string") {
5509
+ _input = stripBom(_input);
5510
+ if (_config.download)
5511
+ streamer = new NetworkStreamer(_config);
5512
+ else
5513
+ streamer = new StringStreamer(_config);
5514
+ } else if (_input.readable === true && isFunction(_input.read) && isFunction(_input.on)) {
5515
+ streamer = new ReadableStreamStreamer(_config);
5516
+ } else if (global.File && _input instanceof File || _input instanceof Object)
5517
+ streamer = new FileStreamer(_config);
5518
+ return streamer.stream(_input);
5519
+ function stripBom(string) {
5520
+ if (string.charCodeAt(0) === 65279) {
5521
+ return string.slice(1);
5522
+ }
5523
+ return string;
5524
+ }
5525
+ }
5526
+ function JsonToCsv(_input, _config) {
5527
+ var _quotes = false;
5528
+ var _writeHeader = true;
5529
+ var _delimiter = ",";
5530
+ var _newline = "\r\n";
5531
+ var _quoteChar = '"';
5532
+ var _escapedQuote = _quoteChar + _quoteChar;
5533
+ var _skipEmptyLines = false;
5534
+ var _columns = null;
5535
+ var _escapeFormulae = false;
5536
+ unpackConfig();
5537
+ var quoteCharRegex = new RegExp(escapeRegExp(_quoteChar), "g");
5538
+ if (typeof _input === "string")
5539
+ _input = JSON.parse(_input);
5540
+ if (Array.isArray(_input)) {
5541
+ if (!_input.length || Array.isArray(_input[0]))
5542
+ return serialize(null, _input, _skipEmptyLines);
5543
+ else if (typeof _input[0] === "object")
5544
+ return serialize(_columns || Object.keys(_input[0]), _input, _skipEmptyLines);
5545
+ } else if (typeof _input === "object") {
5546
+ if (typeof _input.data === "string")
5547
+ _input.data = JSON.parse(_input.data);
5548
+ if (Array.isArray(_input.data)) {
5549
+ if (!_input.fields)
5550
+ _input.fields = _input.meta && _input.meta.fields || _columns;
5551
+ if (!_input.fields)
5552
+ _input.fields = Array.isArray(_input.data[0]) ? _input.fields : typeof _input.data[0] === "object" ? Object.keys(_input.data[0]) : [];
5553
+ if (!Array.isArray(_input.data[0]) && typeof _input.data[0] !== "object")
5554
+ _input.data = [_input.data];
5555
+ }
5556
+ return serialize(_input.fields || [], _input.data || [], _skipEmptyLines);
5557
+ }
5558
+ throw new Error("Unable to serialize unrecognized input");
5559
+ function unpackConfig() {
5560
+ if (typeof _config !== "object")
5561
+ return;
5562
+ if (typeof _config.delimiter === "string" && !Papa.BAD_DELIMITERS.filter(function(value) {
5563
+ return _config.delimiter.indexOf(value) !== -1;
5564
+ }).length) {
5565
+ _delimiter = _config.delimiter;
5566
+ }
5567
+ if (typeof _config.quotes === "boolean" || typeof _config.quotes === "function" || Array.isArray(_config.quotes))
5568
+ _quotes = _config.quotes;
5569
+ if (typeof _config.skipEmptyLines === "boolean" || typeof _config.skipEmptyLines === "string")
5570
+ _skipEmptyLines = _config.skipEmptyLines;
5571
+ if (typeof _config.newline === "string")
5572
+ _newline = _config.newline;
5573
+ if (typeof _config.quoteChar === "string")
5574
+ _quoteChar = _config.quoteChar;
5575
+ if (typeof _config.header === "boolean")
5576
+ _writeHeader = _config.header;
5577
+ if (Array.isArray(_config.columns)) {
5578
+ if (_config.columns.length === 0) throw new Error("Option columns is empty");
5579
+ _columns = _config.columns;
5580
+ }
5581
+ if (_config.escapeChar !== void 0) {
5582
+ _escapedQuote = _config.escapeChar + _quoteChar;
5583
+ }
5584
+ if (typeof _config.escapeFormulae === "boolean" || _config.escapeFormulae instanceof RegExp) {
5585
+ _escapeFormulae = _config.escapeFormulae instanceof RegExp ? _config.escapeFormulae : /^[=+\-@\t\r].*$/;
5586
+ }
5587
+ }
5588
+ function serialize(fields, data, skipEmptyLines) {
5589
+ var csv = "";
5590
+ if (typeof fields === "string")
5591
+ fields = JSON.parse(fields);
5592
+ if (typeof data === "string")
5593
+ data = JSON.parse(data);
5594
+ var hasHeader = Array.isArray(fields) && fields.length > 0;
5595
+ var dataKeyedByField = !Array.isArray(data[0]);
5596
+ if (hasHeader && _writeHeader) {
5597
+ for (var i = 0; i < fields.length; i++) {
5598
+ if (i > 0)
5599
+ csv += _delimiter;
5600
+ csv += safe(fields[i], i);
5601
+ }
5602
+ if (data.length > 0)
5603
+ csv += _newline;
5604
+ }
5605
+ for (var row = 0; row < data.length; row++) {
5606
+ var maxCol = hasHeader ? fields.length : data[row].length;
5607
+ var emptyLine = false;
5608
+ var nullLine = hasHeader ? Object.keys(data[row]).length === 0 : data[row].length === 0;
5609
+ if (skipEmptyLines && !hasHeader) {
5610
+ emptyLine = skipEmptyLines === "greedy" ? data[row].join("").trim() === "" : data[row].length === 1 && data[row][0].length === 0;
5611
+ }
5612
+ if (skipEmptyLines === "greedy" && hasHeader) {
5613
+ var line = [];
5614
+ for (var c = 0; c < maxCol; c++) {
5615
+ var cx = dataKeyedByField ? fields[c] : c;
5616
+ line.push(data[row][cx]);
5617
+ }
5618
+ emptyLine = line.join("").trim() === "";
5619
+ }
5620
+ if (!emptyLine) {
5621
+ for (var col = 0; col < maxCol; col++) {
5622
+ if (col > 0 && !nullLine)
5623
+ csv += _delimiter;
5624
+ var colIdx = hasHeader && dataKeyedByField ? fields[col] : col;
5625
+ csv += safe(data[row][colIdx], col);
5626
+ }
5627
+ if (row < data.length - 1 && (!skipEmptyLines || maxCol > 0 && !nullLine)) {
5628
+ csv += _newline;
5629
+ }
5630
+ }
5631
+ }
5632
+ return csv;
5633
+ }
5634
+ function safe(str, col) {
5635
+ if (typeof str === "undefined" || str === null)
5636
+ return "";
5637
+ if (str.constructor === Date)
5638
+ return JSON.stringify(str).slice(1, 25);
5639
+ var needsQuotes = false;
5640
+ if (_escapeFormulae && typeof str === "string" && _escapeFormulae.test(str)) {
5641
+ str = "'" + str;
5642
+ needsQuotes = true;
5643
+ }
5644
+ var escapedQuoteStr = str.toString().replace(quoteCharRegex, _escapedQuote);
5645
+ needsQuotes = needsQuotes || _quotes === true || typeof _quotes === "function" && _quotes(str, col) || Array.isArray(_quotes) && _quotes[col] || hasAny(escapedQuoteStr, Papa.BAD_DELIMITERS) || escapedQuoteStr.indexOf(_delimiter) > -1 || escapedQuoteStr.charAt(0) === " " || escapedQuoteStr.charAt(escapedQuoteStr.length - 1) === " ";
5646
+ return needsQuotes ? _quoteChar + escapedQuoteStr + _quoteChar : escapedQuoteStr;
5647
+ }
5648
+ function hasAny(str, substrings) {
5649
+ for (var i = 0; i < substrings.length; i++)
5650
+ if (str.indexOf(substrings[i]) > -1)
5651
+ return true;
5652
+ return false;
5653
+ }
5654
+ }
5655
+ function ChunkStreamer(config2) {
5656
+ this._handle = null;
5657
+ this._finished = false;
5658
+ this._completed = false;
5659
+ this._halted = false;
5660
+ this._input = null;
5661
+ this._baseIndex = 0;
5662
+ this._partialLine = "";
5663
+ this._rowCount = 0;
5664
+ this._start = 0;
5665
+ this._nextChunk = null;
5666
+ this.isFirstChunk = true;
5667
+ this._completeResults = {
5668
+ data: [],
5669
+ errors: [],
5670
+ meta: {}
5671
+ };
5672
+ replaceConfig.call(this, config2);
5673
+ this.parseChunk = function(chunk, isFakeChunk) {
5674
+ if (this.isFirstChunk && isFunction(this._config.beforeFirstChunk)) {
5675
+ var modifiedChunk = this._config.beforeFirstChunk(chunk);
5676
+ if (modifiedChunk !== void 0)
5677
+ chunk = modifiedChunk;
5678
+ }
5679
+ this.isFirstChunk = false;
5680
+ this._halted = false;
5681
+ var aggregate = this._partialLine + chunk;
5682
+ this._partialLine = "";
5683
+ var results = this._handle.parse(aggregate, this._baseIndex, !this._finished);
5684
+ if (this._handle.paused() || this._handle.aborted()) {
5685
+ this._halted = true;
5686
+ return;
5687
+ }
5688
+ var lastIndex = results.meta.cursor;
5689
+ if (!this._finished) {
5690
+ this._partialLine = aggregate.substring(lastIndex - this._baseIndex);
5691
+ this._baseIndex = lastIndex;
5692
+ }
5693
+ if (results && results.data)
5694
+ this._rowCount += results.data.length;
5695
+ var finishedIncludingPreview = this._finished || this._config.preview && this._rowCount >= this._config.preview;
5696
+ if (IS_PAPA_WORKER) {
5697
+ global.postMessage({
5698
+ results,
5699
+ workerId: Papa.WORKER_ID,
5700
+ finished: finishedIncludingPreview
5701
+ });
5702
+ } else if (isFunction(this._config.chunk) && !isFakeChunk) {
5703
+ this._config.chunk(results, this._handle);
5704
+ if (this._handle.paused() || this._handle.aborted()) {
5705
+ this._halted = true;
5706
+ return;
5707
+ }
5708
+ results = void 0;
5709
+ this._completeResults = void 0;
5710
+ }
5711
+ if (!this._config.step && !this._config.chunk) {
5712
+ this._completeResults.data = this._completeResults.data.concat(results.data);
5713
+ this._completeResults.errors = this._completeResults.errors.concat(results.errors);
5714
+ this._completeResults.meta = results.meta;
5715
+ }
5716
+ if (!this._completed && finishedIncludingPreview && isFunction(this._config.complete) && (!results || !results.meta.aborted)) {
5717
+ this._config.complete(this._completeResults, this._input);
5718
+ this._completed = true;
5719
+ }
5720
+ if (!finishedIncludingPreview && (!results || !results.meta.paused))
5721
+ this._nextChunk();
5722
+ return results;
5723
+ };
5724
+ this._sendError = function(error) {
5725
+ if (isFunction(this._config.error))
5726
+ this._config.error(error);
5727
+ else if (IS_PAPA_WORKER && this._config.error) {
5728
+ global.postMessage({
5729
+ workerId: Papa.WORKER_ID,
5730
+ error,
5731
+ finished: false
5732
+ });
5733
+ }
5734
+ };
5735
+ function replaceConfig(config3) {
5736
+ var configCopy = copy(config3);
5737
+ configCopy.chunkSize = parseInt(configCopy.chunkSize);
5738
+ if (!config3.step && !config3.chunk)
5739
+ configCopy.chunkSize = null;
5740
+ this._handle = new ParserHandle(configCopy);
5741
+ this._handle.streamer = this;
5742
+ this._config = configCopy;
5743
+ }
5744
+ }
5745
+ function NetworkStreamer(config2) {
5746
+ config2 = config2 || {};
5747
+ if (!config2.chunkSize)
5748
+ config2.chunkSize = Papa.RemoteChunkSize;
5749
+ ChunkStreamer.call(this, config2);
5750
+ var xhr;
5751
+ if (IS_WORKER) {
5752
+ this._nextChunk = function() {
5753
+ this._readChunk();
5754
+ this._chunkLoaded();
5755
+ };
5756
+ } else {
5757
+ this._nextChunk = function() {
5758
+ this._readChunk();
5759
+ };
5760
+ }
5761
+ this.stream = function(url) {
5762
+ this._input = url;
5763
+ this._nextChunk();
5764
+ };
5765
+ this._readChunk = function() {
5766
+ if (this._finished) {
5767
+ this._chunkLoaded();
5768
+ return;
5769
+ }
5770
+ xhr = new XMLHttpRequest();
5771
+ if (this._config.withCredentials) {
5772
+ xhr.withCredentials = this._config.withCredentials;
5773
+ }
5774
+ if (!IS_WORKER) {
5775
+ xhr.onload = bindFunction(this._chunkLoaded, this);
5776
+ xhr.onerror = bindFunction(this._chunkError, this);
5777
+ }
5778
+ xhr.open(this._config.downloadRequestBody ? "POST" : "GET", this._input, !IS_WORKER);
5779
+ if (this._config.downloadRequestHeaders) {
5780
+ var headers = this._config.downloadRequestHeaders;
5781
+ for (var headerName in headers) {
5782
+ xhr.setRequestHeader(headerName, headers[headerName]);
5783
+ }
5784
+ }
5785
+ if (this._config.chunkSize) {
5786
+ var end = this._start + this._config.chunkSize - 1;
5787
+ xhr.setRequestHeader("Range", "bytes=" + this._start + "-" + end);
5788
+ }
5789
+ try {
5790
+ xhr.send(this._config.downloadRequestBody);
5791
+ } catch (err) {
5792
+ this._chunkError(err.message);
5793
+ }
5794
+ if (IS_WORKER && xhr.status === 0)
5795
+ this._chunkError();
5796
+ };
5797
+ this._chunkLoaded = function() {
5798
+ if (xhr.readyState !== 4)
5799
+ return;
5800
+ if (xhr.status < 200 || xhr.status >= 400) {
5801
+ this._chunkError();
5802
+ return;
5803
+ }
5804
+ this._start += this._config.chunkSize ? this._config.chunkSize : xhr.responseText.length;
5805
+ this._finished = !this._config.chunkSize || this._start >= getFileSize(xhr);
5806
+ this.parseChunk(xhr.responseText);
5807
+ };
5808
+ this._chunkError = function(errorMessage) {
5809
+ var errorText = xhr.statusText || errorMessage;
5810
+ this._sendError(new Error(errorText));
5811
+ };
5812
+ function getFileSize(xhr2) {
5813
+ var contentRange = xhr2.getResponseHeader("Content-Range");
5814
+ if (contentRange === null) {
5815
+ return -1;
5816
+ }
5817
+ return parseInt(contentRange.substring(contentRange.lastIndexOf("/") + 1));
5818
+ }
5819
+ }
5820
+ NetworkStreamer.prototype = Object.create(ChunkStreamer.prototype);
5821
+ NetworkStreamer.prototype.constructor = NetworkStreamer;
5822
+ function FileStreamer(config2) {
5823
+ config2 = config2 || {};
5824
+ if (!config2.chunkSize)
5825
+ config2.chunkSize = Papa.LocalChunkSize;
5826
+ ChunkStreamer.call(this, config2);
5827
+ var reader, slice;
5828
+ var usingAsyncReader = typeof FileReader !== "undefined";
5829
+ this.stream = function(file) {
5830
+ this._input = file;
5831
+ slice = file.slice || file.webkitSlice || file.mozSlice;
5832
+ if (usingAsyncReader) {
5833
+ reader = new FileReader();
5834
+ reader.onload = bindFunction(this._chunkLoaded, this);
5835
+ reader.onerror = bindFunction(this._chunkError, this);
5836
+ } else
5837
+ reader = new FileReaderSync();
5838
+ this._nextChunk();
5839
+ };
5840
+ this._nextChunk = function() {
5841
+ if (!this._finished && (!this._config.preview || this._rowCount < this._config.preview))
5842
+ this._readChunk();
5843
+ };
5844
+ this._readChunk = function() {
5845
+ var input4 = this._input;
5846
+ if (this._config.chunkSize) {
5847
+ var end = Math.min(this._start + this._config.chunkSize, this._input.size);
5848
+ input4 = slice.call(input4, this._start, end);
5849
+ }
5850
+ var txt = reader.readAsText(input4, this._config.encoding);
5851
+ if (!usingAsyncReader)
5852
+ this._chunkLoaded({ target: { result: txt } });
5853
+ };
5854
+ this._chunkLoaded = function(event) {
5855
+ this._start += this._config.chunkSize;
5856
+ this._finished = !this._config.chunkSize || this._start >= this._input.size;
5857
+ this.parseChunk(event.target.result);
5858
+ };
5859
+ this._chunkError = function() {
5860
+ this._sendError(reader.error);
5861
+ };
5862
+ }
5863
+ FileStreamer.prototype = Object.create(ChunkStreamer.prototype);
5864
+ FileStreamer.prototype.constructor = FileStreamer;
5865
+ function StringStreamer(config2) {
5866
+ config2 = config2 || {};
5867
+ ChunkStreamer.call(this, config2);
5868
+ var remaining;
5869
+ this.stream = function(s) {
5870
+ remaining = s;
5871
+ return this._nextChunk();
5872
+ };
5873
+ this._nextChunk = function() {
5874
+ if (this._finished) return;
5875
+ var size = this._config.chunkSize;
5876
+ var chunk;
5877
+ if (size) {
5878
+ chunk = remaining.substring(0, size);
5879
+ remaining = remaining.substring(size);
5880
+ } else {
5881
+ chunk = remaining;
5882
+ remaining = "";
5883
+ }
5884
+ this._finished = !remaining;
5885
+ return this.parseChunk(chunk);
5886
+ };
5887
+ }
5888
+ StringStreamer.prototype = Object.create(StringStreamer.prototype);
5889
+ StringStreamer.prototype.constructor = StringStreamer;
5890
+ function ReadableStreamStreamer(config2) {
5891
+ config2 = config2 || {};
5892
+ ChunkStreamer.call(this, config2);
5893
+ var queue = [];
5894
+ var parseOnData = true;
5895
+ var streamHasEnded = false;
5896
+ this.pause = function() {
5897
+ ChunkStreamer.prototype.pause.apply(this, arguments);
5898
+ this._input.pause();
5899
+ };
5900
+ this.resume = function() {
5901
+ ChunkStreamer.prototype.resume.apply(this, arguments);
5902
+ this._input.resume();
5903
+ };
5904
+ this.stream = function(stream) {
5905
+ this._input = stream;
5906
+ this._input.on("data", this._streamData);
5907
+ this._input.on("end", this._streamEnd);
5908
+ this._input.on("error", this._streamError);
5909
+ };
5910
+ this._checkIsFinished = function() {
5911
+ if (streamHasEnded && queue.length === 1) {
5912
+ this._finished = true;
5913
+ }
5914
+ };
5915
+ this._nextChunk = function() {
5916
+ this._checkIsFinished();
5917
+ if (queue.length) {
5918
+ this.parseChunk(queue.shift());
5919
+ } else {
5920
+ parseOnData = true;
5921
+ }
5922
+ };
5923
+ this._streamData = bindFunction(function(chunk) {
5924
+ try {
5925
+ queue.push(typeof chunk === "string" ? chunk : chunk.toString(this._config.encoding));
5926
+ if (parseOnData) {
5927
+ parseOnData = false;
5928
+ this._checkIsFinished();
5929
+ this.parseChunk(queue.shift());
5930
+ }
5931
+ } catch (error) {
5932
+ this._streamError(error);
5933
+ }
5934
+ }, this);
5935
+ this._streamError = bindFunction(function(error) {
5936
+ this._streamCleanUp();
5937
+ this._sendError(error);
5938
+ }, this);
5939
+ this._streamEnd = bindFunction(function() {
5940
+ this._streamCleanUp();
5941
+ streamHasEnded = true;
5942
+ this._streamData("");
5943
+ }, this);
5944
+ this._streamCleanUp = bindFunction(function() {
5945
+ this._input.removeListener("data", this._streamData);
5946
+ this._input.removeListener("end", this._streamEnd);
5947
+ this._input.removeListener("error", this._streamError);
5948
+ }, this);
5949
+ }
5950
+ ReadableStreamStreamer.prototype = Object.create(ChunkStreamer.prototype);
5951
+ ReadableStreamStreamer.prototype.constructor = ReadableStreamStreamer;
5952
+ function DuplexStreamStreamer(_config) {
5953
+ var Duplex = require("stream").Duplex;
5954
+ var config2 = copy(_config);
5955
+ var parseOnWrite = true;
5956
+ var writeStreamHasFinished = false;
5957
+ var parseCallbackQueue = [];
5958
+ var stream = null;
5959
+ this._onCsvData = function(results) {
5960
+ var data = results.data;
5961
+ if (!stream.push(data) && !this._handle.paused()) {
5962
+ this._handle.pause();
5963
+ }
5964
+ };
5965
+ this._onCsvComplete = function() {
5966
+ stream.push(null);
5967
+ };
5968
+ config2.step = bindFunction(this._onCsvData, this);
5969
+ config2.complete = bindFunction(this._onCsvComplete, this);
5970
+ ChunkStreamer.call(this, config2);
5971
+ this._nextChunk = function() {
5972
+ if (writeStreamHasFinished && parseCallbackQueue.length === 1) {
5973
+ this._finished = true;
5974
+ }
5975
+ if (parseCallbackQueue.length) {
5976
+ parseCallbackQueue.shift()();
5977
+ } else {
5978
+ parseOnWrite = true;
5979
+ }
5980
+ };
5981
+ this._addToParseQueue = function(chunk, callback) {
5982
+ parseCallbackQueue.push(bindFunction(function() {
5983
+ this.parseChunk(typeof chunk === "string" ? chunk : chunk.toString(config2.encoding));
5984
+ if (isFunction(callback)) {
5985
+ return callback();
5986
+ }
5987
+ }, this));
5988
+ if (parseOnWrite) {
5989
+ parseOnWrite = false;
5990
+ this._nextChunk();
5991
+ }
5992
+ };
5993
+ this._onRead = function() {
5994
+ if (this._handle.paused()) {
5995
+ this._handle.resume();
5996
+ }
5997
+ };
5998
+ this._onWrite = function(chunk, encoding, callback) {
5999
+ this._addToParseQueue(chunk, callback);
6000
+ };
6001
+ this._onWriteComplete = function() {
6002
+ writeStreamHasFinished = true;
6003
+ this._addToParseQueue("");
6004
+ };
6005
+ this.getStream = function() {
6006
+ return stream;
6007
+ };
6008
+ stream = new Duplex({
6009
+ readableObjectMode: true,
6010
+ decodeStrings: false,
6011
+ read: bindFunction(this._onRead, this),
6012
+ write: bindFunction(this._onWrite, this)
6013
+ });
6014
+ stream.once("finish", bindFunction(this._onWriteComplete, this));
6015
+ }
6016
+ if (typeof PAPA_BROWSER_CONTEXT === "undefined") {
6017
+ DuplexStreamStreamer.prototype = Object.create(ChunkStreamer.prototype);
6018
+ DuplexStreamStreamer.prototype.constructor = DuplexStreamStreamer;
6019
+ }
6020
+ function ParserHandle(_config) {
6021
+ var MAX_FLOAT = Math.pow(2, 53);
6022
+ var MIN_FLOAT = -MAX_FLOAT;
6023
+ var FLOAT = /^\s*-?(\d+\.?|\.\d+|\d+\.\d+)([eE][-+]?\d+)?\s*$/;
6024
+ var ISO_DATE = /^((\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z)))$/;
6025
+ var self2 = this;
6026
+ var _stepCounter = 0;
6027
+ var _rowCounter = 0;
6028
+ var _input;
6029
+ var _parser;
6030
+ var _paused = false;
6031
+ var _aborted = false;
6032
+ var _delimiterError;
6033
+ var _fields = [];
6034
+ var _results = {
6035
+ // The last results returned from the parser
6036
+ data: [],
6037
+ errors: [],
6038
+ meta: {}
6039
+ };
6040
+ if (isFunction(_config.step)) {
6041
+ var userStep = _config.step;
6042
+ _config.step = function(results) {
6043
+ _results = results;
6044
+ if (needsHeaderRow())
6045
+ processResults();
6046
+ else {
6047
+ processResults();
6048
+ if (_results.data.length === 0)
6049
+ return;
6050
+ _stepCounter += results.data.length;
6051
+ if (_config.preview && _stepCounter > _config.preview)
6052
+ _parser.abort();
6053
+ else {
6054
+ _results.data = _results.data[0];
6055
+ userStep(_results, self2);
6056
+ }
6057
+ }
6058
+ };
6059
+ }
6060
+ this.parse = function(input4, baseIndex, ignoreLastRow) {
6061
+ var quoteChar = _config.quoteChar || '"';
6062
+ if (!_config.newline)
6063
+ _config.newline = guessLineEndings(input4, quoteChar);
6064
+ _delimiterError = false;
6065
+ if (!_config.delimiter) {
6066
+ var delimGuess = guessDelimiter(input4, _config.newline, _config.skipEmptyLines, _config.comments, _config.delimitersToGuess);
6067
+ if (delimGuess.successful)
6068
+ _config.delimiter = delimGuess.bestDelimiter;
6069
+ else {
6070
+ _delimiterError = true;
6071
+ _config.delimiter = Papa.DefaultDelimiter;
6072
+ }
6073
+ _results.meta.delimiter = _config.delimiter;
6074
+ } else if (isFunction(_config.delimiter)) {
6075
+ _config.delimiter = _config.delimiter(input4);
6076
+ _results.meta.delimiter = _config.delimiter;
6077
+ }
6078
+ var parserConfig = copy(_config);
6079
+ if (_config.preview && _config.header)
6080
+ parserConfig.preview++;
6081
+ _input = input4;
6082
+ _parser = new Parser(parserConfig);
6083
+ _results = _parser.parse(_input, baseIndex, ignoreLastRow);
6084
+ processResults();
6085
+ return _paused ? { meta: { paused: true } } : _results || { meta: { paused: false } };
6086
+ };
6087
+ this.paused = function() {
6088
+ return _paused;
6089
+ };
6090
+ this.pause = function() {
6091
+ _paused = true;
6092
+ _parser.abort();
6093
+ _input = isFunction(_config.chunk) ? "" : _input.substring(_parser.getCharIndex());
6094
+ };
6095
+ this.resume = function() {
6096
+ if (self2.streamer._halted) {
6097
+ _paused = false;
6098
+ self2.streamer.parseChunk(_input, true);
6099
+ } else {
6100
+ setTimeout(self2.resume, 3);
6101
+ }
6102
+ };
6103
+ this.aborted = function() {
6104
+ return _aborted;
6105
+ };
6106
+ this.abort = function() {
6107
+ _aborted = true;
6108
+ _parser.abort();
6109
+ _results.meta.aborted = true;
6110
+ if (isFunction(_config.complete))
6111
+ _config.complete(_results);
6112
+ _input = "";
6113
+ };
6114
+ function testEmptyLine(s) {
6115
+ return _config.skipEmptyLines === "greedy" ? s.join("").trim() === "" : s.length === 1 && s[0].length === 0;
6116
+ }
6117
+ function testFloat(s) {
6118
+ if (FLOAT.test(s)) {
6119
+ var floatValue = parseFloat(s);
6120
+ if (floatValue > MIN_FLOAT && floatValue < MAX_FLOAT) {
6121
+ return true;
6122
+ }
6123
+ }
6124
+ return false;
6125
+ }
6126
+ function processResults() {
6127
+ if (_results && _delimiterError) {
6128
+ addError("Delimiter", "UndetectableDelimiter", "Unable to auto-detect delimiting character; defaulted to '" + Papa.DefaultDelimiter + "'");
6129
+ _delimiterError = false;
6130
+ }
6131
+ if (_config.skipEmptyLines) {
6132
+ _results.data = _results.data.filter(function(d2) {
6133
+ return !testEmptyLine(d2);
6134
+ });
6135
+ }
6136
+ if (needsHeaderRow())
6137
+ fillHeaderFields();
6138
+ return applyHeaderAndDynamicTypingAndTransformation();
6139
+ }
6140
+ function needsHeaderRow() {
6141
+ return _config.header && _fields.length === 0;
6142
+ }
6143
+ function fillHeaderFields() {
6144
+ if (!_results)
6145
+ return;
6146
+ function addHeader(header, i2) {
6147
+ if (isFunction(_config.transformHeader))
6148
+ header = _config.transformHeader(header, i2);
6149
+ _fields.push(header);
6150
+ }
6151
+ if (Array.isArray(_results.data[0])) {
6152
+ for (var i = 0; needsHeaderRow() && i < _results.data.length; i++)
6153
+ _results.data[i].forEach(addHeader);
6154
+ _results.data.splice(0, 1);
6155
+ } else
6156
+ _results.data.forEach(addHeader);
6157
+ }
6158
+ function shouldApplyDynamicTyping(field) {
6159
+ if (_config.dynamicTypingFunction && _config.dynamicTyping[field] === void 0) {
6160
+ _config.dynamicTyping[field] = _config.dynamicTypingFunction(field);
6161
+ }
6162
+ return (_config.dynamicTyping[field] || _config.dynamicTyping) === true;
6163
+ }
6164
+ function parseDynamic(field, value) {
6165
+ if (shouldApplyDynamicTyping(field)) {
6166
+ if (value === "true" || value === "TRUE")
6167
+ return true;
6168
+ else if (value === "false" || value === "FALSE")
6169
+ return false;
6170
+ else if (testFloat(value))
6171
+ return parseFloat(value);
6172
+ else if (ISO_DATE.test(value))
6173
+ return new Date(value);
6174
+ else
6175
+ return value === "" ? null : value;
6176
+ }
6177
+ return value;
6178
+ }
6179
+ function applyHeaderAndDynamicTypingAndTransformation() {
6180
+ if (!_results || !_config.header && !_config.dynamicTyping && !_config.transform)
6181
+ return _results;
6182
+ function processRow(rowSource, i) {
6183
+ var row = _config.header ? {} : [];
6184
+ var j2;
6185
+ for (j2 = 0; j2 < rowSource.length; j2++) {
6186
+ var field = j2;
6187
+ var value = rowSource[j2];
6188
+ if (_config.header)
6189
+ field = j2 >= _fields.length ? "__parsed_extra" : _fields[j2];
6190
+ if (_config.transform)
6191
+ value = _config.transform(value, field);
6192
+ value = parseDynamic(field, value);
6193
+ if (field === "__parsed_extra") {
6194
+ row[field] = row[field] || [];
6195
+ row[field].push(value);
6196
+ } else
6197
+ row[field] = value;
6198
+ }
6199
+ if (_config.header) {
6200
+ if (j2 > _fields.length)
6201
+ addError("FieldMismatch", "TooManyFields", "Too many fields: expected " + _fields.length + " fields but parsed " + j2, _rowCounter + i);
6202
+ else if (j2 < _fields.length)
6203
+ addError("FieldMismatch", "TooFewFields", "Too few fields: expected " + _fields.length + " fields but parsed " + j2, _rowCounter + i);
6204
+ }
6205
+ return row;
6206
+ }
6207
+ var incrementBy = 1;
6208
+ if (!_results.data.length || Array.isArray(_results.data[0])) {
6209
+ _results.data = _results.data.map(processRow);
6210
+ incrementBy = _results.data.length;
6211
+ } else
6212
+ _results.data = processRow(_results.data, 0);
6213
+ if (_config.header && _results.meta)
6214
+ _results.meta.fields = _fields;
6215
+ _rowCounter += incrementBy;
6216
+ return _results;
6217
+ }
6218
+ function guessDelimiter(input4, newline, skipEmptyLines, comments, delimitersToGuess) {
6219
+ var bestDelim, bestDelta, fieldCountPrevRow, maxFieldCount;
6220
+ delimitersToGuess = delimitersToGuess || [",", " ", "|", ";", Papa.RECORD_SEP, Papa.UNIT_SEP];
6221
+ for (var i = 0; i < delimitersToGuess.length; i++) {
6222
+ var delim = delimitersToGuess[i];
6223
+ var delta = 0, avgFieldCount = 0, emptyLinesCount = 0;
6224
+ fieldCountPrevRow = void 0;
6225
+ var preview = new Parser({
6226
+ comments,
6227
+ delimiter: delim,
6228
+ newline,
6229
+ preview: 10
6230
+ }).parse(input4);
6231
+ for (var j2 = 0; j2 < preview.data.length; j2++) {
6232
+ if (skipEmptyLines && testEmptyLine(preview.data[j2])) {
6233
+ emptyLinesCount++;
6234
+ continue;
6235
+ }
6236
+ var fieldCount = preview.data[j2].length;
6237
+ avgFieldCount += fieldCount;
6238
+ if (typeof fieldCountPrevRow === "undefined") {
6239
+ fieldCountPrevRow = fieldCount;
6240
+ continue;
6241
+ } else if (fieldCount > 0) {
6242
+ delta += Math.abs(fieldCount - fieldCountPrevRow);
6243
+ fieldCountPrevRow = fieldCount;
6244
+ }
6245
+ }
6246
+ if (preview.data.length > 0)
6247
+ avgFieldCount /= preview.data.length - emptyLinesCount;
6248
+ if ((typeof bestDelta === "undefined" || delta <= bestDelta) && (typeof maxFieldCount === "undefined" || avgFieldCount > maxFieldCount) && avgFieldCount > 1.99) {
6249
+ bestDelta = delta;
6250
+ bestDelim = delim;
6251
+ maxFieldCount = avgFieldCount;
6252
+ }
6253
+ }
6254
+ _config.delimiter = bestDelim;
6255
+ return {
6256
+ successful: !!bestDelim,
6257
+ bestDelimiter: bestDelim
6258
+ };
6259
+ }
6260
+ function guessLineEndings(input4, quoteChar) {
6261
+ input4 = input4.substring(0, 1024 * 1024);
6262
+ var re2 = new RegExp(escapeRegExp(quoteChar) + "([^]*?)" + escapeRegExp(quoteChar), "gm");
6263
+ input4 = input4.replace(re2, "");
6264
+ var r = input4.split("\r");
6265
+ var n = input4.split("\n");
6266
+ var nAppearsFirst = n.length > 1 && n[0].length < r[0].length;
6267
+ if (r.length === 1 || nAppearsFirst)
6268
+ return "\n";
6269
+ var numWithN = 0;
6270
+ for (var i = 0; i < r.length; i++) {
6271
+ if (r[i][0] === "\n")
6272
+ numWithN++;
6273
+ }
6274
+ return numWithN >= r.length / 2 ? "\r\n" : "\r";
6275
+ }
6276
+ function addError(type, code, msg, row) {
6277
+ var error = {
6278
+ type,
6279
+ code,
6280
+ message: msg
6281
+ };
6282
+ if (row !== void 0) {
6283
+ error.row = row;
6284
+ }
6285
+ _results.errors.push(error);
6286
+ }
6287
+ }
6288
+ function escapeRegExp(string) {
6289
+ return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
6290
+ }
6291
+ function Parser(config2) {
6292
+ config2 = config2 || {};
6293
+ var delim = config2.delimiter;
6294
+ var newline = config2.newline;
6295
+ var comments = config2.comments;
6296
+ var step = config2.step;
6297
+ var preview = config2.preview;
6298
+ var fastMode = config2.fastMode;
6299
+ var quoteChar;
6300
+ if (config2.quoteChar === void 0 || config2.quoteChar === null) {
6301
+ quoteChar = '"';
6302
+ } else {
6303
+ quoteChar = config2.quoteChar;
6304
+ }
6305
+ var escapeChar = quoteChar;
6306
+ if (config2.escapeChar !== void 0) {
6307
+ escapeChar = config2.escapeChar;
6308
+ }
6309
+ if (typeof delim !== "string" || Papa.BAD_DELIMITERS.indexOf(delim) > -1)
6310
+ delim = ",";
6311
+ if (comments === delim)
6312
+ throw new Error("Comment character same as delimiter");
6313
+ else if (comments === true)
6314
+ comments = "#";
6315
+ else if (typeof comments !== "string" || Papa.BAD_DELIMITERS.indexOf(comments) > -1)
6316
+ comments = false;
6317
+ if (newline !== "\n" && newline !== "\r" && newline !== "\r\n")
6318
+ newline = "\n";
6319
+ var cursor = 0;
6320
+ var aborted = false;
6321
+ this.parse = function(input4, baseIndex, ignoreLastRow) {
6322
+ if (typeof input4 !== "string")
6323
+ throw new Error("Input must be a string");
6324
+ var inputLen = input4.length, delimLen = delim.length, newlineLen = newline.length, commentsLen = comments.length;
6325
+ var stepIsFunction = isFunction(step);
6326
+ cursor = 0;
6327
+ var data = [], errors = [], row = [], lastCursor = 0;
6328
+ if (!input4)
6329
+ return returnable();
6330
+ if (config2.header && !baseIndex) {
6331
+ var firstLine = input4.split(newline)[0];
6332
+ var headers = firstLine.split(delim);
6333
+ var separator = "_";
6334
+ var headerMap = [];
6335
+ var headerCount = {};
6336
+ var duplicateHeaders = false;
6337
+ for (var j2 in headers) {
6338
+ var header = headers[j2];
6339
+ if (isFunction(config2.transformHeader))
6340
+ header = config2.transformHeader(header, j2);
6341
+ var headerName = header;
6342
+ var count = headerCount[header] || 0;
6343
+ if (count > 0) {
6344
+ duplicateHeaders = true;
6345
+ headerName = header + separator + count;
6346
+ }
6347
+ headerCount[header] = count + 1;
6348
+ while (headerMap.includes(headerName)) {
6349
+ headerName = headerName + separator + count;
6350
+ }
6351
+ headerMap.push(headerName);
6352
+ }
6353
+ if (duplicateHeaders) {
6354
+ var editedInput = input4.split(newline);
6355
+ editedInput[0] = headerMap.join(delim);
6356
+ input4 = editedInput.join(newline);
6357
+ }
6358
+ }
6359
+ if (fastMode || fastMode !== false && input4.indexOf(quoteChar) === -1) {
6360
+ var rows = input4.split(newline);
6361
+ for (var i = 0; i < rows.length; i++) {
6362
+ row = rows[i];
6363
+ cursor += row.length;
6364
+ if (i !== rows.length - 1)
6365
+ cursor += newline.length;
6366
+ else if (ignoreLastRow)
6367
+ return returnable();
6368
+ if (comments && row.substring(0, commentsLen) === comments)
6369
+ continue;
6370
+ if (stepIsFunction) {
6371
+ data = [];
6372
+ pushRow(row.split(delim));
6373
+ doStep();
6374
+ if (aborted)
6375
+ return returnable();
6376
+ } else
6377
+ pushRow(row.split(delim));
6378
+ if (preview && i >= preview) {
6379
+ data = data.slice(0, preview);
6380
+ return returnable(true);
6381
+ }
6382
+ }
6383
+ return returnable();
6384
+ }
6385
+ var nextDelim = input4.indexOf(delim, cursor);
6386
+ var nextNewline = input4.indexOf(newline, cursor);
6387
+ var quoteCharRegex = new RegExp(escapeRegExp(escapeChar) + escapeRegExp(quoteChar), "g");
6388
+ var quoteSearch = input4.indexOf(quoteChar, cursor);
6389
+ for (; ; ) {
6390
+ if (input4[cursor] === quoteChar) {
6391
+ quoteSearch = cursor;
6392
+ cursor++;
6393
+ for (; ; ) {
6394
+ quoteSearch = input4.indexOf(quoteChar, quoteSearch + 1);
6395
+ if (quoteSearch === -1) {
6396
+ if (!ignoreLastRow) {
6397
+ errors.push({
6398
+ type: "Quotes",
6399
+ code: "MissingQuotes",
6400
+ message: "Quoted field unterminated",
6401
+ row: data.length,
6402
+ // row has yet to be inserted
6403
+ index: cursor
6404
+ });
6405
+ }
6406
+ return finish();
6407
+ }
6408
+ if (quoteSearch === inputLen - 1) {
6409
+ var value = input4.substring(cursor, quoteSearch).replace(quoteCharRegex, quoteChar);
6410
+ return finish(value);
6411
+ }
6412
+ if (quoteChar === escapeChar && input4[quoteSearch + 1] === escapeChar) {
6413
+ quoteSearch++;
6414
+ continue;
6415
+ }
6416
+ if (quoteChar !== escapeChar && quoteSearch !== 0 && input4[quoteSearch - 1] === escapeChar) {
6417
+ continue;
6418
+ }
6419
+ if (nextDelim !== -1 && nextDelim < quoteSearch + 1) {
6420
+ nextDelim = input4.indexOf(delim, quoteSearch + 1);
6421
+ }
6422
+ if (nextNewline !== -1 && nextNewline < quoteSearch + 1) {
6423
+ nextNewline = input4.indexOf(newline, quoteSearch + 1);
6424
+ }
6425
+ var checkUpTo = nextNewline === -1 ? nextDelim : Math.min(nextDelim, nextNewline);
6426
+ var spacesBetweenQuoteAndDelimiter = extraSpaces(checkUpTo);
6427
+ if (input4.substr(quoteSearch + 1 + spacesBetweenQuoteAndDelimiter, delimLen) === delim) {
6428
+ row.push(input4.substring(cursor, quoteSearch).replace(quoteCharRegex, quoteChar));
6429
+ cursor = quoteSearch + 1 + spacesBetweenQuoteAndDelimiter + delimLen;
6430
+ if (input4[quoteSearch + 1 + spacesBetweenQuoteAndDelimiter + delimLen] !== quoteChar) {
6431
+ quoteSearch = input4.indexOf(quoteChar, cursor);
6432
+ }
6433
+ nextDelim = input4.indexOf(delim, cursor);
6434
+ nextNewline = input4.indexOf(newline, cursor);
6435
+ break;
6436
+ }
6437
+ var spacesBetweenQuoteAndNewLine = extraSpaces(nextNewline);
6438
+ if (input4.substring(quoteSearch + 1 + spacesBetweenQuoteAndNewLine, quoteSearch + 1 + spacesBetweenQuoteAndNewLine + newlineLen) === newline) {
6439
+ row.push(input4.substring(cursor, quoteSearch).replace(quoteCharRegex, quoteChar));
6440
+ saveRow(quoteSearch + 1 + spacesBetweenQuoteAndNewLine + newlineLen);
6441
+ nextDelim = input4.indexOf(delim, cursor);
6442
+ quoteSearch = input4.indexOf(quoteChar, cursor);
6443
+ if (stepIsFunction) {
6444
+ doStep();
6445
+ if (aborted)
6446
+ return returnable();
6447
+ }
6448
+ if (preview && data.length >= preview)
6449
+ return returnable(true);
6450
+ break;
6451
+ }
6452
+ errors.push({
6453
+ type: "Quotes",
6454
+ code: "InvalidQuotes",
6455
+ message: "Trailing quote on quoted field is malformed",
6456
+ row: data.length,
6457
+ // row has yet to be inserted
6458
+ index: cursor
6459
+ });
6460
+ quoteSearch++;
6461
+ continue;
6462
+ }
6463
+ continue;
6464
+ }
6465
+ if (comments && row.length === 0 && input4.substring(cursor, cursor + commentsLen) === comments) {
6466
+ if (nextNewline === -1)
6467
+ return returnable();
6468
+ cursor = nextNewline + newlineLen;
6469
+ nextNewline = input4.indexOf(newline, cursor);
6470
+ nextDelim = input4.indexOf(delim, cursor);
6471
+ continue;
6472
+ }
6473
+ if (nextDelim !== -1 && (nextDelim < nextNewline || nextNewline === -1)) {
6474
+ row.push(input4.substring(cursor, nextDelim));
6475
+ cursor = nextDelim + delimLen;
6476
+ nextDelim = input4.indexOf(delim, cursor);
6477
+ continue;
6478
+ }
6479
+ if (nextNewline !== -1) {
6480
+ row.push(input4.substring(cursor, nextNewline));
6481
+ saveRow(nextNewline + newlineLen);
6482
+ if (stepIsFunction) {
6483
+ doStep();
6484
+ if (aborted)
6485
+ return returnable();
6486
+ }
6487
+ if (preview && data.length >= preview)
6488
+ return returnable(true);
6489
+ continue;
6490
+ }
6491
+ break;
6492
+ }
6493
+ return finish();
6494
+ function pushRow(row2) {
6495
+ data.push(row2);
6496
+ lastCursor = cursor;
6497
+ }
6498
+ function extraSpaces(index) {
6499
+ var spaceLength = 0;
6500
+ if (index !== -1) {
6501
+ var textBetweenClosingQuoteAndIndex = input4.substring(quoteSearch + 1, index);
6502
+ if (textBetweenClosingQuoteAndIndex && textBetweenClosingQuoteAndIndex.trim() === "") {
6503
+ spaceLength = textBetweenClosingQuoteAndIndex.length;
6504
+ }
6505
+ }
6506
+ return spaceLength;
6507
+ }
6508
+ function finish(value2) {
6509
+ if (ignoreLastRow)
6510
+ return returnable();
6511
+ if (typeof value2 === "undefined")
6512
+ value2 = input4.substring(cursor);
6513
+ row.push(value2);
6514
+ cursor = inputLen;
6515
+ pushRow(row);
6516
+ if (stepIsFunction)
6517
+ doStep();
6518
+ return returnable();
6519
+ }
6520
+ function saveRow(newCursor) {
6521
+ cursor = newCursor;
6522
+ pushRow(row);
6523
+ row = [];
6524
+ nextNewline = input4.indexOf(newline, cursor);
6525
+ }
6526
+ function returnable(stopped) {
6527
+ return {
6528
+ data,
6529
+ errors,
6530
+ meta: {
6531
+ delimiter: delim,
6532
+ linebreak: newline,
6533
+ aborted,
6534
+ truncated: !!stopped,
6535
+ cursor: lastCursor + (baseIndex || 0)
6536
+ }
6537
+ };
6538
+ }
6539
+ function doStep() {
6540
+ step(returnable());
6541
+ data = [];
6542
+ errors = [];
6543
+ }
6544
+ };
6545
+ this.abort = function() {
6546
+ aborted = true;
6547
+ };
6548
+ this.getCharIndex = function() {
6549
+ return cursor;
6550
+ };
6551
+ }
6552
+ function newWorker() {
6553
+ if (!Papa.WORKERS_SUPPORTED)
6554
+ return false;
6555
+ var workerUrl = getWorkerBlob();
6556
+ var w2 = new global.Worker(workerUrl);
6557
+ w2.onmessage = mainThreadReceivedMessage;
6558
+ w2.id = workerIdCounter++;
6559
+ workers[w2.id] = w2;
6560
+ return w2;
6561
+ }
6562
+ function mainThreadReceivedMessage(e) {
6563
+ var msg = e.data;
6564
+ var worker = workers[msg.workerId];
6565
+ var aborted = false;
6566
+ if (msg.error)
6567
+ worker.userError(msg.error, msg.file);
6568
+ else if (msg.results && msg.results.data) {
6569
+ var abort = function() {
6570
+ aborted = true;
6571
+ completeWorker(msg.workerId, { data: [], errors: [], meta: { aborted: true } });
6572
+ };
6573
+ var handle = {
6574
+ abort,
6575
+ pause: notImplemented,
6576
+ resume: notImplemented
6577
+ };
6578
+ if (isFunction(worker.userStep)) {
6579
+ for (var i = 0; i < msg.results.data.length; i++) {
6580
+ worker.userStep({
6581
+ data: msg.results.data[i],
6582
+ errors: msg.results.errors,
6583
+ meta: msg.results.meta
6584
+ }, handle);
6585
+ if (aborted)
6586
+ break;
6587
+ }
6588
+ delete msg.results;
6589
+ } else if (isFunction(worker.userChunk)) {
6590
+ worker.userChunk(msg.results, handle, msg.file);
6591
+ delete msg.results;
6592
+ }
6593
+ }
6594
+ if (msg.finished && !aborted)
6595
+ completeWorker(msg.workerId, msg.results);
6596
+ }
6597
+ function completeWorker(workerId, results) {
6598
+ var worker = workers[workerId];
6599
+ if (isFunction(worker.userComplete))
6600
+ worker.userComplete(results);
6601
+ worker.terminate();
6602
+ delete workers[workerId];
6603
+ }
6604
+ function notImplemented() {
6605
+ throw new Error("Not implemented.");
6606
+ }
6607
+ function workerThreadReceivedMessage(e) {
6608
+ var msg = e.data;
6609
+ if (typeof Papa.WORKER_ID === "undefined" && msg)
6610
+ Papa.WORKER_ID = msg.workerId;
6611
+ if (typeof msg.input === "string") {
6612
+ global.postMessage({
6613
+ workerId: Papa.WORKER_ID,
6614
+ results: Papa.parse(msg.input, msg.config),
6615
+ finished: true
6616
+ });
6617
+ } else if (global.File && msg.input instanceof File || msg.input instanceof Object) {
6618
+ var results = Papa.parse(msg.input, msg.config);
6619
+ if (results)
6620
+ global.postMessage({
6621
+ workerId: Papa.WORKER_ID,
6622
+ results,
6623
+ finished: true
6624
+ });
6625
+ }
6626
+ }
6627
+ function copy(obj) {
6628
+ if (typeof obj !== "object" || obj === null)
6629
+ return obj;
6630
+ var cpy = Array.isArray(obj) ? [] : {};
6631
+ for (var key in obj)
6632
+ cpy[key] = copy(obj[key]);
6633
+ return cpy;
6634
+ }
6635
+ function bindFunction(f, self2) {
6636
+ return function() {
6637
+ f.apply(self2, arguments);
6638
+ };
6639
+ }
6640
+ function isFunction(func) {
6641
+ return typeof func === "function";
6642
+ }
6643
+ return Papa;
6644
+ });
6645
+ }
6646
+ });
6647
+
5320
6648
  // packages/helloao-cli/cli.ts
5321
6649
  var import_commander = require("commander");
5322
6650
  var import_path4 = __toESM(require("path"), 1);
@@ -5327,11 +6655,21 @@ var import_linkedom2 = require("linkedom");
5327
6655
  var import_fs_extra = require("fs-extra");
5328
6656
  var import_node_stream = require("node:stream");
5329
6657
  var import_promises = require("node:stream/promises");
5330
- async function downloadFile(url, path5) {
6658
+ async function downloadFile(url, path5, onProgress) {
5331
6659
  console.log("Downloading", url, "to", path5);
5332
- const reader = await fetch(url).then((r) => r.body);
6660
+ const response = await fetch(url);
6661
+ const totalSize = Number(response.headers.get("content-length"));
6662
+ const reader = response.body;
5333
6663
  const writeStream = (0, import_fs_extra.createWriteStream)(path5);
5334
- await (0, import_promises.finished)(import_node_stream.Readable.fromWeb(reader).pipe(writeStream));
6664
+ const readable = import_node_stream.Readable.fromWeb(reader);
6665
+ if (onProgress) {
6666
+ let downloadedSize = 0;
6667
+ readable.on("data", (chunk) => {
6668
+ downloadedSize += chunk.length;
6669
+ onProgress(downloadedSize / totalSize);
6670
+ });
6671
+ }
6672
+ await (0, import_promises.finished)(readable.pipe(writeStream));
5335
6673
  }
5336
6674
 
5337
6675
  // packages/helloao-cli/db.ts
@@ -6195,7 +7533,7 @@ function* batch(input4, batchSize) {
6195
7533
  }
6196
7534
 
6197
7535
  // packages/helloao-tools/dist/esm/parser/usx-parser.js
6198
- var PARSER_VERSION = "1";
7536
+ var PARSER_VERSION = "2";
6199
7537
  var USXParser = class {
6200
7538
  _domParser;
6201
7539
  _noteCounter = 0;
@@ -6314,6 +7652,7 @@ var USXParser = class {
6314
7652
  }
6315
7653
  }
6316
7654
  *iterateVerseContent(chapter, verse, nodes) {
7655
+ let lastParent = null;
6317
7656
  while (true) {
6318
7657
  const { done, value: node } = nodes.next();
6319
7658
  if (done) {
@@ -6329,8 +7668,19 @@ var USXParser = class {
6329
7668
  const style = parent.getAttribute("style");
6330
7669
  if (style === "q1" || style === "q2" || style === "q3" || style === "q4") {
6331
7670
  poem = style === "q1" ? 1 : style === "q2" ? 2 : style === "q3" ? 3 : 4;
6332
- } else if (style === "d") {
6333
- descriptive = true;
7671
+ if (parent.previousElementSibling?.nodeName === "para") {
7672
+ const previousStyle = parent.previousElementSibling?.getAttribute(
7673
+ "style"
7674
+ );
7675
+ if (previousStyle === style && lastParent !== parent) {
7676
+ lastParent = parent;
7677
+ yield {
7678
+ lineBreak: true
7679
+ };
7680
+ }
7681
+ }
7682
+ } else if (style === "d") {
7683
+ descriptive = true;
6334
7684
  }
6335
7685
  }
6336
7686
  for (let content of this.iterateNodeTextContent(
@@ -11016,7 +12366,7 @@ function getFirstNonEmpty(...values) {
11016
12366
  throw new Error("All values are empty or whitespace!");
11017
12367
  }
11018
12368
  function parseVerseReference(text) {
11019
- const match = text.match(/^\s*([A-Z]+)\s+(\d+):(\d+)/);
12369
+ const match = text.match(/^\s*([0-9A-Za-z\s]+)\s+(\d+):(\d+)/);
11020
12370
  if (!match) {
11021
12371
  return null;
11022
12372
  }
@@ -11028,18 +12378,168 @@ function parseVerseReference(text) {
11028
12378
  }
11029
12379
  if (reference.length !== text.length) {
11030
12380
  return {
11031
- book,
12381
+ book: getBookId(book) ?? book,
11032
12382
  chapter,
11033
12383
  verse,
11034
12384
  content: text.substring(reference.length).trim()
11035
12385
  };
11036
12386
  }
11037
12387
  return {
11038
- book,
12388
+ book: getBookId(book) ?? book,
11039
12389
  chapter,
11040
12390
  verse
11041
12391
  };
11042
12392
  }
12393
+ var BOOK_ID_MAP = /* @__PURE__ */ new Map([
12394
+ ["gen", "GEN"],
12395
+ ["genesis", "GEN"],
12396
+ ["exo", "EXO"],
12397
+ ["exodus", "EXO"],
12398
+ ["lev", "LEV"],
12399
+ ["lev", "LEV"],
12400
+ ["laviticus", "LEV"],
12401
+ ["num", "NUM"],
12402
+ ["numbers", "NUM"],
12403
+ ["deu", "DEU"],
12404
+ ["deuteronomy", "DEU"],
12405
+ ["jos", "JOS"],
12406
+ ["joshua", "JOS"],
12407
+ ["jdg", "JDG"],
12408
+ ["judges", "JDG"],
12409
+ ["rut", "RUT"],
12410
+ ["ruth", "RUT"],
12411
+ ["1sa", "1SA"],
12412
+ ["1samuel", "1SA"],
12413
+ ["2sa", "2SA"],
12414
+ ["2samuel", "2SA"],
12415
+ ["1ki", "1KI"],
12416
+ ["1kings", "1KI"],
12417
+ ["2ki", "2KI"],
12418
+ ["2kings", "2KI"],
12419
+ ["1ch", "1CH"],
12420
+ ["1chronicles", "1CH"],
12421
+ ["chronicles1", "1CH"],
12422
+ ["2ch", "2CH"],
12423
+ ["2chronicles", "2CH"],
12424
+ ["chronicles2", "2CH"],
12425
+ ["ezr", "EZR"],
12426
+ ["ezra", "EZR"],
12427
+ ["neh", "NEH"],
12428
+ ["nehemiah", "NEH"],
12429
+ ["est", "EST"],
12430
+ ["ester", "EST"],
12431
+ ["job", "JOB"],
12432
+ ["psa", "PSA"],
12433
+ ["psalms", "PSA"],
12434
+ ["psalm", "PSA"],
12435
+ ["pro", "PRO"],
12436
+ ["proverbs", "PRO"],
12437
+ ["ecc", "ECC"],
12438
+ ["ecclesiastes", "ECC"],
12439
+ ["sng", "SNG"],
12440
+ ["songofsolomon", "SNG"],
12441
+ ["isa", "ISA"],
12442
+ ["isaiah", "ISA"],
12443
+ ["jer", "JER"],
12444
+ ["jeremiah", "JER"],
12445
+ ["lam", "LAM"],
12446
+ ["lamentations", "LAM"],
12447
+ ["ezk", "EZK"],
12448
+ ["ezekiel", "EZK"],
12449
+ ["dan", "DAN"],
12450
+ ["daniel", "DAN"],
12451
+ ["hos", "HOS"],
12452
+ ["hosea", "HOS"],
12453
+ ["jol", "JOL"],
12454
+ ["joel", "JOL"],
12455
+ ["amo", "AMO"],
12456
+ ["amos", "AMO"],
12457
+ ["oba", "OBA"],
12458
+ ["obadiah", "OBA"],
12459
+ ["jon", "JON"],
12460
+ ["jonah", "JON"],
12461
+ ["mic", "MIC"],
12462
+ ["micah", "MIC"],
12463
+ ["nam", "NAM"],
12464
+ ["nahum", "NAM"],
12465
+ ["hab", "HAB"],
12466
+ ["habakkuk", "HAB"],
12467
+ ["zep", "ZEP"],
12468
+ ["zepaniah", "ZEP"],
12469
+ ["hag", "HAG"],
12470
+ ["haggai", "HAG"],
12471
+ ["zec", "ZEC"],
12472
+ ["zechariah", "ZEC"],
12473
+ ["mal", "MAL"],
12474
+ ["malachi", "MAL"],
12475
+ ["mat", "MAT"],
12476
+ ["matthew", "MAT"],
12477
+ ["mrk", "MRK"],
12478
+ ["mark", "MRK"],
12479
+ ["luk", "LUK"],
12480
+ ["luke", "LUK"],
12481
+ ["jhn", "JHN"],
12482
+ ["john", "JHN"],
12483
+ ["act", "ACT"],
12484
+ ["acts", "ACT"],
12485
+ ["rom", "ROM"],
12486
+ ["romans", "ROM"],
12487
+ ["1co", "1CO"],
12488
+ ["1corinthians", "1CO"],
12489
+ ["2co", "2CO"],
12490
+ ["2corinthians", "2CO"],
12491
+ ["gal", "GAL"],
12492
+ ["galatians", "GAL"],
12493
+ ["eph", "EPH"],
12494
+ ["ephesians", "EPH"],
12495
+ ["php", "PHP"],
12496
+ ["philippians", "PHP"],
12497
+ ["col", "COL"],
12498
+ ["colossians", "COL"],
12499
+ ["1th", "1TH"],
12500
+ ["1thessalonians", "1TH"],
12501
+ ["2th", "2TH"],
12502
+ ["2thessalonians", "2TH"],
12503
+ ["1ti", "1TI"],
12504
+ ["1timothy", "1TI"],
12505
+ ["2ti", "2TI"],
12506
+ ["2timothy", "2TI"],
12507
+ ["tit", "TIT"],
12508
+ ["titus", "TIT"],
12509
+ ["phm", "PHM"],
12510
+ ["philemon", "PHM"],
12511
+ ["heb", "HEB"],
12512
+ ["hebrews", "HEB"],
12513
+ ["jas", "JAS"],
12514
+ ["james", "JAS"],
12515
+ ["1pe", "1PE"],
12516
+ ["1peter", "1PE"],
12517
+ ["2pe", "2PE"],
12518
+ ["2peter", "2PE"],
12519
+ ["1jn", "1JN"],
12520
+ ["1john", "1JN"],
12521
+ ["2jn", "2JN"],
12522
+ ["2john", "2JN"],
12523
+ ["3jn", "3JN"],
12524
+ ["3john", "3JN"],
12525
+ ["jud", "JUD"],
12526
+ ["jude", "JUD"],
12527
+ ["rev", "REV"],
12528
+ ["revelation", "REV"]
12529
+ ]);
12530
+ function getBookId(book) {
12531
+ const bookLower = book.toLowerCase().replaceAll(/\s+/g, "");
12532
+ const id2 = BOOK_ID_MAP.get(bookLower);
12533
+ if (id2) {
12534
+ return id2;
12535
+ }
12536
+ for (let [key, id22] of BOOK_ID_MAP) {
12537
+ if (bookLower.startsWith(key)) {
12538
+ return id22;
12539
+ }
12540
+ }
12541
+ return null;
12542
+ }
11043
12543
 
11044
12544
  // packages/helloao-tools/dist/esm/parser/codex-parser.js
11045
12545
  var chapterHeadingSchema = z2.object({
@@ -11048,14 +12548,24 @@ var chapterHeadingSchema = z2.object({
11048
12548
  chapter: z2.coerce.number().int()
11049
12549
  })
11050
12550
  });
12551
+ var verseSchema = z2.object({
12552
+ type: z2.literal("text"),
12553
+ id: z2.string()
12554
+ });
12555
+ var paratextSchema = z2.object({
12556
+ type: z2.literal("paratext"),
12557
+ id: z2.string()
12558
+ });
11051
12559
  var metadataSchema = z2.discriminatedUnion("type", [
11052
- chapterHeadingSchema
12560
+ chapterHeadingSchema,
12561
+ verseSchema,
12562
+ paratextSchema
11053
12563
  ]);
11054
12564
  var codexSchema = z2.object({
11055
12565
  cells: z2.array(
11056
12566
  z2.object({
11057
- // kind: z.number().int(),
11058
- language: z2.string(),
12567
+ kind: z2.number(),
12568
+ languageId: z2.string(),
11059
12569
  value: z2.string(),
11060
12570
  metadata: z2.object({
11061
12571
  type: z2.string()
@@ -11071,9 +12581,9 @@ var CodexParser = class {
11071
12581
  // preserveMarkdown: boolean = true;
11072
12582
  _noteCounter = 0;
11073
12583
  /**
11074
- * Parses the specified USX content.
12584
+ * Parses the specified codex content.
11075
12585
  *
11076
- * @param usx The USX content to parse.
12586
+ * @param codex The codex content to parse.
11077
12587
  * @returns The parse tree that was generated.
11078
12588
  */
11079
12589
  parse(codex) {
@@ -11108,70 +12618,67 @@ var CodexParser = class {
11108
12618
  }
11109
12619
  ]);
11110
12620
  }
12621
+ function stripHTML(value) {
12622
+ return value.replace(/<[^>]*>/g, "");
12623
+ }
12624
+ function toHeading(content) {
12625
+ return {
12626
+ type: "heading",
12627
+ content: [content]
12628
+ };
12629
+ }
11111
12630
  for (let cell of data.cells) {
11112
- if (cell.language === "scripture") {
11113
- const lines = cell.value.split("\n");
11114
- const references = lines.map(
11115
- (l) => parseVerseReference(l) ?? l
11116
- );
11117
- let currentRef = null;
11118
- let content = [];
11119
- for (let i = 0; i < references.length; i++) {
11120
- const ref = references[i];
11121
- const nextRef = references[i + 1];
11122
- if (typeof ref === "string") {
11123
- if (ref === "") {
11124
- if (typeof nextRef === "object") {
11125
- if (currentRef && currentRef.chapter === nextRef.chapter) {
11126
- addChapterContent(currentRef.chapter, [
11127
- {
11128
- type: "line_break"
11129
- }
11130
- ]);
11131
- } else {
11132
- }
11133
- } else {
11134
- content.push({
12631
+ if (cell.languageId === "html") {
12632
+ if (!cell.metadata) continue;
12633
+ const metadata = metadataSchema.parse(cell.metadata);
12634
+ if (metadata.type === "text") {
12635
+ const reference = parseVerseReference(metadata.id);
12636
+ if (!reference)
12637
+ throw new Error("Could not find verse reference.");
12638
+ if (!root.id) root.id = reference.book;
12639
+ const content = stripHTML(cell.value);
12640
+ const lines = content.split("\n").reduce((prev, current) => {
12641
+ if (prev.length === 0) return [current];
12642
+ else
12643
+ return [
12644
+ ...prev,
12645
+ {
11135
12646
  lineBreak: true
12647
+ },
12648
+ current
12649
+ ];
12650
+ }, []);
12651
+ addReference(reference, lines);
12652
+ } else if (metadata.type === "paratext") {
12653
+ const reference = parseVerseReference(`${metadata.id}:1`);
12654
+ if (reference) {
12655
+ const content = stripHTML(cell.value);
12656
+ const lines = content.split("\n").reduce((prev, current) => {
12657
+ if (prev.length === 0)
12658
+ return [toHeading(current)];
12659
+ else
12660
+ return [
12661
+ ...prev,
12662
+ {
12663
+ type: "line_break"
12664
+ },
12665
+ toHeading(current)
12666
+ ];
12667
+ }, []);
12668
+ lines.forEach(
12669
+ (line) => addChapterContent(reference.chapter, [line])
12670
+ );
12671
+ } else {
12672
+ const content = stripHTML(cell.value);
12673
+ if (!cell.metadata) {
12674
+ if (lastChapter) {
12675
+ lastChapter.footnotes.push({
12676
+ noteId: this._noteCounter++,
12677
+ text: content,
12678
+ caller: null
11136
12679
  });
11137
12680
  }
11138
- } else if (ref) {
11139
- content.push(ref);
11140
- }
11141
- } else {
11142
- if (!root.id) {
11143
- root.id = ref.book;
11144
- }
11145
- if (currentRef) {
11146
- currentRef = null;
11147
- content = [];
11148
12681
  }
11149
- currentRef = ref;
11150
- if (ref.content) {
11151
- content.push(ref.content);
11152
- }
11153
- addReference(ref, content);
11154
- }
11155
- }
11156
- } else if (cell.language === "markdown") {
11157
- if (cell.metadata) {
11158
- if (cell.metadata.type === "chapter-heading") {
11159
- const metadata = metadataSchema.parse(cell.metadata);
11160
- const chapter = metadata.data.chapter;
11161
- addChapterContent(chapter, [
11162
- {
11163
- type: "heading",
11164
- content: [cell.value]
11165
- }
11166
- ]);
11167
- }
11168
- } else {
11169
- if (lastChapter) {
11170
- lastChapter.footnotes.push({
11171
- noteId: this._noteCounter++,
11172
- text: cell.value,
11173
- caller: null
11174
- });
11175
12682
  }
11176
12683
  }
11177
12684
  }
@@ -11183,15 +12690,124 @@ var CodexParser = class {
11183
12690
  }
11184
12691
  };
11185
12692
 
12693
+ // packages/helloao-tools/dist/esm/parser/commentary-csv-parser.js
12694
+ var import_papaparse = __toESM(require_papaparse());
12695
+ var CommentaryCsvParser = class {
12696
+ parse(data) {
12697
+ const firstLine = data.indexOf("\n");
12698
+ data = data.substring(firstLine + 1);
12699
+ const lines = (0, import_papaparse.parse)(data, {
12700
+ header: false,
12701
+ // transformHeader: (_, index) => {
12702
+ // const headers = ['book', 'chapter', 'verse', 'commentaries'];
12703
+ // if (index < headers.length) {
12704
+ // return headers[index];
12705
+ // } else {
12706
+ // return '';
12707
+ // }
12708
+ // },
12709
+ delimiter: ",",
12710
+ escapeChar: '"',
12711
+ quoteChar: '"'
12712
+ });
12713
+ return this.parseLines(
12714
+ lines.data.map((line) => ({
12715
+ book: line[0],
12716
+ chapter: line[1],
12717
+ verse: line[2],
12718
+ commentaries: line[3]
12719
+ }))
12720
+ );
12721
+ }
12722
+ parseLines(data) {
12723
+ let tree = {
12724
+ type: "commentary/root",
12725
+ books: []
12726
+ };
12727
+ let book = null;
12728
+ let chapter = null;
12729
+ for (let line of data) {
12730
+ if (hasValue(line.book)) {
12731
+ const id2 = getBookId(line.book);
12732
+ if (!id2) {
12733
+ throw new Error("Invalid book: " + line.book);
12734
+ }
12735
+ book = tree.books.find((b2) => b2.book === id2) ?? null;
12736
+ if (!book) {
12737
+ book = {
12738
+ type: "book",
12739
+ book: id2,
12740
+ introduction: null,
12741
+ chapters: []
12742
+ };
12743
+ tree.books.push(book);
12744
+ }
12745
+ if (!book.introduction) {
12746
+ book.introduction = hasValue(line.commentaries) ? line.commentaries : null;
12747
+ }
12748
+ } else if (hasValue(line.chapter)) {
12749
+ const number = parseInt(line.chapter);
12750
+ if (isNaN(number)) {
12751
+ throw new Error("Invalid chapter number: " + line.chapter);
12752
+ }
12753
+ if (!book) {
12754
+ throw new Error("Chapter without book");
12755
+ }
12756
+ chapter = {
12757
+ type: "chapter",
12758
+ number,
12759
+ introduction: hasValue(line.commentaries) ? line.commentaries : null,
12760
+ verses: []
12761
+ };
12762
+ book.chapters.push(chapter);
12763
+ } else if (hasValue(line.verse)) {
12764
+ const ref = parseVerseReference(line.verse);
12765
+ if (ref) {
12766
+ if (ref.book === book?.book) {
12767
+ if (ref.chapter === chapter?.number) {
12768
+ chapter.verses.push({
12769
+ type: "verse",
12770
+ number: ref.verse,
12771
+ content: [line.commentaries]
12772
+ });
12773
+ } else {
12774
+ chapter = {
12775
+ type: "chapter",
12776
+ number: ref.chapter,
12777
+ introduction: null,
12778
+ verses: [
12779
+ {
12780
+ type: "verse",
12781
+ number: ref.verse,
12782
+ content: [line.commentaries]
12783
+ }
12784
+ ]
12785
+ };
12786
+ book.chapters.push(chapter);
12787
+ }
12788
+ }
12789
+ }
12790
+ }
12791
+ }
12792
+ return tree;
12793
+ }
12794
+ };
12795
+ function hasValue(value) {
12796
+ return value !== null && value !== void 0 && value !== "" && value.trim() !== "";
12797
+ }
12798
+
11186
12799
  // packages/helloao-tools/dist/esm/generation/dataset.js
11187
12800
  function generateDataset(files, parser = new globalThis.DOMParser()) {
11188
12801
  let output = {
11189
- translations: []
12802
+ translations: [],
12803
+ commentaries: []
11190
12804
  };
11191
12805
  let usfmParser = new UsfmParser();
11192
12806
  let usxParser = new USXParser(parser);
11193
12807
  let codexParser = new CodexParser();
12808
+ let csvCommentaryParser = new CommentaryCsvParser();
11194
12809
  let parsedTranslations = /* @__PURE__ */ new Map();
12810
+ let parsedCommentaries = /* @__PURE__ */ new Map();
11195
12811
  const unknownLanguages = /* @__PURE__ */ new Set();
11196
12812
  for (let file of files) {
11197
12813
  try {
@@ -11202,6 +12818,8 @@ function generateDataset(files, parser = new globalThis.DOMParser()) {
11202
12818
  parser2 = usxParser;
11203
12819
  } else if (file.fileType === "json") {
11204
12820
  parser2 = codexParser;
12821
+ } else if (file.fileType === "commentary/csv") {
12822
+ parser2 = csvCommentaryParser;
11205
12823
  } else {
11206
12824
  console.warn(
11207
12825
  "[generate] File does not have a valid type!",
@@ -11210,101 +12828,175 @@ function generateDataset(files, parser = new globalThis.DOMParser()) {
11210
12828
  continue;
11211
12829
  }
11212
12830
  const parsed = parser2.parse(file.content);
11213
- const id2 = parsed.id;
11214
- if (!id2) {
11215
- console.warn(
11216
- "[generate] File does not have a valid book ID!",
11217
- file.name,
11218
- id2
11219
- );
11220
- continue;
11221
- }
11222
- const order = bookOrderMap.get(id2);
11223
- if (typeof order !== "number") {
11224
- console.warn("[generate] Book does not have an order!", id2);
11225
- continue;
11226
- }
11227
- const bookMap = bookIdMap.get(file.metadata.translation.language);
11228
- if (!bookMap) {
11229
- if (!unknownLanguages.has(file.metadata.translation.language)) {
11230
- console.warn(
11231
- "[generate] File does not have a known language!",
11232
- file.name,
11233
- file.metadata.translation.language
11234
- );
11235
- unknownLanguages.add(file.metadata.translation.language);
11236
- }
12831
+ if (parsed.type === "root") {
12832
+ addTranslationTree(file, parsed);
12833
+ } else {
12834
+ addCommentaryTree(file, parsed);
11237
12835
  }
11238
- const bookName = bookMap?.get(id2);
11239
- if (!!bookMap && !bookName) {
12836
+ } catch (err) {
12837
+ console.error(
12838
+ `[generate] Error occurred while parsing ${file.name}`,
12839
+ err
12840
+ );
12841
+ }
12842
+ }
12843
+ function addTranslationTree(file, parsed) {
12844
+ const id2 = parsed.id;
12845
+ if (!id2) {
12846
+ console.warn(
12847
+ "[generate] File does not have a valid book ID!",
12848
+ file.name,
12849
+ id2
12850
+ );
12851
+ return;
12852
+ }
12853
+ const order = bookOrderMap.get(id2);
12854
+ if (typeof order !== "number") {
12855
+ console.warn("[generate] Book does not have an order!", id2);
12856
+ return;
12857
+ }
12858
+ const bookMap = bookIdMap.get(file.metadata.language);
12859
+ if (!bookMap) {
12860
+ if (!unknownLanguages.has(file.metadata.language)) {
11240
12861
  console.warn(
11241
- "[generate] Book name not found for ID!",
12862
+ "[generate] File does not have a known language!",
11242
12863
  file.name,
11243
- id2
12864
+ file.metadata.language
11244
12865
  );
12866
+ unknownLanguages.add(file.metadata.language);
11245
12867
  }
11246
- let translation = parsedTranslations.get(
11247
- file.metadata.translation.id
12868
+ }
12869
+ const bookName = bookMap?.get(id2);
12870
+ if (!!bookMap && !bookName) {
12871
+ console.warn(
12872
+ "[generate] Book name not found for ID!",
12873
+ file.name,
12874
+ id2
11248
12875
  );
11249
- if (!translation) {
11250
- translation = {
11251
- ...(0, import_lodash3.omit)(file.metadata.translation, "direction"),
11252
- textDirection: file.metadata.translation.direction,
11253
- books: []
11254
- };
11255
- output.translations.push(translation);
11256
- parsedTranslations.set(
11257
- file.metadata.translation.id,
11258
- translation
11259
- );
12876
+ }
12877
+ let translation = parsedTranslations.get(file.metadata.id);
12878
+ if (!translation) {
12879
+ translation = {
12880
+ ...(0, import_lodash3.omit)(file.metadata, "direction"),
12881
+ textDirection: file.metadata.direction,
12882
+ books: []
12883
+ };
12884
+ output.translations.push(translation);
12885
+ parsedTranslations.set(file.metadata.id, translation);
12886
+ }
12887
+ const name = parsed.header ?? bookName?.commonName ?? parsed.title;
12888
+ if (!name) {
12889
+ console.warn(
12890
+ "[generate] Book does not have a name!",
12891
+ file.name,
12892
+ id2
12893
+ );
12894
+ return;
12895
+ }
12896
+ const commonName = bookName?.commonName ?? parsed.header ?? parsed.title ?? id2;
12897
+ const book = {
12898
+ id: id2,
12899
+ name,
12900
+ commonName,
12901
+ title: parsed.title ?? null,
12902
+ order,
12903
+ chapters: []
12904
+ };
12905
+ for (let content of parsed.content) {
12906
+ if (content.type === "chapter") {
12907
+ book.chapters.push({
12908
+ chapter: {
12909
+ number: content.number,
12910
+ content: content.content,
12911
+ footnotes: content.footnotes
12912
+ },
12913
+ thisChapterAudioLinks: getAudioUrlsForChapter(
12914
+ translation.id,
12915
+ id2,
12916
+ content.number
12917
+ )
12918
+ });
11260
12919
  }
11261
- const name = parsed.header ?? bookName?.commonName ?? parsed.title;
11262
- if (!name) {
12920
+ }
12921
+ book.chapters = (0, import_lodash3.sortBy)(book.chapters, (c) => c.chapter.number);
12922
+ const index = (0, import_lodash3.sortedIndexBy)(translation.books, book, (b2) => b2.order);
12923
+ translation.books.splice(index, 0, book);
12924
+ }
12925
+ function addCommentaryTree(file, parsed) {
12926
+ let commentary = parsedCommentaries.get(file.metadata.id);
12927
+ if (!commentary) {
12928
+ commentary = {
12929
+ ...(0, import_lodash3.omit)(file.metadata, "direction"),
12930
+ textDirection: file.metadata.direction,
12931
+ books: []
12932
+ };
12933
+ output.commentaries.push(commentary);
12934
+ parsedCommentaries.set(file.metadata.id, commentary);
12935
+ }
12936
+ for (let parsedBook of parsed.books) {
12937
+ let book = commentary.books.find((b2) => b2.id === parsedBook.book);
12938
+ if (book && book.introduction) {
11263
12939
  console.warn(
11264
- "[generate] Book does not have a name!",
12940
+ "[generate] Book already exists in commentary!",
11265
12941
  file.name,
11266
- id2
12942
+ parsedBook.book
11267
12943
  );
11268
12944
  continue;
11269
12945
  }
11270
- const commonName = bookName?.commonName ?? parsed.header ?? parsed.title ?? id2;
11271
- const book = {
11272
- id: id2,
11273
- name,
11274
- commonName,
11275
- title: parsed.title ?? null,
11276
- order,
11277
- chapters: []
11278
- };
11279
- for (let content of parsed.content) {
11280
- if (content.type === "chapter") {
11281
- book.chapters.push({
11282
- chapter: {
11283
- number: content.number,
11284
- content: content.content,
11285
- footnotes: content.footnotes
11286
- },
11287
- thisChapterAudioLinks: getAudioUrlsForChapter(
11288
- translation.id,
11289
- id2,
11290
- content.number
11291
- )
11292
- });
12946
+ if (!book) {
12947
+ const name = getBookNames(file, file.metadata, parsedBook.book);
12948
+ book = {
12949
+ id: parsedBook.book,
12950
+ order: bookOrderMap.get(parsedBook.book) ?? -1,
12951
+ commonName: name?.bookName?.commonName ?? parsedBook.book,
12952
+ name: name?.bookName?.commonName ?? parsedBook.book,
12953
+ chapters: []
12954
+ };
12955
+ }
12956
+ if (parsedBook.introduction) {
12957
+ book.introduction = parsedBook.introduction;
12958
+ }
12959
+ for (let chapter of parsedBook.chapters) {
12960
+ let data = {
12961
+ number: chapter.number,
12962
+ content: chapter.verses
12963
+ };
12964
+ if (chapter.introduction) {
12965
+ data.introduction = chapter.introduction;
11293
12966
  }
12967
+ book.chapters.push({
12968
+ chapter: data
12969
+ });
11294
12970
  }
11295
12971
  book.chapters = (0, import_lodash3.sortBy)(book.chapters, (c) => c.chapter.number);
11296
- const index = (0, import_lodash3.sortedIndexBy)(
11297
- translation.books,
11298
- book,
11299
- (b2) => b2.order
11300
- );
11301
- translation.books.splice(index, 0, book);
11302
- } catch (err) {
11303
- console.error(
11304
- `[generate] Error occurred while parsing ${file.name}`,
11305
- err
12972
+ commentary.books.push(book);
12973
+ }
12974
+ commentary.books = (0, import_lodash3.sortBy)(commentary.books, (b2) => b2.order);
12975
+ }
12976
+ function getBookNames(file, metadata, id2) {
12977
+ const bookMap = bookIdMap.get(metadata.language);
12978
+ if (!bookMap) {
12979
+ if (!unknownLanguages.has(metadata.language)) {
12980
+ console.warn(
12981
+ "[generate] File does not have a known language!",
12982
+ file.name,
12983
+ metadata.language
12984
+ );
12985
+ unknownLanguages.add(metadata.language);
12986
+ }
12987
+ }
12988
+ const bookName = bookMap?.get(id2);
12989
+ if (!!bookMap && !bookName) {
12990
+ console.warn(
12991
+ "[generate] Book name not found for ID!",
12992
+ file.name,
12993
+ id2
11306
12994
  );
12995
+ return null;
11307
12996
  }
12997
+ return {
12998
+ bookName
12999
+ };
11308
13000
  }
11309
13001
  return output;
11310
13002
  }
@@ -11320,6 +13012,11 @@ function generateApiForDataset(dataset, options = {}) {
11320
13012
  translationBooks: [],
11321
13013
  translationBookChapters: [],
11322
13014
  translationBookChapterAudio: [],
13015
+ availableCommentaries: {
13016
+ commentaries: []
13017
+ },
13018
+ commentaryBookChapters: [],
13019
+ commentaryBooks: [],
11323
13020
  pathPrefix: apiPathPrefix
11324
13021
  };
11325
13022
  const getNativeName3 = options.getNativeName;
@@ -11440,6 +13137,97 @@ function generateApiForDataset(dataset, options = {}) {
11440
13137
  api.availableTranslations.translations.push(apiTranslation);
11441
13138
  api.translationBooks.push(translationBooks);
11442
13139
  }
13140
+ for (let { books, ...commentary } of dataset.commentaries) {
13141
+ const apiCommentary = {
13142
+ ...commentary,
13143
+ availableFormats: ["json"],
13144
+ listOfBooksApiLink: listOfCommentaryBooksApiLink(
13145
+ commentary.id,
13146
+ apiPathPrefix
13147
+ ),
13148
+ numberOfBooks: books.length,
13149
+ totalNumberOfChapters: 0,
13150
+ totalNumberOfVerses: 0,
13151
+ languageName: getNativeName3 ? getNativeName3(commentary.language) ?? void 0 : void 0,
13152
+ languageEnglishName: getEnglishName2 ? getEnglishName2(commentary.language) ?? void 0 : void 0
13153
+ };
13154
+ const commentaryBooks = {
13155
+ commentary: apiCommentary,
13156
+ books: []
13157
+ };
13158
+ let commentaryChapters = [];
13159
+ for (let { chapters, ...book } of books) {
13160
+ const apiBook = {
13161
+ ...book,
13162
+ firstChapterApiLink: bookCommentaryChapterApiLink(
13163
+ commentary.id,
13164
+ getBookLink(book),
13165
+ 1,
13166
+ "json",
13167
+ apiPathPrefix
13168
+ ),
13169
+ lastChapterApiLink: bookCommentaryChapterApiLink(
13170
+ commentary.id,
13171
+ getBookLink(book),
13172
+ chapters.length,
13173
+ "json",
13174
+ apiPathPrefix
13175
+ ),
13176
+ numberOfChapters: chapters.length,
13177
+ totalNumberOfVerses: 0
13178
+ };
13179
+ for (let { chapter } of chapters) {
13180
+ const apiBookChapter = {
13181
+ commentary: apiCommentary,
13182
+ book: apiBook,
13183
+ chapter,
13184
+ thisChapterLink: bookCommentaryChapterApiLink(
13185
+ commentary.id,
13186
+ getBookLink(book),
13187
+ chapter.number,
13188
+ "json",
13189
+ apiPathPrefix
13190
+ ),
13191
+ nextChapterApiLink: null,
13192
+ previousChapterApiLink: null,
13193
+ numberOfVerses: 0
13194
+ };
13195
+ for (let c of chapter.content) {
13196
+ if (c.type === "verse") {
13197
+ apiBookChapter.numberOfVerses++;
13198
+ }
13199
+ }
13200
+ apiBook.totalNumberOfVerses += apiBookChapter.numberOfVerses;
13201
+ commentaryChapters.push(apiBookChapter);
13202
+ api.commentaryBookChapters.push(apiBookChapter);
13203
+ }
13204
+ commentaryBooks.books.push(apiBook);
13205
+ apiCommentary.totalNumberOfChapters += apiBook.numberOfChapters;
13206
+ apiCommentary.totalNumberOfVerses += apiBook.totalNumberOfVerses;
13207
+ }
13208
+ for (let i = 0; i < commentaryChapters.length; i++) {
13209
+ if (i > 0) {
13210
+ commentaryChapters[i].previousChapterApiLink = bookCommentaryChapterApiLink(
13211
+ commentary.id,
13212
+ getBookLink(commentaryChapters[i - 1].book),
13213
+ commentaryChapters[i - 1].chapter.number,
13214
+ "json",
13215
+ apiPathPrefix
13216
+ );
13217
+ }
13218
+ if (i < commentaryChapters.length - 1) {
13219
+ commentaryChapters[i].nextChapterApiLink = bookCommentaryChapterApiLink(
13220
+ commentary.id,
13221
+ getBookLink(commentaryChapters[i + 1].book),
13222
+ commentaryChapters[i + 1].chapter.number,
13223
+ "json",
13224
+ apiPathPrefix
13225
+ );
13226
+ }
13227
+ }
13228
+ api.availableCommentaries.commentaries.push(apiCommentary);
13229
+ api.commentaryBooks.push(commentaryBooks);
13230
+ }
11443
13231
  return api;
11444
13232
  function getBookLink(book) {
11445
13233
  return useCommonName ? book.commonName : book.id;
@@ -11468,6 +13256,24 @@ function generateFilesForApi(api) {
11468
13256
  for (let audio of api.translationBookChapterAudio) {
11469
13257
  files.push(downloadedFile(audio.link, audio.originalUrl));
11470
13258
  }
13259
+ files.push(
13260
+ jsonFile(
13261
+ `${api.pathPrefix}/api/available_commentaries.json`,
13262
+ api.availableCommentaries,
13263
+ true
13264
+ )
13265
+ );
13266
+ for (let commentaryBooks of api.commentaryBooks) {
13267
+ files.push(
13268
+ jsonFile(
13269
+ commentaryBooks.commentary.listOfBooksApiLink,
13270
+ commentaryBooks
13271
+ )
13272
+ );
13273
+ }
13274
+ for (let bookChapter of api.commentaryBookChapters) {
13275
+ files.push(jsonFile(bookChapter.thisChapterLink, bookChapter));
13276
+ }
11471
13277
  return files;
11472
13278
  }
11473
13279
  async function* generateOutputFilesFromDatasets(datasets, options) {
@@ -11480,11 +13286,19 @@ async function* generateOutputFilesFromDatasets(datasets, options) {
11480
13286
  function listOfBooksApiLink(translationId, prefix = "") {
11481
13287
  return `${prefix}/api/${translationId}/books.json`;
11482
13288
  }
13289
+ function listOfCommentaryBooksApiLink(commentaryId, prefix = "") {
13290
+ return `${prefix}/api/c/${commentaryId}/books.json`;
13291
+ }
11483
13292
  function bookChapterApiLink(translationId, commonName, chapterNumber, extension, prefix = "") {
11484
13293
  return `${prefix}/api/${translationId}/${replaceSpacesWithUnderscores(
11485
13294
  commonName
11486
13295
  )}/${chapterNumber}.${extension}`;
11487
13296
  }
13297
+ function bookCommentaryChapterApiLink(translationId, commonName, chapterNumber, extension, prefix = "") {
13298
+ return `${prefix}/api/c/${translationId}/${replaceSpacesWithUnderscores(
13299
+ commonName
13300
+ )}/${chapterNumber}.${extension}`;
13301
+ }
11488
13302
  function bookChapterAudioApiLink(translationId, bookId, chapterNumber, reader, prefix = "") {
11489
13303
  return `${prefix}/api/${translationId}/${replaceSpacesWithUnderscores(
11490
13304
  bookId
@@ -11658,17 +13472,49 @@ async function loadTranslationFiles(translation) {
11658
13472
  }
11659
13473
  const filePath = path.resolve(translation, file);
11660
13474
  promises.push(
11661
- loadFile(filePath, {
11662
- translation: metadata
11663
- })
13475
+ loadFile(
13476
+ path.extname(filePath).slice(1),
13477
+ filePath,
13478
+ metadata
13479
+ )
11664
13480
  );
11665
13481
  }
11666
13482
  return await Promise.all(promises);
11667
13483
  }
13484
+ async function loadCommentaryFiles(commentary) {
13485
+ const metadata = await loadCommentaryMetadata(commentary);
13486
+ if (!metadata) {
13487
+ console.error("Could not load metadata for commentary!", commentary);
13488
+ return null;
13489
+ }
13490
+ let files = await (0, import_promises2.readdir)(commentary);
13491
+ let csvFiles = files.filter((f) => (0, import_path.extname)(f) === ".csv");
13492
+ if (csvFiles.length <= 0) {
13493
+ commentary = path.resolve(commentary, "usfm");
13494
+ if ((0, import_fs_extra2.existsSync)(commentary)) {
13495
+ files = await (0, import_promises2.readdir)(commentary);
13496
+ csvFiles = files.filter((f) => (0, import_path.extname)(f) === ".usfm");
13497
+ }
13498
+ }
13499
+ if (csvFiles.length <= 0) {
13500
+ console.error("Could not find USFM files for translation!", commentary);
13501
+ return [];
13502
+ }
13503
+ let promises = [];
13504
+ for (let file of csvFiles) {
13505
+ if (path.parse(file).name === "metadata") {
13506
+ continue;
13507
+ }
13508
+ const filePath = path.resolve(commentary, file);
13509
+ promises.push(loadFile("commentary/csv", filePath, metadata));
13510
+ }
13511
+ return await Promise.all(promises);
13512
+ }
11668
13513
  async function loadTranslationMetadata(translation) {
11669
13514
  const metadataTs = path.resolve(translation, "metadata.ts");
11670
13515
  if ((0, import_fs_extra2.existsSync)(metadataTs)) {
11671
- return (await import(metadataTs)).default;
13516
+ const importPath = new URL("file://" + metadataTs).href;
13517
+ return (await import(importPath)).default;
11672
13518
  } else {
11673
13519
  const metadataJson = path.resolve(translation, "meta.json");
11674
13520
  if ((0, import_fs_extra2.existsSync)(metadataJson)) {
@@ -11697,8 +13543,23 @@ async function loadTranslationMetadata(translation) {
11697
13543
  console.error("Could not find metadata for translation!", translation);
11698
13544
  return null;
11699
13545
  }
11700
- async function loadFile(file, metadata) {
11701
- const extension = path.extname(file);
13546
+ async function loadCommentaryMetadata(commentary) {
13547
+ const metadataTs = path.resolve(commentary, "metadata.ts");
13548
+ if ((0, import_fs_extra2.existsSync)(metadataTs)) {
13549
+ return (await import(metadataTs)).default;
13550
+ } else {
13551
+ const metadataJson = path.resolve(commentary, "metadata.json");
13552
+ if ((0, import_fs_extra2.existsSync)(metadataJson)) {
13553
+ const data = await (0, import_promises2.readFile)(metadataJson, {
13554
+ encoding: "utf-8"
13555
+ });
13556
+ return JSON.parse(data);
13557
+ }
13558
+ }
13559
+ console.error("Could not find metadata for commentary!", commentary);
13560
+ return null;
13561
+ }
13562
+ async function loadFile(fileType, file, metadata) {
11702
13563
  const content = await (0, import_promises2.readFile)(file, {
11703
13564
  encoding: "utf-8"
11704
13565
  });
@@ -11708,7 +13569,7 @@ async function loadFile(file, metadata) {
11708
13569
  metadata,
11709
13570
  name: file,
11710
13571
  sha256: hash,
11711
- fileType: extension.slice(1)
13572
+ fileType
11712
13573
  };
11713
13574
  }
11714
13575
  var FilesUploader = class {
@@ -11815,31 +13676,37 @@ async function getMigrationsPath() {
11815
13676
  }
11816
13677
  return null;
11817
13678
  }
11818
- async function importTranslations(db, dirs, parser, overwrite) {
13679
+ var importTranslations = (db, dirs, parser, overwrite) => importFiles(loadTranslationFiles, db, dirs, parser, overwrite);
13680
+ var importCommentaries = (db, dirs, parser, overwrite) => importFiles(loadCommentaryFiles, db, dirs, parser, overwrite);
13681
+ async function importFiles(loadFilesFromDir, db, dirs, parser, overwrite) {
11819
13682
  let batches = [];
11820
13683
  while (dirs.length > 0) {
11821
13684
  batches.push(dirs.splice(0, 10));
11822
13685
  }
11823
- console.log("Processing", batches.length, "batches of translations");
13686
+ console.log("Processing", batches.length, "batches of directories");
11824
13687
  for (let i = 0; i < batches.length; i++) {
11825
13688
  const batch2 = batches[i];
11826
13689
  console.log(`Processing batch ${i + 1} of ${batches.length}`);
11827
- await importTranslationBatch(db, batch2, parser, overwrite);
13690
+ await loadAndImportBatch(
13691
+ loadFilesFromDir,
13692
+ db,
13693
+ batch2,
13694
+ parser,
13695
+ overwrite
13696
+ );
11828
13697
  }
11829
13698
  }
11830
- async function importTranslationBatch(db, dirs, parser, overwrite) {
13699
+ async function loadAndImportBatch(loadFilesFromDir, db, dirs, parser, overwrite) {
11831
13700
  const promises = [];
11832
13701
  for (let dir of dirs) {
11833
13702
  const fullPath = import_path2.default.resolve(dir);
11834
- promises.push(
11835
- loadTranslationFiles(fullPath).then((files2) => files2 ?? [])
11836
- );
13703
+ promises.push(loadFilesFromDir(fullPath).then((files2) => files2 ?? []));
11837
13704
  }
11838
13705
  const allFiles = await Promise.all(promises);
11839
13706
  const files = allFiles.flat();
11840
- await importTranslationFileBatch(db, files, parser, overwrite);
13707
+ await importFileBatch(db, files, parser, overwrite);
11841
13708
  }
11842
- async function importTranslationFileBatch(db, files, parser, overwrite) {
13709
+ async function importFileBatch(db, files, parser, overwrite) {
11843
13710
  console.log("Importing", files.length, "files");
11844
13711
  if (overwrite) {
11845
13712
  console.log("Overwriting existing translations.");
@@ -11856,10 +13723,14 @@ async function importTranslationFileBatch(db, files, parser, overwrite) {
11856
13723
  parser
11857
13724
  );
11858
13725
  console.log("Generated", output.translations.length, "translations");
13726
+ console.log("Generated", output.commentaries.length, "commentaries");
11859
13727
  insertTranslations(db, output.translations);
11860
13728
  updateTranslationHashes(db, output.translations);
13729
+ insertCommentaries(db, output.commentaries);
13730
+ updateCommentaryHashes(db, output.commentaries);
11861
13731
  insertFileMetadata(db, changedFiles);
11862
- console.log(`Inserted ${output.translations} translations into DB`);
13732
+ console.log(`Inserted ${output.translations.length} translations into DB`);
13733
+ console.log(`Inserted ${output.commentaries.length} commentaries into DB`);
11863
13734
  }
11864
13735
  function getChangedOrNewInputFiles(db, files) {
11865
13736
  const fileExists = db.prepare(
@@ -11867,7 +13738,7 @@ function getChangedOrNewInputFiles(db, files) {
11867
13738
  );
11868
13739
  return files.filter((f) => {
11869
13740
  const count = fileExists.get({
11870
- translationId: f.metadata.translation.id,
13741
+ translationId: f.metadata.id,
11871
13742
  name: import_path2.default.basename(f.name),
11872
13743
  sha256: f.sha256
11873
13744
  });
@@ -11895,7 +13766,7 @@ function insertFileMetadata(db, files) {
11895
13766
  const insertManyFiles = db.transaction((files2) => {
11896
13767
  for (let file of files2) {
11897
13768
  fileUpsert.run({
11898
- translationId: file.metadata.translation.id,
13769
+ translationId: file.metadata.id,
11899
13770
  name: import_path2.default.basename(file.name),
11900
13771
  format: file.fileType,
11901
13772
  sha256: file.sha256,
@@ -11946,32 +13817,344 @@ function insertTranslations(db, translations) {
11946
13817
  englishName: translation.englishName
11947
13818
  });
11948
13819
  }
11949
- });
11950
- insertManyTranslations(translations);
11951
- for (let translation of translations) {
11952
- insertTranslationBooks(db, translation, translation.books);
13820
+ });
13821
+ insertManyTranslations(translations);
13822
+ for (let translation of translations) {
13823
+ insertTranslationBooks(db, translation, translation.books);
13824
+ }
13825
+ }
13826
+ function insertTranslationBooks(db, translation, translationBooks) {
13827
+ const bookUpsert = db.prepare(`INSERT INTO Book(
13828
+ id,
13829
+ translationId,
13830
+ title,
13831
+ name,
13832
+ commonName,
13833
+ numberOfChapters,
13834
+ \`order\`
13835
+ ) VALUES (
13836
+ @id,
13837
+ @translationId,
13838
+ @title,
13839
+ @name,
13840
+ @commonName,
13841
+ @numberOfChapters,
13842
+ @bookOrder
13843
+ ) ON CONFLICT(id,translationId) DO
13844
+ UPDATE SET
13845
+ title=excluded.title,
13846
+ name=excluded.name,
13847
+ commonName=excluded.commonName,
13848
+ numberOfChapters=excluded.numberOfChapters;`);
13849
+ const insertMany = db.transaction((books) => {
13850
+ for (let book of books) {
13851
+ if (!book) {
13852
+ continue;
13853
+ }
13854
+ bookUpsert.run({
13855
+ id: book.id,
13856
+ translationId: translation.id,
13857
+ title: book.title,
13858
+ name: book.name,
13859
+ commonName: book.commonName,
13860
+ numberOfChapters: book.chapters.length,
13861
+ bookOrder: book.order ?? 9999
13862
+ });
13863
+ }
13864
+ });
13865
+ insertMany(translationBooks);
13866
+ for (let book of translationBooks) {
13867
+ insertTranslationContent(db, translation, book, book.chapters);
13868
+ }
13869
+ }
13870
+ function insertTranslationContent(db, translation, book, chapters) {
13871
+ const chapterUpsert = db.prepare(`INSERT INTO Chapter(
13872
+ translationId,
13873
+ bookId,
13874
+ number,
13875
+ json
13876
+ ) VALUES (
13877
+ @translationId,
13878
+ @bookId,
13879
+ @number,
13880
+ @json
13881
+ ) ON CONFLICT(translationId,bookId,number) DO
13882
+ UPDATE SET
13883
+ json=excluded.json;`);
13884
+ const verseUpsert = db.prepare(`INSERT INTO ChapterVerse(
13885
+ translationId,
13886
+ bookId,
13887
+ chapterNumber,
13888
+ number,
13889
+ text,
13890
+ contentJson
13891
+ ) VALUES (
13892
+ @translationId,
13893
+ @bookId,
13894
+ @chapterNumber,
13895
+ @number,
13896
+ @text,
13897
+ @contentJson
13898
+ ) ON CONFLICT(translationId,bookId,chapterNumber,number) DO
13899
+ UPDATE SET
13900
+ text=excluded.text,
13901
+ contentJson=excluded.contentJson;`);
13902
+ const footnoteUpsert = db.prepare(`INSERT INTO ChapterFootnote(
13903
+ translationId,
13904
+ bookId,
13905
+ chapterNumber,
13906
+ id,
13907
+ verseNumber,
13908
+ text
13909
+ ) VALUES (
13910
+ @translationId,
13911
+ @bookId,
13912
+ @chapterNumber,
13913
+ @id,
13914
+ @verseNumber,
13915
+ @text
13916
+ ) ON CONFLICT(translationId,bookId,chapterNumber,id) DO
13917
+ UPDATE SET
13918
+ verseNumber=excluded.verseNumber,
13919
+ text=excluded.text;`);
13920
+ const chapterAudioUpsert = db.prepare(`INSERT INTO ChapterAudioUrl(
13921
+ translationId,
13922
+ bookId,
13923
+ number,
13924
+ reader,
13925
+ url
13926
+ ) VALUES (
13927
+ @translationId,
13928
+ @bookId,
13929
+ @number,
13930
+ @reader,
13931
+ @url
13932
+ ) ON CONFLICT(translationId,bookId,number,reader) DO
13933
+ UPDATE SET
13934
+ url=excluded.url;`);
13935
+ const insertChaptersAndVerses = db.transaction(() => {
13936
+ for (let chapter of chapters) {
13937
+ let verses = [];
13938
+ let footnotes = /* @__PURE__ */ new Map();
13939
+ for (let c of chapter.chapter.footnotes) {
13940
+ footnotes.set(c.noteId, {
13941
+ id: c.noteId,
13942
+ text: c.text
13943
+ });
13944
+ }
13945
+ for (let c of chapter.chapter.content) {
13946
+ if (c.type === "verse") {
13947
+ const verse = c;
13948
+ if (!verse.number) {
13949
+ console.error(
13950
+ "Verse missing number",
13951
+ translation.id,
13952
+ book.id,
13953
+ chapter.chapter.number,
13954
+ verse.number
13955
+ );
13956
+ continue;
13957
+ }
13958
+ let text = "";
13959
+ for (let c2 of verse.content) {
13960
+ if (typeof c2 === "string") {
13961
+ text += c2 + " ";
13962
+ } else if (typeof c2 === "object") {
13963
+ if ("lineBreak" in c2) {
13964
+ text += "\n";
13965
+ } else if ("text" in c2) {
13966
+ text += c2.text + " ";
13967
+ } else if ("noteId" in c2) {
13968
+ const note = footnotes.get(c2.noteId);
13969
+ if (note) {
13970
+ note.verseNumber = verse.number;
13971
+ }
13972
+ }
13973
+ }
13974
+ }
13975
+ let contentJson = JSON.stringify(verse.content);
13976
+ verses.push({
13977
+ number: verse.number,
13978
+ text: text.trimEnd(),
13979
+ contentJson
13980
+ });
13981
+ }
13982
+ }
13983
+ chapterUpsert.run({
13984
+ translationId: translation.id,
13985
+ bookId: book.id,
13986
+ number: chapter.chapter.number,
13987
+ json: JSON.stringify(chapter.chapter)
13988
+ });
13989
+ for (let verse of verses) {
13990
+ verseUpsert.run({
13991
+ translationId: translation.id,
13992
+ bookId: book.id,
13993
+ chapterNumber: chapter.chapter.number,
13994
+ number: verse.number,
13995
+ text: verse.text,
13996
+ contentJson: verse.contentJson
13997
+ });
13998
+ }
13999
+ for (let footnote of footnotes.values()) {
14000
+ footnoteUpsert.run({
14001
+ translationId: translation.id,
14002
+ bookId: book.id,
14003
+ chapterNumber: chapter.chapter.number,
14004
+ id: footnote.id,
14005
+ verseNumber: footnote.verseNumber,
14006
+ text: footnote.text
14007
+ });
14008
+ }
14009
+ for (let reader in chapter.thisChapterAudioLinks) {
14010
+ const url = chapter.thisChapterAudioLinks[reader];
14011
+ if (url) {
14012
+ chapterAudioUpsert.run({
14013
+ translationId: translation.id,
14014
+ bookId: book.id,
14015
+ number: chapter.chapter.number,
14016
+ reader,
14017
+ url
14018
+ });
14019
+ }
14020
+ }
14021
+ }
14022
+ });
14023
+ insertChaptersAndVerses();
14024
+ }
14025
+ function updateTranslationHashes(db, translations) {
14026
+ console.log(`Updating hashes for ${translations.length} translations.`);
14027
+ const updateTranslationHash = db.prepare(
14028
+ `UPDATE Translation SET sha256 = @sha256 WHERE id = @translationId;`
14029
+ );
14030
+ const updateBookHash = db.prepare(
14031
+ `UPDATE Book SET sha256 = @sha256 WHERE translationId = @translationId AND id = @bookId;`
14032
+ );
14033
+ const updateChapterHash = db.prepare(
14034
+ `UPDATE Chapter SET sha256 = @sha256 WHERE translationId = @translationId AND bookId = @bookId AND number = @chapterNumber;`
14035
+ );
14036
+ const getBooks = db.prepare("SELECT * FROM Book WHERE translationId = ?;");
14037
+ const getChapters = db.prepare(
14038
+ "SELECT * FROM Chapter WHERE translationId = @translationId AND bookId = @bookId;"
14039
+ );
14040
+ for (let translation of translations) {
14041
+ const translationSha = (0, import_hash2.sha256)().update(translation.id).update(translation.name).update(translation.language).update(translation.licenseUrl).update(translation.textDirection).update(translation.website).update(translation.englishName).update(translation.shortName);
14042
+ const books = getBooks.all(translation.id);
14043
+ for (let book of books) {
14044
+ const chapters = getChapters.all({
14045
+ translationId: translation.id,
14046
+ bookId: book.id
14047
+ });
14048
+ const bookSha = (0, import_hash2.sha256)().update(book.translationId).update(book.id).update(book.numberOfChapters).update(book.order).update(book.name).update(book.title).update(book.commonName);
14049
+ for (let chapter of chapters) {
14050
+ const hash2 = (0, import_hash2.sha256)().update(chapter.translationId).update(chapter.bookId).update(chapter.number).update(chapter.json).digest("hex");
14051
+ chapter.sha256 = hash2;
14052
+ bookSha.update(hash2);
14053
+ }
14054
+ const updateChapters = db.transaction(() => {
14055
+ for (let chapter of chapters) {
14056
+ updateChapterHash.run({
14057
+ sha256: chapter.sha256,
14058
+ translationId: chapter.translationId,
14059
+ bookId: chapter.bookId,
14060
+ chapterNumber: chapter.number
14061
+ });
14062
+ }
14063
+ });
14064
+ updateChapters();
14065
+ const bookHash = bookSha.digest("hex");
14066
+ book.sha256 = bookHash;
14067
+ translationSha.update(bookHash);
14068
+ }
14069
+ const updateBooks = db.transaction(() => {
14070
+ for (let book of books) {
14071
+ updateBookHash.run({
14072
+ sha256: book.sha256,
14073
+ translationId: book.translationId,
14074
+ bookId: book.id
14075
+ });
14076
+ }
14077
+ });
14078
+ updateBooks();
14079
+ const hash = translationSha.digest("hex");
14080
+ translation.sha256 = hash;
14081
+ }
14082
+ const updateTranslations = db.transaction(() => {
14083
+ for (let translation of translations) {
14084
+ updateTranslationHash.run({
14085
+ sha256: translation.sha256,
14086
+ translationId: translation.id
14087
+ });
14088
+ }
14089
+ });
14090
+ updateTranslations();
14091
+ console.log(`Updated.`);
14092
+ }
14093
+ function insertCommentaries(db, commentaries) {
14094
+ const translationUpsert = db.prepare(`INSERT INTO Commentary(
14095
+ id,
14096
+ name,
14097
+ language,
14098
+ textDirection,
14099
+ licenseUrl,
14100
+ website,
14101
+ englishName
14102
+ ) VALUES (
14103
+ @id,
14104
+ @name,
14105
+ @language,
14106
+ @textDirection,
14107
+ @licenseUrl,
14108
+ @website,
14109
+ @englishName
14110
+ ) ON CONFLICT(id) DO
14111
+ UPDATE SET
14112
+ name=excluded.name,
14113
+ language=excluded.language,
14114
+ textDirection=excluded.textDirection,
14115
+ licenseUrl=excluded.licenseUrl,
14116
+ website=excluded.website,
14117
+ englishName=excluded.englishName;`);
14118
+ const insertManyTranslations = db.transaction(
14119
+ (commentaries2) => {
14120
+ for (let commentary of commentaries2) {
14121
+ translationUpsert.run({
14122
+ id: commentary.id,
14123
+ name: commentary.name,
14124
+ language: commentary.language,
14125
+ textDirection: commentary.textDirection,
14126
+ licenseUrl: commentary.licenseUrl,
14127
+ website: commentary.website,
14128
+ englishName: commentary.englishName
14129
+ });
14130
+ }
14131
+ }
14132
+ );
14133
+ insertManyTranslations(commentaries);
14134
+ for (let commentary of commentaries) {
14135
+ insertCommentaryBooks(db, commentary, commentary.books);
11953
14136
  }
11954
14137
  }
11955
- function insertTranslationBooks(db, translation, translationBooks) {
11956
- const bookUpsert = db.prepare(`INSERT INTO Book(
14138
+ function insertCommentaryBooks(db, commentary, commentaryBooks) {
14139
+ const bookUpsert = db.prepare(`INSERT INTO CommentaryBook(
11957
14140
  id,
11958
- translationId,
11959
- title,
14141
+ commentaryId,
14142
+ introduction,
11960
14143
  name,
11961
14144
  commonName,
11962
14145
  numberOfChapters,
11963
14146
  \`order\`
11964
14147
  ) VALUES (
11965
14148
  @id,
11966
- @translationId,
11967
- @title,
14149
+ @commentaryId,
14150
+ @introduction,
11968
14151
  @name,
11969
14152
  @commonName,
11970
14153
  @numberOfChapters,
11971
14154
  @bookOrder
11972
- ) ON CONFLICT(id,translationId) DO
14155
+ ) ON CONFLICT(id,commentaryId) DO
11973
14156
  UPDATE SET
11974
- title=excluded.title,
14157
+ introduction=excluded.introduction,
11975
14158
  name=excluded.name,
11976
14159
  commonName=excluded.commonName,
11977
14160
  numberOfChapters=excluded.numberOfChapters;`);
@@ -11982,8 +14165,8 @@ function insertTranslationBooks(db, translation, translationBooks) {
11982
14165
  }
11983
14166
  bookUpsert.run({
11984
14167
  id: book.id,
11985
- translationId: translation.id,
11986
- title: book.title,
14168
+ commentaryId: commentary.id,
14169
+ introduction: book.introduction ?? null,
11987
14170
  name: book.name,
11988
14171
  commonName: book.commonName,
11989
14172
  numberOfChapters: book.chapters.length,
@@ -11991,93 +14174,56 @@ function insertTranslationBooks(db, translation, translationBooks) {
11991
14174
  });
11992
14175
  }
11993
14176
  });
11994
- insertMany(translationBooks);
11995
- for (let book of translationBooks) {
11996
- insertTranslationContent(db, translation, book, book.chapters);
14177
+ insertMany(commentaryBooks);
14178
+ for (let book of commentaryBooks) {
14179
+ insertCommentaryContent(db, commentary, book, book.chapters);
11997
14180
  }
11998
14181
  }
11999
- function insertTranslationContent(db, translation, book, chapters) {
12000
- const chapterUpsert = db.prepare(`INSERT INTO Chapter(
12001
- translationId,
14182
+ function insertCommentaryContent(db, commentary, book, chapters) {
14183
+ const chapterUpsert = db.prepare(`INSERT INTO CommentaryChapter(
14184
+ commentaryId,
12002
14185
  bookId,
12003
14186
  number,
14187
+ introduction,
12004
14188
  json
12005
14189
  ) VALUES (
12006
- @translationId,
14190
+ @commentaryId,
12007
14191
  @bookId,
12008
14192
  @number,
14193
+ @introduction,
12009
14194
  @json
12010
- ) ON CONFLICT(translationId,bookId,number) DO
14195
+ ) ON CONFLICT(commentaryId,bookId,number) DO
12011
14196
  UPDATE SET
14197
+ introduction=excluded.introduction,
12012
14198
  json=excluded.json;`);
12013
- const verseUpsert = db.prepare(`INSERT INTO ChapterVerse(
12014
- translationId,
14199
+ const verseUpsert = db.prepare(`INSERT INTO CommentaryChapterVerse(
14200
+ commentaryId,
12015
14201
  bookId,
12016
14202
  chapterNumber,
12017
14203
  number,
12018
14204
  text,
12019
14205
  contentJson
12020
14206
  ) VALUES (
12021
- @translationId,
14207
+ @commentaryId,
12022
14208
  @bookId,
12023
14209
  @chapterNumber,
12024
14210
  @number,
12025
14211
  @text,
12026
14212
  @contentJson
12027
- ) ON CONFLICT(translationId,bookId,chapterNumber,number) DO
14213
+ ) ON CONFLICT(commentaryId,bookId,chapterNumber,number) DO
12028
14214
  UPDATE SET
12029
14215
  text=excluded.text,
12030
14216
  contentJson=excluded.contentJson;`);
12031
- const footnoteUpsert = db.prepare(`INSERT INTO ChapterFootnote(
12032
- translationId,
12033
- bookId,
12034
- chapterNumber,
12035
- id,
12036
- verseNumber,
12037
- text
12038
- ) VALUES (
12039
- @translationId,
12040
- @bookId,
12041
- @chapterNumber,
12042
- @id,
12043
- @verseNumber,
12044
- @text
12045
- ) ON CONFLICT(translationId,bookId,chapterNumber,id) DO
12046
- UPDATE SET
12047
- verseNumber=excluded.verseNumber,
12048
- text=excluded.text;`);
12049
- const chapterAudioUpsert = db.prepare(`INSERT INTO ChapterAudioUrl(
12050
- translationId,
12051
- bookId,
12052
- number,
12053
- reader,
12054
- url
12055
- ) VALUES (
12056
- @translationId,
12057
- @bookId,
12058
- @number,
12059
- @reader,
12060
- @url
12061
- ) ON CONFLICT(translationId,bookId,number,reader) DO
12062
- UPDATE SET
12063
- url=excluded.url;`);
12064
14217
  const insertChaptersAndVerses = db.transaction(() => {
12065
14218
  for (let chapter of chapters) {
12066
14219
  let verses = [];
12067
- let footnotes = /* @__PURE__ */ new Map();
12068
- for (let c of chapter.chapter.footnotes) {
12069
- footnotes.set(c.noteId, {
12070
- id: c.noteId,
12071
- text: c.text
12072
- });
12073
- }
12074
14220
  for (let c of chapter.chapter.content) {
12075
14221
  if (c.type === "verse") {
12076
14222
  const verse = c;
12077
14223
  if (!verse.number) {
12078
14224
  console.error(
12079
14225
  "Verse missing number",
12080
- translation.id,
14226
+ commentary.id,
12081
14227
  book.id,
12082
14228
  chapter.chapter.number,
12083
14229
  verse.number
@@ -12093,11 +14239,6 @@ function insertTranslationContent(db, translation, book, chapters) {
12093
14239
  text += "\n";
12094
14240
  } else if ("text" in c2) {
12095
14241
  text += c2.text + " ";
12096
- } else if ("noteId" in c2) {
12097
- const note = footnotes.get(c2.noteId);
12098
- if (note) {
12099
- note.verseNumber = verse.number;
12100
- }
12101
14242
  }
12102
14243
  }
12103
14244
  }
@@ -12110,14 +14251,15 @@ function insertTranslationContent(db, translation, book, chapters) {
12110
14251
  }
12111
14252
  }
12112
14253
  chapterUpsert.run({
12113
- translationId: translation.id,
14254
+ commentaryId: commentary.id,
12114
14255
  bookId: book.id,
12115
14256
  number: chapter.chapter.number,
14257
+ introduction: chapter.chapter.introduction ?? null,
12116
14258
  json: JSON.stringify(chapter.chapter)
12117
14259
  });
12118
14260
  for (let verse of verses) {
12119
14261
  verseUpsert.run({
12120
- translationId: translation.id,
14262
+ commentaryId: commentary.id,
12121
14263
  bookId: book.id,
12122
14264
  chapterNumber: chapter.chapter.number,
12123
14265
  number: verse.number,
@@ -12125,58 +14267,38 @@ function insertTranslationContent(db, translation, book, chapters) {
12125
14267
  contentJson: verse.contentJson
12126
14268
  });
12127
14269
  }
12128
- for (let footnote of footnotes.values()) {
12129
- footnoteUpsert.run({
12130
- translationId: translation.id,
12131
- bookId: book.id,
12132
- chapterNumber: chapter.chapter.number,
12133
- id: footnote.id,
12134
- verseNumber: footnote.verseNumber,
12135
- text: footnote.text
12136
- });
12137
- }
12138
- for (let reader in chapter.thisChapterAudioLinks) {
12139
- const url = chapter.thisChapterAudioLinks[reader];
12140
- if (url) {
12141
- chapterAudioUpsert.run({
12142
- translationId: translation.id,
12143
- bookId: book.id,
12144
- number: chapter.chapter.number,
12145
- reader,
12146
- url
12147
- });
12148
- }
12149
- }
12150
14270
  }
12151
14271
  });
12152
14272
  insertChaptersAndVerses();
12153
14273
  }
12154
- function updateTranslationHashes(db, translations) {
12155
- console.log(`Updating hashes for ${translations.length} translations.`);
14274
+ function updateCommentaryHashes(db, commentaries) {
14275
+ console.log(`Updating hashes for ${commentaries.length} commentaries.`);
12156
14276
  const updateTranslationHash = db.prepare(
12157
- `UPDATE Translation SET sha256 = @sha256 WHERE id = @translationId;`
14277
+ `UPDATE Commentary SET sha256 = @sha256 WHERE id = @commentaryId;`
12158
14278
  );
12159
14279
  const updateBookHash = db.prepare(
12160
- `UPDATE Book SET sha256 = @sha256 WHERE translationId = @translationId AND id = @bookId;`
14280
+ `UPDATE CommentaryBook SET sha256 = @sha256 WHERE commentaryId = @commentaryId AND id = @bookId;`
12161
14281
  );
12162
14282
  const updateChapterHash = db.prepare(
12163
- `UPDATE Chapter SET sha256 = @sha256 WHERE translationId = @translationId AND bookId = @bookId AND number = @chapterNumber;`
14283
+ `UPDATE CommentaryChapter SET sha256 = @sha256 WHERE commentaryId = @commentaryId AND bookId = @bookId AND number = @chapterNumber;`
14284
+ );
14285
+ const getBooks = db.prepare(
14286
+ "SELECT * FROM CommentaryBook WHERE commentaryId = ?;"
12164
14287
  );
12165
- const getBooks = db.prepare("SELECT * FROM Book WHERE translationId = ?;");
12166
14288
  const getChapters = db.prepare(
12167
- "SELECT * FROM Chapter WHERE translationId = @translationId AND bookId = @bookId;"
14289
+ "SELECT * FROM CommentaryChapter WHERE commentaryId = @commentaryId AND bookId = @bookId;"
12168
14290
  );
12169
- for (let translation of translations) {
12170
- const translationSha = (0, import_hash2.sha256)().update(translation.id).update(translation.name).update(translation.language).update(translation.licenseUrl).update(translation.textDirection).update(translation.website).update(translation.englishName).update(translation.shortName);
12171
- const books = getBooks.all(translation.id);
14291
+ for (let commentary of commentaries) {
14292
+ const commentarySha = (0, import_hash2.sha256)().update(commentary.id).update(commentary.name).update(commentary.language).update(commentary.licenseUrl).update(commentary.textDirection).update(commentary.website).update(commentary.englishName);
14293
+ const books = getBooks.all(commentary.id);
12172
14294
  for (let book of books) {
12173
14295
  const chapters = getChapters.all({
12174
- translationId: translation.id,
14296
+ commentaryId: commentary.id,
12175
14297
  bookId: book.id
12176
14298
  });
12177
- const bookSha = (0, import_hash2.sha256)().update(book.translationId).update(book.id).update(book.numberOfChapters).update(book.order).update(book.name).update(book.title).update(book.commonName);
14299
+ const bookSha = (0, import_hash2.sha256)().update(book.commentaryId).update(book.id).update(book.numberOfChapters).update(book.order).update(book.name).update(book.title).update(book.commonName).update(book.introduction);
12178
14300
  for (let chapter of chapters) {
12179
- const hash2 = (0, import_hash2.sha256)().update(chapter.translationId).update(chapter.bookId).update(chapter.number).update(chapter.json).digest("hex");
14301
+ const hash2 = (0, import_hash2.sha256)().update(chapter.commentaryId).update(chapter.bookId).update(chapter.number).update(chapter.introduction).update(chapter.json).digest("hex");
12180
14302
  chapter.sha256 = hash2;
12181
14303
  bookSha.update(hash2);
12182
14304
  }
@@ -12184,7 +14306,7 @@ function updateTranslationHashes(db, translations) {
12184
14306
  for (let chapter of chapters) {
12185
14307
  updateChapterHash.run({
12186
14308
  sha256: chapter.sha256,
12187
- translationId: chapter.translationId,
14309
+ commentaryId: chapter.commentaryId,
12188
14310
  bookId: chapter.bookId,
12189
14311
  chapterNumber: chapter.number
12190
14312
  });
@@ -12193,30 +14315,30 @@ function updateTranslationHashes(db, translations) {
12193
14315
  updateChapters();
12194
14316
  const bookHash = bookSha.digest("hex");
12195
14317
  book.sha256 = bookHash;
12196
- translationSha.update(bookHash);
14318
+ commentarySha.update(bookHash);
12197
14319
  }
12198
14320
  const updateBooks = db.transaction(() => {
12199
14321
  for (let book of books) {
12200
14322
  updateBookHash.run({
12201
14323
  sha256: book.sha256,
12202
- translationId: book.translationId,
14324
+ commentaryId: book.commentaryId,
12203
14325
  bookId: book.id
12204
14326
  });
12205
14327
  }
12206
14328
  });
12207
14329
  updateBooks();
12208
- const hash = translationSha.digest("hex");
12209
- translation.sha256 = hash;
14330
+ const hash = commentarySha.digest("hex");
14331
+ commentary.sha256 = hash;
12210
14332
  }
12211
- const updateTranslations = db.transaction(() => {
12212
- for (let translation of translations) {
14333
+ const updateCommentaries = db.transaction(() => {
14334
+ for (let commentary of commentaries) {
12213
14335
  updateTranslationHash.run({
12214
- sha256: translation.sha256,
12215
- translationId: translation.id
14336
+ sha256: commentary.sha256,
14337
+ commentaryId: commentary.id
12216
14338
  });
12217
14339
  }
12218
14340
  });
12219
- updateTranslations();
14341
+ updateCommentaries();
12220
14342
  console.log(`Updated.`);
12221
14343
  }
12222
14344
  function getDbPathFromDir(dir) {
@@ -12296,33 +14418,53 @@ async function getDb(dbPath) {
12296
14418
  }
12297
14419
  return db;
12298
14420
  }
12299
- async function* loadDatasets(db, translationsPerBatch = 50, translationsToLoad) {
14421
+ async function* loadDatasets(db, perBatch = 50, translationsToLoad) {
14422
+ yield* loadTranslationDatasets(db, perBatch, translationsToLoad);
14423
+ yield* loadCommentaryDatasets(db, perBatch, translationsToLoad);
14424
+ }
14425
+ async function* loadTranslationDatasets(db, translationsPerBatch = 50, translationsToLoad) {
12300
14426
  let offset = 0;
12301
14427
  let pageSize = translationsPerBatch;
12302
- console.log("Generating API files in batches of", pageSize);
14428
+ console.log("Generating translation datasets in batches of", pageSize);
12303
14429
  const totalTranslations = await db.translation.count();
12304
14430
  const totalBatches = Math.ceil(totalTranslations / pageSize);
12305
14431
  let batchNumber = 1;
12306
14432
  while (true) {
12307
- console.log("Generating API batch", batchNumber, "of", totalBatches);
14433
+ console.log(
14434
+ "Generating translation batch",
14435
+ batchNumber,
14436
+ "of",
14437
+ totalBatches
14438
+ );
12308
14439
  batchNumber++;
12309
- const query = {
14440
+ const translationQuery = {
14441
+ skip: offset,
14442
+ take: pageSize
14443
+ };
14444
+ const commentaryQuery = {
12310
14445
  skip: offset,
12311
14446
  take: pageSize
12312
14447
  };
12313
14448
  if (translationsToLoad && translationsToLoad.length > 0) {
12314
- query.where = {
14449
+ translationQuery.where = {
14450
+ id: {
14451
+ in: translationsToLoad
14452
+ }
14453
+ };
14454
+ commentaryQuery.where = {
12315
14455
  id: {
12316
14456
  in: translationsToLoad
12317
14457
  }
12318
14458
  };
12319
14459
  }
12320
- const translations = await db.translation.findMany(query);
14460
+ const translations = await db.translation.findMany(translationQuery);
14461
+ const commentaries = await db.commentary.findMany(commentaryQuery);
12321
14462
  if (translations.length <= 0) {
12322
14463
  break;
12323
14464
  }
12324
14465
  const dataset = {
12325
- translations: []
14466
+ translations: [],
14467
+ commentaries: []
12326
14468
  };
12327
14469
  for (let translation of translations) {
12328
14470
  const datasetTranslation = {
@@ -12381,6 +14523,84 @@ async function* loadDatasets(db, translationsPerBatch = 50, translationsToLoad)
12381
14523
  offset += pageSize;
12382
14524
  }
12383
14525
  }
14526
+ async function* loadCommentaryDatasets(db, perBatch = 50, commentariesToLoad) {
14527
+ let offset = 0;
14528
+ let pageSize = perBatch;
14529
+ console.log("Generating commentaries datasets in batches of", pageSize);
14530
+ const totalCommentaries = await db.commentary.count();
14531
+ const totalBatches = Math.ceil(totalCommentaries / pageSize);
14532
+ let batchNumber = 1;
14533
+ while (true) {
14534
+ console.log(
14535
+ "Generating commentary batch",
14536
+ batchNumber,
14537
+ "of",
14538
+ totalBatches
14539
+ );
14540
+ batchNumber++;
14541
+ const commentaryQuery = {
14542
+ skip: offset,
14543
+ take: pageSize
14544
+ };
14545
+ if (commentariesToLoad && commentariesToLoad.length > 0) {
14546
+ commentaryQuery.where = {
14547
+ id: {
14548
+ in: commentariesToLoad
14549
+ }
14550
+ };
14551
+ }
14552
+ const commentaries = await db.commentary.findMany(commentaryQuery);
14553
+ if (commentaries.length <= 0) {
14554
+ break;
14555
+ }
14556
+ const dataset = {
14557
+ translations: [],
14558
+ commentaries: []
14559
+ };
14560
+ for (let commentary of commentaries) {
14561
+ const datasetCommentary = {
14562
+ ...commentary,
14563
+ textDirection: commentary.textDirection,
14564
+ books: []
14565
+ };
14566
+ dataset.commentaries.push(datasetCommentary);
14567
+ const books = await db.commentaryBook.findMany({
14568
+ where: {
14569
+ commentaryId: commentary.id
14570
+ },
14571
+ orderBy: {
14572
+ order: "asc"
14573
+ }
14574
+ });
14575
+ for (let book of books) {
14576
+ const chapters = await db.commentaryChapter.findMany({
14577
+ where: {
14578
+ commentaryId: commentary.id,
14579
+ bookId: book.id
14580
+ },
14581
+ orderBy: {
14582
+ number: "asc"
14583
+ }
14584
+ });
14585
+ const bookChapters = chapters.map(
14586
+ (chapter) => {
14587
+ return {
14588
+ chapter: JSON.parse(chapter.json)
14589
+ };
14590
+ }
14591
+ );
14592
+ const datasetBook = {
14593
+ ...book,
14594
+ introduction: book.introduction ?? void 0,
14595
+ chapters: bookChapters
14596
+ };
14597
+ datasetCommentary.books.push(datasetBook);
14598
+ }
14599
+ }
14600
+ yield dataset;
14601
+ offset += pageSize;
14602
+ }
14603
+ }
12384
14604
  function serializeDatasets(datasets, options = {}) {
12385
14605
  return serializeOutputFiles(
12386
14606
  generateOutputFilesFromDatasets(datasets, {
@@ -12401,7 +14621,7 @@ var S3Uploader = class {
12401
14621
  _bucketName;
12402
14622
  _keyPrefix;
12403
14623
  get idealBatchSize() {
12404
- return 50;
14624
+ return 75;
12405
14625
  }
12406
14626
  constructor(bucketName, keyPrefix, profile) {
12407
14627
  this._bucketName = bucketName;
@@ -12409,6 +14629,11 @@ var S3Uploader = class {
12409
14629
  this._client = new import_client_s3.S3Client({
12410
14630
  credentials: !profile || typeof profile === "string" ? (0, import_credential_providers.fromNodeProviderChain)({ profile: profile ?? void 0 }) : profile
12411
14631
  });
14632
+ if (!process.env.AWS_REGION || !process.env.AWS_PROFILE) {
14633
+ console.warn(
14634
+ "No AWS_REGION or AWS_PROFILE environment variable set. This may cause issues with the S3 client."
14635
+ );
14636
+ }
12412
14637
  }
12413
14638
  async upload(file, overwrite) {
12414
14639
  const path5 = file.path.startsWith("/") ? file.path.substring(1) : file.path;
@@ -12437,6 +14662,7 @@ var S3Uploader = class {
12437
14662
  }
12438
14663
  } else {
12439
14664
  console.log(`[s3] Checksum not available: ${key}`);
14665
+ matches = false;
12440
14666
  }
12441
14667
  if (matches && !overwrite) {
12442
14668
  return false;
@@ -12567,6 +14793,10 @@ async function serializeAndUploadDatasets(dest, datasets, options = {}) {
12567
14793
  if (overwriteCommonFiles) {
12568
14794
  console.log("Overwriting only common files");
12569
14795
  }
14796
+ const overwriteMergedFiles = !!options.overwriteMergedFiles;
14797
+ if (overwriteMergedFiles) {
14798
+ console.log("Overwriting only merged files");
14799
+ }
12570
14800
  let filePattern;
12571
14801
  if (!!options.filePattern) {
12572
14802
  filePattern = new RegExp(options.filePattern, "g");
@@ -12639,6 +14869,7 @@ Unable to determine bucket name`
12639
14869
  async function uploadFilesUsingUploader(uploader, options, serializedFiles) {
12640
14870
  const overwrite = !!options.overwrite;
12641
14871
  const overwriteCommonFiles = !!options.overwriteCommonFiles;
14872
+ const overwriteMergedFiles = !!options.overwriteMergedFiles;
12642
14873
  let filePattern;
12643
14874
  if (!!options.filePattern) {
12644
14875
  filePattern = new RegExp(options.filePattern, "g");
@@ -12664,13 +14895,20 @@ async function uploadFilesUsingUploader(uploader, options, serializedFiles) {
12664
14895
  const isAvailableTranslations = file.path.endsWith(
12665
14896
  "available_translations.json"
12666
14897
  );
12667
- const isCommonFile = !isAvailableTranslations;
14898
+ const isAvailableCommentaries = file.path.endsWith(
14899
+ "available_commentaries.json"
14900
+ );
14901
+ const isCommonFile = !isAvailableTranslations && !isAvailableCommentaries;
14902
+ const isMergedFile = isAvailableCommentaries || isAvailableTranslations;
12668
14903
  if (await uploader.upload(
12669
14904
  file,
12670
- overwrite || overwriteCommonFiles && isCommonFile
14905
+ overwrite || overwriteCommonFiles && isCommonFile || isMergedFile && overwriteMergedFiles
12671
14906
  )) {
14907
+ if (options.verbose) {
14908
+ console.log("Uploaded file:", file.path);
14909
+ }
12672
14910
  writtenFiles++;
12673
- } else {
14911
+ } else if (options.verbose) {
12674
14912
  console.warn("File already exists:", file.path);
12675
14913
  console.warn("Skipping file");
12676
14914
  }
@@ -12680,6 +14918,7 @@ async function uploadFilesUsingUploader(uploader, options, serializedFiles) {
12680
14918
  });
12681
14919
  await Promise.all(promises);
12682
14920
  console.log("Wrote", writtenFiles, "files");
14921
+ console.log("Skipped", batch2.length - writtenFiles, "files");
12683
14922
  batchNumber++;
12684
14923
  offset += batchSize;
12685
14924
  batch2 = files.slice(offset, offset + batchSize);
@@ -12699,60 +14938,103 @@ var import_all_iso_language_codes2 = require("all-iso-language-codes");
12699
14938
  async function initDb(dbPath, options) {
12700
14939
  console.log("Initializing new Bible API DB...");
12701
14940
  if (options.source) {
12702
- const db = new import_better_sqlite32.default(getDbPath(dbPath), {});
12703
- const sourcePath = import_node_path.default.resolve(options.source);
12704
- try {
12705
- console.log("Copying schema from source DB...");
12706
- if (options.language) {
12707
- console.log(
12708
- "Copying only the following languages:",
12709
- options.language
12710
- );
12711
- const languages = `(${options.language.map((l) => `'${l}'`).join(", ")})`;
12712
- db.exec(`
12713
- ATTACH DATABASE "${sourcePath}" AS source;
14941
+ if (options.source.startsWith("https://")) {
14942
+ console.log("Downloading source database...");
14943
+ const databasePath = getDbPath(dbPath);
14944
+ let progressIncrement = 0.01;
14945
+ await downloadFile(options.source, databasePath, (progress) => {
14946
+ if (progress >= progressIncrement) {
14947
+ console.log(
14948
+ `Downloading... ${Math.round(progress * 100)}%`
14949
+ );
14950
+ progressIncrement += 0.01;
14951
+ }
14952
+ });
14953
+ } else {
14954
+ const databasePath = getDbPath(dbPath);
14955
+ if (await (0, import_fs_extra4.exists)(databasePath)) {
14956
+ if (!options.overwrite) {
14957
+ console.log("Database already exists.");
14958
+ return;
14959
+ } else {
14960
+ console.log("Overwriting existing database...");
14961
+ await (0, import_promises3.rm)(databasePath);
14962
+ }
14963
+ }
14964
+ const db = new import_better_sqlite32.default(databasePath, {});
14965
+ const sourcePath = import_node_path.default.resolve(options.source);
14966
+ try {
14967
+ console.log("Copying schema from source DB...");
14968
+ if (options.language) {
14969
+ console.log(
14970
+ "Copying only the following languages:",
14971
+ options.language
14972
+ );
14973
+ const languages = `(${options.language.map((l) => `'${l}'`).join(", ")})`;
14974
+ db.exec(`
14975
+ ATTACH DATABASE "${sourcePath}" AS source;
12714
14976
 
12715
- CREATE TABLE "_prisma_migrations" AS SELECT * FROM source._prisma_migrations;
12716
-
12717
- CREATE TABLE "Translation" AS SELECT * FROM source.Translation
12718
- WHERE language IN ${languages};
14977
+ CREATE TABLE "_prisma_migrations" AS SELECT * FROM source._prisma_migrations;
14978
+
14979
+ CREATE TABLE "Translation" AS SELECT * FROM source.Translation
14980
+ WHERE language IN ${languages};
12719
14981
 
12720
- CREATE TABLE "Book" AS SELECT * FROM source.Book
12721
- INNER JOIN source.Translation ON source.Translation.id = source.Book.translationId
12722
- WHERE source.Translation.language IN ${languages};
14982
+ CREATE TABLE "Book" AS SELECT * FROM source.Book
14983
+ INNER JOIN source.Translation ON source.Translation.id = source.Book.translationId
14984
+ WHERE source.Translation.language IN ${languages};
12723
14985
 
12724
- CREATE TABLE "Chapter" AS SELECT * FROM source.Chapter
12725
- INNER JOIN source.Translation ON source.Translation.id = source.Chapter.translationId
12726
- WHERE source.Translation.language IN ${languages};
14986
+ CREATE TABLE "Chapter" AS SELECT * FROM source.Chapter
14987
+ INNER JOIN source.Translation ON source.Translation.id = source.Chapter.translationId
14988
+ WHERE source.Translation.language IN ${languages};
12727
14989
 
12728
- CREATE TABLE "ChapterVerse" AS SELECT * FROM source.ChapterVerse
12729
- INNER JOIN source.Translation ON source.Translation.id = source.ChapterVerse.translationId
12730
- WHERE source.Translation.language IN ${languages};
14990
+ CREATE TABLE "ChapterVerse" AS SELECT * FROM source.ChapterVerse
14991
+ INNER JOIN source.Translation ON source.Translation.id = source.ChapterVerse.translationId
14992
+ WHERE source.Translation.language IN ${languages};
12731
14993
 
12732
- CREATE TABLE "ChapterFootnote" AS SELECT * FROM source.ChapterFootnote
12733
- INNER JOIN source.Translation ON source.Translation.id = source.ChapterFootnote.translationId
12734
- WHERE source.Translation.language IN ${languages};
14994
+ CREATE TABLE "ChapterFootnote" AS SELECT * FROM source.ChapterFootnote
14995
+ INNER JOIN source.Translation ON source.Translation.id = source.ChapterFootnote.translationId
14996
+ WHERE source.Translation.language IN ${languages};
12735
14997
 
12736
- CREATE TABLE "ChapterAudioUrl" AS SELECT * FROM source.ChapterAudioUrl
12737
- INNER JOIN source.Translation ON source.Translation.id = source.ChapterAudioUrl.translationId
12738
- WHERE source.Translation.language IN ${languages};
12739
- `);
12740
- } else {
12741
- db.exec(`
12742
- ATTACH DATABASE "${sourcePath}" AS source;
14998
+ CREATE TABLE "ChapterAudioUrl" AS SELECT * FROM source.ChapterAudioUrl
14999
+ INNER JOIN source.Translation ON source.Translation.id = source.ChapterAudioUrl.translationId
15000
+ WHERE source.Translation.language IN ${languages};
12743
15001
 
12744
- CREATE TABLE "_prisma_migrations" AS SELECT * FROM source._prisma_migrations;
12745
- CREATE TABLE "Translation" AS SELECT * FROM source.Translation;
12746
- CREATE TABLE "Book" AS SELECT * FROM source.Book;
12747
- CREATE TABLE "Chapter" AS SELECT * FROM source.Chapter;
12748
- CREATE TABLE "ChapterVerse" AS SELECT * FROM source.ChapterVerse;
12749
- CREATE TABLE "ChapterFootnote" AS SELECT * FROM source.ChapterFootnote;
12750
- CREATE TABLE "ChapterAudioUrl" AS SELECT * FROM source.ChapterAudioUrl;
12751
- `);
12752
- }
12753
- console.log("Done.");
12754
- } finally {
12755
- db.close();
15002
+ CREATE TABLE "Commentary" AS SELECT * FROM source.Commentary
15003
+ WHERE language IN ${languages};
15004
+
15005
+ CREATE TABLE "CommentaryBook" AS SELECT * FROM source.CommentaryBook
15006
+ INNER JOIN source.Commentary ON source.Commentary.id = source.CommentaryBook.commentaryId
15007
+ WHERE source.Commentary.language IN ${languages};
15008
+
15009
+ CREATE TABLE "CommentaryChapter" AS SELECT * FROM source.CommentaryChapter
15010
+ INNER JOIN source.Commentary ON source.Commentary.id = source.CommentaryChapter.commentaryId
15011
+ WHERE source.Commentary.language IN ${languages};
15012
+
15013
+ CREATE TABLE "CommentaryChapterVerse" AS SELECT * FROM source.CommentaryChapterVerse
15014
+ INNER JOIN source.Commentary ON source.Commentary.id = source.CommentaryChapterVerse.commentaryId
15015
+ WHERE source.Commentary.language IN ${languages};
15016
+ `);
15017
+ } else {
15018
+ db.exec(`
15019
+ ATTACH DATABASE "${sourcePath}" AS source;
15020
+
15021
+ CREATE TABLE "_prisma_migrations" AS SELECT * FROM source._prisma_migrations;
15022
+ CREATE TABLE "Translation" AS SELECT * FROM source.Translation;
15023
+ CREATE TABLE "Book" AS SELECT * FROM source.Book;
15024
+ CREATE TABLE "Chapter" AS SELECT * FROM source.Chapter;
15025
+ CREATE TABLE "ChapterVerse" AS SELECT * FROM source.ChapterVerse;
15026
+ CREATE TABLE "ChapterFootnote" AS SELECT * FROM source.ChapterFootnote;
15027
+ CREATE TABLE "ChapterAudioUrl" AS SELECT * FROM source.ChapterAudioUrl;
15028
+ CREATE TABLE "Commentary" AS SELECT * FROM source.Commentary;
15029
+ CREATE TABLE "CommentaryBook" AS SELECT * FROM source.CommentaryBook;
15030
+ CREATE TABLE "CommentaryChapter" AS SELECT * FROM source.CommentaryChapter;
15031
+ CREATE TABLE "CommentaryChapterVerse" AS SELECT * FROM source.CommentaryChapterVerse;
15032
+ `);
15033
+ }
15034
+ console.log("Done.");
15035
+ } finally {
15036
+ db.close();
15037
+ }
12756
15038
  }
12757
15039
  } else {
12758
15040
  const db = await getDb(getDbPath(dbPath));
@@ -12796,6 +15078,43 @@ async function importTranslations2(dir, options) {
12796
15078
  db.close();
12797
15079
  }
12798
15080
  }
15081
+ async function importCommentary(dir, dirs, options) {
15082
+ const parser = new import_linkedom.DOMParser();
15083
+ globalThis.DOMParser = import_linkedom.DOMParser;
15084
+ globalThis.Element = import_linkedom.Element;
15085
+ globalThis.Node = import_linkedom.Node;
15086
+ const db = await getDbFromDir(process.cwd());
15087
+ try {
15088
+ await importCommentaries(
15089
+ db,
15090
+ [dir, ...dirs],
15091
+ parser,
15092
+ !!options.overwrite
15093
+ );
15094
+ } finally {
15095
+ db.close();
15096
+ }
15097
+ }
15098
+ async function importCommentaries2(dir, options) {
15099
+ const parser = new import_linkedom.DOMParser();
15100
+ globalThis.DOMParser = import_linkedom.DOMParser;
15101
+ globalThis.Element = import_linkedom.Element;
15102
+ globalThis.Node = import_linkedom.Node;
15103
+ const db = await getDbFromDir(process.cwd());
15104
+ try {
15105
+ const files = await (0, import_promises3.readdir)(dir);
15106
+ const commentaryDirs = files.map((f) => import_node_path.default.resolve(dir, f));
15107
+ console.log(`Importing ${commentaryDirs.length} commentaries`);
15108
+ await importCommentaries(
15109
+ db,
15110
+ commentaryDirs,
15111
+ parser,
15112
+ !!options.overwrite
15113
+ );
15114
+ } finally {
15115
+ db.close();
15116
+ }
15117
+ }
12799
15118
  async function fetchTranslations(dir, translations, options = {}) {
12800
15119
  const translationsSet = new Set(translations);
12801
15120
  const client = new import_fetch_client.BibleClient({
@@ -12853,9 +15172,7 @@ async function fetchTranslations(dir, translations, options = {}) {
12853
15172
  const file = {
12854
15173
  fileType: "usx",
12855
15174
  content: contentString,
12856
- metadata: {
12857
- translation
12858
- },
15175
+ metadata: translation,
12859
15176
  name
12860
15177
  };
12861
15178
  return file;
@@ -13096,7 +15413,10 @@ async function start() {
13096
15413
  globalThis.Node = import_linkedom2.Node;
13097
15414
  const program = new import_commander.Command();
13098
15415
  program.name("helloao").description("A CLI for managing a Free Use Bible API.").version("0.0.1");
13099
- program.command("init [path]").description("Initialize a new Bible API DB.").option("--source <path>", "The source database to copy from.").option(
15416
+ program.command("init [path]").description("Initialize a new Bible API DB.").option(
15417
+ "--source <path>",
15418
+ "The source database to copy from. If given a HTTPS URL, then the database will be downloaded from the given URL."
15419
+ ).option("--overwrite", "Whether to overwrite the existing database.").option(
13100
15420
  "--language <languages...>",
13101
15421
  "The language(s) that the database should be initialized with."
13102
15422
  ).action(async (dbPath, options) => {
@@ -13135,6 +15455,17 @@ async function start() {
13135
15455
  ).option("--overwrite", "Whether to overwrite existing files.").action(async (dir, options) => {
13136
15456
  await importTranslations2(dir, options);
13137
15457
  });
15458
+ program.command("import-commentary <dir> [dirs...]").description(
15459
+ "Imports a commentary from the given directory into the database."
15460
+ ).option("--overwrite", "Whether to overwrite existing files.").action(async (dir, dirs, options) => {
15461
+ console.log("options", options);
15462
+ await importCommentary(dir, dirs, options);
15463
+ });
15464
+ program.command("import-commentaries <dir>").description(
15465
+ "Imports all commentaries from the given directory into the database."
15466
+ ).option("--overwrite", "Whether to overwrite existing files.").action(async (dir, options) => {
15467
+ await importCommentaries2(dir, options);
15468
+ });
13138
15469
  program.command("upload-test-translation <input>").description(
13139
15470
  `Uploads a translation to the HelloAO Free Bible API test S3 bucket.
13140
15471
  Requires access to the HelloAO Free Bible API test S3 bucket.
@@ -13314,10 +15645,13 @@ For inquiries, please contact hello@helloao.org.`
13314
15645
  "50"
13315
15646
  ).option(
13316
15647
  "--translations <translations...>",
13317
- "The translations to generate API files for."
15648
+ "The translations or commentaries to generate API files for."
13318
15649
  ).option("--overwrite", "Whether to overwrite existing files.").option(
13319
15650
  "--overwrite-common-files",
13320
15651
  "Whether to overwrite only common files."
15652
+ ).option(
15653
+ "--overwrite-merged-files",
15654
+ "Whether to overwrite only merged files."
13321
15655
  ).option(
13322
15656
  "--file-pattern <pattern>",
13323
15657
  "The file pattern regex that should be used to filter the files that are uploaded."
@@ -13336,7 +15670,10 @@ For inquiries, please contact hello@helloao.org.`
13336
15670
  ).option(
13337
15671
  "--secret-access-key <secretAccessKey>",
13338
15672
  "The AWS Secret Access Key to use for uploading to S3."
13339
- ).option("--pretty", "Whether to generate pretty-printed JSON files.").action(async (dest, options) => {
15673
+ ).option("--pretty", "Whether to generate pretty-printed JSON files.").option(
15674
+ "--verbose",
15675
+ "Whether to output verbose information during the upload."
15676
+ ).action(async (dest, options) => {
13340
15677
  const db = getPrismaDbFromDir(process.cwd());
13341
15678
  try {
13342
15679
  await uploadApiFilesFromDatabase(db, dest, options);
@@ -13396,4 +15733,14 @@ decimal.js/decimal.mjs:
13396
15733
  * MIT Licence
13397
15734
  *)
13398
15735
  */
15736
+ /*! Bundled license information:
15737
+
15738
+ papaparse/papaparse.js:
15739
+ (* @license
15740
+ Papa Parse
15741
+ v5.4.1
15742
+ https://github.com/mholt/PapaParse
15743
+ License: MIT
15744
+ *)
15745
+ */
13399
15746
  //# sourceMappingURL=cli.cjs.map