ifct2017 2.0.14 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/LICENSE +661 -21
  2. package/README.md +1019 -71
  3. package/abbreviations/index.csv +78 -0
  4. package/abbreviations/index.d.ts +39 -0
  5. package/abbreviations/index.js +103 -0
  6. package/abbreviations/index.txt +12 -0
  7. package/about/build.ts +31 -0
  8. package/about/index.d.ts +47 -0
  9. package/about/index.js +110 -0
  10. package/about/index.txt +174 -0
  11. package/build.ts +115 -0
  12. package/carbohydrates/index.csv +8 -0
  13. package/carbohydrates/index.d.ts +42 -0
  14. package/carbohydrates/index.js +112 -0
  15. package/carbohydrates/index.txt +14 -0
  16. package/codes/index.csv +2904 -0
  17. package/codes/index.d.ts +36 -0
  18. package/codes/index.js +102 -0
  19. package/codes/index.txt +12 -0
  20. package/columndescriptions/build.ts +22 -0
  21. package/columndescriptions/index.csv +215 -0
  22. package/columndescriptions/index.d.ts +44 -0
  23. package/columndescriptions/index.js +119 -0
  24. package/columns/build.ts +23 -0
  25. package/columns/index.csv +215 -0
  26. package/columns/index.d.ts +39 -0
  27. package/columns/index.js +111 -0
  28. package/columns/index.txt +71 -0
  29. package/compositingcentres/index.csv +7 -0
  30. package/compositingcentres/index.d.ts +35 -0
  31. package/compositingcentres/index.js +103 -0
  32. package/compositingcentres/index.txt +13 -0
  33. package/compositions/build.ts +212 -0
  34. package/compositions/index.csv +543 -0
  35. package/compositions/index.d.ts +254 -0
  36. package/compositions/index.js +204 -0
  37. package/compositionstats/build.ts +103 -0
  38. package/compositionstats/index.csv +4 -0
  39. package/compositionstats/index.d.ts +31 -0
  40. package/compositionstats/index.js +97 -0
  41. package/contents/index.csv +21 -0
  42. package/contents/index.d.ts +39 -0
  43. package/contents/index.js +102 -0
  44. package/contents/index.txt +13 -0
  45. package/deno.lock +67 -0
  46. package/descriptions/index.csv +543 -0
  47. package/descriptions/index.d.ts +45 -0
  48. package/descriptions/index.js +124 -0
  49. package/descriptions/index.txt +15 -0
  50. package/energies/index.csv +6 -0
  51. package/energies/index.d.ts +34 -0
  52. package/energies/index.js +101 -0
  53. package/energies/index.txt +13 -0
  54. package/frequencydistribution/index.csv +10 -0
  55. package/frequencydistribution/index.d.ts +36 -0
  56. package/frequencydistribution/index.js +90 -0
  57. package/frequencydistribution/index.txt +14 -0
  58. package/groups/index.csv +21 -0
  59. package/groups/index.d.ts +46 -0
  60. package/groups/index.js +118 -0
  61. package/groups/index.txt +14 -0
  62. package/hierarchy/asset.csv +215 -0
  63. package/hierarchy/asset.txt +70 -0
  64. package/hierarchy/build.ts +73 -0
  65. package/hierarchy/index.csv +215 -0
  66. package/hierarchy/index.d.ts +39 -0
  67. package/hierarchy/index.js +100 -0
  68. package/hierarchy/index.txt +14 -0
  69. package/index.d.ts +24 -28
  70. package/index.js +28 -39
  71. package/index.test.ts +717 -0
  72. package/intakes/build.ts +28 -0
  73. package/intakes/index.csv +42 -0
  74. package/intakes/index.d.ts +66 -0
  75. package/intakes/index.js +113 -0
  76. package/intakes/index.txt +20 -0
  77. package/jonesfactors/index.csv +15 -0
  78. package/jonesfactors/index.d.ts +35 -0
  79. package/jonesfactors/index.js +105 -0
  80. package/jonesfactors/index.txt +12 -0
  81. package/languages/index.csv +22 -0
  82. package/languages/index.d.ts +39 -0
  83. package/languages/index.js +103 -0
  84. package/languages/index.txt +12 -0
  85. package/methods/build.ts +101 -0
  86. package/methods/index.csv +37 -0
  87. package/methods/index.d.ts +39 -0
  88. package/methods/index.js +196 -0
  89. package/methods/index.txt +13 -0
  90. package/package.json +15 -63
  91. package/regions/index.csv +7 -0
  92. package/regions/index.d.ts +36 -0
  93. package/regions/index.js +100 -0
  94. package/regions/index.txt +12 -0
  95. package/representations/build.ts +133 -0
  96. package/representations/index.csv +215 -0
  97. package/representations/index.d.ts +36 -0
  98. package/representations/index.js +91 -0
  99. package/retentionfactors/groups.csv +21 -0
  100. package/retentionfactors/index.csv +215 -0
  101. package/samplingunits/index.csv +36 -0
  102. package/samplingunits/index.d.ts +39 -0
  103. package/samplingunits/index.js +110 -0
  104. package/samplingunits/index.txt +14 -0
  105. package/yieldfactors/index.csv +543 -0
  106. package/yieldfactors/index.d.ts +57 -0
  107. package/yieldfactors/index.js +158 -0
  108. package/yieldfactors/index.txt +294 -0
  109. package/corpus.js +0 -6
  110. package/corpus.min.js +0 -1
  111. package/pictures.d.ts +0 -41
@@ -0,0 +1,45 @@
1
+ import { type SetupTableOptions } from "@nodef/extra-sql";
2
+ /** Name of food in local languages, including scientific name. */ export interface Description {
3
+ /** Food Code. */ code: string;
4
+ /** Food Name. */ name: string;
5
+ /** Scientific Name. */ scie: string;
6
+ /** Food Group. */ grup: string;
7
+ /** Description (local names). */ desc: string;
8
+ }
9
+ /**
10
+ * Load the descriptions corpus from the file.
11
+ * @returns descriptions corpus
12
+ */ export declare function loadDescriptions(): Promise<Map<string, Description>>;
13
+ /**
14
+ * Get the path to the descriptions CSV file.
15
+ * @returns CSV file URL
16
+ */ export declare function descriptionsCsv(): string;
17
+ /**
18
+ * Obtain SQL command to create and populate the descriptions table.
19
+ * @param tab table name
20
+ * @param opt options for the table
21
+ * @returns CREATE TABLE, INSERT, CREATE VIEW, CREATE INDEX statements
22
+ */ export declare function descriptionsSql(tab?: string, opt?: SetupTableOptions): Promise<string>;
23
+ /**
24
+ * Find matching descriptions of an code/name/scie/desc query.
25
+ * @param txt code/name/scie/desc query
26
+ * @returns matches `[{code, name, scie, grup, desc}]`
27
+ * @example
28
+ * ```javascript
29
+ * ifct2017.descriptions('pineapple');
30
+ * ifct2017.descriptions('ananas comosus');
31
+ * // → [ { code: 'E053',
32
+ * // → name: 'Pineapple',
33
+ * // → scie: 'Ananas comosus',
34
+ * // → grup: 'Fruits',
35
+ * // → desc: 'A. Ahnaros; B. Anarasa; G. Anenas; H. Ananas; Kan. Ananas; Kash. Punchitipul; Kh. Soh trun; Kon. Anas; Mal. Kayirha chakka; M. Kihom Ananas; O. Sapuri; P. Ananas; Tam. Annasi pazham; Tel. Anasa pandu; U. Ananas.' } ]
36
+ *
37
+ * ifct2017.descriptions('tell me about cow milk.');
38
+ * ifct2017.descriptions('gai ka doodh details.');
39
+ * // → [ { code: 'L002',
40
+ * // → name: 'Milk, Cow',
41
+ * // → scie: '',
42
+ * // → grup: 'Milk and Milk Products',
43
+ * // → desc: 'A. Garoor gakhir; B. Doodh (garu); G. Gai nu dhudh; H. Gai ka doodh; Kan. Hasuvina halu; Kash. Doodh; Kh. Dud masi; M. San Sanghom; Mar. Doodh (gay); O. Gai dudha; P. Gaan da doodh; S. Gow kshiram; Tam. Pasumpaal; Tel. Aavu paalu.' } ]
44
+ * ```
45
+ */ export declare function descriptions(txt: string): Description[];
@@ -0,0 +1,124 @@
1
+ // Copyright (C) 2025-26 Subhajit Sahu
2
+ // SPDX-License-Identifier: AGPL-3.0-or-later
3
+ // See LICENSE for full terms
4
+ import * as csv from "@std/csv";
5
+ import lunr from "lunr"; // @deno-types="npm:@types/lunr@2.3.7"
6
+ import { setupTable } from "@nodef/extra-sql";
7
+ //#endregion
8
+ //#region GLOBALS
9
+ let corpus = null;
10
+ let index = null;
11
+ //#endregion
12
+ //#region FUNCTIONS
13
+ /**
14
+ * Load the descriptions corpus from CSV file.
15
+ * @param file CSV file path
16
+ * @returns descriptions corpus
17
+ */ async function loadFromCsv(file) {
18
+ const map = new Map();
19
+ const data = await (await fetch(file)).text();
20
+ const records = csv.parse(data, {
21
+ skipFirstRow: true,
22
+ comment: "#"
23
+ });
24
+ for (const r of records)map.set(r.code, r);
25
+ return map;
26
+ }
27
+ /**
28
+ * Setup the lunr index for the descriptions corpus.
29
+ * @returns lunr index
30
+ */ function setupIndex(corpus) {
31
+ return lunr(function() {
32
+ this.ref('code');
33
+ this.field('code');
34
+ this.field('name');
35
+ this.field('scie');
36
+ this.field('grup');
37
+ this.field('desc');
38
+ for (const r of corpus.values()){
39
+ let { code, name, scie, grup, desc } = r;
40
+ name = name.replace(/^(\w+),/g, '$1 $1 $1 $1,');
41
+ desc = desc.replace(/\[.*?\]/g, '').replace(/\w+\.\s([\w\',\/\(\)\- ]+)[;\.]?/g, '$1');
42
+ desc = desc.replace(/[,\/\(\)\- ]+/g, ' ').trim();
43
+ this.add({
44
+ code,
45
+ name,
46
+ scie,
47
+ grup,
48
+ desc
49
+ });
50
+ }
51
+ });
52
+ }
53
+ /**
54
+ * Load the descriptions corpus from the file.
55
+ * @returns descriptions corpus
56
+ */ export async function loadDescriptions() {
57
+ if (corpus) return corpus;
58
+ corpus = await loadFromCsv(descriptionsCsv());
59
+ index = setupIndex(corpus);
60
+ return corpus;
61
+ }
62
+ /**
63
+ * Get the path to the descriptions CSV file.
64
+ * @returns CSV file URL
65
+ */ export function descriptionsCsv() {
66
+ return import.meta.resolve('./index.csv');
67
+ }
68
+ /**
69
+ * Obtain SQL command to create and populate the descriptions table.
70
+ * @param tab table name
71
+ * @param opt options for the table
72
+ * @returns CREATE TABLE, INSERT, CREATE VIEW, CREATE INDEX statements
73
+ */ export async function descriptionsSql(tab = "descriptions", opt = {}) {
74
+ return setupTable(tab, {
75
+ code: "TEXT",
76
+ name: "TEXT",
77
+ scie: "TEXT",
78
+ grup: "TEXT",
79
+ desc: "TEXT"
80
+ }, (await loadDescriptions()).values(), Object.assign({
81
+ pk: "code",
82
+ index: true,
83
+ tsvector: {
84
+ code: "A",
85
+ name: "B",
86
+ scie: "B",
87
+ grup: "C",
88
+ desc: "B"
89
+ }
90
+ }, opt));
91
+ }
92
+ /**
93
+ * Find matching descriptions of an code/name/scie/desc query.
94
+ * @param txt code/name/scie/desc query
95
+ * @returns matches `[{code, name, scie, grup, desc}]`
96
+ * @example
97
+ * ```javascript
98
+ * ifct2017.descriptions('pineapple');
99
+ * ifct2017.descriptions('ananas comosus');
100
+ * // → [ { code: 'E053',
101
+ * // → name: 'Pineapple',
102
+ * // → scie: 'Ananas comosus',
103
+ * // → grup: 'Fruits',
104
+ * // → desc: 'A. Ahnaros; B. Anarasa; G. Anenas; H. Ananas; Kan. Ananas; Kash. Punchitipul; Kh. Soh trun; Kon. Anas; Mal. Kayirha chakka; M. Kihom Ananas; O. Sapuri; P. Ananas; Tam. Annasi pazham; Tel. Anasa pandu; U. Ananas.' } ]
105
+ *
106
+ * ifct2017.descriptions('tell me about cow milk.');
107
+ * ifct2017.descriptions('gai ka doodh details.');
108
+ * // → [ { code: 'L002',
109
+ * // → name: 'Milk, Cow',
110
+ * // → scie: '',
111
+ * // → grup: 'Milk and Milk Products',
112
+ * // → desc: 'A. Garoor gakhir; B. Doodh (garu); G. Gai nu dhudh; H. Gai ka doodh; Kan. Hasuvina halu; Kash. Doodh; Kh. Dud masi; M. San Sanghom; Mar. Doodh (gay); O. Gai dudha; P. Gaan da doodh; S. Gow kshiram; Tam. Pasumpaal; Tel. Aavu paalu.' } ]
113
+ * ```
114
+ */ export function descriptions(txt) {
115
+ if (index == null) return [];
116
+ const a = [];
117
+ txt = txt.replace(/\W/g, ' ');
118
+ const mats = index.search(txt);
119
+ let max = 0;
120
+ for (const mat of mats)max = Math.max(max, Object.keys(mat.matchData.metadata).length);
121
+ for (const mat of mats)if (Object.keys(mat.matchData.metadata).length === max) a.push(corpus?.get(mat.ref) || {});
122
+ return a;
123
+ } //#endregion
124
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vaG9tZS9ydW5uZXIvd29yay9pZmN0MjAxNy9pZmN0MjAxNy9kZXNjcmlwdGlvbnMvaW5kZXgudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IChDKSAyMDI1LTI2IFN1Ymhhaml0IFNhaHVcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBR1BMLTMuMC1vci1sYXRlclxuLy8gU2VlIExJQ0VOU0UgZm9yIGZ1bGwgdGVybXNcbmltcG9ydCAqIGFzIGNzdiAgZnJvbSBcIkBzdGQvY3N2XCI7XG5pbXBvcnQgbHVuciBmcm9tIFwibHVuclwiOyAgLy8gQGRlbm8tdHlwZXM9XCJucG06QHR5cGVzL2x1bnJAMi4zLjdcIlxuaW1wb3J0IHt0eXBlIFJvd0RhdGEsIHR5cGUgU2V0dXBUYWJsZU9wdGlvbnMsIHNldHVwVGFibGV9IGZyb20gXCJAbm9kZWYvZXh0cmEtc3FsXCI7XG5cblxuXG5cbi8vI3JlZ2lvbiBUWVBFU1xuLyoqIE5hbWUgb2YgZm9vZCBpbiBsb2NhbCBsYW5ndWFnZXMsIGluY2x1ZGluZyBzY2llbnRpZmljIG5hbWUuICovXG5leHBvcnQgaW50ZXJmYWNlIERlc2NyaXB0aW9uIHtcbiAgLyoqIEZvb2QgQ29kZS4gKi9cbiAgY29kZTogc3RyaW5nLFxuICAvKiogRm9vZCBOYW1lLiAqL1xuICBuYW1lOiBzdHJpbmcsXG4gIC8qKiBTY2llbnRpZmljIE5hbWUuICovXG4gIHNjaWU6IHN0cmluZyxcbiAgLyoqIEZvb2QgR3JvdXAuICovXG4gIGdydXA6IHN0cmluZyxcbiAgLyoqIERlc2NyaXB0aW9uIChsb2NhbCBuYW1lcykuICovXG4gIGRlc2M6IHN0cmluZ1xufTtcbi8vI2VuZHJlZ2lvblxuXG5cblxuXG4vLyNyZWdpb24gR0xPQkFMU1xubGV0IGNvcnB1czogTWFwPHN0cmluZywgRGVzY3JpcHRpb24+IHwgbnVsbCA9IG51bGw7XG5sZXQgaW5kZXg6IGx1bnIuSW5kZXggfCBudWxsID0gbnVsbDtcbi8vI2VuZHJlZ2lvblxuXG5cblxuXG4vLyNyZWdpb24gRlVOQ1RJT05TXG4vKipcbiAqIExvYWQgdGhlIGRlc2NyaXB0aW9ucyBjb3JwdXMgZnJvbSBDU1YgZmlsZS5cbiAqIEBwYXJhbSBmaWxlIENTViBmaWxlIHBhdGhcbiAqIEByZXR1cm5zIGRlc2NyaXB0aW9ucyBjb3JwdXNcbiAqL1xuYXN5bmMgZnVuY3Rpb24gbG9hZEZyb21Dc3YoZmlsZTogc3RyaW5nKSB7XG4gIGNvbnN0IG1hcCAgPSBuZXcgTWFwPHN0cmluZywgRGVzY3JpcHRpb24+KCk7XG4gIGNvbnN0IGRhdGEgPSBhd2FpdCAoYXdhaXQgZmV0Y2goZmlsZSkpLnRleHQoKTtcbiAgY29uc3QgcmVjb3JkcyA9IGNzdi5wYXJzZShkYXRhLCB7c2tpcEZpcnN0Um93OiB0cnVlLCBjb21tZW50OiBcIiNcIn0pO1xuICBmb3IgKGNvbnN0IHIgb2YgcmVjb3JkcylcbiAgICBtYXAuc2V0KHIuY29kZSwgciBhcyB1bmtub3duIGFzIERlc2NyaXB0aW9uKTtcbiAgcmV0dXJuIG1hcDtcbn1cblxuXG4vKipcbiAqIFNldHVwIHRoZSBsdW5yIGluZGV4IGZvciB0aGUgZGVzY3JpcHRpb25zIGNvcnB1cy5cbiAqIEByZXR1cm5zIGx1bnIgaW5kZXhcbiAqL1xuZnVuY3Rpb24gc2V0dXBJbmRleChjb3JwdXM6IE1hcDxzdHJpbmcsIERlc2NyaXB0aW9uPikge1xuICByZXR1cm4gbHVucihmdW5jdGlvbih0aGlzOiBsdW5yLkJ1aWxkZXIpIHtcbiAgICB0aGlzLnJlZignY29kZScpO1xuICAgIHRoaXMuZmllbGQoJ2NvZGUnKTtcbiAgICB0aGlzLmZpZWxkKCduYW1lJyk7XG4gICAgdGhpcy5maWVsZCgnc2NpZScpO1xuICAgIHRoaXMuZmllbGQoJ2dydXAnKTtcbiAgICB0aGlzLmZpZWxkKCdkZXNjJyk7XG4gICAgZm9yIChjb25zdCByIG9mIGNvcnB1cy52YWx1ZXMoKSkge1xuICAgICAgbGV0IHtjb2RlLCBuYW1lLCBzY2llLCBncnVwLCBkZXNjfSA9IHI7XG4gICAgICBuYW1lID0gbmFtZS5yZXBsYWNlKC9eKFxcdyspLC9nLCAnJDEgJDEgJDEgJDEsJyk7XG4gICAgICBkZXNjID0gZGVzYy5yZXBsYWNlKC9cXFsuKj9cXF0vZywgJycpLnJlcGxhY2UoL1xcdytcXC5cXHMoW1xcd1xcJyxcXC9cXChcXClcXC0gXSspWztcXC5dPy9nLCAnJDEnKTtcbiAgICAgIGRlc2MgPSBkZXNjLnJlcGxhY2UoL1ssXFwvXFwoXFwpXFwtIF0rL2csICcgJykudHJpbSgpO1xuICAgICAgdGhpcy5hZGQoe2NvZGUsIG5hbWUsIHNjaWUsIGdydXAsIGRlc2N9KTtcbiAgICB9XG4gIH0pO1xufVxuXG5cbi8qKlxuICogTG9hZCB0aGUgZGVzY3JpcHRpb25zIGNvcnB1cyBmcm9tIHRoZSBmaWxlLlxuICogQHJldHVybnMgZGVzY3JpcHRpb25zIGNvcnB1c1xuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbG9hZERlc2NyaXB0aW9ucygpOiBQcm9taXNlPE1hcDxzdHJpbmcsIERlc2NyaXB0aW9uPj4ge1xuICBpZiAoY29ycHVzKSByZXR1cm4gY29ycHVzO1xuICBjb3JwdXMgPSBhd2FpdCBsb2FkRnJvbUNzdihkZXNjcmlwdGlvbnNDc3YoKSk7XG4gIGluZGV4ICA9IHNldHVwSW5kZXgoY29ycHVzKTtcbiAgcmV0dXJuIGNvcnB1cztcbn1cblxuXG4vKipcbiAqIEdldCB0aGUgcGF0aCB0byB0aGUgZGVzY3JpcHRpb25zIENTViBmaWxlLlxuICogQHJldHVybnMgQ1NWIGZpbGUgVVJMXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZXNjcmlwdGlvbnNDc3YoKTogc3RyaW5nIHtcbiAgcmV0dXJuIGltcG9ydC5tZXRhLnJlc29sdmUoJy4vaW5kZXguY3N2Jyk7XG59XG5cblxuLyoqXG4gKiBPYnRhaW4gU1FMIGNvbW1hbmQgdG8gY3JlYXRlIGFuZCBwb3B1bGF0ZSB0aGUgZGVzY3JpcHRpb25zIHRhYmxlLlxuICogQHBhcmFtIHRhYiB0YWJsZSBuYW1lXG4gKiBAcGFyYW0gb3B0IG9wdGlvbnMgZm9yIHRoZSB0YWJsZVxuICogQHJldHVybnMgQ1JFQVRFIFRBQkxFLCBJTlNFUlQsIENSRUFURSBWSUVXLCBDUkVBVEUgSU5ERVggc3RhdGVtZW50c1xuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZGVzY3JpcHRpb25zU3FsKHRhYjogc3RyaW5nPVwiZGVzY3JpcHRpb25zXCIsIG9wdDogU2V0dXBUYWJsZU9wdGlvbnM9e30pOiBQcm9taXNlPHN0cmluZz4ge1xuICByZXR1cm4gc2V0dXBUYWJsZSh0YWIsIHtjb2RlOiBcIlRFWFRcIiwgbmFtZTogXCJURVhUXCIsIHNjaWU6IFwiVEVYVFwiLCBncnVwOiBcIlRFWFRcIiwgZGVzYzogXCJURVhUXCJ9LFxuICAgIChhd2FpdCBsb2FkRGVzY3JpcHRpb25zKCkpLnZhbHVlcygpIGFzIEl0ZXJhYmxlPFJvd0RhdGE+LFxuICAgIE9iamVjdC5hc3NpZ24oe3BrOiBcImNvZGVcIiwgaW5kZXg6IHRydWUsIHRzdmVjdG9yOiB7Y29kZTogXCJBXCIsIG5hbWU6IFwiQlwiLCBzY2llOiBcIkJcIiwgZ3J1cDogXCJDXCIsIGRlc2M6IFwiQlwifX0sIG9wdCkpO1xufVxuXG5cbi8qKlxuICogRmluZCBtYXRjaGluZyBkZXNjcmlwdGlvbnMgb2YgYW4gY29kZS9uYW1lL3NjaWUvZGVzYyBxdWVyeS5cbiAqIEBwYXJhbSB0eHQgY29kZS9uYW1lL3NjaWUvZGVzYyBxdWVyeVxuICogQHJldHVybnMgbWF0Y2hlcyBgW3tjb2RlLCBuYW1lLCBzY2llLCBncnVwLCBkZXNjfV1gXG4gKiBAZXhhbXBsZVxuICogYGBgamF2YXNjcmlwdFxuICogaWZjdDIwMTcuZGVzY3JpcHRpb25zKCdwaW5lYXBwbGUnKTtcbiAqIGlmY3QyMDE3LmRlc2NyaXB0aW9ucygnYW5hbmFzIGNvbW9zdXMnKTtcbiAqIC8vIOKGkiBbIHsgY29kZTogJ0UwNTMnLFxuICogLy8g4oaSICAgICBuYW1lOiAnUGluZWFwcGxlJyxcbiAqIC8vIOKGkiAgICAgc2NpZTogJ0FuYW5hcyBjb21vc3VzJyxcbiAqIC8vIOKGkiAgICAgZ3J1cDogJ0ZydWl0cycsXG4gKiAvLyDihpIgICAgIGRlc2M6ICdBLiBBaG5hcm9zOyBCLiBBbmFyYXNhOyBHLiBBbmVuYXM7IEguIEFuYW5hczsgS2FuLiBBbmFuYXM7IEthc2guIFB1bmNoaXRpcHVsOyBLaC4gU29oIHRydW47IEtvbi4gQW5hczsgTWFsLiBLYXlpcmhhIGNoYWtrYTsgTS4gS2lob20gQW5hbmFzOyBPLiBTYXB1cmk7IFAuIEFuYW5hczsgVGFtLiBBbm5hc2kgcGF6aGFtOyBUZWwuIEFuYXNhIHBhbmR1OyBVLiBBbmFuYXMuJyB9IF1cbiAqXG4gKiBpZmN0MjAxNy5kZXNjcmlwdGlvbnMoJ3RlbGwgbWUgYWJvdXQgY293IG1pbGsuJyk7XG4gKiBpZmN0MjAxNy5kZXNjcmlwdGlvbnMoJ2dhaSBrYSBkb29kaCBkZXRhaWxzLicpO1xuICogLy8g4oaSIFsgeyBjb2RlOiAnTDAwMicsXG4gKiAvLyDihpIgICAgIG5hbWU6ICdNaWxrLCBDb3cnLFxuICogLy8g4oaSICAgICBzY2llOiAnJyxcbiAqIC8vIOKGkiAgICAgZ3J1cDogJ01pbGsgYW5kIE1pbGsgUHJvZHVjdHMnLFxuICogLy8g4oaSICAgICBkZXNjOiAnQS4gR2Fyb29yIGdha2hpcjsgQi4gRG9vZGggKGdhcnUpOyBHLiBHYWkgbnUgZGh1ZGg7IEguIEdhaSBrYSBkb29kaDsgS2FuLiBIYXN1dmluYSBoYWx1OyBLYXNoLiBEb29kaDsgS2guIER1ZCBtYXNpOyBNLiBTYW4gU2FuZ2hvbTsgTWFyLiBEb29kaCAoZ2F5KTsgTy4gR2FpIGR1ZGhhOyBQLiBHYWFuIGRhIGRvb2RoOyBTLiBHb3cga3NoaXJhbTsgVGFtLiBQYXN1bXBhYWw7IFRlbC4gQWF2dSBwYWFsdS4nIH0gXVxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZXNjcmlwdGlvbnModHh0OiBzdHJpbmcpOiBEZXNjcmlwdGlvbltdIHtcbiAgaWYgKGluZGV4ID09IG51bGwpIHJldHVybiBbXTtcbiAgY29uc3QgYTogRGVzY3JpcHRpb25bXSA9IFtdOyB0eHQgPSB0eHQucmVwbGFjZSgvXFxXL2csICcgJyk7XG4gIGNvbnN0IG1hdHMgPSBpbmRleC5zZWFyY2godHh0KTsgbGV0IG1heCA9IDA7XG4gIGZvciAoY29uc3QgbWF0IG9mIG1hdHMpXG4gICAgbWF4ID0gTWF0aC5tYXgobWF4LCBPYmplY3Qua2V5cyhtYXQubWF0Y2hEYXRhLm1ldGFkYXRhKS5sZW5ndGgpO1xuICBmb3IgKGNvbnN0IG1hdCBvZiBtYXRzKVxuICAgIGlmIChPYmplY3Qua2V5cyhtYXQubWF0Y2hEYXRhLm1ldGFkYXRhKS5sZW5ndGggPT09IG1heCkgYS5wdXNoKGNvcnB1cz8uZ2V0KG1hdC5yZWYpIHx8IHt9IGFzIERlc2NyaXB0aW9uKTtcbiAgcmV0dXJuIGE7XG59XG4vLyNlbmRyZWdpb25cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxzQ0FBc0M7QUFDdEMsNkNBQTZDO0FBQzdDLDZCQUE2QjtBQUM3QixZQUFZLFNBQVUsV0FBVztBQUNqQyxPQUFPLFVBQVUsT0FBTyxDQUFFLHNDQUFzQztBQUNoRSxTQUE4QyxVQUFVLFFBQU8sbUJBQW1CO0FBbUJsRixZQUFZO0FBS1osaUJBQWlCO0FBQ2pCLElBQUksU0FBMEM7QUFDOUMsSUFBSSxRQUEyQjtBQUMvQixZQUFZO0FBS1osbUJBQW1CO0FBQ25COzs7O0NBSUMsR0FDRCxlQUFlLFlBQVksSUFBWTtFQUNyQyxNQUFNLE1BQU8sSUFBSTtFQUNqQixNQUFNLE9BQU8sTUFBTSxDQUFDLE1BQU0sTUFBTSxLQUFLLEVBQUUsSUFBSTtFQUMzQyxNQUFNLFVBQVUsSUFBSSxLQUFLLENBQUMsTUFBTTtJQUFDLGNBQWM7SUFBTSxTQUFTO0VBQUc7RUFDakUsS0FBSyxNQUFNLEtBQUssUUFDZCxJQUFJLEdBQUcsQ0FBQyxFQUFFLElBQUksRUFBRTtFQUNsQixPQUFPO0FBQ1Q7QUFHQTs7O0NBR0MsR0FDRCxTQUFTLFdBQVcsTUFBZ0M7RUFDbEQsT0FBTyxLQUFLO0lBQ1YsSUFBSSxDQUFDLEdBQUcsQ0FBQztJQUNULElBQUksQ0FBQyxLQUFLLENBQUM7SUFDWCxJQUFJLENBQUMsS0FBSyxDQUFDO0lBQ1gsSUFBSSxDQUFDLEtBQUssQ0FBQztJQUNYLElBQUksQ0FBQyxLQUFLLENBQUM7SUFDWCxJQUFJLENBQUMsS0FBSyxDQUFDO0lBQ1gsS0FBSyxNQUFNLEtBQUssT0FBTyxNQUFNLEdBQUk7TUFDL0IsSUFBSSxFQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUMsR0FBRztNQUNyQyxPQUFPLEtBQUssT0FBTyxDQUFDLFlBQVk7TUFDaEMsT0FBTyxLQUFLLE9BQU8sQ0FBQyxZQUFZLElBQUksT0FBTyxDQUFDLHFDQUFxQztNQUNqRixPQUFPLEtBQUssT0FBTyxDQUFDLGtCQUFrQixLQUFLLElBQUk7TUFDL0MsSUFBSSxDQUFDLEdBQUcsQ0FBQztRQUFDO1FBQU07UUFBTTtRQUFNO1FBQU07TUFBSTtJQUN4QztFQUNGO0FBQ0Y7QUFHQTs7O0NBR0MsR0FDRCxPQUFPLGVBQWU7RUFDcEIsSUFBSSxRQUFRLE9BQU87RUFDbkIsU0FBUyxNQUFNLFlBQVk7RUFDM0IsUUFBUyxXQUFXO0VBQ3BCLE9BQU87QUFDVDtBQUdBOzs7Q0FHQyxHQUNELE9BQU8sU0FBUztFQUNkLE9BQU8sWUFBWSxPQUFPLENBQUM7QUFDN0I7QUFHQTs7Ozs7Q0FLQyxHQUNELE9BQU8sZUFBZSxnQkFBZ0IsTUFBWSxjQUFjLEVBQUUsTUFBdUIsQ0FBQyxDQUFDO0VBQ3pGLE9BQU8sV0FBVyxLQUFLO0lBQUMsTUFBTTtJQUFRLE1BQU07SUFBUSxNQUFNO0lBQVEsTUFBTTtJQUFRLE1BQU07RUFBTSxHQUMxRixDQUFDLE1BQU0sa0JBQWtCLEVBQUUsTUFBTSxJQUNqQyxPQUFPLE1BQU0sQ0FBQztJQUFDLElBQUk7SUFBUSxPQUFPO0lBQU0sVUFBVTtNQUFDLE1BQU07TUFBSyxNQUFNO01BQUssTUFBTTtNQUFLLE1BQU07TUFBSyxNQUFNO0lBQUc7RUFBQyxHQUFHO0FBQ2hIO0FBR0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Q0FzQkMsR0FDRCxPQUFPLFNBQVMsYUFBYSxHQUFXO0VBQ3RDLElBQUksU0FBUyxNQUFNLE9BQU8sRUFBRTtFQUM1QixNQUFNLElBQW1CLEVBQUU7RUFBRSxNQUFNLElBQUksT0FBTyxDQUFDLE9BQU87RUFDdEQsTUFBTSxPQUFPLE1BQU0sTUFBTSxDQUFDO0VBQU0sSUFBSSxNQUFNO0VBQzFDLEtBQUssTUFBTSxPQUFPLEtBQ2hCLE1BQU0sS0FBSyxHQUFHLENBQUMsS0FBSyxPQUFPLElBQUksQ0FBQyxJQUFJLFNBQVMsQ0FBQyxRQUFRLEVBQUUsTUFBTTtFQUNoRSxLQUFLLE1BQU0sT0FBTyxLQUNoQixJQUFJLE9BQU8sSUFBSSxDQUFDLElBQUksU0FBUyxDQUFDLFFBQVEsRUFBRSxNQUFNLEtBQUssS0FBSyxFQUFFLElBQUksQ0FBQyxRQUFRLElBQUksSUFBSSxHQUFHLEtBQUssQ0FBQztFQUMxRixPQUFPO0FBQ1QsRUFDQSxZQUFZIn0=
@@ -0,0 +1,15 @@
1
+ Indian Food Composition Tables 2017
2
+ T. Longvah, R. Ananthan, K. Bhaskarachary and K. Venkaiah
3
+
4
+ Copyright © 2017 by National Institute of Nutrition
5
+ Indian Council of Medical Research
6
+ Department of Health Research Ministry of Health and Family Welfare, Government of India
7
+ Jamai Osmania (PO), Hyderabad – 500 007
8
+ Telangana, India Phone: +91 40 27197334, Fax: +91 40 27000339, Email: nin@ap.nic.in
9
+
10
+ FOOD DESCRIPTION
11
+ - Food Code
12
+ - Food Name
13
+ - Scientific Name
14
+ - Food Group
15
+ - Description
@@ -0,0 +1,6 @@
1
+ component,kj,kcal
2
+ Protein,17,4
3
+ Fat,37,9
4
+ Available carbohydrate,17,4
5
+ Fibre,8,2
6
+ Alcohol,29,7
@@ -0,0 +1,34 @@
1
+ import { type SetupTableOptions } from "@nodef/extra-sql";
2
+ /** Metabolizable energy conversion factor. */ export interface Energy {
3
+ /** Component. */ component: string;
4
+ /** kJ/g. */ kj: number;
5
+ /** kcal/g. */ kcal: number;
6
+ }
7
+ /**
8
+ * Load the energies corpus from the file.
9
+ * @returns energies corpus
10
+ */ export declare function loadEnergies(): Promise<Map<string, Energy>>;
11
+ /**
12
+ * Get the path to the energies CSV file.
13
+ * @returns CSV file URL
14
+ */ export declare function energiesCsv(): string;
15
+ /**
16
+ * Obtain SQL command to create and populate the energies table.
17
+ * @param tab table name
18
+ * @param opt options for the table
19
+ * @returns CREATE TABLE, INSERT, CREATE VIEW, CREATE INDEX statements
20
+ */ export declare function energiesSql(tab?: string, opt?: SetupTableOptions): Promise<string>;
21
+ /**
22
+ * Finds matching energies of a component query.
23
+ * @param txt component query
24
+ * @returns matches `[{component, kj, kcal}]`
25
+ * ```javascript
26
+ * ifct2017.energies('dietary fibre');
27
+ * ifct2017.energies('Soluble fibre');
28
+ * // → [ { component: 'Fibre', kj: 8, kcal: 2 } ]
29
+ *
30
+ * ifct2017.energies('what is energy conversion factor of fat?');
31
+ * ifct2017.energies('conversion factor of fat');
32
+ * // → [ { component: 'Fat', kj: 37, kcal: 9 } ]
33
+ * ```
34
+ */ export declare function energies(txt: string): Energy[];
@@ -0,0 +1,101 @@
1
+ // Copyright (C) 2025-26 Subhajit Sahu
2
+ // SPDX-License-Identifier: AGPL-3.0-or-later
3
+ // See LICENSE for full terms
4
+ import * as csv from "@std/csv";
5
+ import lunr from "lunr"; // @deno-types="npm:@types/lunr@2.3.7"
6
+ import { setupTable } from "@nodef/extra-sql";
7
+ //#endregion
8
+ //#region GLOBALS
9
+ let corpus = null;
10
+ let index = null;
11
+ //#endregion
12
+ //#region FUNCTIONS
13
+ /**
14
+ * Load the energies corpus from CSV file.
15
+ * @param file CSV file path
16
+ * @returns energies corpus
17
+ */ async function loadFromCsv(file) {
18
+ const map = new Map();
19
+ const data = await (await fetch(file)).text();
20
+ const records = csv.parse(data, {
21
+ skipFirstRow: true,
22
+ comment: "#"
23
+ });
24
+ for (const r of records){
25
+ const kj = parseFloat(r.kj);
26
+ const kcal = parseFloat(r.kcal);
27
+ map.set(r.component, {
28
+ component: r.component,
29
+ kj,
30
+ kcal
31
+ });
32
+ }
33
+ return map;
34
+ }
35
+ /**
36
+ * Setup the lunr index for the energies corpus.
37
+ * @returns lunr index
38
+ */ function setupIndex(corpus) {
39
+ return lunr(function() {
40
+ this.ref('component');
41
+ this.field('component');
42
+ for (const r of corpus.values())this.add(r);
43
+ });
44
+ }
45
+ /**
46
+ * Load the energies corpus from the file.
47
+ * @returns energies corpus
48
+ */ export async function loadEnergies() {
49
+ if (corpus) return corpus;
50
+ corpus = await loadFromCsv(energiesCsv());
51
+ index = setupIndex(corpus);
52
+ return corpus;
53
+ }
54
+ /**
55
+ * Get the path to the energies CSV file.
56
+ * @returns CSV file URL
57
+ */ export function energiesCsv() {
58
+ return import.meta.resolve('./index.csv');
59
+ }
60
+ /**
61
+ * Obtain SQL command to create and populate the energies table.
62
+ * @param tab table name
63
+ * @param opt options for the table
64
+ * @returns CREATE TABLE, INSERT, CREATE VIEW, CREATE INDEX statements
65
+ */ export async function energiesSql(tab = "energies", opt = {}) {
66
+ return setupTable(tab, {
67
+ component: "TEXT",
68
+ kj: "REAL",
69
+ kcal: "REAL"
70
+ }, (await loadEnergies()).values(), Object.assign({
71
+ pk: "component",
72
+ index: true,
73
+ tsvector: {
74
+ component: "A"
75
+ }
76
+ }, opt));
77
+ }
78
+ /**
79
+ * Finds matching energies of a component query.
80
+ * @param txt component query
81
+ * @returns matches `[{component, kj, kcal}]`
82
+ * ```javascript
83
+ * ifct2017.energies('dietary fibre');
84
+ * ifct2017.energies('Soluble fibre');
85
+ * // → [ { component: 'Fibre', kj: 8, kcal: 2 } ]
86
+ *
87
+ * ifct2017.energies('what is energy conversion factor of fat?');
88
+ * ifct2017.energies('conversion factor of fat');
89
+ * // → [ { component: 'Fat', kj: 37, kcal: 9 } ]
90
+ * ```
91
+ */ export function energies(txt) {
92
+ if (index == null) return [];
93
+ const a = [];
94
+ txt = txt.replace(/\W/g, ' ');
95
+ const mats = index.search(txt);
96
+ let max = 0;
97
+ for (const mat of mats)max = Math.max(max, Object.keys(mat.matchData.metadata).length);
98
+ for (const mat of mats)if (Object.keys(mat.matchData.metadata).length === max) a.push(corpus?.get(mat.ref) || {});
99
+ return a;
100
+ } //#endregion
101
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vaG9tZS9ydW5uZXIvd29yay9pZmN0MjAxNy9pZmN0MjAxNy9lbmVyZ2llcy9pbmRleC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgKEMpIDIwMjUtMjYgU3ViaGFqaXQgU2FodVxuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFHUEwtMy4wLW9yLWxhdGVyXG4vLyBTZWUgTElDRU5TRSBmb3IgZnVsbCB0ZXJtc1xuaW1wb3J0ICogYXMgY3N2ICBmcm9tIFwiQHN0ZC9jc3ZcIjtcbmltcG9ydCBsdW5yIGZyb20gXCJsdW5yXCI7ICAvLyBAZGVuby10eXBlcz1cIm5wbTpAdHlwZXMvbHVuckAyLjMuN1wiXG5pbXBvcnQge3R5cGUgUm93RGF0YSwgdHlwZSBTZXR1cFRhYmxlT3B0aW9ucywgc2V0dXBUYWJsZX0gZnJvbSBcIkBub2RlZi9leHRyYS1zcWxcIjtcblxuXG5cblxuLy8jcmVnaW9uIFRZUEVTXG4vKiogTWV0YWJvbGl6YWJsZSBlbmVyZ3kgY29udmVyc2lvbiBmYWN0b3IuICovXG5leHBvcnQgaW50ZXJmYWNlIEVuZXJneSB7XG4gIC8qKiBDb21wb25lbnQuICovXG4gIGNvbXBvbmVudDogc3RyaW5nLFxuICAvKioga0ovZy4gKi9cbiAga2o6IG51bWJlcixcbiAgLyoqIGtjYWwvZy4gKi9cbiAga2NhbDogbnVtYmVyXG59O1xuLy8jZW5kcmVnaW9uXG5cblxuXG5cbi8vI3JlZ2lvbiBHTE9CQUxTXG5sZXQgY29ycHVzOiBNYXA8c3RyaW5nLCBFbmVyZ3k+IHwgbnVsbCA9IG51bGw7XG5sZXQgaW5kZXg6IGx1bnIuSW5kZXggfCBudWxsID0gbnVsbDtcbi8vI2VuZHJlZ2lvblxuXG5cblxuXG4vLyNyZWdpb24gRlVOQ1RJT05TXG4vKipcbiAqIExvYWQgdGhlIGVuZXJnaWVzIGNvcnB1cyBmcm9tIENTViBmaWxlLlxuICogQHBhcmFtIGZpbGUgQ1NWIGZpbGUgcGF0aFxuICogQHJldHVybnMgZW5lcmdpZXMgY29ycHVzXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGxvYWRGcm9tQ3N2KGZpbGU6IHN0cmluZykge1xuICBjb25zdCBtYXAgID0gbmV3IE1hcDxzdHJpbmcsIEVuZXJneT4oKTtcbiAgY29uc3QgZGF0YSA9IGF3YWl0IChhd2FpdCBmZXRjaChmaWxlKSkudGV4dCgpO1xuICBjb25zdCByZWNvcmRzID0gY3N2LnBhcnNlKGRhdGEsIHtza2lwRmlyc3RSb3c6IHRydWUsIGNvbW1lbnQ6IFwiI1wifSk7XG4gIGZvciAoY29uc3QgciBvZiByZWNvcmRzKSB7XG4gICAgY29uc3Qga2ogICA9IHBhcnNlRmxvYXQoci5raik7XG4gICAgY29uc3Qga2NhbCA9IHBhcnNlRmxvYXQoci5rY2FsKTtcbiAgICBtYXAuc2V0KHIuY29tcG9uZW50LCB7Y29tcG9uZW50OiByLmNvbXBvbmVudCwga2osIGtjYWx9KTtcbiAgfVxuICByZXR1cm4gbWFwO1xufVxuXG5cbi8qKlxuICogU2V0dXAgdGhlIGx1bnIgaW5kZXggZm9yIHRoZSBlbmVyZ2llcyBjb3JwdXMuXG4gKiBAcmV0dXJucyBsdW5yIGluZGV4XG4gKi9cbmZ1bmN0aW9uIHNldHVwSW5kZXgoY29ycHVzOiBNYXA8c3RyaW5nLCBFbmVyZ3k+KSB7XG4gIHJldHVybiBsdW5yKGZ1bmN0aW9uKHRoaXM6IGx1bnIuQnVpbGRlcikge1xuICAgIHRoaXMucmVmKCdjb21wb25lbnQnKTtcbiAgICB0aGlzLmZpZWxkKCdjb21wb25lbnQnKTtcbiAgICBmb3IgKGNvbnN0IHIgb2YgY29ycHVzLnZhbHVlcygpKVxuICAgICAgdGhpcy5hZGQocik7XG4gIH0pO1xufVxuXG5cbi8qKlxuICogTG9hZCB0aGUgZW5lcmdpZXMgY29ycHVzIGZyb20gdGhlIGZpbGUuXG4gKiBAcmV0dXJucyBlbmVyZ2llcyBjb3JwdXNcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGxvYWRFbmVyZ2llcygpOiBQcm9taXNlPE1hcDxzdHJpbmcsIEVuZXJneT4+IHtcbiAgaWYgKGNvcnB1cykgcmV0dXJuIGNvcnB1cztcbiAgY29ycHVzID0gYXdhaXQgbG9hZEZyb21Dc3YoZW5lcmdpZXNDc3YoKSk7XG4gIGluZGV4ICA9IHNldHVwSW5kZXgoY29ycHVzKTtcbiAgcmV0dXJuIGNvcnB1cztcbn1cblxuXG4vKipcbiAqIEdldCB0aGUgcGF0aCB0byB0aGUgZW5lcmdpZXMgQ1NWIGZpbGUuXG4gKiBAcmV0dXJucyBDU1YgZmlsZSBVUkxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVuZXJnaWVzQ3N2KCk6IHN0cmluZyB7XG4gIHJldHVybiBpbXBvcnQubWV0YS5yZXNvbHZlKCcuL2luZGV4LmNzdicpO1xufVxuXG5cbi8qKlxuICogT2J0YWluIFNRTCBjb21tYW5kIHRvIGNyZWF0ZSBhbmQgcG9wdWxhdGUgdGhlIGVuZXJnaWVzIHRhYmxlLlxuICogQHBhcmFtIHRhYiB0YWJsZSBuYW1lXG4gKiBAcGFyYW0gb3B0IG9wdGlvbnMgZm9yIHRoZSB0YWJsZVxuICogQHJldHVybnMgQ1JFQVRFIFRBQkxFLCBJTlNFUlQsIENSRUFURSBWSUVXLCBDUkVBVEUgSU5ERVggc3RhdGVtZW50c1xuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZW5lcmdpZXNTcWwodGFiOiBzdHJpbmc9XCJlbmVyZ2llc1wiLCBvcHQ6IFNldHVwVGFibGVPcHRpb25zPXt9KTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgcmV0dXJuIHNldHVwVGFibGUodGFiLCB7Y29tcG9uZW50OiBcIlRFWFRcIiwga2o6IFwiUkVBTFwiLCBrY2FsOiBcIlJFQUxcIn0sXG4gICAgKGF3YWl0IGxvYWRFbmVyZ2llcygpKS52YWx1ZXMoKSBhcyBJdGVyYWJsZTxSb3dEYXRhPixcbiAgICBPYmplY3QuYXNzaWduKHtwazogXCJjb21wb25lbnRcIiwgaW5kZXg6IHRydWUsIHRzdmVjdG9yOiB7Y29tcG9uZW50OiBcIkFcIn19LCBvcHQpKTtcbn1cblxuXG4vKipcbiAqIEZpbmRzIG1hdGNoaW5nIGVuZXJnaWVzIG9mIGEgY29tcG9uZW50IHF1ZXJ5LlxuICogQHBhcmFtIHR4dCBjb21wb25lbnQgcXVlcnlcbiAqIEByZXR1cm5zIG1hdGNoZXMgYFt7Y29tcG9uZW50LCBraiwga2NhbH1dYFxuICogYGBgamF2YXNjcmlwdFxuICogaWZjdDIwMTcuZW5lcmdpZXMoJ2RpZXRhcnkgZmlicmUnKTtcbiAqIGlmY3QyMDE3LmVuZXJnaWVzKCdTb2x1YmxlIGZpYnJlJyk7XG4gKiAvLyDihpIgWyB7IGNvbXBvbmVudDogJ0ZpYnJlJywga2o6IDgsIGtjYWw6IDIgfSBdXG4gKlxuICogaWZjdDIwMTcuZW5lcmdpZXMoJ3doYXQgaXMgZW5lcmd5IGNvbnZlcnNpb24gZmFjdG9yIG9mIGZhdD8nKTtcbiAqIGlmY3QyMDE3LmVuZXJnaWVzKCdjb252ZXJzaW9uIGZhY3RvciBvZiBmYXQnKTtcbiAqIC8vIOKGkiBbIHsgY29tcG9uZW50OiAnRmF0Jywga2o6IDM3LCBrY2FsOiA5IH0gXVxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbmVyZ2llcyh0eHQ6IHN0cmluZyk6IEVuZXJneVtdIHtcbiAgaWYgKGluZGV4ID09IG51bGwpIHJldHVybiBbXTtcbiAgY29uc3QgYTogRW5lcmd5W10gPSBbXTsgdHh0ID0gdHh0LnJlcGxhY2UoL1xcVy9nLCAnICcpO1xuICBjb25zdCBtYXRzID0gaW5kZXguc2VhcmNoKHR4dCk7IGxldCBtYXggPSAwO1xuICBmb3IgKGNvbnN0IG1hdCBvZiBtYXRzKVxuICAgIG1heCA9IE1hdGgubWF4KG1heCwgT2JqZWN0LmtleXMobWF0Lm1hdGNoRGF0YS5tZXRhZGF0YSkubGVuZ3RoKTtcbiAgZm9yIChjb25zdCBtYXQgb2YgbWF0cylcbiAgICBpZiAoT2JqZWN0LmtleXMobWF0Lm1hdGNoRGF0YS5tZXRhZGF0YSkubGVuZ3RoID09PSBtYXgpIGEucHVzaChjb3JwdXM/LmdldChtYXQucmVmKSB8fCB7fSBhcyBFbmVyZ3kpO1xuICByZXR1cm4gYTtcbn1cbi8vI2VuZHJlZ2lvblxuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHND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
@@ -0,0 +1,13 @@
1
+ Indian Food Composition Tables 2017
2
+ T. Longvah, R. Ananthan, K. Bhaskarachary and K. Venkaiah
3
+
4
+ Copyright © 2017 by National Institute of Nutrition
5
+ Indian Council of Medical Research
6
+ Department of Health Research Ministry of Health and Family Welfare, Government of India
7
+ Jamai Osmania (PO), Hyderabad – 500 007
8
+ Telangana, India Phone: +91 40 27197334, Fax: +91 40 27000339, Email: nin@ap.nic.in
9
+
10
+ METABOLIZEABLE ENERGY CONVERSION FACTORS
11
+ - Component
12
+ - kJ/g
13
+ - kcal/g
@@ -0,0 +1,10 @@
1
+ districts,states,selected,sampled
2
+ 1-5,9,1,9
3
+ 6-10,4,2,8
4
+ 11-20,9,3,27
5
+ 21-30,7,4,28
6
+ 31-40,4,5,20
7
+ 41-50,1,6,6
8
+ 51-60,0,7,0
9
+ 61-70,0,8,0
10
+ >70,1,9,9
@@ -0,0 +1,36 @@
1
+ import { type SetupTableOptions } from "@nodef/extra-sql";
2
+ /** Frequency of States/UTs for fixing the number of districts to be sampled. */ export interface Frequency {
3
+ /** No. of Districts. */ districts: string;
4
+ /** No. of States/UTs. */ states: number;
5
+ /** No. of districts to be selected from each State/UT. */ selected: number;
6
+ /** Total No. of districts to be sampled. */ sampled: number;
7
+ }
8
+ /**
9
+ * Load the frequency distribution corpus from the file.
10
+ * @returns frequency distribution corpus
11
+ */ export declare function loadFrequencyDistribution(): Promise<Map<number, Frequency>>;
12
+ /**
13
+ * Get the path to the frequency distribution CSV file.
14
+ * @returns CSV file URL
15
+ */ export declare function frequencyDistributionCsv(): string;
16
+ /**
17
+ * Obtain SQL command to create and populate the frequency distribution table.
18
+ * @param tab table name
19
+ * @param opt options for the table
20
+ * @returns CREATE TABLE, INSERT, CREATE VIEW, CREATE INDEX statements
21
+ */ export declare function frequencyDistributionSql(tab?: string, opt?: SetupTableOptions): Promise<string>;
22
+ /**
23
+ * Find matching frequency distribution for a given no. of districts.
24
+ * @param dis no. of districts
25
+ * @returns `{districts, states, selected, sampled}` if found, else null
26
+ * @example
27
+ * ```javascript
28
+ * ifct2017.frequencyDistribution(2);
29
+ * ifct2017.frequencyDistribution(5);
30
+ * // → { districts: '1-5', states: 9, selected: 1, sampled: 9 }
31
+ *
32
+ * ifct2017.frequencyDistribution(32);
33
+ * ifct2017.frequencyDistribution(37);
34
+ * // → { districts: '31-40', states: 4, selected: 5, sampled: 20 }
35
+ * ```
36
+ */ export declare function frequencyDistribution(dis: number): Frequency | null;
@@ -0,0 +1,90 @@
1
+ // Copyright (C) 2025-26 Subhajit Sahu
2
+ // SPDX-License-Identifier: AGPL-3.0-or-later
3
+ // See LICENSE for full terms
4
+ import * as csv from "@std/csv";
5
+ import { setupTable } from "@nodef/extra-sql";
6
+ //#endregion
7
+ //#region GLOBALS
8
+ let corpus = null;
9
+ //#endregion
10
+ //#region FUNCTIONS
11
+ /**
12
+ * Load the frequency distribution corpus from CSV file.
13
+ * @param file CSV file path
14
+ * @returns frequency distribution corpus
15
+ */ async function loadFromCsv(file) {
16
+ const map = new Map();
17
+ const data = await (await fetch(file)).text();
18
+ const records = csv.parse(data, {
19
+ skipFirstRow: true,
20
+ comment: "#"
21
+ });
22
+ for (const r of records){
23
+ const states = parseFloat(r.states);
24
+ const selected = parseFloat(r.selected);
25
+ const sampled = parseFloat(r.sampled);
26
+ const key = parseFloat(r.districts.split('-')[0].replace(/\D/g, ''));
27
+ map.set(key === 70 ? 71 : key, {
28
+ districts: r.districts,
29
+ states,
30
+ selected,
31
+ sampled
32
+ });
33
+ }
34
+ return map;
35
+ }
36
+ /**
37
+ * Load the frequency distribution corpus from the file.
38
+ * @returns frequency distribution corpus
39
+ */ export async function loadFrequencyDistribution() {
40
+ if (corpus) return corpus;
41
+ corpus = await loadFromCsv(frequencyDistributionCsv());
42
+ return corpus;
43
+ }
44
+ /**
45
+ * Get the path to the frequency distribution CSV file.
46
+ * @returns CSV file URL
47
+ */ export function frequencyDistributionCsv() {
48
+ return import.meta.resolve('./index.csv');
49
+ }
50
+ /**
51
+ * Obtain SQL command to create and populate the frequency distribution table.
52
+ * @param tab table name
53
+ * @param opt options for the table
54
+ * @returns CREATE TABLE, INSERT, CREATE VIEW, CREATE INDEX statements
55
+ */ export async function frequencyDistributionSql(tab = "frequencydistribution", opt = {}) {
56
+ return setupTable(tab, {
57
+ districts: "TEXT",
58
+ states: "INT",
59
+ selected: "INT",
60
+ sampled: "INT"
61
+ }, (await loadFrequencyDistribution()).values(), Object.assign({
62
+ pk: "districts",
63
+ index: true,
64
+ tsvector: {
65
+ districts: "A"
66
+ }
67
+ }, opt));
68
+ }
69
+ /**
70
+ * Find matching frequency distribution for a given no. of districts.
71
+ * @param dis no. of districts
72
+ * @returns `{districts, states, selected, sampled}` if found, else null
73
+ * @example
74
+ * ```javascript
75
+ * ifct2017.frequencyDistribution(2);
76
+ * ifct2017.frequencyDistribution(5);
77
+ * // → { districts: '1-5', states: 9, selected: 1, sampled: 9 }
78
+ *
79
+ * ifct2017.frequencyDistribution(32);
80
+ * ifct2017.frequencyDistribution(37);
81
+ * // → { districts: '31-40', states: 4, selected: 5, sampled: 20 }
82
+ * ```
83
+ */ export function frequencyDistribution(dis) {
84
+ if (corpus == null) return null;
85
+ if (dis <= 5) return corpus.get(1) || null;
86
+ if (dis <= 10) return corpus.get(6) || null;
87
+ if (dis > 70) return corpus.get(71) || null;
88
+ return corpus.get(Math.floor((dis - 1) / 10) * 10 + 1) || null;
89
+ } //#endregion
90
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vaG9tZS9ydW5uZXIvd29yay9pZmN0MjAxNy9pZmN0MjAxNy9mcmVxdWVuY3lkaXN0cmlidXRpb24vaW5kZXgudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IChDKSAyMDI1LTI2IFN1Ymhhaml0IFNhaHVcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBR1BMLTMuMC1vci1sYXRlclxuLy8gU2VlIExJQ0VOU0UgZm9yIGZ1bGwgdGVybXNcbmltcG9ydCAqIGFzIGNzdiAgZnJvbSBcIkBzdGQvY3N2XCI7XG5pbXBvcnQge3R5cGUgUm93RGF0YSwgdHlwZSBTZXR1cFRhYmxlT3B0aW9ucywgc2V0dXBUYWJsZX0gZnJvbSBcIkBub2RlZi9leHRyYS1zcWxcIjtcblxuXG5cblxuLy8jcmVnaW9uIFRZUEVTXG4vKiogRnJlcXVlbmN5IG9mIFN0YXRlcy9VVHMgZm9yIGZpeGluZyB0aGUgbnVtYmVyIG9mIGRpc3RyaWN0cyB0byBiZSBzYW1wbGVkLiAqL1xuZXhwb3J0IGludGVyZmFjZSBGcmVxdWVuY3kge1xuICAvKiogTm8uIG9mIERpc3RyaWN0cy4gKi9cbiAgZGlzdHJpY3RzOiBzdHJpbmcsXG4gIC8qKiBOby4gb2YgU3RhdGVzL1VUcy4gKi9cbiAgc3RhdGVzOiBudW1iZXIsXG4gIC8qKiBOby4gb2YgZGlzdHJpY3RzIHRvIGJlIHNlbGVjdGVkIGZyb20gZWFjaCBTdGF0ZS9VVC4gKi9cbiAgc2VsZWN0ZWQ6IG51bWJlcixcbiAgLyoqIFRvdGFsIE5vLiBvZiBkaXN0cmljdHMgdG8gYmUgc2FtcGxlZC4gKi9cbiAgc2FtcGxlZDogbnVtYmVyXG59O1xuLy8jZW5kcmVnaW9uXG5cblxuXG5cbi8vI3JlZ2lvbiBHTE9CQUxTXG5sZXQgY29ycHVzOiBNYXA8bnVtYmVyLCBGcmVxdWVuY3k+IHwgbnVsbCA9IG51bGw7XG4vLyNlbmRyZWdpb25cblxuXG5cblxuLy8jcmVnaW9uIEZVTkNUSU9OU1xuLyoqXG4gKiBMb2FkIHRoZSBmcmVxdWVuY3kgZGlzdHJpYnV0aW9uIGNvcnB1cyBmcm9tIENTViBmaWxlLlxuICogQHBhcmFtIGZpbGUgQ1NWIGZpbGUgcGF0aFxuICogQHJldHVybnMgZnJlcXVlbmN5IGRpc3RyaWJ1dGlvbiBjb3JwdXNcbiAqL1xuYXN5bmMgZnVuY3Rpb24gbG9hZEZyb21Dc3YoZmlsZTogc3RyaW5nKSB7XG4gIGNvbnN0IG1hcCAgPSBuZXcgTWFwPG51bWJlciwgRnJlcXVlbmN5PigpO1xuICBjb25zdCBkYXRhID0gYXdhaXQgKGF3YWl0IGZldGNoKGZpbGUpKS50ZXh0KCk7XG4gIGNvbnN0IHJlY29yZHMgPSBjc3YucGFyc2UoZGF0YSwge3NraXBGaXJzdFJvdzogdHJ1ZSwgY29tbWVudDogXCIjXCJ9KTtcbiAgZm9yIChjb25zdCByIG9mIHJlY29yZHMpIHtcbiAgICBjb25zdCBzdGF0ZXMgICA9IHBhcnNlRmxvYXQoci5zdGF0ZXMpO1xuICAgIGNvbnN0IHNlbGVjdGVkID0gcGFyc2VGbG9hdChyLnNlbGVjdGVkKTtcbiAgICBjb25zdCBzYW1wbGVkICA9IHBhcnNlRmxvYXQoci5zYW1wbGVkKTtcbiAgICBjb25zdCBrZXkgPSBwYXJzZUZsb2F0KHIuZGlzdHJpY3RzLnNwbGl0KCctJylbMF0ucmVwbGFjZSgvXFxEL2csICcnKSk7XG4gICAgbWFwLnNldChrZXk9PT03MD8gNzEgOiBrZXksIHtkaXN0cmljdHM6IHIuZGlzdHJpY3RzLCBzdGF0ZXMsIHNlbGVjdGVkLCBzYW1wbGVkfSk7XG4gIH1cbiAgcmV0dXJuIG1hcDtcbn1cblxuXG4vKipcbiAqIExvYWQgdGhlIGZyZXF1ZW5jeSBkaXN0cmlidXRpb24gY29ycHVzIGZyb20gdGhlIGZpbGUuXG4gKiBAcmV0dXJucyBmcmVxdWVuY3kgZGlzdHJpYnV0aW9uIGNvcnB1c1xuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbG9hZEZyZXF1ZW5jeURpc3RyaWJ1dGlvbigpOiBQcm9taXNlPE1hcDxudW1iZXIsIEZyZXF1ZW5jeT4+IHtcbiAgaWYgKGNvcnB1cykgcmV0dXJuIGNvcnB1cztcbiAgY29ycHVzID0gYXdhaXQgbG9hZEZyb21Dc3YoZnJlcXVlbmN5RGlzdHJpYnV0aW9uQ3N2KCkpO1xuICByZXR1cm4gY29ycHVzO1xufVxuXG5cbi8qKlxuICogR2V0IHRoZSBwYXRoIHRvIHRoZSBmcmVxdWVuY3kgZGlzdHJpYnV0aW9uIENTViBmaWxlLlxuICogQHJldHVybnMgQ1NWIGZpbGUgVVJMXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmcmVxdWVuY3lEaXN0cmlidXRpb25Dc3YoKTogc3RyaW5nIHtcbiAgcmV0dXJuIGltcG9ydC5tZXRhLnJlc29sdmUoJy4vaW5kZXguY3N2Jyk7XG59XG5cblxuLyoqXG4gKiBPYnRhaW4gU1FMIGNvbW1hbmQgdG8gY3JlYXRlIGFuZCBwb3B1bGF0ZSB0aGUgZnJlcXVlbmN5IGRpc3RyaWJ1dGlvbiB0YWJsZS5cbiAqIEBwYXJhbSB0YWIgdGFibGUgbmFtZVxuICogQHBhcmFtIG9wdCBvcHRpb25zIGZvciB0aGUgdGFibGVcbiAqIEByZXR1cm5zIENSRUFURSBUQUJMRSwgSU5TRVJULCBDUkVBVEUgVklFVywgQ1JFQVRFIElOREVYIHN0YXRlbWVudHNcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGZyZXF1ZW5jeURpc3RyaWJ1dGlvblNxbCh0YWI6IHN0cmluZz1cImZyZXF1ZW5jeWRpc3RyaWJ1dGlvblwiLCBvcHQ6IFNldHVwVGFibGVPcHRpb25zPXt9KTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgcmV0dXJuIHNldHVwVGFibGUodGFiLCB7ZGlzdHJpY3RzOiBcIlRFWFRcIiwgc3RhdGVzOiBcIklOVFwiLCBzZWxlY3RlZDogXCJJTlRcIiwgc2FtcGxlZDogXCJJTlRcIn0sXG4gICAgKGF3YWl0IGxvYWRGcmVxdWVuY3lEaXN0cmlidXRpb24oKSkudmFsdWVzKCkgYXMgSXRlcmFibGU8Um93RGF0YT4sXG4gICAgT2JqZWN0LmFzc2lnbih7cGs6IFwiZGlzdHJpY3RzXCIsIGluZGV4OiB0cnVlLCB0c3ZlY3Rvcjoge2Rpc3RyaWN0czogXCJBXCJ9fSwgb3B0KSk7XG59XG5cblxuLyoqXG4gKiBGaW5kIG1hdGNoaW5nIGZyZXF1ZW5jeSBkaXN0cmlidXRpb24gZm9yIGEgZ2l2ZW4gbm8uIG9mIGRpc3RyaWN0cy5cbiAqIEBwYXJhbSBkaXMgbm8uIG9mIGRpc3RyaWN0c1xuICogQHJldHVybnMgYHtkaXN0cmljdHMsIHN0YXRlcywgc2VsZWN0ZWQsIHNhbXBsZWR9YCBpZiBmb3VuZCwgZWxzZSBudWxsXG4gKiBAZXhhbXBsZVxuICogYGBgamF2YXNjcmlwdFxuICogaWZjdDIwMTcuZnJlcXVlbmN5RGlzdHJpYnV0aW9uKDIpO1xuICogaWZjdDIwMTcuZnJlcXVlbmN5RGlzdHJpYnV0aW9uKDUpO1xuICogLy8g4oaSIHsgZGlzdHJpY3RzOiAnMS01Jywgc3RhdGVzOiA5LCBzZWxlY3RlZDogMSwgc2FtcGxlZDogOSB9XG4gKlxuICogaWZjdDIwMTcuZnJlcXVlbmN5RGlzdHJpYnV0aW9uKDMyKTtcbiAqIGlmY3QyMDE3LmZyZXF1ZW5jeURpc3RyaWJ1dGlvbigzNyk7XG4gKiAvLyDihpIgeyBkaXN0cmljdHM6ICczMS00MCcsIHN0YXRlczogNCwgc2VsZWN0ZWQ6IDUsIHNhbXBsZWQ6IDIwIH1cbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gZnJlcXVlbmN5RGlzdHJpYnV0aW9uKGRpczogbnVtYmVyKTogRnJlcXVlbmN5IHwgbnVsbCB7XG4gIGlmIChjb3JwdXMgPT0gbnVsbCkgcmV0dXJuIG51bGw7XG4gIGlmIChkaXMgPD0gNSkgIHJldHVybiBjb3JwdXMuZ2V0KDEpICB8fCBudWxsO1xuICBpZiAoZGlzIDw9IDEwKSByZXR1cm4gY29ycHVzLmdldCg2KSAgfHwgbnVsbDtcbiAgaWYgKGRpcyA+IDcwKSAgcmV0dXJuIGNvcnB1cy5nZXQoNzEpIHx8IG51bGw7XG4gIHJldHVybiBjb3JwdXMuZ2V0KE1hdGguZmxvb3IoKGRpcy0xKS8xMCkqMTAgKyAxKSB8fCBudWxsO1xufVxuLy8jZW5kcmVnaW9uXG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsc0NBQXNDO0FBQ3RDLDZDQUE2QztBQUM3Qyw2QkFBNkI7QUFDN0IsWUFBWSxTQUFVLFdBQVc7QUFDakMsU0FBOEMsVUFBVSxRQUFPLG1CQUFtQjtBQWlCbEYsWUFBWTtBQUtaLGlCQUFpQjtBQUNqQixJQUFJLFNBQXdDO0FBQzVDLFlBQVk7QUFLWixtQkFBbUI7QUFDbkI7Ozs7Q0FJQyxHQUNELGVBQWUsWUFBWSxJQUFZO0VBQ3JDLE1BQU0sTUFBTyxJQUFJO0VBQ2pCLE1BQU0sT0FBTyxNQUFNLENBQUMsTUFBTSxNQUFNLEtBQUssRUFBRSxJQUFJO0VBQzNDLE1BQU0sVUFBVSxJQUFJLEtBQUssQ0FBQyxNQUFNO0lBQUMsY0FBYztJQUFNLFNBQVM7RUFBRztFQUNqRSxLQUFLLE1BQU0sS0FBSyxRQUFTO0lBQ3ZCLE1BQU0sU0FBVyxXQUFXLEVBQUUsTUFBTTtJQUNwQyxNQUFNLFdBQVcsV0FBVyxFQUFFLFFBQVE7SUFDdEMsTUFBTSxVQUFXLFdBQVcsRUFBRSxPQUFPO0lBQ3JDLE1BQU0sTUFBTSxXQUFXLEVBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxPQUFPO0lBQ2hFLElBQUksR0FBRyxDQUFDLFFBQU0sS0FBSSxLQUFLLEtBQUs7TUFBQyxXQUFXLEVBQUUsU0FBUztNQUFFO01BQVE7TUFBVTtJQUFPO0VBQ2hGO0VBQ0EsT0FBTztBQUNUO0FBR0E7OztDQUdDLEdBQ0QsT0FBTyxlQUFlO0VBQ3BCLElBQUksUUFBUSxPQUFPO0VBQ25CLFNBQVMsTUFBTSxZQUFZO0VBQzNCLE9BQU87QUFDVDtBQUdBOzs7Q0FHQyxHQUNELE9BQU8sU0FBUztFQUNkLE9BQU8sWUFBWSxPQUFPLENBQUM7QUFDN0I7QUFHQTs7Ozs7Q0FLQyxHQUNELE9BQU8sZUFBZSx5QkFBeUIsTUFBWSx1QkFBdUIsRUFBRSxNQUF1QixDQUFDLENBQUM7RUFDM0csT0FBTyxXQUFXLEtBQUs7SUFBQyxXQUFXO0lBQVEsUUFBUTtJQUFPLFVBQVU7SUFBTyxTQUFTO0VBQUssR0FDdkYsQ0FBQyxNQUFNLDJCQUEyQixFQUFFLE1BQU0sSUFDMUMsT0FBTyxNQUFNLENBQUM7SUFBQyxJQUFJO0lBQWEsT0FBTztJQUFNLFVBQVU7TUFBQyxXQUFXO0lBQUc7RUFBQyxHQUFHO0FBQzlFO0FBR0E7Ozs7Ozs7Ozs7Ozs7O0NBY0MsR0FDRCxPQUFPLFNBQVMsc0JBQXNCLEdBQVc7RUFDL0MsSUFBSSxVQUFVLE1BQU0sT0FBTztFQUMzQixJQUFJLE9BQU8sR0FBSSxPQUFPLE9BQU8sR0FBRyxDQUFDLE1BQU87RUFDeEMsSUFBSSxPQUFPLElBQUksT0FBTyxPQUFPLEdBQUcsQ0FBQyxNQUFPO0VBQ3hDLElBQUksTUFBTSxJQUFLLE9BQU8sT0FBTyxHQUFHLENBQUMsT0FBTztFQUN4QyxPQUFPLE9BQU8sR0FBRyxDQUFDLEtBQUssS0FBSyxDQUFDLENBQUMsTUFBSSxDQUFDLElBQUUsTUFBSSxLQUFLLE1BQU07QUFDdEQsRUFDQSxZQUFZIn0=
@@ -0,0 +1,14 @@
1
+ Indian Food Composition Tables 2017
2
+ T. Longvah, R. Ananthan, K. Bhaskarachary and K. Venkaiah
3
+
4
+ Copyright © 2017 by National Institute of Nutrition
5
+ Indian Council of Medical Research
6
+ Department of Health Research Ministry of Health and Family Welfare, Government of India
7
+ Jamai Osmania (PO), Hyderabad – 500 007
8
+ Telangana, India Phone: +91 40 27197334, Fax: +91 40 27000339, Email: nin@ap.nic.in
9
+
10
+ FREQUENCY DISTRIBUTION OF STATES/UTS FOR FIXING THE NUMBER OF DISTRICTS TO BE SAMPLED
11
+ - No. of Districts
12
+ - No. of States/UTs
13
+ - No. of districts to be selected from each State/UT
14
+ - Total No. of districts to be sampled
@@ -0,0 +1,21 @@
1
+ code,group,entries,tags
2
+ A,Cereals and Millets,24,vegetarian eggetarian fishetarian veg
3
+ B,Grain Legumes,25,vegetarian eggetarian fishetarian veg
4
+ C,Green Leafy Vegetables,34,vegetarian eggetarian fishetarian veg
5
+ D,Other Vegetables,78,vegetarian eggetarian fishetarian veg
6
+ E,Fruits,68,vegetarian eggetarian fishetarian veg
7
+ F,Roots and Tubers,19,vegetarian eggetarian fishetarian veg
8
+ G,Condiments and Spices,33,vegetarian eggetarian fishetarian veg
9
+ H,Nuts and Oil Seeds,21,vegetarian eggetarian fishetarian veg
10
+ I,Sugars,2,vegetarian eggetarian fishetarian veg
11
+ J,Mushrooms,4,vegetarian eggetarian fishetarian veg
12
+ K,Miscellaneous Foods,2,vegetarian eggetarian fishetarian veg
13
+ L,Milk and Milk Products,4,vegetarian eggetarian fishetarian veg
14
+ M,Egg and Egg Products,15,eggetarian fishetarian nonveg
15
+ N,Poultry,19,nonveg
16
+ O,Animal Meat,63,nonveg
17
+ P,Marine Fish,92,fishetarian nonveg
18
+ Q,Marine Shellfish,8,fishetarian nonveg
19
+ R,Marine Mollusks,7,fishetarian nonveg
20
+ S,Fresh Water Fish and Shellfish,10,fishetarian nonveg
21
+ T,Edible Oils and Fats,9,vegetarian eggetarian fishetarian veg
@@ -0,0 +1,46 @@
1
+ import { type SetupTableOptions } from "@nodef/extra-sql";
2
+ /** Categorization of food by its common names. */ export interface Group {
3
+ /** Code. */ code: string;
4
+ /** Food groups. */ group: string;
5
+ /** No. of food entries. */ entries: number;
6
+ /** Tags. */ tags: string;
7
+ }
8
+ /**
9
+ * Load the groups corpus from the file.
10
+ * @returns groups corpus
11
+ */ export declare function loadGroups(): Promise<Map<string, Group>>;
12
+ /**
13
+ * Get the path to the groups CSV file.
14
+ * @returns CSV file URL
15
+ */ export declare function groupsCsv(): string;
16
+ /**
17
+ * Obtain SQL command to create and populate the groups table.
18
+ * @param tab table name
19
+ * @param opt options for the table
20
+ * @returns CREATE TABLE, INSERT, CREATE VIEW, CREATE INDEX statements
21
+ */ export declare function groupsSql(tab?: string, opt?: SetupTableOptions): Promise<string>;
22
+ /**
23
+ * Find matching groups of an code/group/tags query.
24
+ * @param txt code/group/tags query
25
+ * @returns matches `[{code, group, entries, tags}]`
26
+ * @example
27
+ * ```javascript
28
+ * ifct2017.groups('cereals');
29
+ * ifct2017.groups('Millet');
30
+ * // → [ { code: 'A',
31
+ * // → group: 'Cereals and Millets',
32
+ * // → entries: 24,
33
+ * // → tags: 'vegetarian eggetarian fishetarian veg' } ]
34
+ *
35
+ * ifct2017.groups('what is vegetable?');
36
+ * ifct2017.groups('vegetable group code?');
37
+ * // → [ { code: 'D',
38
+ * // → group: 'Other Vegetables',
39
+ * // → entries: 78,
40
+ * // → tags: 'vegetarian eggetarian fishetarian veg' },
41
+ * // → { code: 'C',
42
+ * // → group: 'Green Leafy Vegetables',
43
+ * // → entries: 34,
44
+ * // → tags: 'vegetarian eggetarian fishetarian veg' } ]
45
+ * ```
46
+ */ export declare function groups(txt: string): Group[];