Giter VIP home page Giter VIP logo

gui-qml's People

Contributors

achow101 avatar ajtowns avatar dongcarl avatar fanquake avatar furszy avatar gavinandresen avatar glozow avatar gmaxwell avatar hebasto avatar instagibbs avatar jamesob avatar jarolrod avatar jnewbery avatar jonasschnelli avatar jonatack avatar laanwj avatar luke-jr avatar meshcollider avatar morcos avatar non-github-bitcoin avatar practicalswift avatar promag avatar ryanofsky avatar sdaftuar avatar sipa avatar sjors avatar thebluematt avatar thestack avatar theuni avatar vasild avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gui-qml's Issues

Brainstorm: On the loading of pages within a view container and focus policies

When the OnboardingWizard is loaded, all pages within are all loaded. This has implications for tab functionality and accessibility features like screen readers.

If all pages are loaded, then by default; tabbing can go onto other pages that are not in view essentially making tabbing useless, and screenreader can go off the page, also making them useless.

It appears we have two options to address this:

Option A: Only load one page at a time

We can edit/choose containers that will only have one page loaded at a time. The action of continuing to the next page or going back to a previous page will be responsible for containing the logic that will allow for the correct animation to show.

The SwipeView documentation contains info on how to limit the amount of pages loaded, and

OPTION-A

Option B: Make a hard boundary between pages

We can make hard boundaries between pages by playing around with focus policies (maybe): https://doc.qt.io/qt-6/qtquick-input-focus.html

I'm not so clear on how we would accomplish this one, but conceptually it's possible.

OPTION-B

Guix builds status

For the current main branch (2aa44e6) Guix builds for riscv64-linux-gnu and x86_64-w64-mingw32 failed.

For other platforms:

$ find guix-build-$(git rev-parse --short=12 HEAD)/output/ -type f -print0 | env LC_ALL=C sort -z | xargs -r0 sha256sum
635b24cf8bd83be192f52f595f936fff42a84e9d556cdfb956f4c69bda20698c  guix-build-2aa44e608ac7/output/aarch64-linux-gnu/SHA256SUMS.part
6e8776d85ed710ebaac8d1af9da81506eb4e4fc8ad9205ef12ac71bee3ec149e  guix-build-2aa44e608ac7/output/aarch64-linux-gnu/bitcoin-2aa44e608ac7-aarch64-linux-gnu-debug.tar.gz
12cf8d96230f2db389055dcf5409593556bffb54e2bcd4cff645a7e6a730b90e  guix-build-2aa44e608ac7/output/aarch64-linux-gnu/bitcoin-2aa44e608ac7-aarch64-linux-gnu.tar.gz
294c451b8e2ab3951520d53da04788048ea2d73aea8ba801aba34f51a860faa5  guix-build-2aa44e608ac7/output/arm-linux-gnueabihf/SHA256SUMS.part
6cff26db488213fa1351cb58f6eda11ccf752d7255af104a4c4ed288eb35771c  guix-build-2aa44e608ac7/output/arm-linux-gnueabihf/bitcoin-2aa44e608ac7-arm-linux-gnueabihf-debug.tar.gz
0165da9cf4427a91f5532eb035a433d0c9951d17fc2bed2e9c0c85d61c2da361  guix-build-2aa44e608ac7/output/arm-linux-gnueabihf/bitcoin-2aa44e608ac7-arm-linux-gnueabihf.tar.gz
65ebbaea7efab7daf5450f5276c5983498ed618ab575f66c4cd4d0e386fb458d  guix-build-2aa44e608ac7/output/dist-archive/bitcoin-2aa44e608ac7.tar.gz
350262aa3c8ef2cc026543cf1e5ff79e5f7d8cf9ee79f0bbaea2d74127acfdc4  guix-build-2aa44e608ac7/output/powerpc64-linux-gnu/SHA256SUMS.part
5f94885145fcd472f20c578c5d3aa3e1d42b541d00adf253a4d25ed61a26338d  guix-build-2aa44e608ac7/output/powerpc64-linux-gnu/bitcoin-2aa44e608ac7-powerpc64-linux-gnu-debug.tar.gz
0d043e82e8246657ae1b0cde74809873c4a14c0bfa69637804ddb4b5fde58ae5  guix-build-2aa44e608ac7/output/powerpc64-linux-gnu/bitcoin-2aa44e608ac7-powerpc64-linux-gnu.tar.gz
50721a56d111742035082c34156fe2f3cadcc2c48ea71c93a5789ff5966b1afa  guix-build-2aa44e608ac7/output/powerpc64le-linux-gnu/SHA256SUMS.part
5275ec85f43948bd6c9d7cf1ac76eb17949168918858cf33ee1bbc278f3bb668  guix-build-2aa44e608ac7/output/powerpc64le-linux-gnu/bitcoin-2aa44e608ac7-powerpc64le-linux-gnu-debug.tar.gz
7d694d4efecbf99e2495873e5d24d0edc7680b609fbdbde7cfb0a0f9532f4d49  guix-build-2aa44e608ac7/output/powerpc64le-linux-gnu/bitcoin-2aa44e608ac7-powerpc64le-linux-gnu.tar.gz
0bdbf4b1a10c476524988ff5f16355638937252e88a2560ca5fdf0af1dfd643c  guix-build-2aa44e608ac7/output/x86_64-apple-darwin18/SHA256SUMS.part
e6df4a92a221729c18fcc1135ca86eb7b9732c6a61ab2ec276cd08401a38fa95  guix-build-2aa44e608ac7/output/x86_64-apple-darwin18/bitcoin-2aa44e608ac7-osx-unsigned.dmg
25f2ce901edc2a23d524180d8d099d10ce651660207a5bbbb4d387e96ceaac8d  guix-build-2aa44e608ac7/output/x86_64-apple-darwin18/bitcoin-2aa44e608ac7-osx-unsigned.tar.gz
ab3317d798ee0552e74bb6254e5abe64945b80cb48ed04f12c49ecca8d7cea6a  guix-build-2aa44e608ac7/output/x86_64-apple-darwin18/bitcoin-2aa44e608ac7-osx64.tar.gz
6afb5c24e7f48e86a6f9623371b2994dbf3fc17b9789f04a9b2d6b98f9b3b085  guix-build-2aa44e608ac7/output/x86_64-linux-gnu/SHA256SUMS.part
2caa3acb62852b56f542358e5f5ee8d669d1abe5c541146a5b4d817b388b91ed  guix-build-2aa44e608ac7/output/x86_64-linux-gnu/bitcoin-2aa44e608ac7-x86_64-linux-gnu-debug.tar.gz
52ba14e0cd44883135f39a144c6d301613420dfe227486aa9de45d1063e77c15  guix-build-2aa44e608ac7/output/x86_64-linux-gnu/bitcoin-2aa44e608ac7-x86_64-linux-gnu.tar.gz

[Design] Move Developer Options from About to Settings

Settings > About does not seem to be an obvious place for Developer Settings. I think Jake originally suggested it.

Screenshot 2023-04-13 at 22 07 49

It should be moved out into Settings as the last item. Carry the same text warning for users.
Can provide a mockup if required.

Handle landscape rotation on mobile devices?

Mobile devices can display apps in portrait or landscape mode. We should either decide to not support mobile landscape mode or keep landscape mode in mind and design & develop the GUI to handle landscape rotation.

Below are screenshots as to how landscape mode is currently handled as of ea267eb:

a b
Screenshot_20221107-162342 Screenshot_20221107-162427

Refactor ChainModel

Expose block information as ChainModel property/methods and move time calculations to blockclockdial as the context there is more appropriate for those methods. Doing those calculations within the ChainModel context to be used in the BlockClock dial component is confusing and error prone.

Binding loop on InformationPage ScrollView contentHeight when appMode is "MOBILE"

Current behaviour

The InformationPage's continueButton is special cased to behave differently between mobile and desktop, as defined in the design file. #171 introduced this functionality. And #194 made it work with the new InformationPage control and it's scrollView. The logic on the scrollViews contentHeight implemented in 194 was faulty, and leads to a binding loop. This was hidden by the fact that we can't see terminal output when running the android app.

Expected behaviour

No binding loop.

Steps to reproduce

Apply this patch, then run the gui so this logic is ran when on desktop:

diff --git a/src/qml/controls/InformationPage.qml b/src/qml/controls/InformationPage.qml
index e652de666..c616bcf2a 100644
--- a/src/qml/controls/InformationPage.qml
+++ b/src/qml/controls/InformationPage.qml
@@ -111,7 +111,7 @@ Page {
 
     states: [
         State {
-            name: "MOBILE"
+            name: "DESKTOP"
             AnchorChanges {
                 target: continueButton
                 anchors.top: undefined
@@ -131,7 +131,7 @@ Page {
             }
         },
         State {
-            name: "DESKTOP"
+            name: "MOBILE"
             AnchorChanges {
                 target: continueButton
                 anchors.top: information.bottom

Relevant log output

$ ./src/qt/bitcoin-qt -signet -resetguisettings
qrc:/qml/controls/InformationPage.qml:46:5: QML ScrollView: Binding loop detected for property "contentHeight"

How did you obtain Bitcoin Core

Compiled from source

What version of Bitcoin Core are you using?

master

Operating system and version

Ubuntu 22.04.2 LTS x86_64

Machine specifications

No response

Hardened vs non-hardened key derivation

Currently Bitcoin Core uses hardened private key generation for security reasons which comes with a major UX tradeoff (not possible to use BIP39 recovery phrases).

However, If we want to turn the Bitcoin Core app into a multisig cold-storage wallet (which should be the primary aim imo) it is likely non-hardened addresses need to be used for the below reason:

However, there is a trade-off to using hardened addresses. Regular addresses are derived from public keys, but hardened addresses are derived from private keys. So to generate new hardened addresses requires access to private keys. This means either that private keys would need to be kept on third-party servers or that the client’s hardware wallets would need to be accessed whenever they wanted to generate new addresses. Both of these options are unacceptable.

More details here.

If we use non-hardened addresses for multi-sig it would make sense to also offer this for single-sig. However, something to consider is still offering hardened derivation wallet creation for those more advanced users who do not want to make the trade-off of using non-hardened key derivation. With good design we can cater to a wide range of user risk tolerances and skill levels. We can also offer some kind of progressive security where we educate and move users towards more advanced practices over time.

V1: Meta Issue

V1 release is approaching, this is a meta issue detailing the remaining tasks to complete before we can release:

Requirements

TODO ✍️

    • Add ability to choose a custom datadirectory
      • This would introduce a FileDialog because it's fallback is in qml, instead of a Qt Widgets fallback. A Qt widgets fallback is a non-starter
      • The FileDialog will set selectFolder to true
      • This requires enabling the missing modules in depends which can be found in the following list: DefaultFileDialog.qml includes
    • Update OptionsModel to keep track of what settings are being updated, and only write to settings.json when told to do so
      • During Onboarding, this would be when the user has completed onboarding
      • After Onboarding, this can be whenever a setting is updated and in real time

In Progress 🛠️

Completed ✅

    • Introduce the PeersIndicator component into the BlockClock
      • picked up by: #236)
    • Wire up Developer Options to OptionsModel
      • picked up by: #224)
    • Update ExternalLink icon to fit with design file
      • picked up by: #239)
    • Disable the Prune target setting when the Prune toggle switch is disabled
      • picked up by: #243
    • BlockClock needs a connecting state with an animation
      • picked up by: #252 (missing animation)
    • Introduce definition of the focus outline for focus-able component
      • picked up by: #264
    • Do not show the onboarding wizard if settings.json or bitcoin.conf exist in default datadir or in supplied -datadir
      • picked up by: #247
    • Add an OptionButton to StorageOptions that represents a custom prune target set by a user after they have configured a prune target in Detailed Settings during onboarding
      • picked up by: #245
    • Introduce and setup Proxy configuration
      • picked up by: #223)
    • Implement a new control in place of ValueInput that:
      • only accepts numbers as input, and does some simple validation on the input number to make sure it's valid (Probably should be a TextInput, setting a proper inputMethodHint with an IntValidator)
      • When a value is invalid the following warning should be represented within the setting
      • picked up by: #257

Stretch-Goals

    • Initial testing setup (started in: #215)
    • Console Window
    • Translations

Brainstorming: Detecting network state

We need to have the ability to detect network state to allow for states such as the following (specified in the design file):

Paused: No Wifi Peers: No Internet
Mobile Node - Peers

We have two options to go down through, at least with platforms aside from android.

1. Enable the Qt Network API

This gives us access to the QNetworkConfigurationManager class. Here we have access to the following signals and functions that give us the information we need:

It should be noted that with these functions, Qt checks that the computer is connected to any signal, and not if that signal really has an internet connection.

2. Use system specific terminal commands in a Process

For example, on macOS, this could be something like the following:

#include <QProcess>

class NetworkManager : public QObject
{
    Q_OBJECT
    Q_PROPERTY(bool isOnline READ isOnline NOTIFY isOnlineChanged)

public:
    explicit NetworkManager(QObject *parent = nullptr)
        : QObject(parent), m_isOnline(false)
    {
        checkNetworkAccess();
    }

    bool isOnline() const { return m_isOnline; }

public slots:
    void checkNetworkAccess() {
        QProcess process;
        process.start("scutil --nwi");
        process.waitForFinished();

        QString output = process.readAllStandardOutput();

        // check if output contains 'No network connection'
        m_isOnline = !output.contains("No network");

        emit isOnlineChanged(m_isOnline);
    }

signals:
    void isOnlineChanged(bool isOnline);

private:
    bool m_isOnline;
};

There should be available commands for macOS, linux, and Windows; but this approach won't work for Android, where we'll just plug into some android api for this information.

Brainstorming: Handling Qt license information

Using Qt as an open-source application, it appears we have to have some form of an about Qt page that either provides the GPL license or links to it; but I could be wrong. Opening this to see what Qt specific information we should have before releasing any V1.

See:
https://www.qt.io/licensing/
https://www.gnu.org/licenses/gpl-howto.html
https://doc.qt.io/qt-6/qtqml-index.html#licenses-and-attributions

cc @johnny9 @hebasto

If we need a license/info page, we could include a Qt version setting under Developer Options, that when clicked goes to a page that includes information about Qt.

Screen Shot 2023-05-29 at 6 52 05 PM

The Settings hitbox should be the entire setting itself

2023-01-26_21-09

In the above screenshot, and on master, the hitbox for a setting is the action item itself; nothing else is clickable.

Instead, the hitbox should be the entire area of the setting. This new hitbox which covers the entire setting row area should engage the action item. This means that when looking at the above screenshot:

  • In the first setting, the external link will be engaged
  • In the second setting, the value input field will be engaged
  • In the last setting, the switch will be toggled

Crash when quitting app on macOS

There seems to be some crash when the app is quit.

I get this every time I quit the app.

Just close the app window and quit the application.

Actual behavior

Screenshot 2023-04-13 at 15 21 23

To reproduce

Quit the app

Happens every time I quit the app.

System information

macOS 12 on Apple Silicon.

Dunno

Sticky `Setting` actionItem state

Current behaviour

Take the About setting page for example, this is a page with multiple rows of Settings; each setting being represented by a Setting control. The Setting control is implemented to switch between different color states depending on what's happening to it at the moment (hovered, clicked, disabled, etc...). Within a Setting control, we can have an actionItem, and this actionItem will then have it's "state" tied to the parent Setting state.

It is expected that only one setting within the row would be in the HOVERED state because the mouse can only be hovered over one Setting at a time. It then follows that because a settings actionItem is tied to it's parent setting state, only one actionItem can be in a HOVERED state. But that is not the case on master if you move your mouse really quickly over all the settings. It appears that some actionItems don't get updated about their parent Setting state changing, and get stuck on an old parent state:

Screen Shot 2023-05-31 at 12 51 55 AM

Expected behaviour

Only one Setting and one actionItem should be in a state that is not "filled" or "disabled".

Steps to reproduce

Quickly run your mouse over all settings.

Relevant log output

No response

How did you obtain Bitcoin Core

Compiled from source

What version of Bitcoin Core are you using?

master

Operating system and version

macOS 12.6 M1 Pro

Machine specifications

No response

build: Building depends for the `riscv64-linux-gnu` host fails

On the main branch (2aa44e6):

$ env HOSTS='riscv64-linux-gnu' ./contrib/guix/guix-build
...
linking ../../bin/qml
riscv64-linux-gnu-ld: /bitcoin/depends/work/build/riscv64-linux-gnu/qt/5.12.11-a191f20871a/qtdeclarative/lib/libQt5Qml.a(qv4typedarray.o): in function `.L567':
qv4typedarray.cpp:(.text._Z9atomicXorIhEyPcN3QV45ValueE[_Z9atomicXorIhEyPcN3QV45ValueE]+0x72): undefined reference to `__atomic_fetch_xor_1'
riscv64-linux-gnu-ld: /bitcoin/depends/work/build/riscv64-linux-gnu/qt/5.12.11-a191f20871a/qtdeclarative/lib/libQt5Qml.a(qv4typedarray.o): in function `.L590':
qv4typedarray.cpp:(.text._Z9atomicXorItEyPcN3QV45ValueE[_Z9atomicXorItEyPcN3QV45ValueE]+0x74): undefined reference to `__atomic_fetch_xor_2'
riscv64-linux-gnu-ld: /bitcoin/depends/work/build/riscv64-linux-gnu/qt/5.12.11-a191f20871a/qtdeclarative/lib/libQt5Qml.a(qv4typedarray.o): in function `.L613':
qv4typedarray.cpp:(.text._Z9atomicSubIhEyPcN3QV45ValueE[_Z9atomicSubIhEyPcN3QV45ValueE]+0x72): undefined reference to `__atomic_fetch_sub_1'
riscv64-linux-gnu-ld: /bitcoin/depends/work/build/riscv64-linux-gnu/qt/5.12.11-a191f20871a/qtdeclarative/lib/libQt5Qml.a(qv4typedarray.o): in function `.L636':
qv4typedarray.cpp:(.text._Z8atomicOrItEyPcN3QV45ValueE[_Z8atomicOrItEyPcN3QV45ValueE]+0x74): undefined reference to `__atomic_fetch_or_2'
riscv64-linux-gnu-ld: /bitcoin/depends/work/build/riscv64-linux-gnu/qt/5.12.11-a191f20871a/qtdeclarative/lib/libQt5Qml.a(qv4typedarray.o): in function `.L659':
qv4typedarray.cpp:(.text._Z9atomicAddIaEyPcN3QV45ValueE[_Z9atomicAddIaEyPcN3QV45ValueE]+0x72): undefined reference to `__atomic_fetch_add_1'
riscv64-linux-gnu-ld: /bitcoin/depends/work/build/riscv64-linux-gnu/qt/5.12.11-a191f20871a/qtdeclarative/lib/libQt5Qml.a(qv4typedarray.o): in function `.L682':
qv4typedarray.cpp:(.text._Z8atomicOrIaEyPcN3QV45ValueE[_Z8atomicOrIaEyPcN3QV45ValueE]+0x72): undefined reference to `__atomic_fetch_or_1'
riscv64-linux-gnu-ld: /bitcoin/depends/work/build/riscv64-linux-gnu/qt/5.12.11-a191f20871a/qtdeclarative/lib/libQt5Qml.a(qv4typedarray.o): in function `.L705':
qv4typedarray.cpp:(.text._Z14atomicExchangeIaEyPcN3QV45ValueE[_Z14atomicExchangeIaEyPcN3QV45ValueE]+0x72): undefined reference to `__atomic_exchange_1'
riscv64-linux-gnu-ld: /bitcoin/depends/work/build/riscv64-linux-gnu/qt/5.12.11-a191f20871a/qtdeclarative/lib/libQt5Qml.a(qv4typedarray.o): in function `.L728':
qv4typedarray.cpp:(.text._Z8atomicOrIsEyPcN3QV45ValueE[_Z8atomicOrIsEyPcN3QV45ValueE]+0x74): undefined reference to `__atomic_fetch_or_2'
riscv64-linux-gnu-ld: /bitcoin/depends/work/build/riscv64-linux-gnu/qt/5.12.11-a191f20871a/qtdeclarative/lib/libQt5Qml.a(qv4typedarray.o): in function `.L751':
qv4typedarray.cpp:(.text._Z9atomicXorIaEyPcN3QV45ValueE[_Z9atomicXorIaEyPcN3QV45ValueE]+0x72): undefined reference to `__atomic_fetch_xor_1'
riscv64-linux-gnu-ld: /bitcoin/depends/work/build/riscv64-linux-gnu/qt/5.12.11-a191f20871a/qtdeclarative/lib/libQt5Qml.a(qv4typedarray.o): in function `.L774':
qv4typedarray.cpp:(.text._Z9atomicAndItEyPcN3QV45ValueE[_Z9atomicAndItEyPcN3QV45ValueE]+0x74): undefined reference to `__atomic_fetch_and_2'
riscv64-linux-gnu-ld: /bitcoin/depends/work/build/riscv64-linux-gnu/qt/5.12.11-a191f20871a/qtdeclarative/lib/libQt5Qml.a(qv4typedarray.o): in function `.L797':
qv4typedarray.cpp:(.text._Z9atomicSubIaEyPcN3QV45ValueE[_Z9atomicSubIaEyPcN3QV45ValueE]+0x72): undefined reference to `__atomic_fetch_sub_1'
riscv64-linux-gnu-ld: /bitcoin/depends/work/build/riscv64-linux-gnu/qt/5.12.11-a191f20871a/qtdeclarative/lib/libQt5Qml.a(qv4typedarray.o): in function `.L842':
qv4typedarray.cpp:(.text._Z9atomicXorIsEyPcN3QV45ValueE[_Z9atomicXorIsEyPcN3QV45ValueE]+0x74): undefined reference to `__atomic_fetch_xor_2'
riscv64-linux-gnu-ld: /bitcoin/depends/work/build/riscv64-linux-gnu/qt/5.12.11-a191f20871a/qtdeclarative/lib/libQt5Qml.a(qv4typedarray.o): in function `.L929':
qv4typedarray.cpp:(.text._Z9atomicAddIhEyPcN3QV45ValueE[_Z9atomicAddIhEyPcN3QV45ValueE]+0x72): undefined reference to `__atomic_fetch_add_1'
riscv64-linux-gnu-ld: /bitcoin/depends/work/build/riscv64-linux-gnu/qt/5.12.11-a191f20871a/qtdeclarative/lib/libQt5Qml.a(qv4typedarray.o): in function `.L974':
qv4typedarray.cpp:(.text._Z14atomicExchangeIhEyPcN3QV45ValueE[_Z14atomicExchangeIhEyPcN3QV45ValueE]+0x72): undefined reference to `__atomic_exchange_1'
riscv64-linux-gnu-ld: /bitcoin/depends/work/build/riscv64-linux-gnu/qt/5.12.11-a191f20871a/qtdeclarative/lib/libQt5Qml.a(qv4typedarray.o): in function `.L997':
qv4typedarray.cpp:(.text._Z9atomicAndIaEyPcN3QV45ValueE[_Z9atomicAndIaEyPcN3QV45ValueE]+0x72): undefined reference to `__atomic_fetch_and_1'
riscv64-linux-gnu-ld: /bitcoin/depends/work/build/riscv64-linux-gnu/qt/5.12.11-a191f20871a/qtdeclarative/lib/libQt5Qml.a(qv4typedarray.o): in function `.L1020':
qv4typedarray.cpp:(.text._Z8atomicOrIhEyPcN3QV45ValueE[_Z8atomicOrIhEyPcN3QV45ValueE]+0x72): undefined reference to `__atomic_fetch_or_1'
riscv64-linux-gnu-ld: /bitcoin/depends/work/build/riscv64-linux-gnu/qt/5.12.11-a191f20871a/qtdeclarative/lib/libQt5Qml.a(qv4typedarray.o): in function `.L1064':
qv4typedarray.cpp:(.text._Z9atomicAndIhEyPcN3QV45ValueE[_Z9atomicAndIhEyPcN3QV45ValueE]+0x72): undefined reference to `__atomic_fetch_and_1'
riscv64-linux-gnu-ld: /bitcoin/depends/work/build/riscv64-linux-gnu/qt/5.12.11-a191f20871a/qtdeclarative/lib/libQt5Qml.a(qv4typedarray.o): in function `.L1109':
qv4typedarray.cpp:(.text._Z14atomicExchangeItEyPcN3QV45ValueE[_Z14atomicExchangeItEyPcN3QV45ValueE]+0x74): undefined reference to `__atomic_exchange_2'
riscv64-linux-gnu-ld: /bitcoin/depends/work/build/riscv64-linux-gnu/qt/5.12.11-a191f20871a/qtdeclarative/lib/libQt5Qml.a(qv4typedarray.o): in function `.L1132':
qv4typedarray.cpp:(.text._Z9atomicSubItEyPcN3QV45ValueE[_Z9atomicSubItEyPcN3QV45ValueE]+0x74): undefined reference to `__atomic_fetch_sub_2'
riscv64-linux-gnu-ld: /bitcoin/depends/work/build/riscv64-linux-gnu/qt/5.12.11-a191f20871a/qtdeclarative/lib/libQt5Qml.a(qv4typedarray.o): in function `.L1155':
qv4typedarray.cpp:(.text._Z9atomicAddIsEyPcN3QV45ValueE[_Z9atomicAddIsEyPcN3QV45ValueE]+0x74): undefined reference to `__atomic_fetch_add_2'
riscv64-linux-gnu-ld: /bitcoin/depends/work/build/riscv64-linux-gnu/qt/5.12.11-a191f20871a/qtdeclarative/lib/libQt5Qml.a(qv4typedarray.o): in function `.L1200':
qv4typedarray.cpp:(.text._Z14atomicExchangeIsEyPcN3QV45ValueE[_Z14atomicExchangeIsEyPcN3QV45ValueE]+0x74): undefined reference to `__atomic_exchange_2'
riscv64-linux-gnu-ld: /bitcoin/depends/work/build/riscv64-linux-gnu/qt/5.12.11-a191f20871a/qtdeclarative/lib/libQt5Qml.a(qv4typedarray.o): in function `.L1223':
qv4typedarray.cpp:(.text._Z9atomicAndIsEyPcN3QV45ValueE[_Z9atomicAndIsEyPcN3QV45ValueE]+0x74): undefined reference to `__atomic_fetch_and_2'
riscv64-linux-gnu-ld: /bitcoin/depends/work/build/riscv64-linux-gnu/qt/5.12.11-a191f20871a/qtdeclarative/lib/libQt5Qml.a(qv4typedarray.o): in function `.L1246':
qv4typedarray.cpp:(.text._Z9atomicSubIsEyPcN3QV45ValueE[_Z9atomicSubIsEyPcN3QV45ValueE]+0x74): undefined reference to `__atomic_fetch_sub_2'
riscv64-linux-gnu-ld: /bitcoin/depends/work/build/riscv64-linux-gnu/qt/5.12.11-a191f20871a/qtdeclarative/lib/libQt5Qml.a(qv4typedarray.o): in function `.L1269':
qv4typedarray.cpp:(.text._Z9atomicAddItEyPcN3QV45ValueE[_Z9atomicAddItEyPcN3QV45ValueE]+0x74): undefined reference to `__atomic_fetch_add_2'
riscv64-linux-gnu-ld: /bitcoin/depends/work/build/riscv64-linux-gnu/qt/5.12.11-a191f20871a/qtdeclarative/lib/libQt5Qml.a(qv4typedarray.o): in function `.L1539':
qv4typedarray.cpp:(.text._Z21atomicCompareExchangeItEyPcN3QV45ValueES2_[_Z21atomicCompareExchangeItEyPcN3QV45ValueES2_]+0xde): undefined reference to `__atomic_compare_exchange_2'
riscv64-linux-gnu-ld: /bitcoin/depends/work/build/riscv64-linux-gnu/qt/5.12.11-a191f20871a/qtdeclarative/lib/libQt5Qml.a(qv4typedarray.o): in function `.L1584':
qv4typedarray.cpp:(.text._Z21atomicCompareExchangeIaEyPcN3QV45ValueES2_[_Z21atomicCompareExchangeIaEyPcN3QV45ValueES2_]+0xe2): undefined reference to `__atomic_compare_exchange_1'
riscv64-linux-gnu-ld: /bitcoin/depends/work/build/riscv64-linux-gnu/qt/5.12.11-a191f20871a/qtdeclarative/lib/libQt5Qml.a(qv4typedarray.o): in function `.L1629':
qv4typedarray.cpp:(.text._Z21atomicCompareExchangeIhEyPcN3QV45ValueES2_[_Z21atomicCompareExchangeIhEyPcN3QV45ValueES2_]+0xde): undefined reference to `__atomic_compare_exchange_1'
riscv64-linux-gnu-ld: /bitcoin/depends/work/build/riscv64-linux-gnu/qt/5.12.11-a191f20871a/qtdeclarative/lib/libQt5Qml.a(qv4typedarray.o): in function `.L1674':
qv4typedarray.cpp:(.text._Z21atomicCompareExchangeIsEyPcN3QV45ValueES2_[_Z21atomicCompareExchangeIsEyPcN3QV45ValueES2_]+0xe2): undefined reference to `__atomic_compare_exchange_2'
collect2: error: ld returned 1 exit status
...

QML source code error displayed on terminal if run app with invalid args

Is there an existing issue for this?

  • I have searched the existing issues

Current behaviour

Invalid arguments passed to QML bitcoin-qt app produces another error in source code which is shown on terminal and could confuse users.

image

Expected behaviour

QSettings shouldn't fail and QML source code details shouldn't be displayed on terminal.

Steps to reproduce

Run QML bitcoin-qt with an invalid argument (e.g. src/qt/bitcoin-qt -x)

Relevant log output

No response

How did you obtain Bitcoin Core

Compiled from source

What version of Bitcoin Core are you using?

v25.99

Operating system and version

Ubuntu 20.04 & 22.04

Machine specifications

No response

Getting a "OpenSSL: Connection reset by peer, errno 104" error while Statically building using depends on Ubuntu 22.04

I tried to compile QML using the following sets of steps:

cd depends
make -j8
cd ..
./autogen.sh
CONFIG_SITE=\$PWD/depends/x86_64-pc-linux-gnu/share/config.site ./configure --without-bdb --with-qml
make -j8

But the process fails at the depends on building stage, with the following error:

image

I went to the link (https://bitcoincore.org/depends-sources), which shows a 404 error initially.
It turns out there is no page of that sort available.

image

There can be two scenarios at play:

  • The depends have faulty links. In which case it needs to be fixed
  • I am making some errors in the steps I took to do the static build. In which case, I would humbly ask other contributors to direct me.

Missed font family "Inter"

On macOS (arm64), compiled with system packages:

% ./src/qt/bitcoin-qt
qt.qpa.fonts: Populating font family aliases took 47 ms. Replace uses of missing font family "Inter" with one that exists to avoid this cost

Add Qt Lottie to depends

Would make it possible to use animations throughout (in buttons, illustrations, guidelines, etc).

For example, the following JSON would render

{"v":"5.7.13","fr":29.9700012207031,"ip":0,"op":70.0000028511585,"w":200,"h":200,"nm":"Comp 4 - Lottie test 2","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Circle top 9","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0],"e":[100]},{"t":10.0000004073083}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":0},"o":{"x":0.167,"y":0.167},"t":0,"s":[100,10,0],"e":[100,10,0],"to":[0,0,0],"ti":[0,0,0]},{"t":10.0000004073083}],"ix":2,"l":2},"a":{"a":0,"k":[100,10,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0,0,0.833],"y":[1,1,3.564]},"o":{"x":[0,0,0.167],"y":[0,0,-2.564]},"t":0,"s":[75,75,100],"e":[100,100,100]},{"t":10.0000004073083}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-5.523],[5.523,0],[0,5.523],[-5.523,0]],"o":[[0,5.523],[-5.523,0],[0,-5.523],[5.523,0]],"v":[[10,-90],[0,-80],[-10,-90],[0,-100]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[100,100],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 8","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Circle top 8","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":1,"s":[0],"e":[100]},{"t":11.0000004480392}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":0},"o":{"x":0.167,"y":0.167},"t":1,"s":[10,100,0],"e":[10,100,0],"to":[0,0,0],"ti":[0,0,0]},{"t":11.0000004480392}],"ix":2,"l":2},"a":{"a":0,"k":[100,10,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0,0,0.833],"y":[1,1,3.564]},"o":{"x":[0,0,0.167],"y":[0,0,-2.564]},"t":1,"s":[75,75,100],"e":[100,100,100]},{"t":11.0000004480392}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-5.523],[5.523,0],[0,5.523],[-5.523,0]],"o":[[0,5.523],[-5.523,0],[0,-5.523],[5.523,0]],"v":[[10,-90],[0,-80],[-10,-90],[0,-100]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[100,100],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 8","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":1.00000004073083,"op":301.000012259981,"st":1.00000004073083,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Circle top 7","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":8,"s":[0],"e":[100]},{"t":18.000000733155}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":0},"o":{"x":0.167,"y":0.167},"t":8,"s":[164,164,0],"e":[164,164,0],"to":[0,0,0],"ti":[0,0,0]},{"t":18.000000733155}],"ix":2,"l":2},"a":{"a":0,"k":[100,10,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0,0,0.833],"y":[1,1,3.564]},"o":{"x":[0,0,0.167],"y":[0,0,-2.564]},"t":8,"s":[75,75,100],"e":[100,100,100]},{"t":18.000000733155}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-5.523],[5.523,0],[0,5.523],[-5.523,0]],"o":[[0,5.523],[-5.523,0],[0,-5.523],[5.523,0]],"v":[[10,-90],[0,-80],[-10,-90],[0,-100]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[100,100],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 8","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":8.00000032584668,"op":308.000012545097,"st":8.00000032584668,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Circle top 6","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":16,"s":[0],"e":[100]},{"t":26.0000010590017}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":0},"o":{"x":0.167,"y":0.167},"t":16,"s":[36,164,0],"e":[36,164,0],"to":[0,0,0],"ti":[0,0,0]},{"t":26.0000010590017}],"ix":2,"l":2},"a":{"a":0,"k":[100,10,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0,0,0.833],"y":[1,1,3.564]},"o":{"x":[0,0,0.167],"y":[0,0,-2.564]},"t":16,"s":[75,75,100],"e":[100,100,100]},{"t":26.0000010590017}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-5.523],[5.523,0],[0,5.523],[-5.523,0]],"o":[[0,5.523],[-5.523,0],[0,-5.523],[5.523,0]],"v":[[10,-90],[0,-80],[-10,-90],[0,-100]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[100,100],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 8","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":16.0000006516934,"op":316.000012870944,"st":16.0000006516934,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Circle top 5","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":21,"s":[0],"e":[100]},{"t":31.0000012626559}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":0},"o":{"x":0.167,"y":0.167},"t":21,"s":[36,36,0],"e":[36,36,0],"to":[0,0,0],"ti":[0,0,0]},{"t":31.0000012626559}],"ix":2,"l":2},"a":{"a":0,"k":[100,10,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0,0,0.833],"y":[1,1,3.564]},"o":{"x":[0,0,0.167],"y":[0,0,-2.564]},"t":21,"s":[75,75,100],"e":[100,100,100]},{"t":31.0000012626559}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-5.523],[5.523,0],[0,5.523],[-5.523,0]],"o":[[0,5.523],[-5.523,0],[0,-5.523],[5.523,0]],"v":[[10,-90],[0,-80],[-10,-90],[0,-100]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[100,100],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 8","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":21.0000008553475,"op":321.000013074598,"st":21.0000008553475,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Circle top 4","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":26,"s":[0],"e":[100]},{"t":36.0000014663101}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":0},"o":{"x":0.167,"y":0.167},"t":26,"s":[164,36,0],"e":[164,36,0],"to":[0,0,0],"ti":[0,0,0]},{"t":36.0000014663101}],"ix":2,"l":2},"a":{"a":0,"k":[100,10,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0,0,0.833],"y":[1,1,3.564]},"o":{"x":[0,0,0.167],"y":[0,0,-2.564]},"t":26,"s":[75,75,100],"e":[100,100,100]},{"t":36.0000014663101}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-5.523],[5.523,0],[0,5.523],[-5.523,0]],"o":[[0,5.523],[-5.523,0],[0,-5.523],[5.523,0]],"v":[[10,-90],[0,-80],[-10,-90],[0,-100]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[100,100],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 8","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":26.0000010590017,"op":326.000013278252,"st":26.0000010590017,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Circle top 3","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":28,"s":[0],"e":[100]},{"t":38.0000015477717}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":0},"o":{"x":0.167,"y":0.167},"t":28,"s":[190,100,0],"e":[190,100,0],"to":[0,0,0],"ti":[0,0,0]},{"t":38.0000015477717}],"ix":2,"l":2},"a":{"a":0,"k":[100,10,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0,0,0.833],"y":[1,1,3.564]},"o":{"x":[0,0,0.167],"y":[0,0,-2.564]},"t":28,"s":[75,75,100],"e":[100,100,100]},{"t":38.0000015477717}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-5.523],[5.523,0],[0,5.523],[-5.523,0]],"o":[[0,5.523],[-5.523,0],[0,-5.523],[5.523,0]],"v":[[10,-90],[0,-80],[-10,-90],[0,-100]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[100,100],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 8","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":28.0000011404634,"op":328.000013359714,"st":28.0000011404634,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Circle top 2","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[0],"e":[100]},{"t":40.0000016292334}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":0},"o":{"x":0.167,"y":0.167},"t":30,"s":[100,190,0],"e":[100,190,0],"to":[0,0,0],"ti":[0,0,0]},{"t":40.0000016292334}],"ix":2,"l":2},"a":{"a":0,"k":[100,10,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0,0,0.833],"y":[1,1,3.564]},"o":{"x":[0,0,0.167],"y":[0,0,-2.564]},"t":30,"s":[75,75,100],"e":[100,100,100]},{"t":40.0000016292334}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-5.523],[5.523,0],[0,5.523],[-5.523,0]],"o":[[0,5.523],[-5.523,0],[0,-5.523],[5.523,0]],"v":[[10,-90],[0,-80],[-10,-90],[0,-100]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.945098042488,0.835294127464,0.290196090937,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[100,100],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 8","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30.0000012219251,"op":330.000013441176,"st":30.0000012219251,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"Line 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[100,100,0],"ix":2,"l":2},"a":{"a":0,"k":[100,100,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,40.5]],"o":[[40.5,0],[0,0]],"v":[[-89.75,-0.25],[-1.25,-90.25]],"c":false},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.5,"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0],"y":[0.996]},"o":{"x":[0],"y":[0]},"t":7,"s":[100],"e":[5]},{"t":25.0000010182709}],"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tr","p":{"a":0,"k":[99.75,100.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 9","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":7.00000028511585,"op":70.0000028511585,"st":7.00000028511585,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":"Line 7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[100,100,0],"ix":2,"l":2},"a":{"a":0,"k":[100,100,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-29,-29]],"o":[[0,40],[0,0]],"v":[[-0.75,-89.75],[63.75,63.75]],"c":false},"ix":2},"nm":"Path 7","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.5,"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0],"y":[0.996]},"o":{"x":[0],"y":[0]},"t":16,"s":[100],"e":[5]},{"t":34.0000013848484}],"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tr","p":{"a":0,"k":[99.75,100.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 9","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":16.0000006516934,"op":70.0000028511584,"st":16.0000006516934,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":"Line 5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[100,100,0],"ix":2,"l":2},"a":{"a":0,"k":[100,100,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-29,-29]],"o":[[28.5,-28.5],[0,0]],"v":[[-59.25,58.25],[63.75,63.75]],"c":false},"ix":2},"nm":"Path 5","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.5,"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0],"y":[0.996]},"o":{"x":[0],"y":[0]},"t":19,"s":[95],"e":[0]},{"t":37.0000015070409}],"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tr","p":{"a":0,"k":[99.75,100.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 9","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":19.0000007738859,"op":70.0000028511585,"st":19.0000007738859,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":"Line 6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[100,100,0],"ix":2,"l":2},"a":{"a":0,"k":[100,100,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[32.5,32.5]],"o":[[28.5,-28.5],[0,0]],"v":[[-59.25,58.25],[-63.75,-63.75]],"c":false},"ix":2},"nm":"Path 6","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.5,"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0],"y":[0.997]},"o":{"x":[0],"y":[0]},"t":21,"s":[100],"e":[0]},{"t":39.0000015885026}],"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tr","p":{"a":0,"k":[99.75,100.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 9","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":21.0000008553475,"op":70.0000028511584,"st":21.0000008553475,"bm":0},{"ddd":0,"ind":21,"ty":4,"nm":"Line 10","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[100,100,0],"ix":2,"l":2},"a":{"a":0,"k":[100,100,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[28.5,28.5]],"o":[[-40,0],[0,0]],"v":[[89.75,0.25],[-63.25,-63.75]],"c":false},"ix":2},"nm":"Path 10","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.5,"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0],"y":[0.996]},"o":{"x":[0],"y":[0]},"t":29,"s":[100],"e":[5]},{"t":47.0000019143492}],"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tr","p":{"a":0,"k":[99.75,100.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 9","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":29.0000011811942,"op":70.0000028511584,"st":29.0000011811942,"bm":0},{"ddd":0,"ind":22,"ty":4,"nm":"Line 11","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[100,100,0],"ix":2,"l":2},"a":{"a":0,"k":[100,100,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,41]],"o":[[-28.5,28.5],[0,0]],"v":[[64.25,-63.75],[-0.75,-90.25]],"c":false},"ix":2},"nm":"Path 11","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.5,"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0],"y":[0.996]},"o":{"x":[0],"y":[0]},"t":29,"s":[100],"e":[5]},{"t":47.0000019143492}],"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tr","p":{"a":0,"k":[99.75,100.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 9","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":29.0000011811942,"op":70.0000028511584,"st":29.0000011811942,"bm":0},{"ddd":0,"ind":23,"ty":4,"nm":"Line 4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[100,100,0],"ix":2,"l":2},"a":{"a":0,"k":[100,100,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[28,28]],"o":[[40.5,0],[0,0]],"v":[[-89.75,-0.25],[-63.25,-63.25]],"c":false},"ix":2},"nm":"Path 4","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.5,"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0],"y":[0.996]},"o":{"x":[0],"y":[0]},"t":32,"s":[100],"e":[5]},{"t":50.0000020365418}],"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tr","p":{"a":0,"k":[99.75,100.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 9","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":32.0000013033867,"op":70.0000028511584,"st":32.0000013033867,"bm":0},{"ddd":0,"ind":24,"ty":4,"nm":"Line 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[100,100,0],"ix":2,"l":2},"a":{"a":0,"k":[100,100,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,-41]],"o":[[37,37],[0,0]],"v":[[-63.75,-64.25],[0.25,90.25]],"c":false},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.945098042488,0.835294127464,0.290196090937,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.5,"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0],"y":[0.996]},"o":{"x":[0],"y":[0]},"t":35,"s":[100],"e":[5]},{"t":53.0000021587343}],"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":4,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tr","p":{"a":0,"k":[99.75,100.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 9","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":35.0000014255792,"op":70.0000028511585,"st":35.0000014255792,"bm":0},{"ddd":0,"ind":25,"ty":4,"nm":"Line","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[100,100,0],"ix":2,"l":2},"a":{"a":0,"k":[100,100,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,-41]],"o":[[40.5,0],[0,0]],"v":[[-89.75,-0.25],[0.25,90.25]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0],"y":[0.996]},"o":{"x":[0],"y":[0]},"t":39,"s":[100],"e":[5]},{"t":57.0000023216576}],"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.945098042488,0.835294127464,0.290196090937,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.5,"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[99.75,100.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 9","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":39.0000015885026,"op":70.0000028511584,"st":39.0000015885026,"bm":0},{"ddd":0,"ind":26,"ty":4,"nm":"Line 8","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[100,100,0],"ix":2,"l":2},"a":{"a":0,"k":[100,100,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,-41]],"o":[[-28.5,28.5],[0,0]],"v":[[64.25,-63.75],[0.25,90.25]],"c":false},"ix":2},"nm":"Path 8","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.945098042488,0.835294127464,0.290196090937,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.5,"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0],"y":[0.996]},"o":{"x":[0],"y":[0]},"t":43,"s":[100],"e":[5]},{"t":61.0000024845809}],"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":4,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tr","p":{"a":0,"k":[99.75,100.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 9","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":43.0000017514259,"op":70.0000028511585,"st":43.0000017514259,"bm":0},{"ddd":0,"ind":27,"ty":4,"nm":"Line 9","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[100,100,0],"ix":2,"l":2},"a":{"a":0,"k":[100,100,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,-41]],"o":[[-39.5,0],[0,0]],"v":[[89.25,0.25],[0.25,90.25]],"c":false},"ix":2},"nm":"Path 9","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.945098042488,0.835294127464,0.290196090937,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.5,"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0],"y":[0.996]},"o":{"x":[0],"y":[0]},"t":47,"s":[100],"e":[5]},{"t":65.0000026475043}],"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":4,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tr","p":{"a":0,"k":[99.75,100.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 9","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":47.0000019143492,"op":70.0000028511584,"st":47.0000019143492,"bm":0}],"markers":[]}
Screen.Recording.2021-10-22.at.12.03.12.mov

Update QML plugins

I think we can drop quick controls 1 and we could at least add quick layouts.

Document minimum required Qt version

In the current state of this repo it is supposed that the bitcoin-qt binary could be built against dynamically linked Qt packages provided by a system package manager (apt -- on Debian-based systems, Homebrew -- on macOS).

The current Qt version on Homebrew is 5.15.2.

Qt versions on some Linux distros:

The current Qt version in depends is:

$(package)_version=5.12.11

From Qt blog:


My suggestion is to stick to Qt 5.12 LTS that allows developers and testers use a broader set of Linux systems, unless Qt 5.15 has crucial for this project features.

Make Icons available through QML Icon Themes

Currently, with the way our Image Provider is set up, every Icon will need an entry under
1.Makefile.qt.include

QML_RES_ICONS = \
  qml/res/icons/sun.png\
  ...

2.bitcoin_qml.qrc

 <qresource prefix="/icons">
        ...
        <file alias="sun">res/icons/sun.png</file>

3.imageprovider.cpp

if (id == "sun") {
        *size = requested_size;
        return QIcon(":/icons/sun").pixmap(requested_size);
}

Then access to the Icon will require explicitly stating its URL, for example: icon.source: "image://images/sun"

We should instead make use of QML's Icon Themes. Instead of maintaining all these different entries in order to serve one icon, we could have an index.theme file which lists all entries. Then Icons are available by name, for example: icon.name: "sun"

Useful skills:

Qt5/6, QML

Want to work on this issue?

For guidance on contributing, please read CONTRIBUTING.md before opening your pull request.

Enable Ahead-of-Time Compilation

Currently build works with invalid syntax, like

--- a/src/qml/controls/OptionButton.qml
+++ b/src/qml/controls/OptionButton.qml
@@ -65,7 +65,7 @@ Button {
                 rightPadding: 7
                 bottomPadding: 4
                 leftPadding: 7
-                color: "black"
+                co lor: "black"
                 text: qsTr("Recommended")
             }
         }

which gives a runtime error:

QQmlApplicationEngine failed to load component
qrc:/qml/pages/stub.qml:43:9: Type ConnectionOptions unavailable
qrc:/qml/components/ConnectionOptions.qml:15:5: Type OptionButton unavailable
qrc:/qml/controls/OptionButton.qml:68:20: Unexpected token `identifier'

Fix this by turning to build-time errors. It's unclear how to use it with Autotools though.

Reference:
https://doc.qt.io/qt-5.15/qtquick-deployment.html#ahead-of-time-compilation
https://doc.qt.io/archives/QtQuickCompiler/index.html

Five dots under block time are confusing

This is more a design issue rather then a technical one. Feel free to close or move if this is not the right place.

I found the five dots under "Blocktime" as pictured below to be confusing. My intuition on a Android phone was to swipe or tap on them to go to other screens / block clock designs. I this always paused my IBD. I think this are two separate problems.

  1. It's not clear that clicking on the blocktime will pause the IBD.
  2. The dots don't really convey that we don't have connections or are opening connections.

image

App/block clock does not reflect network disconnection

The application & the block clock do not display an error state when network connection is lost.

Something like this? Not sure if it is implemented.

Screenshot 2023-04-18

Actual behavior
This one is on the build from #311

Screenshot 2023-04-18

This one is from a older build.

Screenshot 2023-04-17 at 12 27 36

I've observed this more than once.

Repro: Turn off wifi when the app is running. I think it also occurred when the app is launched and the wifi is off.

Running macOS 12.5.6.

Required property `paused` was not initialized in `PeersIndicator.qml`

On the recent master branch (810fa55):

2023-04-18T09:07:58Z SetNetworkActive: false
2023-04-18T09:08:02Z SetNetworkActive: true
2023-04-18T09:08:19Z New outbound peer connected: version: 70015, blocks=785937, peer=238 (outbound-full-relay)
2023-04-18T09:08:26Z New outbound peer connected: version: 70016, blocks=785937, peer=239 (outbound-full-relay)
2023-04-18T09:08:28Z New outbound peer connected: version: 70016, blocks=785937, peer=240 (outbound-full-relay)
2023-04-18T09:08:34Z New outbound peer connected: version: 70016, blocks=785937, peer=241 (outbound-full-relay)
2023-04-18T09:08:45Z New outbound peer connected: version: 70016, blocks=785937, peer=242 (outbound-full-relay)
2023-04-18T09:08:57Z New outbound peer connected: version: 70016, blocks=785937, peer=243 (outbound-full-relay)
2023-04-18T09:08:58Z New outbound peer connected: version: 70016, blocks=785937, peer=244 (outbound-full-relay)
2023-04-18T09:09:04Z New outbound peer connected: version: 70016, blocks=785937, peer=245 (outbound-full-relay)
2023-04-18T09:09:27Z GUI: qrc:/qml/components/PeersIndicator.qml:13:5: Required property paused was not initialized
2023-04-18T09:09:27Z GUI: qrc:/qml/pages/node/Peers.qml:38:9: Unable to assign [undefined] to int

To reproduce, one needs to open "Peers" view.

Extracting components into a reusable Bitcoin App UI library

We have decided that:

  1. we will make our own components and style them how we want. We are not going to be relying on any built-in qt style for consistency across platforms.

  2. components will be independent from the underlying core state

Because we are putting in the work to build out our own components and style, it would be a disservice to the community not to have this available for others to use.

I propose a goal of this project should be the creation of a Bitcoin App UI library consisting of our components. This library could live on its own repo or included as part of the BDK. This library would be similar to KDE's kirigami

Practical usability of this library

From my understanding, This library would be accessible across different frameworks and languages. It would not be limited to people who are building a bitcoin app with c++ and qml.

Here is a list of qml bindings that are available: https://wiki.qt.io/Language_Bindings

To show the extent of compatibility, there exist community built QML binding for other languages like Rust (qml-rust, qmlrs), OCaml and Python. QML components are also accessible to javascript UI frameworks like react reactqml

Remove unnecessary line breaks

The copy in the Figma designs included some custom line breaks to make the shape of the text look nicer (common thing these goofy designers do). These were ported into the code. Since the application width is flexible, this can cause line breaks in awkward places. Let's remove them.

  • Strengthen bitcoin screen, line break between "bitcoin" and "so" (code)
  • Block clock screen, line break between "every" and "10", and "dial" and "that" (code)

Useful skills:

Just some basic text edits.

Want to work on this issue?

For guidance on contributing, please read CONTRIBUTING.md before opening your pull request.

Binding loop detected in `NetworkTraffic.qml`

On the recent master branch (810fa55):

2023-04-18T09:09:44Z GUI: qrc:/qml/pages/node/NetworkTraffic.qml:28:9: QML Rectangle: Binding loop detected for property "width"
2023-04-18T09:09:44Z GUI: qrc:/qml/pages/node/NetworkTraffic.qml:28:9: QML Rectangle: Binding loop detected for property "width"
2023-04-18T09:09:44Z GUI: qrc:/qml/pages/node/NetworkTraffic.qml:28:9: QML Rectangle: Binding loop detected for property "height"

To reproduce, one needs to open "Network Traffic" view.

Fix confusing naming between Settings components and Settings pages

Right now we have completely confusing naming between our Settings components which contain the definition for the ColumnLayout containing the action items that can configure the option; and our Settings pages, which contain the definition for the Page that will contain said setting component

For example:
The file pages/settings/SettingsConnection.qml is a page and inside of here we have a component called ConnectionSettings which resides at components/ConnectionSettings.

SettingsConnection <-> ConnectionSettings

These are the same words, but in reverse order. We need a better naming system.

Document goals and limitations of this repo

It should be clear for new contributors what are goals of this repo, and what are its limitations.

Some limitations are obvious -- as QML module is not a part of depends for now, only builds with system packages are available.

Also, as this repo is experimental, it seems reasonable to limit systems on which code is tested. My suggestion is:

  • latest Ubuntu LTS
  • latest Ubuntu
  • latest macOS

As for goals, I reiterate my suggestion to adopt the Bitcoin Design Guide and follow it.

Feature: Add ability to locate & launch bitcoin.conf from the UI

The current UI does not provide a way to access bitcoin.conf

  • The bitcoin.conf file can be accessed from the UI in legacy UI
  • It is an easy-to-use but powerful tool that is also very popular. Jameson Loop even has a whole website dedicated to building the file.
  • It is a way to handle vast array of settings and features Core makes possible
  • It's seems good balance between powers & limitations of the UI and the RPC console

Suggestion: Given the potential to mess up things by users who don't know what they are doing, bitcoin.conf can be located in the Developer Options.

Thoughts? Can provide mockiup if required.

edit: added last bullet point.
How do folks feel about including it in the V1 milestone/MVP?

Bottom and right edges of display are grey on Android Pixel 6a

Is there an existing issue for this?

  • I have searched the existing issues

Current behaviour

The space at the bittom of the app screen displays as grey.

There’s also a narrow (~3 pixel) grey column on the right side.

This display bug happens on all the menus/screens, not just the one from the screenshot

IMG_3087

Expected behaviour

The black background should fill the entire screen.

Steps to reproduce

Install the Android64 apk on a Google Pixel 6a.

Relevant log output

None

How did you obtain Bitcoin Core

Pre-built binaries

What version of Bitcoin Core are you using?

v24.99.0-e0aacd194c3a

Operating system and version

Android 13

Machine specifications

Google Pixel 6a

FHD+ (1080 x 2400) OLED at 429 ppi
71.8mm X 152.2mm
20:9 aspect ratio

Adjust the UI/Set minimum width&height values for mobile multitasking

On Android, applications can be opened in multitasking mode. This allows more than one application open to be displayed on the screen at one time; each app taking up a portion of the screen. There are many use-cases as to why the Bitcoin Core App would be opened in multitasking mode on a mobile device, including but not limited to, copy-pasting and address from another app into the GUI.

As of right now, the GUI doesn't work well in multitasking mode. We need to set constraints and possibly minimum width&height values to allow for the GUI to work well in multitasking mode.

This isn't a priority as of right now, but something that we should address at some point as it is not exactly possible to prevent the app from being opened in multitask mode. A quick fix is to allow for scrolling up and down through the window and setting minimum widths

See screenshots below:

Android Tablet
The following screenshots represent the UI issues with opening the GUI in multitask mode on an Android Tablet. Notice that the UI just gets clipped, with elements being outside of the clickable visual area given to the GUI.

a b c
Screenshot_20221106_230526 Screenshot_20221106_230559 Screenshot_20221106_230624

Android Phone

a b c
Screenshot_20221107-161209_Gmail Screenshot_20221107-162723_Apps Screenshot_20221107-161126

In consideration of `initerrormessage.qml`

Issue with Dialog

On master, and when the initerrormessage window is displayed, if the user were to click on the underlying ApplicationWindow (this would be the white space outside of the dialog) the Dialog containing the initerrormessage will disappear. This leaves the user with no way to quit the application other than to quit from the terminal or quit from the window exit button (if there is one, depending on the window manager used).

Init Error Message Pops up Click on area outside dialog
Screen Shot 2022-06-05 at 7 31 27 PM Screen Shot 2022-06-05 at 7 31 43 PM

This should not happen, and is a good first issue!

Design Considerations

Along the design side, how user friendly is it to only open up this small window? Instead what if we opened up the main window and made the dialog pop up as so:

init-error-proposal

This expresses more efficiently that "The application attempted to run, but ran into a fatal error, and here is the error"

Continue Button inconsistent width on mobile

The continue button is drawn in two different widths depending if the current onboarding view uses the OnboardingInfo control or not. This is inconsistent and visually jarring. We either let the continue button expand the entire width of the screen on android or limit the width to the content width.

Screenshots to illustrate the issue:

uses OnboardingInfo does not use OnboardingInfo
Screenshot_20221107_174343 Screenshot_20221107_174353

Misaligned ExternalLink and OptionsButton

The ExternalLink and OptionsButton displayed by Settings.qml are not properly right-aligned.

Here are some screenshots addressing this issue:

Screenshot from 2022-08-15 19-24-34
Screenshot from 2022-08-15 19-23-26
Screenshot from 2022-08-15 19-35-09

I experimented with different Layouts and anchor settings, which I suspected to be the cause of misalignment; however, it does not seem to fix this issue.
Interestingly the ValueInput items are properly right-aligned, even though it does not seem to have alignment settings different from the abovementioned components.

There is a finite possibility that this can be a bug with the qml itself. Hence I urge other contributors as well to look through this issue.

Document the reference development environment setup

It is expected that working on QML application designers and developers are going to use tool sets that differ from ones we use while working on Qt widget based app. For example, Qt Designer is useful for widgets only.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.