mirror of
https://github.com/SeedSigner/seedsigner.git
synced 2026-10-05 15:08:25 +00:00
New SeedQR and mnemonic printable templates
* Renaming and re-org of existing templates * Removed older, less polished templates
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,294 +0,0 @@
|
||||
import math
|
||||
|
||||
def generate_qr_template(qr_size, num_words=24, block_size=5, show_timing_marks=False):
|
||||
if num_words == 24:
|
||||
word_cols = 2
|
||||
else:
|
||||
word_cols = 1
|
||||
|
||||
html = """
|
||||
<html>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Open+Sans&display=swap" rel="stylesheet">
|
||||
|
||||
<style>
|
||||
body {
|
||||
margin-top: 5em;
|
||||
text-align: center;
|
||||
font-family: "Open Sans", sans-serif;
|
||||
-webkit-print-color-adjust: exact;
|
||||
}
|
||||
.title {
|
||||
margin-top: 0.5em;
|
||||
font-size: 1.5em;
|
||||
margin-bottom: 1em
|
||||
}
|
||||
table {
|
||||
margin-top: 1em;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
td {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
}
|
||||
.qrcell {
|
||||
text-align: center;
|
||||
font-size: 0.35em;
|
||||
color: black;
|
||||
width: 13px;
|
||||
height: 9px;
|
||||
}
|
||||
.qr_table {
|
||||
margin-left: 4em;
|
||||
display: inline-block;
|
||||
}
|
||||
.filled {
|
||||
background-color: black;
|
||||
border: none;
|
||||
color: white;
|
||||
}
|
||||
.col_name, .row_name {
|
||||
text-align: center;
|
||||
font-size: 0.7em;
|
||||
color: #aaa;
|
||||
}
|
||||
.col_name {
|
||||
border-top: 1px solid #bbb;
|
||||
border-bottom: 1px solid #bbb;
|
||||
height: 2em;
|
||||
}
|
||||
.row_name {
|
||||
border-right: 1px solid #bbb;
|
||||
border-left: 1px solid #bbb;
|
||||
width: 2em;
|
||||
}
|
||||
.first_td {
|
||||
border-top: 1px solid #bbb;
|
||||
border-left: 1px solid #bbb;
|
||||
}
|
||||
.col_block_divider {
|
||||
border-right: 1px solid #bbb;
|
||||
}
|
||||
.row_block_divider {
|
||||
border-bottom: 1px solid #bbb;
|
||||
}
|
||||
.no_border {
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.word_list_table {
|
||||
border: 1px solid #aaa;
|
||||
"""
|
||||
|
||||
if num_words == 12:
|
||||
html += "margin-left: 10em;\n"
|
||||
else:
|
||||
html += "margin-left: 0;\n"
|
||||
|
||||
html += """
|
||||
float: left;
|
||||
}
|
||||
.word_list {
|
||||
font-size: 0.5em;
|
||||
text-align: right;
|
||||
padding-top: 2em;
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
}
|
||||
.word_row {
|
||||
height: 2.5em;
|
||||
}
|
||||
.word_num {
|
||||
width: 1em;
|
||||
text-align: right;
|
||||
color: #999;
|
||||
}
|
||||
.word_blank {
|
||||
color: #ccc;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
"""
|
||||
|
||||
html += """
|
||||
<table align="center" class="word_list_table">
|
||||
<tr>
|
||||
<td class="word_list">
|
||||
"""
|
||||
for i in range(1, num_words + 1):
|
||||
if i == 13:
|
||||
html += """
|
||||
</td>
|
||||
<td class="word_list">
|
||||
"""
|
||||
html += f"""<div class="word_row">
|
||||
<span class="word_num">{i}: </span><span class="word_blank">____________________________</span>
|
||||
</div>
|
||||
"""
|
||||
html += "</td></tr></table>"
|
||||
|
||||
y_names = "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,X,Y,Z"
|
||||
|
||||
html += """<table align="center" class="qr_table">"""
|
||||
html += f"""<tr rowspan="{block_size}"><td class="col_block_divider row_block_divider first_td"></td>"""
|
||||
for j in range(0, math.ceil(qr_size/block_size)):
|
||||
html += f"""<td colspan="{block_size}" class="col_name col_block_divider">{j + 1}</td>"""
|
||||
html += "</tr>"
|
||||
|
||||
for i in range(0, qr_size):
|
||||
html += """<tr>\n"""
|
||||
if i % block_size == 0:
|
||||
html += f"""<td rowspan="{block_size}" class="row_name row_block_divider qrcell">{y_names.split(",")[int(i / block_size)]}</td>"""
|
||||
for j in range(0, qr_size):
|
||||
html += f"""<td class="qrcell {"row_block_divider" if i == qr_size - 1 else ""} {"col_block_divider" if j == qr_size -1 else ""}" id="{i}_{j}">·</td>"""
|
||||
html += """</tr>\n"""
|
||||
html += "</table>"
|
||||
|
||||
html += "<script>"
|
||||
|
||||
def fill(i, j, clear_contents=True):
|
||||
js_result = f"""document.getElementById("{i}_{j}").classList.add("filled");\n"""
|
||||
if clear_contents:
|
||||
js_result += f"""document.getElementById("{i}_{j}").textContent = '';\n"""
|
||||
return js_result
|
||||
|
||||
def no_border(i, j):
|
||||
js_result = f"""document.getElementById("{i}_{j}").classList.remove("row_block_divider");\n"""
|
||||
js_result += f"""document.getElementById("{i}_{j}").classList.remove("col_block_divider");\n"""
|
||||
js_result += f"""document.getElementById("{i}_{j}").classList.add("no_border");\n"""
|
||||
return js_result
|
||||
|
||||
|
||||
# Generate the corner registration box
|
||||
def fill_registration_box(offset_i, offset_j):
|
||||
result = ""
|
||||
for i in range(0, 7):
|
||||
clear_middot = i != 0 and i != 6
|
||||
i += offset_i
|
||||
result += fill(i, offset_j + 0, clear_contents=clear_middot)
|
||||
result += fill(i, offset_j + 6, clear_contents=clear_middot)
|
||||
for j in range(1, 6):
|
||||
j += offset_j
|
||||
result += fill (offset_i + 0, j)
|
||||
result += fill (offset_i + 6, j)
|
||||
for i in range(2, 5):
|
||||
clear_middot = i != 2 and i != 4
|
||||
i += offset_i
|
||||
result += fill(i, offset_j + 2, clear_contents=clear_middot)
|
||||
result += fill(i, offset_j + 3)
|
||||
result += fill(i, offset_j + 4, clear_contents=clear_middot)
|
||||
|
||||
for i in range(offset_i, offset_i + 7):
|
||||
for j in range(offset_j, offset_j + 7):
|
||||
result += no_border(i, j)
|
||||
return result
|
||||
|
||||
html += fill_registration_box(0, 0)
|
||||
html += fill_registration_box(0, qr_size - 7)
|
||||
html += fill_registration_box(qr_size - 7, 0)
|
||||
|
||||
if show_timing_marks:
|
||||
# Fill the dotted timing marks
|
||||
html += fill(8, 6)
|
||||
html += fill(10, 6)
|
||||
html += fill(12, 6)
|
||||
if qr_size > 21:
|
||||
html += fill(14, 6)
|
||||
html += fill(16, 6)
|
||||
if qr_size > 25:
|
||||
html += fill(18, 6)
|
||||
html += fill(20, 6)
|
||||
|
||||
html += fill(6, 8)
|
||||
html += fill(6, 10)
|
||||
html += fill(6, 12)
|
||||
if qr_size > 21:
|
||||
html += fill(6, 14)
|
||||
html += fill(6, 16)
|
||||
if qr_size > 25:
|
||||
html += fill(6, 18)
|
||||
html += fill(6, 20)
|
||||
|
||||
if qr_size > 21:
|
||||
# Fill the smaller inset registration box
|
||||
html += fill(qr_size - 7, qr_size - 7, clear_contents=False)
|
||||
|
||||
# fill the sides
|
||||
for i in range(qr_size - 9, qr_size - 4):
|
||||
clear_middot = i != (qr_size - 9) and i != (qr_size - 5)
|
||||
html += fill(i, qr_size - 9, clear_contents=clear_middot)
|
||||
html += fill(i, qr_size - 5, clear_contents=clear_middot)
|
||||
for j in range(qr_size - 8, qr_size - 5):
|
||||
html += fill(qr_size - 9, j)
|
||||
html += fill(qr_size - 5, j)
|
||||
for i in range(qr_size - 9, qr_size - 4):
|
||||
for j in range(qr_size - 9, qr_size - 4):
|
||||
html += no_border(i, j)
|
||||
|
||||
|
||||
def add_block_dividers(i, j, class_name):
|
||||
return f"""document.getElementById("{i}_{j}").classList.add("{class_name}");\n"""
|
||||
|
||||
for i in range (0, qr_size):
|
||||
for j in range (block_size - 1, qr_size, block_size):
|
||||
html += add_block_dividers(i, j, "col_block_divider")
|
||||
|
||||
for i in range (block_size - 1, qr_size, block_size):
|
||||
for j in range (0, qr_size):
|
||||
html += add_block_dividers(i, j, "row_block_divider")
|
||||
|
||||
|
||||
html += """</script>
|
||||
</body>
|
||||
</html>"""
|
||||
|
||||
return html
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description="""
|
||||
Generates a blank QR code template at 21x21, 25x25, or 29x29.
|
||||
|
||||
ex: python3 qr_code_template.py 25 12
|
||||
ex: python3 qr_code_template.py 29 24
|
||||
|
||||
Optionally change the block size divider guides:
|
||||
|
||||
python3 qr_code_template.py 29 24 --block_size 6
|
||||
""",
|
||||
formatter_class=argparse.RawTextHelpFormatter
|
||||
)
|
||||
|
||||
# Required positional arguments
|
||||
parser.add_argument('qr_size',
|
||||
type=int,
|
||||
choices=[21, 25, 29],
|
||||
help="QR code size. 21 for 21x21, 25 for 25x25, 29 for 29x29")
|
||||
parser.add_argument('num_words',
|
||||
type=int,
|
||||
choices=[12, 24],
|
||||
help="Number of words in the mnemonic seed. 12 or 24")
|
||||
|
||||
# Add optional arguments
|
||||
parser.add_argument('-b', '--block_size',
|
||||
type=int,
|
||||
default=5,
|
||||
help="Size of the manual entry zoom blocks")
|
||||
parser.add_argument('-t', '--timing_marks',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help="Show timing marks (the dashed blocks linking the three large registration boxes")
|
||||
args = parser.parse_args()
|
||||
|
||||
html = generate_qr_template(qr_size=args.qr_size, num_words=args.num_words, block_size=args.block_size, show_timing_marks=args.timing_marks)
|
||||
file = open(f"{args.num_words}words_seedqr_template-{args.qr_size}x{args.qr_size}.html", "w")
|
||||
file.write(html)
|
||||
file.close()
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user