initial import

This commit is contained in:
seedhammer 2026-05-13 15:40:19 +02:00
commit 67e137af6a
179 changed files with 11049 additions and 0 deletions

24
LICENSE Normal file
View File

@ -0,0 +1,24 @@
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <https://unlicense.org>

16
README.md Normal file
View File

@ -0,0 +1,16 @@
## Public content of seedhammer.com
### Run local viewer
```sh
$ go run ./cmd/viewer
```
The [Nix](https://nixos.org) helper script runs a webserver on localhost:8080 and
reloads it on file changes.
```sh
$ nix run .#
```

View File

@ -0,0 +1,21 @@
--
title: Attitude to Privacy
description: A bitcoin-only company operated by a privacy-concerned team.
--
We believe that your privacy is a fundamental right, and we take your privacy just as seriously as our own.
This website does not track its visitors and only use cookies for the shopping cart. Note that embedded content such as tweets may track its viewers.
You only need to provide the following to order from us:
- A Name (we recommend using a pseudonym)
- A Phone Number our courier company can reach you on (can be a burner phone)
- An email address (consider using a disposable email address)
- A delivery address (we ship to Post office boxes and local parcel delivery centres)
We understand that privacy is important to our customers, which is why we delete all this data (except for the order number and order content) 4 months after dispatch.
This ensures that only information we strictly need to deliver you order is being stored and only for as long as necessary.
Payments are anonymous when using BTC on our BTC Pay Server with either a Lightning or On Chain payment option.

30
about/contact.md Normal file

File diff suppressed because one or more lines are too long

6
about/fs.go Normal file
View File

@ -0,0 +1,6 @@
package about
import "embed"
//go:embed *.md
var FS embed.FS

72
about/how-it-started.md Normal file
View File

@ -0,0 +1,72 @@
--
title: How It Started
description: What problem does SeedHammer solve for Bitcoiners and how an innovative new way of securing multisig backups was invented.
--
The story behind SeedHammer starts in 2021, when we were searching for an easy, secure and scalable way to create backups of multisig bitcoin wallets onto a durable material like steel.
While there were lots of manual metal backup options available, they were either missing a way to store the wallet descriptor or XPUBs, had security or reliability flaws or were tedious and time consuming to use when backing up complex multisignature wallets.
## XPUBs Must Be Part of the Backup
For multisig setups especially, just backing up the seed phrases of each share is not enough. Without also having the XPUBs for all the seeds in a multisig wallet, you cant later recover the wallet or move the funds.
A so-called wallet “output descriptor” contains exactly these XPUBs (and a bit more information) in order to recreate a multisig wallet fast and easy. Most wallets recommend separately backing up the wallet descriptor on paper or using online storage, but thats either fragile or it risks your wallets privacy, or both.
You want to store those XPUBs as securely and safely as your seed words, but none of the existing metal seed backup solutions catered for this. We ended up with the good old embossing stamps and a bunch of steel plates from the local hardware shop.
## A Painful Experience
Individually hammering the descriptor (or all the XPUBs) by hand quickly became unmanageable, tedious and physically unpleasant. Furthermore, the result was not convincing in its visual appearance, and it was hard to validate the accuracy of the long strings of text. A single error while hammering a plate means throwing the plate away and starting again.
Loading the XPUB backups back into the wallet coordinator software for testing was also extremely tedious and error prone. The sleep-well-at-night factor was simply not high enough.
Due to these impracticalities we looked into the possibility of developing an automated solution that not only would do the process faster and easier but also introduce the possibility for easy recovery with QR codes.
## An Automated Solution
We believed the ideal solution was to have a provably air gapped offline “hammer” that can automatically engrave all the required information, both the seed and the descriptor onto a set of metal plates.
In the search for an automated backup solution, it became clear that there was no existing solution available that was specific to a Bitcoiners needs. After months of research and trial and error, we finally found an off-the-shelf industrial engraving machine that was:
- durable enough for the job of hammering multisig setups.
- provably air gapped and stateless.
We then added some improvements to the physical machine and developed a simple, intuitive and easy-to-use controller software. Together we called it the SeedHammer.
## The Controller {#controller}
We started to develop the controller on the same development board as Specter DIY. However, mainly because of delivery problems, we chose to move away from this approach.
In frustration we chose to build the software as an app that could run on Android, Mac OS, Linux etc. letting the user decide which unit to run it from - and if the user wanted a controller with the machine we would offer a cheap burner phone.
But we never felt quite satisfied with this approach as it would be too tempting to run it on a device that would not be truly air gapped. Furthermore we could not satisfactorily prove that the phone would not leak the private keys.
Yet again we switched platform and chose to use the same hardware setup as SeedSigner (Raspberry Pi Zero). A few things was in favor of this choice:
- Around half the price of a Specter DIY (incl. case) at that time.
- The Specter board is a development board (no guarantee for its continuation).
- The obvious advantage of Specter DIY, secure boot, can be circumvented.
- An statement from The Raspberry Pi Foundation that Pi Zero soon will be publicly available again in satisfying quantities.
Without any evidence we also had a feeling that many of our initial users would own or be familiarized with a SeedSigner already. And the choice did not rule out a later version of the software that could run on any other open source signing device.
## Self-contained Setup
Without violating any industry standards we wanted to figure out a way so the minimum amount of physical backup steel plates would be enough to recover the full multisig wallet - without a separate descriptor stored anywhere.
We did explore the idea of adding the full descriptor on the backside of each plate, but it would take far too long for the machine to hammer. Furthermore having the full descriptor on every plate is also a privacy risk as anyone with access to just a single plate would be able to easily see the full transaction history.
Then it dawned on us why not split up the descriptor into its component parts and distribute those parts rotationally onto the back of each of the seed plates. This way, any quorum of plates would inherently contain both the minimum number of seeds required to sign transactions as well as all the information needed to recreate the full wallet.
To give the user further comfort, we add onto the seed plates some additional non critical information like the fingerprint, title as well as the number of seeds (M-of-N).
## Recover With Minimum of Shares
The new way to structure the data on each plates front- and backside makes the minimum amount of plates enough to recover the wallet - even without any separately stored full descriptor.
Another security benefit is that the wallet balance and transaction history is also only easily available to people who have physical access to the M-of-N signing quorum so only those able to move coins can easily see how many coins are in the wallet.
In all other multisig backups we looked at on the market, losing the wallet descriptor and just a single plate (and therefor the derived XPUB) would mean an irretrievable loss of access to the funds in the multisig wallet.
This problem is now solved with the SeedHammer.

20
about/index.md Normal file

File diff suppressed because one or more lines are too long

23
about/our-goal.md Normal file
View File

@ -0,0 +1,23 @@
--
title: Our Goal
description: What we want to bring to the world. Our leading star.
--
## Goal
Our ultimate goal is to empower everyone to self-custody their Bitcoin in an easy, convenient and secure manner.
## From Seed Creation to Secure Spending
To be more specific we want to empower individuals at every stage of their Bitcoin custody journey, starting from receiving their first Bitcoin and extending all the way to spending it from a self-sovereign cold storage solution.
This journey involves several key steps, including generating a secure seed, funding a wallet, creating backups, facilitating recovery, and enabling seamless spending.
## Current Focus
The part of the journey we are working on now is the backup and recovery.
We want to enable everyone to produce self-sovereign steel backups of Bitcoin wallets.
The process must be user friendly, intuitive and simple.
Recovery should be as easy as scanning a QR - and for multisig: possible with the minimum amount of shares.
The solution must be air gapped and trustless, based on open source software and robust enough to be used by anyone from sovereign individuals to nation states.

View File

@ -0,0 +1,12 @@
--
title: The SeedHammer Ethos
description: Our values boiled down.
--
- No one needs to ever trust SeedHammer to safely use our products or services.
- The SeedHammer software will forever be free and open source.
- The SeedHammer hardware will forever be made of either:
- publicly available off-the-shelf components.
- easily auditable physical devices.
- Features will always be user- and community-driven so long as it does not conflict with the rest of the ethos.
- SeedHammer will forever be bitcoin only.

197
article.go Normal file
View File

@ -0,0 +1,197 @@
package content
import (
"bytes"
"fmt"
"html/template"
"io/fs"
"net/http"
"path"
"path/filepath"
"sort"
"strings"
"time"
"github.com/yuin/goldmark"
meta "github.com/yuin/goldmark-meta"
"github.com/yuin/goldmark/extension"
"github.com/yuin/goldmark/parser"
"github.com/yuin/goldmark/renderer/html"
"seedhammer.com/website/content/article"
"seedhammer.com/website/content/page"
)
type Article struct {
Slug string
Title string
Author string
AuthorLink string
Description string
Image string
Type string
Published time.Time
Content template.HTML
}
var allArticles struct {
bySlug map[string]Article
byDate []Article
tmpl *template.Template
}
type Section struct {
ID string
Name string
}
type TOC []struct {
Slug string
Name string
Index int
Sections []Section
}
func init() {
allArticles.tmpl = template.Must(template.ParseFS(page.FS, "icons.html", "base.html", "article.html")).Lookup("base")
arts, err := loadArticles(article.FS)
if err != nil {
panic(err)
}
allArticles.byDate = arts
allArticles.bySlug = make(map[string]Article)
for _, a := range arts {
allArticles.bySlug[a.Slug] = a
}
}
func docsHandler(urlPath string, fs fs.FS, toc TOC) http.Handler {
arts, err := loadArticles(fs)
if err != nil {
panic(err)
}
bySlug := make(map[string]Article)
for _, a := range arts {
bySlug[a.Slug] = a
}
for i := range toc {
toc[i].Index = i + 1
}
tmpl, ok := Templates[path.Base(urlPath)]
if !ok {
panic("template not found")
}
return CachingHandler(LoggingFunc(func(w http.ResponseWriter, r *http.Request) error {
slug := strings.TrimPrefix(r.URL.Path, "/"+urlPath+"/")
md := slug
switch md {
case "":
md = "index"
case "index":
return ErrNotFound
}
doc, ok := bySlug[md]
if !ok {
return ErrNotFound
}
args := struct {
Base string
TOC TOC
ActiveSlug string
Doc Article
}{
Base: "/" + urlPath,
ActiveSlug: slug,
TOC: toc,
Doc: doc,
}
if err := RenderPageTemplate(w, r, tmpl, args); err != nil {
return fmt.Errorf("docs: template failed: %v", err)
}
return nil
}))
}
func renderArticleTOC(w http.ResponseWriter, r *http.Request) error {
if err := RenderPageTemplate(w, r, Templates["articles"], allArticles.byDate); err != nil {
return fmt.Errorf("article: template failed: %v", err)
}
return nil
}
func renderArticles(w http.ResponseWriter, r *http.Request) error {
name := strings.TrimPrefix(r.URL.Path, "/article/")
if name == "" {
return renderArticleTOC(w, r)
}
art, ok := allArticles.bySlug[name]
if !ok {
return ErrNotFound
}
if err := RenderPageTemplate(w, r, allArticles.tmpl, art); err != nil {
return fmt.Errorf("article: template failed: %v", err)
}
return nil
}
func loadArticles(f fs.FS) ([]Article, error) {
var articles []Article
err := fs.WalkDir(f, ".", func(path string, d fs.DirEntry, err error) error {
ext := filepath.Ext(path)
if ext != ".md" {
return err
}
base := filepath.Base(path)
name := strings.TrimSuffix(base, ext)
md := goldmark.New(
goldmark.WithExtensions(
meta.Meta,
extension.Table,
),
goldmark.WithParserOptions(parser.WithHeadingAttribute()),
goldmark.WithRendererOptions(html.WithUnsafe()),
)
src, err := fs.ReadFile(f, path)
if err != nil {
return err
}
var buf bytes.Buffer
context := parser.NewContext()
if err := md.Convert(src, &buf, parser.WithContext(context)); err != nil {
return fmt.Errorf("article: %s: %w", path, err)
}
m := meta.Get(context)
art := Article{
Slug: name,
Content: template.HTML(buf.String()),
}
if d, ok := m["published"]; ok {
published, err := time.ParseInLocation("2006-01-02", d.(string), time.UTC)
if err != nil {
return fmt.Errorf("article: %s: failed to parse `published` field: %w", path, err)
}
art.Published = published
}
if title, ok := m["title"]; ok {
art.Title = title.(string)
}
if desc, ok := m["description"]; ok {
art.Description = desc.(string)
}
if desc, ok := m["author"]; ok {
art.Author = desc.(string)
}
if desc, ok := m["authorlink"]; ok {
art.AuthorLink = desc.(string)
}
if img, ok := m["image"]; ok {
art.Image = img.(string)
}
articles = append(articles, art)
return err
})
sort.SliceStable(articles, func(i, j int) bool {
return articles[i].Published.After(articles[j].Published)
})
return articles, err
}

View File

@ -0,0 +1,41 @@
--
author: SeedHammer
authorlink: https://twitter.com/SeedHammer
title: Adjust Raspberry Pi Camera Focus
description: Learn how to perform a focal lens adjustment on the Raspberry Pi camera.
published: 2023-09-15
image: camera-lens-adjustment.webp
--
If you experience poor QR scanning performance with the SeedSigner (or SeedHammer) controller then it is most likely due to the Raspberry Pi camera lens being adjusted to a wrong focal length from the factory. However, this can be easy adjusted with the right technique and tools.
<div class="grid">
<div></div>
<div>
<div class="img-center"><img src="/static/img/qr-out-of-focus.webp" alt="Raspberry Pi Zero camera before adjustment of the focus point" style="width: 120px"><small>Before adjustment.</small></div>
</div>
<div>
<div class="img-center"><img src="/static/img/qr-in-focus.webp" alt="Raspberry Pi Zero camera after adjustment of the focus point" style="width: 120px"><small>After adjustment.</small></div>
</div>
<div></div>
</div>
## Adjusting The Camera Focus
The Raspberry Pi camera is equipped with a lens capable of rotation for focus adjustments. Although it is marketed as a fixed-focus camera, it comes with three adhesive fix points to secure the lens in a particular position. In the image below, you can observe the glue placement, denoted by letters A, B, and C:
<div class="img-center"><img src="/static/img/raspberry-pi-camera-lens.webp" style="width: 320px; alt="Raspberry Pi Camera Lens"><small>Source: Raspberry Pi Foundation.</small></div>
In order to enable lens rotation for focus adjustments, carefully remove these adhesive blobs by hand using a sharp tool such as a needle, scalpel, or dental pick. Ensure that you completely disconnect the camera from the Raspberry Pi before proceeding with these adjustments.
<div class="img-center"><img src="/static/img/raspberry-pi-camera-remove-glue.webp" style="width: 320px; alt="Raspberry Pi Camera Remove Glue Blobs"><small>Source: Raspberry Pi Foundation.</small></div>
After successfully cleared away all traces of the adhesive, use a pair of tweezers or jewelry pliers to grasp the inner section of the camera, as illustrated below. It should turn without resistance. Gently rotate it counterclockwise a few times.
<div class="img-center"><img src="/static/img/raspberry-pi-camera-rotate-lens.webp" style="width: 320px; alt="Rotate lens on Raspberry Pi camera"><small>Source: Raspberry Pi Foundation.</small></div>
Subsequently, reconnect the camera to the Raspberry Pi and check the scanning performance. Repeat turning the lens until near field QR scanning seems in focus and works as expected.
Exercise caution to avoid over-rotating the lens, as excessive rotation may cause it to disengage, making it somewhat challenging to reposition it on the thread. Should this occur, gently place it back in position and rotate it clockwise until it securely engages.
Once you've attained the desired focus, there's no need for reapplication of adhesive. The lens will remain fixed in place and won't inadvertently shift, even in the event of minor impacts or jolts.

6
article/article.go Normal file
View File

@ -0,0 +1,6 @@
package article
import "embed"
//go:embed *.md
var FS embed.FS

95
article/attack-vectors.md Normal file
View File

@ -0,0 +1,95 @@
--
author: SeedHammer
authorlink: https://twitter.com/SeedHammer
title: Attack Vectors
description: Known security vulnerabilities to using SeedHammer.
published: 2023-02-25
image: evil-attack.webp
--
Your seed phrases are your bitcoin, so it is wise to be hypervigilant of the risks of using any electronic device that will come into contact with your seeds.
The risk we are defending against is exfiltration of seed phrases that the SeedHammer has come into contact with this is the objective any attacker will want to achieve.
Here are the attack vectors that we are working on diligently defending you from.
## Sound {#sound}
With sufficient knowledge of how a machine like SeedHammer works, being in close proximity, recording sound at the time actual seeds are being hammered, there is a theoretical possibility that someone could figure out the seed words being hammered into your plates.
<del>So when you do setup your SeedHammer, for now, think about doing so in a location where your machine cannot be easily overheard. Consider unplugging any smart speakers, powering down mobile phones and any device capable of recording sound in the area. You may also wish to play loud recorded music while the hammer is running.</del>
Since v0.11.1 of the SeedHammer controller software exfiltration of the private data is addressed by the introduction of [constant time engraving](https://github.com/seedhammer/seedhammer/releases/tag/v0.11.1):
<div class="embed-responsive embed-responsive-16by9"><iframe class="embed-responsive-item" src="https://www.youtube.com/embed/b3gb3Cgpwnc" title="Elimination of Sound Exfiltration: Seed Phrase"></iframe></div>
This also applies to the SeedQR codes:
<div class="embed-responsive embed-responsive-16by9"><iframe class="embed-responsive-item" src="https://www.youtube.com/embed/jIbB9UYTz4w" title="Elimination of Sound Exfiltration: Seed Phrase"></iframe></div>
## Radio Waves
Systems that use Bluetooth or WiFi transmit data that can be potentially decrypted and eavesdropped. Thats why SeedHammer has been designed around only using components that have no wireless or network transmission capabilities at all.
The entire system, from the hammering machine to the Raspberry Pi Zero controller, is completely air-gapped from the internet.
## Electromagnetic Noise
The stepper motors that control the engraving process on the SeedHammer produce very faint electromagnetic waves. A very sophisticated eavesdropper in close proximity to the machine - when it is operating - could potentially figure out a way of using those electromagnetic waves to guess what the machine is hammering into the plates.
It's obviously an unlikely scenario. A simple precaution dont tell anyone when or where your SeedHammer machine is going to be used.
## Data Exfiltration {#data-exfil}
The SeedHammer app can potentially exfiltrate your seeds by storing them on the SD card in the Raspberry Pi Zero. This can be due to either:
1. The image loaded onto the SD card has been tampered with by a middleman.
2. The original open source code contains an undiscovered backdoor.
To ensures that you truly have the image we intended to distribute always [verify](https://seedhammer.com/get-started/install-the-software#verify) the image you download from our [Github](https://github.com/seedhammer/seedhammer).
To eliminate any risk what so ever for any data exfiltration follow the in-app instructions and simply remove the SD card before entering any seeds.
![Remove SD card warning in the SeedHammer app](/static/img/remove-sd-card-warning.webp)
## Onlookers
Dont invite friends over to show them your SeedHammer hammering your actual seeds. Also, keep your device away from windows without blinds, security cameras or phones, laptops, TVs and tablets when hammering your seeds.
## Supply Chain Attack
The more obvious it is that a device is used to secure bitcoin, the more likely its supply chain will be of interest to criminals.
The Seedhammer machine and the Raspberry Pi components that make up the SeedSigner controller are all non-bitcoin specific devices.
Weve also designed the architecture of the SeedHammer system so that you dont have to trust the supply chain it comes from.
## Auto Generation of Seed Words {#generate-seed}
Bitcoin specific hardware products often try to help speed up the user experience by automatically generating a ready-to-use random seed phrase.
Because of the below mentioned risks associated with auto-generation of seeds, we do not offer auto-generation in the SeedHammer controller software:
- Backdoors
Any software or hardware wallet that offers to generate bitcoin private keys should be considered dangerous. It is impossible to rule out the risk of a backdoor in the software. Even if the company that makes the wallet is reputable, the device running the software could be compromised by third parties.
- Pre-loaded Seeds
Even air gapped devices running software that can produce private keys should not be considered 100% safe.
By air gapping on specialised hardware, it may be impossible for a third party to exfiltrate the keys, but the firmware the hardware came with may have been preloaded with keys already known to a malicious third party.
Some signers and wallets offer the user the option to introduce their own entropy via dice rolls or other techniques in order to improve your trust in the seed generation process. However, it is hard to prove conclusively that the software is actually using the entropy the user has introduced.
- Weak Entropy
Even if the software is open source and the developers behind a project are well intentioned, truly strong entropy is notoriously hard to produce.
We encourage our users to think carefully about how their seed phrases they are backing up were generated and the risks involved in not generating your own seed phrases from scratch.
*In order to generate your seeds as secure as possible consider using coin flips and/or dice rolls to manually generate strong entropy. There are many video tutorials available online to teach you the simple steps needed to create your own strongly random seeds entirely offline and without trusting a third party.*
## Comments
Do you have any questions, comments or maybe ideas on how to improve the security of SeedHammer do not hesitate to contact us at [team@seedhammer.com](mailto:team@seedhammer.com).

View File

@ -0,0 +1,74 @@
--
author: SeedHammer
authorlink: https://twitter.com/SeedHammer
title: Corrosion Test of The SeedHammer Steel Plates
description: See how the SeedHammer steel plates perform in an accelerated salt fog corrosion test (ASTM B117).
published: 2024-02-22
image: corrosion-test.webp
--
The original SeedHammer plates are made of stainless steel 316L - also known as marine grade. In order to test the corrosion resistance of steel 316L, we subjected the material to an internationally recognized accelerated corrosion test known as ASTM B117. *The European equivalent of this test is EN ISO 9227.*
We understand that most (if not all) users will never intentionally expose their SeedHammer backup plates to marine grade environment or bury them in the ground or other moist environments without any protective casing. Nonetheless, we want to adopt the same "paranoia"-approach to corrosion that we apply to everything else (such as our code) and see how the plates perform.
## What is ASTM B117
ASTM B117 is a standard by the American Society for Testing and Materials (ASTM) that outlines an accelerated corrosion testing method for metallic materials. This test simulates a corrosive salt spray environment to quickly evaluate the corrosion resistance of materials. The procedure involves exposing materials to a saline fog at a controlled temperature, aiming to accelerate the corrosion process and assess the protective quality of coatings.
## Benchmark
It's challenging to directly correlate test results with real-world exposure, as this depends on a multitude of variables in the conditions to which the metal is exposed. Nonetheless, ASTM B117 serves as an ideal benchmark for comparing alternatives to identify the most suitable material. For this reason, we chose to benchmark the stainless steel 316L against normal steel S235.
## The Results
We created a duplicate of the original plate using S235 steel. Before the test, we engraved the same seed onto each plate.
### The Stainless Steel 316L Plate
The original SeedHammer plate shows no signs of corrosion throughout the test. The plate remains easily readable even after many days in the test cabinet, and the test is concluded after a full 17 days without any negative effects on the plate.
<div class="grid">
<div>
<div class="img-center"><a href="/static/img/316l-408hrs.webp"><img src="/static/img/316l-408hrs.webp" alt="Steel 316L ASTM B117 testing 120 hrs" style="width: 300px"></a><small>Stainless steel 316L after 17 days of testing.</small></div>
</div>
<div>
<p>After 17 days (408 hours), the testing facility decided to halt the test, as no further changes in the material were expected.</p>
<p>The deposits around the screw holes are not due to the material but rather some residues from ordinary steel touching it (screw threads).</p>
</div>
</div>
### The ordindary steel S235 plate
The benchmarking plate demonstrates the severity of the ASTM B117 test. Within just one hour in the test cabinet, the plate showed signs of corrosion, and after few days it became totally unreadable due to severe amounts of corrosion.
<div class="grid">
<div>
<div class="img-center"><img src="/static/img/s235-1hrs.webp" alt="Steel 235 ASTM B117 testing 1 hr" style="width: 300px"><small>Steel S235 after 1 hour of testing.</small></div>
</div>
<div>
<p>After 1 hour, the plate shows signs of corrosion, although not to the extent that it becomes unreadable.</p>
</div>
</div>
<div class="grid">
<div>
<div class="img-center"><img src="/static/img/s235-3hrs.webp" alt="Steel 235 ASTM B117 testing 3 hrs" style="width: 300px"><small>Steel S235 after 3 hours af testing.</small></div>
</div>
<div>
<p>After 3 hours, the corrosion has progressed to a stage where reading the plate becomes difficult, and the QR code can not be scanned at all.</p>
</div>
</div>
<div class="grid">
<div>
<div class="img-center"><img src="/static/img/s235-48hrs.webp" alt="Steel 235 ASTM B117 testing 48 hrs" style="width: 300px"><small>Steel S235 after 2 days of testing.</small></div>
</div>
<div>
<p>After 48 hours, the plate is covered in corrosion to the extent that it becomes unreadable and is effectively useless.</p>
<p>It might be possible to retreive some information from the plate if the corrosion is grinded down. However, as the S235 acts as an benchmarking plate and clearly shows that steel 316L is far superior the experiment concluded here.</p>
</div>
</div>
## Conclusion
The test illustrates the resilience of stainless steel 316L to corrosion, even when exposed to harsh conditions for a prolonged duration.
Based on these results, we are confident that stainless steel 316L is an appropriate material for the SeedHammer plates in regard to corrosion.

View File

@ -0,0 +1,34 @@
--
author: SeedHammer
authorlink: https://twitter.com/SeedHammer
title: Enhance QR Readability With a Marker Pen
description: Improve the readability of QR codes hammered into steel by applying a solid marker.
published: 2023-08-09
image: marker-qr.webp
--
## Apply a Solid Marker
Some cameras have a hard time scanning QR codes off steel - which can be due to low resolution, unsuitable focal length of the camera, or simply bad lighting conditions.
By applying a solid marker like the one we [offer here](/shop#PSOLIDMARKERBLK) the readability can be improved to same level as a paper QR.
![QR before and after solid marker](/static/img/solid-marker-on-qr.webp)
## About Our Solid Marker
The marker we offer is a Sakura Solid Marker which contains solidified paint in a marker form. It marks through dust, rust, water inside or outside on smooth or rough surfaces. Dries within minutes and is permanent once dry. The resulting markings won't fade or wash off easily.
<div class="img-center"><img alt="Sakura Solid Marker" src="/static/img/solid-marker-black.webp" style="width: 200px;"></div>
## How to Apply The Marker
Simply apply the marker on the desired area.
![QR before and after solid marker](/static/img/solid-marker-applied-on-qr.webp)
Wipe the excess marker off leaving only paint in the dimples of the QR. Let it dry up.
<div class="img-center"><img alt="Steel plate after appliance of solid marker in QR code" src="/static/img/steel-plate-after-solid-marker-in-qr.webp" style="width: 377px;"></div>
Learn more about how to scan QR codes off steel in [this](/article/how-to-scan-qr-codes-off-steel-plates) article.

View File

@ -0,0 +1,29 @@
--
author: SeedHammer
authorlink: https://twitter.com/SeedHammer
title: How to Recover From a SeedHammer Backup
description: Learn how to recover a backup created with SeedHammer.
published: 2023-05-01
image: bitcoin-recovery.webp
--
## Recover Singlesig Wallet {#singlesig}
<p class="alert alert-warning">Keep the seed phrase and the SeedQR code away from all cameras except the signing device.</p>
1. Load the seed into a stateless signer.
- Use the seed words or scan the CompactSeedQR.
1. Most stateless signers can export the wallet as read-only (into eg. Sparrow Wallet).
## Recover Multisig Wallet {#multisig}
<p class="alert alert-warning">Keep the SeedQR code away from any camera controlled by Sparrow Wallet.</p>
<p class="alert alert-warning">Never input the seed words into Sparrow Wallet.</p>
1. Create a new wallet in Sparrow Wallet.
1. Under "Script Policy" click the camera icon. ![Click Script Policy in Sparrow](/static/img/sparrow-import-descriptor.webp)
1. Have the quorum of plates at hand. Cover the seed side of the plates (the side that contains the seed words).
1. Scan the QR code(s) on the descriptor side of the individual plate (the side **that does not** contain the seed words).
![Scan the QR into Sparrow](/static/img/sparrow-scan-descriptor.webp)
- Scan every QR on all descriptor sides until Sparrow Wallet recreates the wallet.

View File

@ -0,0 +1,61 @@
--
author: SeedHammer
authorlink: https://twitter.com/SeedHammer
title: How to Scan QR Codes off Steel Plates
description: Learn the technique to easily read the QR codes from the SeedHammer steel plates.
published: 2023-04-07
image: scan-qr-of-steel.webp
--
The technique is demonstrated in this video and explained in depth below.
<div class="embed-responsive embed-responsive-16by9"><iframe class="embed-responsive-item" src="https://www.youtube.com/embed/SCTtZ-DvZ2Y" title="How to Scan a QR off Steel Plates"></iframe></div>
## Dark QR on Bright Background
Most simple QR code scanners expect the QR code to be dark on a bright background. Amongst others this goes for the SeedSigner, Blockstream Jade, Sparrow Wallet and the SeedHammer controller software itself.
![Light vs. dark QR on SeedHammer steel plates](/static/img/light-vs-dark-qr.webp)
As soon as the QR turns dark it is easy readable.
## How To Scan a Seed QR {#scan}
To obtain a dark QR on a bright background use a light source to hit the plate at an angle.
1. Position yourself so a wide/diffuse light source (a lamp, sun from a window etc) is behind you.
1. Hold the SeedHammer steel plate up like a small mirror, and pan/tilt the plate until the light source is reflected in the center of the QR code.
1. The QR code now turns dark and can be scanned.
<div class="grid">
<div><img src="/static/img/scan-seedsigner.webp" alt="SeedSigner scanning a CompactSeedQR from a SeedHammer backup plate"></div>
<div><img src="/static/img/scan-jade.webp" alt="Blockstream Jade scanning a CompactSeedQR from a SeedHammer backup plate"></div>
<div><img src="/static/img/scan-seedhammer.webp" alt="SeedHammer app scanning a CompactSeedQR from a SeedHammer backup plate"></div>
</div>
## How To Scan a Descriptor QR
The theory is the same as described [above](#scan). However scanning of a descriptor QR can be more tricky because the QR details are smaller.
Furthermore a static mounted webcam is often used to scan a descriptor into the coordinator software, limiting pan and tilt maneuvering.
One way to do it is:
1. Activate the descriptor scan mode in the coordinator software (see [this guide](/get-started/perform-recovery#multisig)).
1. Make the screen as bright as possible (max brightness and white pixels on the screen) in order to make it function as light source.
1. Present the descriptor side of the plate (never the Seed side!) to the webcam.
1. Pan and tilt the QR until it turns dark and can be scanned.
![Sparrow Wallet scanning a descriptor QR from a SeedHammer multisig backup plate](/static/img/scan-sparrow.webp)
On Mac it is possible to use your iPhone as external camera which can make scanning easier.
## Increase The Readability of a QR
Increase the readability of QR on steel by painting the QR with a black marker and wipe off the residual.
This makes any QR about as readable as QR codes on paper or on a screen.
Read the full article on applying a [solid marker here](/article/enhance-qr-readability-with-solid-marker).
![QR code painted with a marker for higher readability](/static/img/qr-with-marker.webp)

View File

@ -0,0 +1,55 @@
---
author: SeedHammer
authorlink: https://twitter.com/SeedHammer
title: Multisig Does Not Protect Against Weak Entropy
description: Read about the challenges of true randomness and how multisig doesn't guard against weak entropy sources.
published: 2023-11-28
image: randomness.webp
---
This article is inspired by the common misconception expressed on social media that multisignature (multisig) wallets protect against weak entropy.
In a [recent case](https://twitter.com/mononautical/status/1728946782611366105), someone allegedly sent 140 BTC to a fresh cold wallet, which was instantly swept by a third party. The attacker managed to steal almost 56 BTC while paying 83.7 in transaction fees. Since the wallet was emptied immediately, it must have been monitored - one very likely explanation could be weak entropy.
Many are of the belief that if those coins had been sent to cold storage in a multisig wallet, then this would never have occurred. But that is wrong and a misconception.
<article>Multisig setups are not mitigating the danger of keys created with weak entropy.</article>
A crucial aspect often overlooked is the quality of entropy used in generating the private keys in multisig setups. The reality is simple: a multisig wallet consisting of shares all made with equally low entropy does not protect against a wallet hack.
## The Challenge of True Randomness
Generating truly random numbers is a significant challenge in cryptography. Computers struggle to produce real randomness, which is vital for secure cryptographic keys. This randomness, or entropy, is the cornerstone of a secure Bitcoin private key - no matter if that key is intended to be used for singlesig wallet or as a cosigner in a multisignature wallet.
A Bitcoin private key is essentially a random number. If the process of generating this number is predictable, the key becomes easier to guess or brute-force. Such vulnerabilities can be exploited by attackers, rendering even sophisticated cryptographic systems insecure.
## Multisig and Longer Seed Phrases
It is tempting to assume that, say, a 2-of-3 multisig setup where each share is a 12-word seed is equivalent to the security of a 24-word seed phrase. This is not correct, because the shares are independent.
By way of analogy, guessing seed phrases is like rolling sixes with dice. The effort of guessing two seeds is like re-rolling two dice individually until both show sixes, whereas the effort of guessing a single 24-word seed is like re-rolling two dice simultaneously. As the chance of hitting two sixes at once is significantly harder than hitting a six with one die and another six with a second die, the 24-word seed is more secure.
However, even longer seed phrases don't help; if the randomness source is weak enough or even malicious, guessing the seed phrase requires very little effort regardless of seed length.
## Reliable Sources of Entropy
Two sources can generally be considered reliable for generating entropy for Bitcoin private keys: Bitcoin Core and manual entropy methods.
### Bitcoin Core: Rigorously Audited but not User-Friendly
Bitcoin Core undergoes extensive scrutiny by a large community of skilled developers, making it one of the most audited and trusted Bitcoin implementations, including its randomness generator. However, there are practical challenges in using Bitcoin Core for entropy:
- User Interface Limitations: Bitcoin Core's user interface is not particularly user-friendly, especially for those not well-versed in technical aspects of Bitcoin.
- Air-Gapped Security Requirement: For optimal security, Bitcoin Core should be run on an air-gapped computer that will never connect to the internet again. This requirement can be cumbersome and is not feasible for everyone.
### Manual Entropy Methods: Accessible but Prone to Human Error
Manual entropy methods, such as seed generation through dice or cards, offer a more accessible way to generate entropy. These methods involve physically rolling dice, picking cards, or using a similar randomization method to create a sequence of words or characters. While these methods are user-friendly and don't require specialized software or hardware, they have their own drawbacks:
- Human Bias: Even when trying to be random, humans can introduce bias into the process, which can reduce the entropy of the generated keys.
- Error Potential: Manual methods are susceptible to human error, such as misreading dice or making transcription errors, which can compromise the security of the generated keys.
- Biased Equipment: Not all dice are created equal. Many dice, especially those not meeting casino-grade standards, can have slight biases that affect their roll outcomes. If picking out of a jar, the amount of free air, method of shaking/stirring, wear and tear on the pills/balls, however subtle, can also reduce the entropy.
## Limitations of Entropy in Hardware Wallets
Many users might wonder why not simply rely on the entropy provided by dedicated Bitcoin hardware wallets. The main reason is that hardware wallets are susceptible to supply chain attacks. Because of the nature of randomness, it is practically impossible to detect whether a particular seed is truly random or generated by malicious firmware or hardware installed during production or delivery of the device.
Even if a device contains no backdoors, its random number generator is most likely not nearly as scrutinized as Bitcoin Core's implementation. An accidentally broken generator is as bad as a malicious one.
In conclusion, the strength of a multisig arrangement is heavily dependent on the entropy of the individual keys. Without high-quality entropy, even a multisig setup cannot guarantee robust security against hacks.
*Keep in mind that a multisig wallet consisting of high entropy shares is, of course, more secure than a singlesig with high entropy. And the physical distribution of the shares will also protect against physical theft, which has nothing to do with the entropy.*

46
article/steel-316.md Normal file
View File

@ -0,0 +1,46 @@
--
author: SeedHammer
authorlink: https://twitter.com/SeedHammer
title: Steel 316
description: Read about the differences between ordinary stainless steel and steel 316 in relation to bitcoin cold storage backups.
published: 2023-02-28
image: steel-types.webp
--
## Why Steel 316 is Superior for Bitcoin Cold Storage
When it comes to storing your bitcoins, security and durability are of the utmost importance. Steel 316's superior resistance to corrosion and heat makes it a more suitable choice for cold storage wallets compared to steel 304. Its ability to withstand harsh environments (water, fire, chemicals and deformation) means it is less likely to degrade over time, which can prolong the lifespan of the backup and protect it for the long term.
Additionally, Steel 316 is resistant to pitting and crevice corrosion, which is common in environments where chlorides are present. This makes it an ideal choice for a cold storage wallet, as the metal will not corrode easily even if exposed to harsh chemicals.
## Stainless Steel Grades
Stainless steel is a type of steel that contains at least 10.5% chromium, which gives it its characteristic resistance to corrosion. However, different grades of stainless steel can have varying levels of other elements, such as nickel, molybdenum, and titanium, which can affect its properties and performance. The most common grades of stainless steel are 304 and 316.
## Steel 304
Steel 304, also known as 18/8 stainless steel, is a common grade of stainless steel that contains 18% chromium and 8% nickel. It is known for its excellent corrosion resistance and is often used in a wide range of applications, including food preparation equipment, kitchen sinks, and medical instruments.
## Steel 316
Steel 316, also known as marine grade stainless steel, is a higher-end grade of stainless steel that contains 16% chromium, 10% nickel, and 2% molybdenum. This combination of elements gives steel 316 superior resistance to corrosion and heat compared to steel 304. It is often used in harsh environments, such as marine and chemical processing applications.
The melting point of steel 304 and 316 is around 1400-1450°C (2550-2650°F). However, it is worth noting that the melting point is not the only important factor when it comes to the performance of steel in high temperatures, the ability to withstand high temperature without losing its other properties is also important.
Stainless steel 316 has a higher resistance to high-temperature environments compared to 304, which means that it will maintain its strength, ductility and corrosion resistance at high temperatures better than 304.
## Pitting and Crevice Corrosion
Pitting and crevice corrosion are types of localized corrosion that occur in stainless steel and other metals. They are caused by the presence of certain chemicals, such as chlorides, in the environment.
Pitting corrosion is a type of localized corrosion that occurs when small, deep holes or pits form on the surface of a metal. This type of corrosion is caused by the preferential attack of certain areas of the metal, often due to the presence of small defects or inclusions on the metal surface. Pitting corrosion can weaken the metal and make it more susceptible to failure.
Crevice corrosion occurs when a corrosive environment is trapped in a small crevice or gap, such as under a gasket or in a tight-fitting joint. The corrosive environment can attack the metal in the crevice, causing corrosion to occur in a localized area. Crevice corrosion can also weaken the metal and make it more susceptible to failure.
Both pitting and crevice corrosion can be prevented by using materials that are more resistant to the specific corrosive environment, such as stainless steel 316L.
See our corossion test of the SeedHammer plates [here](/article/corrosion-test-of-seedhammer-steel-plates).
## Conclusion
When it comes to storing bitcoin in a cold storage wallet, the material the wallet's backup is made of is just as important as the design and functionality of the wallet itself. Stainless steel is a popular choice for cold storage wallets due to its durability and resistance to corrosion. However, not all stainless steel is created equal, and the grade of steel used can have a significant impact on the security and longevity of the backup.

View File

@ -0,0 +1,25 @@
--
author: SeedHammer
authorlink: https://twitter.com/SeedHammer
title: The SeedHammer Controller
description: Read about the controller, where to buy it and how to build it yourself.
published: 2023-02-26
image: the-raspberry-pi-0-controller.webp
--
The SeedHammer <a href="https://github.com/seedhammer/seedhammer/" target="_blank">controller software</a> runs on the same air gapped hardware as a <a href="https://seedsigner.com/" target="_blank">SeedSigner</a>.
<div class="img-center"><img src="/static/img/seedhammer-controller.webp" style="width: 377px;"></div>
You can choose to either buy a SeedSigner directly [from us](/shop), one of the online resellers or build it yourself.
Check out <a href="https://seedsigner.com/hardware/" target="_blank">https://seedsigner.com/hardware/</a> for more details, where to buy the components and list of resellers.
## The Hardware
- Raspberry Pi Zero (version 1.3).
- WaveShare 1.3 inch LCD hat with 240×240 pixel display.
- Pi Zero compatible camera module.
- MicroSD Card with at least 4GB capacity.
Read more about why we chose to develop the controller on this hardware [here](/about/how-it-started#controller).

View File

@ -0,0 +1,94 @@
--
author: SeedHammer
authorlink: https://twitter.com/SeedHammer
title: The SeedHammer Descriptor Partitioning Scheme
description: A technical explanation of the distribution model of descriptor parts used in SeedHammer backups to achieve wallet recovery from any given quorum combination.
published: 2023-08-17
image: partitioning-scheme.webp
--
## The Problem: Multisig Backup Requires All Public Keys
It is widely known that to sign a transaction with an M-of-N multisig wallet, the quorum of private keys (M) is required. What is less known is that all (N) public keys are also needed:
<div class="grid center-layout">
<div></div>
<div>
<div class="img-center">
<img src="/static/img/multisig-wallet-sign-transaction.svg" alt="In order to restore a multisig wallet all public keys must be present" style="width: 300px">
</div>
</div>
<div></div>
</div>
You don't usually notice this, because the public keys are saved in the wallet software in the form of a list of XPUBs - or more recently as a wallet output descriptor.
Creating secure and durable backups for multisig wallets necessitates the storage of both private and public keys.
*Note that singlesig backups technically also require both kinds of keys, but since the public key can be derived from the private, losing the public key for a singlesig is usually not a problem.*
## Size Matters
The straightforward backup approach for an M-of-N multisig wallet is to produce N backup shares, each containing a BIP39 seed phrase and the complete set of public keys in the form of the wallet descriptor. This way, no matter which M shares you have access to, the quorum of private keys and the complete set of public keys are available.
For SeedHammer backup plates, however, the complete descriptor is too large to engrave within the physical constraints of our metal plates. Even if we supported plates large enough to engrave the descriptor, the corresponding QR code would be exceedingly difficult to scan.
Splitting the descriptor into parts is a better approach to minimize the data size. But how? Consider the descriptor for a 2-of-3 multisig wallet. The naive split of the descriptor into 3 parts, one for each share, will not work because any quorum (2) of shares contain only two thirds of the descriptor. Splitting the descriptor into 2 parts, A and B, is better, but then how do you assign the parts to shares? If you assign A to share 1 and B to share 2, any one part assigned to share 3 will leave you with two A parts or two B parts in the unfortunate cases.
## The UR Format
The [Uniform Resources (UR) format](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-005-ur.md) is an existing standard for a related problem: splitting potentially large data items into smaller shares that are easier to scan as QR codes. The standard includes an [efficient representation](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-010-output-desc.md) of output descriptors, and is supported by most multisig wallet software.
Most importantly, the standard supports a fountain encoding scheme which allows combining data shares with the XOR operator, ⊕. The operator creates a mix of two or more parts the same size as the constituent parts, so A ⊕ B does not take up more engraving space than just part A or B by themselves. In addition, XOR'ed data cancel out; for example, A ⊕ B ⊕ B equals A.
Consider the 2-of-3 descriptor from before split into 2 halves, A and B. The fountain encoding assignment to shares is the following:
- Share 1: A
- Share 2: B
- Share 3: A ⊕ B
Recovery works no matter which combination of 2 shares are available:
<div class="grid">
<img src="/static/img/part-a-b-ab.svg" alt="Illustration of how the different descriptor parts distributes over the 3 shares in a 2-of-3 multisig.">
</div>
- Share 1 and 2 trivially combines into the full descriptor,
- Share 1 and 3 recovers part A and A ⊕ B, which recovers B by computing A ⊕ A ⊕ B = B,
- Share 2 and 3 recovers B and A ⊕ B, which recovers A by computing B ⊕ A ⊕ B = A.
The split is also minimal in size, in that each share contains data exactly half the size of the complete descriptor.
## Other wallet configurations
Up to this point, we have successfully applied the fountain encoding scheme to the following multisig configurations:
- 1-of-1
- 1-of-2
- 2-of-3
- 3-of-5
- Any M-of-N, where M = N-1
For posterity, the 3-of-5 scheme splits the descriptor into 6 parts, A B C D E F, where each share contains 2 parts, like so:
- Share 1: Contains A and F ⊕ B ⊕ E
- Share 2: Contains B and F ⊕ A ⊕ C
- Share 3: Contains C and F ⊕ B ⊕ D
- Share 4: Contains D and F ⊕ C ⊕ E
- Share 5: Contains E and F ⊕ D ⊕ A
Every combination of 3 shares recovers all 6 parts. For example, shares 1, 2, 3 contains the parts A, B, C, F ⊕ B ⊕ E, F ⊕ A ⊕ C, F ⊕ B ⊕ D, and:
- part F is computed by A ⊕ C ⊕ F ⊕ A ⊕ C,
- part E is computed by F ⊕ B ⊕ F ⊕ B ⊕ E,
- part D is computed by F ⊕ B ⊕ F ⊕ B ⊕ D.
The scheme is also minimal because every share contains 2 parts each 1/6 of the descriptor, or 1/3 of the descriptor.
<div class="text-center">
<img src="/static/img/descriptor-sides.webp" alt="Example of the public sides of all 3 different sizes of SeedHammer plates">
<p><small>Example of a descriptor side of singlesig, 2-of-3, and 3-of-5 backups respectively.</small></p>
</div>
Read more about the SeedHammer plates in general in our article [The SeedHammer Metal Plates
](/article/the-seedhammer-metal-plates).

View File

@ -0,0 +1,105 @@
--
author: SeedHammer
authorlink: https://twitter.com/SeedHammer
title: The SeedHammer Metal Plates
description: Guidelines, limitations and information about the SeedHammer steel plates.
published: 2023-02-27
image: seedhammer-metal-plates.webp
--
It is possible to backup both single and multisig setups. However there are some guidelines for which type of plates to use for each setup.
## Overview
To get a full overview look up this table:
| | SH02 | SH03 |
|----------------------------------------|------|------|
| Singlesig, 12 and 24 words | Yes | |
| 2-of-2, 12 and 24 words | Yes | |
| 2-of-3, 12 and 24 words | Yes | |
| 3-of-3, 12 and 24 words | Yes | |
| 3-of-5, 12 and 24 words | | Yes |
| M-of-N, where M = N-1, 12 and 24 words | Yes | |
| 1-of-2, 12 and 24 words | | Yes |
## Plate SH01
The SH01 plate was deprecated as part of release [v1.3.1](https://github.com/seedhammer/seedhammer/releases/tag/v1.3.1). Every engraving that would have used SH01 will now use the SH02 plate size instead.
<del>SH01 is credit card sized and works for single-signature wallets with 12 word seed phrases.</del>
<del>The plate are split into two - a seed side and a descriptor side.</del>
- <del>Seed Side:</del>
- <del>12 words fit on one side incl. a CompactSeedQR, the master fingerprint and plate number.</del>
- <del>Descriptor Side:</del>
- <del>On the opposite side the full descriptor is engraved together with a QR code representing the same data.</del>
## Plate SH02
SH02 is square and works for single-signature wallets with 12 and 24 words, 2-of-2, 2-of-3, 3-of-3 multi-signature wallets, as well as M-of-N, where M = N-1, 12 and 24 words.
The plate are split into two - a seed side and a descriptor side.
It is possible to engrave both on the same plate as well as to split them into two plates. Two plates make it possible to screw the plates together, with the shiny sides facing out.
- Seed Side:
- 12 or 24 words fit on one side incl. a CompactSeedQR, the master fingerprint and plate number.
- Descriptor Side:
- On the opposite side different parts of the descriptor are engraved together with one or two QR codes representing the same data. In the case of a singlesig wallet the full descriptor is engraved.
<div class="grid">
<div>
<div class="img-center"><img src="/static/img/multisig-1-of-3-seed-side.webp" alt="The SeedHammer Metal Plate SH02 with 24 words" style="width: 300px"><small>SH02: Seed side in a 2-of-3 multisig.</small></div>
</div>
<div>
<div class="img-center"><img src="/static/img/multisig-1-of-3-descriptor-side.webp" alt="The SeedHammer Metal Plate SH02 with 24 words" style="width: 300px"><small>SH02: Descriptor side in a 2-of-3 multisig.</small></div>
</div>
</div>
## Plate SH03
SH03 is rectangular and works for 1-of-2 and 3-of-5 multisig wallets.
The plate are split into two - a seed side and a descriptor side.
It is possible to engrave both on the same plate as well as to split them into two plates. Two plates make it possible to screw the plates together, with the shiny sides facing out.
- Seed Side:
- 12 or 24 words fit on one side incl. a CompactSeedQR, the master fingerprint and plate number.
- Descriptor Side:
- On the opposite side different parts of the descriptor are engraved together with one or two QR codes representing the same data.
<div class="grid">
<div>
<div class="img-center"><img src="/static/img/multisig-1-of-5-seed-side.webp" alt="The SeedHammer Metal Plate SH03 with 24 words" style="width: 300px"><small>SH03: Seed side in a 3-of-5 multisig.</small></div>
</div>
<div>
<div class="img-center"><img src="/static/img/multisig-1-of-5-descriptor-side.webp" alt="The SeedHammer Metal Plate SH03 with 24 words" style="width: 300px"><small>SH03: Descriptor side in a 3-of-5 multisig.</small></div>
</div>
</div>
## Advantages
The descriptor-parts are distributed among the plates in such a way that any quorum can recover the wallet. No need to store a digital or paper copy of the descriptor. Read our article [The SeedHammer Descriptor Partitioning Scheme](/article/the-seedhammer-descriptor-partitioning-scheme) for a more technical explaination.
The QR codes make it easy and fast to recover the multisig wallet by scanning them into a coordinator software like Sparrow Wallet.
Complies with multisig standards, no special tools needed for recovery.
<div class="grid center-layout">
<div></div>
<div>
<div class="img-center"><img src="/static/img/3-of-5-multisig.webp" alt="The SeedHammer Metal Plate SH03 with 24 words" style="width: 300px"><small>Any combination of the minimum number of shares will be enough to perform a full recovery.</small></div>
</div>
<div></div>
</div>
## Backup Plate Material
The metal plates are made of 2 or 3 mm thick stainless steel 316L - also known as marine grade steel.
Steel 316's superior resistance to corrosion and heat as well as its ability to withstand harsh environments makes it a more suitable choice for cold storage wallets compared to ordinary stainless steel 304.
Read more about the advantages of steel 316 [here](/article/steel-316).

13
cmd/viewer/main.go Normal file
View File

@ -0,0 +1,13 @@
package main
import (
"net/http"
"seedhammer.com/website/content"
)
func main() {
mux := new(http.ServeMux)
content.Register(mux)
http.ListenAndServe(":8080", mux)
}

106
data.go Normal file
View File

@ -0,0 +1,106 @@
package content
var getstartedTOC = TOC{
{
Name: "Unpack & Setup",
Slug: "unpack-and-setup",
Sections: []Section{
{Name: "Check Content", ID: "check"},
{Name: "Setting Up The Machine", ID: "setup"},
},
},
{
Name: "Install The Software",
Slug: "install-the-software",
Sections: []Section{
{Name: "Download", ID: "download"},
{Name: "Verify Image", ID: "verify"},
{Name: "Write Image", ID: "write"},
{Name: "Start The Controller", ID: "start"},
},
},
{
Name: "Load Seed & Wallet",
Slug: "load-seed-and-wallet",
Sections: []Section{
{Name: "Load Seed", ID: "input"},
{Name: "Scan Output Descriptor or Public Key", ID: "scan-output-descriptor-or-public-key"},
},
},
{
Name: "Engrave Plate",
Slug: "engrave-plate",
Sections: []Section{
{Name: "Onscreen Instructions", ID: "instructions"},
{Name: "In-app Tips", ID: "tips"},
},
},
{
Name: "Verify Backup",
Slug: "verify-backup",
Sections: []Section{
{Name: "Verify Singlesig", ID: "singlesig"},
{Name: "Verify Multisig", ID: "multisig"},
},
},
{
Name: "Perform Recovery",
Slug: "perform-recovery",
Sections: []Section{
{Name: "Recover Singlesig", ID: "singlesig"},
{Name: "Recover Multisig", ID: "multisig"},
},
},
}
var manualTOC = TOC{
{
Name: "Firmware Upgrade",
Slug: "firmware-upgrade",
Sections: []Section{
{Name: "Requirements", ID: "requirements"},
{Name: "Download", ID: "download"},
{Name: "Connect", ID: "connect"},
{Name: "Upload", ID: "upload"},
},
},
{
Name: "Engrave Descriptor (Android)",
Slug: "engrave-descriptor-android",
Sections: []Section{
{Name: "Install NFC Tools", ID: "install"},
{Name: "Transfer Descriptor", ID: "transfer"},
},
},
{
Name: "Engrave Descriptor (iOS)",
Slug: "engrave-descriptor-ios",
Sections: []Section{
{Name: "Install NFC Tools", ID: "install"},
{Name: "Transfer Descriptor", ID: "transfer"},
},
},
}
var aboutTOC = TOC{
{Name: "How It Started", Slug: "how-it-started", Sections: []Section{}},
{Name: "Our Goal", Slug: "our-goal", Sections: []Section{}},
{Name: "The SeedHammer Ethos", Slug: "the-seedhammer-ethos", Sections: []Section{}},
{Name: "Attitude to Privacy", Slug: "attitude-to-privacy", Sections: []Section{}},
{Name: "Contact", Slug: "contact", Sections: []Section{}},
}
type Nav struct {
Name string
URL string
Target string
}
var topNav = []Nav{
{Name: "Shop", URL: "/shop"},
{Name: "Guide", URL: "/doc/manual"},
{Name: "FAQ", URL: "/faq"},
{Name: "Articles", URL: "/article/"},
{Name: "Software", URL: "https://github.com/seedhammer/seedhammer/releases/latest", Target: "_blank"},
{Name: "About", URL: "/about/"},
}

6
doc/manual/docs.go Normal file
View File

@ -0,0 +1,6 @@
package manual
import "embed"
//go:embed *.md
var FS embed.FS

View File

@ -0,0 +1,36 @@
--
title: Engrave Descriptor (Android)
published: 2025-10-20
--
## Install NFC Tools {#install}
Install <a href="https://play.google.com/store/apps/details?id=com.wakdev.wdnfc&hl" target="_blank">NFC Tools</a> on your phone.
## Transfer Descriptor {#transfer}
- Open **NFC Tools**.
- Go to **Write**.
![NFC Tools app Write](/static/img/nfcandroid0.webp)
- Tap **Add a record**.
![NFC Tools app Add record](/static/img/nfcandroid1.webp)
- Select **Text**.
![NFC Tools app Text](/static/img/nfcandroid2.webp)
- Paste your descriptor text and go back.
![NFC Tools app paste](/static/img/nfcandroid3.webp)
- Tap **Write**
![NFC Tools app Write](/static/img/nfcandroid4.webp)
- Hold your phone near the NFC logo on the machine until its successfully scanned.
![Transfer descriptor complete](/static/img/nfccomplete.webp)

View File

@ -0,0 +1,36 @@
--
title: Engrave Descriptor (iOS)
published: 2025-10-20
--
## Install NFC Tools {#install}
Install <a href="https://apps.apple.com/us/app/nfc-tools/id1252962749" target="_blank">NFC Tools</a> on your iPhone.
## Transfer Descriptor {#transfer}
- Open **NFC Tools**.
- Go to **Write**.
![NFC Tools app Write](/static/img/nfciphone0.webp)
- Tap **Add a record**.
![NFC Tools app Add record](/static/img/nfciphone1.webp)
- Select **Text**.
![NFC Tools app Text](/static/img/nfciphone2.webp)
- Paste your descriptor text and go back.
![NFC Tools app paste](/static/img/nfciphone3.webp)
- Tap **Write**
![NFC Tools app Write](/static/img/nfciphone4.webp)
- Hold your phone near the NFC logo on the machine until it is successfully scanned.
![Transfer descriptor complete](/static/img/nfccomplete.webp)

View File

@ -0,0 +1,35 @@
--
title: Firmware Upgrade
published: 2025-09-24
--
## Requirements {#requirements}
- Android or Windows computer
- USB-C cable
## Download the Firmware {#download}
- Go to our <a href="https://github.com/seedhammer/seedhammer/releases" target="_blank">releases page.</a>
- Open the "Assets" section under the latest firmware release (`v1.4.1` or newer).
- Download the `seedhammerii-vX.Y.Z.uf2` firmware file.
- Save it on your computer or Android device.
**Note:** You may disconnect your device from the internet from this step onward.
## Connect the Machine {#connect}
- Plug the USB-C cable into your computer or phone. Unplug the machine.
- Locate the white firmware button on the underside of the control board near the hammerhead.
- Press and hold the firmware button.
- While holding the button, connect the cable to the machine.
- Release the button when a USB drive appears.
**Important:** Do not connect the machine to your device until **after** pressing the firmware button.
## Upload the Firmware {#upload}
- Drag, move or copy the firmware file to the USB drive.
The machine will automatically begin upgrading. When the screen lights up, the upgrade is complete.

8
doc/manual/index.md Normal file
View File

@ -0,0 +1,8 @@
--
title: User Manual
description: SeedHammer II.
--
This is the manual for the SeedHammer II.
If you're looking for the manual for the legacy machine, [go here](/get-started/).

61
flake.lock generated Normal file
View File

@ -0,0 +1,61 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1778430510,
"narHash": "sha256-Ti+ZBvW6yrWWAg2szExVTwCd4qOJ3KlVr1tFHfyfi8Q=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "8fd9daa3db09ced9700431c5b7ad0e8ba199b575",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-25.11",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs",
"utils": "utils"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

60
flake.nix Normal file
View File

@ -0,0 +1,60 @@
{
description = "SeedHammer website";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
utils.url = "github:numtide/flake-utils";
};
outputs =
{
self,
nixpkgs,
utils,
}:
utils.lib.eachDefaultSystem (
system:
let
pkgs = import nixpkgs {
inherit system;
};
in
{
formatter = pkgs.nixpkgs-fmt;
packages = {
default = pkgs.writeShellScriptBin "run-viewer" ''
sigint_handler()
{
kill $PID
exit
}
trap sigint_handler SIGINT
function watch() {
${pkgs.fswatch}/bin/fswatch -1 -r -e '.git/*' -e '.jj/*' -e notify.socket .
}
TMPDIR=$(mktemp -d)
while true; do
if ! ${pkgs.go}/bin/go build -o "$TMPDIR/viewer" ./cmd/viewer; then
watch
continue
fi
"$TMPDIR/viewer" $@ &
PID=$!
watch
kill $PID
done
'';
};
devShells.default =
with pkgs;
mkShell ({
packages = [
go
];
});
}
);
}

6
getstarted/docs.go Normal file
View File

@ -0,0 +1,6 @@
package getstarted
import "embed"
//go:embed *.md
var FS embed.FS

View File

@ -0,0 +1,83 @@
--
title: Engrave Plate
description: Start the engraving process.
published: 2023-02-07
--
## Onscreen Instructions {#instructions}
Follow the onscreen instructions on the controller.
Tips shown on the bottom of the screen refers to the below section.
When all plates for the wallet have been engraved, continue to [verifying the backup](/get-started/verify-backup).
## In-app Tips {#tips}
### 1: Overview Screen {#1}
- Make sure that the master fingerprint matches the seed you want to produce a backup for.
### 2: Turned Off and Disconnected {#2}
Make sure the engraver is turned off.
![Turn off machine](/static/img/oi-power-off.webp)
If the device is connected to the machine disconnect it.
Make sure to power the device using the outermost USB port.
![Unplug device](/static/img/oi-unplug-device.webp)
### 3: Move Hammerhead {#3}
Manually move the hammerhead to the far upper left position.
![Move hammerhead](/static/img/oi-move-hammer-head.webp)
### 4: Place Steel Plates {#4}
Make sure you place the correct steel plate (SH01, SH02 or SH03) depending on the wallet type you are engraving.
![Place steel plates](/static/img/oi-place-steel-plates.webp)
Do not use any washers even though they were supplied with the machine.
### 5: Adjust Needle Distance {#5}
Loosen the horizontal hammerhead finger screw.
![Loosen screw](/static/img/oi-hammerhead-screw.webp)
Adjust the needle distance using the top wheel to approximately 1.5 mm above the plates (the thickness of 2 credit cards), ensuring it does not exceed 2.0 mm, as this can cause the needle to fail to hammer properly.
### 6: Tighten Finger Screw and Set Depth {#6}
Tighten the horizontal hammerhead finger screw.
![Thigten screw](/static/img/oi-hammerhead-screw.webp)
Make sure the depth selector is set to "Strong".
![Set to Strong](/static/img/oi-depth-selector.webp)
### 7: Turn Machine On and Connect Controller Device {#7}
Turn on the engraving machine.
![Turn on the SeedHammer machine](/static/img/oi-power-on.webp)
Connect this device to the engraving machine via the middle port.
![Connect device](/static/img/oi-plug-in-device.webp)
### 8: Start Engraving {#8}
The process is loud, use hearing protection.
When the machine hammers, excess oil can be released from the hammer head. This is normal and will stop on its own.
![Residual oil](/static/img/oi-oil.webp)
In case of emergency or unexpected engraving behaviour, press the stop-button on front of the machine.
![Emergency Stop](/static/img/oi-stop.webp)

8
getstarted/index.md Normal file
View File

@ -0,0 +1,8 @@
--
title: Manual for the Legacy Machine
description: The original SeedHammer machine.
--
If you're looking for the manual for the Seedhammer II, [go here](/doc/manual/).
This guide covers the 6 steps from the initial unpacking to a complete recovery of a newly engraved backup.

View File

@ -0,0 +1,64 @@
--
title: Install The Software
description: Installation and verification of the controller software.
published: 2023-02-07
--
## Download {#download}
Get the latest version of the <a href="https://github.com/seedhammer/seedhammer/releases/latest" target="_blank">SeedHammer software</a>.
- Download the disk image `seedhammer-vX.Y.Z.img`
- Download the signature file `seedhammer-vX.Y.Z.img.sig`
...where `vX.Y.Z` is the most recent version number.
In addition download our <a href="/static/seedhammer-signers.pub" download>public signing key</a>.
- This file should be downloaded only once and re-used for verification of future software versions.
All 3 files should be in the same directory:
<img src="/static/img/download-software-files.webp" alt="all files should be in the same directory" style="width:initial;margin-left:initial;border:1px solid #e1e1e1;">
## Verify Image {#verify}
Verify the software image signature.
- Verify the `seedhammer-vX.Y.Z.img` with the ssh-keygen tool:
<code>$ ssh-keygen -Y verify -f seedhammer-signers.pub -I gh@seedhammer.com -n seedhammer.img -s <strong>seedhammer-vX.Y.Z.img.sig</strong> < <strong>seedhammer-vX.Y.Z.img</strong></code>
- The command should succeed with a message similar to:
```Good "seedhammer.img" signature for gh@seedhammer.com with ED25519 key SHA256:xqo5VI7m8vh8UHgceOt27dep1EZ7SyCFjJOogcQBrvw```
<p class="alert alert-warning">
For extra security build the software from source code. Instructions are in our <a href="https://github.com/seedhammer/seedhammer#building-from-source" target="_blank">GitHub README</a>.
</p>
## Write Image {#write}
Write `seedhammer-vX.Y.Z.img` to an empty or unused microSD card.
On Windows and macOS, use a tool like [balenaEtcher](https://www.balena.io/etcher#download-etcher).
On linux, use a tool like dd:
```dd if=seedhammer-vx.y.z.img of=/dev/sdx conv=fdatasync bs=1M```
## Start The Controller {#start}
<p class="alert alert-warning">
Never connect the controller to a computer, use a regular power adapter.
</p>
Test that the microSD card works by starting the controller.
- Install the microSD card into a compatible controller (SeedSigner).
- Power on the controller by plugging a micro-USB cable into the **outermost port**.
- Remove the microSD card when the startup screen appears.
![Power device](/static/img/power-device.webp)
**Important:**
- The controller should be powered on via the outermost USB port as the SeedHammer machine **must** use the middle port.
After starting the software, proceed [to load a seed](/get-started/load-seed-and-wallet).

View File

@ -0,0 +1,87 @@
--
title: Load Seed & Wallet
description: Load the seed into the controller software, and optionally include the wallet descriptor.
published: 2023-02-07
--
## Load Seed {#input}
All backups begin by loading the seed words you want to back up.
When backing up a multisig wallet, load any seed that is a part of the multisig setup.
- Choose "Backup Wallet" on the startup screen.
- Remove the SD card when prompted to do so.
- Select either keybord or camera input method.
- Keyboard:
- Choose number of words.
- Input the seed words in the correct order.
- Camera:
- Scan a QR code containing a 12- or 24-word seed phrase (SeedQR, CompactSeedQR or Mnemonic).
- Confirm the seed.
<p class="alert alert-warning">Ensure the SD card is removed as prompted in the app before entering any seed.<br><br><img src="/static/img/remove-sd-card-warning.webp" alt="Remove SD card warning in the SeedHammer app"></p>
## Scan or Skip Output Descriptor/Public Key {#scan-output-descriptor-or-public-key}
Select either to scan, skip, or re-use an output descriptor or public key.
### Scan
Choose 'Scan' if you want the backup to include the public part of your wallet. This facilitates trustless loading into wallet or coordinator software, allowing for the viewing of balances and addresses.
We highly recommend this option, particularly for multisig wallets.
- Scan the output descriptor or public key (XPUB) of the wallet. Currently the software supports:
- Output descriptors from [Sparrow Wallet](https://sparrowwallet.com/), [Nunchuk](https://nunchuk.io/), and [BlueWallet](https://bluewallet.io/).
- Descriptors in text mode (raw or wrapped in JSON).
- Raw public keys (XPUBs).
- Confirm the wallet.
- Click the info-button to see the receive and change addresses of the wallet.
After confirming the wallet [start the engraving process](/get-started/engrave-plate).
### Skip
Choose 'Skip' if you wish to back up only the seed and nothing else.
You will immediately be directed to the [start of the engraving process](/get-started/engrave-plate).
<p class="alert alert-warning">If you skip scanning the output descriptor, you will be unable to restore a multisig wallet with only the minimum number of plates at hand (as described <a href="/article/how-to-recover-from-seedhammer-backup#multisig">here</a>), because there will be no descriptor side available.</p>
### Re-use
Choose 'Re-use' if you wish to re-use the last entered descriptor or public key from this session.
Note: Should the controller have been powered off, the option to re-use the descriptor will become unavailable.
### How to Scan a Descriptor
<details>
<summary>Scan Output Descriptor from Sparrow Wallet</summary>
<p>
<ul>
<li>Open the wallet you want to back up.</li>
<li>Under "Setting"-tab click "Export" and choose export for either Jade Multisig, Keystone Multisig, Passport Multisig, or Specter Desktop.<br><img src="/static/img/sparrow-export-descriptor-with-title.webp" alt="Click the Export button in Sparrow"></li>
<li>Scan the QR code.<br><img src="/static/img/sparrow-show-descriptor.webp" alt="Scan the QR into Sparrow"></li>
</ul>
<p>
</details>
<details>
<summary>Scan Output Descriptor from Nunchuk</summary>
<p>
<ul>
<li>Open the wallet you want to back up.</li>
<li>Under "View wallet config" -> More options menu (3 dots) -> "Export wallet configuration" click "QR code".</li>
<li>Scan the QR code.</li>
</ul>
<p>
</details>
<details>
<summary>Scan Output Descriptor from BlueWallet</summary>
<p>
<ul>
<li>Open the wallet you want to back up.</li>
<li>Under the options menu (3 dots) click "Export Coordinator Setup".</li>
<li>Scan the QR code.</li>
</ul>
<p>
</details>

View File

@ -0,0 +1,26 @@
--
title: Perform Recovery
description: Make a full recovery of the backed-up wallet to ensure the backup can be trusted.
published: 2023-02-07
--
## Recover Singlesig Wallet {#singlesig}
<p class="alert alert-warning">Keep the seed phrase and the SeedQR code away from all cameras except the signing device.</p>
1. Load the seed into a stateless signer.
- Use the seed words or scan the CompactSeedQR.
1. Most stateless signers can export the wallet as read-only (into eg. Sparrow Wallet).
## Recover Multisig Wallet {#multisig}
<p class="alert alert-warning">Keep the SeedQR code away from any camera controlled by Sparrow Wallet.</p>
<p class="alert alert-warning">Never input the seed words into Sparrow Wallet.</p>
1. Create a new wallet in Sparrow Wallet.
1. Under "Script Policy" click the camera icon. ![Click Script Policy in Sparrow](/static/img/sparrow-import-descriptor.webp)
1. Have the quorum of plates at hand. Cover the seed side of the plates (the side that contains the seed words).
1. Scan the QR code(s) on the descriptor side of the individual plate (the side **that does not** contain the seed words).
![Scan the QR into Sparrow](/static/img/sparrow-scan-descriptor.webp)
- Scan every QR on all descriptor sides until Sparrow Wallet recreates the wallet.

View File

@ -0,0 +1,51 @@
--
title: Unpack & Setup
description: The initial unpacking and setup.
published: 2023-02-07
--
## Check Content {#check}
When you receive the SeedHammer make sure that the box includes the following:
- SeedHammer machine
- Power cable
- USB cables
- Blue data cable
- Black adapter cable
- Screwdriver
- Set of extra nuts and bolts
- Correct amount of steel plates
...and if your order included a controller:
- SeedSigner + 2 microSD cards
## Setup The Machine {#setup}
### Remove Needle Cap
- Loosen the horizontal hammerhead finger screw and adjust the needle up in order to remove the protective cap.
![Loosen screw](/static/img/oi-hammerhead-screw.webp)
![Adjust needle distance](/static/img/oi-top-screw.webp)
### Connect The Hammerhead Cable
- Familiarize yourself with the green male plug and how its connectors are arranged.
- Gently attach the plug to the socket on the back of the machine.
- When the plug fits the socket push gently while turning the plug's cap until it snaps into the guides.
- Turn the cap firmly until you feel a click.
### Connect The Blue USB Cable
- The square end fits into the USB socket on the back of the machine.
- The other end (standard USB plug) fits into the black USB-A-to-micro-USB adapter cable that came with the machine.
### Connect The Power Cable
- Plug the power cable into the black socket on the back of the machine.
- Do not turn on the machine yet.
Proceed to [install the software](/get-started/install-the-software).

View File

@ -0,0 +1,65 @@
--
title: Verify Backup
description: Verify that you can trust the backup when you need to recover.
published: 2023-02-07
--
## Singlesig Backup {#singlesig}
Verifying a singlesig backup:
1. Verify that the master fingerprint is correct.
1. Verify that the seed words are correct (and in the same order).
1. Verify that the QR contains the same data by scanning it with a [SeedSigner](https://seedsigner.com/software/).
- Boot up a SeedSigner.
- Choose "Scan".
- Confirm the fingerprint displayed on the screen.
- Navigate to "Backup Seed" -> "View Seed Words".
- Confirm the seed words.
## Multisig Backup {#multisig}
### Verify Seed Side
For each plate in the multisig backup:
1. Verify that the master fingerprint is correct.
1. Verify that the seed words are correct (and in same order).
1. Verify that the numbering (eg. 1/3, 2/3, etc.) is as expected.
- No two plates should have the same numbering unless you have made a copy of that particular plate.
1. Verify the content of the CompactSeedQR by scanning it with a stateless signer.
- Ask the signer to show the backup seed.
- Verify that the seed words shown on the signer are correct (and in same order).
### Verify Descriptor Side
1. Verify that the QR code contains the text written next to it.
- Scan it with an offline QR scanner (eg. QR scanner app on a mobile phone with flight mode enabled).
- Be aware that some QR scanners save a list of recently scanned QR data. Remember to delete this list and delete the app before going out of flight mode again.
1. Perform a test recovery with any combination of the quorum.
- Create a new wallet in Sparrow Wallet.
- Under "Script Policy" click the camera icon. ![Click Script Policy in Sparrow](/static/img/sparrow-import-descriptor.webp)
- Scan the QR code(s) on the side **that does not** contain the seed words. ![Scan the QR into Sparrow](/static/img/sparrow-scan-descriptor.webp)
- In a 2-of-3 multisig recover with any of these combinations of plates:
- Share 1 and 2.
- Share 1 and 3.
- Share 2 and 3.
- In a 3-of-5 multisig recover with any of these combinations of plates:
- Share 1, 2, and 3
- Share 1, 2, and 4
- Share 1, 2, and 5
- Share 1, 3, and 4
- Share 1, 3, and 5
- Share 1, 4, and 5
- Share 2, 3, and 4
- Share 2, 3, and 5
- Share 2, 4, and 5
- Share 3, 4, and 5
**Important:**
<p class="alert alert-warning">Never bring the seed QR codes near the camera controlled by the Sparrow Wallet.</p>
<p class="alert alert-warning">Never input the seed words into Sparrow Wallet.</p>
In the case of singlesig we recommend to [perform a test recovery](/get-started/perform-recovery).

16
go.mod Normal file
View File

@ -0,0 +1,16 @@
module seedhammer.com/website/content
go 1.26.2
require (
github.com/btcsuite/btcd/btcutil v1.1.6
github.com/gorilla/feeds v1.2.0
github.com/lpar/gzipped/v2 v2.1.0
github.com/yuin/goldmark v1.8.2
github.com/yuin/goldmark-meta v1.1.0
)
require (
github.com/kevinpollet/nego v0.0.0-20200324111829-b3061ca9dd9d // indirect
gopkg.in/yaml.v2 v2.3.0 // indirect
)

129
go.sum Normal file
View File

@ -0,0 +1,129 @@
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c/go.mod h1:tjmYdS6MLJ5/s0Fj4DbLgSbDHbEqLJrtnHecBFkdz5M=
github.com/btcsuite/btcd v0.23.5-0.20231215221805-96c9fd8078fd/go.mod h1:nm3Bko6zh6bWP60UxwoT5LzdGJsQJaPo6HjduXq9p6A=
github.com/btcsuite/btcd v0.24.2/go.mod h1:5C8ChTkl5ejr3WHj8tkQSCmydiMEPB0ZhQhehpq7Dgg=
github.com/btcsuite/btcd/btcec/v2 v2.1.0/go.mod h1:2VzYrv4Gm4apmbVVsSq5bqf1Ec8v56E48Vt0Y/umPgA=
github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE=
github.com/btcsuite/btcd/btcutil v1.0.0/go.mod h1:Uoxwv0pqYWhD//tfTiipkxNfdhG9UrLwaeswfjfdF0A=
github.com/btcsuite/btcd/btcutil v1.1.0/go.mod h1:5OapHB7A2hBBWLm48mmw4MOHNJCcUBTwmWH/0Jn8VHE=
github.com/btcsuite/btcd/btcutil v1.1.5/go.mod h1:PSZZ4UitpLBWzxGd5VGOrLnmOjtPP/a6HaFo12zMs00=
github.com/btcsuite/btcd/btcutil v1.1.6 h1:zFL2+c3Lb9gEgqKNzowKUPQNb8jV7v5Oaodi/AYFd6c=
github.com/btcsuite/btcd/btcutil v1.1.6/go.mod h1:9dFymx8HpuLqBnsPELrImQeTQfKBQqzqGbbV3jK55aE=
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY=
github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I=
github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs=
github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/gorilla/feeds v1.2.0 h1:O6pBiXJ5JHhPvqy53NsjKOThq+dNFm8+DFrxBEdzSCc=
github.com/gorilla/feeds v1.2.0/go.mod h1:WMib8uJP3BbY+X8Szd1rA5Pzhdfh+HCCAYT2z7Fza6Y=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
github.com/kevinpollet/nego v0.0.0-20200324111829-b3061ca9dd9d h1:BaIpmhcqpBnz4+NZjUjVGxKNA+/E7ovKsjmwqjXcGYc=
github.com/kevinpollet/nego v0.0.0-20200324111829-b3061ca9dd9d/go.mod h1:3FSWkzk9h42opyV0o357Fq6gsLF/A6MI/qOca9kKobY=
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/lpar/gzipped/v2 v2.1.0 h1:87/ug239roEqXLVOnXZg6NjDfFvMwmkGTKnFWJPUA9U=
github.com/lpar/gzipped/v2 v2.1.0/go.mod h1:G3UlFoFYzjCx6NV4zDmD1BIWMNBaJuKoUvxrEWJuZ3Y=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc=
github.com/yuin/goldmark v1.8.2 h1:kEGpgqJXdgbkhcOgBxkC0X0PmoPG1ZyoZ117rDVp4zE=
github.com/yuin/goldmark v1.8.2/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg=
github.com/yuin/goldmark-meta v1.1.0 h1:pWw+JLHGZe8Rk0EGsMVssiNb/AaPMHfSRszZeUeiOUc=
github.com/yuin/goldmark-meta v1.1.0/go.mod h1:U4spWENafuA7Zyg+Lj5RqK/MF+ovMYtBvXi1lBb2VP0=
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

32
page/about.html Normal file
View File

@ -0,0 +1,32 @@
{{template "base" .}}
{{define "title"}}{{.Doc.Title}}{{end}}
{{define "description"}}{{.Doc.Description}}{{end}}
{{define "content"}}
<section class="container">
<div class="grid docs-layout">
<aside>
<nav>
<ul>
{{range .TOC}}
<li>
<a href="/about/{{.Slug}}">{{.Name}}</a>
</li>
{{end}}
</ul>
</aside>
<div></div>
{{with .Doc}}
<div class="guide">
<hgroup class="text-center">
<h1>{{.Title}}</h1>
<h2>{{.Description}}</h2>
</hgroup>
{{.Content}}
</div>
{{end}}
<div></div>
</div>
</section>
{{end}}

34
page/article.html Normal file
View File

@ -0,0 +1,34 @@
{{template "base" .}}
{{define "title"}}{{.Title}}{{end}}
{{define "description"}}{{.Description}}{{end}}
{{define "image"}}{{.Image}}{{end}}
{{define "type"}}article{{end}}
{{define "content"}}
<section class="container">
<div class="grid center-layout">
<div></div>
<div>
<nav aria-label="breadcrumb">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/article/">Articles</a></li>
<li>{{.Title}}</li>
</ul>
</nav>
<div>
<small class="date">{{.Published.Format "2 Jan, 2006"}} · <a href="{{.AuthorLink}}">{{.Author}}</a></small>
</div>
<hgroup>
<h1>{{.Title}}</h1>
<h2>{{.Description}}</h2>
</hgroup>
<div class="article">
{{.Content}}
</div>
</div>
<div></div>
</div>
</section>
{{end}}

31
page/articles.html Normal file
View File

@ -0,0 +1,31 @@
{{template "base" .}}
{{define "title"}}Articles from SeedHammer{{end}}
{{define "description"}}Latest news, updates and insights from SeedHammer Cold Storage.{{end}}
{{define "type"}}website{{end}}
{{define "image"}}seedhammer-front-and-controller.webp{{end}}
{{define "head-extra"}}
<link rel="alternate" type="application/rss+xml" href="/article/rss" title="RSS Feed">
{{end}}
{{define "content"}}
<section class="container">
<h1 class="text-center">Articles</h1>
<div class="grid articles">
{{range .}}
<div>
<a href="/article/{{.Slug}}">
<img src="/static/img/{{.Image}}">
<p>
<small>
<span class="date">{{.Published.Format "02 Jan 2006"}} · By {{.Author}}</span><br>
<strong>{{.Title}}</strong><br>
{{.Description}}
</small>
</p>
</a>
</div>
{{end}}
</div>
</section>
{{end}}

118
page/base.html Normal file
View File

@ -0,0 +1,118 @@
{{define "base"}}<!doctype html>
<html lang="en" data-theme="{{template "theme"}}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="/static/img/favicon.ico" type="image/x-icon">
<link rel="stylesheet" href="/static/css/pico.css">
<link rel="stylesheet" href="/static/css/override.css">
{{template "priority-preload"}}
{{template "head-extra"}}
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{{template "title" .Content}}</title>
<meta name="description" content="{{template "description" .Content}}">
<meta property="og:site_name" content="SeedHammer">
<meta property="og:url" content="{{.PageURL}}">
<meta property="og:type" content="{{template "type" .Content}}" />
<meta property="og:title" content="{{template "title" .Content}}">
<meta property="og:description" content="{{template "description" .Content}}">
<meta property="og:image" content="https://seedhammer.com/static/img/{{template "image" .Content}}">
<meta name="twitter:card" content="summary_large_image">
<meta property="twitter:url" content="{{.PageURL}}">
<meta name="twitter:title" content="{{template "title" .Content}}">
<meta name="twitter:description" content="{{template "description" .Content}}">
<meta name="twitter:image" content="https://seedhammer.com/static/img/{{template "image" .Content}}">
<meta name="twitter:image:alt" content="{{template "description" .Content}}">
</head>
<body>
<header>
<div class="container">
<nav>
<ul>
<li>
<a href="/" id="logo-container">
<svg xmlns="http://www.w3.org/2000/svg" width="220px" height="23px" viewBox="0 0 440.05 45.2">
<title>seedhammer-logo</title>
<path class="a"
d="M70.6,45.2a20.28,20.28,0,0,1-6.6-1,16.33,16.33,0,0,1-5.2-2.9,13.05,13.05,0,0,1-3.4-4.4,1.53,1.53,0,0,1,0-1.6,2.15,2.15,0,0,1,1.4-1,2,2,0,0,1,1.5.2,2.16,2.16,0,0,1,1.1,1.2,10.92,10.92,0,0,0,2.4,2.9,11.47,11.47,0,0,0,3.8,2,15.28,15.28,0,0,0,4.9.7,12.07,12.07,0,0,0,5.2-1,8.39,8.39,0,0,0,3.6-2.8A7.27,7.27,0,0,0,80.6,33a7.58,7.58,0,0,0-2.5-5.8c-1.7-1.6-4.3-2.7-7.8-3.1a18.28,18.28,0,0,1-10.1-4,10.4,10.4,0,0,1-3.7-7.9,9.83,9.83,0,0,1,1.8-5.9,10.8,10.8,0,0,1,5-3.8,18.12,18.12,0,0,1,7.2-1.4,13.83,13.83,0,0,1,5.5,1,13.91,13.91,0,0,1,4.3,2.5,14.29,14.29,0,0,1,3,3.5,1.2,1.2,0,0,1,.6,1.4,1.89,1.89,0,0,1-1,1.3,2.29,2.29,0,0,1-3-1,15,15,0,0,0-2.1-2.4,7.53,7.53,0,0,0-3-1.8,13.33,13.33,0,0,0-4.3-.7,11.4,11.4,0,0,0-7,1.9,6.06,6.06,0,0,0-2.7,5.4,6.2,6.2,0,0,0,1,3.5,7.55,7.55,0,0,0,3.3,2.7,20.24,20.24,0,0,0,6.2,1.7c4.6.7,8,2.1,10.3,4.2a11.38,11.38,0,0,1,3.3,8.4A12.53,12.53,0,0,1,83.8,38a10.49,10.49,0,0,1-3,3.9,11.89,11.89,0,0,1-4.6,2.4A16.86,16.86,0,0,1,70.6,45.2Z"
transform="translate(0 0)" />
<path class="a"
d="M107.2,44.9a15.71,15.71,0,0,1-7.9-2,13.62,13.62,0,0,1-5.4-5.5,16.09,16.09,0,0,1-2-8,16,16,0,0,1,1.9-8,15,15,0,0,1,5.1-5.5,15,15,0,0,1,14.8-.1,12.33,12.33,0,0,1,4.8,5.3,17.43,17.43,0,0,1,1.7,7.7,1.68,1.68,0,0,1-.6,1.4,1.74,1.74,0,0,1-1.4.5H94.7V27.2h24l-2.4,1.7a13.68,13.68,0,0,0-1.2-5.8,9.72,9.72,0,0,0-3.5-4,9.35,9.35,0,0,0-5.3-1.4,10.08,10.08,0,0,0-5.5,1.5,10.47,10.47,0,0,0-3.7,4.1,13.2,13.2,0,0,0-1.3,6,11.88,11.88,0,0,0,1.5,6,11.23,11.23,0,0,0,4,4.1,11.5,11.5,0,0,0,5.9,1.5,11.25,11.25,0,0,0,4-.7,10.67,10.67,0,0,0,3.2-1.7,2.39,2.39,0,0,1,1.4-.5,1.84,1.84,0,0,1,1.3.4,1.75,1.75,0,0,1,.7,1.4,1.61,1.61,0,0,1-.6,1.3,16.78,16.78,0,0,1-4.6,2.6A12.34,12.34,0,0,1,107.2,44.9Z"
transform="translate(0 0)" />
<path class="a"
d="M140,44.9a15.71,15.71,0,0,1-7.9-2,13.62,13.62,0,0,1-5.4-5.5,16.09,16.09,0,0,1-2-8,16,16,0,0,1,1.9-8,14.19,14.19,0,0,1,5.1-5.5,15,15,0,0,1,14.8-.1,12.33,12.33,0,0,1,4.8,5.3,17.43,17.43,0,0,1,1.7,7.7,1.68,1.68,0,0,1-.6,1.4,1.87,1.87,0,0,1-1.4.5H127.5V27.2h24l-2.4,1.7a13.68,13.68,0,0,0-1.2-5.8,9.72,9.72,0,0,0-3.5-4,9.35,9.35,0,0,0-5.3-1.4,10.08,10.08,0,0,0-5.5,1.5,10.47,10.47,0,0,0-3.7,4.1,13.2,13.2,0,0,0-1.3,6,11.88,11.88,0,0,0,1.5,6,11.23,11.23,0,0,0,4,4.1,11.5,11.5,0,0,0,5.9,1.5,11.25,11.25,0,0,0,4-.7,10.67,10.67,0,0,0,3.2-1.7,2.39,2.39,0,0,1,1.4-.5,1.84,1.84,0,0,1,1.3.4,1.75,1.75,0,0,1,.7,1.4,1.61,1.61,0,0,1-.6,1.3,16.78,16.78,0,0,1-4.6,2.6A11.77,11.77,0,0,1,140,44.9Z"
transform="translate(0 0)" />
<path class="a"
d="M173,44.9a16.26,16.26,0,0,1-7.9-2,14.53,14.53,0,0,1-5.5-5.5,16,16,0,0,1-2-7.9,16.26,16.26,0,0,1,2-7.9,14.35,14.35,0,0,1,12.9-7.5,13.55,13.55,0,0,1,6.7,1.6,13.06,13.06,0,0,1,4.8,4.2V3.6a2.06,2.06,0,0,1,2.2-2.2,2.45,2.45,0,0,1,1.6.6,2.11,2.11,0,0,1,.6,1.6V29.7a16.78,16.78,0,0,1-2.1,7.8,15.26,15.26,0,0,1-5.5,5.5A17.28,17.28,0,0,1,173,44.9Zm0-3.9a11,11,0,0,0,5.7-1.5,11.23,11.23,0,0,0,4-4.1,11.5,11.5,0,0,0,1.5-5.9,11.77,11.77,0,0,0-1.5-5.9,10.52,10.52,0,0,0-4-4.1,11.58,11.58,0,0,0-11.4,0,11.23,11.23,0,0,0-4,4.1,11.77,11.77,0,0,0-1.5,5.9,11.5,11.5,0,0,0,1.5,5.9,11.23,11.23,0,0,0,4,4.1A11,11,0,0,0,173,41Z"
transform="translate(0 0)" />
<path class="a"
d="M201,44.6a2.05,2.05,0,0,1-2.1-2.1V3.6a2.45,2.45,0,0,1,.6-1.6,2,2,0,0,1,1.5-.6,2.45,2.45,0,0,1,1.6.6,2.11,2.11,0,0,1,.6,1.6V20.9h27V3.6a2.45,2.45,0,0,1,.6-1.6,2,2,0,0,1,1.5-.6,2.45,2.45,0,0,1,1.6.6,2.11,2.11,0,0,1,.6,1.6V42.5a2,2,0,0,1-.6,1.5,2.11,2.11,0,0,1-1.6.6,2.05,2.05,0,0,1-2.1-2.1V24.7h-27V42.5a2,2,0,0,1-.6,1.5A2.27,2.27,0,0,1,201,44.6Z"
transform="translate(0 0)" />
<path class="a"
d="M258.4,44.9a14.35,14.35,0,0,1-12.9-7.5,15.71,15.71,0,0,1-2-7.9,15.71,15.71,0,0,1,2-7.9,14.53,14.53,0,0,1,5.5-5.5,16.41,16.41,0,0,1,15.7,0,15.26,15.26,0,0,1,5.5,5.5,17.19,17.19,0,0,1,2.1,7.9l-1.7,1.3a13.61,13.61,0,0,1-1.9,7.2,13.33,13.33,0,0,1-5,5A15,15,0,0,1,258.4,44.9Zm.4-3.9a11,11,0,0,0,5.7-1.5,11.23,11.23,0,0,0,4-4.1,11.77,11.77,0,0,0,1.5-5.9,11.5,11.5,0,0,0-1.5-5.9,11.23,11.23,0,0,0-4-4.1,11.58,11.58,0,0,0-11.4,0,11.23,11.23,0,0,0-4,4.1,11.5,11.5,0,0,0-1.5,5.9,11.77,11.77,0,0,0,1.5,5.9,10.52,10.52,0,0,0,4,4.1A11,11,0,0,0,258.8,41ZM272,44.6a2.05,2.05,0,0,1-2.1-2.1V33l1.1-4.4,3.3.8v13a2,2,0,0,1-.6,1.5A2.34,2.34,0,0,1,272,44.6Z"
transform="translate(0 0)" />
<path class="a"
d="M284.6,44.6A2.11,2.11,0,0,1,283,44a2,2,0,0,1-.6-1.5v-26A2,2,0,0,1,283,15a2.11,2.11,0,0,1,1.6-.6,2.05,2.05,0,0,1,2.1,2.1v26a2,2,0,0,1-.6,1.5A1.75,1.75,0,0,1,284.6,44.6Zm19.5,0a2.45,2.45,0,0,1-1.6-.6,1.72,1.72,0,0,1-.6-1.5V26.6a9.23,9.23,0,0,0-2-6.2,6.74,6.74,0,0,0-5.3-2.3,7.31,7.31,0,0,0-5.6,2.2,7.76,7.76,0,0,0-2.2,5.8h-3a14,14,0,0,1,1.6-6.3A11.42,11.42,0,0,1,301,15.5a9.86,9.86,0,0,1,3.9,4.4,15.26,15.26,0,0,1,1.4,6.6V42.4a2,2,0,0,1-.6,1.5A2.13,2.13,0,0,1,304.1,44.6Zm19.3,0a2.05,2.05,0,0,1-2.1-2.1V26.6a9.23,9.23,0,0,0-2-6.2,6.88,6.88,0,0,0-5.3-2.3,7.38,7.38,0,0,0-5.6,2.3,7.87,7.87,0,0,0-2.1,6.1h-3.8a13.59,13.59,0,0,1,1.6-6.5,11.36,11.36,0,0,1,4.3-4.4,12.53,12.53,0,0,1,6.1-1.5,11.14,11.14,0,0,1,5.8,1.5,9.86,9.86,0,0,1,3.9,4.4,15.26,15.26,0,0,1,1.4,6.6V42.5A2,2,0,0,1,325,44,2.45,2.45,0,0,1,323.4,44.6Z"
transform="translate(0 0)" />
<path class="a"
d="M337.1,44.6a2.11,2.11,0,0,1-1.6-.6,2,2,0,0,1-.6-1.5v-26a2,2,0,0,1,.6-1.5,2.11,2.11,0,0,1,1.6-.6,2.05,2.05,0,0,1,2.1,2.1v26a2.05,2.05,0,0,1-2.1,2.1Zm19.4,0a2.05,2.05,0,0,1-2.1-2.1V26.6a9.23,9.23,0,0,0-2-6.2,6.74,6.74,0,0,0-5.3-2.3,7.31,7.31,0,0,0-5.6,2.2,7.76,7.76,0,0,0-2.2,5.8h-3a14,14,0,0,1,1.6-6.3,11.42,11.42,0,0,1,15.6-4.3,9.86,9.86,0,0,1,3.9,4.4,15.26,15.26,0,0,1,1.4,6.6V42.4a2,2,0,0,1-.6,1.5A2.51,2.51,0,0,1,356.5,44.6Zm19.3,0a2.05,2.05,0,0,1-2.1-2.1V26.6a9.23,9.23,0,0,0-2-6.2,6.88,6.88,0,0,0-5.3-2.3,7.38,7.38,0,0,0-5.6,2.3,7.87,7.87,0,0,0-2.1,6.1h-3.8a13.59,13.59,0,0,1,1.6-6.5,11.36,11.36,0,0,1,4.3-4.4,12.53,12.53,0,0,1,6.1-1.5,11.14,11.14,0,0,1,5.8,1.5,9.86,9.86,0,0,1,3.9,4.4,15.26,15.26,0,0,1,1.4,6.6V42.5a2,2,0,0,1-.6,1.5A2.45,2.45,0,0,1,375.8,44.6Z"
transform="translate(0 0)" />
<path class="a"
d="M401,44.9a15.71,15.71,0,0,1-7.9-2,13.62,13.62,0,0,1-5.4-5.5,16.09,16.09,0,0,1-2-8,16,16,0,0,1,1.9-8,15,15,0,0,1,5.1-5.5,15,15,0,0,1,14.8-.1,12.33,12.33,0,0,1,4.8,5.3,17.43,17.43,0,0,1,1.7,7.7,1.68,1.68,0,0,1-.6,1.4,1.74,1.74,0,0,1-1.4.5H388.5V27.2h24l-2.4,1.7a13.68,13.68,0,0,0-1.2-5.8,9.72,9.72,0,0,0-3.5-4,9.35,9.35,0,0,0-5.3-1.4,10.08,10.08,0,0,0-5.5,1.5,10.47,10.47,0,0,0-3.7,4.1,13.2,13.2,0,0,0-1.3,6,11.88,11.88,0,0,0,1.5,6,11.23,11.23,0,0,0,4,4.1,11.5,11.5,0,0,0,5.9,1.5,11.25,11.25,0,0,0,4-.7,10.67,10.67,0,0,0,3.2-1.7,2.39,2.39,0,0,1,1.4-.5,1.84,1.84,0,0,1,1.3.4,1.75,1.75,0,0,1,.7,1.4,1.61,1.61,0,0,1-.6,1.3,16.78,16.78,0,0,1-4.6,2.6A11.77,11.77,0,0,1,401,44.9Z"
transform="translate(0 0)" />
<path class="a"
d="M423.4,44.6a2.11,2.11,0,0,1-1.6-.6,2,2,0,0,1-.6-1.5v-26a2.06,2.06,0,0,1,2.2-2.2,1.75,1.75,0,0,1,1.5.6,2.11,2.11,0,0,1,.6,1.6V42.6a1.75,1.75,0,0,1-.6,1.5A2.25,2.25,0,0,1,423.4,44.6ZM423.1,26a12.45,12.45,0,0,1,1.8-6.1,12.64,12.64,0,0,1,4.3-4.3,11.66,11.66,0,0,1,5.8-1.5,8.24,8.24,0,0,1,3.9.7,1.83,1.83,0,0,1,1.1,2.1,1.53,1.53,0,0,1-.7,1.1,1.91,1.91,0,0,1-1.3.2c-.5,0-1.1-.1-1.7-.1a12.13,12.13,0,0,0-5.5.6,7.77,7.77,0,0,0-3.8,2.8,7.53,7.53,0,0,0-1.4,4.5Z"
transform="translate(0 0)" />
<path class="a"
d="M7.6,35.9,0,29.6l5.7-2.7,9.6,9.5V0H5.7A5.63,5.63,0,0,0,0,5.7V39.5a5.7,5.7,0,0,0,5.7,5.7H17.6L2.2,38.9Z"
transform="translate(0 0)" />
<path class="a" d="M45.2,29.5V5.7A5.7,5.7,0,0,0,39.5,0H29.8V36.4l9.7-9.6Z" transform="translate(0 0)" />
<polygon class="a" points="15.3 36.4 10.8 38.6 17.6 45.2 22.6 45.2 15.3 36.5 15.3 36.4" />
<polygon class="a" points="29.9 36.4 29.9 36.5 22.6 45.2 27.6 45.2 34.5 38.6 29.9 36.4" />
<path class="a" d="M37.7,35.9l5.4,2.9L27.6,45.1H39.5a5.7,5.7,0,0,0,5.7-5.7V29.5Z"
transform="translate(0 0)" />
</svg>
</a>
</li>
</ul>
<label style="width: 0;height: 0;opacity: 0;" for="hamburger">Hamburger Menu</label>
<input type="checkbox" name="hamburger" id="hamburger" />
<ul>
{{range .Nav}}
<li{{if eq .URL $.NavURL}} class="active" {{end}}>
<a href="{{.URL}}" {{if .Target}} target="{{.Target}}" {{end}}>{{.Name}}</a>
</li>
{{end}}
</ul>
</nav>
</div>
</header>
<main>
{{template "content" .Content}}
</main>
<footer>
<div class="container">
<div class="grid">
<p><small>This website does not <a href="/about/attitude-to-privacy">track its visitors</a>.</small></p>
<p><small>Made with love for {{template "icn-bitcoin"}} bitcoin · <a href="https://twitter.com/SeedHammer" target="_blank">Twitter</a> · <a
href="https://www.youtube.com/@SeedHammer" target="_blank">Youtube</a> · <a
href="https://signal.group/#CjQKIArvsDmiLDuUXsIFXsNFUa8mbElkGBjDSJghbuJk3Xe_EhB0bOzBoKCgOSF-HgCc8NIW"
target="_blank">Signal</a></small></p>
</div>
</div>
</footer>
</body>
</html>
{{end}}
{{define "theme"}}light{{end}}
{{define "type"}}website{{end}}
{{define "image"}}seedhammer-front-and-controller.webp{{end}}
{{define "priority-preload"}}{{end}}
{{define "head-extra"}}{{end}}

102
page/cart.html Normal file
View File

@ -0,0 +1,102 @@
{{template "base" .}}
{{define "title"}}Order the SeedHammer machine and accessories{{end}}
{{define "description"}}Place your order here. The Ultimate Cold Storage for Single- and Multisig Bitcoin Setups.{{end}}
{{define "line"}}
<input type="hidden" name="id" value="{{.ID}}">
<div class="product-main">
<h2>{{.Product.Name}}</h2>
</div>
<div class="product-pic">
<img class="product-image" src="{{.Product.Image}}" alt="{{.Product.Name}}"></div>
<div class="product-description">
<ul>
{{range .Product.Content}}
<li>{{.}}</li>
{{end}}
</ul>
</div>
<div class="product-amount">
<input type="number" name="quantity" value="{{.Quantity}}" class="mb-0 cart-amount" multiple="1" min=0 oninput="validity.valid||(value='');"> <span>{{.Product.Unit}}</span>
</div>
<div class="product-price">
{{if ne .Price .Product.Price}}<small><del>{{.Product.Price}}</del></small><br>{{end}}{{.Price}}
</div>
{{if .Product.Warning}}
<div class="product-footer">
<div class="alert alert-warning"><span class="circle">!</span> {{.Product.Warning}}</div>
</div>
{{end}}
{{if .Product.Danger}}
<div class="product-footer">
<div class="alert alert-danger"><span class="circle">!</span> {{.Product.Danger}}</div>
</div>
{{end}}
{{end}}
{{define "content"}}
<section class="container">
<div class="grid center-layout">
<div></div>
<div>
<hgroup class="text-center">
<h1>{{if .Preorder}}Preorder SeedHammer II{{else}}Shop{{end}}</h1>
<p><small><i>Amounts are in US dollars. Payment in bitcoin only. Import taxes are not included.</i></small></p>
</hgroup>
{{if .Preorder}}<p class="alert alert-danger"><span class="circle">!</span> All products below are preorders. Shipping and taxes not included. More information on our <a target="_blank" href="https://geyser.fund/project/seedhammerii/">Crowdfunding page</a>.</p>{{end}}
{{if .Error}}<p class="alert alert-warning">{{.Error}}</p>{{end}}
{{if .Coupons}}<p class="alert alert-success">Discount: "{{index .Coupons 0}}"</p>{{end}}
<form method="post">
<input type="hidden" name="r" value="/shop/checkout">
<div class="grid product-row product-header">
<div class="product-main">Product</div>
<div class="product-amount">Quantity</div>
<div class="product-price">Price</div>
</div>
{{range .Order.Lines}}
{{if not .Product.Legacy}}
<div class="grid product-row" id="{{.ID}}">
{{template "line" .}}
</div>
{{end}}
{{end}}
{{if .LegacyPlates}}
<button type="button" id="showProductsBtn">Show Legacy Plates</button>
{{range .Order.Lines}}
{{if .Product.Legacy}}
<div class="grid product-row hidden-row is-hidden" id="{{.ID}}">
{{template "line" .}}
</div>
{{end}}
{{end}}
{{end}}
<button type="submit">Go To Checkout</button>
<style>
.is-hidden {display: none; }
#showProductsBtn {
background: #fff; color: #02427d;
}
</style>
{{if .LegacyPlates}}
<script>
(function() {
var btn = document.getElementById("showProductsBtn");
var rows = document.getElementsByClassName("hidden-row");
var hidden = true;
btn.addEventListener("click", function() {
hidden = !hidden;
for (var i = 0; i < rows.length; i++) {
rows[i].classList.toggle("is-hidden", hidden);
}
btn.textContent = hidden ? "Show Legacy Plates" : "Hide Legacy Plates";
});
})();
</script>
{{end}}
</form>
</div>
<div></div>
</div>
</section>
{{end}}

67
page/checkout.html Normal file
View File

@ -0,0 +1,67 @@
{{template "base" .}}
{{define "title"}}SeedHammer Checkout{{end}}
{{define "description"}}SeedHammer Checkout{{end}}
{{define "content"}}
<section class="container">
<div class="grid center-layout">
<div></div>
<div>
<hgroup class="text-center">
<h1>Checkout</h1>
<p><small>Personal data is deleted 4 months after dispatch, except country. Order content and payment information are retained for support purposes. Read our <a href="/about/attitude-to-privacy" target="_blank">attitude to privacy</a>.</small></p>
</hgroup>
<h2>Delivery Information</h2>
{{if .Error}}<p class="alert alert-warning">{{.Error}}</p>{{end}}
<form method="POST">
<input type="hidden" name="r" value="/shop/summary">
{{with .Order.Address}}
{{if not $.Preorder}}
<input type="text" id="name" name="name" maxlength="{{$.MaxNameLength}}" placeholder="First and last name" value="{{.Name}}" required>
<small>Tip: Use a name and address unrelated to yourself.</small>
<fieldset>
<label for="switch">
<input type="checkbox" id="company-switch" name="switch" role="switch">Company
<div class="grid mt-4">
<div><input type="text" id="company" name="company" maxlength="{{$.MaxNameLength}}" placeholder="Company" value="{{.Company}}"></div>
<div><input type="text" id="vat" name="vat" placeholder="TAX ID (EIN/VAT/IOSS/EORI)" value="{{.VAT}}"></div>
</div>
</label>
</fieldset>
<input type="text" id="address" name="address" placeholder="Address" value="{{.Address}}" required>
<small>Tip: Get delivery to a business, office or parcel shop in order not to reveal your exact location.</small>
<input type="text" id="address2" name="address2" placeholder="Address 2" value="{{.Address2}}">
<div class="grid">
<input type="text" id="city" name="city" placeholder="City" value="{{.City}}" required>
<input type="zip" id="zip" name="zip" placeholder="ZIP/Postal Code" value="{{.Zip}}">
</div>
<select id="select-country" name="country" required>
<option value="" disabled{{if not .Country}} selected="true"{{end}}>Country</option>
{{range $.Countries}}
<option value="{{.ID}}" {{if eq $.Order.Address.Country .ID}} selected="true"{{end}}>{{.Name}}</option>
{{end}}
</select>
{{end}}
<div class="grid mb-5">
<label>
<input type="email" id="email" name="email" value="{{.Email}}" placeholder="Email" required>
<small>Tip: Use a burner email. More info <a href="https://duckduckgo.com/?q=create+temporary+email+address">here</a>.</small></label>
{{if not $.Preorder}}
<label><input type="tel" id="tel" name="phone" value="{{.Phone}}" placeholder="Phone Number" required minlength="6">
<small>Tip: Use a burner number. More info <a href="https://duckduckgo.com/?q=create+burner+phone+number">here</a>.</small></label>
{{end}}
</div>
{{if not $.Preorder}}
<p><i><small>Orders are shipped from the EU and will take 2-3 weeks to arrive depending on shipping type and destination. Amounts are in US dollars. Payment only in bitcoin. Customs may apply. Read the <a href="/terms-and-conditions" target="_blank">TAC here</a>.</small></i></p>
{{else}}
<p><i><small>Preorders are expected to ship in Q2 2025. Shipping and taxes not included. We will contact you for delivery information and shipping charge when your order is ready to ship. Amounts are in US dollars. Payment only in bitcoin. Customs may apply. Read the <a href="/terms-and-conditions" target="_blank">TAC here</a>.</small></i></p>
{{end}}
<button type="submit">Go To Summary</a>
{{end}}
</form>
</div>
<div></div>
</div>
</section>
{{end}}

94
page/faq.html Normal file
View File

@ -0,0 +1,94 @@
{{template "base" .}}
{{define "title"}}SeedHammer FAQ{{end}}
{{define "description"}}Most Frequenlty Asked Questions about SeedHammer{{end}}
{{define "content"}}
<section class="container">
<div class="grid center-layout">
<div></div>
<div>
<h1 class="text-center">FAQ</h1>
<details>
<summary>Can I backup solely the descriptor part of a setup?</summary>
<p>Yes, it's possible to back up the descriptor part of a setup, resulting in a complete set of plates. However, they will be blank on the side intended for the seed phrase.</p>
<p>When prompted to turn the plate in the hammer process, halt the process, refrain from continuing the hammering, and proceed to load a new seed.</p>
</details>
<details>
<summary>Can I backup solely the seed phrase of a setup?</summary>
<p>Yes, you can back up exclusively the seed, omitting the descriptor part of the setup. This approach gives a complete set of plates, without a descriptor. Consequently, they will remain blank on the side designated for the descriptor.</p>
<p>Upon being prompted to hammer the first side of a plate, engage the dry-run mode (further details can be found <a href="https://github.com/seedhammer#dry-run-engraving">here</a>). Remember to deactivate the dry-run mode before proceeding to hammer the second side (the seed side).</p>
</details>
<details>
<summary>Can I backup a passphrase-protected wallet?</summary>
<p>Yes, from version <a href="https://github.com/seedhammer/seedhammer/releases/tag/v1.1.1">v1.1.1</a> and forward.</p>
<p>Note that backing up a passphrase-protected multisig wallet is not possible, as matching the seed with the descriptor part becomes impossible.</p>
<p>A workaround for passphrase-protected multisig wallets is to back up each share as a single signature wallet and, optionally, skip the descriptor side. However, this approach will result in the loss of the unique feature of a self-contained setup.</p>
</details>
<details>
<summary>What do you mean by "self-contained" setup?</summary>
<p>This means that the minimum amount of shares (physical plates) is enough to recover the wallet, and the need for storing a copy of the XPUBs (often in the form of a descriptor) digital or on paper along each backup/plate is eliminated.</p>
<p>Read more about the technical solution we used to achieve this in our article <a href="/article/the-seedhammer-descriptor-partitioning-scheme">The SeedHammer Descriptor Partitioning Scheme</a>.</p>
</details>
<details>
<summary>What are the weaknesses of SeedHammer?</summary>
<p>See our article on <a href="/article/attack-vectors">attack vectors</a>.</p>
</details>
<details>
<summary>Can I buy the SeedHammer machine elsewhere?</summary>
<p>The SeedHammer machine is a off-the-shelf industrial electric marking machine for making nameplates etc.</p>
<p>It can be bought in various online hardware stores - however physical alterations are needed to function as a SeedHammer.</p>
</details>
<details>
<summary>Which wallet types can I backup with SeedHammer?</summary>
<p>It is possible to backup both single and multisig setups. However there are some guidelines for which type of plates to use for each setup.</p>
<p>Read about our steel plates and supported formats in our article <a href="/article/the-seedhammer-metal-plates">The Seedhammer Metal Plates</a>.</p>
</details>
<details>
<summary>What is the difference between the plates (SH01, SH02 and SH03)?</summary>
<p>SH01 is credit card sized, SH02 is square, and SH03 is rectangular. All are made of 3 mm <a href="/article/steel-316">stainless steel 316</a>.</p>
<p>The sizes of the plates determine which type of wallet setup that can be engraved on them.</p>
<p>Read more about this in our article <a href="/article/the-seedhammer-metal-plates">The Seedhammer Metal Plates</a>.</p>
</details>
<details>
<summary>Do you ship to anywhere in the world?</summary>
<p>Yes, we ship worldwide with very few exceptions.</p>
<p>Are you in doubt contact us at <a href="mailto:support@seedhammer.com">support@seedhammer.com</a>.</p>
</details>
<details>
<summary>Can I write a title on the plates?</summary>
<p>Yes, from version <a href="https://github.com/seedhammer/seedhammer/releases/tag/v1.2.0">v1.2.0</a> and forward.</p>
<p>When scanning descriptors from compatible wallet software, the wallet title will be shown on the descriptor information screen and engraved on the plate (max. 18 characters, limited character set).</p>
<p>The compatible wallets are: BlueWallet (vaults only), Nunchuk wallets and wallets capable of exporting descriptors in one of those formats.</p>
<p>When using Sparrow Wallet exporting descriptors in the following formats also work: Jade Multisig, Keystone Multisig, Passport Multisig, and Specter Desktop.</p>
</details>
<details>
<summary>What is the difference between SeedHammer and the many other steel backup solutions?</summary>
<p>The main difference is that SeedHammer can make self-contained multisig backups.</p>
<p>This means that the minimum amount of shares (physical plates) is enough to recover the wallet, and the need for storing a copy of the XPUBs (often in the form of a descriptor) digital or on paper along each backup/plate is eliminated.</p>
<p>There are also other benefits, such as QR codes for convenient recovery and signing, the ability to create distributed setups, gift cards, etc.</p>
<p>Moreover, precision engraving ensures that all information, such as the seed phrase and other text, is easily readable and discernible.</p>
<p>If you only ever need to back up a single 12- or 24-word bitcoin seed phrase many of the other steel backup solutions are most likely more suitable.</p>
</details>
<details>
<summary>Will the SeedHammer controller generate a seed?</summary>
<p>No, the SeedHammer software will never be able to generate a seed phrase because of the obvious vulnerabilities this approach would introduce. Read more <a href="/article/attack-vectors#generate-seed">here</a>.</p>
</details>
</div>
<div></div>
</div>
</section>
{{end}}

41
page/get-started.html Normal file
View File

@ -0,0 +1,41 @@
{{template "base" .}}
{{define "title"}}{{.Doc.Title}}{{end}}
{{define "description"}}{{.Doc.Description}}{{end}}
{{define "type"}}article{{end}}
{{define "content"}}
<section class="container">
<div class="grid docs-layout">
<aside>
<nav>
{{range .TOC}}
<details{{if eq .Slug $.ActiveSlug}} open{{end}}>
<summary><a href="{{$.Base}}/{{.Slug}}"><span class="circle">{{.Index}}</span> {{.Name}}</a></summary>
<ul>
{{with $article := .}}
{{range .Sections}}
<li>
<a href="{{$.Base}}/{{$article.Slug}}#{{.ID}}">{{.Name}}</a>
</li>
{{end}}
{{end}}
</ul>
</details>
{{end}}
</nav>
</aside>
<div></div>
{{with .Doc}}
<div class="guide">
<hgroup class="text-center">
<h1>{{.Title}}</h1>
<h2>{{.Description}}</h2>
</hgroup>
{{.Content}}
</div>
{{end}}
<div></div>
</div>
</section>
{{end}}

5
page/icons.html Normal file
View File

@ -0,0 +1,5 @@
{{define "icn-bitcoin"}}<svg version="1.1" class="btc-logo" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="16px" height="16px" viewBox="0 0 512 512" xml:space="preserve"><g><path d="M235,265.3l-14.6,58.5c18.2,4.4,73.7,22.4,81.8-10.8C310.9,278.7,253,269.9,235,265.3z"/><path d="M255,185.4l-13.2,53.1c15,3.8,61.3,19,68.9-11C318.4,196,269.9,189,255,185.4z"/><path d="M314.8,27.1C184.9-5.2,53.3,73.8,20.8,203.8s46.7,261.5,176.7,293.9S459,450.9,491.5,321C523.9,191.2,444.8,59.7,314.8,27.1z M363.2,228c-3.6,23.6-16.6,35.1-33.9,39.1c24,12.4,35.9,31.5,24.4,64.5c-14.4,40.9-48.5,44.5-93.8,35.9l-11,44.1l-26.6-6.6l10.8-43.5c-7-1.8-14-3.6-21.2-5.6l-11,43.7l-26.6-6.6l11-44.1l-53.7-13.6l13.2-30.5c0,0,19.6,5.2,19.4,4.8c7.6,1.8,11-3,12.2-6.4l29.9-119.8c0.4-5.6-1.6-12.8-12.4-15.6c0.4-0.2-19.4-4.8-19.4-4.8l7-28.3 l53.7,13.4l10.8-43.7l26.6,6.6L262,153.9c7.2,1.6,14.4,3.2,21.4,5l10.6-42.5l26.6,6.6l-11,43.7C343.4,178.2,367.9,195.6,363.2,228z"/></g></svg>{{end}}
{{define "icn-copy"}}<svg class="icnCopy" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M4 2a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2zm2-1a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1zM2 5a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1v-1h1v1a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h1v1z"/></svg>{{end}}
{{define "icn-check"}}<svg class="icnCheck" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16"><path d="M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z"/></svg>{{end}}

118
page/index.html Normal file
View File

@ -0,0 +1,118 @@
{{template "base" .}}
{{define "title"}}Multisig Steel Backup. Self Custody for Individuals and Businesses{{end}}
{{define "description"}}Easily backup bitcoin multisig and singlesig wallets automatically onto stainless steel. Professional self custody solution for private and businesses.{{end}}
{{define "theme"}}green{{end}}
{{define "priority-preload"}}
<link rel="preload" fetchpriority="high" as="image" href="/static/img/seedhammer-hero-green.webp" type="image/webp">
{{end}}
{{define "content"}}
<section id="hero">
<div class="container">
<div class="grid">
<div>
<h1 class="mb-0 mt-4">Steel Backup Specialized for Bitcoin Multisig Wallets</h1>
<div class="mt-4">
<ul>
<li><p class="mb-0"><a href="#self-contained-multisig-setup">Self-contained</a>: Recover with Minimum of Shares.</p></li>
<li><p class="mb-0">QR Codes for Easy Recovery and Air Gapped Signing.</p></li>
<li><p class="mb-0">Works with all signers and hardware wallets.</p></li>
</ul>
</div>
<p class="text-center mt-6 mb-6"><a href="/shop" role="button">Order Now <span class="btn-flow">>></span></a></p>
</div>
<div>
<div class="video-container">
<div class="video-facade" data-video-id="7V-R7SZqkhQ">
<img src="/static/img/video-facade.webp" alt="Video Thumbnail">
</div>
<div class="video-iframe"></div>
</div>
</div>
</div>
</div>
</section>
<section>
<div class="container">
<hgroup>
<h2 class="text-center" id="self-contained-multisig-setup">Self-contained Multisig Backups</h2>
<h3 class="text-center">SeedHammer eliminates the need for storing a descriptor.</h3>
</hgroup>
<p class="text-center">Without the public keys for <strong>all</strong> the seeds in a multisig wallet, you can't recover the wallet.<br>Other backup solutions require a separate digital or printed copy of the wallet.</p>
<div class="grid mt-6">
<div class="img-center">
<img style="width: 75%;" src="/static/img/3-of-5-multisig.webp" alt="By design M-of-N cosigners is enough to recover a multisig wallet backed up with SeedHammer">
</div>
<div>
<h3 class="text-center">Recover With Minimum of Shares</h3>
<p>The minimum amount of shares is enough to recover a multisig wallet backed up with SeedHammer.</p>
<ul class="ms-4">
<li>Withstand damage or loss of all shares beyond the quorum.</li>
<li>Any combination of M-of-N plates contain enough data for a full recovery.</li>
<li>Fast and convenient recovery with QR codes.</li>
</ul>
</div>
</div>
<div class="grid mt-7">
<div>
<h3 class="text-center">No Need to Backup Wallet Descriptor</h3>
<p>The descriptor is split into parts which are distributed among the plates in a way so any quorum can recover the wallet.</p>
<ul class="ms-4">
<li>Perform complete recovery with the minimum number of plates.</li>
<li>No need to separately store the descriptor online, offline or alongside each physical plate.</li>
<li>Complies with multisig standards, no special tools needed for recovery.</li>
</ul>
</div>
<div>
<div class="img-center">
<img src="/static/img/no-descriptor-needed.webp" alt="SeedHammer eliminates the need for storing a separate wallet output descriptor in multisignature backups">
<small>One side contains the seed,<br>the other side contains a part of the descriptor.</small>
</div>
</div>
</div>
</div>
</section>
<section>
<div class="container">
<div class="grid">
<div>
<div class="img-center mb-6">
<img src="/static/img/seedhammer-front-and-controller.webp" width="85%" alt="The SeedHammer Machine incl. Raspberry Pi (SeedSigner) running the controller software">
</div>
</div>
<div>
<h2 class="text-center">Built for The Security Conscious</h2>
<p>The controller software is <a href="https://github.com/seedhammer/seedhammer/blob/main/LICENSE" target="_blank">open source</a> and runs on the same air gapped <a href="/article/the-seedhammer-controller">hardware as SeedSigner</a>.</p>
<p>The electric hammer is a modified off-the-shelf machine. It is stateless and contains no radio capabilities (wifi, bluetooth, etc.).</p>
<p>The singlesig and multisig backups are easily verifiable.</p>
<p>Read more in our article on <a href="/article/attack-vectors">attack vectors</a>.</p>
</div>
</div>
</div>
</section>
<section>
<div class="container">
<hgroup>
<h2 class="text-center">See More On <a href="https://twitter.com/SeedHammer">Twitter</a></h2>
<h3 class="text-center"><a href="https://twitter.com/SeedHammer">twitter.com/SeedHammer</a></h3>
</hgroup>
<div class="grid">
<div>
<blockquote class="twitter-tweet" data-conversation="none" data-dnt="true"><p lang="en" dir="ltr">Some do! <a href="https://t.co/xj7tDjivzh">pic.twitter.com/xj7tDjivzh</a></p>&mdash; Erik (@brikk_) <a href="https://twitter.com/brikk_/status/1675534057109610500?ref_src=twsrc%5Etfw">July 2, 2023</a></blockquote>
</div>
<div>
<blockquote class="twitter-tweet" data-dnt="true"><p lang="en" dir="ltr">Sovereignty or nah? <a href="https://twitter.com/SeedSigner?ref_src=twsrc%5Etfw">@SeedSigner</a> <a href="https://twitter.com/start9labs?ref_src=twsrc%5Etfw">@start9labs</a> <a href="https://twitter.com/SeedHammer?ref_src=twsrc%5Etfw">@SeedHammer</a> <a href="https://t.co/2Mxw9sa5pC">pic.twitter.com/2Mxw9sa5pC</a></p>&mdash; ericjaffe (@ericjaffe) <a href="https://twitter.com/ericjaffe/status/1675255817879126016?ref_src=twsrc%5Etfw">July 1, 2023</a></blockquote>
</div>
<div>
<blockquote class="twitter-tweet" data-dnt="true"><p lang="en" dir="ltr"><a href="https://twitter.com/SeedHammer?ref_src=twsrc%5Etfw">@SeedHammer</a> <a href="https://twitter.com/SeedSigner?ref_src=twsrc%5Etfw">@SeedSigner</a> guess what arrived today? Now need to fond time to set it up and knock a few tests out. <a href="https://t.co/XiCivvXUyB">pic.twitter.com/XiCivvXUyB</a></p>&mdash; MoparMiningLLC (@MoparMining) <a href="https://twitter.com/MoparMining/status/1653122935807156237?ref_src=twsrc%5Etfw">May 1, 2023</a></blockquote>
</div>
<div>
<blockquote class="twitter-tweet" data-dnt="true"><p lang="en" dir="ltr">On stage demonstrating <a href="https://twitter.com/SeedHammer?ref_src=twsrc%5Etfw">@SeedHammer</a> <a href="https://twitter.com/seedor_io?ref_src=twsrc%5Etfw">@seedor_io</a> and <a href="https://twitter.com/SeedSigner?ref_src=twsrc%5Etfw">@SeedSigner</a> at <a href="https://twitter.com/BitcoinAlive?ref_src=twsrc%5Etfw">@BitcoinAlive</a> <a href="https://t.co/L08xJjHs4H">pic.twitter.com/L08xJjHs4H</a></p>&mdash; mineracks (@mineracks) <a href="https://twitter.com/mineracks/status/1647092860091777024?ref_src=twsrc%5Etfw">April 15, 2023</a></blockquote>
</div>
</div>
</div>
</section>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<script>document.addEventListener("DOMContentLoaded", function (){ var facades=document.querySelectorAll(".video-facade"); facades.forEach(function (facade){ facade.addEventListener("mouseover", function (){ var videoId=facade.getAttribute("data-video-id"); var iframe=document.createElement("iframe"); iframe.setAttribute("src", "https://www.youtube.com/embed/" + videoId + "?autoplay=1"); iframe.setAttribute("title", "SeedHammer intro video"); iframe.setAttribute("frameborder", "0"); iframe.setAttribute("allow", "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"); iframe.setAttribute("allowfullscreen", "1"); var videoIframeContainer=facade.nextElementSibling; videoIframeContainer.appendChild(iframe); videoIframeContainer.style.display="block"; facade.style.display="none"})})}); </script>
{{end}}

21
page/invoice_expired.html Normal file
View File

@ -0,0 +1,21 @@
{{template "base" .}}
{{define "title"}}SeedHammer Checkout{{end}}
{{define "description"}}{{end}}
{{define "content"}}
<section class="container">
<div class="grid center-layout">
<div></div>
<div>
<hgroup class="text-center">
<h1>Payment for Order #{{.OrderID}}</h1>
<p><small>Pay on-chain or through Lightning, amounts in satoshi.</small></p>
</hgroup>
<p class="alert alert-warning">Invoice expired.</p>
</div>
<div></div>
</div>
</section>
{{end}}

185
page/invoice_pending.html Normal file
View File

@ -0,0 +1,185 @@
{{template "base" .}}
{{define "title"}}SeedHammer Checkout{{end}}
{{define "description"}}{{end}}
{{define "content"}}
<section class="container">
<div class="grid center-layout">
<div></div>
<div>
<hgroup class="text-center">
<h1>Payment for Order #{{.OrderID}}</h1>
<p><small>Pay on-chain or through Lightning, amounts in satoshi.</small></p>
</hgroup>
<h2 class="text-center" style="color: #000000;">{{.Order.TotalSats}}</h2>
<div class="text-center">
<span style="display: inline-block; cursor: copy;" id="payment-qrcode"></span>
</div>
<p class="text-center">Invoice expires <span id="expires"></span></p>
<a role="button" href="{{.URL}}" target="_blank" style="display: block">Pay in wallet</a>
<table>
<thead>
<tr>
<th></th>
<th></th>
</tr>
</thead>
<tbody id="copyTable">
<tr>
<td>Address</td>
<td class="text-end copyTarget" data-clipboard-text="{{.OnChain}}">{{.OnChainShort}}
<button class="copyBtn" type="button">
{{template "icn-copy"}}
{{template "icn-check"}}
</button>
</td>
</tr>
<tr>
<td>Lightning</td>
<td class="text-end copyTarget" data-clipboard-text="{{.Lightning}}">{{.LightningShort}}
<button class="copyBtn" type="button">
{{template "icn-copy"}}
{{template "icn-check"}}
</button>
</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th>Details</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>Order ID</td>
<td class="text-end">#{{.OrderID}}</td>
</tr>
<tr>
<td>Total</td>
<td class="text-end">{{.Order.Total}}</td>
</tr>
<tr>
<td>Exchange Rate</td>
<td class="text-end">1 BTC = {{.Order.ExchangeRate}}</td>
</tr>
<tr>
<td>Amount due</td>
<td class="text-end">{{.Order.TotalSats}}</td>
</tr>
</tbody>
</table>
</div>
<div></div>
</div>
</section>
<style>
.copyBtn {
display: unset;
margin: unset;
padding: unset;
background: unset;
border-color: unset;
color: unset;
border: unset;
box-shadow: unset;
width: unset;
padding-left: 10px;
}
.copyBtn:active {
transform: translateY(1px);
}
.copyBtn .icnCheck {display: none;}
.copyBtn.show-check .icnCopy {display: none;}
.copyBtn.show-check .icnCheck {display: inline;}
</style>
<script src="/static/js/qrcode.min.js"></script>
<script type="text/javascript">
function setupQR() {
const container = document.getElementById("payment-qrcode");
const qr = new QRCode(
container,
{
useSVG: true,
correctLevel : QRCode.CorrectLevel.L
}
);
// QR encoding of upper case characters is more compact.
const url = {{.URL}}.toUpperCase();
qr.makeCode(url);
const svgs = container.getElementsByTagName('svg');
for(let i = 0; i < svgs.length; i++) {
// Limit the width of the QR code.
svgs[i].style = 'max-width: 300px';
}
}
function setupUI() {
document.getElementById('copyTable').addEventListener('click', async (e) => {
const btn = e.target.closest('.copyBtn');
if (!btn) return;
const row = btn.closest('tr');
const text = row.querySelector('.copyTarget')?.dataset["clipboardText"].trim();
if (!text) return;
await navigator.clipboard.writeText(text);
btn.classList.add("show-check");
setTimeout(() => btn.classList.remove("show-check"), 2000);
});
document.getElementById('payment-qrcode').addEventListener('click', async (e) => {
await navigator.clipboard.writeText({{.URL}});
});
}
function setExpiry(unixSeconds) {
const expires = new Date(unixSeconds*1000);
let seconds = Math.max(0, expires - new Date())/1000;
const days = Math.floor(seconds/(24*60*60));
seconds = seconds%(24*60*60);
const hours = Math.floor(seconds/(60*60));
seconds = seconds%(60*60);
const minutes = Math.floor(seconds/60);
seconds = Math.floor(seconds%60);
let remaining = "";
if (days > 0) {
remaining = "in " + days + " days, " + hours + " hours.";
} else if (hours > 0) {
remaining = "in " + hours + " hours, " + minutes + " minutes.";
} else if (minutes > 0) {
remaining = "in " + minutes + " minutes.";
} else {
remaining = "in " + seconds + " seconds.";
}
document.getElementById('expires').textContent = remaining;
}
function pollNotification(url) {
const notifyURL = "/shop/invoice_status?invoiceid="+encodeURIComponent({{.InvoiceID}});
setTimeout(function() {
fetch(notifyURL).then((val) => {
if (val.ok) {
val.json().then((res) => {
setExpiry(res.expiry);
if (res.status != "new") {
window.location.reload();
}
});
}
}).finally(() => {
pollNotification();
});
}, 1000);
}
setupUI();
setupQR();
setExpiry({{.Expires}});
pollNotification();
</script>
{{end}}

108
page/invoice_settled.html Normal file
View File

@ -0,0 +1,108 @@
{{template "base" .}}
{{define "title"}}SeedHammer Checkout{{end}}
{{define "description"}}{{end}}
{{define "content"}}
<section class="container">
<div class="grid center-layout">
<div></div>
<div>
<hgroup class="text-center">
<h1>Payment for Order #{{.OrderID}}</h1>
<p><small>Pay on-chain or through Lightning, amounts in satoshi.</small></p>
</hgroup>
<p class="alert alert-success">Payment received!</p>
<h2>Thank you</h2>
<p>Thank you for your order which has <strong>order no. {{.OrderID}}</strong>. The order confirmation will be sent to <strong>{{with .Order.Address}}{{.Email}}{{end}}</strong> shortly.</p>
{{if .Preorder}}
<p>We will email you for delivery information and shipping charges when your order is ready to ship.</p>
{{else}}
<p>You will receive an email with tracking information upon dispatch.</p>
<p>In the case of any questions or comments to your order please contact us at <a href="mailto:support@seedhammer.com">support@seedhammer.com</a> with reference to your order number - we will answer as fast as possible.</p>
{{end}}
<h3>Copy of your order</h3>
<p>Here is a copy of your order. Everything under "Delivery Address" will be deleted 4 month after dispatch or upon request, except country. Read more about our attitude to privacy <a href="/about#privacy" target="_blank">here</a>.</p>
<h4>Delivery Address</h4>
<div class="grid">
{{with .Order.Address}}
{{if not $.Preorder}}
<p>
{{if .Company}}{{.Company}}<br>{{end}}
{{if .VAT}}VAT/Tax ID: {{.VAT}}<br>{{end}}
{{.Name}}<br>
{{.Address}}<br>
{{if .Address2}}{{.Address2}}<br>{{end}}
{{.City}}{{if .Zip}} {{.Zip}}{{end}}<br>
{{.CountryName}}
</p>
{{end}}
{{if .Phone}}<p>Phone: {{.Phone}}<br>{{end}}
Email: {{.Email}}
</p>
{{end}}
</div>
<h4>Order No. {{.OrderID}}</h4>
<table>
<thead>
<tr>
<th class="min hide-mobile">Prod.&nbsp;ID</th>
<th>Product</th>
<th class="text-center min">Quantity</th>
<th class="text-start min">Unit</th>
<th class="text-end min">Price</th>
<th class="text-end min">Total</th>
</tr>
</thead>
<tbody>
{{range .Order.Lines}}
<tr>
<td class="min hide-mobile">{{.ID}}</td>
<td>{{.Product.Name}}</td>
<td class="text-center min">{{.Quantity}}</td>
<td class="text-start min">{{.Product.Unit}}</td>
<td class="text-end min">{{.Price}}</td>
<td class="text-end min">{{.Total}}</td>
</tr>
{{end}}
</tbody>
<tfoot>
<tr>
<td class="hide-mobile"></td>
<td colspan="4" class="text-end">Sub Total</td>
<td colspan="1" class="text-end min">{{.Order.SubTotal}}</td>
</tr>
{{if .Order.Shipping.ID}}
<tr>
<td class="hide-mobile"></td>
<td colspan="4" class="text-end">Shipping <small>({{.Order.Shipping.Name}})</small></td>
<td colspan="1" class="text-end min">{{.Order.Shipping.Price}}</td>
</tr>
{{end}}
{{if .Order.Tax}}
<tr>
<td class="hide-mobile"></td>
<td colspan="4" class="text-end">Tax</td>
<td colspan="1" class="text-end min">{{.Order.Tax}}</td>
</tr>
{{end}}
<tr>
<td class="hide-mobile"></td>
<td colspan="4" class="text-end">Total</td>
<td colspan="1" class="text-end min">{{.Order.Total}}</td>
</tr>
<tr>
<td class="hide-mobile"></td>
<td colspan="4" class="text-end">Total (1BTC = {{.Order.ExchangeRate}})</td>
<td colspan="1" class="text-end min">{{.Order.TotalSats}}</td>
</tr>
</tfoot>
</table>
<p class="text-center">Thank you,</p>
<p class="text-center"><i>The SeedHammer Team</i></p>
</div>
<div></div>
</div>
</section>
{{end}}

41
page/manual.html Normal file
View File

@ -0,0 +1,41 @@
{{template "base" .}}
{{define "title"}}{{.Doc.Title}}{{end}}
{{define "description"}}{{.Doc.Description}}{{end}}
{{define "type"}}article{{end}}
{{define "content"}}
<section class="container">
<div class="grid docs-layout">
<aside>
<nav>
{{range .TOC}}
<details{{if eq .Slug $.ActiveSlug}} open{{end}}>
<summary><a href="{{$.Base}}/{{.Slug}}"><span class="circle">{{.Index}}</span> {{.Name}}</a></summary>
<ul>
{{with $article := .}}
{{range .Sections}}
<li>
<a href="{{$.Base}}/{{$article.Slug}}#{{.ID}}">{{.Name}}</a>
</li>
{{end}}
{{end}}
</ul>
</details>
{{end}}
</nav>
</aside>
<div></div>
{{with .Doc}}
<div class="guide">
<hgroup class="text-center">
<h1>{{.Title}}</h1>
<h2>{{.Description}}</h2>
</hgroup>
{{.Content}}
</div>
{{end}}
<div></div>
</div>
</section>
{{end}}

6
page/page.go Normal file
View File

@ -0,0 +1,6 @@
package page
import "embed"
//go:embed *.html
var FS embed.FS

117
page/sh2.html Normal file
View File

@ -0,0 +1,117 @@
{{template "base" .}}
{{define "title"}}Multisig Steel Backup. Self Custody for Individuals and Businesses{{end}}
{{define "description"}}Easily backup bitcoin multisig and singlesig wallets automatically onto stainless steel. Professional self custody solution for private and businesses.{{end}}
{{define "theme"}}green{{end}}
{{define "image"}}seedhammerii.webp{{end}}
{{define "content"}}
<section id="hero">
<video playsinline="" muted="muted" loop="loop" autoplay="autoplay" poster="/static/img/seedhammerii.webp">
</video>
<div class="shade"></div>
<div class="container">
<div class="grid">
<div>
<h1 class="mb-2">Introducing SeedHammer II</h1>
<p>Smaller, lighter and more secure than the original.<br>Integrated controller.</p>
</div>
<div></div>
</div>
<div class="grid">
<div>
<a href="/shop" role="button" class="inverse">Order now</a>
</div>
</div>
<div class="grid">
<div class="center-content explore-more">
<a href="#section-backup-from-any-wallet">
<div class="down-arrow primary-inverse"></div>
</a>
</div>
</div>
</div>
</section>
<section>
<div class="container">
<hgroup>
<h2 class="text-center" id="self-contained-multisig-setup">Self-contained Multisig Backups</h2>
<h3 class="text-center">SeedHammer eliminates the need for storing a descriptor.</h3>
</hgroup>
<p class="text-center">Without the public keys for <strong>all</strong> the seeds in a multisig wallet, you can't recover the wallet.<br>Other backup solutions require a separate digital or printed copy of the wallet.</p>
<div class="grid mt-6">
<div class="img-center">
<img style="width: 75%;" src="/static/img/3-of-5-multisig.webp" alt="By design M-of-N cosigners is enough to recover a multisig wallet backed up with SeedHammer">
</div>
<div>
<h3 class="text-center">Recover With Minimum of Shares</h3>
<p>The minimum amount of shares is enough to recover a multisig wallet backed up with SeedHammer.</p>
<ul class="ms-4">
<li>Withstand damage or loss of all shares beyond the quorum.</li>
<li>Any combination of M-of-N plates contain enough data for a full recovery.</li>
<li>Fast and convenient recovery with QR codes.</li>
</ul>
</div>
</div>
<div class="grid mt-7">
<div>
<h3 class="text-center">No Need to Backup Wallet Descriptor</h3>
<p>The descriptor is split into parts which are distributed among the plates in a way so any quorum can recover the wallet.</p>
<ul class="ms-4">
<li>Perform complete recovery with the minimum number of plates.</li>
<li>No need to separately store the descriptor online, offline or alongside each physical plate.</li>
<li>Complies with multisig standards, no special tools needed for recovery.</li>
</ul>
</div>
<div>
<div class="img-center">
<img src="/static/img/no-descriptor-needed.webp" alt="SeedHammer eliminates the need for storing a separate wallet output descriptor in multisignature backups">
<small>One side contains the seed,<br>the other side contains a part of the descriptor.</small>
</div>
</div>
</div>
</div>
</section>
<section>
<div class="container">
<div class="grid">
<div>
<div class="img-center mb-6">
<img src="/static/img/seedhammer-front-and-controller.webp" width="85%" alt="The SeedHammer Machine incl. Raspberry Pi (SeedSigner) running the controller software">
</div>
</div>
<div>
<h2 class="text-center">Built for The Security Conscious</h2>
<p>The controller software is <a href="https://github.com/seedhammer/seedhammer/blob/main/LICENSE" target="_blank">open source</a> and runs on the same air gapped <a href="/article/the-seedhammer-controller">hardware as SeedSigner</a>.</p>
<p>The electric hammer is a modified off-the-shelf machine. It is stateless and contains no radio capabilities (wifi, bluetooth, etc.).</p>
<p>The singlesig and multisig backups are easily verifiable.</p>
<p>Read more in our article on <a href="/article/attack-vectors">attack vectors</a>.</p>
</div>
</div>
</div>
</section>
<section>
<div class="container">
<hgroup>
<h2 class="text-center">See More On <a href="https://twitter.com/SeedHammer">Twitter</a></h2>
<h3 class="text-center"><a href="https://twitter.com/SeedHammer">twitter.com/SeedHammer</a></h3>
</hgroup>
<div class="grid">
<div>
<blockquote class="twitter-tweet" data-conversation="none" data-dnt="true"><p lang="en" dir="ltr">Some do! <a href="https://t.co/xj7tDjivzh">pic.twitter.com/xj7tDjivzh</a></p>&mdash; Erik (@brikk_) <a href="https://twitter.com/brikk_/status/1675534057109610500?ref_src=twsrc%5Etfw">July 2, 2023</a></blockquote>
</div>
<div>
<blockquote class="twitter-tweet" data-dnt="true"><p lang="en" dir="ltr">Sovereignty or nah? <a href="https://twitter.com/SeedSigner?ref_src=twsrc%5Etfw">@SeedSigner</a> <a href="https://twitter.com/start9labs?ref_src=twsrc%5Etfw">@start9labs</a> <a href="https://twitter.com/SeedHammer?ref_src=twsrc%5Etfw">@SeedHammer</a> <a href="https://t.co/2Mxw9sa5pC">pic.twitter.com/2Mxw9sa5pC</a></p>&mdash; ericjaffe (@ericjaffe) <a href="https://twitter.com/ericjaffe/status/1675255817879126016?ref_src=twsrc%5Etfw">July 1, 2023</a></blockquote>
</div>
<div>
<blockquote class="twitter-tweet" data-dnt="true"><p lang="en" dir="ltr"><a href="https://twitter.com/SeedHammer?ref_src=twsrc%5Etfw">@SeedHammer</a> <a href="https://twitter.com/SeedSigner?ref_src=twsrc%5Etfw">@SeedSigner</a> guess what arrived today? Now need to fond time to set it up and knock a few tests out. <a href="https://t.co/XiCivvXUyB">pic.twitter.com/XiCivvXUyB</a></p>&mdash; MoparMiningLLC (@MoparMining) <a href="https://twitter.com/MoparMining/status/1653122935807156237?ref_src=twsrc%5Etfw">May 1, 2023</a></blockquote>
</div>
<div>
<blockquote class="twitter-tweet" data-dnt="true"><p lang="en" dir="ltr">On stage demonstrating <a href="https://twitter.com/SeedHammer?ref_src=twsrc%5Etfw">@SeedHammer</a> <a href="https://twitter.com/seedor_io?ref_src=twsrc%5Etfw">@seedor_io</a> and <a href="https://twitter.com/SeedSigner?ref_src=twsrc%5Etfw">@SeedSigner</a> at <a href="https://twitter.com/BitcoinAlive?ref_src=twsrc%5Etfw">@BitcoinAlive</a> <a href="https://t.co/L08xJjHs4H">pic.twitter.com/L08xJjHs4H</a></p>&mdash; mineracks (@mineracks) <a href="https://twitter.com/mineracks/status/1647092860091777024?ref_src=twsrc%5Etfw">April 15, 2023</a></blockquote>
</div>
</div>
</div>
</section>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<script>document.addEventListener("DOMContentLoaded", function (){ var facades=document.querySelectorAll(".video-facade"); facades.forEach(function (facade){ facade.addEventListener("mouseover", function (){ var videoId=facade.getAttribute("data-video-id"); var iframe=document.createElement("iframe"); iframe.setAttribute("src", "https://www.youtube.com/embed/" + videoId + "?autoplay=1"); iframe.setAttribute("title", "SeedHammer intro video"); iframe.setAttribute("frameborder", "0"); iframe.setAttribute("allow", "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"); iframe.setAttribute("allowfullscreen", "1"); var videoIframeContainer=facade.nextElementSibling; videoIframeContainer.appendChild(iframe); videoIframeContainer.style.display="block"; facade.style.display="none"})})}); </script>
{{end}}

112
page/summary.html Normal file
View File

@ -0,0 +1,112 @@
{{template "base" .}}
{{define "title"}}SeedHammer Checkout{{end}}
{{define "description"}}{{end}}
{{define "content"}}
<section class="container">
<div class="grid center-layout">
<div></div>
<div>
<hgroup class="text-center">
<h1>{{if .Preorder}}Preorder{{else}}Order{{end}} Summary</h1>
<p><small>Verify your {{if .Preorder}}pre{{end}}order details before payment.</small></p>
</hgroup>
<h2>Delivery Information</h2>
<div class="grid">
{{with .Order.Address}}
{{if not $.Preorder}}
<p>
{{if .Company}}{{.Company}}<br>{{end}}
{{if .VAT}}VAT/Tax ID: {{.VAT}}<br>{{end}}
{{.Name}}<br>
{{.Address}}<br>
{{if .Address2}}{{.Address2}}<br>{{end}}
{{.City}}{{if .Zip}} {{.Zip}}{{end}}<br>
{{.CountryName}}
</p>
{{end}}
<p>
{{if .Phone}}Phone: {{.Phone}}<br>{{end}}
Email: {{.Email}}
</p>
{{end}}
</div>
<h2>Products</h2>
<table>
<thead>
<tr>
<th class="min hide-mobile">Prod.&nbsp;ID</th>
<th>Product</th>
<th class="text-center min">Quantity</th>
<th class="text-start min">Unit</th>
<th class="text-end min">Price</th>
<th class="text-end min">Total</th>
</tr>
</thead>
{{with .Order}}
<tbody>
{{range .Lines}}
<tr>
<td class="min hide-mobile">{{.ID}}</td>
<td>{{.Product.Name}}</td>
<td class="text-center min">{{.Quantity}}</td>
<td class="text-start min">{{.Product.Unit}}</td>
<td class="text-end min">{{if ne .Price .Product.Price}}<small><del>{{.Product.Price}}</del></small><br>{{end}}{{.Price}}</td>
<td class="text-end min">{{.Total}}</td>
</tr>
{{end}}
</tbody>
<tfoot>
{{if $.Shippings}}
<tr>
<td class="hide-mobile"></td>
<td colspan="4" class="text-end">Sub Total</td>
<td colspan="1" class="text-end min">{{.SubTotal}}</td>
</tr>
<tr>
<td class="hide-mobile"></td>
<td colspan="4">
<form method="POST" style="margin: 0;">
<input type="hidden" name="action" value="update_shipping">
<select name="shipping" onchange="this.form.submit()">
{{range $.Shippings}}
<option value="{{.ID}}"{{if eq .ID $.Order.Shipping.ID}} selected="true"{{end}}>{{.Name}} {{.Price}}</option>
{{end}}
</select>
</form>
</td>
<td colspan="1" class="text-end min">{{.Shipping.Price}}</td>
</tr>
{{end}}
{{if .Coupons}}
<tr>
<td class="hide-mobile"></td>
<td colspan="4" class="text-end">Discount {{index .Coupons 0}}</td>
<td colspan="1" class="text-end min">{{.CouponAmount}}</td>
</tr>
{{end}}
{{if .Tax}}
<tr>
<td class="hide-mobile"></td>
<td colspan="4" class="text-end">Tax</td>
<td colspan="1" class="text-end min">{{.Tax}}</td>
</tr>
{{end}}
<tr>
<td class="hide-mobile"></td>
<td colspan="4" class="text-end">Total</td>
<td colspan="1" class="text-end min">{{.Total}}</td>
</tr>
</tfoot>
{{end}}
</table>
<form method="POST">
<input type="hidden" name="action" value="pay">
<button type="submit">Pay with {{template "icn-bitcoin"}} bitcoin</a>
</form>
</div>
<div></div>
</div>
</section>
{{end}}

View File

@ -0,0 +1,63 @@
{{template "base" .}}
{{define "title"}}About SeedHammer{{end}}
{{define "description"}}Read about SeedHammer and our Ethos{{end}}
{{define "content"}}
<section class="container">
<div class="grid docs-layout">
<aside>
<nav>
<details open>
<summary>Terms & Conditions</summary>
<ul>
<li>
<a href="#shipping-time">Shipping Time</a>
</li>
<li>
<a href="#duty-taxes-and-customs">Duty, Taxes, and Customs</a>
</li>
<li>
<a href="#amounts-and-currencies">Amounts and Currencies</a>
</li>
<li>
<a href="#payment-options">Payment Options</a>
</li>
<li>
<a href="#refund">Refund Policy</a>
</li>
<li>
<a href="#privacy">Attitude to Privacy</a>
</li>
<li>
<a href="#contact">Contact Information</a>
</li>
</ul>
</details>
</nav>
</aside>
<div></div>
<div>
<h1 class="text-center">Terms and Conditions</h1>
<h2 id="shipping-time">Shipping Time</h2>
<p>Orders will be shipped from Switzerland and the estimated delivery time is approximately 2-3 weeks. However, please note that delivery times may vary depending on the destination country, shipping method, and customs clearance procedures.</p>
<h2 id="duty-taxes-and-customs">Duty, Taxes, and Customs</h2>
<p>The customer is responsible for paying all expenses related to duty, taxes, and customs. These charges vary by country and may be applied to your order upon delivery. Please note that we have no control over these fees, and we advise customers to contact their local customs office for further information.</p>
<h2 id="amounts-and-currencies">Amounts and Currencies</h2>
<p>All amounts shown on Seedhammer.com are in US Dollars (USD). Please note that the actual amount charged to your account may vary based on the current USD/BTC exchange rate on the time of the transaction.</p>
<h2 id="payment-options">Payment Options</h2>
<p>We only accept payments in bitcoin. We do not accept any other form of payment. Customers can make payments via their bitcoin wallets, and we will provide a unique wallet address for each transaction in the last step of our checkout.</p>
<h2 id="refund">Refund Policy</h2>
<p>We want our customers to be satisfied with their purchase. Therefore, we offer a full refund within 30 days from the time of arrival (based on delivery scan on tracking code). To initiate a refund, please contact us at support@seedhammer.com with your order number and reason for the return we will then return with further details.</p>
<p>Please note that the refund amount will be paid out in bitcoin, and the exchange rate used will be based on the USD/BTC exchange rate on the day of the refund.</p>
<h2 id="privacy">Attitude to Privacy</h2>
Please see our about-section <a href="/about/attitude-to-privacy">Attitude to Privacy</a>
<h2 id="contact">Contact Information</h2>
<p>If you have any questions or concerns regarding our TAC, shipping, payment, or refund policy, do not hesitate contact us at support@seedhammer.com. We will respond to your inquiries as soon as possible. Please be patient - we are a small team.</p>
<p>Thank you for reading all the way through our TAC - and if you end up becoming a customer thank you for supporting us!</p>
</div>
<div></div>
</div>
</section>
{{end}}

222
routes.go Normal file
View File

@ -0,0 +1,222 @@
package content
import (
"embed"
"errors"
"fmt"
"html/template"
"io"
"io/fs"
"log"
"net/http"
"net/url"
"path/filepath"
"strings"
"github.com/btcsuite/btcd/btcutil/bech32"
"github.com/gorilla/feeds"
"github.com/lpar/gzipped/v2"
"seedhammer.com/website/content/about"
"seedhammer.com/website/content/doc/manual"
"seedhammer.com/website/content/getstarted"
"seedhammer.com/website/content/page"
)
//go:embed static
var staticFiles embed.FS
var Templates map[string]*template.Template
type LoggingFunc func(http.ResponseWriter, *http.Request) error
var ErrNotFound = errors.New("resource not found")
var nostrID []byte
const (
domain = "seedhammer.com"
nostrNPUB = "npub1z072s0nvldeva7a6qek3kj358f0h5gm640kkllkk52h0qrjtnw8q38wfm4"
)
func init() {
_, decoded, err := bech32.Decode(nostrNPUB)
if err != nil {
panic(err)
}
dec2, err := bech32.ConvertBits(decoded, 5, 8, false)
if err != nil {
panic(err)
}
nostrID = dec2
}
func init() {
p, err := LoadTemplates(page.FS)
if err != nil {
panic(err)
}
Templates = p
}
func Register(mux *http.ServeMux) {
mux.Handle("GET /static/", CachingHandler(gzipped.FileServer(gzipped.FS(staticFiles))))
mux.Handle("GET /favicon.ico", http.NotFoundHandler())
mux.Handle("GET /article/", CachingHandler(LoggingFunc(renderArticles)))
mux.Handle("GET /article/rss", CachingHandler(LoggingFunc(renderRssArticles)))
mux.Handle("GET /tip", http.RedirectHandler("/get-started/engrave-plate", http.StatusFound))
mux.Handle("GET /get-started/", docsHandler("get-started", getstarted.FS, getstartedTOC))
mux.Handle("GET /doc/manual/", docsHandler("doc/manual", manual.FS, manualTOC))
mux.Handle("GET /doc/", http.RedirectHandler("/doc/manual/", http.StatusFound))
mux.Handle("GET /about/", docsHandler("about", about.FS, aboutTOC))
mux.Handle("GET /website/content", goImportHandler(http.NotFoundHandler()))
mux.Handle("GET /.well-known/nostr.json", http.HandlerFunc(nip05Handler))
mux.Handle("GET /{page}", goImportHandler(pageHandler()))
mux.Handle("GET /{$}", goImportHandler(pageHandler()))
}
func goImportHandler(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Query().Get("go-get") != "1" {
h.ServeHTTP(w, r)
return
}
module := r.URL.Path
var repo string
switch r.URL.Path {
case "/":
repo = "https://github.com/seedhammer/seedhammer"
case "/website/content":
repo = "https://github.com/seedhammer/website-content"
default:
http.NotFound(w, r)
return
}
root := "seedhammer.com" + module
fmt.Fprintf(w, `<html><head>
<meta name="go-import" content="%[1]s git %[2]s">
<meta name="go-source" content="%[1]s _ %[2]s/tree/main{/dir} %[2]s/tree/main{/dir}/{file}#L{line}">
</head></html>`, root, repo)
})
}
func RenderPageTemplate(w io.Writer, r *http.Request, tmpl *template.Template, args any) error {
if tmpl == nil {
return ErrNotFound
}
u := r.URL
u.Host = domain
u.Scheme = "https"
pargs := struct {
PageURL *url.URL
Nav []Nav
NavURL string
Content any
}{
PageURL: u,
Nav: topNav,
Content: args,
}
for _, nav := range pargs.Nav {
if strings.HasPrefix(r.URL.Path, nav.URL) {
pargs.NavURL = nav.URL
break
}
}
return tmpl.Lookup("base").Execute(w, pargs)
}
func (f LoggingFunc) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if err := f(w, r); err != nil {
if errors.Is(err, ErrNotFound) {
http.Error(w, "not found", http.StatusNotFound)
return
}
log.Printf("ERROR: %v: %v", r.URL, err)
http.Error(w, "invalid request", http.StatusBadRequest)
return
}
}
func nip05Handler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Access-Control-Allow-Origin", "*")
fmt.Fprintf(w, `{
"names": {
"_": "%x"
}
}`, nostrID)
}
func renderRssArticles(w http.ResponseWriter, r *http.Request) error {
w.Header().Add("Content-Type", "application/rss+xml")
feed := &feeds.Feed{
Title: "Articles from SeedHammer",
Description: "Latest news, updates and insights from SeedHammer Cold Storage.",
Author: &feeds.Author{Name: "", Email: ""},
Link: &feeds.Link{Href: "https://" + domain},
}
arts := allArticles.byDate
const limit = 100
if len(arts) > limit {
arts = arts[:limit]
}
for _, a := range arts {
feed.Items = append(feed.Items, &feeds.Item{
Title: a.Title,
Link: &feeds.Link{Href: fmt.Sprintf("https://%s/article/%s", domain, a.Slug)},
Author: &feeds.Author{Name: a.Author, Email: a.AuthorLink},
Description: a.Description,
Created: a.Published,
})
}
return feed.WriteRss(w)
}
func LoadTemplates(dir fs.FS) (map[string]*template.Template, error) {
pages := make(map[string]*template.Template)
err := fs.WalkDir(dir, ".", func(path string, d fs.DirEntry, err error) error {
ext := filepath.Ext(path)
if ext != ".html" {
return err
}
base := filepath.Base(path)
if base == "base.html" {
return err
}
tmpl, err := template.ParseFS(dir, "icons.html", "base.html", path)
if err != nil {
return err
}
name := strings.TrimSuffix(base, ext)
pages[name] = tmpl
return err
})
return pages, err
}
func pageHandler() http.Handler {
return CachingHandler(LoggingFunc(func(w http.ResponseWriter, r *http.Request) error {
tname := r.PathValue("page")
if tname == "" {
tname = "sh2"
}
tmpl, ok := Templates[tname]
if !ok {
return ErrNotFound
}
if err := RenderPageTemplate(w, r, tmpl, nil); err != nil {
return fmt.Errorf("page: template failed: %v", err)
}
return nil
}))
}
func CachingHandler(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Cache-Control", "public, max-age=3600")
h.ServeHTTP(w, r)
})
}

198
static/css/admin.css Normal file
View File

@ -0,0 +1,198 @@
[data-theme=light],
:root:not([data-theme=dark]) {
--muted-border-color: rgba(2,66,125,0.1);
}
.uppercase {
text-transform: uppercase;
}
.important {
color:red;
font-weight: bold;
text-transform: uppercase;
}
.nav-item {
list-style: none;
margin-bottom: 0;
}
.btn-sm {
padding: 0 0.25rem;
font-size: 0.875rem;
border-radius: 0.2rem;
}
.btn-danger {
border-color: #dc3545;
background-color: #dc3545;
}
.nav {
display: flex;
flex-wrap: wrap;
padding-left: 0;
margin-bottom: 0;
list-style: none;
}
.nav-tabs {
border-bottom: 1px solid #dee2e6;
}
.nav-item {
list-style: none;
margin-bottom: 0;
}
.nav-item input[type="radio"] {
display: none;
}
.nav-link {
display: block;
padding: 0.5rem 1rem;
text-decoration: none;
transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out;
}
.nav-tabs .nav-link.active, .nav-tabs .nav-item.show .nav-link {
color: #495057;
background-color: #fff;
border-color: #dee2e6 #dee2e6 #fff;
}
.nav-tabs .nav-link {
margin-bottom: -1px;
background: none;
border: 1px solid transparent;
border-top-left-radius: 0.25rem;
border-top-right-radius: 0.25rem;
}
#prev-order, #next-order {
position: absolute;
right: 30px;
}
#prev-order {
left: 30px;
right: inherit;
}
table [data-tooltip]:not(a,button,input) {
border-bottom: var(--border-width) solid var(--table-border-color);
}
table form {
margin-bottom: 0;
}
[data-tooltip]::before {
max-width: 550px;
white-space: pre;
}
.address td {
text-transform: uppercase;
color: grey;
font-size: 0.8rem;
}
.chkbox {
width: 20px;
height: 20px;
Border: 1px solid black;
display: inline-block;
}
#print-button {
width: 100%;
}
#instructions {
border: 1px solid var(--color);
padding: 1rem 2rem 0rem;
}
.albino-table, .address {
margin-bottom: 0;
}
.albino-table td {
border-bottom: none;
vertical-align: top;
}
td img {
width: 20%;
}
.badge {
display: inline-block;
padding: 0.65em 0.35rem;
font-size: 0.75em;
line-height: 1;
color: #fff;
text-align: center;
white-space: nowrap;
vertical-align: baseline;
border-radius: 1rem;
font-weight: bold;
}
.text-bg-new {
background-color: #6c757d;
}
.text-bg-invoiced {
background-color: #ffc107;
}
.text-bg-settled {
background-color: #0d6efd;
}
.text-bg-done {
background-color: #198754;
}
.text-bg-cancelled {
background-color: #DC3545;
}
section {
padding-top: 15px;
}
input[name="change"] {
width: 4rem;
padding: 0.25rem;
height: 2rem;
text-align: center;
}
.input-sm {
padding: 0 !important;
margin: 0 !important;
vertical-align: middle;
height: 2em !important;
line-height: 1em;
}
.address-fields input,
section.order input[name="shipping"] {
border: 1px solid transparent;
}
.address-fields input:hover,
section.order input[name="shipping"]:hover {
border: var(--border-width) solid var(--border-color);
}
.address-fields .grid p:first-child {
font-weight: bold;
}
section.order input[name="trackingid"] {
text-overflow: ellipsis;
}
[data-theme=light] section:nth-child(2n) {
background-color: transparent;
}
#invoiceForm {
display: none;
margin-bottom: 0;
min-width: 50%;
}
#invoiceForm.show {
display: grid;
}
.hide-on-screen {
display: none;
}
@media print {
.hide-on-print {
display: none;
}
.hide-on-screen {
display: block;
}
[data-theme=light],
:root:not([data-theme=dark]) {
--color: black;
--h1-color: black;
--h2-color: black;
--h3-color: black;
}
section {
padding-top: 0;
padding-bottom: 0;
}
}

799
static/css/override.css Normal file
View File

@ -0,0 +1,799 @@
@font-face {
font-family: "Poppins";
src: local("Poppins-Light"), local("Poppins Light"), url("../fonts/Poppins-Light.ttf") format('truetype');
font-weight: 300;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: "Poppins";
src: local("Poppins-SemiBold"), local("Poppins SemiBold"), url("../fonts/Poppins-SemiBold.ttf") format('truetype');
font-weight: bold;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: "Ubuntu";
src: local("Ubuntu-Bold"), local("Ubuntu Bold"), url("../fonts/Ubuntu-Bold.ttf") format('truetype');
font-weight: bold;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: "Ubuntu";
src: local("Ubuntu-Regular"), local("Ubuntu Regular"), url("../fonts/Ubuntu-Regular.ttf") format('truetype');
font-weight: 300;
font-style: normal;
font-display: swap;
}
:root {
--font-family: "Poppins", serif;
--font-family-secondary: "Ubuntu", serif;
--font-weight: 300;
--font-size: 13px;
scroll-behavior: smooth;
scroll-padding-top: 63px;
--nav-sub-element-spacing-vertical: 0.5rem;
}
[data-theme=light],
:root:not([data-theme=dark]) {
--background-color: white;
--muted-border-color: transparent;
--color: rgb(2,66,125);
--color-inverse: rgb(0,0,0);
--primary: var(--color);
--primary-hover: rgba(2,66,125,0.5);
--primary-focus: rgba(2,66,125,0.25);
--primary-inverse: #FFF;
--secondary: rgba(2,66,125);
--secondary-hover: rgba(2,66,125,0.9);
--secondary-focus: rgba(2,66,125,0.25);
--secondary-inverse: #fff;
--h1-color: var(--color);
--h2-color: var(--color);
--h3-color: var(--color);
--h4-color: var(--color);
--h5-color: var(--color);
--h6-color: var(--color);
--card-background-color: white;
--card-sectionning-background-color: rgba(0,133,255,0.05);
--mobile-menu-background: rgba(255,255,255,0.3);
}
[data-theme=light] section:nth-child(2n) {
background-color: var(--card-sectionning-background-color);
}
[data-theme=light] .circle {
color: white;
}
[data-theme=green],
:root:not([data-theme=dark],[data-theme=light]) {
--background-color: rgb(38 127 38);
--color: rgba(255,255,255,0.9);
--muted-color: rgba(255,255,255,0.75);
--primary-hover: rgb(255,255,255);
--primary-focus: rgba(255,255,255,0.2);
--primary-inverse: var(--background-color);
--card-sectionning-background-color: rgb(34 115 35);
--mobile-menu-background: rgba(0,0,0,0.1);
--card-background-color: var(--background-color);
--form-element-background-color: var(--background-color);
--form-element-border-color: var(--color);
--icon-close: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='18' y1='6' x2='6' y2='18'%3E%3C/line%3E%3Cline x1='6' y1='6' x2='18' y2='18'%3E%3C/line%3E%3C/svg%3E");
--icon-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
}
[data-theme=green] section:nth-child(2n) {
background-color: var(--card-sectionning-background-color);
}
[data-theme=green] .circle {
color: rgb(38 127 38);
}
[data-theme=green] .alert-warning {
border: 3px solid var(--color);
border-radius: 0.25rem;
color: var(--background-color);
background-color: var(--color);
}
[data-theme=orange],
:root:not([data-theme=dark],[data-theme=light],[data-theme=green]) {
--background-color: rgb(221 151 0);
--color: rgba(255,255,255,0.9);
--muted-color: var(--color);
--primary-hover: rgb(255,255,255);
--primary-focus: rgba(255,255,255,0.1);
--primary-inverse: var(--background-color);
--card-sectionning-background-color: rgb(214 142 0);
--mobile-menu-background: rgba(0,0,0,0.1);
--card-background-color: var(--background-color);
--form-element-background-color: var(--background-color);
--form-element-border-color: var(--color);
--icon-close: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='18' y1='6' x2='6' y2='18'%3E%3C/line%3E%3Cline x1='6' y1='6' x2='18' y2='18'%3E%3C/line%3E%3C/svg%3E");
--icon-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
}
[data-theme=orange] section:nth-child(2n) {
background-color: var(--card-sectionning-background-color);
}
[data-theme=orange] .circle {
color: rgb(221 151 0);
}
body > header, body > footer {
padding: 0;
}
.center-list,
footer p {
text-align: center;
}
.center-list ul {
display: inline-block;
text-align: left;
}
section {
margin: 0;
padding-top: var(--block-spacing-vertical);
padding-bottom: var(--block-spacing-vertical);
}
section.orange {
background-color: rgb(221 151 0);
}
section.blue {
background-color: #51b0f6;
}
section#hero {
background-size: cover;
background-position: 50% 50%;
margin-top: -63px;
min-height: 100vh;
position: relative;
margin-top: calc(-1 * var(--block-spacing-vertical));
display: flex;
flex-direction: column;
justify-content: flex-end;
}
section#hero video {
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
object-fit: cover;
object-position: center center;
}
section#hero .container {
position: relative;
}
.shade {
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.6);
}
.coldcardPromo {
position: absolute;
right: 40px;
bottom: 0;
max-width: 300px;
width: 22vw;
height: auto;
}
[data-theme=light] section#hero {
background-image: url(/static/img/seedhammer-hero-light.webp);
}
[data-theme=dark] section#hero {
background-image: url(/static/img/seedhammer-hero-dark.webp);
}
[data-theme=green] section#hero {
background-image: url(/static/img/seedhammer-hero-green.webp);
background-color: grey;
background-blend-mode: multiply;
}
nav li.active a {
background-color: var(--primary);
color: var(--primary-inverse);
}
nav ul ul {
display: none;
margin-top: var(--nav-element-spacing-vertical);
}
nav ul li:hover > ul {
display: inherit;
}
nav ul ul li {
display: list-item;
list-style: none;
padding: var(--nav-sub-element-spacing-vertical) var(--nav-element-spacing-horizontal);
}
#logo-container {
line-height: 22px;
}
.nav-link {
color: var(--primary);
}
aside details summary {
color: var(--h1-color);
text-transform: uppercase;
}
aside ul {
margin-left: inherit !important;
}
nav[aria-label=breadcrumb] ul {
font-size: 0.8rem;
}
h1,h2,h3,h4,h5,h6,details summary,
button, input[type=submit], input[type=button], input[type=reset], a[role=button] {
font-family: var(--font-family-secondary);
}
:is(button, input[type="submit"], input[type="button"], [role="button"]).inverse {
--color: var(--color-inverse);
}
h2 {
--font-size: 1.5rem;
--typography-spacing-vertical: 2rem;
}
h3 {
--font-size: 1.25rem;
--typography-spacing-vertical: 1rem;
}
p a, table a,
.guide a,
.article a,
.product-description a {
text-decoration: underline;
}
b,
strong {
font-weight: bold;
}
.text-start {
text-align: left !important;
}
.text-center {
text-align: center;
}
.text-end {
text-align: right !important;
}
.text-uppercase {
text-transform: uppercase !important;
}
.mt-4 {
margin-top: 1.5rem !important;
}
.mt-5 {
margin-top: 2rem !important;
}
.mt-6 {
margin-top: 3rem !important;
}
.mt-7 {
margin-top: 4rem !important;
}
.mb-0 {
margin-bottom: 0 !important;
}
.mb-2 {
margin-bottom: 0.5rem !important;
}
.mb-6 {
margin-bottom: 2rem !important;
}
.ms-4 {
margin-left: 1.5rem !important;
}
.pull-left {
float: left;
}
.pull-right {
float: right;
}
ul li {
list-style: disc;
}
header {
position: fixed;
top: 0;
z-index: 500;
background-color: var(--muted-border-color);
}
/* iOS compatibility */
header::before {
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
background-color: var(--mobile-menu-background);
content: "";
height: 49px;
position: absolute;
width: 100%;
z-index: -500;
}
.alert {
position: relative;
padding: 0.55rem 0.75rem;
margin-bottom: var(--spacing);
border: 3px solid;
border-radius: 0.25rem;
color: var(--color);
background-color: #fff3cd;
}
.alert-warning {
color: var(--color);
border-color: #ffecb5;
background-color: #fff3cd;
}
.alert-danger {
color: #842029;
border-color: #f5c2c7;
background-color: #f8d7da;
}
.alert-success {
color: #0f5132;
border-color: #badbcc;
background-color: #d1e7dd;
}
details {
border-bottom-color: var(--primary-focus);
padding-bottom: var(--spacing);
}
details[open] > summary {
margin-bottom: var(--typography-spacing-vertical);
font-weight: bold;
}
.btn-flow {
width: 0px;
display: inline-grid;
overflow: hidden;
transition: width var(--transition);
}
*:hover>.btn-flow {
width: 20px;
}
.circle {
background-color: var(--color);
border-radius: 9px;
font-weight: bold;
text-decoration: none;
font-size: 0.8em;
cursor: pointer;
width: 14px;
height: 14px;
display: inline-block;
text-align: center;
line-height: 1.15rem;
}
.img-center {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
margin-bottom: var(--typography-spacing-vertical);
text-align: center;
}
.guide img, .article img {
width: 100%;
}
.guide li img, .article li img {
margin-top: var(--spacing);
margin-bottom: var(--spacing);
}
[type=checkbox][role=switch] + .grid {
display: none;
}
.video-container {
display: flex;
align-items: center;
height: 100%;
position: relative;
}
.video-facade {
cursor: pointer;
}
.video-facade img {
width: 100%;
height: auto;
}
.video-iframe {
width: 100%;
display: none;
}
.video-iframe iframe {
display: block;
margin: 0 auto;
width: 100%;
height: 315px;
}
[type=checkbox][role=switch]:checked + .grid {
display: grid;
}
@-webkit-keyframes pulse {
0% {
-webkit-transform: scaleX(1);
transform: scaleX(1);
}
50% {
-webkit-transform: scale3d(1.05, 1.05, 1.05);
transform: scale3d(1.05, 1.05, 1.05);
}
to {
-webkit-transform: scaleX(1);
transform: scaleX(1);
}
}
@keyframes pulse {
0% {
color: inherit;
}
50% {
color: transparent
}
to {
color: inherit;
}
}
:target {
-webkit-animation-name: pulse;
animation-name: pulse;
-webkit-animation-timing-function: ease-in-out;
animation-timing-function: ease-in-out;
animation-duration: 1s;
animation-delay: 0.75s;
}
.svg {
margin-bottom: 2px;
vertical-align: middle;
width: 1em;
}
.btc-logo {
margin-bottom: 3px;
}
.usps > div {
display: flex;
flex-direction: column;
justify-content: space-between;
}
.usps small {
font-size: 0.75rem;
}
.grid.usps {
grid-template-columns: 0 1fr 0 1fr 0 1fr 0 1fr 0 1fr 0;
}
.grid.articles {
grid-template-columns: 1fr;
}
dialog article .close {
margin-bottom: 0;
}
input.cart-amount {
width: 60px;
}
thead th,
thead td,
tfoot td {
font-weight: bold;
}
td, th {
padding: calc(var(--spacing)/ 2) calc(var(--spacing)/ 4);
}
td {
width: auto;
}
td.min {
width: 1%;
white-space: nowrap;
}
.product-row.product-header {
grid-template-areas:
"main main main main main main amount amount amount price price";
font-weight: bold;
font-size: 1em;
margin-bottom: 1rem;
}
.product-row {
margin-bottom: 3rem;
font-size: 0.875em;
grid-column-gap: 0;
grid-gap: var(--spacing);
align-items: center;
grid-template-areas:
"main main main main main main main main main main main"
"description description description description description amount amount amount amount price price"
"footer footer footer footer footer footer footer footer footer footer footer";
grid-template-columns: repeat(auto-fit,minmax(0%,1fr));
}
.product-row ul {
font-size: 0.875em;
margin-bottom: 0;
}
.product-row h2 {
font-size: 1.5em;
margin: 0;
}
.product-main {
grid-area: main;
}
.product-pic {
grid-area: pic;
}
.product-description {
grid-area: description;
}
.product-amount {
grid-area: amount;
justify-self: center;
}
.product-price {
grid-area: price;
justify-self: end;
}
.product-footer {
grid-area: footer;
}
.product-image, .product-pic {
display: none;
}
.date {
text-transform: uppercase;
color: grey;
}
.btc {
content: url(../img/btc.svg);
}
#hamburger {
display: none;
background-color: transparent;
}
#hamburger:checked + ul {
display: grid;
}
select[name="shipping"] {
margin: 0;
font-size: 0.875rem;
float: right;
}
.embed-responsive {
position: relative;
display: block;
height: 0;
padding: 0;
overflow: hidden;
}
.embed-responsive .embed-responsive-item, .embed-responsive embed, .embed-responsive iframe, .embed-responsive object, .embed-responsive video {
position: absolute;
top: 0;
bottom: 0;
left: 0;
width: 100%;
height: 100%;
border: 0;
}
.embed-responsive-16by9 {
padding-bottom: 56.3%;
margin-bottom: var(--typography-spacing-vertical);
}
@media (min-width: 576px) {
:root {
--font-size: 13px;
}
.product-image, .product-pic {
display: block;
}
.product-row.product-header {
grid-template-areas:
"main main main main main main main main main amount amount amount price price";
}
.product-row {
grid-template-areas:
"main main main main main main main main main main main main main main"
"pic pic pic description description description description description description amount amount amount price price"
"footer footer footer footer footer footer footer footer footer footer footer footer footer footer";
}
.grid.usps {
grid-template-columns: 1fr 2fr 1fr 2fr 1fr 2fr 1fr 2fr 1fr 2fr 1fr;
grid-column-gap: 0.8rem;
}
.usps small {
font-size: 0.8rem;
}
.guide img {
width: 300px;
margin-left: calc(50% - 150px);
}
.headings, hgroup, nav[aria-label=breadcrumb] {
margin-bottom: calc(2*var(--typography-spacing-vertical));
}
.article li img {
width: 400px;
margin-left: calc(50% - 150px);
}
}
@media (min-width: 768px) {
:root {
--font-size: 14px;
}
.circle {
width: 15px;
height: 15px;
}
.grid.usps {
grid-column-gap: var(--spacing);
}
.usps small {
font-size: 0.8rem;
}
input.cart-amount {
width: 70px;
}
.grid.articles {
grid-template-columns: 1fr 1fr 1fr;
}
}
@media (min-width: 992px) {
:root {
--font-size: 16px;
}
header::before {
background-color: transparent;
height: 63px;
}
nav ul ul {
position: absolute;
top: 46px;
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border-radius: 0 0 5px 5px;
}
aside nav {
position: fixed;
width: 250px;
max-height: calc(100vh - 144px);
overflow-x: hidden;
overflow-y: auto;
}
aside li, main>aside summary {
padding-top: 0;
padding-bottom: 0;
font-size: 0.8rem;
}
aside details summary {
color: var(--h1-color);
font-size: 0.8rem;
text-transform: uppercase;
}
footer p {
text-align: left;
}
footer p + p {
text-align: right;
}
.grid.center-layout {
grid-template-columns: 1fr 3fr 1fr;
}
.grid.docs-layout {
grid-template-columns: 250px auto 500px auto;
grid-column-gap: calc(var(--block-spacing-horizontal) * 3);
}
.grid.usps {
grid-template-columns: 2fr 2fr 2fr 2fr 2fr 2fr 2fr 2fr 2fr 2fr 2fr;
}
.usps small {
font-size: var(--font-size);
}
.circle {
width: 17px;
height: 17px;
}
aside li, main>aside summary {
padding-top: 0;
padding-bottom: 0;
font-size: 0.8rem;
}
input.cart-amount {
width: 63px;
}
}
@media (min-width: 1200px) {
:root {
--font-size: 18px;
}
.circle {
width: 18px;
height: 18px;
line-height: var(--spacing);
}
.grid.usps {
grid-template-columns: 1fr 2fr 1fr 2fr 1fr 2fr 1fr 2fr 1fr 2fr 1fr;
}
input.cart-amount {
width: 80px;
}
.video-iframe iframe {
width: 560px;
height: 315px;
}
}
@media (max-width: 767px) {
.hide-mobile {
display: none;
}
section#hero .container {
margin-bottom: 11vw;
}
.coldcardPromo {
right: 13px;
min-width: 130px;
}
}
@media (max-width: 991px) {
body > main {
padding-top: 49px;
}
header nav, header nav ul {
display: grid;
}
header nav ul {
text-align: center;
}
nav {
justify-content: center;
}
nav ul + * + * + ul {
display: none;
}
#hamburger:checked {
background-color: transparent;
}
#hamburger {
width: 30px;
height: 24px;
position: absolute;
margin: 0px;
top: 13px;
right: 13px;
display: block;
border:none;
box-shadow: none;
}
#hamburger::before, #hamburger::after {
content: "";
position: absolute;
width: 100%;
height: 4px;
color: var(--color);
background-color: currentColor;
transition: all var(--transition);
border-radius: 2px;
}
#hamburger:hover::before,
#hamburger:checked::before {
top: 10px;
transform: rotate(45deg);
}
#hamburger:hover::after,
#hamburger:checked::after {
box-shadow: 0 0 transparent;
bottom: 10px;
transform: rotate(-45deg);
}
#hamburger::before,
#hamburger:not(:checked)::before {
top: 0;
transform: rotate(0);
}
#hamburger::after,
#hamburger:not(:checked)::after {
bottom: 0;
box-shadow: 0 -10px currentColor;
transform: rotate(0);
}
header > .container {
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
}
section#hero {
margin-top: -49px;
padding-top: calc(2 * var(--block-spacing-vertical));
}
}

2654
static/css/pico.css Normal file

File diff suppressed because it is too large Load Diff

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.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
static/img/316l-120hrs.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
static/img/316l-408hrs.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

BIN
static/img/casino-dice.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

BIN
static/img/dice-cup.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

BIN
static/img/evil-attack.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
static/img/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
static/img/marker-qr.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

@ -0,0 +1,163 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.6, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Lag_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 447.8 303.3" style="enable-background:new 0 0 447.8 303.3;" xml:space="preserve">
<style type="text/css">
.st0{fill:none;stroke:#000000;stroke-width:2.8346;stroke-miterlimit:10;}
.st1{enable-background:new ;}
.st2{fill:#FFFFFF;}
.st3{fill:#FFFFFF;stroke:#1D1E1C;stroke-width:2.8346;stroke-miterlimit:10;}
.st4{fill:none;stroke:#000000;stroke-width:2.8346;stroke-linecap:round;stroke-miterlimit:10;}
</style>
<g>
<g>
<circle class="st0" cx="22.9" cy="78.5" r="21.5"/>
<path d="M54.2,86.2c3,0,5.9,0,8.9,0c4.4,0,8.7-4,9.1-8.4c0.1-0.6,0.1-1.2,0.2-1.8c0.3-1.2,1-2.2,2.3-2.5s2.5,0,3.3,1.1
c0.6,0.8,1.2,1.4,2.3,1.1c1.2-0.3,1.7-1.2,1.9-2.3c0.3-1.7,1.3-2.7,2.9-2.6c1.2,0.1,2.1-0.4,2.9-1.1c1.1-0.9,2.2-1.7,3.3-2.6
c1.3-1.1,3-0.8,4.3,0.3c1.7,1.5,3.3,3.4,6,3.3c0.8,0,1.4,0.5,2,0.9c0.9,0.6,1.7,0.8,2.7-0.1c1.5-1.2,3.2-2.3,5.3-0.8
c0.9,0.6,1.8-0.1,2.5-0.7c1.8-1.6,3.6-2.4,5.8-0.7c0.5,0.4,0.9,0.1,1.3-0.2c2.3-1.6,4.5-3.2,6.4-5.2c0.8-0.9,1.1-1.7,0.5-2.7
c-0.7-1.2-1.4-2.4-2.2-3.6c-0.7-0.9-1.6-1.6-2.8-1.6c-11.9-0.4-23.8-0.8-35.8-1.2c-0.8,0-1.5,0-2.2,0.3c-2.2,0.8-3.2,0.1-3.3-2.2
c0-0.9,0.3-2-0.9-2.5c-1.2-0.6-2.3-1-3.7,0.1c-2.2,1.7-4.6,0.5-4.8-2.3c-0.1-2-0.6-4-1.7-5.7c-1.8-2.8-4.6-4-7.9-4
c-6.2,0-12.4,0.1-18.6,0c-3.8-0.1-6.2,1.8-7.8,5c-0.7,1.5-1.5,2.8-2.5,4.1c-5.5,6.5-6.3,13.9-4.2,21.8c0.8,3.2,2,6.2,4.8,8.2
c0.4,0.3,0.5,0.8,0.6,1.3c1.2,4.9,4.2,7.3,9.2,7.4C47.7,86.2,50.9,86.2,54.2,86.2z M46.3,61.6c0,2.6,0,5.3,0,7.9
c0,1.1-0.3,1.7-1.6,1.7c-2.4,0-4.7,0-7.1,0c-1,0-1.7-0.4-2-1.3c-2-5.5-2-10.9,0-16.4c0.4-1,1-1.4,2.1-1.4c2.3,0,4.6,0.1,6.9,0
c1.3,0,1.7,0.6,1.7,1.8C46.2,56.5,46.3,59,46.3,61.6z"/>
<g class="st1">
<path class="st2" d="M56.2,61.8c-0.2,0.3-0.5,0.6-0.8,0.8s-0.9,0.3-1.4,0.3h-1v2.5h-1.7v-6.9h2.7c0.5,0,1,0.1,1.4,0.3
c0.4,0.2,0.7,0.5,0.9,0.8c0.2,0.3,0.3,0.7,0.3,1.1C56.4,61.1,56.4,61.5,56.2,61.8z M54.5,61.3c0.2-0.2,0.2-0.4,0.2-0.6
c0-0.3-0.1-0.5-0.2-0.6c-0.2-0.2-0.4-0.2-0.7-0.2h-0.9v1.7h0.9C54.1,61.6,54.3,61.5,54.5,61.3z"/>
<path class="st2" d="M60.8,65.4l-1.4-2.6H59v2.6h-1.7v-6.9h2.8c0.5,0,1,0.1,1.4,0.3c0.4,0.2,0.7,0.5,0.9,0.8
c0.2,0.3,0.3,0.7,0.3,1.1c0,0.5-0.1,0.9-0.4,1.2s-0.6,0.6-1.1,0.8l1.6,2.7H60.8z M59,61.6h1c0.3,0,0.5-0.1,0.7-0.2
c0.2-0.2,0.2-0.4,0.2-0.6c0-0.3-0.1-0.5-0.2-0.6s-0.4-0.2-0.7-0.2h-1V61.6z"/>
<path class="st2" d="M65.4,58.5v6.9h-1.7v-6.9H65.4z"/>
<path class="st2" d="M73.1,58.5l-2.4,6.9h-2.1l-2.4-6.9h1.8l1.7,5.2l1.7-5.2H73.1z"/>
<path class="st2" d="M78.1,64.2h-2.6l-0.4,1.2h-1.8l2.5-6.9h1.9l2.5,6.9h-1.8L78.1,64.2z M77.7,62.9l-0.9-2.5L76,62.9H77.7z"/>
<path class="st2" d="M86,58.5v1.3h-1.8v5.6h-1.7v-5.6h-1.8v-1.3H86z"/>
<path class="st2" d="M88.5,59.8v1.4h2.2v1.3h-2.2V64h2.5v1.3h-4.2v-6.9h4.2v1.3H88.5z"/>
</g>
</g>
<g>
<circle class="st0" cx="25.1" cy="161" r="21.5"/>
<path d="M56.4,168.7c3,0,5.9,0,8.9,0c4.4,0,8.7-4,9.1-8.4c0.1-0.6,0.1-1.2,0.2-1.8c0.3-1.2,1-2.2,2.3-2.5s2.5,0,3.3,1.1
c0.6,0.8,1.2,1.4,2.3,1.1c1.2-0.3,1.7-1.2,1.9-2.3c0.3-1.7,1.3-2.7,2.9-2.6c1.2,0.1,2.1-0.4,2.9-1.1c1.1-0.9,2.2-1.7,3.3-2.6
c1.3-1.1,3-0.8,4.3,0.3c1.7,1.5,3.3,3.4,6,3.3c0.8,0,1.4,0.5,2,0.9c0.9,0.6,1.7,0.8,2.7-0.1c1.5-1.2,3.2-2.3,5.3-0.8
c0.9,0.6,1.8-0.1,2.5-0.7c1.8-1.6,3.6-2.4,5.8-0.7c0.5,0.4,0.9,0.1,1.3-0.2c2.3-1.6,4.5-3.2,6.4-5.2c0.8-0.9,1.1-1.7,0.5-2.7
c-0.7-1.2-1.4-2.4-2.2-3.6c-0.7-0.9-1.6-1.6-2.8-1.6c-11.9-0.4-23.8-0.8-35.8-1.2c-0.8,0-1.5,0-2.2,0.3c-2.2,0.8-3.2,0.1-3.3-2.2
c0-0.9,0.3-2-0.9-2.5c-1.2-0.6-2.3-1-3.7,0.1c-2.2,1.7-4.6,0.5-4.8-2.3c-0.1-2-0.6-4-1.7-5.7c-1.8-2.8-4.6-4-7.9-4
c-6.2,0-12.4,0.1-18.6,0c-3.8-0.1-6.2,1.8-7.8,5c-0.7,1.5-1.5,2.8-2.5,4.1c-5.5,6.5-6.3,13.9-4.2,21.8c0.8,3.2,2,6.2,4.8,8.2
c0.4,0.3,0.5,0.8,0.6,1.3c1.2,4.9,4.2,7.3,9.2,7.4C49.9,168.7,53.2,168.7,56.4,168.7z M48.5,144.1c0,2.6,0,5.3,0,7.9
c0,1.1-0.3,1.7-1.6,1.7c-2.4,0-4.7,0-7.1,0c-1,0-1.7-0.4-2-1.3c-2-5.5-2-10.9,0-16.4c0.4-1,1-1.4,2.1-1.4c2.3,0,4.6,0.1,6.9,0
c1.3,0,1.7,0.6,1.7,1.8C48.5,139,48.5,141.6,48.5,144.1z"/>
<g class="st1">
<path class="st2" d="M58.4,144.3c-0.2,0.3-0.5,0.6-0.8,0.8s-0.9,0.3-1.4,0.3h-1v2.5h-1.7V141h2.7c0.5,0,1,0.1,1.4,0.3
c0.4,0.2,0.7,0.5,0.9,0.8c0.2,0.3,0.3,0.7,0.3,1.1C58.7,143.6,58.6,144,58.4,144.3z M56.7,143.8c0.2-0.2,0.2-0.4,0.2-0.6
c0-0.3-0.1-0.5-0.2-0.6c-0.2-0.2-0.4-0.2-0.7-0.2h-0.9v1.7H56C56.3,144.1,56.6,144,56.7,143.8z"/>
<path class="st2" d="M63.1,147.9l-1.4-2.6h-0.4v2.6h-1.7V141h2.8c0.5,0,1,0.1,1.4,0.3c0.4,0.2,0.7,0.5,0.9,0.8
c0.2,0.3,0.3,0.7,0.3,1.1c0,0.5-0.1,0.9-0.4,1.2s-0.6,0.6-1.1,0.8l1.6,2.7H63.1z M61.2,144.1h1c0.3,0,0.5-0.1,0.7-0.2
c0.2-0.2,0.2-0.4,0.2-0.6c0-0.3-0.1-0.5-0.2-0.6c-0.2-0.2-0.4-0.2-0.7-0.2h-1V144.1z"/>
<path class="st2" d="M67.6,141v6.9H66V141H67.6z"/>
<path class="st2" d="M75.3,141l-2.4,6.9h-2.1l-2.4-6.9h1.8l1.7,5.2l1.7-5.2H75.3z"/>
<path class="st2" d="M80.3,146.7h-2.6l-0.4,1.2h-1.8l2.5-6.9H80l2.5,6.9h-1.8L80.3,146.7z M79.9,145.4l-0.9-2.5l-0.8,2.5H79.9z"
/>
<path class="st2" d="M88.2,141v1.3h-1.8v5.6h-1.7v-5.6h-1.8V141H88.2z"/>
<path class="st2" d="M90.8,142.3v1.4H93v1.3h-2.2v1.5h2.5v1.3h-4.2V141h4.2v1.3H90.8z"/>
</g>
</g>
<g>
<circle class="st0" cx="26.6" cy="243.5" r="21.5"/>
<path d="M57.9,251.2c3,0,5.9,0,8.9,0c4.4,0,8.7-4,9.1-8.4c0.1-0.6,0.1-1.2,0.2-1.8c0.3-1.2,1-2.2,2.3-2.5s2.5,0,3.3,1.1
c0.6,0.8,1.2,1.4,2.3,1.1c1.2-0.3,1.7-1.2,1.9-2.3c0.3-1.7,1.3-2.7,2.9-2.6c1.2,0.1,2.1-0.4,2.9-1.1c1.1-0.9,2.2-1.7,3.3-2.6
c1.3-1.1,3-0.8,4.3,0.3c1.7,1.5,3.3,3.4,6,3.3c0.8,0,1.4,0.5,2,0.9c0.9,0.6,1.7,0.8,2.7-0.1c1.5-1.2,3.2-2.3,5.3-0.8
c0.9,0.6,1.8-0.1,2.5-0.7c1.8-1.6,3.6-2.4,5.8-0.7c0.5,0.4,0.9,0.1,1.3-0.2c2.3-1.6,4.5-3.2,6.4-5.2c0.8-0.9,1.1-1.7,0.5-2.7
c-0.7-1.2-1.4-2.4-2.2-3.6c-0.7-0.9-1.6-1.6-2.8-1.6c-11.9-0.4-23.8-0.8-35.8-1.2c-0.8,0-1.5,0-2.2,0.3c-2.2,0.8-3.2,0.1-3.3-2.2
c0-0.9,0.3-2-0.9-2.5c-1.2-0.6-2.3-1-3.7,0.1c-2.2,1.7-4.6,0.5-4.8-2.3c-0.1-2-0.6-4-1.7-5.7c-1.8-2.8-4.6-4-7.9-4
c-6.2,0-12.4,0.1-18.6,0c-3.8-0.1-6.2,1.8-7.8,5c-0.7,1.5-1.5,2.8-2.5,4.1c-5.5,6.5-6.3,13.9-4.2,21.8c0.8,3.2,2,6.2,4.8,8.2
c0.4,0.3,0.5,0.8,0.6,1.3c1.2,4.9,4.2,7.3,9.2,7.4C51.4,251.2,54.6,251.2,57.9,251.2z M50,226.7c0,2.6,0,5.3,0,7.9
c0,1.1-0.3,1.7-1.6,1.7c-2.4,0-4.7,0-7.1,0c-1,0-1.7-0.4-2-1.3c-2-5.5-2-10.9,0-16.4c0.4-1,1-1.4,2.1-1.4c2.3,0,4.6,0.1,6.9,0
c1.3,0,1.7,0.6,1.7,1.8C50,221.5,50,224.1,50,226.7z"/>
<g class="st1">
<path class="st2" d="M59.9,226.8c-0.2,0.3-0.5,0.6-0.8,0.8s-0.9,0.3-1.4,0.3h-1v2.5h-1.7v-6.9h2.7c0.5,0,1,0.1,1.4,0.3
c0.4,0.2,0.7,0.5,0.9,0.8c0.2,0.3,0.3,0.7,0.3,1.1C60.2,226.1,60.1,226.5,59.9,226.8z M58.2,226.4c0.2-0.2,0.2-0.4,0.2-0.6
c0-0.3-0.1-0.5-0.2-0.6c-0.2-0.2-0.4-0.2-0.7-0.2h-0.9v1.7h0.9C57.8,226.6,58.1,226.5,58.2,226.4z"/>
<path class="st2" d="M64.6,230.4l-1.4-2.6h-0.4v2.6H61v-6.9h2.8c0.5,0,1,0.1,1.4,0.3c0.4,0.2,0.7,0.5,0.9,0.8
c0.2,0.3,0.3,0.7,0.3,1.1c0,0.5-0.1,0.9-0.4,1.2s-0.6,0.6-1.1,0.8l1.6,2.7H64.6z M62.7,226.6h1c0.3,0,0.5-0.1,0.7-0.2
c0.2-0.2,0.2-0.4,0.2-0.6c0-0.3-0.1-0.5-0.2-0.6s-0.4-0.2-0.7-0.2h-1V226.6z"/>
<path class="st2" d="M69.1,223.5v6.9h-1.7v-6.9H69.1z"/>
<path class="st2" d="M76.8,223.5l-2.4,6.9h-2.1l-2.4-6.9h1.8l1.7,5.2l1.7-5.2H76.8z"/>
<path class="st2" d="M81.8,229.2h-2.6l-0.4,1.2h-1.8l2.5-6.9h1.9l2.5,6.9h-1.8L81.8,229.2z M81.4,227.9l-0.9-2.5l-0.8,2.5H81.4z"
/>
<path class="st2" d="M89.7,223.5v1.3h-1.8v5.6h-1.7v-5.6h-1.8v-1.3H89.7z"/>
<path class="st2" d="M92.2,224.8v1.4h2.2v1.3h-2.2v1.5h2.5v1.3h-4.2v-6.9h4.2v1.3H92.2z"/>
</g>
</g>
</g>
<g>
<g>
<path class="st3" d="M399.4,225.2H210.6c-7.8,0-14.2-6.3-14.2-14.2V91c0-7.8,6.3-14.2,14.2-14.2h188.8c7.8,0,14.2,6.3,14.2,14.2
v120C413.5,218.9,407.2,225.2,399.4,225.2z"/>
<path class="st3" d="M415.8,177h-70c-2.8,0-5.1-2.3-5.1-5.1v-41.8c0-2.8,2.3-5.1,5.1-5.1h70c2.8,0,5.1,2.3,5.1,5.1v41.8
C420.9,174.8,418.6,177,415.8,177z"/>
</g>
<g class="st1">
<path d="M264.7,104.1c1.8-1.5,3.2-2.7,4.3-3.7c1-1,1.9-2,2.6-3c0.7-1,1.1-2.1,1.1-3.1c0-0.8-0.2-1.3-0.5-1.8
c-0.3-0.4-0.9-0.6-1.6-0.6c-0.7,0-1.2,0.3-1.6,0.8c-0.4,0.5-0.6,1.3-0.6,2.2h-4.5c0-1.6,0.4-2.9,1-3.9c0.6-1,1.5-1.8,2.5-2.3
c1-0.5,2.2-0.7,3.5-0.7c2.2,0,3.8,0.6,4.9,1.7c1.1,1.1,1.7,2.6,1.7,4.4c0,2-0.7,3.8-2,5.5s-3,3.3-5.1,4.9h7.4v3.8h-13.8v-3.5
C264.5,104.3,264.8,104.1,264.7,104.1z"/>
<path d="M292.1,97v3.9h-12.1V97H292.1z"/>
<path d="M299.1,107.9c-1.2-0.6-2.1-1.6-2.8-2.8s-1-2.6-1-4.2c0-1.6,0.3-3,1-4.2c0.7-1.2,1.7-2.1,2.9-2.8c1.2-0.6,2.6-1,4.1-1
s2.9,0.3,4.1,1c1.2,0.6,2.2,1.6,2.9,2.8c0.7,1.2,1,2.6,1,4.2c0,1.6-0.4,3-1.1,4.2c-0.7,1.2-1.7,2.1-2.9,2.8c-1.2,0.6-2.6,1-4.1,1
S300.3,108.5,299.1,107.9z M305.5,103.8c0.6-0.7,1-1.6,1-2.8c0-1.2-0.3-2.2-0.9-2.8c-0.6-0.7-1.4-1-2.3-1c-0.9,0-1.7,0.3-2.3,1
c-0.6,0.7-0.9,1.6-0.9,2.8c0,1.2,0.3,2.2,0.9,2.8c0.6,0.7,1.3,1,2.2,1S304.8,104.4,305.5,103.8z"/>
<path d="M321.4,97.2h-2.5v11.5h-4.7V97.2h-1.7v-3.9h1.7v-0.4c0-1.9,0.5-3.3,1.6-4.3c1.1-1,2.7-1.5,4.8-1.5c0.3,0,0.6,0,0.8,0v4
c-0.9-0.1-1.5,0.1-1.9,0.4c-0.4,0.3-0.6,0.9-0.6,1.7v0.1h2.5V97.2z"/>
<path d="M335.5,97v3.9h-12.1V97H335.5z"/>
<path d="M341.2,89.6c1.2-1.1,2.9-1.6,4.9-1.6c1.4,0,2.6,0.2,3.5,0.7c1,0.5,1.7,1.1,2.2,2s0.8,1.8,0.8,2.8c0,1.2-0.3,2.2-0.9,3
s-1.3,1.3-2.1,1.6v0.1c1,0.3,1.9,0.9,2.5,1.7s0.9,1.8,0.9,3.1c0,1.1-0.3,2.1-0.8,3s-1.3,1.6-2.3,2.1c-1,0.5-2.2,0.7-3.6,0.7
c-2.2,0-4-0.5-5.3-1.6s-2-2.7-2.1-4.9h4.6c0,0.8,0.2,1.4,0.7,1.9s1.1,0.7,1.9,0.7c0.7,0,1.3-0.2,1.7-0.6c0.4-0.4,0.6-1,0.6-1.6
c0-0.9-0.3-1.5-0.8-1.9c-0.6-0.4-1.5-0.6-2.7-0.6h-0.9v-3.8h0.9c0.9,0,1.7-0.2,2.3-0.5c0.6-0.3,0.9-0.9,0.9-1.7
c0-0.7-0.2-1.2-0.6-1.5S346.7,92,346,92c-0.7,0-1.2,0.2-1.6,0.6c-0.3,0.4-0.5,0.9-0.6,1.6h-4.6C339.4,92.2,340,90.7,341.2,89.6z"
/>
</g>
<g class="st1">
<path d="M275.9,196c1.1,1.2,1.7,2.8,1.7,4.8v9h-4.7v-8.3c0-1-0.3-1.8-0.8-2.3c-0.5-0.5-1.2-0.8-2.2-0.8c-0.9,0-1.6,0.3-2.2,0.8
c-0.5,0.5-0.8,1.3-0.8,2.3v8.3h-4.7v-8.3c0-1-0.3-1.8-0.8-2.3c-0.5-0.5-1.2-0.8-2.2-0.8c-0.9,0-1.6,0.3-2.2,0.8
c-0.5,0.5-0.8,1.3-0.8,2.3v8.3h-4.7v-15.4h4.7v1.9c0.5-0.6,1.1-1.2,1.9-1.5c0.8-0.4,1.6-0.6,2.6-0.6c1.2,0,2.2,0.2,3.1,0.7
c0.9,0.5,1.6,1.2,2.1,2.1c0.5-0.8,1.3-1.5,2.2-2.1s1.9-0.8,3-0.8C273.2,194.2,274.7,194.8,275.9,196z"/>
<path d="M296,194.4v15.4h-4.7v-2.1c-0.5,0.7-1.1,1.2-1.9,1.6s-1.7,0.6-2.7,0.6c-1.2,0-2.2-0.3-3.1-0.8c-0.9-0.5-1.6-1.3-2.1-2.3
c-0.5-1-0.7-2.2-0.7-3.5v-9h4.7v8.3c0,1,0.3,1.8,0.8,2.4c0.5,0.6,1.2,0.9,2.1,0.9c0.9,0,1.6-0.3,2.2-0.9c0.5-0.6,0.8-1.4,0.8-2.4
v-8.3H296z"/>
<path d="M304.1,189.4v20.4h-4.7v-20.4H304.1z"/>
<path d="M316.1,205.8v4h-2.4c-1.7,0-3-0.4-4-1.3c-1-0.8-1.4-2.2-1.4-4.1v-6.1h-1.9v-3.9h1.9v-3.7h4.7v3.7h3.1v3.9H313v6.2
c0,0.5,0.1,0.8,0.3,1c0.2,0.2,0.6,0.3,1.1,0.3H316.1z"/>
<path d="M319.1,192.1c-0.5-0.5-0.8-1.1-0.8-1.8c0-0.7,0.3-1.3,0.8-1.8c0.5-0.5,1.2-0.7,2-0.7c0.8,0,1.5,0.2,2,0.7
c0.5,0.5,0.8,1.1,0.8,1.8c0,0.7-0.3,1.3-0.8,1.8c-0.5,0.5-1.2,0.7-2,0.7C320.3,192.8,319.6,192.5,319.1,192.1z M323.4,194.4v15.4
h-4.7v-15.4H323.4z"/>
<path d="M329.5,209.3c-1-0.5-1.9-1.1-2.5-1.9c-0.6-0.8-0.9-1.7-1-2.7h4.7c0.1,0.5,0.3,1,0.7,1.3s1,0.5,1.6,0.5
c0.6,0,1-0.1,1.4-0.3c0.3-0.2,0.5-0.5,0.5-0.9c0-0.4-0.2-0.8-0.7-1s-1.2-0.4-2.2-0.7c-1.1-0.3-2-0.5-2.8-0.8
c-0.7-0.3-1.4-0.7-1.9-1.3s-0.8-1.4-0.8-2.5c0-0.9,0.2-1.7,0.7-2.4c0.5-0.7,1.2-1.3,2.1-1.7c0.9-0.4,2.1-0.6,3.4-0.6
c1.9,0,3.4,0.5,4.6,1.4c1.1,1,1.7,2.2,1.9,3.8h-4.3c-0.1-0.5-0.3-1-0.7-1.3s-0.9-0.5-1.6-0.5c-0.6,0-1,0.1-1.3,0.3
s-0.4,0.5-0.4,0.9c0,0.4,0.2,0.8,0.7,1c0.5,0.2,1.2,0.4,2.2,0.7c1.1,0.3,2.1,0.6,2.8,0.9c0.7,0.3,1.3,0.7,1.9,1.4
c0.5,0.6,0.8,1.5,0.8,2.5c0,0.9-0.3,1.7-0.8,2.4c-0.5,0.7-1.2,1.3-2.2,1.7c-0.9,0.4-2,0.6-3.3,0.6
C331.8,210,330.6,209.7,329.5,209.3z"/>
<path d="M342.6,192.1c-0.5-0.5-0.8-1.1-0.8-1.8c0-0.7,0.3-1.3,0.8-1.8c0.5-0.5,1.2-0.7,2-0.7c0.8,0,1.5,0.2,2,0.7
c0.5,0.5,0.8,1.1,0.8,1.8c0,0.7-0.3,1.3-0.8,1.8c-0.5,0.5-1.2,0.7-2,0.7C343.8,192.8,343.1,192.5,342.6,192.1z M346.9,194.4v15.4
h-4.7v-15.4H346.9z"/>
<path d="M359,194.8c0.8,0.4,1.4,1,1.9,1.7v-2.2h4.7v15.3c0,1.4-0.3,2.7-0.8,3.8c-0.6,1.1-1.4,2.1-2.6,2.7c-1.1,0.7-2.6,1-4.3,1
c-2.3,0-4.1-0.5-5.5-1.6c-1.4-1.1-2.2-2.5-2.4-4.4h4.7c0.1,0.6,0.5,1.1,1,1.4c0.6,0.3,1.2,0.5,2,0.5c1,0,1.7-0.3,2.3-0.8
c0.6-0.6,0.9-1.5,0.9-2.7v-2.2c-0.5,0.7-1.1,1.3-1.9,1.7s-1.8,0.7-2.8,0.7c-1.3,0-2.4-0.3-3.4-1c-1-0.7-1.8-1.6-2.4-2.8
s-0.9-2.6-0.9-4.2c0-1.6,0.3-3,0.9-4.2c0.6-1.2,1.4-2.1,2.4-2.8c1-0.6,2.2-1,3.4-1C357.3,194.2,358.2,194.4,359,194.8z
M359.9,199.3c-0.7-0.7-1.4-1-2.4-1c-0.9,0-1.7,0.3-2.4,1s-1,1.6-1,2.8c0,1.2,0.3,2.1,1,2.8c0.7,0.7,1.4,1,2.4,1
c0.9,0,1.7-0.3,2.4-1c0.7-0.7,1-1.6,1-2.8C360.9,200.9,360.6,200,359.9,199.3z"/>
</g>
</g>
<g>
<line class="st4" x1="308.7" y1="43.5" x2="308.7" y2="1.4"/>
<line class="st4" x1="308.7" y1="301.9" x2="308.7" y2="259.9"/>
</g>
<g>
<line class="st4" x1="187.7" y1="62.1" x2="170.9" y2="45.3"/>
<line class="st4" x1="446.4" y1="258" x2="429.6" y2="241.2"/>
<line class="st4" x1="429.6" y1="62.1" x2="446.4" y2="45.3"/>
<line class="st4" x1="170.9" y1="258" x2="187.7" y2="241.2"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -0,0 +1,192 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.6, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Lag_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 422.7 303.3" enable-background="new 0 0 422.7 303.3" xml:space="preserve">
<g>
<g>
<circle fill="none" stroke="#000000" stroke-width="2.8346" stroke-miterlimit="10" cx="22.9" cy="39.6" r="21.5"/>
<path fill="#026634" d="M48.1,81.4c2.8,0.9,5.7,1.8,8.5,2.7c4.2,1.3,9.5-1.2,11.3-5.3c0.2-0.5,0.4-1.1,0.7-1.6
c0.6-1.1,1.6-1.8,2.9-1.7c1.3,0.2,2.4,0.8,2.9,2.1c0.3,0.9,0.8,1.7,1.9,1.7c1.2,0.1,2-0.6,2.6-1.6c0.8-1.6,2-2.2,3.6-1.6
c1.1,0.4,2.1,0.3,3.1-0.1c1.3-0.5,2.6-1,3.9-1.5c1.6-0.7,3.1,0.1,4,1.6c1.2,2,2.2,4.3,4.7,4.9c0.8,0.2,1.2,0.9,1.6,1.5
c0.7,0.9,1.4,1.2,2.6,0.7c1.8-0.7,3.7-1.2,5.3,0.8c0.7,0.9,1.7,0.5,2.6,0.1c2.2-1,4.2-1.2,5.7,1.1c0.3,0.5,0.9,0.3,1.3,0.2
c2.6-0.8,5.2-1.7,7.7-3c1.1-0.6,1.5-1.3,1.3-2.5c-0.3-1.4-0.6-2.7-1-4.1c-0.4-1.1-1-2-2.2-2.4c-11.2-4-22.5-8-33.7-12
C88.7,61.1,88,61,87.2,61c-2.4,0.1-3.1-0.9-2.5-3.1c0.3-0.9,0.9-1.8-0.1-2.7s-1.9-1.7-3.6-1.1c-2.6,1-4.5-0.9-3.8-3.7
c0.5-2,0.6-4,0.1-5.9c-0.9-3.2-3.2-5.2-6.3-6.2c-6-1.7-12-3.5-17.9-5.5c-3.6-1.2-6.5-0.1-8.9,2.5c-1.1,1.2-2.2,2.2-3.6,3.1
C33.5,42.9,30.4,49.7,30,57.9c-0.2,3.3,0.1,6.5,2.1,9.3c0.3,0.4,0.2,0.9,0.2,1.4c-0.3,5,1.8,8.3,6.6,9.8
C41.9,79.4,45,80.4,48.1,81.4z M48,55.6c-0.8,2.5-1.6,5-2.4,7.6c-0.3,1.1-0.8,1.5-2,1.1c-2.2-0.8-4.5-1.5-6.8-2.1
c-1-0.3-1.5-0.9-1.5-1.9c-0.3-5.8,1.4-11,4.9-15.7c0.6-0.8,1.4-1,2.4-0.7c2.2,0.7,4.4,1.5,6.6,2.1c1.3,0.4,1.4,1,1,2.2
C49.5,50.7,48.8,53.2,48,55.6z"/>
<g enable-background="new ">
<path fill="#FFFFFF" d="M57.4,58.8c-0.3,0.3-0.6,0.4-1,0.5c-0.4,0.1-0.9,0-1.4-0.1l-1-0.3l-0.7,2.4l-1.6-0.5l2.1-6.6l2.6,0.8
c0.5,0.2,0.9,0.4,1.2,0.7c0.3,0.3,0.5,0.6,0.6,1c0.1,0.4,0.1,0.8-0.1,1.2C57.8,58.2,57.6,58.5,57.4,58.8z M55.9,57.8
c0.2-0.1,0.3-0.3,0.4-0.5c0.1-0.3,0.1-0.5,0-0.7c-0.1-0.2-0.3-0.3-0.6-0.4l-0.9-0.3l-0.5,1.6l0.9,0.3
C55.5,57.9,55.7,57.9,55.9,57.8z"/>
<path fill="#FFFFFF" d="M61,56.4l-1.2,3.9c-0.1,0.4-0.1,0.7,0,1c0.1,0.3,0.4,0.5,0.8,0.6c0.4,0.1,0.7,0.1,1,0
c0.3-0.1,0.5-0.4,0.6-0.8l1.2-3.9l1.6,0.5l-1.2,3.9c-0.2,0.6-0.5,1-0.8,1.4c-0.4,0.3-0.8,0.5-1.3,0.6c-0.5,0.1-1,0-1.5-0.1
c-0.5-0.2-0.9-0.4-1.3-0.7c-0.3-0.3-0.6-0.7-0.7-1.2c-0.1-0.5-0.1-1,0.1-1.6l1.2-3.9L61,56.4z"/>
<path fill="#FFFFFF" d="M69.8,63.3c0.1,0.4,0.1,0.7,0,1.1c-0.2,0.6-0.5,0.9-1,1.1s-1.1,0.2-1.8,0l-3.1-1l2.1-6.6l3,0.9
c0.7,0.2,1.1,0.5,1.4,1c0.3,0.4,0.3,0.9,0.2,1.4c-0.1,0.4-0.3,0.7-0.6,0.9c-0.3,0.2-0.6,0.3-1,0.3C69.4,62.7,69.6,63,69.8,63.3z
M67.8,64.2c0.2-0.1,0.3-0.2,0.4-0.5c0.1-0.2,0.1-0.4-0.1-0.6c-0.1-0.2-0.3-0.3-0.6-0.4l-1.2-0.4L66,63.8l1.2,0.4
C67.4,64.3,67.7,64.3,67.8,64.2z M66.8,61.2l1,0.3c0.3,0.1,0.5,0.1,0.7,0c0.2-0.1,0.3-0.2,0.4-0.4c0.1-0.2,0.1-0.4,0-0.6
c-0.1-0.2-0.3-0.3-0.5-0.4l-1-0.3L66.8,61.2z"/>
<path fill="#FFFFFF" d="M72.1,65.8l2.1,0.7l-0.4,1.2l-3.7-1.2l2.1-6.6l1.6,0.5L72.1,65.8z"/>
<path fill="#FFFFFF" d="M78.3,61.9l-2.1,6.6L74.6,68l2.1-6.6L78.3,61.9z"/>
<path fill="#FFFFFF" d="M79.1,63.9c0.4-0.4,1-0.7,1.6-0.8c0.6-0.1,1.2-0.1,1.8,0.1c0.8,0.2,1.4,0.7,1.8,1.3s0.6,1.3,0.6,2
l-1.8-0.6c0-0.3-0.2-0.6-0.4-0.8s-0.4-0.4-0.8-0.5c-0.5-0.2-0.9-0.1-1.4,0.1C80.3,65,80,65.4,79.8,66s-0.2,1.1,0,1.5
c0.2,0.4,0.5,0.7,1,0.9c0.3,0.1,0.6,0.1,0.9,0s0.5-0.2,0.8-0.5l1.8,0.6c-0.4,0.7-1,1.1-1.6,1.3c-0.7,0.2-1.4,0.2-2.2,0
c-0.6-0.2-1.2-0.5-1.6-1s-0.7-1-0.8-1.6c-0.1-0.6-0.1-1.2,0.1-1.9C78.4,64.8,78.7,64.3,79.1,63.9z"/>
</g>
</g>
<g>
<circle fill="none" stroke="#000000" stroke-width="2.8346" stroke-miterlimit="10" cx="22.9" cy="122.5" r="21.5"/>
<path fill="#026634" d="M48.1,164.2c2.8,0.9,5.7,1.8,8.5,2.7c4.2,1.3,9.5-1.2,11.3-5.3c0.2-0.5,0.4-1.1,0.7-1.6
c0.6-1.1,1.6-1.8,2.9-1.7c1.3,0.2,2.4,0.8,2.9,2.1c0.3,0.9,0.8,1.7,1.9,1.7c1.2,0.1,2-0.6,2.6-1.6c0.8-1.6,2-2.2,3.6-1.6
c1.1,0.4,2.1,0.3,3.1-0.1c1.3-0.5,2.6-1,3.9-1.5c1.6-0.7,3.1,0.1,4,1.6c1.2,2,2.2,4.3,4.7,4.9c0.8,0.2,1.2,0.9,1.6,1.5
c0.7,0.9,1.4,1.2,2.6,0.7c1.8-0.7,3.7-1.2,5.3,0.8c0.7,0.9,1.7,0.5,2.6,0.1c2.2-1,4.2-1.2,5.7,1.1c0.3,0.5,0.9,0.3,1.3,0.2
c2.6-0.8,5.2-1.7,7.7-3c1.1-0.6,1.5-1.3,1.3-2.5c-0.3-1.4-0.6-2.7-1-4.1c-0.4-1.1-1-2-2.2-2.4c-11.2-4-22.5-8-33.7-12
c-0.7-0.3-1.4-0.4-2.2-0.4c-2.4,0.1-3.1-0.9-2.5-3.1c0.3-0.9,0.9-1.8-0.1-2.7s-1.9-1.7-3.6-1.1c-2.6,1-4.5-0.9-3.8-3.7
c0.5-2,0.6-4,0.1-5.9c-0.9-3.2-3.2-5.2-6.3-6.2c-5.9-1.8-11.9-3.6-17.8-5.6c-3.6-1.2-6.5-0.1-8.9,2.5c-1.1,1.2-2.2,2.2-3.6,3.1
c-7.1,4.5-10.2,11.3-10.6,19.5c-0.2,3.3,0.1,6.5,2.1,9.3c0.3,0.4,0.2,0.9,0.2,1.4c-0.3,5,1.8,8.3,6.6,9.8
C41.9,162.3,45,163.2,48.1,164.2z M48,138.4c-0.8,2.5-1.6,5-2.4,7.6c-0.3,1.1-0.8,1.5-2,1.1c-2.2-0.8-4.5-1.5-6.8-2.1
c-1-0.3-1.5-0.9-1.5-1.9c-0.3-5.8,1.4-11,4.9-15.7c0.6-0.8,1.4-1,2.4-0.7c2.2,0.7,4.4,1.5,6.6,2.1c1.3,0.4,1.4,1,1,2.2
C49.5,133.5,48.8,136,48,138.4z"/>
<g enable-background="new ">
<path fill="#FFFFFF" d="M57.4,141.6c-0.3,0.3-0.6,0.4-1,0.5s-0.9,0-1.4-0.1l-1-0.3l-0.7,2.4l-1.6-0.5l2.1-6.6l2.6,0.8
c0.5,0.2,0.9,0.4,1.2,0.7s0.5,0.6,0.6,1c0.1,0.4,0.1,0.8-0.1,1.2C57.8,141,57.6,141.3,57.4,141.6z M55.9,140.6
c0.2-0.1,0.3-0.3,0.4-0.5c0.1-0.3,0.1-0.5,0-0.7c-0.1-0.2-0.3-0.3-0.6-0.4l-0.9-0.3l-0.5,1.6l0.9,0.3
C55.5,140.7,55.7,140.7,55.9,140.6z"/>
<path fill="#FFFFFF" d="M61,139.3l-1.2,3.9c-0.1,0.4-0.1,0.7,0,1c0.1,0.3,0.4,0.5,0.8,0.6c0.4,0.1,0.7,0.1,1,0
c0.3-0.1,0.5-0.4,0.6-0.8l1.2-3.9l1.6,0.5l-1.2,3.9c-0.2,0.6-0.5,1-0.8,1.4c-0.4,0.3-0.8,0.5-1.3,0.6c-0.5,0.1-1,0-1.5-0.1
s-1-0.4-1.3-0.7c-0.3-0.3-0.6-0.7-0.7-1.2c-0.1-0.5-0.1-1,0.1-1.6l1.2-3.9L61,139.3z"/>
<path fill="#FFFFFF" d="M69.8,146.2c0.1,0.4,0.1,0.7,0,1.1c-0.2,0.5-0.5,0.9-1,1.1c-0.5,0.2-1.1,0.2-1.8,0l-3.1-1l2.1-6.6l3,0.9
c0.7,0.2,1.1,0.5,1.4,1c0.3,0.4,0.3,0.9,0.2,1.4c-0.1,0.4-0.3,0.7-0.6,0.9c-0.3,0.2-0.6,0.3-1,0.3
C69.4,145.5,69.6,145.8,69.8,146.2z M67.8,147c0.2-0.1,0.3-0.2,0.4-0.5c0.1-0.2,0.1-0.4-0.1-0.6c-0.1-0.2-0.3-0.3-0.6-0.4
l-1.2-0.4l-0.5,1.5l1.2,0.4C67.4,147.1,67.7,147.1,67.8,147z M66.8,144l1,0.3c0.3,0.1,0.5,0.1,0.7,0c0.2-0.1,0.3-0.2,0.4-0.4
c0.1-0.2,0.1-0.4,0-0.6c-0.1-0.2-0.3-0.3-0.5-0.4l-1-0.3L66.8,144z"/>
<path fill="#FFFFFF" d="M72.1,148.6l2.1,0.7l-0.4,1.2l-3.7-1.2l2.1-6.6l1.6,0.5L72.1,148.6z"/>
<path fill="#FFFFFF" d="M78.3,144.7l-2.1,6.6l-1.6-0.5l2.1-6.6L78.3,144.7z"/>
<path fill="#FFFFFF" d="M79.1,146.7c0.4-0.4,1-0.7,1.6-0.8c0.6-0.1,1.2-0.1,1.8,0.1c0.8,0.2,1.4,0.7,1.8,1.3
c0.4,0.6,0.6,1.3,0.6,2l-1.8-0.6c0-0.3-0.2-0.6-0.4-0.8c-0.2-0.2-0.4-0.4-0.8-0.5c-0.5-0.2-0.9-0.1-1.4,0.1
c-0.4,0.2-0.7,0.7-0.9,1.2c-0.2,0.6-0.2,1.1,0,1.5c0.2,0.4,0.5,0.7,1,0.9c0.3,0.1,0.6,0.1,0.9,0c0.3-0.1,0.5-0.2,0.8-0.5l1.8,0.6
c-0.4,0.7-1,1.1-1.6,1.3c-0.7,0.2-1.4,0.2-2.2,0c-0.6-0.2-1.2-0.5-1.6-1c-0.4-0.4-0.7-1-0.8-1.6c-0.1-0.6-0.1-1.2,0.1-1.9
C78.4,147.6,78.7,147.1,79.1,146.7z"/>
</g>
</g>
<g>
<circle fill="none" stroke="#000000" stroke-width="2.8346" stroke-miterlimit="10" cx="22.9" cy="205.3" r="21.5"/>
<path fill="#026634" d="M48.1,247c2.8,0.9,5.7,1.8,8.5,2.7c4.2,1.3,9.5-1.2,11.3-5.3c0.2-0.5,0.4-1.1,0.7-1.6
c0.6-1.1,1.6-1.8,2.9-1.7c1.3,0.2,2.4,0.8,2.9,2.1c0.3,0.9,0.8,1.7,1.9,1.7c1.2,0.1,2-0.6,2.6-1.6c0.8-1.6,2-2.2,3.6-1.6
c1.1,0.4,2.1,0.3,3.1-0.1c1.3-0.5,2.6-1,3.9-1.5c1.6-0.7,3.1,0.1,4,1.6c1.2,2,2.2,4.3,4.7,4.9c0.8,0.2,1.2,0.9,1.6,1.5
c0.7,0.9,1.4,1.2,2.6,0.7c1.8-0.7,3.7-1.2,5.3,0.8c0.7,0.9,1.7,0.5,2.6,0.1c2.2-1,4.2-1.2,5.7,1.1c0.3,0.5,0.9,0.3,1.3,0.2
c2.6-0.8,5.2-1.7,7.7-3c1.1-0.6,1.5-1.3,1.3-2.5c-0.3-1.4-0.6-2.7-1-4.1c-0.4-1.1-1-2-2.2-2.4c-11.2-4-22.5-8-33.7-12
c-0.7-0.3-1.4-0.4-2.2-0.4c-2.4,0.1-3.1-0.9-2.5-3.1c0.3-0.9,0.9-1.8-0.1-2.7s-1.9-1.7-3.6-1.1c-2.6,1-4.5-0.9-3.8-3.7
c0.5-2,0.6-4,0.1-5.9c-0.9-3.2-3.2-5.2-6.3-6.2c-5.9-1.8-11.9-3.6-17.8-5.6c-3.6-1.2-6.5-0.1-8.9,2.5c-1.1,1.2-2.2,2.2-3.6,3.1
c-7.1,4.5-10.2,11.3-10.6,19.5c-0.2,3.3,0.1,6.5,2.1,9.3c0.3,0.4,0.2,0.9,0.2,1.4c-0.3,5,1.8,8.3,6.6,9.8
C41.9,245.1,45,246,48.1,247z M48,221.2c-0.8,2.5-1.6,5-2.4,7.6c-0.3,1.1-0.8,1.5-2,1.1c-2.2-0.8-4.5-1.5-6.8-2.1
c-1-0.3-1.5-0.9-1.5-1.9c-0.3-5.8,1.4-11,4.9-15.7c0.6-0.8,1.4-1,2.4-0.7c2.2,0.7,4.4,1.5,6.6,2.1c1.3,0.4,1.4,1,1,2.2
C49.5,216.3,48.8,218.8,48,221.2z"/>
<g enable-background="new ">
<path fill="#FFFFFF" d="M57.4,224.4c-0.3,0.3-0.6,0.4-1,0.5c-0.4,0.1-0.9,0-1.4-0.1l-1-0.3l-0.7,2.4l-1.6-0.5l2.1-6.6l2.6,0.8
c0.5,0.2,0.9,0.4,1.2,0.7c0.3,0.3,0.5,0.6,0.6,1c0.1,0.4,0.1,0.8-0.1,1.2C57.8,223.8,57.6,224.1,57.4,224.4z M55.9,223.4
c0.2-0.1,0.3-0.3,0.4-0.5c0.1-0.3,0.1-0.5,0-0.7c-0.1-0.2-0.3-0.3-0.6-0.4l-0.9-0.3l-0.5,1.6l0.9,0.3
C55.5,223.5,55.7,223.5,55.9,223.4z"/>
<path fill="#FFFFFF" d="M61,222.1l-1.2,3.9c-0.1,0.4-0.1,0.7,0,1c0.1,0.3,0.4,0.5,0.8,0.6c0.4,0.1,0.7,0.1,1,0
c0.3-0.1,0.5-0.4,0.6-0.8l1.2-3.9l1.6,0.5l-1.2,3.9c-0.2,0.6-0.5,1-0.8,1.4c-0.4,0.3-0.8,0.5-1.3,0.6s-1,0-1.5-0.1
s-1-0.4-1.3-0.7c-0.3-0.3-0.6-0.7-0.7-1.2c-0.1-0.5-0.1-1,0.1-1.6l1.2-3.9L61,222.1z"/>
<path fill="#FFFFFF" d="M69.8,229c0.1,0.4,0.1,0.7,0,1.1c-0.2,0.5-0.5,0.9-1,1.1c-0.5,0.2-1.1,0.2-1.8,0l-3.1-1l2.1-6.6l3,0.9
c0.7,0.2,1.1,0.5,1.4,1c0.3,0.4,0.3,0.9,0.2,1.4c-0.1,0.4-0.3,0.7-0.6,0.9c-0.3,0.2-0.6,0.3-1,0.3
C69.4,228.3,69.6,228.6,69.8,229z M67.8,229.8c0.2-0.1,0.3-0.2,0.4-0.5c0.1-0.2,0.1-0.4-0.1-0.6c-0.1-0.2-0.3-0.3-0.6-0.4
l-1.2-0.4l-0.5,1.5l1.2,0.4C67.4,229.9,67.7,229.9,67.8,229.8z M66.8,226.8l1,0.3c0.3,0.1,0.5,0.1,0.7,0s0.3-0.2,0.4-0.4
c0.1-0.2,0.1-0.4,0-0.6c-0.1-0.2-0.3-0.3-0.5-0.4l-1-0.3L66.8,226.8z"/>
<path fill="#FFFFFF" d="M72.1,231.5l2.1,0.7l-0.4,1.2l-3.7-1.2l2.1-6.6l1.6,0.5L72.1,231.5z"/>
<path fill="#FFFFFF" d="M78.3,227.5l-2.1,6.6l-1.6-0.5l2.1-6.6L78.3,227.5z"/>
<path fill="#FFFFFF" d="M79.1,229.5c0.4-0.4,1-0.7,1.6-0.8c0.6-0.1,1.2-0.1,1.8,0.1c0.8,0.2,1.4,0.7,1.8,1.3
c0.4,0.6,0.6,1.3,0.6,2l-1.8-0.6c0-0.3-0.2-0.6-0.4-0.8c-0.2-0.2-0.4-0.4-0.8-0.5c-0.5-0.2-0.9-0.1-1.4,0.1
c-0.4,0.2-0.7,0.7-0.9,1.2c-0.2,0.6-0.2,1.1,0,1.5c0.2,0.4,0.5,0.7,1,0.9c0.3,0.1,0.6,0.1,0.9,0c0.3-0.1,0.5-0.2,0.8-0.5l1.8,0.6
c-0.4,0.7-1,1.1-1.6,1.3c-0.7,0.2-1.4,0.2-2.2,0c-0.6-0.2-1.2-0.5-1.6-1c-0.4-0.4-0.7-1-0.8-1.6c-0.1-0.6-0.1-1.2,0.1-1.9
C78.4,230.4,78.7,229.9,79.1,229.5z"/>
</g>
</g>
</g>
<g>
<g>
<path fill="#FFFFFF" stroke="#1D1E1C" stroke-width="2.8346" stroke-miterlimit="10" d="M374.2,225.2H185.5
c-7.8,0-14.2-6.3-14.2-14.2V91c0-7.8,6.3-14.2,14.2-14.2h188.8c7.8,0,14.2,6.3,14.2,14.2v120C388.4,218.9,382.1,225.2,374.2,225.2
z"/>
<path fill="#FFFFFF" stroke="#1D1E1C" stroke-width="2.8346" stroke-miterlimit="10" d="M390.7,177h-70c-2.8,0-5.1-2.3-5.1-5.1
v-41.8c0-2.8,2.3-5.1,5.1-5.1h70c2.8,0,5.1,2.3,5.1,5.1v41.8C395.8,174.8,393.5,177,390.7,177z"/>
</g>
<path d="M283.4,175c-5,0-10,0-15,0c-0.3,0-0.6,0-0.9,0c-2.3-0.1-2.4-0.2-2.4-2.5c0-8.6,0-17.1,0-25.7c0-1.1,0-2,1.5-1.9
c0.9,0,0.8-0.8,0.8-1.4c0-3-0.1-6,0-8.9c0.4-7,3.6-12.3,10.1-15.2c7.7-3.4,16.7,0.5,20.3,8.7c1,2.2,1.5,4.5,1.5,6.9
c0,2.8,0,5.7,0,8.5c0,1,0.2,1.7,1.4,1.6c1.3-0.1,1.2,0.8,1.2,1.7c0,7,0,13.9,0,20.9c0,1.9,0,3.8,0,5.6c0,1.1-0.3,1.7-1.5,1.8
c-4,0.3-8,0.1-12,0.2C286.8,175.1,285.1,175.1,283.4,175L283.4,175z M283.6,144.9c2.9,0,5.9,0,8.8,0c0.8,0,1.4-0.2,1.4-1.2
c-0.1-3.3,0.2-6.6-0.2-9.9c-0.6-5.6-5-9.7-10.2-9.5c-5.1,0.1-9.5,4.7-9.7,10.2c-0.1,3,0,6.1,0,9.1c0,1.1,0.4,1.4,1.5,1.4
C277.9,144.8,280.7,144.9,283.6,144.9z"/>
<g enable-background="new ">
<path d="M239.6,104.1c1.8-1.5,3.2-2.7,4.3-3.7c1-1,1.9-2,2.6-3c0.7-1,1.1-2.1,1.1-3.1c0-0.8-0.2-1.3-0.5-1.8
c-0.3-0.4-0.9-0.6-1.6-0.6c-0.7,0-1.2,0.3-1.6,0.8c-0.4,0.5-0.6,1.3-0.6,2.2h-4.5c0-1.6,0.4-2.9,1-3.9c0.6-1,1.5-1.8,2.5-2.3
c1-0.5,2.2-0.7,3.5-0.7c2.2,0,3.8,0.6,4.9,1.7c1.1,1.1,1.7,2.6,1.7,4.4c0,2-0.7,3.8-2,5.5s-3,3.3-5.1,4.9h7.4v3.8h-13.8v-3.5
C239.4,104.3,239.7,104.1,239.6,104.1z"/>
<path d="M266.9,97v3.9h-12.1V97H266.9z"/>
<path d="M274,107.9c-1.2-0.6-2.1-1.6-2.8-2.8c-0.7-1.2-1-2.6-1-4.2c0-1.6,0.3-3,1-4.2s1.7-2.1,2.9-2.8s2.6-1,4.1-1
c1.5,0,2.9,0.3,4.1,1s2.2,1.6,2.9,2.8s1,2.6,1,4.2c0,1.6-0.4,3-1.1,4.2c-0.7,1.2-1.7,2.1-2.9,2.8c-1.2,0.6-2.6,1-4.1,1
S275.2,108.5,274,107.9z M280.4,103.8c0.6-0.7,1-1.6,1-2.8c0-1.2-0.3-2.2-0.9-2.8c-0.6-0.7-1.4-1-2.3-1c-0.9,0-1.7,0.3-2.3,1
c-0.6,0.7-0.9,1.6-0.9,2.8c0,1.2,0.3,2.2,0.9,2.8c0.6,0.7,1.3,1,2.2,1S279.7,104.4,280.4,103.8z"/>
<path d="M296.3,97.2h-2.5v11.5h-4.7V97.2h-1.7v-3.9h1.7v-0.4c0-1.9,0.5-3.3,1.6-4.3c1.1-1,2.7-1.5,4.8-1.5c0.3,0,0.6,0,0.8,0v4
c-0.9-0.1-1.5,0.1-1.9,0.4c-0.4,0.3-0.6,0.9-0.6,1.7v0.1h2.5V97.2z"/>
<path d="M310.4,97v3.9h-12.1V97H310.4z"/>
<path d="M316.1,89.6c1.2-1.1,2.9-1.6,4.9-1.6c1.4,0,2.6,0.2,3.5,0.7c1,0.5,1.7,1.1,2.2,2s0.8,1.8,0.8,2.8c0,1.2-0.3,2.2-0.9,3
s-1.3,1.3-2.1,1.6v0.1c1,0.3,1.9,0.9,2.5,1.7s0.9,1.8,0.9,3.1c0,1.1-0.3,2.1-0.8,3s-1.3,1.6-2.3,2.1c-1,0.5-2.2,0.7-3.6,0.7
c-2.2,0-4-0.5-5.3-1.6s-2-2.7-2.1-4.9h4.6c0,0.8,0.2,1.4,0.7,1.9s1.1,0.7,1.9,0.7c0.7,0,1.3-0.2,1.7-0.6c0.4-0.4,0.6-1,0.6-1.6
c0-0.9-0.3-1.5-0.8-1.9s-1.5-0.6-2.7-0.6H319v-3.8h0.9c0.9,0,1.7-0.2,2.3-0.5c0.6-0.3,0.9-0.9,0.9-1.7c0-0.7-0.2-1.2-0.6-1.5
s-0.9-0.6-1.5-0.6c-0.7,0-1.2,0.2-1.6,0.6c-0.3,0.4-0.5,0.9-0.6,1.6h-4.6C314.3,92.2,314.9,90.7,316.1,89.6z"/>
</g>
<g enable-background="new ">
<path d="M250.8,196c1.1,1.2,1.7,2.8,1.7,4.8v9h-4.7v-8.3c0-1-0.3-1.8-0.8-2.3c-0.5-0.5-1.2-0.8-2.2-0.8s-1.6,0.3-2.2,0.8
c-0.5,0.5-0.8,1.3-0.8,2.3v8.3h-4.7v-8.3c0-1-0.3-1.8-0.8-2.3c-0.5-0.5-1.2-0.8-2.2-0.8s-1.6,0.3-2.2,0.8
c-0.5,0.5-0.8,1.3-0.8,2.3v8.3h-4.7v-15.4h4.7v1.9c0.5-0.6,1.1-1.2,1.9-1.5c0.8-0.4,1.6-0.6,2.6-0.6c1.2,0,2.2,0.2,3.1,0.7
c0.9,0.5,1.6,1.2,2.1,2.1c0.5-0.8,1.3-1.5,2.2-2.1c0.9-0.5,1.9-0.8,3-0.8C248.1,194.2,249.6,194.8,250.8,196z"/>
<path d="M270.9,194.4v15.4h-4.7v-2.1c-0.5,0.7-1.1,1.2-1.9,1.6s-1.7,0.6-2.7,0.6c-1.2,0-2.2-0.3-3.1-0.8c-0.9-0.5-1.6-1.3-2.1-2.3
c-0.5-1-0.7-2.2-0.7-3.5v-9h4.7v8.3c0,1,0.3,1.8,0.8,2.4c0.5,0.6,1.2,0.9,2.1,0.9c0.9,0,1.6-0.3,2.2-0.9c0.5-0.6,0.8-1.4,0.8-2.4
v-8.3H270.9z"/>
<path d="M279,189.4v20.4h-4.7v-20.4H279z"/>
<path d="M291,205.8v4h-2.4c-1.7,0-3-0.4-4-1.3c-1-0.8-1.4-2.2-1.4-4.1v-6.1h-1.9v-3.9h1.9v-3.7h4.7v3.7h3.1v3.9h-3.1v6.2
c0,0.5,0.1,0.8,0.3,1c0.2,0.2,0.6,0.3,1.1,0.3H291z"/>
<path d="M294,192.1c-0.5-0.5-0.8-1.1-0.8-1.8c0-0.7,0.3-1.3,0.8-1.8c0.5-0.5,1.2-0.7,2-0.7c0.8,0,1.5,0.2,2,0.7
c0.5,0.5,0.8,1.1,0.8,1.8c0,0.7-0.3,1.3-0.8,1.8c-0.5,0.5-1.2,0.7-2,0.7C295.2,192.8,294.5,192.5,294,192.1z M298.3,194.4v15.4
h-4.7v-15.4H298.3z"/>
<path d="M304.4,209.3c-1-0.5-1.9-1.1-2.5-1.9c-0.6-0.8-0.9-1.7-1-2.7h4.7c0.1,0.5,0.3,1,0.7,1.3c0.4,0.3,1,0.5,1.6,0.5
c0.6,0,1-0.1,1.4-0.3s0.5-0.5,0.5-0.9c0-0.4-0.2-0.8-0.7-1c-0.5-0.2-1.2-0.4-2.2-0.7c-1.1-0.3-2-0.5-2.8-0.8
c-0.7-0.3-1.4-0.7-1.9-1.3c-0.5-0.6-0.8-1.4-0.8-2.5c0-0.9,0.2-1.7,0.7-2.4c0.5-0.7,1.2-1.3,2.1-1.7c0.9-0.4,2.1-0.6,3.4-0.6
c1.9,0,3.4,0.5,4.6,1.4c1.1,1,1.7,2.2,1.9,3.8h-4.3c-0.1-0.5-0.3-1-0.7-1.3s-0.9-0.5-1.6-0.5c-0.6,0-1,0.1-1.3,0.3
s-0.4,0.5-0.4,0.9c0,0.4,0.2,0.8,0.7,1c0.5,0.2,1.2,0.4,2.2,0.7c1.1,0.3,2.1,0.6,2.8,0.9c0.7,0.3,1.3,0.7,1.9,1.4
c0.5,0.6,0.8,1.5,0.8,2.5c0,0.9-0.3,1.7-0.8,2.4c-0.5,0.7-1.2,1.3-2.2,1.7c-0.9,0.4-2,0.6-3.3,0.6
C306.6,210,305.5,209.7,304.4,209.3z"/>
<path d="M317.4,192.1c-0.5-0.5-0.8-1.1-0.8-1.8c0-0.7,0.3-1.3,0.8-1.8c0.5-0.5,1.2-0.7,2-0.7c0.8,0,1.5,0.2,2,0.7
c0.5,0.5,0.8,1.1,0.8,1.8c0,0.7-0.3,1.3-0.8,1.8c-0.5,0.5-1.2,0.7-2,0.7C318.6,192.8,318,192.5,317.4,192.1z M321.8,194.4v15.4
h-4.7v-15.4H321.8z"/>
<path d="M333.9,194.8c0.8,0.4,1.4,1,1.9,1.7v-2.2h4.7v15.3c0,1.4-0.3,2.7-0.8,3.8c-0.6,1.1-1.4,2.1-2.6,2.7c-1.1,0.7-2.6,1-4.3,1
c-2.3,0-4.1-0.5-5.5-1.6c-1.4-1.1-2.2-2.5-2.4-4.4h4.7c0.1,0.6,0.5,1.1,1,1.4c0.5,0.3,1.2,0.5,2,0.5c1,0,1.7-0.3,2.3-0.8
c0.6-0.6,0.9-1.5,0.9-2.7v-2.2c-0.5,0.7-1.1,1.3-1.9,1.7s-1.8,0.7-2.8,0.7c-1.3,0-2.4-0.3-3.4-1s-1.8-1.6-2.4-2.8
s-0.9-2.6-0.9-4.2c0-1.6,0.3-3,0.9-4.2c0.6-1.2,1.4-2.1,2.4-2.8s2.2-1,3.4-1C332.1,194.2,333.1,194.4,333.9,194.8z M334.8,199.3
c-0.7-0.7-1.4-1-2.4-1s-1.7,0.3-2.4,1s-1,1.6-1,2.8c0,1.2,0.3,2.1,1,2.8c0.7,0.7,1.4,1,2.4,1s1.7-0.3,2.4-1c0.7-0.7,1-1.6,1-2.8
C335.8,200.9,335.5,200,334.8,199.3z"/>
</g>
</g>
<g>
<line fill="none" stroke="#000000" stroke-width="2.8346" stroke-linecap="round" stroke-miterlimit="10" x1="283.6" y1="43.5" x2="283.6" y2="1.4"/>
<line fill="none" stroke="#000000" stroke-width="2.8346" stroke-linecap="round" stroke-miterlimit="10" x1="283.6" y1="301.9" x2="283.6" y2="259.9"/>
</g>
<g>
<line fill="none" stroke="#000000" stroke-width="2.8346" stroke-linecap="round" stroke-miterlimit="10" x1="162.6" y1="62.1" x2="145.8" y2="45.3"/>
<line fill="none" stroke="#000000" stroke-width="2.8346" stroke-linecap="round" stroke-miterlimit="10" x1="421.3" y1="258" x2="404.5" y2="241.2"/>
<line fill="none" stroke="#000000" stroke-width="2.8346" stroke-linecap="round" stroke-miterlimit="10" x1="404.5" y1="62.1" x2="421.3" y2="45.3"/>
<line fill="none" stroke="#000000" stroke-width="2.8346" stroke-linecap="round" stroke-miterlimit="10" x1="145.8" y1="258" x2="162.6" y2="241.2"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -0,0 +1,234 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.6, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Lag_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 452.1 265.4" style="enable-background:new 0 0 452.1 265.4;" xml:space="preserve">
<style type="text/css">
.st0{fill:none;stroke:#000000;stroke-width:2.8346;stroke-miterlimit:10;}
.st1{fill:#026634;}
.st2{enable-background:new ;}
.st3{fill:#FFFFFF;}
.st4{fill:#FFFFFF;stroke:#1D1E1C;stroke-width:2.8346;stroke-miterlimit:10;}
</style>
<g>
<g>
<circle class="st0" cx="22.9" cy="40.2" r="21.5"/>
<path class="st1" d="M48.1,81.9c2.8,0.9,5.7,1.8,8.5,2.7c4.2,1.3,9.5-1.2,11.3-5.3c0.2-0.5,0.4-1.1,0.7-1.6
c0.6-1.1,1.6-1.8,2.9-1.7c1.3,0.2,2.4,0.8,2.9,2.1c0.3,0.9,0.8,1.7,1.9,1.7c1.2,0.1,2-0.6,2.6-1.6c0.8-1.6,2-2.2,3.6-1.6
c1.1,0.4,2.1,0.3,3.1-0.1c1.3-0.5,2.6-1,3.9-1.5c1.6-0.7,3.1,0.1,4,1.6c1.2,2,2.2,4.3,4.7,4.9c0.8,0.2,1.2,0.9,1.6,1.5
c0.7,0.9,1.4,1.2,2.6,0.7c1.8-0.7,3.7-1.2,5.3,0.8c0.7,0.9,1.7,0.5,2.6,0.1c2.2-1,4.2-1.2,5.7,1.1c0.3,0.5,0.9,0.3,1.3,0.2
c2.6-0.8,5.2-1.7,7.7-3c1.1-0.6,1.5-1.3,1.3-2.5c-0.3-1.4-0.6-2.7-1-4.1c-0.4-1.1-1-2-2.2-2.4c-11.2-4-22.5-8-33.7-12
c-0.7-0.3-1.4-0.4-2.2-0.4c-2.4,0.1-3.1-0.9-2.5-3.1c0.3-0.9,0.9-1.8-0.1-2.7S82.7,54,81,54.6c-2.6,1-4.5-0.9-3.8-3.7
c0.5-2,0.6-4,0.1-5.9c-0.9-3.2-3.2-5.2-6.3-6.2c-6-1.7-12-3.5-17.9-5.4c-3.6-1.2-6.5-0.1-8.9,2.5c-1.1,1.2-2.2,2.2-3.6,3.1
C33.5,43.5,30.4,50.3,30,58.5c-0.2,3.3,0.1,6.5,2.1,9.3c0.3,0.4,0.2,0.9,0.2,1.4c-0.3,5,1.8,8.3,6.6,9.8
C41.9,80,45,80.9,48.1,81.9z M48,56.1c-0.8,2.5-1.6,5-2.4,7.6c-0.3,1.1-0.8,1.5-2,1.1c-2.2-0.8-4.5-1.5-6.8-2.1
c-1-0.3-1.5-0.9-1.5-1.9c-0.3-5.8,1.4-11,4.9-15.7c0.6-0.8,1.4-1,2.4-0.7c2.2,0.7,4.4,1.5,6.6,2.1c1.3,0.4,1.4,1,1,2.2
C49.5,51.2,48.8,53.7,48,56.1z"/>
<g class="st2">
<path class="st3" d="M57.4,59.3c-0.3,0.3-0.6,0.4-1,0.5c-0.4,0.1-0.9,0-1.4-0.1l-1-0.3l-0.7,2.4l-1.6-0.5l2.1-6.6l2.6,0.8
c0.5,0.2,0.9,0.4,1.2,0.7c0.3,0.3,0.5,0.6,0.6,1c0.1,0.4,0.1,0.8-0.1,1.2C57.8,58.7,57.6,59,57.4,59.3z M55.9,58.3
c0.2-0.1,0.3-0.3,0.4-0.5c0.1-0.3,0.1-0.5,0-0.7c-0.1-0.2-0.3-0.3-0.6-0.4l-0.9-0.3L54.3,58l0.9,0.3
C55.5,58.4,55.7,58.4,55.9,58.3z"/>
<path class="st3" d="M61,56.9l-1.2,3.9c-0.1,0.4-0.1,0.7,0,1c0.1,0.3,0.4,0.5,0.8,0.6c0.4,0.1,0.7,0.1,1,0
c0.3-0.1,0.5-0.4,0.6-0.8l1.2-3.9l1.6,0.5l-1.2,3.9c-0.2,0.6-0.5,1-0.8,1.4c-0.4,0.3-0.8,0.5-1.3,0.6c-0.5,0.1-1,0-1.5-0.1
s-1-0.4-1.3-0.7c-0.3-0.3-0.6-0.7-0.7-1.2c-0.1-0.5-0.1-1,0.1-1.6l1.2-3.9L61,56.9z"/>
<path class="st3" d="M69.8,63.9c0.1,0.4,0.1,0.7,0,1.1c-0.2,0.5-0.5,0.9-1,1.1c-0.5,0.2-1.1,0.2-1.8,0l-3.1-1l2.1-6.6l3,0.9
c0.7,0.2,1.1,0.5,1.4,1c0.3,0.4,0.3,0.9,0.2,1.4c-0.1,0.4-0.3,0.7-0.6,0.9c-0.3,0.2-0.6,0.3-1,0.3C69.4,63.2,69.6,63.5,69.8,63.9
z M67.8,64.7c0.2-0.1,0.3-0.2,0.4-0.5s0.1-0.4-0.1-0.6c-0.1-0.2-0.3-0.3-0.6-0.4l-1.2-0.4L66,64.3l1.2,0.4
C67.4,64.8,67.7,64.8,67.8,64.7z M66.8,61.7l1,0.3c0.3,0.1,0.5,0.1,0.7,0c0.2-0.1,0.3-0.2,0.4-0.4c0.1-0.2,0.1-0.4,0-0.6
c-0.1-0.2-0.3-0.3-0.5-0.4l-1-0.3L66.8,61.7z"/>
<path class="st3" d="M72.1,66.3l2.1,0.7l-0.4,1.2l-3.7-1.2l2.1-6.6l1.6,0.5L72.1,66.3z"/>
<path class="st3" d="M78.3,62.4L76.2,69l-1.6-0.5l2.1-6.6L78.3,62.4z"/>
<path class="st3" d="M79.1,64.4c0.4-0.4,1-0.7,1.6-0.8c0.6-0.1,1.2-0.1,1.8,0.1c0.8,0.2,1.4,0.7,1.8,1.3s0.6,1.3,0.6,2l-1.8-0.6
c0-0.3-0.2-0.6-0.4-0.8s-0.4-0.4-0.8-0.5c-0.5-0.2-0.9-0.1-1.4,0.1c-0.4,0.2-0.7,0.7-0.9,1.2c-0.2,0.6-0.2,1.1,0,1.5
c0.2,0.4,0.5,0.7,1,0.9c0.3,0.1,0.6,0.1,0.9,0c0.3-0.1,0.5-0.2,0.8-0.5l1.8,0.6c-0.4,0.7-1,1.1-1.6,1.3s-1.4,0.2-2.2,0
c-0.6-0.2-1.2-0.5-1.6-1c-0.4-0.4-0.7-1-0.8-1.6c-0.1-0.6-0.1-1.2,0.1-1.9S78.7,64.8,79.1,64.4z"/>
</g>
<path d="M54.2,47.8c3,0,5.9,0,8.9,0c4.4,0,8.7-4,9.1-8.4c0.1-0.6,0.1-1.2,0.2-1.8c0.3-1.2,1-2.2,2.3-2.5s2.5,0,3.3,1.1
c0.6,0.8,1.2,1.4,2.3,1.1c1.2-0.3,1.7-1.2,1.9-2.3c0.3-1.7,1.3-2.7,2.9-2.6c1.2,0.1,2.1-0.4,2.9-1.1c1.1-0.9,2.2-1.7,3.3-2.6
c1.3-1.1,3-0.8,4.3,0.3c1.7,1.5,3.3,3.4,6,3.3c0.8,0,1.4,0.5,2,0.9c0.9,0.6,1.7,0.8,2.7-0.1c1.5-1.2,3.2-2.3,5.3-0.8
c0.9,0.6,1.8-0.1,2.5-0.7c1.8-1.6,3.6-2.4,5.8-0.7c0.5,0.4,0.9,0.1,1.3-0.2c2.3-1.6,4.5-3.2,6.4-5.2c0.8-0.9,1.1-1.7,0.5-2.7
c-0.7-1.2-1.4-2.4-2.2-3.6c-0.7-0.9-1.6-1.6-2.8-1.6c-11.9-0.4-23.8-0.8-35.8-1.2c-0.8,0-1.5,0-2.2,0.3c-2.2,0.8-3.2,0.1-3.3-2.2
c0-0.9,0.3-2-0.9-2.5c-1.2-0.6-2.3-1-3.7,0.1c-2.2,1.7-4.6,0.5-4.8-2.3c-0.1-2-0.6-4-1.7-5.7C69,1.1,66.3,0,63,0
c-6.2,0-12.4,0.1-18.6,0c-3.8-0.1-6.2,1.8-7.8,5c-0.7,1.5-1.5,2.8-2.5,4.1c-5.5,6.5-6.3,13.9-4.2,21.8c0.8,3.2,2,6.2,4.8,8.2
c0.4,0.3,0.5,0.8,0.6,1.3c1.2,4.9,4.2,7.3,9.2,7.4C47.7,47.8,50.9,47.8,54.2,47.8z M46.3,23.3c0,2.6,0,5.3,0,7.9
c0,1.1-0.3,1.7-1.6,1.7c-2.4,0-4.7,0-7.1,0c-1,0-1.7-0.4-2-1.3c-2-5.5-2-10.9,0-16.4c0.4-1,1-1.4,2.1-1.4c2.3,0,4.6,0.1,6.9,0
c1.3,0,1.7,0.6,1.7,1.8C46.2,18.1,46.3,20.7,46.3,23.3z"/>
<g class="st2">
<path class="st3" d="M56.2,23.5c-0.2,0.3-0.5,0.6-0.8,0.8s-0.9,0.3-1.4,0.3h-1V27h-1.7v-6.9h2.7c0.5,0,1,0.1,1.4,0.3
c0.4,0.2,0.7,0.5,0.9,0.8c0.2,0.3,0.3,0.7,0.3,1.1C56.4,22.8,56.4,23.1,56.2,23.5z M54.5,23c0.2-0.2,0.2-0.4,0.2-0.6
c0-0.3-0.1-0.5-0.2-0.6c-0.2-0.2-0.4-0.2-0.7-0.2h-0.9v1.7h0.9C54.1,23.2,54.3,23.2,54.5,23z"/>
<path class="st3" d="M60.8,27l-1.4-2.6H59V27h-1.7v-6.9h2.8c0.5,0,1,0.1,1.4,0.3c0.4,0.2,0.7,0.5,0.9,0.8
c0.2,0.3,0.3,0.7,0.3,1.1c0,0.5-0.1,0.9-0.4,1.2s-0.6,0.6-1.1,0.8l1.6,2.7H60.8z M59,23.3h1c0.3,0,0.5-0.1,0.7-0.2
c0.2-0.2,0.2-0.4,0.2-0.6c0-0.3-0.1-0.5-0.2-0.6s-0.4-0.2-0.7-0.2h-1V23.3z"/>
<path class="st3" d="M65.4,20.1V27h-1.7v-6.9H65.4z"/>
<path class="st3" d="M73.1,20.1L70.6,27h-2.1l-2.4-6.9h1.8l1.7,5.2l1.7-5.2H73.1z"/>
<path class="st3" d="M78.1,25.8h-2.6L75.1,27h-1.8l2.5-6.9h1.9l2.5,6.9h-1.8L78.1,25.8z M77.7,24.5L76.8,22L76,24.5H77.7z"/>
<path class="st3" d="M86,20.1v1.3h-1.8V27h-1.7v-5.6h-1.8v-1.3H86z"/>
<path class="st3" d="M88.5,21.5v1.4h2.2v1.3h-2.2v1.5h2.5V27h-4.2v-6.9h4.2v1.3H88.5z"/>
</g>
</g>
<g>
<circle class="st0" cx="25.1" cy="134.5" r="21.5"/>
<path class="st1" d="M50.3,176.3c2.8,0.9,5.7,1.8,8.5,2.7c4.2,1.3,9.5-1.2,11.3-5.3c0.2-0.5,0.4-1.1,0.7-1.6
c0.6-1.1,1.6-1.8,2.9-1.7c1.3,0.2,2.4,0.8,2.9,2.1c0.3,0.9,0.8,1.7,1.9,1.7c1.2,0.1,2-0.6,2.6-1.6c0.8-1.6,2-2.2,3.6-1.6
c1.1,0.4,2.1,0.3,3.1-0.1c1.3-0.5,2.6-1,3.9-1.5c1.6-0.7,3.1,0.1,4,1.6c1.2,2,2.2,4.3,4.7,4.9c0.8,0.2,1.2,0.9,1.6,1.5
c0.7,0.9,1.4,1.2,2.6,0.7c1.8-0.7,3.7-1.2,5.3,0.8c0.7,0.9,1.7,0.5,2.6,0.1c2.2-1,4.2-1.2,5.7,1.1c0.3,0.5,0.9,0.3,1.3,0.2
c2.6-0.8,5.2-1.7,7.7-3c1.1-0.6,1.5-1.3,1.3-2.5c-0.3-1.4-0.6-2.7-1-4.1c-0.4-1.1-1-2-2.2-2.4c-11.2-4-22.5-8-33.7-12
c-0.7-0.3-1.4-0.4-2.2-0.4c-2.4,0.1-3.1-0.9-2.5-3.1c0.3-0.9,0.9-1.8-0.1-2.7s-1.9-1.7-3.6-1.1c-2.6,1-4.5-0.9-3.8-3.7
c0.5-2,0.6-4,0.1-5.9c-0.9-3.2-3.2-5.2-6.3-6.2c-5.9-1.8-11.9-3.6-17.8-5.6c-3.6-1.2-6.5-0.1-8.9,2.5c-1.1,1.2-2.2,2.2-3.6,3.1
c-7.1,4.5-10.2,11.3-10.6,19.5c-0.2,3.3,0.1,6.5,2.1,9.3c0.3,0.4,0.2,0.9,0.2,1.4c-0.3,5,1.8,8.3,6.6,9.8
C44.1,174.3,47.2,175.3,50.3,176.3z M50.2,150.5c-0.8,2.5-1.6,5-2.4,7.6c-0.3,1.1-0.8,1.5-2,1.1c-2.2-0.8-4.5-1.5-6.8-2.1
c-1-0.3-1.5-0.9-1.5-1.9c-0.3-5.8,1.4-11,4.9-15.7c0.6-0.8,1.4-1,2.4-0.7c2.2,0.7,4.4,1.5,6.6,2.1c1.3,0.4,1.4,1,1,2.2
C51.7,145.6,51,148,50.2,150.5z"/>
<g class="st2">
<path class="st3" d="M59.6,153.6c-0.3,0.3-0.6,0.4-1,0.5s-0.9,0-1.4-0.1l-1-0.3l-0.7,2.4l-1.6-0.5l2.1-6.6l2.6,0.8
c0.5,0.2,0.9,0.4,1.2,0.7c0.3,0.3,0.5,0.6,0.6,1c0.1,0.4,0.1,0.8-0.1,1.2C60.1,153.1,59.9,153.4,59.6,153.6z M58.1,152.7
c0.2-0.1,0.3-0.3,0.4-0.5c0.1-0.3,0.1-0.5,0-0.7c-0.1-0.2-0.3-0.3-0.6-0.4l-0.9-0.3l-0.5,1.6l0.9,0.3
C57.7,152.8,57.9,152.8,58.1,152.7z"/>
<path class="st3" d="M63.3,151.3l-1.2,3.9c-0.1,0.4-0.1,0.7,0,1c0.1,0.3,0.4,0.5,0.8,0.6c0.4,0.1,0.7,0.1,1,0
c0.3-0.1,0.5-0.4,0.6-0.8l1.2-3.9l1.6,0.5l-1.2,3.9c-0.2,0.6-0.5,1-0.8,1.4c-0.4,0.3-0.8,0.5-1.3,0.6c-0.5,0.1-1,0-1.5-0.1
s-1-0.4-1.3-0.7c-0.3-0.3-0.6-0.7-0.7-1.2c-0.1-0.5-0.1-1,0.1-1.6l1.2-3.9L63.3,151.3z"/>
<path class="st3" d="M72,158.2c0.1,0.4,0.1,0.7,0,1.1c-0.2,0.5-0.5,0.9-1,1.1c-0.5,0.2-1.1,0.2-1.8,0l-3.1-1l2.1-6.6l3,0.9
c0.7,0.2,1.1,0.5,1.4,1c0.3,0.4,0.3,0.9,0.2,1.4c-0.1,0.4-0.3,0.7-0.6,0.9c-0.3,0.2-0.6,0.3-1,0.3
C71.6,157.6,71.9,157.9,72,158.2z M70.1,159.1c0.2-0.1,0.3-0.2,0.4-0.5c0.1-0.2,0.1-0.4-0.1-0.6c-0.1-0.2-0.3-0.3-0.6-0.4
l-1.2-0.4l-0.5,1.5l1.2,0.4C69.7,159.2,69.9,159.2,70.1,159.1z M69,156.1l1,0.3c0.3,0.1,0.5,0.1,0.7,0s0.3-0.2,0.4-0.4
c0.1-0.2,0.1-0.4,0-0.6c-0.1-0.2-0.3-0.3-0.5-0.4l-1-0.3L69,156.1z"/>
<path class="st3" d="M74.4,160.7l2.1,0.7l-0.4,1.2l-3.7-1.2l2.1-6.6l1.6,0.5L74.4,160.7z"/>
<path class="st3" d="M80.5,156.8l-2.1,6.6l-1.6-0.5l2.1-6.6L80.5,156.8z"/>
<path class="st3" d="M81.4,158.7c0.4-0.4,1-0.7,1.6-0.8c0.6-0.1,1.2-0.1,1.8,0.1c0.8,0.2,1.4,0.7,1.8,1.3c0.4,0.6,0.6,1.3,0.6,2
l-1.8-0.6c0-0.3-0.2-0.6-0.4-0.8c-0.2-0.2-0.4-0.4-0.8-0.5c-0.5-0.2-0.9-0.1-1.4,0.1c-0.4,0.2-0.7,0.7-0.9,1.2s-0.2,1.1,0,1.5
c0.2,0.4,0.5,0.7,1,0.9c0.3,0.1,0.6,0.1,0.9,0c0.3-0.1,0.5-0.2,0.8-0.5l1.8,0.6c-0.4,0.7-1,1.1-1.6,1.3c-0.7,0.2-1.4,0.2-2.2,0
c-0.6-0.2-1.2-0.5-1.6-1s-0.7-1-0.8-1.6c-0.1-0.6-0.1-1.2,0.1-1.9C80.6,159.7,80.9,159.2,81.4,158.7z"/>
</g>
<path d="M56.4,142.2c3,0,5.9,0,8.9,0c4.4,0,8.7-4,9.1-8.4c0.1-0.6,0.1-1.2,0.2-1.8c0.3-1.2,1-2.2,2.3-2.5s2.5,0,3.3,1.1
c0.6,0.8,1.2,1.4,2.3,1.1c1.2-0.3,1.7-1.2,1.9-2.3c0.3-1.7,1.3-2.7,2.9-2.6c1.2,0.1,2.1-0.4,2.9-1.1c1.1-0.9,2.2-1.7,3.3-2.6
c1.3-1.1,3-0.8,4.3,0.3c1.7,1.5,3.3,3.4,6,3.3c0.8,0,1.4,0.5,2,0.9c0.9,0.6,1.7,0.8,2.7-0.1c1.5-1.2,3.2-2.3,5.3-0.8
c0.9,0.6,1.8-0.1,2.5-0.7c1.8-1.6,3.6-2.4,5.8-0.7c0.5,0.4,0.9,0.1,1.3-0.2c2.3-1.6,4.5-3.2,6.4-5.2c0.8-0.9,1.1-1.7,0.5-2.7
c-0.7-1.2-1.4-2.4-2.2-3.6c-0.7-0.9-1.6-1.6-2.8-1.6c-11.9-0.4-23.8-0.8-35.8-1.2c-0.8,0-1.5,0-2.2,0.3c-2.2,0.8-3.2,0.1-3.3-2.2
c0-0.9,0.3-2-0.9-2.5c-1.2-0.6-2.3-1-3.7,0.1c-2.2,1.7-4.6,0.5-4.8-2.3c-0.1-2-0.6-4-1.7-5.7c-1.8-2.8-4.6-4-7.9-4
c-6.2,0-12.4,0.1-18.6,0c-3.8-0.1-6.2,1.8-7.8,5c-0.7,1.5-1.5,2.8-2.5,4.1c-5.5,6.5-6.3,13.9-4.2,21.8c0.8,3.2,2,6.2,4.8,8.2
c0.4,0.3,0.5,0.8,0.6,1.3c1.2,4.9,4.2,7.3,9.2,7.4C49.9,142.2,53.2,142.2,56.4,142.2z M48.5,117.7c0,2.6,0,5.3,0,7.9
c0,1.1-0.3,1.7-1.6,1.7c-2.4,0-4.7,0-7.1,0c-1,0-1.7-0.4-2-1.3c-2-5.5-2-10.9,0-16.4c0.4-1,1-1.4,2.1-1.4c2.3,0,4.6,0.1,6.9,0
c1.3,0,1.7,0.6,1.7,1.8C48.5,112.5,48.5,115.1,48.5,117.7z"/>
<g class="st2">
<path class="st3" d="M58.4,117.8c-0.2,0.3-0.5,0.6-0.8,0.8s-0.9,0.3-1.4,0.3h-1v2.5h-1.7v-6.9h2.7c0.5,0,1,0.1,1.4,0.3
c0.4,0.2,0.7,0.5,0.9,0.8c0.2,0.3,0.3,0.7,0.3,1.1C58.7,117.1,58.6,117.5,58.4,117.8z M56.7,117.4c0.2-0.2,0.2-0.4,0.2-0.6
c0-0.3-0.1-0.5-0.2-0.6c-0.2-0.2-0.4-0.2-0.7-0.2h-0.9v1.7H56C56.3,117.6,56.6,117.5,56.7,117.4z"/>
<path class="st3" d="M63.1,121.4l-1.4-2.6h-0.4v2.6h-1.7v-6.9h2.8c0.5,0,1,0.1,1.4,0.3c0.4,0.2,0.7,0.5,0.9,0.8
c0.2,0.3,0.3,0.7,0.3,1.1c0,0.5-0.1,0.9-0.4,1.2s-0.6,0.6-1.1,0.8l1.6,2.7H63.1z M61.2,117.6h1c0.3,0,0.5-0.1,0.7-0.2
c0.2-0.2,0.2-0.4,0.2-0.6c0-0.3-0.1-0.5-0.2-0.6c-0.2-0.2-0.4-0.2-0.7-0.2h-1V117.6z"/>
<path class="st3" d="M67.6,114.5v6.9H66v-6.9H67.6z"/>
<path class="st3" d="M75.3,114.5l-2.4,6.9h-2.1l-2.4-6.9h1.8l1.7,5.2l1.7-5.2H75.3z"/>
<path class="st3" d="M80.3,120.2h-2.6l-0.4,1.2h-1.8l2.5-6.9H80l2.5,6.9h-1.8L80.3,120.2z M79.9,118.9l-0.9-2.5l-0.8,2.5H79.9z"
/>
<path class="st3" d="M88.2,114.5v1.3h-1.8v5.6h-1.7v-5.6h-1.8v-1.3H88.2z"/>
<path class="st3" d="M90.8,115.9v1.4H93v1.3h-2.2v1.5h2.5v1.3h-4.2v-6.9h4.2v1.3H90.8z"/>
</g>
</g>
<g>
<circle class="st0" cx="25.1" cy="219.6" r="21.5"/>
<path class="st1" d="M50.3,261.3c2.8,0.9,5.7,1.8,8.5,2.7c4.2,1.3,9.5-1.2,11.3-5.3c0.2-0.5,0.4-1.1,0.7-1.6
c0.6-1.1,1.6-1.8,2.9-1.7c1.3,0.2,2.4,0.8,2.9,2.1c0.3,0.9,0.8,1.7,1.9,1.7c1.2,0.1,2-0.6,2.6-1.6c0.8-1.6,2-2.2,3.6-1.6
c1.1,0.4,2.1,0.3,3.1-0.1c1.3-0.5,2.6-1,3.9-1.5c1.6-0.7,3.1,0.1,4,1.6c1.2,2,2.2,4.3,4.7,4.9c0.8,0.2,1.2,0.9,1.6,1.5
c0.7,0.9,1.4,1.2,2.6,0.7c1.8-0.7,3.7-1.2,5.3,0.8c0.7,0.9,1.7,0.5,2.6,0.1c2.2-1,4.2-1.2,5.7,1.1c0.3,0.5,0.9,0.3,1.3,0.2
c2.6-0.8,5.2-1.7,7.7-3c1.1-0.6,1.5-1.3,1.3-2.5c-0.3-1.4-0.6-2.7-1-4.1c-0.4-1.1-1-2-2.2-2.4c-11.2-4-22.5-8-33.7-12
c-0.7-0.3-1.4-0.4-2.2-0.4c-2.4,0.1-3.1-0.9-2.5-3.1c0.3-0.9,0.9-1.8-0.1-2.7s-1.9-1.7-3.6-1.1c-2.6,1-4.5-0.9-3.8-3.7
c0.5-2,0.6-4,0.1-5.9c-0.9-3.2-3.2-5.2-6.3-6.2c-5.9-1.8-11.9-3.6-17.8-5.6c-3.6-1.2-6.5-0.1-8.9,2.5c-1.1,1.2-2.2,2.2-3.6,3.1
c-7.1,4.5-10.2,11.3-10.6,19.5c-0.2,3.3,0.1,6.5,2.1,9.3c0.3,0.4,0.2,0.9,0.2,1.4c-0.3,5,1.8,8.3,6.6,9.8
C44.1,259.4,47.2,260.3,50.3,261.3z M50.2,235.6c-0.8,2.5-1.6,5-2.4,7.6c-0.3,1.1-0.8,1.5-2,1.1c-2.2-0.8-4.5-1.5-6.8-2.1
c-1-0.3-1.5-0.9-1.5-1.9c-0.3-5.8,1.4-11,4.9-15.7c0.6-0.8,1.4-1,2.4-0.7c2.2,0.7,4.4,1.5,6.6,2.1c1.3,0.4,1.4,1,1,2.2
C51.7,230.6,51,233.1,50.2,235.6z"/>
<g class="st2">
<path class="st3" d="M59.6,238.7c-0.3,0.3-0.6,0.4-1,0.5c-0.4,0.1-0.9,0-1.4-0.1l-1-0.3l-0.7,2.4l-1.6-0.5l2.1-6.6l2.6,0.8
c0.5,0.2,0.9,0.4,1.2,0.7c0.3,0.3,0.5,0.6,0.6,1c0.1,0.4,0.1,0.8-0.1,1.2C60.1,238.1,59.9,238.4,59.6,238.7z M58.1,237.8
c0.2-0.1,0.3-0.3,0.4-0.5c0.1-0.3,0.1-0.5,0-0.7c-0.1-0.2-0.3-0.3-0.6-0.4l-0.9-0.3l-0.5,1.6l0.9,0.3
C57.7,237.9,57.9,237.9,58.1,237.8z"/>
<path class="st3" d="M63.3,236.4l-1.2,3.9c-0.1,0.4-0.1,0.7,0,1c0.1,0.3,0.4,0.5,0.8,0.6c0.4,0.1,0.7,0.1,1,0
c0.3-0.1,0.5-0.4,0.6-0.8l1.2-3.9l1.6,0.5l-1.2,3.9c-0.2,0.6-0.5,1-0.8,1.4s-0.8,0.5-1.3,0.6c-0.5,0.1-1,0-1.5-0.1
s-1-0.4-1.3-0.7c-0.3-0.3-0.6-0.7-0.7-1.2c-0.1-0.5-0.1-1,0.1-1.6l1.2-3.9L63.3,236.4z"/>
<path class="st3" d="M72,243.3c0.1,0.4,0.1,0.7,0,1.1c-0.2,0.5-0.5,0.9-1,1.1c-0.5,0.2-1.1,0.2-1.8,0l-3.1-1l2.1-6.6l3,0.9
c0.7,0.2,1.1,0.5,1.4,1s0.3,0.9,0.2,1.4c-0.1,0.4-0.3,0.7-0.6,0.9c-0.3,0.2-0.6,0.3-1,0.3C71.6,242.6,71.9,242.9,72,243.3z
M70.1,244.1c0.2-0.1,0.3-0.2,0.4-0.5c0.1-0.2,0.1-0.4-0.1-0.6c-0.1-0.2-0.3-0.3-0.6-0.4l-1.2-0.4l-0.5,1.5l1.2,0.4
C69.7,244.2,69.9,244.2,70.1,244.1z M69,241.1l1,0.3c0.3,0.1,0.5,0.1,0.7,0c0.2-0.1,0.3-0.2,0.4-0.4c0.1-0.2,0.1-0.4,0-0.6
c-0.1-0.2-0.3-0.3-0.5-0.4l-1-0.3L69,241.1z"/>
<path class="st3" d="M74.4,245.8l2.1,0.7l-0.4,1.2l-3.7-1.2l2.1-6.6l1.6,0.5L74.4,245.8z"/>
<path class="st3" d="M80.5,241.8l-2.1,6.6l-1.6-0.5l2.1-6.6L80.5,241.8z"/>
<path class="st3" d="M81.4,243.8c0.4-0.4,1-0.7,1.6-0.8c0.6-0.1,1.2-0.1,1.8,0.1c0.8,0.2,1.4,0.7,1.8,1.3s0.6,1.3,0.6,2l-1.8-0.6
c0-0.3-0.2-0.6-0.4-0.8c-0.2-0.2-0.4-0.4-0.8-0.5c-0.5-0.2-0.9-0.1-1.4,0.1c-0.4,0.2-0.7,0.7-0.9,1.2s-0.2,1.1,0,1.5
c0.2,0.4,0.5,0.7,1,0.9c0.3,0.1,0.6,0.1,0.9,0c0.3-0.1,0.5-0.2,0.8-0.5l1.8,0.6c-0.4,0.7-1,1.1-1.6,1.3c-0.7,0.2-1.4,0.2-2.2,0
c-0.6-0.2-1.2-0.5-1.6-1c-0.4-0.4-0.7-1-0.8-1.6c-0.1-0.6-0.1-1.2,0.1-1.9C80.6,244.8,80.9,244.2,81.4,243.8z"/>
</g>
</g>
</g>
<g>
<g>
<path class="st4" d="M445.5,158.1h-70c-2.8,0-5.1-2.3-5.1-5.1v-41.8c0-2.8,2.3-5.1,5.1-5.1h70c2.8,0,5.1,2.3,5.1,5.1V153
C450.6,155.8,448.4,158.1,445.5,158.1z"/>
<path class="st4" d="M365.8,206.3H177c-7.8,0-14.2-6.3-14.2-14.2v-120c0-7.8,6.3-14.2,14.2-14.2h188.8c7.8,0,14.2,6.3,14.2,14.2
v120C380,199.9,373.6,206.3,365.8,206.3z"/>
</g>
<path d="M270.3,158.9c-4.5,0-9.1,0-13.6,0c-2.8,0-2.8,0-2.8-2.8c0-7.4,0-14.8,0-22.2c0-1.8,0-1.8,1.8-1.8c7.2,0,14.5,0,21.7,0
c1.3,0,1.7-0.4,1.7-1.7c-0.1-5.4-0.1-10.7,0-16.1c0-5.9,4.1-11.6,9.5-13.6c6.8-2.5,14.5,0.8,17.5,7.6c1,2.2,1.5,4.5,1.5,6.9
c0,4.5,0,8.9,0,13.4c0,1-0.1,2.1-1.1,2.3c-1.2,0.3-2.6,0.5-3.7-0.4c-0.5-0.4-0.6-1-0.5-1.6c0.1-0.7,0.7-0.6,1.2-0.7
c1-0.2,1.4-0.9,0.6-1.4c-2.2-1.4-1.8-3.5-1.8-5.6c0-2.4,0.1-4.7-0.1-7.1c-0.3-3.7-2.2-6.5-5.7-7.9c-3.2-1.3-6.3-0.8-8.9,1.5
c-1.9,1.6-2.9,3.7-3.2,6.2c-0.3,3.2-0.2,6.4-0.1,9.6c0,1.3-0.3,2.3-1.2,3.2c-0.9,0.8-0.8,1.2,0.4,1.5c0.6,0.2,0.8,0.5,0.8,1.1
c0,0.5,0,1,0,1.5c0,0.8,0.3,1.2,1.1,1.2c1.1-0.1,1.4,0.5,1.4,1.5c0,7.8,0,15.7,0,23.5c0,1.5-0.2,1.7-2.1,1.8
c-3.4,0.1-6.8,0.1-10.1,0.1C273.1,159,271.7,159,270.3,158.9L270.3,158.9z"/>
<g class="st2">
<path d="M231.2,85.2c1.8-1.5,3.2-2.7,4.3-3.7c1-1,1.9-2,2.6-3c0.7-1,1.1-2.1,1.1-3.1c0-0.8-0.2-1.3-0.5-1.8
c-0.3-0.4-0.9-0.6-1.6-0.6c-0.7,0-1.2,0.3-1.6,0.8c-0.4,0.5-0.6,1.3-0.6,2.2h-4.5c0-1.6,0.4-2.9,1-3.9c0.6-1,1.5-1.8,2.5-2.3
c1-0.5,2.2-0.7,3.5-0.7c2.2,0,3.8,0.6,4.9,1.7c1.1,1.1,1.7,2.6,1.7,4.4c0,2-0.7,3.8-2,5.5s-3,3.3-5.1,4.9h7.4v3.8h-13.8v-3.5
C230.9,85.4,231.2,85.2,231.2,85.2z"/>
<path d="M258.5,78.1V82h-12.1v-3.9H258.5z"/>
<path d="M265.6,88.9c-1.2-0.6-2.1-1.6-2.8-2.8s-1-2.6-1-4.2c0-1.6,0.3-3,1-4.2c0.7-1.2,1.7-2.1,2.9-2.8c1.2-0.6,2.6-1,4.1-1
s2.9,0.3,4.1,1c1.2,0.6,2.2,1.6,2.9,2.8c0.7,1.2,1,2.6,1,4.2c0,1.6-0.4,3-1.1,4.2c-0.7,1.2-1.7,2.1-2.9,2.8c-1.2,0.6-2.6,1-4.1,1
S266.8,89.6,265.6,88.9z M271.9,84.8c0.6-0.7,1-1.6,1-2.8c0-1.2-0.3-2.2-0.9-2.8c-0.6-0.7-1.4-1-2.3-1c-0.9,0-1.7,0.3-2.3,1
c-0.6,0.7-0.9,1.6-0.9,2.8c0,1.2,0.3,2.2,0.9,2.8c0.6,0.7,1.3,1,2.2,1S271.3,85.5,271.9,84.8z"/>
<path d="M287.9,78.2h-2.5v11.5h-4.7V78.2h-1.7v-3.9h1.7v-0.4c0-1.9,0.5-3.3,1.6-4.3c1.1-1,2.7-1.5,4.8-1.5c0.3,0,0.6,0,0.8,0v4
c-0.9-0.1-1.5,0.1-1.9,0.4c-0.4,0.3-0.6,0.9-0.6,1.7v0.1h2.5V78.2z"/>
<path d="M301.9,78.1V82h-12.1v-3.9H301.9z"/>
<path d="M307.7,70.7c1.2-1.1,2.9-1.6,4.9-1.6c1.4,0,2.6,0.2,3.5,0.7c1,0.5,1.7,1.1,2.2,2s0.8,1.8,0.8,2.8c0,1.2-0.3,2.2-0.9,3
s-1.3,1.3-2.1,1.6v0.1c1,0.3,1.9,0.9,2.5,1.7s0.9,1.8,0.9,3.1c0,1.1-0.3,2.1-0.8,3s-1.3,1.6-2.3,2.1c-1,0.5-2.2,0.7-3.6,0.7
c-2.2,0-4-0.5-5.3-1.6s-2-2.7-2.1-4.9h4.6c0,0.8,0.2,1.4,0.7,1.9s1.1,0.7,1.9,0.7c0.7,0,1.3-0.2,1.7-0.6c0.4-0.4,0.6-1,0.6-1.6
c0-0.9-0.3-1.5-0.8-1.9c-0.6-0.4-1.5-0.6-2.7-0.6h-0.9v-3.8h0.9c0.9,0,1.7-0.2,2.3-0.5c0.6-0.3,0.9-0.9,0.9-1.7
c0-0.7-0.2-1.2-0.6-1.5s-0.9-0.6-1.5-0.6c-0.7,0-1.2,0.2-1.6,0.6c-0.3,0.4-0.5,0.9-0.6,1.6h-4.6C305.8,73.3,306.5,71.8,307.7,70.7
z"/>
</g>
<g class="st2">
<path d="M242.3,177c1.1,1.2,1.7,2.8,1.7,4.8v9h-4.7v-8.3c0-1-0.3-1.8-0.8-2.3c-0.5-0.5-1.2-0.8-2.2-0.8s-1.6,0.3-2.2,0.8
c-0.5,0.5-0.8,1.3-0.8,2.3v8.3h-4.7v-8.3c0-1-0.3-1.8-0.8-2.3c-0.5-0.5-1.2-0.8-2.2-0.8c-0.9,0-1.6,0.3-2.2,0.8
c-0.5,0.5-0.8,1.3-0.8,2.3v8.3h-4.7v-15.4h4.7v1.9c0.5-0.6,1.1-1.2,1.9-1.5c0.8-0.4,1.6-0.6,2.6-0.6c1.2,0,2.2,0.2,3.1,0.7
c0.9,0.5,1.6,1.2,2.1,2.1c0.5-0.8,1.3-1.5,2.2-2.1c0.9-0.5,1.9-0.8,3-0.8C239.7,175.3,241.2,175.9,242.3,177z"/>
<path d="M262.5,175.4v15.4h-4.7v-2.1c-0.5,0.7-1.1,1.2-1.9,1.6c-0.8,0.4-1.7,0.6-2.7,0.6c-1.2,0-2.2-0.3-3.1-0.8
c-0.9-0.5-1.6-1.3-2.1-2.3c-0.5-1-0.7-2.2-0.7-3.5v-9h4.7v8.3c0,1,0.3,1.8,0.8,2.4c0.5,0.6,1.2,0.9,2.1,0.9c0.9,0,1.6-0.3,2.2-0.9
c0.5-0.6,0.8-1.4,0.8-2.4v-8.3H262.5z"/>
<path d="M270.6,170.4v20.4h-4.7v-20.4H270.6z"/>
<path d="M282.6,186.8v4h-2.4c-1.7,0-3-0.4-4-1.3c-1-0.8-1.4-2.2-1.4-4.1v-6.1h-1.9v-3.9h1.9v-3.7h4.7v3.7h3.1v3.9h-3.1v6.2
c0,0.5,0.1,0.8,0.3,1c0.2,0.2,0.6,0.3,1.1,0.3H282.6z"/>
<path d="M285.5,173.1c-0.5-0.5-0.8-1.1-0.8-1.8c0-0.7,0.3-1.3,0.8-1.8s1.2-0.7,2-0.7c0.8,0,1.5,0.2,2,0.7c0.5,0.5,0.8,1.1,0.8,1.8
c0,0.7-0.3,1.3-0.8,1.8c-0.5,0.5-1.2,0.7-2,0.7C286.7,173.9,286.1,173.6,285.5,173.1z M289.9,175.4v15.4h-4.7v-15.4H289.9z"/>
<path d="M296,190.3c-1-0.5-1.9-1.1-2.5-1.9c-0.6-0.8-0.9-1.7-1-2.7h4.7c0.1,0.5,0.3,1,0.7,1.3s1,0.5,1.6,0.5c0.6,0,1-0.1,1.4-0.3
s0.5-0.5,0.5-0.9c0-0.4-0.2-0.8-0.7-1c-0.5-0.2-1.2-0.4-2.2-0.7c-1.1-0.3-2-0.5-2.8-0.8c-0.7-0.3-1.4-0.7-1.9-1.3S293,181,293,180
c0-0.9,0.2-1.7,0.7-2.4c0.5-0.7,1.2-1.3,2.1-1.7c0.9-0.4,2.1-0.6,3.4-0.6c1.9,0,3.4,0.5,4.6,1.4c1.1,1,1.7,2.2,1.9,3.8h-4.4
c-0.1-0.5-0.3-1-0.7-1.3s-0.9-0.5-1.6-0.5c-0.6,0-1,0.1-1.3,0.3c-0.3,0.2-0.4,0.5-0.4,0.9c0,0.4,0.2,0.8,0.7,1
c0.5,0.2,1.2,0.4,2.2,0.7c1.1,0.3,2.1,0.6,2.8,0.9c0.7,0.3,1.3,0.7,1.9,1.4c0.5,0.6,0.8,1.5,0.8,2.5c0,0.9-0.3,1.7-0.8,2.4
c-0.5,0.7-1.2,1.3-2.2,1.7c-0.9,0.4-2,0.6-3.3,0.6C298.2,191,297,190.8,296,190.3z"/>
<path d="M309,173.1c-0.5-0.5-0.8-1.1-0.8-1.8c0-0.7,0.3-1.3,0.8-1.8s1.2-0.7,2-0.7c0.8,0,1.5,0.2,2,0.7c0.5,0.5,0.8,1.1,0.8,1.8
c0,0.7-0.3,1.3-0.8,1.8c-0.5,0.5-1.2,0.7-2,0.7C310.2,173.9,309.5,173.6,309,173.1z M313.4,175.4v15.4h-4.7v-15.4H313.4z"/>
<path d="M325.5,175.9c0.8,0.4,1.4,1,1.9,1.7v-2.2h4.7v15.3c0,1.4-0.3,2.7-0.8,3.8c-0.6,1.1-1.4,2.1-2.6,2.7c-1.1,0.7-2.6,1-4.3,1
c-2.3,0-4.1-0.5-5.5-1.6c-1.4-1.1-2.2-2.5-2.4-4.4h4.7c0.1,0.6,0.5,1.1,1,1.4c0.5,0.3,1.2,0.5,2,0.5c1,0,1.7-0.3,2.3-0.8
c0.6-0.6,0.9-1.5,0.9-2.7v-2.2c-0.5,0.7-1.1,1.3-1.9,1.7s-1.8,0.7-2.8,0.7c-1.3,0-2.4-0.3-3.4-1c-1-0.7-1.8-1.6-2.4-2.8
c-0.6-1.2-0.9-2.6-0.9-4.2c0-1.6,0.3-3,0.9-4.2c0.6-1.2,1.4-2.1,2.4-2.8c1-0.6,2.2-1,3.4-1C323.7,175.2,324.7,175.4,325.5,175.9z
M326.4,180.3c-0.7-0.7-1.4-1-2.4-1c-0.9,0-1.7,0.3-2.4,1s-1,1.6-1,2.8c0,1.2,0.3,2.1,1,2.8c0.7,0.7,1.4,1,2.4,1
c0.9,0,1.7-0.3,2.4-1s1-1.6,1-2.8C327.4,182,327,181,326.4,180.3z"/>
</g>
<g>
<circle class="st0" cx="427.6" cy="132.1" r="11.9"/>
<circle cx="427.6" cy="132.1" r="4.3"/>
</g>
<g>
<circle cx="337.1" cy="132.1" r="11.9"/>
<circle class="st3" cx="337.1" cy="132.1" r="4.3"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 20 KiB

BIN
static/img/nfcandroid0.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

BIN
static/img/nfcandroid1.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

BIN
static/img/nfcandroid2.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

BIN
static/img/nfcandroid3.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
static/img/nfcandroid4.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
static/img/nfcandroid5.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
static/img/nfccomplete.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

BIN
static/img/nfciphone0.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Some files were not shown because too many files have changed in this diff Show More