squared 0.4.25 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/CHANGELOG.md +62 -364
 - data/README.md +1279 -650
 - data/README.ruby.md +722 -0
 - data/lib/squared/common/base.rb +8 -9
 - data/lib/squared/common/format.rb +17 -24
 - data/lib/squared/common/prompt.rb +38 -42
 - data/lib/squared/common/shell.rb +29 -29
 - data/lib/squared/common/system.rb +34 -37
 - data/lib/squared/common/utils.rb +3 -28
 - data/lib/squared/common.rb +2 -1
 - data/lib/squared/config.rb +21 -21
 - data/lib/squared/version.rb +1 -1
 - data/lib/squared/workspace/application.rb +67 -91
 - data/lib/squared/workspace/project/base.rb +355 -476
 - data/lib/squared/workspace/project/docker.rb +175 -203
 - data/lib/squared/workspace/project/git.rb +357 -498
 - data/lib/squared/workspace/project/node.rb +138 -213
 - data/lib/squared/workspace/project/python.rb +88 -306
 - data/lib/squared/workspace/project/ruby.rb +220 -300
 - data/lib/squared/workspace/project/support/class.rb +94 -288
 - data/lib/squared/workspace/project.rb +0 -10
 - data/lib/squared/workspace/repo.rb +53 -92
 - data/lib/squared/workspace/series.rb +34 -32
 - data/lib/squared/workspace/support/data.rb +3 -2
 - data/lib/squared/workspace/support.rb +0 -1
 - data/lib/squared/workspace.rb +1 -1
 - data/squared.gemspec +5 -5
 - metadata +8 -12
 - data/lib/squared/common/class.rb +0 -110
 - data/lib/squared/workspace/support/base.rb +0 -37
 
    
        data/README.md
    CHANGED
    
    | 
         @@ -1,731 +1,1360 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            # squared  
     | 
| 
      
 1 
     | 
    
         
            +
            # squared 5.5
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
            * [docs](https://squared.readthedocs.io)
         
     | 
| 
      
 3 
     | 
    
         
            +
            ## Documentation
         
     | 
| 
       5 
4 
     | 
    
         | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
      
 5 
     | 
    
         
            +
            ### HTML
         
     | 
| 
       7 
6 
     | 
    
         | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
            | 2024-12-07 |   0.1.0 |  2.4.0 |  3.3.6 |   2.39 |
         
     | 
| 
       11 
     | 
    
         
            -
            | 2025-01-07 |   0.2.0 |  2.4.0 |  3.4.0 |   2.39 |
         
     | 
| 
       12 
     | 
    
         
            -
            | 2025-02-07 |   0.3.0 |  2.4.0 |  3.4.1 |   2.39 |
         
     | 
| 
       13 
     | 
    
         
            -
            | 2025-03-06 |   0.4.0 |  2.4.0 |  3.4.2 |   2.39 |
         
     | 
| 
      
 7 
     | 
    
         
            +
            * [squared](https://squared.readthedocs.io)
         
     | 
| 
      
 8 
     | 
    
         
            +
            * [E-mc](https://e-mc.readthedocs.io)
         
     | 
| 
       14 
9 
     | 
    
         | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
      
 10 
     | 
    
         
            +
            > [!NOTE]
         
     | 
| 
      
 11 
     | 
    
         
            +
            > Content in the README was migrated into `Read the Docs`. The file is no longer fully maintained.
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            ### README
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            * [squared-express](https://github.com/anpham6/squared-express#readme)
         
     | 
| 
      
 16 
     | 
    
         
            +
            * [E-mc](https://github.com/anpham6/e-mc#readme)
         
     | 
| 
      
 17 
     | 
    
         
            +
            * [Pi-r](https://github.com/anpham6/pi-r#readme)
         
     | 
| 
      
 18 
     | 
    
         
            +
            * [Pi-r2](https://github.com/anpham6/pi-r2#readme)
         
     | 
| 
       16 
19 
     | 
    
         | 
| 
       17 
20 
     | 
    
         
             
            ## Installation
         
     | 
| 
       18 
21 
     | 
    
         | 
| 
      
 22 
     | 
    
         
            +
            * NodeJS 18
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            ### NPX
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
       19 
26 
     | 
    
         
             
            ```sh
         
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
      
 27 
     | 
    
         
            +
            > npm init
         
     | 
| 
      
 28 
     | 
    
         
            +
            > npm i sqd-cli sqd-serve
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
            > npx sqd init
         
     | 
| 
      
 31 
     | 
    
         
            +
            # OR
         
     | 
| 
      
 32 
     | 
    
         
            +
            > npx sqd init --public --local-serve # Same as squared-express
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
            > npx sqd serve --access-all
         
     | 
| 
      
 35 
     | 
    
         
            +
            # OR
         
     | 
| 
      
 36 
     | 
    
         
            +
            > node serve.cjs --access-all
         
     | 
| 
       21 
37 
     | 
    
         
             
            ```
         
     | 
| 
       22 
38 
     | 
    
         | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
      
 39 
     | 
    
         
            +
            ```sh
         
     | 
| 
      
 40 
     | 
    
         
            +
            > npm init
         
     | 
| 
      
 41 
     | 
    
         
            +
            > npm i squared sqd-serve
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
            > mkdir dist html
         
     | 
| 
      
 44 
     | 
    
         
            +
            > cp -r ./node_modules/squared/dist/* ./dist
         
     | 
| 
      
 45 
     | 
    
         
            +
            > cp ./node_modules/squared/html/* ./html     # optional
         
     | 
| 
      
 46 
     | 
    
         
            +
            > cp ./node_modules/sqd-serve/config/json/* . # yaml
         
     | 
| 
       24 
47 
     | 
    
         | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
      
 48 
     | 
    
         
            +
            > npx serve
         
     | 
| 
      
 49 
     | 
    
         
            +
            ```
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
            ### GitHub
         
     | 
| 
       29 
52 
     | 
    
         | 
| 
       30 
53 
     | 
    
         
             
            ```sh
         
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
      
 54 
     | 
    
         
            +
            > git clone https://github.com/anpham6/squared
         
     | 
| 
      
 55 
     | 
    
         
            +
            > cd squared
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
            > npm i
         
     | 
| 
      
 58 
     | 
    
         
            +
            > npm run prod
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
            > cd ..
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
            > git clone https://github.com/anpham6/squared-express
         
     | 
| 
      
 63 
     | 
    
         
            +
            > cd squared-express
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
            > npm i
         
     | 
| 
      
 66 
     | 
    
         
            +
            > npm run prod
         
     | 
| 
      
 67 
     | 
    
         
            +
            > npm run deploy # deploy:yaml
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
            > cd ../squared
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
            > node serve.cjs --access-all # squared.{json,yml}
         
     | 
| 
       35 
72 
     | 
    
         
             
            ```
         
     | 
| 
       36 
73 
     | 
    
         | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
      
 74 
     | 
    
         
            +
            ### Repo
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
            * Python 3.6+
         
     | 
| 
      
 77 
     | 
    
         
            +
            * [Commands](https://source.android.com/docs/setup/reference/repo)
         
     | 
| 
       38 
78 
     | 
    
         | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
      
 79 
     | 
    
         
            +
            #### Install
         
     | 
| 
       40 
80 
     | 
    
         | 
| 
       41 
     | 
    
         
            -
            ``` 
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
      
 81 
     | 
    
         
            +
            ```sh
         
     | 
| 
      
 82 
     | 
    
         
            +
            mkdir -p ~/bin/repo
         
     | 
| 
      
 83 
     | 
    
         
            +
            PATH="${HOME}/bin:${PATH}"
         
     | 
| 
       43 
84 
     | 
    
         | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
            require "squared/workspace/project/node"             #
         
     | 
| 
       47 
     | 
    
         
            -
            require "squared/workspace/project/python"           #
         
     | 
| 
       48 
     | 
    
         
            -
            require "squared/workspace/project/ruby"             #
         
     | 
| 
       49 
     | 
    
         
            -
            require "squared/workspace/project/docker"           #
         
     | 
| 
      
 85 
     | 
    
         
            +
            curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
         
     | 
| 
      
 86 
     | 
    
         
            +
            chmod a+rx ~/bin/repo
         
     | 
| 
       50 
87 
     | 
    
         
             
            # OR
         
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
      
 88 
     | 
    
         
            +
            scripts/repo-install.sh ~/bin
         
     | 
| 
      
 89 
     | 
    
         
            +
            ```
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
            #### Usage
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
            ```sh
         
     | 
| 
      
 94 
     | 
    
         
            +
            mkdir workspaces
         
     | 
| 
      
 95 
     | 
    
         
            +
            cd workspaces
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
            repo init -u https://github.com/anpham6/squared-repo -m latest.xml
         
     | 
| 
      
 98 
     | 
    
         
            +
            repo sync -j4
         
     | 
| 
       52 
99 
     | 
    
         | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
      
 100 
     | 
    
         
            +
            cd squared
         
     | 
| 
      
 101 
     | 
    
         
            +
            npm i
         
     | 
| 
      
 102 
     | 
    
         
            +
            ```
         
     | 
| 
       54 
103 
     | 
    
         | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
      
 104 
     | 
    
         
            +
            #### Ruby
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
            Workspace management uses [Ruby](https://www.ruby-lang.org/en/documentation/installation) for syncing and building. It is not installed by default on most operating systems.
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
            ```sh
         
     | 
| 
      
 109 
     | 
    
         
            +
            mkdir workspaces
         
     | 
| 
      
 110 
     | 
    
         
            +
            cd workspaces            # REPO_ROOT
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
            wget https://unpkg.com/squared/Rakefile
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
            rake -T                  # List tasks
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
            # REPO_BUILD={dev,prod}
         
     | 
| 
      
 117 
     | 
    
         
            +
            # PIPE_FAIL=1
         
     | 
| 
      
 118 
     | 
    
         
            +
            rake repo:init           # nightly
         
     | 
| 
      
 119 
     | 
    
         
            +
            rake repo:init[latest]   # squared
         
     | 
| 
      
 120 
     | 
    
         
            +
            rake repo:init[0.11.x]   # e-mc
         
     | 
| 
       58 
121 
     | 
    
         
             
            # OR
         
     | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
       60 
     | 
    
         
            -
            #  
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
       63 
     | 
    
         
            -
             
     | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
       67 
     | 
    
         
            -
             
     | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
       69 
     | 
    
         
            -
             
     | 
| 
       70 
     | 
    
         
            -
             
     | 
| 
       71 
     | 
    
         
            -
            #  
     | 
| 
       72 
     | 
    
         
            -
            #  
     | 
| 
       73 
     | 
    
         
            -
             
     | 
| 
       74 
     | 
    
         
            -
             
     | 
| 
       75 
     | 
    
         
            -
             
     | 
| 
       76 
     | 
    
         
            -
             
     | 
| 
       77 
     | 
    
         
            -
             
     | 
| 
       78 
     | 
    
         
            -
             
     | 
| 
       79 
     | 
    
         
            -
             
     | 
| 
       80 
     | 
    
         
            -
             
     | 
| 
       81 
     | 
    
         
            -
             
     | 
| 
       82 
     | 
    
         
            -
             
     | 
| 
       83 
     | 
    
         
            -
             
     | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
       85 
     | 
    
         
            -
             
     | 
| 
       86 
     | 
    
         
            -
             
     | 
| 
       87 
     | 
    
         
            -
             
     | 
| 
       88 
     | 
    
         
            -
             
     | 
| 
       89 
     | 
    
         
            -
             
     | 
| 
       90 
     | 
    
         
            -
             
     | 
| 
       91 
     | 
    
         
            -
               
     | 
| 
       92 
     | 
    
         
            -
             
     | 
| 
       93 
     | 
    
         
            -
             
     | 
| 
       94 
     | 
    
         
            -
             
     | 
| 
       95 
     | 
    
         
            -
             
     | 
| 
       96 
     | 
    
         
            -
             
     | 
| 
       97 
     | 
    
         
            -
             
     | 
| 
       98 
     | 
    
         
            -
             
     | 
| 
       99 
     | 
    
         
            -
             
     | 
| 
       100 
     | 
    
         
            -
             
     | 
| 
       101 
     | 
    
         
            -
             
     | 
| 
       102 
     | 
    
         
            -
             
     | 
| 
       103 
     | 
    
         
            -
             
     | 
| 
       104 
     | 
    
         
            -
             
     | 
| 
       105 
     | 
    
         
            -
             
     | 
| 
       106 
     | 
    
         
            -
             
     | 
| 
       107 
     | 
    
         
            -
             
     | 
| 
       108 
     | 
    
         
            -
             
     | 
| 
       109 
     | 
    
         
            -
             
     | 
| 
       110 
     | 
    
         
            -
             
     | 
| 
       111 
     | 
    
         
            -
             
     | 
| 
       112 
     | 
    
         
            -
             
     | 
| 
       113 
     | 
    
         
            -
             
     | 
| 
       114 
     | 
    
         
            -
             
     | 
| 
       115 
     | 
    
         
            -
             
     | 
| 
       116 
     | 
    
         
            -
             
     | 
| 
       117 
     | 
    
         
            -
             
     | 
| 
       118 
     | 
    
         
            -
             
     | 
| 
       119 
     | 
    
         
            -
             
     | 
| 
       120 
     | 
    
         
            -
             
     | 
| 
       121 
     | 
    
         
            -
             
     | 
| 
       122 
     | 
    
         
            -
             
     | 
| 
       123 
     | 
    
         
            -
             
     | 
| 
       124 
     | 
    
         
            -
             
     | 
| 
       125 
     | 
    
         
            -
             
     | 
| 
       126 
     | 
    
         
            -
             
     | 
| 
       127 
     | 
    
         
            -
             
     | 
| 
       128 
     | 
    
         
            -
             
     | 
| 
       129 
     | 
    
         
            -
             
     | 
| 
       130 
     | 
    
         
            -
             
     | 
| 
       131 
     | 
    
         
            -
             
     | 
| 
       132 
     | 
    
         
            -
             
     | 
| 
       133 
     | 
    
         
            -
             
     | 
| 
       134 
     | 
    
         
            -
             
     | 
| 
       135 
     | 
    
         
            -
             
     | 
| 
       136 
     | 
    
         
            -
             
     | 
| 
       137 
     | 
    
         
            -
             
     | 
| 
       138 
     | 
    
         
            -
             
     | 
| 
       139 
     | 
    
         
            -
             
     | 
| 
       140 
     | 
    
         
            -
             
     | 
| 
       141 
     | 
    
         
            -
             
     | 
| 
       142 
     | 
    
         
            -
             
     | 
| 
       143 
     | 
    
         
            -
             
     | 
| 
       144 
     | 
    
         
            -
             
     | 
| 
       145 
     | 
    
         
            -
             
     | 
| 
       146 
     | 
    
         
            -
             
     | 
| 
       147 
     | 
    
         
            -
                 
     | 
| 
       148 
     | 
    
         
            -
             
     | 
| 
       149 
     | 
    
         
            -
             
     | 
| 
       150 
     | 
    
         
            -
             
     | 
| 
       151 
     | 
    
         
            -
             
     | 
| 
       152 
     | 
    
         
            -
             
     | 
| 
       153 
     | 
    
         
            -
             
     | 
| 
       154 
     | 
    
         
            -
             
     | 
| 
       155 
     | 
    
         
            -
             
     | 
| 
       156 
     | 
    
         
            -
             
     | 
| 
       157 
     | 
    
         
            -
             
     | 
| 
       158 
     | 
    
         
            -
             
     | 
| 
       159 
     | 
    
         
            -
             
     | 
| 
       160 
     | 
    
         
            -
             
     | 
| 
       161 
     | 
    
         
            -
             
     | 
| 
       162 
     | 
    
         
            -
             
     | 
| 
       163 
     | 
    
         
            -
             
     | 
| 
       164 
     | 
    
         
            -
             
     | 
| 
       165 
     | 
    
         
            -
             
     | 
| 
       166 
     | 
    
         
            -
             
     | 
| 
       167 
     | 
    
         
            -
             
     | 
| 
       168 
     | 
    
         
            -
             
     | 
| 
       169 
     | 
    
         
            -
             
     | 
| 
       170 
     | 
    
         
            -
             
     | 
| 
       171 
     | 
    
         
            -
             
     | 
| 
       172 
     | 
    
         
            -
             
     | 
| 
       173 
     | 
    
         
            -
             
     | 
| 
       174 
     | 
    
         
            -
             
     | 
| 
       175 
     | 
    
         
            -
             
     | 
| 
       176 
     | 
    
         
            -
             
     | 
| 
       177 
     | 
    
         
            -
             
     | 
| 
       178 
     | 
    
         
            -
             
     | 
| 
       179 
     | 
    
         
            -
             
     | 
| 
       180 
     | 
    
         
            -
             
     | 
| 
       181 
     | 
    
         
            -
             
     | 
| 
       182 
     | 
    
         
            -
             
     | 
| 
       183 
     | 
    
         
            -
             
     | 
| 
       184 
     | 
    
         
            -
             
     | 
| 
       185 
     | 
    
         
            -
             
     | 
| 
       186 
     | 
    
         
            -
             
     | 
| 
       187 
     | 
    
         
            -
             
     | 
| 
       188 
     | 
    
         
            -
             
     | 
| 
       189 
     | 
    
         
            -
             
     | 
| 
       190 
     | 
    
         
            -
             
     | 
| 
       191 
     | 
    
         
            -
             
     | 
| 
       192 
     | 
    
         
            -
             
     | 
| 
       193 
     | 
    
         
            -
             
     | 
| 
       194 
     | 
    
         
            -
             
     | 
| 
       195 
     | 
    
         
            -
             
     | 
| 
       196 
     | 
    
         
            -
             
     | 
| 
       197 
     | 
    
         
            -
             
     | 
| 
       198 
     | 
    
         
            -
             
     | 
| 
       199 
     | 
    
         
            -
             
     | 
| 
       200 
     | 
    
         
            -
             
     | 
| 
       201 
     | 
    
         
            -
             
     | 
| 
       202 
     | 
    
         
            -
             
     | 
| 
       203 
     | 
    
         
            -
             
     | 
| 
       204 
     | 
    
         
            -
             
     | 
| 
      
 122 
     | 
    
         
            +
            REPO_ROOT=/tmp/123 NODE_INSTALL=pnpm repo:init
         
     | 
| 
      
 123 
     | 
    
         
            +
            # OR - without Repo
         
     | 
| 
      
 124 
     | 
    
         
            +
            rake clone:node          # master
         
     | 
| 
      
 125 
     | 
    
         
            +
            rake clone               # node + docs
         
     | 
| 
      
 126 
     | 
    
         
            +
            ```
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
            > [!TIP]
         
     | 
| 
      
 129 
     | 
    
         
            +
            > Use the supplied Rakefile inside the **squared** project folder once the source has been downloaded.
         
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
            #### Docker
         
     | 
| 
      
 132 
     | 
    
         
            +
             
     | 
| 
      
 133 
     | 
    
         
            +
            ```sh
         
     | 
| 
      
 134 
     | 
    
         
            +
            # NODE_TAG=latest
         
     | 
| 
      
 135 
     | 
    
         
            +
            # RUBY_VERSION=2.4.0-3.4.0
         
     | 
| 
      
 136 
     | 
    
         
            +
            # MANIFEST=nightly,prod,latest,android
         
     | 
| 
      
 137 
     | 
    
         
            +
            # BUILD={dev,prod}
         
     | 
| 
      
 138 
     | 
    
         
            +
            # DEV={0,1,local}
         
     | 
| 
      
 139 
     | 
    
         
            +
            # DOCS=any
         
     | 
| 
      
 140 
     | 
    
         
            +
            # PIPE_FAIL={0,1}
         
     | 
| 
      
 141 
     | 
    
         
            +
            # PORT=3000
         
     | 
| 
      
 142 
     | 
    
         
            +
            docker build -t squared --build-arg MANIFEST=prod --build-arg NODE_ENV=production .
         
     | 
| 
      
 143 
     | 
    
         
            +
            docker build -t node --build-arg NODE_TAG=22 --build-arg NODE_INSTALL=pnpm -f Dockerfile.slim .
         
     | 
| 
      
 144 
     | 
    
         
            +
            NODE=22 docker buildx bake node
         
     | 
| 
      
 145 
     | 
    
         
            +
            # OR
         
     | 
| 
      
 146 
     | 
    
         
            +
            docker build -t ruby --build-arg RUBY_TAG=3.4.0 --build-arg NODE_VERSION=22 --build-arg PIPE_FAIL=0 -f Dockerfile.ruby .
         
     | 
| 
      
 147 
     | 
    
         
            +
            RUBY=3.4.0 docker buildx bake ruby
         
     | 
| 
      
 148 
     | 
    
         
            +
            # OR
         
     | 
| 
      
 149 
     | 
    
         
            +
            docker build -t nginx --build-arg NGINX_VERSION=1.27 --build-arg PORT=3000 --build-arg NODE_VERSION=20 -f Dockerfile.nginx .
         
     | 
| 
      
 150 
     | 
    
         
            +
            NGINX=1.27 docker buildx bake nginx
         
     | 
| 
      
 151 
     | 
    
         
            +
             
     | 
| 
      
 152 
     | 
    
         
            +
            # Express
         
     | 
| 
      
 153 
     | 
    
         
            +
            docker run -it --name express --rm -p 3000:3000 \
         
     | 
| 
      
 154 
     | 
    
         
            +
              --mount type=bind,src=${PWD},dst=/workspaces/squared/.config \
         
     | 
| 
      
 155 
     | 
    
         
            +
              --mount type=bind,src=${PWD}/html,dst=/workspaces/squared/www \
         
     | 
| 
      
 156 
     | 
    
         
            +
              squared
         
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
      
 158 
     | 
    
         
            +
            docker run -it --name express --rm -p 443:443 --build-arg PORT=443 squared \
         
     | 
| 
      
 159 
     | 
    
         
            +
              serve --access-all --https --env=production
         
     | 
| 
      
 160 
     | 
    
         
            +
             
     | 
| 
      
 161 
     | 
    
         
            +
            # Terminal
         
     | 
| 
      
 162 
     | 
    
         
            +
            docker run -it --name debian squared /bin/bash # irb
         
     | 
| 
      
 163 
     | 
    
         
            +
            ```
         
     | 
| 
      
 164 
     | 
    
         
            +
             
     | 
| 
      
 165 
     | 
    
         
            +
            ### Browser
         
     | 
| 
      
 166 
     | 
    
         
            +
             
     | 
| 
      
 167 
     | 
    
         
            +
            * Download (squared@version): https://unpkg.com/squared
         
     | 
| 
      
 168 
     | 
    
         
            +
            * Global JS variable: **squared**
         
     | 
| 
      
 169 
     | 
    
         
            +
            * ES2018
         
     | 
| 
      
 170 
     | 
    
         
            +
             
     | 
| 
      
 171 
     | 
    
         
            +
            > - https://unpkg.com/squared/dist/squared.min.js
         
     | 
| 
      
 172 
     | 
    
         
            +
            > - https://unpkg.com/squared/dist/squared.base-dom.min.js
         
     | 
| 
      
 173 
     | 
    
         
            +
            > - https://unpkg.com/squared/dist/vdom.framework.min.js
         
     | 
| 
      
 174 
     | 
    
         
            +
             
     | 
| 
      
 175 
     | 
    
         
            +
            > * https://unpkg.com/squared/dist/squared.min.js
         
     | 
| 
      
 176 
     | 
    
         
            +
            > * https://unpkg.com/squared/dist/vdom-lite.framework.min.js
         
     | 
| 
      
 177 
     | 
    
         
            +
             
     | 
| 
      
 178 
     | 
    
         
            +
            ## Usage
         
     | 
| 
      
 179 
     | 
    
         
            +
             
     | 
| 
      
 180 
     | 
    
         
            +
            Library files are in the `/dist` folder. A minimum of **two** files are required to run *squared*.
         
     | 
| 
      
 181 
     | 
    
         
            +
             
     | 
| 
      
 182 
     | 
    
         
            +
            1. squared
         
     | 
| 
      
 183 
     | 
    
         
            +
            2. squared-base - *required: except vdom-lite*
         
     | 
| 
      
 184 
     | 
    
         
            +
            3. **squared-svg** - *optional*
         
     | 
| 
      
 185 
     | 
    
         
            +
            4. framework (e.g. **android** | **chrome** | vdom | vdom-lite)
         
     | 
| 
      
 186 
     | 
    
         
            +
            5. extensions - *optional*
         
     | 
| 
      
 187 
     | 
    
         
            +
             
     | 
| 
      
 188 
     | 
    
         
            +
            Usable combinations: 1-2-4 + 1-2-4-5 + 1-2-3-4-5 + 1-vdom-lite
         
     | 
| 
      
 189 
     | 
    
         
            +
             
     | 
| 
      
 190 
     | 
    
         
            +
            File bundles for common combinations are available in the `/dist/bundles` folder and do not require a call to **setFramework**.
         
     | 
| 
      
 191 
     | 
    
         
            +
             
     | 
| 
      
 192 
     | 
    
         
            +
            > [!WARNING]
         
     | 
| 
      
 193 
     | 
    
         
            +
            > Libraries in bold are transpiled with **ES2020**.
         
     | 
| 
      
 194 
     | 
    
         
            +
             
     | 
| 
      
 195 
     | 
    
         
            +
            ### Example: android
         
     | 
| 
      
 196 
     | 
    
         
            +
             
     | 
| 
      
 197 
     | 
    
         
            +
            The primary function `parseDocument` can be called on multiple elements and multiple times per session. The application will continuously and progressively build the layout files into a single entity with combined shared resources.
         
     | 
| 
      
 198 
     | 
    
         
            +
             
     | 
| 
      
 199 
     | 
    
         
            +
            * ES2020
         
     | 
| 
      
 200 
     | 
    
         
            +
             
     | 
| 
      
 201 
     | 
    
         
            +
            > [!CAUTION]
         
     | 
| 
      
 202 
     | 
    
         
            +
            > Using `parseDocumentSync` is not recommended when your page has images or fonts.
         
     | 
| 
      
 203 
     | 
    
         
            +
             
     | 
| 
      
 204 
     | 
    
         
            +
            ```html
         
     | 
| 
      
 205 
     | 
    
         
            +
            <script src="/dist/squared.min.js"></script>
         
     | 
| 
      
 206 
     | 
    
         
            +
            <script src="/dist/squared.base.min.js"></script>
         
     | 
| 
      
 207 
     | 
    
         
            +
            <script src="/dist/squared.svg.min.js"></script>
         
     | 
| 
      
 208 
     | 
    
         
            +
            <script src="/dist/android.framework.min.js"></script>
         
     | 
| 
      
 209 
     | 
    
         
            +
            <script>
         
     | 
| 
      
 210 
     | 
    
         
            +
                squared.settings.targetAPI = 35; // Optional
         
     | 
| 
      
 211 
     | 
    
         
            +
             
     | 
| 
      
 212 
     | 
    
         
            +
                document.addEventListener("DOMContentLoaded", async () => {
         
     | 
| 
      
 213 
     | 
    
         
            +
                    squared.setFramework(android, {/* settings */});
         
     | 
| 
      
 214 
     | 
    
         
            +
             
     | 
| 
      
 215 
     | 
    
         
            +
                    await squared.parseDocument(): Node // document.body (default)
         
     | 
| 
      
 216 
     | 
    
         
            +
                    // OR
         
     | 
| 
      
 217 
     | 
    
         
            +
                    await squared.parseDocument(/* HTMLElement */, /* "fragment-id" */, /* ...etc */): Node[]
         
     | 
| 
      
 218 
     | 
    
         
            +
                    // OR
         
     | 
| 
      
 219 
     | 
    
         
            +
                    await squared.parseDocument(
         
     | 
| 
      
 220 
     | 
    
         
            +
                        { // Custom settings do not affect other layouts
         
     | 
| 
      
 221 
     | 
    
         
            +
                            element: document.body,
         
     | 
| 
      
 222 
     | 
    
         
            +
                            projectId: "project-1", // Default is "_"
         
     | 
| 
      
 223 
     | 
    
         
            +
                            resourceQualifier: "land", // "res/*" folder suffix
         
     | 
| 
      
 224 
     | 
    
         
            +
                            /* OR */
         
     | 
| 
      
 225 
     | 
    
         
            +
                            resourceQualifier: {
         
     | 
| 
      
 226 
     | 
    
         
            +
                                suffix: "land", // Used for "true" or "undefined" groups (optional)
         
     | 
| 
      
 227 
     | 
    
         
            +
                                layout: true, // Will copy to "res/layout-land" when "suffix" is defined
         
     | 
| 
      
 228 
     | 
    
         
            +
                                string: undefined, // Will copy to default location "res/values" when "suffix" is undefined
         
     | 
| 
      
 229 
     | 
    
         
            +
                                font: false, // Will not copy anything to "res/font" or "res/font-land"
         
     | 
| 
      
 230 
     | 
    
         
            +
                                image: "hdpi", // Will copy to "res/drawable-hdpi"
         
     | 
| 
      
 231 
     | 
    
         
            +
                                video: "w720dp", // Will copy to "res/raw-w720dp"
         
     | 
| 
      
 232 
     | 
    
         
            +
                                audio: "w720dp", // Same as "video" and treated separately
         
     | 
| 
      
 233 
     | 
    
         
            +
                                animation: "v34", // Will copy to "res/anim-v34"
         
     | 
| 
      
 234 
     | 
    
         
            +
                                menu: "" // Will copy to default location "res/menu"
         
     | 
| 
      
 235 
     | 
    
         
            +
                                /* integer + fraction + array + color + dimension + style + theme = Same as "string" */
         
     | 
| 
      
 236 
     | 
    
         
            +
                            },
         
     | 
| 
      
 237 
     | 
    
         
            +
                            enabledMultiline: false,
         
     | 
| 
      
 238 
     | 
    
         
            +
                            enabledSubstitute: true,
         
     | 
| 
      
 239 
     | 
    
         
            +
                            include: ["android.substitute"], // Automatically removed after finalize
         
     | 
| 
      
 240 
     | 
    
         
            +
                            exclude: ["squared.list", "squared.grid"], // Disabled only during parseDocument
         
     | 
| 
      
 241 
     | 
    
         
            +
                            excludeQuery: [{
         
     | 
| 
      
 242 
     | 
    
         
            +
                                selector: "main > article", // Hide elements
         
     | 
| 
      
 243 
     | 
    
         
            +
                                /* OR */
         
     | 
| 
      
 244 
     | 
    
         
            +
                                resource: squared.base.lib.constant.NODE_RESOURCE.BOX_STYLE, // Exclusions during processing
         
     | 
| 
      
 245 
     | 
    
         
            +
                                procedure: squared.base.lib.constant.NODE_PROCEDURE.OPTIMIZATION,
         
     | 
| 
      
 246 
     | 
    
         
            +
                                section: squared.base.lib.constant.APP_SECTION.DOM_TRAVERSE
         
     | 
| 
      
 247 
     | 
    
         
            +
                            }],
         
     | 
| 
      
 248 
     | 
    
         
            +
                            customizationsBaseAPI: -1,
         
     | 
| 
      
 249 
     | 
    
         
            +
                            observe(mutations, observer, settings) { // Uses MutationObserver
         
     | 
| 
      
 250 
     | 
    
         
            +
                                squared.reset(); // Required when calling "parseDocument" after a File action
         
     | 
| 
      
 251 
     | 
    
         
            +
                                squared.parseDocument(settings).then(() => {
         
     | 
| 
      
 252 
     | 
    
         
            +
                                    squared.copyTo("/path/project", { modified: true }).then(response => console.log(response));
         
     | 
| 
      
 253 
     | 
    
         
            +
                                });
         
     | 
| 
      
 254 
     | 
    
         
            +
                            },
         
     | 
| 
      
 255 
     | 
    
         
            +
                            afterCascade(sessionId, node) {/* Restore previous state */},
         
     | 
| 
      
 256 
     | 
    
         
            +
                            beforeRender(layout: LayoutUI) {/* Edit initial values */},
         
     | 
| 
      
 257 
     | 
    
         
            +
                            afterFinalize(node: NodeUI) {/* Edit controller values */}
         
     | 
| 
      
 258 
     | 
    
         
            +
                        },
         
     | 
| 
      
 259 
     | 
    
         
            +
                        { // Only "element" is required
         
     | 
| 
      
 260 
     | 
    
         
            +
                            element: "fragment-1",
         
     | 
| 
      
 261 
     | 
    
         
            +
                            projectId: "project-1", // Implicit once projectId is not "_"
         
     | 
| 
      
 262 
     | 
    
         
            +
                            resourceQualifier: "land",
         
     | 
| 
      
 263 
     | 
    
         
            +
                            pathname: "app/src/main/res/layout-hdpi", // Will not be overridden by resourceQualifier "land"
         
     | 
| 
      
 264 
     | 
    
         
            +
                            filename: "fragment.xml",
         
     | 
| 
      
 265 
     | 
    
         
            +
                            baseLayoutAsFragment: {
         
     | 
| 
      
 266 
     | 
    
         
            +
                                name: "androidx.navigation.fragment.NavHostFragment",
         
     | 
| 
      
 267 
     | 
    
         
            +
                                documentId: "main_content",
         
     | 
| 
      
 268 
     | 
    
         
            +
                                app: {
         
     | 
| 
      
 269 
     | 
    
         
            +
                                    navGraph: "@navigation/product_list_graph",
         
     | 
| 
      
 270 
     | 
    
         
            +
                                    defaultNavHost: "true"
         
     | 
| 
      
 271 
     | 
    
         
            +
                                }
         
     | 
| 
      
 272 
     | 
    
         
            +
                            },
         
     | 
| 
      
 273 
     | 
    
         
            +
                            beforeCascade(sessionId) {
         
     | 
| 
      
 274 
     | 
    
         
            +
                                document.getElementById("fragment-id").style.display = "block"; // Use inline styles
         
     | 
| 
      
 275 
     | 
    
         
            +
                            }
         
     | 
| 
      
 276 
     | 
    
         
            +
                        }
         
     | 
| 
      
 277 
     | 
    
         
            +
                    );
         
     | 
| 
      
 278 
     | 
    
         
            +
                    await squared.parseDocument({
         
     | 
| 
      
 279 
     | 
    
         
            +
                        element: "fragment-2",
         
     | 
| 
      
 280 
     | 
    
         
            +
                        projectId: "sqd2", // Explicit
         
     | 
| 
      
 281 
     | 
    
         
            +
                        resourceQualifier: "port", // Will not conflict with projectId "project-1"
         
     | 
| 
      
 282 
     | 
    
         
            +
                        enabledFragment: true,
         
     | 
| 
      
 283 
     | 
    
         
            +
                        fragmentableElements: [
         
     | 
| 
      
 284 
     | 
    
         
            +
                            {
         
     | 
| 
      
 285 
     | 
    
         
            +
                              selector: "main", // querySelector
         
     | 
| 
      
 286 
     | 
    
         
            +
                              name: "androidx.navigation.fragment.NavHostFragment",
         
     | 
| 
      
 287 
     | 
    
         
            +
                              filename: "navigation.xml",
         
     | 
| 
      
 288 
     | 
    
         
            +
                              documentId: "main_content"
         
     | 
| 
      
 289 
     | 
    
         
            +
                            },
         
     | 
| 
      
 290 
     | 
    
         
            +
                            "main > article" // Declarative double nested fragments are invalid (querySelectorAll)
         
     | 
| 
      
 291 
     | 
    
         
            +
                        ],
         
     | 
| 
      
 292 
     | 
    
         
            +
                        options: {
         
     | 
| 
      
 293 
     | 
    
         
            +
                            "android.resource.fragment": {
         
     | 
| 
      
 294 
     | 
    
         
            +
                                dynamicNestedFragments: true // FragmentContainerView or FrameLayout as the container (name and tag are ignored)
         
     | 
| 
      
 295 
     | 
    
         
            +
                            }
         
     | 
| 
      
 296 
     | 
    
         
            +
                        }
         
     | 
| 
      
 297 
     | 
    
         
            +
                    });
         
     | 
| 
      
 298 
     | 
    
         
            +
                    // OR - Chromium
         
     | 
| 
      
 299 
     | 
    
         
            +
                    squared.prefetch("css").then(() => squared.parseDocument()); // Cross-origin support
         
     | 
| 
      
 300 
     | 
    
         
            +
                    Promise.all(
         
     | 
| 
      
 301 
     | 
    
         
            +
                        squared.prefetch("css", true), // All stylesheets
         
     | 
| 
      
 302 
     | 
    
         
            +
                        squared.prefetch("css", "./undetected.css", element.shadowRoot),
         
     | 
| 
      
 303 
     | 
    
         
            +
                        squared.prefetch("svg", "http://embedded.example.com/icon.svg", "../images/android.svg")
         
     | 
| 
      
 304 
     | 
    
         
            +
                    )
         
     | 
| 
      
 305 
     | 
    
         
            +
                    .then(() => squared.parseDocument());
         
     | 
| 
      
 306 
     | 
    
         
            +
             
     | 
| 
      
 307 
     | 
    
         
            +
                    // Modify attributes
         
     | 
| 
      
 308 
     | 
    
         
            +
             
     | 
| 
      
 309 
     | 
    
         
            +
                    const body = squared.findDocumentNode(document.body);
         
     | 
| 
      
 310 
     | 
    
         
            +
                    body.android("layout_width", "match_parent");
         
     | 
| 
      
 311 
     | 
    
         
            +
                    body.lockAttr("android", "layout_width");
         
     | 
| 
      
 312 
     | 
    
         
            +
             
     | 
| 
      
 313 
     | 
    
         
            +
                    await squared.close(/* projectId */); // Next call to parseDocument will reset project (optional)
         
     | 
| 
      
 314 
     | 
    
         
            +
             
     | 
| 
      
 315 
     | 
    
         
            +
                    squared.kill("30s").then(result => {/* killed when result > 0 */}); // Abort next request in 30 seconds
         
     | 
| 
      
 316 
     | 
    
         
            +
             
     | 
| 
      
 317 
     | 
    
         
            +
                    // File actions - implicitly calls "close"
         
     | 
| 
      
 318 
     | 
    
         
            +
             
     | 
| 
      
 319 
     | 
    
         
            +
                    await squared.save(/* "project-1" */, /* broadcastId | timeout */); // Uses defaults from settings
         
     | 
| 
      
 320 
     | 
    
         
            +
                    // OR
         
     | 
| 
      
 321 
     | 
    
         
            +
                    await squared.saveAs(/* archive filename */, { projectId: "project-1" });
         
     | 
| 
      
 322 
     | 
    
         
            +
                    await squared.saveAs(/* archive filename */, { timeout: 10 }); // Kills request if not complete in 10 seconds
         
     | 
| 
      
 323 
     | 
    
         
            +
                    await squared.saveAs(/* archive filename */, { throwErrors: true }).catch(err => console.log(err)); // Will cancel partial archive download
         
     | 
| 
      
 324 
     | 
    
         
            +
                    // OR
         
     | 
| 
      
 325 
     | 
    
         
            +
                    await squared.copyTo(/* directory */, {/* options */});
         
     | 
| 
      
 326 
     | 
    
         
            +
                    await squared.copyTo(/* directory */, { modified: true }); // Can be used with observe
         
     | 
| 
      
 327 
     | 
    
         
            +
                    // OR
         
     | 
| 
      
 328 
     | 
    
         
            +
                    await squared.appendTo(/* archive location */, {/* options */});
         
     | 
| 
      
 329 
     | 
    
         
            +
             
     | 
| 
      
 330 
     | 
    
         
            +
                    // Other features
         
     | 
| 
      
 331 
     | 
    
         
            +
             
     | 
| 
      
 332 
     | 
    
         
            +
                    squared.observe();
         
     | 
| 
      
 333 
     | 
    
         
            +
                    // OR
         
     | 
| 
      
 334 
     | 
    
         
            +
                    await squared.observeSrc(
         
     | 
| 
      
 335 
     | 
    
         
            +
                        "link[rel=stylesheet]", // HTMLElement
         
     | 
| 
      
 336 
     | 
    
         
            +
                        (ev, element) => {
         
     | 
| 
      
 337 
     | 
    
         
            +
                            squared.reset();
         
     | 
| 
      
 338 
     | 
    
         
            +
                            squared.parseDocument().then(() => squared.copyTo("/path/project"));
         
     | 
| 
      
 339 
     | 
    
         
            +
                        },
         
     | 
| 
      
 340 
     | 
    
         
            +
                        { port: 8080, secure: false, action: "reload" /* "hot" */, expires: "1h" } // squared.json: "observe"
         
     | 
| 
      
 341 
     | 
    
         
            +
                    );
         
     | 
| 
      
 342 
     | 
    
         
            +
             
     | 
| 
      
 343 
     | 
    
         
            +
                    squared.reset(/* projectId */); // Start new "parseDocument" session (optional)
         
     | 
| 
      
 344 
     | 
    
         
            +
                });
         
     | 
| 
      
 345 
     | 
    
         
            +
            </script>
         
     | 
| 
      
 346 
     | 
    
         
            +
            ```
         
     | 
| 
      
 347 
     | 
    
         
            +
             
     | 
| 
      
 348 
     | 
    
         
            +
            > [!CAUTION]
         
     | 
| 
      
 349 
     | 
    
         
            +
            > Calling `saveAs` or `copyTo` methods before the images have completely loaded can cause them to be excluded from the generated layout. In these cases you should use the asynchronous `parseDocument` method to set a callback for your commands.
         
     | 
| 
      
 350 
     | 
    
         
            +
             
     | 
| 
      
 351 
     | 
    
         
            +
            ### Example: chrome
         
     | 
| 
      
 352 
     | 
    
         
            +
             
     | 
| 
      
 353 
     | 
    
         
            +
            Used primarly for developing single page layouts but can also bundle assets using query selector syntax. It is adequate for most projects and gives you the ability to develop your application as a module in place.
         
     | 
| 
      
 354 
     | 
    
         
            +
             
     | 
| 
      
 355 
     | 
    
         
            +
            * ES2020
         
     | 
| 
      
 356 
     | 
    
         
            +
             
     | 
| 
      
 357 
     | 
    
         
            +
            ```html
         
     | 
| 
      
 358 
     | 
    
         
            +
            <script src="/dist/squared.min.js"></script>
         
     | 
| 
      
 359 
     | 
    
         
            +
            <script src="/dist/squared.base.min.js"></script>
         
     | 
| 
      
 360 
     | 
    
         
            +
            <script src="/dist/chrome.framework.min.js"></script>
         
     | 
| 
      
 361 
     | 
    
         
            +
            <script>
         
     | 
| 
      
 362 
     | 
    
         
            +
                document.addEventListener("DOMContentLoaded", async () => {
         
     | 
| 
      
 363 
     | 
    
         
            +
                    squared.setFramework(chrome, {/* settings */});
         
     | 
| 
      
 364 
     | 
    
         
            +
             
     | 
| 
      
 365 
     | 
    
         
            +
                    await squared.save(); // Uses defaults from settings
         
     | 
| 
      
 366 
     | 
    
         
            +
                    // OR
         
     | 
| 
      
 367 
     | 
    
         
            +
                    await squared.saveAs(/* archive filename */, {/* options */});
         
     | 
| 
      
 368 
     | 
    
         
            +
                    // OR
         
     | 
| 
      
 369 
     | 
    
         
            +
                    await squared.copyTo(/* directory */, {/* options */});
         
     | 
| 
      
 370 
     | 
    
         
            +
                    // OR
         
     | 
| 
      
 371 
     | 
    
         
            +
                    await squared.appendTo(/* archive location */, {/* options */});
         
     | 
| 
      
 372 
     | 
    
         
            +
             
     | 
| 
      
 373 
     | 
    
         
            +
                    // Observe
         
     | 
| 
      
 374 
     | 
    
         
            +
                    await squared.copyTo(/* directory */, { useOriginalHtmlPage: false, observe: /* Same as Android */ | true /* Auto-reload */}).then(() => squared.observe());
         
     | 
| 
      
 375 
     | 
    
         
            +
                });
         
     | 
| 
      
 376 
     | 
    
         
            +
            </script>
         
     | 
| 
      
 377 
     | 
    
         
            +
            ```
         
     | 
| 
      
 378 
     | 
    
         
            +
             
     | 
| 
      
 379 
     | 
    
         
            +
            ### Example: vdom
         
     | 
| 
      
 380 
     | 
    
         
            +
             
     | 
| 
      
 381 
     | 
    
         
            +
            The most minimal framework possible (*55kb gzipped*) and can be useful when debugging through DevTools. The `lite` version is about half the bundle size and is recommended for most browser applications.
         
     | 
| 
      
 382 
     | 
    
         
            +
             
     | 
| 
      
 383 
     | 
    
         
            +
            * ES2018
         
     | 
| 
      
 384 
     | 
    
         
            +
             
     | 
| 
      
 385 
     | 
    
         
            +
            ```html
         
     | 
| 
      
 386 
     | 
    
         
            +
            <script src="/dist/squared.min.js"></script>
         
     | 
| 
      
 387 
     | 
    
         
            +
            <script src="/dist/squared.base-dom.min.js"></script>
         
     | 
| 
      
 388 
     | 
    
         
            +
            <script src="/dist/vdom.framework.min.js"></script>
         
     | 
| 
      
 389 
     | 
    
         
            +
            <script>
         
     | 
| 
      
 390 
     | 
    
         
            +
                document.addEventListener("DOMContentLoaded", async () => {
         
     | 
| 
      
 391 
     | 
    
         
            +
                    squared.setFramework(vdom, {/* settings */});
         
     | 
| 
      
 392 
     | 
    
         
            +
             
     | 
| 
      
 393 
     | 
    
         
            +
                    const element = squared.querySelector("body", true /* synchronous */);
         
     | 
| 
      
 394 
     | 
    
         
            +
                    // OR
         
     | 
| 
      
 395 
     | 
    
         
            +
                    const elements = await squared.querySelectorAll("*");
         
     | 
| 
      
 396 
     | 
    
         
            +
                    // OR
         
     | 
| 
      
 397 
     | 
    
         
            +
                    const element = squared.fromElement(document.body, true /* synchronous */);
         
     | 
| 
      
 398 
     | 
    
         
            +
                    // OR
         
     | 
| 
      
 399 
     | 
    
         
            +
                    const elements = await squared.getElementById("content-id").querySelectorAll("*");
         
     | 
| 
      
 400 
     | 
    
         
            +
                });
         
     | 
| 
      
 401 
     | 
    
         
            +
            </script>
         
     | 
| 
      
 402 
     | 
    
         
            +
            ```
         
     | 
| 
      
 403 
     | 
    
         
            +
             
     | 
| 
      
 404 
     | 
    
         
            +
            There are **ES2018** minified versions (\*.min.js) and also **ES2018** non-minified versions.
         
     | 
| 
      
 405 
     | 
    
         
            +
             
     | 
| 
      
 406 
     | 
    
         
            +
            ## User Settings
         
     | 
| 
      
 407 
     | 
    
         
            +
             
     | 
| 
      
 408 
     | 
    
         
            +
            These settings are available in the global variable `squared` to customize your desired output structure. Each framework shares a common set of settings and also a subset of their own settings.
         
     | 
| 
      
 409 
     | 
    
         
            +
             
     | 
| 
      
 410 
     | 
    
         
            +
            ### Example: android
         
     | 
| 
      
 411 
     | 
    
         
            +
             
     | 
| 
      
 412 
     | 
    
         
            +
            - [Read the Docs](https://squared.readthedocs.io/en/latest/settings/android.html)
         
     | 
| 
      
 413 
     | 
    
         
            +
             
     | 
| 
      
 414 
     | 
    
         
            +
            ```javascript
         
     | 
| 
      
 415 
     | 
    
         
            +
            squared.settings = {
         
     | 
| 
      
 416 
     | 
    
         
            +
                targetAPI: 35,
         
     | 
| 
      
 417 
     | 
    
         
            +
                supportRTL: true,
         
     | 
| 
      
 418 
     | 
    
         
            +
                supportNegativeLeftTop: true,
         
     | 
| 
      
 419 
     | 
    
         
            +
                preloadImages: true,
         
     | 
| 
      
 420 
     | 
    
         
            +
                preloadFonts: true,
         
     | 
| 
      
 421 
     | 
    
         
            +
                preloadLocalFonts: true, // Chromium
         
     | 
| 
      
 422 
     | 
    
         
            +
                preloadCustomElements: true,
         
     | 
| 
      
 423 
     | 
    
         
            +
                enabledSVG: true,
         
     | 
| 
      
 424 
     | 
    
         
            +
                enabledMultiline: true,
         
     | 
| 
      
 425 
     | 
    
         
            +
                enabledViewModel: true,
         
     | 
| 
      
 426 
     | 
    
         
            +
                enabledIncludes: false,
         
     | 
| 
      
 427 
     | 
    
         
            +
                enabledFragment: false,
         
     | 
| 
      
 428 
     | 
    
         
            +
                enabledSubstitute: false,
         
     | 
| 
      
 429 
     | 
    
         
            +
                enabledCompose: false,
         
     | 
| 
      
 430 
     | 
    
         
            +
                dataBindableElements: [], // { selector, attr, expression, namespace?, twoWay? } (see Data Binding section)
         
     | 
| 
      
 431 
     | 
    
         
            +
                includableElements: [], // { selectorStart, selectorEnd, pathname?, filename?, merge?, viewModel? }
         
     | 
| 
      
 432 
     | 
    
         
            +
                substitutableElements: [], // { selector, tag, tagChild?, renderChildren?, autoLayout? }
         
     | 
| 
      
 433 
     | 
    
         
            +
                fragmentableElements: [], // selector | ExtensionFragmentElement
         
     | 
| 
      
 434 
     | 
    
         
            +
                composableElements: [], // selector or property (see Jetpack Compose section)
         
     | 
| 
      
 435 
     | 
    
         
            +
                baseLayoutAsFragment: false | "fragment-name" | ["fragment-name", "fragment-tag"] | { selector, pathname?, filename?, name?, tag? }, // ExtensionFragmentElement
         
     | 
| 
      
 436 
     | 
    
         
            +
                baseLayoutToolsIgnore: "", // Android Studio (e.g. "TooManyViews, HardcodedText")
         
     | 
| 
      
 437 
     | 
    
         
            +
                fontMeasureAdjust: 0.75, // thicker < 0 | thinner > 0 (data-android-font-measure-adjust)
         
     | 
| 
      
 438 
     | 
    
         
            +
                lineHeightAdjust: 1.1, // shorter < 1 | taller > 1 (data-android-line-height-adjust)
         
     | 
| 
      
 439 
     | 
    
         
            +
                preferMaterialDesign: false | "MaterialComponents" | "Material3", // Default is "Material3"
         
     | 
| 
      
 440 
     | 
    
         
            +
                createDownloadableFonts: true,
         
     | 
| 
      
 441 
     | 
    
         
            +
                createElementMap: false,
         
     | 
| 
      
 442 
     | 
    
         
            +
                pierceShadowRoot: true,
         
     | 
| 
      
 443 
     | 
    
         
            +
                adaptStyleMap: true, // Use rendered values for output
         
     | 
| 
      
 444 
     | 
    
         
            +
                lockElementSettings: true,
         
     | 
| 
      
 445 
     | 
    
         
            +
                customizationsBaseAPI: 0, // 0 - All | -1 - None
         
     | 
| 
      
 446 
     | 
    
         
            +
                customizationsBaseAPI: [0, 33, 34], // Multiple
         
     | 
| 
      
 447 
     | 
    
         
            +
                removeDeprecatedAttributes: true, // Remove all
         
     | 
| 
      
 448 
     | 
    
         
            +
                removeDeprecatedAttributes: ["enabled", "singleLine"], // Remove all except "enabled" + "singleLine"
         
     | 
| 
      
 449 
     | 
    
         
            +
                removeUnusedResourceViewId: false,
         
     | 
| 
      
 450 
     | 
    
         
            +
                idNamingStyle: "android",
         
     | 
| 
      
 451 
     | 
    
         
            +
                idNamingStyle: "html", // Use element tagName
         
     | 
| 
      
 452 
     | 
    
         
            +
                idNamingStyle: {
         
     | 
| 
      
 453 
     | 
    
         
            +
                    "__default__": "html", // Optional
         
     | 
| 
      
 454 
     | 
    
         
            +
                    "DIV": "comments", // HTML is uppercase (comments_1 then comments_2)
         
     | 
| 
      
 455 
     | 
    
         
            +
                    "svg": ["vector", 0], // SVG elements areis lowercase (vector_0 then vector_1)
         
     | 
| 
      
 456 
     | 
    
         
            +
                    "#text": "text", // Plain text
         
     | 
| 
      
 457 
     | 
    
         
            +
                    "::first-letter": "dropcap", // Pseudo element
         
     | 
| 
      
 458 
     | 
    
         
            +
                    "main > section": ["content", 1, 2], // content_1 then content_3
         
     | 
| 
      
 459 
     | 
    
         
            +
                    "form input[type=submit]": function(node) {
         
     | 
| 
      
 460 
     | 
    
         
            +
                        return "submit_" + node.id;
         
     | 
| 
      
 461 
     | 
    
         
            +
                    }
         
     | 
| 
      
 462 
     | 
    
         
            +
                },
         
     | 
| 
      
 463 
     | 
    
         
            +
                customizationsOverwritePrivilege: true,
         
     | 
| 
      
 464 
     | 
    
         
            +
                outputMainFileName: "activity_main.xml",
         
     | 
| 
      
 465 
     | 
    
         
            +
                outputFragmentFileName: "fragment_main.xml",
         
     | 
| 
      
 466 
     | 
    
         
            +
                /* Project - parseDocument (first only) */
         
     | 
| 
      
 467 
     | 
    
         
            +
                resourceQualifier: "", // "land" -> "res/layout-land" | "port" -> "res/layout-port" (appended to every "res" folder)
         
     | 
| 
      
 468 
     | 
    
         
            +
                resourceSystemColors: {
         
     | 
| 
      
 469 
     | 
    
         
            +
                    "system_accent1_100": "white", // Will be converted to ARGB
         
     | 
| 
      
 470 
     | 
    
         
            +
                    "system_accent1_200": ['#ff0000', 0.75], // opacity
         
     | 
| 
      
 471 
     | 
    
         
            +
                    "system_accent1_300": squared.lib.color.parseColor("#000", 1)
         
     | 
| 
      
 472 
     | 
    
         
            +
                },
         
     | 
| 
      
 473 
     | 
    
         
            +
                manifestPackage: "", // OR: RequestData<{ namespace: "android.application.id" }>
         
     | 
| 
      
 474 
     | 
    
         
            +
                manifestLabelAppName: "android",
         
     | 
| 
      
 475 
     | 
    
         
            +
                manifestThemeName: "AppTheme",
         
     | 
| 
      
 476 
     | 
    
         
            +
                manifestParentThemeName: "Theme.AppCompat.Light.NoActionBar",
         
     | 
| 
      
 477 
     | 
    
         
            +
                manifestActivityName: ".MainActivity",
         
     | 
| 
      
 478 
     | 
    
         
            +
                outputDocumentEditing: true,
         
     | 
| 
      
 479 
     | 
    
         
            +
                outputDocumentCSS: [], // CSS properties to be processed at server (e.g. "boxShadow")
         
     | 
| 
      
 480 
     | 
    
         
            +
                outputDirectory: "app/src/main",
         
     | 
| 
      
 481 
     | 
    
         
            +
                createManifest: false, // Update AndroidManifest.xml
         
     | 
| 
      
 482 
     | 
    
         
            +
                createBuildDependencies: false | "ktx" | "baseline-profile" | ["ktx", "baseline-profile"], // Update build.gradle
         
     | 
| 
      
 483 
     | 
    
         
            +
             
     | 
| 
      
 484 
     | 
    
         
            +
                // Not customizable with parseDocument
         
     | 
| 
      
 485 
     | 
    
         
            +
                builtInExtensions: [
         
     | 
| 
      
 486 
     | 
    
         
            +
                    "squared.accessibility",
         
     | 
| 
      
 487 
     | 
    
         
            +
                    "android.delegate.background",
         
     | 
| 
      
 488 
     | 
    
         
            +
                    "android.delegate.negative-x",
         
     | 
| 
      
 489 
     | 
    
         
            +
                    "android.delegate.positive-x",
         
     | 
| 
      
 490 
     | 
    
         
            +
                    "android.delegate.max-width-height",
         
     | 
| 
      
 491 
     | 
    
         
            +
                    "android.delegate.percent",
         
     | 
| 
      
 492 
     | 
    
         
            +
                    "android.delegate.content",
         
     | 
| 
      
 493 
     | 
    
         
            +
                    "android.delegate.scrollbar",
         
     | 
| 
      
 494 
     | 
    
         
            +
                    "android.delegate.radiogroup",
         
     | 
| 
      
 495 
     | 
    
         
            +
                    "android.delegate.multiline",
         
     | 
| 
      
 496 
     | 
    
         
            +
                    "squared.relative",
         
     | 
| 
      
 497 
     | 
    
         
            +
                    "squared.css-grid",
         
     | 
| 
      
 498 
     | 
    
         
            +
                    "squared.flexbox",
         
     | 
| 
      
 499 
     | 
    
         
            +
                    "squared.table",
         
     | 
| 
      
 500 
     | 
    
         
            +
                    "squared.column",
         
     | 
| 
      
 501 
     | 
    
         
            +
                    "squared.list",
         
     | 
| 
      
 502 
     | 
    
         
            +
                    "squared.grid",
         
     | 
| 
      
 503 
     | 
    
         
            +
                    "squared.sprite",
         
     | 
| 
      
 504 
     | 
    
         
            +
                    "squared.whitespace",
         
     | 
| 
      
 505 
     | 
    
         
            +
                    "android.resource.background",
         
     | 
| 
      
 506 
     | 
    
         
            +
                    "android.resource.svg",
         
     | 
| 
      
 507 
     | 
    
         
            +
                    "android.resource.strings",
         
     | 
| 
      
 508 
     | 
    
         
            +
                    "android.resource.fonts",
         
     | 
| 
      
 509 
     | 
    
         
            +
                    "android.resource.dimens",
         
     | 
| 
      
 510 
     | 
    
         
            +
                    "android.resource.styles",
         
     | 
| 
      
 511 
     | 
    
         
            +
                    "android.resource.data",
         
     | 
| 
      
 512 
     | 
    
         
            +
             
     | 
| 
      
 513 
     | 
    
         
            +
                    /* EXCLUDED (breaks layout) */
         
     | 
| 
      
 514 
     | 
    
         
            +
                    "android.resource.includes", // enabledIncludes
         
     | 
| 
      
 515 
     | 
    
         
            +
                    "android.substitute", // enabledSubstitute
         
     | 
| 
      
 516 
     | 
    
         
            +
                    "android.resource.fragment", // enabledFragment
         
     | 
| 
      
 517 
     | 
    
         
            +
                    "jetpack.compose.view" // enabledCompose
         
     | 
| 
      
 518 
     | 
    
         
            +
                ],
         
     | 
| 
      
 519 
     | 
    
         
            +
                compressImages: false, // TinyPNG API Key <https://tinypng.com/developers>
         
     | 
| 
      
 520 
     | 
    
         
            +
                compressImages: "****************", // API key
         
     | 
| 
      
 521 
     | 
    
         
            +
                compressImages: [{ plugin: "imagemin-pngquant", format: "png", options: { quality: [0.6, 0.8] } }], // v5.5
         
     | 
| 
      
 522 
     | 
    
         
            +
                convertImages: "", // png | jpeg | webp | gif | bmp
         
     | 
| 
      
 523 
     | 
    
         
            +
                showAttributes: true,
         
     | 
| 
      
 524 
     | 
    
         
            +
                showAttributes: {
         
     | 
| 
      
 525 
     | 
    
         
            +
                  "hyphenationFrequency": "full", // Replace all ("android" is the default namespace)
         
     | 
| 
      
 526 
     | 
    
         
            +
                  "android:fontFeatureSettings": null, // Delete all
         
     | 
| 
      
 527 
     | 
    
         
            +
                  "app:menu": [
         
     | 
| 
      
 528 
     | 
    
         
            +
                    "@menu/menu_1", "@menu/menu_2", // Replace with "@menu/menu_2" when value is "@menu/menu_1"
         
     | 
| 
      
 529 
     | 
    
         
            +
                    "@menu/menu_3", null // Delete attribute when value is "@menu/menu_3"
         
     | 
| 
      
 530 
     | 
    
         
            +
                  ],
         
     | 
| 
      
 531 
     | 
    
         
            +
                  /* OR */
         
     | 
| 
      
 532 
     | 
    
         
            +
                  "app:menu": {
         
     | 
| 
      
 533 
     | 
    
         
            +
                    "@menu/menu_1": "@menu/menu_2",
         
     | 
| 
      
 534 
     | 
    
         
            +
                    "@menu/menu_3": null
         
     | 
| 
       205 
535 
     | 
    
         
             
                  }
         
     | 
| 
      
 536 
     | 
    
         
            +
                },
         
     | 
| 
      
 537 
     | 
    
         
            +
                showComments: false | ["boxShadow"] | { self: ["boxShadow"], nextSibling: ["marginBottom"], previousSibling: ["marginTop"], parent: ["position", "top", "left"] }, // TODO in layout.xml
         
     | 
| 
      
 538 
     | 
    
         
            +
                showComments: { include: { tagName: true | ["button"], attributes: true | ["style"], dataset: false, bounds: true }, self: ["boxShadow", ".className"] },
         
     | 
| 
      
 539 
     | 
    
         
            +
                showErrorMessages: false,
         
     | 
| 
      
 540 
     | 
    
         
            +
                convertPixels: "dp", // "sp" | "pt" | "in" | "mm"
         
     | 
| 
      
 541 
     | 
    
         
            +
                convertLineHeight: "sp", // "dp" | "pt" | "in" | "mm"
         
     | 
| 
      
 542 
     | 
    
         
            +
                convertEntities: ["numeric"],
         
     | 
| 
      
 543 
     | 
    
         
            +
                convertEntities: ["codepoints", {/* JSON (last) */}], // https://html.spec.whatwg.org/entities.json
         
     | 
| 
      
 544 
     | 
    
         
            +
                insertSpaces: 4,
         
     | 
| 
      
 545 
     | 
    
         
            +
                outputDocumentHandler: "android",
         
     | 
| 
      
 546 
     | 
    
         
            +
                outputEmptyCopyDirectory: false, // Sub directories within target directory (OR: RequestData<{ emptyDir: false }>)
         
     | 
| 
      
 547 
     | 
    
         
            +
                outputSummaryModal: false | "path/summary.css" | ".status-4 { color: purple; }",
         
     | 
| 
      
 548 
     | 
    
         
            +
                outputTasks: {
         
     | 
| 
      
 549 
     | 
    
         
            +
                  "**/drawable/*.xml": { handler: "gulp", task: "minify" }
         
     | 
| 
      
 550 
     | 
    
         
            +
                },
         
     | 
| 
      
 551 
     | 
    
         
            +
                outputWatch: {
         
     | 
| 
      
 552 
     | 
    
         
            +
                  "**/drawable/*.png": true,
         
     | 
| 
      
 553 
     | 
    
         
            +
                  "**/drawable/*.jpg": { interval: 1000, expires: "2h" }
         
     | 
| 
      
 554 
     | 
    
         
            +
                },
         
     | 
| 
      
 555 
     | 
    
         
            +
                outputArchiveName: "android-xml",
         
     | 
| 
      
 556 
     | 
    
         
            +
                outputArchiveFormat: "zip", // tar | 7z | gz
         
     | 
| 
      
 557 
     | 
    
         
            +
                outputArchiveCache: false // Downloadable URL in ResponseData<downloadUrl>
         
     | 
| 
      
 558 
     | 
    
         
            +
            };
         
     | 
| 
      
 559 
     | 
    
         
            +
             
     | 
| 
      
 560 
     | 
    
         
            +
            // Optional
         
     | 
| 
      
 561 
     | 
    
         
            +
            squared.settings = {
         
     | 
| 
      
 562 
     | 
    
         
            +
                resolutionDPI: 160, // 320dpi = 2560x1600
         
     | 
| 
      
 563 
     | 
    
         
            +
                resolutionScreenWidth: 1280,
         
     | 
| 
      
 564 
     | 
    
         
            +
                resolutionScreenHeight: 800,
         
     | 
| 
      
 565 
     | 
    
         
            +
                framesPerSecond: 60,
         
     | 
| 
      
 566 
     | 
    
         
            +
                useShapeGeometryBox: true, // Bounding box uses native SVG method getBbox
         
     | 
| 
      
 567 
     | 
    
         
            +
                formatUUID: "8-4-4-4-12", // UUID: 8-4-[12345]3-[89ab]3-12
         
     | 
| 
      
 568 
     | 
    
         
            +
                formatDictionary: "0123456789abcdef",
         
     | 
| 
      
 569 
     | 
    
         
            +
                outputConfigName: "sqd.config",
         
     | 
| 
      
 570 
     | 
    
         
            +
                observePort: 8080,
         
     | 
| 
      
 571 
     | 
    
         
            +
                observeSecurePort: 8443,
         
     | 
| 
      
 572 
     | 
    
         
            +
                observeExpires: "1h", // Server defaults will be used
         
     | 
| 
      
 573 
     | 
    
         
            +
                broadcastPort: 3080,
         
     | 
| 
      
 574 
     | 
    
         
            +
                broadcastSecurePort: 3443
         
     | 
| 
      
 575 
     | 
    
         
            +
            };
         
     | 
| 
      
 576 
     | 
    
         
            +
            ```
         
     | 
| 
      
 577 
     | 
    
         
            +
             
     | 
| 
      
 578 
     | 
    
         
            +
            ### Example: chrome
         
     | 
| 
      
 579 
     | 
    
         
            +
             
     | 
| 
      
 580 
     | 
    
         
            +
            - [Read the Docs](https://squared.readthedocs.io/en/latest/settings/chrome.html)
         
     | 
| 
      
 581 
     | 
    
         
            +
             
     | 
| 
      
 582 
     | 
    
         
            +
            ```javascript
         
     | 
| 
      
 583 
     | 
    
         
            +
            squared.settings = {
         
     | 
| 
      
 584 
     | 
    
         
            +
                preloadImages: false,
         
     | 
| 
      
 585 
     | 
    
         
            +
                preloadFonts: false,
         
     | 
| 
      
 586 
     | 
    
         
            +
                preloadLocalFonts: false,
         
     | 
| 
      
 587 
     | 
    
         
            +
                preloadCustomElements: false,
         
     | 
| 
      
 588 
     | 
    
         
            +
                excludePlainText: true,
         
     | 
| 
      
 589 
     | 
    
         
            +
                createElementMap: true,
         
     | 
| 
      
 590 
     | 
    
         
            +
                pierceShadowRoot: true,
         
     | 
| 
      
 591 
     | 
    
         
            +
                adaptStyleMap: false,
         
     | 
| 
      
 592 
     | 
    
         
            +
                builtInExtensions: [],
         
     | 
| 
      
 593 
     | 
    
         
            +
                showErrorMessages: false,
         
     | 
| 
      
 594 
     | 
    
         
            +
                webSocketPort: 80,
         
     | 
| 
      
 595 
     | 
    
         
            +
                webSocketSecurePort: 443,
         
     | 
| 
      
 596 
     | 
    
         
            +
                outputDocumentHandler: "chrome",
         
     | 
| 
      
 597 
     | 
    
         
            +
                outputEmptyCopyDirectory: false,
         
     | 
| 
      
 598 
     | 
    
         
            +
                outputSummaryModal: false,
         
     | 
| 
      
 599 
     | 
    
         
            +
                outputTasks: {
         
     | 
| 
      
 600 
     | 
    
         
            +
                  "*.js": [{ handler: "gulp", task: "minify" }, { handler: "gulp", task: "beautify" }]
         
     | 
| 
      
 601 
     | 
    
         
            +
                },
         
     | 
| 
      
 602 
     | 
    
         
            +
                outputWatch: { "*": true },
         
     | 
| 
      
 603 
     | 
    
         
            +
                outputArchiveName: "chrome-data",
         
     | 
| 
      
 604 
     | 
    
         
            +
                outputArchiveFormat: "zip",
         
     | 
| 
      
 605 
     | 
    
         
            +
                outputArchiveCache: false
         
     | 
| 
      
 606 
     | 
    
         
            +
            };
         
     | 
| 
      
 607 
     | 
    
         
            +
             
     | 
| 
      
 608 
     | 
    
         
            +
            // Optional (Same as Android)
         
     | 
| 
      
 609 
     | 
    
         
            +
             
     | 
| 
      
 610 
     | 
    
         
            +
            ```
         
     | 
| 
      
 611 
     | 
    
         
            +
             
     | 
| 
      
 612 
     | 
    
         
            +
            ### Example: vdom
         
     | 
| 
      
 613 
     | 
    
         
            +
             
     | 
| 
      
 614 
     | 
    
         
            +
            - [Read the Docs](https://squared.readthedocs.io/en/latest/settings/vdom.html)
         
     | 
| 
      
 615 
     | 
    
         
            +
             
     | 
| 
      
 616 
     | 
    
         
            +
            ```javascript
         
     | 
| 
      
 617 
     | 
    
         
            +
            squared.settings = {
         
     | 
| 
      
 618 
     | 
    
         
            +
                createElementMap: true,
         
     | 
| 
      
 619 
     | 
    
         
            +
                pierceShadowRoot: false,
         
     | 
| 
      
 620 
     | 
    
         
            +
                adaptStyleMap: false,
         
     | 
| 
      
 621 
     | 
    
         
            +
                builtInExtensions: [],
         
     | 
| 
      
 622 
     | 
    
         
            +
                showErrorMessages: false
         
     | 
| 
      
 623 
     | 
    
         
            +
            };
         
     | 
| 
      
 624 
     | 
    
         
            +
            ```
         
     | 
| 
      
 625 
     | 
    
         
            +
             
     | 
| 
      
 626 
     | 
    
         
            +
            ## Local Storage
         
     | 
| 
      
 627 
     | 
    
         
            +
             
     | 
| 
      
 628 
     | 
    
         
            +
            Custom named user settings per framework can be saved to local storage as JSON and reused across all pages in the same domain. Extensions are configured using the same procedure.
         
     | 
| 
      
 629 
     | 
    
         
            +
             
     | 
| 
      
 630 
     | 
    
         
            +
            ```javascript
         
     | 
| 
      
 631 
     | 
    
         
            +
            // Save
         
     | 
| 
      
 632 
     | 
    
         
            +
            squared.setFramework(android, { compressImages: true }, "android-example");
         
     | 
| 
      
 633 
     | 
    
         
            +
             
     | 
| 
      
 634 
     | 
    
         
            +
            // Load
         
     | 
| 
      
 635 
     | 
    
         
            +
            squared.setFramework(android, "android-example");
         
     | 
| 
      
 636 
     | 
    
         
            +
            ```
         
     | 
| 
      
 637 
     | 
    
         
            +
             
     | 
| 
      
 638 
     | 
    
         
            +
            ```javascript
         
     | 
| 
      
 639 
     | 
    
         
            +
            // Save
         
     | 
| 
      
 640 
     | 
    
         
            +
            await squared.copyTo("/path/project", {/* options will be saved */}, "copy-example", true); // Will overwrite and not merge with previously saved settings
         
     | 
| 
      
 641 
     | 
    
         
            +
             
     | 
| 
      
 642 
     | 
    
         
            +
            // Load
         
     | 
| 
      
 643 
     | 
    
         
            +
            await squared.copyTo("/path/project", {/* takes precedence */}, "http://localhost:3000/copy-to/base-config.json"); // Object.assign({ base-config.json }, options)
         
     | 
| 
      
 644 
     | 
    
         
            +
            await squared.copyTo("/path/project", {/* takes precedence */}, "copy-example"); // Object.assign({ copy-example }, options)
         
     | 
| 
      
 645 
     | 
    
         
            +
             
     | 
| 
      
 646 
     | 
    
         
            +
            await squared.copyTo("/path/project", "http://localhost:3000/copy-to/base-config.json"); // options = { base-config.json }
         
     | 
| 
      
 647 
     | 
    
         
            +
            await squared.copyTo("/path/project", "copy-example"); // options = { copy_example }
         
     | 
| 
      
 648 
     | 
    
         
            +
            ```
         
     | 
| 
      
 649 
     | 
    
         
            +
             
     | 
| 
      
 650 
     | 
    
         
            +
            ## Public Properties and Methods
         
     | 
| 
      
 651 
     | 
    
         
            +
             
     | 
| 
      
 652 
     | 
    
         
            +
            - [Read the Docs](https://squared.readthedocs.io/en/latest/methods/squared.html)
         
     | 
| 
      
 653 
     | 
    
         
            +
             
     | 
| 
      
 654 
     | 
    
         
            +
            ```javascript
         
     | 
| 
      
 655 
     | 
    
         
            +
            .settings // See user preferences section
         
     | 
| 
      
 656 
     | 
    
         
            +
             
     | 
| 
      
 657 
     | 
    
         
            +
            setFramework(app: {}, options?: PlainObject, setting?: string, cache?: boolean) // Install application interpreter
         
     | 
| 
      
 658 
     | 
    
         
            +
            setFramework(app: {}, loadName: string, cache?: boolean) // Load settings from local storage
         
     | 
| 
      
 659 
     | 
    
         
            +
             
     | 
| 
      
 660 
     | 
    
         
            +
            // http - hostname(:port)? | https - hostname:443
         
     | 
| 
      
 661 
     | 
    
         
            +
            setHostname(value: string /* http(s)://hostname(:port) */) // Use another cors-enabled server for processing files (--cors <origin>)
         
     | 
| 
      
 662 
     | 
    
         
            +
             
     | 
| 
      
 663 
     | 
    
         
            +
            setEndpoint(name: string, value: string) // Set alternate pathname for API v1 functions (ASSETS_COPY | ASSETS_ARCHIVE | LOADER_DATA | THREADS_KILL | WEBSOCKET_OBSERVE)
         
     | 
| 
      
 664 
     | 
    
         
            +
            setLocalAddress(...values: (string | URL | Location)[]) // Additional hostnames which are interpreted as localhost (e.g. http://127.0.0.1)
         
     | 
| 
      
 665 
     | 
    
         
            +
             
     | 
| 
      
 666 
     | 
    
         
            +
            prefetch(type: "css" | "javascript" | "image" | "svg", all?: boolean, ...targets: unknown[]) // Cross-origin support for CSS
         
     | 
| 
      
 667 
     | 
    
         
            +
             
     | 
| 
      
 668 
     | 
    
         
            +
            parseDocument(...elements: (HTMLElement | string | ElementSettings)[]) // See installation section (Promise)
         
     | 
| 
      
 669 
     | 
    
         
            +
            parseDocumentSync(...elements: (HTMLElement | string | ElementSettings)[]) // Skips preloadImages and preloadFonts (synchronous)
         
     | 
| 
      
 670 
     | 
    
         
            +
             
     | 
| 
      
 671 
     | 
    
         
            +
            latest(count?: number) // Most recent parseDocument session ids (1 newest / -1 oldest: string, other: string[])
         
     | 
| 
      
 672 
     | 
    
         
            +
             
     | 
| 
      
 673 
     | 
    
         
            +
            auth(token: string) // Set JWT authorization token for all requests
         
     | 
| 
      
 674 
     | 
    
         
            +
             
     | 
| 
      
 675 
     | 
    
         
            +
            save(projectId?: string) // Save current session to a new archive using default settings
         
     | 
| 
      
 676 
     | 
    
         
            +
            save(projectId?: string, broadcastId?: string)
         
     | 
| 
      
 677 
     | 
    
         
            +
            save(projectId?: string, timeout?: number)
         
     | 
| 
      
 678 
     | 
    
         
            +
             
     | 
| 
      
 679 
     | 
    
         
            +
            close(projectId?: string) // Close current session
         
     | 
| 
      
 680 
     | 
    
         
            +
            reset(projectId?: string) // Clear cache and reopen new session
         
     | 
| 
      
 681 
     | 
    
         
            +
            clear() // Clear all data stored in memory
         
     | 
| 
      
 682 
     | 
    
         
            +
             
     | 
| 
      
 683 
     | 
    
         
            +
            toString() // Current framework loaded
         
     | 
| 
      
 684 
     | 
    
         
            +
            toString(projectId: string) // await squared.close(projectId) (required)
         
     | 
| 
      
 685 
     | 
    
         
            +
             
     | 
| 
      
 686 
     | 
    
         
            +
            add(...names: (string | Extension | ExtensionRequestObject)[]) // See extension configuration section
         
     | 
| 
      
 687 
     | 
    
         
            +
            remove(...names: (string | Extension)[]) // Remove extensions by namespace or control
         
     | 
| 
      
 688 
     | 
    
         
            +
            get(...names: string[]) // Retrieve extensions by namespace
         
     | 
| 
      
 689 
     | 
    
         
            +
            attr(name: string | Extension, attrName: string, value?: unknown) // Set or get extension options attribute value
         
     | 
| 
      
 690 
     | 
    
         
            +
            apply(name: string | Extension, options: PlainObject, setting?: string) // See extension configuration section
         
     | 
| 
      
 691 
     | 
    
         
            +
             
     | 
| 
      
 692 
     | 
    
         
            +
            extend(functionMap: {}, framework?: /* 0 - ALL | 1 - vdom | 2 - android | 4 - chrome */) // Add extension functions and properties to Node prototype
         
     | 
| 
      
 693 
     | 
    
         
            +
             
     | 
| 
      
 694 
     | 
    
         
            +
            observe(value?: boolean | MutationObserverInit) // Start after DOM and third-party libraries initialization
         
     | 
| 
      
 695 
     | 
    
         
            +
            broadcast(callback: BroadcastMessageCallback, options: FileBroadcastOptions | string) // Redirect stdout messages to DevTools console
         
     | 
| 
      
 696 
     | 
    
         
            +
             
     | 
| 
      
 697 
     | 
    
         
            +
            // Promise (Recommended "cache": createElementMap - true)
         
     | 
| 
      
 698 
     | 
    
         
            +
             
     | 
| 
      
 699 
     | 
    
         
            +
            getElementById(value: string, sync?: boolean, cache?: boolean) // sync - false | cache - true (default)
         
     | 
| 
      
 700 
     | 
    
         
            +
            querySelector(value: string, sync?: boolean, cache?: boolean)
         
     | 
| 
      
 701 
     | 
    
         
            +
            querySelectorAll(value: string, sync?: boolean, cache?: boolean)
         
     | 
| 
      
 702 
     | 
    
         
            +
             
     | 
| 
      
 703 
     | 
    
         
            +
            fromElement(element: HTMLElement | string, sync?: boolean, cache?: boolean) // sync - false | cache - false (default)
         
     | 
| 
      
 704 
     | 
    
         
            +
            fromNode(node: Node, sync?: boolean, cache?: boolean)
         
     | 
| 
      
 705 
     | 
    
         
            +
            findDocumentNode(element: HTMLElement | string /* querySelector | elementId | controlId */, all?: boolean) // Use before saving to modify internal Node attributes
         
     | 
| 
      
 706 
     | 
    
         
            +
             
     | 
| 
      
 707 
     | 
    
         
            +
            observeSrc(element: HTMLElement | string /* querySelector */, callback: WebSocketMessageChange, options?: FileObserveOptions) // Can be used to watch any element with externally hosted files (src/href)
         
     | 
| 
      
 708 
     | 
    
         
            +
            observeSrc(element: HTMLElement | string, options: FileObserveOptions) // Uses location.reload (reload - true)
         
     | 
| 
      
 709 
     | 
    
         
            +
            ```
         
     | 
| 
      
 710 
     | 
    
         
            +
             
     | 
| 
      
 711 
     | 
    
         
            +
            Packaging methods will return a Promise and requires a squared-express installation. These features are not supported when the framework is VDOM.
         
     | 
| 
      
 712 
     | 
    
         
            +
             
     | 
| 
      
 713 
     | 
    
         
            +
            ```javascript
         
     | 
| 
      
 714 
     | 
    
         
            +
            saveAs(filename: string, options?: {}, setting?: string, overwrite?: boolean) // Save current session as a new archive
         
     | 
| 
      
 715 
     | 
    
         
            +
            saveFiles(filename: string, options: {}, setting?: string, overwrite?: boolean) // Create new archive from FileAsset[]
         
     | 
| 
      
 716 
     | 
    
         
            +
             
     | 
| 
      
 717 
     | 
    
         
            +
            // Required (local archives): --disk-read | --unc-read | --access-all (command-line)
         
     | 
| 
      
 718 
     | 
    
         
            +
             
     | 
| 
      
 719 
     | 
    
         
            +
            appendTo(pathname: string, options?: {}, setting?: string, overwrite?: boolean) // Create new archive from a preexisting archive and current session
         
     | 
| 
      
 720 
     | 
    
         
            +
            appendFiles(pathname: string, options: {}, setting?: string, overwrite?: boolean) // Create new archive from a preexisting archive and FileAsset[]
         
     | 
| 
      
 721 
     | 
    
         
            +
             
     | 
| 
      
 722 
     | 
    
         
            +
            // Required (all): --disk-write | --unc-write | --access-all (command-line)
         
     | 
| 
      
 723 
     | 
    
         
            +
             
     | 
| 
      
 724 
     | 
    
         
            +
            copyTo(pathname: string | string[], options?: {}, setting?: string, overwrite?: boolean) // Copy current session to local
         
     | 
| 
      
 725 
     | 
    
         
            +
            copyFiles(pathname: string | string[], options: {}, setting?: string, overwrite?: boolean) // Copy FileAsset[] to local
         
     | 
| 
      
 726 
     | 
    
         
            +
             
     | 
| 
      
 727 
     | 
    
         
            +
            kill(pid: number, timeout?: number) // Use -1 or options.pid (set by system) + seconds
         
     | 
| 
      
 728 
     | 
    
         
            +
            kill(timeout: string)
         
     | 
| 
      
 729 
     | 
    
         
            +
            kill() // Terminate previous request
         
     | 
| 
      
 730 
     | 
    
         
            +
            kill(0) // By username (auth required)
         
     | 
| 
      
 731 
     | 
    
         
            +
            kill(-1, 10) // Terminate previous request in 10 seconds
         
     | 
| 
      
 732 
     | 
    
         
            +
            kill(NaN, 10) // Terminate in 10 seconds (next request) ("timeout" is required)
         
     | 
| 
      
 733 
     | 
    
         
            +
            kill("10s") // Only "s" + "ms" (next request)
         
     | 
| 
      
 734 
     | 
    
         
            +
            ```
         
     | 
| 
      
 735 
     | 
    
         
            +
             
     | 
| 
      
 736 
     | 
    
         
            +
            ## Extending Node object
         
     | 
| 
      
 737 
     | 
    
         
            +
             
     | 
| 
      
 738 
     | 
    
         
            +
            You can add functions and initial variables to the Node object including overwriting preexisting class definitions per framework. Accessor properties are also supported using the *get/set* object syntax.
         
     | 
| 
      
 739 
     | 
    
         
            +
             
     | 
| 
      
 740 
     | 
    
         
            +
            ```javascript
         
     | 
| 
      
 741 
     | 
    
         
            +
            squared.extend({
         
     | 
| 
      
 742 
     | 
    
         
            +
                _id: 1,
         
     | 
| 
      
 743 
     | 
    
         
            +
                altId: {
         
     | 
| 
      
 744 
     | 
    
         
            +
                    get() {
         
     | 
| 
      
 745 
     | 
    
         
            +
                        return this._id;
         
     | 
| 
      
 746 
     | 
    
         
            +
                    },
         
     | 
| 
      
 747 
     | 
    
         
            +
                    set(value) {
         
     | 
| 
      
 748 
     | 
    
         
            +
                        this._id += value;
         
     | 
| 
      
 749 
     | 
    
         
            +
                    }
         
     | 
| 
      
 750 
     | 
    
         
            +
                },
         
     | 
| 
      
 751 
     | 
    
         
            +
                customId: {
         
     | 
| 
      
 752 
     | 
    
         
            +
                    value: 2,
         
     | 
| 
      
 753 
     | 
    
         
            +
                    configurable: false,
         
     | 
| 
      
 754 
     | 
    
         
            +
                    enumerable: false
         
     | 
| 
      
 755 
     | 
    
         
            +
                },
         
     | 
| 
      
 756 
     | 
    
         
            +
                addEvent(eventName, callback) {
         
     | 
| 
      
 757 
     | 
    
         
            +
                    this.element.addEventListener(eventName, callback);
         
     | 
| 
      
 758 
     | 
    
         
            +
                }
         
     | 
| 
      
 759 
     | 
    
         
            +
            });
         
     | 
| 
      
 760 
     | 
    
         
            +
            squared.setFramework(vdom);
         
     | 
| 
      
 761 
     | 
    
         
            +
             
     | 
| 
      
 762 
     | 
    
         
            +
            const body = await squared.fromElement(document.body);
         
     | 
| 
      
 763 
     | 
    
         
            +
            body.altId = 2; // body.altId: 3
         
     | 
| 
      
 764 
     | 
    
         
            +
            body.addEvent("click", function (ev) {
         
     | 
| 
      
 765 
     | 
    
         
            +
                this.classList.toggle("example");
         
     | 
| 
      
 766 
     | 
    
         
            +
            });
         
     | 
| 
      
 767 
     | 
    
         
            +
            ```
         
     | 
| 
      
 768 
     | 
    
         
            +
             
     | 
| 
      
 769 
     | 
    
         
            +
            ## Forwarding Request
         
     | 
| 
      
 770 
     | 
    
         
            +
             
     | 
| 
      
 771 
     | 
    
         
            +
            Using another identical remote server to build the project when performing a `saveAs` or `copyTo` request can be achieved by changing only the origin address.
         
     | 
| 
      
 772 
     | 
    
         
            +
             
     | 
| 
      
 773 
     | 
    
         
            +
            ```javascript
         
     | 
| 
      
 774 
     | 
    
         
            +
            squared.setHostname("http://hostname:8000");
         
     | 
| 
      
 775 
     | 
    
         
            +
            // OR
         
     | 
| 
      
 776 
     | 
    
         
            +
            squared.setHostname(); // Reset to window.location (e.g. localhost:3000)
         
     | 
| 
      
 777 
     | 
    
         
            +
             
     | 
| 
      
 778 
     | 
    
         
            +
            await squared.saveAs("chrome.zip"); // Current browser
         
     | 
| 
      
 779 
     | 
    
         
            +
            // OR
         
     | 
| 
      
 780 
     | 
    
         
            +
            await squared.copyTo("/path/project"); // Remote server
         
     | 
| 
      
 781 
     | 
    
         
            +
            ```
         
     | 
| 
      
 782 
     | 
    
         
            +
             
     | 
| 
      
 783 
     | 
    
         
            +
            ## Broadcasting
         
     | 
| 
      
 784 
     | 
    
         
            +
             
     | 
| 
      
 785 
     | 
    
         
            +
            Console messages (stdout) can be sent to the browser console instead through DevTools.
         
     | 
| 
      
 786 
     | 
    
         
            +
             
     | 
| 
      
 787 
     | 
    
         
            +
            ```javascript
         
     | 
| 
      
 788 
     | 
    
         
            +
            squared.broadcast(result => { console.log(result.value); }, "111-111-111"); // System messages from squared-express
         
     | 
| 
      
 789 
     | 
    
         
            +
            squared.broadcast(result => { console.log(result.value); }, "222-222-222"); // Messages from "project-1" project
         
     | 
| 
      
 790 
     | 
    
         
            +
            squared.broadcast(result => { console.log(result.value); }, { socketId: "333-333-333", socketKey: "socket_id" }); // Messages sent from another channel (default is "socketId")
         
     | 
| 
      
 791 
     | 
    
         
            +
             
     | 
| 
      
 792 
     | 
    
         
            +
            await squared.copyTo("/path/project/project-1", {
         
     | 
| 
      
 793 
     | 
    
         
            +
                projectId: "project-1",
         
     | 
| 
      
 794 
     | 
    
         
            +
                log: { useColor: true }, // Chromium
         
     | 
| 
      
 795 
     | 
    
         
            +
                broadcastId: "222-222-222" // Specific use alias for "socketId"
         
     | 
| 
      
 796 
     | 
    
         
            +
            });
         
     | 
| 
      
 797 
     | 
    
         
            +
            ```
         
     | 
| 
      
 798 
     | 
    
         
            +
             
     | 
| 
      
 799 
     | 
    
         
            +
            ## Extension Configuration
         
     | 
| 
      
 800 
     | 
    
         
            +
             
     | 
| 
      
 801 
     | 
    
         
            +
            Layout rendering can be customized using extensions as the program was built to be nearly completely modular. Some of the common layouts already have built-in extensions which you can load or unload based on your preference.
         
     | 
| 
      
 802 
     | 
    
         
            +
             
     | 
| 
      
 803 
     | 
    
         
            +
            ```typescript
         
     | 
| 
      
 804 
     | 
    
         
            +
            // Create an extension
         
     | 
| 
      
 805 
     | 
    
         
            +
            class Sample extends squared.base.Extension {
         
     | 
| 
      
 806 
     | 
    
         
            +
                options = {
         
     | 
| 
      
 807 
     | 
    
         
            +
                    attributeName: [];
         
     | 
| 
      
 808 
     | 
    
         
            +
                };
         
     | 
| 
      
 809 
     | 
    
         
            +
             
     | 
| 
      
 810 
     | 
    
         
            +
                constructor(name, framework = 0, options = {}) { // 0 - ALL | 1 - vdom | 2 - android | 4 - chrome (framework)
         
     | 
| 
      
 811 
     | 
    
         
            +
                    super(name, framework, options);
         
     | 
| 
      
 812 
     | 
    
         
            +
                }
         
     | 
| 
      
 813 
     | 
    
         
            +
             
     | 
| 
      
 814 
     | 
    
         
            +
                processNode(node: NodeUI) {
         
     | 
| 
      
 815 
     | 
    
         
            +
                    const data = this.project.get(node.element, node.localSettings.projectId);
         
     | 
| 
      
 816 
     | 
    
         
            +
                    if (data) {
         
     | 
| 
      
 817 
     | 
    
         
            +
                        node.each((child, index) => child.element.title = data[index]);
         
     | 
| 
      
 818 
     | 
    
         
            +
                    }
         
     | 
| 
       206 
819 
     | 
    
         
             
                }
         
     | 
| 
       207 
     | 
    
         
            -
             
     | 
| 
       208 
     | 
    
         
            -
             
     | 
| 
       209 
     | 
    
         
            -
             
     | 
| 
       210 
     | 
    
         
            -
             
     | 
| 
       211 
     | 
    
         
            -
             
     | 
| 
       212 
     | 
    
         
            -
             
     | 
| 
      
 820 
     | 
    
         
            +
            }
         
     | 
| 
      
 821 
     | 
    
         
            +
             
     | 
| 
      
 822 
     | 
    
         
            +
            // Install an extension
         
     | 
| 
      
 823 
     | 
    
         
            +
            const sample = new Sample("widget.example.com", 0, {/* Same as configure */});
         
     | 
| 
      
 824 
     | 
    
         
            +
            squared.add(sample);
         
     | 
| 
      
 825 
     | 
    
         
            +
            // OR
         
     | 
| 
      
 826 
     | 
    
         
            +
            squared.add([sample, {/* config */}]);
         
     | 
| 
      
 827 
     | 
    
         
            +
             
     | 
| 
      
 828 
     | 
    
         
            +
            // Configure an extension
         
     | 
| 
      
 829 
     | 
    
         
            +
            squared.attr("widget.example.com", "attributeName", ["width", "height"]); // typeof is enforced and will only set existing attributes
         
     | 
| 
      
 830 
     | 
    
         
            +
             
     | 
| 
      
 831 
     | 
    
         
            +
            // Add project data
         
     | 
| 
      
 832 
     | 
    
         
            +
            const ext = squared.get("widget.example.com");
         
     | 
| 
      
 833 
     | 
    
         
            +
             
     | 
| 
      
 834 
     | 
    
         
            +
            ext.project.set(element, await fetch(url?id=1)); // Map interface with optional "projectId" argument
         
     | 
| 
      
 835 
     | 
    
         
            +
            ext.project.set(element, await fetch(url?id=2), "project-1");
         
     | 
| 
      
 836 
     | 
    
         
            +
             
     | 
| 
      
 837 
     | 
    
         
            +
            const data = ext.project.get(element, "project-2"); // Returns data from default project (id=1)
         
     | 
| 
      
 838 
     | 
    
         
            +
            ```
         
     | 
| 
      
 839 
     | 
    
         
            +
             
     | 
| 
      
 840 
     | 
    
         
            +
            Some extensions have a few settings which can be configured. The default settings usually achieve the best overall rendering accuracy without noticeably affecting performance.
         
     | 
| 
      
 841 
     | 
    
         
            +
             
     | 
| 
      
 842 
     | 
    
         
            +
            ## ANDROID
         
     | 
| 
      
 843 
     | 
    
         
            +
             
     | 
| 
      
 844 
     | 
    
         
            +
            ### Public Methods
         
     | 
| 
      
 845 
     | 
    
         
            +
             
     | 
| 
      
 846 
     | 
    
         
            +
            - [Read the Docs](https://squared.readthedocs.io/en/latest/methods/android.html)
         
     | 
| 
      
 847 
     | 
    
         
            +
             
     | 
| 
      
 848 
     | 
    
         
            +
            ```javascript
         
     | 
| 
      
 849 
     | 
    
         
            +
            android.setViewModel(data: {}, sessionId?: string) // Object data for layout bindings
         
     | 
| 
      
 850 
     | 
    
         
            +
            android.setViewModelByProject(data: {}, projectId?: string)
         
     | 
| 
      
 851 
     | 
    
         
            +
            android.removeObserver(element: HTMLElement) // Disconnect an observed element from "parseDocument"
         
     | 
| 
      
 852 
     | 
    
         
            +
            android.addXmlNs(name: string, uri: string) // Add global namespaces for third-party controls
         
     | 
| 
      
 853 
     | 
    
         
            +
            android.addDependency(group: string, name: string, version?: string, type?: number) // Add application dependency implementation (build.gradle)
         
     | 
| 
      
 854 
     | 
    
         
            +
            android.addDependencyByProject(projectId: string, group: string, name: string, version?: string, type?: number) // DEPENDENCY_TYPE: 0 - implementation 1 - api 2 - compileOnly 3 - compileOnlyApi 4 - runtimeOnly 5 - testImplementation 8 - androidTestImplementation
         
     | 
| 
      
 855 
     | 
    
         
            +
            android.customize(build: number, tagNameOrWidget: string, options: {}) // Global attributes applied to specific views
         
     | 
| 
      
 856 
     | 
    
         
            +
            android.loadCustomizations(name: string) // Load customizations from Local Storage
         
     | 
| 
      
 857 
     | 
    
         
            +
            android.saveCustomizations(name: string) // Save "customize" data into Local Storage (includes xmlns)
         
     | 
| 
      
 858 
     | 
    
         
            +
            android.resetCustomizations() // All session customizations are deleted
         
     | 
| 
      
 859 
     | 
    
         
            +
            android.addFontProvider(authority: string, package: string, certs: string[], webFonts: string | {}) // Add additional Web fonts (Google Fonts already included)
         
     | 
| 
      
 860 
     | 
    
         
            +
            android.setResolutionByDeviceName(value: string) // Settings prefixed with "resolution" (e.g. Pixel C)
         
     | 
| 
      
 861 
     | 
    
         
            +
            android.getLocalSettings() // Modify controller styles and parsing rules
         
     | 
| 
      
 862 
     | 
    
         
            +
            ```
         
     | 
| 
      
 863 
     | 
    
         
            +
             
     | 
| 
      
 864 
     | 
    
         
            +
            ```javascript
         
     | 
| 
      
 865 
     | 
    
         
            +
            // NOTE: squared.settings.targetAPI is always parsed (Except: customizationsBaseAPI = -1)
         
     | 
| 
      
 866 
     | 
    
         
            +
             
     | 
| 
      
 867 
     | 
    
         
            +
            android.customize(android.lib.constant.BUILD_VERSION.ALL /* 0 */, "Button", {
         
     | 
| 
      
 868 
     | 
    
         
            +
                android: {
         
     | 
| 
      
 869 
     | 
    
         
            +
                    minWidth: "35px",
         
     | 
| 
      
 870 
     | 
    
         
            +
                    minHeight: "25px"
         
     | 
| 
       213 
871 
     | 
    
         
             
                },
         
     | 
| 
       214 
     | 
    
         
            -
                 
     | 
| 
       215 
     | 
    
         
            -
             
     | 
| 
       216 
     | 
    
         
            -
                 
     | 
| 
       217 
     | 
    
         
            -
             
     | 
| 
       218 
     | 
    
         
            -
             
     | 
| 
      
 872 
     | 
    
         
            +
                "_": { // Non-namespaced attributes
         
     | 
| 
      
 873 
     | 
    
         
            +
                    style: "@style/Widget.Material3.Button.TextButton"
         
     | 
| 
      
 874 
     | 
    
         
            +
                }
         
     | 
| 
      
 875 
     | 
    
         
            +
            });
         
     | 
| 
      
 876 
     | 
    
         
            +
             
     | 
| 
      
 877 
     | 
    
         
            +
            android.customize(android.lib.constant.BUILD_VERSION.KITKAT /* 19 */, "svg", {
         
     | 
| 
      
 878 
     | 
    
         
            +
                android: {
         
     | 
| 
      
 879 
     | 
    
         
            +
                    "[src]": "app:srcCompat" // Change namespace to "app"
         
     | 
| 
       219 
880 
     | 
    
         
             
                }
         
     | 
| 
       220 
     | 
    
         
            -
             
     | 
| 
       221 
     | 
    
         
            -
             
     | 
| 
       222 
     | 
    
         
            -
             
     | 
| 
       223 
     | 
    
         
            -
             
     | 
| 
       224 
     | 
    
         
            -
             
     | 
| 
       225 
     | 
    
         
            -
             
     | 
| 
       226 
     | 
    
         
            -
              .with(:python) do                                             # rake clone:python
         
     | 
| 
       227 
     | 
    
         
            -
                add("android-docs")
         
     | 
| 
       228 
     | 
    
         
            -
                add("chrome-docs") do
         
     | 
| 
       229 
     | 
    
         
            -
                  revbuild(include: "source/", exclude: ["source/conf.py"]) # Limit files being watched
         
     | 
| 
       230 
     | 
    
         
            -
                end
         
     | 
| 
       231 
     | 
    
         
            -
              end
         
     | 
| 
       232 
     | 
    
         
            -
              .git("https://github.com/anpham6", ["emc", "pir"])            # Targets any defined project
         
     | 
| 
       233 
     | 
    
         
            -
              .git("https://github.com/anpham6", cache: true)               # Uses already defined root projects + revbuild
         
     | 
| 
       234 
     | 
    
         
            -
              .revbuild                                                     # Enables task revbuild (squared.revb)
         
     | 
| 
       235 
     | 
    
         
            -
              .revbuild(file: "../build.json")                              # $ROOT/build.json
         
     | 
| 
       236 
     | 
    
         
            -
              .build(parallel: ["clone"])                                   # rake clone + rake clone:sync
         
     | 
| 
       237 
     | 
    
         
            -
            ```
         
     | 
| 
       238 
     | 
    
         
            -
             
     | 
| 
       239 
     | 
    
         
            -
            ### Build
         
     | 
| 
       240 
     | 
    
         
            -
             
     | 
| 
       241 
     | 
    
         
            -
            #### Chain
         
     | 
| 
       242 
     | 
    
         
            -
             
     | 
| 
       243 
     | 
    
         
            -
            There has to be at least one project which uses the ``step`` attribute. Other placement attributes are ignored.
         
     | 
| 
       244 
     | 
    
         
            -
             
     | 
| 
       245 
     | 
    
         
            -
            **NOTE**: Projects can only reference non-global namespaced tasks. (e.g. with ":")
         
     | 
| 
       246 
     | 
    
         
            -
             
     | 
| 
       247 
     | 
    
         
            -
            ```ruby
         
     | 
| 
       248 
     | 
    
         
            -
            Workspace::Application
         
     | 
| 
       249 
     | 
    
         
            -
              .new
         
     | 
| 
       250 
     | 
    
         
            -
              .with(:node) do
         
     | 
| 
       251 
     | 
    
         
            -
                add("e-mc", "emc") do
         
     | 
| 
       252 
     | 
    
         
            -
                  chain "all", "clean", step: 1                                        # Required
         
     | 
| 
       253 
     | 
    
         
            -
                  chain "all", "build", step: 2
         
     | 
| 
       254 
     | 
    
         
            -
                end
         
     | 
| 
       255 
     | 
    
         
            -
                add("pi-r", "pir") do
         
     | 
| 
       256 
     | 
    
         
            -
                  chain "all", "build", after: "emc:build"                             # step: 3
         
     | 
| 
       257 
     | 
    
         
            -
                end
         
     | 
| 
       258 
     | 
    
         
            -
                add("pi-r2", "pir2") do
         
     | 
| 
       259 
     | 
    
         
            -
                  chain "all", "build", before: "squared"                              # step: 3
         
     | 
| 
       260 
     | 
    
         
            -
                end
         
     | 
| 
       261 
     | 
    
         
            -
                add("squared-express", "express") do
         
     | 
| 
       262 
     | 
    
         
            -
                  chain "all", "clean", with: "emc"                                    # step: 1
         
     | 
| 
       263 
     | 
    
         
            -
                  chain "all", "build", with: "pir"                                    # step: 3
         
     | 
| 
       264 
     | 
    
         
            -
                end
         
     | 
| 
       265 
     | 
    
         
            -
                add("squared") do
         
     | 
| 
       266 
     | 
    
         
            -
                  revbuild(include: %w[src/ framework/ types/])                        # Git revision build command (optional)
         
     | 
| 
       267 
     | 
    
         
            -
                  chain "all", "revbuild", after: "express:build"                      # step: 4
         
     | 
| 
       268 
     | 
    
         
            -
                  chain "publish", "bump:patch", "publish:latest", step: 0, sync: true # rake publish -> squared:bump:patch -> squared:publish:latest
         
     | 
| 
       269 
     | 
    
         
            -
                end
         
     | 
| 
       270 
     | 
    
         
            -
              end
         
     | 
| 
       271 
     | 
    
         
            -
              .with(:python) do
         
     | 
| 
       272 
     | 
    
         
            -
                doc("make html")
         
     | 
| 
       273 
     | 
    
         
            -
                add("android-docs") do
         
     | 
| 
       274 
     | 
    
         
            -
                  chain "all", "doc", with: "squared", after: "squared"                # step: 4
         
     | 
| 
       275 
     | 
    
         
            -
                end
         
     | 
| 
       276 
     | 
    
         
            -
                add("chrome-docs") do
         
     | 
| 
       277 
     | 
    
         
            -
                  chain "all", "doc", with: "squared", before: "squared:revbuild"      # Same
         
     | 
| 
       278 
     | 
    
         
            -
                end
         
     | 
| 
       279 
     | 
    
         
            -
              end
         
     | 
| 
       280 
     | 
    
         
            -
              .chain "all", "status", with: "squared", after: "android-docs"           # Global tasks (e.g. without ":")
         
     | 
| 
       281 
     | 
    
         
            -
              .build
         
     | 
| 
      
 881 
     | 
    
         
            +
            });
         
     | 
| 
      
 882 
     | 
    
         
            +
             
     | 
| 
      
 883 
     | 
    
         
            +
            // Local Storage
         
     | 
| 
      
 884 
     | 
    
         
            +
            android.saveCustomizations("customize-example"); // Save at least once in one layout
         
     | 
| 
      
 885 
     | 
    
         
            +
             
     | 
| 
      
 886 
     | 
    
         
            +
            android.loadCustomizations("customize-example"); // Load in any other layout
         
     | 
| 
       282 
887 
     | 
    
         
             
            ```
         
     | 
| 
       283 
888 
     | 
    
         | 
| 
       284 
     | 
    
         
            -
            ``` 
     | 
| 
       285 
     | 
    
         
            -
             
     | 
| 
       286 
     | 
    
         
            -
             
     | 
| 
       287 
     | 
    
         
            -
             
     | 
| 
       288 
     | 
    
         
            -
             
     | 
| 
       289 
     | 
    
         
            -
             
     | 
| 
       290 
     | 
    
         
            -
             
     | 
| 
       291 
     | 
    
         
            -
             
     | 
| 
       292 
     | 
    
         
            -
             
     | 
| 
       293 
     | 
    
         
            -
            * Step 3: pir:build + express:build + pir2:build (thread)
         
     | 
| 
       294 
     | 
    
         
            -
            * Step 4: chrome-docs:doc + squared:revbuild + android-docs:doc + status (sync)
         
     | 
| 
       295 
     | 
    
         
            -
             
     | 
| 
       296 
     | 
    
         
            -
            #### Graph
         
     | 
| 
       297 
     | 
    
         
            -
             
     | 
| 
       298 
     | 
    
         
            -
            ```ruby
         
     | 
| 
       299 
     | 
    
         
            -
            Workspace::Application
         
     | 
| 
       300 
     | 
    
         
            -
              .new(main: "squared")
         
     | 
| 
       301 
     | 
    
         
            -
              .graph(["depend"], ref: :git)                                                # Optional
         
     | 
| 
       302 
     | 
    
         
            -
              .with(:python) do
         
     | 
| 
       303 
     | 
    
         
            -
                doc(windows? ? ".\make.bat html" : "make html")                            # rake android-docs:doc | rake doc:python
         
     | 
| 
       304 
     | 
    
         
            -
                add("android-docs", "android", venv: "/home/user/.venv")                   # rake android-docs:depend
         
     | 
| 
       305 
     | 
    
         
            -
                add("chrome-docs", "chrome", graph: "android", venv: %w[.venv --clear]) do # /workspaces/chrome-docs/.venv
         
     | 
| 
       306 
     | 
    
         
            -
                  apply :dependindex, 1                                                    # Use Poetry for dependencies (optional)
         
     | 
| 
       307 
     | 
    
         
            -
                end
         
     | 
| 
       308 
     | 
    
         
            -
              end
         
     | 
| 
       309 
     | 
    
         
            -
              .with(:node) do
         
     | 
| 
       310 
     | 
    
         
            -
                graph(["build", "copy"], on: {                                             # Overrides "git"
         
     | 
| 
       311 
     | 
    
         
            -
                  first: proc { puts "1" },
         
     | 
| 
       312 
     | 
    
         
            -
                  last: proc { puts "2" }
         
     | 
| 
       313 
     | 
    
         
            -
                })
         
     | 
| 
       314 
     | 
    
         
            -
                script("build:dev")                                                        # npm run build:dev
         
     | 
| 
       315 
     | 
    
         
            -
                # OR
         
     | 
| 
       316 
     | 
    
         
            -
                run([nil, "build:dev", { "PATH" => "~/.bin" }, "--workspace", "--silent"]) # PATH="~/.bin" npm run build:dev --workspace -- --silent
         
     | 
| 
       317 
     | 
    
         
            -
                # OR
         
     | 
| 
       318 
     | 
    
         
            -
                run({                                                                      # Same
         
     | 
| 
       319 
     | 
    
         
            -
                  script: "build:dev",                                                     #
         
     | 
| 
       320 
     | 
    
         
            -
                  env: { "PATH" => "~/.bin" },                                             #
         
     | 
| 
       321 
     | 
    
         
            -
                  opts: "--workspace",                                                     #
         
     | 
| 
       322 
     | 
    
         
            -
                  args: "--silent"                                                         #
         
     | 
| 
       323 
     | 
    
         
            -
                })
         
     | 
| 
       324 
     | 
    
         
            -
             
     | 
| 
       325 
     | 
    
         
            -
                add("e-mc", "emc") do
         
     | 
| 
       326 
     | 
    
         
            -
                  first("build", "emc:clean", "emc:depend")                                # rake emc:clean && rake emc:depend && rake emc:build && echo "123"
         
     | 
| 
       327 
     | 
    
         
            -
                  last("build", out: "123") { |out: nil| puts out }                        #
         
     | 
| 
       328 
     | 
    
         
            -
                  error("build") { |err: nil| log.debug err }                              #
         
     | 
| 
       329 
     | 
    
         
            -
                end
         
     | 
| 
       330 
     | 
    
         
            -
                add("pi-r", "pir", graph: "emc", first: {
         
     | 
| 
       331 
     | 
    
         
            -
                  build: proc { puts self.name }                                           # puts "pir"
         
     | 
| 
       332 
     | 
    
         
            -
                })
         
     | 
| 
       333 
     | 
    
         
            -
                add("squared-express", "express", graph: "pir")
         
     | 
| 
       334 
     | 
    
         
            -
                add("squared", graph: ["chrome", "express"]) do
         
     | 
| 
       335 
     | 
    
         
            -
                  first("git:ls-files") { puts "1" }                                       # skipped
         
     | 
| 
       336 
     | 
    
         
            -
                  first("git:ls-files", override: true) { puts "2" }                       # puts "2"
         
     | 
| 
       337 
     | 
    
         
            -
                  last("git:ls-files") { puts workspace.root }                             # puts "/workspaces"
         
     | 
| 
       338 
     | 
    
         
            -
                end
         
     | 
| 
       339 
     | 
    
         
            -
              end
         
     | 
| 
       340 
     | 
    
         
            -
              .with(:ruby) do
         
     | 
| 
       341 
     | 
    
         
            -
                run("gem build")                                                           # gem build
         
     | 
| 
       342 
     | 
    
         
            -
                # OR
         
     | 
| 
       343 
     | 
    
         
            -
                run("gem build", on: { first: -> { p "2" }, last: -> { p "4" } }) do       # run | depend | graph | clean | doc | lint | test
         
     | 
| 
       344 
     | 
    
         
            -
                  p "1"
         
     | 
| 
       345 
     | 
    
         
            -
                end
         
     | 
| 
       346 
     | 
    
         
            -
                # OR
         
     | 
| 
       347 
     | 
    
         
            -
                run(on: { first: -> { p "pass" }, last: -> { p "pass" } }) do
         
     | 
| 
       348 
     | 
    
         
            -
                  p "1"
         
     | 
| 
       349 
     | 
    
         
            -
                end
         
     | 
| 
       350 
     | 
    
         
            -
                # OR
         
     | 
| 
       351 
     | 
    
         
            -
                run(["gem build", "--force", { "RUBY_VERSION" => "3.4.0" }])               # RUBY_VERSION="3.4.0" gem build --force
         
     | 
| 
       352 
     | 
    
         
            -
                # OR
         
     | 
| 
       353 
     | 
    
         
            -
                run({                                                                      #
         
     | 
| 
       354 
     | 
    
         
            -
                  command: "gem build",                                                    # RUBY_VERSION="3.4.0" gem build --silent --force
         
     | 
| 
       355 
     | 
    
         
            -
                  opts: "--force",                                                         # composable
         
     | 
| 
       356 
     | 
    
         
            -
                  env: { "PATH" => "~/.bin" },                                             #
         
     | 
| 
       357 
     | 
    
         
            -
                  args: { silent: true }                                                   #
         
     | 
| 
       358 
     | 
    
         
            -
                })
         
     | 
| 
       359 
     | 
    
         
            -
                # OR
         
     | 
| 
       360 
     | 
    
         
            -
                run(["gem pristine", ["gem build", "gem cleanup"], nil, "--debug"])        # gem pristine --debug && gem build --debug && gem cleanup --debug
         
     | 
| 
       361 
     | 
    
         
            -
                #
         
     | 
| 
       362 
     | 
    
         
            -
                # All commands are either Array or Hash
         
     | 
| 
       363 
     | 
    
         
            -
                #
         
     | 
| 
       364 
     | 
    
         
            -
                run([                                                                      # PATH="~/.bin" GEM_HOME="~/.gems/ruby-3.4.0" (merged)
         
     | 
| 
       365 
     | 
    
         
            -
                  ["gem pristine", "--all", { "PATH" => "~/.bin" }, "--silent"],           # gem pristine --silent --all
         
     | 
| 
       366 
     | 
    
         
            -
                  ["gem build", { strict: true }, { "GEM_HOME" => "~/.gems/ruby-3.4.0" }]  # gem build --strict
         
     | 
| 
       367 
     | 
    
         
            -
                ])                                                                         #
         
     | 
| 
       368 
     | 
    
         
            -
                # OR
         
     | 
| 
       369 
     | 
    
         
            -
                run([                                                                      # Same
         
     | 
| 
       370 
     | 
    
         
            -
                  {                                                                        #
         
     | 
| 
       371 
     | 
    
         
            -
                    env: { "PATH" => "~/.bin" },                                           #
         
     | 
| 
       372 
     | 
    
         
            -
                    command: "gem pristine",                                               #
         
     | 
| 
       373 
     | 
    
         
            -
                    opts: "--all", args: "--silent"                                        #
         
     | 
| 
       374 
     | 
    
         
            -
                  },                                                                       #
         
     | 
| 
       375 
     | 
    
         
            -
                  {                                                                        #
         
     | 
| 
       376 
     | 
    
         
            -
                    env: { "GEM_HOME" => "~/.gems/ruby-3.4.0" },                           #
         
     | 
| 
       377 
     | 
    
         
            -
                    command: "gem build",                                                  #
         
     | 
| 
       378 
     | 
    
         
            -
                    opts: { strict: true }                                                 #
         
     | 
| 
       379 
     | 
    
         
            -
                  }                                                                        #
         
     | 
| 
       380 
     | 
    
         
            -
                ])
         
     | 
| 
       381 
     | 
    
         
            -
             
     | 
| 
       382 
     | 
    
         
            -
                add("pathname", test: ["rake test", { jobs: ENV["RAKE_JOBS"] }])           # rake test --jobs 4
         
     | 
| 
       383 
     | 
    
         
            -
                add("fileutils", graph: "pathname")
         
     | 
| 
       384 
     | 
    
         
            -
                add("optparse", run: "gem build", env: { "PATH" => "~/.bin" }, opts: "-v") # PATH="~/.bin" gem build -v
         
     | 
| 
       385 
     | 
    
         
            -
                add("rake", graph: ["fileutils", "optparse"])
         
     | 
| 
       386 
     | 
    
         
            -
                banner(command: false)                                                     # Always hide banner
         
     | 
| 
       387 
     | 
    
         
            -
              end
         
     | 
| 
       388 
     | 
    
         
            -
              .build
         
     | 
| 
      
 889 
     | 
    
         
            +
            ```javascript
         
     | 
| 
      
 890 
     | 
    
         
            +
            android.addXmlNs("tools", "http://schemas.android.com/tools");
         
     | 
| 
      
 891 
     | 
    
         
            +
             
     | 
| 
      
 892 
     | 
    
         
            +
            android.customize(16 /* Jelly Bean */, "ImageView", {
         
     | 
| 
      
 893 
     | 
    
         
            +
                tools: {
         
     | 
| 
      
 894 
     | 
    
         
            +
                    ignore: "ContentDescription",
         
     | 
| 
      
 895 
     | 
    
         
            +
                    targetApi: "16"
         
     | 
| 
      
 896 
     | 
    
         
            +
                }
         
     | 
| 
      
 897 
     | 
    
         
            +
            });
         
     | 
| 
       389 
898 
     | 
    
         
             
            ```
         
     | 
| 
       390 
899 
     | 
    
         | 
| 
       391 
     | 
    
         
            -
             
     | 
| 
       392 
     | 
    
         
            -
             
     | 
| 
       393 
     | 
    
         
            -
             
     | 
| 
       394 
     | 
    
         
            -
            rake chrome:graph   # android + chrome
         
     | 
| 
       395 
     | 
    
         
            -
            rake graph:python   # same
         
     | 
| 
       396 
     | 
    
         
            -
            rake squared:graph  # android + chrome + emc + pir + express + squared
         
     | 
| 
       397 
     | 
    
         
            -
            rake graph:node     # same
         
     | 
| 
       398 
     | 
    
         
            -
            rake rake:graph     # pathname + fileutils + optparse + rake
         
     | 
| 
       399 
     | 
    
         
            -
            rake graph:ruby     # same
         
     | 
| 
       400 
     | 
    
         
            -
            rake graph          # graph:node + graph:ruby
         
     | 
| 
      
 900 
     | 
    
         
            +
            ### Static Methods
         
     | 
| 
      
 901 
     | 
    
         
            +
             
     | 
| 
      
 902 
     | 
    
         
            +
            Project resources can include additional values that are required during compilation. TypeScript definitions are available in the `types/android` directory.
         
     | 
| 
       401 
903 
     | 
    
         | 
| 
       402 
     | 
    
         
            -
             
     | 
| 
       403 
     | 
    
         
            -
             
     | 
| 
      
 904 
     | 
    
         
            +
            ```javascript
         
     | 
| 
      
 905 
     | 
    
         
            +
            squared.parseDocument().then(node => {
         
     | 
| 
      
 906 
     | 
    
         
            +
                const resourceId = node.localSettings.resourceId;
         
     | 
| 
      
 907 
     | 
    
         
            +
                android.base.Resource.addString(resourceId, value, /* name */);
         
     | 
| 
      
 908 
     | 
    
         
            +
                android.base.Resource.addArray(resourceId, name, items);
         
     | 
| 
      
 909 
     | 
    
         
            +
                android.base.Resource.addColor(resourceId, color);
         
     | 
| 
      
 910 
     | 
    
         
            +
                android.base.Resource.addDimen(resourceId, name, value);
         
     | 
| 
      
 911 
     | 
    
         
            +
                android.base.Resource.addTheme(resourceId, theme);
         
     | 
| 
      
 912 
     | 
    
         
            +
                squared.save();
         
     | 
| 
      
 913 
     | 
    
         
            +
            });
         
     | 
| 
       404 
914 
     | 
    
         
             
            ```
         
     | 
| 
       405 
915 
     | 
    
         | 
| 
       406 
     | 
    
         
            -
            ###  
     | 
| 
      
 916 
     | 
    
         
            +
            ### Data Binding
         
     | 
| 
      
 917 
     | 
    
         
            +
             
     | 
| 
      
 918 
     | 
    
         
            +
            View model data can be applied to most HTML elements using the dataset attribute. Different view models can be used for every `parseDocument` session.
         
     | 
| 
      
 919 
     | 
    
         
            +
             
     | 
| 
      
 920 
     | 
    
         
            +
            Leaving the `sessionId` empty uses the default view model which is searched last for all projects when attempting a bind.
         
     | 
| 
      
 921 
     | 
    
         
            +
             
     | 
| 
      
 922 
     | 
    
         
            +
            ```javascript
         
     | 
| 
      
 923 
     | 
    
         
            +
            // NOTE: latest(undefined = 1): string (1: most recent sessionId | -1: first sessionId)
         
     | 
| 
      
 924 
     | 
    
         
            +
             
     | 
| 
      
 925 
     | 
    
         
            +
            squared.parseDocument("id-1", "id-2", "id-3").then(nodes => {
         
     | 
| 
      
 926 
     | 
    
         
            +
                const sessions = squared.latest(2); // ["00001", "00002", "00003"] => ["00002", "00003"]
         
     | 
| 
      
 927 
     | 
    
         
            +
                android.setViewModel(
         
     | 
| 
      
 928 
     | 
    
         
            +
                    {
         
     | 
| 
      
 929 
     | 
    
         
            +
                        import: ["java.util.Map", "java.util.List"],
         
     | 
| 
      
 930 
     | 
    
         
            +
                        variable: [
         
     | 
| 
      
 931 
     | 
    
         
            +
                            { name: "user", type: "com.example.User" },
         
     | 
| 
      
 932 
     | 
    
         
            +
                            { name: "list", type: "List<String>" },
         
     | 
| 
      
 933 
     | 
    
         
            +
                            { name: "map", type: "Map<String, String>" },
         
     | 
| 
      
 934 
     | 
    
         
            +
                            { name: "index", type: "int" },
         
     | 
| 
      
 935 
     | 
    
         
            +
                            { name: "key", type: "String" }
         
     | 
| 
      
 936 
     | 
    
         
            +
                        ]
         
     | 
| 
      
 937 
     | 
    
         
            +
                    },
         
     | 
| 
      
 938 
     | 
    
         
            +
                    sessions[0] // nodes[1].sessionId
         
     | 
| 
      
 939 
     | 
    
         
            +
                );
         
     | 
| 
      
 940 
     | 
    
         
            +
                android.setViewModel(
         
     | 
| 
      
 941 
     | 
    
         
            +
                    {
         
     | 
| 
      
 942 
     | 
    
         
            +
                        import: ["java.util.Map"],
         
     | 
| 
      
 943 
     | 
    
         
            +
                        variable: [
         
     | 
| 
      
 944 
     | 
    
         
            +
                            { name: "map", type: "Map<String, String>" }
         
     | 
| 
      
 945 
     | 
    
         
            +
                        ]
         
     | 
| 
      
 946 
     | 
    
         
            +
                    },
         
     | 
| 
      
 947 
     | 
    
         
            +
                    sessions[1] // nodes[2].sessionId
         
     | 
| 
      
 948 
     | 
    
         
            +
                );
         
     | 
| 
      
 949 
     | 
    
         
            +
            });
         
     | 
| 
      
 950 
     | 
    
         
            +
             
     | 
| 
      
 951 
     | 
    
         
            +
            squared.parseDocument({
         
     | 
| 
      
 952 
     | 
    
         
            +
                element: "main",
         
     | 
| 
      
 953 
     | 
    
         
            +
                enabledViewModel: true,
         
     | 
| 
      
 954 
     | 
    
         
            +
                dataBindableElements: [
         
     | 
| 
      
 955 
     | 
    
         
            +
                    {
         
     | 
| 
      
 956 
     | 
    
         
            +
                        selector: "#first_name",
         
     | 
| 
      
 957 
     | 
    
         
            +
                        namespace: "android", // "android" is default
         
     | 
| 
      
 958 
     | 
    
         
            +
                        attr: "text",
         
     | 
| 
      
 959 
     | 
    
         
            +
                        expression: "user.firstName"
         
     | 
| 
      
 960 
     | 
    
         
            +
                    },
         
     | 
| 
      
 961 
     | 
    
         
            +
                    {
         
     | 
| 
      
 962 
     | 
    
         
            +
                        selector: "#last_name",
         
     | 
| 
      
 963 
     | 
    
         
            +
                        attr: "text",
         
     | 
| 
      
 964 
     | 
    
         
            +
                        expression: "user.lastName"
         
     | 
| 
      
 965 
     | 
    
         
            +
                    },
         
     | 
| 
      
 966 
     | 
    
         
            +
                    {
         
     | 
| 
      
 967 
     | 
    
         
            +
                        selector: "#remember_me",
         
     | 
| 
      
 968 
     | 
    
         
            +
                        attr: "checked",
         
     | 
| 
      
 969 
     | 
    
         
            +
                        expression: "user.rememberMe",
         
     | 
| 
      
 970 
     | 
    
         
            +
                        twoWay: true
         
     | 
| 
      
 971 
     | 
    
         
            +
                    }
         
     | 
| 
      
 972 
     | 
    
         
            +
                ],
         
     | 
| 
      
 973 
     | 
    
         
            +
                data: {
         
     | 
| 
      
 974 
     | 
    
         
            +
                    viewModel: {
         
     | 
| 
      
 975 
     | 
    
         
            +
                        import: ["java.util.Map"],
         
     | 
| 
      
 976 
     | 
    
         
            +
                        variable: [
         
     | 
| 
      
 977 
     | 
    
         
            +
                            { name: "map", type: "Map<String, String>" }
         
     | 
| 
      
 978 
     | 
    
         
            +
                        ]
         
     | 
| 
      
 979 
     | 
    
         
            +
                    }
         
     | 
| 
      
 980 
     | 
    
         
            +
                }
         
     | 
| 
      
 981 
     | 
    
         
            +
            });
         
     | 
| 
      
 982 
     | 
    
         
            +
             
     | 
| 
      
 983 
     | 
    
         
            +
            squared.save();
         
     | 
| 
      
 984 
     | 
    
         
            +
            ```
         
     | 
| 
       407 
985 
     | 
    
         | 
| 
       408 
     | 
    
         
            -
             
     | 
| 
       409 
     | 
    
         
            -
            Workspace::Series.batch(:ruby, :node, {
         
     | 
| 
       410 
     | 
    
         
            -
              stage: %i[graph test],
         
     | 
| 
       411 
     | 
    
         
            -
              reset: %i[stash pull]
         
     | 
| 
       412 
     | 
    
         
            -
            })
         
     | 
| 
      
 986 
     | 
    
         
            +
            Inlining is also supported and might be more convenient for simple layouts. JavaScript is recommended when you are calling `parseDocument` multiple times.
         
     | 
| 
       413 
987 
     | 
    
         | 
| 
       414 
     | 
    
         
            -
             
     | 
| 
      
 988 
     | 
    
         
            +
            ```
         
     | 
| 
      
 989 
     | 
    
         
            +
            data-viewmodel-{namespace}-{attribute} -> data-viewmodel-android-text
         
     | 
| 
       415 
990 
     | 
    
         
             
            ```
         
     | 
| 
       416 
991 
     | 
    
         | 
| 
       417 
     | 
    
         
            -
             
     | 
| 
      
 992 
     | 
    
         
            +
            These two additional output parameters are required when using the "**data-viewmodel**" prefix.
         
     | 
| 
       418 
993 
     | 
    
         | 
| 
       419 
     | 
    
         
            -
            ``` 
     | 
| 
       420 
     | 
    
         
            -
             
     | 
| 
       421 
     | 
    
         
            -
             
     | 
| 
      
 994 
     | 
    
         
            +
            ```html
         
     | 
| 
      
 995 
     | 
    
         
            +
            <div id="main">
         
     | 
| 
      
 996 
     | 
    
         
            +
                <label>Name:</label>
         
     | 
| 
      
 997 
     | 
    
         
            +
                <input id="first_name" type="text" data-viewmodel-android-text="user.firstName" />
         
     | 
| 
      
 998 
     | 
    
         
            +
                <input id="last_name" type="text" data-viewmodel-android-text="user.lastName" />
         
     | 
| 
      
 999 
     | 
    
         
            +
                <input id="remember_me" type="checkbox" data-viewmodel-android-checked="=user.rememberMe" /> <!-- "=" for two-way binding -->
         
     | 
| 
      
 1000 
     | 
    
         
            +
            </div>
         
     | 
| 
      
 1001 
     | 
    
         
            +
            ```
         
     | 
| 
       422 
1002 
     | 
    
         | 
| 
       423 
     | 
    
         
            -
             
     | 
| 
       424 
     | 
    
         
            -
             
     | 
| 
       425 
     | 
    
         
            -
             
     | 
| 
       426 
     | 
    
         
            -
             
     | 
| 
       427 
     | 
    
         
            -
             
     | 
| 
       428 
     | 
    
         
            -
             
     | 
| 
      
 1003 
     | 
    
         
            +
            ```xml
         
     | 
| 
      
 1004 
     | 
    
         
            +
            <layout>
         
     | 
| 
      
 1005 
     | 
    
         
            +
                <data>
         
     | 
| 
      
 1006 
     | 
    
         
            +
                    <import type="java.util.Map" />
         
     | 
| 
      
 1007 
     | 
    
         
            +
                    <import type="java.util.List" />
         
     | 
| 
      
 1008 
     | 
    
         
            +
                    <variable name="user" type="com.example.User" />
         
     | 
| 
      
 1009 
     | 
    
         
            +
                    <variable name="list" type="List<String>" />
         
     | 
| 
      
 1010 
     | 
    
         
            +
                    <variable name="map" type="Map<String, String>" />
         
     | 
| 
      
 1011 
     | 
    
         
            +
                    <variable name="index" type="int" />
         
     | 
| 
      
 1012 
     | 
    
         
            +
                    <variable name="key" type="String" />
         
     | 
| 
      
 1013 
     | 
    
         
            +
                </data>
         
     | 
| 
      
 1014 
     | 
    
         
            +
                <LinearLayout android:id="@+id/main">
         
     | 
| 
      
 1015 
     | 
    
         
            +
                    <TextView android:text="Name:" />
         
     | 
| 
      
 1016 
     | 
    
         
            +
                    <EditText
         
     | 
| 
      
 1017 
     | 
    
         
            +
                        android:id="@+id/first_name"
         
     | 
| 
      
 1018 
     | 
    
         
            +
                        android:inputType="text"
         
     | 
| 
      
 1019 
     | 
    
         
            +
                        android:text="@{user.firstName}" />
         
     | 
| 
      
 1020 
     | 
    
         
            +
                    <EditText
         
     | 
| 
      
 1021 
     | 
    
         
            +
                        android:id="@+id/last_name"
         
     | 
| 
      
 1022 
     | 
    
         
            +
                        android:inputType="text"
         
     | 
| 
      
 1023 
     | 
    
         
            +
                        android:text="@{user.lastName}" />
         
     | 
| 
      
 1024 
     | 
    
         
            +
                    <CheckBox
         
     | 
| 
      
 1025 
     | 
    
         
            +
                        android:id="@+id/remember_me"
         
     | 
| 
      
 1026 
     | 
    
         
            +
                        android:checked="@={user.rememberMe}" />
         
     | 
| 
      
 1027 
     | 
    
         
            +
                </LinearLayout>
         
     | 
| 
      
 1028 
     | 
    
         
            +
            </layout>
         
     | 
| 
      
 1029 
     | 
    
         
            +
            ```
         
     | 
| 
       429 
1030 
     | 
    
         | 
| 
       430 
     | 
    
         
            -
             
     | 
| 
       431 
     | 
    
         
            -
            rake doc              # optparse + android
         
     | 
| 
       432 
     | 
    
         
            -
            rake depend           # All except "default"
         
     | 
| 
      
 1031 
     | 
    
         
            +
            ### Layout Includes / Merge Tag
         
     | 
| 
       433 
1032 
     | 
    
         | 
| 
       434 
     | 
    
         
            -
             
     | 
| 
      
 1033 
     | 
    
         
            +
            Some applications can benefit from using includes or merge tags to share common templates. Nested includes is supported.
         
     | 
| 
       435 
1034 
     | 
    
         | 
| 
       436 
     | 
    
         
            -
             
     | 
| 
       437 
     | 
    
         
            -
             
     | 
| 
       438 
     | 
    
         
            -
             
     | 
| 
       439 
     | 
    
         
            -
             
     | 
| 
       440 
     | 
    
         
            -
             
     | 
| 
      
 1035 
     | 
    
         
            +
            ```html
         
     | 
| 
      
 1036 
     | 
    
         
            +
            <div>
         
     | 
| 
      
 1037 
     | 
    
         
            +
                <div id="item1">Item 1</div>
         
     | 
| 
      
 1038 
     | 
    
         
            +
                <div id="item2" data-android-include-start="true" data-android-include-merge="true" data-pathname-android="app/src/main/res/layout-land" data-filename-android="filename1.xml">Item 2</div>
         
     | 
| 
      
 1039 
     | 
    
         
            +
                <div id="item3">Item 3</div>
         
     | 
| 
      
 1040 
     | 
    
         
            +
                <div id="item4" data-android-include-end="true">Item 4</div>
         
     | 
| 
      
 1041 
     | 
    
         
            +
                <div id="item5" data-android-include="filename2" data-android-include-end="true" data-android-include-viewmodel="exampleData">Item 5</div> <!-- viewModel -->
         
     | 
| 
      
 1042 
     | 
    
         
            +
            </div>
         
     | 
| 
      
 1043 
     | 
    
         
            +
            ```
         
     | 
| 
       441 
1044 
     | 
    
         | 
| 
       442 
     | 
    
         
            -
             
     | 
| 
       443 
     | 
    
         
            -
             
     | 
| 
      
 1045 
     | 
    
         
            +
            ```javascript
         
     | 
| 
      
 1046 
     | 
    
         
            +
            android.setViewModelByProject({ variable: [{ name: "exampleData", type: "com.example.ExampleData" }] }, "project-1"); // Default is "_"
         
     | 
| 
      
 1047 
     | 
    
         
            +
             
     | 
| 
      
 1048 
     | 
    
         
            +
            squared.parseDocument({
         
     | 
| 
      
 1049 
     | 
    
         
            +
                element: document.body,
         
     | 
| 
      
 1050 
     | 
    
         
            +
                projectId: "project-1", // Affects all layouts in same project
         
     | 
| 
      
 1051 
     | 
    
         
            +
                enabledIncludes: true,
         
     | 
| 
      
 1052 
     | 
    
         
            +
                includableElements: [
         
     | 
| 
      
 1053 
     | 
    
         
            +
                    {
         
     | 
| 
      
 1054 
     | 
    
         
            +
                        selectorStart: "#item2",
         
     | 
| 
      
 1055 
     | 
    
         
            +
                        selectorEnd: "#item4",
         
     | 
| 
      
 1056 
     | 
    
         
            +
                        pathname: "app/src/main/res/layout-land",
         
     | 
| 
      
 1057 
     | 
    
         
            +
                        filename: "filename1.xml",
         
     | 
| 
      
 1058 
     | 
    
         
            +
                        merge: true // Multiple elements will auto-merge
         
     | 
| 
      
 1059 
     | 
    
         
            +
                    },
         
     | 
| 
      
 1060 
     | 
    
         
            +
                    {
         
     | 
| 
      
 1061 
     | 
    
         
            +
                        selectorStart: "#item5",
         
     | 
| 
      
 1062 
     | 
    
         
            +
                        selectorEnd: "#item5",
         
     | 
| 
      
 1063 
     | 
    
         
            +
                        filename: "filename2",
         
     | 
| 
      
 1064 
     | 
    
         
            +
                        viewModel: "exampleData" // One element only (merge=false)
         
     | 
| 
      
 1065 
     | 
    
         
            +
                    }
         
     | 
| 
      
 1066 
     | 
    
         
            +
                ]
         
     | 
| 
      
 1067 
     | 
    
         
            +
            });
         
     | 
| 
      
 1068 
     | 
    
         
            +
            ```
         
     | 
| 
      
 1069 
     | 
    
         
            +
            > [!NOTE]
         
     | 
| 
      
 1070 
     | 
    
         
            +
            > By sessionId has precedence when associating a view model.
         
     | 
| 
      
 1071 
     | 
    
         
            +
             
     | 
| 
      
 1072 
     | 
    
         
            +
            ```xml
         
     | 
| 
      
 1073 
     | 
    
         
            +
            <LinearLayout>
         
     | 
| 
      
 1074 
     | 
    
         
            +
                <TextView>Item 1</TextView>
         
     | 
| 
      
 1075 
     | 
    
         
            +
                <include layout="@layout/filename1" />
         
     | 
| 
      
 1076 
     | 
    
         
            +
                <include layout="@layout/filename2" app:exampleData="@{exampleData}" />
         
     | 
| 
      
 1077 
     | 
    
         
            +
            </LinearLayout>
         
     | 
| 
      
 1078 
     | 
    
         
            +
            <!-- res/layout/activity_main.xml -->
         
     | 
| 
      
 1079 
     | 
    
         
            +
             
     | 
| 
      
 1080 
     | 
    
         
            +
            <merge>
         
     | 
| 
      
 1081 
     | 
    
         
            +
                <TextView>Item 2</TextView>
         
     | 
| 
      
 1082 
     | 
    
         
            +
                <TextView>Item 3</TextView>
         
     | 
| 
      
 1083 
     | 
    
         
            +
                <TextView>Item 4</TextView>
         
     | 
| 
      
 1084 
     | 
    
         
            +
            </merge>
         
     | 
| 
      
 1085 
     | 
    
         
            +
            <!-- res/layout-land/filename1.xml -->
         
     | 
| 
      
 1086 
     | 
    
         
            +
             
     | 
| 
      
 1087 
     | 
    
         
            +
            <layout>
         
     | 
| 
      
 1088 
     | 
    
         
            +
                <data>
         
     | 
| 
      
 1089 
     | 
    
         
            +
                    <variable name="exampleData" type="com.example.ExampleData" />
         
     | 
| 
      
 1090 
     | 
    
         
            +
                </data>
         
     | 
| 
      
 1091 
     | 
    
         
            +
                <TextView>Item 5</TextView>
         
     | 
| 
      
 1092 
     | 
    
         
            +
            </layout>
         
     | 
| 
      
 1093 
     | 
    
         
            +
            <!-- res/layout/filename2.xml -->
         
     | 
| 
       444 
1094 
     | 
    
         
             
            ```
         
     | 
| 
       445 
1095 
     | 
    
         | 
| 
       446 
     | 
    
         
            -
             
     | 
| 
       447 
     | 
    
         
            -
            rake build:app                   # squared + cli + sqd-serve
         
     | 
| 
       448 
     | 
    
         
            -
            rake squared:build:workspace     # cli + sqd-serve
         
     | 
| 
       449 
     | 
    
         
            -
            rake pull:sqd                    # sqd-admin
         
     | 
| 
       450 
     | 
    
         
            -
            rake squared:pull:workspace      # sqd-serve + sqd-admin
         
     | 
| 
       451 
     | 
    
         
            -
            rake squared:outdated:workspace  # cli + sqd-serve + sqd-admin
         
     | 
| 
       452 
     | 
    
         
            -
            ```
         
     | 
| 
       453 
     | 
    
         
            -
             
     | 
| 
       454 
     | 
    
         
            -
            ## Methods
         
     | 
| 
       455 
     | 
    
         
            -
             
     | 
| 
       456 
     | 
    
         
            -
            Task:
         
     | 
| 
       457 
     | 
    
         
            -
             
     | 
| 
       458 
     | 
    
         
            -
            * run
         
     | 
| 
       459 
     | 
    
         
            -
            * script
         
     | 
| 
       460 
     | 
    
         
            -
            * depend
         
     | 
| 
       461 
     | 
    
         
            -
            * archive
         
     | 
| 
       462 
     | 
    
         
            -
            * graph
         
     | 
| 
       463 
     | 
    
         
            -
            * doc
         
     | 
| 
       464 
     | 
    
         
            -
            * lint
         
     | 
| 
       465 
     | 
    
         
            -
            * test
         
     | 
| 
       466 
     | 
    
         
            -
            * clean
         
     | 
| 
       467 
     | 
    
         
            -
             
     | 
| 
       468 
     | 
    
         
            -
            Non-task:
         
     | 
| 
       469 
     | 
    
         
            -
             
     | 
| 
       470 
     | 
    
         
            -
            * log
         
     | 
| 
       471 
     | 
    
         
            -
            * exclude
         
     | 
| 
       472 
     | 
    
         
            -
             
     | 
| 
       473 
     | 
    
         
            -
            ## Styles
         
     | 
| 
       474 
     | 
    
         
            -
             
     | 
| 
       475 
     | 
    
         
            -
            * banner
         
     | 
| 
       476 
     | 
    
         
            -
            * border
         
     | 
| 
       477 
     | 
    
         
            -
            * header
         
     | 
| 
       478 
     | 
    
         
            -
            * active
         
     | 
| 
       479 
     | 
    
         
            -
            * inline
         
     | 
| 
       480 
     | 
    
         
            -
            * subject
         
     | 
| 
       481 
     | 
    
         
            -
            * border
         
     | 
| 
       482 
     | 
    
         
            -
            * warn
         
     | 
| 
       483 
     | 
    
         
            -
            * caution
         
     | 
| 
       484 
     | 
    
         
            -
            * current
         
     | 
| 
       485 
     | 
    
         
            -
            * latest
         
     | 
| 
       486 
     | 
    
         
            -
            * extra
         
     | 
| 
       487 
     | 
    
         
            -
            * major
         
     | 
| 
       488 
     | 
    
         
            -
            * red
         
     | 
| 
       489 
     | 
    
         
            -
            * yellow
         
     | 
| 
       490 
     | 
    
         
            -
            * green
         
     | 
| 
       491 
     | 
    
         
            -
             
     | 
| 
       492 
     | 
    
         
            -
            ## Git
         
     | 
| 
       493 
     | 
    
         
            -
             
     | 
| 
       494 
     | 
    
         
            -
            Most project classes will inherit from `Git` which enables these tasks:
         
     | 
| 
       495 
     | 
    
         
            -
             
     | 
| 
       496 
     | 
    
         
            -
            | Task       | Git              |  Command                                      |
         
     | 
| 
       497 
     | 
    
         
            -
            | :--------- | :--------------- | :-------------------------------------------- |
         
     | 
| 
       498 
     | 
    
         
            -
            | branch     | branch           | create track delete move copy list current    |
         
     | 
| 
       499 
     | 
    
         
            -
            | checkout   | checkout         | commit branch track detach path               |
         
     | 
| 
       500 
     | 
    
         
            -
            | commit     | commit           | add all amend amend-orig fixup                |
         
     | 
| 
       501 
     | 
    
         
            -
            | diff       | diff             | head branch files view between contain        |
         
     | 
| 
       502 
     | 
    
         
            -
            | fetch      | fetch            | origin remote all                             |
         
     | 
| 
       503 
     | 
    
         
            -
            | files      | ls-files         | cached modified deleted others                |
         
     | 
| 
       504 
     | 
    
         
            -
            | git        |                  | add blame clean mv revert rm status           |
         
     | 
| 
       505 
     | 
    
         
            -
            | log        | log              | view between contain                          |
         
     | 
| 
       506 
     | 
    
         
            -
            | merge      | merge            | commit no-commit send                         |
         
     | 
| 
       507 
     | 
    
         
            -
            | pull       | pull             | origin remote all                             |
         
     | 
| 
       508 
     | 
    
         
            -
            | rebase     | rebase           | branch onto send                              |
         
     | 
| 
       509 
     | 
    
         
            -
            | refs       | ls-remote --refs | heads tags remote                             |
         
     | 
| 
       510 
     | 
    
         
            -
            | reset      | reset            | commit index patch mode undo                  |
         
     | 
| 
       511 
     | 
    
         
            -
            | restore    | restore          | source staged worktree                        |
         
     | 
| 
       512 
     | 
    
         
            -
            | rev        | rev              | commit build output                           |
         
     | 
| 
       513 
     | 
    
         
            -
            | show       | show             | format oneline textconv                       |
         
     | 
| 
       514 
     | 
    
         
            -
            | stash      | stash            | push pop apply branch drop clear list         |
         
     | 
| 
       515 
     | 
    
         
            -
            | submodule  | submodule        | status update branch url sync                 |
         
     | 
| 
       516 
     | 
    
         
            -
            | switch     | switch           | branch create detach                          |
         
     | 
| 
       517 
     | 
    
         
            -
            | tag        | tag              | add sign delete list                          |
         
     | 
| 
       518 
     | 
    
         
            -
             
     | 
| 
       519 
     | 
    
         
            -
            You can disable all of them at once using the `exclude` property.
         
     | 
| 
       520 
     | 
    
         
            -
             
     | 
| 
       521 
     | 
    
         
            -
            ```ruby
         
     | 
| 
       522 
     | 
    
         
            -
            Workspace::Application.exclude('autostash', 'rebase')
         
     | 
| 
       523 
     | 
    
         
            -
             
     | 
| 
       524 
     | 
    
         
            -
            Workspace::Application
         
     | 
| 
       525 
     | 
    
         
            -
              .new
         
     | 
| 
       526 
     | 
    
         
            -
              .add("squared", exclude: :git)
         
     | 
| 
       527 
     | 
    
         
            -
            ```
         
     | 
| 
       528 
     | 
    
         
            -
             
     | 
| 
       529 
     | 
    
         
            -
            You can disable one or more of them using the `pass` property as a *string*.
         
     | 
| 
       530 
     | 
    
         
            -
             
     | 
| 
       531 
     | 
    
         
            -
            ```ruby
         
     | 
| 
       532 
     | 
    
         
            -
            Workspace::Application
         
     | 
| 
       533 
     | 
    
         
            -
              .new
         
     | 
| 
       534 
     | 
    
         
            -
              .add("squared", pass: ["pull"], ref: :node)
         
     | 
| 
       535 
     | 
    
         
            -
              .pass("pull", ref: :node) { read_packagemanager(:private) }
         
     | 
| 
       536 
     | 
    
         
            -
            ```
         
     | 
| 
       537 
     | 
    
         
            -
             
     | 
| 
       538 
     | 
    
         
            -
            ### Commit Hash
         
     | 
| 
       539 
     | 
    
         
            -
             
     | 
| 
       540 
     | 
    
         
            -
            Commands which use commit hashes are parsed using a ":" prefix as to not be confused for an option.
         
     | 
| 
      
 1096 
     | 
    
         
            +
            The attributes "**data-android-include-start**" and "**data-android-include-end**" can only be applied to elements which share the same parent container. See `/demos/gradient.html` for usage instructions.
         
     | 
| 
       541 
1097 
     | 
    
         | 
| 
       542 
     | 
    
         
            -
             
     | 
| 
       543 
     | 
    
         
            -
             
     | 
| 
       544 
     | 
    
         
            -
             
     | 
| 
       545 
     | 
    
         
            -
             
     | 
| 
      
 1098 
     | 
    
         
            +
            > [!TIP]
         
     | 
| 
      
 1099 
     | 
    
         
            +
            > "**data-pathname-android**" AND "**data-filename-android**" can also be used with any `parseDocument` base element.
         
     | 
| 
      
 1100 
     | 
    
         
            +
             
     | 
| 
      
 1101 
     | 
    
         
            +
            ### Redirecting Output Location
         
     | 
| 
      
 1102 
     | 
    
         
            +
             
     | 
| 
      
 1103 
     | 
    
         
            +
            Sometimes it is necessary to extract elements and append them into other containers for it to look identical on the Android device. Redirection will fail if the *target location* is not a block/container element.
         
     | 
| 
      
 1104 
     | 
    
         
            +
             
     | 
| 
      
 1105 
     | 
    
         
            +
            ```html
         
     | 
| 
      
 1106 
     | 
    
         
            +
            <div>
         
     | 
| 
      
 1107 
     | 
    
         
            +
                <span>Item 1</span>
         
     | 
| 
      
 1108 
     | 
    
         
            +
                <span data-android-target="location">Item 2</span>
         
     | 
| 
      
 1109 
     | 
    
         
            +
                <span data-android-target="location" data-android-target-index="1">Item 3</span>
         
     | 
| 
      
 1110 
     | 
    
         
            +
            <div>
         
     | 
| 
      
 1111 
     | 
    
         
            +
            <ul id="location">
         
     | 
| 
      
 1112 
     | 
    
         
            +
                <li>Item 4</li>
         
     | 
| 
      
 1113 
     | 
    
         
            +
                <li>Item 5</li>
         
     | 
| 
      
 1114 
     | 
    
         
            +
                <!-- span -->
         
     | 
| 
      
 1115 
     | 
    
         
            +
            </ul>
         
     | 
| 
      
 1116 
     | 
    
         
            +
            ```
         
     | 
| 
      
 1117 
     | 
    
         
            +
             
     | 
| 
      
 1118 
     | 
    
         
            +
            ```xml
         
     | 
| 
      
 1119 
     | 
    
         
            +
            <LinearLayout>
         
     | 
| 
      
 1120 
     | 
    
         
            +
                <TextView>Item 1</TextView>
         
     | 
| 
      
 1121 
     | 
    
         
            +
            </LinearLayout>
         
     | 
| 
      
 1122 
     | 
    
         
            +
            <LinearLayout>
         
     | 
| 
      
 1123 
     | 
    
         
            +
                <TextView>Item 4</TextView>
         
     | 
| 
      
 1124 
     | 
    
         
            +
                <TextView>Item 3</TextView>
         
     | 
| 
      
 1125 
     | 
    
         
            +
                <TextView>Item 5</TextView>
         
     | 
| 
      
 1126 
     | 
    
         
            +
                <TextView>Item 2</TextView>
         
     | 
| 
      
 1127 
     | 
    
         
            +
            </LinearLayout>
         
     | 
| 
       546 
1128 
     | 
    
         
             
            ```
         
     | 
| 
       547 
1129 
     | 
    
         | 
| 
       548 
     | 
    
         
            -
             
     | 
| 
      
 1130 
     | 
    
         
            +
            Using `target` into a ConstraintLayout or RelativeLayout container will not include automatic positioning.
         
     | 
| 
      
 1131 
     | 
    
         
            +
             
     | 
| 
      
 1132 
     | 
    
         
            +
            ### Custom Attributes
         
     | 
| 
       549 
1133 
     | 
    
         | 
| 
       550 
     | 
    
         
            -
             
     | 
| 
      
 1134 
     | 
    
         
            +
            System or extension generated attributes can be overridden preceding finalization. They will only be visible on the declared framework.
         
     | 
| 
       551 
1135 
     | 
    
         | 
| 
       552 
     | 
    
         
            -
             
     | 
| 
      
 1136 
     | 
    
         
            +
            ```
         
     | 
| 
      
 1137 
     | 
    
         
            +
            data-android-attr-{namespace}? -> Default is "android"
         
     | 
| 
      
 1138 
     | 
    
         
            +
            ```
         
     | 
| 
       553 
1139 
     | 
    
         | 
| 
       554 
     | 
    
         
            -
            ``` 
     | 
| 
       555 
     | 
    
         
            -
             
     | 
| 
       556 
     | 
    
         
            -
             
     | 
| 
       557 
     | 
    
         
            -
             
     | 
| 
       558 
     | 
    
         
            -
             
     | 
| 
       559 
     | 
    
         
            -
              GEM: "~/.rvm/gems/ruby-3.4.0/bin/gem",
         
     | 
| 
       560 
     | 
    
         
            -
              BUNDLE: "~/.rvm/gems/ruby-3.4.0/bin/bundle",
         
     | 
| 
       561 
     | 
    
         
            -
              RAKE: "~/.rvm/gems/ruby-3.4.0/bin/rake",
         
     | 
| 
       562 
     | 
    
         
            -
              NPM: "/opt/node/v22.0.0/bin/npm",
         
     | 
| 
       563 
     | 
    
         
            -
              PYTHON: "#{ENV["PYTHONPATH"]}/bin/python"
         
     | 
| 
       564 
     | 
    
         
            -
            })
         
     | 
| 
      
 1140 
     | 
    
         
            +
            ```html
         
     | 
| 
      
 1141 
     | 
    
         
            +
            <div id="customId"
         
     | 
| 
      
 1142 
     | 
    
         
            +
                data-android-attr="layout_width::match_parent;layout_height::match_parent"
         
     | 
| 
      
 1143 
     | 
    
         
            +
                data-android-attr-app="layout_scrollFlags::scroll|exitUntilCollapsed">
         
     | 
| 
      
 1144 
     | 
    
         
            +
            </div>
         
     | 
| 
       565 
1145 
     | 
    
         
             
            ```
         
     | 
| 
       566 
1146 
     | 
    
         | 
| 
       567 
     | 
    
         
            -
             
     | 
| 
      
 1147 
     | 
    
         
            +
            ```xml
         
     | 
| 
      
 1148 
     | 
    
         
            +
            <LinearLayout
         
     | 
| 
      
 1149 
     | 
    
         
            +
                android:id="@+id/customId"
         
     | 
| 
      
 1150 
     | 
    
         
            +
                android:layout_width="match_parent"
         
     | 
| 
      
 1151 
     | 
    
         
            +
                android:layout_height="match_parent"
         
     | 
| 
      
 1152 
     | 
    
         
            +
                app:layout_scrollFlags="scroll|exitUntilCollapsed" />
         
     | 
| 
      
 1153 
     | 
    
         
            +
            ```
         
     | 
| 
       568 
1154 
     | 
    
         | 
| 
       569 
     | 
    
         
            -
            ``` 
     | 
| 
       570 
     | 
    
         
            -
             
     | 
| 
       571 
     | 
    
         
            -
             
     | 
| 
       572 
     | 
    
         
            -
             
     | 
| 
      
 1155 
     | 
    
         
            +
            ```javascript
         
     | 
| 
      
 1156 
     | 
    
         
            +
            const node = squared.findDocumentNode("customId"); // querySelector is supported
         
     | 
| 
      
 1157 
     | 
    
         
            +
            node.android("layout_width", "match_parent");
         
     | 
| 
      
 1158 
     | 
    
         
            +
            node.android("layout_height", "match_parent");
         
     | 
| 
      
 1159 
     | 
    
         
            +
            node.app("layout_scrollFlags", "scroll|exitUntilCollapsed");
         
     | 
| 
       573 
1160 
     | 
    
         
             
            ```
         
     | 
| 
       574 
1161 
     | 
    
         | 
| 
       575 
     | 
    
         
            -
             
     | 
| 
       576 
     | 
    
         
            -
            BUILD_TYPE                   # global
         
     | 
| 
       577 
     | 
    
         
            -
            ${PROG}_COLOR=0              # --no-color (e.g. GIT_COLOR)
         
     | 
| 
      
 1162 
     | 
    
         
            +
            ### SVG animations
         
     | 
| 
       578 
1163 
     | 
    
         | 
| 
       579 
     | 
    
         
            -
             
     | 
| 
       580 
     | 
    
         
            -
            # LD_LIBRARY_PATH="path/to/lib" CFLAGS="-Wall" gcc a.c -o a.o       -g    -O2
         
     | 
| 
       581 
     | 
    
         
            -
            BUILD_${NAME}                # gcc a.c -o a.o
         
     | 
| 
       582 
     | 
    
         
            -
            BUILD_${NAME}_OPTS           # -g
         
     | 
| 
       583 
     | 
    
         
            -
            BUILD_${NAME}_ENV            # {"LD_LIBRARY_PATH":"path/to/lib","CFLAGS":"-Wall"} (hash/json)
         
     | 
| 
       584 
     | 
    
         
            -
            BUILD_${NAME}_TYPE           # debug
         
     | 
| 
      
 1164 
     | 
    
         
            +
            Only the XML based layout and resource files can be viewed on the Android device/emulator without any Java/Kotlin backend code. To play animations in the emulator you also have to `start` the animation in *MainActivity.java*.
         
     | 
| 
       585 
1165 
     | 
    
         | 
| 
       586 
     | 
    
         
            -
             
     | 
| 
       587 
     | 
    
         
            -
             
     | 
| 
       588 
     | 
    
         
            -
            BUILD_${NAME}                # build:dev
         
     | 
| 
       589 
     | 
    
         
            -
            BUILD_${NAME}_OPTS           # --loglevel=error --workspaces=false
         
     | 
| 
       590 
     | 
    
         
            -
            BUILD_${NAME}_ENV            # {"NODE_ENV":"production","NO_COLOR":"1"} (hash/json)
         
     | 
| 
       591 
     | 
    
         
            -
            BUILD_${NAME}_DEV            # pattern,0,1 (:dev)
         
     | 
| 
       592 
     | 
    
         
            -
            BUILD_${NAME}_PROD           # pattern,0,1 (:prod)
         
     | 
| 
       593 
     | 
    
         
            -
            ${REF}_${NAME}_OPTS          # --quiet (e.g. NODE_SQUARED_OPTS)
         
     | 
| 
      
 1166 
     | 
    
         
            +
            ```java
         
     | 
| 
      
 1167 
     | 
    
         
            +
            import android.graphics.drawable.Animatable;
         
     | 
| 
       594 
1168 
     | 
    
         | 
| 
       595 
     | 
    
         
            -
             
     | 
| 
       596 
     | 
    
         
            -
             
     | 
| 
      
 1169 
     | 
    
         
            +
            android.widget.ImageView imageView1 = findViewById(R.id.imageview_1);
         
     | 
| 
      
 1170 
     | 
    
         
            +
            if (imageView1 != null) {
         
     | 
| 
      
 1171 
     | 
    
         
            +
                Animatable animatable = (Animatable) imageView1.getDrawable();
         
     | 
| 
      
 1172 
     | 
    
         
            +
                animatable.start();
         
     | 
| 
      
 1173 
     | 
    
         
            +
            }
         
     | 
| 
      
 1174 
     | 
    
         
            +
            ```
         
     | 
| 
       597 
1175 
     | 
    
         | 
| 
       598 
     | 
    
         
            -
             
     | 
| 
       599 
     | 
    
         
            -
            BANNER_${NAME}=0             #
         
     | 
| 
      
 1176 
     | 
    
         
            +
            ### Jetpack Compose
         
     | 
| 
       600 
1177 
     | 
    
         | 
| 
       601 
     | 
    
         
            -
             
     | 
| 
       602 
     | 
    
         
            -
            VERBOSE_${NAME}=0            # 0,1,2,n
         
     | 
| 
      
 1178 
     | 
    
         
            +
            Most mobile applications do not have a deeply nested hierarchy and are generally better to implement using declarative programming.
         
     | 
| 
       603 
1179 
     | 
    
         | 
| 
       604 
     | 
    
         
            -
             
     | 
| 
       605 
     | 
    
         
            -
             
     | 
| 
      
 1180 
     | 
    
         
            +
            ```javascript
         
     | 
| 
      
 1181 
     | 
    
         
            +
            squared.settings.composableElements = ["main", "#content", "--boxShadow", "--height=300px", {
         
     | 
| 
      
 1182 
     | 
    
         
            +
                selector: "main",
         
     | 
| 
      
 1183 
     | 
    
         
            +
                android: {
         
     | 
| 
      
 1184 
     | 
    
         
            +
                    layout_height: "match_parent"
         
     | 
| 
      
 1185 
     | 
    
         
            +
                },
         
     | 
| 
      
 1186 
     | 
    
         
            +
                tools: {
         
     | 
| 
      
 1187 
     | 
    
         
            +
                    composableName: "com.example.compose.Preview"
         
     | 
| 
      
 1188 
     | 
    
         
            +
                }
         
     | 
| 
      
 1189 
     | 
    
         
            +
            }];
         
     | 
| 
      
 1190 
     | 
    
         
            +
            squared.settings.createBuildDependencies = true; // Optional
         
     | 
| 
      
 1191 
     | 
    
         
            +
            ```
         
     | 
| 
       606 
1192 
     | 
    
         | 
| 
       607 
     | 
    
         
            -
             
     | 
| 
       608 
     | 
    
         
            -
             
     | 
| 
      
 1193 
     | 
    
         
            +
            You can also do it using the "**android.substitute**" extension directly inside the HTML element.
         
     | 
| 
      
 1194 
     | 
    
         
            +
             
     | 
| 
      
 1195 
     | 
    
         
            +
            ```javascript
         
     | 
| 
      
 1196 
     | 
    
         
            +
            // android.substitute is only used here to demonstrate using extensions
         
     | 
| 
      
 1197 
     | 
    
         
            +
             
     | 
| 
      
 1198 
     | 
    
         
            +
            squared.add(["android.substitute", {
         
     | 
| 
      
 1199 
     | 
    
         
            +
                element: {
         
     | 
| 
      
 1200 
     | 
    
         
            +
                    content: { android: { layout_width: "match_parent" } }
         
     | 
| 
      
 1201 
     | 
    
         
            +
                }
         
     | 
| 
      
 1202 
     | 
    
         
            +
            }]);
         
     | 
| 
      
 1203 
     | 
    
         
            +
             
     | 
| 
      
 1204 
     | 
    
         
            +
            const items = squared.attr("android.substitute", "viewAttributes");
         
     | 
| 
      
 1205 
     | 
    
         
            +
            items.push("hint", "buttonTint");
         
     | 
| 
      
 1206 
     | 
    
         
            +
            /* OR */
         
     | 
| 
      
 1207 
     | 
    
         
            +
            squared.attr("android.substitute", "viewAttributes", items.concat(["hint", "buttonTint"])); // Attributes to preserve (default is "android.view.View")
         
     | 
| 
      
 1208 
     | 
    
         
            +
            squared.attr("android.substitute", "attributeMapping", { "android:src": "app:srcCompat", "icon": "navigationIcon" /* android */});
         
     | 
| 
      
 1209 
     | 
    
         
            +
             
     | 
| 
      
 1210 
     | 
    
         
            +
            squared.parseDocument({
         
     | 
| 
      
 1211 
     | 
    
         
            +
                element: document.body,
         
     | 
| 
      
 1212 
     | 
    
         
            +
                substitutableElements: [{
         
     | 
| 
      
 1213 
     | 
    
         
            +
                    selector: "#content",
         
     | 
| 
      
 1214 
     | 
    
         
            +
                    tag: "androidx.compose.ui.platform.ComposeView",
         
     | 
| 
      
 1215 
     | 
    
         
            +
                    renderChildren: false
         
     | 
| 
      
 1216 
     | 
    
         
            +
                }],
         
     | 
| 
      
 1217 
     | 
    
         
            +
             
     | 
| 
      
 1218 
     | 
    
         
            +
                // Some extensions have convenience properties
         
     | 
| 
      
 1219 
     | 
    
         
            +
                enabledSubstitute: true,
         
     | 
| 
      
 1220 
     | 
    
         
            +
                /* OR */
         
     | 
| 
      
 1221 
     | 
    
         
            +
                include: ["android.substitute"]
         
     | 
| 
      
 1222 
     | 
    
         
            +
            });
         
     | 
| 
       609 
1223 
     | 
    
         
             
            ```
         
     | 
| 
       610 
1224 
     | 
    
         | 
| 
       611 
     | 
    
         
            -
             
     | 
| 
      
 1225 
     | 
    
         
            +
            ```html
         
     | 
| 
      
 1226 
     | 
    
         
            +
            <body>
         
     | 
| 
      
 1227 
     | 
    
         
            +
                <header style="height: 100px"></header>
         
     | 
| 
      
 1228 
     | 
    
         
            +
                <main id="content"
         
     | 
| 
      
 1229 
     | 
    
         
            +
                      data-use="android.substitute"
         
     | 
| 
      
 1230 
     | 
    
         
            +
                      data-android-substitute-tag="androidx.compose.ui.platform.ComposeView"
         
     | 
| 
      
 1231 
     | 
    
         
            +
                      style="height: 300px; box-shadow: 10px 5px 5px black;">
         
     | 
| 
      
 1232 
     | 
    
         
            +
                    <!-- Interior elements are not rendered -->
         
     | 
| 
      
 1233 
     | 
    
         
            +
                </main>
         
     | 
| 
      
 1234 
     | 
    
         
            +
                <footer style="height: 80px"></footer>
         
     | 
| 
      
 1235 
     | 
    
         
            +
            </body>
         
     | 
| 
      
 1236 
     | 
    
         
            +
            ```
         
     | 
| 
       612 
1237 
     | 
    
         | 
| 
       613 
     | 
    
         
            -
             
     | 
| 
       614 
     | 
    
         
            -
             
     | 
| 
       615 
     | 
    
         
            -
             
     | 
| 
      
 1238 
     | 
    
         
            +
            Compose will remove child elements by default. You can preserve them by explictly using the renderChildren property. (data-android-substitute-render-children="true")
         
     | 
| 
      
 1239 
     | 
    
         
            +
             
     | 
| 
      
 1240 
     | 
    
         
            +
            ```html
         
     | 
| 
      
 1241 
     | 
    
         
            +
            <div id="fragment"
         
     | 
| 
      
 1242 
     | 
    
         
            +
                data-use="android.substitute"
         
     | 
| 
      
 1243 
     | 
    
         
            +
                data-android-substitute-tag="androidx.fragment.app.FragmentContainerView"
         
     | 
| 
      
 1244 
     | 
    
         
            +
                data-android-substitute-render-children="false"
         
     | 
| 
      
 1245 
     | 
    
         
            +
                data-android-attr="name::com.github.fragment;tag::example">
         
     | 
| 
      
 1246 
     | 
    
         
            +
                <!-- Interior elements are not rendered -->
         
     | 
| 
      
 1247 
     | 
    
         
            +
            </div>
         
     | 
| 
       616 
1248 
     | 
    
         
             
            ```
         
     | 
| 
       617 
1249 
     | 
    
         | 
| 
       618 
     | 
    
         
            -
             
     | 
| 
      
 1250 
     | 
    
         
            +
            You can also use "**android.substitute**" to create fragments within a layout similar to Compose.
         
     | 
| 
      
 1251 
     | 
    
         
            +
             
     | 
| 
      
 1252 
     | 
    
         
            +
            Usually you do not render child elements when using Compose View. There are some cases where it can be used effectively to reproduce the desired layout.
         
     | 
| 
      
 1253 
     | 
    
         
            +
             
     | 
| 
      
 1254 
     | 
    
         
            +
            ```javascript
         
     | 
| 
      
 1255 
     | 
    
         
            +
            squared.parseDocument({
         
     | 
| 
      
 1256 
     | 
    
         
            +
                element: document.body,
         
     | 
| 
      
 1257 
     | 
    
         
            +
                include: ["android.substitute"], // OR: settings.enabledSubstitute
         
     | 
| 
      
 1258 
     | 
    
         
            +
                substitutableElements: [{
         
     | 
| 
      
 1259 
     | 
    
         
            +
                    selector: "#navigation",
         
     | 
| 
      
 1260 
     | 
    
         
            +
                    tag: "com.google.android.material.tabs.TabLayout",
         
     | 
| 
      
 1261 
     | 
    
         
            +
                    tagChild: "com.google.android.material.tabs.TabItem",
         
     | 
| 
      
 1262 
     | 
    
         
            +
                    tagChildAttr: {
         
     | 
| 
      
 1263 
     | 
    
         
            +
                        android: {
         
     | 
| 
      
 1264 
     | 
    
         
            +
                            layout_height: "match_parent"
         
     | 
| 
      
 1265 
     | 
    
         
            +
                        }
         
     | 
| 
      
 1266 
     | 
    
         
            +
                    },
         
     | 
| 
      
 1267 
     | 
    
         
            +
                    renderChildren: true,
         
     | 
| 
      
 1268 
     | 
    
         
            +
                    autoLayout: true
         
     | 
| 
      
 1269 
     | 
    
         
            +
                }]
         
     | 
| 
      
 1270 
     | 
    
         
            +
            });
         
     | 
| 
      
 1271 
     | 
    
         
            +
            ```
         
     | 
| 
       619 
1272 
     | 
    
         | 
| 
       620 
     | 
    
         
            -
             
     | 
| 
      
 1273 
     | 
    
         
            +
            ```html
         
     | 
| 
      
 1274 
     | 
    
         
            +
            <ul id="navigation"
         
     | 
| 
      
 1275 
     | 
    
         
            +
                data-use-android="android.substitute"
         
     | 
| 
      
 1276 
     | 
    
         
            +
                data-android-attr="layout_height::match_parent"
         
     | 
| 
      
 1277 
     | 
    
         
            +
                data-android-substitute-tag="com.google.android.material.tabs.TabLayout"
         
     | 
| 
      
 1278 
     | 
    
         
            +
                data-android-substitute-tag-child="com.google.android.material.tabs.TabItem"
         
     | 
| 
      
 1279 
     | 
    
         
            +
                data-android-substitute-tag-child-attr="layout_height::match_parent"
         
     | 
| 
      
 1280 
     | 
    
         
            +
                data-android-substitute-auto-layout="true">
         
     | 
| 
      
 1281 
     | 
    
         
            +
                <li>TAB 1</li>
         
     | 
| 
      
 1282 
     | 
    
         
            +
                <li>TAB 2</li>
         
     | 
| 
      
 1283 
     | 
    
         
            +
                <li>TAB 3</li>
         
     | 
| 
      
 1284 
     | 
    
         
            +
            </ul>
         
     | 
| 
      
 1285 
     | 
    
         
            +
            ```
         
     | 
| 
       621 
1286 
     | 
    
         | 
| 
       622 
     | 
    
         
            -
            ``` 
     | 
| 
       623 
     | 
    
         
            -
             
     | 
| 
       624 
     | 
    
         
            -
             
     | 
| 
       625 
     | 
    
         
            -
             
     | 
| 
       626 
     | 
    
         
            -
             
     | 
| 
       627 
     | 
    
         
            -
             
     | 
| 
       628 
     | 
    
         
            -
             
     | 
| 
      
 1287 
     | 
    
         
            +
            ```xml
         
     | 
| 
      
 1288 
     | 
    
         
            +
            <com.google.android.material.tabs.TabLayout
         
     | 
| 
      
 1289 
     | 
    
         
            +
                android:id="@+id/navigation"
         
     | 
| 
      
 1290 
     | 
    
         
            +
                android:layout_height="match_parent"
         
     | 
| 
      
 1291 
     | 
    
         
            +
                android:layout_width="wrap_content">
         
     | 
| 
      
 1292 
     | 
    
         
            +
                <com.google.android.material.tabs.TabItem
         
     | 
| 
      
 1293 
     | 
    
         
            +
                    android:layout_height="match_parent"
         
     | 
| 
      
 1294 
     | 
    
         
            +
                    android:layout_width="wrap_content"
         
     | 
| 
      
 1295 
     | 
    
         
            +
                    android:text="@string/tab_1" />
         
     | 
| 
      
 1296 
     | 
    
         
            +
                <com.google.android.material.tabs.TabItem
         
     | 
| 
      
 1297 
     | 
    
         
            +
                    android:layout_height="match_parent"
         
     | 
| 
      
 1298 
     | 
    
         
            +
                    android:layout_width="wrap_content"
         
     | 
| 
      
 1299 
     | 
    
         
            +
                    android:text="@string/tab_2" />
         
     | 
| 
      
 1300 
     | 
    
         
            +
                <com.google.android.material.tabs.TabItem
         
     | 
| 
      
 1301 
     | 
    
         
            +
                    android:layout_height="match_parent"
         
     | 
| 
      
 1302 
     | 
    
         
            +
                    android:layout_width="wrap_content"
         
     | 
| 
      
 1303 
     | 
    
         
            +
                    android:text="@string/tab_3" />
         
     | 
| 
      
 1304 
     | 
    
         
            +
            </com.google.android.material.tabs.TabLayout>
         
     | 
| 
       629 
1305 
     | 
    
         
             
            ```
         
     | 
| 
       630 
1306 
     | 
    
         | 
| 
       631 
     | 
    
         
            -
            ###  
     | 
| 
      
 1307 
     | 
    
         
            +
            ### Downloadable Fonts
         
     | 
| 
       632 
1308 
     | 
    
         | 
| 
       633 
     | 
    
         
            -
             
     | 
| 
      
 1309 
     | 
    
         
            +
            Google Fonts are pre-installed and can be used without any additional configuration.
         
     | 
| 
       634 
1310 
     | 
    
         | 
| 
       635 
     | 
    
         
            -
             
     | 
| 
       636 
     | 
    
         
            -
            GIT_OPTIONS=q,strategy=ort  # all
         
     | 
| 
       637 
     | 
    
         
            -
            GIT_OPTIONS_${NAME}=v,ff    # project only
         
     | 
| 
       638 
     | 
    
         
            -
            GIT_AUTOSTASH=1             # rebase (all)
         
     | 
| 
       639 
     | 
    
         
            -
            GIT_AUTOSTASH_${NAME}=0     # rebase (project only)
         
     | 
| 
       640 
     | 
    
         
            -
            ```
         
     | 
| 
       641 
     | 
    
         
            -
             
     | 
| 
       642 
     | 
    
         
            -
            | Command    | Flag              |  ENV                                                                  |
         
     | 
| 
       643 
     | 
    
         
            -
            | :--------- | :---------------- | :-------------------------------------------------------------------- |
         
     | 
| 
       644 
     | 
    
         
            -
            | branch     | create            | TRACK=0,1,s F|FORCE                                                   |
         
     | 
| 
       645 
     | 
    
         
            -
            | branch     | move copy         | F|FORCE                                                               |
         
     | 
| 
       646 
     | 
    
         
            -
            | branch     | delete            | COUNT=n                                                               |
         
     | 
| 
       647 
     | 
    
         
            -
            | branch     | global            | SYNC                                                                  |
         
     | 
| 
       648 
     | 
    
         
            -
            | checkout   | branch            | DETACH TRACK=s COUNT=n                                                |
         
     | 
| 
       649 
     | 
    
         
            -
            | checkout   | detach            | REFLOG=1                                                              |
         
     | 
| 
       650 
     | 
    
         
            -
            | checkout   | track             | COUNT=n                                                               |
         
     | 
| 
       651 
     | 
    
         
            -
            | checkout   | global path       | HEAD=s PATHSPEC=s                                                     |
         
     | 
| 
       652 
     | 
    
         
            -
            | checkout   | *                 | F|FORCE MERGE                                                         |
         
     | 
| 
       653 
     | 
    
         
            -
            | clone      | *                 | DEPTH=n ORIGIN=s BRANCH=s REVISION=s LOCAL=0,1                        |
         
     | 
| 
       654 
     | 
    
         
            -
            | commit     | *                 | UPSTREAM=s DRY_RUN EDIT=0 M|MESSAGE=s                                 |
         
     | 
| 
       655 
     | 
    
         
            -
            | diff       | -between -contain | MERGE_BASE                                                            |
         
     | 
| 
       656 
     | 
    
         
            -
            | diff       | head branch       | INDEX=n                                                               |
         
     | 
| 
       657 
     | 
    
         
            -
            | diff       | *                 | PATHSPEC=s                                                            |
         
     | 
| 
       658 
     | 
    
         
            -
            | fetch      | -remote           | ALL                                                                   |
         
     | 
| 
       659 
     | 
    
         
            -
            | fetch      | remote            | REFSPEC=s                                                             |
         
     | 
| 
       660 
     | 
    
         
            -
            | fetch      | *                 | F|FORCE RECURSE_SUBMODULES=0,1,s                                      |
         
     | 
| 
       661 
     | 
    
         
            -
            | git        | rm                | PATHSPEC=s                                                            |
         
     | 
| 
       662 
     | 
    
         
            -
            | log        | *                 | PATHSPEC=s                                                            |
         
     | 
| 
       663 
     | 
    
         
            -
            | pull       | remote            | REFSPEC=s                                                             |
         
     | 
| 
       664 
     | 
    
         
            -
            | pull       | -remote           | REBASE=0,1 ALL                                                        |
         
     | 
| 
       665 
     | 
    
         
            -
            | pull       | all               | FF_ONLY=0                                                             |
         
     | 
| 
       666 
     | 
    
         
            -
            | pull       | *                 | AUTOSTASH F|FORCE RECURSE_SUBMODULES=0,1,s                            |
         
     | 
| 
       667 
     | 
    
         
            -
            | rebase     | branch            | HEAD=s                                                                |
         
     | 
| 
       668 
     | 
    
         
            -
            | rebase     | onto              | INTERACTIVE I HEAD=s                                                  |
         
     | 
| 
       669 
     | 
    
         
            -
            | reset      | mode (mixed)      | N REFRESH=0                                                           |
         
     | 
| 
       670 
     | 
    
         
            -
            | reset      | index             | PATHSPEC=s                                                            |
         
     | 
| 
       671 
     | 
    
         
            -
            | reset      | commit            | COUNT=n REFLOG=1                                                      |
         
     | 
| 
       672 
     | 
    
         
            -
            | reset      | -commit           | HEAD=s                                                                |
         
     | 
| 
       673 
     | 
    
         
            -
            | restore    | *                 | PATHSPEC=s                                                            |
         
     | 
| 
       674 
     | 
    
         
            -
            | revbuild   | global            | UNTRACKED_FILES=s IGNORE_SUBMODULES=s IGNORED=s (status)              |
         
     | 
| 
       675 
     | 
    
         
            -
            | stash      | push              | PATHSPEC=s                                                            |
         
     | 
| 
       676 
     | 
    
         
            -
            | stash      | global            | ALL=0,1 KEEP_INDEX=0,1 INCLUDE_UNTRACKED=0,1 STAGED=0,1 M|MESSAGE=s   |
         
     | 
| 
       677 
     | 
    
         
            -
            | status     | global            | BRANCH LONG IGNORE_SUBMODULES=s,0-3 PATHSPEC=s                        |
         
     | 
| 
       678 
     | 
    
         
            -
            | submodule  | -branch -url      | R|RECURSIVE                                                           |
         
     | 
| 
       679 
     | 
    
         
            -
            | switch     | detach            | REFLOG=1                                                              |
         
     | 
| 
       680 
     | 
    
         
            -
            | switch     | -detach           | HEAD=s                                                                |
         
     | 
| 
       681 
     | 
    
         
            -
            | switch     | *                 | F|FORCE                                                               |
         
     | 
| 
       682 
     | 
    
         
            -
            | tag        | add               | SIGN FORCE HEAD=s M|MESSAGE=s                                         |
         
     | 
| 
       683 
     | 
    
         
            -
            | tag        | sign              | F|FORCE HEAD=s M|MESSAGE=s                                            |
         
     | 
| 
       684 
     | 
    
         
            -
            | tag        | delete            | COUNT=n                                                               |
         
     | 
| 
       685 
     | 
    
         
            -
            | rev        | commit branch     | HEAD=s                                                                |
         
     | 
| 
       686 
     | 
    
         
            -
             
     | 
| 
       687 
     | 
    
         
            -
            ### Docker
         
     | 
| 
       688 
     | 
    
         
            -
             
     | 
| 
       689 
     | 
    
         
            -
            * Version: 28.3
         
     | 
| 
      
 1311 
     | 
    
         
            +
            * [Guide](https://developer.android.com/guide/topics/ui/look-and-feel/downloadable-fonts)
         
     | 
| 
       690 
1312 
     | 
    
         | 
| 
       691 
     | 
    
         
            -
            ``` 
     | 
| 
       692 
     | 
    
         
            -
             
     | 
| 
       693 
     | 
    
         
            -
             
     | 
| 
       694 
     | 
    
         
            -
             
     | 
| 
       695 
     | 
    
         
            -
             
     | 
| 
       696 
     | 
    
         
            -
             
     | 
| 
       697 
     | 
    
         
            -
             
     | 
| 
       698 
     | 
    
         
            -
            ```
         
     | 
| 
       699 
     | 
    
         
            -
             
     | 
| 
       700 
     | 
    
         
            -
            | Command    | Flag              |  ENV                                            |
         
     | 
| 
       701 
     | 
    
         
            -
            | :--------- | :---------------- | :---------------------------------------------- |
         
     | 
| 
       702 
     | 
    
         
            -
            | buildx     | build             | TAG=s                                           |
         
     | 
| 
       703 
     | 
    
         
            -
            | buildx     | bake              | SERVICE=s                                       |
         
     | 
| 
       704 
     | 
    
         
            -
            | compose    | build             | TARGET=s                                        |
         
     | 
| 
       705 
     | 
    
         
            -
            | container  | commit            | REGISTRY=s PLATFORM=s DISABLE_CONTENT_TRUST=0,1 |
         
     | 
| 
       706 
     | 
    
         
            -
            | image      | rm                | Y=0,1                                           |
         
     | 
| 
       707 
     | 
    
         
            -
            | image      | push              | TAG=s REGISTRY=s                                |
         
     | 
| 
      
 1313 
     | 
    
         
            +
            ```xml
         
     | 
| 
      
 1314 
     | 
    
         
            +
            <!-- build.gradle -->
         
     | 
| 
      
 1315 
     | 
    
         
            +
            dependencies {
         
     | 
| 
      
 1316 
     | 
    
         
            +
                implementation 'androidx.appcompat:appcompat:1.6.0' <!-- createBuildDependencies = true -->
         
     | 
| 
      
 1317 
     | 
    
         
            +
                <!-- OR -->
         
     | 
| 
      
 1318 
     | 
    
         
            +
                implementation 'com.android.support:appcompat-v7:28.0.0'
         
     | 
| 
      
 1319 
     | 
    
         
            +
            }
         
     | 
| 
       708 
1320 
     | 
    
         | 
| 
       709 
     | 
    
         
            -
             
     | 
| 
      
 1321 
     | 
    
         
            +
            <!-- AndroidManifest.xml -->
         
     | 
| 
      
 1322 
     | 
    
         
            +
            <manifest xmlns:android="http://schemas.android.com/apk/res/android"> <!-- createManifest = true -->
         
     | 
| 
      
 1323 
     | 
    
         
            +
                <application android:theme="@style/AppTheme">
         
     | 
| 
      
 1324 
     | 
    
         
            +
                    <meta-data android:name="preloaded_fonts" android:resource="@array/preloaded_fonts" />
         
     | 
| 
      
 1325 
     | 
    
         
            +
                </application>
         
     | 
| 
      
 1326 
     | 
    
         
            +
            </manifest>
         
     | 
| 
      
 1327 
     | 
    
         
            +
            ```
         
     | 
| 
       710 
1328 
     | 
    
         | 
| 
       711 
     | 
    
         
            -
             
     | 
| 
      
 1329 
     | 
    
         
            +
            ```javascript
         
     | 
| 
      
 1330 
     | 
    
         
            +
            // https://developers.google.com/fonts/docs/developer_api
         
     | 
| 
      
 1331 
     | 
    
         
            +
             
     | 
| 
      
 1332 
     | 
    
         
            +
            await android.addFontProvider(
         
     | 
| 
      
 1333 
     | 
    
         
            +
                "com.google.android.gms.fonts",
         
     | 
| 
      
 1334 
     | 
    
         
            +
                "com.google.android.gms",
         
     | 
| 
      
 1335 
     | 
    
         
            +
                ["MIIEqDCCA5CgAwIBAgIJANWFuGx9007...", "MIIEQzCCAyugAwIBAgIJAMLgh0Zk..."],
         
     | 
| 
      
 1336 
     | 
    
         
            +
                "https://www.googleapis.com/webfonts/v1/webfonts?key=1234567890" // JSON object is synchronous
         
     | 
| 
      
 1337 
     | 
    
         
            +
            );
         
     | 
| 
      
 1338 
     | 
    
         
            +
            /* OR */
         
     | 
| 
      
 1339 
     | 
    
         
            +
            squared.attr("android.resource.fonts", "installGoogleFonts", false); // Use browser and local fonts only
         
     | 
| 
      
 1340 
     | 
    
         
            +
            ```
         
     | 
| 
       712 
1341 
     | 
    
         | 
| 
       713 
     | 
    
         
            -
             
     | 
| 
       714 
     | 
    
         
            -
             
     | 
| 
       715 
     | 
    
         
            -
             
     | 
| 
       716 
     | 
    
         
            -
             
     | 
| 
       717 
     | 
    
         
            -
             
     | 
| 
       718 
     | 
    
         
            -
             
     | 
| 
       719 
     | 
    
         
            -
             
     | 
| 
       720 
     | 
    
         
            -
             
     | 
| 
       721 
     | 
    
         
            -
             
     | 
| 
       722 
     | 
    
         
            -
             
     | 
| 
       723 
     | 
    
         
            -
             
     | 
| 
       724 
     | 
    
         
            -
             
     | 
| 
       725 
     | 
    
         
            -
             
     | 
| 
       726 
     | 
    
         
            -
             
     | 
| 
       727 
     | 
    
         
            -
             
     | 
| 
       728 
     | 
    
         
            -
             
     | 
| 
      
 1342 
     | 
    
         
            +
            ### Excluding Procedures / Applied Attributes
         
     | 
| 
      
 1343 
     | 
    
         
            +
             
     | 
| 
      
 1344 
     | 
    
         
            +
            Most attributes can be excluded from the generated XML using the dataset feature in HTML. One or more can be applied to any tag using the OR "**|**" operator. These may cause warnings when you compile your project and should only be used when an extension has their custom attributes overwritten.
         
     | 
| 
      
 1345 
     | 
    
         
            +
             
     | 
| 
      
 1346 
     | 
    
         
            +
            NOTE: Defining an element "**id**" will prevent it from being removed during the optimization phase.
         
     | 
| 
      
 1347 
     | 
    
         
            +
             
     | 
| 
      
 1348 
     | 
    
         
            +
            ```html
         
     | 
| 
      
 1349 
     | 
    
         
            +
            <div data-exclude-section="DOM_TRAVERSE | EXTENSION | RENDER | ALL"
         
     | 
| 
      
 1350 
     | 
    
         
            +
                 data-exclude-procedure="CONSTRAINT | LAYOUT | ALIGNMENT | ACCESSIBILITY | LOCALIZATION | CUSTOMIZATION | OPTIMIZATION | ALL"
         
     | 
| 
      
 1351 
     | 
    
         
            +
                 data-exclude-resource="BOX_STYLE | BOX_SPACING | FONT_STYLE | VALUE_STRING | IMAGE_SOURCE | ASSET | ALL"
         
     | 
| 
      
 1352 
     | 
    
         
            +
                 data-exclude-optimization="EXCLUDE | INHERIT | ALIGNMENT | POSITION | DIMENSION | MARGIN | PADDING | BASELINE | WHITESPACE | TRANSLATE | TRANSFORM | SCALING">
         
     | 
| 
      
 1353 
     | 
    
         
            +
            </div>
         
     | 
| 
      
 1354 
     | 
    
         
            +
            <div>
         
     | 
| 
      
 1355 
     | 
    
         
            +
                <span data-exclude-resource="FONT_STYLE">content</span>
         
     | 
| 
      
 1356 
     | 
    
         
            +
                <input id="cb1" type="checkbox" data-exclude-procedure="ACCESSIBILITY"><label for="cb1">checkbox text</label>
         
     | 
| 
      
 1357 
     | 
    
         
            +
            </div>
         
     | 
| 
       729 
1358 
     | 
    
         
             
            ```
         
     | 
| 
       730 
1359 
     | 
    
         | 
| 
       731 
1360 
     | 
    
         
             
            ## LICENSE
         
     |