From d9fee9fa83c3c0312d03aefe8a608d77d9b667bc Mon Sep 17 00:00:00 2001 From: Esko Dijk Date: Wed, 12 Jun 2024 22:30:52 +0200 Subject: [PATCH] Updates/Fixes: merge in recent OTNS1 PRs (#161) This commit includes all PRs merged into OTNS (v1) main branch, since the OTNS (v2) fork was created in 2022. Some PRs are applied as is, others are adapted to the new OTNS2 codebase. Also this includes version increases for Go 1.x and some Go and Python libraries used to newer versions. It also introduces some new features that were needed to optimally merge the PRs according to their intent. * YAML based startup script configuration: some node types (ftd/mtd/br) can now have their own unique startup command sequence, encoded in the same script file. This also enables for the future a fully YAML based configuration of a simulation including all node positions, radio models, startup scripts, etc. * [github-actions] fix for pushes do not run CI (#395) - this was not done. It appears it is currently not needed, leads to many cancelled CI tasks. CI tasks will run already on every push to the PR branch. Keeping this note as informative message. * update golangci-lint tool and fix pretty issue based on commit abf59e0 * [script] install python3-venv as an attempt to fix failing Docker build * Bump wheel from 0.34.2 to 0.38.1 in /pylibs/unittests (#439) Bumps [wheel](https://github.com/pypa/wheel) from 0.34.2 to 0.38.1. - [Release notes](https://github.com/pypa/wheel/releases) - [Changelog](https://github.com/pypa/wheel/blob/main/docs/news.rst) - [Commits](https://github.com/pypa/wheel/compare/0.34.2...0.38.1) --- updated-dependencies: - dependency-name: wheel dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump golang.org/x/net from 0.0.0-20201021035429-f5854403a974 to 0.7.0 (#478) Bumps [golang.org/x/net](https://github.com/golang/net) from 0.0.0-20201021035429-f5854403a974 to 0.7.0. - [Release notes](https://github.com/golang/net/releases) - [Commits](https://github.com/golang/net/commits/v0.7.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * [.github][go.mod] update to go 1.22 * [.github] some version quoting issues / bump setup-go action * [.github][GUIDE][go.mod] require Go 1.18 minimum; build for 1.20 and 1.22 also; clarified GUIDE * docker file updates -> go 1.22 / removed unneeded items * [script] fix hanging golangci-lint for go 1.20, 1.22 - bump version to 1.59.0 * [scripts] add wheel to install_python_libs() (#485) This should address this warning https://github.com/openthread/openthread/actions/runs/4321875033/jobs/7543625431#step:8:348 * [.github] quote go versions * [dependabot] reduce frequency to monthly (#494) * [all] [tests] properly configure operational dataset (#502) * [pylibs] fix raw test_commissioning by giving more time for nodes to scan channels. * [.github] change order of unit tests * [openthread] bump * Bump grpcio from 1.46.3 to 1.53.0 in /pylibs/unittests (#506) Bumps [grpcio](https://github.com/grpc/grpc) from 1.46.3 to 1.53.0. - [Release notes](https://github.com/grpc/grpc/releases) - [Changelog](https://github.com/grpc/grpc/blob/master/doc/grpc_release_schedule.md) - [Commits](https://github.com/grpc/grpc/compare/v1.46.3...v1.53.0) --- updated-dependencies: - dependency-name: grpcio dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * [pylibs] fixes requirements.txt bump protobuf, wheel * [go.mod] lib versions update * [otnstester][cli] fix cli unit-test * [pylibs] in tests don't set trace watch level by default / remove unnecessary 'watch default debug' * [script] fix issue that historic commits not found in --depth 1 cloned repo. * [pylibs] force_key_rotation test extension * [pylibs] increase network-limits time limit for case BR is a Parent, to avoid spurious test fails. * [pylibs] otns-performance stress test runs with fixed random seed (to get a more predictable baseline performance for number of events), to avoid spurious test fails on number of events. --------- Signed-off-by: dependabot[bot] Co-authored-by: Simon Lin Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Mason Tran Co-authored-by: Jonathan Hui --- .github/dependabot.yml | 8 +- .github/workflows/build.yml | 5 +- .github/workflows/develop.yml | 4 +- .github/workflows/docker.yml | 4 +- .github/workflows/lint.yml | 5 +- .github/workflows/stress.yml | 5 +- .github/workflows/test.yml | 19 +- .golangci.yml | 3 + GUIDE.md | 15 +- cli/ast.go | 6 +- etc/cli-scripts/ot-script-example.cli | 20 - etc/cli-scripts/ot-script-example.yaml | 48 ++ etc/docker/environment/Dockerfile | 4 +- etc/docker/playground/Dockerfile | 11 +- go.mod | 26 +- openthread | 2 +- ot-rfsim/script/bootstrap | 98 --- otns_main/otns_main.go | 4 +- otnstester/OtnsTest.go | 2 +- otoutfilter/OTOutFilter_test.go | 6 +- pylibs/case_studies/forced_key_rotation.py | 2 + pylibs/otns/cli/OTNS.py | 31 + pylibs/setup.py | 2 +- pylibs/stress_tests/BaseStressTest.py | 4 +- pylibs/stress_tests/network_limits.py | 40 +- pylibs/stress_tests/otns_performance.py | 3 +- pylibs/unittests/requirements.txt | 8 +- pylibs/unittests/test_basic.py | 23 +- pylibs/unittests/test_commissioning.py | 31 +- script/common.sh | 10 +- script/install-deps | 3 +- script/pack-web | 29 +- script/utils.sh | 4 +- simulation/node.go | 4 + simulation/node_config.go | 69 +- simulation/nodescript_parser.go | 30 +- simulation/simulation_config.go | 13 +- simulation/types.go | 25 + types/node_config.go | 2 +- web/site/bindata.go | 745 ++++++++++++--------- 40 files changed, 792 insertions(+), 581 deletions(-) create mode 100644 .golangci.yml delete mode 100644 etc/cli-scripts/ot-script-example.cli create mode 100644 etc/cli-scripts/ot-script-example.yaml delete mode 100755 ot-rfsim/script/bootstrap diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 8fc7c610..2d796228 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,4 +1,4 @@ -# Copyright (c) 2021-2022, The OTNS Authors. +# Copyright (c) 2021-2024, The OTNS Authors. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -29,12 +29,12 @@ updates: - package-ecosystem: "gitsubmodule" directory: "/" schedule: - interval: "weekly" + interval: "monthly" allow: - - dependency-name: "ot-rfsim" + - dependency-name: "openthread" commit-message: prefix: "submodule" rebase-strategy: "disabled" open-pull-requests-limit: 1 assignees: - - "EskoDijk" + - "jwhui" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 105aba3f..1b52e219 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -27,6 +27,7 @@ name: Build on: + workflow_dispatch: pull_request: branches: - 'main' @@ -46,10 +47,10 @@ jobs: strategy: fail-fast: false matrix: - go: [ 1.18, 1.22 ] + go: [ '1.18', '1.20', '1.22' ] os: [ ubuntu-22.04, macos-13, macos-14 ] steps: - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version: ${{ matrix.go }} - uses: actions/checkout@v3 diff --git a/.github/workflows/develop.yml b/.github/workflows/develop.yml index 34033298..ee03579a 100644 --- a/.github/workflows/develop.yml +++ b/.github/workflows/develop.yml @@ -49,11 +49,11 @@ jobs: strategy: fail-fast: false matrix: - go: [1.18] + go: [1.22] python-version: ['3.10'] os: [ubuntu-22.04] steps: - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version: ${{ matrix.go }} - uses: actions/setup-python@v5 diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 53fbf9af..97842b3c 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -1,4 +1,4 @@ -# Copyright (c) 2020-2023, The OTNS Authors. +# Copyright (c) 2020-2024, The OTNS Authors. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -56,7 +56,7 @@ jobs: submodules: recursive fetch-depth: 0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@v3 - name: Prepare id: prepare run: | diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 7f87a37c..39fdd468 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -27,6 +27,7 @@ name: Lint on: + workflow_dispatch: pull_request: branches: - 'main' @@ -46,9 +47,9 @@ jobs: env: HOMEBREW_NO_AUTO_UPDATE: 1 steps: - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: - go-version: 1.18 + go-version: '1.22' - uses: actions/checkout@v3 - name: Check pretty run: | diff --git a/.github/workflows/stress.yml b/.github/workflows/stress.yml index 1a1086f1..6a91083e 100644 --- a/.github/workflows/stress.yml +++ b/.github/workflows/stress.yml @@ -27,6 +27,7 @@ name: Stress on: + workflow_dispatch: pull_request: branches: - 'main' @@ -46,14 +47,14 @@ jobs: fail-fast: false matrix: python-version: ['3.10'] - go-version: [1.18] + go-version: ['1.22'] suite: ["network-forming", "commissioning", "connectivity", "network-latency", "multicast-performance", "otns-performance", "network-limits"] runs-on: ubuntu-22.04 timeout-minutes: 120 env: HOMEBREW_NO_AUTO_UPDATE: 1 steps: - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version: ${{ matrix.go-version }} - name: Set up Python diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6f86499d..4c93ddf5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -27,6 +27,7 @@ name: Test on: + workflow_dispatch: pull_request: branches: - 'main' @@ -51,9 +52,9 @@ jobs: env: HOMEBREW_NO_AUTO_UPDATE: 1 steps: - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: - go-version: 1.18 + go-version: '1.22' - uses: actions/checkout@v3 - name: Test run: | @@ -73,20 +74,20 @@ jobs: env: HOMEBREW_NO_AUTO_UPDATE: 1 steps: - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: - go-version: 1.18 + go-version: '1.22' - name: Set up Python uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - uses: actions/checkout@v3 - - name: Test multiple OT-versions - run: | - ./script/test py-ver-unittests - name: Test single OT-version run: | ./script/test py-unittests + - name: Test multiple OT-versions + run: | + ./script/test py-ver-unittests py-examples: name: Examples (${{ matrix.os }}) @@ -100,9 +101,9 @@ jobs: env: HOMEBREW_NO_AUTO_UPDATE: 1 steps: - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: - go-version: 1.18 + go-version: '1.22' - name: Set up Python uses: actions/setup-python@v5 with: diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 00000000..f56cbb1c --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,3 @@ +run: + skip-files: + - "web/site/bindata.go" \ No newline at end of file diff --git a/GUIDE.md b/GUIDE.md index 8a336b2a..dc50ac20 100644 --- a/GUIDE.md +++ b/GUIDE.md @@ -5,7 +5,7 @@ This guide covers the installation of Go, installation of OTNS, use of the OTNS OTNS requires [Go 1.18 or higher](https://golang.org/dl/) to build: - - Install Go from https://golang.org/dl/ + - Install Go from https://golang.org/dl/ or via a package manager (in this case check the Go version is high enough). - Add `$(go env GOPATH)/bin` (normally `$HOME/go/bin`) to `$PATH`. ## Get OTNS code @@ -17,19 +17,21 @@ cd otns ## Automated installation -An automated way to install dependencies, OTNS and all OT nodes is the following command: +An automated way to install dependencies, OTNS and all OT nodes, and test the result, is the following command: ```bash -./script/test build_openthread_versions +./script/test go-tests ``` -Alternatively the extensive unit tests can be run also with the following command: +Alternatively the more extensive Python unit tests can be run also with the following command: ```bash ./script/test py-unittests ``` -However, this can take a long time (5-10 minutes). +However, this can take a long time (5-10 minutes). Running any Python (`py-*`) tests will set up a Python 3 virtual +environment locally in the `.venv-otns` directory. This virtual environment must also be active when manually running +any OTNS Python scripts. ## Manual step-by-step installation @@ -171,7 +173,8 @@ See [OTNS CLI Reference](cli/README.md). ## OTNS Python Scripting [pyOTNS](pylibs/otns) library provides utilities to create and manage simulations through OTNS CLI. It is installed in a -Python 3 virtual environment `.venv-otns`. +Python 3 virtual environment `.venv-otns` by the `./script/install` script. The `./script/test` script also calls this +install script when needed as part of setup. ### Python Scripting Documentation diff --git a/cli/ast.go b/cli/ast.go index 31243ba6..8b525a9e 100644 --- a/cli/ast.go +++ b/cli/ast.go @@ -275,9 +275,9 @@ type ScanCmd struct { // noinspection GoVetStructTag type SpeedCmd struct { - Cmd struct{} `"speed"` //nolint - Max *MaxSpeedFlag `( @@` //nolint - Speed *float64 `| [ (@Int|@Float) ] )` //nolint + Cmd struct{} `"speed"` //nolint + Max *MaxSpeedFlag `[ ( @@` //nolint + Speed *float64 `| (@Int|@Float) ) ]` //nolint } // noinspection GoVetStructTag diff --git a/etc/cli-scripts/ot-script-example.cli b/etc/cli-scripts/ot-script-example.cli deleted file mode 100644 index e59114c6..00000000 --- a/etc/cli-scripts/ot-script-example.cli +++ /dev/null @@ -1,20 +0,0 @@ -# -# Example OT node CLI script, which can be passed to otns using the -ot-script parameter. -# - -# Basic require parameters -networkname Test\ Network -panid 0x1234 -channel 15 -networkkey 998877665544332211ffeeddccbbaa00 - -# Some extra settings -ccathreshold -80 -txpower 10 -routerselectionjitter 10 - -# Autostart the node -ifconfig up -channel monitor stop -thread start - diff --git a/etc/cli-scripts/ot-script-example.yaml b/etc/cli-scripts/ot-script-example.yaml new file mode 100644 index 00000000..b61af40f --- /dev/null +++ b/etc/cli-scripts/ot-script-example.yaml @@ -0,0 +1,48 @@ +# +# Example OT node CLI script, which can be passed to otns using the -ot-script parameter. +# It's in YAML format. Script comment lines start with '#'. +# TODO: enable using script config in same file with YAML network config. +# + +script: + ftd: | + # Active Dataset parameters. This only works for an FTD (e.g. type 'router' or 'fed'). + # Therefore it's in the 'ftd' script section. + dataset init new + dataset networkname Test\ Network + dataset panid 0x1234 + dataset channel 15 + dataset networkkey 998877665544332211ffeeddccbbaa00 + dataset meshlocalprefix fd00:abba:: + dataset commit active + + # Some extra settings - differ from usual setup. + routerselectionjitter 10 + + mtd: | + # MTD not able to use 'dataset init new'. Therefore, other way of providing active dataset. + networkkey 998877665544332211ffeeddccbbaa00 + panid 0x1234 + channel 15 + + br: | + # BR-specific configuration goes here. There's some spaces at EOL to test script-parsing. + ############# + routerselectionjitter 1 + routerdowngradethreshold 33 + routerupgradethreshold 33 + netdata publish route fc00::/7 s med + bbr enable + srp server enable + br init 1 1 + br enable + + all: | + # Some extra settings - differ from usual setup. These are applied to all node types, + # except for 'raw' added nodes. + ccathreshold -50 + txpower 10 + + # Autostart the node + ifconfig up + thread start diff --git a/etc/docker/environment/Dockerfile b/etc/docker/environment/Dockerfile index d2e86d49..116915b2 100644 --- a/etc/docker/environment/Dockerfile +++ b/etc/docker/environment/Dockerfile @@ -1,4 +1,4 @@ -# Copyright (c) 2022-2023, The OTNS Authors. +# Copyright (c) 2022-2024, The OTNS Authors. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -24,7 +24,7 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -FROM golang:1.18 +FROM golang:1.22 RUN apt-get update && apt-get install -y python3 python3-pip sudo unzip nodejs npm git && rm -rf /var/lib/apt/lists/* diff --git a/etc/docker/playground/Dockerfile b/etc/docker/playground/Dockerfile index a966cee8..82abc0f5 100644 --- a/etc/docker/playground/Dockerfile +++ b/etc/docker/playground/Dockerfile @@ -1,4 +1,4 @@ -# Copyright (c) 2020, The OTNS Authors. +# Copyright (c) 2020-2024, The OTNS Authors. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ # POSSIBILITY OF SUCH DAMAGE. # Stage 0: build OTNS and dependencies -FROM golang:1.18 +FROM golang:1.22 RUN apt-get update RUN apt-get install -y python3 python3-pip unzip @@ -33,13 +33,8 @@ RUN apt-get install -y python3 python3-pip unzip COPY . /otns WORKDIR /otns RUN ./script/install-deps +RUN ./script/test build-openthread-versions RUN ./script/install -WORKDIR /otns/ot-rfsim -RUN ./script/bootstrap -RUN ./script/build_latest -RUN ./script/build_v11 -RUN ./script/build_v12 -RUN ./script/build_v13 RUN strip /go/bin/grpcwebproxy /go/bin/otns diff --git a/go.mod b/go.mod index cf3c7cba..e3e41233 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2023, The OTNS Authors. +// Copyright (c) 2020-2024, The OTNS Authors. // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -29,28 +29,26 @@ module github.com/openthread/ot-ns go 1.18 require ( - github.com/alecthomas/participle v0.5.0 + github.com/alecthomas/participle v0.7.1 github.com/chzyer/readline v1.5.1 github.com/mitchellh/go-wordwrap v1.0.1 github.com/pkg/errors v0.9.1 - github.com/stretchr/testify v1.8.4 - go.uber.org/zap v1.22.0 - golang.org/x/term v0.4.0 - google.golang.org/grpc v1.48.0 - google.golang.org/protobuf v1.27.1 + github.com/stretchr/testify v1.9.0 + go.uber.org/zap v1.27.0 + golang.org/x/term v0.21.0 + google.golang.org/grpc v1.64.0 + google.golang.org/protobuf v1.34.1 gopkg.in/yaml.v3 v3.0.1 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/golang/protobuf v1.5.2 // indirect github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.uber.org/atomic v1.7.0 // indirect - go.uber.org/multierr v1.6.0 // indirect - golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 // indirect - golang.org/x/sys v0.4.0 // indirect - golang.org/x/text v0.3.3 // indirect - google.golang.org/genproto v0.0.0-20200608115520-7c474a2e3482 // indirect + go.uber.org/multierr v1.10.0 // indirect + golang.org/x/net v0.22.0 // indirect + golang.org/x/sys v0.21.0 // indirect + golang.org/x/text v0.14.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect ) diff --git a/openthread b/openthread index b5b17ba3..d6eb56c3 160000 --- a/openthread +++ b/openthread @@ -1 +1 @@ -Subproject commit b5b17ba3965d325c172f16cbad86ce5a1f5d025b +Subproject commit d6eb56c3196acea33f91ecb23a84fa05993e8583 diff --git a/ot-rfsim/script/bootstrap b/ot-rfsim/script/bootstrap deleted file mode 100755 index 1de50f60..00000000 --- a/ot-rfsim/script/bootstrap +++ /dev/null @@ -1,98 +0,0 @@ -#!/bin/bash -# -# Copyright (c) 2017-2024, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# -# Description: -# This file installs all needed dependencies and toolchains needed for -# ot-rfsim compilation and programming. -# - -set -euxo pipefail - -install_packages_apt() -{ - echo 'Installing toolchain dependencies...' - - # apt-get update and install dependencies - apt-get update - apt-get --no-install-recommends install -y g++ lsb-release cmake ninja-build shellcheck -} - -install_packages_opkg() -{ - echo 'opkg not supported currently' && false -} - -install_packages_rpm() -{ - echo 'rpm not supported currently' && false -} - -install_packages_brew() -{ - echo 'Installing toolchain dependencies...' - - # add build tools - brew install cmake ninja shfmt shellcheck - - # check for gcc for simulation - if ! command -v gcc; then - echo 'warning: clang/gcc needed for simulation' - echo 'warning: please install Command Line Tools from https://developer.apple.com/download/more/' - fi -} - -install_packages_source() -{ - echo 'source not supported currently' && false -} - -install_packages() -{ - PM=source - if command -v apt-get; then - PM=apt - elif command -v rpm; then - PM=rpm - elif command -v opkg; then - PM=opkg - elif command -v brew; then - PM=brew - fi - install_packages_$PM -} - -main() -{ - if [ "$EUID" -ne 0 ]; then - echo "Please run as root user, e.g. 'sudo ./script/bootstrap'." && false - fi - install_packages - echo 'bootstrap for ot-rfsim completed successfully.' -} - -main diff --git a/otns_main/otns_main.go b/otns_main/otns_main.go index 7bd09e2a..ad2a3ca1 100644 --- a/otns_main/otns_main.go +++ b/otns_main/otns_main.go @@ -283,9 +283,9 @@ func createSimulation(simId int, ctx *progctx.ProgCtx) (*simulation.Simulation, simcfg.Id = simId if len(args.InitScriptName) > 0 { if args.InitScriptName == "none" { - simcfg.NewNodeConfig.InitScript = []string{} // zero lines of init-script + simcfg.NewNodeScripts = &simulation.YamlScriptConfig{} } else { - simcfg.NewNodeConfig.InitScript, err = simulation.ReadNodeScript(args.InitScriptName) + simcfg.NewNodeScripts, err = simulation.ReadNodeScript(args.InitScriptName) if err != nil { return nil, err } diff --git a/otnstester/OtnsTest.go b/otnstester/OtnsTest.go index 107a3473..c2204017 100644 --- a/otnstester/OtnsTest.go +++ b/otnstester/OtnsTest.go @@ -429,7 +429,7 @@ func NewOtnsTest(t *testing.T) *OtnsTest { }) }() - grpcConn, err := grpc.Dial("localhost:8999", grpc.WithTransportCredentials(insecure.NewCredentials())) + grpcConn, err := grpc.NewClient("localhost:8999", grpc.WithTransportCredentials(insecure.NewCredentials())) ot.ExpectNoError(err) grpcClient := visualize_grpc_pb.NewVisualizeGrpcServiceClient(grpcConn) diff --git a/otoutfilter/OTOutFilter_test.go b/otoutfilter/OTOutFilter_test.go index 50b0b730..7ed36a1c 100644 --- a/otoutfilter/OTOutFilter_test.go +++ b/otoutfilter/OTOutFilter_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2022, The OTNS Authors. +// Copyright (c) 2020-2024, The OTNS Authors. // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -27,7 +27,7 @@ package otoutfilter import ( - "io/ioutil" + "io" "strings" "testing" ) @@ -70,7 +70,7 @@ func TestOTOutFilter(t *testing.T) { "" r := NewOTOutFilter(strings.NewReader(input), "Node<1> - ", nil) - output, err := ioutil.ReadAll(r) + output, err := io.ReadAll(r) if err != nil { t.Fatal(err) } diff --git a/pylibs/case_studies/forced_key_rotation.py b/pylibs/case_studies/forced_key_rotation.py index 50f6a980..d1556d3e 100755 --- a/pylibs/case_studies/forced_key_rotation.py +++ b/pylibs/case_studies/forced_key_rotation.py @@ -56,6 +56,8 @@ def main(): ns.ping(1,2) ns.go(10) + # run some time to catch MLE messages from node 2 - should reflect same Key Index. + ns.go(150) ns.web_display() if __name__ == '__main__': diff --git a/pylibs/otns/cli/OTNS.py b/pylibs/otns/cli/OTNS.py index c369e954..783bad51 100644 --- a/pylibs/otns/cli/OTNS.py +++ b/pylibs/otns/cli/OTNS.py @@ -937,6 +937,37 @@ def set_networkkey(self, nodeid: int, key: str) -> None: """ self.node_cmd(nodeid, f'networkkey {key}') + def config_dataset(self, nodeid: int, channel: int = None, panid: int = None, extpanid: str = None, networkkey: str = None, network_name: str = None, + dataset='active'): + """ + Configure the active/pending dataset + + :param nodeid: target node ID + :param channel: the channel number. + :param panid: the Pan ID. + :param extpanid: the Extended PAN ID. + :param networkkey: the network key (REQUIRED) + :param network_name: the network name + """ + assert dataset in ('active', 'pending'), dataset + + self.node_cmd(nodeid, 'dataset clear') + + if channel is not None: + self.node_cmd(nodeid, f'dataset channel {channel}') + + if panid is not None: + self.node_cmd(nodeid, f'dataset panid 0x{panid:04x}') + + if networkkey is not None: + self.node_cmd(nodeid, f'dataset networkkey {networkkey}') + + if network_name is not None: + network_name = self._escape_whitespace(network_name) + self.node_cmd(nodeid, f'dataset networkname {network_name}') + + self.node_cmd(nodeid, f'dataset commit {dataset}') + def web(self, tab_name: str = "") -> None: """ Open web browser for visualization. diff --git a/pylibs/setup.py b/pylibs/setup.py index 67cffd4c..6d8e90da 100755 --- a/pylibs/setup.py +++ b/pylibs/setup.py @@ -29,7 +29,7 @@ setuptools.setup( name="pyOTNS", - version="2.0.0", + version="2.1.0", author="The OTNS Authors", description="Run OTNS2 OpenThread mesh network simulations from Python code", url="https://github.com/EskoDijk/ot-ns", diff --git a/pylibs/stress_tests/BaseStressTest.py b/pylibs/stress_tests/BaseStressTest.py index e5e7be91..01b69db5 100644 --- a/pylibs/stress_tests/BaseStressTest.py +++ b/pylibs/stress_tests/BaseStressTest.py @@ -66,9 +66,9 @@ def run_wrapper(self: 'BaseStressTest', report=True): class BaseStressTest(object, metaclass=StressTestMetaclass): - def __init__(self, name, headers, web=True, raw=False): + def __init__(self, name, headers, web=True, raw=False, rand_seed=0): self.name = name - self._otns_args = ['-log','info','-logfile','none'] # use ['-log', 'debug'] for more debug messages + self._otns_args = ['-log','info','-logfile','none','-seed',str(rand_seed)] # use ['-log', 'debug'] for more debug messages if raw: self._otns_args.append('-ot-script') self._otns_args.append('none') diff --git a/pylibs/stress_tests/network_limits.py b/pylibs/stress_tests/network_limits.py index 94060532..34c67e84 100755 --- a/pylibs/stress_tests/network_limits.py +++ b/pylibs/stress_tests/network_limits.py @@ -42,11 +42,21 @@ class StressTest(BaseStressTest): SUITE = 'network-limits' + # Time limits for attaching in minutes, per parent-type and child-type. For BR as Parent, + # more time is allowed (as it has more capacity). TIME_LIMIT = { - 'fed': 1, - 'med': 1, - 'sed': 1, - 'ssed': 1, + 'router': { + 'fed': 1, + 'med': 1, + 'sed': 1, + 'ssed': 1, + }, + 'br': { + 'fed': 2, + 'med': 2, + 'sed': 2, + 'ssed': 2, + }, } def __init__(self): @@ -55,27 +65,28 @@ def __init__(self): def run(self): self.ns.speed = 30 # speed is lowered to see the visualization, when run locally. - self.test('fed') - self.test('med') - self.test('sed') - self.test('ssed') + self.test('fed', 'router') + self.test('med', 'router') + self.test('sed', 'router') + self.test('ssed', 'router') # a BR can support more children (compile-time configured) self.test('fed', 'br', CHILDREN_N_BR) self.test('med', 'br', CHILDREN_N_BR) self.test('sed', 'br', CHILDREN_N_BR) - self.test('ssed', 'br', CHILDREN_N_BR) + self.test('ssed','br', CHILDREN_N_BR) - def test(self, child_type: str, parent_type: str = 'router', n_children_max: int = CHILDREN_N): + def test(self, child_type: str, parent_type: str, n_children_max: int = CHILDREN_N): self.reset() self.ns.log = 'debug' - self.ns.watch_default('trace') + #self.ns.watch_default('trace') # can enable trace level to see radio state details self.ns.add(parent_type, PARENT_X, PARENT_Y) self.ns.go(7) - time_limit = StressTest.TIME_LIMIT[child_type] + time_limit = StressTest.TIME_LIMIT[parent_type][child_type] all_children = [] + logging.info(f"Testing '{parent_type}' parent with child type '{child_type}' (N={n_children_max})") for i in range(n_children_max): angle = math.pi * 2 * i / n_children_max @@ -93,11 +104,10 @@ def test(self, child_type: str, parent_type: str = 'router', n_children_max: int if self.ns.get_state(child) == 'child': n_children += 1 if n_children == n_children_max: - logging.info("All %s children has attached successfully within %d minutes.", child_type, i + 1) + logging.info("All %s children attached successfully within %d minutes, with time limit set to %d minutes.", child_type, i + 1, time_limit) break - self.ns.speed = 0.01 - self.ns.go(0.01) # trick to ensure final topology is briefly shown in web UI + self.ns.web_display() if n_children < n_children_max: raise Exception("Not all %s children attached within time limit of %d minutes." % (child_type, time_limit)) diff --git a/pylibs/stress_tests/otns_performance.py b/pylibs/stress_tests/otns_performance.py index 4ff3adbb..1f8e4482 100755 --- a/pylibs/stress_tests/otns_performance.py +++ b/pylibs/stress_tests/otns_performance.py @@ -57,7 +57,8 @@ class OtnsPerformanceStressTest(BaseStressTest): def __init__(self): super(OtnsPerformanceStressTest, self).__init__("OTNS Performance Test", ['Simulation Time', 'Execution Time', 'Speed Up', - 'Alarm Events', 'Radio Events']) + 'Alarm Events', 'Radio Events'], + rand_seed=48392) def run(self): ns = self.ns diff --git a/pylibs/unittests/requirements.txt b/pylibs/unittests/requirements.txt index 17c990c0..4e262d75 100644 --- a/pylibs/unittests/requirements.txt +++ b/pylibs/unittests/requirements.txt @@ -1,4 +1,4 @@ -grpcio-tools>=1.31.0 -grpcio>=1.31.0 -protobuf==3.15.0 -wheel==0.34.2 +grpcio-tools==1.53.0 +grpcio==1.53.0 +protobuf==4.21.6 +wheel==0.42.0 diff --git a/pylibs/unittests/test_basic.py b/pylibs/unittests/test_basic.py index 86417dd9..5f9a7269 100755 --- a/pylibs/unittests/test_basic.py +++ b/pylibs/unittests/test_basic.py @@ -190,7 +190,6 @@ def testDelNodeAndImmediatelyRecreate(self): ns = self.ns ns.loglevel = 'debug' - ns.watch_default('debug') # add extra detail in all node's logs id = ns.add("router") self.assertTrue(len(ns.nodes()) == 1 and 1 in ns.nodes() and id == 1) self.go(i/100) @@ -351,7 +350,7 @@ def testWithOTNS(self): """ make sure OTNS works in with-statement """ - self.tearDown() + self.ns.close() with OTNS(otns_args=['-log', 'debug']) as ns: self.assertEqual(OTNS.DEFAULT_SIMULATE_SPEED, ns.speed) @@ -663,7 +662,7 @@ def testCmdCommand(self): self.assertEqual(0, len(output)) def testRandomSeedSetting(self): - self.tearDown() + self.ns.close() nodes = range(1,6) # create a new OTNS with 'seed' parameter. @@ -878,6 +877,24 @@ def testSendUdpCoap(self): for a in addrs: self.assertFalse(a.startswith("ff13")) # see Go simulation.SendMcastPrefix + def testLoadOtScript(self): + self.ns.close() + + with OTNS(otns_args=['-ot-script', './etc/cli-scripts/ot-script-example.yaml', '-log', 'debug']) as ns: + self.ns = ns + ns.add('router') + ns.go(10) + ns.add('router') + ns.add('router') + ns.add('med') + ns.add('fed') + ns.go(30) + self.assertFormPartitions(1) + ns.add('br') + ns.add('sed') + ns.go(30) + self.assertFormPartitions(1) + if __name__ == '__main__': unittest.main() diff --git a/pylibs/unittests/test_commissioning.py b/pylibs/unittests/test_commissioning.py index b4a6f8f6..c364905c 100755 --- a/pylibs/unittests/test_commissioning.py +++ b/pylibs/unittests/test_commissioning.py @@ -37,7 +37,7 @@ class CommissioningTests(OTNSTestCase): def setUp(self) -> None: - self.ns = OTNS(otns_args=['-ot-script', 'none', '-log', 'debug']) + self.ns = OTNS(otns_args=['-ot-script', 'none', '-log', 'debug', '-pcap', 'wpan-tap']) self.ns.speed = float('inf') def testRawNoSetup(self): @@ -50,17 +50,30 @@ def testRawNoSetup(self): def testRawSetup(self): ns = self.ns - n1 = ns.add("router", x=0, y=0) - n2 = ns.add("router", x=50, y=0) - n3 = ns.add("router", x=0, y=50) - for id in (n1, n2, n3): - ns.set_network_name(id, "test") - ns.set_panid(id, 0xface) - ns.set_networkkey(id, "00112233445566778899aabbccddeeff") + n1 = ns.add("router") + n2 = ns.add("router") + n3 = ns.add("router") + + # n1 with full dataset becomes Leader. + ns.node_cmd(n1, "dataset init new") + ns.node_cmd(n1, "dataset panid 0xface") + ns.node_cmd(n1, "dataset extpanid dead00beef00cafe") + ns.node_cmd(n1, "dataset networkkey 00112233445566778899aabbccddeeff") + ns.node_cmd(n1, "dataset networkname test") + ns.node_cmd(n1, "dataset channel 15") + ns.node_cmd(n1, "dataset commit active") + ns.ifconfig_up(n1) + ns.thread_start(n1) + + # n2, n3 with partial dataset - if channel not given - will scan channels to find n1. + # This can take some time and may fail even then (FIXME: find cause). + # To prevent this failure, channel is provided here. + for id in (n2, n3): + ns.config_dataset(id, channel=15, panid=0xface, extpanid="dead00beef00cafe", network_name="test", networkkey="00112233445566778899aabbccddeeff") ns.ifconfig_up(id) ns.thread_start(id) - self.go(30) + self.go(300) self.assertFormPartitions(1) def testCommissioning(self): diff --git a/script/common.sh b/script/common.sh index e4ab454c..01e40065 100644 --- a/script/common.sh +++ b/script/common.sh @@ -63,13 +63,7 @@ go_install() get_openthread() { if [[ ! -f ./openthread/script/bootstrap ]]; then - git submodule update --init --recursive --depth 1 - fi -} - -get_openthread_versions() -{ - if [[ ! -f ./openthread/script/bootstrap ]]; then + # --depth 1 is not used here, due to need to build historic commits for OT nodes. git submodule update --init --recursive fi } @@ -109,7 +103,7 @@ build_openthread_br() build_openthread_versions() { - get_openthread_versions + get_openthread install_openthread_buildtools ( cd ot-rfsim diff --git a/script/install-deps b/script/install-deps index d2be3b2d..70127e14 100755 --- a/script/install-deps +++ b/script/install-deps @@ -35,6 +35,7 @@ apt_update_once=0 install_packages() { install_package wget --apt wget --brew wget || true + install_package python3-venv --apt wget --brew wget || true } install_grpcwebproxy() @@ -55,7 +56,7 @@ install_grpcwebproxy() install_python_libs() { activate_python_venv - python3 -m pip install setuptools + python3 -m pip install setuptools wheel } main() diff --git a/script/pack-web b/script/pack-web index 0e8c08e2..85560e61 100755 --- a/script/pack-web +++ b/script/pack-web @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright (c) 2020-2023, The OTNS Authors. +# Copyright (c) 2020-2024, The OTNS Authors. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -33,21 +33,20 @@ main() { readonly sitedir="$OTNSDIR"/web/site - cd "$sitedir" || return 1 - npm install - npm version - npx webpack ./js/visualize.js -o ./static/js/visualize.js - npx webpack ./js/energyViewer.js -o ./static/js/energyViewer.js - npx webpack ./js/statsViewer.js -o ./static/js/statsViewer.js + ( + cd "$sitedir" + npm install + npm version + npx webpack ./js/visualize.js -o ./static/js/visualize.js + npx webpack ./js/energyViewer.js -o ./static/js/energyViewer.js + npx webpack ./js/statsViewer.js -o ./static/js/statsViewer.js - go-bindata -pkg web_site -o _bindata.go templates/... static/... - head -26 bindata.go >_merge_bindata.go - cat _bindata.go >>_merge_bindata.go - mv _merge_bindata.go bindata.go - rm -f _bindata.go - golangci-lint run "${GOLINT_ARGS[@]}" --fix bindata.go - - cd - || return 1 + go-bindata -pkg web_site -o _bindata.go templates/... static/... + head -26 bindata.go >_merge_bindata.go + cat _bindata.go >>_merge_bindata.go + mv _merge_bindata.go bindata.go + rm -f _bindata.go + ) } ./script/compile-proto diff --git a/script/utils.sh b/script/utils.sh index f5787ce2..2de0ebf2 100644 --- a/script/utils.sh +++ b/script/utils.sh @@ -111,10 +111,10 @@ install_package() function install_pretty_tools() { if ! installed golangci-lint; then - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b "$(go env GOPATH)"/bin v1.50.1 + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b "$(go env GOPATH)"/bin v1.59.0 fi - install_package shfmt --brew shfmt --snap shfmt + go install mvdan.cc/sh/v3/cmd/shfmt@latest install_package shellcheck --apt shellcheck --brew shellcheck } diff --git a/simulation/node.go b/simulation/node.go index fac66bce..74786e0e 100644 --- a/simulation/node.go +++ b/simulation/node.go @@ -162,6 +162,10 @@ func (node *Node) runScript(cfg []string) error { } for _, cmd := range cfg { + cmd = strings.TrimSpace(cmd) + if len(cmd) == 0 || strings.HasPrefix(cmd, "#") { + continue // skip empty lines and comments + } if node.CommandResult() != nil { return node.CommandResult() } diff --git a/simulation/node_config.go b/simulation/node_config.go index 91c3bee8..27b84995 100644 --- a/simulation/node_config.go +++ b/simulation/node_config.go @@ -47,18 +47,38 @@ const ( versionLatestTag = "v14" ) -// defaultNodeInitScript is an array of commands, sent to a new node by default (unless changed). -var defaultNodeInitScript = []string{ - "networkname " + DefaultNetworkName, - "networkkey " + DefaultNetworkKey, +// defaultFtdInitScript is an array of commands, sent to a new FTD node by default (unless changed). +var defaultFtdInitScript = []string{ + "dataset init new", + fmt.Sprintf("dataset networkname %s", DefaultNetworkName), + fmt.Sprintf("dataset networkkey %s", DefaultNetworkKey), + fmt.Sprintf("dataset panid 0x%x", DefaultPanid), + fmt.Sprintf("dataset channel %d", DefaultChannel), + fmt.Sprintf("dataset extpanid %s", DefaultExtPanid), + fmt.Sprintf("dataset meshlocalprefix %s", DefaultMeshLocalPrefix), + fmt.Sprintf("dataset pskc %s", DefaultPskc), + //"routerselectionjitter 1", // jitter can be set to '1' to speed up network formation for realtime tests. + "dataset commit active", +} + +// defaultMtdInitScript is an array of commands, sent to a new MTD node by default (unless changed). +// because the MTD doesn't support 'dataset init new', an alternative way is needed to configure the +// active dataset. Another alternative (not used here) is 'dataset init tlvs 0e0800000000000100...' with +// the full dataset in hex format. +var defaultMtdInitScript = []string{ + fmt.Sprintf("networkkey %s", DefaultNetworkKey), fmt.Sprintf("panid 0x%x", DefaultPanid), fmt.Sprintf("channel %d", DefaultChannel), - //"routerselectionjitter 1", // jitter can be set to '1' to speed up network formation for realtime tests. + fmt.Sprintf("extpanid %s", DefaultExtPanid), +} + +// defaultAllInitScript is an array of commands, sent to any type of new node (as last script commands). +var defaultAllInitScript = []string{ "ifconfig up", "thread start", } -// defaultBrScript is an array of commands, sent to a new BR by default (unless changed). +// defaultBrScript is an array of additional commands, sent to a new BR by default (unless changed). var defaultBrScript = []string{ "routerselectionjitter 1", // BR wants to become Router early on. "routerdowngradethreshold 33", // BR never wants to downgrade. @@ -141,11 +161,20 @@ func DefaultNodeConfig() NodeConfig { RadioRange: defaultRadioRange, ExecutablePath: "", Restore: false, - InitScript: defaultNodeInitScript, + InitScript: []string{}, RandomSeed: 0, // 0 means not specified, i.e. truly unpredictable. } } +func DefaultNodeScripts() *YamlScriptConfig { + return &YamlScriptConfig{ + Mtd: strings.Join(defaultMtdInitScript, "\n"), + Ftd: strings.Join(defaultFtdInitScript, "\n"), + Br: strings.Join(defaultBrScript, "\n"), + All: strings.Join(defaultAllInitScript, "\n"), + } +} + // NodeConfigFinalize finalizes the configuration for a new Node before it's used to create it. This is not // mandatory to call, but a convenience method for the caller to avoid setting all details itself. func (s *Simulation) NodeConfigFinalize(nodeCfg *NodeConfig) { @@ -166,18 +195,24 @@ func (s *Simulation) NodeConfigFinalize(nodeCfg *NodeConfig) { nodeCfg.RandomSeed = prng.NewNodeRandomSeed() } - // for a BR, do extra init steps to set prefix/routes/etc. - if nodeCfg.IsBorderRouter { - nodeCfg.InitScript = append(nodeCfg.InitScript, defaultBrScript...) - } + // build node init-script + if !nodeCfg.IsRaw { + if nodeCfg.IsBorderRouter { // for a BR, do extra init steps to set prefix/routes/etc. + nodeCfg.InitScript = append(nodeCfg.InitScript, s.cfg.NewNodeScripts.BuildBrScript()...) + } else if nodeCfg.IsMtd { + nodeCfg.InitScript = append(nodeCfg.InitScript, s.cfg.NewNodeScripts.BuildMtdScript()...) + } else { + nodeCfg.InitScript = append(nodeCfg.InitScript, s.cfg.NewNodeScripts.BuildFtdScript()...) + } - // for SSED, do extra CSL init command. - if nodeCfg.Type == SSED { - cslScript := defaultCslScript - if len(nodeCfg.Version) > 0 && nodeCfg.Version <= "v13" { - cslScript = defaultLegacyCslScript // older nodes use different parameter unit + // for SSED, do extra CSL init command. + if nodeCfg.Type == SSED { + cslScript := defaultCslScript + if len(nodeCfg.Version) > 0 && nodeCfg.Version <= "v13" { + cslScript = defaultLegacyCslScript // older nodes use different parameter unit + } + nodeCfg.InitScript = append(nodeCfg.InitScript, cslScript...) } - nodeCfg.InitScript = append(nodeCfg.InitScript, cslScript...) } // for Wifi interferer, run specific script. diff --git a/simulation/nodescript_parser.go b/simulation/nodescript_parser.go index 7c7e43a8..cb48df08 100644 --- a/simulation/nodescript_parser.go +++ b/simulation/nodescript_parser.go @@ -1,4 +1,4 @@ -// Copyright (c) 2022-2023, The OTNS Authors. +// Copyright (c) 2022-2024, The OTNS Authors. // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -28,24 +28,22 @@ package simulation import ( "fmt" - "io/ioutil" - "strings" + "os" + + "gopkg.in/yaml.v3" ) -func ReadNodeScript(fn string) ([]string, error) { - script, err := ioutil.ReadFile(fn) +func ReadNodeScript(fn string) (*YamlScriptConfig, error) { + b, err := os.ReadFile(fn) if err != nil { - err = fmt.Errorf("could not read OT node script file: %s (%w)", fn, err) - return []string{}, err + err = fmt.Errorf("could not load script config file '%s': %v", fn, err) + return nil, err } - linesToFilter := strings.Split(string(script), "\n") - linesFiltered := make([]string, 0) - for _, line := range linesToFilter { - line = strings.TrimSpace(line) - if strings.HasPrefix(line, "#") || strings.HasPrefix(line, "//") || line == "" { - continue - } - linesFiltered = append(linesFiltered, line) + cfgFile := YamlConfigFile{} + err = yaml.Unmarshal(b, &cfgFile) + if err != nil { + err = fmt.Errorf("error in YAML file: %v", err) + return nil, err } - return linesFiltered, nil + return &cfgFile.ScriptConfig, nil } diff --git a/simulation/simulation_config.go b/simulation/simulation_config.go index 3a1b3c45..7af4d166 100644 --- a/simulation/simulation_config.go +++ b/simulation/simulation_config.go @@ -33,16 +33,20 @@ import ( ) const ( - DefaultNetworkName = "OTSIM" - DefaultNetworkKey = "00112233445566778899aabbccddeeff" - DefaultPanid = 0xface - DefaultChannel = 11 + DefaultChannel = 11 + DefaultExtPanid = "dead00beef00cafe" + DefaultMeshLocalPrefix = "fdde:ad00:beef:0::" + DefaultNetworkKey = "00112233445566778899aabbccddeeff" + DefaultNetworkName = "otns" + DefaultPanid = 0xface + DefaultPskc = "3aa55f91ca47d1e4e71a08cb35e91591" ) type Config struct { ExeConfig ExecutableConfig ExeConfigDefault ExecutableConfig NewNodeConfig NodeConfig + NewNodeScripts *YamlScriptConfig Speed float64 ReadOnly bool Realtime bool @@ -64,6 +68,7 @@ func DefaultConfig() *Config { ExeConfig: DefaultExecutableConfig, ExeConfigDefault: DefaultExecutableConfig, NewNodeConfig: DefaultNodeConfig(), + NewNodeScripts: DefaultNodeScripts(), Speed: 1, ReadOnly: false, Realtime: false, diff --git a/simulation/types.go b/simulation/types.go index 4cbf3f78..65ee6ae2 100644 --- a/simulation/types.go +++ b/simulation/types.go @@ -30,6 +30,7 @@ import ( "fmt" "io" "regexp" + "strings" . "github.com/openthread/ot-ns/types" ) @@ -64,10 +65,19 @@ type NodeCounters map[string]int // YamlConfigFile is the complete YAML structure for a config file for load/save. type YamlConfigFile struct { + ScriptConfig YamlScriptConfig `yaml:"script"` NetworkConfig YamlNetworkConfig `yaml:"network"` NodesList []YamlNodeConfig `yaml:"nodes"` } +// YamlScriptConfig defines startup scripts for nodes, depending on node type. +type YamlScriptConfig struct { + Mtd string `yaml:"mtd"` + Ftd string `yaml:"ftd"` + Br string `yaml:"br"` + All string `yaml:"all"` +} + // YamlNetworkConfig is a global network config that can be loaded/saved in YAML. type YamlNetworkConfig struct { Position [3]int `yaml:"pos-shift,flow"` // provides an optional 3D position shift of all nodes. @@ -93,3 +103,18 @@ func (yc *YamlConfigFile) MinNodeId() NodeId { } return m } + +func (ys *YamlScriptConfig) BuildMtdScript() []string { + script := ys.Mtd + "\n" + ys.All + return strings.Split(script, "\n") +} + +func (ys *YamlScriptConfig) BuildFtdScript() []string { + script := ys.Ftd + "\n" + ys.All + return strings.Split(script, "\n") +} + +func (ys *YamlScriptConfig) BuildBrScript() []string { + script := ys.Ftd + "\n" + ys.Br + "\n" + ys.All + return strings.Split(script, "\n") +} diff --git a/types/node_config.go b/types/node_config.go index 7312f3eb..55127d18 100644 --- a/types/node_config.go +++ b/types/node_config.go @@ -43,7 +43,7 @@ type NodeConfig struct { RadioRange int ExecutablePath string // executable full path or "" for auto-determined Restore bool - InitScript []string + InitScript []string // a sequence of CLI commands executed at first startup of node RandomSeed int32 } diff --git a/web/site/bindata.go b/web/site/bindata.go index 8fb240db..a8824138 100644 --- a/web/site/bindata.go +++ b/web/site/bindata.go @@ -1396,166 +1396,163 @@ func AssetNames() []string { // _bindata is a table, holding each asset generator, mapped to its name. var _bindata = map[string]func() ([]byte, error){ - "static/image/checked-checkbox-32.png": static_image_checked_checkbox_32_png, - "static/image/gua.png": static_image_gua_png, - "static/image/pause-32.png": static_image_pause_32_png, - "static/image/play-32.png": static_image_play_32_png, - "static/image/unchecked-checkbox-32.png": static_image_unchecked_checkbox_32_png, - "static/image/white-shapes/circle-128.png": static_image_white_shapes_circle_128_png, - "static/image/white-shapes/circle-16.png": static_image_white_shapes_circle_16_png, - "static/image/white-shapes/circle-24.png": static_image_white_shapes_circle_24_png, - "static/image/white-shapes/circle-256.png": static_image_white_shapes_circle_256_png, - "static/image/white-shapes/circle-32.png": static_image_white_shapes_circle_32_png, - "static/image/white-shapes/circle-48.png": static_image_white_shapes_circle_48_png, - "static/image/white-shapes/circle-512.png": static_image_white_shapes_circle_512_png, - "static/image/white-shapes/circle-64.png": static_image_white_shapes_circle_64_png, - "static/image/white-shapes/circle-dashed-4-128.png": static_image_white_shapes_circle_dashed_4_128_png, - "static/image/white-shapes/circle-dashed-4-16.png": static_image_white_shapes_circle_dashed_4_16_png, - "static/image/white-shapes/circle-dashed-4-24.png": static_image_white_shapes_circle_dashed_4_24_png, - "static/image/white-shapes/circle-dashed-4-256.png": static_image_white_shapes_circle_dashed_4_256_png, - "static/image/white-shapes/circle-dashed-4-32.png": static_image_white_shapes_circle_dashed_4_32_png, - "static/image/white-shapes/circle-dashed-4-48.png": static_image_white_shapes_circle_dashed_4_48_png, - "static/image/white-shapes/circle-dashed-4-512.png": static_image_white_shapes_circle_dashed_4_512_png, - "static/image/white-shapes/circle-dashed-4-64.png": static_image_white_shapes_circle_dashed_4_64_png, - "static/image/white-shapes/circle-dashed-6-128.png": static_image_white_shapes_circle_dashed_6_128_png, - "static/image/white-shapes/circle-dashed-6-16.png": static_image_white_shapes_circle_dashed_6_16_png, - "static/image/white-shapes/circle-dashed-6-24.png": static_image_white_shapes_circle_dashed_6_24_png, - "static/image/white-shapes/circle-dashed-6-256.png": static_image_white_shapes_circle_dashed_6_256_png, - "static/image/white-shapes/circle-dashed-6-32.png": static_image_white_shapes_circle_dashed_6_32_png, - "static/image/white-shapes/circle-dashed-6-48.png": static_image_white_shapes_circle_dashed_6_48_png, - "static/image/white-shapes/circle-dashed-6-512.png": static_image_white_shapes_circle_dashed_6_512_png, - "static/image/white-shapes/circle-dashed-6-64.png": static_image_white_shapes_circle_dashed_6_64_png, - "static/image/white-shapes/circle-dashed-8-128.png": static_image_white_shapes_circle_dashed_8_128_png, - "static/image/white-shapes/circle-dashed-8-16.png": static_image_white_shapes_circle_dashed_8_16_png, - "static/image/white-shapes/circle-dashed-8-24.png": static_image_white_shapes_circle_dashed_8_24_png, - "static/image/white-shapes/circle-dashed-8-256.png": static_image_white_shapes_circle_dashed_8_256_png, - "static/image/white-shapes/circle-dashed-8-32.png": static_image_white_shapes_circle_dashed_8_32_png, - "static/image/white-shapes/circle-dashed-8-48.png": static_image_white_shapes_circle_dashed_8_48_png, - "static/image/white-shapes/circle-dashed-8-512.png": static_image_white_shapes_circle_dashed_8_512_png, - "static/image/white-shapes/circle-dashed-8-64.png": static_image_white_shapes_circle_dashed_8_64_png, - "static/image/white-shapes/circle-outline-128.png": static_image_white_shapes_circle_outline_128_png, - "static/image/white-shapes/circle-outline-16.png": static_image_white_shapes_circle_outline_16_png, - "static/image/white-shapes/circle-outline-24.png": static_image_white_shapes_circle_outline_24_png, - "static/image/white-shapes/circle-outline-256.png": static_image_white_shapes_circle_outline_256_png, - "static/image/white-shapes/circle-outline-32.png": static_image_white_shapes_circle_outline_32_png, - "static/image/white-shapes/circle-outline-48.png": static_image_white_shapes_circle_outline_48_png, - "static/image/white-shapes/circle-outline-512.png": static_image_white_shapes_circle_outline_512_png, - "static/image/white-shapes/circle-outline-64.png": static_image_white_shapes_circle_outline_64_png, - "static/image/white-shapes/hexagon-128.png": static_image_white_shapes_hexagon_128_png, - "static/image/white-shapes/hexagon-16.png": static_image_white_shapes_hexagon_16_png, - "static/image/white-shapes/hexagon-24.png": static_image_white_shapes_hexagon_24_png, - "static/image/white-shapes/hexagon-256.png": static_image_white_shapes_hexagon_256_png, - "static/image/white-shapes/hexagon-32.png": static_image_white_shapes_hexagon_32_png, - "static/image/white-shapes/hexagon-48.png": static_image_white_shapes_hexagon_48_png, - "static/image/white-shapes/hexagon-512.png": static_image_white_shapes_hexagon_512_png, - "static/image/white-shapes/hexagon-64.png": static_image_white_shapes_hexagon_64_png, - "static/image/white-shapes/hexagon-outline-128.png": static_image_white_shapes_hexagon_outline_128_png, - "static/image/white-shapes/hexagon-outline-16.png": static_image_white_shapes_hexagon_outline_16_png, - "static/image/white-shapes/hexagon-outline-24.png": static_image_white_shapes_hexagon_outline_24_png, - "static/image/white-shapes/hexagon-outline-256.png": static_image_white_shapes_hexagon_outline_256_png, - "static/image/white-shapes/hexagon-outline-32.png": static_image_white_shapes_hexagon_outline_32_png, - "static/image/white-shapes/hexagon-outline-48.png": static_image_white_shapes_hexagon_outline_48_png, - "static/image/white-shapes/hexagon-outline-512.png": static_image_white_shapes_hexagon_outline_512_png, - "static/image/white-shapes/hexagon-outline-64.png": static_image_white_shapes_hexagon_outline_64_png, - "static/image/white-shapes/octagon-128.png": static_image_white_shapes_octagon_128_png, - "static/image/white-shapes/octagon-16.png": static_image_white_shapes_octagon_16_png, - "static/image/white-shapes/octagon-24.png": static_image_white_shapes_octagon_24_png, - "static/image/white-shapes/octagon-256.png": static_image_white_shapes_octagon_256_png, - "static/image/white-shapes/octagon-32.png": static_image_white_shapes_octagon_32_png, - "static/image/white-shapes/octagon-48.png": static_image_white_shapes_octagon_48_png, - "static/image/white-shapes/octagon-512.png": static_image_white_shapes_octagon_512_png, - "static/image/white-shapes/octagon-64.png": static_image_white_shapes_octagon_64_png, - "static/image/white-shapes/octagon-outline-128.png": static_image_white_shapes_octagon_outline_128_png, - "static/image/white-shapes/octagon-outline-16.png": static_image_white_shapes_octagon_outline_16_png, - "static/image/white-shapes/octagon-outline-24.png": static_image_white_shapes_octagon_outline_24_png, - "static/image/white-shapes/octagon-outline-256.png": static_image_white_shapes_octagon_outline_256_png, - "static/image/white-shapes/octagon-outline-32.png": static_image_white_shapes_octagon_outline_32_png, - "static/image/white-shapes/octagon-outline-48.png": static_image_white_shapes_octagon_outline_48_png, - "static/image/white-shapes/octagon-outline-512.png": static_image_white_shapes_octagon_outline_512_png, - "static/image/white-shapes/octagon-outline-64.png": static_image_white_shapes_octagon_outline_64_png, - "static/image/white-shapes/square-128.png": static_image_white_shapes_square_128_png, - "static/image/white-shapes/square-16.png": static_image_white_shapes_square_16_png, - "static/image/white-shapes/square-24.png": static_image_white_shapes_square_24_png, - "static/image/white-shapes/square-256.png": static_image_white_shapes_square_256_png, - "static/image/white-shapes/square-32.png": static_image_white_shapes_square_32_png, - "static/image/white-shapes/square-48.png": static_image_white_shapes_square_48_png, - "static/image/white-shapes/square-512.png": static_image_white_shapes_square_512_png, - "static/image/white-shapes/square-64.png": static_image_white_shapes_square_64_png, - "static/image/white-shapes/square-dashed-128.png": static_image_white_shapes_square_dashed_128_png, - "static/image/white-shapes/square-dashed-16.png": static_image_white_shapes_square_dashed_16_png, - "static/image/white-shapes/square-dashed-24.png": static_image_white_shapes_square_dashed_24_png, - "static/image/white-shapes/square-dashed-256.png": static_image_white_shapes_square_dashed_256_png, - "static/image/white-shapes/square-dashed-32.png": static_image_white_shapes_square_dashed_32_png, - "static/image/white-shapes/square-dashed-48.png": static_image_white_shapes_square_dashed_48_png, - "static/image/white-shapes/square-dashed-512.png": static_image_white_shapes_square_dashed_512_png, - "static/image/white-shapes/square-dashed-64.png": static_image_white_shapes_square_dashed_64_png, + "static/image/checked-checkbox-32.png": static_image_checked_checkbox_32_png, + "static/image/gua.png": static_image_gua_png, + "static/image/pause-32.png": static_image_pause_32_png, + "static/image/play-32.png": static_image_play_32_png, + "static/image/unchecked-checkbox-32.png": static_image_unchecked_checkbox_32_png, + "static/image/white-shapes/circle-128.png": static_image_white_shapes_circle_128_png, + "static/image/white-shapes/circle-16.png": static_image_white_shapes_circle_16_png, + "static/image/white-shapes/circle-24.png": static_image_white_shapes_circle_24_png, + "static/image/white-shapes/circle-256.png": static_image_white_shapes_circle_256_png, + "static/image/white-shapes/circle-32.png": static_image_white_shapes_circle_32_png, + "static/image/white-shapes/circle-48.png": static_image_white_shapes_circle_48_png, + "static/image/white-shapes/circle-512.png": static_image_white_shapes_circle_512_png, + "static/image/white-shapes/circle-64.png": static_image_white_shapes_circle_64_png, + "static/image/white-shapes/circle-dashed-4-128.png": static_image_white_shapes_circle_dashed_4_128_png, + "static/image/white-shapes/circle-dashed-4-16.png": static_image_white_shapes_circle_dashed_4_16_png, + "static/image/white-shapes/circle-dashed-4-24.png": static_image_white_shapes_circle_dashed_4_24_png, + "static/image/white-shapes/circle-dashed-4-256.png": static_image_white_shapes_circle_dashed_4_256_png, + "static/image/white-shapes/circle-dashed-4-32.png": static_image_white_shapes_circle_dashed_4_32_png, + "static/image/white-shapes/circle-dashed-4-48.png": static_image_white_shapes_circle_dashed_4_48_png, + "static/image/white-shapes/circle-dashed-4-512.png": static_image_white_shapes_circle_dashed_4_512_png, + "static/image/white-shapes/circle-dashed-4-64.png": static_image_white_shapes_circle_dashed_4_64_png, + "static/image/white-shapes/circle-dashed-6-128.png": static_image_white_shapes_circle_dashed_6_128_png, + "static/image/white-shapes/circle-dashed-6-16.png": static_image_white_shapes_circle_dashed_6_16_png, + "static/image/white-shapes/circle-dashed-6-24.png": static_image_white_shapes_circle_dashed_6_24_png, + "static/image/white-shapes/circle-dashed-6-256.png": static_image_white_shapes_circle_dashed_6_256_png, + "static/image/white-shapes/circle-dashed-6-32.png": static_image_white_shapes_circle_dashed_6_32_png, + "static/image/white-shapes/circle-dashed-6-48.png": static_image_white_shapes_circle_dashed_6_48_png, + "static/image/white-shapes/circle-dashed-6-512.png": static_image_white_shapes_circle_dashed_6_512_png, + "static/image/white-shapes/circle-dashed-6-64.png": static_image_white_shapes_circle_dashed_6_64_png, + "static/image/white-shapes/circle-dashed-8-128.png": static_image_white_shapes_circle_dashed_8_128_png, + "static/image/white-shapes/circle-dashed-8-16.png": static_image_white_shapes_circle_dashed_8_16_png, + "static/image/white-shapes/circle-dashed-8-24.png": static_image_white_shapes_circle_dashed_8_24_png, + "static/image/white-shapes/circle-dashed-8-256.png": static_image_white_shapes_circle_dashed_8_256_png, + "static/image/white-shapes/circle-dashed-8-32.png": static_image_white_shapes_circle_dashed_8_32_png, + "static/image/white-shapes/circle-dashed-8-48.png": static_image_white_shapes_circle_dashed_8_48_png, + "static/image/white-shapes/circle-dashed-8-512.png": static_image_white_shapes_circle_dashed_8_512_png, + "static/image/white-shapes/circle-dashed-8-64.png": static_image_white_shapes_circle_dashed_8_64_png, + "static/image/white-shapes/circle-outline-128.png": static_image_white_shapes_circle_outline_128_png, + "static/image/white-shapes/circle-outline-16.png": static_image_white_shapes_circle_outline_16_png, + "static/image/white-shapes/circle-outline-24.png": static_image_white_shapes_circle_outline_24_png, + "static/image/white-shapes/circle-outline-256.png": static_image_white_shapes_circle_outline_256_png, + "static/image/white-shapes/circle-outline-32.png": static_image_white_shapes_circle_outline_32_png, + "static/image/white-shapes/circle-outline-48.png": static_image_white_shapes_circle_outline_48_png, + "static/image/white-shapes/circle-outline-512.png": static_image_white_shapes_circle_outline_512_png, + "static/image/white-shapes/circle-outline-64.png": static_image_white_shapes_circle_outline_64_png, + "static/image/white-shapes/hexagon-128.png": static_image_white_shapes_hexagon_128_png, + "static/image/white-shapes/hexagon-16.png": static_image_white_shapes_hexagon_16_png, + "static/image/white-shapes/hexagon-24.png": static_image_white_shapes_hexagon_24_png, + "static/image/white-shapes/hexagon-256.png": static_image_white_shapes_hexagon_256_png, + "static/image/white-shapes/hexagon-32.png": static_image_white_shapes_hexagon_32_png, + "static/image/white-shapes/hexagon-48.png": static_image_white_shapes_hexagon_48_png, + "static/image/white-shapes/hexagon-512.png": static_image_white_shapes_hexagon_512_png, + "static/image/white-shapes/hexagon-64.png": static_image_white_shapes_hexagon_64_png, + "static/image/white-shapes/hexagon-outline-128.png": static_image_white_shapes_hexagon_outline_128_png, + "static/image/white-shapes/hexagon-outline-16.png": static_image_white_shapes_hexagon_outline_16_png, + "static/image/white-shapes/hexagon-outline-24.png": static_image_white_shapes_hexagon_outline_24_png, + "static/image/white-shapes/hexagon-outline-256.png": static_image_white_shapes_hexagon_outline_256_png, + "static/image/white-shapes/hexagon-outline-32.png": static_image_white_shapes_hexagon_outline_32_png, + "static/image/white-shapes/hexagon-outline-48.png": static_image_white_shapes_hexagon_outline_48_png, + "static/image/white-shapes/hexagon-outline-512.png": static_image_white_shapes_hexagon_outline_512_png, + "static/image/white-shapes/hexagon-outline-64.png": static_image_white_shapes_hexagon_outline_64_png, + "static/image/white-shapes/octagon-128.png": static_image_white_shapes_octagon_128_png, + "static/image/white-shapes/octagon-16.png": static_image_white_shapes_octagon_16_png, + "static/image/white-shapes/octagon-24.png": static_image_white_shapes_octagon_24_png, + "static/image/white-shapes/octagon-256.png": static_image_white_shapes_octagon_256_png, + "static/image/white-shapes/octagon-32.png": static_image_white_shapes_octagon_32_png, + "static/image/white-shapes/octagon-48.png": static_image_white_shapes_octagon_48_png, + "static/image/white-shapes/octagon-512.png": static_image_white_shapes_octagon_512_png, + "static/image/white-shapes/octagon-64.png": static_image_white_shapes_octagon_64_png, + "static/image/white-shapes/octagon-outline-128.png": static_image_white_shapes_octagon_outline_128_png, + "static/image/white-shapes/octagon-outline-16.png": static_image_white_shapes_octagon_outline_16_png, + "static/image/white-shapes/octagon-outline-24.png": static_image_white_shapes_octagon_outline_24_png, + "static/image/white-shapes/octagon-outline-256.png": static_image_white_shapes_octagon_outline_256_png, + "static/image/white-shapes/octagon-outline-32.png": static_image_white_shapes_octagon_outline_32_png, + "static/image/white-shapes/octagon-outline-48.png": static_image_white_shapes_octagon_outline_48_png, + "static/image/white-shapes/octagon-outline-512.png": static_image_white_shapes_octagon_outline_512_png, + "static/image/white-shapes/octagon-outline-64.png": static_image_white_shapes_octagon_outline_64_png, + "static/image/white-shapes/square-128.png": static_image_white_shapes_square_128_png, + "static/image/white-shapes/square-16.png": static_image_white_shapes_square_16_png, + "static/image/white-shapes/square-24.png": static_image_white_shapes_square_24_png, + "static/image/white-shapes/square-256.png": static_image_white_shapes_square_256_png, + "static/image/white-shapes/square-32.png": static_image_white_shapes_square_32_png, + "static/image/white-shapes/square-48.png": static_image_white_shapes_square_48_png, + "static/image/white-shapes/square-512.png": static_image_white_shapes_square_512_png, + "static/image/white-shapes/square-64.png": static_image_white_shapes_square_64_png, + "static/image/white-shapes/square-dashed-128.png": static_image_white_shapes_square_dashed_128_png, + "static/image/white-shapes/square-dashed-16.png": static_image_white_shapes_square_dashed_16_png, + "static/image/white-shapes/square-dashed-24.png": static_image_white_shapes_square_dashed_24_png, + "static/image/white-shapes/square-dashed-256.png": static_image_white_shapes_square_dashed_256_png, + "static/image/white-shapes/square-dashed-32.png": static_image_white_shapes_square_dashed_32_png, + "static/image/white-shapes/square-dashed-48.png": static_image_white_shapes_square_dashed_48_png, + "static/image/white-shapes/square-dashed-512.png": static_image_white_shapes_square_dashed_512_png, + "static/image/white-shapes/square-dashed-64.png": static_image_white_shapes_square_dashed_64_png, "static/image/white-shapes/square-dashed-rounded-128.png": static_image_white_shapes_square_dashed_rounded_128_png, - "static/image/white-shapes/square-dashed-rounded-16.png": static_image_white_shapes_square_dashed_rounded_16_png, - "static/image/white-shapes/square-dashed-rounded-24.png": static_image_white_shapes_square_dashed_rounded_24_png, + "static/image/white-shapes/square-dashed-rounded-16.png": static_image_white_shapes_square_dashed_rounded_16_png, + "static/image/white-shapes/square-dashed-rounded-24.png": static_image_white_shapes_square_dashed_rounded_24_png, "static/image/white-shapes/square-dashed-rounded-256.png": static_image_white_shapes_square_dashed_rounded_256_png, - "static/image/white-shapes/square-dashed-rounded-32.png": static_image_white_shapes_square_dashed_rounded_32_png, - "static/image/white-shapes/square-dashed-rounded-48.png": static_image_white_shapes_square_dashed_rounded_48_png, + "static/image/white-shapes/square-dashed-rounded-32.png": static_image_white_shapes_square_dashed_rounded_32_png, + "static/image/white-shapes/square-dashed-rounded-48.png": static_image_white_shapes_square_dashed_rounded_48_png, "static/image/white-shapes/square-dashed-rounded-512.png": static_image_white_shapes_square_dashed_rounded_512_png, - "static/image/white-shapes/square-dashed-rounded-64.png": static_image_white_shapes_square_dashed_rounded_64_png, - "static/image/white-shapes/square-ios-app-128.png": static_image_white_shapes_square_ios_app_128_png, - "static/image/white-shapes/square-ios-app-16.png": static_image_white_shapes_square_ios_app_16_png, - "static/image/white-shapes/square-ios-app-24.png": static_image_white_shapes_square_ios_app_24_png, - "static/image/white-shapes/square-ios-app-256.png": static_image_white_shapes_square_ios_app_256_png, - "static/image/white-shapes/square-ios-app-32.png": static_image_white_shapes_square_ios_app_32_png, - "static/image/white-shapes/square-ios-app-48.png": static_image_white_shapes_square_ios_app_48_png, - "static/image/white-shapes/square-ios-app-512.png": static_image_white_shapes_square_ios_app_512_png, - "static/image/white-shapes/square-ios-app-64.png": static_image_white_shapes_square_ios_app_64_png, - "static/image/white-shapes/square-outline-128.png": static_image_white_shapes_square_outline_128_png, - "static/image/white-shapes/square-outline-16.png": static_image_white_shapes_square_outline_16_png, - "static/image/white-shapes/square-outline-24.png": static_image_white_shapes_square_outline_24_png, - "static/image/white-shapes/square-outline-256.png": static_image_white_shapes_square_outline_256_png, - "static/image/white-shapes/square-outline-32.png": static_image_white_shapes_square_outline_32_png, - "static/image/white-shapes/square-outline-48.png": static_image_white_shapes_square_outline_48_png, - "static/image/white-shapes/square-outline-512.png": static_image_white_shapes_square_outline_512_png, - "static/image/white-shapes/square-outline-64.png": static_image_white_shapes_square_outline_64_png, - "static/image/white-shapes/square-rounded-128.png": static_image_white_shapes_square_rounded_128_png, - "static/image/white-shapes/square-rounded-16.png": static_image_white_shapes_square_rounded_16_png, - "static/image/white-shapes/square-rounded-24.png": static_image_white_shapes_square_rounded_24_png, - "static/image/white-shapes/square-rounded-256.png": static_image_white_shapes_square_rounded_256_png, - "static/image/white-shapes/square-rounded-32.png": static_image_white_shapes_square_rounded_32_png, - "static/image/white-shapes/square-rounded-48.png": static_image_white_shapes_square_rounded_48_png, - "static/image/white-shapes/square-rounded-512.png": static_image_white_shapes_square_rounded_512_png, - "static/image/white-shapes/square-rounded-64.png": static_image_white_shapes_square_rounded_64_png, - "static/image/white-shapes/triangle-128.png": static_image_white_shapes_triangle_128_png, - "static/image/white-shapes/triangle-16.png": static_image_white_shapes_triangle_16_png, - "static/image/white-shapes/triangle-24.png": static_image_white_shapes_triangle_24_png, - "static/image/white-shapes/triangle-256.png": static_image_white_shapes_triangle_256_png, - "static/image/white-shapes/triangle-32.png": static_image_white_shapes_triangle_32_png, - "static/image/white-shapes/triangle-48.png": static_image_white_shapes_triangle_48_png, - "static/image/white-shapes/triangle-512.png": static_image_white_shapes_triangle_512_png, - "static/image/white-shapes/triangle-64.png": static_image_white_shapes_triangle_64_png, - "static/image/white-shapes/triangle-outline-128.png": static_image_white_shapes_triangle_outline_128_png, - "static/image/white-shapes/triangle-outline-16.png": static_image_white_shapes_triangle_outline_16_png, - "static/image/white-shapes/triangle-outline-24.png": static_image_white_shapes_triangle_outline_24_png, - "static/image/white-shapes/triangle-outline-256.png": static_image_white_shapes_triangle_outline_256_png, - "static/image/white-shapes/triangle-outline-32.png": static_image_white_shapes_triangle_outline_32_png, - "static/image/white-shapes/triangle-outline-48.png": static_image_white_shapes_triangle_outline_48_png, - "static/image/white-shapes/triangle-outline-512.png": static_image_white_shapes_triangle_outline_512_png, - "static/image/white-shapes/triangle-outline-64.png": static_image_white_shapes_triangle_outline_64_png, - "static/js/energyViewer.js": static_js_energyviewer_js, - "static/js/statsViewer.js": static_js_statsviewer_js, - "static/js/visualize.js": static_js_visualize_js, - "templates/energyViewer.html": templates_energyviewer_html, - "templates/statsViewer.html": templates_statsviewer_html, - "templates/visualize.html": templates_visualize_html, + "static/image/white-shapes/square-dashed-rounded-64.png": static_image_white_shapes_square_dashed_rounded_64_png, + "static/image/white-shapes/square-ios-app-128.png": static_image_white_shapes_square_ios_app_128_png, + "static/image/white-shapes/square-ios-app-16.png": static_image_white_shapes_square_ios_app_16_png, + "static/image/white-shapes/square-ios-app-24.png": static_image_white_shapes_square_ios_app_24_png, + "static/image/white-shapes/square-ios-app-256.png": static_image_white_shapes_square_ios_app_256_png, + "static/image/white-shapes/square-ios-app-32.png": static_image_white_shapes_square_ios_app_32_png, + "static/image/white-shapes/square-ios-app-48.png": static_image_white_shapes_square_ios_app_48_png, + "static/image/white-shapes/square-ios-app-512.png": static_image_white_shapes_square_ios_app_512_png, + "static/image/white-shapes/square-ios-app-64.png": static_image_white_shapes_square_ios_app_64_png, + "static/image/white-shapes/square-outline-128.png": static_image_white_shapes_square_outline_128_png, + "static/image/white-shapes/square-outline-16.png": static_image_white_shapes_square_outline_16_png, + "static/image/white-shapes/square-outline-24.png": static_image_white_shapes_square_outline_24_png, + "static/image/white-shapes/square-outline-256.png": static_image_white_shapes_square_outline_256_png, + "static/image/white-shapes/square-outline-32.png": static_image_white_shapes_square_outline_32_png, + "static/image/white-shapes/square-outline-48.png": static_image_white_shapes_square_outline_48_png, + "static/image/white-shapes/square-outline-512.png": static_image_white_shapes_square_outline_512_png, + "static/image/white-shapes/square-outline-64.png": static_image_white_shapes_square_outline_64_png, + "static/image/white-shapes/square-rounded-128.png": static_image_white_shapes_square_rounded_128_png, + "static/image/white-shapes/square-rounded-16.png": static_image_white_shapes_square_rounded_16_png, + "static/image/white-shapes/square-rounded-24.png": static_image_white_shapes_square_rounded_24_png, + "static/image/white-shapes/square-rounded-256.png": static_image_white_shapes_square_rounded_256_png, + "static/image/white-shapes/square-rounded-32.png": static_image_white_shapes_square_rounded_32_png, + "static/image/white-shapes/square-rounded-48.png": static_image_white_shapes_square_rounded_48_png, + "static/image/white-shapes/square-rounded-512.png": static_image_white_shapes_square_rounded_512_png, + "static/image/white-shapes/square-rounded-64.png": static_image_white_shapes_square_rounded_64_png, + "static/image/white-shapes/triangle-128.png": static_image_white_shapes_triangle_128_png, + "static/image/white-shapes/triangle-16.png": static_image_white_shapes_triangle_16_png, + "static/image/white-shapes/triangle-24.png": static_image_white_shapes_triangle_24_png, + "static/image/white-shapes/triangle-256.png": static_image_white_shapes_triangle_256_png, + "static/image/white-shapes/triangle-32.png": static_image_white_shapes_triangle_32_png, + "static/image/white-shapes/triangle-48.png": static_image_white_shapes_triangle_48_png, + "static/image/white-shapes/triangle-512.png": static_image_white_shapes_triangle_512_png, + "static/image/white-shapes/triangle-64.png": static_image_white_shapes_triangle_64_png, + "static/image/white-shapes/triangle-outline-128.png": static_image_white_shapes_triangle_outline_128_png, + "static/image/white-shapes/triangle-outline-16.png": static_image_white_shapes_triangle_outline_16_png, + "static/image/white-shapes/triangle-outline-24.png": static_image_white_shapes_triangle_outline_24_png, + "static/image/white-shapes/triangle-outline-256.png": static_image_white_shapes_triangle_outline_256_png, + "static/image/white-shapes/triangle-outline-32.png": static_image_white_shapes_triangle_outline_32_png, + "static/image/white-shapes/triangle-outline-48.png": static_image_white_shapes_triangle_outline_48_png, + "static/image/white-shapes/triangle-outline-512.png": static_image_white_shapes_triangle_outline_512_png, + "static/image/white-shapes/triangle-outline-64.png": static_image_white_shapes_triangle_outline_64_png, + "static/js/energyViewer.js": static_js_energyviewer_js, + "static/js/statsViewer.js": static_js_statsviewer_js, + "static/js/visualize.js": static_js_visualize_js, + "templates/energyViewer.html": templates_energyviewer_html, + "templates/statsViewer.html": templates_statsviewer_html, + "templates/visualize.html": templates_visualize_html, } - // AssetDir returns the file names below a certain // directory embedded in the file by go-bindata. // For example if you run go-bindata on data/... and data contains the // following hierarchy: -// -// data/ -// foo.txt -// img/ -// a.png -// b.png -// +// data/ +// foo.txt +// img/ +// a.png +// b.png // then AssetDir("data") would return []string{"foo.txt", "img"} // AssetDir("data/img") would return []string{"a.png", "b.png"} // AssetDir("foo.txt") and AssetDir("notexist") would return an error @@ -1583,166 +1580,312 @@ func AssetDir(name string) ([]string, error) { } type _bintree_t struct { - Func func() ([]byte, error) + Func func() ([]byte, error) Children map[string]*_bintree_t } - var _bintree = &_bintree_t{nil, map[string]*_bintree_t{ "static": &_bintree_t{nil, map[string]*_bintree_t{ "image": &_bintree_t{nil, map[string]*_bintree_t{ - "checked-checkbox-32.png": &_bintree_t{static_image_checked_checkbox_32_png, map[string]*_bintree_t{}}, - "gua.png": &_bintree_t{static_image_gua_png, map[string]*_bintree_t{}}, - "pause-32.png": &_bintree_t{static_image_pause_32_png, map[string]*_bintree_t{}}, - "play-32.png": &_bintree_t{static_image_play_32_png, map[string]*_bintree_t{}}, - "unchecked-checkbox-32.png": &_bintree_t{static_image_unchecked_checkbox_32_png, map[string]*_bintree_t{}}, + "checked-checkbox-32.png": &_bintree_t{static_image_checked_checkbox_32_png, map[string]*_bintree_t{ + }}, + "gua.png": &_bintree_t{static_image_gua_png, map[string]*_bintree_t{ + }}, + "pause-32.png": &_bintree_t{static_image_pause_32_png, map[string]*_bintree_t{ + }}, + "play-32.png": &_bintree_t{static_image_play_32_png, map[string]*_bintree_t{ + }}, + "unchecked-checkbox-32.png": &_bintree_t{static_image_unchecked_checkbox_32_png, map[string]*_bintree_t{ + }}, "white-shapes": &_bintree_t{nil, map[string]*_bintree_t{ - "circle-128.png": &_bintree_t{static_image_white_shapes_circle_128_png, map[string]*_bintree_t{}}, - "circle-16.png": &_bintree_t{static_image_white_shapes_circle_16_png, map[string]*_bintree_t{}}, - "circle-24.png": &_bintree_t{static_image_white_shapes_circle_24_png, map[string]*_bintree_t{}}, - "circle-256.png": &_bintree_t{static_image_white_shapes_circle_256_png, map[string]*_bintree_t{}}, - "circle-32.png": &_bintree_t{static_image_white_shapes_circle_32_png, map[string]*_bintree_t{}}, - "circle-48.png": &_bintree_t{static_image_white_shapes_circle_48_png, map[string]*_bintree_t{}}, - "circle-512.png": &_bintree_t{static_image_white_shapes_circle_512_png, map[string]*_bintree_t{}}, - "circle-64.png": &_bintree_t{static_image_white_shapes_circle_64_png, map[string]*_bintree_t{}}, - "circle-dashed-4-128.png": &_bintree_t{static_image_white_shapes_circle_dashed_4_128_png, map[string]*_bintree_t{}}, - "circle-dashed-4-16.png": &_bintree_t{static_image_white_shapes_circle_dashed_4_16_png, map[string]*_bintree_t{}}, - "circle-dashed-4-24.png": &_bintree_t{static_image_white_shapes_circle_dashed_4_24_png, map[string]*_bintree_t{}}, - "circle-dashed-4-256.png": &_bintree_t{static_image_white_shapes_circle_dashed_4_256_png, map[string]*_bintree_t{}}, - "circle-dashed-4-32.png": &_bintree_t{static_image_white_shapes_circle_dashed_4_32_png, map[string]*_bintree_t{}}, - "circle-dashed-4-48.png": &_bintree_t{static_image_white_shapes_circle_dashed_4_48_png, map[string]*_bintree_t{}}, - "circle-dashed-4-512.png": &_bintree_t{static_image_white_shapes_circle_dashed_4_512_png, map[string]*_bintree_t{}}, - "circle-dashed-4-64.png": &_bintree_t{static_image_white_shapes_circle_dashed_4_64_png, map[string]*_bintree_t{}}, - "circle-dashed-6-128.png": &_bintree_t{static_image_white_shapes_circle_dashed_6_128_png, map[string]*_bintree_t{}}, - "circle-dashed-6-16.png": &_bintree_t{static_image_white_shapes_circle_dashed_6_16_png, map[string]*_bintree_t{}}, - "circle-dashed-6-24.png": &_bintree_t{static_image_white_shapes_circle_dashed_6_24_png, map[string]*_bintree_t{}}, - "circle-dashed-6-256.png": &_bintree_t{static_image_white_shapes_circle_dashed_6_256_png, map[string]*_bintree_t{}}, - "circle-dashed-6-32.png": &_bintree_t{static_image_white_shapes_circle_dashed_6_32_png, map[string]*_bintree_t{}}, - "circle-dashed-6-48.png": &_bintree_t{static_image_white_shapes_circle_dashed_6_48_png, map[string]*_bintree_t{}}, - "circle-dashed-6-512.png": &_bintree_t{static_image_white_shapes_circle_dashed_6_512_png, map[string]*_bintree_t{}}, - "circle-dashed-6-64.png": &_bintree_t{static_image_white_shapes_circle_dashed_6_64_png, map[string]*_bintree_t{}}, - "circle-dashed-8-128.png": &_bintree_t{static_image_white_shapes_circle_dashed_8_128_png, map[string]*_bintree_t{}}, - "circle-dashed-8-16.png": &_bintree_t{static_image_white_shapes_circle_dashed_8_16_png, map[string]*_bintree_t{}}, - "circle-dashed-8-24.png": &_bintree_t{static_image_white_shapes_circle_dashed_8_24_png, map[string]*_bintree_t{}}, - "circle-dashed-8-256.png": &_bintree_t{static_image_white_shapes_circle_dashed_8_256_png, map[string]*_bintree_t{}}, - "circle-dashed-8-32.png": &_bintree_t{static_image_white_shapes_circle_dashed_8_32_png, map[string]*_bintree_t{}}, - "circle-dashed-8-48.png": &_bintree_t{static_image_white_shapes_circle_dashed_8_48_png, map[string]*_bintree_t{}}, - "circle-dashed-8-512.png": &_bintree_t{static_image_white_shapes_circle_dashed_8_512_png, map[string]*_bintree_t{}}, - "circle-dashed-8-64.png": &_bintree_t{static_image_white_shapes_circle_dashed_8_64_png, map[string]*_bintree_t{}}, - "circle-outline-128.png": &_bintree_t{static_image_white_shapes_circle_outline_128_png, map[string]*_bintree_t{}}, - "circle-outline-16.png": &_bintree_t{static_image_white_shapes_circle_outline_16_png, map[string]*_bintree_t{}}, - "circle-outline-24.png": &_bintree_t{static_image_white_shapes_circle_outline_24_png, map[string]*_bintree_t{}}, - "circle-outline-256.png": &_bintree_t{static_image_white_shapes_circle_outline_256_png, map[string]*_bintree_t{}}, - "circle-outline-32.png": &_bintree_t{static_image_white_shapes_circle_outline_32_png, map[string]*_bintree_t{}}, - "circle-outline-48.png": &_bintree_t{static_image_white_shapes_circle_outline_48_png, map[string]*_bintree_t{}}, - "circle-outline-512.png": &_bintree_t{static_image_white_shapes_circle_outline_512_png, map[string]*_bintree_t{}}, - "circle-outline-64.png": &_bintree_t{static_image_white_shapes_circle_outline_64_png, map[string]*_bintree_t{}}, - "hexagon-128.png": &_bintree_t{static_image_white_shapes_hexagon_128_png, map[string]*_bintree_t{}}, - "hexagon-16.png": &_bintree_t{static_image_white_shapes_hexagon_16_png, map[string]*_bintree_t{}}, - "hexagon-24.png": &_bintree_t{static_image_white_shapes_hexagon_24_png, map[string]*_bintree_t{}}, - "hexagon-256.png": &_bintree_t{static_image_white_shapes_hexagon_256_png, map[string]*_bintree_t{}}, - "hexagon-32.png": &_bintree_t{static_image_white_shapes_hexagon_32_png, map[string]*_bintree_t{}}, - "hexagon-48.png": &_bintree_t{static_image_white_shapes_hexagon_48_png, map[string]*_bintree_t{}}, - "hexagon-512.png": &_bintree_t{static_image_white_shapes_hexagon_512_png, map[string]*_bintree_t{}}, - "hexagon-64.png": &_bintree_t{static_image_white_shapes_hexagon_64_png, map[string]*_bintree_t{}}, - "hexagon-outline-128.png": &_bintree_t{static_image_white_shapes_hexagon_outline_128_png, map[string]*_bintree_t{}}, - "hexagon-outline-16.png": &_bintree_t{static_image_white_shapes_hexagon_outline_16_png, map[string]*_bintree_t{}}, - "hexagon-outline-24.png": &_bintree_t{static_image_white_shapes_hexagon_outline_24_png, map[string]*_bintree_t{}}, - "hexagon-outline-256.png": &_bintree_t{static_image_white_shapes_hexagon_outline_256_png, map[string]*_bintree_t{}}, - "hexagon-outline-32.png": &_bintree_t{static_image_white_shapes_hexagon_outline_32_png, map[string]*_bintree_t{}}, - "hexagon-outline-48.png": &_bintree_t{static_image_white_shapes_hexagon_outline_48_png, map[string]*_bintree_t{}}, - "hexagon-outline-512.png": &_bintree_t{static_image_white_shapes_hexagon_outline_512_png, map[string]*_bintree_t{}}, - "hexagon-outline-64.png": &_bintree_t{static_image_white_shapes_hexagon_outline_64_png, map[string]*_bintree_t{}}, - "octagon-128.png": &_bintree_t{static_image_white_shapes_octagon_128_png, map[string]*_bintree_t{}}, - "octagon-16.png": &_bintree_t{static_image_white_shapes_octagon_16_png, map[string]*_bintree_t{}}, - "octagon-24.png": &_bintree_t{static_image_white_shapes_octagon_24_png, map[string]*_bintree_t{}}, - "octagon-256.png": &_bintree_t{static_image_white_shapes_octagon_256_png, map[string]*_bintree_t{}}, - "octagon-32.png": &_bintree_t{static_image_white_shapes_octagon_32_png, map[string]*_bintree_t{}}, - "octagon-48.png": &_bintree_t{static_image_white_shapes_octagon_48_png, map[string]*_bintree_t{}}, - "octagon-512.png": &_bintree_t{static_image_white_shapes_octagon_512_png, map[string]*_bintree_t{}}, - "octagon-64.png": &_bintree_t{static_image_white_shapes_octagon_64_png, map[string]*_bintree_t{}}, - "octagon-outline-128.png": &_bintree_t{static_image_white_shapes_octagon_outline_128_png, map[string]*_bintree_t{}}, - "octagon-outline-16.png": &_bintree_t{static_image_white_shapes_octagon_outline_16_png, map[string]*_bintree_t{}}, - "octagon-outline-24.png": &_bintree_t{static_image_white_shapes_octagon_outline_24_png, map[string]*_bintree_t{}}, - "octagon-outline-256.png": &_bintree_t{static_image_white_shapes_octagon_outline_256_png, map[string]*_bintree_t{}}, - "octagon-outline-32.png": &_bintree_t{static_image_white_shapes_octagon_outline_32_png, map[string]*_bintree_t{}}, - "octagon-outline-48.png": &_bintree_t{static_image_white_shapes_octagon_outline_48_png, map[string]*_bintree_t{}}, - "octagon-outline-512.png": &_bintree_t{static_image_white_shapes_octagon_outline_512_png, map[string]*_bintree_t{}}, - "octagon-outline-64.png": &_bintree_t{static_image_white_shapes_octagon_outline_64_png, map[string]*_bintree_t{}}, - "square-128.png": &_bintree_t{static_image_white_shapes_square_128_png, map[string]*_bintree_t{}}, - "square-16.png": &_bintree_t{static_image_white_shapes_square_16_png, map[string]*_bintree_t{}}, - "square-24.png": &_bintree_t{static_image_white_shapes_square_24_png, map[string]*_bintree_t{}}, - "square-256.png": &_bintree_t{static_image_white_shapes_square_256_png, map[string]*_bintree_t{}}, - "square-32.png": &_bintree_t{static_image_white_shapes_square_32_png, map[string]*_bintree_t{}}, - "square-48.png": &_bintree_t{static_image_white_shapes_square_48_png, map[string]*_bintree_t{}}, - "square-512.png": &_bintree_t{static_image_white_shapes_square_512_png, map[string]*_bintree_t{}}, - "square-64.png": &_bintree_t{static_image_white_shapes_square_64_png, map[string]*_bintree_t{}}, - "square-dashed-128.png": &_bintree_t{static_image_white_shapes_square_dashed_128_png, map[string]*_bintree_t{}}, - "square-dashed-16.png": &_bintree_t{static_image_white_shapes_square_dashed_16_png, map[string]*_bintree_t{}}, - "square-dashed-24.png": &_bintree_t{static_image_white_shapes_square_dashed_24_png, map[string]*_bintree_t{}}, - "square-dashed-256.png": &_bintree_t{static_image_white_shapes_square_dashed_256_png, map[string]*_bintree_t{}}, - "square-dashed-32.png": &_bintree_t{static_image_white_shapes_square_dashed_32_png, map[string]*_bintree_t{}}, - "square-dashed-48.png": &_bintree_t{static_image_white_shapes_square_dashed_48_png, map[string]*_bintree_t{}}, - "square-dashed-512.png": &_bintree_t{static_image_white_shapes_square_dashed_512_png, map[string]*_bintree_t{}}, - "square-dashed-64.png": &_bintree_t{static_image_white_shapes_square_dashed_64_png, map[string]*_bintree_t{}}, - "square-dashed-rounded-128.png": &_bintree_t{static_image_white_shapes_square_dashed_rounded_128_png, map[string]*_bintree_t{}}, - "square-dashed-rounded-16.png": &_bintree_t{static_image_white_shapes_square_dashed_rounded_16_png, map[string]*_bintree_t{}}, - "square-dashed-rounded-24.png": &_bintree_t{static_image_white_shapes_square_dashed_rounded_24_png, map[string]*_bintree_t{}}, - "square-dashed-rounded-256.png": &_bintree_t{static_image_white_shapes_square_dashed_rounded_256_png, map[string]*_bintree_t{}}, - "square-dashed-rounded-32.png": &_bintree_t{static_image_white_shapes_square_dashed_rounded_32_png, map[string]*_bintree_t{}}, - "square-dashed-rounded-48.png": &_bintree_t{static_image_white_shapes_square_dashed_rounded_48_png, map[string]*_bintree_t{}}, - "square-dashed-rounded-512.png": &_bintree_t{static_image_white_shapes_square_dashed_rounded_512_png, map[string]*_bintree_t{}}, - "square-dashed-rounded-64.png": &_bintree_t{static_image_white_shapes_square_dashed_rounded_64_png, map[string]*_bintree_t{}}, - "square-ios-app-128.png": &_bintree_t{static_image_white_shapes_square_ios_app_128_png, map[string]*_bintree_t{}}, - "square-ios-app-16.png": &_bintree_t{static_image_white_shapes_square_ios_app_16_png, map[string]*_bintree_t{}}, - "square-ios-app-24.png": &_bintree_t{static_image_white_shapes_square_ios_app_24_png, map[string]*_bintree_t{}}, - "square-ios-app-256.png": &_bintree_t{static_image_white_shapes_square_ios_app_256_png, map[string]*_bintree_t{}}, - "square-ios-app-32.png": &_bintree_t{static_image_white_shapes_square_ios_app_32_png, map[string]*_bintree_t{}}, - "square-ios-app-48.png": &_bintree_t{static_image_white_shapes_square_ios_app_48_png, map[string]*_bintree_t{}}, - "square-ios-app-512.png": &_bintree_t{static_image_white_shapes_square_ios_app_512_png, map[string]*_bintree_t{}}, - "square-ios-app-64.png": &_bintree_t{static_image_white_shapes_square_ios_app_64_png, map[string]*_bintree_t{}}, - "square-outline-128.png": &_bintree_t{static_image_white_shapes_square_outline_128_png, map[string]*_bintree_t{}}, - "square-outline-16.png": &_bintree_t{static_image_white_shapes_square_outline_16_png, map[string]*_bintree_t{}}, - "square-outline-24.png": &_bintree_t{static_image_white_shapes_square_outline_24_png, map[string]*_bintree_t{}}, - "square-outline-256.png": &_bintree_t{static_image_white_shapes_square_outline_256_png, map[string]*_bintree_t{}}, - "square-outline-32.png": &_bintree_t{static_image_white_shapes_square_outline_32_png, map[string]*_bintree_t{}}, - "square-outline-48.png": &_bintree_t{static_image_white_shapes_square_outline_48_png, map[string]*_bintree_t{}}, - "square-outline-512.png": &_bintree_t{static_image_white_shapes_square_outline_512_png, map[string]*_bintree_t{}}, - "square-outline-64.png": &_bintree_t{static_image_white_shapes_square_outline_64_png, map[string]*_bintree_t{}}, - "square-rounded-128.png": &_bintree_t{static_image_white_shapes_square_rounded_128_png, map[string]*_bintree_t{}}, - "square-rounded-16.png": &_bintree_t{static_image_white_shapes_square_rounded_16_png, map[string]*_bintree_t{}}, - "square-rounded-24.png": &_bintree_t{static_image_white_shapes_square_rounded_24_png, map[string]*_bintree_t{}}, - "square-rounded-256.png": &_bintree_t{static_image_white_shapes_square_rounded_256_png, map[string]*_bintree_t{}}, - "square-rounded-32.png": &_bintree_t{static_image_white_shapes_square_rounded_32_png, map[string]*_bintree_t{}}, - "square-rounded-48.png": &_bintree_t{static_image_white_shapes_square_rounded_48_png, map[string]*_bintree_t{}}, - "square-rounded-512.png": &_bintree_t{static_image_white_shapes_square_rounded_512_png, map[string]*_bintree_t{}}, - "square-rounded-64.png": &_bintree_t{static_image_white_shapes_square_rounded_64_png, map[string]*_bintree_t{}}, - "triangle-128.png": &_bintree_t{static_image_white_shapes_triangle_128_png, map[string]*_bintree_t{}}, - "triangle-16.png": &_bintree_t{static_image_white_shapes_triangle_16_png, map[string]*_bintree_t{}}, - "triangle-24.png": &_bintree_t{static_image_white_shapes_triangle_24_png, map[string]*_bintree_t{}}, - "triangle-256.png": &_bintree_t{static_image_white_shapes_triangle_256_png, map[string]*_bintree_t{}}, - "triangle-32.png": &_bintree_t{static_image_white_shapes_triangle_32_png, map[string]*_bintree_t{}}, - "triangle-48.png": &_bintree_t{static_image_white_shapes_triangle_48_png, map[string]*_bintree_t{}}, - "triangle-512.png": &_bintree_t{static_image_white_shapes_triangle_512_png, map[string]*_bintree_t{}}, - "triangle-64.png": &_bintree_t{static_image_white_shapes_triangle_64_png, map[string]*_bintree_t{}}, - "triangle-outline-128.png": &_bintree_t{static_image_white_shapes_triangle_outline_128_png, map[string]*_bintree_t{}}, - "triangle-outline-16.png": &_bintree_t{static_image_white_shapes_triangle_outline_16_png, map[string]*_bintree_t{}}, - "triangle-outline-24.png": &_bintree_t{static_image_white_shapes_triangle_outline_24_png, map[string]*_bintree_t{}}, - "triangle-outline-256.png": &_bintree_t{static_image_white_shapes_triangle_outline_256_png, map[string]*_bintree_t{}}, - "triangle-outline-32.png": &_bintree_t{static_image_white_shapes_triangle_outline_32_png, map[string]*_bintree_t{}}, - "triangle-outline-48.png": &_bintree_t{static_image_white_shapes_triangle_outline_48_png, map[string]*_bintree_t{}}, - "triangle-outline-512.png": &_bintree_t{static_image_white_shapes_triangle_outline_512_png, map[string]*_bintree_t{}}, - "triangle-outline-64.png": &_bintree_t{static_image_white_shapes_triangle_outline_64_png, map[string]*_bintree_t{}}, + "circle-128.png": &_bintree_t{static_image_white_shapes_circle_128_png, map[string]*_bintree_t{ + }}, + "circle-16.png": &_bintree_t{static_image_white_shapes_circle_16_png, map[string]*_bintree_t{ + }}, + "circle-24.png": &_bintree_t{static_image_white_shapes_circle_24_png, map[string]*_bintree_t{ + }}, + "circle-256.png": &_bintree_t{static_image_white_shapes_circle_256_png, map[string]*_bintree_t{ + }}, + "circle-32.png": &_bintree_t{static_image_white_shapes_circle_32_png, map[string]*_bintree_t{ + }}, + "circle-48.png": &_bintree_t{static_image_white_shapes_circle_48_png, map[string]*_bintree_t{ + }}, + "circle-512.png": &_bintree_t{static_image_white_shapes_circle_512_png, map[string]*_bintree_t{ + }}, + "circle-64.png": &_bintree_t{static_image_white_shapes_circle_64_png, map[string]*_bintree_t{ + }}, + "circle-dashed-4-128.png": &_bintree_t{static_image_white_shapes_circle_dashed_4_128_png, map[string]*_bintree_t{ + }}, + "circle-dashed-4-16.png": &_bintree_t{static_image_white_shapes_circle_dashed_4_16_png, map[string]*_bintree_t{ + }}, + "circle-dashed-4-24.png": &_bintree_t{static_image_white_shapes_circle_dashed_4_24_png, map[string]*_bintree_t{ + }}, + "circle-dashed-4-256.png": &_bintree_t{static_image_white_shapes_circle_dashed_4_256_png, map[string]*_bintree_t{ + }}, + "circle-dashed-4-32.png": &_bintree_t{static_image_white_shapes_circle_dashed_4_32_png, map[string]*_bintree_t{ + }}, + "circle-dashed-4-48.png": &_bintree_t{static_image_white_shapes_circle_dashed_4_48_png, map[string]*_bintree_t{ + }}, + "circle-dashed-4-512.png": &_bintree_t{static_image_white_shapes_circle_dashed_4_512_png, map[string]*_bintree_t{ + }}, + "circle-dashed-4-64.png": &_bintree_t{static_image_white_shapes_circle_dashed_4_64_png, map[string]*_bintree_t{ + }}, + "circle-dashed-6-128.png": &_bintree_t{static_image_white_shapes_circle_dashed_6_128_png, map[string]*_bintree_t{ + }}, + "circle-dashed-6-16.png": &_bintree_t{static_image_white_shapes_circle_dashed_6_16_png, map[string]*_bintree_t{ + }}, + "circle-dashed-6-24.png": &_bintree_t{static_image_white_shapes_circle_dashed_6_24_png, map[string]*_bintree_t{ + }}, + "circle-dashed-6-256.png": &_bintree_t{static_image_white_shapes_circle_dashed_6_256_png, map[string]*_bintree_t{ + }}, + "circle-dashed-6-32.png": &_bintree_t{static_image_white_shapes_circle_dashed_6_32_png, map[string]*_bintree_t{ + }}, + "circle-dashed-6-48.png": &_bintree_t{static_image_white_shapes_circle_dashed_6_48_png, map[string]*_bintree_t{ + }}, + "circle-dashed-6-512.png": &_bintree_t{static_image_white_shapes_circle_dashed_6_512_png, map[string]*_bintree_t{ + }}, + "circle-dashed-6-64.png": &_bintree_t{static_image_white_shapes_circle_dashed_6_64_png, map[string]*_bintree_t{ + }}, + "circle-dashed-8-128.png": &_bintree_t{static_image_white_shapes_circle_dashed_8_128_png, map[string]*_bintree_t{ + }}, + "circle-dashed-8-16.png": &_bintree_t{static_image_white_shapes_circle_dashed_8_16_png, map[string]*_bintree_t{ + }}, + "circle-dashed-8-24.png": &_bintree_t{static_image_white_shapes_circle_dashed_8_24_png, map[string]*_bintree_t{ + }}, + "circle-dashed-8-256.png": &_bintree_t{static_image_white_shapes_circle_dashed_8_256_png, map[string]*_bintree_t{ + }}, + "circle-dashed-8-32.png": &_bintree_t{static_image_white_shapes_circle_dashed_8_32_png, map[string]*_bintree_t{ + }}, + "circle-dashed-8-48.png": &_bintree_t{static_image_white_shapes_circle_dashed_8_48_png, map[string]*_bintree_t{ + }}, + "circle-dashed-8-512.png": &_bintree_t{static_image_white_shapes_circle_dashed_8_512_png, map[string]*_bintree_t{ + }}, + "circle-dashed-8-64.png": &_bintree_t{static_image_white_shapes_circle_dashed_8_64_png, map[string]*_bintree_t{ + }}, + "circle-outline-128.png": &_bintree_t{static_image_white_shapes_circle_outline_128_png, map[string]*_bintree_t{ + }}, + "circle-outline-16.png": &_bintree_t{static_image_white_shapes_circle_outline_16_png, map[string]*_bintree_t{ + }}, + "circle-outline-24.png": &_bintree_t{static_image_white_shapes_circle_outline_24_png, map[string]*_bintree_t{ + }}, + "circle-outline-256.png": &_bintree_t{static_image_white_shapes_circle_outline_256_png, map[string]*_bintree_t{ + }}, + "circle-outline-32.png": &_bintree_t{static_image_white_shapes_circle_outline_32_png, map[string]*_bintree_t{ + }}, + "circle-outline-48.png": &_bintree_t{static_image_white_shapes_circle_outline_48_png, map[string]*_bintree_t{ + }}, + "circle-outline-512.png": &_bintree_t{static_image_white_shapes_circle_outline_512_png, map[string]*_bintree_t{ + }}, + "circle-outline-64.png": &_bintree_t{static_image_white_shapes_circle_outline_64_png, map[string]*_bintree_t{ + }}, + "hexagon-128.png": &_bintree_t{static_image_white_shapes_hexagon_128_png, map[string]*_bintree_t{ + }}, + "hexagon-16.png": &_bintree_t{static_image_white_shapes_hexagon_16_png, map[string]*_bintree_t{ + }}, + "hexagon-24.png": &_bintree_t{static_image_white_shapes_hexagon_24_png, map[string]*_bintree_t{ + }}, + "hexagon-256.png": &_bintree_t{static_image_white_shapes_hexagon_256_png, map[string]*_bintree_t{ + }}, + "hexagon-32.png": &_bintree_t{static_image_white_shapes_hexagon_32_png, map[string]*_bintree_t{ + }}, + "hexagon-48.png": &_bintree_t{static_image_white_shapes_hexagon_48_png, map[string]*_bintree_t{ + }}, + "hexagon-512.png": &_bintree_t{static_image_white_shapes_hexagon_512_png, map[string]*_bintree_t{ + }}, + "hexagon-64.png": &_bintree_t{static_image_white_shapes_hexagon_64_png, map[string]*_bintree_t{ + }}, + "hexagon-outline-128.png": &_bintree_t{static_image_white_shapes_hexagon_outline_128_png, map[string]*_bintree_t{ + }}, + "hexagon-outline-16.png": &_bintree_t{static_image_white_shapes_hexagon_outline_16_png, map[string]*_bintree_t{ + }}, + "hexagon-outline-24.png": &_bintree_t{static_image_white_shapes_hexagon_outline_24_png, map[string]*_bintree_t{ + }}, + "hexagon-outline-256.png": &_bintree_t{static_image_white_shapes_hexagon_outline_256_png, map[string]*_bintree_t{ + }}, + "hexagon-outline-32.png": &_bintree_t{static_image_white_shapes_hexagon_outline_32_png, map[string]*_bintree_t{ + }}, + "hexagon-outline-48.png": &_bintree_t{static_image_white_shapes_hexagon_outline_48_png, map[string]*_bintree_t{ + }}, + "hexagon-outline-512.png": &_bintree_t{static_image_white_shapes_hexagon_outline_512_png, map[string]*_bintree_t{ + }}, + "hexagon-outline-64.png": &_bintree_t{static_image_white_shapes_hexagon_outline_64_png, map[string]*_bintree_t{ + }}, + "octagon-128.png": &_bintree_t{static_image_white_shapes_octagon_128_png, map[string]*_bintree_t{ + }}, + "octagon-16.png": &_bintree_t{static_image_white_shapes_octagon_16_png, map[string]*_bintree_t{ + }}, + "octagon-24.png": &_bintree_t{static_image_white_shapes_octagon_24_png, map[string]*_bintree_t{ + }}, + "octagon-256.png": &_bintree_t{static_image_white_shapes_octagon_256_png, map[string]*_bintree_t{ + }}, + "octagon-32.png": &_bintree_t{static_image_white_shapes_octagon_32_png, map[string]*_bintree_t{ + }}, + "octagon-48.png": &_bintree_t{static_image_white_shapes_octagon_48_png, map[string]*_bintree_t{ + }}, + "octagon-512.png": &_bintree_t{static_image_white_shapes_octagon_512_png, map[string]*_bintree_t{ + }}, + "octagon-64.png": &_bintree_t{static_image_white_shapes_octagon_64_png, map[string]*_bintree_t{ + }}, + "octagon-outline-128.png": &_bintree_t{static_image_white_shapes_octagon_outline_128_png, map[string]*_bintree_t{ + }}, + "octagon-outline-16.png": &_bintree_t{static_image_white_shapes_octagon_outline_16_png, map[string]*_bintree_t{ + }}, + "octagon-outline-24.png": &_bintree_t{static_image_white_shapes_octagon_outline_24_png, map[string]*_bintree_t{ + }}, + "octagon-outline-256.png": &_bintree_t{static_image_white_shapes_octagon_outline_256_png, map[string]*_bintree_t{ + }}, + "octagon-outline-32.png": &_bintree_t{static_image_white_shapes_octagon_outline_32_png, map[string]*_bintree_t{ + }}, + "octagon-outline-48.png": &_bintree_t{static_image_white_shapes_octagon_outline_48_png, map[string]*_bintree_t{ + }}, + "octagon-outline-512.png": &_bintree_t{static_image_white_shapes_octagon_outline_512_png, map[string]*_bintree_t{ + }}, + "octagon-outline-64.png": &_bintree_t{static_image_white_shapes_octagon_outline_64_png, map[string]*_bintree_t{ + }}, + "square-128.png": &_bintree_t{static_image_white_shapes_square_128_png, map[string]*_bintree_t{ + }}, + "square-16.png": &_bintree_t{static_image_white_shapes_square_16_png, map[string]*_bintree_t{ + }}, + "square-24.png": &_bintree_t{static_image_white_shapes_square_24_png, map[string]*_bintree_t{ + }}, + "square-256.png": &_bintree_t{static_image_white_shapes_square_256_png, map[string]*_bintree_t{ + }}, + "square-32.png": &_bintree_t{static_image_white_shapes_square_32_png, map[string]*_bintree_t{ + }}, + "square-48.png": &_bintree_t{static_image_white_shapes_square_48_png, map[string]*_bintree_t{ + }}, + "square-512.png": &_bintree_t{static_image_white_shapes_square_512_png, map[string]*_bintree_t{ + }}, + "square-64.png": &_bintree_t{static_image_white_shapes_square_64_png, map[string]*_bintree_t{ + }}, + "square-dashed-128.png": &_bintree_t{static_image_white_shapes_square_dashed_128_png, map[string]*_bintree_t{ + }}, + "square-dashed-16.png": &_bintree_t{static_image_white_shapes_square_dashed_16_png, map[string]*_bintree_t{ + }}, + "square-dashed-24.png": &_bintree_t{static_image_white_shapes_square_dashed_24_png, map[string]*_bintree_t{ + }}, + "square-dashed-256.png": &_bintree_t{static_image_white_shapes_square_dashed_256_png, map[string]*_bintree_t{ + }}, + "square-dashed-32.png": &_bintree_t{static_image_white_shapes_square_dashed_32_png, map[string]*_bintree_t{ + }}, + "square-dashed-48.png": &_bintree_t{static_image_white_shapes_square_dashed_48_png, map[string]*_bintree_t{ + }}, + "square-dashed-512.png": &_bintree_t{static_image_white_shapes_square_dashed_512_png, map[string]*_bintree_t{ + }}, + "square-dashed-64.png": &_bintree_t{static_image_white_shapes_square_dashed_64_png, map[string]*_bintree_t{ + }}, + "square-dashed-rounded-128.png": &_bintree_t{static_image_white_shapes_square_dashed_rounded_128_png, map[string]*_bintree_t{ + }}, + "square-dashed-rounded-16.png": &_bintree_t{static_image_white_shapes_square_dashed_rounded_16_png, map[string]*_bintree_t{ + }}, + "square-dashed-rounded-24.png": &_bintree_t{static_image_white_shapes_square_dashed_rounded_24_png, map[string]*_bintree_t{ + }}, + "square-dashed-rounded-256.png": &_bintree_t{static_image_white_shapes_square_dashed_rounded_256_png, map[string]*_bintree_t{ + }}, + "square-dashed-rounded-32.png": &_bintree_t{static_image_white_shapes_square_dashed_rounded_32_png, map[string]*_bintree_t{ + }}, + "square-dashed-rounded-48.png": &_bintree_t{static_image_white_shapes_square_dashed_rounded_48_png, map[string]*_bintree_t{ + }}, + "square-dashed-rounded-512.png": &_bintree_t{static_image_white_shapes_square_dashed_rounded_512_png, map[string]*_bintree_t{ + }}, + "square-dashed-rounded-64.png": &_bintree_t{static_image_white_shapes_square_dashed_rounded_64_png, map[string]*_bintree_t{ + }}, + "square-ios-app-128.png": &_bintree_t{static_image_white_shapes_square_ios_app_128_png, map[string]*_bintree_t{ + }}, + "square-ios-app-16.png": &_bintree_t{static_image_white_shapes_square_ios_app_16_png, map[string]*_bintree_t{ + }}, + "square-ios-app-24.png": &_bintree_t{static_image_white_shapes_square_ios_app_24_png, map[string]*_bintree_t{ + }}, + "square-ios-app-256.png": &_bintree_t{static_image_white_shapes_square_ios_app_256_png, map[string]*_bintree_t{ + }}, + "square-ios-app-32.png": &_bintree_t{static_image_white_shapes_square_ios_app_32_png, map[string]*_bintree_t{ + }}, + "square-ios-app-48.png": &_bintree_t{static_image_white_shapes_square_ios_app_48_png, map[string]*_bintree_t{ + }}, + "square-ios-app-512.png": &_bintree_t{static_image_white_shapes_square_ios_app_512_png, map[string]*_bintree_t{ + }}, + "square-ios-app-64.png": &_bintree_t{static_image_white_shapes_square_ios_app_64_png, map[string]*_bintree_t{ + }}, + "square-outline-128.png": &_bintree_t{static_image_white_shapes_square_outline_128_png, map[string]*_bintree_t{ + }}, + "square-outline-16.png": &_bintree_t{static_image_white_shapes_square_outline_16_png, map[string]*_bintree_t{ + }}, + "square-outline-24.png": &_bintree_t{static_image_white_shapes_square_outline_24_png, map[string]*_bintree_t{ + }}, + "square-outline-256.png": &_bintree_t{static_image_white_shapes_square_outline_256_png, map[string]*_bintree_t{ + }}, + "square-outline-32.png": &_bintree_t{static_image_white_shapes_square_outline_32_png, map[string]*_bintree_t{ + }}, + "square-outline-48.png": &_bintree_t{static_image_white_shapes_square_outline_48_png, map[string]*_bintree_t{ + }}, + "square-outline-512.png": &_bintree_t{static_image_white_shapes_square_outline_512_png, map[string]*_bintree_t{ + }}, + "square-outline-64.png": &_bintree_t{static_image_white_shapes_square_outline_64_png, map[string]*_bintree_t{ + }}, + "square-rounded-128.png": &_bintree_t{static_image_white_shapes_square_rounded_128_png, map[string]*_bintree_t{ + }}, + "square-rounded-16.png": &_bintree_t{static_image_white_shapes_square_rounded_16_png, map[string]*_bintree_t{ + }}, + "square-rounded-24.png": &_bintree_t{static_image_white_shapes_square_rounded_24_png, map[string]*_bintree_t{ + }}, + "square-rounded-256.png": &_bintree_t{static_image_white_shapes_square_rounded_256_png, map[string]*_bintree_t{ + }}, + "square-rounded-32.png": &_bintree_t{static_image_white_shapes_square_rounded_32_png, map[string]*_bintree_t{ + }}, + "square-rounded-48.png": &_bintree_t{static_image_white_shapes_square_rounded_48_png, map[string]*_bintree_t{ + }}, + "square-rounded-512.png": &_bintree_t{static_image_white_shapes_square_rounded_512_png, map[string]*_bintree_t{ + }}, + "square-rounded-64.png": &_bintree_t{static_image_white_shapes_square_rounded_64_png, map[string]*_bintree_t{ + }}, + "triangle-128.png": &_bintree_t{static_image_white_shapes_triangle_128_png, map[string]*_bintree_t{ + }}, + "triangle-16.png": &_bintree_t{static_image_white_shapes_triangle_16_png, map[string]*_bintree_t{ + }}, + "triangle-24.png": &_bintree_t{static_image_white_shapes_triangle_24_png, map[string]*_bintree_t{ + }}, + "triangle-256.png": &_bintree_t{static_image_white_shapes_triangle_256_png, map[string]*_bintree_t{ + }}, + "triangle-32.png": &_bintree_t{static_image_white_shapes_triangle_32_png, map[string]*_bintree_t{ + }}, + "triangle-48.png": &_bintree_t{static_image_white_shapes_triangle_48_png, map[string]*_bintree_t{ + }}, + "triangle-512.png": &_bintree_t{static_image_white_shapes_triangle_512_png, map[string]*_bintree_t{ + }}, + "triangle-64.png": &_bintree_t{static_image_white_shapes_triangle_64_png, map[string]*_bintree_t{ + }}, + "triangle-outline-128.png": &_bintree_t{static_image_white_shapes_triangle_outline_128_png, map[string]*_bintree_t{ + }}, + "triangle-outline-16.png": &_bintree_t{static_image_white_shapes_triangle_outline_16_png, map[string]*_bintree_t{ + }}, + "triangle-outline-24.png": &_bintree_t{static_image_white_shapes_triangle_outline_24_png, map[string]*_bintree_t{ + }}, + "triangle-outline-256.png": &_bintree_t{static_image_white_shapes_triangle_outline_256_png, map[string]*_bintree_t{ + }}, + "triangle-outline-32.png": &_bintree_t{static_image_white_shapes_triangle_outline_32_png, map[string]*_bintree_t{ + }}, + "triangle-outline-48.png": &_bintree_t{static_image_white_shapes_triangle_outline_48_png, map[string]*_bintree_t{ + }}, + "triangle-outline-512.png": &_bintree_t{static_image_white_shapes_triangle_outline_512_png, map[string]*_bintree_t{ + }}, + "triangle-outline-64.png": &_bintree_t{static_image_white_shapes_triangle_outline_64_png, map[string]*_bintree_t{ + }}, }}, }}, "js": &_bintree_t{nil, map[string]*_bintree_t{ - "energyViewer.js": &_bintree_t{static_js_energyviewer_js, map[string]*_bintree_t{}}, - "statsViewer.js": &_bintree_t{static_js_statsviewer_js, map[string]*_bintree_t{}}, - "visualize.js": &_bintree_t{static_js_visualize_js, map[string]*_bintree_t{}}, + "energyViewer.js": &_bintree_t{static_js_energyviewer_js, map[string]*_bintree_t{ + }}, + "statsViewer.js": &_bintree_t{static_js_statsviewer_js, map[string]*_bintree_t{ + }}, + "visualize.js": &_bintree_t{static_js_visualize_js, map[string]*_bintree_t{ + }}, }}, }}, "templates": &_bintree_t{nil, map[string]*_bintree_t{ - "energyViewer.html": &_bintree_t{templates_energyviewer_html, map[string]*_bintree_t{}}, - "statsViewer.html": &_bintree_t{templates_statsviewer_html, map[string]*_bintree_t{}}, - "visualize.html": &_bintree_t{templates_visualize_html, map[string]*_bintree_t{}}, + "energyViewer.html": &_bintree_t{templates_energyviewer_html, map[string]*_bintree_t{ + }}, + "statsViewer.html": &_bintree_t{templates_statsviewer_html, map[string]*_bintree_t{ + }}, + "visualize.html": &_bintree_t{templates_visualize_html, map[string]*_bintree_t{ + }}, }}, }}