github.com/kayoticsully/syncthing@v0.8.9-0.20140724133906-c45a2fdc03f8/gui/index.html (about)

     1  <!DOCTYPE html>
     2  <!--
     3  // Copyright (C) 2014 Jakob Borg and Contributors (see the CONTRIBUTORS file).
     4  // All rights reserved. Use of this source code is governed by an MIT-style
     5  // license that can be found in the LICENSE file.
     6  -->
     7  <html lang="en" ng-app="syncthing" ng-controller="SyncthingCtrl" class="ng-cloak">
     8  <head>
     9    <meta charset="utf-8">
    10    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    11    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    12    <meta name="description" content="">
    13    <meta name="author" content="">
    14    <link rel="shortcut icon" href="favicon.png">
    15  
    16    <title>Syncthing | {{thisNodeName()}}</title>
    17    <link href="bootstrap/css/bootstrap.min.css" rel="stylesheet">
    18    <style type="text/css">
    19      body {
    20        padding-bottom: 70px;
    21        font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    22      }
    23  
    24      ul+h5 {
    25        margin-top: 1.5em;
    26      }
    27  
    28      .text-monospace {
    29        font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
    30      }
    31  
    32      .table-condensed>thead>tr>th, .table-condensed>tbody>tr>th, .table-condensed>tfoot>tr>th, .table-condensed>thead>tr>td, .table-condensed>tbody>tr>td, .table-condensed>tfoot>tr>td {
    33        border-top: none;
    34      }
    35  
    36      .logo {
    37        margin: 0;
    38        padding: 0;
    39        top: -5px;
    40        position: relative;
    41      }
    42  
    43      .list-no-bullet {
    44        list-style-type: none
    45      }
    46  
    47      .li-column {
    48        display: inline-block;
    49        min-width: 7em;
    50        margin-right: 1em;
    51        background-color: rgb(236, 240, 241);
    52        border-radius: 3px;
    53        padding: 1px 4px;
    54        margin: 2px 2px;
    55      }
    56      .li-column span.data {
    57        margin-left: 0.5em;
    58        min-width: 10em;
    59        text-align: right;
    60        display: inline-block;
    61      }
    62  
    63      .ng-cloak {
    64        display: none !important;
    65      }
    66  
    67      .table th {
    68        white-space: nowrap;
    69        font-weight: 400;
    70      }
    71  
    72      .table td {
    73        padding-left: 20px !important;
    74      }
    75  
    76      .table td.small-data {
    77        white-space: nowrap;
    78      }
    79  
    80      @media (max-width:767px) {
    81        .table-responsive>.table>tbody>tr>td {
    82          /* revert a bootstrap setting e.g.:
    83           * for mobile phones to allow linebreaks in long repro folder/shared with
    84           * columns. */
    85          white-space: normal;
    86        }
    87      }
    88    </style>
    89  </head>
    90  
    91  <body>
    92  
    93    <!-- Top bar -->
    94  
    95    <nav class="navbar navbar-top navbar-default" role="navigation">
    96      <div class="container">
    97        <span class="navbar-brand"><img class="logo" src="st-logo-128.png" width="32" height="32" /> Syncthing<small class="hidden-xs"> <span class="text-muted">|</span> {{thisNodeName()}}</small></span>
    98        <ul class="nav navbar-nav navbar-right">
    99          <li ng-if="upgradeInfo.newer">
   100            <button type="button" class="btn navbar-btn btn-default" href="" ng-click="upgrade()">
   101            <span class="glyphicon glyphicon-chevron-up"></span>&emsp;
   102            <span translate translate-value-version="{{upgradeInfo.latest}}">Upgrade To {%version%}</span>
   103            </button>
   104          </li>
   105          <li class="dropdown">
   106            <a href="#" class="dropdown-toggle" data-toggle="dropdown"><span translate>Edit</spanq&nbsp;<b class="caret"></b></a>
   107            <ul class="dropdown-menu">
   108              <li><a href="" ng-click="addRepo()"><span class="glyphicon glyphicon-hdd"></span>&emsp;<span translate>Add Repository</span></a></li>
   109              <li><a href="" ng-click="addNode()"><span class="glyphicon glyphicon-retweet"></span>&emsp;<span translate>Add Node</span></a></li>
   110              <li class="divider"></li>
   111              <li><a href="" ng-click="editSettings()"><span class="glyphicon glyphicon-cog"></span>&emsp;<span translate>Settings</span></a></li>
   112              <li><a href="" ng-click="idNode()"><span class="glyphicon glyphicon-qrcode"></span>&emsp;<span translate>Show ID</span></a></li>
   113              <li class="divider"></li>
   114              <li><a href="" ng-click="shutdown()"><span class="glyphicon glyphicon-off"></span>&emsp;<span translate>Shutdown</span></a></li>
   115              <li><a href="" ng-click="restart()"><span class="glyphicon glyphicon-refresh"></span>&emsp;<span translate>Restart</span></a></li>
   116              <li class="divider"></li>
   117              <li><a href="" ng-click="about()"><span class="glyphicon glyphicon-heart-empty"></span>&emsp;<span translate>About</span></a></li>
   118            </ul>
   119          </li>
   120        </ul>
   121      </div>
   122    </nav>
   123  
   124    <div class="container">
   125  
   126      <!-- First row, only shown if necessary; Restart warning -->
   127  
   128      <div ng-if="!configInSync" class="row">
   129        <div class="col-md-12">
   130          <div class="panel panel-warning">
   131            <div class="panel-heading"><h3 translate class="panel-title">Restart Needed</h3></div>
   132            <div class="panel-body">
   133              <p translate>The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.</p>
   134            </div>
   135            <div class="panel-footer">
   136              <button type="button" class="btn btn-sm btn-default pull-right" ng-click="restart()"><span class="glyphicon glyphicon-refresh"></span>&emsp;<span translate>Restart</span></button>
   137              <div class="clearfix"></div>
   138            </div>
   139          </div>
   140        </div>
   141      </div>
   142  
   143      <!-- First regular row -->
   144  
   145      <div class="row">
   146  
   147        <!-- Repository list (top left) -->
   148  
   149        <div class="col-md-6">
   150          <div class="panel-group" id="repositories">
   151            <div class="panel panel-{{repoClass(repo.ID)}}" ng-repeat="repo in repoList()">
   152              <div class="panel-heading">
   153                <h3 class="panel-title">
   154                  <a data-toggle="collapse" data-parent="#repositories" href="#repo-{{$index}}">
   155                    <span class="glyphicon glyphicon-hdd"></span> {{repo.Directory | shortPath}}
   156                    <span class="pull-right hidden-xs">{{repoStatus(repo.ID)}}</span>
   157                  </a>
   158                </h3>
   159              </div>
   160              <div id="repo-{{$index}}" class="panel-collapse collapse">
   161                <div class="panel-body">
   162                  <div class="table-responsive">
   163                    <table class="table table-condensed table-striped">
   164                      <tbody>
   165                        <tr>
   166                          <th><span class="glyphicon glyphicon-tag"></span>&emsp;<span translate>Repository ID</span></th>
   167                          <td class="text-right">{{repo.ID}}</td>
   168                        </tr>
   169                        <tr>
   170                          <th><span class="glyphicon glyphicon-folder-open"></span>&emsp;<span translate>Folder</span></th>
   171                          <td class="text-right">{{repo.Directory}}</td>
   172                        </tr>
   173                        <tr ng-if="model[repo.ID].invalid">
   174                          <th><span class="glyphicon glyphicon-warning-sign"></span>&emsp;<span translate>Error</span></th>
   175                          <td class="text-right">{{model[repo.ID].invalid}}</td>
   176                        </tr>
   177                        <tr>
   178                          <th><span class="glyphicon glyphicon-comment"></span>&emsp;<span translate>Synchronization</span></th>
   179                          <td class="text-right">{{repoStatus(repo.ID)}}</td>
   180                        </tr>
   181                        <tr>
   182                          <th><span class="glyphicon glyphicon-globe"></span>&emsp;<span translate>Global Repository</span></th>
   183                          <td class="text-right">{{model[repo.ID].globalFiles | alwaysNumber}} <span translate>items</span>, {{model[repo.ID].globalBytes | binary}}B</td>
   184                        </tr>
   185                        <tr>
   186                          <th><span class="glyphicon glyphicon-home"></span>&emsp;<span translate>Local Repository</span></th>
   187                          <td class="text-right">{{model[repo.ID].localFiles | alwaysNumber}} <span translate>items</span>, {{model[repo.ID].localBytes | binary}}B</td>
   188                        </tr>
   189                        <tr>
   190                          <th><span class="glyphicon glyphicon-cloud-download"></span>&emsp;<span translate>Out Of Sync</span></th>
   191                          <td class="text-right">
   192                          <a ng-if="model[repo.ID].needFiles > 0" ng-click="showNeed(repo.ID)" href="">{{model[repo.ID].needFiles | alwaysNumber}} <span translate>items</span>, {{model[repo.ID].needBytes | binary}}B</a>
   193                          <span ng-if="model[repo.ID].needFiles == 0">0 <span translate>items</span>, 0 B</span>
   194                          </td>
   195                        </tr>
   196                        <tr>
   197                          <th><span class="glyphicon glyphicon-lock"></span>&emsp;<span translate>Master Repo</span></th>
   198                          <td class="text-right">
   199                            <span translate ng-if="repo.ReadOnly">Yes</span>
   200                            <span translate ng-if="!repo.ReadOnly">No</span>
   201                          </td>
   202                        </tr>
   203                        <tr>
   204                          <th><span class="glyphicon glyphicon-unchecked"></span>&emsp;<span translate>Ignore Permissions</span></th>
   205                          <td class="text-right">
   206                            <span translate ng-if="repo.IgnorePerms">Yes</span>
   207                            <span translate ng-if="!repo.IgnorePerms">No</span>
   208                          </td>
   209                        </tr>
   210                        <tr>
   211                          <th><span class="glyphicon glyphicon-share-alt"></span>&emsp;<span translate>Shared With</span></th>
   212                          <td class="text-right">{{sharesRepo(repo)}}</td>
   213                        </tr>
   214                      </tbody>
   215                    </table>
   216                  </div>
   217                  <span class="pull-right">
   218                    <a class="btn btn-sm btn-primary" href="" ng-click="editRepo(repo)"><span class="glyphicon glyphicon-pencil"></span>&emsp;<span translate>Edit</span></a>
   219                    <a class="btn btn-sm btn-danger" ng-if="repo.ReadOnly && model[repo.ID].needFiles > 0" ng-click="override(repo.ID)" href=""><span class="glyphicon glyphicon-upload"></span>&emsp;<span translate>Override Changes</span></a>
   220                  </span>
   221                </div>
   222              </div>
   223            </div>
   224          </div>
   225        </div>
   226  
   227        <!-- Node list (top right) -->
   228  
   229        <div class="col-md-6">
   230          <div class="panel-group" id="nodes">
   231            <div class="panel panel-default" ng-repeat="nodeCfg in [thisNode()]">
   232              <div class="panel-heading">
   233                <h3 class="panel-title">
   234                  <a data-toggle="collapse" data-parent="#nodes" href="#node-this"><span class="glyphicon glyphicon-home"></span> {{nodeName(nodeCfg)}}</a>
   235                </h3>
   236              </div>
   237              <div id="node-this" class="panel-collapse collapse in">
   238                <div class="panel-body">
   239                  <div class="table-responsive">
   240                    <table class="table table-condensed table-striped">
   241                      <tbody>
   242                        <tr>
   243                          <th><span class="glyphicon glyphicon-th"></span>&emsp;<span translate>RAM Utilization</span></th>
   244                          <td class="text-right">{{system.sys | binary}}B</td>
   245                        </tr>
   246                        <tr>
   247                          <th><span class="glyphicon glyphicon-tasks"></span>&emsp;<span translate>CPU Utilization</span></th>
   248                          <td class="text-right">{{system.cpuPercent | alwaysNumber | natural:1}}%</td>
   249                        </tr>
   250                        <tr>
   251                          <th><span class="glyphicon glyphicon-cloud-download"></span>&emsp;<span translate>Download Rate</span></th>
   252                          <td class="text-right">{{connections['total'].inbps | metric}}bps ({{connections['total'].InBytesTotal | binary}}B)</td>
   253                        </tr>
   254                        <tr>
   255                          <th><span class="glyphicon glyphicon-cloud-upload"></span>&emsp;<span translate>Upload Rate</span></th>
   256                          <td class="text-right">{{connections['total'].outbps | metric}}bps ({{connections['total'].OutBytesTotal | binary}}B)</td>
   257                        </tr>
   258                        <tr ng-if="system.extAnnounceOK != undefined">
   259                          <th><span class="glyphicon glyphicon-bullhorn"></span>&emsp;<span translate>Announce Server</span></th>
   260                          <td class="text-right">
   261                            <span class="data text-success" ng-if="system.extAnnounceOK"><span translate>Online</span></span>
   262                            <span class="data text-danger" ng-if="!system.extAnnounceOK"><span translate>Offline</span></span>
   263                          </td>
   264                        </tr>
   265                        <tr>
   266                          <th><span class="glyphicon glyphicon-tag"></span>&emsp;<span translate>Version</span></th>
   267                          <td class="text-right">{{version}}</td>
   268                        </tr>
   269                      </tbody>
   270                    </table>
   271                  </div>
   272                  <span class="pull-right"><a class="btn btn-sm btn-primary" href="" ng-click="editNode(nodeCfg)"><span class="glyphicon glyphicon-pencil"></span>&emsp;<span translate>Edit</span></a></span>
   273                </div>
   274              </div>
   275            </div>
   276  
   277            <div class="panel panel-{{nodeClass(nodeCfg)}}" ng-repeat="nodeCfg in otherNodes()">
   278              <div class="panel-heading">
   279                <h3 class="panel-title">
   280                  <a data-toggle="collapse" data-parent="#nodes" href="#node-{{$index}}">
   281                    <span class="glyphicon glyphicon-retweet"></span>
   282                    {{nodeName(nodeCfg)}}
   283                    <span class="pull-right hidden-xs">{{nodeStatus(nodeCfg)}}</span>
   284                  </a>
   285                </h3>
   286              </div>
   287              <div id="node-{{$index}}" class="panel-collapse collapse">
   288                <div class="panel-body">
   289                  <div class="table-responsive">
   290                    <table class="table table-condensed table-striped">
   291                      <tbody>
   292                        <tr>
   293                          <th><span class="glyphicon glyphicon-link"></span>&emsp;<span translate>Address</span></th>
   294                          <td class="text-right">{{nodeAddr(nodeCfg)}}</td>
   295                        </tr>
   296                        <tr>
   297                          <th><span class="glyphicon glyphicon-comment"></span>&emsp;<span translate>Synchronization</span></th>
   298                          <td class="text-right">{{nodeStatus(nodeCfg)}}</td>
   299                        </tr>
   300                        <tr>
   301                          <th><span class="glyphicon glyphicon-cloud-download"></span>&emsp;<span translate>Download Rate</span></th>
   302                          <td class="text-right">{{connections[nodeCfg.NodeID].inbps | metric}}bps ({{connections[nodeCfg.NodeID].InBytesTotal | binary}}B)</td>
   303                        </tr>
   304                        <tr>
   305                          <th><span class="glyphicon glyphicon-cloud-upload"></span>&emsp;<span translate>Upload Rate</span></th>
   306                          <td class="text-right">{{connections[nodeCfg.NodeID].outbps | metric}}bps ({{connections[nodeCfg.NodeID].OutBytesTotal | binary}}B)</td>
   307                        </tr>
   308                        <tr>
   309                          <th><span class="glyphicon glyphicon-tag"></span>&emsp;<span translate>Version</span></th>
   310                          <td class="text-right">{{nodeVer(nodeCfg)}}</td>
   311                        </tr>
   312                      </tbody>
   313                    </table>
   314                  </div>
   315                  <span class="pull-right"><a class="btn btn-sm btn-primary" href="" ng-click="editNode(nodeCfg)"><span class="glyphicon glyphicon-pencil"></span>&emsp;<span translate>Edit</span></a></span>
   316                </div>
   317              </div>
   318            </div>
   319          </div>
   320        </div>
   321      </div> <!-- /row -->
   322  
   323      <!-- Errors -->
   324  
   325      <div ng-if="errorList().length > 0" class="row">
   326        <div class="col-md-12">
   327          <div class="panel panel-warning">
   328            <div class="panel-heading"><h3 class="panel-title"><span translate>Notice</span></h3></div>
   329            <div class="panel-body">
   330              <p ng-repeat="err in errorList()"><small>{{err.Time | date:"H:mm:ss"}}:</small> {{friendlyNodes(err.Error)}}</p>
   331            </div>
   332            <div class="panel-footer">
   333              <button type="button" class="pull-right btn btn-sm btn-default" ng-click="clearErrors()"><span class="glyphicon glyphicon-ok"></span>&emsp;<span translate>OK</span></button>
   334              <div class="clearfix"></div>
   335            </div>
   336          </div>
   337        </div>
   338      </div>
   339  
   340    </div> <!-- /container -->
   341  
   342    <!-- Bottom bar -->
   343  
   344    <nav class="navbar navbar-default navbar-fixed-bottom hidden-xs">
   345      <div class="container">
   346        <ul class="nav navbar-nav">
   347          <li><a class="navbar-link" href="http://discourse.syncthing.net/"><span translate>Support / Forum</span></a></li>
   348          <li><a class="navbar-link" href="https://github.com/calmh/syncthing/releases"><span translate>Latest Release</span></a></li>
   349          <li><a class="navbar-link" href="http://discourse.syncthing.net/category/documentation"><span translate>Documentation</span></a></li>
   350          <li><a class="navbar-link" href="https://github.com/calmh/syncthing/issues"><span translate>Bugs</span></a></li>
   351          <li><a class="navbar-link" href="https://github.com/calmh/syncthing"><span translate>Source Code</span></a></li>
   352        </ul>
   353      </div>
   354    </nav>
   355  
   356    <!-- Network error modal -->
   357  
   358    <modal id="networkError" status="danger" icon="exclamation-sign" title="{{'Connection Error' | translate}}">
   359      <p translate>
   360        Syncthing seems to be down, or there is a problem with your Internet connection. Retrying&hellip;
   361      </p>
   362    </modal>
   363  
   364    <!-- Restarting modal -->
   365  
   366    <modal id="restarting" icon="refresh" title="{{restartingTitle}}" status="info">
   367      <p>{{restartingBody}} <span translate>Please wait</span>&hellip;</p>
   368    </modal>
   369  
   370    <!-- Shutdown modal -->
   371  
   372    <modal id="shutdown" icon="off" status="success" title="Shutdown Complete">
   373      <p translate>Syncthing has been shut down.</p>
   374    </modal>
   375  
   376    <!-- ID modal -->
   377  
   378    <modal id="idqr" large="yes" status="info" close="yes" icon="qrcode" title="{{'Node Identification' | translate}} &mdash; {{nodeName(thisNode())}}">
   379      <div class="well well-sm text-monospace text-center">{{myID}}</div>
   380      <img ng-if="myID" class="center-block img-thumbnail" src="qr/{{myID}}"/>
   381    </modal>
   382  
   383    <!-- Node editor modal -->
   384  
   385    <div id="editNode" class="modal fade">
   386      <div class="modal-dialog modal-lg">
   387        <div class="modal-content">
   388          <div class="modal-header">
   389            <h4 translate ng-show="!editingExisting" class="modal-title">Add Node</h4>
   390            <h4 translate ng-show="editingExisting" class="modal-title">Edit Node</h4>
   391          </div>
   392          <div class="modal-body">
   393            <form role="form" name="nodeEditor">
   394              <div class="form-group" ng-class="{'has-error': nodeEditor.nodeID.$invalid && nodeEditor.nodeID.$dirty}">
   395                <label translate for="nodeID">Node ID</label>
   396                <input ng-if="!editingExisting" name="nodeID" id="nodeID" class="form-control text-monospace" type="text" ng-model="currentNode.NodeID" required valid-nodeid></input>
   397                <div ng-if="editingExisting" class="well well-sm text-monospace">{{currentNode.NodeID}}</div>
   398                <p class="help-block">
   399                  <span translate ng-if="nodeEditor.nodeID.$valid || nodeEditor.nodeID.$pristine">The node ID to enter here can be found in the "Edit > Show ID" dialog on the other node. Spaces and dashes are optional (ignored).</span>
   400                  <span translate ng-show="!editingExisting && (nodeEditor.nodeID.$valid || nodeEditor.nodeID.$pristine)">When adding a new node, keep in mind that this node must be added on the other side too.</span>
   401                  <span translate ng-if="nodeEditor.nodeID.$error.required && nodeEditor.nodeID.$dirty">The node ID cannot be blank.</span>
   402                  <span translate ng-if="nodeEditor.nodeID.$error.validNodeid && nodeEditor.nodeID.$dirty">The entered node ID does not look valid. It should be a 52 character string consisting of letters and numbers, with spaces and dashes being optional.</span>
   403                </p>
   404              </div>
   405              <div class="form-group">
   406                <label translate for="name">Node Name</label>
   407                <input placeholder="Home Server" id="name" class="form-control" type="text" ng-model="currentNode.Name"></input>
   408                <p translate class="help-block">Shown instead of Node ID in the cluster status.</p>
   409              </div>
   410              <div class="form-group">
   411                <label translate for="addresses">Addresses</label>
   412                <input placeholder="dynamic" ng-disabled="currentNode.NodeID == myID" id="addresses" class="form-control" type="text" ng-model="currentNode.AddressesStr"></input>
   413                <p translate class="help-block">Enter comma separated "ip:port" addresses or "dynamic" to perform automatic discovery of the address.</p>
   414              </div>
   415            </form>
   416          </div>
   417          <div class="modal-footer">
   418            <button type="button" class="btn btn-primary" ng-click="saveNode()" ng-disabled="nodeEditor.$invalid"><span class="glyphicon glyphicon-ok"></span>&emsp;<span translate>Save</span></button>
   419            <button type="button" class="btn btn-default" data-dismiss="modal"><span class="glyphicon glyphicon-remove"></span>&emsp;<span translate>Close</span></button>
   420            <button ng-if="editingExisting && !editingSelf" type="button" class="btn btn-danger pull-left" ng-click="deleteNode()"><span class="glyphicon glyphicon-minus"></span>&emsp;<span translate>Delete</span></button>
   421          </div>
   422        </div>
   423      </div>
   424    </div>
   425  
   426    <!-- Repo editor modal -->
   427  
   428    <div id="editRepo" class="modal fade">
   429      <div class="modal-dialog modal-lg">
   430        <div class="modal-content">
   431          <div class="modal-header">
   432            <h4 ng-show="!editingExisting" class="modal-title"><span translate>Add Repository</span></h4>
   433            <h4 ng-show="editingExisting" class="modal-title"><span translate>Edit Repository</span></h4>
   434          </div>
   435          <div class="modal-body">
   436            <form role="form" name="repoEditor">
   437              <div class="row">
   438                <div class="col-md-12">
   439                  <div class="form-group" ng-class="{'has-error': repoEditor.repoID.$invalid && repoEditor.repoID.$dirty}">
   440                    <label for="repoID"><span translate>Repository ID</span></label>
   441                    <input name="repoID" placeholder="documents" ng-disabled="editingExisting" id="repoID" class="form-control" type="text" ng-model="currentRepo.ID" required unique-repo ng-pattern="/^[a-zA-Z0-9-_.]{1,64}$/"></input>
   442                    <p class="help-block">
   443                      <span translate ng-if="repoEditor.repoID.$valid || repoEditor.repoID.$pristine">Short identifier for the repository. Must be the same on all cluster nodes.</span>
   444                      <span translate ng-if="repoEditor.repoID.$error.uniqueRepo">The repository ID must be unique.</span>
   445                      <span translate ng-if="repoEditor.repoID.$error.required && repoEditor.repoID.$dirty">The repository ID cannot be blank.</span>
   446                      <span translate ng-if="repoEditor.repoID.$error.pattern && repoEditor.repoID.$dirty">The repository ID must be a short identifier (64 characters or less) consisting of letters, numbers and the the dot (.), dash (-) and underscode (_) characters only.</span>
   447                    </p>
   448                  </div>
   449                  <div class="form-group" ng-class="{'has-error': repoEditor.repoPath.$invalid && repoEditor.repoPath.$dirty}">
   450                    <label translate for="repoPath">Repository Path</label>
   451                    <input name="repoPath" placeholder="~/Documents" id="repoPath" class="form-control" type="text" ng-model="currentRepo.Directory" required></input>
   452                    <p class="help-block">
   453                      <span translate ng-if="repoEditor.repoPath.$valid || repoEditor.repoPath.$pristine">Path to the repository on the local computer. Will be created if it does not exist. The tilde character (~) can be used as a shortcut for</span> <code>{{system.tilde}}</code>.
   454                      <span translate ng-if="repoEditor.repoPath.$error.required && repoEditor.repoPath.$dirty">The repository path cannot be blank.</span>
   455                    </p>
   456                  </div>
   457                </div>
   458              </div>
   459              <div class="row">
   460                <div class="col-md-6">
   461                  <div class="form-group">
   462                    <div class="checkbox">
   463                      <label>
   464                        <input type="checkbox" ng-model="currentRepo.ReadOnly"> <span translate>Repository Master</span>
   465                      </label>
   466                    </div>
   467                    <p translate class="help-block">Files are protected from changes made on other nodes, but changes made on this node will be sent to the rest of the cluster.</p>
   468                  </div>
   469                  <div class="form-group">
   470                    <div class="checkbox">
   471                      <label>
   472                        <input type="checkbox" ng-model="currentRepo.IgnorePerms"> <span translate>Ignore Permissions</span>
   473                      </label>
   474                    </div>
   475                    <p translate class="help-block">File permission bits are ignored when looking for changes. Use on FAT filesystems.</p>
   476                  </div>
   477                  <div class="form-group">
   478                    <label translate for="nodes">Share With Nodes</label>
   479                    <div class="checkbox" ng-repeat="node in otherNodes()">
   480                      <label>
   481                        <input type="checkbox" ng-model="currentRepo.selectedNodes[node.NodeID]"> {{nodeName(node)}}
   482                      </label>
   483                    </div>
   484                    <p translate class="help-block">Select the nodes to share this repository with.</p>
   485                  </div>
   486                </div>
   487                <div class="col-md-6">
   488                  <div class="form-group">
   489                    <div class="checkbox">
   490                      <label>
   491                        <input type="checkbox" ng-model="currentRepo.simpleFileVersioning"> <span translate>File Versioning</span>
   492                      </label>
   493                    </div>
   494                    <p translate class="help-block">Files are moved to date stamped versions in a .stversions folder when replaced or deleted by syncthing.</p>
   495                  </div>
   496                  <div class="form-group" ng-if="currentRepo.simpleFileVersioning" ng-class="{'has-error': repoEditor.simpleKeep.$invalid && repoEditor.simpleKeep.$dirty}">
   497                    <label translate for="simpleKeep">Keep Versions</label>
   498                    <input name="simpleKeep" id="simpleKeep" class="form-control" type="number" ng-model="currentRepo.simpleKeep" required min="1"></input>
   499                    <p class="help-block">
   500                      <span translate ng-if="repoEditor.simpleKeep.$valid || repoEditor.simpleKeep.$pristine">The number of old versions to keep, per file.</span>
   501                      <span translate ng-if="repoEditor.simpleKeep.$error.required && repoEditor.simpleKeep.$dirty">The number of versions must be a number and cannot be blank.</span>
   502                      <span translate ng-if="repoEditor.simpleKeep.$error.min && repoEditor.simpleKeep.$dirty">You must keep at least one version.</span>
   503                    </p>
   504                  </div>
   505  
   506                </div>
   507              </div>
   508            </form>
   509            <div translate ng-show="!editingExisting">When adding a new repository, keep in mind that the Repository ID is used to tie repositories together between nodes. They are case sensitive and must match exactly between all nodes.</div>
   510          </div>
   511          <div class="modal-footer">
   512            <button type="button" class="btn btn-primary" ng-click="saveRepo()" ng-disabled="repoEditor.$invalid"><span class="glyphicon glyphicon-ok"></span>&emsp;<span translate>Save</span></button>
   513            <button type="button" class="btn btn-default" data-dismiss="modal"><span class="glyphicon glyphicon-remove"></span>&emsp;<span translate>Close</span></button>
   514            <button ng-if="editingExisting" type="button" class="btn btn-danger pull-left" ng-click="deleteRepo()"><span class="glyphicon glyphicon-minus"></span>&emsp;<span translate>Delete</span></button>
   515          </div>
   516        </div>
   517      </div>
   518    </div>
   519  
   520    <!-- Settings modal -->
   521  
   522    <div id="settings" class="modal fade">
   523      <div class="modal-dialog modal-lg">
   524        <div class="modal-content">
   525          <div class="modal-header">
   526            <h4 translate class="modal-title">Settings</h4>
   527          </div>
   528          <div class="modal-body">
   529            <form role="form">
   530              <div class="row">
   531  
   532                <div class="col-md-6">
   533                  <div class="form-group">
   534                    <label translate for="ListenStr">Sync Protocol Listen Addresses</label>
   535                    <input id="ListenStr" class="form-control" type="text" ng-model="tmpOptions.ListenStr">
   536                  </div>
   537                  <div class="form-group">
   538                    <label translate for="MaxSendKbps">Outgoing Rate Limit (KiB/s)</label>
   539                    <input id="MaxSendKbps" class="form-control" type="number" ng-model="tmpOptions.MaxSendKbps">
   540                  </div>
   541                  <div class="form-group">
   542                    <label translate for="RescanIntervalS">Rescan Interval (s)</label>
   543                    <input id="RescanIntervalS" class="form-control" type="number" ng-model="tmpOptions.RescanIntervalS">
   544                  </div>
   545                  <div class="form-group">
   546                    <label translate for="ReconnectIntervalS">Reconnect Interval (s)</label>
   547                    <input id="ReconnectIntervalS" class="form-control" type="number" ng-model="tmpOptions.ReconnectIntervalS">
   548                  </div>
   549                  <div class="form-group">
   550                    <label translate for="ParallelRequests">Max Outstanding Requests</label>
   551                    <input id="ParallelRequests" class="form-control" type="number" ng-model="tmpOptions.ParallelRequests">
   552                  </div>
   553                  <div class="form-group">
   554                    <label translate for="MaxChangeKbps">Max File Change Rate (KiB/s)</label>
   555                    <input id="MaxChangeKbps" class="form-control" type="number" ng-model="tmpOptions.MaxChangeKbps">
   556                  </div>
   557                  <div class="form-group">
   558                    <div class="checkbox">
   559                      <label>
   560                        <span translate>Local Discovery</span> <input id="LocalAnnEnabled" type="checkbox" ng-model="tmpOptions.LocalAnnEnabled">
   561                      </label>
   562                    </div>
   563                  </div>
   564                  <div class="form-group">
   565                    <label translate for="LocalAnnPort">Local Discovery Port</label>
   566                    <input ng-disabled="!tmpOptions.LocalAnnEnabled" id="LocalAnnPort" class="form-control" type="number" ng-model="tmpOptions.LocalAnnPort">
   567                  </div>
   568                  <div class="form-group">
   569                    <div class="checkbox">
   570                      <label>
   571                        <span translate>Global Discovery</span> <input id="GlobalAnnEnabled" type="checkbox" ng-model="tmpOptions.GlobalAnnEnabled">
   572                      </label>
   573                    </div>
   574                  </div>
   575                  <div class="form-group">
   576                    <div class="checkbox">
   577                      <label>
   578                        <span translate>Enable UPnP</span> <input id="UPnPEnabled" type="checkbox" ng-model="tmpOptions.UPnPEnabled">
   579                      </label>
   580                    </div>
   581                  </div>
   582                </div>
   583  
   584                <div class="col-md-6">
   585                  <div class="form-group">
   586                    <label translate for="Address">GUI Listen Addresses</label>
   587                    <input id="Address" class="form-control" type="text" ng-model="tmpGUI.Address">
   588                  </div>
   589                  <div class="form-group">
   590                    <label translate for="User">GUI Authentication User</label>
   591                    <input id="User" class="form-control" type="text" ng-model="tmpGUI.User">
   592                  </div>
   593                  <div class="form-group">
   594                    <label translate for="Password">GUI Authentication Password</label>
   595                    <input id="Password" class="form-control" type="password" ng-model="tmpGUI.Password">
   596                  </div>
   597                  <div class="form-group">
   598                    <div class="checkbox">
   599                      <label>
   600                      <span translate>Use HTTPS for GUI</span> <input id="UseTLS" type="checkbox" ng-model="tmpGUI.UseTLS">
   601                      </label>
   602                    </div>
   603                  </div>
   604                  <div class="form-group">
   605                    <div class="checkbox">
   606                      <label>
   607                        <span translate>Start Browser</span> <input id="StartBrowser" type="checkbox" ng-model="tmpOptions.StartBrowser">
   608                      </label>
   609                    </div>
   610                  </div>
   611  
   612                  <hr/>
   613  
   614                  <div class="form-group">
   615                    <label><span translate>API Key</span> (<a translate href="http://discourse.syncthing.net/t/v0-8-14-api-keys/335">Usage</a>)</label>
   616                    <div class="well well-sm text-monospace">{{tmpGUI.APIKey || "-"}}</div>
   617                    <button translate type="button" class="btn btn-sm btn-default" ng-click="setAPIKey(tmpGUI)">Generate</button>
   618                  </div>
   619  
   620                  <hr/>
   621  
   622                  <div class="form-group">
   623                    <div class="checkbox">
   624                      <label>
   625                        <span translate>Anonymous Usage Reporting</span> <input id="UREnabled" type="checkbox" ng-model="tmpOptions.UREnabled">
   626                      </label>
   627                    </div>
   628                  </div>
   629                </div>
   630  
   631              </div>
   632            </form>
   633          </div>
   634          <div class="modal-footer">
   635            <button type="button" class="btn btn-primary" ng-click="saveSettings()"><span class="glyphicon glyphicon-ok"></span>&emsp;<span translate>Save</span></button>
   636            <button type="button" class="btn btn-default" data-dismiss="modal"><span class="glyphicon glyphicon-remove"></span>&emsp;<span translate>Close</span></button>
   637          </div>
   638        </div>
   639      </div>
   640    </div>
   641  
   642    <!-- Usage report modal -->
   643  
   644    <div id="ur" class="modal fade">
   645      <div class="modal-dialog modal-lg">
   646        <div class="modal-content">
   647          <div class="modal-header alert alert-success">
   648            <h4 translate class="modal-title">Allow Anonymous Usage Reporting?</h4>
   649          </div>
   650          <div class="modal-body">
   651          <p translate>The encrypted usage report is sent daily. It is used to track common platforms, repo sizes and app versions. If the reported data set is changed you will be prompted with this dialog again.</p>
   652          <p translate translate-value-url="https://data.syncthing.net">The aggregated statistics are publicly available at {{url}}</p>
   653          <button translate type="button" class="btn btn-default" ng-show="!reportPreview" ng-click="reportPreview = true">Preview Usage Report</button>
   654          <pre ng-if="reportPreview"><small>{{reportData | json}}</small></pre>
   655          </div>
   656          <div class="modal-footer">
   657            <button type="button" class="btn btn-success" ng-click="acceptUR()"><span class="glyphicon glyphicon-ok"></span>&emsp;<span translate>Yes</span></button>
   658            <button type="button" class="btn btn-danger" ng-click="declineUR()"><span class="glyphicon glyphicon-remove"></span>&emsp;<span translate>No</span></button>
   659          </div>
   660        </div>
   661      </div>
   662    </div>
   663  
   664    <!-- Needed files modal -->
   665  
   666    <modal id="needed" large="yes" status="info" icon="cloud-download" close="yes" title="Out of Sync Items">
   667      <table class="table table-striped table-condensed">
   668        <tr ng-repeat="f in needed" ng-init="a = needAction(f)">
   669          <td class="small-data"><span class="glyphicon glyphicon-{{needIcons[a]}}"></span> {{needActions[a]}}</td>
   670          <td title="{{f.Name}}">{{f.Name | basename}}</td>
   671          <td class="text-right small-data"><span ng-if="f.Size > 0">{{f.Size | binary}}B</span></td>
   672        </tr>
   673      </table>
   674    </modal>
   675  
   676    <!-- About modal -->
   677  
   678    <modal id="about" large="yes" close="yes" status="info" title="About">
   679      <h1 class="text-center"><img src="st-logo-128.png" style="vertical-align: -16px" width="64" height="64"/> Syncthing<br/><small>{{version}}</small></h1>
   680      <hr/>
   681  
   682      <p translate>Copyright &copy; 2014 Jakob Borg and the following Contributors:</p>
   683      <div class="row">
   684        <div class="col-md-6">
   685          <ul>
   686            <li>Aaron Bieber</li>
   687            <li>Andrew Dunham</li>
   688            <li>Arthur Axel fREW Schmidt</li>
   689            <li>Ben Sidhom</li>
   690            <li>Brandon Philips</li>
   691          </ul>
   692          </div>
   693        <div class="col-md-6">
   694          <ul>
   695            <li>James Patterson</li>
   696            <li>Jens Diemer</li>
   697            <li>Philippe Schommers</li>
   698            <li>Ryan Sullivan</li>
   699            <li>Veeti Paananen</li>
   700          </ul>
   701          </div>
   702      </div>
   703      <hr/>
   704  
   705      <p translate>Syncthing includes the following software or portions thereof:</p>
   706      <ul>
   707        <li><a href="http://golang.org/">The Go Programming Languange</a>, Copyright &copy; 2012 The Go Authors.</li>
   708        <li><a href="https://bitbucket.org/kardianos/osext">kardianos/osext</a>, Copyright &copy; 2012 Daniel Theophanes.</li>
   709        <li><a href="https://code.google.com/p/snappy-go/">snappy-go</a>, Copyright &copy; 2011 The Snappy-Go Authors.</li>
   710        <li><a href="https://github.com/golang/groupcache">groupcache/lru</a>, Copyright &copy; 2013 Google Inc.</li>
   711        <li><a href="https://github.com/juju/ratelimit">juju/ratelimit</a>, Copyright &copy; 2014 Canonical Ltd.</li>
   712        <li><a href="https://github.com/syndtr/goleveldb">syndtr/goleveldb</a>, Copyright &copy; 2012, Suryandaru Triandana</li>
   713        <li><a href="https://github.com/vitrun/qart">vitrun/qart</a>, Copyright &copy; The Go Authors.</li>
   714        <li><a href="https://angularjs.org/">AngularJS</a>, Copyright &copy; 2010-2014 Google, Inc.</li>
   715        <li><a href="http://getbootstrap.com/">Bootstrap</a>, Copyright &copy; 2011-2014 Twitter, Inc.</li>
   716      </ul>
   717    </modal>
   718  
   719  
   720    <script src="angular.min.js"></script>
   721    <script src="angular-translate.min.js"></script>
   722    <script src="angular-translate-loader.min.js"></script>
   723    <script src="jquery-2.0.3.min.js"></script>
   724    <script src="bootstrap/js/bootstrap.min.js"></script>
   725    <script src="app.js"></script>
   726  </body>
   727  </html>