wikitongues-db 0.2.1 → 0.2.3

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/index.mjs CHANGED
@@ -217,7 +217,13 @@ var MULTILINGUAL_ALIASES = {
217
217
  sw: "swh",
218
218
  so: "som",
219
219
  zu: "zul",
220
- xh: "xho"
220
+ xh: "xho",
221
+ et: "est",
222
+ az: "aze",
223
+ lv: "lav",
224
+ ne: "nep",
225
+ ff: "ful",
226
+ mg: "mlg"
221
227
  };
222
228
  var MACROLANGUAGE_EXPANSIONS = {
223
229
  fas: ["fas", "pes", "prs"],
@@ -266,7 +272,10 @@ var MACROLANGUAGE_EXPANSIONS = {
266
272
  est: ["est", "ekk", "vro"],
267
273
  aka: ["aka", "twi", "fat"],
268
274
  nep: ["nep", "npi"],
269
- ful: ["ful", "fuf", "fuh", "fub", "fuq"]
275
+ ful: ["ful", "fuf", "fuh", "fub", "fuq"],
276
+ lav: ["lav", "lvs", "ltg"],
277
+ mon: ["mon", "khk", "mvf"],
278
+ mlg: ["mlg", "plt", "skg", "tkg"]
270
279
  };
271
280
  var LanguageResolver = class {
272
281
  isoToName = /* @__PURE__ */ new Map();
@@ -308,6 +317,14 @@ var LanguageResolver = class {
308
317
  this.aliases.set(prefix, iso);
309
318
  }
310
319
  }
320
+ const part1 = lang.standards.iso639_3.part1?.toLowerCase();
321
+ if (part1 && !this.aliases.has(part1)) {
322
+ this.aliases.set(part1, iso);
323
+ }
324
+ const macro = lang.standards.bcp47.macrolanguage?.toLowerCase();
325
+ if (macro && !this.aliases.has(macro)) {
326
+ this.aliases.set(macro, iso);
327
+ }
311
328
  const gc = lang.glottocode;
312
329
  this.glottoToIso.set(gc, iso);
313
330
  this.isoToGlotto.set(iso, gc);
@@ -373,7 +390,7 @@ var LanguageResolver = class {
373
390
  }
374
391
  }
375
392
  }
376
- if (matchedIsos.size === 0) {
393
+ if (matchedIsos.size === 0 && norm.length >= 4) {
377
394
  for (const [autoKey, isoSet] of this.autonymToIso.entries()) {
378
395
  if (autoKey.includes(norm)) {
379
396
  for (const iso of isoSet) {
@@ -486,6 +503,12 @@ var reference_default = {
486
503
  type: "L",
487
504
  invertedName: "Albanian, Tosk"
488
505
  },
506
+ alt: {
507
+ name: "Southern Altai",
508
+ scope: "I",
509
+ type: "L",
510
+ invertedName: "Altai, Southern"
511
+ },
489
512
  amh: {
490
513
  name: "Amharic",
491
514
  scope: "I",
@@ -1653,6 +1676,12 @@ var reference_default = {
1653
1676
  type: "L",
1654
1677
  invertedName: "Kabiy\xE8"
1655
1678
  },
1679
+ kcg: {
1680
+ name: "Tyap",
1681
+ scope: "I",
1682
+ type: "L",
1683
+ invertedName: "Tyap"
1684
+ },
1656
1685
  kdd: {
1657
1686
  name: "Yankunytjatjara",
1658
1687
  scope: "I",
@@ -1741,6 +1770,12 @@ var reference_default = {
1741
1770
  type: "L",
1742
1771
  invertedName: "Khmu"
1743
1772
  },
1773
+ kls: {
1774
+ name: "Kalasha",
1775
+ scope: "I",
1776
+ type: "L",
1777
+ invertedName: "Kalasha"
1778
+ },
1744
1779
  klu: {
1745
1780
  name: "Klao",
1746
1781
  scope: "I",
@@ -5221,6 +5256,14 @@ var reference_default = {
5221
5256
  longitude: 47.776611,
5222
5257
  familyId: "nakh1245"
5223
5258
  },
5259
+ kala1372: {
5260
+ name: "Chitral Kalasha",
5261
+ level: "language",
5262
+ macroarea: "Eurasia",
5263
+ latitude: 35.6415,
5264
+ longitude: 71.6657,
5265
+ familyId: "indo1319"
5266
+ },
5224
5267
  kala1399: {
5225
5268
  name: "Kalaallisut",
5226
5269
  level: "language",
@@ -6539,6 +6582,15 @@ var reference_default = {
6539
6582
  latitude: 16.74515934758395,
6540
6583
  longitude: -94.92819268907601
6541
6584
  },
6585
+ ower1238: {
6586
+ name: "Owerri",
6587
+ level: "dialect",
6588
+ macroarea: "Africa",
6589
+ latitude: 4.62705,
6590
+ longitude: 7.23441,
6591
+ familyId: "atla1278",
6592
+ parentLanguageId: "nucl1417"
6593
+ },
6542
6594
  paip1241: {
6543
6595
  name: "Paipai",
6544
6596
  level: "language",
@@ -7004,6 +7056,15 @@ var reference_default = {
7004
7056
  familyId: "sino1245",
7005
7057
  parentLanguageId: "wuch1236"
7006
7058
  },
7059
+ shet1241: {
7060
+ name: "Shaetlan",
7061
+ level: "dialect",
7062
+ macroarea: "Eurasia",
7063
+ latitude: 55.886945,
7064
+ longitude: -3.710133,
7065
+ familyId: "indo1319",
7066
+ parentLanguageId: "scot1243"
7067
+ },
7007
7068
  shin1264: {
7008
7069
  name: "Shina",
7009
7070
  level: "language",
@@ -7184,6 +7245,14 @@ var reference_default = {
7184
7245
  longitude: 27,
7185
7246
  familyId: "ural1272"
7186
7247
  },
7248
+ sout2694: {
7249
+ name: "Southern Altai",
7250
+ level: "language",
7251
+ macroarea: "Eurasia",
7252
+ latitude: 50.1347,
7253
+ longitude: 86.8705,
7254
+ familyId: "turk1311"
7255
+ },
7187
7256
  sout2772: {
7188
7257
  name: "Southern Daly",
7189
7258
  level: "family",
@@ -7704,6 +7773,14 @@ var reference_default = {
7704
7773
  familyId: "atla1278",
7705
7774
  parentLanguageId: "akan1250"
7706
7775
  },
7776
+ tyap1238: {
7777
+ name: "Tyap",
7778
+ level: "language",
7779
+ macroarea: "Africa",
7780
+ latitude: 9.75568,
7781
+ longitude: 8.3082,
7782
+ familyId: "atla1278"
7783
+ },
7707
7784
  uigh1240: {
7708
7785
  name: "Uighur",
7709
7786
  level: "language",
@@ -8069,6 +8146,9 @@ var reference_default = {
8069
8146
  description: "Tosk Albanian",
8070
8147
  macrolanguage: "sq"
8071
8148
  },
8149
+ alt: {
8150
+ description: "Southern Altai"
8151
+ },
8072
8152
  am: {
8073
8153
  description: "Amharic",
8074
8154
  suppressScript: "Ethi"
@@ -8687,6 +8767,9 @@ var reference_default = {
8687
8767
  kbp: {
8688
8768
  description: "Kabiy\xE8"
8689
8769
  },
8770
+ kcg: {
8771
+ description: "Tyap"
8772
+ },
8690
8773
  kdd: {
8691
8774
  description: "Yankunytjatjara"
8692
8775
  },
@@ -8732,6 +8815,9 @@ var reference_default = {
8732
8815
  description: "Kalaallisut; Greenlandic",
8733
8816
  suppressScript: "Latn"
8734
8817
  },
8818
+ kls: {
8819
+ description: "Kalasha"
8820
+ },
8735
8821
  klu: {
8736
8822
  description: "Klao"
8737
8823
  },
@@ -9718,6 +9804,9 @@ var reference_default = {
9718
9804
  sy: {
9719
9805
  description: "Syrian Arab Republic"
9720
9806
  },
9807
+ tw: {
9808
+ description: "Taiwan, Province of China"
9809
+ },
9721
9810
  us: {
9722
9811
  description: "United States"
9723
9812
  }
@@ -9828,6 +9917,7 @@ var ReferenceHydrator = class {
9828
9917
  }
9829
9918
  const resolved = { tag: raw, primarySubtag: primary, variantSubtags: [] };
9830
9919
  if (lang.description) resolved.description = lang.description;
9920
+ if (lang.macrolanguage) resolved.macrolanguage = lang.macrolanguage;
9831
9921
  let state = 0;
9832
9922
  for (const sub of parts.slice(1)) {
9833
9923
  const lower = sub.toLowerCase();
@@ -10109,6 +10199,8 @@ var Video = class _Video {
10109
10199
  const set = /* @__PURE__ */ new Set();
10110
10200
  for (const lang of this.allLanguages) {
10111
10201
  if (lang.iso639_3) set.add(lang.iso639_3);
10202
+ if (lang.standards.iso639_3.part1) set.add(lang.standards.iso639_3.part1);
10203
+ if (lang.standards.bcp47.macrolanguage) set.add(lang.standards.bcp47.macrolanguage);
10112
10204
  }
10113
10205
  return set;
10114
10206
  }
@@ -10119,6 +10211,9 @@ var Video = class _Video {
10119
10211
  const set = /* @__PURE__ */ new Set();
10120
10212
  for (const lang of this.allLanguages) {
10121
10213
  if (lang.bcp47) set.add(lang.bcp47);
10214
+ if (lang.iso639_3) set.add(lang.iso639_3);
10215
+ if (lang.standards.iso639_3.part1) set.add(lang.standards.iso639_3.part1);
10216
+ if (lang.standards.bcp47.macrolanguage) set.add(lang.standards.bcp47.macrolanguage);
10122
10217
  }
10123
10218
  return set;
10124
10219
  }
@@ -10156,6 +10251,8 @@ var Video = class _Video {
10156
10251
  const qNorm = normalizeText(q);
10157
10252
  for (const lang of this.allLanguages) {
10158
10253
  if (lang.iso639_3 === qLower) return true;
10254
+ if (lang.standards.iso639_3.part1?.toLowerCase() === qLower) return true;
10255
+ if (lang.standards.bcp47.macrolanguage?.toLowerCase() === qLower) return true;
10159
10256
  const bcp = lang.bcp47.toLowerCase();
10160
10257
  if (bcp === qLower || bcp.startsWith(`${qLower}-`)) return true;
10161
10258
  if (lang.glottocode === qLower) return true;
@@ -10164,7 +10261,8 @@ var Video = class _Video {
10164
10261
  const labelNorm = normalizeText(label);
10165
10262
  if (labelNorm === qNorm || ` ${labelNorm} `.includes(` ${qNorm} `)) return true;
10166
10263
  }
10167
- if (lang.autonym.toLowerCase().includes(qLower)) return true;
10264
+ const autoLower = lang.autonym.toLowerCase();
10265
+ if (autoLower === qLower || qLower.length >= 4 && autoLower.includes(qLower)) return true;
10168
10266
  }
10169
10267
  return false;
10170
10268
  }
@@ -10272,6 +10370,12 @@ var VideoCollection = class _VideoCollection {
10272
10370
  }
10273
10371
  return this._videos.some((v) => v.id === item.id);
10274
10372
  }
10373
+ /**
10374
+ * Check if any video in the collection matches the given language query.
10375
+ */
10376
+ hasLanguage(query) {
10377
+ return this._videos.some((v) => v.hasLanguage(query));
10378
+ }
10275
10379
  // -------------------------------------------------------------------------
10276
10380
  // Aggregation & Summary Properties
10277
10381
  // -------------------------------------------------------------------------
@@ -10577,7 +10681,7 @@ var DatasetIndex = class {
10577
10681
  const list = map.get(key);
10578
10682
  if (!list) {
10579
10683
  map.set(key, [video]);
10580
- } else {
10684
+ } else if (!list.some((v) => v.id === video.id)) {
10581
10685
  list.push(video);
10582
10686
  }
10583
10687
  }
@@ -10590,12 +10694,30 @@ var DatasetIndex = class {
10590
10694
  if (plIso) {
10591
10695
  this.appendToMap(this.byIsoPrimary, plIso, video);
10592
10696
  this.appendToMap(this.byIso, plIso, video);
10697
+ const part1 = video.primaryLanguage.standards.iso639_3.part1?.toLowerCase();
10698
+ if (part1 && part1 !== plIso) {
10699
+ this.appendToMap(this.byIsoPrimary, part1, video);
10700
+ this.appendToMap(this.byIso, part1, video);
10701
+ }
10702
+ const macro = video.primaryLanguage.standards.bcp47.macrolanguage?.toLowerCase();
10703
+ if (macro && macro !== plIso && macro !== part1) {
10704
+ this.appendToMap(this.byIsoPrimary, macro, video);
10705
+ this.appendToMap(this.byIso, macro, video);
10706
+ }
10593
10707
  }
10594
10708
  for (const addLang of video.additionalLanguages) {
10595
10709
  const aIso = addLang.iso639_3;
10596
- if (aIso && aIso !== plIso) {
10710
+ if (aIso) {
10597
10711
  this.appendToMap(this.byIso, aIso, video);
10598
10712
  }
10713
+ const part1 = addLang.standards.iso639_3.part1?.toLowerCase();
10714
+ if (part1 && part1 !== aIso) {
10715
+ this.appendToMap(this.byIso, part1, video);
10716
+ }
10717
+ const macro = addLang.standards.bcp47.macrolanguage?.toLowerCase();
10718
+ if (macro && macro !== aIso && macro !== part1) {
10719
+ this.appendToMap(this.byIso, macro, video);
10720
+ }
10599
10721
  }
10600
10722
  for (const lang of video.allLanguages) {
10601
10723
  const bcp = lang.bcp47.toLowerCase().trim();
@@ -10606,6 +10728,18 @@ var DatasetIndex = class {
10606
10728
  this.appendToMap(this.byBcp47, prefix, video);
10607
10729
  }
10608
10730
  }
10731
+ const iso = lang.iso639_3?.toLowerCase().trim();
10732
+ if (iso && iso !== bcp) {
10733
+ this.appendToMap(this.byBcp47, iso, video);
10734
+ }
10735
+ const part1 = lang.standards.iso639_3.part1?.toLowerCase().trim();
10736
+ if (part1 && part1 !== bcp && part1 !== iso) {
10737
+ this.appendToMap(this.byBcp47, part1, video);
10738
+ }
10739
+ const macro = lang.standards.bcp47.macrolanguage?.toLowerCase().trim();
10740
+ if (macro && macro !== bcp && macro !== iso && macro !== part1) {
10741
+ this.appendToMap(this.byBcp47, macro, video);
10742
+ }
10609
10743
  }
10610
10744
  for (const lang of video.allLanguages) {
10611
10745
  this.appendToMap(this.byGlottocode, lang.glottocode, video);
@@ -10848,6 +10982,14 @@ var QueryBuilder = class _QueryBuilder {
10848
10982
  if (matchedIsos.has(lIso) || lIso === rawLower) {
10849
10983
  return true;
10850
10984
  }
10985
+ const part1 = lang.standards.iso639_3.part1?.toLowerCase();
10986
+ if (part1 && (matchedIsos.has(part1) || part1 === rawLower)) {
10987
+ return true;
10988
+ }
10989
+ const macro = lang.standards.bcp47.macrolanguage?.toLowerCase();
10990
+ if (macro && (matchedIsos.has(macro) || macro === rawLower)) {
10991
+ return true;
10992
+ }
10851
10993
  const lBcp = lang.bcp47.toLowerCase();
10852
10994
  if (lBcp === rawLower || lBcp.startsWith(`${rawLower}-`)) {
10853
10995
  return true;
@@ -10860,7 +11002,9 @@ var QueryBuilder = class _QueryBuilder {
10860
11002
  const lNorm = normalizeText(label);
10861
11003
  if (lNorm === norm || pattern && pattern.test(lNorm)) return true;
10862
11004
  }
10863
- if (lang.autonym.toLowerCase().includes(rawLower)) return true;
11005
+ const autoLower = lang.autonym.toLowerCase();
11006
+ if (autoLower === rawLower) return true;
11007
+ if (rawLower.length >= 4 && autoLower.includes(rawLower)) return true;
10864
11008
  }
10865
11009
  return false;
10866
11010
  };
@@ -10883,13 +11027,17 @@ var QueryBuilder = class _QueryBuilder {
10883
11027
  iso(code, includeAdditional = true) {
10884
11028
  const codeClean = code.trim().toLowerCase();
10885
11029
  const predicate = (v) => {
10886
- if (v.primaryLanguage.iso639_3.toLowerCase() === codeClean) {
11030
+ const matchIso = (l) => {
11031
+ if (l.iso639_3.toLowerCase() === codeClean) return true;
11032
+ if (l.standards.iso639_3.part1?.toLowerCase() === codeClean) return true;
11033
+ if (l.standards.bcp47.macrolanguage?.toLowerCase() === codeClean) return true;
11034
+ return false;
11035
+ };
11036
+ if (matchIso(v.primaryLanguage)) {
10887
11037
  return true;
10888
11038
  }
10889
11039
  if (includeAdditional) {
10890
- return v.additionalLanguages.some(
10891
- (al) => al.iso639_3.toLowerCase() === codeClean
10892
- );
11040
+ return v.additionalLanguages.some(matchIso);
10893
11041
  }
10894
11042
  return false;
10895
11043
  };
@@ -10901,10 +11049,13 @@ var QueryBuilder = class _QueryBuilder {
10901
11049
  const predicate = (v) => {
10902
11050
  for (const lang of v.allLanguages) {
10903
11051
  const lTag = lang.bcp47.toLowerCase();
11052
+ const lIso = lang.iso639_3.toLowerCase();
11053
+ const part1 = lang.standards.iso639_3.part1?.toLowerCase();
11054
+ const macro = lang.standards.bcp47.macrolanguage?.toLowerCase();
10904
11055
  if (exact) {
10905
- if (lTag === tagClean) return true;
11056
+ if (lTag === tagClean || lIso === tagClean || part1 === tagClean || macro === tagClean) return true;
10906
11057
  } else {
10907
- if (lTag === tagClean || lTag.startsWith(`${tagClean}-`)) return true;
11058
+ if (lTag === tagClean || lTag.startsWith(`${tagClean}-`) || lIso === tagClean || part1 === tagClean || macro === tagClean) return true;
10908
11059
  }
10909
11060
  }
10910
11061
  return false;
@@ -63950,140 +64101,2500 @@ Best wishes to everybody at home, and I'm looking forward to be surrounded by re
63950
64101
  "2019 International Year of Indigenous Languages"
63951
64102
  ]
63952
64103
  }
63953
- }
63954
- ];
63955
-
63956
- // src/dataset.ts
63957
- var dataset = wikitongues_normalized_default;
63958
-
63959
- // src/client.ts
63960
- var WikitonguesDB = class _WikitonguesDB {
63961
- _videos = [];
63962
- hydrator;
63963
- resolver;
63964
- index;
63965
- searchEngine;
63966
- /**
63967
- * Loads and hydrates every record. Throws HydrationError on the first record whose
63968
- * standards do not resolve against the reference tables (see CLASSIFICATION_RULES.md §3.1.1).
63969
- */
63970
- constructor(options) {
63971
- this.hydrator = new ReferenceHydrator(options?.reference);
63972
- this.resolver = new LanguageResolver();
63973
- const rawRecords = options?.data || options?.records || dataset;
63974
- for (const record of rawRecords) {
63975
- const video = record instanceof Video ? record : Video.fromDict(record, this.hydrator);
63976
- this._videos.push(video);
63977
- for (const lang of video.allLanguages) {
63978
- this.resolver.registerDatasetLanguage(lang);
64104
+ },
64105
+ {
64106
+ id: "MxvdCaFjJZo",
64107
+ url: "https://www.youtube.com/watch?v=MxvdCaFjJZo",
64108
+ duration_seconds: 25,
64109
+ upload_date: "2026-09-18",
64110
+ license: "ALL_RIGHTS_RESERVED",
64111
+ content_type: "oral_history",
64112
+ primary_language: {
64113
+ standards: {
64114
+ iso639_3: "zul",
64115
+ glottocode: "zulu1248",
64116
+ bcp47: "zu"
64117
+ },
64118
+ speaker_claim: null,
64119
+ wikitongues_classification: "Zulu",
64120
+ wikitongues_lineage: null,
64121
+ autonym: "isiZulu"
64122
+ },
64123
+ additional_languages: [],
64124
+ speakers: [
64125
+ {
64126
+ name: "Halala Shezi (Lolly)",
64127
+ role: "native",
64128
+ origin: "South Africa"
63979
64129
  }
64130
+ ],
64131
+ provenance: {
64132
+ country_code: "ZA",
64133
+ country_name: "South Africa",
64134
+ region: null,
64135
+ city: null,
64136
+ recorded_by: null,
64137
+ recording_date: null
64138
+ },
64139
+ transcription: {
64140
+ has_subtitles: false,
64141
+ available_subtitles: [],
64142
+ native_text: null,
64143
+ english_translation: null
64144
+ },
64145
+ raw_metadata: {
64146
+ title: "Lolly speaking Zulu",
64147
+ tags: [
64148
+ "Wikitongues"
64149
+ ]
63980
64150
  }
63981
- this.index = new DatasetIndex(this._videos);
63982
- this.searchEngine = new SearchEngine(this._videos, this.resolver);
63983
- }
63984
- get length() {
63985
- return this._videos.length;
63986
- }
63987
- // -------------------------------------------------------------------------
63988
- // Static Factory Methods
63989
- // -------------------------------------------------------------------------
63990
- /**
63991
- * Create a WikitonguesDB instance directly from an in-memory list of dicts or Videos.
63992
- */
63993
- static fromRecords(records) {
63994
- return new _WikitonguesDB({ records });
63995
- }
63996
- /**
63997
- * Create a WikitonguesDB instance from a JSON string or JSON array.
63998
- */
63999
- static fromJSON(json) {
64000
- const data = typeof json === "string" ? JSON.parse(json) : json;
64001
- return new _WikitonguesDB({ data });
64002
- }
64003
- /**
64004
- * Create a WikitonguesDB instance from a JSON or JSONL file path (Node.js environments).
64005
- */
64006
- static fromFile(filepath) {
64007
- try {
64008
- const fs = __require("fs");
64009
- const content = fs.readFileSync(filepath, "utf-8");
64010
- const trimmed = content.trim();
64011
- let records = [];
64012
- if (trimmed.startsWith("[")) {
64013
- records = JSON.parse(trimmed);
64014
- } else {
64015
- records = trimmed.split("\n").filter((line) => line.trim()).map((line) => JSON.parse(line));
64151
+ },
64152
+ {
64153
+ id: "WgbfWSs0YaY",
64154
+ url: "https://www.youtube.com/watch?v=WgbfWSs0YaY",
64155
+ duration_seconds: 26,
64156
+ upload_date: "2026-09-16",
64157
+ license: "ALL_RIGHTS_RESERVED",
64158
+ content_type: "oral_history",
64159
+ primary_language: {
64160
+ standards: {
64161
+ iso639_3: "zul",
64162
+ glottocode: "zulu1248",
64163
+ bcp47: "zu"
64164
+ },
64165
+ speaker_claim: null,
64166
+ wikitongues_classification: "Zulu",
64167
+ wikitongues_lineage: null,
64168
+ autonym: "isiZulu"
64169
+ },
64170
+ additional_languages: [],
64171
+ speakers: [
64172
+ {
64173
+ name: "Halala Shezi (Lolly)",
64174
+ role: "native",
64175
+ origin: "South Africa"
64016
64176
  }
64017
- return new _WikitonguesDB({ data: records });
64018
- } catch (err) {
64019
- throw new Error(`Failed to load dataset from file '${filepath}': ${err.message}`);
64177
+ ],
64178
+ provenance: {
64179
+ country_code: "ZA",
64180
+ country_name: "South Africa",
64181
+ region: null,
64182
+ city: null,
64183
+ recorded_by: null,
64184
+ recording_date: null
64185
+ },
64186
+ transcription: {
64187
+ has_subtitles: false,
64188
+ available_subtitles: [],
64189
+ native_text: null,
64190
+ english_translation: null
64191
+ },
64192
+ raw_metadata: {
64193
+ title: "Lolly speaking Zulu",
64194
+ tags: [
64195
+ "Wikitongues"
64196
+ ]
64020
64197
  }
64021
- }
64022
- // -------------------------------------------------------------------------
64023
- // Direct Lookups (O(1))
64024
- // -------------------------------------------------------------------------
64025
- /**
64026
- * Lookup a video by its YouTube ID in O(1) time.
64027
- */
64028
- get(videoId) {
64029
- return this.index.byId.get(videoId.trim()) || null;
64030
- }
64031
- /**
64032
- * Lookup videos matching a 3-letter SIL ISO 639-3 code in O(1) time.
64033
- */
64034
- getByIso(code) {
64035
- const list = this.index.byIso.get(code.trim().toLowerCase());
64036
- return new VideoCollection(list || []);
64037
- }
64038
- /**
64039
- * Lookup videos matching a BCP 47 language tag in O(1) time.
64040
- */
64041
- getByBcp47(tag) {
64042
- const list = this.index.byBcp47.get(tag.trim().toLowerCase());
64043
- return new VideoCollection(list || []);
64044
- }
64045
- /**
64046
- * Lookup videos matching a Glottolog code in O(1) time. A language node also matches videos
64047
- * classified under one of its dialect nodes (e.g. `port1283` returns `braz1246` recordings).
64048
- */
64049
- getByGlottocode(glottocode) {
64050
- const list = this.index.byGlottocode.get(glottocode.trim().toLowerCase());
64051
- return new VideoCollection(list || []);
64052
- }
64053
- /**
64054
- * Lookup videos matching an ISO 3166-1 alpha-2 code or country name in O(1) time.
64055
- */
64056
- getByCountry(countryCodeOrName) {
64057
- const c = countryCodeOrName.trim();
64058
- if (c.length === 2 && this.index.byCountryCode.has(c.toUpperCase())) {
64059
- return new VideoCollection(this.index.byCountryCode.get(c.toUpperCase()) || []);
64198
+ },
64199
+ {
64200
+ id: "kF-HQw0BQNk",
64201
+ url: "https://www.youtube.com/watch?v=kF-HQw0BQNk",
64202
+ duration_seconds: 26,
64203
+ upload_date: "2026-09-14",
64204
+ license: "ALL_RIGHTS_RESERVED",
64205
+ content_type: "oral_history",
64206
+ primary_language: {
64207
+ standards: {
64208
+ iso639_3: "quc",
64209
+ glottocode: "kich1262",
64210
+ bcp47: "quc"
64211
+ },
64212
+ speaker_claim: null,
64213
+ wikitongues_classification: "K'iche'",
64214
+ wikitongues_lineage: null,
64215
+ autonym: "Qatzijob'al"
64216
+ },
64217
+ additional_languages: [],
64218
+ speakers: [
64219
+ {
64220
+ name: "Lorenzo",
64221
+ role: "native",
64222
+ origin: "Guatemala"
64223
+ }
64224
+ ],
64225
+ provenance: {
64226
+ country_code: "GT",
64227
+ country_name: "Guatemala",
64228
+ region: null,
64229
+ city: null,
64230
+ recorded_by: null,
64231
+ recording_date: null
64232
+ },
64233
+ transcription: {
64234
+ has_subtitles: false,
64235
+ available_subtitles: [],
64236
+ native_text: null,
64237
+ english_translation: null
64238
+ },
64239
+ raw_metadata: {
64240
+ title: "Lorenzo speaking K'iche",
64241
+ tags: [
64242
+ "Wikitongues"
64243
+ ]
64060
64244
  }
64061
- const normName = normalizeText(c);
64062
- if (this.index.byCountryName.has(normName)) {
64063
- return new VideoCollection(this.index.byCountryName.get(normName) || []);
64245
+ },
64246
+ {
64247
+ id: "mp6Tj1hE55o",
64248
+ url: "https://www.youtube.com/watch?v=mp6Tj1hE55o",
64249
+ duration_seconds: 23,
64250
+ upload_date: "2026-09-11",
64251
+ license: "ALL_RIGHTS_RESERVED",
64252
+ content_type: "oral_history",
64253
+ primary_language: {
64254
+ standards: {
64255
+ iso639_3: "quc",
64256
+ glottocode: "kich1262",
64257
+ bcp47: "quc"
64258
+ },
64259
+ speaker_claim: null,
64260
+ wikitongues_classification: "K'iche'",
64261
+ wikitongues_lineage: null,
64262
+ autonym: "Qatzijob'al"
64263
+ },
64264
+ additional_languages: [],
64265
+ speakers: [
64266
+ {
64267
+ name: "Lorenzo",
64268
+ role: "native",
64269
+ origin: "Guatemala"
64270
+ }
64271
+ ],
64272
+ provenance: {
64273
+ country_code: "GT",
64274
+ country_name: "Guatemala",
64275
+ region: null,
64276
+ city: null,
64277
+ recorded_by: null,
64278
+ recording_date: null
64279
+ },
64280
+ transcription: {
64281
+ has_subtitles: false,
64282
+ available_subtitles: [],
64283
+ native_text: null,
64284
+ english_translation: null
64285
+ },
64286
+ raw_metadata: {
64287
+ title: "Lorenzo speaking K'iche",
64288
+ tags: [
64289
+ "Wikitongues"
64290
+ ]
64064
64291
  }
64065
- return this.query().country(c).all();
64066
- }
64067
- /**
64068
- * Lookup videos for a given speaker name.
64069
- */
64070
- getBySpeaker(name) {
64071
- const normName = normalizeText(name);
64072
- if (this.index.bySpeakerName.has(normName)) {
64073
- return new VideoCollection(this.index.bySpeakerName.get(normName) || []);
64292
+ },
64293
+ {
64294
+ id: "LIcFLAdGTuw",
64295
+ url: "https://www.youtube.com/watch?v=LIcFLAdGTuw",
64296
+ duration_seconds: 38,
64297
+ upload_date: "2026-09-09",
64298
+ license: "ALL_RIGHTS_RESERVED",
64299
+ content_type: "oral_history",
64300
+ primary_language: {
64301
+ standards: {
64302
+ iso639_3: "quc",
64303
+ glottocode: "kich1262",
64304
+ bcp47: "quc"
64305
+ },
64306
+ speaker_claim: null,
64307
+ wikitongues_classification: "K'iche'",
64308
+ wikitongues_lineage: null,
64309
+ autonym: "Qatzijob'al"
64310
+ },
64311
+ additional_languages: [],
64312
+ speakers: [
64313
+ {
64314
+ name: "Lorenzo",
64315
+ role: "native",
64316
+ origin: "Guatemala"
64317
+ }
64318
+ ],
64319
+ provenance: {
64320
+ country_code: "GT",
64321
+ country_name: "Guatemala",
64322
+ region: null,
64323
+ city: null,
64324
+ recorded_by: null,
64325
+ recording_date: null
64326
+ },
64327
+ transcription: {
64328
+ has_subtitles: false,
64329
+ available_subtitles: [],
64330
+ native_text: null,
64331
+ english_translation: null
64332
+ },
64333
+ raw_metadata: {
64334
+ title: "Lorenzo speaking K'iche",
64335
+ tags: [
64336
+ "Wikitongues"
64337
+ ]
64074
64338
  }
64075
- return this.query().speaker({ name }).all();
64076
- }
64077
- // -------------------------------------------------------------------------
64078
- // Smart Lookups & Shortcut Queries
64079
- // -------------------------------------------------------------------------
64080
- /**
64081
- * Intelligent language search: resolves natural names, multilingual aliases ('russe'),
64082
- * ISO 639-3 ('rus'), BCP 47 ('ru'), Glottocodes, autonyms ('Русский'), Wikitongues
64083
- * classifications, Glottolog / ISO names and speaker claims.
64084
- */
64085
- findByLanguage(languageQuery, includeAdditional = true) {
64086
- return this.query().language(languageQuery, includeAdditional).all();
64339
+ },
64340
+ {
64341
+ id: "KK1boSHTmIk",
64342
+ url: "https://www.youtube.com/watch?v=KK1boSHTmIk",
64343
+ duration_seconds: 46,
64344
+ upload_date: "2026-04-23",
64345
+ license: "ALL_RIGHTS_RESERVED",
64346
+ content_type: "oral_history",
64347
+ primary_language: {
64348
+ standards: {
64349
+ iso639_3: "cmn",
64350
+ glottocode: "mand1415",
64351
+ bcp47: "cmn"
64352
+ },
64353
+ speaker_claim: null,
64354
+ wikitongues_classification: "Mandarin",
64355
+ wikitongues_lineage: null,
64356
+ autonym: "\u666E\u901A\u8BDD"
64357
+ },
64358
+ additional_languages: [],
64359
+ speakers: [
64360
+ {
64361
+ name: "Wanyu",
64362
+ role: "native",
64363
+ origin: "China"
64364
+ }
64365
+ ],
64366
+ provenance: {
64367
+ country_code: "CN",
64368
+ country_name: "China",
64369
+ region: null,
64370
+ city: null,
64371
+ recorded_by: null,
64372
+ recording_date: null
64373
+ },
64374
+ transcription: {
64375
+ has_subtitles: false,
64376
+ available_subtitles: [],
64377
+ native_text: null,
64378
+ english_translation: null
64379
+ },
64380
+ raw_metadata: {
64381
+ title: "Wanyu speaking Mandarin",
64382
+ tags: [
64383
+ "Wikitongues",
64384
+ "IYIL2019",
64385
+ "2019 International Year of Indigenous Languages"
64386
+ ]
64387
+ }
64388
+ },
64389
+ {
64390
+ id: "oGz_R-r-HLY",
64391
+ url: "https://www.youtube.com/watch?v=oGz_R-r-HLY",
64392
+ duration_seconds: 58,
64393
+ upload_date: "2026-04-21",
64394
+ license: "ALL_RIGHTS_RESERVED",
64395
+ content_type: "oral_history",
64396
+ primary_language: {
64397
+ standards: {
64398
+ iso639_3: "cmn",
64399
+ glottocode: "mand1415",
64400
+ bcp47: "cmn"
64401
+ },
64402
+ speaker_claim: null,
64403
+ wikitongues_classification: "Mandarin",
64404
+ wikitongues_lineage: null,
64405
+ autonym: "\u666E\u901A\u8BDD"
64406
+ },
64407
+ additional_languages: [],
64408
+ speakers: [
64409
+ {
64410
+ name: "Wanyu",
64411
+ role: "native",
64412
+ origin: "China"
64413
+ }
64414
+ ],
64415
+ provenance: {
64416
+ country_code: "CN",
64417
+ country_name: "China",
64418
+ region: null,
64419
+ city: null,
64420
+ recorded_by: null,
64421
+ recording_date: null
64422
+ },
64423
+ transcription: {
64424
+ has_subtitles: false,
64425
+ available_subtitles: [],
64426
+ native_text: null,
64427
+ english_translation: null
64428
+ },
64429
+ raw_metadata: {
64430
+ title: "Wanyu speaking Mandarin",
64431
+ tags: [
64432
+ "Wikitongues",
64433
+ "IYIL2019",
64434
+ "2019 International Year of Indigenous Languages"
64435
+ ]
64436
+ }
64437
+ },
64438
+ {
64439
+ id: "Tg2w5WKPIOw",
64440
+ url: "https://www.youtube.com/watch?v=Tg2w5WKPIOw",
64441
+ duration_seconds: 39,
64442
+ upload_date: "2026-04-19",
64443
+ license: "ALL_RIGHTS_RESERVED",
64444
+ content_type: "oral_history",
64445
+ primary_language: {
64446
+ standards: {
64447
+ iso639_3: "eng",
64448
+ glottocode: "stan1293",
64449
+ bcp47: "en-BM"
64450
+ },
64451
+ speaker_claim: null,
64452
+ wikitongues_classification: "Bermudian English",
64453
+ wikitongues_lineage: null,
64454
+ autonym: "English"
64455
+ },
64456
+ additional_languages: [],
64457
+ speakers: [
64458
+ {
64459
+ name: "Trey",
64460
+ role: "native",
64461
+ origin: "Bermuda"
64462
+ }
64463
+ ],
64464
+ provenance: {
64465
+ country_code: "BM",
64466
+ country_name: "Bermuda",
64467
+ region: null,
64468
+ city: null,
64469
+ recorded_by: null,
64470
+ recording_date: null
64471
+ },
64472
+ transcription: {
64473
+ has_subtitles: false,
64474
+ available_subtitles: [],
64475
+ native_text: null,
64476
+ english_translation: null
64477
+ },
64478
+ raw_metadata: {
64479
+ title: "Trey speaking Bermudian English",
64480
+ tags: [
64481
+ "Wikitongues",
64482
+ "IYIL2019",
64483
+ "2019 International Year of Indigenous Languages"
64484
+ ]
64485
+ }
64486
+ },
64487
+ {
64488
+ id: "-cbdIMW-cpU",
64489
+ url: "https://www.youtube.com/watch?v=-cbdIMW-cpU",
64490
+ duration_seconds: 33,
64491
+ upload_date: "2026-04-17",
64492
+ license: "ALL_RIGHTS_RESERVED",
64493
+ content_type: "oral_history",
64494
+ primary_language: {
64495
+ standards: {
64496
+ iso639_3: "eng",
64497
+ glottocode: "stan1293",
64498
+ bcp47: "en-BM"
64499
+ },
64500
+ speaker_claim: null,
64501
+ wikitongues_classification: "Bermudian English",
64502
+ wikitongues_lineage: null,
64503
+ autonym: "English"
64504
+ },
64505
+ additional_languages: [],
64506
+ speakers: [
64507
+ {
64508
+ name: "Trey",
64509
+ role: "native",
64510
+ origin: "Bermuda"
64511
+ }
64512
+ ],
64513
+ provenance: {
64514
+ country_code: "BM",
64515
+ country_name: "Bermuda",
64516
+ region: null,
64517
+ city: null,
64518
+ recorded_by: null,
64519
+ recording_date: null
64520
+ },
64521
+ transcription: {
64522
+ has_subtitles: false,
64523
+ available_subtitles: [],
64524
+ native_text: null,
64525
+ english_translation: null
64526
+ },
64527
+ raw_metadata: {
64528
+ title: "Trey speaking Bermudian English",
64529
+ tags: [
64530
+ "Wikitongues",
64531
+ "IYIL2019",
64532
+ "2019 International Year of Indigenous Languages"
64533
+ ]
64534
+ }
64535
+ },
64536
+ {
64537
+ id: "inmozOx5Gos",
64538
+ url: "https://www.youtube.com/watch?v=inmozOx5Gos",
64539
+ duration_seconds: 78,
64540
+ upload_date: "2026-04-15",
64541
+ license: "ALL_RIGHTS_RESERVED",
64542
+ content_type: "oral_history",
64543
+ primary_language: {
64544
+ standards: {
64545
+ iso639_3: "eng",
64546
+ glottocode: "stan1293",
64547
+ bcp47: "en-BM"
64548
+ },
64549
+ speaker_claim: null,
64550
+ wikitongues_classification: "Bermudian English",
64551
+ wikitongues_lineage: null,
64552
+ autonym: "English"
64553
+ },
64554
+ additional_languages: [],
64555
+ speakers: [
64556
+ {
64557
+ name: "Trey",
64558
+ role: "native",
64559
+ origin: "Bermuda"
64560
+ }
64561
+ ],
64562
+ provenance: {
64563
+ country_code: "BM",
64564
+ country_name: "Bermuda",
64565
+ region: null,
64566
+ city: null,
64567
+ recorded_by: null,
64568
+ recording_date: null
64569
+ },
64570
+ transcription: {
64571
+ has_subtitles: false,
64572
+ available_subtitles: [],
64573
+ native_text: null,
64574
+ english_translation: null
64575
+ },
64576
+ raw_metadata: {
64577
+ title: "Trey speaks Bermudian English",
64578
+ tags: [
64579
+ "Wikitongues",
64580
+ "IYIL2019",
64581
+ "2019 International Year of Indigenous Languages"
64582
+ ]
64583
+ }
64584
+ },
64585
+ {
64586
+ id: "2S-P_O-_1N8",
64587
+ url: "https://www.youtube.com/watch?v=2S-P_O-_1N8",
64588
+ duration_seconds: 45,
64589
+ upload_date: "2026-03-22",
64590
+ license: "ALL_RIGHTS_RESERVED",
64591
+ content_type: "oral_history",
64592
+ primary_language: {
64593
+ standards: {
64594
+ iso639_3: "cym",
64595
+ glottocode: "wels1247",
64596
+ bcp47: "cy"
64597
+ },
64598
+ speaker_claim: null,
64599
+ wikitongues_classification: "Welsh",
64600
+ wikitongues_lineage: null,
64601
+ autonym: "Cymraeg"
64602
+ },
64603
+ additional_languages: [],
64604
+ speakers: [
64605
+ {
64606
+ name: "Hywel",
64607
+ role: "native",
64608
+ origin: "Wales"
64609
+ }
64610
+ ],
64611
+ provenance: {
64612
+ country_code: "GB",
64613
+ country_name: "United Kingdom",
64614
+ region: "Wales",
64615
+ city: null,
64616
+ recorded_by: null,
64617
+ recording_date: null
64618
+ },
64619
+ transcription: {
64620
+ has_subtitles: false,
64621
+ available_subtitles: [],
64622
+ native_text: null,
64623
+ english_translation: null
64624
+ },
64625
+ raw_metadata: {
64626
+ title: "Hywel speaking Welsh",
64627
+ tags: []
64628
+ }
64629
+ },
64630
+ {
64631
+ id: "N4q_mynBip0",
64632
+ url: "https://www.youtube.com/watch?v=N4q_mynBip0",
64633
+ duration_seconds: 30,
64634
+ upload_date: "2026-03-20",
64635
+ license: "ALL_RIGHTS_RESERVED",
64636
+ content_type: "oral_history",
64637
+ primary_language: {
64638
+ standards: {
64639
+ iso639_3: "cym",
64640
+ glottocode: "wels1247",
64641
+ bcp47: "cy"
64642
+ },
64643
+ speaker_claim: null,
64644
+ wikitongues_classification: "Welsh",
64645
+ wikitongues_lineage: null,
64646
+ autonym: "Cymraeg"
64647
+ },
64648
+ additional_languages: [],
64649
+ speakers: [
64650
+ {
64651
+ name: "Hywel",
64652
+ role: "native",
64653
+ origin: "Wales"
64654
+ }
64655
+ ],
64656
+ provenance: {
64657
+ country_code: "GB",
64658
+ country_name: "United Kingdom",
64659
+ region: "Wales",
64660
+ city: null,
64661
+ recorded_by: null,
64662
+ recording_date: null
64663
+ },
64664
+ transcription: {
64665
+ has_subtitles: false,
64666
+ available_subtitles: [],
64667
+ native_text: null,
64668
+ english_translation: null
64669
+ },
64670
+ raw_metadata: {
64671
+ title: "Hywel speaking Welsh",
64672
+ tags: []
64673
+ }
64674
+ },
64675
+ {
64676
+ id: "FyWJnhCa-ng",
64677
+ url: "https://www.youtube.com/watch?v=FyWJnhCa-ng",
64678
+ duration_seconds: 25,
64679
+ upload_date: "2026-03-16",
64680
+ license: "ALL_RIGHTS_RESERVED",
64681
+ content_type: "oral_history",
64682
+ primary_language: {
64683
+ standards: {
64684
+ iso639_3: "cym",
64685
+ glottocode: "wels1247",
64686
+ bcp47: "cy"
64687
+ },
64688
+ speaker_claim: null,
64689
+ wikitongues_classification: "Welsh",
64690
+ wikitongues_lineage: null,
64691
+ autonym: "Cymraeg"
64692
+ },
64693
+ additional_languages: [],
64694
+ speakers: [
64695
+ {
64696
+ name: "Hywel",
64697
+ role: "native",
64698
+ origin: "Wales"
64699
+ }
64700
+ ],
64701
+ provenance: {
64702
+ country_code: "GB",
64703
+ country_name: "United Kingdom",
64704
+ region: "Wales",
64705
+ city: null,
64706
+ recorded_by: null,
64707
+ recording_date: null
64708
+ },
64709
+ transcription: {
64710
+ has_subtitles: false,
64711
+ available_subtitles: [],
64712
+ native_text: null,
64713
+ english_translation: null
64714
+ },
64715
+ raw_metadata: {
64716
+ title: "Hywel speaking Welsh",
64717
+ tags: []
64718
+ }
64719
+ },
64720
+ {
64721
+ id: "gB6x-lINQXM",
64722
+ url: "https://www.youtube.com/watch?v=gB6x-lINQXM",
64723
+ duration_seconds: 40,
64724
+ upload_date: "2026-03-14",
64725
+ license: "ALL_RIGHTS_RESERVED",
64726
+ content_type: "oral_history",
64727
+ primary_language: {
64728
+ standards: {
64729
+ iso639_3: "deu",
64730
+ glottocode: "stan1295",
64731
+ bcp47: "de-US"
64732
+ },
64733
+ speaker_claim: null,
64734
+ wikitongues_classification: "Texas German",
64735
+ wikitongues_lineage: null,
64736
+ autonym: "Texasdeutsch"
64737
+ },
64738
+ additional_languages: [],
64739
+ speakers: [
64740
+ {
64741
+ name: "Vernell",
64742
+ role: "native",
64743
+ origin: "Texas"
64744
+ }
64745
+ ],
64746
+ provenance: {
64747
+ country_code: "US",
64748
+ country_name: "United States",
64749
+ region: "Texas",
64750
+ city: "Fredericksburg",
64751
+ recorded_by: null,
64752
+ recording_date: null
64753
+ },
64754
+ transcription: {
64755
+ has_subtitles: false,
64756
+ available_subtitles: [],
64757
+ native_text: null,
64758
+ english_translation: null
64759
+ },
64760
+ raw_metadata: {
64761
+ title: "Vernell speaks Texas German",
64762
+ tags: []
64763
+ }
64764
+ },
64765
+ {
64766
+ id: "3L_akwiAvPI",
64767
+ url: "https://www.youtube.com/watch?v=3L_akwiAvPI",
64768
+ duration_seconds: 29,
64769
+ upload_date: "2026-03-12",
64770
+ license: "ALL_RIGHTS_RESERVED",
64771
+ content_type: "oral_history",
64772
+ primary_language: {
64773
+ standards: {
64774
+ iso639_3: "deu",
64775
+ glottocode: "stan1295",
64776
+ bcp47: "de-US"
64777
+ },
64778
+ speaker_claim: null,
64779
+ wikitongues_classification: "Texas German",
64780
+ wikitongues_lineage: null,
64781
+ autonym: "Texasdeutsch"
64782
+ },
64783
+ additional_languages: [],
64784
+ speakers: [
64785
+ {
64786
+ name: "Vernell",
64787
+ role: "native",
64788
+ origin: "Texas"
64789
+ }
64790
+ ],
64791
+ provenance: {
64792
+ country_code: "US",
64793
+ country_name: "United States",
64794
+ region: "Texas",
64795
+ city: "Fredericksburg",
64796
+ recorded_by: null,
64797
+ recording_date: null
64798
+ },
64799
+ transcription: {
64800
+ has_subtitles: false,
64801
+ available_subtitles: [],
64802
+ native_text: null,
64803
+ english_translation: null
64804
+ },
64805
+ raw_metadata: {
64806
+ title: "Vernell speaks Texas German",
64807
+ tags: []
64808
+ }
64809
+ },
64810
+ {
64811
+ id: "ACkloeSPfFA",
64812
+ url: "https://www.youtube.com/watch?v=ACkloeSPfFA",
64813
+ duration_seconds: 73,
64814
+ upload_date: "2026-03-11",
64815
+ license: "ALL_RIGHTS_RESERVED",
64816
+ content_type: "oral_history",
64817
+ primary_language: {
64818
+ standards: {
64819
+ iso639_3: "frc",
64820
+ glottocode: "caju1236",
64821
+ bcp47: "frc"
64822
+ },
64823
+ speaker_claim: null,
64824
+ wikitongues_classification: "Louisiana French",
64825
+ wikitongues_lineage: null,
64826
+ autonym: "Fran\xE7ais louisianais"
64827
+ },
64828
+ additional_languages: [],
64829
+ speakers: [
64830
+ {
64831
+ name: "Sam Craft",
64832
+ role: "heritage",
64833
+ origin: "Louisiana"
64834
+ }
64835
+ ],
64836
+ provenance: {
64837
+ country_code: "US",
64838
+ country_name: "United States",
64839
+ region: "Louisiana",
64840
+ city: null,
64841
+ recorded_by: null,
64842
+ recording_date: null
64843
+ },
64844
+ transcription: {
64845
+ has_subtitles: false,
64846
+ available_subtitles: [],
64847
+ native_text: null,
64848
+ english_translation: null
64849
+ },
64850
+ raw_metadata: {
64851
+ title: "Sam speaking Louisiana French (Part 3)",
64852
+ tags: []
64853
+ }
64854
+ },
64855
+ {
64856
+ id: "TwwLkiLNkBg",
64857
+ url: "https://www.youtube.com/watch?v=TwwLkiLNkBg",
64858
+ duration_seconds: 58,
64859
+ upload_date: "2026-03-10",
64860
+ license: "ALL_RIGHTS_RESERVED",
64861
+ content_type: "oral_history",
64862
+ primary_language: {
64863
+ standards: {
64864
+ iso639_3: "frc",
64865
+ glottocode: "caju1236",
64866
+ bcp47: "frc"
64867
+ },
64868
+ speaker_claim: null,
64869
+ wikitongues_classification: "Louisiana French",
64870
+ wikitongues_lineage: null,
64871
+ autonym: "Fran\xE7ais louisianais"
64872
+ },
64873
+ additional_languages: [],
64874
+ speakers: [
64875
+ {
64876
+ name: "Sam Craft",
64877
+ role: "heritage",
64878
+ origin: "Louisiana"
64879
+ }
64880
+ ],
64881
+ provenance: {
64882
+ country_code: "US",
64883
+ country_name: "United States",
64884
+ region: "Louisiana",
64885
+ city: null,
64886
+ recorded_by: null,
64887
+ recording_date: null
64888
+ },
64889
+ transcription: {
64890
+ has_subtitles: false,
64891
+ available_subtitles: [],
64892
+ native_text: null,
64893
+ english_translation: null
64894
+ },
64895
+ raw_metadata: {
64896
+ title: "Sam speaking Louisiana French (Part 2)",
64897
+ tags: [
64898
+ "Wikitongues"
64899
+ ]
64900
+ }
64901
+ },
64902
+ {
64903
+ id: "su4ynRj560Q",
64904
+ url: "https://www.youtube.com/watch?v=su4ynRj560Q",
64905
+ duration_seconds: 87,
64906
+ upload_date: "2026-03-10",
64907
+ license: "ALL_RIGHTS_RESERVED",
64908
+ content_type: "oral_history",
64909
+ primary_language: {
64910
+ standards: {
64911
+ iso639_3: "frc",
64912
+ glottocode: "caju1236",
64913
+ bcp47: "frc"
64914
+ },
64915
+ speaker_claim: null,
64916
+ wikitongues_classification: "Louisiana French",
64917
+ wikitongues_lineage: null,
64918
+ autonym: "Fran\xE7ais louisianais"
64919
+ },
64920
+ additional_languages: [],
64921
+ speakers: [
64922
+ {
64923
+ name: "Sam Craft",
64924
+ role: "heritage",
64925
+ origin: "Louisiana"
64926
+ }
64927
+ ],
64928
+ provenance: {
64929
+ country_code: "US",
64930
+ country_name: "United States",
64931
+ region: "Louisiana",
64932
+ city: null,
64933
+ recorded_by: null,
64934
+ recording_date: null
64935
+ },
64936
+ transcription: {
64937
+ has_subtitles: false,
64938
+ available_subtitles: [],
64939
+ native_text: null,
64940
+ english_translation: null
64941
+ },
64942
+ raw_metadata: {
64943
+ title: "Sam speaking Louisiana French (Part 1)",
64944
+ tags: [
64945
+ "Wikitongues",
64946
+ "IYIL2019",
64947
+ "2019 International Year of Indigenous Languages"
64948
+ ]
64949
+ }
64950
+ },
64951
+ {
64952
+ id: "JFC9iGDrDTA",
64953
+ url: "https://www.youtube.com/watch?v=JFC9iGDrDTA",
64954
+ duration_seconds: 103,
64955
+ upload_date: "2026-02-13",
64956
+ license: "ALL_RIGHTS_RESERVED",
64957
+ content_type: "reading_or_song",
64958
+ primary_language: {
64959
+ standards: {
64960
+ iso639_3: "sco",
64961
+ glottocode: "shet1241",
64962
+ bcp47: "sco"
64963
+ },
64964
+ speaker_claim: null,
64965
+ wikitongues_classification: "Shetlandic",
64966
+ wikitongues_lineage: null,
64967
+ autonym: "Shaetlan"
64968
+ },
64969
+ additional_languages: [
64970
+ {
64971
+ standards: {
64972
+ iso639_3: "eng",
64973
+ glottocode: "stan1293",
64974
+ bcp47: "en"
64975
+ },
64976
+ speaker_claim: null,
64977
+ wikitongues_classification: "English",
64978
+ wikitongues_lineage: null,
64979
+ autonym: "English"
64980
+ }
64981
+ ],
64982
+ speakers: [
64983
+ {
64984
+ name: "Christine De Luca",
64985
+ role: "native",
64986
+ origin: "Shetland"
64987
+ }
64988
+ ],
64989
+ provenance: {
64990
+ country_code: "GB",
64991
+ country_name: "United Kingdom",
64992
+ region: "Scotland",
64993
+ city: "Edinburgh",
64994
+ recorded_by: null,
64995
+ recording_date: null
64996
+ },
64997
+ transcription: {
64998
+ has_subtitles: false,
64999
+ available_subtitles: [],
65000
+ native_text: null,
65001
+ english_translation: null
65002
+ },
65003
+ raw_metadata: {
65004
+ title: "Christine reads a poem in English and Shetlandic",
65005
+ tags: [
65006
+ "Wikitongues",
65007
+ "IYIL2019",
65008
+ "2019 International Year of Indigenous Languages"
65009
+ ]
65010
+ }
65011
+ },
65012
+ {
65013
+ id: "p6QqAeuzuGY",
65014
+ url: "https://www.youtube.com/watch?v=p6QqAeuzuGY",
65015
+ duration_seconds: 78,
65016
+ upload_date: "2026-02-11",
65017
+ license: "ALL_RIGHTS_RESERVED",
65018
+ content_type: "oral_history",
65019
+ primary_language: {
65020
+ standards: {
65021
+ iso639_3: "sco",
65022
+ glottocode: "shet1241",
65023
+ bcp47: "sco"
65024
+ },
65025
+ speaker_claim: null,
65026
+ wikitongues_classification: "Shetlandic",
65027
+ wikitongues_lineage: null,
65028
+ autonym: "Shaetlan"
65029
+ },
65030
+ additional_languages: [],
65031
+ speakers: [
65032
+ {
65033
+ name: "Christine De Luca",
65034
+ role: "native",
65035
+ origin: "Shetland"
65036
+ }
65037
+ ],
65038
+ provenance: {
65039
+ country_code: "GB",
65040
+ country_name: "United Kingdom",
65041
+ region: "Scotland",
65042
+ city: "Edinburgh",
65043
+ recorded_by: null,
65044
+ recording_date: null
65045
+ },
65046
+ transcription: {
65047
+ has_subtitles: false,
65048
+ available_subtitles: [],
65049
+ native_text: null,
65050
+ english_translation: null
65051
+ },
65052
+ raw_metadata: {
65053
+ title: "Christine was taught English. Writing led her back to her mother tongue.",
65054
+ tags: [
65055
+ "Wikitongues",
65056
+ "IYIL2019",
65057
+ "2019 International Year of Indigenous Languages"
65058
+ ]
65059
+ }
65060
+ },
65061
+ {
65062
+ id: "FDYuB3KfViY",
65063
+ url: "https://www.youtube.com/watch?v=FDYuB3KfViY",
65064
+ duration_seconds: 65,
65065
+ upload_date: "2026-02-09",
65066
+ license: "ALL_RIGHTS_RESERVED",
65067
+ content_type: "oral_history",
65068
+ primary_language: {
65069
+ standards: {
65070
+ iso639_3: "sco",
65071
+ glottocode: "shet1241",
65072
+ bcp47: "sco"
65073
+ },
65074
+ speaker_claim: null,
65075
+ wikitongues_classification: "Shetlandic",
65076
+ wikitongues_lineage: null,
65077
+ autonym: "Shaetlan"
65078
+ },
65079
+ additional_languages: [],
65080
+ speakers: [
65081
+ {
65082
+ name: "Christine De Luca",
65083
+ role: "native",
65084
+ origin: "Shetland"
65085
+ }
65086
+ ],
65087
+ provenance: {
65088
+ country_code: "GB",
65089
+ country_name: "United Kingdom",
65090
+ region: "Scotland",
65091
+ city: "Edinburgh",
65092
+ recorded_by: null,
65093
+ recording_date: null
65094
+ },
65095
+ transcription: {
65096
+ has_subtitles: false,
65097
+ available_subtitles: [],
65098
+ native_text: null,
65099
+ english_translation: null
65100
+ },
65101
+ raw_metadata: {
65102
+ title: `Edinburgh's Poet Laureate (2014-2017) challenges the idea that Shetlandic is "less than"`,
65103
+ tags: [
65104
+ "Wikitongues",
65105
+ "IYIL2019",
65106
+ "2019 International Year of Indigenous Languages"
65107
+ ]
65108
+ }
65109
+ },
65110
+ {
65111
+ id: "bicQILtQ8is",
65112
+ url: "https://www.youtube.com/watch?v=bicQILtQ8is",
65113
+ duration_seconds: 82,
65114
+ upload_date: "2026-02-06",
65115
+ license: "ALL_RIGHTS_RESERVED",
65116
+ content_type: "reading_or_song",
65117
+ primary_language: {
65118
+ standards: {
65119
+ iso639_3: "gul",
65120
+ glottocode: "gull1241",
65121
+ bcp47: "gul-US"
65122
+ },
65123
+ speaker_claim: null,
65124
+ wikitongues_classification: "Gullah",
65125
+ wikitongues_lineage: null,
65126
+ autonym: "Gullah"
65127
+ },
65128
+ additional_languages: [],
65129
+ speakers: [
65130
+ {
65131
+ name: "Caroline",
65132
+ role: "native",
65133
+ origin: "South Carolina"
65134
+ }
65135
+ ],
65136
+ provenance: {
65137
+ country_code: "US",
65138
+ country_name: "United States",
65139
+ region: "South Carolina",
65140
+ city: "Charleston",
65141
+ recorded_by: null,
65142
+ recording_date: null
65143
+ },
65144
+ transcription: {
65145
+ has_subtitles: false,
65146
+ available_subtitles: [],
65147
+ native_text: null,
65148
+ english_translation: null
65149
+ },
65150
+ raw_metadata: {
65151
+ title: "The New Testament, read in Gullah",
65152
+ tags: [
65153
+ "Wikitongues",
65154
+ "IYIL2019",
65155
+ "2019 International Year of Indigenous Languages"
65156
+ ]
65157
+ }
65158
+ },
65159
+ {
65160
+ id: "ig9niswAGCk",
65161
+ url: "https://www.youtube.com/watch?v=ig9niswAGCk",
65162
+ duration_seconds: 75,
65163
+ upload_date: "2026-02-04",
65164
+ license: "ALL_RIGHTS_RESERVED",
65165
+ content_type: "oral_history",
65166
+ primary_language: {
65167
+ standards: {
65168
+ iso639_3: "gul",
65169
+ glottocode: "gull1241",
65170
+ bcp47: "gul-US"
65171
+ },
65172
+ speaker_claim: null,
65173
+ wikitongues_classification: "Gullah",
65174
+ wikitongues_lineage: null,
65175
+ autonym: "Gullah"
65176
+ },
65177
+ additional_languages: [],
65178
+ speakers: [
65179
+ {
65180
+ name: "Caroline",
65181
+ role: "native",
65182
+ origin: "South Carolina"
65183
+ }
65184
+ ],
65185
+ provenance: {
65186
+ country_code: "US",
65187
+ country_name: "United States",
65188
+ region: "South Carolina",
65189
+ city: "Charleston",
65190
+ recorded_by: null,
65191
+ recording_date: null
65192
+ },
65193
+ transcription: {
65194
+ has_subtitles: false,
65195
+ available_subtitles: [],
65196
+ native_text: null,
65197
+ english_translation: null
65198
+ },
65199
+ raw_metadata: {
65200
+ title: "Caroline used to be corrected for speaking Gullah, now she teaches it.",
65201
+ tags: [
65202
+ "Wikitongues",
65203
+ "IYIL2019",
65204
+ "2019 International Year of Indigenous Languages"
65205
+ ]
65206
+ }
65207
+ },
65208
+ {
65209
+ id: "2Y5aRpz4k30",
65210
+ url: "https://www.youtube.com/watch?v=2Y5aRpz4k30",
65211
+ duration_seconds: 54,
65212
+ upload_date: "2026-02-02",
65213
+ license: "ALL_RIGHTS_RESERVED",
65214
+ content_type: "language_lesson",
65215
+ primary_language: {
65216
+ standards: {
65217
+ iso639_3: "gul",
65218
+ glottocode: "gull1241",
65219
+ bcp47: "gul-US"
65220
+ },
65221
+ speaker_claim: null,
65222
+ wikitongues_classification: "Gullah",
65223
+ wikitongues_lineage: null,
65224
+ autonym: "Gullah"
65225
+ },
65226
+ additional_languages: [],
65227
+ speakers: [
65228
+ {
65229
+ name: "Caroline",
65230
+ role: "native",
65231
+ origin: "South Carolina"
65232
+ }
65233
+ ],
65234
+ provenance: {
65235
+ country_code: "US",
65236
+ country_name: "United States",
65237
+ region: "South Carolina",
65238
+ city: "Charleston",
65239
+ recorded_by: null,
65240
+ recording_date: null
65241
+ },
65242
+ transcription: {
65243
+ has_subtitles: false,
65244
+ available_subtitles: [],
65245
+ native_text: null,
65246
+ english_translation: null
65247
+ },
65248
+ raw_metadata: {
65249
+ title: "Gullah: a living language from the U.S. South",
65250
+ tags: [
65251
+ "Wikitongues",
65252
+ "IYIL2019",
65253
+ "2019 International Year of Indigenous Languages"
65254
+ ]
65255
+ }
65256
+ },
65257
+ {
65258
+ id: "nGeLETLlFXA",
65259
+ url: "https://www.youtube.com/watch?v=nGeLETLlFXA",
65260
+ duration_seconds: 100,
65261
+ upload_date: "2025-12-10",
65262
+ license: "CC-BY-NC-4.0",
65263
+ content_type: "oral_history",
65264
+ primary_language: {
65265
+ standards: {
65266
+ iso639_3: "quh",
65267
+ glottocode: "sout2991",
65268
+ bcp47: "quh"
65269
+ },
65270
+ speaker_claim: null,
65271
+ wikitongues_classification: "South Bolivian Quechua",
65272
+ wikitongues_lineage: "Quechuan",
65273
+ autonym: "Qhichwa"
65274
+ },
65275
+ additional_languages: [],
65276
+ speakers: [
65277
+ {
65278
+ name: "Nicaela",
65279
+ role: "native",
65280
+ origin: "Bolivia"
65281
+ }
65282
+ ],
65283
+ provenance: {
65284
+ country_code: "BO",
65285
+ country_name: "Bolivia",
65286
+ region: null,
65287
+ city: null,
65288
+ recorded_by: null,
65289
+ recording_date: null
65290
+ },
65291
+ transcription: {
65292
+ has_subtitles: false,
65293
+ available_subtitles: [],
65294
+ native_text: null,
65295
+ english_translation: null
65296
+ },
65297
+ raw_metadata: {
65298
+ title: "Nicaela speaking South Bolivian Quechua | Quechuan | Language of the Americas | Wikitongues",
65299
+ tags: [
65300
+ "Wikitongues",
65301
+ "IYIL2019",
65302
+ "2019 International Year of Indigenous Languages"
65303
+ ]
65304
+ }
65305
+ },
65306
+ {
65307
+ id: "0jzN1GREMv0",
65308
+ url: "https://www.youtube.com/watch?v=0jzN1GREMv0",
65309
+ duration_seconds: 48,
65310
+ upload_date: "2025-02-21",
65311
+ license: "CC-BY-NC-4.0",
65312
+ content_type: "language_lesson",
65313
+ primary_language: {
65314
+ standards: {
65315
+ iso639_3: "gle",
65316
+ glottocode: "iris1253",
65317
+ bcp47: "ga"
65318
+ },
65319
+ speaker_claim: null,
65320
+ wikitongues_classification: "Irish",
65321
+ wikitongues_lineage: null,
65322
+ autonym: "Gaeilge"
65323
+ },
65324
+ additional_languages: [],
65325
+ speakers: [
65326
+ {
65327
+ name: "Ahmad",
65328
+ role: "second_language",
65329
+ origin: "Syria"
65330
+ }
65331
+ ],
65332
+ provenance: {
65333
+ country_code: null,
65334
+ country_name: null,
65335
+ region: null,
65336
+ city: null,
65337
+ recorded_by: "Wikitongues",
65338
+ recording_date: null
65339
+ },
65340
+ transcription: {
65341
+ has_subtitles: false,
65342
+ available_subtitles: [],
65343
+ native_text: null,
65344
+ english_translation: null
65345
+ },
65346
+ raw_metadata: {
65347
+ title: "Learn Irish with Ahmad | International Mother Language Day | Wikitongues",
65348
+ tags: [
65349
+ "Wikitongues",
65350
+ "IYIL2019",
65351
+ "2019 International Year of Indigenous Languages"
65352
+ ]
65353
+ }
65354
+ },
65355
+ {
65356
+ id: "7Se_-1IX2j4",
65357
+ url: "https://www.youtube.com/watch?v=7Se_-1IX2j4",
65358
+ duration_seconds: 71,
65359
+ upload_date: "2025-02-21",
65360
+ license: "CC-BY-NC-4.0",
65361
+ content_type: "language_lesson",
65362
+ primary_language: {
65363
+ standards: {
65364
+ iso639_3: "yor",
65365
+ glottocode: "yoru1245",
65366
+ bcp47: "yo"
65367
+ },
65368
+ speaker_claim: null,
65369
+ wikitongues_classification: "Yoruba",
65370
+ wikitongues_lineage: null,
65371
+ autonym: "\xC8d\xE8 Yor\xF9b\xE1"
65372
+ },
65373
+ additional_languages: [],
65374
+ speakers: [
65375
+ {
65376
+ name: "Hanifa",
65377
+ role: "native",
65378
+ origin: "Nigeria"
65379
+ }
65380
+ ],
65381
+ provenance: {
65382
+ country_code: "NG",
65383
+ country_name: "Nigeria",
65384
+ region: null,
65385
+ city: null,
65386
+ recorded_by: null,
65387
+ recording_date: null
65388
+ },
65389
+ transcription: {
65390
+ has_subtitles: false,
65391
+ available_subtitles: [],
65392
+ native_text: null,
65393
+ english_translation: null
65394
+ },
65395
+ raw_metadata: {
65396
+ title: "Yoruba with Hanifa | International Mother Language Day | Wikitongues",
65397
+ tags: [
65398
+ "Wikitongues",
65399
+ "IYIL2019",
65400
+ "2019 International Year of Indigenous Languages"
65401
+ ]
65402
+ }
65403
+ },
65404
+ {
65405
+ id: "rHVxTCtfqrw",
65406
+ url: "https://www.youtube.com/watch?v=rHVxTCtfqrw",
65407
+ duration_seconds: 96,
65408
+ upload_date: "2025-02-21",
65409
+ license: "CC-BY-NC-4.0",
65410
+ content_type: "language_lesson",
65411
+ primary_language: {
65412
+ standards: {
65413
+ iso639_3: "ibo",
65414
+ glottocode: "nucl1417",
65415
+ bcp47: "ig"
65416
+ },
65417
+ speaker_claim: null,
65418
+ wikitongues_classification: "Central Igbo",
65419
+ wikitongues_lineage: null,
65420
+ autonym: "As\u1EE5s\u1EE5 Igbo"
65421
+ },
65422
+ additional_languages: [],
65423
+ speakers: [
65424
+ {
65425
+ name: "Oluchukwu",
65426
+ role: "native",
65427
+ origin: "Nigeria"
65428
+ }
65429
+ ],
65430
+ provenance: {
65431
+ country_code: "NG",
65432
+ country_name: "Nigeria",
65433
+ region: null,
65434
+ city: null,
65435
+ recorded_by: null,
65436
+ recording_date: null
65437
+ },
65438
+ transcription: {
65439
+ has_subtitles: false,
65440
+ available_subtitles: [],
65441
+ native_text: null,
65442
+ english_translation: null
65443
+ },
65444
+ raw_metadata: {
65445
+ title: "Learn Central Igbo with Oluchukwu | International Mother Language Day | Wikitongues",
65446
+ tags: [
65447
+ "Wikitongues",
65448
+ "IYIL2019",
65449
+ "2019 International Year of Indigenous Languages"
65450
+ ]
65451
+ }
65452
+ },
65453
+ {
65454
+ id: "6i0neXrFZfg",
65455
+ url: "https://www.youtube.com/watch?v=6i0neXrFZfg",
65456
+ duration_seconds: 57,
65457
+ upload_date: "2025-02-21",
65458
+ license: "CC-BY-SA-4.0",
65459
+ content_type: "language_lesson",
65460
+ primary_language: {
65461
+ standards: {
65462
+ iso639_3: "kcg",
65463
+ glottocode: "tyap1238",
65464
+ bcp47: "kcg"
65465
+ },
65466
+ speaker_claim: null,
65467
+ wikitongues_classification: "Tyap",
65468
+ wikitongues_lineage: null,
65469
+ autonym: "Tyap"
65470
+ },
65471
+ additional_languages: [],
65472
+ speakers: [
65473
+ {
65474
+ name: "Kambai",
65475
+ role: "native",
65476
+ origin: "Nigeria"
65477
+ }
65478
+ ],
65479
+ provenance: {
65480
+ country_code: "NG",
65481
+ country_name: "Nigeria",
65482
+ region: null,
65483
+ city: null,
65484
+ recorded_by: null,
65485
+ recording_date: null
65486
+ },
65487
+ transcription: {
65488
+ has_subtitles: false,
65489
+ available_subtitles: [],
65490
+ native_text: null,
65491
+ english_translation: null
65492
+ },
65493
+ raw_metadata: {
65494
+ title: "Learn Tyap with Kambai | International Mother Language Day | Wikitongues",
65495
+ tags: [
65496
+ "Wikitongues",
65497
+ "IYIL2019",
65498
+ "2019 International Year of Indigenous Languages"
65499
+ ]
65500
+ }
65501
+ },
65502
+ {
65503
+ id: "B1Yu1EuUyUQ",
65504
+ url: "https://www.youtube.com/watch?v=B1Yu1EuUyUQ",
65505
+ duration_seconds: 42,
65506
+ upload_date: "2025-02-21",
65507
+ license: "CC-BY-SA-4.0",
65508
+ content_type: "language_lesson",
65509
+ primary_language: {
65510
+ standards: {
65511
+ iso639_3: "ind",
65512
+ glottocode: "stin1234",
65513
+ bcp47: "id"
65514
+ },
65515
+ speaker_claim: null,
65516
+ wikitongues_classification: "Bahasa Indonesia",
65517
+ wikitongues_lineage: null,
65518
+ autonym: "Bahasa Indonesia"
65519
+ },
65520
+ additional_languages: [],
65521
+ speakers: [
65522
+ {
65523
+ name: "Neysa",
65524
+ role: "native",
65525
+ origin: "Indonesia"
65526
+ }
65527
+ ],
65528
+ provenance: {
65529
+ country_code: "ID",
65530
+ country_name: "Indonesia",
65531
+ region: null,
65532
+ city: null,
65533
+ recorded_by: null,
65534
+ recording_date: null
65535
+ },
65536
+ transcription: {
65537
+ has_subtitles: false,
65538
+ available_subtitles: [],
65539
+ native_text: null,
65540
+ english_translation: null
65541
+ },
65542
+ raw_metadata: {
65543
+ title: "Learn Bahasa Indonesia with Neysa | International Mother Language Day | Wikitongues",
65544
+ tags: [
65545
+ "Wikitongues",
65546
+ "IYIL2019",
65547
+ "2019 International Year of Indigenous Languages"
65548
+ ]
65549
+ }
65550
+ },
65551
+ {
65552
+ id: "5WKzRb2_Tt0",
65553
+ url: "https://www.youtube.com/watch?v=5WKzRb2_Tt0",
65554
+ duration_seconds: 60,
65555
+ upload_date: "2025-02-21",
65556
+ license: "CC-BY-SA-4.0",
65557
+ content_type: "language_lesson",
65558
+ primary_language: {
65559
+ standards: {
65560
+ iso639_3: "ibo",
65561
+ glottocode: "ower1238",
65562
+ bcp47: "ig"
65563
+ },
65564
+ speaker_claim: null,
65565
+ wikitongues_classification: "Owerri Igbo",
65566
+ wikitongues_lineage: null,
65567
+ autonym: "As\u1EE5s\u1EE5 Igbo"
65568
+ },
65569
+ additional_languages: [],
65570
+ speakers: [
65571
+ {
65572
+ name: "Lucy",
65573
+ role: "native",
65574
+ origin: "Nigeria"
65575
+ }
65576
+ ],
65577
+ provenance: {
65578
+ country_code: "NG",
65579
+ country_name: "Nigeria",
65580
+ region: null,
65581
+ city: null,
65582
+ recorded_by: null,
65583
+ recording_date: null
65584
+ },
65585
+ transcription: {
65586
+ has_subtitles: false,
65587
+ available_subtitles: [],
65588
+ native_text: null,
65589
+ english_translation: null
65590
+ },
65591
+ raw_metadata: {
65592
+ title: "Learn Owerri Igbo with Lucy | International Mother Language Day | Wikitongues",
65593
+ tags: [
65594
+ "Wikitongues",
65595
+ "IYIL2019",
65596
+ "2019 International Year of Indigenous Languages"
65597
+ ]
65598
+ }
65599
+ },
65600
+ {
65601
+ id: "W4CM82mvMv8",
65602
+ url: "https://www.youtube.com/watch?v=W4CM82mvMv8",
65603
+ duration_seconds: 52,
65604
+ upload_date: "2025-02-21",
65605
+ license: "CC-BY-NC-4.0",
65606
+ content_type: "language_lesson",
65607
+ primary_language: {
65608
+ standards: {
65609
+ iso639_3: "fin",
65610
+ glottocode: "finn1318",
65611
+ bcp47: "fi"
65612
+ },
65613
+ speaker_claim: null,
65614
+ wikitongues_classification: "Finnish",
65615
+ wikitongues_lineage: null,
65616
+ autonym: "Suomi"
65617
+ },
65618
+ additional_languages: [],
65619
+ speakers: [
65620
+ {
65621
+ name: "Kristen",
65622
+ role: "second_language",
65623
+ origin: null
65624
+ }
65625
+ ],
65626
+ provenance: {
65627
+ country_code: null,
65628
+ country_name: null,
65629
+ region: null,
65630
+ city: null,
65631
+ recorded_by: "Wikitongues",
65632
+ recording_date: null
65633
+ },
65634
+ transcription: {
65635
+ has_subtitles: false,
65636
+ available_subtitles: [],
65637
+ native_text: null,
65638
+ english_translation: null
65639
+ },
65640
+ raw_metadata: {
65641
+ title: "Learn Finnish with Kristen | International Mother Language Day | Wikitongues",
65642
+ tags: [
65643
+ "Wikitongues",
65644
+ "IYIL2019",
65645
+ "2019 International Year of Indigenous Languages"
65646
+ ]
65647
+ }
65648
+ },
65649
+ {
65650
+ id: "l3F1h1XyXEY",
65651
+ url: "https://www.youtube.com/watch?v=l3F1h1XyXEY",
65652
+ duration_seconds: 60,
65653
+ upload_date: "2025-02-21",
65654
+ license: "CC-BY-SA-4.0",
65655
+ content_type: "language_lesson",
65656
+ primary_language: {
65657
+ standards: {
65658
+ iso639_3: "hau",
65659
+ glottocode: "haus1257",
65660
+ bcp47: "ha"
65661
+ },
65662
+ speaker_claim: null,
65663
+ wikitongues_classification: "Hausa",
65664
+ wikitongues_lineage: null,
65665
+ autonym: "Harshen Hausa"
65666
+ },
65667
+ additional_languages: [],
65668
+ speakers: [
65669
+ {
65670
+ name: "Sadam",
65671
+ role: "native",
65672
+ origin: "Nigeria"
65673
+ }
65674
+ ],
65675
+ provenance: {
65676
+ country_code: "NG",
65677
+ country_name: "Nigeria",
65678
+ region: null,
65679
+ city: null,
65680
+ recorded_by: null,
65681
+ recording_date: null
65682
+ },
65683
+ transcription: {
65684
+ has_subtitles: false,
65685
+ available_subtitles: [],
65686
+ native_text: null,
65687
+ english_translation: null
65688
+ },
65689
+ raw_metadata: {
65690
+ title: "Learn Hausa with Sadam | International Mother Language Day | Wikitongues",
65691
+ tags: [
65692
+ "Wikitongues",
65693
+ "IYIL2019",
65694
+ "2019 International Year of Indigenous Languages"
65695
+ ]
65696
+ }
65697
+ },
65698
+ {
65699
+ id: "yasjvWgLkqU",
65700
+ url: "https://www.youtube.com/watch?v=yasjvWgLkqU",
65701
+ duration_seconds: 60,
65702
+ upload_date: "2024-11-19",
65703
+ license: "ALL_RIGHTS_RESERVED",
65704
+ content_type: "meta",
65705
+ primary_language: {
65706
+ standards: {
65707
+ iso639_3: "eng",
65708
+ glottocode: "stan1293",
65709
+ bcp47: "en"
65710
+ },
65711
+ speaker_claim: null,
65712
+ wikitongues_classification: "English",
65713
+ wikitongues_lineage: null,
65714
+ autonym: "English"
65715
+ },
65716
+ additional_languages: [],
65717
+ speakers: [],
65718
+ provenance: {
65719
+ country_code: null,
65720
+ country_name: null,
65721
+ region: null,
65722
+ city: null,
65723
+ recorded_by: "Wikitongues",
65724
+ recording_date: null
65725
+ },
65726
+ transcription: {
65727
+ has_subtitles: false,
65728
+ available_subtitles: [],
65729
+ native_text: null,
65730
+ english_translation: null
65731
+ },
65732
+ raw_metadata: {
65733
+ title: "Discover N\xFCshu: The secret script created by women, for women!",
65734
+ tags: []
65735
+ }
65736
+ },
65737
+ {
65738
+ id: "5gZ7muELrXw",
65739
+ url: "https://www.youtube.com/watch?v=5gZ7muELrXw",
65740
+ duration_seconds: 1697,
65741
+ upload_date: "2022-11-05",
65742
+ license: "ALL_RIGHTS_RESERVED",
65743
+ content_type: "meta",
65744
+ primary_language: {
65745
+ standards: {
65746
+ iso639_3: "eng",
65747
+ glottocode: "stan1293",
65748
+ bcp47: "en"
65749
+ },
65750
+ speaker_claim: null,
65751
+ wikitongues_classification: "English",
65752
+ wikitongues_lineage: null,
65753
+ autonym: "English"
65754
+ },
65755
+ additional_languages: [],
65756
+ speakers: [],
65757
+ provenance: {
65758
+ country_code: null,
65759
+ country_name: null,
65760
+ region: null,
65761
+ city: null,
65762
+ recorded_by: "Wikitongues",
65763
+ recording_date: null
65764
+ },
65765
+ transcription: {
65766
+ has_subtitles: false,
65767
+ available_subtitles: [],
65768
+ native_text: null,
65769
+ english_translation: null
65770
+ },
65771
+ raw_metadata: {
65772
+ title: "Language Revitalization Accelerator Q&A",
65773
+ tags: []
65774
+ }
65775
+ },
65776
+ {
65777
+ id: "faidns4sK3Q",
65778
+ url: "https://www.youtube.com/watch?v=faidns4sK3Q",
65779
+ duration_seconds: 1611,
65780
+ upload_date: "2022-04-14",
65781
+ license: "ALL_RIGHTS_RESERVED",
65782
+ content_type: "meta",
65783
+ primary_language: {
65784
+ standards: {
65785
+ iso639_3: "eng",
65786
+ glottocode: "stan1293",
65787
+ bcp47: "en"
65788
+ },
65789
+ speaker_claim: null,
65790
+ wikitongues_classification: "English",
65791
+ wikitongues_lineage: null,
65792
+ autonym: "English"
65793
+ },
65794
+ additional_languages: [],
65795
+ speakers: [],
65796
+ provenance: {
65797
+ country_code: null,
65798
+ country_name: null,
65799
+ region: null,
65800
+ city: null,
65801
+ recorded_by: "Wikitongues",
65802
+ recording_date: null
65803
+ },
65804
+ transcription: {
65805
+ has_subtitles: false,
65806
+ available_subtitles: [],
65807
+ native_text: null,
65808
+ english_translation: null
65809
+ },
65810
+ raw_metadata: {
65811
+ title: "Announcing the 2022 grant recipients",
65812
+ tags: []
65813
+ }
65814
+ },
65815
+ {
65816
+ id: "6UctiHFsUrE",
65817
+ url: "https://www.youtube.com/watch?v=6UctiHFsUrE",
65818
+ duration_seconds: 3921,
65819
+ upload_date: "2020-11-11",
65820
+ license: "ALL_RIGHTS_RESERVED",
65821
+ content_type: "meta",
65822
+ primary_language: {
65823
+ standards: {
65824
+ iso639_3: "eng",
65825
+ glottocode: "stan1293",
65826
+ bcp47: "en"
65827
+ },
65828
+ speaker_claim: null,
65829
+ wikitongues_classification: "English",
65830
+ wikitongues_lineage: null,
65831
+ autonym: "English"
65832
+ },
65833
+ additional_languages: [],
65834
+ speakers: [
65835
+ {
65836
+ name: "Cordel Green",
65837
+ role: "fellow_activist",
65838
+ origin: "Jamaica"
65839
+ },
65840
+ {
65841
+ name: "Daniel Sikazwe",
65842
+ role: "fellow_activist",
65843
+ origin: "Zambia"
65844
+ }
65845
+ ],
65846
+ provenance: {
65847
+ country_code: null,
65848
+ country_name: null,
65849
+ region: null,
65850
+ city: null,
65851
+ recorded_by: "Wikitongues",
65852
+ recording_date: null
65853
+ },
65854
+ transcription: {
65855
+ has_subtitles: false,
65856
+ available_subtitles: [],
65857
+ native_text: null,
65858
+ english_translation: null
65859
+ },
65860
+ raw_metadata: {
65861
+ title: "Radio in Language Diversity | Conversations from Jamaica and Zambia | Wikitongues",
65862
+ tags: [
65863
+ "language diversity in media",
65864
+ "radio",
65865
+ "language diversity",
65866
+ "linguistic diversity",
65867
+ "language toolkit",
65868
+ "radio for language",
65869
+ "multilingual radio",
65870
+ "multilingual radio stations",
65871
+ "jamaica",
65872
+ "jamaican radio",
65873
+ "jamaican languages",
65874
+ "zambia",
65875
+ "zambian radio",
65876
+ "zambian languages",
65877
+ "language education",
65878
+ "jamaicain patois lessons",
65879
+ "radio jam upchurch",
65880
+ "speaking on the radio",
65881
+ "all walks of life",
65882
+ "sociolinguistics",
65883
+ "jamaican music",
65884
+ "jamaican patois lessons",
65885
+ "indigenous langauges",
65886
+ "how to promote language",
65887
+ "gullah",
65888
+ "wikitongues"
65889
+ ]
65890
+ }
65891
+ },
65892
+ {
65893
+ id: "iDPp2yORw94",
65894
+ url: "https://www.youtube.com/watch?v=iDPp2yORw94",
65895
+ duration_seconds: 4151,
65896
+ upload_date: "2020-10-11",
65897
+ license: "ALL_RIGHTS_RESERVED",
65898
+ content_type: "meta",
65899
+ primary_language: {
65900
+ standards: {
65901
+ iso639_3: "eng",
65902
+ glottocode: "stan1293",
65903
+ bcp47: "en"
65904
+ },
65905
+ speaker_claim: null,
65906
+ wikitongues_classification: "English",
65907
+ wikitongues_lineage: null,
65908
+ autonym: "English"
65909
+ },
65910
+ additional_languages: [],
65911
+ speakers: [
65912
+ {
65913
+ name: "Ryan Andrew Milov-Cordoba (Call Me C\xF3rdoba)",
65914
+ role: "fellow_activist",
65915
+ origin: "United States"
65916
+ }
65917
+ ],
65918
+ provenance: {
65919
+ country_code: null,
65920
+ country_name: null,
65921
+ region: null,
65922
+ city: null,
65923
+ recorded_by: "Wikitongues",
65924
+ recording_date: null
65925
+ },
65926
+ transcription: {
65927
+ has_subtitles: false,
65928
+ available_subtitles: [],
65929
+ native_text: null,
65930
+ english_translation: null
65931
+ },
65932
+ raw_metadata: {
65933
+ title: "Music in Language Diversity | Conversation and music with Call Me C\xF3rdoba | Wikitongues",
65934
+ tags: [
65935
+ "music in language diversity",
65936
+ "language diversity in education",
65937
+ "linguistic diversity",
65938
+ "indigenous peoples day",
65939
+ "call me cordoba",
65940
+ "arabic contemporary music",
65941
+ "Save my language",
65942
+ "global issues",
65943
+ "language learning",
65944
+ "language revitalization",
65945
+ "language preservation",
65946
+ "endangered languages",
65947
+ "endangered languages project",
65948
+ "Living Tongues Institute",
65949
+ "Wikitongues",
65950
+ "David Harrison",
65951
+ "Mother tongue",
65952
+ "Linguistics",
65953
+ "Indigenous languages",
65954
+ "arabic language learning",
65955
+ "\u0627\u0644\u062A\u0646\u0648\u0639 \u0627\u0644\u0644\u063A\u0648\u064A",
65956
+ "bahau"
65957
+ ]
65958
+ }
65959
+ },
65960
+ {
65961
+ id: "HaYhISDoVyM",
65962
+ url: "https://www.youtube.com/watch?v=HaYhISDoVyM",
65963
+ duration_seconds: 1576,
65964
+ upload_date: "2020-09-28",
65965
+ license: "ALL_RIGHTS_RESERVED",
65966
+ content_type: "meta",
65967
+ primary_language: {
65968
+ standards: {
65969
+ iso639_3: "eng",
65970
+ glottocode: "stan1293",
65971
+ bcp47: "en"
65972
+ },
65973
+ speaker_claim: null,
65974
+ wikitongues_classification: "English",
65975
+ wikitongues_lineage: null,
65976
+ autonym: "English"
65977
+ },
65978
+ additional_languages: [],
65979
+ speakers: [],
65980
+ provenance: {
65981
+ country_code: null,
65982
+ country_name: null,
65983
+ region: null,
65984
+ city: null,
65985
+ recorded_by: "Wikitongues",
65986
+ recording_date: null
65987
+ },
65988
+ transcription: {
65989
+ has_subtitles: false,
65990
+ available_subtitles: [],
65991
+ native_text: null,
65992
+ english_translation: null
65993
+ },
65994
+ raw_metadata: {
65995
+ title: "Wikitongues Updates, September 2020",
65996
+ tags: []
65997
+ }
65998
+ },
65999
+ {
66000
+ id: "2UmHjJvPGec",
66001
+ url: "https://www.youtube.com/watch?v=2UmHjJvPGec",
66002
+ duration_seconds: 10161,
66003
+ upload_date: "2020-08-02",
66004
+ license: "ALL_RIGHTS_RESERVED",
66005
+ content_type: "meta",
66006
+ primary_language: {
66007
+ standards: {
66008
+ iso639_3: "eng",
66009
+ glottocode: "stan1293",
66010
+ bcp47: "en"
66011
+ },
66012
+ speaker_claim: null,
66013
+ wikitongues_classification: "English",
66014
+ wikitongues_lineage: null,
66015
+ autonym: "English"
66016
+ },
66017
+ additional_languages: [],
66018
+ speakers: [],
66019
+ provenance: {
66020
+ country_code: null,
66021
+ country_name: null,
66022
+ region: null,
66023
+ city: null,
66024
+ recorded_by: "Wikitongues",
66025
+ recording_date: null
66026
+ },
66027
+ transcription: {
66028
+ has_subtitles: false,
66029
+ available_subtitles: [],
66030
+ native_text: null,
66031
+ english_translation: null
66032
+ },
66033
+ raw_metadata: {
66034
+ title: "Wikitongues Virtual Birthday Party",
66035
+ tags: [
66036
+ "birthday party",
66037
+ "birthday party coronavirus",
66038
+ "zoom university",
66039
+ "virtual birthday party",
66040
+ "Wikitongues",
66041
+ "wikitongues birthday party",
66042
+ "virtual birthday party ideas",
66043
+ "wikitongues virtual birthday party",
66044
+ "international coronavirus response",
66045
+ "how to have fun in pandemic",
66046
+ "everything is online now",
66047
+ "annual language celebration",
66048
+ "good things that came from coronavirus",
66049
+ "how to have fun when the world is ending",
66050
+ "New York",
66051
+ "eastern europe",
66052
+ "jakarta",
66053
+ "sociolinguistics",
66054
+ "language variation and change",
66055
+ "gullah"
66056
+ ]
66057
+ }
66058
+ },
66059
+ {
66060
+ id: "1UutaDfzaqc",
66061
+ url: "https://www.youtube.com/watch?v=1UutaDfzaqc",
66062
+ duration_seconds: 3906,
66063
+ upload_date: "2020-06-26",
66064
+ license: "ALL_RIGHTS_RESERVED",
66065
+ content_type: "meta",
66066
+ primary_language: {
66067
+ standards: {
66068
+ iso639_3: "eng",
66069
+ glottocode: "stan1293",
66070
+ bcp47: "en"
66071
+ },
66072
+ speaker_claim: null,
66073
+ wikitongues_classification: "English",
66074
+ wikitongues_lineage: null,
66075
+ autonym: "English"
66076
+ },
66077
+ additional_languages: [],
66078
+ speakers: [],
66079
+ provenance: {
66080
+ country_code: null,
66081
+ country_name: null,
66082
+ region: null,
66083
+ city: null,
66084
+ recorded_by: "Wikitongues",
66085
+ recording_date: null
66086
+ },
66087
+ transcription: {
66088
+ has_subtitles: false,
66089
+ available_subtitles: [],
66090
+ native_text: null,
66091
+ english_translation: null
66092
+ },
66093
+ raw_metadata: {
66094
+ title: "How do I save my language? Introducing the Language Sustainability Toolkit",
66095
+ tags: [
66096
+ "Save my language",
66097
+ "My language",
66098
+ "global issues",
66099
+ "Language",
66100
+ "language learning",
66101
+ "language learning apps",
66102
+ "language revitalization canada",
66103
+ "hawaiian language revitalization",
66104
+ "native american language revitalization",
66105
+ "ojibwe language revitalization",
66106
+ "language revitalization",
66107
+ "language preservation",
66108
+ "endangered languages",
66109
+ "endangered languages project",
66110
+ "Living Tongues Institute",
66111
+ "Wikitongues",
66112
+ "David Harrison",
66113
+ "Anna Luisa Daigneault",
66114
+ "Mother tongue",
66115
+ "Linguistics",
66116
+ "Indigenous languages",
66117
+ "Sustainability"
66118
+ ]
66119
+ }
66120
+ },
66121
+ {
66122
+ id: "pEU_EC7OcdE",
66123
+ url: "https://www.youtube.com/watch?v=pEU_EC7OcdE",
66124
+ duration_seconds: 3878,
66125
+ upload_date: "2020-06-24",
66126
+ license: "ALL_RIGHTS_RESERVED",
66127
+ content_type: "meta",
66128
+ primary_language: {
66129
+ standards: {
66130
+ iso639_3: "eng",
66131
+ glottocode: "stan1293",
66132
+ bcp47: "en"
66133
+ },
66134
+ speaker_claim: null,
66135
+ wikitongues_classification: "English",
66136
+ wikitongues_lineage: null,
66137
+ autonym: "English"
66138
+ },
66139
+ additional_languages: [],
66140
+ speakers: [
66141
+ {
66142
+ name: "Tim Brooks",
66143
+ role: "fellow_activist",
66144
+ origin: "United States"
66145
+ }
66146
+ ],
66147
+ provenance: {
66148
+ country_code: null,
66149
+ country_name: null,
66150
+ region: null,
66151
+ city: null,
66152
+ recorded_by: "Wikitongues",
66153
+ recording_date: null
66154
+ },
66155
+ transcription: {
66156
+ has_subtitles: false,
66157
+ available_subtitles: [],
66158
+ native_text: null,
66159
+ english_translation: null
66160
+ },
66161
+ raw_metadata: {
66162
+ title: "Tim Brooks from Endangered Alphabets | FIRST-EVER Wikitongues live-stream!",
66163
+ tags: [
66164
+ "Tim Brooks",
66165
+ "Endangered Alphabets",
66166
+ "Alphabets",
66167
+ "alphabet in spanish",
66168
+ "writing systems",
66169
+ "Writing systems of the world",
66170
+ "writing systems in europe",
66171
+ "Wikitongues",
66172
+ "sociolinguistics",
66173
+ "balinese language",
66174
+ "languages of the philippines",
66175
+ "Easter Island",
66176
+ "Rapa Nui",
66177
+ "rongorongo script",
66178
+ "rongorongo language",
66179
+ "semitic abjads alphabet",
66180
+ "Hebrew alphabet",
66181
+ "samaritans",
66182
+ "israel and palestine",
66183
+ "israel and philippines relationship",
66184
+ "Louisiana French",
66185
+ "english conversation",
66186
+ "british accent vs american accent",
66187
+ "Mongolian"
66188
+ ]
66189
+ }
66190
+ },
66191
+ {
66192
+ id: "pd0YZ9o22QI",
66193
+ url: "https://www.youtube.com/watch?v=pd0YZ9o22QI",
66194
+ duration_seconds: 33,
66195
+ upload_date: "2020-02-27",
66196
+ license: "CC-BY-NC-4.0",
66197
+ content_type: "oral_history",
66198
+ primary_language: {
66199
+ standards: {
66200
+ iso639_3: "kls",
66201
+ glottocode: "kala1372",
66202
+ bcp47: "kls"
66203
+ },
66204
+ speaker_claim: null,
66205
+ wikitongues_classification: "Kalasha",
66206
+ wikitongues_lineage: null,
66207
+ autonym: "Kalashamondr"
66208
+ },
66209
+ additional_languages: [],
66210
+ speakers: [
66211
+ {
66212
+ name: "Najib",
66213
+ role: "native",
66214
+ origin: "Pakistan"
66215
+ }
66216
+ ],
66217
+ provenance: {
66218
+ country_code: "PK",
66219
+ country_name: "Pakistan",
66220
+ region: "Khyber Pakhtunkhwa",
66221
+ city: "Chitral",
66222
+ recorded_by: "Rizwan Hussain",
66223
+ recording_date: null
66224
+ },
66225
+ transcription: {
66226
+ has_subtitles: false,
66227
+ available_subtitles: [],
66228
+ native_text: null,
66229
+ english_translation: null
66230
+ },
66231
+ raw_metadata: {
66232
+ title: "WIKITONGUES: Najib speaking Kalasha",
66233
+ tags: [
66234
+ "Wikitongues",
66235
+ "IYIL2019",
66236
+ "2019 International Year of Indigenous Languages",
66237
+ "Kalasha language",
66238
+ "Kalasha-mun",
66239
+ "Pakistan",
66240
+ "Pakistani people",
66241
+ "South Asian people",
66242
+ "Dardic languages"
66243
+ ]
66244
+ }
66245
+ },
66246
+ {
66247
+ id: "gUWkNeLUZsg",
66248
+ url: "https://www.youtube.com/watch?v=gUWkNeLUZsg",
66249
+ duration_seconds: 30,
66250
+ upload_date: "2020-02-16",
66251
+ license: "CC-BY-SA-4.0",
66252
+ content_type: "oral_history",
66253
+ primary_language: {
66254
+ standards: {
66255
+ iso639_3: "mlt",
66256
+ glottocode: "malt1254",
66257
+ bcp47: "mt"
66258
+ },
66259
+ speaker_claim: null,
66260
+ wikitongues_classification: "Maltese",
66261
+ wikitongues_lineage: null,
66262
+ autonym: "Malti"
66263
+ },
66264
+ additional_languages: [],
66265
+ speakers: [
66266
+ {
66267
+ name: "Keith",
66268
+ role: "native",
66269
+ origin: "Malta"
66270
+ }
66271
+ ],
66272
+ provenance: {
66273
+ country_code: "MT",
66274
+ country_name: "Malta",
66275
+ region: null,
66276
+ city: "Valletta",
66277
+ recorded_by: "Irena Dahl",
66278
+ recording_date: null
66279
+ },
66280
+ transcription: {
66281
+ has_subtitles: false,
66282
+ available_subtitles: [],
66283
+ native_text: null,
66284
+ english_translation: null
66285
+ },
66286
+ raw_metadata: {
66287
+ title: "WIKITONGUES: Keith speaking Maltese",
66288
+ tags: [
66289
+ "Wikitongues",
66290
+ "IYIL2019",
66291
+ "2019 International Year of Indigenous Languages",
66292
+ "Maltese",
66293
+ "Maltese language",
66294
+ "Maltese people",
66295
+ "Malta",
66296
+ "Semitic languages",
66297
+ "Arabic dialects",
66298
+ "European languages"
66299
+ ]
66300
+ }
66301
+ },
66302
+ {
66303
+ id: "gE11A0fmkR0",
66304
+ url: "https://www.youtube.com/watch?v=gE11A0fmkR0",
66305
+ duration_seconds: 21,
66306
+ upload_date: "2019-08-30",
66307
+ license: "CC-BY-SA-4.0",
66308
+ content_type: "oral_history",
66309
+ primary_language: {
66310
+ standards: {
66311
+ iso639_3: "alt",
66312
+ glottocode: "sout2694",
66313
+ bcp47: "alt"
66314
+ },
66315
+ speaker_claim: null,
66316
+ wikitongues_classification: "Altai",
66317
+ wikitongues_lineage: null,
66318
+ autonym: "\u0410\u043B\u0442\u0430\u0439 \u0442\u0438\u043B"
66319
+ },
66320
+ additional_languages: [],
66321
+ speakers: [
66322
+ {
66323
+ name: "Dmitry",
66324
+ role: "native",
66325
+ origin: "Russia"
66326
+ }
66327
+ ],
66328
+ provenance: {
66329
+ country_code: "RU",
66330
+ country_name: "Russia",
66331
+ region: "Altai Republic",
66332
+ city: null,
66333
+ recorded_by: "Archyn Termishev",
66334
+ recording_date: null
66335
+ },
66336
+ transcription: {
66337
+ has_subtitles: false,
66338
+ available_subtitles: [],
66339
+ native_text: null,
66340
+ english_translation: null
66341
+ },
66342
+ raw_metadata: {
66343
+ title: "WIKITONGUES: Dmitry speaking Altai",
66344
+ tags: [
66345
+ "Wikitongues",
66346
+ "IYIL2019",
66347
+ "2019 International Year of Indigenous Languages"
66348
+ ]
66349
+ }
66350
+ },
66351
+ {
66352
+ id: "TotFWZLrQAY",
66353
+ url: "https://www.youtube.com/watch?v=TotFWZLrQAY",
66354
+ duration_seconds: 55,
66355
+ upload_date: "2014-08-07",
66356
+ license: "ALL_RIGHTS_RESERVED",
66357
+ content_type: "oral_history",
66358
+ primary_language: {
66359
+ standards: {
66360
+ iso639_3: "epo",
66361
+ glottocode: "espe1235",
66362
+ bcp47: "eo"
66363
+ },
66364
+ speaker_claim: null,
66365
+ wikitongues_classification: "Esperanto",
66366
+ wikitongues_lineage: null,
66367
+ autonym: "Esperanto"
66368
+ },
66369
+ additional_languages: [],
66370
+ speakers: [
66371
+ {
66372
+ name: "Hilliard (Hiljardo)",
66373
+ role: "second_language",
66374
+ origin: "United States"
66375
+ }
66376
+ ],
66377
+ provenance: {
66378
+ country_code: "US",
66379
+ country_name: "United States",
66380
+ region: "Connecticut",
66381
+ city: null,
66382
+ recorded_by: null,
66383
+ recording_date: null
66384
+ },
66385
+ transcription: {
66386
+ has_subtitles: false,
66387
+ available_subtitles: [],
66388
+ native_text: "Saluton. Mia nomo estas Hiljardo, en Esperanto, kaj mi parolis Esperanton dum du monatoj. Mi havas dek kvar de jaroj. Mi lernis Esperanton por lerni pri aliaj kulturoj kaj aliaj popoloj. Esperanto helpas min multe. Mi ofte konversacias kun homoj de la mondo. Mi lo\u011Das en Konektikuto en Usono. Mi amas lerni pri lingvoj kaj historio. Mi anka\u016D parolas anglan lingvon, francan lingvon, rusan lingvon, nederlandan lingvon, kaj afrikanson. Mi amas lerni novajn lingvojn , \u0109ar \u011Di estas sana, kaj \u011Di estas bona ekzerco por la cerbo. Dankon por rigardi.",
66389
+ english_translation: 'Hi. Mi name is "Hiljardo" [Hilliard], in Esperanto, and I have spoken Esperanto for two months. I am fourteen years old. I learned Esperanto to learn about foreign cultures and foreign peoples. Esperanto helps me a lot. I often converse with people from the world. I live in Connecticut in the United States of America. I like to learn about languages and history. I also speak English, French, Russian, Dutch, and Afrikaans. I like to learn new languages, because it is healthy, and it is a good exercise for the brain. Thanks for watching.'
66390
+ },
66391
+ raw_metadata: {
66392
+ title: "WIKITONGUES: Hiljiardo speaking Esperanto",
66393
+ tags: [
66394
+ "Wikitongues",
66395
+ "Esperanto Language (Human Language)"
66396
+ ]
66397
+ }
66398
+ },
66399
+ {
66400
+ id: "--DnU743JLU",
66401
+ url: "https://www.youtube.com/watch?v=--DnU743JLU",
66402
+ duration_seconds: 40,
66403
+ upload_date: "2013-02-18",
66404
+ license: "ALL_RIGHTS_RESERVED",
66405
+ content_type: "oral_history",
66406
+ primary_language: {
66407
+ standards: {
66408
+ iso639_3: "nan",
66409
+ glottocode: "minn1241",
66410
+ bcp47: "nan-TW"
66411
+ },
66412
+ speaker_claim: null,
66413
+ wikitongues_classification: "Taiwanese Min Nan",
66414
+ wikitongues_lineage: null,
66415
+ autonym: "\u81FA\u7063\u8A71"
66416
+ },
66417
+ additional_languages: [],
66418
+ speakers: [
66419
+ {
66420
+ name: "Liang Cheng Chia (Sunny)",
66421
+ role: "native",
66422
+ origin: "Taiwan"
66423
+ }
66424
+ ],
66425
+ provenance: {
66426
+ country_code: "TW",
66427
+ country_name: "Taiwan",
66428
+ region: null,
66429
+ city: "Kaohsiung",
66430
+ recorded_by: null,
66431
+ recording_date: null
66432
+ },
66433
+ transcription: {
66434
+ has_subtitles: false,
66435
+ available_subtitles: [],
66436
+ native_text: null,
66437
+ english_translation: null
66438
+ },
66439
+ raw_metadata: {
66440
+ title: "WIKITONGUES: Sunny speaking Taiwanese Min Nan",
66441
+ tags: [
66442
+ "Taiwanese",
66443
+ "Hokkien",
66444
+ "Taiwan",
66445
+ "nation",
66446
+ "country",
66447
+ "Vietnam",
66448
+ "USA",
66449
+ "languages of Taiwan",
66450
+ "Min Nan",
66451
+ "Chinese"
66452
+ ]
66453
+ }
66454
+ }
66455
+ ];
66456
+
66457
+ // src/dataset.ts
66458
+ var dataset = wikitongues_normalized_default;
66459
+
66460
+ // src/client.ts
66461
+ var WikitonguesDB = class _WikitonguesDB {
66462
+ _videos = [];
66463
+ hydrator;
66464
+ resolver;
66465
+ index;
66466
+ searchEngine;
66467
+ /**
66468
+ * Loads and hydrates every record. Throws HydrationError on the first record whose
66469
+ * standards do not resolve against the reference tables (see CLASSIFICATION_RULES.md §3.1.1).
66470
+ */
66471
+ constructor(options) {
66472
+ this.hydrator = new ReferenceHydrator(options?.reference);
66473
+ this.resolver = new LanguageResolver();
66474
+ const rawRecords = options?.data || options?.records || dataset;
66475
+ for (const record of rawRecords) {
66476
+ const video = record instanceof Video ? record : Video.fromDict(record, this.hydrator);
66477
+ this._videos.push(video);
66478
+ for (const lang of video.allLanguages) {
66479
+ this.resolver.registerDatasetLanguage(lang);
66480
+ }
66481
+ }
66482
+ this.index = new DatasetIndex(this._videos);
66483
+ this.searchEngine = new SearchEngine(this._videos, this.resolver);
66484
+ }
66485
+ get length() {
66486
+ return this._videos.length;
66487
+ }
66488
+ // -------------------------------------------------------------------------
66489
+ // Static Factory Methods
66490
+ // -------------------------------------------------------------------------
66491
+ /**
66492
+ * Create a WikitonguesDB instance directly from an in-memory list of dicts or Videos.
66493
+ */
66494
+ static fromRecords(records) {
66495
+ return new _WikitonguesDB({ records });
66496
+ }
66497
+ /**
66498
+ * Create a WikitonguesDB instance from a JSON string or JSON array.
66499
+ */
66500
+ static fromJSON(json) {
66501
+ const data = typeof json === "string" ? JSON.parse(json) : json;
66502
+ return new _WikitonguesDB({ data });
66503
+ }
66504
+ /**
66505
+ * Create a WikitonguesDB instance from a JSON or JSONL file path (Node.js environments).
66506
+ */
66507
+ static fromFile(filepath) {
66508
+ try {
66509
+ const fs = __require("fs");
66510
+ const content = fs.readFileSync(filepath, "utf-8");
66511
+ const trimmed = content.trim();
66512
+ let records = [];
66513
+ if (trimmed.startsWith("[")) {
66514
+ records = JSON.parse(trimmed);
66515
+ } else {
66516
+ records = trimmed.split("\n").filter((line) => line.trim()).map((line) => JSON.parse(line));
66517
+ }
66518
+ return new _WikitonguesDB({ data: records });
66519
+ } catch (err) {
66520
+ throw new Error(`Failed to load dataset from file '${filepath}': ${err.message}`);
66521
+ }
66522
+ }
66523
+ // -------------------------------------------------------------------------
66524
+ // Direct Lookups (O(1))
66525
+ // -------------------------------------------------------------------------
66526
+ /**
66527
+ * Lookup a video by its YouTube ID in O(1) time.
66528
+ */
66529
+ get(videoId) {
66530
+ return this.index.byId.get(videoId.trim()) || null;
66531
+ }
66532
+ /**
66533
+ * Lookup videos matching a 3-letter SIL ISO 639-3 code in O(1) time.
66534
+ */
66535
+ getByIso(code) {
66536
+ const list = this.index.byIso.get(code.trim().toLowerCase());
66537
+ return new VideoCollection(list || []);
66538
+ }
66539
+ /**
66540
+ * Lookup videos matching a BCP 47 language tag in O(1) time.
66541
+ */
66542
+ getByBcp47(tag) {
66543
+ const list = this.index.byBcp47.get(tag.trim().toLowerCase());
66544
+ return new VideoCollection(list || []);
66545
+ }
66546
+ /**
66547
+ * Lookup videos matching a Glottolog code in O(1) time. A language node also matches videos
66548
+ * classified under one of its dialect nodes (e.g. `port1283` returns `braz1246` recordings).
66549
+ */
66550
+ getByGlottocode(glottocode) {
66551
+ const list = this.index.byGlottocode.get(glottocode.trim().toLowerCase());
66552
+ return new VideoCollection(list || []);
66553
+ }
66554
+ /**
66555
+ * Lookup videos matching an ISO 3166-1 alpha-2 code or country name in O(1) time.
66556
+ */
66557
+ getByCountry(countryCodeOrName) {
66558
+ const c = countryCodeOrName.trim();
66559
+ if (c.length === 2 && this.index.byCountryCode.has(c.toUpperCase())) {
66560
+ return new VideoCollection(this.index.byCountryCode.get(c.toUpperCase()) || []);
66561
+ }
66562
+ const normName = normalizeText(c);
66563
+ if (this.index.byCountryName.has(normName)) {
66564
+ return new VideoCollection(this.index.byCountryName.get(normName) || []);
66565
+ }
66566
+ return this.query().country(c).all();
66567
+ }
66568
+ /**
66569
+ * Lookup videos for a given speaker name.
66570
+ */
66571
+ getBySpeaker(name) {
66572
+ const normName = normalizeText(name);
66573
+ if (this.index.bySpeakerName.has(normName)) {
66574
+ return new VideoCollection(this.index.bySpeakerName.get(normName) || []);
66575
+ }
66576
+ return this.query().speaker({ name }).all();
66577
+ }
66578
+ // -------------------------------------------------------------------------
66579
+ // Smart Lookups & Shortcut Queries
66580
+ // -------------------------------------------------------------------------
66581
+ /**
66582
+ * Intelligent language search: resolves natural names, multilingual aliases ('russe'),
66583
+ * ISO 639-3 ('rus'), BCP 47 ('ru'), Glottocodes, autonyms ('Русский'), Wikitongues
66584
+ * classifications, Glottolog / ISO names and speaker claims.
66585
+ */
66586
+ findByLanguage(languageQuery, includeAdditional = true) {
66587
+ return this.query().language(languageQuery, includeAdditional).all();
66588
+ }
66589
+ /**
66590
+ * Check if the database contains any video matching the language query
66591
+ * (by ISO 639-3, ISO 639-1, BCP 47, macrolanguage, or name).
66592
+ */
66593
+ hasLanguage(query) {
66594
+ const qClean = query.trim().toLowerCase();
66595
+ if (this.index.byIso.has(qClean)) return true;
66596
+ if (this.index.byBcp47.has(qClean)) return true;
66597
+ return this.findByLanguage(query).length > 0;
64087
66598
  }
64088
66599
  /**
64089
66600
  * Shortcut method to filter videos by common criteria.