tigertag 1.0.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.
@@ -0,0 +1,132 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ // TigerTag RFID Guide
5
+ // Copyright (C) 2025 TigerTag
6
+ //
7
+ // This program is free software: you can redistribute it and/or modify
8
+ // it under the terms of the GNU General Public License as published by
9
+ // the Free Software Foundation, either version 3 of the License.
10
+
11
+ const fs = require('fs');
12
+ const path = require('path');
13
+
14
+ const { TigerTag, TigerTagDB, SignatureResult, syncDatabases } = require('../src/index');
15
+ const { _BUNDLED_DB_PATH } = require('../src/db');
16
+
17
+ const VERSION = require('../package.json').version;
18
+
19
+ const HELP = `
20
+ Usage: tigertag [dump.bin] [options]
21
+
22
+ Parse, verify, and export TigerTag RFID chip dumps.
23
+
24
+ Arguments:
25
+ dump.bin Binary .bin file to parse
26
+
27
+ Options:
28
+ --db <path> Database folder (default: bundled database)
29
+ --json Output as JSON
30
+ --raw Raw protocol fields, no DB lookup
31
+ --no-sync Do not auto-download databases
32
+ --sync-only Update databases and exit
33
+ --version Show version
34
+ -h, --help Show this help
35
+
36
+ Dump formats:
37
+ 180 bytes Full chip dump (pages 0-44): UID auto-extracted, signature verifiable
38
+ 144 bytes User data + signature (pages 0x04-0x27)
39
+ 80 bytes User data only (pages 0x04-0x17)
40
+
41
+ Examples:
42
+ tigertag dump.bin Parse + human-readable output
43
+ tigertag dump.bin --json Output as JSON
44
+ tigertag dump.bin --raw Raw protocol fields, no DB lookup
45
+ tigertag --sync-only Update reference databases and exit
46
+
47
+ Spec: https://github.com/TigerTag-Project/TigerTag-RFID-Guide
48
+ `.trim();
49
+
50
+ function parseArgs(argv) {
51
+ const args = { dump: null, db: null, json: false, raw: false, noSync: false, syncOnly: false };
52
+ for (let i = 0; i < argv.length; i++) {
53
+ const a = argv[i];
54
+ if (a === '--json') args.json = true;
55
+ else if (a === '--raw') args.raw = true;
56
+ else if (a === '--no-sync') args.noSync = true;
57
+ else if (a === '--sync-only') args.syncOnly = true;
58
+ else if (a === '--version') { console.log(`tigertag ${VERSION}`); process.exit(0); }
59
+ else if (a === '-h' || a === '--help') { console.log(HELP); process.exit(0); }
60
+ else if (a === '--db') args.db = argv[++i];
61
+ else if (!a.startsWith('-')) args.dump = a;
62
+ }
63
+ return args;
64
+ }
65
+
66
+ async function main() {
67
+ const args = parseArgs(process.argv.slice(2));
68
+ const dbPath = args.db ? path.resolve(args.db) : _BUNDLED_DB_PATH;
69
+
70
+ if (args.syncOnly) {
71
+ try {
72
+ const updated = await syncDatabases(dbPath, { verbose: true });
73
+ if (updated.length > 0) {
74
+ console.log(`\nUpdated ${updated.length} file(s): ${updated.join(', ')}`);
75
+ } else {
76
+ console.log('\nAll databases already up to date.');
77
+ }
78
+ } catch (err) {
79
+ process.stderr.write(`Error: ${err.message}\n`);
80
+ process.exit(1);
81
+ }
82
+ return;
83
+ }
84
+
85
+ if (!args.dump) {
86
+ console.log(HELP);
87
+ return;
88
+ }
89
+
90
+ let raw;
91
+ try {
92
+ raw = fs.readFileSync(args.dump);
93
+ } catch (_) {
94
+ process.stderr.write(`Error: file not found: ${args.dump}\n`);
95
+ process.exit(1);
96
+ }
97
+
98
+ let tag;
99
+ try {
100
+ tag = TigerTag.fromDump(raw);
101
+ } catch (err) {
102
+ process.stderr.write(`Error: ${err.message}\n`);
103
+ process.exit(1);
104
+ }
105
+
106
+ for (const w of tag.validate()) {
107
+ process.stderr.write(`Warning: ${w}\n`);
108
+ }
109
+
110
+ if (args.raw) {
111
+ console.log(JSON.stringify(tag.toRawDict(), null, 2));
112
+ return;
113
+ }
114
+
115
+ const db = new TigerTagDB({ dbPath });
116
+ const sigResult = tag.isSigned
117
+ ? tag.verify(db)
118
+ : new SignatureResult(SignatureResult.UNSIGNED);
119
+
120
+ if (args.json) {
121
+ const d = tag.toDict(db);
122
+ d.signature = sigResult.toDict();
123
+ console.log(JSON.stringify(d, null, 2, (_, v) => typeof v === 'bigint' ? v.toString() : v));
124
+ } else {
125
+ console.log(tag.pretty(db, sigResult));
126
+ }
127
+ }
128
+
129
+ main().catch((err) => {
130
+ process.stderr.write(`Error: ${err.message}\n`);
131
+ process.exit(1);
132
+ });
@@ -0,0 +1 @@
1
+ [{"id":0,"label":"-","color_count":0},{"id":21,"label":"Clear","color_count":1},{"id":24,"label":"Tricolor","color_count":3},{"id":64,"label":"Glitter","color_count":1},{"id":67,"label":"Translucent","color_count":1},{"id":91,"label":"Glow in the Dark","color_count":1},{"id":92,"label":"Silk","color_count":1},{"id":97,"label":"Lithophane","color_count":1},{"id":104,"label":"Basic","color_count":1},{"id":123,"label":"Wood","color_count":1},{"id":126,"label":"Pearl","color_count":1},{"id":129,"label":"Gloss","color_count":1},{"id":134,"label":"Satin","color_count":1},{"id":145,"label":"Rainbow","color_count":3},{"id":168,"label":"Thermoreactif","color_count":1},{"id":173,"label":"Stone","color_count":1},{"id":216,"label":"Neon","color_count":1},{"id":220,"label":"Pastel","color_count":1},{"id":232,"label":"Marble","color_count":1},{"id":238,"label":"Carbon","color_count":1},{"id":247,"label":"Matt","color_count":1},{"id":252,"label":"Bicolor","color_count":2},{"id":255,"label":"None","color_count":0}]
@@ -0,0 +1 @@
1
+ [{"id":1,"name":"Atome3D","type_ids":[142,173]},{"id":1068,"name":"SainSmart","type_ids":[142]},{"id":1120,"name":"Proto-Pasta","type_ids":[142]},{"id":1421,"name":"3DJake","type_ids":[142]},{"id":2517,"name":"Smart Materials 3D","type_ids":[142]},{"id":2833,"name":"Xstrand","type_ids":[142]},{"id":3132,"name":"Hatchbox","type_ids":[142]},{"id":3924,"name":"FiloAlfa","type_ids":[142]},{"id":4011,"name":"QIDI Tech","type_ids":[142]},{"id":4048,"name":"Owa","type_ids":[142]},{"id":4344,"name":"MatterHackers","type_ids":[142]},{"id":4356,"name":"Landu","type_ids":[142]},{"id":4565,"name":"Valment","type_ids":[142]},{"id":4700,"name":"Filforme","type_ids":[142]},{"id":6305,"name":"Markforged","type_ids":[142]},{"id":7432,"name":"Aliz","type_ids":[142]},{"id":7674,"name":"Extrudr","type_ids":[142]},{"id":7812,"name":"Jayo","type_ids":[142]},{"id":7980,"name":"Fillamentum","type_ids":[142]},{"id":8182,"name":"Fiberlogy","type_ids":[142]},{"id":8303,"name":"GST3D","type_ids":[142]},{"id":8384,"name":"Taulman3D","type_ids":[142]},{"id":8496,"name":"CaiLab","type_ids":[142]},{"id":8586,"name":"NinjaTek","type_ids":[142]},{"id":8675,"name":"SOVB 3D","type_ids":[142]},{"id":8756,"name":"BlueCast","type_ids":[173]},{"id":8921,"name":"Duramic 3D","type_ids":[142]},{"id":8990,"name":"Ice Filaments","type_ids":[142]},{"id":9192,"name":"3D Solutech","type_ids":[142]},{"id":9299,"name":"FDPlast","type_ids":[142]},{"id":9394,"name":"Gizmo Dorks","type_ids":[142]},{"id":9596,"name":"Ziro","type_ids":[142]},{"id":9798,"name":"AMOLEN","type_ids":[142]},{"id":11379,"name":"Filaments.ca","type_ids":[142]},{"id":11429,"name":"3D4Makers","type_ids":[142]},{"id":11501,"name":"InnovateFil","type_ids":[142]},{"id":12345,"name":"MakerBot","type_ids":[142]},{"id":12498,"name":"Forshape","type_ids":[142]},{"id":12635,"name":"Snapmaker","type_ids":[142]},{"id":13667,"name":"RS Pro","type_ids":[142]},{"id":14250,"name":"Jessie (Printed Solid)","type_ids":[142]},{"id":14982,"name":"3D-Fuel","type_ids":[142]},{"id":15899,"name":"Kimya","type_ids":[142]},{"id":15962,"name":"Anycubic","type_ids":[142,173]},{"id":18629,"name":"PrintoMax 3D","type_ids":[142]},{"id":19265,"name":"CC3D","type_ids":[142]},{"id":19961,"name":"Rosa3D","type_ids":[142]},{"id":20523,"name":"Raise3D","type_ids":[142,173]},{"id":20851,"name":"Tronxy","type_ids":[142]},{"id":22652,"name":"Spectrum","type_ids":[142]},{"id":23181,"name":"ArianePlast","type_ids":[142]},{"id":23456,"name":"Monoprice","type_ids":[142]},{"id":24363,"name":"Tecbears","type_ids":[142]},{"id":26379,"name":"Formlabs","type_ids":[173]},{"id":26595,"name":"Sovol","type_ids":[142]},{"id":26956,"name":"Creality","type_ids":[142,173]},{"id":28055,"name":"TAGin3D","type_ids":[142]},{"id":28136,"name":"Polar Filament","type_ids":[142]},{"id":28940,"name":"Eryone","type_ids":[142]},{"id":28988,"name":"KINGROON","type_ids":[142]},{"id":29045,"name":"Yousu","type_ids":[142]},{"id":29302,"name":"IIIDMAX","type_ids":[142]},{"id":31438,"name":"Wondermaker","type_ids":[142]},{"id":32348,"name":"Addnorth","type_ids":[142]},{"id":32587,"name":"Amazon","type_ids":[142]},{"id":33566,"name":"Siraya Tech","type_ids":[142,173]},{"id":33594,"name":"DEEPLEE","type_ids":[142]},{"id":33788,"name":"Verbatim","type_ids":[142]},{"id":34567,"name":"Push Plastic","type_ids":[142]},{"id":34597,"name":"EconoFil","type_ids":[142]},{"id":35123,"name":"Bambu Lab","type_ids":[142]},{"id":35501,"name":"Zortrax","type_ids":[142]},{"id":35857,"name":"Nobufil","type_ids":[142]},{"id":35882,"name":"Phrozen","type_ids":[142,173]},{"id":36702,"name":"Tianse","type_ids":[142]},{"id":37434,"name":"Winkle","type_ids":[142]},{"id":38533,"name":"Lotactree","type_ids":[142]},{"id":39002,"name":"GreenGate3D","type_ids":[142]},{"id":39382,"name":"Longer","type_ids":[142]},{"id":39652,"name":"3DXTech","type_ids":[142]},{"id":41847,"name":"OneFil","type_ids":[142]},{"id":41932,"name":"Jamg He","type_ids":[173,142]},{"id":42911,"name":"UltiMaker","type_ids":[142]},{"id":44630,"name":"NIT","type_ids":[142]},{"id":45670,"name":"Panchroma","type_ids":[142]},{"id":45678,"name":"Atomic Filament","type_ids":[142]},{"id":46010,"name":"AceAddity","type_ids":[142,173]},{"id":46203,"name":"Overture","type_ids":[142]},{"id":46392,"name":"Prusament","type_ids":[142,173]},{"id":47560,"name":"Wanhao","type_ids":[142]},{"id":47930,"name":"eSun","type_ids":[142,173]},{"id":48261,"name":"Gsun3D","type_ids":[142]},{"id":48804,"name":"R3D","type_ids":[142]},{"id":49784,"name":"GIANTARN","type_ids":[142]},{"id":50311,"name":"G3D Pro","type_ids":[142,173]},{"id":50604,"name":"Polymaker","type_ids":[142]},{"id":51139,"name":"FusRock","type_ids":[142]},{"id":51443,"name":"BASF","type_ids":[142,173]},{"id":51857,"name":"Sunlu","type_ids":[142,173]},{"id":52222,"name":"ColorFabb","type_ids":[142]},{"id":52467,"name":"Geeetech","type_ids":[142]},{"id":52757,"name":"Yumi","type_ids":[142]},{"id":53043,"name":"FormFutura","type_ids":[142,173]},{"id":53640,"name":"Magigoo","type_ids":[142]},{"id":53856,"name":"Lattice Medical","type_ids":[142]},{"id":54112,"name":"Kexcelled","type_ids":[142]},{"id":55229,"name":"Filament PM","type_ids":[142]},{"id":55763,"name":"Nanovia","type_ids":[142]},{"id":55869,"name":"Biqu","type_ids":[142]},{"id":56780,"name":"Fiberon","type_ids":[142]},{"id":56789,"name":"Coex 3D","type_ids":[142]},{"id":57209,"name":"FrancoFil","type_ids":[142]},{"id":57632,"name":"ELEGOO","type_ids":[142,173]},{"id":58231,"name":"IC3D","type_ids":[142]},{"id":58410,"name":"AzureFilm","type_ids":[142]},{"id":58972,"name":"Tinmorry","type_ids":[142]},{"id":59597,"name":"Filamentive","type_ids":[142]},{"id":60882,"name":"Recreus","type_ids":[142]},{"id":62436,"name":"Ambrosia","type_ids":[142]},{"id":63024,"name":"Multicomp Pro","type_ids":[142]},{"id":63340,"name":"Flashforge","type_ids":[142]},{"id":65535,"name":"Generic","type_ids":[142,173]}]
@@ -0,0 +1 @@
1
+ [{"id":56,"label":"1.75"},{"id":221,"label":"2.85"}]
@@ -0,0 +1 @@
1
+ [{"id":18775,"label":"PE-CF","material_type":"PE","filled_type":"CF","density":1.1,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":175,"nozzleTempMax":220,"dryTemp":80,"dryTime":12,"bedTempMin":55,"bedTempMax":60},"metadata":{"bambuID":"GFP98"}},{"id":34944,"label":"PETG-GF","material_type":"","filled_type":null,"density":null,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":230,"nozzleTempMax":270,"dryTemp":70,"dryTime":8,"bedTempMin":70,"bedTempMax":90},"metadata":{"bambuID":"GFG50","crealityID":"00014","crealityPressureAdvance":0.03}},{"id":9691,"label":"EVA","material_type":"EVA","filled_type":null,"density":0.94,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":175,"nozzleTempMax":220,"dryTemp":50,"dryTime":4,"bedTempMin":55,"bedTempMax":60},"metadata":{"bambuID":"GFR99"}},{"id":49804,"label":"ASA-AF","material_type":"ASA","filled_type":"AF","density":null,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":250,"nozzleTempMax":280,"dryTemp":80,"dryTime":8,"bedTempMin":90,"bedTempMax":95},"metadata":{"bambuID":"GFB51"}},{"id":7951,"label":"PETG-rCF","material_type":"PETG","filled_type":"CF","density":1.27,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":240,"nozzleTempMax":270,"dryTemp":70,"dryTime":8,"bedTempMin":65,"bedTempMax":70},"metadata":{"bambuID":"GFG98","crealityID":"00014","crealityPressureAdvance":0.03}},{"id":11053,"label":"PET-CF","material_type":"PET","filled_type":"CF","density":1.3,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":260,"nozzleTempMax":290,"dryTemp":85,"dryTime":12,"bedTempMin":90,"bedTempMax":95},"metadata":{"bambuID":"GFG99","crealityID":"00013","crealityPressureAdvance":0.03}},{"id":53890,"label":"PCTG-CF","material_type":"PCTG","filled_type":"CF","density":null,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":240,"nozzleTempMax":270,"dryTemp":65,"dryTime":8,"bedTempMin":70,"bedTempMax":75},"metadata":{"crealityID":"00014","crealityPressureAdvance":0.03,"bambuID":"GFG97"}},{"id":51636,"label":"PES","material_type":"","filled_type":null,"density":null,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":340,"nozzleTempMax":380,"dryTemp":120,"dryTime":6,"bedTempMin":120,"bedTempMax":140},"metadata":{"crealityID":"00001","crealityPressureAdvance":0.04,"bambuID":"GFA00"}},{"id":18130,"label":"PS","material_type":"PS","filled_type":null,"density":1.05,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":220,"nozzleTempMax":260,"dryTemp":75,"dryTime":2,"bedTempMin":60,"bedTempMax":100},"metadata":{}},{"id":9456,"label":"PLA Marble","material_type":"PLA","filled_type":null,"density":1.24,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":190,"nozzleTempMax":260,"dryTemp":50,"dryTime":8,"bedTempMin":45,"bedTempMax":55},"metadata":{"bambuID":"GFA07"}},{"id":27676,"label":"ASA-CF","material_type":"ASA","filled_type":"CF","density":1.05,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":250,"nozzleTempMax":280,"dryTemp":80,"dryTime":8,"bedTempMin":90,"bedTempMax":95},"metadata":{"bambuID":"GFB51","crealityID":"00007","crealityPressureAdvance":0.06}},{"id":30594,"label":"PA-GF","material_type":"PA","filled_type":"GF","density":1.52,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":260,"nozzleTempMax":300,"dryTemp":85,"dryTime":12,"bedTempMin":40,"bedTempMax":45},"metadata":{}},{"id":58142,"label":"TPU-GF","material_type":"TPU","filled_type":"GF","density":null,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":200,"nozzleTempMax":250,"dryTemp":75,"dryTime":8,"bedTempMin":35,"bedTempMax":40},"metadata":{"crealityID":"00005","crealityPressureAdvance":0.04,"bambuID":"GFU99"}},{"id":24270,"label":"PPS-CF","material_type":"PPS","filled_type":"CF","density":1.38,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":310,"nozzleTempMax":340,"dryTemp":130,"dryTime":12,"bedTempMin":110,"bedTempMax":115},"metadata":{"crealityID":"00018","bambuID":"GFT98"}},{"id":48001,"label":"PLA Wood","material_type":"PLA","filled_type":"Wood","density":1.28,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":190,"nozzleTempMax":240,"dryTemp":60,"dryTime":8,"bedTempMin":45,"bedTempMax":55},"metadata":{"crealityID":"17001","crealityPressureAdvance":0.04,"bambuID":"GFA16"}},{"id":56527,"label":"PEI-1010","material_type":"PEI-1010","filled_type":null,"density":1.27,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":370,"nozzleTempMax":420,"dryTemp":130,"dryTime":12,"bedTempMin":150,"bedTempMax":160},"metadata":{}},{"id":24116,"label":"TPC","material_type":"TPC","filled_type":null,"density":1.15,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":220,"nozzleTempMax":245,"dryTemp":75,"dryTime":8,"bedTempMin":60,"bedTempMax":90},"metadata":{}},{"id":57469,"label":"PETG HF","material_type":"PETG","filled_type":null,"density":1.27,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":220,"nozzleTempMax":270,"dryTemp":70,"dryTime":8,"bedTempMin":70,"bedTempMax":75},"metadata":{"bambuID":"GFG96","crealityID":"06002","crealityPressureAdvance":0.05}},{"id":46591,"label":"PLA+","material_type":"PLA","filled_type":null,"density":1.24,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":190,"nozzleTempMax":240,"dryTemp":50,"dryTime":8,"bedTempMin":45,"bedTempMax":55},"metadata":{"bambuID":"GFL03","crealityID":"09001","crealityPressureAdvance":0.04}},{"id":425,"label":"ABS-CF","material_type":"ABS","filled_type":"CF","density":1.04,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":240,"nozzleTempMax":280,"dryTemp":80,"dryTime":8,"bedTempMin":85,"bedTempMax":90},"metadata":{"bambuID":"GFB99","crealityID":"00004","crealityPressureAdvance":0.06}},{"id":42962,"label":"PP-GF","material_type":"PP","filled_type":"GF","density":0.9,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":220,"nozzleTempMax":250,"dryTemp":60,"dryTime":4,"bedTempMin":55,"bedTempMax":60},"metadata":{"bambuID":"GFP95"}},{"id":10122,"label":"PEKK-CF","material_type":"","filled_type":null,"density":null,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":350,"nozzleTempMax":400,"dryTemp":120,"dryTime":6,"bedTempMin":120,"bedTempMax":140},"metadata":{"crealityID":"00001","crealityPressureAdvance":0.04,"bambuID":"GFA00"}},{"id":27268,"label":"PCTPE","material_type":"PCPTFE","filled_type":null,"density":1.01,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":235,"nozzleTempMax":245,"dryTemp":90,"dryTime":3,"bedTempMin":50,"bedTempMax":55},"metadata":{}},{"id":59328,"label":"PA","material_type":"PA","filled_type":null,"density":1.52,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":240,"nozzleTempMax":280,"dryTemp":85,"dryTime":12,"bedTempMin":100,"bedTempMax":105},"metadata":{"bambuID":"GFN99","crealityID":"00008","crealityPressureAdvance":0.058}},{"id":18703,"label":"PETP","material_type":"PET","filled_type":null,"density":1.38,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":220,"nozzleTempMax":260,"dryTemp":70,"dryTime":8,"bedTempMin":90,"bedTempMax":95},"metadata":{}},{"id":33958,"label":"TPE","material_type":"TPE","filled_type":null,"density":1,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":210,"nozzleTempMax":260,"dryTemp":65,"dryTime":8,"bedTempMin":45,"bedTempMax":60},"metadata":{}},{"id":48310,"label":"PLA-CF","material_type":"PLA","filled_type":"CF","density":1.24,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":190,"nozzleTempMax":240,"dryTemp":60,"dryTime":8,"bedTempMin":45,"bedTempMax":55},"metadata":{"bambuID":"GFL98","crealityID":"00006","crealityPressureAdvance":0.05}},{"id":31011,"label":"ASA-AERO","material_type":"ASA","filled_type":"AERO","density":1.05,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":240,"nozzleTempMax":280,"dryTemp":80,"dryTime":8,"bedTempMin":95,"bedTempMax":100},"metadata":{"bambuID":"GFB02"}},{"id":27635,"label":"PE","material_type":"PE","filled_type":null,"density":0.94,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":175,"nozzleTempMax":220,"dryTemp":0,"dryTime":0,"bedTempMin":55,"bedTempMax":60},"metadata":{"bambuID":"GFP99"}},{"id":42623,"label":"PMMA","material_type":"PMMA","filled_type":null,"density":1.18,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":240,"nozzleTempMax":265,"dryTemp":80,"dryTime":4,"bedTempMin":100,"bedTempMax":110},"metadata":{}},{"id":24629,"label":"PLA High Speed","material_type":"PLA","filled_type":null,"density":1.24,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":190,"nozzleTempMax":240,"dryTemp":50,"dryTime":8,"bedTempMin":45,"bedTempMax":55},"metadata":{"bambuID":"GFL95","crealityID":"01001","crealityPressureAdvance":0.04}},{"id":65535,"label":"None","material_type":"None","filled_type":null,"density":null,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":0,"nozzleTempMax":0,"dryTemp":0,"dryTime":0,"bedTempMin":0,"bedTempMax":0},"metadata":{}},{"id":3368,"label":"PC-ABS","material_type":"PC","filled_type":null,"density":1.19,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":240,"nozzleTempMax":290,"dryTemp":85,"dryTime":8,"bedTempMin":90,"bedTempMax":95},"metadata":{}},{"id":50206,"label":"POM","material_type":"POM","filled_type":null,"density":1.4,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":230,"nozzleTempMax":250,"dryTemp":75,"dryTime":3,"bedTempMin":90,"bedTempMax":110},"metadata":{}},{"id":43518,"label":"TPU","material_type":"TPU","filled_type":null,"density":1.21,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":200,"nozzleTempMax":250,"dryTemp":75,"dryTime":8,"bedTempMin":35,"bedTempMax":40},"metadata":{"bambuID":"GFU99","crealityID":"00005","crealityPressureAdvance":0.04}},{"id":7649,"label":"PETG HS","material_type":"PETG","filled_type":null,"density":1.27,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":220,"nozzleTempMax":270,"dryTemp":70,"dryTime":8,"bedTempMin":70,"bedTempMax":75},"metadata":{"bambuID":"GFG96","crealityID":"06002","crealityPressureAdvance":0.05}},{"id":45962,"label":"PVB","material_type":"PVB","filled_type":null,"density":1.07,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":205,"nozzleTempMax":225,"dryTemp":45,"dryTime":8,"bedTempMin":30,"bedTempMax":70},"metadata":{}},{"id":12216,"label":"PEEK-GF","material_type":"","filled_type":null,"density":null,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":380,"nozzleTempMax":420,"dryTemp":120,"dryTime":6,"bedTempMin":130,"bedTempMax":160},"metadata":{"crealityID":"00001","crealityPressureAdvance":0.04,"bambuID":"GFA00"}},{"id":30884,"label":"PP","material_type":"PP","filled_type":null,"density":0.9,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":220,"nozzleTempMax":250,"dryTemp":60,"dryTime":4,"bedTempMin":55,"bedTempMax":60},"metadata":{"bambuID":"GFP97","crealityID":"00019","crealityPressureAdvance":0.4}},{"id":39944,"label":"PA-CF","material_type":"PA","filled_type":"CF","density":1.52,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":260,"nozzleTempMax":300,"dryTemp":85,"dryTime":12,"bedTempMin":100,"bedTempMax":105},"metadata":{"bambuID":"GFN98","crealityID":"00009","crealityPressureAdvance":0.044}},{"id":1173,"label":"PA6-GF","material_type":"PA6","filled_type":"GF","density":1.52,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":260,"nozzleTempMax":300,"dryTemp":85,"dryTime":12,"bedTempMin":40,"bedTempMax":45},"metadata":{"bambuID":"GFN08"}},{"id":62335,"label":"PEI-1010-CF","material_type":"PEI-1010","filled_type":"CF","density":null,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":370,"nozzleTempMax":430,"dryTemp":150,"dryTime":8,"bedTempMin":80,"bedTempMax":100},"metadata":{}},{"id":51007,"label":"Biopolymer","material_type":"","filled_type":null,"density":null,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":190,"nozzleTempMax":240,"dryTemp":50,"dryTime":8,"bedTempMin":45,"bedTempMax":5},"metadata":{"bambuID":"GFL99","crealityID":"00001","crealityPressureAdvance":0.04}},{"id":8394,"label":"Castable Resin","material_type":"","filled_type":null,"density":1.05,"filled":false,"product_type_id":173,"recommended":{"washTime":0,"postCuringTemp":0,"postCuringTime":0,"workTempMin":0,"workTempMax":0},"metadata":{}},{"id":24115,"label":"SEBS","material_type":"SEBS","filled_type":null,"density":0.9,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":245,"nozzleTempMax":260,"dryTemp":65,"dryTime":3,"bedTempMin":70,"bedTempMax":80},"metadata":{}},{"id":56666,"label":"PA6","material_type":"PA6","filled_type":null,"density":1.52,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":240,"nozzleTempMax":280,"dryTemp":85,"dryTime":12,"bedTempMin":100,"bedTempMax":105},"metadata":{"bambuID":"GFN05","crealityID":"00015","crealityPressureAdvance":0.044}},{"id":48469,"label":"PEEK-CF","material_type":"","filled_type":null,"density":null,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":380,"nozzleTempMax":420,"dryTemp":120,"dryTime":6,"bedTempMin":130,"bedTempMax":160},"metadata":{"crealityID":"00001","crealityPressureAdvance":0.04,"bambuID":"GFA00"}},{"id":35100,"label":"ASA-GF","material_type":"ASA","filled_type":"GF","density":null,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":250,"nozzleTempMax":280,"dryTemp":80,"dryTime":8,"bedTempMin":90,"bedTempMax":95},"metadata":{"bambuID":"GFB51","crealityID":"00007","crealityPressureAdvance":0.06}},{"id":14508,"label":"PEI-9085","material_type":"","filled_type":null,"density":null,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":350,"nozzleTempMax":390,"dryTemp":150,"dryTime":12,"bedTempMin":120,"bedTempMax":160},"metadata":{"crealityID":"00001","crealityPressureAdvance":0.04,"bambuID":"GFA00"}},{"id":5238,"label":"PETG-PTFE","material_type":"PETG","filled_type":null,"density":null,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":230,"nozzleTempMax":255,"dryTemp":55,"dryTime":6,"bedTempMin":70,"bedTempMax":80},"metadata":{"bambuID":"GFG50","crealityID":"00014","crealityPressureAdvance":0.03}},{"id":54568,"label":"ASA+","material_type":"ASA","filled_type":null,"density":null,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":250,"nozzleTempMax":280,"dryTemp":65,"dryTime":8,"bedTempMin":90,"bedTempMax":110},"metadata":{}},{"id":9483,"label":"PVA","material_type":"PVA","filled_type":null,"density":1.23,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":190,"nozzleTempMax":240,"dryTemp":85,"dryTime":12,"bedTempMin":30,"bedTempMax":60},"metadata":{"bambuID":"GFS99","crealityID":"00011"}},{"id":10272,"label":"PSU","material_type":"PSU","filled_type":null,"density":1.24,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":360,"nozzleTempMax":400,"dryTemp":110,"dryTime":4,"bedTempMin":140,"bedTempMax":160},"metadata":{}},{"id":41134,"label":"PEI-9085-CF","material_type":"","filled_type":null,"density":null,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":360,"nozzleTempMax":400,"dryTemp":150,"dryTime":12,"bedTempMin":120,"bedTempMax":160},"metadata":{"crealityID":"00001","crealityPressureAdvance":0.04,"bambuID":"GFA00"}},{"id":12844,"label":"ASA","material_type":"ASA","filled_type":null,"density":1.05,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":240,"nozzleTempMax":280,"dryTemp":80,"dryTime":8,"bedTempMin":95,"bedTempMax":100},"metadata":{"bambuID":"GFB98","crealityID":"00007","crealityPressureAdvance":0.06}},{"id":63946,"label":"TPI","material_type":"TPI","filled_type":null,"density":1.38,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":360,"nozzleTempMax":390,"dryTemp":120,"dryTime":24,"bedTempMin":0,"bedTempMax":0},"metadata":{}},{"id":55279,"label":"PBT","material_type":"PBT","filled_type":null,"density":1.2,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":235,"nozzleTempMax":245,"dryTemp":75,"dryTime":6,"bedTempMin":0,"bedTempMax":0},"metadata":{}},{"id":20073,"label":"PVC","material_type":"PVC","filled_type":null,"density":1.38,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":215,"nozzleTempMax":230,"dryTemp":80,"dryTime":1,"bedTempMin":80,"bedTempMax":85},"metadata":{}},{"id":21307,"label":"SBS","material_type":"SBS","filled_type":null,"density":null,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":195,"nozzleTempMax":250,"dryTemp":50,"dryTime":4,"bedTempMin":0,"bedTempMax":55},"metadata":{"crealityID":"00004","crealityPressureAdvance":0.06,"bambuID":"GFB99"}},{"id":8504,"label":"PPA-CF","material_type":"PPA","filled_type":"CF","density":1.42,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":280,"nozzleTempMax":320,"dryTemp":110,"dryTime":12,"bedTempMin":100,"bedTempMax":105},"metadata":{"bambuID":"GFN97"}},{"id":35377,"label":"PEI-9085-GF","material_type":"","filled_type":null,"density":null,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":360,"nozzleTempMax":400,"dryTemp":150,"dryTime":12,"bedTempMin":120,"bedTempMax":160},"metadata":{"crealityID":"00001","crealityPressureAdvance":0.04,"bambuID":"GFA00"}},{"id":38250,"label":"PEI-1010-GF","material_type":"","filled_type":null,"density":null,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":380,"nozzleTempMax":430,"dryTemp":150,"dryTime":12,"bedTempMin":120,"bedTempMax":160},"metadata":{"crealityID":"00001","crealityPressureAdvance":0.04,"bambuID":"GFA00"}},{"id":29815,"label":"PEEK","material_type":"PEEK","filled_type":null,"density":1.32,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":390,"nozzleTempMax":410,"dryTemp":120,"dryTime":6,"bedTempMin":130,"bedTempMax":145},"metadata":{}},{"id":38256,"label":"PETG","material_type":"PETG","filled_type":null,"density":1.27,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":220,"nozzleTempMax":270,"dryTemp":70,"dryTime":8,"bedTempMin":70,"bedTempMax":75},"metadata":{"bambuID":"GFG99","crealityID":"00003","crealityPressureAdvance":0.07}},{"id":12878,"label":"CoPE","material_type":"","filled_type":null,"density":null,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":190,"nozzleTempMax":240,"dryTemp":70,"dryTime":6,"bedTempMin":30,"bedTempMax":45},"metadata":{"bambuID":"GFU99","crealityID":"00005","crealityPressureAdvance":0.04}},{"id":55418,"label":"PETG-CF","material_type":"PETG","filled_type":"CF","density":1.27,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":240,"nozzleTempMax":270,"dryTemp":70,"dryTime":8,"bedTempMin":75,"bedTempMax":80},"metadata":{"bambuID":"GFG98","crealityID":"00014","crealityPressureAdvance":0.03}},{"id":61563,"label":"PC-PBT-GF","material_type":"PC","filled_type":"GF","density":null,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":260,"nozzleTempMax":280,"dryTemp":90,"dryTime":2,"bedTempMin":90,"bedTempMax":100},"metadata":{"crealityID":"00021","crealityPressureAdvance":0.05,"bambuID":"GFC99"}},{"id":34409,"label":"TPS","material_type":"TPS","filled_type":null,"density":1,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":280,"nozzleTempMax":290,"dryTemp":80,"dryTime":24,"bedTempMin":70,"bedTempMax":90},"metadata":{}},{"id":1680,"label":"PE-GF","material_type":"","filled_type":null,"density":null,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":220,"nozzleTempMax":260,"dryTemp":80,"dryTime":8,"bedTempMin":60,"bedTempMax":80},"metadata":{"crealityID":"00013","crealityPressureAdvance":0.03,"bambuID":"GFP98"}},{"id":59849,"label":"PCL","material_type":"","filled_type":null,"density":null,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":80,"nozzleTempMax":140,"dryTemp":0,"dryTime":0,"bedTempMin":25,"bedTempMax":45},"metadata":{"crealityID":"00001","crealityPressureAdvance":0.04,"bambuID":"GFA00"}},{"id":20588,"label":"PC-CF","material_type":"","filled_type":null,"density":null,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":270,"nozzleTempMax":310,"dryTemp":90,"dryTime":8,"bedTempMin":100,"bedTempMax":120},"metadata":{"crealityID":"00021","crealityPressureAdvance":0.05,"bambuID":"GFC99"}},{"id":15041,"label":"PCTG","material_type":"PCTG","filled_type":null,"density":1.21,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":240,"nozzleTempMax":270,"dryTemp":65,"dryTime":8,"bedTempMin":70,"bedTempMax":75},"metadata":{"bambuID":"GFG97"}},{"id":46154,"label":"PPS","material_type":"PPS","filled_type":null,"density":1.35,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":300,"nozzleTempMax":340,"dryTemp":130,"dryTime":12,"bedTempMin":110,"bedTempMax":115},"metadata":{"crealityID":"00017","bambuID":"GFT97"}},{"id":3481,"label":"PCTG-GF","material_type":"PCTG","filled_type":"GF","density":null,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":240,"nozzleTempMax":270,"dryTemp":65,"dryTime":8,"bedTempMin":70,"bedTempMax":75},"metadata":{"crealityID":"00014","crealityPressureAdvance":0.03,"bambuID":"GFG97"}},{"id":46276,"label":"PPA-GF","material_type":"PPA","filled_type":"GF","density":1.45,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":280,"nozzleTempMax":320,"dryTemp":110,"dryTime":12,"bedTempMin":100,"bedTempMax":105},"metadata":{"bambuID":"GFN96"}},{"id":23080,"label":"PAHT","material_type":"","filled_type":null,"density":null,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":260,"nozzleTempMax":300,"dryTemp":90,"dryTime":12,"bedTempMin":90,"bedTempMax":110},"metadata":{"crealityID":"00016","crealityPressureAdvance":0.058,"bambuID":"GFN04"}},{"id":52077,"label":"PET","material_type":"PET","filled_type":null,"density":1.27,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":260,"nozzleTempMax":290,"dryTemp":85,"dryTime":12,"bedTempMin":65,"bedTempMax":70},"metadata":{"bambuID":"GFG99","crealityID":"00020","crealityPressureAdvance":0.13}},{"id":22652,"label":"PAHT-GF","material_type":"","filled_type":null,"density":null,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":270,"nozzleTempMax":310,"dryTemp":90,"dryTime":12,"bedTempMin":90,"bedTempMax":110},"metadata":{"crealityID":"00016","crealityPressureAdvance":0.058,"bambuID":"GFN04"}},{"id":5733,"label":"TPU-AMS","material_type":"TPU","filled_type":null,"density":1.21,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":200,"nozzleTempMax":250,"dryTemp":75,"dryTime":8,"bedTempMin":35,"bedTempMax":40},"metadata":{"crealityID":"00005","crealityPressureAdvance":0.04,"bambuID":"GFU02"}},{"id":38219,"label":"PLA","material_type":"PLA","filled_type":null,"density":1.24,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":190,"nozzleTempMax":240,"dryTemp":50,"dryTime":8,"bedTempMin":45,"bedTempMax":55},"metadata":{"bambuID":"GFL99","crealityID":"00001","crealityPressureAdvance":0.04}},{"id":22678,"label":"PET-GF","material_type":"PET","filled_type":"GF","density":null,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":280,"nozzleTempMax":300,"dryTemp":50,"dryTime":8,"bedTempMin":80,"bedTempMax":85},"metadata":{"bambuID":"GFG98","crealityID":"00013","crealityPressureAdvance":0.03}},{"id":2053,"label":"PA12-GF","material_type":"PA12","filled_type":"GF","density":1.52,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":260,"nozzleTempMax":300,"dryTemp":85,"dryTime":12,"bedTempMin":40,"bedTempMax":45},"metadata":{}},{"id":12264,"label":"PA6-CF","material_type":"PA6","filled_type":"CF","density":1.52,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":260,"nozzleTempMax":300,"dryTemp":85,"dryTime":12,"bedTempMin":40,"bedTempMax":45},"metadata":{"crealityID":"00015","crealityPressureAdvance":0.044,"bambuID":"GFN05"}},{"id":29272,"label":"PA11","material_type":"","filled_type":null,"density":null,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":260,"nozzleTempMax":290,"dryTemp":80,"dryTime":12,"bedTempMin":80,"bedTempMax":100},"metadata":{"crealityID":"00008","crealityPressureAdvance":0.058,"bambuID":"GFN99"}},{"id":51861,"label":"PETG-ESD","material_type":"PETG","filled_type":null,"density":1.27,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":240,"nozzleTempMax":270,"dryTemp":70,"dryTime":8,"bedTempMin":65,"bedTempMax":70},"metadata":{"bambuID":"GFG50","crealityID":"00014","crealityPressureAdvance":0.03}},{"id":47651,"label":"PC-PBT-CF","material_type":"PC","filled_type":"CF","density":null,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":260,"nozzleTempMax":280,"dryTemp":90,"dryTime":2,"bedTempMin":90,"bedTempMax":100},"metadata":{"crealityID":"00021","crealityPressureAdvance":0.05,"bambuID":"GFC99"}},{"id":20562,"label":"ABS","material_type":"ABS","filled_type":null,"density":1.04,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":240,"nozzleTempMax":280,"dryTemp":80,"dryTime":8,"bedTempMin":85,"bedTempMax":90},"metadata":{"bambuID":"GFB99","crealityID":"00004","crealityPressureAdvance":0.06}},{"id":53970,"label":"PEKK","material_type":"PEKK","filled_type":null,"density":1.28,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":380,"nozzleTempMax":440,"dryTemp":130,"dryTime":4,"bedTempMin":120,"bedTempMax":140},"metadata":{}},{"id":18451,"label":"PA11-CF","material_type":"","filled_type":null,"density":null,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":270,"nozzleTempMax":300,"dryTemp":80,"dryTime":12,"bedTempMin":80,"bedTempMax":100},"metadata":{"crealityID":"00009","crealityPressureAdvance":0.044,"bambuID":"GFN98"}},{"id":6605,"label":"PA11-GF","material_type":"","filled_type":null,"density":null,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":270,"nozzleTempMax":300,"dryTemp":80,"dryTime":12,"bedTempMin":80,"bedTempMax":100},"metadata":{"bambuID":"GFN08","crealityID":"00015","crealityPressureAdvance":0.044}},{"id":48815,"label":"PAHT-CF","material_type":"PAHT","filled_type":"CF","density":1.52,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":260,"nozzleTempMax":300,"dryTemp":85,"dryTime":12,"bedTempMin":100,"bedTempMax":105},"metadata":{"crealityID":"00016","crealityPressureAdvance":0.058,"bambuID":"GFN04"}},{"id":39667,"label":"PA12-CF","material_type":"PA12","filled_type":"CF","density":1.52,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":260,"nozzleTempMax":300,"dryTemp":85,"dryTime":12,"bedTempMin":40,"bedTempMax":45},"metadata":{"crealityID":"00009","crealityPressureAdvance":0.044,"bambuID":"GFL52"}},{"id":49074,"label":"ABS-GF","material_type":"ABS","filled_type":"GF","density":1.04,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":240,"nozzleTempMax":280,"dryTemp":80,"dryTime":8,"bedTempMin":85,"bedTempMax":90},"metadata":{}},{"id":55796,"label":"PA12","material_type":"PA12","filled_type":null,"density":1.52,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":250,"nozzleTempMax":290,"dryTemp":85,"dryTime":12,"bedTempMin":70,"bedTempMax":90},"metadata":{}},{"id":58498,"label":"PEBA","material_type":"PEBA","filled_type":null,"density":1.01,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":225,"nozzleTempMax":250,"dryTemp":70,"dryTime":3,"bedTempMin":95,"bedTempMax":100},"metadata":{}},{"id":61048,"label":"PVDF","material_type":"PVDF","filled_type":null,"density":1.78,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":240,"nozzleTempMax":265,"dryTemp":0,"dryTime":0,"bedTempMin":90,"bedTempMax":110},"metadata":{}},{"id":26029,"label":"HIPS","material_type":"HIPS","filled_type":null,"density":1.03,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":220,"nozzleTempMax":270,"dryTemp":80,"dryTime":6,"bedTempMin":90,"bedTempMax":95},"metadata":{"bambuID":"GFS98","crealityID":"00012"}},{"id":8345,"label":"PLA+ Silk","material_type":"PLA","filled_type":null,"density":1.24,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":190,"nozzleTempMax":240,"dryTemp":50,"dryTime":8,"bedTempMin":45,"bedTempMax":55},"metadata":{"bambuID":"GFA06","crealityID":"00002","crealityPressureAdvance":0.04}},{"id":13850,"label":"PPA","material_type":"PPA","filled_type":null,"density":1.15,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":280,"nozzleTempMax":320,"dryTemp":110,"dryTime":12,"bedTempMin":100,"bedTempMax":105},"metadata":{}},{"id":10738,"label":"PC-PTFE","material_type":"PC","filled_type":"PTFE","density":1.3,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":270,"nozzleTempMax":290,"dryTemp":80,"dryTime":4,"bedTempMin":110,"bedTempMax":130},"metadata":{}},{"id":4587,"label":"PC-PBT","material_type":"PC","filled_type":null,"density":1.2,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":260,"nozzleTempMax":280,"dryTemp":90,"dryTime":2,"bedTempMin":90,"bedTempMax":100},"metadata":{"bambuID":"GFC00","crealityID":"00021","crealityPressureAdvance":0.05}},{"id":10187,"label":"PHA","material_type":"PHA","filled_type":null,"density":1.25,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":190,"nozzleTempMax":240,"dryTemp":50,"dryTime":24,"bedTempMin":55,"bedTempMax":60},"metadata":{"bambuID":"GFR98"}},{"id":735,"label":"ABS-AF","material_type":"ABS","filled_type":"AF","density":1.04,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":240,"nozzleTempMax":290,"dryTemp":85,"dryTime":8,"bedTempMin":85,"bedTempMax":90},"metadata":{"bambuID":"GFB00","crealityID":"00004","crealityPressureAdvance":0.06}},{"id":28110,"label":"SBC","material_type":"SBC","filled_type":null,"density":1.01,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":220,"nozzleTempMax":260,"dryTemp":45,"dryTime":6,"bedTempMin":65,"bedTempMax":70},"metadata":{}},{"id":50497,"label":"PP-CF","material_type":"PP","filled_type":"CF","density":0.9,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":220,"nozzleTempMax":250,"dryTemp":60,"dryTime":4,"bedTempMin":55,"bedTempMax":60},"metadata":{"bambuID":"GFP96"}},{"id":30458,"label":"PC","material_type":"PC","filled_type":null,"density":1.3,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":260,"nozzleTempMax":290,"dryTemp":85,"dryTime":8,"bedTempMin":110,"bedTempMax":115},"metadata":{"bambuID":"GFC99","crealityID":"00021","crealityPressureAdvance":0.05}},{"id":10478,"label":"Castable Filament","material_type":"","filled_type":null,"density":null,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":190,"nozzleTempMax":220,"dryTemp":55,"dryTime":12,"bedTempMin":30,"bedTempMax":70},"metadata":{}},{"id":48047,"label":"TPU High Speed","material_type":"TPU","filled_type":null,"density":1.21,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":200,"nozzleTempMax":250,"dryTemp":75,"dryTime":8,"bedTempMin":35,"bedTempMax":40},"metadata":{"bambuID":"GFU00","crealityID":"00005","crealityPressureAdvance":0.04}},{"id":18922,"label":"PLA-ESD","material_type":"PLA","filled_type":null,"density":1.24,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":190,"nozzleTempMax":240,"dryTemp":50,"dryTime":8,"bedTempMin":45,"bedTempMax":55},"metadata":{"bambuID":"GFL98","crealityID":"00006","crealityPressureAdvance":0.05}},{"id":11506,"label":"PLA-AERO","material_type":"PLA","filled_type":"AERO","density":1.24,"filled":true,"product_type_id":142,"recommended":{"nozzleTempMin":210,"nozzleTempMax":260,"dryTemp":50,"dryTime":8,"bedTempMin":45,"bedTempMax":55},"metadata":{"crealityID":"00007","crealityPressureAdvance":0.06,"bambuID":"GFA11"}},{"id":49152,"label":"PPSU","material_type":"PPSU","filled_type":null,"density":1.37,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":360,"nozzleTempMax":400,"dryTemp":130,"dryTime":12,"bedTempMin":140,"bedTempMax":170},"metadata":{}},{"id":10602,"label":"PLA Silk","material_type":"PLA","filled_type":null,"density":1.24,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":190,"nozzleTempMax":240,"dryTemp":50,"dryTime":8,"bedTempMin":45,"bedTempMax":55},"metadata":{"bambuID":"GFL96","crealityID":"00002","crealityPressureAdvance":0.04}},{"id":34049,"label":"BVOH","material_type":"BVOH","filled_type":null,"density":1.14,"filled":false,"product_type_id":142,"recommended":{"nozzleTempMin":190,"nozzleTempMax":240,"dryTemp":85,"dryTime":12,"bedTempMin":55,"bedTempMax":60},"metadata":{"bambuID":"GFS97","crealityID":"00010","crealityPressureAdvance":0.4}}]
@@ -0,0 +1 @@
1
+ [{"id":10,"label":"mg","type":"weight"},{"id":21,"label":"g","type":"weight"},{"id":35,"label":"kg","type":"weight"},{"id":48,"label":"ml","type":"volume"},{"id":62,"label":"cl","type":"volume"},{"id":79,"label":"L","type":"volume"},{"id":95,"label":"m³","type":"volume"},{"id":112,"label":"mm","type":"size"},{"id":130,"label":"cm","type":"size"},{"id":149,"label":"m","type":"size"},{"id":170,"label":"m²","type":"area"}]
@@ -0,0 +1 @@
1
+ [{"id":142,"label":"Filament"},{"id":173,"label":"Resin"}]
@@ -0,0 +1 @@
1
+ [{"id":0,"version":"0.0","name":"RFID Empty","tag":"TIGER_TAG_UNINITIALIZED","public_key":""},{"id":1542820452,"version":"1.0","name":"TigerTag","tag":"TIGER_TAG_MAKER_V1.0","public_key":"-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEwtX8JRYMoAXTbkU7EXJYKX7g4Mf0\nZ3WUuuGzlfyiEiS5UseXT6l1t1ZbMgzsg5IVA0TB7+/w6eyTlgnz/HXONw==\n-----END PUBLIC KEY-----"},{"id":1816240865,"version":"1.0","name":"TigerTag Init","tag":"TIGER_TAG_INIT","public_key":"-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEwtX8JRYMoAXTbkU7EXJYKX7g4Mf0\nZ3WUuuGzlfyiEiS5UseXT6l1t1ZbMgzsg5IVA0TB7+/w6eyTlgnz/HXONw==\n-----END PUBLIC KEY-----"},{"id":3155151767,"version":"1.0","name":"TigerTag+","tag":"TIGER_TAG_PRO_V1.0","public_key":"-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEwtX8JRYMoAXTbkU7EXJYKX7g4Mf0\nZ3WUuuGzlfyiEiS5UseXT6l1t1ZbMgzsg5IVA0TB7+/w6eyTlgnz/HXONw==\n-----END PUBLIC KEY-----"}]
@@ -0,0 +1 @@
1
+ {"versions":1763073059935,"types":1777884684291,"brands":1777885837902,"filament_diameters":1777895560487,"filament_materials":1778798861002,"aspects":1777894570720,"measure_units":1777896731691}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "tigertag",
3
+ "version": "1.0.0",
4
+ "description": "JavaScript SDK for TigerTag RFID material identification",
5
+ "main": "src/index.js",
6
+ "bin": {
7
+ "tigertag": "bin/tigertag.js"
8
+ },
9
+ "files": [
10
+ "src/",
11
+ "database/",
12
+ "bin/",
13
+ "README.md",
14
+ "LICENSE.md",
15
+ "CHANGELOG.md"
16
+ ],
17
+ "engines": {
18
+ "node": ">=18"
19
+ },
20
+ "keywords": [
21
+ "tigertag",
22
+ "rfid",
23
+ "nfc",
24
+ "materials",
25
+ "manufacturing",
26
+ "ntag213",
27
+ "identification",
28
+ "3d-printing",
29
+ "filament",
30
+ "resin",
31
+ "ecdsa",
32
+ "electron"
33
+ ],
34
+ "author": "TigerTag <tigertag@tigertag.io> (https://tigertag.io)",
35
+ "license": "GPL-3.0",
36
+ "homepage": "https://tigertag.io",
37
+ "repository": {
38
+ "type": "git",
39
+ "url": "https://github.com/TigerTag-Project/TigerTag-SDK-JS.git"
40
+ },
41
+ "bugs": {
42
+ "url": "https://github.com/TigerTag-Project/TigerTag-SDK-JS/issues"
43
+ },
44
+ "scripts": {
45
+ "test": "jest --testPathPattern=test/",
46
+ "generate-fixtures": "node scripts/generate_fixtures.js",
47
+ "playground": "node tools/server.js"
48
+ },
49
+ "devDependencies": {
50
+ "jest": "^29.0.0",
51
+ "nfc-pcsc": "^0.8.1",
52
+ "ws": "^8.20.1"
53
+ }
54
+ }
package/src/db.js ADDED
@@ -0,0 +1,292 @@
1
+ 'use strict';
2
+
3
+ // TigerTag RFID Guide
4
+ // Copyright (C) 2025 TigerTag
5
+ //
6
+ // This program is free software: you can redistribute it and/or modify
7
+ // it under the terms of the GNU General Public License as published by
8
+ // the Free Software Foundation, either version 3 of the License.
9
+
10
+ /**
11
+ * TigerTag reference database loader and sync utilities.
12
+ */
13
+
14
+ const fs = require('fs');
15
+ const path = require('path');
16
+
17
+ const _API_BASE = 'https://api.tigertag.io/api:tigertag';
18
+ const _GITHUB_RAW_BASE = 'https://raw.githubusercontent.com/TigerTag-Project/TigerTag-RFID-Guide/main/database';
19
+ const _HTTP_TIMEOUT = 30000;
20
+
21
+ // Maps last_update key → [API endpoint, local filename]
22
+ const _DATASETS = {
23
+ versions: ['version/get/all', 'id_version.json'],
24
+ types: ['type/get/all', 'id_type.json'],
25
+ brands: ['brand/get/all', 'id_brand.json'],
26
+ filament_diameters: ['diameter/filament/get/all', 'id_diameter.json'],
27
+ filament_materials: ['material/get/all', 'id_material.json'],
28
+ aspects: ['aspect/get/all', 'id_aspect.json'],
29
+ measure_units: ['measure_unit/get/all', 'id_measure_unit.json'],
30
+ };
31
+
32
+ const _BUNDLED_DB_PATH = path.join(__dirname, '..', 'database');
33
+
34
+ /**
35
+ * Download or update TigerTag reference JSON databases.
36
+ * Tries the live TigerTag API first; falls back to the GitHub mirror.
37
+ * Only downloads files whose timestamp has changed.
38
+ *
39
+ * @param {string} [dbPath] - Folder where JSON files are stored (created if missing).
40
+ * @param {object} [options]
41
+ * @param {boolean} [options.force=false] - Re-download all files even if up to date.
42
+ * @param {boolean} [options.verbose=true] - Print progress to stdout.
43
+ * @returns {Promise<string[]>} List of filenames that were downloaded/updated.
44
+ */
45
+ async function syncDatabases(dbPath, { force = false, verbose = true } = {}) {
46
+ const resolvedPath = path.resolve(dbPath || _BUNDLED_DB_PATH);
47
+ fs.mkdirSync(resolvedPath, { recursive: true });
48
+
49
+ const lastUpdatePath = path.join(resolvedPath, 'last_update.json');
50
+
51
+ const _log = verbose ? (msg) => console.log(msg) : () => {};
52
+
53
+ async function _get(url) {
54
+ const controller = new AbortController();
55
+ const timer = setTimeout(() => controller.abort(), _HTTP_TIMEOUT);
56
+ try {
57
+ const resp = await fetch(url, { signal: controller.signal });
58
+ if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
59
+ const text = await resp.text();
60
+ return { data: JSON.parse(text), text };
61
+ } finally {
62
+ clearTimeout(timer);
63
+ }
64
+ }
65
+
66
+ let remoteData, remoteText, datasetUrlFn;
67
+
68
+ try {
69
+ const result = await _get(`${_API_BASE}/all/last_update`);
70
+ remoteData = result.data;
71
+ remoteText = result.text;
72
+ datasetUrlFn = (endpoint, _filename) => `${_API_BASE}/${endpoint}`;
73
+ _log('[info] source: api');
74
+ } catch (exc) {
75
+ _log(`[warn] TigerTag API unreachable (${exc.message}), falling back to GitHub mirror`);
76
+ try {
77
+ const result = await _get(`${_GITHUB_RAW_BASE}/last_update.json`);
78
+ remoteData = result.data;
79
+ remoteText = result.text;
80
+ datasetUrlFn = (_endpoint, filename) => `${_GITHUB_RAW_BASE}/${filename}`;
81
+ _log('[info] source: github');
82
+ } catch (exc2) {
83
+ throw new Error(
84
+ `Both API and GitHub mirror are unreachable.\nAPI error: ${exc.message}\nGitHub error: ${exc2.message}\nCheck your internet connection.`,
85
+ );
86
+ }
87
+ }
88
+
89
+ let localData = {};
90
+ if (fs.existsSync(lastUpdatePath)) {
91
+ try {
92
+ localData = JSON.parse(fs.readFileSync(lastUpdatePath, 'utf8'));
93
+ } catch (_) {}
94
+ }
95
+
96
+ const updated = [];
97
+
98
+ for (const [key, [endpoint, filename]] of Object.entries(_DATASETS)) {
99
+ const remoteTs = remoteData[key];
100
+ const localTs = localData[key];
101
+ const localFile = path.join(resolvedPath, filename);
102
+
103
+ if (remoteTs == null) {
104
+ _log(`[skip] ${key}: not in last_update payload`);
105
+ continue;
106
+ }
107
+
108
+ if (!force && remoteTs === localTs && fs.existsSync(localFile)) {
109
+ _log(`[ok] ${filename}: up to date`);
110
+ continue;
111
+ }
112
+
113
+ _log(`[sync] ${filename}: ${localTs} → ${remoteTs}`);
114
+ const controller = new AbortController();
115
+ const timer = setTimeout(() => controller.abort(), _HTTP_TIMEOUT);
116
+ try {
117
+ const resp = await fetch(datasetUrlFn(endpoint, filename), { signal: controller.signal });
118
+ if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
119
+ const data = await resp.json();
120
+ fs.writeFileSync(localFile, JSON.stringify(data, null, 2), 'utf8');
121
+ updated.push(filename);
122
+ } finally {
123
+ clearTimeout(timer);
124
+ }
125
+ }
126
+
127
+ if (updated.length > 0 || JSON.stringify(localData) !== JSON.stringify(remoteData)) {
128
+ fs.writeFileSync(lastUpdatePath, remoteText, 'utf8');
129
+ if (!updated.includes('last_update.json')) updated.push('last_update.json');
130
+ }
131
+
132
+ return updated;
133
+ }
134
+
135
+ /**
136
+ * Loads and exposes TigerTag JSON reference databases.
137
+ *
138
+ * Ships with bundled JSON files so the SDK works offline immediately after install.
139
+ * Optionally syncs updates from the TigerTag API or GitHub mirror via sync().
140
+ *
141
+ * All ID lookups return the full JSON entry object (or null if not found).
142
+ * The JSON files are the single source of truth — no hardcoded ID mappings.
143
+ *
144
+ * @example
145
+ * const db = new TigerTagDB();
146
+ * const mat = db.material(38219);
147
+ * console.log(mat.label); // "PLA"
148
+ * console.log(mat.density); // 1.24
149
+ */
150
+ class TigerTagDB {
151
+ /**
152
+ * @param {object} [options]
153
+ * @param {string} [options.dbPath] - Path to database directory. Defaults to bundled DB.
154
+ * @param {boolean} [options.autoSync] - Flag; call db.sync() manually to download files.
155
+ * @param {boolean} [options.verbose] - Print sync progress (default true).
156
+ */
157
+ constructor({ dbPath, autoSync = false, verbose = true } = {}) {
158
+ this._path = dbPath ? path.resolve(dbPath) : _BUNDLED_DB_PATH;
159
+ this._autoSync = autoSync;
160
+ this._verbose = verbose;
161
+ this._ensureDb();
162
+ this._versions = this._load('id_version.json');
163
+ this._materials = this._load('id_material.json');
164
+ this._aspects = this._load('id_aspect.json');
165
+ this._types = this._load('id_type.json');
166
+ this._diameters = this._load('id_diameter.json');
167
+ this._brands = this._load('id_brand.json');
168
+ this._units = this._load('id_measure_unit.json');
169
+ }
170
+
171
+ _ensureDb() {
172
+ const missing = TigerTagDB.REQUIRED_FILES.filter(
173
+ (fn) => !fs.existsSync(path.join(this._path, fn)),
174
+ );
175
+ if (missing.length === 0) return;
176
+
177
+ // Fallback to bundled database if user provided a custom path
178
+ if (this._path !== _BUNDLED_DB_PATH && fs.existsSync(_BUNDLED_DB_PATH)) {
179
+ const stillMissing = TigerTagDB.REQUIRED_FILES.filter(
180
+ (fn) => !fs.existsSync(path.join(_BUNDLED_DB_PATH, fn)),
181
+ );
182
+ if (stillMissing.length === 0) {
183
+ this._path = _BUNDLED_DB_PATH;
184
+ return;
185
+ }
186
+ }
187
+
188
+ process.stderr.write(
189
+ `\nTigerTag database files not found.\n Expected: ${path.resolve(this._path)}\n\n Missing:\n`
190
+ + missing.map((fn) => ` - ${fn}`).join('\n')
191
+ + '\n\n Call await db.sync() to download them.\n\n',
192
+ );
193
+ }
194
+
195
+ _load(filename) {
196
+ const fp = path.join(this._path, filename);
197
+ if (!fs.existsSync(fp)) return [];
198
+ try {
199
+ return JSON.parse(fs.readFileSync(fp, 'utf8'));
200
+ } catch (_) {
201
+ return [];
202
+ }
203
+ }
204
+
205
+ _reloadAll() {
206
+ this._versions = this._load('id_version.json');
207
+ this._materials = this._load('id_material.json');
208
+ this._aspects = this._load('id_aspect.json');
209
+ this._types = this._load('id_type.json');
210
+ this._diameters = this._load('id_diameter.json');
211
+ this._brands = this._load('id_brand.json');
212
+ this._units = this._load('id_measure_unit.json');
213
+ }
214
+
215
+ static _find(table, idValue) {
216
+ return table.find((e) => e.id === idValue) || null;
217
+ }
218
+
219
+ /**
220
+ * Manually trigger a database update.
221
+ * @param {boolean} [force=false] - Re-download all files even if up to date.
222
+ * @returns {Promise<string[]>} List of filenames that were downloaded/updated.
223
+ */
224
+ async sync(force = false) {
225
+ const updated = await syncDatabases(this._path, { force, verbose: this._verbose });
226
+ this._reloadAll();
227
+ return updated;
228
+ }
229
+
230
+ /**
231
+ * Look up a version entry by id_tigertag value. Includes public_key for signature verification.
232
+ * @param {number} id
233
+ * @returns {object|null}
234
+ */
235
+ version(id) { return TigerTagDB._find(this._versions, id); }
236
+
237
+ /**
238
+ * Look up a material entry. Includes density, recommended temps, bambuID, etc.
239
+ * @param {number} id
240
+ * @returns {object|null}
241
+ */
242
+ material(id) { return TigerTagDB._find(this._materials, id); }
243
+
244
+ /**
245
+ * Look up an aspect entry. Includes color_count.
246
+ * @param {number} id
247
+ * @returns {object|null}
248
+ */
249
+ aspect(id) { return TigerTagDB._find(this._aspects, id); }
250
+
251
+ /**
252
+ * Look up a type entry.
253
+ * @param {number} id
254
+ * @returns {object|null}
255
+ */
256
+ type(id) { return TigerTagDB._find(this._types, id); }
257
+
258
+ /**
259
+ * Look up a diameter entry.
260
+ * @param {number} id
261
+ * @returns {object|null}
262
+ */
263
+ diameter(id) { return TigerTagDB._find(this._diameters, id); }
264
+
265
+ /**
266
+ * Look up a brand entry.
267
+ * @param {number} id
268
+ * @returns {object|null}
269
+ */
270
+ brand(id) { return TigerTagDB._find(this._brands, id); }
271
+
272
+ /**
273
+ * Look up a measure unit entry.
274
+ * @param {number} id
275
+ * @returns {object|null}
276
+ */
277
+ unit(id) { return TigerTagDB._find(this._units, id); }
278
+
279
+ /**
280
+ * Safe label string from any DB entry object.
281
+ * @param {object|null} entry
282
+ * @returns {string}
283
+ */
284
+ static label(entry) {
285
+ if (!entry) return 'Unknown';
286
+ return entry.label || entry.name || 'Unknown';
287
+ }
288
+ }
289
+
290
+ TigerTagDB.REQUIRED_FILES = Object.values(_DATASETS).map(([, fn]) => fn);
291
+
292
+ module.exports = { TigerTagDB, syncDatabases, _BUNDLED_DB_PATH };