From f455246fde086dda0cb61b92c84a5146a831a2bf Mon Sep 17 00:00:00 2001 From: cirakg Date: Tue, 20 Oct 2026 06:56:58 +0200 Subject: test(codes): compare QR with segno, decode QR dumps and the QR screenshot Co-Authored-By: Claude Opus 5.5 --- test/codes/CodeCacheTest.mc | 54 +++++++++++++ test/codes/QrTest.mc | 120 ++++++++++++++++++++++++++++ test/data/CodeVectors.mc | 36 +++++++++ test/golden/fenix7/about.png | Bin 4037 -> 4032 bytes test/golden/fenix7/code.png | Bin 3294 -> 3339 bytes test/golden/fenix7/code_qr.png | Bin 0 -> 3794 bytes test/golden/fr255s/about.png | Bin 2385 -> 2382 bytes test/golden/fr255s/code.png | Bin 2267 -> 2273 bytes test/golden/fr255s/code_qr.png | Bin 0 -> 2604 bytes test/golden/fr70/about.png | Bin 15606 -> 15572 bytes test/golden/fr70/code.png | Bin 13889 -> 13887 bytes test/golden/fr70/code_qr.png | Bin 0 -> 12968 bytes test/golden/fr965/about.png | Bin 15984 -> 16027 bytes test/golden/fr965/code.png | Bin 12507 -> 12467 bytes test/golden/fr965/code_qr.png | Bin 0 -> 11727 bytes test/golden/instinct3amoled45mm/about.png | Bin 13651 -> 13621 bytes test/golden/instinct3amoled45mm/code.png | Bin 11749 -> 11824 bytes test/golden/instinct3amoled45mm/code_qr.png | Bin 0 -> 12096 bytes test/golden/venusq2/code.png | Bin 3037 -> 3040 bytes test/golden/venusq2/code_qr.png | Bin 0 -> 3388 bytes test/golden/venux1/code.png | Bin 11473 -> 11468 bytes test/golden/venux1/code_qr.png | Bin 0 -> 10767 bytes 22 files changed, 210 insertions(+) create mode 100644 test/codes/CodeCacheTest.mc create mode 100644 test/codes/QrTest.mc create mode 100644 test/golden/fenix7/code_qr.png create mode 100644 test/golden/fr255s/code_qr.png create mode 100644 test/golden/fr70/code_qr.png create mode 100644 test/golden/fr965/code_qr.png create mode 100644 test/golden/instinct3amoled45mm/code_qr.png create mode 100644 test/golden/venusq2/code_qr.png create mode 100644 test/golden/venux1/code_qr.png (limited to 'test') diff --git a/test/codes/CodeCacheTest.mc b/test/codes/CodeCacheTest.mc new file mode 100644 index 0000000..e09d902 --- /dev/null +++ b/test/codes/CodeCacheTest.mc @@ -0,0 +1,54 @@ +// Author: cirakg & claude ai +// Summary: Tests for the encrypted barcode matrix cache: round trip, keys of locked entries, invalidation and tampering. + +import Toybox.Lang; +import Toybox.Test; + +(:test) +function codeCacheRoundTripsAndInvalidates(logger as Test.Logger) as Boolean { + var store = new MemoryBackend(); + var vault = new Vault(store, new FakeTime()); + var e = StorageFixtures.code("QR card"); + e.type = Codes.QR; + var id = vault.add(e); + var qr = Qr.encode("cache me", 1, 0, -1) as Qr.MatrixCode; + var matrix = new Codes.Matrix(qr.size, qr.size, 4, qr.modules); + vault.saveCodeCache(id, matrix.toBytes()); + var back = Codes.Matrix.fromBytes(vault.loadCodeCache(id) as ByteArray); + var same = back != null && back.width == qr.size && back.quiet == 4 && Bytes.equal(back.modules, qr.modules); + // The cache is sealed: tampering gives no cache rather than a wrong code. + var stored = store.raw("x." + id) as ByteArray; + stored[stored.size() - 1] = stored[stored.size() - 1] ^ 1; + var tampered = vault.loadCodeCache(id) == null; + vault.saveCodeCache(id, matrix.toBytes()); + var opened = vault.open(id); + vault.update(opened); + opened.wipeSecrets(); + var clearedByUpdate = store.getValue("x." + id) == null; + vault.saveCodeCache(id, matrix.toBytes()); + vault.remove(id); + return same && tampered && clearedByUpdate && store.getValue("x." + id) == null; +} + +// A locked entry's cache uses the master key: unreadable while locked. +(:test) +function codeCacheOfLockedEntriesNeedsTheSession(logger as Test.Logger) as Boolean { + var vault = new Vault(new MemoryBackend(), new FakeTime()); + StorageFixtures.setPin(vault, StorageFixtures.PIN); + var e = StorageFixtures.code("Locked QR"); + e.type = Codes.QR; + e.locked = true; + var id = vault.add(e); + vault.saveCodeCache(id, [3, 1, 4, 0xE0]b); + vault.lock(); + var code = 0; + try { + vault.loadCodeCache(id); + } catch (err instanceof VaultError) { + code = err.code; + } + StorageFixtures.unlock(vault, StorageFixtures.PIN); + var back = vault.loadCodeCache(id); + return code == VaultError.LOCKED && back != null && Bytes.equal(back, [3, 1, 4, 0xE0]b) + && Codes.Matrix.fromBytes([3, 1, 4, 0xE0]b) != null && Codes.Matrix.fromBytes([3, 1, 4]b) == null; +} diff --git a/test/codes/QrTest.mc b/test/codes/QrTest.mc new file mode 100644 index 0000000..50cb35a --- /dev/null +++ b/test/codes/QrTest.mc @@ -0,0 +1,120 @@ +// Author: cirakg & claude ai +// Summary: Tests for the QR encoder: segno reference matrices (forced and automatic version and mask), decoding dumps, capacity, timing. + +import Toybox.Lang; +import Toybox.System; +import Toybox.Test; + +(:test) +module QrFixtures { + + // Row-major modules packed 8 per byte, as hex (the CodeVectors format). + function packedHex(code as Qr.MatrixCode) as String { + var m = code.modules; + var out = new [(m.size() + 7) / 8]b; + for (var i = 0; i < m.size(); i++) { + if (m[i] == 1) { + out[i / 8] = out[i / 8] | (0x80 >> (i % 8)); + } + } + return Bytes.toHex(out); + } +} + +// README 12.4 check 1 for QR: identical to segno with forced version and +// mask, and the same automatic version and mask choice. +(:test) +function qrMatchesSegno(logger as Test.Logger) as Boolean { + var rows = CodeVectors.QR; + for (var i = 0; i < rows.size(); i++) { + var row = rows[i] as Array; + var payload = row[0] as String; + var result = Qr.encode(payload, row[1] as Number, row[2] as Number, row[3] as Number); + if (result instanceof Codes.CodeError) { + logger.error("row " + i + ": " + result.message); + return false; + } + var expectedVersion = row[4] as Number; + var expectedMask = row[5] as Number; + if (result.version != expectedVersion || result.mask != expectedMask) { + logger.error("row " + i + " '" + Text.clip(payload, 20) + "': version " + result.version + " mask " + result.mask + + ", segno " + expectedVersion + " / " + expectedMask); + return false; + } + var got = QrFixtures.packedHex(result); + var expected = row[6] as String; + if (!got.equals(expected)) { + logger.error("row " + i + " '" + Text.clip(payload, 20) + "' (version " + result.version + ") matrix differs"); + logger.debug("QRGOT " + got); + return false; + } + } + logger.debug("CODES qr reference rows=" + rows.size()); + return true; +} + +// README 12.4 check 2: mixed-mode (segmented), Unicode and long payloads, +// decoded by tools/check_codes.py with zxing-cpp. +(:test) +function qrDumpForDecoding(logger as Test.Logger) as Boolean { + var payloads = [ + "ABC12345678901234xyz", "Membership 0042-7731-55 · Zürich", "12345678901234567890HELLO WORLD hello world", + "WIFI:T:WPA;S:FakeNet;P:not-a-real-password;;", "😀 emoji and Ünïcödé", "a" + ]; + var seed = 777; + for (var i = 0; i < 24; i++) { + var text = ""; + var length = 1 + i * 13 % 90; + for (var k = 0; k < length; k++) { + seed = (seed * 1103515245 + 12345) & 0x7FFFFFFF; + var pool = (seed >> 16) % 3 == 0 ? "0123456789" : ((seed >> 16) % 3 == 1 ? "ABCXYZ $%*+-./:" : "abcxyz,!?é"); + var at = (seed >> 4) % pool.length(); + text += pool.substring(at, at + 1); + } + payloads.add(text); + } + for (var i = 0; i < payloads.size(); i++) { + var text = payloads[i] as String; + var result = Qr.encode(text, i % 4, 0, -1); + if (result instanceof Codes.CodeError) { + logger.error("'" + text + "': " + result.message); + return false; + } + logger.debug("QRDUMP " + result.size + " " + Bytes.toHex(Bytes.fromUtf8(text)) + " " + QrFixtures.packedHex(result)); + } + return true; +} + +(:test) +function qrReportsCapacity(logger as Test.Logger) as Boolean { + var big = ""; + for (var i = 0; i < 300; i++) { + big += "abcdefghij"; + } + var tooLong = Qr.encode(big, 3, 0, -1); + var forced = Qr.encode("hello world, too long for version 1", 3, 1, -1); + var empty = Qr.encode("", 1, 0, -1); + return tooLong instanceof Codes.CodeError && (tooLong.message.find("too long") != null) + && forced instanceof Codes.CodeError && empty instanceof Codes.CodeError; +} + +// Timing and step counts for PERFORMANCE.md (simulator). +(:test) +function qrBenchmark(logger as Test.Logger) as Boolean { + var text = ""; + for (var i = 0; i < 20; i++) { + text += "abcdefghij"; + } + var inputs = ["https://example.com/member/12345", text, text + text + text + text + text]; + for (var i = 0; i < inputs.size(); i++) { + var job = new Qr.QrJob(inputs[i] as String, 1, 0, -1); + var steps = 0; + var start = System.getTimer(); + while (!job.step(1)) { + steps++; + } + var code = job.result as Qr.MatrixCode; + logger.debug("BENCH qr_v" + code.version + " ms=" + (System.getTimer() - start) + " steps=" + steps); + } + return true; +} diff --git a/test/data/CodeVectors.mc b/test/data/CodeVectors.mc index 64f8644..bb5f7bd 100644 --- a/test/data/CodeVectors.mc +++ b/test/data/CodeVectors.mc @@ -227,4 +227,40 @@ module CodeVectors { [7, "5620356163", 25, "101011101000111000101010111010001000111011100011101000101010001110111010100010001110001110101011101"], [8, "B+2C", 17, "1001001011010110110110101001011010100100110"] ]; + + // [payload, level, version (0 auto), mask (-1 auto), segno version, segno mask, + // segno matrix as hex of row-major bits] + const QR = [ + ["01234567", 1, 1, 2, 1, 2, "fe5bfc13d06ea0bb7585dbabaec14507faafe01300be4be0ad4b08d53e1083c1f948005f33f9ac1057c5ba8965d6482ead2904036fef4a00"], + ["HELLO WORLD", 2, 1, 6, 1, 6, "fe13fc16506e96bb75f5dbad2ec12507faafe01b005eced5e87b8ac4c168b18dfeef8044a3f999f05497bad23dd5c52e908705ce6fe50100"], + ["hello, worlddddddddddddddddddddd", 0, 2, 0, 2, 0, "fe333fc13b906ea88bb74665dba332ec13b907faaafe01bb00efcce206e651e4822cff1bbd0e2ace1882671e5aa34e927b82a6ccf80066c5ffa26b705b91abaacf8dd3685eeaa66b05bb2afecda980"], + ["Zürich ✓ fakeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", 1, 5, 3, 5, 3, "fef33d0bfc16bf1c506e936e38bb751f85e5dba16d0baec1049c7107faaaaaafe01e8c7200b720f43a590489e848a1e438e377518871c4f53ad42f0eb842e85cbf7db0e394ce96f1c6c37eb22f4064af185e9329b8e38f454995c71bb2efef42b8e4da5e872018c38e028236871ebec3fb42f6f88f8e85fe15e48e381d7a831c7a113fc2f4fa004185e447fad638aa705adc7318ba4af42f95d6e5e894eeb1b8e1f104e071c9cfea342e6780"], + ["https://example.com/member/abccccccccccccc", 1, 0, -1, 3, 7, "fe6373fc136b506e9af2bb746665dba67a2ec151e907faaaafe00b5900968e9507a426524ef4a47d51284b63614de5dcf43a03afd0b3ed3bcbaa3b506c1247763a68dd91a67165f739a6e9fa00726c5ff82aaa505e851fba02cf85d5c2f7ae95883b04c8b42feaa4bd00"], + ["314159265358979323846264338327950288419716939937510", 3, 0, -1, 3, 3, "fe2cabfc1323d06e886abb7404f5dbadbcaec10e0907faaaafe01f3f0033a49683e08632dff753a25a06ec28f034511c6c33df3c34c59e0b5f495f225eda6a0e43e4a006420982eb45a3a2f90049a473fb482b9048151bba2f0f85d64b802ebe3adb04656f0fe55fbc00"], + ["THE QUICK BROWN FOX 0123456789 $%*+-./::", 2, 7, 4, 7, 4, "fe3768f68bfc10c2fd0e906ea7f4be94bb742a9143b5dbad97f8f3aec167fc7f2107faaaaaaaafe006391d62004a9bdfc1ada0cdf238a7baddae1d271eb9ca11ad08d74a6e4bbb647bd639847d825cfeaa0366f81c27638c6ed9961afa49f47cc5e0c8e50a7daed1a5107c429fb5197348fc19fa64fa8c5cdc79f454ebba6b67ab871d2113ad1edfd0ffd8cf9e66a01f549df4f5d3d00a572b9b91d6281beea02a1a12029b79eb76246cdeb0f9db803319038f36cf50e89e5ebee2257e589dc2c4e4786a44f08eb9262bb9b6a8ff9afe007ed46e7c6bf8eaaa71ebf043a3128b17bad33fce0fb5d20349da0d6e8c2ff27c61058cb637419fe617679e3780"], + ["vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv", 1, 10, 5, 10, 5, "fe0e40b333333fc14ca23abfa8906ead43f3e53fcbb75c9de33333a5dba3093be85e92ec10b8e31bfab107faaaaaaaaaaafe01ecd7c7abfb00828a617f7a17672020def33333f3a6f686094f949854ac5d7bfabfbbd3ebdbe0ccccc489673d8e76276e7e3efa6894f949855b82c3eeeeefef6b0d71617a17251c421ce76276e7f79240d222224334947c7bfabfbbd621d21617a17250e037df33333f39dc1e2094f94984c8d757bfabfbbd4f23da0ccccc489a7220e76276e7ffe5f81fcf94be411a24346eeef1c2a95e12b7a17ad2473d0f1627647d7edeecfa2223f26bf85b6babfaedf792676f7a16cd0ce215dc33338fc1b8d91fcf949660af3576babfaecaa23ba02cccda19e835fc862769bc6b8959fcf949643335e33aeeeebcc7ed496f7a16cd1e8f7bc862769bdddd2544a2224d3f280276babfaed0f35196f7a16cd0c1206dc33338fa9b2159fcf94965f0a4076babfaed0288a23ecccdf8804743f1627647ff96148acf94ea504f71f46eeef1cba3ffb7f7a16fd5d0703ff6276af2e8ae24b2222337043a0f5fabf89cfed9fb457a17e500"], + ["ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ", 0, 0, -1, 9, 4, "fefa22054563fc171897da59906ea1670caea4bb75aaa2a96955dba0409f9d722ec164d747525107faaaaaaaaaafe00f61f1c51500ce182bfea4b17bc23fee7a209ee1ab5d745d809de19044b177e82e7dcbdb689fdc36e202d05f74f6fc22a9256c36e508ad46e822c9fb975a36a4f22bcd51265bd05597ada373992435d23336190bea9e3bd79519b6f54a0d85381d5418ef3b3aaaebb6a79462b6f8a8f9ffd02afd451febc4bffc5a5845baa5456b8a2aa5f108831969d171ff408f9d74fda6e1c5c3525523afc4bec2efec8d1cacaf2b6a4e272f5d7f440cee6c1126744f6c63a02aa1d040e53327b762ec287fb540428bef431274b913527de2bc3d2f5217e9349350ab2b60cafbf83d337a05b582bfc64cdb8d77f24093f15372c0580f6cc91a6120f0bf83abfb006ab946a2846bf9f4d6b2d3ab305afe91575d12bacf5ffb4b0fc5d101418eba53ae83346256d34d0533df9c51416fed18a76a4a0000"], + ["9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", 1, 0, -1, 13, 7, "fe4a90b14553917bfc135f70be759a0c106e9098f4f1e5b4f8bb745957b49ff75515dba6f193dfbe714eaec17daec7c471cf9107faaaaaaaaaaaaaafe0004fb471cb1d500096c7aff4ff382d8d01a1e4220b520004cd6584ebab973d811c739bd2391d5be53c71eca3364f4575555951702fba31c71c71473f1cc63d471d60d6aef33f7924dd9dddc78552fe3bd65b6db7e2c9e343b4f4bf94f5f77cf24dbd71d55525c03381ecc51f71c7947ffb665d1c71c75e57ea8e1e8757f77551168d100b40cfb6cb830b24b20f825924d7355a931b05c54444556264851514f1c73e507be1ffcc31e71cf94790046155546551015f34ad79834835c794603d57623d688354fc6abc7c95f5509154522bfd3ce3c73e51c37fa310a8ff1c358f88c78f8f64511444c502ac482bab24c71ab7719f481d1b641c51d6fe8478dff715ddf8f6858e3dc71cf9493ecffba5271c68d654fd94cd7ed555dddd45429018b7314dbe504c4edba9fcad9471076f95d4555fdd5777108966d7072871f614f2bcfa2f14f5c70c3bd4657cb7d9577f74c61eeb914264b6f9471fa470d38109248b1daab857c53044456d44ea2bdf1d61c71b7179c1f68c71c71c38f77b36eb56d55556131a7c65c98dd835872c227cdc021424929c4059a9681d09111515f2884d8c71d53e92c983ca3e31c69c73873960ef5057515564716bfe7d876d00d79c31007a8fc42b4f9c7dc9a54b51fff7ffddf980669839c714f9447bf81ee346bc71d66ab056ec6dd15459df15ba5c713ef95f3e5fc5d5ea8d416d7f7147ae83e8c6f5dbff745304340f621834d618efea45bbec71d60c7a00"], + ["byte data byte data byte data byte data byte data byte data byte data byte data byte data byte data byte data byte data byte data byte data byte data byte data byte data byte data byte data byte data byte data byte data byte data byte data byte data byte data byte data byte data byte data byte data byte data byte data byte data byte data byte data byte data byte data byte data byte data byte data ", 3, 0, -1, 21, 6, "fe363eb7c12901ec7db7eef3fc1287842a724204e3a17a94106ea71c78d0bb61bec46a57a4bb750aec25ba758b7775dff165dba10a7ff65c0f973cfe7976aec13dbdf1b583449597115a0907faaaaaaaaaaaaaaaaaaaaaafe004a6845543518319461702001b7fc73ff028fe9233f968f064c4fc7681d9654c2be57dddf135b744fed4c880e0ec5e85ae289bc721eb31a4e6952772379792a90b3399dbdf3502abbaacccae5e8365378fb678dd594d7cb65b9405d7936df2b9b91ed59e3ebff347b706ebed83f3133afd725ed9c814c3417165bbeb3f40436301d03b15dfe50453c7b8278fe3c5e40b3a2f1d8d8ccdaee000fd287c013e9d1381fa29af7c22aaf06665aab338a29e59caf5fd534b3d725c945d15f41b8e369010fde0170499a85ba293b937a90eb72547f8d7a179fb1ad03a19cc2d1176eb4bbd69d48a2bd2c0a79e6178f51ed1e373ebc9ef8e1cbf19fffdf85bfa51216e4755591b5bb4733911d4ac185ea26d0abb5eeb4de2ac544ea77144b046cf1b1594fc423f8406f8464feade9fc8c8bea2399b7149c590dfa98695a3143702736f6bd42f5b67bfb89bb82448aaa86e4a26a747d5774f36b6b4e7948028423d6a84ae4dc8eba4d2983277feaaba171db02635bb5523008c4f7cbdf3fca665997fcbeebba98dd3ef19f6f8b33a2d8897149ffa0ec5bc21a4af98a716e1ee7b871b3035b7fce9feb2bd4e14ac9f8f28842789570320bfc9931c71c5a8a9ea2dc24f6371196dbcc8d8db88eedda3ce43dd223a617833616c37b8b5e062cfda3ff26b2f703870d49903de4995f5f754d23e43972f2a2be3629eed5ef406235cde6f94c406ca89a1f9593ff5167f4245fb09fbecfbbf8fc550651adef4498d513c79c76abcd23aa9f62bc90eada81ea291d093c691771eb3147b1311d4fb4a87efb6cff262ff20e5fd12cdae3acee0d4cb735f1e5be26bf9066d5a5e37c4d50cd8f7f32861265b98abc0b39617a9463b7112ada65b26d0a20f4d6ae9477d07878a66707dde77d5fd3fa68567ac3696bdadfb81eeb8406e6b77d530386ca73897861e7d87bf7962e4a564f36aba2ce023f8c0e966090abe61c7347e98ebf9beb9372833f65ec4f7303a7f99197776e97bdf33116f5b75a0d8604590c86d3290669bab15479146bbb0b5357be7b405cd1dff3fa663f99d7c9cce5393587b28b4fab56917c17230432e75f5bd88c53e4730869fba82874f62f7ae6dc15fc755d7513f164efa222be3ca8fec5aff851f401c6b7c71b17ac72379190ab65e2a47e6a824febf6eba9b454d2919dcdc702171be71c54fe2033f9313fed94ff8e81ff72087ba55d28f768e77f3b32bf9fe1ef970899fd242ba299e90208ed5dab58a937ef127367540d96b9ff855417fc0d30d8cc8a890319fd8a962b89b4a37205c438c16b28c7f608262967dbe68440b2cef3a3eba8ed354777da1ba10532605d4f6117680e96848cf63cea1e7cb7725ba9531b13d7728bd4dee9ceb9ffb2be52ccb28d5c386abf034914734f7ea0963679500b45937da84c9a0b111b7cccfe776037d33321d9fd184756edea830fb67df6d450ef48c07ec255ab57851ce0c26a0d9708d6620e48db48c8eab6ad137c1cb432c3a95e95a9f40b46733e5c2ffeb6b3fbfcffb8064ba910f00c4806f1f755c73fb73c7afa872ba570ab85aaad042fac44f63d136e247a9791bbaa55dbfbd0af864fbefbf7fcdd57bb7aa26fef85bc61ce38b2e833baea3e454c11e81ec48f704c2fdcbc283b1c4d3b13b1fdfe388ff7aabd2534b9ffcb7b800"], + ["prektsmgqerpcriyjm!,!hkfankqtsrqopz!vmhnotiroq;r!?ekcipppppppppppppppppppppppp", 0, 0, -1, 4, 2, "fe729f3fc164b6106e9249ebb754fa75dba72ff2ec164a3507faaaaafe00921a00fba7cbd50eb94fb3d2b24a08ccb923dbf12c7f2dcfc096f91719a582f46bd23a6e1687d2c972294f925afa591bc69124fad67a7f3986e795c93e7b26aa5521d21dacaa8673fc00796f45ffba716bd04d03b1dba874af9dd795dc72ea26229d059008fcfe86409500"], + [",fveff,ysr!us?zzjcyozbjtpnh?aps;rigvz;okfkwirejqj!qa;;;;;;;;;;", 1, 0, -1, 4, 5, "fe1824bfc14272106ea8c56bb753ce85dba32112ec12c77107faaaaafe0192450082ce4b6706b2b8af21897b9c4a91734fd063629b1d8deae9855c6fa0bcdad356cd0ff6c2598868afb3c8fcecd52029c01ef4fb2fa48da6cca872faee207101f643ddefa690f80079ec47ff915b6b904c6311eba2ae2f85d1d8a27ee92dee37049e609cfeda53a500"], + ["197834199444734599047796", 1, 0, -1, 1, 6, "febbfc15506eb4bb74d5dbadaec10107faafe000009fb4bb0ceedba68fb853c8f3d600444ffa48d05cb8baa2fdd7e12e9667049fdfeec100"], + ["17300540039481501468148583841710577909639375835732099", 3, 0, -1, 3, 1, "fe10fbfc1451106ea93ebb7522d5dba88a2ec168f507faaaafe00da80027a04df14188fda3a7c7c9a0a4d6dfe5ec070e702f449aa2cdb820a4401a768b29aac52038cfc7d2235452eda7fbfe005eb463fb4caad0516915ba79efadd1af462eacc4370461642fe760bf80"], + ["156713373123807826012956072920985024575793509150", 3, 0, -1, 3, 3, "fe5283fc11ab106e8514bb74f845dba878aec1233d07faaaafe01ab200338c2682a46b59a5d21e1fd8f652bb72ad11da250b4a7fd592d78d3121572959824bc78862ec28ac7a055145e44fff0050c46ffa1d2bd0451310ba6f2fedd549712eaf160b0460c3cfe5b84400"], + ["97058709262", 0, 0, -1, 1, 0, "fe5bfc13906eb6bb74a5dba2aec10507faafe01b00eff6258213d8ba3981c4aab0a9004a97fbdcd057b3baf76dd019aeba2b05460fe8b480"], + ["34961507286771922", 3, 0, -1, 1, 3, "fe43fc13506e9cbb7485dba9aec12507faafe0160033de85ed18aa9c64638c4530f70070dffa5c104bacba29ddd451aea8a904687fe3c500"], + ["159255232356897556335229745653445256127057", 1, 0, -1, 2, 1, "febe3fc12d906eafebb74415dba722ec173d07faaafe009b00a30592f65033ddedf18c994bf32c7bd9ab359f7ac4384a494afa3cfb0044c53fb3aad047511ba66f95d039d2eac2df04cb42fefdd380"], + ["/-1.VZIP", 2, 0, -1, 1, 2, "fe9bfc11506e90bb7435dba82ec16507faafe002007f598ea8c92a972b09933fee48806faffbcd5057ecba8995d7432ead5905831fe75e00"], + ["qx?p!r!igvzrwoqv?ikkkkkkkkkkkkkk", 0, 0, -1, 2, 2, "fe14bfc140d06e9eabb757d5dba142ec142907faaafe00f500fbbfd51aca69afc17eadaf621dedfea48aa6aa9c965742b51b9a7efe806ac6bfa12a7043511badffadd6a762ea915b053569fede0780"], + ["-0", 0, 0, -1, 1, 2, "fe4bfc14906e90bb7525dba3aec17507faafe00700fbcd57454997ed2df203792d4a004f2ffb2c504bcabac925d5492ebd3905035fef4e00"], + ["v,qtunyigbqrjuio?b!kfeqlhyqbtayc,cbttttttt", 1, 0, -1, 3, 6, "fee443fc1761906eb546bb74d895dbac8b2ec1216107faaaafe002e4009fabd4bdc5cb8fb6fa79c90893e3bfe998a19a4ee3dfac1eee210541ddbed4080eab9e8732d35f57d8be195cb73dfa8064944bfb46eb90541f18bab61fd5d73c226e9f436704e16adfed90a800"], + ["xntf!iv,mrluxuvoxe;zys,k,rsyatpmhhjgr;ykennnnnnnnnnnn", 0, 0, -1, 3, 2, "fe12f3fc156c506e942cbb757a95dba16faec156b507faaaafe00a4000fbbe7d5160b7ded7aa41e998a66b266de592760a4dc43f35a31822662b9f3e582dea849de2c2fa1138271da9ade4ff805a6467fabcea904a2310babfcfa5d4a50b6ea3cbe505e337afe9fd3200"], + ["-*$5XFB2%88", 2, 0, -1, 1, 4, "fe03fc10106ebebb7435dbaeaec14507faafe00b004ad5a78476d68c67c2b2a3ec72806ce3f86c7049e2badfcdd373ee934905309fe33b80"], + ["850902690648268841680344282300334174509686325772", 3, 0, -1, 3, 5, "fecadbfc1369506eaff0bb7408c5dbaf462ec11fe107faaaafe01aef00066982ae27b71e35c82d6d03ae302d65fc0cf0b4b4710a16008d2e0dd7ebb9f3568d0e01f8f5264779b3084b31a6fc8054944bf9daeaf0556514ba35af8dd346432e942d9d042e54bfe0fe0d00"], + ["476546", 2, 0, -1, 1, 5, "fee3fc14106e82bb7435dba42ec10d07faafe00b0043941c606c5492ce48ee2ffdfe00700bfa32b04f47ba4ca5d1fa2e8f7705beafe49200"], + ["18814959338", 2, 0, -1, 1, 3, "fe1bfc16906ebabb74f5dba4aec10d07faafe00d007630374ab109fc1d092798e396806107f964b05c3dba678dd694aeb2d905883fe05100"], + ["gahjdgfqhu,;cweecqopj?fr;wehvpsqomenwqrxyezoe;kmyx;vyvqdee", 3, 0, -1, 6, 3, "fe45120dbfc1370302106e975d7ecbb74d9c3195dbad9b03b2ec1201d34907faaaaaaafe0163e20a0033cae5d7686c35b8e4fe5baaaf6209140ec41f2f38bd5597692780f22cfb3faa57a395e6d879c0f7aa53d1992a583ede83d94a22e7bb5f3192bf26a1a3ebfa6824f7bc4adc374fdeca2183391438e85205f01f0b657783a8cdc41c9170868f114679ac7b703a9362eb4b219b463115b6aafea9c24a7829fbf11bed6252bdcefb805aac84c4ffa346f36bd04c3f31512ba2116e4fa5d599f3c2ceeaf52c0a4b047c3d57dafe5b8e48b900"], + ["rlcekuvw?gmdkyn!tuemukewpdsxhwdc!nnnnnnnnnnnnn", 2, 0, -1, 4, 2, "fed2fb3fc107a5106e92cb6bb74c5875dbac6792ec14cb2507faaaaafe00193e007f655b98ba173cb266c612b6d5851580cb76ab2d86095dc93678970b2c28d5facde685918c708e3cb1d09a02815d00958cf2fbf638944030e91e7aee93d509e53efdaacb13fd805e6d47ffa8aaebd05ebdb1ebac962f95d4f4ea46ea191e89052bf81cfe4d5bd900"], + ["9413149993340443910325583", 1, 0, -1, 1, 3, "fedbfc16906e8ebb75d5dba52ec10d07faafe01300b77a5ae2f39f84955268f8a0a080693bfb75905c79ba6a7dd536aea3f104e33febcd00"] + ]; } diff --git a/test/golden/fenix7/about.png b/test/golden/fenix7/about.png index 3f74946..1e4799d 100644 Binary files a/test/golden/fenix7/about.png and b/test/golden/fenix7/about.png differ diff --git a/test/golden/fenix7/code.png b/test/golden/fenix7/code.png index d42686b..11d13d0 100644 Binary files a/test/golden/fenix7/code.png and b/test/golden/fenix7/code.png differ diff --git a/test/golden/fenix7/code_qr.png b/test/golden/fenix7/code_qr.png new file mode 100644 index 0000000..32ccc0a Binary files /dev/null and b/test/golden/fenix7/code_qr.png differ diff --git a/test/golden/fr255s/about.png b/test/golden/fr255s/about.png index b2f2548..70134e0 100644 Binary files a/test/golden/fr255s/about.png and b/test/golden/fr255s/about.png differ diff --git a/test/golden/fr255s/code.png b/test/golden/fr255s/code.png index fc6989a..7b112ec 100644 Binary files a/test/golden/fr255s/code.png and b/test/golden/fr255s/code.png differ diff --git a/test/golden/fr255s/code_qr.png b/test/golden/fr255s/code_qr.png new file mode 100644 index 0000000..96e1792 Binary files /dev/null and b/test/golden/fr255s/code_qr.png differ diff --git a/test/golden/fr70/about.png b/test/golden/fr70/about.png index d7d18a0..8980df8 100644 Binary files a/test/golden/fr70/about.png and b/test/golden/fr70/about.png differ diff --git a/test/golden/fr70/code.png b/test/golden/fr70/code.png index 4353f5b..a0a2453 100644 Binary files a/test/golden/fr70/code.png and b/test/golden/fr70/code.png differ diff --git a/test/golden/fr70/code_qr.png b/test/golden/fr70/code_qr.png new file mode 100644 index 0000000..628b094 Binary files /dev/null and b/test/golden/fr70/code_qr.png differ diff --git a/test/golden/fr965/about.png b/test/golden/fr965/about.png index 65e3902..8e7d950 100644 Binary files a/test/golden/fr965/about.png and b/test/golden/fr965/about.png differ diff --git a/test/golden/fr965/code.png b/test/golden/fr965/code.png index 35d817e..dca4ce3 100644 Binary files a/test/golden/fr965/code.png and b/test/golden/fr965/code.png differ diff --git a/test/golden/fr965/code_qr.png b/test/golden/fr965/code_qr.png new file mode 100644 index 0000000..97db8bd Binary files /dev/null and b/test/golden/fr965/code_qr.png differ diff --git a/test/golden/instinct3amoled45mm/about.png b/test/golden/instinct3amoled45mm/about.png index 75ad5de..89f3826 100644 Binary files a/test/golden/instinct3amoled45mm/about.png and b/test/golden/instinct3amoled45mm/about.png differ diff --git a/test/golden/instinct3amoled45mm/code.png b/test/golden/instinct3amoled45mm/code.png index 6cabbac..f393183 100644 Binary files a/test/golden/instinct3amoled45mm/code.png and b/test/golden/instinct3amoled45mm/code.png differ diff --git a/test/golden/instinct3amoled45mm/code_qr.png b/test/golden/instinct3amoled45mm/code_qr.png new file mode 100644 index 0000000..a0e427a Binary files /dev/null and b/test/golden/instinct3amoled45mm/code_qr.png differ diff --git a/test/golden/venusq2/code.png b/test/golden/venusq2/code.png index 42c16a7..8ef5016 100644 Binary files a/test/golden/venusq2/code.png and b/test/golden/venusq2/code.png differ diff --git a/test/golden/venusq2/code_qr.png b/test/golden/venusq2/code_qr.png new file mode 100644 index 0000000..63bc766 Binary files /dev/null and b/test/golden/venusq2/code_qr.png differ diff --git a/test/golden/venux1/code.png b/test/golden/venux1/code.png index bcfd63e..a80362d 100644 Binary files a/test/golden/venux1/code.png and b/test/golden/venux1/code.png differ diff --git a/test/golden/venux1/code_qr.png b/test/golden/venux1/code_qr.png new file mode 100644 index 0000000..8d34f4c Binary files /dev/null and b/test/golden/venux1/code_qr.png differ -- cgit v1.2.3