Merged in editor-with-mui (pull request #61)
Editor with mui * hide keyboard help in mobile * fix translation * docs * translations * duplicated dependency * keep selected node while note/link editor is focused * code reorganization * fix * fix * fix node focus is lost when note/link editors are open througth shortcuts
@ -0,0 +1 @@
|
|||||||
|
../packages/webapp/dist/src_components_maps-page_account-menu_index_tsx-src_components_maps-page_action-dispatcher_in-ba81d4.bundle.js
|
@ -0,0 +1 @@
|
|||||||
|
../packages/webapp/dist/src_components_maps-page_account-menu_index_tsx-src_components_maps-page_action-dispatcher_in-ba81d4.bundle.js.map
|
214
libraries/bootstrap/css/bootstrap-colorpicker.css
vendored
@ -1,214 +0,0 @@
|
|||||||
/*!
|
|
||||||
* Bootstrap Colorpicker
|
|
||||||
* http://mjolnic.github.io/bootstrap-colorpicker/
|
|
||||||
*
|
|
||||||
* Originally written by (c) 2012 Stefan Petre
|
|
||||||
* Licensed under the Apache License v2.0
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.txt
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
.colorpicker-saturation {
|
|
||||||
float: left;
|
|
||||||
width: 100px;
|
|
||||||
height: 100px;
|
|
||||||
cursor: crosshair;
|
|
||||||
background-image: url('../img/bootstrap-colorpicker/saturation.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
.colorpicker-saturation i {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
display: block;
|
|
||||||
width: 5px;
|
|
||||||
height: 5px;
|
|
||||||
margin: -4px 0 0 -4px;
|
|
||||||
border: 1px solid #000;
|
|
||||||
-webkit-border-radius: 5px;
|
|
||||||
-moz-border-radius: 5px;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.colorpicker-saturation i b {
|
|
||||||
display: block;
|
|
||||||
width: 5px;
|
|
||||||
height: 5px;
|
|
||||||
border: 1px solid #fff;
|
|
||||||
-webkit-border-radius: 5px;
|
|
||||||
-moz-border-radius: 5px;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.colorpicker-hue,
|
|
||||||
.colorpicker-alpha {
|
|
||||||
float: left;
|
|
||||||
width: 15px;
|
|
||||||
height: 100px;
|
|
||||||
margin-bottom: 4px;
|
|
||||||
margin-left: 4px;
|
|
||||||
cursor: row-resize;
|
|
||||||
}
|
|
||||||
|
|
||||||
.colorpicker-hue i,
|
|
||||||
.colorpicker-alpha i {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
height: 1px;
|
|
||||||
margin-top: -1px;
|
|
||||||
background: #000;
|
|
||||||
border-top: 1px solid #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.colorpicker-hue {
|
|
||||||
background-image: url('../img/bootstrap-colorpicker/hue.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
.colorpicker-alpha {
|
|
||||||
display: none;
|
|
||||||
background-image: url('../img/bootstrap-colorpicker/alpha.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
.colorpicker {
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
z-index: 2500;
|
|
||||||
min-width: 130px;
|
|
||||||
padding: 4px;
|
|
||||||
margin-top: 1px;
|
|
||||||
-webkit-border-radius: 4px;
|
|
||||||
-moz-border-radius: 4px;
|
|
||||||
border-radius: 4px;
|
|
||||||
*zoom: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.colorpicker:before,
|
|
||||||
.colorpicker:after {
|
|
||||||
display: table;
|
|
||||||
line-height: 0;
|
|
||||||
content: '';
|
|
||||||
}
|
|
||||||
|
|
||||||
.colorpicker:after {
|
|
||||||
clear: both;
|
|
||||||
}
|
|
||||||
|
|
||||||
.colorpicker:before {
|
|
||||||
position: absolute;
|
|
||||||
top: -7px;
|
|
||||||
left: 6px;
|
|
||||||
display: inline-block;
|
|
||||||
border-right: 7px solid transparent;
|
|
||||||
border-bottom: 7px solid #ccc;
|
|
||||||
border-left: 7px solid transparent;
|
|
||||||
border-bottom-color: rgba(0, 0, 0, 0.2);
|
|
||||||
content: '';
|
|
||||||
}
|
|
||||||
|
|
||||||
.colorpicker:after {
|
|
||||||
position: absolute;
|
|
||||||
top: -6px;
|
|
||||||
left: 7px;
|
|
||||||
display: inline-block;
|
|
||||||
border-right: 6px solid transparent;
|
|
||||||
border-bottom: 6px solid #ffffff;
|
|
||||||
border-left: 6px solid transparent;
|
|
||||||
content: '';
|
|
||||||
}
|
|
||||||
|
|
||||||
.colorpicker div {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.colorpicker.colorpicker-with-alpha {
|
|
||||||
min-width: 140px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.colorpicker.colorpicker-with-alpha .colorpicker-alpha {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.colorpicker-color {
|
|
||||||
height: 10px;
|
|
||||||
margin-top: 5px;
|
|
||||||
clear: both;
|
|
||||||
background-image: url('../img/bootstrap-colorpicker/alpha.png');
|
|
||||||
background-position: 0 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.colorpicker-color div {
|
|
||||||
height: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.colorpicker-element .input-group-addon i {
|
|
||||||
display: block;
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.colorpicker.colorpicker-inline {
|
|
||||||
position: relative;
|
|
||||||
display: inline-block;
|
|
||||||
float: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.colorpicker.colorpicker-horizontal {
|
|
||||||
width: 110px;
|
|
||||||
height: auto;
|
|
||||||
min-width: 110px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.colorpicker.colorpicker-horizontal .colorpicker-saturation {
|
|
||||||
margin-bottom: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.colorpicker.colorpicker-horizontal .colorpicker-color {
|
|
||||||
width: 100px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.colorpicker.colorpicker-horizontal .colorpicker-hue,
|
|
||||||
.colorpicker.colorpicker-horizontal .colorpicker-alpha {
|
|
||||||
float: left;
|
|
||||||
width: 100px;
|
|
||||||
height: 15px;
|
|
||||||
margin-bottom: 4px;
|
|
||||||
margin-left: 0;
|
|
||||||
cursor: col-resize;
|
|
||||||
}
|
|
||||||
|
|
||||||
.colorpicker.colorpicker-horizontal .colorpicker-hue i,
|
|
||||||
.colorpicker.colorpicker-horizontal .colorpicker-alpha i {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
display: block;
|
|
||||||
width: 1px;
|
|
||||||
height: 15px;
|
|
||||||
margin-top: 0;
|
|
||||||
background: #ffffff;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.colorpicker.colorpicker-horizontal .colorpicker-hue {
|
|
||||||
background-image: url('../img/bootstrap-colorpicker/hue-horizontal.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
.colorpicker.colorpicker-horizontal .colorpicker-alpha {
|
|
||||||
background-image: url('../img/bootstrap-colorpicker/alpha-horizontal.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
.colorpicker.colorpicker-hidden {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.colorpicker.colorpicker-visible {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.colorpicker-inline.colorpicker-visible {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
@ -1,185 +0,0 @@
|
|||||||
/*!
|
|
||||||
* Bootstrap Colorpicker
|
|
||||||
* http://mjolnic.github.io/bootstrap-colorpicker/
|
|
||||||
*
|
|
||||||
* Originally written by (c) 2012 Stefan Petre
|
|
||||||
* Licensed under the Apache License v2.0
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.txt
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
.colorpicker-saturation {
|
|
||||||
float: left;
|
|
||||||
width: 100px;
|
|
||||||
height: 100px;
|
|
||||||
cursor: crosshair;
|
|
||||||
background-image: url('../img/bootstrap-colorpicker/saturation.png');
|
|
||||||
}
|
|
||||||
.colorpicker-saturation i {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
display: block;
|
|
||||||
width: 5px;
|
|
||||||
height: 5px;
|
|
||||||
margin: -4px 0 0 -4px;
|
|
||||||
border: 1px solid #000;
|
|
||||||
-webkit-border-radius: 5px;
|
|
||||||
-moz-border-radius: 5px;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
.colorpicker-saturation i b {
|
|
||||||
display: block;
|
|
||||||
width: 5px;
|
|
||||||
height: 5px;
|
|
||||||
border: 1px solid #fff;
|
|
||||||
-webkit-border-radius: 5px;
|
|
||||||
-moz-border-radius: 5px;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
.colorpicker-hue,
|
|
||||||
.colorpicker-alpha {
|
|
||||||
float: left;
|
|
||||||
width: 15px;
|
|
||||||
height: 100px;
|
|
||||||
margin-bottom: 4px;
|
|
||||||
margin-left: 4px;
|
|
||||||
cursor: row-resize;
|
|
||||||
}
|
|
||||||
.colorpicker-hue i,
|
|
||||||
.colorpicker-alpha i {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
height: 1px;
|
|
||||||
margin-top: -1px;
|
|
||||||
background: #000;
|
|
||||||
border-top: 1px solid #fff;
|
|
||||||
}
|
|
||||||
.colorpicker-hue {
|
|
||||||
background-image: url('../img/bootstrap-colorpicker/hue.png');
|
|
||||||
}
|
|
||||||
.colorpicker-alpha {
|
|
||||||
display: none;
|
|
||||||
background-image: url('../img/bootstrap-colorpicker/alpha.png');
|
|
||||||
}
|
|
||||||
.colorpicker {
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
z-index: 2500;
|
|
||||||
min-width: 130px;
|
|
||||||
padding: 4px;
|
|
||||||
margin-top: 1px;
|
|
||||||
-webkit-border-radius: 4px;
|
|
||||||
-moz-border-radius: 4px;
|
|
||||||
border-radius: 4px;
|
|
||||||
*zoom: 1;
|
|
||||||
}
|
|
||||||
.colorpicker:before,
|
|
||||||
.colorpicker:after {
|
|
||||||
display: table;
|
|
||||||
line-height: 0;
|
|
||||||
content: '';
|
|
||||||
}
|
|
||||||
.colorpicker:after {
|
|
||||||
clear: both;
|
|
||||||
}
|
|
||||||
.colorpicker:before {
|
|
||||||
position: absolute;
|
|
||||||
top: -7px;
|
|
||||||
left: 6px;
|
|
||||||
display: inline-block;
|
|
||||||
border-right: 7px solid transparent;
|
|
||||||
border-bottom: 7px solid #ccc;
|
|
||||||
border-left: 7px solid transparent;
|
|
||||||
border-bottom-color: rgba(0, 0, 0, 0.2);
|
|
||||||
content: '';
|
|
||||||
}
|
|
||||||
.colorpicker:after {
|
|
||||||
position: absolute;
|
|
||||||
top: -6px;
|
|
||||||
left: 7px;
|
|
||||||
display: inline-block;
|
|
||||||
border-right: 6px solid transparent;
|
|
||||||
border-bottom: 6px solid #fff;
|
|
||||||
border-left: 6px solid transparent;
|
|
||||||
content: '';
|
|
||||||
}
|
|
||||||
.colorpicker div {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
.colorpicker.colorpicker-with-alpha {
|
|
||||||
min-width: 140px;
|
|
||||||
}
|
|
||||||
.colorpicker.colorpicker-with-alpha .colorpicker-alpha {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.colorpicker-color {
|
|
||||||
height: 10px;
|
|
||||||
margin-top: 5px;
|
|
||||||
clear: both;
|
|
||||||
background-image: url('../img/bootstrap-colorpicker/alpha.png');
|
|
||||||
background-position: 0 100%;
|
|
||||||
}
|
|
||||||
.colorpicker-color div {
|
|
||||||
height: 10px;
|
|
||||||
}
|
|
||||||
.colorpicker-element .input-group-addon i {
|
|
||||||
display: block;
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.colorpicker.colorpicker-inline {
|
|
||||||
position: relative;
|
|
||||||
display: inline-block;
|
|
||||||
float: none;
|
|
||||||
}
|
|
||||||
.colorpicker.colorpicker-horizontal {
|
|
||||||
width: 110px;
|
|
||||||
height: auto;
|
|
||||||
min-width: 110px;
|
|
||||||
}
|
|
||||||
.colorpicker.colorpicker-horizontal .colorpicker-saturation {
|
|
||||||
margin-bottom: 4px;
|
|
||||||
}
|
|
||||||
.colorpicker.colorpicker-horizontal .colorpicker-color {
|
|
||||||
width: 100px;
|
|
||||||
}
|
|
||||||
.colorpicker.colorpicker-horizontal .colorpicker-hue,
|
|
||||||
.colorpicker.colorpicker-horizontal .colorpicker-alpha {
|
|
||||||
float: left;
|
|
||||||
width: 100px;
|
|
||||||
height: 15px;
|
|
||||||
margin-bottom: 4px;
|
|
||||||
margin-left: 0;
|
|
||||||
cursor: col-resize;
|
|
||||||
}
|
|
||||||
.colorpicker.colorpicker-horizontal .colorpicker-hue i,
|
|
||||||
.colorpicker.colorpicker-horizontal .colorpicker-alpha i {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
display: block;
|
|
||||||
width: 1px;
|
|
||||||
height: 15px;
|
|
||||||
margin-top: 0;
|
|
||||||
background: #fff;
|
|
||||||
border: 0;
|
|
||||||
}
|
|
||||||
.colorpicker.colorpicker-horizontal .colorpicker-hue {
|
|
||||||
background-image: url('../img/bootstrap-colorpicker/hue-horizontal.png');
|
|
||||||
}
|
|
||||||
.colorpicker.colorpicker-horizontal .colorpicker-alpha {
|
|
||||||
background-image: url('../img/bootstrap-colorpicker/alpha-horizontal.png');
|
|
||||||
}
|
|
||||||
.colorpicker.colorpicker-hidden {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.colorpicker.colorpicker-visible {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.colorpicker-inline.colorpicker-visible {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
347
libraries/bootstrap/css/bootstrap-theme.css
vendored
@ -1,347 +0,0 @@
|
|||||||
/*!
|
|
||||||
* Bootstrap v3.1.1 (http://getbootstrap.com)
|
|
||||||
* Copyright 2011-2014 Twitter, Inc.
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
|
||||||
*/
|
|
||||||
|
|
||||||
.btn-default,
|
|
||||||
.btn-primary,
|
|
||||||
.btn-success,
|
|
||||||
.btn-info,
|
|
||||||
.btn-warning,
|
|
||||||
.btn-danger {
|
|
||||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);
|
|
||||||
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);
|
|
||||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);
|
|
||||||
}
|
|
||||||
.btn-default:active,
|
|
||||||
.btn-primary:active,
|
|
||||||
.btn-success:active,
|
|
||||||
.btn-info:active,
|
|
||||||
.btn-warning:active,
|
|
||||||
.btn-danger:active,
|
|
||||||
.btn-default.active,
|
|
||||||
.btn-primary.active,
|
|
||||||
.btn-success.active,
|
|
||||||
.btn-info.active,
|
|
||||||
.btn-warning.active,
|
|
||||||
.btn-danger.active {
|
|
||||||
-webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
|
|
||||||
box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
|
|
||||||
}
|
|
||||||
.btn:active,
|
|
||||||
.btn.active {
|
|
||||||
background-image: none;
|
|
||||||
}
|
|
||||||
.btn-default {
|
|
||||||
text-shadow: 0 1px 0 #fff;
|
|
||||||
background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
border-color: #dbdbdb;
|
|
||||||
border-color: #ccc;
|
|
||||||
}
|
|
||||||
.btn-default:hover,
|
|
||||||
.btn-default:focus {
|
|
||||||
background-color: #e0e0e0;
|
|
||||||
background-position: 0 -15px;
|
|
||||||
}
|
|
||||||
.btn-default:active,
|
|
||||||
.btn-default.active {
|
|
||||||
background-color: #e0e0e0;
|
|
||||||
border-color: #dbdbdb;
|
|
||||||
}
|
|
||||||
.btn-primary {
|
|
||||||
background-image: -webkit-linear-gradient(top, #428bca 0%, #2d6ca2 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #428bca 0%, #2d6ca2 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff2d6ca2', GradientType=0);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
border-color: #2b669a;
|
|
||||||
}
|
|
||||||
.btn-primary:hover,
|
|
||||||
.btn-primary:focus {
|
|
||||||
background-color: #2d6ca2;
|
|
||||||
background-position: 0 -15px;
|
|
||||||
}
|
|
||||||
.btn-primary:active,
|
|
||||||
.btn-primary.active {
|
|
||||||
background-color: #2d6ca2;
|
|
||||||
border-color: #2b669a;
|
|
||||||
}
|
|
||||||
.btn-success {
|
|
||||||
background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
border-color: #3e8f3e;
|
|
||||||
}
|
|
||||||
.btn-success:hover,
|
|
||||||
.btn-success:focus {
|
|
||||||
background-color: #419641;
|
|
||||||
background-position: 0 -15px;
|
|
||||||
}
|
|
||||||
.btn-success:active,
|
|
||||||
.btn-success.active {
|
|
||||||
background-color: #419641;
|
|
||||||
border-color: #3e8f3e;
|
|
||||||
}
|
|
||||||
.btn-info {
|
|
||||||
background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
border-color: #28a4c9;
|
|
||||||
}
|
|
||||||
.btn-info:hover,
|
|
||||||
.btn-info:focus {
|
|
||||||
background-color: #2aabd2;
|
|
||||||
background-position: 0 -15px;
|
|
||||||
}
|
|
||||||
.btn-info:active,
|
|
||||||
.btn-info.active {
|
|
||||||
background-color: #2aabd2;
|
|
||||||
border-color: #28a4c9;
|
|
||||||
}
|
|
||||||
.btn-warning {
|
|
||||||
background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
border-color: #e38d13;
|
|
||||||
}
|
|
||||||
.btn-warning:hover,
|
|
||||||
.btn-warning:focus {
|
|
||||||
background-color: #eb9316;
|
|
||||||
background-position: 0 -15px;
|
|
||||||
}
|
|
||||||
.btn-warning:active,
|
|
||||||
.btn-warning.active {
|
|
||||||
background-color: #eb9316;
|
|
||||||
border-color: #e38d13;
|
|
||||||
}
|
|
||||||
.btn-danger {
|
|
||||||
background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
border-color: #b92c28;
|
|
||||||
}
|
|
||||||
.btn-danger:hover,
|
|
||||||
.btn-danger:focus {
|
|
||||||
background-color: #c12e2a;
|
|
||||||
background-position: 0 -15px;
|
|
||||||
}
|
|
||||||
.btn-danger:active,
|
|
||||||
.btn-danger.active {
|
|
||||||
background-color: #c12e2a;
|
|
||||||
border-color: #b92c28;
|
|
||||||
}
|
|
||||||
.thumbnail,
|
|
||||||
.img-thumbnail {
|
|
||||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);
|
|
||||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);
|
|
||||||
}
|
|
||||||
.dropdown-menu > li > a:hover,
|
|
||||||
.dropdown-menu > li > a:focus {
|
|
||||||
background-color: #e8e8e8;
|
|
||||||
background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
}
|
|
||||||
.dropdown-menu > .active > a,
|
|
||||||
.dropdown-menu > .active > a:hover,
|
|
||||||
.dropdown-menu > .active > a:focus {
|
|
||||||
background-color: #357ebd;
|
|
||||||
background-image: -webkit-linear-gradient(top, #428bca 0%, #357ebd 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #428bca 0%, #357ebd 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
}
|
|
||||||
.navbar-default {
|
|
||||||
background-image: -webkit-linear-gradient(top, #fff 0%, #f8f8f8 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #fff 0%, #f8f8f8 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
border-radius: 4px;
|
|
||||||
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);
|
|
||||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);
|
|
||||||
}
|
|
||||||
.navbar-default .navbar-nav > .active > a {
|
|
||||||
background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f3f3f3 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #ebebeb 0%, #f3f3f3 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff3f3f3', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
-webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);
|
|
||||||
box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);
|
|
||||||
}
|
|
||||||
.navbar-brand,
|
|
||||||
.navbar-nav > li > a {
|
|
||||||
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.25);
|
|
||||||
}
|
|
||||||
.navbar-inverse {
|
|
||||||
background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
}
|
|
||||||
.navbar-inverse .navbar-nav > .active > a {
|
|
||||||
background-image: -webkit-linear-gradient(top, #222 0%, #282828 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #222 0%, #282828 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff282828', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
-webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);
|
|
||||||
box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);
|
|
||||||
}
|
|
||||||
.navbar-inverse .navbar-brand,
|
|
||||||
.navbar-inverse .navbar-nav > li > a {
|
|
||||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
|
||||||
}
|
|
||||||
.navbar-static-top,
|
|
||||||
.navbar-fixed-top,
|
|
||||||
.navbar-fixed-bottom {
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
.alert {
|
|
||||||
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.2);
|
|
||||||
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);
|
|
||||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);
|
|
||||||
}
|
|
||||||
.alert-success {
|
|
||||||
background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
border-color: #b2dba1;
|
|
||||||
}
|
|
||||||
.alert-info {
|
|
||||||
background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
border-color: #9acfea;
|
|
||||||
}
|
|
||||||
.alert-warning {
|
|
||||||
background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
border-color: #f5e79e;
|
|
||||||
}
|
|
||||||
.alert-danger {
|
|
||||||
background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
border-color: #dca7a7;
|
|
||||||
}
|
|
||||||
.progress {
|
|
||||||
background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
}
|
|
||||||
.progress-bar {
|
|
||||||
background-image: -webkit-linear-gradient(top, #428bca 0%, #3071a9 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #428bca 0%, #3071a9 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3071a9', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
}
|
|
||||||
.progress-bar-success {
|
|
||||||
background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
}
|
|
||||||
.progress-bar-info {
|
|
||||||
background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
}
|
|
||||||
.progress-bar-warning {
|
|
||||||
background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
}
|
|
||||||
.progress-bar-danger {
|
|
||||||
background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
}
|
|
||||||
.list-group {
|
|
||||||
border-radius: 4px;
|
|
||||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);
|
|
||||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);
|
|
||||||
}
|
|
||||||
.list-group-item.active,
|
|
||||||
.list-group-item.active:hover,
|
|
||||||
.list-group-item.active:focus {
|
|
||||||
text-shadow: 0 -1px 0 #3071a9;
|
|
||||||
background-image: -webkit-linear-gradient(top, #428bca 0%, #3278b3 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #428bca 0%, #3278b3 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3278b3', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
border-color: #3278b3;
|
|
||||||
}
|
|
||||||
.panel {
|
|
||||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
|
|
||||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
|
|
||||||
}
|
|
||||||
.panel-default > .panel-heading {
|
|
||||||
background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
}
|
|
||||||
.panel-primary > .panel-heading {
|
|
||||||
background-image: -webkit-linear-gradient(top, #428bca 0%, #357ebd 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #428bca 0%, #357ebd 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
}
|
|
||||||
.panel-success > .panel-heading {
|
|
||||||
background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
}
|
|
||||||
.panel-info > .panel-heading {
|
|
||||||
background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
}
|
|
||||||
.panel-warning > .panel-heading {
|
|
||||||
background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
}
|
|
||||||
.panel-danger > .panel-heading {
|
|
||||||
background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
}
|
|
||||||
.well {
|
|
||||||
background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
border-color: #dcdcdc;
|
|
||||||
-webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);
|
|
||||||
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);
|
|
||||||
}
|
|
||||||
/*# sourceMappingURL=bootstrap-theme.css.map */
|
|
346
libraries/bootstrap/css/bootstrap-theme.min.css
vendored
@ -1,346 +0,0 @@
|
|||||||
/*!
|
|
||||||
* Bootstrap v3.1.1 (http://getbootstrap.com)
|
|
||||||
* Copyright 2011-2014 Twitter, Inc.
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
|
||||||
*/
|
|
||||||
|
|
||||||
.btn-default,
|
|
||||||
.btn-primary,
|
|
||||||
.btn-success,
|
|
||||||
.btn-info,
|
|
||||||
.btn-warning,
|
|
||||||
.btn-danger {
|
|
||||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);
|
|
||||||
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);
|
|
||||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);
|
|
||||||
}
|
|
||||||
.btn-default:active,
|
|
||||||
.btn-primary:active,
|
|
||||||
.btn-success:active,
|
|
||||||
.btn-info:active,
|
|
||||||
.btn-warning:active,
|
|
||||||
.btn-danger:active,
|
|
||||||
.btn-default.active,
|
|
||||||
.btn-primary.active,
|
|
||||||
.btn-success.active,
|
|
||||||
.btn-info.active,
|
|
||||||
.btn-warning.active,
|
|
||||||
.btn-danger.active {
|
|
||||||
-webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
|
|
||||||
box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
|
|
||||||
}
|
|
||||||
.btn:active,
|
|
||||||
.btn.active {
|
|
||||||
background-image: none;
|
|
||||||
}
|
|
||||||
.btn-default {
|
|
||||||
background-image: -webkit-linear-gradient(top, #fff 0, #e0e0e0 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #fff 0, #e0e0e0 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
border-color: #dbdbdb;
|
|
||||||
text-shadow: 0 1px 0 #fff;
|
|
||||||
border-color: #ccc;
|
|
||||||
}
|
|
||||||
.btn-default:hover,
|
|
||||||
.btn-default:focus {
|
|
||||||
background-color: #e0e0e0;
|
|
||||||
background-position: 0 -15px;
|
|
||||||
}
|
|
||||||
.btn-default:active,
|
|
||||||
.btn-default.active {
|
|
||||||
background-color: #e0e0e0;
|
|
||||||
border-color: #dbdbdb;
|
|
||||||
}
|
|
||||||
.btn-primary {
|
|
||||||
background-image: -webkit-linear-gradient(top, #428bca 0, #2d6ca2 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #428bca 0, #2d6ca2 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff2d6ca2', GradientType=0);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
border-color: #2b669a;
|
|
||||||
}
|
|
||||||
.btn-primary:hover,
|
|
||||||
.btn-primary:focus {
|
|
||||||
background-color: #2d6ca2;
|
|
||||||
background-position: 0 -15px;
|
|
||||||
}
|
|
||||||
.btn-primary:active,
|
|
||||||
.btn-primary.active {
|
|
||||||
background-color: #2d6ca2;
|
|
||||||
border-color: #2b669a;
|
|
||||||
}
|
|
||||||
.btn-success {
|
|
||||||
background-image: -webkit-linear-gradient(top, #5cb85c 0, #419641 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #5cb85c 0, #419641 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
border-color: #3e8f3e;
|
|
||||||
}
|
|
||||||
.btn-success:hover,
|
|
||||||
.btn-success:focus {
|
|
||||||
background-color: #419641;
|
|
||||||
background-position: 0 -15px;
|
|
||||||
}
|
|
||||||
.btn-success:active,
|
|
||||||
.btn-success.active {
|
|
||||||
background-color: #419641;
|
|
||||||
border-color: #3e8f3e;
|
|
||||||
}
|
|
||||||
.btn-info {
|
|
||||||
background-image: -webkit-linear-gradient(top, #5bc0de 0, #2aabd2 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #5bc0de 0, #2aabd2 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
border-color: #28a4c9;
|
|
||||||
}
|
|
||||||
.btn-info:hover,
|
|
||||||
.btn-info:focus {
|
|
||||||
background-color: #2aabd2;
|
|
||||||
background-position: 0 -15px;
|
|
||||||
}
|
|
||||||
.btn-info:active,
|
|
||||||
.btn-info.active {
|
|
||||||
background-color: #2aabd2;
|
|
||||||
border-color: #28a4c9;
|
|
||||||
}
|
|
||||||
.btn-warning {
|
|
||||||
background-image: -webkit-linear-gradient(top, #f0ad4e 0, #eb9316 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #f0ad4e 0, #eb9316 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
border-color: #e38d13;
|
|
||||||
}
|
|
||||||
.btn-warning:hover,
|
|
||||||
.btn-warning:focus {
|
|
||||||
background-color: #eb9316;
|
|
||||||
background-position: 0 -15px;
|
|
||||||
}
|
|
||||||
.btn-warning:active,
|
|
||||||
.btn-warning.active {
|
|
||||||
background-color: #eb9316;
|
|
||||||
border-color: #e38d13;
|
|
||||||
}
|
|
||||||
.btn-danger {
|
|
||||||
background-image: -webkit-linear-gradient(top, #d9534f 0, #c12e2a 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #d9534f 0, #c12e2a 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
border-color: #b92c28;
|
|
||||||
}
|
|
||||||
.btn-danger:hover,
|
|
||||||
.btn-danger:focus {
|
|
||||||
background-color: #c12e2a;
|
|
||||||
background-position: 0 -15px;
|
|
||||||
}
|
|
||||||
.btn-danger:active,
|
|
||||||
.btn-danger.active {
|
|
||||||
background-color: #c12e2a;
|
|
||||||
border-color: #b92c28;
|
|
||||||
}
|
|
||||||
.thumbnail,
|
|
||||||
.img-thumbnail {
|
|
||||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);
|
|
||||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);
|
|
||||||
}
|
|
||||||
.dropdown-menu > li > a:hover,
|
|
||||||
.dropdown-menu > li > a:focus {
|
|
||||||
background-image: -webkit-linear-gradient(top, #f5f5f5 0, #e8e8e8 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #f5f5f5 0, #e8e8e8 100%);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
|
|
||||||
background-color: #e8e8e8;
|
|
||||||
}
|
|
||||||
.dropdown-menu > .active > a,
|
|
||||||
.dropdown-menu > .active > a:hover,
|
|
||||||
.dropdown-menu > .active > a:focus {
|
|
||||||
background-image: -webkit-linear-gradient(top, #428bca 0, #357ebd 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #428bca 0, #357ebd 100%);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0);
|
|
||||||
background-color: #357ebd;
|
|
||||||
}
|
|
||||||
.navbar-default {
|
|
||||||
background-image: -webkit-linear-gradient(top, #fff 0, #f8f8f8 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #fff 0, #f8f8f8 100%);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
|
||||||
border-radius: 4px;
|
|
||||||
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);
|
|
||||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);
|
|
||||||
}
|
|
||||||
.navbar-default .navbar-nav > .active > a {
|
|
||||||
background-image: -webkit-linear-gradient(top, #ebebeb 0, #f3f3f3 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #ebebeb 0, #f3f3f3 100%);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff3f3f3', GradientType=0);
|
|
||||||
-webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);
|
|
||||||
box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);
|
|
||||||
}
|
|
||||||
.navbar-brand,
|
|
||||||
.navbar-nav > li > a {
|
|
||||||
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.25);
|
|
||||||
}
|
|
||||||
.navbar-inverse {
|
|
||||||
background-image: -webkit-linear-gradient(top, #3c3c3c 0, #222 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #3c3c3c 0, #222 100%);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
|
||||||
}
|
|
||||||
.navbar-inverse .navbar-nav > .active > a {
|
|
||||||
background-image: -webkit-linear-gradient(top, #222 0, #282828 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #222 0, #282828 100%);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff282828', GradientType=0);
|
|
||||||
-webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);
|
|
||||||
box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);
|
|
||||||
}
|
|
||||||
.navbar-inverse .navbar-brand,
|
|
||||||
.navbar-inverse .navbar-nav > li > a {
|
|
||||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
|
||||||
}
|
|
||||||
.navbar-static-top,
|
|
||||||
.navbar-fixed-top,
|
|
||||||
.navbar-fixed-bottom {
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
.alert {
|
|
||||||
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.2);
|
|
||||||
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);
|
|
||||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);
|
|
||||||
}
|
|
||||||
.alert-success {
|
|
||||||
background-image: -webkit-linear-gradient(top, #dff0d8 0, #c8e5bc 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #dff0d8 0, #c8e5bc 100%);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);
|
|
||||||
border-color: #b2dba1;
|
|
||||||
}
|
|
||||||
.alert-info {
|
|
||||||
background-image: -webkit-linear-gradient(top, #d9edf7 0, #b9def0 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #d9edf7 0, #b9def0 100%);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);
|
|
||||||
border-color: #9acfea;
|
|
||||||
}
|
|
||||||
.alert-warning {
|
|
||||||
background-image: -webkit-linear-gradient(top, #fcf8e3 0, #f8efc0 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #fcf8e3 0, #f8efc0 100%);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);
|
|
||||||
border-color: #f5e79e;
|
|
||||||
}
|
|
||||||
.alert-danger {
|
|
||||||
background-image: -webkit-linear-gradient(top, #f2dede 0, #e7c3c3 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #f2dede 0, #e7c3c3 100%);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);
|
|
||||||
border-color: #dca7a7;
|
|
||||||
}
|
|
||||||
.progress {
|
|
||||||
background-image: -webkit-linear-gradient(top, #ebebeb 0, #f5f5f5 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #ebebeb 0, #f5f5f5 100%);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);
|
|
||||||
}
|
|
||||||
.progress-bar {
|
|
||||||
background-image: -webkit-linear-gradient(top, #428bca 0, #3071a9 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #428bca 0, #3071a9 100%);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3071a9', GradientType=0);
|
|
||||||
}
|
|
||||||
.progress-bar-success {
|
|
||||||
background-image: -webkit-linear-gradient(top, #5cb85c 0, #449d44 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #5cb85c 0, #449d44 100%);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);
|
|
||||||
}
|
|
||||||
.progress-bar-info {
|
|
||||||
background-image: -webkit-linear-gradient(top, #5bc0de 0, #31b0d5 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #5bc0de 0, #31b0d5 100%);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);
|
|
||||||
}
|
|
||||||
.progress-bar-warning {
|
|
||||||
background-image: -webkit-linear-gradient(top, #f0ad4e 0, #ec971f 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #f0ad4e 0, #ec971f 100%);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);
|
|
||||||
}
|
|
||||||
.progress-bar-danger {
|
|
||||||
background-image: -webkit-linear-gradient(top, #d9534f 0, #c9302c 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #d9534f 0, #c9302c 100%);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);
|
|
||||||
}
|
|
||||||
.list-group {
|
|
||||||
border-radius: 4px;
|
|
||||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);
|
|
||||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);
|
|
||||||
}
|
|
||||||
.list-group-item.active,
|
|
||||||
.list-group-item.active:hover,
|
|
||||||
.list-group-item.active:focus {
|
|
||||||
text-shadow: 0 -1px 0 #3071a9;
|
|
||||||
background-image: -webkit-linear-gradient(top, #428bca 0, #3278b3 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #428bca 0, #3278b3 100%);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3278b3', GradientType=0);
|
|
||||||
border-color: #3278b3;
|
|
||||||
}
|
|
||||||
.panel {
|
|
||||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
|
|
||||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
|
|
||||||
}
|
|
||||||
.panel-default > .panel-heading {
|
|
||||||
background-image: -webkit-linear-gradient(top, #f5f5f5 0, #e8e8e8 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #f5f5f5 0, #e8e8e8 100%);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
|
|
||||||
}
|
|
||||||
.panel-primary > .panel-heading {
|
|
||||||
background-image: -webkit-linear-gradient(top, #428bca 0, #357ebd 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #428bca 0, #357ebd 100%);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0);
|
|
||||||
}
|
|
||||||
.panel-success > .panel-heading {
|
|
||||||
background-image: -webkit-linear-gradient(top, #dff0d8 0, #d0e9c6 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #dff0d8 0, #d0e9c6 100%);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);
|
|
||||||
}
|
|
||||||
.panel-info > .panel-heading {
|
|
||||||
background-image: -webkit-linear-gradient(top, #d9edf7 0, #c4e3f3 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #d9edf7 0, #c4e3f3 100%);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);
|
|
||||||
}
|
|
||||||
.panel-warning > .panel-heading {
|
|
||||||
background-image: -webkit-linear-gradient(top, #fcf8e3 0, #faf2cc 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #fcf8e3 0, #faf2cc 100%);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);
|
|
||||||
}
|
|
||||||
.panel-danger > .panel-heading {
|
|
||||||
background-image: -webkit-linear-gradient(top, #f2dede 0, #ebcccc 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #f2dede 0, #ebcccc 100%);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);
|
|
||||||
}
|
|
||||||
.well {
|
|
||||||
background-image: -webkit-linear-gradient(top, #e8e8e8 0, #f5f5f5 100%);
|
|
||||||
background-image: linear-gradient(to bottom, #e8e8e8 0, #f5f5f5 100%);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);
|
|
||||||
border-color: #dcdcdc;
|
|
||||||
-webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);
|
|
||||||
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);
|
|
||||||
}
|
|
6057
libraries/bootstrap/css/bootstrap.css
vendored
6051
libraries/bootstrap/css/bootstrap.min.css
vendored
@ -1,229 +0,0 @@
|
|||||||
<?xml version="1.0" standalone="no"?>
|
|
||||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<metadata></metadata>
|
|
||||||
<defs>
|
|
||||||
<font id="glyphicons_halflingsregular" horiz-adv-x="1200" >
|
|
||||||
<font-face units-per-em="1200" ascent="960" descent="-240" />
|
|
||||||
<missing-glyph horiz-adv-x="500" />
|
|
||||||
<glyph />
|
|
||||||
<glyph />
|
|
||||||
<glyph unicode="
" />
|
|
||||||
<glyph unicode=" " />
|
|
||||||
<glyph unicode="*" d="M100 500v200h259l-183 183l141 141l183 -183v259h200v-259l183 183l141 -141l-183 -183h259v-200h-259l183 -183l-141 -141l-183 183v-259h-200v259l-183 -183l-141 141l183 183h-259z" />
|
|
||||||
<glyph unicode="+" d="M0 400v300h400v400h300v-400h400v-300h-400v-400h-300v400h-400z" />
|
|
||||||
<glyph unicode=" " />
|
|
||||||
<glyph unicode=" " horiz-adv-x="652" />
|
|
||||||
<glyph unicode=" " horiz-adv-x="1304" />
|
|
||||||
<glyph unicode=" " horiz-adv-x="652" />
|
|
||||||
<glyph unicode=" " horiz-adv-x="1304" />
|
|
||||||
<glyph unicode=" " horiz-adv-x="434" />
|
|
||||||
<glyph unicode=" " horiz-adv-x="326" />
|
|
||||||
<glyph unicode=" " horiz-adv-x="217" />
|
|
||||||
<glyph unicode=" " horiz-adv-x="217" />
|
|
||||||
<glyph unicode=" " horiz-adv-x="163" />
|
|
||||||
<glyph unicode=" " horiz-adv-x="260" />
|
|
||||||
<glyph unicode=" " horiz-adv-x="72" />
|
|
||||||
<glyph unicode=" " horiz-adv-x="260" />
|
|
||||||
<glyph unicode=" " horiz-adv-x="326" />
|
|
||||||
<glyph unicode="€" d="M100 500l100 100h113q0 47 5 100h-218l100 100h135q37 167 112 257q117 141 297 141q242 0 354 -189q60 -103 66 -209h-181q0 55 -25.5 99t-63.5 68t-75 36.5t-67 12.5q-24 0 -52.5 -10t-62.5 -32t-65.5 -67t-50.5 -107h379l-100 -100h-300q-6 -46 -6 -100h406l-100 -100 h-300q9 -74 33 -132t52.5 -91t62 -54.5t59 -29t46.5 -7.5q29 0 66 13t75 37t63.5 67.5t25.5 96.5h174q-31 -172 -128 -278q-107 -117 -274 -117q-205 0 -324 158q-36 46 -69 131.5t-45 205.5h-217z" />
|
|
||||||
<glyph unicode="−" d="M200 400h900v300h-900v-300z" />
|
|
||||||
<glyph unicode="◼" horiz-adv-x="500" d="M0 0z" />
|
|
||||||
<glyph unicode="☁" d="M-14 494q0 -80 56.5 -137t135.5 -57h750q120 0 205 86.5t85 207.5t-85 207t-205 86q-46 0 -90 -14q-44 97 -134.5 156.5t-200.5 59.5q-152 0 -260 -107.5t-108 -260.5q0 -25 2 -37q-66 -14 -108.5 -67.5t-42.5 -122.5z" />
|
|
||||||
<glyph unicode="✉" d="M0 100l400 400l200 -200l200 200l400 -400h-1200zM0 300v600l300 -300zM0 1100l600 -603l600 603h-1200zM900 600l300 300v-600z" />
|
|
||||||
<glyph unicode="✏" d="M-13 -13l333 112l-223 223zM187 403l214 -214l614 614l-214 214zM887 1103l214 -214l99 92q13 13 13 32.5t-13 33.5l-153 153q-15 13 -33 13t-33 -13z" />
|
|
||||||
<glyph unicode="" d="M0 1200h1200l-500 -550v-550h300v-100h-800v100h300v550z" />
|
|
||||||
<glyph unicode="" d="M14 84q18 -55 86 -75.5t147 5.5q65 21 109 69t44 90v606l600 155v-521q-64 16 -138 -7q-79 -26 -122.5 -83t-25.5 -111q18 -55 86 -75.5t147 4.5q70 23 111.5 63.5t41.5 95.5v881q0 10 -7 15.5t-17 2.5l-752 -193q-10 -3 -17 -12.5t-7 -19.5v-689q-64 17 -138 -7 q-79 -25 -122.5 -82t-25.5 -112z" />
|
|
||||||
<glyph unicode="" d="M23 693q0 200 142 342t342 142t342 -142t142 -342q0 -142 -78 -261l300 -300q7 -8 7 -18t-7 -18l-109 -109q-8 -7 -18 -7t-18 7l-300 300q-119 -78 -261 -78q-200 0 -342 142t-142 342zM176 693q0 -136 97 -233t234 -97t233.5 96.5t96.5 233.5t-96.5 233.5t-233.5 96.5 t-234 -97t-97 -233z" />
|
|
||||||
<glyph unicode="" d="M100 784q0 64 28 123t73 100.5t104.5 64t119 20.5t120 -38.5t104.5 -104.5q48 69 109.5 105t121.5 38t118.5 -20.5t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-149.5 152.5t-126.5 127.5 t-94 124.5t-33.5 117.5z" />
|
|
||||||
<glyph unicode="" d="M-72 800h479l146 400h2l146 -400h472l-382 -278l145 -449l-384 275l-382 -275l146 447zM168 71l2 1z" />
|
|
||||||
<glyph unicode="" d="M-72 800h479l146 400h2l146 -400h472l-382 -278l145 -449l-384 275l-382 -275l146 447zM168 71l2 1zM237 700l196 -142l-73 -226l192 140l195 -141l-74 229l193 140h-235l-77 211l-78 -211h-239z" />
|
|
||||||
<glyph unicode="" d="M0 0v143l400 257v100q-37 0 -68.5 74.5t-31.5 125.5v200q0 124 88 212t212 88t212 -88t88 -212v-200q0 -51 -31.5 -125.5t-68.5 -74.5v-100l400 -257v-143h-1200z" />
|
|
||||||
<glyph unicode="" d="M0 0v1100h1200v-1100h-1200zM100 100h100v100h-100v-100zM100 300h100v100h-100v-100zM100 500h100v100h-100v-100zM100 700h100v100h-100v-100zM100 900h100v100h-100v-100zM300 100h600v400h-600v-400zM300 600h600v400h-600v-400zM1000 100h100v100h-100v-100z M1000 300h100v100h-100v-100zM1000 500h100v100h-100v-100zM1000 700h100v100h-100v-100zM1000 900h100v100h-100v-100z" />
|
|
||||||
<glyph unicode="" d="M0 50v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5zM0 650v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5zM600 50v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5zM600 650v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5z" />
|
|
||||||
<glyph unicode="" d="M0 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM0 450v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200 q-21 0 -35.5 14.5t-14.5 35.5zM0 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5 t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 450v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5 v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM800 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM800 450v200q0 21 14.5 35.5t35.5 14.5h200 q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM800 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5z" />
|
|
||||||
<glyph unicode="" d="M0 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM0 450q0 -21 14.5 -35.5t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v200q0 21 -14.5 35.5t-35.5 14.5h-200q-21 0 -35.5 -14.5 t-14.5 -35.5v-200zM0 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 50v200q0 21 14.5 35.5t35.5 14.5h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5 t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5zM400 450v200q0 21 14.5 35.5t35.5 14.5h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5zM400 850v200q0 21 14.5 35.5t35.5 14.5h700q21 0 35.5 -14.5t14.5 -35.5 v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5z" />
|
|
||||||
<glyph unicode="" d="M29 454l419 -420l818 820l-212 212l-607 -607l-206 207z" />
|
|
||||||
<glyph unicode="" d="M106 318l282 282l-282 282l212 212l282 -282l282 282l212 -212l-282 -282l282 -282l-212 -212l-282 282l-282 -282z" />
|
|
||||||
<glyph unicode="" d="M23 693q0 200 142 342t342 142t342 -142t142 -342q0 -142 -78 -261l300 -300q7 -8 7 -18t-7 -18l-109 -109q-8 -7 -18 -7t-18 7l-300 300q-119 -78 -261 -78q-200 0 -342 142t-142 342zM176 693q0 -136 97 -233t234 -97t233.5 96.5t96.5 233.5t-96.5 233.5t-233.5 96.5 t-234 -97t-97 -233zM300 600v200h100v100h200v-100h100v-200h-100v-100h-200v100h-100z" />
|
|
||||||
<glyph unicode="" d="M23 694q0 200 142 342t342 142t342 -142t142 -342q0 -141 -78 -262l300 -299q7 -7 7 -18t-7 -18l-109 -109q-8 -8 -18 -8t-18 8l-300 300q-119 -78 -261 -78q-200 0 -342 142t-142 342zM176 694q0 -136 97 -233t234 -97t233.5 97t96.5 233t-96.5 233t-233.5 97t-234 -97 t-97 -233zM300 601h400v200h-400v-200z" />
|
|
||||||
<glyph unicode="" d="M23 600q0 183 105 331t272 210v-166q-103 -55 -165 -155t-62 -220q0 -177 125 -302t302 -125t302 125t125 302q0 120 -62 220t-165 155v166q167 -62 272 -210t105 -331q0 -118 -45.5 -224.5t-123 -184t-184 -123t-224.5 -45.5t-224.5 45.5t-184 123t-123 184t-45.5 224.5 zM500 750q0 -21 14.5 -35.5t35.5 -14.5h100q21 0 35.5 14.5t14.5 35.5v400q0 21 -14.5 35.5t-35.5 14.5h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-400z" />
|
|
||||||
<glyph unicode="" d="M100 1h200v300h-200v-300zM400 1v500h200v-500h-200zM700 1v800h200v-800h-200zM1000 1v1200h200v-1200h-200z" />
|
|
||||||
<glyph unicode="" d="M26 601q0 -33 6 -74l151 -38l2 -6q14 -49 38 -93l3 -5l-80 -134q45 -59 105 -105l133 81l5 -3q45 -26 94 -39l5 -2l38 -151q40 -5 74 -5q27 0 74 5l38 151l6 2q46 13 93 39l5 3l134 -81q56 44 104 105l-80 134l3 5q24 44 39 93l1 6l152 38q5 40 5 74q0 28 -5 73l-152 38 l-1 6q-16 51 -39 93l-3 5l80 134q-44 58 -104 105l-134 -81l-5 3q-45 25 -93 39l-6 1l-38 152q-40 5 -74 5q-27 0 -74 -5l-38 -152l-5 -1q-50 -14 -94 -39l-5 -3l-133 81q-59 -47 -105 -105l80 -134l-3 -5q-25 -47 -38 -93l-2 -6l-151 -38q-6 -48 -6 -73zM385 601 q0 88 63 151t152 63t152 -63t63 -151q0 -89 -63 -152t-152 -63t-152 63t-63 152z" />
|
|
||||||
<glyph unicode="" d="M100 1025v50q0 10 7.5 17.5t17.5 7.5h275v100q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5v-100h275q10 0 17.5 -7.5t7.5 -17.5v-50q0 -11 -7 -18t-18 -7h-1050q-11 0 -18 7t-7 18zM200 100v800h900v-800q0 -41 -29.5 -71t-70.5 -30h-700q-41 0 -70.5 30 t-29.5 71zM300 100h100v700h-100v-700zM500 100h100v700h-100v-700zM500 1100h300v100h-300v-100zM700 100h100v700h-100v-700zM900 100h100v700h-100v-700z" />
|
|
||||||
<glyph unicode="" d="M1 601l656 644l644 -644h-200v-600h-300v400h-300v-400h-300v600h-200z" />
|
|
||||||
<glyph unicode="" d="M100 25v1150q0 11 7 18t18 7h475v-500h400v-675q0 -11 -7 -18t-18 -7h-850q-11 0 -18 7t-7 18zM700 800v300l300 -300h-300z" />
|
|
||||||
<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM500 500v400h100 v-300h200v-100h-300z" />
|
|
||||||
<glyph unicode="" d="M-100 0l431 1200h209l-21 -300h162l-20 300h208l431 -1200h-538l-41 400h-242l-40 -400h-539zM488 500h224l-27 300h-170z" />
|
|
||||||
<glyph unicode="" d="M0 0v400h490l-290 300h200v500h300v-500h200l-290 -300h490v-400h-1100zM813 200h175v100h-175v-100z" />
|
|
||||||
<glyph unicode="" d="M1 600q0 122 47.5 233t127.5 191t191 127.5t233 47.5t233 -47.5t191 -127.5t127.5 -191t47.5 -233t-47.5 -233t-127.5 -191t-191 -127.5t-233 -47.5t-233 47.5t-191 127.5t-127.5 191t-47.5 233zM188 600q0 -170 121 -291t291 -121t291 121t121 291t-121 291t-291 121 t-291 -121t-121 -291zM350 600h150v300h200v-300h150l-250 -300z" />
|
|
||||||
<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM350 600l250 300 l250 -300h-150v-300h-200v300h-150z" />
|
|
||||||
<glyph unicode="" d="M0 25v475l200 700h800l199 -700l1 -475q0 -11 -7 -18t-18 -7h-1150q-11 0 -18 7t-7 18zM200 500h200l50 -200h300l50 200h200l-97 500h-606z" />
|
|
||||||
<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -172 121.5 -293t292.5 -121t292.5 121t121.5 293q0 171 -121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM500 397v401 l297 -200z" />
|
|
||||||
<glyph unicode="" d="M23 600q0 -118 45.5 -224.5t123 -184t184 -123t224.5 -45.5t224.5 45.5t184 123t123 184t45.5 224.5h-150q0 -177 -125 -302t-302 -125t-302 125t-125 302t125 302t302 125q136 0 246 -81l-146 -146h400v400l-145 -145q-157 122 -355 122q-118 0 -224.5 -45.5t-184 -123 t-123 -184t-45.5 -224.5z" />
|
|
||||||
<glyph unicode="" d="M23 600q0 118 45.5 224.5t123 184t184 123t224.5 45.5q198 0 355 -122l145 145v-400h-400l147 147q-112 80 -247 80q-177 0 -302 -125t-125 -302h-150zM100 0v400h400l-147 -147q112 -80 247 -80q177 0 302 125t125 302h150q0 -118 -45.5 -224.5t-123 -184t-184 -123 t-224.5 -45.5q-198 0 -355 122z" />
|
|
||||||
<glyph unicode="" d="M100 0h1100v1200h-1100v-1200zM200 100v900h900v-900h-900zM300 200v100h100v-100h-100zM300 400v100h100v-100h-100zM300 600v100h100v-100h-100zM300 800v100h100v-100h-100zM500 200h500v100h-500v-100zM500 400v100h500v-100h-500zM500 600v100h500v-100h-500z M500 800v100h500v-100h-500z" />
|
|
||||||
<glyph unicode="" d="M0 100v600q0 41 29.5 70.5t70.5 29.5h100v200q0 82 59 141t141 59h300q82 0 141 -59t59 -141v-200h100q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-900q-41 0 -70.5 29.5t-29.5 70.5zM400 800h300v150q0 21 -14.5 35.5t-35.5 14.5h-200 q-21 0 -35.5 -14.5t-14.5 -35.5v-150z" />
|
|
||||||
<glyph unicode="" d="M100 0v1100h100v-1100h-100zM300 400q60 60 127.5 84t127.5 17.5t122 -23t119 -30t110 -11t103 42t91 120.5v500q-40 -81 -101.5 -115.5t-127.5 -29.5t-138 25t-139.5 40t-125.5 25t-103 -29.5t-65 -115.5v-500z" />
|
|
||||||
<glyph unicode="" d="M0 275q0 -11 7 -18t18 -7h50q11 0 18 7t7 18v300q0 127 70.5 231.5t184.5 161.5t245 57t245 -57t184.5 -161.5t70.5 -231.5v-300q0 -11 7 -18t18 -7h50q11 0 18 7t7 18v300q0 116 -49.5 227t-131 192.5t-192.5 131t-227 49.5t-227 -49.5t-192.5 -131t-131 -192.5 t-49.5 -227v-300zM200 20v460q0 8 6 14t14 6h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14zM800 20v460q0 8 6 14t14 6h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14z" />
|
|
||||||
<glyph unicode="" d="M0 400h300l300 -200v800l-300 -200h-300v-400zM688 459l141 141l-141 141l71 71l141 -141l141 141l71 -71l-141 -141l141 -141l-71 -71l-141 141l-141 -141z" />
|
|
||||||
<glyph unicode="" d="M0 400h300l300 -200v800l-300 -200h-300v-400zM700 857l69 53q111 -135 111 -310q0 -169 -106 -302l-67 54q86 110 86 248q0 146 -93 257z" />
|
|
||||||
<glyph unicode="" d="M0 401v400h300l300 200v-800l-300 200h-300zM702 858l69 53q111 -135 111 -310q0 -170 -106 -303l-67 55q86 110 86 248q0 145 -93 257zM889 951l7 -8q123 -151 123 -344q0 -189 -119 -339l-7 -8l81 -66l6 8q142 178 142 405q0 230 -144 408l-6 8z" />
|
|
||||||
<glyph unicode="" d="M0 0h500v500h-200v100h-100v-100h-200v-500zM0 600h100v100h400v100h100v100h-100v300h-500v-600zM100 100v300h300v-300h-300zM100 800v300h300v-300h-300zM200 200v100h100v-100h-100zM200 900h100v100h-100v-100zM500 500v100h300v-300h200v-100h-100v-100h-200v100 h-100v100h100v200h-200zM600 0v100h100v-100h-100zM600 1000h100v-300h200v-300h300v200h-200v100h200v500h-600v-200zM800 800v300h300v-300h-300zM900 0v100h300v-100h-300zM900 900v100h100v-100h-100zM1100 200v100h100v-100h-100z" />
|
|
||||||
<glyph unicode="" d="M0 200h100v1000h-100v-1000zM100 0v100h300v-100h-300zM200 200v1000h100v-1000h-100zM500 0v91h100v-91h-100zM500 200v1000h200v-1000h-200zM700 0v91h100v-91h-100zM800 200v1000h100v-1000h-100zM900 0v91h200v-91h-200zM1000 200v1000h200v-1000h-200z" />
|
|
||||||
<glyph unicode="" d="M0 700l1 475q0 10 7.5 17.5t17.5 7.5h474l700 -700l-500 -500zM148 953q0 -42 29 -71q30 -30 71.5 -30t71.5 30q29 29 29 71t-29 71q-30 30 -71.5 30t-71.5 -30q-29 -29 -29 -71z" />
|
|
||||||
<glyph unicode="" d="M1 700l1 475q0 11 7 18t18 7h474l700 -700l-500 -500zM148 953q0 -42 30 -71q29 -30 71 -30t71 30q30 29 30 71t-30 71q-29 30 -71 30t-71 -30q-30 -29 -30 -71zM701 1200h100l700 -700l-500 -500l-50 50l450 450z" />
|
|
||||||
<glyph unicode="" d="M100 0v1025l175 175h925v-1000l-100 -100v1000h-750l-100 -100h750v-1000h-900z" />
|
|
||||||
<glyph unicode="" d="M200 0l450 444l450 -443v1150q0 20 -14.5 35t-35.5 15h-800q-21 0 -35.5 -15t-14.5 -35v-1151z" />
|
|
||||||
<glyph unicode="" d="M0 100v700h200l100 -200h600l100 200h200v-700h-200v200h-800v-200h-200zM253 829l40 -124h592l62 124l-94 346q-2 11 -10 18t-18 7h-450q-10 0 -18 -7t-10 -18zM281 24l38 152q2 10 11.5 17t19.5 7h500q10 0 19.5 -7t11.5 -17l38 -152q2 -10 -3.5 -17t-15.5 -7h-600 q-10 0 -15.5 7t-3.5 17z" />
|
|
||||||
<glyph unicode="" d="M0 200q0 -41 29.5 -70.5t70.5 -29.5h1000q41 0 70.5 29.5t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5h-150q-4 8 -11.5 21.5t-33 48t-53 61t-69 48t-83.5 21.5h-200q-41 0 -82 -20.5t-70 -50t-52 -59t-34 -50.5l-12 -20h-150q-41 0 -70.5 -29.5t-29.5 -70.5v-600z M356 500q0 100 72 172t172 72t172 -72t72 -172t-72 -172t-172 -72t-172 72t-72 172zM494 500q0 -44 31 -75t75 -31t75 31t31 75t-31 75t-75 31t-75 -31t-31 -75zM900 700v100h100v-100h-100z" />
|
|
||||||
<glyph unicode="" d="M53 0h365v66q-41 0 -72 11t-49 38t1 71l92 234h391l82 -222q16 -45 -5.5 -88.5t-74.5 -43.5v-66h417v66q-34 1 -74 43q-18 19 -33 42t-21 37l-6 13l-385 998h-93l-399 -1006q-24 -48 -52 -75q-12 -12 -33 -25t-36 -20l-15 -7v-66zM416 521l178 457l46 -140l116 -317h-340 z" />
|
|
||||||
<glyph unicode="" d="M100 0v89q41 7 70.5 32.5t29.5 65.5v827q0 28 -1 39.5t-5.5 26t-15.5 21t-29 14t-49 14.5v71l471 -1q120 0 213 -88t93 -228q0 -55 -11.5 -101.5t-28 -74t-33.5 -47.5t-28 -28l-12 -7q8 -3 21.5 -9t48 -31.5t60.5 -58t47.5 -91.5t21.5 -129q0 -84 -59 -156.5t-142 -111 t-162 -38.5h-500zM400 200h161q89 0 153 48.5t64 132.5q0 90 -62.5 154.5t-156.5 64.5h-159v-400zM400 700h139q76 0 130 61.5t54 138.5q0 82 -84 130.5t-239 48.5v-379z" />
|
|
||||||
<glyph unicode="" d="M200 0v57q77 7 134.5 40.5t65.5 80.5l173 849q10 56 -10 74t-91 37q-6 1 -10.5 2.5t-9.5 2.5v57h425l2 -57q-33 -8 -62 -25.5t-46 -37t-29.5 -38t-17.5 -30.5l-5 -12l-128 -825q-10 -52 14 -82t95 -36v-57h-500z" />
|
|
||||||
<glyph unicode="" d="M-75 200h75v800h-75l125 167l125 -167h-75v-800h75l-125 -167zM300 900v300h150h700h150v-300h-50q0 29 -8 48.5t-18.5 30t-33.5 15t-39.5 5.5t-50.5 1h-200v-850l100 -50v-100h-400v100l100 50v850h-200q-34 0 -50.5 -1t-40 -5.5t-33.5 -15t-18.5 -30t-8.5 -48.5h-49z " />
|
|
||||||
<glyph unicode="" d="M33 51l167 125v-75h800v75l167 -125l-167 -125v75h-800v-75zM100 901v300h150h700h150v-300h-50q0 29 -8 48.5t-18 30t-33.5 15t-40 5.5t-50.5 1h-200v-650l100 -50v-100h-400v100l100 50v650h-200q-34 0 -50.5 -1t-39.5 -5.5t-33.5 -15t-18.5 -30t-8 -48.5h-50z" />
|
|
||||||
<glyph unicode="" d="M0 50q0 -20 14.5 -35t35.5 -15h1100q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM0 350q0 -20 14.5 -35t35.5 -15h800q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-800q-21 0 -35.5 -14.5t-14.5 -35.5 v-100zM0 650q0 -20 14.5 -35t35.5 -15h1000q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1000q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM0 950q0 -20 14.5 -35t35.5 -15h600q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-600q-21 0 -35.5 -14.5 t-14.5 -35.5v-100z" />
|
|
||||||
<glyph unicode="" d="M0 50q0 -20 14.5 -35t35.5 -15h1100q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM0 650q0 -20 14.5 -35t35.5 -15h1100q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5 v-100zM200 350q0 -20 14.5 -35t35.5 -15h700q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-700q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM200 950q0 -20 14.5 -35t35.5 -15h700q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-700q-21 0 -35.5 -14.5 t-14.5 -35.5v-100z" />
|
|
||||||
<glyph unicode="" d="M0 50v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15t-14.5 35zM100 650v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1000q-21 0 -35.5 15 t-14.5 35zM300 350v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800q-21 0 -35.5 15t-14.5 35zM500 950v100q0 21 14.5 35.5t35.5 14.5h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-600 q-21 0 -35.5 15t-14.5 35z" />
|
|
||||||
<glyph unicode="" d="M0 50v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15t-14.5 35zM0 350v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15 t-14.5 35zM0 650v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15t-14.5 35zM0 950v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100 q-21 0 -35.5 15t-14.5 35z" />
|
|
||||||
<glyph unicode="" d="M0 50v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15t-14.5 35zM0 350v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15 t-14.5 35zM0 650v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15t-14.5 35zM0 950v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15 t-14.5 35zM300 50v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800q-21 0 -35.5 15t-14.5 35zM300 350v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800 q-21 0 -35.5 15t-14.5 35zM300 650v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800q-21 0 -35.5 15t-14.5 35zM300 950v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15 h-800q-21 0 -35.5 15t-14.5 35z" />
|
|
||||||
<glyph unicode="" d="M-101 500v100h201v75l166 -125l-166 -125v75h-201zM300 0h100v1100h-100v-1100zM500 50q0 -20 14.5 -35t35.5 -15h600q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-600q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM500 350q0 -20 14.5 -35t35.5 -15h300q20 0 35 15t15 35 v100q0 21 -15 35.5t-35 14.5h-300q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM500 650q0 -20 14.5 -35t35.5 -15h500q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM500 950q0 -20 14.5 -35t35.5 -15h100q20 0 35 15t15 35v100 q0 21 -15 35.5t-35 14.5h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-100z" />
|
|
||||||
<glyph unicode="" d="M1 50q0 -20 14.5 -35t35.5 -15h600q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-600q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM1 350q0 -20 14.5 -35t35.5 -15h300q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-300q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM1 650 q0 -20 14.5 -35t35.5 -15h500q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM1 950q0 -20 14.5 -35t35.5 -15h100q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM801 0v1100h100v-1100 h-100zM934 550l167 -125v75h200v100h-200v75z" />
|
|
||||||
<glyph unicode="" d="M0 275v650q0 31 22 53t53 22h750q31 0 53 -22t22 -53v-650q0 -31 -22 -53t-53 -22h-750q-31 0 -53 22t-22 53zM900 600l300 300v-600z" />
|
|
||||||
<glyph unicode="" d="M0 44v1012q0 18 13 31t31 13h1112q19 0 31.5 -13t12.5 -31v-1012q0 -18 -12.5 -31t-31.5 -13h-1112q-18 0 -31 13t-13 31zM100 263l247 182l298 -131l-74 156l293 318l236 -288v500h-1000v-737zM208 750q0 56 39 95t95 39t95 -39t39 -95t-39 -95t-95 -39t-95 39t-39 95z " />
|
|
||||||
<glyph unicode="" d="M148 745q0 124 60.5 231.5t165 172t226.5 64.5q123 0 227 -63t164.5 -169.5t60.5 -229.5t-73 -272q-73 -114 -166.5 -237t-150.5 -189l-57 -66q-10 9 -27 26t-66.5 70.5t-96 109t-104 135.5t-100.5 155q-63 139 -63 262zM342 772q0 -107 75.5 -182.5t181.5 -75.5 q107 0 182.5 75.5t75.5 182.5t-75.5 182t-182.5 75t-182 -75.5t-75 -181.5z" />
|
|
||||||
<glyph unicode="" d="M1 600q0 122 47.5 233t127.5 191t191 127.5t233 47.5t233 -47.5t191 -127.5t127.5 -191t47.5 -233t-47.5 -233t-127.5 -191t-191 -127.5t-233 -47.5t-233 47.5t-191 127.5t-127.5 191t-47.5 233zM173 600q0 -177 125.5 -302t301.5 -125v854q-176 0 -301.5 -125 t-125.5 -302z" />
|
|
||||||
<glyph unicode="" d="M117 406q0 94 34 186t88.5 172.5t112 159t115 177t87.5 194.5q21 -71 57.5 -142.5t76 -130.5t83 -118.5t82 -117t70 -116t50 -125.5t18.5 -136q0 -89 -39 -165.5t-102 -126.5t-140 -79.5t-156 -33.5q-114 6 -211.5 53t-161.5 139t-64 210zM243 414q14 -82 59.5 -136 t136.5 -80l16 98q-7 6 -18 17t-34 48t-33 77q-15 73 -14 143.5t10 122.5l9 51q-92 -110 -119.5 -185t-12.5 -156z" />
|
|
||||||
<glyph unicode="" d="M0 400v300q0 165 117.5 282.5t282.5 117.5q366 -6 397 -14l-186 -186h-311q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v125l200 200v-225q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5 t-117.5 282.5zM436 341l161 50l412 412l-114 113l-405 -405zM995 1015l113 -113l113 113l-21 85l-92 28z" />
|
|
||||||
<glyph unicode="" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h261l2 -80q-133 -32 -218 -120h-145q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5l200 153v-53q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5t-117.5 282.5 zM423 524q30 38 81.5 64t103 35.5t99 14t77.5 3.5l29 -1v-209l360 324l-359 318v-216q-7 0 -19 -1t-48 -8t-69.5 -18.5t-76.5 -37t-76.5 -59t-62 -88t-39.5 -121.5z" />
|
|
||||||
<glyph unicode="" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h300q61 0 127 -23l-178 -177h-349q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v69l200 200v-169q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5 t-117.5 282.5zM342 632l283 -284l567 567l-137 137l-430 -431l-146 147z" />
|
|
||||||
<glyph unicode="" d="M0 603l300 296v-198h200v200h-200l300 300l295 -300h-195v-200h200v198l300 -296l-300 -300v198h-200v-200h195l-295 -300l-300 300h200v200h-200v-198z" />
|
|
||||||
<glyph unicode="" d="M200 50v1000q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-437l500 487v-1100l-500 488v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5z" />
|
|
||||||
<glyph unicode="" d="M0 50v1000q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-437l500 487v-487l500 487v-1100l-500 488v-488l-500 488v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5z" />
|
|
||||||
<glyph unicode="" d="M136 550l564 550v-487l500 487v-1100l-500 488v-488z" />
|
|
||||||
<glyph unicode="" d="M200 0l900 550l-900 550v-1100z" />
|
|
||||||
<glyph unicode="" d="M200 150q0 -21 14.5 -35.5t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v800q0 21 -14.5 35.5t-35.5 14.5h-200q-21 0 -35.5 -14.5t-14.5 -35.5v-800zM600 150q0 -21 14.5 -35.5t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v800q0 21 -14.5 35.5t-35.5 14.5h-200 q-21 0 -35.5 -14.5t-14.5 -35.5v-800z" />
|
|
||||||
<glyph unicode="" d="M200 150q0 -20 14.5 -35t35.5 -15h800q21 0 35.5 15t14.5 35v800q0 21 -14.5 35.5t-35.5 14.5h-800q-21 0 -35.5 -14.5t-14.5 -35.5v-800z" />
|
|
||||||
<glyph unicode="" d="M0 0v1100l500 -487v487l564 -550l-564 -550v488z" />
|
|
||||||
<glyph unicode="" d="M0 0v1100l500 -487v487l500 -487v437q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-1000q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v438l-500 -488v488z" />
|
|
||||||
<glyph unicode="" d="M300 0v1100l500 -487v437q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-1000q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v438z" />
|
|
||||||
<glyph unicode="" d="M100 250v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5zM100 500h1100l-550 564z" />
|
|
||||||
<glyph unicode="" d="M185 599l592 -592l240 240l-353 353l353 353l-240 240z" />
|
|
||||||
<glyph unicode="" d="M272 194l353 353l-353 353l241 240l572 -571l21 -22l-1 -1v-1l-592 -591z" />
|
|
||||||
<glyph unicode="" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM300 500h200v-200h200v200h200v200h-200v200h-200v-200h-200v-200z" />
|
|
||||||
<glyph unicode="" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM300 500h600v200h-600v-200z" />
|
|
||||||
<glyph unicode="" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM246 459l213 -213l141 142l141 -142l213 213l-142 141l142 141l-213 212l-141 -141l-141 142l-212 -213l141 -141 z" />
|
|
||||||
<glyph unicode="" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM270 551l276 -277l411 411l-175 174l-236 -236l-102 102z" />
|
|
||||||
<glyph unicode="" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM364 700h143q4 0 11.5 -1t11 -1t6.5 3t3 9t1 11t3.5 8.5t3.5 6t5.5 4t6.5 2.5t9 1.5t9 0.5h11.5h12.5 q19 0 30 -10t11 -26q0 -22 -4 -28t-27 -22q-5 -1 -12.5 -3t-27 -13.5t-34 -27t-26.5 -46t-11 -68.5h200q5 3 14 8t31.5 25.5t39.5 45.5t31 69t14 94q0 51 -17.5 89t-42 58t-58.5 32t-58.5 15t-51.5 3q-50 0 -90.5 -12t-75 -38.5t-53.5 -74.5t-19 -114zM500 300h200v100h-200 v-100z" />
|
|
||||||
<glyph unicode="" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM400 300h400v100h-100v300h-300v-100h100v-200h-100v-100zM500 800h200v100h-200v-100z" />
|
|
||||||
<glyph unicode="" d="M0 500v200h195q31 125 98.5 199.5t206.5 100.5v200h200v-200q54 -20 113 -60t112.5 -105.5t71.5 -134.5h203v-200h-203q-25 -102 -116.5 -186t-180.5 -117v-197h-200v197q-140 27 -208 102.5t-98 200.5h-194zM290 500q24 -73 79.5 -127.5t130.5 -78.5v206h200v-206 q149 48 201 206h-201v200h200q-25 74 -75.5 127t-124.5 77v-204h-200v203q-75 -23 -130 -77t-79 -126h209v-200h-210z" />
|
|
||||||
<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM356 465l135 135 l-135 135l109 109l135 -135l135 135l109 -109l-135 -135l135 -135l-109 -109l-135 135l-135 -135z" />
|
|
||||||
<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM322 537l141 141 l87 -87l204 205l142 -142l-346 -345z" />
|
|
||||||
<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -115 62 -215l568 567q-100 62 -216 62q-171 0 -292.5 -121.5t-121.5 -292.5zM391 245q97 -59 209 -59q171 0 292.5 121.5t121.5 292.5 q0 112 -59 209z" />
|
|
||||||
<glyph unicode="" d="M0 547l600 453v-300h600v-300h-600v-301z" />
|
|
||||||
<glyph unicode="" d="M0 400v300h600v300l600 -453l-600 -448v301h-600z" />
|
|
||||||
<glyph unicode="" d="M204 600l450 600l444 -600h-298v-600h-300v600h-296z" />
|
|
||||||
<glyph unicode="" d="M104 600h296v600h300v-600h298l-449 -600z" />
|
|
||||||
<glyph unicode="" d="M0 200q6 132 41 238.5t103.5 193t184 138t271.5 59.5v271l600 -453l-600 -448v301q-95 -2 -183 -20t-170 -52t-147 -92.5t-100 -135.5z" />
|
|
||||||
<glyph unicode="" d="M0 0v400l129 -129l294 294l142 -142l-294 -294l129 -129h-400zM635 777l142 -142l294 294l129 -129v400h-400l129 -129z" />
|
|
||||||
<glyph unicode="" d="M34 176l295 295l-129 129h400v-400l-129 130l-295 -295zM600 600v400l129 -129l295 295l142 -141l-295 -295l129 -130h-400z" />
|
|
||||||
<glyph unicode="" d="M23 600q0 118 45.5 224.5t123 184t184 123t224.5 45.5t224.5 -45.5t184 -123t123 -184t45.5 -224.5t-45.5 -224.5t-123 -184t-184 -123t-224.5 -45.5t-224.5 45.5t-184 123t-123 184t-45.5 224.5zM456 851l58 -302q4 -20 21.5 -34.5t37.5 -14.5h54q20 0 37.5 14.5 t21.5 34.5l58 302q4 20 -8 34.5t-32 14.5h-207q-21 0 -33 -14.5t-8 -34.5zM500 300h200v100h-200v-100z" />
|
|
||||||
<glyph unicode="" d="M0 800h100v-200h400v300h200v-300h400v200h100v100h-111q1 1 1 6.5t-1.5 15t-3.5 17.5l-34 172q-11 39 -41.5 63t-69.5 24q-32 0 -61 -17l-239 -144q-22 -13 -40 -35q-19 24 -40 36l-238 144q-33 18 -62 18q-39 0 -69.5 -23t-40.5 -61l-35 -177q-2 -8 -3 -18t-1 -15v-6 h-111v-100zM100 0h400v400h-400v-400zM200 900q-3 0 14 48t36 96l18 47l213 -191h-281zM700 0v400h400v-400h-400zM731 900l202 197q5 -12 12 -32.5t23 -64t25 -72t7 -28.5h-269z" />
|
|
||||||
<glyph unicode="" d="M0 -22v143l216 193q-9 53 -13 83t-5.5 94t9 113t38.5 114t74 124q47 60 99.5 102.5t103 68t127.5 48t145.5 37.5t184.5 43.5t220 58.5q0 -189 -22 -343t-59 -258t-89 -181.5t-108.5 -120t-122 -68t-125.5 -30t-121.5 -1.5t-107.5 12.5t-87.5 17t-56.5 7.5l-99 -55z M238.5 300.5q19.5 -6.5 86.5 76.5q55 66 367 234q70 38 118.5 69.5t102 79t99 111.5t86.5 148q22 50 24 60t-6 19q-7 5 -17 5t-26.5 -14.5t-33.5 -39.5q-35 -51 -113.5 -108.5t-139.5 -89.5l-61 -32q-369 -197 -458 -401q-48 -111 -28.5 -117.5z" />
|
|
||||||
<glyph unicode="" d="M111 408q0 -33 5 -63q9 -56 44 -119.5t105 -108.5q31 -21 64 -16t62 23.5t57 49.5t48 61.5t35 60.5q32 66 39 184.5t-13 157.5q79 -80 122 -164t26 -184q-5 -33 -20.5 -69.5t-37.5 -80.5q-10 -19 -14.5 -29t-12 -26t-9 -23.5t-3 -19t2.5 -15.5t11 -9.5t19.5 -5t30.5 2.5 t42 8q57 20 91 34t87.5 44.5t87 64t65.5 88.5t47 122q38 172 -44.5 341.5t-246.5 278.5q22 -44 43 -129q39 -159 -32 -154q-15 2 -33 9q-79 33 -120.5 100t-44 175.5t48.5 257.5q-13 -8 -34 -23.5t-72.5 -66.5t-88.5 -105.5t-60 -138t-8 -166.5q2 -12 8 -41.5t8 -43t6 -39.5 t3.5 -39.5t-1 -33.5t-6 -31.5t-13.5 -24t-21 -20.5t-31 -12q-38 -10 -67 13t-40.5 61.5t-15 81.5t10.5 75q-52 -46 -83.5 -101t-39 -107t-7.5 -85z" />
|
|
||||||
<glyph unicode="" d="M-61 600l26 40q6 10 20 30t49 63.5t74.5 85.5t97 90t116.5 83.5t132.5 59t145.5 23.5t145.5 -23.5t132.5 -59t116.5 -83.5t97 -90t74.5 -85.5t49 -63.5t20 -30l26 -40l-26 -40q-6 -10 -20 -30t-49 -63.5t-74.5 -85.5t-97 -90t-116.5 -83.5t-132.5 -59t-145.5 -23.5 t-145.5 23.5t-132.5 59t-116.5 83.5t-97 90t-74.5 85.5t-49 63.5t-20 30zM120 600q7 -10 40.5 -58t56 -78.5t68 -77.5t87.5 -75t103 -49.5t125 -21.5t123.5 20t100.5 45.5t85.5 71.5t66.5 75.5t58 81.5t47 66q-1 1 -28.5 37.5t-42 55t-43.5 53t-57.5 63.5t-58.5 54 q49 -74 49 -163q0 -124 -88 -212t-212 -88t-212 88t-88 212q0 85 46 158q-102 -87 -226 -258zM377 656q49 -124 154 -191l105 105q-37 24 -75 72t-57 84l-20 36z" />
|
|
||||||
<glyph unicode="" d="M-61 600l26 40q6 10 20 30t49 63.5t74.5 85.5t97 90t116.5 83.5t132.5 59t145.5 23.5q61 0 121 -17l37 142h148l-314 -1200h-148l37 143q-82 21 -165 71.5t-140 102t-109.5 112t-72 88.5t-29.5 43zM120 600q210 -282 393 -336l37 141q-107 18 -178.5 101.5t-71.5 193.5 q0 85 46 158q-102 -87 -226 -258zM377 656q49 -124 154 -191l47 47l23 87q-30 28 -59 69t-44 68l-14 26zM780 161l38 145q22 15 44.5 34t46 44t40.5 44t41 50.5t33.5 43.5t33 44t24.5 34q-97 127 -140 175l39 146q67 -54 131.5 -125.5t87.5 -103.5t36 -52l26 -40l-26 -40 q-7 -12 -25.5 -38t-63.5 -79.5t-95.5 -102.5t-124 -100t-146.5 -79z" />
|
|
||||||
<glyph unicode="" d="M-97.5 34q13.5 -34 50.5 -34h1294q37 0 50.5 35.5t-7.5 67.5l-642 1056q-20 34 -48 36.5t-48 -29.5l-642 -1066q-21 -32 -7.5 -66zM155 200l445 723l445 -723h-345v100h-200v-100h-345zM500 600l100 -300l100 300v100h-200v-100z" />
|
|
||||||
<glyph unicode="" d="M100 262v41q0 20 11 44.5t26 38.5l363 325v339q0 62 44 106t106 44t106 -44t44 -106v-339l363 -325q15 -14 26 -38.5t11 -44.5v-41q0 -20 -12 -26.5t-29 5.5l-359 249v-263q100 -91 100 -113v-64q0 -20 -13 -28.5t-32 0.5l-94 78h-222l-94 -78q-19 -9 -32 -0.5t-13 28.5 v64q0 22 100 113v263l-359 -249q-17 -12 -29 -5.5t-12 26.5z" />
|
|
||||||
<glyph unicode="" d="M0 50q0 -20 14.5 -35t35.5 -15h1000q21 0 35.5 15t14.5 35v750h-1100v-750zM0 900h1100v150q0 21 -14.5 35.5t-35.5 14.5h-150v100h-100v-100h-500v100h-100v-100h-150q-21 0 -35.5 -14.5t-14.5 -35.5v-150zM100 100v100h100v-100h-100zM100 300v100h100v-100h-100z M100 500v100h100v-100h-100zM300 100v100h100v-100h-100zM300 300v100h100v-100h-100zM300 500v100h100v-100h-100zM500 100v100h100v-100h-100zM500 300v100h100v-100h-100zM500 500v100h100v-100h-100zM700 100v100h100v-100h-100zM700 300v100h100v-100h-100zM700 500 v100h100v-100h-100zM900 100v100h100v-100h-100zM900 300v100h100v-100h-100zM900 500v100h100v-100h-100z" />
|
|
||||||
<glyph unicode="" d="M0 200v200h259l600 600h241v198l300 -295l-300 -300v197h-159l-600 -600h-341zM0 800h259l122 -122l141 142l-181 180h-341v-200zM678 381l141 142l122 -123h159v198l300 -295l-300 -300v197h-241z" />
|
|
||||||
<glyph unicode="" d="M0 400v600q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-596l-304 -300v300h-100q-41 0 -70.5 29.5t-29.5 70.5z" />
|
|
||||||
<glyph unicode="" d="M100 600v200h300v-250q0 -113 6 -145q17 -92 102 -117q39 -11 92 -11q37 0 66.5 5.5t50 15.5t36 24t24 31.5t14 37.5t7 42t2.5 45t0 47v25v250h300v-200q0 -42 -3 -83t-15 -104t-31.5 -116t-58 -109.5t-89 -96.5t-129 -65.5t-174.5 -25.5t-174.5 25.5t-129 65.5t-89 96.5 t-58 109.5t-31.5 116t-15 104t-3 83zM100 900v300h300v-300h-300zM800 900v300h300v-300h-300z" />
|
|
||||||
<glyph unicode="" d="M-30 411l227 -227l352 353l353 -353l226 227l-578 579z" />
|
|
||||||
<glyph unicode="" d="M70 797l580 -579l578 579l-226 227l-353 -353l-352 353z" />
|
|
||||||
<glyph unicode="" d="M-198 700l299 283l300 -283h-203v-400h385l215 -200h-800v600h-196zM402 1000l215 -200h381v-400h-198l299 -283l299 283h-200v600h-796z" />
|
|
||||||
<glyph unicode="" d="M18 939q-5 24 10 42q14 19 39 19h896l38 162q5 17 18.5 27.5t30.5 10.5h94q20 0 35 -14.5t15 -35.5t-15 -35.5t-35 -14.5h-54l-201 -961q-2 -4 -6 -10.5t-19 -17.5t-33 -11h-31v-50q0 -20 -14.5 -35t-35.5 -15t-35.5 15t-14.5 35v50h-300v-50q0 -20 -14.5 -35t-35.5 -15 t-35.5 15t-14.5 35v50h-50q-21 0 -35.5 15t-14.5 35q0 21 14.5 35.5t35.5 14.5h535l48 200h-633q-32 0 -54.5 21t-27.5 43z" />
|
|
||||||
<glyph unicode="" d="M0 0v800h1200v-800h-1200zM0 900v100h200q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5h500v-100h-1200z" />
|
|
||||||
<glyph unicode="" d="M1 0l300 700h1200l-300 -700h-1200zM1 400v600h200q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5h500v-200h-1000z" />
|
|
||||||
<glyph unicode="" d="M302 300h198v600h-198l298 300l298 -300h-198v-600h198l-298 -300z" />
|
|
||||||
<glyph unicode="" d="M0 600l300 298v-198h600v198l300 -298l-300 -297v197h-600v-197z" />
|
|
||||||
<glyph unicode="" d="M0 100v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM31 400l172 739q5 22 23 41.5t38 19.5h672q19 0 37.5 -22.5t23.5 -45.5l172 -732h-1138zM800 100h100v100h-100v-100z M1000 100h100v100h-100v-100z" />
|
|
||||||
<glyph unicode="" d="M-101 600v50q0 24 25 49t50 38l25 13v-250l-11 5.5t-24 14t-30 21.5t-24 27.5t-11 31.5zM100 500v250v8v8v7t0.5 7t1.5 5.5t2 5t3 4t4.5 3.5t6 1.5t7.5 0.5h200l675 250v-850l-675 200h-38l47 -276q2 -12 -3 -17.5t-11 -6t-21 -0.5h-8h-83q-20 0 -34.5 14t-18.5 35 q-55 337 -55 351zM1100 200v850q0 21 14.5 35.5t35.5 14.5q20 0 35 -14.5t15 -35.5v-850q0 -20 -15 -35t-35 -15q-21 0 -35.5 15t-14.5 35z" />
|
|
||||||
<glyph unicode="" d="M74 350q0 21 13.5 35.5t33.5 14.5h18l117 173l63 327q15 77 76 140t144 83l-18 32q-6 19 3 32t29 13h94q20 0 29 -10.5t3 -29.5q-18 -36 -18 -37q83 -19 144 -82.5t76 -140.5l63 -327l118 -173h17q20 0 33.5 -14.5t13.5 -35.5q0 -20 -13 -40t-31 -27q-8 -3 -23 -8.5 t-65 -20t-103 -25t-132.5 -19.5t-158.5 -9q-125 0 -245.5 20.5t-178.5 40.5l-58 20q-18 7 -31 27.5t-13 40.5zM497 110q12 -49 40 -79.5t63 -30.5t63 30.5t39 79.5q-48 -6 -102 -6t-103 6z" />
|
|
||||||
<glyph unicode="" d="M21 445l233 -45l-78 -224l224 78l45 -233l155 179l155 -179l45 233l224 -78l-78 224l234 45l-180 155l180 156l-234 44l78 225l-224 -78l-45 233l-155 -180l-155 180l-45 -233l-224 78l78 -225l-233 -44l179 -156z" />
|
|
||||||
<glyph unicode="" d="M0 200h200v600h-200v-600zM300 275q0 -75 100 -75h61q124 -100 139 -100h250q46 0 83 57l238 344q29 31 29 74v100q0 44 -30.5 84.5t-69.5 40.5h-328q28 118 28 125v150q0 44 -30.5 84.5t-69.5 40.5h-50q-27 0 -51 -20t-38 -48l-96 -198l-145 -196q-20 -26 -20 -63v-400z M400 300v375l150 213l100 212h50v-175l-50 -225h450v-125l-250 -375h-214l-136 100h-100z" />
|
|
||||||
<glyph unicode="" d="M0 400v600h200v-600h-200zM300 525v400q0 75 100 75h61q124 100 139 100h250q46 0 83 -57l238 -344q29 -31 29 -74v-100q0 -44 -30.5 -84.5t-69.5 -40.5h-328q28 -118 28 -125v-150q0 -44 -30.5 -84.5t-69.5 -40.5h-50q-27 0 -51 20t-38 48l-96 198l-145 196 q-20 26 -20 63zM400 525l150 -212l100 -213h50v175l-50 225h450v125l-250 375h-214l-136 -100h-100v-375z" />
|
|
||||||
<glyph unicode="" d="M8 200v600h200v-600h-200zM308 275v525q0 17 14 35.5t28 28.5l14 9l362 230q14 6 25 6q17 0 29 -12l109 -112q14 -14 14 -34q0 -18 -11 -32l-85 -121h302q85 0 138.5 -38t53.5 -110t-54.5 -111t-138.5 -39h-107l-130 -339q-7 -22 -20.5 -41.5t-28.5 -19.5h-341 q-7 0 -90 81t-83 94zM408 289l100 -89h293l131 339q6 21 19.5 41t28.5 20h203q16 0 25 15t9 36q0 20 -9 34.5t-25 14.5h-457h-6.5h-7.5t-6.5 0.5t-6 1t-5 1.5t-5.5 2.5t-4 4t-4 5.5q-5 12 -5 20q0 14 10 27l147 183l-86 83l-339 -236v-503z" />
|
|
||||||
<glyph unicode="" d="M-101 651q0 72 54 110t139 38l302 -1l-85 121q-11 16 -11 32q0 21 14 34l109 113q13 12 29 12q11 0 25 -6l365 -230q7 -4 17 -10.5t26.5 -26t16.5 -36.5v-526q0 -13 -86 -93.5t-94 -80.5h-341q-16 0 -29.5 20t-19.5 41l-130 339h-107q-84 0 -139 39t-55 111zM-1 601h222 q15 0 28.5 -20.5t19.5 -40.5l131 -339h293l107 89v502l-343 237l-87 -83l145 -184q10 -11 10 -26q0 -11 -5 -20q-1 -3 -3.5 -5.5l-4 -4t-5 -2.5t-5.5 -1.5t-6.5 -1t-6.5 -0.5h-7.5h-6.5h-476v-100zM1000 201v600h200v-600h-200z" />
|
|
||||||
<glyph unicode="" d="M97 719l230 -363q4 -6 10.5 -15.5t26 -25t36.5 -15.5h525q13 0 94 83t81 90v342q0 15 -20 28.5t-41 19.5l-339 131v106q0 84 -39 139t-111 55t-110 -53.5t-38 -138.5v-302l-121 84q-15 12 -33.5 11.5t-32.5 -13.5l-112 -110q-22 -22 -6 -53zM172 739l83 86l183 -146 q22 -18 47 -5q3 1 5.5 3.5l4 4t2.5 5t1.5 5.5t1 6.5t0.5 6.5v7.5v6.5v456q0 22 25 31t50 -0.5t25 -30.5v-202q0 -16 20 -29.5t41 -19.5l339 -130v-294l-89 -100h-503zM400 0v200h600v-200h-600z" />
|
|
||||||
<glyph unicode="" d="M2 585q-16 -31 6 -53l112 -110q13 -13 32 -13.5t34 10.5l121 85q0 -51 -0.5 -153.5t-0.5 -148.5q0 -84 38.5 -138t110.5 -54t111 55t39 139v106l339 131q20 6 40.5 19.5t20.5 28.5v342q0 7 -81 90t-94 83h-525q-17 0 -35.5 -14t-28.5 -28l-10 -15zM77 565l236 339h503 l89 -100v-294l-340 -130q-20 -6 -40 -20t-20 -29v-202q0 -22 -25 -31t-50 0t-25 31v456v14.5t-1.5 11.5t-5 12t-9.5 7q-24 13 -46 -5l-184 -146zM305 1104v200h600v-200h-600z" />
|
|
||||||
<glyph unicode="" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q162 0 299.5 -80t217.5 -218t80 -300t-80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM298 701l2 -201h300l-2 -194l402 294l-402 298v-197h-300z" />
|
|
||||||
<glyph unicode="" d="M0 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t231.5 47.5q122 0 232.5 -47.5t190.5 -127.5t127.5 -190.5t47.5 -232.5q0 -162 -80 -299.5t-218 -217.5t-300 -80t-299.5 80t-217.5 217.5t-80 299.5zM200 600l402 -294l-2 194h300l2 201h-300v197z" />
|
|
||||||
<glyph unicode="" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q162 0 299.5 -80t217.5 -218t80 -300t-80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM300 600h200v-300h200v300h200l-300 400z" />
|
|
||||||
<glyph unicode="" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q162 0 299.5 -80t217.5 -218t80 -300t-80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM300 600l300 -400l300 400h-200v300h-200v-300h-200z" />
|
|
||||||
<glyph unicode="" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q121 0 231.5 -47.5t190.5 -127.5t127.5 -190.5t47.5 -232.5q0 -162 -80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM254 780q-8 -33 5.5 -92.5t7.5 -87.5q0 -9 17 -44t16 -60 q12 0 23 -5.5t23 -15t20 -13.5q24 -12 108 -42q22 -8 53 -31.5t59.5 -38.5t57.5 -11q8 -18 -15 -55t-20 -57q42 -71 87 -80q0 -6 -3 -15.5t-3.5 -14.5t4.5 -17q104 -3 221 112q30 29 47 47t34.5 49t20.5 62q-14 9 -37 9.5t-36 7.5q-14 7 -49 15t-52 19q-9 0 -39.5 -0.5 t-46.5 -1.5t-39 -6.5t-39 -16.5q-50 -35 -66 -12q-4 2 -3.5 25.5t0.5 25.5q-6 13 -26.5 17t-24.5 7q2 22 -2 41t-16.5 28t-38.5 -20q-23 -25 -42 4q-19 28 -8 58q6 16 22 22q6 -1 26 -1.5t33.5 -4t19.5 -13.5q12 -19 32 -37.5t34 -27.5l14 -8q0 3 9.5 39.5t5.5 57.5 q-4 23 14.5 44.5t22.5 31.5q5 14 10 35t8.5 31t15.5 22.5t34 21.5q-6 18 10 37q8 0 23.5 -1.5t24.5 -1.5t20.5 4.5t20.5 15.5q-10 23 -30.5 42.5t-38 30t-49 26.5t-43.5 23q11 39 2 44q31 -13 58 -14.5t39 3.5l11 4q7 36 -16.5 53.5t-64.5 28.5t-56 23q-19 -3 -37 0 q-15 -12 -36.5 -21t-34.5 -12t-44 -8t-39 -6q-15 -3 -45.5 0.5t-45.5 -2.5q-21 -7 -52 -26.5t-34 -34.5q-3 -11 6.5 -22.5t8.5 -18.5q-3 -34 -27.5 -90.5t-29.5 -79.5zM518 916q3 12 16 30t16 25q10 -10 18.5 -10t14 6t14.5 14.5t16 12.5q0 -24 17 -66.5t17 -43.5 q-9 2 -31 5t-36 5t-32 8t-30 14zM692 1003h1h-1z" />
|
|
||||||
<glyph unicode="" d="M0 164.5q0 21.5 15 37.5l600 599q-33 101 6 201.5t135 154.5q164 92 306 -9l-259 -138l145 -232l251 126q13 -175 -151 -267q-123 -70 -253 -23l-596 -596q-15 -16 -36.5 -16t-36.5 16l-111 110q-15 15 -15 36.5z" />
|
|
||||||
<glyph unicode="" horiz-adv-x="1220" d="M0 196v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM0 596v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5zM0 996v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM600 596h500v100h-500v-100zM800 196h300v100h-300v-100zM900 996h200v100h-200v-100z" />
|
|
||||||
<glyph unicode="" d="M100 1100v100h1000v-100h-1000zM150 1000h900l-350 -500v-300l-200 -200v500z" />
|
|
||||||
<glyph unicode="" d="M0 200v200h1200v-200q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM0 500v400q0 41 29.5 70.5t70.5 29.5h300v100q0 41 29.5 70.5t70.5 29.5h200q41 0 70.5 -29.5t29.5 -70.5v-100h300q41 0 70.5 -29.5t29.5 -70.5v-400h-500v100h-200v-100h-500z M500 1000h200v100h-200v-100z" />
|
|
||||||
<glyph unicode="" d="M0 0v400l129 -129l200 200l142 -142l-200 -200l129 -129h-400zM0 800l129 129l200 -200l142 142l-200 200l129 129h-400v-400zM729 329l142 142l200 -200l129 129v-400h-400l129 129zM729 871l200 200l-129 129h400v-400l-129 129l-200 -200z" />
|
|
||||||
<glyph unicode="" d="M0 596q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM182 596q0 -172 121.5 -293t292.5 -121t292.5 121t121.5 293q0 171 -121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM291 655 q0 23 15.5 38.5t38.5 15.5t39 -16t16 -38q0 -23 -16 -39t-39 -16q-22 0 -38 16t-16 39zM400 850q0 22 16 38.5t39 16.5q22 0 38 -16t16 -39t-16 -39t-38 -16q-23 0 -39 16.5t-16 38.5zM514 609q0 32 20.5 56.5t51.5 29.5l122 126l1 1q-9 14 -9 28q0 22 16 38.5t39 16.5 q22 0 38 -16t16 -39t-16 -39t-38 -16q-14 0 -29 10l-55 -145q17 -22 17 -51q0 -36 -25.5 -61.5t-61.5 -25.5t-61.5 25.5t-25.5 61.5zM800 655q0 22 16 38t39 16t38.5 -15.5t15.5 -38.5t-16 -39t-38 -16q-23 0 -39 16t-16 39z" />
|
|
||||||
<glyph unicode="" d="M-40 375q-13 -95 35 -173q35 -57 94 -89t129 -32q63 0 119 28q33 16 65 40.5t52.5 45.5t59.5 64q40 44 57 61l394 394q35 35 47 84t-3 96q-27 87 -117 104q-20 2 -29 2q-46 0 -78.5 -16.5t-67.5 -51.5l-389 -396l-7 -7l69 -67l377 373q20 22 39 38q23 23 50 23 q38 0 53 -36q16 -39 -20 -75l-547 -547q-52 -52 -125 -52q-55 0 -100 33t-54 96q-5 35 2.5 66t31.5 63t42 50t56 54q24 21 44 41l348 348q52 52 82.5 79.5t84 54t107.5 26.5q25 0 48 -4q95 -17 154 -94.5t51 -175.5q-7 -101 -98 -192l-252 -249l-253 -256l7 -7l69 -60 l517 511q67 67 95 157t11 183q-16 87 -67 154t-130 103q-69 33 -152 33q-107 0 -197 -55q-40 -24 -111 -95l-512 -512q-68 -68 -81 -163z" />
|
|
||||||
<glyph unicode="" d="M80 784q0 131 98.5 229.5t230.5 98.5q143 0 241 -129q103 129 246 129q129 0 226 -98.5t97 -229.5q0 -46 -17.5 -91t-61 -99t-77 -89.5t-104.5 -105.5q-197 -191 -293 -322l-17 -23l-16 23q-43 58 -100 122.5t-92 99.5t-101 100q-71 70 -104.5 105.5t-77 89.5t-61 99 t-17.5 91zM250 784q0 -27 30.5 -70t61.5 -75.5t95 -94.5l22 -22q93 -90 190 -201q82 92 195 203l12 12q64 62 97.5 97t64.5 79t31 72q0 71 -48 119.5t-105 48.5q-74 0 -132 -83l-118 -171l-114 174q-51 80 -123 80q-60 0 -109.5 -49.5t-49.5 -118.5z" />
|
|
||||||
<glyph unicode="" d="M57 353q0 -95 66 -159l141 -142q68 -66 159 -66q93 0 159 66l283 283q66 66 66 159t-66 159l-141 141q-8 9 -19 17l-105 -105l212 -212l-389 -389l-247 248l95 95l-18 18q-46 45 -75 101l-55 -55q-66 -66 -66 -159zM269 706q0 -93 66 -159l141 -141q7 -7 19 -17l105 105 l-212 212l389 389l247 -247l-95 -96l18 -17q47 -49 77 -100l29 29q35 35 62.5 88t27.5 96q0 93 -66 159l-141 141q-66 66 -159 66q-95 0 -159 -66l-283 -283q-66 -64 -66 -159z" />
|
|
||||||
<glyph unicode="" d="M200 100v953q0 21 30 46t81 48t129 38t163 15t162 -15t127 -38t79 -48t29 -46v-953q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-41 0 -70.5 29.5t-29.5 70.5zM300 300h600v700h-600v-700zM496 150q0 -43 30.5 -73.5t73.5 -30.5t73.5 30.5t30.5 73.5t-30.5 73.5t-73.5 30.5 t-73.5 -30.5t-30.5 -73.5z" />
|
|
||||||
<glyph unicode="" d="M0 0l303 380l207 208l-210 212h300l267 279l-35 36q-15 14 -15 35t15 35q14 15 35 15t35 -15l283 -282q15 -15 15 -36t-15 -35q-14 -15 -35 -15t-35 15l-36 35l-279 -267v-300l-212 210l-208 -207z" />
|
|
||||||
<glyph unicode="" d="M295 433h139q5 -77 48.5 -126.5t117.5 -64.5v335q-6 1 -15.5 4t-11.5 3q-46 14 -79 26.5t-72 36t-62.5 52t-40 72.5t-16.5 99q0 92 44 159.5t109 101t144 40.5v78h100v-79q38 -4 72.5 -13.5t75.5 -31.5t71 -53.5t51.5 -84t24.5 -118.5h-159q-8 72 -35 109.5t-101 50.5 v-307l64 -14q34 -7 64 -16.5t70 -31.5t67.5 -52t47.5 -80.5t20 -112.5q0 -139 -89 -224t-244 -96v-77h-100v78q-152 17 -237 104q-40 40 -52.5 93.5t-15.5 139.5zM466 889q0 -29 8 -51t16.5 -34t29.5 -22.5t31 -13.5t38 -10q7 -2 11 -3v274q-61 -8 -97.5 -37.5t-36.5 -102.5 zM700 237q170 18 170 151q0 64 -44 99.5t-126 60.5v-311z" />
|
|
||||||
<glyph unicode="" d="M100 600v100h166q-24 49 -44 104q-10 26 -14.5 55.5t-3 72.5t25 90t68.5 87q97 88 263 88q129 0 230 -89t101 -208h-153q0 52 -34 89.5t-74 51.5t-76 14q-37 0 -79 -14.5t-62 -35.5q-41 -44 -41 -101q0 -28 16.5 -69.5t28 -62.5t41.5 -72h241v-100h-197q8 -50 -2.5 -115 t-31.5 -94q-41 -59 -99 -113q35 11 84 18t70 7q33 1 103 -16t103 -17q76 0 136 30l50 -147q-41 -25 -80.5 -36.5t-59 -13t-61.5 -1.5q-23 0 -128 33t-155 29q-39 -4 -82 -17t-66 -25l-24 -11l-55 145l16.5 11t15.5 10t13.5 9.5t14.5 12t14.5 14t17.5 18.5q48 55 54 126.5 t-30 142.5h-221z" />
|
|
||||||
<glyph unicode="" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM602 900l298 300l298 -300h-198v-900h-200v900h-198z" />
|
|
||||||
<glyph unicode="" d="M2 300h198v900h200v-900h198l-298 -300zM700 0v200h100v-100h200v-100h-300zM700 400v100h300v-200h-99v-100h-100v100h99v100h-200zM700 700v500h300v-500h-100v100h-100v-100h-100zM801 900h100v200h-100v-200z" />
|
|
||||||
<glyph unicode="" d="M2 300h198v900h200v-900h198l-298 -300zM700 0v500h300v-500h-100v100h-100v-100h-100zM700 700v200h100v-100h200v-100h-300zM700 1100v100h300v-200h-99v-100h-100v100h99v100h-200zM801 200h100v200h-100v-200z" />
|
|
||||||
<glyph unicode="" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM800 100v400h300v-500h-100v100h-200zM800 1100v100h200v-500h-100v400h-100zM901 200h100v200h-100v-200z" />
|
|
||||||
<glyph unicode="" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM800 400v100h200v-500h-100v400h-100zM800 800v400h300v-500h-100v100h-200zM901 900h100v200h-100v-200z" />
|
|
||||||
<glyph unicode="" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM700 100v200h500v-200h-500zM700 400v200h400v-200h-400zM700 700v200h300v-200h-300zM700 1000v200h200v-200h-200z" />
|
|
||||||
<glyph unicode="" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM700 100v200h200v-200h-200zM700 400v200h300v-200h-300zM700 700v200h400v-200h-400zM700 1000v200h500v-200h-500z" />
|
|
||||||
<glyph unicode="" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h300q162 0 281 -118.5t119 -281.5v-300q0 -165 -118.5 -282.5t-281.5 -117.5h-300q-165 0 -282.5 117.5t-117.5 282.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500z" />
|
|
||||||
<glyph unicode="" d="M0 400v300q0 163 119 281.5t281 118.5h300q165 0 282.5 -117.5t117.5 -282.5v-300q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-163 0 -281.5 117.5t-118.5 282.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM400 300l333 250l-333 250v-500z" />
|
|
||||||
<glyph unicode="" d="M0 400v300q0 163 117.5 281.5t282.5 118.5h300q163 0 281.5 -119t118.5 -281v-300q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5t-117.5 282.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM300 700l250 -333l250 333h-500z" />
|
|
||||||
<glyph unicode="" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h300q165 0 282.5 -117.5t117.5 -282.5v-300q0 -162 -118.5 -281t-281.5 -119h-300q-165 0 -282.5 118.5t-117.5 281.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM300 400h500l-250 333z" />
|
|
||||||
<glyph unicode="" d="M0 400v300h300v200l400 -350l-400 -350v200h-300zM500 0v200h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5h-500v200h400q165 0 282.5 -117.5t117.5 -282.5v-300q0 -165 -117.5 -282.5t-282.5 -117.5h-400z" />
|
|
||||||
<glyph unicode="" d="M217 519q8 -19 31 -19h302q-155 -438 -160 -458q-5 -21 4 -32l9 -8h9q14 0 26 15q11 13 274.5 321.5t264.5 308.5q14 19 5 36q-8 17 -31 17l-301 -1q1 4 78 219.5t79 227.5q2 15 -5 27l-9 9h-9q-15 0 -25 -16q-4 -6 -98 -111.5t-228.5 -257t-209.5 -237.5q-16 -19 -6 -41 z" />
|
|
||||||
<glyph unicode="" d="M0 400q0 -165 117.5 -282.5t282.5 -117.5h300q47 0 100 15v185h-500q-41 0 -70.5 29.5t-29.5 70.5v500q0 41 29.5 70.5t70.5 29.5h500v185q-14 4 -114 7.5t-193 5.5l-93 2q-165 0 -282.5 -117.5t-117.5 -282.5v-300zM600 400v300h300v200l400 -350l-400 -350v200h-300z " />
|
|
||||||
<glyph unicode="" d="M0 400q0 -165 117.5 -282.5t282.5 -117.5h300q163 0 281.5 117.5t118.5 282.5v98l-78 73l-122 -123v-148q0 -41 -29.5 -70.5t-70.5 -29.5h-500q-41 0 -70.5 29.5t-29.5 70.5v500q0 41 29.5 70.5t70.5 29.5h156l118 122l-74 78h-100q-165 0 -282.5 -117.5t-117.5 -282.5 v-300zM496 709l353 342l-149 149h500v-500l-149 149l-342 -353z" />
|
|
||||||
<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM406 600 q0 80 57 137t137 57t137 -57t57 -137t-57 -137t-137 -57t-137 57t-57 137z" />
|
|
||||||
<glyph unicode="" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 800l445 -500l450 500h-295v400h-300v-400h-300zM900 150h100v50h-100v-50z" />
|
|
||||||
<glyph unicode="" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 700h300v-300h300v300h295l-445 500zM900 150h100v50h-100v-50z" />
|
|
||||||
<glyph unicode="" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 705l305 -305l596 596l-154 155l-442 -442l-150 151zM900 150h100v50h-100v-50z" />
|
|
||||||
<glyph unicode="" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 988l97 -98l212 213l-97 97zM200 400l697 1l3 699l-250 -239l-149 149l-212 -212l149 -149zM900 150h100v50h-100v-50z" />
|
|
||||||
<glyph unicode="" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM200 612l212 -212l98 97l-213 212zM300 1200l239 -250l-149 -149l212 -212l149 148l249 -237l-1 697zM900 150h100v50h-100v-50z" />
|
|
||||||
<glyph unicode="" d="M23 415l1177 784v-1079l-475 272l-310 -393v416h-392zM494 210l672 938l-672 -712v-226z" />
|
|
||||||
<glyph unicode="" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-850q0 -21 -15 -35.5t-35 -14.5h-150v400h-700v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 1000h100v200h-100v-200z" />
|
|
||||||
<glyph unicode="" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-218l-276 -275l-120 120l-126 -127h-378v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM581 306l123 123l120 -120l353 352l123 -123l-475 -476zM600 1000h100v200h-100v-200z" />
|
|
||||||
<glyph unicode="" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-269l-103 -103l-170 170l-298 -298h-329v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 1000h100v200h-100v-200zM700 133l170 170l-170 170l127 127l170 -170l170 170l127 -128l-170 -169l170 -170 l-127 -127l-170 170l-170 -170z" />
|
|
||||||
<glyph unicode="" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-300h-400v-200h-500v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 300l300 -300l300 300h-200v300h-200v-300h-200zM600 1000v200h100v-200h-100z" />
|
|
||||||
<glyph unicode="" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-402l-200 200l-298 -298h-402v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 300h200v-300h200v300h200l-300 300zM600 1000v200h100v-200h-100z" />
|
|
||||||
<glyph unicode="" d="M0 250q0 -21 14.5 -35.5t35.5 -14.5h1100q21 0 35.5 14.5t14.5 35.5v550h-1200v-550zM0 900h1200v150q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5v-150zM100 300v200h400v-200h-400z" />
|
|
||||||
<glyph unicode="" d="M0 400l300 298v-198h400v-200h-400v-198zM100 800v200h100v-200h-100zM300 800v200h100v-200h-100zM500 800v200h400v198l300 -298l-300 -298v198h-400zM800 300v200h100v-200h-100zM1000 300h100v200h-100v-200z" />
|
|
||||||
<glyph unicode="" d="M100 700v400l50 100l50 -100v-300h100v300l50 100l50 -100v-300h100v300l50 100l50 -100v-400l-100 -203v-447q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v447zM800 597q0 -29 10.5 -55.5t25 -43t29 -28.5t25.5 -18l10 -5v-397q0 -21 14.5 -35.5 t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v1106q0 31 -18 40.5t-44 -7.5l-276 -116q-25 -17 -43.5 -51.5t-18.5 -65.5v-359z" />
|
|
||||||
<glyph unicode="" d="M100 0h400v56q-75 0 -87.5 6t-12.5 44v394h500v-394q0 -38 -12.5 -44t-87.5 -6v-56h400v56q-4 0 -11 0.5t-24 3t-30 7t-24 15t-11 24.5v888q0 22 25 34.5t50 13.5l25 2v56h-400v-56q75 0 87.5 -6t12.5 -44v-394h-500v394q0 38 12.5 44t87.5 6v56h-400v-56q4 0 11 -0.5 t24 -3t30 -7t24 -15t11 -24.5v-888q0 -22 -25 -34.5t-50 -13.5l-25 -2v-56z" />
|
|
||||||
<glyph unicode="" d="M0 300q0 -41 29.5 -70.5t70.5 -29.5h300q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5h-300q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM100 100h400l200 200h105l295 98v-298h-425l-100 -100h-375zM100 300v200h300v-200h-300zM100 600v200h300v-200h-300z M100 1000h400l200 -200v-98l295 98h105v200h-425l-100 100h-375zM700 402v163l400 133v-163z" />
|
|
||||||
<glyph unicode="" d="M16.5 974.5q0.5 -21.5 16 -90t46.5 -140t104 -177.5t175 -208q103 -103 207.5 -176t180 -103.5t137 -47t92.5 -16.5l31 1l163 162q17 18 13.5 41t-22.5 37l-192 136q-19 14 -45 12t-42 -19l-118 -118q-142 101 -268 227t-227 268l118 118q17 17 20 41.5t-11 44.5 l-139 194q-14 19 -36.5 22t-40.5 -14l-162 -162q-1 -11 -0.5 -32.5z" />
|
|
||||||
<glyph unicode="" d="M0 50v212q0 20 10.5 45.5t24.5 39.5l365 303v50q0 4 1 10.5t12 22.5t30 28.5t60 23t97 10.5t97 -10t60 -23.5t30 -27.5t12 -24l1 -10v-50l365 -303q14 -14 24.5 -39.5t10.5 -45.5v-212q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-20 0 -35 14.5t-15 35.5zM0 712 q0 -21 14.5 -33.5t34.5 -8.5l202 33q20 4 34.5 21t14.5 38v146q141 24 300 24t300 -24v-146q0 -21 14.5 -38t34.5 -21l202 -33q20 -4 34.5 8.5t14.5 33.5v200q-6 8 -19 20.5t-63 45t-112 57t-171 45t-235 20.5q-92 0 -175 -10.5t-141.5 -27t-108.5 -36.5t-81.5 -40 t-53.5 -36.5t-31 -27.5l-9 -10v-200z" />
|
|
||||||
<glyph unicode="" d="M100 0v100h1100v-100h-1100zM175 200h950l-125 150v250l100 100v400h-100v-200h-100v200h-200v-200h-100v200h-200v-200h-100v200h-100v-400l100 -100v-250z" />
|
|
||||||
<glyph unicode="" d="M100 0h300v400q0 41 -29.5 70.5t-70.5 29.5h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-400zM500 0v1000q0 41 29.5 70.5t70.5 29.5h100q41 0 70.5 -29.5t29.5 -70.5v-1000h-300zM900 0v700q0 41 29.5 70.5t70.5 29.5h100q41 0 70.5 -29.5t29.5 -70.5v-700h-300z" />
|
|
||||||
<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v300h-200v100h200v100h-300v-300h200v-100h-200v-100zM600 300h200v100h100v300h-100v100h-200v-500 zM700 400v300h100v-300h-100z" />
|
|
||||||
<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h100v200h100v-200h100v500h-100v-200h-100v200h-100v-500zM600 300h200v100h100v300h-100v100h-200v-500 zM700 400v300h100v-300h-100z" />
|
|
||||||
<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v100h-200v300h200v100h-300v-500zM600 300h300v100h-200v300h200v100h-300v-500z" />
|
|
||||||
<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 550l300 -150v300zM600 400l300 150l-300 150v-300z" />
|
|
||||||
<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300v500h700v-500h-700zM300 400h130q41 0 68 42t27 107t-28.5 108t-66.5 43h-130v-300zM575 549 q0 -65 27 -107t68 -42h130v300h-130q-38 0 -66.5 -43t-28.5 -108z" />
|
|
||||||
<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v300h-200v100h200v100h-300v-300h200v-100h-200v-100zM601 300h100v100h-100v-100zM700 700h100 v-400h100v500h-200v-100z" />
|
|
||||||
<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v400h-200v100h-100v-500zM301 400v200h100v-200h-100zM601 300h100v100h-100v-100zM700 700h100 v-400h100v500h-200v-100z" />
|
|
||||||
<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 700v100h300v-300h-99v-100h-100v100h99v200h-200zM201 300v100h100v-100h-100zM601 300v100h100v-100h-100z M700 700v100h200v-500h-100v400h-100z" />
|
|
||||||
<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM400 500v200 l100 100h300v-100h-300v-200h300v-100h-300z" />
|
|
||||||
<glyph unicode="" d="M0 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM182 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM400 400v400h300 l100 -100v-100h-100v100h-200v-100h200v-100h-200v-100h-100zM700 400v100h100v-100h-100z" />
|
|
||||||
<glyph unicode="" d="M-14 494q0 -80 56.5 -137t135.5 -57h222v300h400v-300h128q120 0 205 86.5t85 207.5t-85 207t-205 86q-46 0 -90 -14q-44 97 -134.5 156.5t-200.5 59.5q-152 0 -260 -107.5t-108 -260.5q0 -25 2 -37q-66 -14 -108.5 -67.5t-42.5 -122.5zM300 200h200v300h200v-300h200 l-300 -300z" />
|
|
||||||
<glyph unicode="" d="M-14 494q0 -80 56.5 -137t135.5 -57h8l414 414l403 -403q94 26 154.5 104.5t60.5 178.5q0 120 -85 206.5t-205 86.5q-46 0 -90 -14q-44 97 -134.5 156.5t-200.5 59.5q-152 0 -260 -107.5t-108 -260.5q0 -25 2 -37q-66 -14 -108.5 -67.5t-42.5 -122.5zM300 200l300 300 l300 -300h-200v-300h-200v300h-200z" />
|
|
||||||
<glyph unicode="" d="M100 200h400v-155l-75 -45h350l-75 45v155h400l-270 300h170l-270 300h170l-300 333l-300 -333h170l-270 -300h170z" />
|
|
||||||
<glyph unicode="" d="M121 700q0 -53 28.5 -97t75.5 -65q-4 -16 -4 -38q0 -74 52.5 -126.5t126.5 -52.5q56 0 100 30v-306l-75 -45h350l-75 45v306q46 -30 100 -30q74 0 126.5 52.5t52.5 126.5q0 24 -9 55q50 32 79.5 83t29.5 112q0 90 -61.5 155.5t-150.5 71.5q-26 89 -99.5 145.5 t-167.5 56.5q-116 0 -197.5 -81.5t-81.5 -197.5q0 -4 1 -11.5t1 -11.5q-14 2 -23 2q-74 0 -126.5 -52.5t-52.5 -126.5z" />
|
|
||||||
</font>
|
|
||||||
</defs></svg>
|
|
Before Width: | Height: | Size: 62 KiB |
Before Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 8.6 KiB |
Before Width: | Height: | Size: 4.1 KiB |
1929
libraries/bootstrap/js/bootstrap.js
vendored
1186
libraries/bootstrap/js/bootstrap.min.js
vendored
@ -8,6 +8,7 @@
|
|||||||
"cy:run": "cypress run",
|
"cy:run": "cypress run",
|
||||||
"test:integration": "start-server-and-test 'yarn playground' http-get://localhost:8081 'yarn cy:run'",
|
"test:integration": "start-server-and-test 'yarn playground' http-get://localhost:8081 'yarn cy:run'",
|
||||||
"test": "yarn test:integration",
|
"test": "yarn test:integration",
|
||||||
|
"test:unit": "jest ./test/unit/* --detectOpenHandles",
|
||||||
"i18n:extract": "formatjs extract 'src/**/*.ts*' --ignore 'src/@types/**/*' --out-file lang/es.json",
|
"i18n:extract": "formatjs extract 'src/**/*.ts*' --ignore 'src/@types/**/*' --out-file lang/es.json",
|
||||||
"i18n:compile": "for lang in {'es','en','fr','de','zh','ru'};do formatjs compile lang/${lang}.json --ast --out-file src/compiled-lang/${lang}.json;done"
|
"i18n:compile": "for lang in {'es','en','fr','de','zh','ru'};do formatjs compile lang/${lang}.json --ast --out-file src/compiled-lang/${lang}.json;done"
|
||||||
},
|
},
|
||||||
@ -19,8 +20,12 @@
|
|||||||
"@babel/preset-env": "^7.18.6",
|
"@babel/preset-env": "^7.18.6",
|
||||||
"@babel/preset-react": "^7.18.6",
|
"@babel/preset-react": "^7.18.6",
|
||||||
"@formatjs/cli": "^4.8.1",
|
"@formatjs/cli": "^4.8.1",
|
||||||
|
"@babel/preset-typescript": "^7.16.5",
|
||||||
|
"@testing-library/react": "^12.0.0",
|
||||||
|
"@types/jest": "^29.0.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^4.8.1",
|
"@typescript-eslint/eslint-plugin": "^4.8.1",
|
||||||
"@typescript-eslint/parser": "^4.8.1",
|
"@typescript-eslint/parser": "^4.8.1",
|
||||||
|
"babel-polyfill": "^6.26.0",
|
||||||
"clean-webpack-plugin": "^4.0.0",
|
"clean-webpack-plugin": "^4.0.0",
|
||||||
"compression-webpack-plugin": "^9.2.0",
|
"compression-webpack-plugin": "^9.2.0",
|
||||||
"copy-webpack-plugin": "^10.2.1",
|
"copy-webpack-plugin": "^10.2.1",
|
||||||
@ -33,6 +38,9 @@
|
|||||||
"eslint-plugin-react-hooks": "^4.2.0",
|
"eslint-plugin-react-hooks": "^4.2.0",
|
||||||
"html-webpack-plugin": "^5.5.0",
|
"html-webpack-plugin": "^5.5.0",
|
||||||
"prettier": "^2.2.1",
|
"prettier": "^2.2.1",
|
||||||
|
"react": "^17.0.2",
|
||||||
|
"react-dom": "^17.0.2",
|
||||||
|
"ts-jest": "^29.0.0",
|
||||||
"ts-loader": "^8.0.11",
|
"ts-loader": "^8.0.11",
|
||||||
"ts-node": "^9.0.0",
|
"ts-node": "^9.0.0",
|
||||||
"typescript": "^4.1.2",
|
"typescript": "^4.1.2",
|
||||||
@ -41,13 +49,31 @@
|
|||||||
"webpack-merge": "^5.8.0"
|
"webpack-merge": "^5.8.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@wisemapping/mindplot": "^5.0.1"
|
"@wisemapping/mindplot": "^5.0.1",
|
||||||
|
"react-color": "^2.19.3"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@types/styled-components": "^5.1.26",
|
"@types/styled-components": "^5.1.26",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
"react-intl": "^4.7.6",
|
"react-intl": "^5.24.3",
|
||||||
"styled-components": "^5.3.5"
|
"styled-components": "^5.3.5",
|
||||||
|
"@emotion/react": "^11.10.4",
|
||||||
|
"@emotion/styled": "^11.10.4",
|
||||||
|
"@mui/icons-material": "^5.9.3",
|
||||||
|
"@mui/material": "^5.9.3"
|
||||||
|
},
|
||||||
|
"jest": {
|
||||||
|
"testEnvironment": "jsdom",
|
||||||
|
"verbose": true,
|
||||||
|
"preset": "ts-jest",
|
||||||
|
"moduleFileExtensions": [
|
||||||
|
"js",
|
||||||
|
"ts",
|
||||||
|
"tsx"
|
||||||
|
],
|
||||||
|
"transform": {
|
||||||
|
"^.+\\.js?$": "babel-jest"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
20
packages/editor/src/bootstrap-fixes.css
vendored
@ -1,20 +0,0 @@
|
|||||||
/*
|
|
||||||
These are patches or hacks to avoid boostrap interfering with Mui styles
|
|
||||||
This file is meant to be removed when removing bootstrap
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
/* bootstrap modal */
|
|
||||||
|
|
||||||
.wise-editor .modal {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal-backdrop {
|
|
||||||
position: fixed;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
width: 100vw;
|
|
||||||
height: 100vh;
|
|
||||||
background: rgba(0, 0, 0, 0.5);
|
|
||||||
z-index: 1000;
|
|
||||||
}
|
|
6061
packages/editor/src/bootstrap-prefix.min.css
vendored
@ -1,154 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright [2021] [wisemapping]
|
|
||||||
*
|
|
||||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
|
||||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
|
||||||
* "powered by wisemapping" text requirement on every single page;
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the license at
|
|
||||||
*
|
|
||||||
* http://www.wisemapping.org/license
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import $ from 'jquery';
|
|
||||||
import Options from '@wisemapping/mindplot/src/components/Options';
|
|
||||||
import { $msg } from '@wisemapping/mindplot/src/components/Messages';
|
|
||||||
|
|
||||||
class BootstrapDialog extends Options {
|
|
||||||
constructor(title, options) {
|
|
||||||
super();
|
|
||||||
this.options = {
|
|
||||||
cancelButton: false,
|
|
||||||
closeButton: false,
|
|
||||||
acceptButton: true,
|
|
||||||
removeButton: false,
|
|
||||||
errorMessage: false,
|
|
||||||
onEventData: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
this.setOptions(options);
|
|
||||||
this.options.onEventData.dialog = this;
|
|
||||||
this._native = $('<div class="modal fade" tabindex="-1"></div>').append(
|
|
||||||
'<div class="modal-dialog"></div>',
|
|
||||||
);
|
|
||||||
const content = $('<div class="modal-content"></div>');
|
|
||||||
const header = this._buildHeader(title);
|
|
||||||
|
|
||||||
if (header) {
|
|
||||||
content.append(header);
|
|
||||||
}
|
|
||||||
const body = $('<div class="modal-body"></div>');
|
|
||||||
if (this.options.errorMessage) {
|
|
||||||
const error = $('<div class="alert alert-danger"></div>');
|
|
||||||
error.hide();
|
|
||||||
body.append(error);
|
|
||||||
}
|
|
||||||
content.append(body);
|
|
||||||
const footer = this._buildFooter();
|
|
||||||
if (footer) {
|
|
||||||
content.append(footer);
|
|
||||||
}
|
|
||||||
this._native.find('.modal-dialog').append(content);
|
|
||||||
this._native.on('hidden.bs.modal', function remove() {
|
|
||||||
$(this).remove();
|
|
||||||
});
|
|
||||||
this._native.on('shown.bs.modal', this.onDialogShown);
|
|
||||||
|
|
||||||
this._native.appendTo('#mindplot-tooltips');
|
|
||||||
}
|
|
||||||
|
|
||||||
_buildFooter() {
|
|
||||||
let footer = null;
|
|
||||||
if (this.options.acceptButton || this.options.removeButton || this.options.cancelButton) {
|
|
||||||
footer = $('<div class="modal-footer" style="paddingTop:5;textAlign:center">');
|
|
||||||
}
|
|
||||||
if (this.options.acceptButton) {
|
|
||||||
this.acceptButton = $(
|
|
||||||
`<button type="button" class="btn btn-primary" id="acceptBtn" data-dismiss="modal">${$msg(
|
|
||||||
'ACCEPT',
|
|
||||||
)}</button>`,
|
|
||||||
);
|
|
||||||
footer.append(this.acceptButton);
|
|
||||||
this.acceptButton.unbind('click').on('click', this.options.onEventData, this.onAcceptClick);
|
|
||||||
}
|
|
||||||
if (this.options.removeButton) {
|
|
||||||
this.removeButton = $(
|
|
||||||
`<button type="button" class="btn btn-secondary" id="removeBtn" data-dismiss="modal">${$msg(
|
|
||||||
'REMOVE',
|
|
||||||
)}</button>`,
|
|
||||||
);
|
|
||||||
footer.append(this.removeButton);
|
|
||||||
this.removeButton.on('click', this.options.onEventData, this.onRemoveClick);
|
|
||||||
}
|
|
||||||
if (this.options.cancelButton) {
|
|
||||||
footer.append(
|
|
||||||
`<button type="button" class="btn btn-secondary" data-dismiss="modal">${$msg(
|
|
||||||
'CANCEL',
|
|
||||||
)}</button>`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return footer;
|
|
||||||
}
|
|
||||||
|
|
||||||
_buildHeader(title) {
|
|
||||||
let header = null;
|
|
||||||
if (this.options.closeButton || title) {
|
|
||||||
header = $('<div class="modal-header"></div>');
|
|
||||||
}
|
|
||||||
if (this.options.closeButton) {
|
|
||||||
header.append(
|
|
||||||
'<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (title) {
|
|
||||||
header.append(`<h2 class="modal-title">${title}</h2>`);
|
|
||||||
}
|
|
||||||
return header;
|
|
||||||
}
|
|
||||||
|
|
||||||
onAcceptClick(event) {
|
|
||||||
throw new Error('Unsupported operation');
|
|
||||||
}
|
|
||||||
|
|
||||||
onDialogShown() {
|
|
||||||
// Overwrite default behaviour ...
|
|
||||||
}
|
|
||||||
|
|
||||||
onRemoveClick(event) {
|
|
||||||
throw new Error('Unsupported operation');
|
|
||||||
}
|
|
||||||
|
|
||||||
show() {
|
|
||||||
this._native.modal();
|
|
||||||
}
|
|
||||||
|
|
||||||
setContent(content) {
|
|
||||||
const modalBody = this._native.find('.modal-body');
|
|
||||||
modalBody.append(content);
|
|
||||||
}
|
|
||||||
|
|
||||||
css(options) {
|
|
||||||
this._native.find('.modal-dialog').css(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
close() {
|
|
||||||
this._native.modal('hide');
|
|
||||||
}
|
|
||||||
|
|
||||||
alertError(message) {
|
|
||||||
this._native.find('.alert-danger').text(message);
|
|
||||||
this._native.find('.alert-danger').show();
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanError() {
|
|
||||||
this._native.find('.alert-danger').hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default BootstrapDialog;
|
|
@ -1,70 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright [2021] [wisemapping]
|
|
||||||
*
|
|
||||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
|
||||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
|
||||||
* "powered by wisemapping" text requirement on every single page;
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the license at
|
|
||||||
*
|
|
||||||
* http://www.wisemapping.org/license
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
import $ from 'jquery';
|
|
||||||
import { $defined } from '@wisemapping/core-js';
|
|
||||||
import BootstrapDialog from './BootstrapDialog';
|
|
||||||
|
|
||||||
class BootstrapDialogRequest extends BootstrapDialog {
|
|
||||||
constructor(url, title, options) {
|
|
||||||
super(title, options);
|
|
||||||
this.requestOptions = {};
|
|
||||||
this.requestOptions.cache = false;
|
|
||||||
const me = this;
|
|
||||||
|
|
||||||
this.requestOptions.fail = (xhr) => {
|
|
||||||
// Intercept form requests ...
|
|
||||||
console.log('Failure:');
|
|
||||||
console.log(xhr);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.requestOptions.success = function success() {
|
|
||||||
// Intercept form requests ...
|
|
||||||
const forms = me._native.find('form');
|
|
||||||
forms.forEach((form) => {
|
|
||||||
$(form).on('submit', (event) => {
|
|
||||||
// Intercept form ...
|
|
||||||
me.requestOptions.url = form.action;
|
|
||||||
me.requestOptions.method = form.method ? form.method : 'post';
|
|
||||||
$.ajax(me.requestOptions);
|
|
||||||
event.stopPropagation();
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
this._native.find('.modal-body').load(url, () => {
|
|
||||||
me.acceptButton.unbind('click').click(() => {
|
|
||||||
if ($defined(global.submitDialogForm) && typeof global.submitDialogForm === 'function') {
|
|
||||||
global.submitDialogForm();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
me._native.on('hidden.bs.modal', function onModalHide() {
|
|
||||||
$(this).remove();
|
|
||||||
});
|
|
||||||
me.show();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onDialogShown() {
|
|
||||||
if ($defined(global.onDialogShown) && typeof global.onDialogShown === 'function') {
|
|
||||||
global.onDialogShown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default BootstrapDialogRequest;
|
|
@ -1,90 +0,0 @@
|
|||||||
import {
|
|
||||||
WidgetManager,
|
|
||||||
Topic,
|
|
||||||
LinkModel,
|
|
||||||
LinkIcon,
|
|
||||||
NoteModel,
|
|
||||||
NoteIcon,
|
|
||||||
$msg,
|
|
||||||
} from '@wisemapping/mindplot';
|
|
||||||
import LinkIconTooltip from './LinkIconTooltip';
|
|
||||||
import LinkEditor from './LinkEditor';
|
|
||||||
import FloatingTip from './FloatingTip';
|
|
||||||
import NoteEditor from './NoteEditor';
|
|
||||||
import $ from 'jquery';
|
|
||||||
|
|
||||||
export default class BootstrapWidgetManager extends WidgetManager {
|
|
||||||
createTooltipForLink(topic: Topic, linkModel: LinkModel, linkIcon: LinkIcon) {
|
|
||||||
const htmlImage = linkIcon.getImage().peer;
|
|
||||||
const toolTip = new LinkIconTooltip(linkIcon);
|
|
||||||
linkIcon.addEvent('mouseleave', (event) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
if (!$('#linkPopover:hover').length) {
|
|
||||||
toolTip.hide();
|
|
||||||
}
|
|
||||||
event.stopPropagation();
|
|
||||||
}, 100);
|
|
||||||
});
|
|
||||||
$(htmlImage._native).mouseenter(() => {
|
|
||||||
toolTip.show();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
showEditorForLink(topic: Topic, linkModel: LinkModel, linkIcon: LinkIcon) {
|
|
||||||
const editorModel = {
|
|
||||||
getValue(): string {
|
|
||||||
return topic.getLinkValue();
|
|
||||||
},
|
|
||||||
setValue(value: string) {
|
|
||||||
topic.setLinkValue(value);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
topic.closeEditors();
|
|
||||||
const editor = new LinkEditor(editorModel);
|
|
||||||
editor.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
private _buildTooltipContentForNote(noteModel: NoteModel): JQuery {
|
|
||||||
if ($('body').find('#textPopoverNote').length === 1) {
|
|
||||||
const text = $('body').find('#textPopoverNote');
|
|
||||||
text.text(noteModel.getText());
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
const result = $('<div id="textPopoverNote"></div>').css({ padding: '5px' });
|
|
||||||
|
|
||||||
const text = $('<div></div>').text(noteModel.getText()).css({
|
|
||||||
'white-space': 'pre-wrap',
|
|
||||||
'word-wrap': 'break-word',
|
|
||||||
});
|
|
||||||
result.append(text);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
createTooltipForNote(topic: Topic, noteModel: NoteModel, noteIcon: NoteIcon) {
|
|
||||||
const htmlImage = noteIcon.getImage().peer;
|
|
||||||
const me = this;
|
|
||||||
const toolTip = new FloatingTip($(htmlImage._native), {
|
|
||||||
title: $msg('NOTE'),
|
|
||||||
content() {
|
|
||||||
return me._buildTooltipContentForNote(noteModel);
|
|
||||||
},
|
|
||||||
html: true,
|
|
||||||
placement: 'bottom',
|
|
||||||
destroyOnExit: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
showEditorForNote(topic: Topic, noteModel: NoteModel, noteIcon: NoteIcon) {
|
|
||||||
const editorModel = {
|
|
||||||
getValue(): string {
|
|
||||||
return topic.getNoteValue();
|
|
||||||
},
|
|
||||||
setValue(value: string) {
|
|
||||||
topic.setNoteValue(value);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
topic.closeEditors();
|
|
||||||
const editor = new NoteEditor(editorModel);
|
|
||||||
editor.show();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,85 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright [2021] [wisemapping]
|
|
||||||
*
|
|
||||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
|
||||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
|
||||||
* "powered by wisemapping" text requirement on every single page;
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the license at
|
|
||||||
*
|
|
||||||
* http://www.wisemapping.org/license
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
import merge from 'lodash/merge';
|
|
||||||
import Events from '../menu/Events';
|
|
||||||
|
|
||||||
const defaultOptions = {
|
|
||||||
animation: true,
|
|
||||||
html: false,
|
|
||||||
placement: 'right',
|
|
||||||
selector: false,
|
|
||||||
trigger: 'hover',
|
|
||||||
title: '',
|
|
||||||
content: '',
|
|
||||||
delay: 0,
|
|
||||||
container: '#mindplot-tooltips',
|
|
||||||
destroyOnExit: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
class FloatingTip extends Events {
|
|
||||||
private options;
|
|
||||||
|
|
||||||
private element;
|
|
||||||
|
|
||||||
constructor(element, options) {
|
|
||||||
super();
|
|
||||||
const opts = { ...defaultOptions, ...options };
|
|
||||||
this.setOptions(opts);
|
|
||||||
this.element = element;
|
|
||||||
this._createPopover();
|
|
||||||
}
|
|
||||||
|
|
||||||
_createPopover() {
|
|
||||||
this.element.popover(this.options);
|
|
||||||
const me = this;
|
|
||||||
if (this.options.destroyOnExit) {
|
|
||||||
this.element.one('hidden.bs.popover', () => {
|
|
||||||
me.element.popover('destroy');
|
|
||||||
me._createPopover();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
show() {
|
|
||||||
this.element.popover('show');
|
|
||||||
this.fireEvent('show');
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
hide() {
|
|
||||||
this.element.popover('hide');
|
|
||||||
this.fireEvent('hide');
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
setOptions(...args) {
|
|
||||||
const options = merge({}, this.options, ...args);
|
|
||||||
this.options = options;
|
|
||||||
|
|
||||||
if (this.addEvent) {
|
|
||||||
Object.keys(options).forEach((option) => {
|
|
||||||
if (options[option] instanceof Function && /^on[A-Z]/.test(option)) {
|
|
||||||
this.addEvent(option, options[option]);
|
|
||||||
delete options[option];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export default FloatingTip;
|
|
@ -1,167 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright [2021] [wisemapping]
|
|
||||||
*
|
|
||||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
|
||||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
|
||||||
* "powered by wisemapping" text requirement on every single page;
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the license at
|
|
||||||
*
|
|
||||||
* http://www.wisemapping.org/license
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
import $ from 'jquery';
|
|
||||||
import { $assert } from '@wisemapping/core-js';
|
|
||||||
import { $msg } from '@wisemapping/mindplot';
|
|
||||||
import BootstrapDialog from './BootstrapDialog';
|
|
||||||
|
|
||||||
interface LinkEditorModel {
|
|
||||||
getValue(): string;
|
|
||||||
setValue(value: string): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
class LinkEditor extends BootstrapDialog {
|
|
||||||
private form: JQuery<HTMLElement>;
|
|
||||||
|
|
||||||
private formSubmitted: boolean;
|
|
||||||
|
|
||||||
constructor(model: LinkEditorModel) {
|
|
||||||
$assert(model, 'model can not be null');
|
|
||||||
super($msg('LINK'), {
|
|
||||||
cancelButton: true,
|
|
||||||
closeButton: true,
|
|
||||||
acceptButton: true,
|
|
||||||
removeButton: typeof model.getValue() !== 'undefined',
|
|
||||||
errorMessage: true,
|
|
||||||
onEventData: { model },
|
|
||||||
});
|
|
||||||
this.css({ margin: '150px auto' });
|
|
||||||
const panel = this._buildPanel(model);
|
|
||||||
this.setContent(panel);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected _buildPanel(model: LinkEditorModel) {
|
|
||||||
const result = $('<div></div>').css('padding-top', '5px');
|
|
||||||
this.form = $('<form></form>').attr({
|
|
||||||
action: 'none',
|
|
||||||
id: 'linkFormId',
|
|
||||||
});
|
|
||||||
const text = $('<p></p>').text($msg('PASTE_URL_HERE'));
|
|
||||||
text.css('margin', '0px 0px 20px');
|
|
||||||
|
|
||||||
this.form.append(text);
|
|
||||||
|
|
||||||
const section = $('<div></div>').attr({
|
|
||||||
class: 'input-group',
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add Input
|
|
||||||
const input = $('<input id="inputUrl"/>').attr({
|
|
||||||
placeholder: 'https://www.example.com/',
|
|
||||||
required: 'true',
|
|
||||||
autofocus: 'autofocus',
|
|
||||||
class: 'form-control',
|
|
||||||
});
|
|
||||||
input.on('keypress', (event) => {
|
|
||||||
event.stopPropagation();
|
|
||||||
});
|
|
||||||
|
|
||||||
if (model.getValue() != null) {
|
|
||||||
input.val(model.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open Button
|
|
||||||
const openButton = $('<button></button>').attr({
|
|
||||||
type: 'button',
|
|
||||||
class: 'btn btn-default',
|
|
||||||
});
|
|
||||||
|
|
||||||
openButton.html($msg('OPEN_LINK')).css('margin-left', '0px');
|
|
||||||
openButton.on('click', () => {
|
|
||||||
const value = input.val() as string;
|
|
||||||
window.open(value, '_blank', 'status=1,width=700,height=450,resize=1');
|
|
||||||
});
|
|
||||||
const spanControl = $('<span class="input-group-btn"></span>').append(openButton);
|
|
||||||
|
|
||||||
section.append(input);
|
|
||||||
section.append(spanControl);
|
|
||||||
this.form.append(section);
|
|
||||||
|
|
||||||
const me = this;
|
|
||||||
this.form.off('submit').on('submit', (event) => {
|
|
||||||
event.preventDefault();
|
|
||||||
let inputValue = input.val() as string;
|
|
||||||
inputValue = this.hasProtocol(inputValue) ? inputValue : `https://${inputValue}`;
|
|
||||||
if (me.checkURL(inputValue)) {
|
|
||||||
me.cleanError();
|
|
||||||
if (inputValue !== null && inputValue.trim() !== '') {
|
|
||||||
model.setValue(inputValue);
|
|
||||||
}
|
|
||||||
me.close();
|
|
||||||
this.formSubmitted = true;
|
|
||||||
} else {
|
|
||||||
me.alertError($msg('URL_ERROR'));
|
|
||||||
event.stopPropagation();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
result.append(this.form);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* checks whether the input is a valid url
|
|
||||||
* @return {Boolean} true if the url is valid
|
|
||||||
*/
|
|
||||||
private checkURL(url: string): boolean {
|
|
||||||
const regex =
|
|
||||||
/^(http|https):\/\/[a-z0-9]+([-.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/i;
|
|
||||||
return regex.test(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* checks whether the input is a valid url
|
|
||||||
* @return {Boolean} true if the url is valid
|
|
||||||
*/
|
|
||||||
private hasProtocol(url: string): boolean {
|
|
||||||
const regex = /^(http|https):\/\//i;
|
|
||||||
return regex.test(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* overrides abstract parent method
|
|
||||||
* triggered when the user clicks the accept button - submits the url input
|
|
||||||
* @param event
|
|
||||||
*/
|
|
||||||
onAcceptClick(event: Event): void {
|
|
||||||
this.formSubmitted = false;
|
|
||||||
$('#linkFormId').trigger('submit');
|
|
||||||
if (!this.formSubmitted) {
|
|
||||||
event.stopPropagation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* overrides parent method
|
|
||||||
* sets the url input on focus
|
|
||||||
*/
|
|
||||||
onDialogShown(): void {
|
|
||||||
$(this).find('#inputUrl').focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* overrides abstract parent method
|
|
||||||
* triggered when the user clicks the remove button - deletes the link
|
|
||||||
*/
|
|
||||||
onRemoveClick(event) {
|
|
||||||
event.data.model.setValue(null);
|
|
||||||
event.data.dialog.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default LinkEditor;
|
|
@ -1,65 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright [2021] [wisemapping]
|
|
||||||
*
|
|
||||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
|
||||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
|
||||||
* "powered by wisemapping" text requirement on every single page;
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the license at
|
|
||||||
*
|
|
||||||
* http://www.wisemapping.org/license
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
import { $assert } from '@wisemapping/core-js';
|
|
||||||
import $ from 'jquery';
|
|
||||||
import { LinkIcon } from '@wisemapping/mindplot';
|
|
||||||
import { LinkModel } from '@wisemapping/mindplot';
|
|
||||||
import { $msg } from '@wisemapping/mindplot';
|
|
||||||
import FloatingTip from './FloatingTip';
|
|
||||||
|
|
||||||
class LinkIconTooltip extends FloatingTip {
|
|
||||||
constructor(linkIcon: LinkIcon) {
|
|
||||||
$assert(linkIcon, 'linkIcon can not be null');
|
|
||||||
const nativeElement = $(linkIcon.getImage().peer._native);
|
|
||||||
super(nativeElement, {
|
|
||||||
// Content can also be a function of the target element!
|
|
||||||
content() {
|
|
||||||
return LinkIconTooltip._buildContent(linkIcon);
|
|
||||||
},
|
|
||||||
html: true,
|
|
||||||
placement: 'bottom',
|
|
||||||
title: $msg('LINK'),
|
|
||||||
trigger: 'manual',
|
|
||||||
template:
|
|
||||||
'<div id="linkPopover" class="popover" onmouseover="jQuery(this).mouseleave(function() {jQuery(this).fadeOut(200); });" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>',
|
|
||||||
destroyOnExit: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private static _buildContent(linkIcon: LinkIcon): JQuery<HTMLElement> {
|
|
||||||
const model = linkIcon.getModel() as LinkModel;
|
|
||||||
const url = model.getUrl();
|
|
||||||
const linkText = `${url}`;
|
|
||||||
|
|
||||||
const result = $('<div></div>').css({
|
|
||||||
padding: '5px',
|
|
||||||
width: '100%',
|
|
||||||
});
|
|
||||||
const link = $('<a id="linkPopoverAnchor"></a>').attr({
|
|
||||||
href: url,
|
|
||||||
alt: 'Open in new window ...',
|
|
||||||
target: '_blank',
|
|
||||||
});
|
|
||||||
|
|
||||||
link.html(linkText);
|
|
||||||
result.append(link);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default LinkIconTooltip;
|
|
@ -1,97 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright [2021] [wisemapping]
|
|
||||||
*
|
|
||||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
|
||||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
|
||||||
* "powered by wisemapping" text requirement on every single page;
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the license at
|
|
||||||
*
|
|
||||||
* http://www.wisemapping.org/license
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
import { $assert } from '@wisemapping/core-js';
|
|
||||||
import $ from 'jquery';
|
|
||||||
import BootstrapDialog from '../../../../editor/src/classes/bootstrap/BootstrapDialog';
|
|
||||||
import { $msg } from '@wisemapping/mindplot';
|
|
||||||
|
|
||||||
interface NoteEditorModel {
|
|
||||||
getValue(): string;
|
|
||||||
setValue(value: string): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
class NoteEditor extends BootstrapDialog {
|
|
||||||
constructor(model: NoteEditorModel) {
|
|
||||||
$assert(model, 'model can not be null');
|
|
||||||
super($msg('NOTE'), {
|
|
||||||
cancelButton: true,
|
|
||||||
closeButton: true,
|
|
||||||
acceptButton: true,
|
|
||||||
removeButton: typeof model.getValue() !== 'undefined',
|
|
||||||
onEventData: { model },
|
|
||||||
});
|
|
||||||
this.css({ margin: '150px auto' });
|
|
||||||
const panel = this._buildPanel(model);
|
|
||||||
this.setContent(panel);
|
|
||||||
}
|
|
||||||
|
|
||||||
_buildPanel(model: NoteEditorModel) {
|
|
||||||
const result = $('<div></div>').css('padding-top', '5px');
|
|
||||||
|
|
||||||
const form = $('<form></form>').attr({
|
|
||||||
action: 'none',
|
|
||||||
id: 'noteFormId',
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add textarea
|
|
||||||
const textArea = $('<textarea></textarea autofocus>').attr({
|
|
||||||
placeholder: $msg('WRITE_YOUR_TEXT_HERE'),
|
|
||||||
required: 'true',
|
|
||||||
class: 'form-control',
|
|
||||||
});
|
|
||||||
textArea.css({
|
|
||||||
width: '100%',
|
|
||||||
height: 80,
|
|
||||||
resize: 'none',
|
|
||||||
});
|
|
||||||
textArea.on('keypress', (event) => {
|
|
||||||
event.stopPropagation();
|
|
||||||
});
|
|
||||||
form.append(textArea);
|
|
||||||
|
|
||||||
if (model.getValue() != null) {
|
|
||||||
textArea.val(model.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
result.append(form);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
onAcceptClick(event): void {
|
|
||||||
event.data.dialog._submitForm(event.data.model);
|
|
||||||
}
|
|
||||||
|
|
||||||
_submitForm(model: NoteEditorModel) {
|
|
||||||
const textarea = this._native.find('textarea');
|
|
||||||
if (textarea.val()) {
|
|
||||||
model.setValue(textarea.val() as string);
|
|
||||||
}
|
|
||||||
this.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
onDialogShown() {
|
|
||||||
$(this).find('textarea').trigger('focus');
|
|
||||||
}
|
|
||||||
|
|
||||||
onRemoveClick(event) {
|
|
||||||
event.data.model.setValue(null);
|
|
||||||
event.data.dialog.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default NoteEditor;
|
|
@ -1,72 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright [2021] [wisemapping]
|
|
||||||
*
|
|
||||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
|
||||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
|
||||||
* "powered by wisemapping" text requirement on every single page;
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the license at
|
|
||||||
*
|
|
||||||
* http://www.wisemapping.org/license
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
import $ from 'jquery';
|
|
||||||
import ListToolbarPanel from './ListToolbarPanel';
|
|
||||||
|
|
||||||
class AccountSettingsPanel extends ListToolbarPanel {
|
|
||||||
constructor(elemId) {
|
|
||||||
const model = {
|
|
||||||
getValue() {
|
|
||||||
// Overwite default behaviour ...
|
|
||||||
},
|
|
||||||
setValue() {
|
|
||||||
const elem = document.getElementById('logoutFrom');
|
|
||||||
elem.submit();
|
|
||||||
},
|
|
||||||
};
|
|
||||||
super(elemId, model);
|
|
||||||
}
|
|
||||||
|
|
||||||
show() {
|
|
||||||
if (!this.isVisible()) {
|
|
||||||
this.fireEvent('show');
|
|
||||||
this._tip.show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hide() {
|
|
||||||
if (this.isVisible()) {
|
|
||||||
this.fireEvent('hide');
|
|
||||||
this._tip.hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
isTopicAction() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
isRelAction() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line class-methods-use-this
|
|
||||||
buildPanel() {
|
|
||||||
const content = $("<div class='toolbarPanel' id='accountSettingsPanel'></div>");
|
|
||||||
content[0].innerHTML = `
|
|
||||||
<p style='text-align:center;font-weight:bold;'>${global.accountName}</p>
|
|
||||||
<p>${global.accountEmail}</p>
|
|
||||||
<form action="/c/logout" method='POST' id="logoutFrom"></form>
|
|
||||||
<div id="account-logout" model='logout' style='text-align:center'>
|
|
||||||
Logout
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default AccountSettingsPanel;
|
|
@ -1,214 +0,0 @@
|
|||||||
export const css = `
|
|
||||||
.palette-panel {
|
|
||||||
cursor: default;
|
|
||||||
font: normal 13px "Helvetica Neue", Helvetica, Arial, sans-serif;
|
|
||||||
margin: 0;
|
|
||||||
outline: none;
|
|
||||||
padding: 4px 0;
|
|
||||||
z-index: 20000;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.palette {
|
|
||||||
cursor: default;
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.palette-table {
|
|
||||||
border: 1px solid #666;
|
|
||||||
border-collapse: collapse;
|
|
||||||
margin: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
tbody {
|
|
||||||
display: table-row-group;
|
|
||||||
vertical-align: middle;
|
|
||||||
border-color: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.palette-table {
|
|
||||||
border-collapse: collapse;
|
|
||||||
}
|
|
||||||
|
|
||||||
tr {
|
|
||||||
display: table-row;
|
|
||||||
vertical-align: inherit;
|
|
||||||
border-color: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.palette-cell {
|
|
||||||
border: 0;
|
|
||||||
border-right: 1px solid #666;
|
|
||||||
cursor: pointer;
|
|
||||||
height: 18px;
|
|
||||||
margin: 0;
|
|
||||||
text-align: center;
|
|
||||||
vertical-align: middle;
|
|
||||||
width: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.palette-cell .palette-colorswatch {
|
|
||||||
border: none;
|
|
||||||
font-size: x-small;
|
|
||||||
height: 18px;
|
|
||||||
position: relative;
|
|
||||||
width: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.palette-cell-selected .palette-colorswatch {
|
|
||||||
border: 1px solid #333;
|
|
||||||
color: white;
|
|
||||||
font-weight: bold;
|
|
||||||
height: 16px;
|
|
||||||
width: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.palette-colorswatch:hover {
|
|
||||||
border: 1px solid white;
|
|
||||||
height: 16px;
|
|
||||||
width: 16px;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const cell = (color) => `<td class="palette-cell palette-cell-selected">
|
|
||||||
<div class="palette-colorswatch" style="background-color: rgb${color};"
|
|
||||||
title="RGB ${color}"></div>
|
|
||||||
</td>`;
|
|
||||||
|
|
||||||
export const row = (colors) => `
|
|
||||||
<tr class="palette-row">
|
|
||||||
${colors.map((c) => cell(c)).join('\n')}
|
|
||||||
</tr>
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const palette = (rows, id) => `
|
|
||||||
<div class="palette" id="${id}">
|
|
||||||
<table class="palette-table" cellspacing="0" cellpadding="0" role="grid"
|
|
||||||
aria-activedescendent="palette-cell-244">
|
|
||||||
<tbody class="palette-body">
|
|
||||||
${rows.map((r) => row(r)).join('\n')}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const buildHtml = () => {
|
|
||||||
const palettes = [
|
|
||||||
{
|
|
||||||
id: ':3p',
|
|
||||||
colors: [
|
|
||||||
[
|
|
||||||
'(0, 0, 0)',
|
|
||||||
'(68, 68, 68)',
|
|
||||||
'(102, 102, 102)',
|
|
||||||
'(153, 153, 153)',
|
|
||||||
'(204, 204, 204)',
|
|
||||||
'(238, 238, 238)',
|
|
||||||
'(243, 243, 243)',
|
|
||||||
'(254, 255, 255)',
|
|
||||||
],
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '3q',
|
|
||||||
colors: [
|
|
||||||
[
|
|
||||||
'(255, 0, 0)',
|
|
||||||
'(255, 153, 0)',
|
|
||||||
'(255, 255, 0)',
|
|
||||||
'(0, 255, 0)',
|
|
||||||
'(0, 255, 255)',
|
|
||||||
'(0, 0, 255)',
|
|
||||||
'(153, 0, 255)',
|
|
||||||
'(255, 0, 255)',
|
|
||||||
],
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '3r',
|
|
||||||
colors: [
|
|
||||||
[
|
|
||||||
'(244, 204, 204)',
|
|
||||||
'(252, 229, 205)',
|
|
||||||
'(255, 242, 204)',
|
|
||||||
'(217, 234, 211)',
|
|
||||||
'(208, 224, 227)',
|
|
||||||
'(207, 226, 243)',
|
|
||||||
'(217, 210, 233)',
|
|
||||||
'(234, 209, 220)',
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'(234, 153, 153)',
|
|
||||||
'(249, 203, 156)',
|
|
||||||
'(255, 229, 153)',
|
|
||||||
'(182, 215, 168)',
|
|
||||||
'(162, 196, 201)',
|
|
||||||
'(159, 197, 232)',
|
|
||||||
'(180, 167, 214)',
|
|
||||||
'(213, 166, 189)',
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'(224, 102, 102)',
|
|
||||||
'(246, 178, 107)',
|
|
||||||
'(255, 217, 102)',
|
|
||||||
'(147, 196, 125)',
|
|
||||||
'(118, 165, 175)',
|
|
||||||
'(111, 168, 220)',
|
|
||||||
'(142, 124, 195)',
|
|
||||||
'(194, 123, 160)',
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'(204, 0, 0)',
|
|
||||||
'(230, 145, 56)',
|
|
||||||
'(241, 194, 50)',
|
|
||||||
'(106, 168, 79)',
|
|
||||||
'(69, 129, 142)',
|
|
||||||
'(61, 133, 198)',
|
|
||||||
'(103, 78, 167)',
|
|
||||||
'(166, 77, 121)',
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'(153, 0, 0)',
|
|
||||||
'(180, 95, 6)',
|
|
||||||
'(191, 144, 0)',
|
|
||||||
'(56, 118, 29)',
|
|
||||||
'(19, 79, 92)',
|
|
||||||
'(11, 83, 148)',
|
|
||||||
'(53, 28, 117)',
|
|
||||||
'(116, 27, 71)',
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'(102, 0, 0)',
|
|
||||||
'(120, 63, 4)',
|
|
||||||
'(127, 96, 0)',
|
|
||||||
'(39, 78, 19)',
|
|
||||||
'(12, 52, 61)',
|
|
||||||
'(7, 55, 99)',
|
|
||||||
'(32, 18, 77)',
|
|
||||||
'(76, 17, 48)',
|
|
||||||
],
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '2p',
|
|
||||||
colors: [
|
|
||||||
[
|
|
||||||
'(255, 255, 255)',
|
|
||||||
'(224, 229, 239)',
|
|
||||||
'(80, 157, 192)',
|
|
||||||
'(57, 113, 177)',
|
|
||||||
'(2, 59, 185)',
|
|
||||||
'(244, 184, 45)',
|
|
||||||
'(241, 163, 39)',
|
|
||||||
'(82, 92, 97)',
|
|
||||||
],
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
return `<div id="color-palette" class="palette-panel palette-panel-vertical palette-panel-noaccel"
|
|
||||||
style="-webkit-user-select: none; left: 451px; top: 128px; visibility: visible; " role="menu" aria-haspopup="true"
|
|
||||||
aria-activedescendant="">
|
|
||||||
${palettes.map((p) => palette(p.colors, p.id)).join('\n')}
|
|
||||||
</div>`;
|
|
||||||
};
|
|
@ -1,95 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright [2021] [wisemapping]
|
|
||||||
*
|
|
||||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
|
||||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
|
||||||
* "powered by wisemapping" text requirement on every single page;
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the license at
|
|
||||||
*
|
|
||||||
* http://www.wisemapping.org/license
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
import $ from 'jquery';
|
|
||||||
import { $assert, $defined } from '@wisemapping/core-js';
|
|
||||||
import ToolbarPaneItem from './ToolbarPaneItem';
|
|
||||||
import { buildHtml, css } from './ColorPaletteHtml';
|
|
||||||
|
|
||||||
// rgbToHex implementation from https://stackoverflow.com/a/3627747/58128
|
|
||||||
export const rgb2hex = (rgb) =>
|
|
||||||
`#${rgb
|
|
||||||
.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/)
|
|
||||||
.slice(1)
|
|
||||||
.map((n) => parseInt(n, 10).toString(16).padStart(2, '0'))
|
|
||||||
.join('')}`;
|
|
||||||
|
|
||||||
class ColorPalettePanel extends ToolbarPaneItem {
|
|
||||||
constructor(buttonId, model, baseUrl) {
|
|
||||||
$assert($defined(baseUrl), 'baseUrl can not be null');
|
|
||||||
super(buttonId, model, true);
|
|
||||||
this._baseUrl = baseUrl;
|
|
||||||
this._panelElem = super._init();
|
|
||||||
}
|
|
||||||
|
|
||||||
_load() {
|
|
||||||
if (!ColorPalettePanel._panelContent) {
|
|
||||||
// Load all the CSS styles ...
|
|
||||||
$('<style>').append(css).appendTo($('head')).attr({ type: 'text/css' });
|
|
||||||
|
|
||||||
ColorPalettePanel._panelContent = buildHtml();
|
|
||||||
}
|
|
||||||
return ColorPalettePanel._panelContent;
|
|
||||||
}
|
|
||||||
|
|
||||||
buildPanel() {
|
|
||||||
const content = $('<div class="toolbarPanel"></div>').attr(
|
|
||||||
'id',
|
|
||||||
`${this._buttonId}colorPalette`,
|
|
||||||
);
|
|
||||||
content.html(this._load());
|
|
||||||
|
|
||||||
// Register on toolbar elements ...
|
|
||||||
const colorCells = content.find('div[class=palette-colorswatch]');
|
|
||||||
const model = this.getModel();
|
|
||||||
const me = this;
|
|
||||||
colorCells.each((index, elem) => {
|
|
||||||
$(elem).on('click', () => {
|
|
||||||
const color = $(elem).css('background-color');
|
|
||||||
model.setValue(color);
|
|
||||||
me.hide();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
|
|
||||||
_updateSelectedItem() {
|
|
||||||
const panelElem = this.getPanelElem();
|
|
||||||
|
|
||||||
// Clear selected cell based on the color ...
|
|
||||||
panelElem.find("td[class='palette-cell palette-cell-selected']").attr('class', 'palette-cell');
|
|
||||||
|
|
||||||
// Mark the cell as selected ...
|
|
||||||
const colorCells = panelElem.find('div[class=palette-colorswatch]');
|
|
||||||
const model = this.getModel();
|
|
||||||
let modelValue = model.getValue();
|
|
||||||
colorCells.each((index, elem) => {
|
|
||||||
const color = rgb2hex($(elem).css('background-color'));
|
|
||||||
if (modelValue != null && modelValue[0] === 'r') {
|
|
||||||
modelValue = rgb2hex(modelValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (modelValue != null && modelValue.toUpperCase() === color.toUpperCase()) {
|
|
||||||
$(elem).parent().attr('class', 'palette-cell palette-cell-selected');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return panelElem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ColorPalettePanel;
|
|
@ -1,48 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright [2021] [wisemapping]
|
|
||||||
*
|
|
||||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
|
||||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
|
||||||
* "powered by wisemapping" text requirement on every single page;
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the license at
|
|
||||||
*
|
|
||||||
* http://www.wisemapping.org/license
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
import $ from 'jquery';
|
|
||||||
import ListToolbarPanel from './ListToolbarPanel';
|
|
||||||
|
|
||||||
class FontFamilyPanel extends ListToolbarPanel {
|
|
||||||
// eslint-disable-next-line class-methods-use-this
|
|
||||||
buildPanel() {
|
|
||||||
const content = $("<div class='toolbarPanel' id='fontFamilyPanel'></div>");
|
|
||||||
const list = [
|
|
||||||
'Arial',
|
|
||||||
'Baskerville',
|
|
||||||
'Tahoma',
|
|
||||||
'Limunari',
|
|
||||||
'Brush Script MT',
|
|
||||||
'Verdana',
|
|
||||||
'Times',
|
|
||||||
'Cursive',
|
|
||||||
'Fantasy',
|
|
||||||
'Perpetua',
|
|
||||||
'Brush Script',
|
|
||||||
'Copperplate',
|
|
||||||
]
|
|
||||||
.sort()
|
|
||||||
.map((f) => `<div model="${f}" class="toolbarPanelLink" style="font-family:${f};">${f}</div>`)
|
|
||||||
.join('\n');
|
|
||||||
|
|
||||||
content.html(list);
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default FontFamilyPanel;
|
|
@ -1,36 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright [2021] [wisemapping]
|
|
||||||
*
|
|
||||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
|
||||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
|
||||||
* "powered by wisemapping" text requirement on every single page;
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the license at
|
|
||||||
*
|
|
||||||
* http://www.wisemapping.org/license
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
import $ from 'jquery';
|
|
||||||
import ListToolbarPanel from './ListToolbarPanel';
|
|
||||||
|
|
||||||
class FontSizePanel extends ListToolbarPanel {
|
|
||||||
// eslint-disable-next-line class-methods-use-this
|
|
||||||
buildPanel() {
|
|
||||||
const content = $("<div class='toolbarPanel' id='fontSizePanel'></div>");
|
|
||||||
content[0].innerHTML =
|
|
||||||
'' +
|
|
||||||
'<div id="small" model="6" style="font-size:8px">Small</div>' +
|
|
||||||
'<div id="normal" model="8" style="font-size:12px">Normal</div>' +
|
|
||||||
'<div id="large" model="10" style="font-size:15px">Large</div>' +
|
|
||||||
'<div id="huge" model="15" style="font-size:24px">Huge</div>';
|
|
||||||
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default FontSizePanel;
|
|
@ -1,125 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright [2021] [wisemapping]
|
|
||||||
*
|
|
||||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
|
||||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
|
||||||
* "powered by wisemapping" text requirement on every single page;
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the license at
|
|
||||||
*
|
|
||||||
* http://www.wisemapping.org/license
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
import { $assert } from '@wisemapping/core-js';
|
|
||||||
import { $msg } from '@wisemapping/mindplot/src/components/Messages';
|
|
||||||
import PersistenceManager from '@wisemapping/mindplot/src/components/PersistenceManager';
|
|
||||||
import { $notify } from '@wisemapping/mindplot/src/components/widget/ToolbarNotifier';
|
|
||||||
import { $notifyModal } from '../menu/ModalDialogNotifier';
|
|
||||||
import Designer from '@wisemapping/mindplot/src/components/Designer';
|
|
||||||
import ToolbarItem from '../menu/ToolbarItem';
|
|
||||||
|
|
||||||
class IMenu {
|
|
||||||
private _designer: Designer;
|
|
||||||
|
|
||||||
protected _toolbarElems: ToolbarItem[];
|
|
||||||
|
|
||||||
private _mindmapUpdated: boolean;
|
|
||||||
|
|
||||||
constructor(designer: Designer, containerId: string) {
|
|
||||||
$assert(designer, 'designer can not be null');
|
|
||||||
$assert(containerId, 'containerId can not be null');
|
|
||||||
|
|
||||||
this._designer = designer;
|
|
||||||
this._toolbarElems = [];
|
|
||||||
this._mindmapUpdated = false;
|
|
||||||
const me = this;
|
|
||||||
|
|
||||||
// Register update events ...
|
|
||||||
this._designer.addEvent('modelUpdate', () => {
|
|
||||||
me.setRequireChange(true);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
clear() {
|
|
||||||
this._toolbarElems.forEach((item) => {
|
|
||||||
item.hide();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
discardChanges(designer: Designer) {
|
|
||||||
// Avoid autosave before leaving the page ....
|
|
||||||
this.setRequireChange(false);
|
|
||||||
|
|
||||||
// Finally call discard function ...
|
|
||||||
const persistenceManager = PersistenceManager.getInstance();
|
|
||||||
const mindmap = designer.getMindmap();
|
|
||||||
persistenceManager.discardChanges(mindmap.getId());
|
|
||||||
|
|
||||||
// Unlock map ...
|
|
||||||
this.unlockMap(designer);
|
|
||||||
|
|
||||||
// Reload the page ...
|
|
||||||
window.location.reload();
|
|
||||||
}
|
|
||||||
|
|
||||||
unlockMap(designer: Designer) {
|
|
||||||
const mindmap = designer.getMindmap();
|
|
||||||
const persistenceManager = PersistenceManager.getInstance();
|
|
||||||
|
|
||||||
// If the map could not be loaded, partial map load could happen.
|
|
||||||
if (mindmap) {
|
|
||||||
persistenceManager.unlockMap(mindmap.getId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
save(saveElem: JQuery, designer: Designer, saveHistory: boolean) {
|
|
||||||
// Load map content ...
|
|
||||||
const mindmap = designer.getMindmap();
|
|
||||||
const mindmapProp = designer.getMindmapProperties();
|
|
||||||
|
|
||||||
// Display save message ..
|
|
||||||
if (saveHistory) {
|
|
||||||
$notify($msg('SAVING'));
|
|
||||||
saveElem.css('cursor', 'wait');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call persistence manager for saving ...
|
|
||||||
const menu = this;
|
|
||||||
const persistenceManager = PersistenceManager.getInstance();
|
|
||||||
persistenceManager.save(mindmap, mindmapProp, saveHistory, {
|
|
||||||
onSuccess() {
|
|
||||||
if (saveHistory) {
|
|
||||||
saveElem.css('cursor', 'pointer');
|
|
||||||
$notify($msg('SAVE_COMPLETE'));
|
|
||||||
}
|
|
||||||
menu.setRequireChange(false);
|
|
||||||
},
|
|
||||||
onError(error) {
|
|
||||||
if (saveHistory) {
|
|
||||||
saveElem.css('cursor', 'pointer');
|
|
||||||
|
|
||||||
if (error.severity !== 'FATAL') {
|
|
||||||
$notify(error.message);
|
|
||||||
} else {
|
|
||||||
$notifyModal(error.message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
isSaveRequired(): boolean {
|
|
||||||
return this._mindmapUpdated;
|
|
||||||
}
|
|
||||||
|
|
||||||
setRequireChange(value: boolean) {
|
|
||||||
this._mindmapUpdated = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default IMenu;
|
|
@ -1,68 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright [2021] [wisemapping]
|
|
||||||
*
|
|
||||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
|
||||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
|
||||||
* "powered by wisemapping" text requirement on every single page;
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the license at
|
|
||||||
*
|
|
||||||
* http://www.wisemapping.org/license
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
import $ from 'jquery';
|
|
||||||
import ToolbarPaneItem from './ToolbarPaneItem';
|
|
||||||
import { ImageIcon } from '@wisemapping/mindplot';
|
|
||||||
|
|
||||||
class IconPanel extends ToolbarPaneItem {
|
|
||||||
_updateSelectedItem() {
|
|
||||||
return this.getPanelElem();
|
|
||||||
}
|
|
||||||
|
|
||||||
buildPanel() {
|
|
||||||
const content = $('<div class="toolbarPanel" id="IconsPanel"></div>').css({
|
|
||||||
width: 295,
|
|
||||||
height: 305,
|
|
||||||
});
|
|
||||||
content.on('click', (event) => {
|
|
||||||
event.stopPropagation();
|
|
||||||
});
|
|
||||||
|
|
||||||
let count = 0;
|
|
||||||
let familyContent;
|
|
||||||
for (let i = 0; i < ImageIcon.prototype.ICON_FAMILIES.length; i += 1) {
|
|
||||||
const familyIcons = ImageIcon.prototype.ICON_FAMILIES[i].icons;
|
|
||||||
for (let j = 0; j < familyIcons.length; j += 1) {
|
|
||||||
if (count % 12 === 0) {
|
|
||||||
familyContent = $('<div></div>');
|
|
||||||
content.append(familyContent);
|
|
||||||
}
|
|
||||||
|
|
||||||
const iconId = familyIcons[j];
|
|
||||||
const img = $('<img>')
|
|
||||||
.attr('id', iconId)
|
|
||||||
.attr('src', ImageIcon.getImageUrl(iconId))
|
|
||||||
.attr('class', 'panelIcon');
|
|
||||||
|
|
||||||
familyContent.append(img);
|
|
||||||
|
|
||||||
const panel = this;
|
|
||||||
const model = this.getModel();
|
|
||||||
img.on('click', (event) => {
|
|
||||||
model.setValue($(event.target).attr('id'));
|
|
||||||
panel.hide();
|
|
||||||
});
|
|
||||||
|
|
||||||
count += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default IconPanel;
|
|
@ -1,145 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright [2021] [wisemapping]
|
|
||||||
*
|
|
||||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
|
||||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
|
||||||
* "powered by wisemapping" text requirement on every single page;
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the license at
|
|
||||||
*
|
|
||||||
* http://www.wisemapping.org/license
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
import BootstrapDialog from '../bootstrap/BootstrapDialog';
|
|
||||||
import { $msg } from '@wisemapping/mindplot';
|
|
||||||
|
|
||||||
class KeyboardShortcutDialog extends BootstrapDialog {
|
|
||||||
constructor() {
|
|
||||||
super($msg('SHORTCUTS'), {
|
|
||||||
closeButton: true,
|
|
||||||
acceptButton: false,
|
|
||||||
});
|
|
||||||
this.setContent(`<div id="keyboardTable">
|
|
||||||
<table>
|
|
||||||
<colgroup>
|
|
||||||
<col width="40%"/>
|
|
||||||
<col width="30%"/>
|
|
||||||
<col width="30%"/>
|
|
||||||
</colgroup>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>${$msg('ACTION')}</th>
|
|
||||||
<th>Windows - Linux</th>
|
|
||||||
<th>Mac OS X</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td>${$msg('SAVE_CHANGES')}</td>
|
|
||||||
<td>${$msg('CTRL')} + S</td>
|
|
||||||
<td>⌘ + S</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>${$msg('CREATE_SIBLING_TOPIC')}</td>
|
|
||||||
<td>Enter</td>
|
|
||||||
<td>Enter</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>${$msg('CREATE_CHILD_TOPIC')}</td>
|
|
||||||
<td>${$msg('K_INSERT')} / Tab</td>
|
|
||||||
<td>⌘ + Enter / Tab</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>${$msg('DELETE_TOPIC')}</td>
|
|
||||||
<td>${$msg('K_DELETE')}</td>
|
|
||||||
<td>Delete</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>${$msg('EDIT_TOPIC_TEXT')}</td>
|
|
||||||
<td>${$msg('JUST_START_TYPING')} | F2</td>
|
|
||||||
<td>${$msg('JUST_START_TYPING')} | F2</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>${$msg('MULTIPLE_LINES')}</td>
|
|
||||||
<td>${$msg('CTRL')} + Enter</td>
|
|
||||||
<td>⌘ + Enter</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>${$msg('COPY_AND_PASTE_TOPICS')}</td>
|
|
||||||
<td>${$msg('CTRL')} + C / ${$msg('CTRL')} + V</td>
|
|
||||||
<td>⌘ + C / ⌘ + V</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>${$msg('COLLAPSE_CHILDREN')}</td>
|
|
||||||
<td>${$msg('SPACE_BAR')}</td>
|
|
||||||
<td>${$msg('SPACE_BAR')}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>${$msg('TOPIC_NAVIGATION')}</td>
|
|
||||||
<td>${$msg('ARROW_KEYS')}</td>
|
|
||||||
<td>${$msg('ARROW_KEYS')}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>${$msg('SELECT_MULTIPLE_NODES')}</td>
|
|
||||||
<td>${$msg('CTRL')} + ${$msg('MOUSE_CLICK')}</td>
|
|
||||||
<td>${$msg('CTRL')} + ${$msg('MOUSE_CLICK')}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>${$msg('UNDO_EDITION')}</td>
|
|
||||||
<td>${$msg('CTRL')} + Z</td>
|
|
||||||
<td>⌘ + Z</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>${$msg('REDO_EDITION')}</td>
|
|
||||||
<td>${$msg('CTRL')} + Shift + Z</td>
|
|
||||||
<td>⌘ + Shift + Z</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>${$msg('SELECT_ALL_TOPIC')}</td>
|
|
||||||
<td>${$msg('CTRL')} + A</td>
|
|
||||||
<td>⌘ + A</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>${$msg('CANCEL_TEXT_CHANGES')}</td>
|
|
||||||
<td>Esc</td>
|
|
||||||
<td>Esc</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>${$msg('DESELECT_ALL_TOPIC')}</td>
|
|
||||||
<td>${$msg('CTRL')} + Shift + A</td>
|
|
||||||
<td>⌘ + Shift + A</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>${$msg('CHANGE_TEXT_ITALIC')}</td>
|
|
||||||
<td>${$msg('CTRL')} + I</td>
|
|
||||||
<td>⌘ + I</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>${$msg('CHANGE_TEXT_BOLD')}</td>
|
|
||||||
<td>${$msg('CTRL')} + B</td>
|
|
||||||
<td>⌘ + B</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>${$msg('TOPIC_NOTE')}</td>
|
|
||||||
<td>${$msg('CTRL')} + K</td>
|
|
||||||
<td>⌘ + K</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>${$msg('TOPIC_LINK')}</td>
|
|
||||||
<td>${$msg('CTRL')} + L</td>
|
|
||||||
<td>⌘ + L</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>`);
|
|
||||||
this.show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default KeyboardShortcutDialog;
|
|
@ -1,67 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright [2021] [wisemapping]
|
|
||||||
*
|
|
||||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
|
||||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
|
||||||
* "powered by wisemapping" text requirement on every single page;
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the license at
|
|
||||||
*
|
|
||||||
* http://www.wisemapping.org/license
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
import $ from 'jquery';
|
|
||||||
import { $assert } from '@wisemapping/core-js';
|
|
||||||
import FloatingTip from '../bootstrap/FloatingTip';
|
|
||||||
|
|
||||||
class KeyboardShortcutTooltip extends FloatingTip {
|
|
||||||
constructor(buttonElem, text) {
|
|
||||||
$assert(buttonElem, 'buttonElem can not be null');
|
|
||||||
$assert(text, 'text can not be null');
|
|
||||||
|
|
||||||
const children = buttonElem.children().first();
|
|
||||||
const tipElemId = `${buttonElem.attr('id')}Tip`;
|
|
||||||
const tipDiv = $('<div></div>').attr('id', tipElemId);
|
|
||||||
tipDiv.append(children);
|
|
||||||
buttonElem.append(tipDiv);
|
|
||||||
|
|
||||||
super(tipDiv, {
|
|
||||||
// content can be a function or string
|
|
||||||
content: KeyboardShortcutTooltip._buildContent(text),
|
|
||||||
html: true,
|
|
||||||
placement: 'bottom',
|
|
||||||
className: 'keyboardShortcutTip',
|
|
||||||
template:
|
|
||||||
'<div class="popover popoverBlack" role="tooltip"><div class="arrow arrowBlack"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>',
|
|
||||||
});
|
|
||||||
tipDiv.on('click', (e) => {
|
|
||||||
tipDiv.trigger('mouseleave', e);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
static _buildContent(text) {
|
|
||||||
const result = $('<div></div>');
|
|
||||||
result.css({
|
|
||||||
padding: '3px 0px',
|
|
||||||
width: '100%',
|
|
||||||
});
|
|
||||||
|
|
||||||
const textContainer = $('<div></div>').text(text);
|
|
||||||
textContainer.css({
|
|
||||||
width: '100%',
|
|
||||||
'font-size': '90%',
|
|
||||||
textAlign: 'center',
|
|
||||||
'font-weight': 'bold',
|
|
||||||
});
|
|
||||||
|
|
||||||
result.append(textContainer);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default KeyboardShortcutTooltip;
|
|
@ -1,57 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright [2021] [wisemapping]
|
|
||||||
*
|
|
||||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
|
||||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
|
||||||
* "powered by wisemapping" text requirement on every single page;
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the license at
|
|
||||||
*
|
|
||||||
* http://www.wisemapping.org/license
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
import $ from 'jquery';
|
|
||||||
import { $assert, $defined } from '@wisemapping/core-js';
|
|
||||||
import ToolbarPaneItem from './ToolbarPaneItem';
|
|
||||||
|
|
||||||
class ListToolbarPanel extends ToolbarPaneItem {
|
|
||||||
constructor(buttonId, model) {
|
|
||||||
super(buttonId, model);
|
|
||||||
this._initPanel();
|
|
||||||
}
|
|
||||||
|
|
||||||
_initPanel() {
|
|
||||||
// Register on toolbar elements ...
|
|
||||||
const me = this;
|
|
||||||
this.getPanelElem()
|
|
||||||
.children('div')
|
|
||||||
.bind('click', function click(event) {
|
|
||||||
event.stopPropagation();
|
|
||||||
me.hide();
|
|
||||||
const value = $defined($(this).attr('model')) ? $(this).attr('model') : $(this).attr('id');
|
|
||||||
me.getModel().setValue(value);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
_updateSelectedItem() {
|
|
||||||
const panelElem = this.getPanelElem();
|
|
||||||
const menuElems = panelElem.find('div');
|
|
||||||
const value = this.getModel().getValue();
|
|
||||||
menuElems.each((index, elem) => {
|
|
||||||
const elemValue = $defined($(elem).attr('model'))
|
|
||||||
? $(elem).attr('model')
|
|
||||||
: $(elem).attr('id');
|
|
||||||
$assert(elemValue, 'elemValue can not be null');
|
|
||||||
if (elemValue === value) $(elem).attr('class', 'toolbarPanelLinkSelectedLink');
|
|
||||||
else $(elem).attr('class', 'toolbarPanelLink');
|
|
||||||
});
|
|
||||||
return panelElem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ListToolbarPanel;
|
|
@ -1,428 +0,0 @@
|
|||||||
/* eslint-disable no-new */
|
|
||||||
/*
|
|
||||||
* Copyright [2021] [wisemapping]
|
|
||||||
*
|
|
||||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
|
||||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
|
||||||
* "powered by wisemapping" text requirement on every single page;
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the license at
|
|
||||||
*
|
|
||||||
* http://www.wisemapping.org/license
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
import $ from 'jquery';
|
|
||||||
import { Designer } from '@wisemapping/mindplot';
|
|
||||||
import FontFamilyPanel from './FontFamilyPanel';
|
|
||||||
import FontSizePanel from './FontSizePanel';
|
|
||||||
import TopicShapePanel from './TopicShapePanel';
|
|
||||||
import IconPanel from './IconPanel';
|
|
||||||
import ColorPalettePanel from './ColorPalettePanel';
|
|
||||||
import ToolbarItem from './ToolbarItem';
|
|
||||||
import KeyboardShortcutTooltip from './KeyboardShortcutTooltip';
|
|
||||||
import KeyboardShortcutDialog from './KeyboardShortcutDialog';
|
|
||||||
import AccountSettingsPanel from './AccountSettingsPanel';
|
|
||||||
import IMenu from './IMenu';
|
|
||||||
import { $msg } from '@wisemapping/mindplot';
|
|
||||||
|
|
||||||
class Menu extends IMenu {
|
|
||||||
constructor(designer: Designer, containerId: string, readOnly = false, baseUrl = '') {
|
|
||||||
super(designer, containerId);
|
|
||||||
const widgetsBaseUrl = `${baseUrl}css/widget`;
|
|
||||||
|
|
||||||
// Create panels ...
|
|
||||||
|
|
||||||
const designerModel = designer.getModel();
|
|
||||||
|
|
||||||
// Common actions ....
|
|
||||||
const backTolist = $('#backToList');
|
|
||||||
backTolist.bind('click', (event) => {
|
|
||||||
event.stopPropagation();
|
|
||||||
window.location.href = '/c/maps/';
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
Menu._registerTooltip('backToList', $msg('BACK_TO_MAP_LIST'));
|
|
||||||
|
|
||||||
this._addButton('zoom-plus', false, false, () => {
|
|
||||||
designer.zoomIn();
|
|
||||||
});
|
|
||||||
Menu._registerTooltip('zoom-plus', $msg('ZOOM_IN'));
|
|
||||||
|
|
||||||
this._addButton('zoom-minus', false, false, () => {
|
|
||||||
designer.zoomOut();
|
|
||||||
});
|
|
||||||
Menu._registerTooltip('zoom-minus', $msg('ZOOM_OUT'));
|
|
||||||
|
|
||||||
this._addButton('position', false, false, () => {
|
|
||||||
designer.zoomToFit();
|
|
||||||
});
|
|
||||||
// Disabled because this tooltip overflows the screen and makes the button un-clickeable
|
|
||||||
// This should be enabled when migrating to material-ui
|
|
||||||
//Menu._registerTooltip('position', $msg('CENTER_POSITION'));
|
|
||||||
|
|
||||||
// Edition actions ...
|
|
||||||
if (!readOnly) {
|
|
||||||
const fontFamilyModel = {
|
|
||||||
getValue() {
|
|
||||||
const nodes = designerModel.filterSelectedTopics();
|
|
||||||
let result = null;
|
|
||||||
for (let i = 0; i < nodes.length; i++) {
|
|
||||||
const fontFamily = nodes[i].getFontFamily();
|
|
||||||
if (result != null && result !== fontFamily) {
|
|
||||||
result = null;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
result = fontFamily;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
|
|
||||||
setValue(value: string) {
|
|
||||||
designer.changeFontFamily(value);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
this._toolbarElems.push(new FontFamilyPanel('fontFamily', fontFamilyModel));
|
|
||||||
Menu._registerTooltip('fontFamily', $msg('FONT_FAMILY'));
|
|
||||||
|
|
||||||
const fontSizeModel = {
|
|
||||||
getValue(): number {
|
|
||||||
const nodes = designerModel.filterSelectedTopics();
|
|
||||||
|
|
||||||
let result = null;
|
|
||||||
for (let i = 0; i < nodes.length; i++) {
|
|
||||||
const fontSize = nodes[i].getFontSize();
|
|
||||||
if (result != null && result !== fontSize) {
|
|
||||||
result = null;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
result = fontSize;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
setValue(value: number) {
|
|
||||||
designer.changeFontSize(value);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
this._toolbarElems.push(new FontSizePanel('fontSize', fontSizeModel));
|
|
||||||
Menu._registerTooltip('fontSize', $msg('FONT_SIZE'));
|
|
||||||
|
|
||||||
const topicShapeModel = {
|
|
||||||
getValue() {
|
|
||||||
const nodes = designerModel.filterSelectedTopics();
|
|
||||||
let result = null;
|
|
||||||
for (let i = 0; i < nodes.length; i++) {
|
|
||||||
const shapeType = nodes[i].getShapeType();
|
|
||||||
if (result != null && result !== shapeType) {
|
|
||||||
result = null;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
result = shapeType;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
setValue(value: string) {
|
|
||||||
designer.changeTopicShape(value);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
this._toolbarElems.push(new TopicShapePanel('topicShape', topicShapeModel));
|
|
||||||
Menu._registerTooltip('topicShape', $msg('TOPIC_SHAPE'));
|
|
||||||
|
|
||||||
// Create icon panel dialog ...
|
|
||||||
const topicIconModel = {
|
|
||||||
getValue() {
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
setValue(value: string) {
|
|
||||||
designer.addIconType(value);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
this._toolbarElems.push(new IconPanel('topicIcon', topicIconModel));
|
|
||||||
Menu._registerTooltip('topicIcon', $msg('TOPIC_ICON'));
|
|
||||||
|
|
||||||
const topicColorModel = {
|
|
||||||
getValue() {
|
|
||||||
const nodes = designerModel.filterSelectedTopics();
|
|
||||||
let result = null;
|
|
||||||
for (let i = 0; i < nodes.length; i++) {
|
|
||||||
const color = nodes[i].getBackgroundColor();
|
|
||||||
if (result != null && result !== color) {
|
|
||||||
result = null;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
result = color;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
setValue(hex: string) {
|
|
||||||
designer.changeBackgroundColor(hex);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
this._toolbarElems.push(new ColorPalettePanel('topicColor', topicColorModel, widgetsBaseUrl));
|
|
||||||
Menu._registerTooltip('topicColor', $msg('TOPIC_COLOR'));
|
|
||||||
|
|
||||||
const borderColorModel = {
|
|
||||||
getValue() {
|
|
||||||
const nodes = designerModel.filterSelectedTopics();
|
|
||||||
let result = null;
|
|
||||||
for (let i = 0; i < nodes.length; i++) {
|
|
||||||
const color = nodes[i].getBorderColor();
|
|
||||||
if (result != null && result !== color) {
|
|
||||||
result = null;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
result = color;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
setValue(hex: string) {
|
|
||||||
designer.changeBorderColor(hex);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
this._toolbarElems.push(
|
|
||||||
new ColorPalettePanel('topicBorder', borderColorModel, widgetsBaseUrl),
|
|
||||||
);
|
|
||||||
Menu._registerTooltip('topicBorder', $msg('TOPIC_BORDER_COLOR'));
|
|
||||||
|
|
||||||
const fontColorModel = {
|
|
||||||
getValue() {
|
|
||||||
let result = null;
|
|
||||||
const nodes = designerModel.filterSelectedTopics();
|
|
||||||
for (let i = 0; i < nodes.length; i++) {
|
|
||||||
const color = nodes[i].getFontColor();
|
|
||||||
if (result != null && result !== color) {
|
|
||||||
result = null;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
result = color;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
setValue(hex) {
|
|
||||||
designer.changeFontColor(hex);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
this._toolbarElems.push(new ColorPalettePanel('fontColor', fontColorModel, baseUrl));
|
|
||||||
Menu._registerTooltip('fontColor', $msg('FONT_COLOR'));
|
|
||||||
|
|
||||||
const undoButton = this._addButton('undoEdition', false, false, () => {
|
|
||||||
designer.undo();
|
|
||||||
});
|
|
||||||
if (undoButton) {
|
|
||||||
undoButton.disable();
|
|
||||||
}
|
|
||||||
Menu._registerTooltip('undoEdition', $msg('UNDO'), $msg('CTRL') + ' + Z');
|
|
||||||
|
|
||||||
const redoButton = this._addButton('redoEdition', false, false, () => {
|
|
||||||
designer.redo();
|
|
||||||
});
|
|
||||||
if (redoButton) {
|
|
||||||
redoButton.disable();
|
|
||||||
}
|
|
||||||
Menu._registerTooltip('redoEdition', $msg('REDO'), $msg('CTRL') + ' + Shift + Z');
|
|
||||||
|
|
||||||
if (redoButton && undoButton) {
|
|
||||||
designer.addEvent('modelUpdate', (event) => {
|
|
||||||
if (event.undoSteps > 0) {
|
|
||||||
undoButton.enable();
|
|
||||||
} else {
|
|
||||||
undoButton.disable();
|
|
||||||
}
|
|
||||||
if (event.redoSteps > 0) {
|
|
||||||
redoButton.enable();
|
|
||||||
} else {
|
|
||||||
redoButton.disable();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this._addButton('addTopic', true, false, () => {
|
|
||||||
designer.createSiblingForSelectedNode();
|
|
||||||
});
|
|
||||||
Menu._registerTooltip('addTopic', $msg('ADD_TOPIC'));
|
|
||||||
|
|
||||||
this._addButton('deleteTopic', true, true, () => {
|
|
||||||
designer.deleteSelectedEntities();
|
|
||||||
});
|
|
||||||
Menu._registerTooltip('deleteTopic', $msg('TOPIC_DELETE'), $msg('K_DELETE'));
|
|
||||||
|
|
||||||
this._addButton('topicLink', true, false, () => {
|
|
||||||
designer.addLink();
|
|
||||||
});
|
|
||||||
Menu._registerTooltip('topicLink', $msg('TOPIC_LINK'));
|
|
||||||
|
|
||||||
this._addButton('topicRelation', true, false, (event) => {
|
|
||||||
designer.showRelPivot(event);
|
|
||||||
});
|
|
||||||
Menu._registerTooltip('topicRelation', $msg('TOPIC_RELATIONSHIP'));
|
|
||||||
|
|
||||||
this._addButton('topicNote', true, false, () => {
|
|
||||||
designer.addNote();
|
|
||||||
});
|
|
||||||
Menu._registerTooltip('topicNote', $msg('TOPIC_NOTE'));
|
|
||||||
|
|
||||||
this._addButton('fontBold', true, false, () => {
|
|
||||||
designer.changeFontWeight();
|
|
||||||
});
|
|
||||||
Menu._registerTooltip('fontBold', $msg('FONT_BOLD'), $msg('CTRL') + ' + B');
|
|
||||||
|
|
||||||
this._addButton('fontItalic', true, false, () => {
|
|
||||||
designer.changeFontStyle();
|
|
||||||
});
|
|
||||||
Menu._registerTooltip('fontItalic', $msg('FONT_ITALIC'), $msg('CTRL') + ' + I');
|
|
||||||
|
|
||||||
if (!readOnly) {
|
|
||||||
// Register action on save ...
|
|
||||||
const saveElem = $('#save');
|
|
||||||
this._addButton('save', false, false, () => {
|
|
||||||
this.save(saveElem, designer, true);
|
|
||||||
});
|
|
||||||
Menu._registerTooltip('save', $msg('SAVE'), $msg('CTRL') + ' + S');
|
|
||||||
|
|
||||||
// Register unload save ...
|
|
||||||
window.addEventListener('beforeunload', () => {
|
|
||||||
if (this.isSaveRequired()) {
|
|
||||||
this.save(saveElem, designer, false);
|
|
||||||
}
|
|
||||||
this.unlockMap(designer);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Autosave on a fixed period of time ...
|
|
||||||
setInterval(() => {
|
|
||||||
if (this.isSaveRequired()) {
|
|
||||||
this.save(saveElem, designer, false);
|
|
||||||
}
|
|
||||||
}, 10000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Menu._registerTooltip('export', $msg('EXPORT'));
|
|
||||||
|
|
||||||
Menu._registerTooltip('print', $msg('PRINT'));
|
|
||||||
|
|
||||||
const shareElem = $('#shareIt');
|
|
||||||
if (shareElem.length !== 0) {
|
|
||||||
Menu._registerTooltip('shareIt', $msg('COLLABORATE'));
|
|
||||||
}
|
|
||||||
|
|
||||||
const publishElem = $('#publishIt');
|
|
||||||
if (publishElem.length !== 0) {
|
|
||||||
Menu._registerTooltip('publishIt', $msg('PUBLISH'));
|
|
||||||
}
|
|
||||||
|
|
||||||
const historyElem = $('#history');
|
|
||||||
if (historyElem.length !== 0) {
|
|
||||||
Menu._registerTooltip('history', $msg('HISTORY'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keyboard Shortcuts Action ...
|
|
||||||
const keyboardShortcut = $('#keyboardShortcuts');
|
|
||||||
if (keyboardShortcut.length !== 0) {
|
|
||||||
keyboardShortcut.bind('click', (event) => {
|
|
||||||
new KeyboardShortcutDialog();
|
|
||||||
designer.onObjectFocusEvent();
|
|
||||||
event.preventDefault();
|
|
||||||
});
|
|
||||||
Menu._registerTooltip('keyboardShortcuts', $msg('KEYBOARD_SHOTCUTS'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Account dialog ...
|
|
||||||
const accountSettings = $('#account');
|
|
||||||
if (accountSettings.length !== 0) {
|
|
||||||
accountSettings.bind('click', (event) => {
|
|
||||||
event.preventDefault();
|
|
||||||
});
|
|
||||||
this._toolbarElems.push(new AccountSettingsPanel('account'));
|
|
||||||
Menu._registerTooltip('account', `${global.accountEmail}`);
|
|
||||||
|
|
||||||
this._registerEvents(designer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private _registerEvents(designer: Designer) {
|
|
||||||
// Register on close events ...
|
|
||||||
this._toolbarElems.forEach((panel) => {
|
|
||||||
panel.addEvent('show', () => {
|
|
||||||
this.clear();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
designer.addEvent('onblur', () => {
|
|
||||||
const topics = designer.getModel().filterSelectedTopics();
|
|
||||||
const rels = designer.getModel().filterSelectedRelationships();
|
|
||||||
|
|
||||||
this._toolbarElems.forEach((panel) => {
|
|
||||||
const isTopicAction = panel.isTopicAction();
|
|
||||||
const isRelAction = panel.isRelAction();
|
|
||||||
|
|
||||||
if (isTopicAction || isRelAction) {
|
|
||||||
if ((isTopicAction && topics.length !== 0) || (isRelAction && rels.length !== 0)) {
|
|
||||||
panel.enable();
|
|
||||||
} else {
|
|
||||||
panel.disable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
designer.addEvent('onfocus', () => {
|
|
||||||
const topics = designer.getModel().filterSelectedTopics();
|
|
||||||
const rels = designer.getModel().filterSelectedRelationships();
|
|
||||||
|
|
||||||
this._toolbarElems.forEach((button) => {
|
|
||||||
const isTopicAction = button.isTopicAction();
|
|
||||||
const isRelAction = button.isRelAction();
|
|
||||||
|
|
||||||
if (isTopicAction || isRelAction) {
|
|
||||||
if (isTopicAction && topics.length > 0) {
|
|
||||||
button.enable();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isRelAction && rels.length > 0) {
|
|
||||||
button.enable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private _addButton(buttonId: string, isTopic: boolean, isRelationship: boolean, fn) {
|
|
||||||
// Register Events ...
|
|
||||||
let result = null;
|
|
||||||
if ($(`#${buttonId}`)) {
|
|
||||||
const button = new ToolbarItem(
|
|
||||||
buttonId,
|
|
||||||
(event) => {
|
|
||||||
fn(event);
|
|
||||||
this.clear();
|
|
||||||
},
|
|
||||||
{ topicAction: isTopic, relAction: isRelationship },
|
|
||||||
);
|
|
||||||
|
|
||||||
this._toolbarElems.push(button);
|
|
||||||
result = button;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static _registerTooltip(buttonId: string, text: string, shortcut: string = null) {
|
|
||||||
if ($(`#${buttonId}`)) {
|
|
||||||
let tooltip = text;
|
|
||||||
if (shortcut) {
|
|
||||||
const platformedShortcut =
|
|
||||||
navigator.appVersion.indexOf('Mac') !== -1
|
|
||||||
? shortcut.replace('meta+', '⌘')
|
|
||||||
: shortcut.replace('meta+', 'ctrl+');
|
|
||||||
tooltip = `${tooltip} (${platformedShortcut})`;
|
|
||||||
}
|
|
||||||
return new KeyboardShortcutTooltip($(`#${buttonId}`), tooltip);
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Menu;
|
|
@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright [2021] [wisemapping]
|
|
||||||
*
|
|
||||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
|
||||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
|
||||||
* "powered by wisemapping" text requirement on every single page;
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the license at
|
|
||||||
* http://www.wisemapping.org/license
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
import { $assert } from '@wisemapping/core-js';
|
|
||||||
import $ from 'jquery';
|
|
||||||
|
|
||||||
class ModalDialogNotifier {
|
|
||||||
show(message, title) {
|
|
||||||
$assert(message, 'message can not be null');
|
|
||||||
|
|
||||||
const modalDialog = $(
|
|
||||||
`<div class="modal fade">
|
|
||||||
<div class="modal-dialog">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-body">
|
|
||||||
</div>
|
|
||||||
<div class="alert alert-block alert-warning">
|
|
||||||
<div style="display: inline-block" class="alert-content"></div>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>`,
|
|
||||||
);
|
|
||||||
|
|
||||||
const p = `<p>${message}</p>`;
|
|
||||||
const h4 = title ? `<h4>${title}</h4>` : '';
|
|
||||||
|
|
||||||
modalDialog.find('.alert-content').append(h4 + p);
|
|
||||||
modalDialog.modal();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const dialogNotifier = new ModalDialogNotifier();
|
|
||||||
const $notifyModal = dialogNotifier.show.bind(dialogNotifier);
|
|
||||||
|
|
||||||
// eslint-disable-next-line import/prefer-default-export
|
|
||||||
export { $notifyModal };
|
|
@ -1,87 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright [2021] [wisemapping]
|
|
||||||
*
|
|
||||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
|
||||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
|
||||||
* "powered by wisemapping" text requirement on every single page;
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the license at
|
|
||||||
*
|
|
||||||
* http://www.wisemapping.org/license
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
import $ from 'jquery';
|
|
||||||
import { $assert } from '@wisemapping/core-js';
|
|
||||||
import Events from './Events';
|
|
||||||
|
|
||||||
class ToolbarItem extends Events {
|
|
||||||
constructor(buttonId, fn, options) {
|
|
||||||
$assert(buttonId, 'buttonId can not be null');
|
|
||||||
super();
|
|
||||||
this._buttonId = buttonId;
|
|
||||||
this._options = options;
|
|
||||||
if (fn) {
|
|
||||||
this.setEventHandler(fn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setEventHandler(fn) {
|
|
||||||
$assert(fn, 'fn can not be null');
|
|
||||||
this._fn = fn;
|
|
||||||
this._enable = false;
|
|
||||||
this.enable();
|
|
||||||
}
|
|
||||||
|
|
||||||
getButtonElem() {
|
|
||||||
const elem = $(`#${this._buttonId}`);
|
|
||||||
$assert(elem, `Could not find element for ${this._buttonId}`);
|
|
||||||
return elem;
|
|
||||||
}
|
|
||||||
|
|
||||||
show() {
|
|
||||||
this.fireEvent('show');
|
|
||||||
}
|
|
||||||
|
|
||||||
hide() {
|
|
||||||
this.fireEvent('hide');
|
|
||||||
}
|
|
||||||
|
|
||||||
isTopicAction() {
|
|
||||||
return this._options.topicAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
isRelAction() {
|
|
||||||
return this._options.relAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
disable() {
|
|
||||||
const elem = this.getButtonElem();
|
|
||||||
if (this._enable) {
|
|
||||||
elem.unbind('click', this._fn);
|
|
||||||
elem.removeClass('buttonOn');
|
|
||||||
elem.addClass('buttonOff');
|
|
||||||
this._enable = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enable() {
|
|
||||||
const elem = this.getButtonElem();
|
|
||||||
if (!this._enable) {
|
|
||||||
elem.bind('click', this._fn);
|
|
||||||
elem.removeClass('buttonOff');
|
|
||||||
elem.addClass('buttonOn');
|
|
||||||
this._enable = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getTip() {
|
|
||||||
return this._tip;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ToolbarItem;
|
|
@ -1,126 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright [2021] [wisemapping]
|
|
||||||
*
|
|
||||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
|
||||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
|
||||||
* "powered by wisemapping" text requirement on every single page;
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the license at
|
|
||||||
*
|
|
||||||
* http://www.wisemapping.org/license
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
import { $assert } from '@wisemapping/core-js';
|
|
||||||
import ToolbarItem from './ToolbarItem';
|
|
||||||
import FloatingTip from '../bootstrap/FloatingTip';
|
|
||||||
|
|
||||||
class ToolbarPaneItem extends ToolbarItem {
|
|
||||||
constructor(buttonId, model, delayInit) {
|
|
||||||
$assert(buttonId, 'buttonId can not be null');
|
|
||||||
$assert(model, 'model can not be null');
|
|
||||||
super(buttonId, null, { topicAction: true, relAction: false });
|
|
||||||
|
|
||||||
const handler = () => (this.isVisible() ? this.hide() : this.show());
|
|
||||||
this.setEventHandler(handler);
|
|
||||||
this._model = model;
|
|
||||||
if (!delayInit) {
|
|
||||||
this._panelElem = this._init();
|
|
||||||
}
|
|
||||||
this._visible = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_init() {
|
|
||||||
// Load the context of the panel ...
|
|
||||||
const panelElem = this.buildPanel();
|
|
||||||
panelElem.css('cursor', 'default');
|
|
||||||
const buttonElem = this.getButtonElem();
|
|
||||||
|
|
||||||
const me = this;
|
|
||||||
this._tip = new FloatingTip(buttonElem, {
|
|
||||||
html: true,
|
|
||||||
placement: 'bottom',
|
|
||||||
content() {
|
|
||||||
return me._updateSelectedItem();
|
|
||||||
},
|
|
||||||
className: 'toolbarPaneTip',
|
|
||||||
trigger: 'manual',
|
|
||||||
template:
|
|
||||||
'<div class="popover" role="tooltip"><div class="arrow arrowGray"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>',
|
|
||||||
});
|
|
||||||
|
|
||||||
this._tip.addEvent('hide', () => {
|
|
||||||
me._visible = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
this._tip.addEvent('show', () => {
|
|
||||||
me._visible = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
return panelElem;
|
|
||||||
}
|
|
||||||
|
|
||||||
getModel() {
|
|
||||||
return this._model;
|
|
||||||
}
|
|
||||||
|
|
||||||
getPanelElem() {
|
|
||||||
return this._panelElem;
|
|
||||||
}
|
|
||||||
|
|
||||||
show() {
|
|
||||||
if (!this.isVisible()) {
|
|
||||||
super.show();
|
|
||||||
this._tip.show();
|
|
||||||
this.getButtonElem().get(0).className = 'buttonExtActive';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hide() {
|
|
||||||
if (this.isVisible()) {
|
|
||||||
super.hide();
|
|
||||||
this._tip.hide();
|
|
||||||
this.getButtonElem().get(0).className = 'buttonExtOn';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
isVisible() {
|
|
||||||
return this._visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
disable() {
|
|
||||||
this.hide();
|
|
||||||
const elem = this.getButtonElem();
|
|
||||||
if (this._enable) {
|
|
||||||
elem.unbind('click', this._fn);
|
|
||||||
elem.removeClass('buttonExtOn');
|
|
||||||
|
|
||||||
// Todo: Hack...
|
|
||||||
elem.removeClass('buttonOn');
|
|
||||||
|
|
||||||
elem.addClass('buttonExtOff');
|
|
||||||
this._enable = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enable() {
|
|
||||||
const elem = this.getButtonElem();
|
|
||||||
if (!this._enable) {
|
|
||||||
elem.bind('click', this._fn);
|
|
||||||
elem.removeClass('buttonExtOff');
|
|
||||||
elem.addClass('buttonExtOn');
|
|
||||||
this._enable = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line class-methods-use-this
|
|
||||||
buildPanel() {
|
|
||||||
throw new Error('Method must be implemented');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ToolbarPaneItem;
|
|
@ -1,38 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright [2021] [wisemapping]
|
|
||||||
*
|
|
||||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
|
||||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
|
||||||
* "powered by wisemapping" text requirement on every single page;
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the license at
|
|
||||||
*
|
|
||||||
* http://www.wisemapping.org/license
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
import $ from 'jquery';
|
|
||||||
import ListToolbarPanel from './ListToolbarPanel';
|
|
||||||
import RectangleImage from '../../../assets/images/shape-rectangle.svg';
|
|
||||||
import RectangleRoundImage from '../../../assets/images/shape-rectangle-round.svg';
|
|
||||||
import LineImage from '../../../assets/images/shape-line.svg';
|
|
||||||
import CircleImage from '../../../assets/images/shape-circle.svg';
|
|
||||||
|
|
||||||
class TopicShapePanel extends ListToolbarPanel {
|
|
||||||
// eslint-disable-next-line class-methods-use-this
|
|
||||||
buildPanel() {
|
|
||||||
const content = $("<div class='toolbarPanel' id='topicShapePanel'></div>");
|
|
||||||
content[0].innerHTML = `
|
|
||||||
<div id="rectagle" model="rectagle"><img src="${RectangleImage}" alt="Rectangle"></div>
|
|
||||||
<div id="rounded_rectagle" model="rounded rectagle" ><img src="${RectangleRoundImage}" alt="Rounded Rectangle"></div>
|
|
||||||
<div id="line" model="line"><img src="${LineImage}" alt="Line"></div>
|
|
||||||
<div id="elipse" model="elipse"><img src="${CircleImage}"></div>`;
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default TopicShapePanel;
|
|
@ -1,27 +1,6 @@
|
|||||||
import styled from 'styled-components';
|
// import styled from 'styled-components';
|
||||||
|
import Button from '@mui/material/Button';
|
||||||
|
|
||||||
const ActionButton = styled.div`
|
const ActionButton = Button;
|
||||||
cursor: pointer;
|
|
||||||
margin: 0px 10px;
|
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
|
||||||
user-select: none;
|
|
||||||
vertical-align: middle;
|
|
||||||
justify-content: center;
|
|
||||||
padding: 10px 25px;
|
|
||||||
font-size: 15px;
|
|
||||||
min-width: 64px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
font-weight: 600;
|
|
||||||
border-radius: 9px;
|
|
||||||
color: white;
|
|
||||||
background-color: #ffa800;
|
|
||||||
display: inline-block;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
transition: background-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,
|
|
||||||
box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,
|
|
||||||
border 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
export default ActionButton;
|
export default ActionButton;
|
||||||
|
@ -41,34 +41,10 @@ const Footer = ({ editorMode, isMobile }: FooterPropsType): React.ReactElement =
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if the toolbar is present, the alert must not overlap
|
// if the toolbar is present, the alert must not overlap
|
||||||
var alertTopAdjustmentStyle =
|
var alertTopAdjustmentStyle = 'tryInfoPanelWithToolbar';
|
||||||
editorMode !== 'viewonly' && !isMobile
|
|
||||||
? 'tryInfoPanelWithToolbar'
|
|
||||||
: 'tryInfoPanelWithoutToolbar';
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div id="floating-panel">
|
|
||||||
{!isMobile && (
|
|
||||||
<div id="keyboardShortcuts" className="buttonExtOn">
|
|
||||||
<img src={KeyboardSvg} />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div id="zoom-button">
|
|
||||||
<button id="zoom-plus">
|
|
||||||
<img src={AddSvg} />
|
|
||||||
</button>
|
|
||||||
<button id="zoom-minus">
|
|
||||||
<img src={MinusSvg} />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div id="position">
|
|
||||||
<button id="position-button">
|
|
||||||
<img src={CenterFocusSvg} />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<StyledLogo id="bottom-logo"></StyledLogo>
|
|
||||||
<Notifier id="headerNotifier"></Notifier>
|
<Notifier id="headerNotifier"></Notifier>
|
||||||
{titleKey && (
|
{titleKey && (
|
||||||
<div className={dialogClass + ' ' + alertTopAdjustmentStyle}>
|
<div className={dialogClass + ' ' + alertTopAdjustmentStyle}>
|
||||||
|
@ -28,4 +28,5 @@ export const Notifier = styled.div`
|
|||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
display: none;
|
display: none;
|
||||||
bottom: 10px;
|
bottom: 10px;
|
||||||
|
font-family: 'Montserrat', Arial, Helvetica, sans-serif;
|
||||||
`;
|
`;
|
||||||
|
66
packages/editor/src/components/menu/MuiWidgetManager.ts
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import {
|
||||||
|
WidgetManager,
|
||||||
|
Topic,
|
||||||
|
LinkModel,
|
||||||
|
LinkIcon,
|
||||||
|
NoteModel,
|
||||||
|
NoteIcon,
|
||||||
|
} from '@wisemapping/mindplot';
|
||||||
|
import { linkContent, noteContent } from './contents';
|
||||||
|
|
||||||
|
export default class MuiWidgetManager extends WidgetManager {
|
||||||
|
private editorOpen: boolean;
|
||||||
|
private editorContent: React.ReactElement;
|
||||||
|
private setPopoverOpen: (boolean) => void;
|
||||||
|
private setPopoverTarget: (target: Element) => void;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
setPopoverOpen: (open: boolean) => void,
|
||||||
|
setPopoverTarget: (target: Element) => void,
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
this.setPopoverOpen = setPopoverOpen;
|
||||||
|
this.setPopoverTarget = setPopoverTarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
showEditorForLink(topic: Topic, linkModel: LinkModel, linkIcon: LinkIcon) {
|
||||||
|
const model: any = {
|
||||||
|
getValue: () => topic.getLinkValue(),
|
||||||
|
setValue: (value) => topic.setLinkValue(value),
|
||||||
|
};
|
||||||
|
this.editorContent = linkContent(model, () => this.setPopoverOpen(false));
|
||||||
|
this.setPopoverTarget(topic.getOuterShape().peer._native);
|
||||||
|
this.setPopoverOpen(true);
|
||||||
|
topic.closeEditors();
|
||||||
|
}
|
||||||
|
|
||||||
|
isEditorOpen(): boolean {
|
||||||
|
return this.editorOpen;
|
||||||
|
}
|
||||||
|
|
||||||
|
getEditorContent(): React.ReactElement {
|
||||||
|
return this.editorContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleClose: (event: {}, reason: 'backdropClick' | 'escapeKeyDown') => void = () => {
|
||||||
|
this.setPopoverOpen(false);
|
||||||
|
this.editorContent = undefined;
|
||||||
|
this.setPopoverTarget(undefined);
|
||||||
|
};
|
||||||
|
|
||||||
|
showEditorForNote(topic: Topic, noteModel: NoteModel, noteIcon: NoteIcon) {
|
||||||
|
const model = {
|
||||||
|
getValue(): string {
|
||||||
|
return topic.getNoteValue();
|
||||||
|
},
|
||||||
|
setValue(value: string) {
|
||||||
|
topic.setNoteValue(value);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
this.editorContent = noteContent(model, () => this.setPopoverOpen(false));
|
||||||
|
this.setPopoverTarget(topic.getOuterShape().peer._native);
|
||||||
|
this.setPopoverOpen(true);
|
||||||
|
topic.closeEditors();
|
||||||
|
}
|
||||||
|
}
|
12
packages/editor/src/components/menu/contents.tsx
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { NoteForm, UrlForm } from '../toolbar/toolbarCustomComponents';
|
||||||
|
|
||||||
|
function linkContent(linkModel, closeModal): React.ReactElement {
|
||||||
|
return <UrlForm closeModal={closeModal} urlModel={linkModel}></UrlForm>;
|
||||||
|
}
|
||||||
|
|
||||||
|
function noteContent(noteModel, closeModal): React.ReactElement {
|
||||||
|
return <NoteForm closeModal={closeModal} noteModel={noteModel}></NoteForm>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export { linkContent, noteContent };
|
10
packages/editor/src/components/menu/useMuiWidgetManager.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import { useState, useRef } from 'react';
|
||||||
|
import MuiWidgetManager from './MuiWidgetManager';
|
||||||
|
|
||||||
|
export const useMuiWidgetManager = (): [boolean, Element | undefined, MuiWidgetManager] => {
|
||||||
|
const [popoverOpen, setPopoverOpen] = useState(false);
|
||||||
|
const [popoverTarget, setPopoverTarget] = useState(undefined);
|
||||||
|
const widgetManager = useRef(new MuiWidgetManager(setPopoverOpen, setPopoverTarget));
|
||||||
|
|
||||||
|
return [popoverOpen, popoverTarget, widgetManager.current];
|
||||||
|
};
|
34
packages/editor/src/components/toolbar/AppBar.tsx
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { ToolbarOptionConfiguration } from './ToolbarOptionConfigurationInterface';
|
||||||
|
import MaterialToolbar from '@mui/material/Toolbar';
|
||||||
|
import AppBar from '@mui/material/AppBar';
|
||||||
|
import { ToolbarMenuItem } from './Toolbar';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* App bar
|
||||||
|
* @param props.configurations the configurations array
|
||||||
|
* @returns toolbar wich contains an entry for each configuration in the array
|
||||||
|
*/
|
||||||
|
const Menubar = (props: { configurations: ToolbarOptionConfiguration[] }) => {
|
||||||
|
return (
|
||||||
|
<AppBar
|
||||||
|
role="menubar"
|
||||||
|
position="absolute"
|
||||||
|
color="default"
|
||||||
|
className="material-menubar"
|
||||||
|
sx={{
|
||||||
|
'& MuiButtonBase-root': {
|
||||||
|
marginX: '1rem',
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<MaterialToolbar>
|
||||||
|
{props.configurations.map((c, i) => {
|
||||||
|
return <ToolbarMenuItem key={i} configuration={c} />;
|
||||||
|
})}
|
||||||
|
</MaterialToolbar>
|
||||||
|
</AppBar>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Menubar;
|
203
packages/editor/src/components/toolbar/Toolbar.tsx
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
import React, { useRef, useState } from 'react';
|
||||||
|
import AppBar from '@mui/material/AppBar';
|
||||||
|
import Divider from '@mui/material/Divider';
|
||||||
|
import IconButton from '@mui/material/IconButton';
|
||||||
|
import Popover, { PopoverOrigin } from '@mui/material/Popover';
|
||||||
|
import Tooltip from '@mui/material/Tooltip';
|
||||||
|
import './appbar-buttons.css';
|
||||||
|
import Box from '@mui/material/Box';
|
||||||
|
import { ToolbarOptionConfiguration } from './ToolbarOptionConfigurationInterface';
|
||||||
|
import ToolbarPosition, { defaultPosition } from './ToolbarPositionInterface';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common button
|
||||||
|
* @param props.configuration the configuration
|
||||||
|
* @returns common button menu entry that uses the onClick of the configuration.
|
||||||
|
*/
|
||||||
|
export const ToolbarButtonOption = (props: { configuration: ToolbarOptionConfiguration }) => {
|
||||||
|
const selected = props.configuration.selected && props.configuration.selected();
|
||||||
|
return (
|
||||||
|
<Tooltip title={props.configuration.tooltip || ''} disableInteractive>
|
||||||
|
<Box component="span" my="auto">
|
||||||
|
<IconButton
|
||||||
|
onClick={props.configuration.onClick}
|
||||||
|
disabled={props.configuration.disabled && props.configuration.disabled()}
|
||||||
|
aria-pressed={selected}
|
||||||
|
// color={selected ? 'secondary' : 'default'}
|
||||||
|
>
|
||||||
|
{typeof props.configuration.icon === 'function'
|
||||||
|
? props.configuration.icon()
|
||||||
|
: props.configuration.icon}
|
||||||
|
</IconButton>
|
||||||
|
</Box>
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const verticalAligment: { anchorOrigin: PopoverOrigin; transformOrigin: PopoverOrigin } = {
|
||||||
|
anchorOrigin: {
|
||||||
|
vertical: 48,
|
||||||
|
horizontal: 'right',
|
||||||
|
},
|
||||||
|
transformOrigin: {
|
||||||
|
vertical: 'top',
|
||||||
|
horizontal: 'right',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const horizontalAligment: { anchorOrigin: PopoverOrigin; transformOrigin: PopoverOrigin } = {
|
||||||
|
anchorOrigin: {
|
||||||
|
vertical: 'center',
|
||||||
|
horizontal: -3,
|
||||||
|
},
|
||||||
|
transformOrigin: {
|
||||||
|
vertical: 'center',
|
||||||
|
horizontal: 'right',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Submenu button and popover
|
||||||
|
* @param props.configuration the configuration
|
||||||
|
* @returns submenu entry that contains one ToolbarMenuItem for each option. Inserts a divider for null options.
|
||||||
|
*/
|
||||||
|
export const ToolbarSubmenu = (props: {
|
||||||
|
configuration: ToolbarOptionConfiguration;
|
||||||
|
vertical?: boolean;
|
||||||
|
elevation?: number;
|
||||||
|
}) => {
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
const itemRef = useRef(null);
|
||||||
|
|
||||||
|
const orientationProps = props.vertical ? verticalAligment : horizontalAligment;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box
|
||||||
|
component="span"
|
||||||
|
display="inline-flex"
|
||||||
|
role="menuitem"
|
||||||
|
ref={itemRef}
|
||||||
|
onMouseLeave={() => !props.configuration.useClickToClose && setOpen(false)}
|
||||||
|
onMouseEnter={() => {
|
||||||
|
if (props.configuration.disabled && props.configuration.disabled()) return;
|
||||||
|
if (!props.configuration.useClickToClose) setOpen(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ToolbarButtonOption
|
||||||
|
configuration={{ ...props.configuration, onClick: () => setOpen(true) }}
|
||||||
|
/>
|
||||||
|
<Popover
|
||||||
|
role="submenu"
|
||||||
|
open={open}
|
||||||
|
onClose={() => setOpen(false)}
|
||||||
|
anchorEl={itemRef.current}
|
||||||
|
container={itemRef.current}
|
||||||
|
anchorOrigin={orientationProps.anchorOrigin}
|
||||||
|
transformOrigin={orientationProps.transformOrigin}
|
||||||
|
PaperProps={{
|
||||||
|
onMouseLeave: () => !props.configuration.useClickToClose && setOpen(false),
|
||||||
|
square: true,
|
||||||
|
}}
|
||||||
|
sx={{
|
||||||
|
zIndex: props.configuration.useClickToClose ? '1' : '-1',
|
||||||
|
}}
|
||||||
|
elevation={props.elevation}
|
||||||
|
>
|
||||||
|
<div style={{ display: 'flex' }} onScroll={(e) => e.stopPropagation()}>
|
||||||
|
{props.configuration.options?.map((o, i) => {
|
||||||
|
if (!o?.render) {
|
||||||
|
return (
|
||||||
|
<ToolbarMenuItem
|
||||||
|
vertical={!!!props.vertical}
|
||||||
|
key={i}
|
||||||
|
configuration={o as ToolbarOptionConfiguration}
|
||||||
|
elevation={props.elevation + 3}
|
||||||
|
></ToolbarMenuItem>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return <span key={i}>{o.render(() => setOpen(false))}</span>;
|
||||||
|
}
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</Popover>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper for all menu entries
|
||||||
|
* @param props.configuration the configuration
|
||||||
|
* @returns menu item wich contains a submenu if options is set or a button if onClick is set or null otherwise.
|
||||||
|
*/
|
||||||
|
export const ToolbarMenuItem = (props: {
|
||||||
|
configuration: ToolbarOptionConfiguration | null;
|
||||||
|
vertical?: boolean;
|
||||||
|
elevation?: number;
|
||||||
|
}) => {
|
||||||
|
if (props.configuration === null)
|
||||||
|
return (
|
||||||
|
<Divider
|
||||||
|
data-testid="divider"
|
||||||
|
orientation={!props.vertical ? 'vertical' : 'horizontal'}
|
||||||
|
flexItem
|
||||||
|
sx={{
|
||||||
|
borderLeftWidth: 1,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
if (props.configuration.visible === false) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (props.configuration.render) {
|
||||||
|
return <>{props.configuration.render(null)}</>;
|
||||||
|
}
|
||||||
|
if (!props.configuration.options && props.configuration.onClick)
|
||||||
|
return <ToolbarButtonOption configuration={props.configuration}></ToolbarButtonOption>;
|
||||||
|
else {
|
||||||
|
if (props.configuration.options)
|
||||||
|
return (
|
||||||
|
<ToolbarSubmenu
|
||||||
|
configuration={props.configuration}
|
||||||
|
vertical={props.vertical}
|
||||||
|
elevation={props.elevation || 0}
|
||||||
|
></ToolbarSubmenu>
|
||||||
|
);
|
||||||
|
else return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// const getOrientationProps = (orientation: 'horizontal' | 'vertical'): [top:number, number, ]
|
||||||
|
/**
|
||||||
|
* The entry point for create a Toolbar
|
||||||
|
* @param props.configurations the configurations array
|
||||||
|
* @returns toolbar wich contains a button/submenu for each configuration in the array
|
||||||
|
*/
|
||||||
|
const Toolbar = (props: {
|
||||||
|
configurations: ToolbarOptionConfiguration[];
|
||||||
|
position?: ToolbarPosition;
|
||||||
|
rerender?: number;
|
||||||
|
}) => {
|
||||||
|
const position = props.position || defaultPosition;
|
||||||
|
return (
|
||||||
|
<AppBar
|
||||||
|
position="fixed"
|
||||||
|
sx={{
|
||||||
|
flexDirection: position.vertical ? 'column' : 'row',
|
||||||
|
width: position.vertical ? '40px' : 'unset',
|
||||||
|
right: position.position.right,
|
||||||
|
top: position.position.top,
|
||||||
|
backgroundColor: 'white',
|
||||||
|
}}
|
||||||
|
role="menu"
|
||||||
|
aria-orientation={position.vertical ? 'vertical' : 'horizontal'}
|
||||||
|
>
|
||||||
|
{props.configurations.map((c, i) => {
|
||||||
|
return (
|
||||||
|
<ToolbarMenuItem key={i} configuration={c} elevation={2} vertical={!position.vertical} />
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</AppBar>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Toolbar;
|
@ -0,0 +1,44 @@
|
|||||||
|
/**
|
||||||
|
* Interface for menu configuration.
|
||||||
|
* One of these properties must be set: onClick, render or options.
|
||||||
|
* Property onClick is the event handler for a common button of this menu. Set options for a submenu or render for a custom element in place (from the second level onwards).
|
||||||
|
* On the first level option has priority over onClick. Second level onwards render is the first option.
|
||||||
|
*/
|
||||||
|
export interface ToolbarOptionConfiguration {
|
||||||
|
/**
|
||||||
|
* the React element for put in menu entry button
|
||||||
|
*/
|
||||||
|
icon?: React.ReactElement | (() => React.ReactElement);
|
||||||
|
/**
|
||||||
|
* text for menu entry tooltip
|
||||||
|
*/
|
||||||
|
tooltip?: string;
|
||||||
|
/**
|
||||||
|
* the event handler for a common button
|
||||||
|
*/
|
||||||
|
onClick?: (event: any) => void;
|
||||||
|
/**
|
||||||
|
* custom element for a menu entry
|
||||||
|
*/
|
||||||
|
render?: (closeMenu: () => void) => React.ReactElement;
|
||||||
|
/**
|
||||||
|
* submenu options. If null, a divider will be inserted.
|
||||||
|
*/
|
||||||
|
options?: (ToolbarOptionConfiguration | null)[];
|
||||||
|
/**
|
||||||
|
* option is disabled
|
||||||
|
*/
|
||||||
|
disabled?: () => boolean;
|
||||||
|
/**
|
||||||
|
* option is selected
|
||||||
|
*/
|
||||||
|
selected?: () => boolean;
|
||||||
|
/**
|
||||||
|
* for submenu popover, if true, popover will not be closed when mouse leave it.
|
||||||
|
*/
|
||||||
|
useClickToClose?: boolean;
|
||||||
|
/**
|
||||||
|
* if false the nmenu entry or button is not visible. Entries with custom render will ignore this property
|
||||||
|
*/
|
||||||
|
visible?: boolean;
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
/**
|
||||||
|
* Configure position of a toolbar
|
||||||
|
*/
|
||||||
|
export default interface ToolbarPosition {
|
||||||
|
/**
|
||||||
|
* if true, first level will be displayed in vertical orientation
|
||||||
|
*/
|
||||||
|
vertical?: boolean;
|
||||||
|
position?: {
|
||||||
|
/**
|
||||||
|
* css properties for appbar rigth
|
||||||
|
*/
|
||||||
|
right: string;
|
||||||
|
/**
|
||||||
|
* css properties for appbar top
|
||||||
|
*/
|
||||||
|
top: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export const defaultPosition: ToolbarPosition = {
|
||||||
|
vertical: true,
|
||||||
|
position: {
|
||||||
|
right: '50px',
|
||||||
|
top: '100px',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const horizontalPosition = {
|
||||||
|
position: {
|
||||||
|
right: '50px',
|
||||||
|
top: '90%',
|
||||||
|
},
|
||||||
|
vertical: false,
|
||||||
|
};
|
@ -0,0 +1,265 @@
|
|||||||
|
import { Designer } from '@wisemapping/mindplot';
|
||||||
|
|
||||||
|
export enum SwitchValueDirection {
|
||||||
|
'up',
|
||||||
|
'down',
|
||||||
|
}
|
||||||
|
|
||||||
|
const fontSizes = [6, 8, 10, 15];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface to get and set a property of the mindplot selected node
|
||||||
|
*/
|
||||||
|
export interface NodePropertyValueModel {
|
||||||
|
/**
|
||||||
|
* get the property value
|
||||||
|
*/
|
||||||
|
getValue: () => any;
|
||||||
|
/**
|
||||||
|
* set the property value
|
||||||
|
*/
|
||||||
|
setValue?: (value: any) => void;
|
||||||
|
/**
|
||||||
|
* toogle boolean values or change for next/previous in reduced lists of values
|
||||||
|
*/
|
||||||
|
switchValue?: (direction?: SwitchValueDirection) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given an array and the current value it return the next posible value
|
||||||
|
* @param values posible values
|
||||||
|
* @param current the current vaule
|
||||||
|
* @returns the next vaule in the array or same if is the last
|
||||||
|
*/
|
||||||
|
export function getNextValue(values: any[], current: any): any {
|
||||||
|
const nextIndex = values.indexOf(current) + 1;
|
||||||
|
if (nextIndex === values.length) return current;
|
||||||
|
return values[nextIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given an array and the current value it return the previous value
|
||||||
|
* @param values posible values
|
||||||
|
* @param current the current vaule
|
||||||
|
* @returns the previous vaule in the array or same if is the first
|
||||||
|
*/
|
||||||
|
export function getPreviousValue(values: any[], current: any): any {
|
||||||
|
const currentIndex = values.indexOf(current);
|
||||||
|
if (currentIndex === 0) return current;
|
||||||
|
if (currentIndex === -1) return values[values.length - 1];
|
||||||
|
return values[currentIndex - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the unique property value of object in the array or null if more than one exits
|
||||||
|
*/
|
||||||
|
export function getTheUniqueValueOrNull(
|
||||||
|
objectsArray: object[],
|
||||||
|
propertyValueGetter: (object: object) => string | number,
|
||||||
|
) {
|
||||||
|
let result;
|
||||||
|
for (let i = 0; i < objectsArray.length; i++) {
|
||||||
|
const value = propertyValueGetter(objectsArray[i]);
|
||||||
|
if (result != null && result !== value) {
|
||||||
|
result = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
result = value;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a designer build NodePropertyValueModel instances for the mindplot node properties
|
||||||
|
*/
|
||||||
|
export class NodePropertyValueModelBuilder {
|
||||||
|
designer: Designer;
|
||||||
|
|
||||||
|
fontSizeModel: NodePropertyValueModel;
|
||||||
|
selectedTopicColorModel: NodePropertyValueModel;
|
||||||
|
fontFamilyModel: NodePropertyValueModel;
|
||||||
|
fontStyleModel: NodePropertyValueModel;
|
||||||
|
borderColorModel: NodePropertyValueModel;
|
||||||
|
fontColorModel: NodePropertyValueModel;
|
||||||
|
topicShapeModel: NodePropertyValueModel;
|
||||||
|
topicIconModel: NodePropertyValueModel;
|
||||||
|
noteModel: NodePropertyValueModel;
|
||||||
|
linkModel: NodePropertyValueModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param designer designer to change node properties values
|
||||||
|
*/
|
||||||
|
constructor(designer: Designer) {
|
||||||
|
this.designer = designer;
|
||||||
|
}
|
||||||
|
|
||||||
|
private selectedTopic() {
|
||||||
|
return designer.getModel().selectedTopic();
|
||||||
|
}
|
||||||
|
|
||||||
|
private getFontSize() {
|
||||||
|
return designer.getModel().selectedTopic()?.getFontSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
private uniqueOrNull(propertyGetter: (Topic) => any | null) {
|
||||||
|
const nodes = designer.getModel().filterSelectedTopics();
|
||||||
|
return getTheUniqueValueOrNull(nodes, propertyGetter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @returns model to and switch font weigth
|
||||||
|
*/
|
||||||
|
fontWeigthModel(): NodePropertyValueModel {
|
||||||
|
return {
|
||||||
|
getValue: () => designer.getModel().selectedTopic()?.getFontWeight(),
|
||||||
|
switchValue: () => designer.changeFontWeight(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @returns model to and switch font size in both directions. Font sizes used to iterate: [6, 8, 10, 15]
|
||||||
|
*/
|
||||||
|
getFontSizeModel(): NodePropertyValueModel {
|
||||||
|
if (!this.fontSizeModel)
|
||||||
|
this.fontSizeModel = {
|
||||||
|
getValue: () => this.getFontSize(),
|
||||||
|
switchValue: (direction?) => {
|
||||||
|
let newValue = undefined;
|
||||||
|
if (direction === SwitchValueDirection.down) {
|
||||||
|
newValue = getPreviousValue(fontSizes, this.getFontSize());
|
||||||
|
}
|
||||||
|
if (direction === SwitchValueDirection.up) {
|
||||||
|
newValue = getNextValue(fontSizes, this.getFontSize());
|
||||||
|
}
|
||||||
|
designer.changeFontSize(newValue);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return this.fontSizeModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @returns model to get and set topic color
|
||||||
|
*/
|
||||||
|
getSelectedTopicColorModel(): NodePropertyValueModel {
|
||||||
|
if (!this.selectedTopicColorModel)
|
||||||
|
this.selectedTopicColorModel = {
|
||||||
|
getValue: () => designer.getModel().selectedTopic()?.getBackgroundColor(),
|
||||||
|
setValue: (color) => designer.changeBackgroundColor(color),
|
||||||
|
};
|
||||||
|
|
||||||
|
return this.selectedTopicColorModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @returns model to get and set the node link
|
||||||
|
*/
|
||||||
|
getLinkModel(): NodePropertyValueModel {
|
||||||
|
// const selected = this.selectedTopic();
|
||||||
|
if (!this.linkModel)
|
||||||
|
this.linkModel = {
|
||||||
|
getValue: (): string => this.selectedTopic()?.getLinkValue(),
|
||||||
|
setValue: (value: string) => {
|
||||||
|
this.selectedTopic().setLinkValue(value);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return this.linkModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @returns model to get and set topic border color
|
||||||
|
*/
|
||||||
|
getColorBorderModel(): NodePropertyValueModel {
|
||||||
|
if (!this.borderColorModel)
|
||||||
|
this.borderColorModel = {
|
||||||
|
getValue: () => this.uniqueOrNull((node) => node.getBorderColor()),
|
||||||
|
setValue: (hex: string) => designer.changeBorderColor(hex),
|
||||||
|
};
|
||||||
|
return this.borderColorModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @returns model to get and set topic font color
|
||||||
|
*/
|
||||||
|
getFontColorModel(): NodePropertyValueModel {
|
||||||
|
if (!this.fontColorModel)
|
||||||
|
this.fontColorModel = {
|
||||||
|
getValue: () => this.uniqueOrNull((node) => node.getFontColor()),
|
||||||
|
setValue: (hex: string) => designer.changeFontColor(hex),
|
||||||
|
};
|
||||||
|
return this.fontColorModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @returns model to get and set topic icon
|
||||||
|
*/
|
||||||
|
getTopicIconModel(): NodePropertyValueModel {
|
||||||
|
if (!this.topicIconModel)
|
||||||
|
this.topicIconModel = {
|
||||||
|
getValue: () => null,
|
||||||
|
setValue: (value: string) => designer.addIconType(value),
|
||||||
|
};
|
||||||
|
return this.topicIconModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @returns model to get and set topic note
|
||||||
|
*/
|
||||||
|
getNoteModel(): NodePropertyValueModel {
|
||||||
|
if (!this.noteModel)
|
||||||
|
this.noteModel = {
|
||||||
|
getValue: (): string => this.selectedTopic()?.getNoteValue(),
|
||||||
|
setValue: (value: string) => {
|
||||||
|
this.selectedTopic().setNoteValue(value);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return this.noteModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @returns model to get and set topic font family
|
||||||
|
*/
|
||||||
|
getFontFamilyModel(): NodePropertyValueModel {
|
||||||
|
if (!this.fontFamilyModel)
|
||||||
|
this.fontFamilyModel = {
|
||||||
|
getValue: () => this.uniqueOrNull((node) => node.getFontFamily()),
|
||||||
|
setValue: (value: string) => designer.changeFontFamily(value),
|
||||||
|
};
|
||||||
|
return this.fontFamilyModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @returns model to get and switch topic style
|
||||||
|
*/
|
||||||
|
getFontStyleModel(): NodePropertyValueModel {
|
||||||
|
if (!this.fontStyleModel)
|
||||||
|
this.fontStyleModel = {
|
||||||
|
getValue: () => this.selectedTopic().getFontStyle(),
|
||||||
|
switchValue: () => designer.changeFontStyle(),
|
||||||
|
};
|
||||||
|
return this.fontStyleModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @returns model to get and set topic shape
|
||||||
|
*/
|
||||||
|
getTopicShapeModel(): NodePropertyValueModel {
|
||||||
|
if (!this.topicShapeModel)
|
||||||
|
this.topicShapeModel = {
|
||||||
|
getValue: () => this.uniqueOrNull((node) => node.getShapeType()),
|
||||||
|
setValue: (value: string) => designer.changeTopicShape(value),
|
||||||
|
};
|
||||||
|
return this.topicShapeModel;
|
||||||
|
}
|
||||||
|
}
|
16
packages/editor/src/components/toolbar/appbar-buttons.css
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
.material-menubar .MuiButtonBase-root:last-child {
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
margin-left: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.truncated {
|
||||||
|
max-width: 250px;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
button[aria-pressed="true"] {
|
||||||
|
background-color: rgba(0, 0, 0, 0.04);
|
||||||
|
}
|
74
packages/editor/src/components/toolbar/colors.json
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
[
|
||||||
|
"#000000",
|
||||||
|
"#444444",
|
||||||
|
"#666666",
|
||||||
|
"#999999",
|
||||||
|
"#cccccc",
|
||||||
|
"#eeeeee",
|
||||||
|
"#f3f3f3",
|
||||||
|
"#ffffff",
|
||||||
|
"#f0f5ff",
|
||||||
|
"#e0e5ef",
|
||||||
|
"#509dc0",
|
||||||
|
"#3971b1",
|
||||||
|
"#023bb9",
|
||||||
|
"#f4b82d",
|
||||||
|
"#f1a327",
|
||||||
|
"#525c61",
|
||||||
|
"#f4cccc",
|
||||||
|
"#fce5cd",
|
||||||
|
"#fff2cc",
|
||||||
|
"#d9ead3",
|
||||||
|
"#d0e0e3",
|
||||||
|
"#cfe2f3",
|
||||||
|
"#d9d2e9",
|
||||||
|
"#ead1dc",
|
||||||
|
"#ea9999",
|
||||||
|
"#f9cb9c",
|
||||||
|
"#ffe599",
|
||||||
|
"#b6d7a8",
|
||||||
|
"#a2c4c9",
|
||||||
|
"#9fc5e8",
|
||||||
|
"#b4a7d6",
|
||||||
|
"#d5a6bd",
|
||||||
|
"#e06666",
|
||||||
|
"#f6b26b",
|
||||||
|
"#ffd966",
|
||||||
|
"#93c47d",
|
||||||
|
"#76a5af",
|
||||||
|
"#6fa8dc",
|
||||||
|
"#8e7cc3",
|
||||||
|
"#c27ba0",
|
||||||
|
"#cc0000",
|
||||||
|
"#e69138",
|
||||||
|
"#f1c232",
|
||||||
|
"#6aa84f",
|
||||||
|
"#45818e",
|
||||||
|
"#3d85c6",
|
||||||
|
"#674ea7",
|
||||||
|
"#a64d79",
|
||||||
|
"#990000",
|
||||||
|
"#b45f06",
|
||||||
|
"#bf9000",
|
||||||
|
"#38761d",
|
||||||
|
"#134f5c",
|
||||||
|
"#0b5394",
|
||||||
|
"#351c75",
|
||||||
|
"#741b47",
|
||||||
|
"#660000",
|
||||||
|
"#783f04",
|
||||||
|
"#7f6000",
|
||||||
|
"#274e13",
|
||||||
|
"#0c343d",
|
||||||
|
"#073763",
|
||||||
|
"#20124d",
|
||||||
|
"#4c1130",
|
||||||
|
"#ff0000",
|
||||||
|
"#ff9900",
|
||||||
|
"#ffff00",
|
||||||
|
"#00ff00",
|
||||||
|
"#00ffff",
|
||||||
|
"#0000ff",
|
||||||
|
"#9900ff",
|
||||||
|
"#ff00ff"
|
||||||
|
]
|
@ -17,6 +17,7 @@ div#headerNotifier {
|
|||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
display: none;
|
display: none;
|
||||||
bottom: 10px;
|
bottom: 10px;
|
||||||
|
font-family: 'Montserrat', Arial, Helvetica, sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
div#toolbarRight {
|
div#toolbarRight {
|
||||||
|
173
packages/editor/src/components/toolbar/iconGroups.json
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "people",
|
||||||
|
"icons": [
|
||||||
|
"face_smile",
|
||||||
|
"face_plain",
|
||||||
|
"face_sad",
|
||||||
|
"face_crying",
|
||||||
|
"face_surprise",
|
||||||
|
"face_wink",
|
||||||
|
"funy_angel",
|
||||||
|
"funy_devilish",
|
||||||
|
"funy_glasses",
|
||||||
|
"funy_grin",
|
||||||
|
"funy_kiss",
|
||||||
|
"funy_monkey",
|
||||||
|
"people_group",
|
||||||
|
"people_male1",
|
||||||
|
"people_male2",
|
||||||
|
"people_female1",
|
||||||
|
"people_female2"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "things",
|
||||||
|
"icons": [
|
||||||
|
"sport_basketball",
|
||||||
|
"sport_football",
|
||||||
|
"sport_golf",
|
||||||
|
"sport_raquet",
|
||||||
|
"sport_shuttlecock",
|
||||||
|
"sport_soccer",
|
||||||
|
"sport_tennis",
|
||||||
|
"bulb_light_on",
|
||||||
|
"bulb_light_off",
|
||||||
|
"hard_cd",
|
||||||
|
"hard_computer",
|
||||||
|
"hard_controller",
|
||||||
|
"hard_driver_disk",
|
||||||
|
"hard_ipod",
|
||||||
|
"hard_keyboard",
|
||||||
|
"hard_mouse",
|
||||||
|
"hard_printer",
|
||||||
|
"hard_webcam",
|
||||||
|
"hard_microphone",
|
||||||
|
"things_address_book",
|
||||||
|
"things_wrench",
|
||||||
|
"things_pin",
|
||||||
|
"things_window-layout",
|
||||||
|
"things_bubbles",
|
||||||
|
"object_bell",
|
||||||
|
"object_clanbomber",
|
||||||
|
"object_key",
|
||||||
|
"object_pencil",
|
||||||
|
"object_phone",
|
||||||
|
"object_magnifier",
|
||||||
|
"object_clip",
|
||||||
|
"object_music",
|
||||||
|
"object_star",
|
||||||
|
"object_wizard",
|
||||||
|
"object_house",
|
||||||
|
"object_cake",
|
||||||
|
"object_camera",
|
||||||
|
"object_palette",
|
||||||
|
"object_rainbow"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "other",
|
||||||
|
"icons": [
|
||||||
|
"chart_bar",
|
||||||
|
"chart_line",
|
||||||
|
"chart_curve",
|
||||||
|
"chart_pie",
|
||||||
|
"chart_organisation",
|
||||||
|
"thumb_thumb_up",
|
||||||
|
"thumb_thumb_down",
|
||||||
|
"tick_tick",
|
||||||
|
"tick_cross",
|
||||||
|
"onoff_clock",
|
||||||
|
"onoff_clock_red",
|
||||||
|
"onoff_add",
|
||||||
|
"onoff_delete",
|
||||||
|
"onoff_status_offline",
|
||||||
|
"onoff_status_online",
|
||||||
|
"money_money",
|
||||||
|
"money_dollar",
|
||||||
|
"money_euro",
|
||||||
|
"money_pound",
|
||||||
|
"money_yen",
|
||||||
|
"money_coins",
|
||||||
|
"money_ruby",
|
||||||
|
"time_calendar",
|
||||||
|
"time_clock",
|
||||||
|
"time_hourglass",
|
||||||
|
"number_1",
|
||||||
|
"number_2",
|
||||||
|
"number_3",
|
||||||
|
"number_4",
|
||||||
|
"number_5",
|
||||||
|
"number_6",
|
||||||
|
"number_7",
|
||||||
|
"number_8",
|
||||||
|
"number_9",
|
||||||
|
"sign_warning",
|
||||||
|
"sign_info",
|
||||||
|
"sign_stop",
|
||||||
|
"sign_help",
|
||||||
|
"sign_cancel",
|
||||||
|
"soft_bug",
|
||||||
|
"soft_cursor",
|
||||||
|
"soft_database_table",
|
||||||
|
"soft_database",
|
||||||
|
"soft_feed",
|
||||||
|
"soft_folder_explore",
|
||||||
|
"soft_rss",
|
||||||
|
"soft_penguin",
|
||||||
|
"arrow_up",
|
||||||
|
"arrow_down",
|
||||||
|
"arrow_left",
|
||||||
|
"arrow_right",
|
||||||
|
"arrowc_rotate_anticlockwise",
|
||||||
|
"arrowc_rotate_clockwise",
|
||||||
|
"arrowc_turn_left",
|
||||||
|
"arrowc_turn_right",
|
||||||
|
"mail_envelop",
|
||||||
|
"mail_mailbox",
|
||||||
|
"mail_edit",
|
||||||
|
"mail_list",
|
||||||
|
"flag_blue",
|
||||||
|
"flag_green",
|
||||||
|
"flag_orange",
|
||||||
|
"flag_pink",
|
||||||
|
"flag_purple",
|
||||||
|
"flag_yellow",
|
||||||
|
"social_facebook",
|
||||||
|
"social_twitter",
|
||||||
|
"social_redit",
|
||||||
|
"social_instagram",
|
||||||
|
"social_google-plus",
|
||||||
|
"meetapps_slack",
|
||||||
|
"meetapps_google-meet",
|
||||||
|
"meetapps_whatapp",
|
||||||
|
"meetapps_ms-teams",
|
||||||
|
"meetapps_zoom",
|
||||||
|
"meetapps_facebook-messenger",
|
||||||
|
"appsgoogle_youtube",
|
||||||
|
"appsgoogle_gmail",
|
||||||
|
"appsgoogle_maps",
|
||||||
|
"tag_blue",
|
||||||
|
"tag_green",
|
||||||
|
"tag_orange",
|
||||||
|
"tag_red",
|
||||||
|
"tag_pink",
|
||||||
|
"tag_yellow",
|
||||||
|
"weather_clear-night",
|
||||||
|
"weather_clear",
|
||||||
|
"weather_few-clouds-night",
|
||||||
|
"weather_few-clouds",
|
||||||
|
"weather_overcast",
|
||||||
|
"weather_severe-alert",
|
||||||
|
"weather_showers-scattered",
|
||||||
|
"weather_showers",
|
||||||
|
"weather_snow",
|
||||||
|
"weather_storm",
|
||||||
|
"task_0",
|
||||||
|
"task_25",
|
||||||
|
"task_50",
|
||||||
|
"task_75",
|
||||||
|
"task_100"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
18
packages/editor/src/components/toolbar/index.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import Toolbar from './Toolbar';
|
||||||
|
import { horizontalPosition } from './ToolbarPositionInterface';
|
||||||
|
import Appbar from './AppBar';
|
||||||
|
import {
|
||||||
|
buildEditorAppBarConfiguration,
|
||||||
|
buildToolbarCongiruation,
|
||||||
|
buildZoomToolbarConfiguration,
|
||||||
|
} from './toolbarConfigurationBuilder';
|
||||||
|
|
||||||
|
export default Toolbar;
|
||||||
|
export const configurationBuilder = {
|
||||||
|
buildEditorAppBarConfiguration,
|
||||||
|
buildToolbarCongiruation,
|
||||||
|
buildZoomToolbarConfiguration,
|
||||||
|
};
|
||||||
|
export { horizontalPosition, Appbar };
|
||||||
|
|
||||||
|
export type ToolbarActionType = 'export' | 'publish' | 'history' | 'print' | 'share' | 'info';
|
@ -1,164 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { useIntl } from 'react-intl';
|
|
||||||
|
|
||||||
import BackIconSvg from '../../../images/back-icon.svg';
|
|
||||||
import SaveSvg from '../../../images/save.svg';
|
|
||||||
import UndoSvg from '../../../images/undo.svg';
|
|
||||||
import RedoSvg from '../../../images/redo.svg';
|
|
||||||
import TopicAddSvg from '../../../images/topic-add.svg';
|
|
||||||
import TopicDeleteSvg from '../../../images/topic-delete.svg';
|
|
||||||
import TopicBorderSvg from '../../../images/topic-border.svg';
|
|
||||||
import TopicColorSvg from '../../../images/topic-color.svg';
|
|
||||||
import TopicShapeSvg from '../../../images/topic-shape.svg';
|
|
||||||
import FontTypeSvg from '../../../images/font-type.svg';
|
|
||||||
import FontSizeSvg from '../../../images/font-size.svg';
|
|
||||||
import FontBoldSvg from '../../../images/font-bold.svg';
|
|
||||||
import FontItalicSvg from '../../../images/font-italic.svg';
|
|
||||||
import FontColorSvg from '../../../images/font-color.svg';
|
|
||||||
import TopicIconSvg from '../../../images/topic-icon.svg';
|
|
||||||
import TopicNoteSvg from '../../../images/topic-note.svg';
|
|
||||||
import TopicLinkSvg from '../../../images/topic-link.svg';
|
|
||||||
import TopicRelationSvg from '../../../images/topic-relation.svg';
|
|
||||||
import ExportSvg from '../../../images/export.svg';
|
|
||||||
import InfoSvg from '../../../images/info.svg';
|
|
||||||
import PublicSvg from '../../../images/public.svg';
|
|
||||||
import HistorySvg from '../../../images/history.svg';
|
|
||||||
import PrintSvg from '../../../images/print.svg';
|
|
||||||
import AccountSvg from '../../../images/account.svg';
|
|
||||||
import './global-styled.css';
|
|
||||||
|
|
||||||
import { HeaderContainer, ToolbarButton, ToolbarButtonExt, ToolbarRightContainer } from './styled';
|
|
||||||
import ActionButton from '../action-button';
|
|
||||||
import { EditorRenderMode } from '@wisemapping/mindplot';
|
|
||||||
|
|
||||||
export type ToolbarActionType = 'export' | 'publish' | 'history' | 'print' | 'share' | 'info';
|
|
||||||
|
|
||||||
export type ToolbarPropsType = {
|
|
||||||
editorMode: EditorRenderMode;
|
|
||||||
onAction: (action: ToolbarActionType) => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function Toolbar({
|
|
||||||
editorMode: editorMode,
|
|
||||||
onAction,
|
|
||||||
}: ToolbarPropsType): React.ReactElement {
|
|
||||||
const intl = useIntl();
|
|
||||||
return (
|
|
||||||
<HeaderContainer className="wise-editor">
|
|
||||||
<div id="toolbar">
|
|
||||||
<div id="backToList">
|
|
||||||
<img src={BackIconSvg} />
|
|
||||||
</div>
|
|
||||||
{(editorMode === 'edition-editor' || editorMode === 'edition-owner') && (
|
|
||||||
<div id="persist" className="buttonContainer">
|
|
||||||
<ToolbarButton id="save" className="buttonOn">
|
|
||||||
<img src={SaveSvg} />
|
|
||||||
</ToolbarButton>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{(editorMode === 'edition-editor' ||
|
|
||||||
editorMode === 'edition-owner' ||
|
|
||||||
editorMode === 'showcase') && (
|
|
||||||
<>
|
|
||||||
<div id="edit" className="buttonContainer">
|
|
||||||
<ToolbarButton id="undoEdition" className="buttonOn">
|
|
||||||
<img src={UndoSvg} />
|
|
||||||
</ToolbarButton>
|
|
||||||
<ToolbarButton id="redoEdition" className="buttonOn">
|
|
||||||
<img src={RedoSvg} />
|
|
||||||
</ToolbarButton>
|
|
||||||
</div>
|
|
||||||
<div id="nodeStyle" className="buttonContainer">
|
|
||||||
<ToolbarButton id="addTopic" className="buttonOn">
|
|
||||||
<img src={TopicAddSvg} />
|
|
||||||
</ToolbarButton>
|
|
||||||
<ToolbarButton id="deleteTopic" className="buttonOn">
|
|
||||||
<img src={TopicDeleteSvg} />
|
|
||||||
</ToolbarButton>
|
|
||||||
<ToolbarButtonExt id="topicBorder" className="buttonExtOn">
|
|
||||||
<img src={TopicBorderSvg} />
|
|
||||||
</ToolbarButtonExt>
|
|
||||||
<ToolbarButtonExt id="topicColor" className="buttonExtOn">
|
|
||||||
<img src={TopicColorSvg} />
|
|
||||||
</ToolbarButtonExt>
|
|
||||||
<ToolbarButtonExt id="topicShape" className="buttonExtOn">
|
|
||||||
<img src={TopicShapeSvg} />
|
|
||||||
</ToolbarButtonExt>
|
|
||||||
</div>
|
|
||||||
<div id="font" className="buttonContainer">
|
|
||||||
<ToolbarButton id="fontFamily" className="buttonOn">
|
|
||||||
<img src={FontTypeSvg} />
|
|
||||||
</ToolbarButton>
|
|
||||||
<ToolbarButtonExt id="fontSize" className="buttonExtOn">
|
|
||||||
<img src={FontSizeSvg} />
|
|
||||||
</ToolbarButtonExt>
|
|
||||||
<ToolbarButton id="fontBold" className="buttonOn">
|
|
||||||
<img src={FontBoldSvg} />
|
|
||||||
</ToolbarButton>
|
|
||||||
<ToolbarButton id="fontItalic" className="buttonOn">
|
|
||||||
<img src={FontItalicSvg} />
|
|
||||||
</ToolbarButton>
|
|
||||||
<ToolbarButtonExt id="fontColor" className="buttonExtOn">
|
|
||||||
<img src={FontColorSvg} />
|
|
||||||
</ToolbarButtonExt>
|
|
||||||
</div>
|
|
||||||
<div id="nodeContent" className="buttonContainer">
|
|
||||||
<ToolbarButtonExt id="topicIcon" className="buttonExtOn">
|
|
||||||
<img src={TopicIconSvg} />
|
|
||||||
</ToolbarButtonExt>
|
|
||||||
<ToolbarButton id="topicNote" className="buttonOn">
|
|
||||||
<img src={TopicNoteSvg} />
|
|
||||||
</ToolbarButton>
|
|
||||||
<ToolbarButton id="topicLink" className="buttonOn">
|
|
||||||
<img src={TopicLinkSvg} />
|
|
||||||
</ToolbarButton>
|
|
||||||
<ToolbarButton id="topicRelation" className="buttonOn">
|
|
||||||
<img src={TopicRelationSvg} />
|
|
||||||
</ToolbarButton>
|
|
||||||
</div>
|
|
||||||
<div id="separator" className="buttonContainer"></div>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
<ToolbarRightContainer>
|
|
||||||
<ToolbarButton id="export" className="buttonOn" onClick={() => onAction('export')}>
|
|
||||||
<img src={ExportSvg} />
|
|
||||||
</ToolbarButton>
|
|
||||||
{(editorMode === 'edition-owner' ||
|
|
||||||
editorMode === 'edition-editor' ||
|
|
||||||
editorMode === 'edition-viewer') && (
|
|
||||||
<ToolbarButton id="print" className="buttonOn" onClick={() => onAction('print')}>
|
|
||||||
<img src={PrintSvg} />
|
|
||||||
</ToolbarButton>
|
|
||||||
)}
|
|
||||||
<ToolbarButton id="info" className="buttonOn" onClick={() => onAction('info')}>
|
|
||||||
<img src={InfoSvg} />
|
|
||||||
</ToolbarButton>
|
|
||||||
{editorMode === 'edition-owner' && (
|
|
||||||
<>
|
|
||||||
<ToolbarButton id="history" className="buttonOn" onClick={() => onAction('history')}>
|
|
||||||
<img src={HistorySvg} />
|
|
||||||
</ToolbarButton>
|
|
||||||
<ToolbarButton
|
|
||||||
id="publishIt"
|
|
||||||
className="buttonOn"
|
|
||||||
onClick={() => onAction('publish')}
|
|
||||||
>
|
|
||||||
<img src={PublicSvg} />
|
|
||||||
</ToolbarButton>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
{(editorMode === 'edition-owner' || editorMode === 'edition-editor') && (
|
|
||||||
<ToolbarButton id="account">
|
|
||||||
<img src={AccountSvg} />
|
|
||||||
</ToolbarButton>
|
|
||||||
)}
|
|
||||||
{editorMode === 'edition-owner' && (
|
|
||||||
<ActionButton onClick={() => onAction('share')}>
|
|
||||||
{intl.formatMessage({ id: 'action.share', defaultMessage: 'Share' })}
|
|
||||||
</ActionButton>
|
|
||||||
)}
|
|
||||||
</ToolbarRightContainer>
|
|
||||||
</div>
|
|
||||||
</HeaderContainer>
|
|
||||||
);
|
|
||||||
}
|
|
@ -0,0 +1,469 @@
|
|||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import BrushOutlinedIcon from '@mui/icons-material/BrushOutlined';
|
||||||
|
import FontDownloadOutlinedIcon from '@mui/icons-material/FontDownloadOutlined';
|
||||||
|
import TextIncreaseOutlinedIcon from '@mui/icons-material/TextIncreaseOutlined';
|
||||||
|
import TextDecreaseOutlinedIcon from '@mui/icons-material/TextDecreaseOutlined';
|
||||||
|
import FormatBoldOutlinedIcon from '@mui/icons-material/FormatBoldOutlined';
|
||||||
|
import SettingsEthernetIcon from '@mui/icons-material/SettingsEthernet';
|
||||||
|
import FormatItalicIcon from '@mui/icons-material/FormatItalic';
|
||||||
|
import NoteOutlinedIcon from '@mui/icons-material/NoteOutlined';
|
||||||
|
import LinkOutlinedIcon from '@mui/icons-material/LinkOutlined';
|
||||||
|
import ZoomOutOutlinedIcon from '@mui/icons-material/ZoomOutOutlined';
|
||||||
|
import ZoomInOutlinedIcon from '@mui/icons-material/ZoomInOutlined';
|
||||||
|
import CenterFocusStrongOutlinedIcon from '@mui/icons-material/CenterFocusStrongOutlined';
|
||||||
|
import SentimentSatisfiedAltIcon from '@mui/icons-material/SentimentSatisfiedAlt';
|
||||||
|
import UndoOutlinedIcon from '@mui/icons-material/UndoOutlined';
|
||||||
|
import RedoOutlinedIcon from '@mui/icons-material/RedoOutlined';
|
||||||
|
import RestoreOutlinedIcon from '@mui/icons-material/RestoreOutlined';
|
||||||
|
import SaveOutlinedIcon from '@mui/icons-material/SaveOutlined';
|
||||||
|
import PrintOutlinedIcon from '@mui/icons-material/PrintOutlined';
|
||||||
|
import FileDownloadOutlinedIcon from '@mui/icons-material/FileDownloadOutlined';
|
||||||
|
import CloudUploadOutlinedIcon from '@mui/icons-material/CloudUploadOutlined';
|
||||||
|
import HelpOutlineOutlinedIcon from '@mui/icons-material/InfoOutlined';
|
||||||
|
import ArrowBackIosNewOutlinedIcon from '@mui/icons-material/ArrowBackIosNewOutlined';
|
||||||
|
import CircleOutlinedIcon from '@mui/icons-material/CircleOutlined';
|
||||||
|
import SquareOutlinedIcon from '@mui/icons-material/SquareOutlined';
|
||||||
|
import CheckBoxOutlineBlankOutlinedIcon from '@mui/icons-material/CheckBoxOutlineBlankOutlined';
|
||||||
|
import HorizontalRuleOutlinedIcon from '@mui/icons-material/HorizontalRuleOutlined';
|
||||||
|
import RemoveCircleOutlineIcon from '@mui/icons-material/RemoveCircleOutline';
|
||||||
|
import AddCircleOutlineOutlinedIcon from '@mui/icons-material/AddCircleOutlineOutlined';
|
||||||
|
import Button from '@mui/material/Button';
|
||||||
|
import Box from '@mui/material/Box';
|
||||||
|
|
||||||
|
import LogoTextBlackSvg from '../../../images/logo-text-black.svg';
|
||||||
|
import Palette from '@mui/icons-material/Square';
|
||||||
|
import SquareOutlined from '@mui/icons-material/SquareOutlined';
|
||||||
|
import { $msg, Designer, EditorRenderMode } from '@wisemapping/mindplot';
|
||||||
|
import { ToolbarOptionConfiguration } from './ToolbarOptionConfigurationInterface';
|
||||||
|
import { SwitchValueDirection, NodePropertyValueModelBuilder } from './ToolbarValueModelBuilder';
|
||||||
|
import {
|
||||||
|
ColorPicker,
|
||||||
|
FontFamilySelect,
|
||||||
|
KeyboardShorcutsHelp,
|
||||||
|
NoteForm,
|
||||||
|
ToolbarEmojiPcker,
|
||||||
|
UndoAndRedoButton,
|
||||||
|
UrlForm,
|
||||||
|
} from './toolbarCustomComponents';
|
||||||
|
import Typography from '@mui/material/Typography';
|
||||||
|
import { ToolbarActionType } from '.';
|
||||||
|
import KeyboardOutlined from '@mui/icons-material/KeyboardOutlined';
|
||||||
|
import Tooltip from '@mui/material/Tooltip';
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param designer designer to aply changes
|
||||||
|
* @returns configuration for @wisemapping/editor primary toolbar
|
||||||
|
*/
|
||||||
|
export function buildToolbarCongiruation(designer: Designer): ToolbarOptionConfiguration[] {
|
||||||
|
if (!designer) return [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* model builder
|
||||||
|
*/
|
||||||
|
const toolbarValueModelBuilder = new NodePropertyValueModelBuilder(designer);
|
||||||
|
|
||||||
|
// <div id="rectagle" model="rectagle"><img src="${RectangleImage}" alt="Rectangle"></div>
|
||||||
|
// <div id="rounded_rectagle" model="rounded rectagle" ><img src="${RectangleRoundImage}" alt="Rounded Rectangle"></div>
|
||||||
|
// <div id="line" model="line"><img src="${LineImage}" alt="Line"></div>
|
||||||
|
// <div id="elipse" model="elipse"><img src="${CircleImage}"></div>`;
|
||||||
|
/**
|
||||||
|
* submenu to manipulate node color and shape
|
||||||
|
*/
|
||||||
|
const colorAndShapeToolbarConfiguration: ToolbarOptionConfiguration = {
|
||||||
|
icon: <BrushOutlinedIcon />,
|
||||||
|
|
||||||
|
tooltip: $msg('TOPIC_SHAPE'),
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
icon: <SquareOutlinedIcon />,
|
||||||
|
tooltip: $msg('TOPIC_SHAPE_RECTANGLE'),
|
||||||
|
onClick: () => toolbarValueModelBuilder.getTopicShapeModel().setValue('rectagle'),
|
||||||
|
selected: () => toolbarValueModelBuilder.getTopicShapeModel().getValue() === 'rectagle',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <CheckBoxOutlineBlankOutlinedIcon />,
|
||||||
|
tooltip: $msg('TOPIC_SHAPE_ROUNDED'),
|
||||||
|
onClick: () => toolbarValueModelBuilder.getTopicShapeModel().setValue('rounded rectagle'),
|
||||||
|
selected: () =>
|
||||||
|
toolbarValueModelBuilder.getTopicShapeModel().getValue() === 'rounded rectagle',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <HorizontalRuleOutlinedIcon />,
|
||||||
|
tooltip: $msg('TOPIC_SHAPE_LINE'),
|
||||||
|
onClick: () => toolbarValueModelBuilder.getTopicShapeModel().setValue('line'),
|
||||||
|
selected: () => toolbarValueModelBuilder.getTopicShapeModel().getValue() === 'line',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <CircleOutlinedIcon />,
|
||||||
|
tooltip: $msg('TOPIC_SHAPE_ELLIPSE'),
|
||||||
|
onClick: () => toolbarValueModelBuilder.getTopicShapeModel().setValue('elipse'),
|
||||||
|
selected: () => toolbarValueModelBuilder.getTopicShapeModel().getValue() === 'elipse',
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
{
|
||||||
|
icon: () => (
|
||||||
|
<Palette
|
||||||
|
htmlColor={toolbarValueModelBuilder.getSelectedTopicColorModel().getValue()}
|
||||||
|
></Palette>
|
||||||
|
),
|
||||||
|
tooltip: $msg('TOPIC_COLOR'),
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
render: (closeModal) => {
|
||||||
|
return (
|
||||||
|
<ColorPicker
|
||||||
|
closeModal={closeModal}
|
||||||
|
colorModel={toolbarValueModelBuilder.getSelectedTopicColorModel()}
|
||||||
|
></ColorPicker>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: () => (
|
||||||
|
<SquareOutlined
|
||||||
|
htmlColor={toolbarValueModelBuilder.getColorBorderModel().getValue()}
|
||||||
|
></SquareOutlined>
|
||||||
|
),
|
||||||
|
tooltip: $msg('TOPIC_BORDER_COLOR'),
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
render: (closeModal) => {
|
||||||
|
return (
|
||||||
|
<ColorPicker
|
||||||
|
closeModal={closeModal}
|
||||||
|
colorModel={toolbarValueModelBuilder.getColorBorderModel()}
|
||||||
|
></ColorPicker>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
disabled: () => designer.getModel().filterSelectedTopics().length === 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* submenu to manipulate node font
|
||||||
|
*/
|
||||||
|
const fontFormatToolbarConfiguration: ToolbarOptionConfiguration = {
|
||||||
|
icon: <FontDownloadOutlinedIcon></FontDownloadOutlinedIcon>,
|
||||||
|
tooltip: $msg('FONT_FORMAT'),
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
render: () => (
|
||||||
|
<FontFamilySelect fontFamilyModel={toolbarValueModelBuilder.getFontFamilyModel()} />
|
||||||
|
),
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
{
|
||||||
|
icon: <TextIncreaseOutlinedIcon></TextIncreaseOutlinedIcon>,
|
||||||
|
tooltip: $msg('FONT_INCREASE'),
|
||||||
|
onClick: () =>
|
||||||
|
toolbarValueModelBuilder.getFontSizeModel().switchValue(SwitchValueDirection.up),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <TextDecreaseOutlinedIcon></TextDecreaseOutlinedIcon>,
|
||||||
|
tooltip: $msg('FONT_DECREASE'),
|
||||||
|
onClick: () =>
|
||||||
|
toolbarValueModelBuilder.getFontSizeModel().switchValue(SwitchValueDirection.down),
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
{
|
||||||
|
icon: <FormatBoldOutlinedIcon></FormatBoldOutlinedIcon>,
|
||||||
|
tooltip: $msg('FONT_BOLD') + ' (' + $msg('CTRL') + ' + B)',
|
||||||
|
onClick: toolbarValueModelBuilder.fontWeigthModel().switchValue,
|
||||||
|
selected: () => toolbarValueModelBuilder.fontWeigthModel().getValue() === 'bold',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <FormatItalicIcon />,
|
||||||
|
tooltip: $msg('FONT_ITALIC') + ' (' + $msg('CTRL') + ' + I)',
|
||||||
|
onClick: toolbarValueModelBuilder.getFontStyleModel().switchValue,
|
||||||
|
selected: () => toolbarValueModelBuilder.getFontStyleModel().getValue() === 'italic',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: () => (
|
||||||
|
<Palette htmlColor={toolbarValueModelBuilder.getFontColorModel().getValue()}></Palette>
|
||||||
|
),
|
||||||
|
tooltip: $msg('FONT_COLOR'),
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
render: (closeModal) => {
|
||||||
|
return (
|
||||||
|
<ColorPicker
|
||||||
|
closeModal={closeModal}
|
||||||
|
colorModel={toolbarValueModelBuilder.getFontColorModel()}
|
||||||
|
></ColorPicker>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
disabled: () => designer.getModel().filterSelectedTopics().length === 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* button to show relation pivot
|
||||||
|
*/
|
||||||
|
const addRelationConfiguration: ToolbarOptionConfiguration = {
|
||||||
|
icon: <SettingsEthernetIcon></SettingsEthernetIcon>,
|
||||||
|
tooltip: $msg('TOPIC_RELATIONSHIP'),
|
||||||
|
onClick: (e) => {
|
||||||
|
designer.showRelPivot(e);
|
||||||
|
},
|
||||||
|
disabled: () => designer.getModel().filterSelectedTopics().length === 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tool for node link edition
|
||||||
|
*/
|
||||||
|
const editLinkUrlConfiguration: ToolbarOptionConfiguration = {
|
||||||
|
icon: <LinkOutlinedIcon />,
|
||||||
|
tooltip: $msg('TOPIC_LINK'),
|
||||||
|
useClickToClose: true,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
render: (closeModal) => (
|
||||||
|
<UrlForm
|
||||||
|
closeModal={closeModal}
|
||||||
|
urlModel={toolbarValueModelBuilder.getLinkModel()}
|
||||||
|
></UrlForm>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
disabled: () => designer.getModel().filterSelectedTopics().length === 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tool for node note edition
|
||||||
|
*/
|
||||||
|
const editNoteConfiguration: ToolbarOptionConfiguration = {
|
||||||
|
icon: <NoteOutlinedIcon />,
|
||||||
|
tooltip: $msg('TOPIC_NOTE'),
|
||||||
|
useClickToClose: true,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
tooltip: 'Node note',
|
||||||
|
render: (closeModal) => (
|
||||||
|
<NoteForm
|
||||||
|
closeModal={closeModal}
|
||||||
|
noteModel={toolbarValueModelBuilder.getNoteModel()}
|
||||||
|
></NoteForm>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
disabled: () => designer.getModel().filterSelectedTopics().length === 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tool for emoji selection
|
||||||
|
*/
|
||||||
|
const editIconConfiguration: ToolbarOptionConfiguration = {
|
||||||
|
icon: <SentimentSatisfiedAltIcon />,
|
||||||
|
tooltip: $msg('TOPIC_ICON'),
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
tooltip: 'Node icon',
|
||||||
|
render: (closeModal) => (
|
||||||
|
<ToolbarEmojiPcker
|
||||||
|
closeModal={closeModal}
|
||||||
|
iconModel={toolbarValueModelBuilder.getTopicIconModel()}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
disabled: () => designer.getModel().filterSelectedTopics().length === 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
const addNodeToolbarConfiguration = {
|
||||||
|
icon: <AddCircleOutlineOutlinedIcon />,
|
||||||
|
tooltip: $msg('TOPIC_ADD'),
|
||||||
|
onClick: () => designer.createSiblingForSelectedNode(),
|
||||||
|
disabled: () => designer.getModel().filterSelectedTopics().length === 0,
|
||||||
|
};
|
||||||
|
const deleteNodeToolbarConfiguration = {
|
||||||
|
icon: <RemoveCircleOutlineIcon />,
|
||||||
|
tooltip: $msg('TOPIC_DELETE'),
|
||||||
|
onClick: () => designer.deleteSelectedEntities(),
|
||||||
|
disabled: () => designer.getModel().filterSelectedTopics().length === 0,
|
||||||
|
};
|
||||||
|
return [
|
||||||
|
addNodeToolbarConfiguration,
|
||||||
|
deleteNodeToolbarConfiguration,
|
||||||
|
colorAndShapeToolbarConfiguration,
|
||||||
|
fontFormatToolbarConfiguration,
|
||||||
|
editIconConfiguration,
|
||||||
|
editNoteConfiguration,
|
||||||
|
editLinkUrlConfiguration,
|
||||||
|
addRelationConfiguration,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildZoomToolbarConfiguration(isMobile: boolean, designer: Designer) {
|
||||||
|
if (!designer) return [];
|
||||||
|
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
icon: <KeyboardOutlined />,
|
||||||
|
tooltip: $msg('KEYBOARD_SHOTCUTS'),
|
||||||
|
visible: !isMobile,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
render: () => <KeyboardShorcutsHelp />,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// zoom value candidate, neds to fixit
|
||||||
|
render: () => (
|
||||||
|
<Box sx={{ p: 0.5 }}>
|
||||||
|
<Typography variant="overline" color="gray">
|
||||||
|
%{Math.floor((1 / designer.getWorkSpace()?.getZoom()) * 100)}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <ZoomInOutlinedIcon />,
|
||||||
|
tooltip: $msg('ZOOM_IN'),
|
||||||
|
onClick: (e) => {
|
||||||
|
designer.zoomIn();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <ZoomOutOutlinedIcon />,
|
||||||
|
tooltip: $msg('ZOOM_OUT'),
|
||||||
|
onClick: (e) => {
|
||||||
|
designer.zoomOut();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <CenterFocusStrongOutlinedIcon />,
|
||||||
|
tooltip: $msg('CENTER_POSITION'),
|
||||||
|
onClick: (e) => {
|
||||||
|
designer.zoomToFit();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildEditorAppBarConfiguration(
|
||||||
|
designer: Designer,
|
||||||
|
onAction: (type: ToolbarActionType) => void,
|
||||||
|
save: () => void,
|
||||||
|
editorMode: EditorRenderMode,
|
||||||
|
isMobile: boolean,
|
||||||
|
): ToolbarOptionConfiguration[] {
|
||||||
|
let commonConfiguration = [
|
||||||
|
{
|
||||||
|
icon: <ArrowBackIosNewOutlinedIcon />,
|
||||||
|
tooltip: $msg('BACK_TO_MAP_LIST'),
|
||||||
|
onClick: () => history.back(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
render: () => <img src={LogoTextBlackSvg} />,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
if (editorMode === 'viewonly' || editorMode === 'showcase' || isMobile)
|
||||||
|
return commonConfiguration;
|
||||||
|
if (!designer) return [];
|
||||||
|
|
||||||
|
const isEditor =
|
||||||
|
editorMode === 'edition-owner' ||
|
||||||
|
editorMode === 'edition-editor' ||
|
||||||
|
editorMode === 'edition-viewer';
|
||||||
|
|
||||||
|
if (isEditor) {
|
||||||
|
return [
|
||||||
|
...commonConfiguration,
|
||||||
|
{
|
||||||
|
render: () => (
|
||||||
|
<Tooltip title={designer.getMindmap().getCentralTopic().getText()}>
|
||||||
|
<Typography
|
||||||
|
className="truncated"
|
||||||
|
variant="body1"
|
||||||
|
component="div"
|
||||||
|
sx={{ marginX: '1.5rem' }}
|
||||||
|
>
|
||||||
|
{designer.getMindmap().getCentralTopic().getText()}
|
||||||
|
</Typography>
|
||||||
|
</Tooltip>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
{
|
||||||
|
render: () => (
|
||||||
|
<UndoAndRedoButton
|
||||||
|
configuration={{
|
||||||
|
icon: <UndoOutlinedIcon />,
|
||||||
|
tooltip: $msg('UNDO') + ' (' + $msg('CTRL') + ' + Z)',
|
||||||
|
onClick: () => designer.undo(),
|
||||||
|
}}
|
||||||
|
disabledCondition={(event) => event.undoSteps > 0}
|
||||||
|
></UndoAndRedoButton>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
render: () => (
|
||||||
|
<UndoAndRedoButton
|
||||||
|
configuration={{
|
||||||
|
icon: <RedoOutlinedIcon />,
|
||||||
|
tooltip: $msg('REDO') + ' (' + $msg('CTRL') + ' + Shift + Z)',
|
||||||
|
onClick: () => designer.redo(),
|
||||||
|
}}
|
||||||
|
disabledCondition={(event) => event.redoSteps > 0}
|
||||||
|
></UndoAndRedoButton>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
{
|
||||||
|
icon: <RestoreOutlinedIcon />,
|
||||||
|
tooltip: $msg('HISTORY'),
|
||||||
|
onClick: () => onAction('history'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <SaveOutlinedIcon />,
|
||||||
|
tooltip: $msg('SAVE') + ' (' + $msg('CTRL') + ' + S)',
|
||||||
|
onClick: save,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
render: () => <Typography component="div" sx={{ flexGrow: 1 }} />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <PrintOutlinedIcon />,
|
||||||
|
tooltip: $msg('PRINT'),
|
||||||
|
onClick: () => onAction('print'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <FileDownloadOutlinedIcon />,
|
||||||
|
tooltip: $msg('EXPORT'),
|
||||||
|
onClick: () => onAction('export'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <CloudUploadOutlinedIcon />,
|
||||||
|
onClick: () => onAction('publish'),
|
||||||
|
tooltip: $msg('PUBLISH'),
|
||||||
|
disabled: () => editorMode !== 'edition-owner',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
render: () => (
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
onClick={() => onAction('share')}
|
||||||
|
disabled={editorMode !== 'edition-owner'}
|
||||||
|
>
|
||||||
|
{$msg('COLLABORATE')}
|
||||||
|
</Button>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <HelpOutlineOutlinedIcon />,
|
||||||
|
onClick: () => onAction('info'),
|
||||||
|
tooltip: $msg('MAP_INFO'),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,463 @@
|
|||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import Box from '@mui/material/Box';
|
||||||
|
import Button from '@mui/material/Button';
|
||||||
|
import FormControl from '@mui/material/FormControl';
|
||||||
|
import IconButton from '@mui/material/IconButton';
|
||||||
|
import OpenInNewOutlinedIcon from '@mui/icons-material/OpenInNewOutlined';
|
||||||
|
import DeleteOutlineOutlinedIcon from '@mui/icons-material/DeleteOutlineOutlined';
|
||||||
|
import MenuItem from '@mui/material/MenuItem';
|
||||||
|
import Select, { SelectChangeEvent } from '@mui/material/Select';
|
||||||
|
import TextField, { TextFieldProps } from '@mui/material/TextField';
|
||||||
|
import Typography from '@mui/material/Typography';
|
||||||
|
import { $msg, DesignerKeyboard, ImageIcon } from '@wisemapping/mindplot';
|
||||||
|
|
||||||
|
import { CirclePicker as ReactColorPicker } from 'react-color';
|
||||||
|
import { NodePropertyValueModel } from './ToolbarValueModelBuilder';
|
||||||
|
import iconGroups from './iconGroups.json';
|
||||||
|
import colors from './colors.json';
|
||||||
|
import Link from '@mui/material/Link';
|
||||||
|
import Tab from '@mui/material/Tab';
|
||||||
|
import Tabs from '@mui/material/Tabs';
|
||||||
|
import { ToolbarMenuItem } from './Toolbar';
|
||||||
|
import { ToolbarOptionConfiguration } from './ToolbarOptionConfigurationInterface';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Color picker for toolbar
|
||||||
|
*/
|
||||||
|
export const ColorPicker = (props: {
|
||||||
|
closeModal: () => void;
|
||||||
|
colorModel: NodePropertyValueModel;
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<Box component="div" sx={{ m: 2 }}>
|
||||||
|
<ReactColorPicker
|
||||||
|
color={props.colorModel.getValue() || '#fff'}
|
||||||
|
onChangeComplete={(color) => {
|
||||||
|
props.colorModel.setValue(color.hex);
|
||||||
|
props.closeModal();
|
||||||
|
}}
|
||||||
|
colors={colors}
|
||||||
|
width={216}
|
||||||
|
circleSpacing={9}
|
||||||
|
circleSize={18}
|
||||||
|
></ReactColorPicker>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* checks whether the input is a valid url
|
||||||
|
* @return {Boolean} true if the url is valid
|
||||||
|
*/
|
||||||
|
function checkURL(url: string): boolean {
|
||||||
|
const regex =
|
||||||
|
/^((http|https):\/\/)?[a-z0-9]+([-.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/i;
|
||||||
|
return regex.test(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
const SaveAndDelete = (props: {
|
||||||
|
model: NodePropertyValueModel;
|
||||||
|
closeModal: () => void;
|
||||||
|
submitHandler: () => void;
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<Box component="span">
|
||||||
|
<IconButton
|
||||||
|
onClick={() => {
|
||||||
|
props.closeModal();
|
||||||
|
props.model.setValue(undefined);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<DeleteOutlineOutlinedIcon />
|
||||||
|
</IconButton>
|
||||||
|
<Button color="primary" variant="outlined" onClick={props.submitHandler} sx={{ mr: 1 }}>
|
||||||
|
{$msg('ACCEPT')}
|
||||||
|
</Button>
|
||||||
|
<Button color="primary" variant="contained" onClick={props.closeModal}>
|
||||||
|
{$msg('CANCEL')}
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Url form for toolbar and node contextual editor
|
||||||
|
*/
|
||||||
|
export const UrlForm = (props: { closeModal: () => void; urlModel: NodePropertyValueModel }) => {
|
||||||
|
const [url, setUrl] = useState(props.urlModel.getValue());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* if url is valid set model value and calls closeModal
|
||||||
|
*/
|
||||||
|
const submitHandler = () => {
|
||||||
|
if (checkURL(url)) {
|
||||||
|
props.closeModal();
|
||||||
|
props.urlModel.setValue(url);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const keyDownHandler = (event) => {
|
||||||
|
if (event.key === 'Enter') {
|
||||||
|
event.preventDefault();
|
||||||
|
submitHandler();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const isValidUrl = !url || checkURL(url);
|
||||||
|
return (
|
||||||
|
<Box display="flex" sx={{ p: 1 }}>
|
||||||
|
<Input
|
||||||
|
autoFocus
|
||||||
|
error={!isValidUrl}
|
||||||
|
helperText={isValidUrl ? '' : $msg('URL_ERROR')}
|
||||||
|
placeholder={$msg('PASTE_URL_HERE')}
|
||||||
|
label="URL"
|
||||||
|
value={url}
|
||||||
|
onChange={(event) => setUrl(event.target.value)}
|
||||||
|
variant="outlined"
|
||||||
|
size="small"
|
||||||
|
onKeyDown={keyDownHandler}
|
||||||
|
InputProps={{
|
||||||
|
endAdornment: (
|
||||||
|
<Link href={isValidUrl ? url : ''} target="_blank">
|
||||||
|
<IconButton disabled={!isValidUrl}>
|
||||||
|
<OpenInNewOutlinedIcon></OpenInNewOutlinedIcon>
|
||||||
|
</IconButton>
|
||||||
|
</Link>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
sx={{ pr: 1 }}
|
||||||
|
></Input>
|
||||||
|
<SaveAndDelete
|
||||||
|
model={props.urlModel}
|
||||||
|
closeModal={props.closeModal}
|
||||||
|
submitHandler={submitHandler}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param props text field props.
|
||||||
|
* @returns wrapped mui TextField, that disable mindplot keyboard events on focus and enable it on blur
|
||||||
|
*/
|
||||||
|
const Input = (props: TextFieldProps) => {
|
||||||
|
useEffect(() => {
|
||||||
|
return () => DesignerKeyboard.resume();
|
||||||
|
}, []);
|
||||||
|
return (
|
||||||
|
<TextField
|
||||||
|
{...props}
|
||||||
|
onFocus={(e) => {
|
||||||
|
DesignerKeyboard.pause();
|
||||||
|
props.onFocus && props.onFocus(e);
|
||||||
|
}}
|
||||||
|
onBlur={(e) => {
|
||||||
|
DesignerKeyboard.resume();
|
||||||
|
props.onBlur && props.onBlur(e);
|
||||||
|
}}
|
||||||
|
></TextField>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Note form for toolbar and node contextual editor
|
||||||
|
*/
|
||||||
|
export const NoteForm = (props: {
|
||||||
|
closeModal: () => void;
|
||||||
|
noteModel: NodePropertyValueModel | null;
|
||||||
|
}) => {
|
||||||
|
const [note, setNote] = useState(props.noteModel.getValue());
|
||||||
|
|
||||||
|
const submitHandler = () => {
|
||||||
|
props.closeModal();
|
||||||
|
props.noteModel.setValue(note);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box sx={{ p: 2, width: '300px' }}>
|
||||||
|
<Input
|
||||||
|
autoFocus
|
||||||
|
multiline
|
||||||
|
label={$msg('NOTE')}
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
rows={12}
|
||||||
|
margin="dense"
|
||||||
|
value={note}
|
||||||
|
onChange={(event) => setNote(event.target.value)}
|
||||||
|
></Input>
|
||||||
|
<br />
|
||||||
|
<SaveAndDelete
|
||||||
|
model={props.noteModel}
|
||||||
|
closeModal={props.closeModal}
|
||||||
|
submitHandler={submitHandler}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Font family selector for editor toolbar
|
||||||
|
*/
|
||||||
|
export function FontFamilySelect(props: { fontFamilyModel: NodePropertyValueModel }) {
|
||||||
|
const [font, setFont] = React.useState(props.fontFamilyModel.getValue());
|
||||||
|
|
||||||
|
const handleChange = (event: SelectChangeEvent) => {
|
||||||
|
setFont(event.target.value as string);
|
||||||
|
props.fontFamilyModel.setValue(event.target.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box sx={{ minWidth: 120 }}>
|
||||||
|
<FormControl variant="standard" sx={{ m: 1, minWidth: 220 }} size="small">
|
||||||
|
<Select id="demo-simple-select" value={font || ''} onChange={handleChange}>
|
||||||
|
{[
|
||||||
|
'Arial',
|
||||||
|
'Baskerville',
|
||||||
|
'Tahoma',
|
||||||
|
'Limunari',
|
||||||
|
'Brush Script MT',
|
||||||
|
'Verdana',
|
||||||
|
'Times',
|
||||||
|
'Cursive',
|
||||||
|
'Fantasy',
|
||||||
|
'Perpetua',
|
||||||
|
'Brush Script',
|
||||||
|
'Copperplate',
|
||||||
|
]
|
||||||
|
.sort()
|
||||||
|
.map((f) => (
|
||||||
|
<MenuItem value={f} key={f}>
|
||||||
|
<Typography fontFamily={f}>{f}</Typography>
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tab panel used for display icon families in tabs
|
||||||
|
*/
|
||||||
|
function TabPanel(props: { children?: React.ReactNode; index: number; value: number }) {
|
||||||
|
const { children, value, index } = props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
role="tabpanel"
|
||||||
|
hidden={value !== index}
|
||||||
|
id={`simple-tabpanel-${index}`}
|
||||||
|
aria-labelledby={`simple-tab-${index}`}
|
||||||
|
>
|
||||||
|
{value === index && <Box>{children}</Box>}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function a11yProps(index: number) {
|
||||||
|
return {
|
||||||
|
id: `simple-tab-${index}`,
|
||||||
|
'aria-controls': `simple-tabpanel-${index}`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* emoji picker for editor toolbar
|
||||||
|
*/
|
||||||
|
export const ToolbarEmojiPcker = (props: {
|
||||||
|
closeModal: () => void;
|
||||||
|
iconModel: NodePropertyValueModel;
|
||||||
|
}) => {
|
||||||
|
const [value, setValue] = React.useState(0);
|
||||||
|
|
||||||
|
const handleChange = (event: React.SyntheticEvent, newValue: number) => {
|
||||||
|
setValue(newValue);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box sx={{ width: '250px' }}>
|
||||||
|
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
|
||||||
|
<Tabs variant="fullWidth" value={value} onChange={handleChange} aria-label="Icons tabs">
|
||||||
|
{iconGroups.map((family, i) => (
|
||||||
|
<Tab
|
||||||
|
key={family.id}
|
||||||
|
icon={<img className="panelIcon" src={ImageIcon.getImageUrl(family.icons[0])} />}
|
||||||
|
{...a11yProps(i)}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</Tabs>
|
||||||
|
</Box>
|
||||||
|
{iconGroups.map((family, i) => (
|
||||||
|
<TabPanel key={family.id} value={value} index={i}>
|
||||||
|
{family.icons.map((icon) => (
|
||||||
|
<img
|
||||||
|
className="panelIcon"
|
||||||
|
key={icon}
|
||||||
|
src={ImageIcon.getImageUrl(icon)}
|
||||||
|
onClick={() => {
|
||||||
|
props.iconModel.setValue(icon);
|
||||||
|
props.closeModal();
|
||||||
|
}}
|
||||||
|
></img>
|
||||||
|
))}
|
||||||
|
</TabPanel>
|
||||||
|
))}
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const UndoAndRedoButton = (props: {
|
||||||
|
configuration: ToolbarOptionConfiguration;
|
||||||
|
disabledCondition: (event) => boolean;
|
||||||
|
}) => {
|
||||||
|
const [disabled, setDisabled] = useState(true);
|
||||||
|
useEffect(() => {
|
||||||
|
const handleUpdate: any = (event) => {
|
||||||
|
if (props.disabledCondition(event)) {
|
||||||
|
setDisabled(false);
|
||||||
|
} else {
|
||||||
|
setDisabled(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
designer.addEvent('modelUpdate', handleUpdate);
|
||||||
|
return () => {
|
||||||
|
designer.removeEvent('modelUpdate', handleUpdate);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ToolbarMenuItem
|
||||||
|
configuration={{
|
||||||
|
...props.configuration,
|
||||||
|
disabled: () => disabled,
|
||||||
|
}}
|
||||||
|
></ToolbarMenuItem>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const KeyboardShorcutsHelp = () => {
|
||||||
|
return (
|
||||||
|
<div id="keyboardTable" style={{ position: 'relative', zIndex: '2' }}>
|
||||||
|
<table>
|
||||||
|
<colgroup>
|
||||||
|
<col width="40%" />
|
||||||
|
<col width="30%" />
|
||||||
|
<col width="30%" />
|
||||||
|
</colgroup>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>{$msg('ACTION')}</th>
|
||||||
|
<th>Windows - Linux</th>
|
||||||
|
<th>Mac OS X</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>{$msg('SAVE_CHANGES')}</td>
|
||||||
|
<td>{$msg('CTRL')} + S</td>
|
||||||
|
<td>⌘ + S</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{$msg('CREATE_SIBLING_TOPIC')}</td>
|
||||||
|
<td>Enter</td>
|
||||||
|
<td>Enter</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{$msg('CREATE_CHILD_TOPIC')}</td>
|
||||||
|
<td>{$msg('K_INSERT')} / Tab</td>
|
||||||
|
<td>⌘ + Enter / Tab</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{$msg('DELETE_TOPIC')}</td>
|
||||||
|
<td>{$msg('K_DELETE')}</td>
|
||||||
|
<td>Delete</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{$msg('EDIT_TOPIC_TEXT')}</td>
|
||||||
|
<td>{$msg('JUST_START_TYPING')} | F2</td>
|
||||||
|
<td>{$msg('JUST_START_TYPING')} | F2</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{$msg('MULTIPLE_LINES')}</td>
|
||||||
|
<td>{$msg('CTRL')} + Enter</td>
|
||||||
|
<td>⌘ + Enter</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{$msg('COPY_AND_PASTE_TOPICS')}</td>
|
||||||
|
<td>
|
||||||
|
{$msg('CTRL')} + C / {$msg('CTRL')} + V
|
||||||
|
</td>
|
||||||
|
<td>⌘ + C / ⌘ + V</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>{$msg('COLLAPSE_CHILDREN')}</td>
|
||||||
|
<td>{$msg('SPACE_BAR')}</td>
|
||||||
|
<td>{$msg('SPACE_BAR')}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{$msg('TOPIC_NAVIGATION')}</td>
|
||||||
|
<td>{$msg('ARROW_KEYS')}</td>
|
||||||
|
<td>{$msg('ARROW_KEYS')}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{$msg('SELECT_MULTIPLE_NODES')}</td>
|
||||||
|
<td>
|
||||||
|
{$msg('CTRL')} + {$msg('MOUSE_CLICK')}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{$msg('CTRL')} + {$msg('MOUSE_CLICK')}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{$msg('UNDO_EDITION')}</td>
|
||||||
|
<td>{$msg('CTRL')} + Z</td>
|
||||||
|
<td>⌘ + Z</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{$msg('REDO_EDITION')}</td>
|
||||||
|
<td>{$msg('CTRL')} + Shift + Z</td>
|
||||||
|
<td>⌘ + Shift + Z</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{$msg('SELECT_ALL_TOPIC')}</td>
|
||||||
|
<td>{$msg('CTRL')} + A</td>
|
||||||
|
<td>⌘ + A</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{$msg('CANCEL_TEXT_CHANGES')}</td>
|
||||||
|
<td>Esc</td>
|
||||||
|
<td>Esc</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{$msg('DESELECT_ALL_TOPIC')}</td>
|
||||||
|
<td>{$msg('CTRL')} + Shift + A</td>
|
||||||
|
<td>⌘ + Shift + A</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{$msg('CHANGE_TEXT_ITALIC')}</td>
|
||||||
|
<td>{$msg('CTRL')} + I</td>
|
||||||
|
<td>⌘ + I</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{$msg('CHANGE_TEXT_BOLD')}</td>
|
||||||
|
<td>{$msg('CTRL')} + B</td>
|
||||||
|
<td>⌘ + B</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{$msg('TOPIC_NOTE')}</td>
|
||||||
|
<td>{$msg('CTRL')} + K</td>
|
||||||
|
<td>⌘ + K</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{$msg('TOPIC_LINK')}</td>
|
||||||
|
<td>{$msg('CTRL')} + L</td>
|
||||||
|
<td>⌘ + L</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
@ -1,9 +1,6 @@
|
|||||||
/********************************************************************************/
|
/********************************************************************************/
|
||||||
/* Header & Toolbar Styles */
|
/* Header & Toolbar Styles */
|
||||||
/********************************************************************************/
|
/********************************************************************************/
|
||||||
@import 'bootstrap-prefix.min.css';
|
|
||||||
@import 'bootstrap-fixes.css';
|
|
||||||
|
|
||||||
html {
|
html {
|
||||||
/* avoid bootstrap overriding font-size and breaking Mui */
|
/* avoid bootstrap overriding font-size and breaking Mui */
|
||||||
font-size: initial;
|
font-size: initial;
|
||||||
@ -264,7 +261,7 @@ div#shotcuts>img {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.tryInfoPanelWithToolbar {
|
.tryInfoPanelWithToolbar {
|
||||||
top: 55px;
|
top: 65px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tryInfoPanelWithoutToolbar {
|
.tryInfoPanelWithoutToolbar {
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import React, { useEffect, useRef, useState } from 'react';
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
import Toolbar, { ToolbarActionType } from './components/toolbar';
|
import { ToolbarActionType } from './components/toolbar';
|
||||||
import Footer from './components/footer';
|
import Popover from '@mui/material/Popover';
|
||||||
|
|
||||||
import { IntlProvider } from 'react-intl';
|
import { IntlProvider } from 'react-intl';
|
||||||
import {
|
import {
|
||||||
$notify,
|
$notify,
|
||||||
buildDesigner,
|
|
||||||
PersistenceManager,
|
PersistenceManager,
|
||||||
DesignerOptionsBuilder,
|
DesignerOptionsBuilder,
|
||||||
Designer,
|
Designer,
|
||||||
@ -20,13 +20,17 @@ import {
|
|||||||
Exporter,
|
Exporter,
|
||||||
Importer,
|
Importer,
|
||||||
TextImporterFactory,
|
TextImporterFactory,
|
||||||
|
MindplotWebComponent,
|
||||||
} from '@wisemapping/mindplot';
|
} from '@wisemapping/mindplot';
|
||||||
import './global-styled.css';
|
import './global-styled.css';
|
||||||
import I18nMsg from './classes/i18n-msg';
|
import I18nMsg from './classes/i18n-msg';
|
||||||
import Menu from './classes/menu/Menu';
|
import { useMuiWidgetManager } from './components/menu/useMuiWidgetManager';
|
||||||
import BootstrapWidgetManager from './classes/bootstrap/BootstrapWidgetManager';
|
import Toolbar, { horizontalPosition, Appbar, configurationBuilder } from './components/toolbar';
|
||||||
|
import { theme as defaultEditorTheme } from './theme';
|
||||||
require('../../../libraries/bootstrap/js/bootstrap.min');
|
import ThemeProvider from '@mui/material/styles/ThemeProvider';
|
||||||
|
import { Theme } from '@mui/material/styles';
|
||||||
|
import { Notifier } from './components/footer/styled';
|
||||||
|
import Footer from './components/footer';
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
// used in mindplot
|
// used in mindplot
|
||||||
@ -75,32 +79,89 @@ export type EditorProps = {
|
|||||||
persistenceManager: PersistenceManager;
|
persistenceManager: PersistenceManager;
|
||||||
onAction: (action: ToolbarActionType) => void;
|
onAction: (action: ToolbarActionType) => void;
|
||||||
onLoad?: (designer: Designer) => void;
|
onLoad?: (designer: Designer) => void;
|
||||||
|
theme?: Theme;
|
||||||
|
accountConfiguration?: React.ReactElement;
|
||||||
};
|
};
|
||||||
|
|
||||||
const Editor = ({ mapId, options, persistenceManager, onAction, onLoad }: EditorProps) => {
|
const Editor = ({
|
||||||
|
mapId,
|
||||||
|
options,
|
||||||
|
persistenceManager,
|
||||||
|
onAction,
|
||||||
|
onLoad,
|
||||||
|
theme,
|
||||||
|
accountConfiguration,
|
||||||
|
}: EditorProps) => {
|
||||||
const [isMobile, setIsMobile] = useState(undefined);
|
const [isMobile, setIsMobile] = useState(undefined);
|
||||||
const mindplotComponent: any = useRef();
|
const [mindplotComponent, setMindplotComponent]: [MindplotWebComponent | undefined, Function] =
|
||||||
|
useState();
|
||||||
|
|
||||||
|
const editMode =
|
||||||
|
options.mode === 'edition-owner' ||
|
||||||
|
options.mode === 'edition-editor' ||
|
||||||
|
options.mode === 'edition-viewer';
|
||||||
|
const editorTheme: Theme = theme ? theme : defaultEditorTheme;
|
||||||
|
const [toolbarsRerenderSwitch, setToolbarsRerenderSwitch] = useState(0);
|
||||||
|
const toolbarConfiguration = useRef([]);
|
||||||
|
const mindplotRef = useCallback((node: MindplotWebComponent) => {
|
||||||
|
setMindplotComponent(node);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const [popoverOpen, popoverTarget, widgetManager] = useMuiWidgetManager();
|
||||||
|
|
||||||
|
const onNodeBlurHandler = () => {
|
||||||
|
if (!mindplotComponent.getDesigner().getModel().selectedTopic())
|
||||||
|
setToolbarsRerenderSwitch(Date.now());
|
||||||
|
};
|
||||||
|
|
||||||
|
const onNodeFocusHandler = () => {
|
||||||
|
setToolbarsRerenderSwitch(Date.now());
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (mindplotComponent === undefined) return;
|
||||||
// Change page title ...
|
// Change page title ...
|
||||||
document.title = `${options.mapTitle} | WiseMapping `;
|
document.title = `${options.mapTitle} | WiseMapping `;
|
||||||
|
|
||||||
// Load mindmap ...
|
// Load mindmap ...
|
||||||
|
|
||||||
const designer = onLoadDesigner(mapId, options, persistenceManager);
|
const designer = onLoadDesigner(mapId, options, persistenceManager);
|
||||||
|
|
||||||
|
designer.addEvent('onblur', onNodeBlurHandler);
|
||||||
|
|
||||||
|
designer.addEvent('onfocus', onNodeFocusHandler);
|
||||||
|
|
||||||
|
designer.addEvent('modelUpdate', onNodeFocusHandler);
|
||||||
|
|
||||||
|
designer.getWorkSpace().getScreenManager().addEvent('update', onNodeFocusHandler);
|
||||||
|
|
||||||
|
if (editMode) {
|
||||||
|
// Register unload save ...
|
||||||
|
window.addEventListener('beforeunload', () => {
|
||||||
|
mindplotComponent.save(false);
|
||||||
|
mindplotComponent.unlockMap();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Autosave on a fixed period of time ...
|
||||||
|
setInterval(() => {
|
||||||
|
mindplotComponent.save(false);
|
||||||
|
}, 10000);
|
||||||
|
}
|
||||||
|
|
||||||
|
toolbarConfiguration.current = configurationBuilder.buildToolbarCongiruation(designer);
|
||||||
// Has extended actions been customized ...
|
// Has extended actions been customized ...
|
||||||
if (onLoad) {
|
if (onLoad) {
|
||||||
onLoad(designer);
|
onLoad(designer);
|
||||||
}
|
}
|
||||||
|
|
||||||
mindplotComponent.current.loadMap(mapId);
|
mindplotComponent.loadMap(mapId);
|
||||||
|
|
||||||
setIsMobile(checkMobile());
|
setIsMobile(checkMobile());
|
||||||
|
|
||||||
if (options.locked) {
|
if (options.locked) {
|
||||||
$notify(options.lockedMsg, false);
|
$notify(options.lockedMsg, false);
|
||||||
}
|
}
|
||||||
}, []);
|
}, [mindplotComponent !== undefined]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (options.enableKeyboardEvents) {
|
if (options.enableKeyboardEvents) {
|
||||||
@ -126,50 +187,68 @@ const Editor = ({ mapId, options, persistenceManager, onAction, onLoad }: Editor
|
|||||||
options: EditorOptions,
|
options: EditorOptions,
|
||||||
persistenceManager: PersistenceManager,
|
persistenceManager: PersistenceManager,
|
||||||
): Designer => {
|
): Designer => {
|
||||||
mindplotComponent.current.buildDesigner(persistenceManager, new BootstrapWidgetManager());
|
|
||||||
|
|
||||||
// Build designer ...
|
// Build designer ...
|
||||||
const result = mindplotComponent.current && mindplotComponent.current.getDesigner();
|
mindplotComponent.buildDesigner(persistenceManager, widgetManager);
|
||||||
|
return mindplotComponent.getDesigner();
|
||||||
// Register toolbar event ...
|
|
||||||
if (
|
|
||||||
options.mode === 'edition-owner' ||
|
|
||||||
options.mode === 'edition-editor' ||
|
|
||||||
options.mode === 'edition-viewer' ||
|
|
||||||
options.mode === 'showcase'
|
|
||||||
) {
|
|
||||||
const menu = new Menu(designer, 'toolbar');
|
|
||||||
|
|
||||||
// If a node has focus, focus can be move to another node using the keys.
|
|
||||||
designer.cleanScreen = () => {
|
|
||||||
menu.clear();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const locale = options.locale;
|
const locale = options.locale;
|
||||||
const msg = I18nMsg.loadLocaleData(locale);
|
const msg = I18nMsg.loadLocaleData(locale);
|
||||||
const mindplotStyle = options.mode === 'viewonly' ? { top: 0 } : { top: 'inherit' };
|
const menubarConfiguration = configurationBuilder.buildEditorAppBarConfiguration(
|
||||||
|
mindplotComponent?.getDesigner(),
|
||||||
|
onAction,
|
||||||
|
() => {
|
||||||
|
mindplotComponent.save(true);
|
||||||
|
},
|
||||||
|
options.mode,
|
||||||
|
isMobile,
|
||||||
|
);
|
||||||
|
menubarConfiguration.push({
|
||||||
|
render: () => accountConfiguration,
|
||||||
|
});
|
||||||
// if the Toolbar is not hidden before the variable 'isMobile' is defined, it appears intermittently when the page loads
|
// if the Toolbar is not hidden before the variable 'isMobile' is defined, it appears intermittently when the page loads
|
||||||
// if the Toolbar is not rendered, Menu.ts cant find buttons for create event listeners
|
// if the Toolbar is not rendered, Menu.ts cant find buttons for create event listeners
|
||||||
// so, with this hack the Toolbar is rendered but no visible until the variable 'isMobile' is defined
|
// so, with this hack the Toolbar is rendered but no visible until the variable 'isMobile' is defined
|
||||||
const toolbarContainerStyle = isMobile === undefined ? { display: 'none' } : { display: 'block' };
|
|
||||||
return (
|
return (
|
||||||
|
<ThemeProvider theme={editorTheme}>
|
||||||
<IntlProvider locale={locale} messages={msg}>
|
<IntlProvider locale={locale} messages={msg}>
|
||||||
<div style={toolbarContainerStyle}>
|
<Appbar configurations={menubarConfiguration} />
|
||||||
{options.mode !== 'viewonly' && !isMobile && (
|
<Popover
|
||||||
<Toolbar editorMode={options.mode} onAction={onAction} />
|
id="popover"
|
||||||
|
open={popoverOpen}
|
||||||
|
anchorEl={popoverTarget}
|
||||||
|
onClose={widgetManager.handleClose}
|
||||||
|
anchorOrigin={{
|
||||||
|
vertical: 'bottom',
|
||||||
|
horizontal: 'left',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{widgetManager.getEditorContent()}
|
||||||
|
</Popover>
|
||||||
|
{editMode && !isMobile && (
|
||||||
|
<Toolbar
|
||||||
|
configurations={toolbarConfiguration.current}
|
||||||
|
rerender={toolbarsRerenderSwitch}
|
||||||
|
></Toolbar>
|
||||||
)}
|
)}
|
||||||
</div>
|
<Toolbar
|
||||||
|
configurations={configurationBuilder.buildZoomToolbarConfiguration(
|
||||||
|
isMobile,
|
||||||
|
mindplotComponent?.getDesigner(),
|
||||||
|
)}
|
||||||
|
position={horizontalPosition}
|
||||||
|
rerender={toolbarsRerenderSwitch}
|
||||||
|
></Toolbar>
|
||||||
<mindplot-component
|
<mindplot-component
|
||||||
ref={mindplotComponent}
|
ref={mindplotRef}
|
||||||
id="mindmap-comp"
|
id="mindmap-comp"
|
||||||
mode={options.mode}
|
mode={options.mode}
|
||||||
|
locale={options.locale}
|
||||||
></mindplot-component>
|
></mindplot-component>
|
||||||
<div id="mindplot-tooltips" className="wise-editor"></div>
|
<Notifier id="headerNotifier"></Notifier>
|
||||||
<Footer editorMode={options.mode} isMobile={isMobile} />
|
<Footer editorMode={options.mode} isMobile={isMobile}></Footer>
|
||||||
</IntlProvider>
|
</IntlProvider>
|
||||||
|
</ThemeProvider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
export default Editor;
|
export default Editor;
|
||||||
|
28
packages/editor/src/theme/index.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { createTheme, Theme } from '@mui/material/styles';
|
||||||
|
|
||||||
|
const theme: Theme = createTheme({
|
||||||
|
palette: {
|
||||||
|
mode: 'light',
|
||||||
|
primary: {
|
||||||
|
light: '#ffa800',
|
||||||
|
main: '#ffa800',
|
||||||
|
dark: '#ffa800',
|
||||||
|
contrastText: '#FFFFFF',
|
||||||
|
},
|
||||||
|
secondary: {
|
||||||
|
light: '#a19f9f',
|
||||||
|
main: '#5a5a5a',
|
||||||
|
dark: '#000000',
|
||||||
|
contrastText: '#FFFFFF',
|
||||||
|
},
|
||||||
|
background: {
|
||||||
|
paper: '#fff',
|
||||||
|
default: '#fff',
|
||||||
|
},
|
||||||
|
text: {
|
||||||
|
primary: '#313131',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export { theme };
|
@ -0,0 +1,69 @@
|
|||||||
|
import {
|
||||||
|
getNextValue,
|
||||||
|
getPreviousValue,
|
||||||
|
getTheUniqueValueOrNull,
|
||||||
|
} from '../../../src/components/toolbar/ToolbarValueModelBuilder';
|
||||||
|
|
||||||
|
describe('getNextValue', () => {
|
||||||
|
it('Given an array and the current value it return the next value of the array', () => {
|
||||||
|
expect(getNextValue([1, 2, 3], 2)).toEqual(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Given an array and the current value when the last value is selected it return same', () => {
|
||||||
|
expect(getNextValue([1, 2, 3], 3)).toEqual(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Given a current value not present in values array return the first element', () => {
|
||||||
|
expect(getNextValue([1, 2, 3], 4)).toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Given an array and the current value undefined it return the next value of the array', () => {
|
||||||
|
expect(getNextValue([1, undefined, 3], undefined)).toEqual(3);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getPrevioustValue', () => {
|
||||||
|
it('Given an array and the current value it return the previous value of the array', () => {
|
||||||
|
expect(getPreviousValue([1, 2, 3], 2)).toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Given an array and the current value when the first value is selected it return same', () => {
|
||||||
|
expect(getPreviousValue([1, 2, 3], 1)).toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Given a current value not present in values array return the last element', () => {
|
||||||
|
expect(getPreviousValue([1, 2, 3], 4)).toEqual(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Given an array and the current value undefined it return the next value of the array', () => {
|
||||||
|
expect(getPreviousValue([1, undefined, 3], undefined)).toEqual(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getTheUniqueValueOrNull', () => {
|
||||||
|
const testArray = [
|
||||||
|
{
|
||||||
|
a: 'va',
|
||||||
|
b: 'vb',
|
||||||
|
c: 'vc',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
a: 'va',
|
||||||
|
b: 'vb!!!!!',
|
||||||
|
c: 'vc',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
a: 'va',
|
||||||
|
b: 'vb',
|
||||||
|
c: 'vc',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
it("Given an array of objects testArray and a function that returns the property named 'a', it returns the property value 'va'", () => {
|
||||||
|
expect(getTheUniqueValueOrNull(testArray, (o) => o['a'])).toEqual('va');
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Given an array of objects testArray and a function that returns the property named 'b', it returns null", () => {
|
||||||
|
expect(getTheUniqueValueOrNull(testArray, (o) => o['b'])).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
290
packages/editor/test/unit/toolbar/toolbar.test.tsx
Normal file
@ -0,0 +1,290 @@
|
|||||||
|
/**
|
||||||
|
* @jest-environment jsdom
|
||||||
|
*/
|
||||||
|
import React from 'react';
|
||||||
|
import { render, fireEvent, waitFor, screen } from '@testing-library/react';
|
||||||
|
import ThreeDRotation from '@mui/icons-material/ThreeDRotation';
|
||||||
|
import Toolbar, {
|
||||||
|
ToolbarButtonOption,
|
||||||
|
ToolbarMenuItem,
|
||||||
|
ToolbarSubmenu,
|
||||||
|
} from '../../../src/components/toolbar/Toolbar';
|
||||||
|
import { ToolbarOptionConfiguration } from '../../../src/components/toolbar/ToolbarOptionConfigurationInterface';
|
||||||
|
import Menubar from '../../../src/components/toolbar/AppBar';
|
||||||
|
require('babel-polyfill');
|
||||||
|
jest.mock('../../../src/components/toolbar/appbar-buttons.css', () => '');
|
||||||
|
|
||||||
|
const config: ToolbarOptionConfiguration = {
|
||||||
|
icon: <ThreeDRotation></ThreeDRotation>,
|
||||||
|
onClick: jest.fn(),
|
||||||
|
};
|
||||||
|
|
||||||
|
const notVisibleConfig: ToolbarOptionConfiguration = {
|
||||||
|
icon: <ThreeDRotation></ThreeDRotation>,
|
||||||
|
onClick: jest.fn(),
|
||||||
|
visible: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
const disabledAndNotSelectedButtonConfig: ToolbarOptionConfiguration = {
|
||||||
|
icon: <ThreeDRotation></ThreeDRotation>,
|
||||||
|
onClick: jest.fn(),
|
||||||
|
disabled: () => true,
|
||||||
|
selected: () => false,
|
||||||
|
};
|
||||||
|
|
||||||
|
const selectedButtonConfig: ToolbarOptionConfiguration = {
|
||||||
|
icon: <ThreeDRotation></ThreeDRotation>,
|
||||||
|
onClick: jest.fn(),
|
||||||
|
selected: () => true,
|
||||||
|
};
|
||||||
|
|
||||||
|
const disabledSubMenuConfig: ToolbarOptionConfiguration = {
|
||||||
|
icon: <ThreeDRotation></ThreeDRotation>,
|
||||||
|
options: [config],
|
||||||
|
disabled: () => true,
|
||||||
|
};
|
||||||
|
const withRenderConfig: ToolbarOptionConfiguration = {
|
||||||
|
icon: <ThreeDRotation></ThreeDRotation>,
|
||||||
|
render: () => <div data-testid="custom-render-div">test</div>,
|
||||||
|
};
|
||||||
|
const withCloseSubmenuRender: ToolbarOptionConfiguration = {
|
||||||
|
icon: <ThreeDRotation></ThreeDRotation>,
|
||||||
|
render: (closeMenu) => {
|
||||||
|
return (
|
||||||
|
<div data-testid="custom-render-div" onClick={closeMenu}>
|
||||||
|
Test
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const submenuConfig: ToolbarOptionConfiguration = {
|
||||||
|
icon: <ThreeDRotation></ThreeDRotation>,
|
||||||
|
options: [config, null, config, null, withRenderConfig],
|
||||||
|
};
|
||||||
|
const notVisibleSubmenuConfig: ToolbarOptionConfiguration = {
|
||||||
|
icon: <ThreeDRotation></ThreeDRotation>,
|
||||||
|
options: [config, null, config, null, withRenderConfig],
|
||||||
|
visible: false,
|
||||||
|
};
|
||||||
|
const submenuConfig2: ToolbarOptionConfiguration = {
|
||||||
|
icon: <ThreeDRotation></ThreeDRotation>,
|
||||||
|
options: [withCloseSubmenuRender],
|
||||||
|
};
|
||||||
|
const iconFunctionConfig: ToolbarOptionConfiguration = {
|
||||||
|
icon: () => <ThreeDRotation></ThreeDRotation>,
|
||||||
|
onClick: jest.fn(),
|
||||||
|
};
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Editor Toolbar Button', () => {
|
||||||
|
it('Given an option shows a button and executes onClick', () => {
|
||||||
|
render(<ToolbarButtonOption configuration={config}></ToolbarButtonOption>);
|
||||||
|
const btn = screen.getByRole('button');
|
||||||
|
|
||||||
|
fireEvent.click(btn);
|
||||||
|
|
||||||
|
expect(config.onClick).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Given an option shows the icon on the button', () => {
|
||||||
|
render(<ToolbarButtonOption configuration={config}></ToolbarButtonOption>);
|
||||||
|
|
||||||
|
screen.getByTestId('ThreeDRotationIcon');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Given an option shows the tooltip on hover', async () => {
|
||||||
|
const tooltipConfiguration = { ...config, tooltip: 'tooltip' };
|
||||||
|
render(<ToolbarButtonOption configuration={tooltipConfiguration}></ToolbarButtonOption>);
|
||||||
|
const btn = screen.getByRole('button');
|
||||||
|
|
||||||
|
fireEvent.mouseOver(btn);
|
||||||
|
|
||||||
|
await screen.findByText('tooltip');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Given an option with a function icon implementation shows the icon on the button', () => {
|
||||||
|
render(<ToolbarButtonOption configuration={iconFunctionConfig}></ToolbarButtonOption>);
|
||||||
|
|
||||||
|
screen.getByTestId('ThreeDRotationIcon');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Given a disabled option shows a button and not executes onClick', () => {
|
||||||
|
render(
|
||||||
|
<ToolbarButtonOption
|
||||||
|
configuration={disabledAndNotSelectedButtonConfig}
|
||||||
|
></ToolbarButtonOption>,
|
||||||
|
);
|
||||||
|
const btn = screen.getByRole('button');
|
||||||
|
|
||||||
|
fireEvent.click(btn);
|
||||||
|
|
||||||
|
expect(config.onClick).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Given a selected option shows a selected button', () => {
|
||||||
|
render(<ToolbarButtonOption configuration={selectedButtonConfig}></ToolbarButtonOption>);
|
||||||
|
const btn = screen.getByRole('button');
|
||||||
|
|
||||||
|
expect(btn.getAttribute('aria-pressed')).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Given a not selected option shows a not selected button', () => {
|
||||||
|
render(
|
||||||
|
<ToolbarButtonOption
|
||||||
|
configuration={disabledAndNotSelectedButtonConfig}
|
||||||
|
></ToolbarButtonOption>,
|
||||||
|
);
|
||||||
|
const btn = screen.getByRole('button');
|
||||||
|
|
||||||
|
expect(btn.getAttribute('aria-pressed')).toEqual('false');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Editor Toolbar Submenu', () => {
|
||||||
|
it('Given an option shows a menuitem and shows a submenu ', async () => {
|
||||||
|
render(<ToolbarSubmenu configuration={submenuConfig}></ToolbarSubmenu>);
|
||||||
|
const item = screen.getByRole('menuitem');
|
||||||
|
|
||||||
|
fireEvent.mouseOver(item);
|
||||||
|
|
||||||
|
await screen.findByRole('submenu');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Shows a button for each option', async () => {
|
||||||
|
render(<ToolbarSubmenu configuration={submenuConfig}></ToolbarSubmenu>);
|
||||||
|
const item = screen.getByRole('menuitem');
|
||||||
|
|
||||||
|
fireEvent.mouseOver(item);
|
||||||
|
const submenuButtons = await screen.findAllByRole('button');
|
||||||
|
|
||||||
|
expect(submenuButtons).toHaveLength(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Shows a divider for each null', async () => {
|
||||||
|
render(<ToolbarSubmenu configuration={submenuConfig}></ToolbarSubmenu>);
|
||||||
|
const item = screen.getByRole('menuitem');
|
||||||
|
|
||||||
|
fireEvent.mouseOver(item);
|
||||||
|
const dividers = await screen.findAllByTestId('divider');
|
||||||
|
|
||||||
|
expect(dividers).toHaveLength(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Execute render if set', async () => {
|
||||||
|
render(<ToolbarSubmenu configuration={submenuConfig}></ToolbarSubmenu>);
|
||||||
|
const item = screen.getByRole('menuitem');
|
||||||
|
|
||||||
|
fireEvent.mouseOver(item);
|
||||||
|
|
||||||
|
await screen.findByTestId('custom-render-div');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Execute render passing a function to close popover', async () => {
|
||||||
|
render(<ToolbarSubmenu configuration={submenuConfig2}></ToolbarSubmenu>);
|
||||||
|
const item = screen.getByRole('menuitem');
|
||||||
|
fireEvent.mouseOver(item);
|
||||||
|
const clickeableDiv = await screen.findByTestId('custom-render-div');
|
||||||
|
|
||||||
|
fireEvent.click(clickeableDiv);
|
||||||
|
|
||||||
|
expect(screen.queryByRole('submenu')).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Given a disabled configuratio when mouse is over, not shows a submenu ', async () => {
|
||||||
|
render(<ToolbarSubmenu configuration={disabledSubMenuConfig}></ToolbarSubmenu>);
|
||||||
|
const item = screen.getByRole('menuitem');
|
||||||
|
|
||||||
|
fireEvent.mouseOver(item);
|
||||||
|
|
||||||
|
expect(screen.queryByRole('submenu')).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('toolbar menu item', () => {
|
||||||
|
it('Render button if no options is passed', () => {
|
||||||
|
render(<ToolbarMenuItem configuration={config}></ToolbarMenuItem>);
|
||||||
|
screen.getByRole('button');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Render submenu if options is passed', () => {
|
||||||
|
render(<ToolbarMenuItem configuration={submenuConfig}></ToolbarMenuItem>);
|
||||||
|
screen.getByRole('menuitem');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Render null when visible configuration is falsy', () => {
|
||||||
|
expect(
|
||||||
|
render(<ToolbarMenuItem configuration={notVisibleConfig}></ToolbarMenuItem>).container
|
||||||
|
.innerHTML,
|
||||||
|
).toBe('');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Render null when visible configuration is falsy', () => {
|
||||||
|
expect(
|
||||||
|
render(<ToolbarMenuItem configuration={notVisibleSubmenuConfig}></ToolbarMenuItem>).container
|
||||||
|
.innerHTML,
|
||||||
|
).toBe('');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Toolbar', () => {
|
||||||
|
it('When render it displays a menu', () => {
|
||||||
|
render(<Toolbar configurations={[submenuConfig, submenuConfig2]}></Toolbar>);
|
||||||
|
|
||||||
|
screen.getByRole('menu');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Given an options array for configurations with 2 options when render it displays a menu with 2 menuitems', () => {
|
||||||
|
render(<Toolbar configurations={[submenuConfig, submenuConfig2]}></Toolbar>);
|
||||||
|
const items = screen.getAllByRole('menuitem');
|
||||||
|
|
||||||
|
expect(items).toHaveLength(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('When render it displays a menu in horizontal orientation', () => {
|
||||||
|
const horizontalPosition = {
|
||||||
|
position: {
|
||||||
|
right: '40px',
|
||||||
|
top: '90%',
|
||||||
|
},
|
||||||
|
vertical: false,
|
||||||
|
};
|
||||||
|
render(
|
||||||
|
<Toolbar
|
||||||
|
configurations={[submenuConfig, submenuConfig2]}
|
||||||
|
position={horizontalPosition}
|
||||||
|
></Toolbar>,
|
||||||
|
);
|
||||||
|
|
||||||
|
screen.getByRole('menu');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Execute render if set', () => {
|
||||||
|
render(<Toolbar configurations={[withRenderConfig]} />);
|
||||||
|
|
||||||
|
screen.getByTestId('custom-render-div');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Menubar', () => {
|
||||||
|
it('When render it displays a menu', () => {
|
||||||
|
render(<Menubar configurations={[config, config]}></Menubar>);
|
||||||
|
|
||||||
|
screen.getByRole('menubar');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Given an options array for configurations with 2 options when render it displays a menu with 2 menuitems', () => {
|
||||||
|
render(<Menubar configurations={[config, config]}></Menubar>);
|
||||||
|
const items = screen.getAllByRole('button');
|
||||||
|
|
||||||
|
expect(items).toHaveLength(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Execute render if set', () => {
|
||||||
|
render(<Menubar configurations={[withRenderConfig]} />);
|
||||||
|
|
||||||
|
screen.getByTestId('custom-render-div');
|
||||||
|
});
|
||||||
|
});
|
@ -141,6 +141,9 @@ class Designer extends Events {
|
|||||||
document.addEventListener(
|
document.addEventListener(
|
||||||
'wheel',
|
'wheel',
|
||||||
(event: WheelEvent) => {
|
(event: WheelEvent) => {
|
||||||
|
// TODO re-do this better. This line avoid manage zoom with mouse wheel if mindplot kb shortcuts are disabled.
|
||||||
|
if (DesignerKeyboard.isDisabled()) return;
|
||||||
|
|
||||||
if (event.deltaX > 0 || event.deltaY > 0) {
|
if (event.deltaX > 0 || event.deltaY > 0) {
|
||||||
this.zoomOut(zoomFactor);
|
this.zoomOut(zoomFactor);
|
||||||
} else {
|
} else {
|
||||||
@ -286,8 +289,7 @@ class Designer extends Events {
|
|||||||
|
|
||||||
onObjectFocusEvent(currentObject?: Topic, event?): void {
|
onObjectFocusEvent(currentObject?: Topic, event?): void {
|
||||||
// Close node editors ..
|
// Close node editors ..
|
||||||
const topics = this.getModel().getTopics();
|
this.closeNodeEditors();
|
||||||
topics.forEach((topic) => topic.closeEditors());
|
|
||||||
|
|
||||||
const model = this.getModel();
|
const model = this.getModel();
|
||||||
const objects = model.getEntities();
|
const objects = model.getEntities();
|
||||||
@ -301,6 +303,11 @@ class Designer extends Events {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
closeNodeEditors() {
|
||||||
|
const topics = this.getModel().getTopics();
|
||||||
|
topics.forEach((topic) => topic.closeEditors());
|
||||||
|
}
|
||||||
|
|
||||||
/** sets focus to all model entities, i.e. relationships and topics */
|
/** sets focus to all model entities, i.e. relationships and topics */
|
||||||
selectAll(): void {
|
selectAll(): void {
|
||||||
const model = this.getModel();
|
const model = this.getModel();
|
||||||
@ -885,7 +892,7 @@ class Designer extends Events {
|
|||||||
if (topic) {
|
if (topic) {
|
||||||
const manager = WidgetManager.getInstance();
|
const manager = WidgetManager.getInstance();
|
||||||
manager.showEditorForLink(topic, null, null);
|
manager.showEditorForLink(topic, null, null);
|
||||||
this.onObjectFocusEvent();
|
this.closeNodeEditors();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -895,7 +902,7 @@ class Designer extends Events {
|
|||||||
if (topic) {
|
if (topic) {
|
||||||
const manager = WidgetManager.getInstance();
|
const manager = WidgetManager.getInstance();
|
||||||
manager.showEditorForNote(topic, null, null);
|
manager.showEditorForNote(topic, null, null);
|
||||||
this.onObjectFocusEvent();
|
this.closeNodeEditors();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,10 +123,6 @@ class DesignerKeyboard extends Keyboard {
|
|||||||
designer.changeFontWeight();
|
designer.changeFontWeight();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.addShortcut(['ctrl+s', 'meta+s'], () => {
|
|
||||||
$(document).find('#save').trigger('click');
|
|
||||||
});
|
|
||||||
|
|
||||||
this.addShortcut(['ctrl+i', 'meta+i'], () => {
|
this.addShortcut(['ctrl+i', 'meta+i'], () => {
|
||||||
designer.changeFontStyle();
|
designer.changeFontStyle();
|
||||||
});
|
});
|
||||||
|
@ -27,7 +27,7 @@ abstract class Icon {
|
|||||||
protected _group: IconGroup;
|
protected _group: IconGroup;
|
||||||
|
|
||||||
constructor(url: string) {
|
constructor(url: string) {
|
||||||
$assert(url, 'topic can not be null');
|
$assert(url, 'image url can not be null');
|
||||||
this._image = new Image();
|
this._image = new Image();
|
||||||
this._image.setHref(url);
|
this._image.setHref(url);
|
||||||
this._image.setSize(Icon.SIZE, Icon.SIZE);
|
this._image.setSize(Icon.SIZE, Icon.SIZE);
|
||||||
|
@ -7,6 +7,9 @@ import Mindmap from './model/Mindmap';
|
|||||||
import PersistenceManager from './PersistenceManager';
|
import PersistenceManager from './PersistenceManager';
|
||||||
import WidgetManager from './WidgetManager';
|
import WidgetManager from './WidgetManager';
|
||||||
import mindplotStyles from './styles/mindplot-styles';
|
import mindplotStyles from './styles/mindplot-styles';
|
||||||
|
import { $notify } from './widget/ToolbarNotifier';
|
||||||
|
import { $msg } from './Messages';
|
||||||
|
import DesignerKeyboard from './DesignerKeyboard';
|
||||||
|
|
||||||
const defaultPersistenceManager = () => new LocalStorageManager('map.xml', false, false);
|
const defaultPersistenceManager = () => new LocalStorageManager('map.xml', false, false);
|
||||||
|
|
||||||
@ -14,6 +17,7 @@ export type MindplotWebComponentInterface = {
|
|||||||
id: string;
|
id: string;
|
||||||
mode: string;
|
mode: string;
|
||||||
ref: any;
|
ref: any;
|
||||||
|
locale?: string;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* WebComponent implementation for minplot designer.
|
* WebComponent implementation for minplot designer.
|
||||||
@ -27,6 +31,8 @@ class MindplotWebComponent extends HTMLElement {
|
|||||||
|
|
||||||
private _designer: Designer;
|
private _designer: Designer;
|
||||||
|
|
||||||
|
private saveRequired: boolean;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||||
@ -53,6 +59,7 @@ class MindplotWebComponent extends HTMLElement {
|
|||||||
*/
|
*/
|
||||||
buildDesigner(persistence?: PersistenceManager, widgetManager?: WidgetManager) {
|
buildDesigner(persistence?: PersistenceManager, widgetManager?: WidgetManager) {
|
||||||
const editorRenderMode = this.getAttribute('mode') as EditorRenderMode;
|
const editorRenderMode = this.getAttribute('mode') as EditorRenderMode;
|
||||||
|
const locale = this.getAttribute('locale');
|
||||||
const persistenceManager = persistence || defaultPersistenceManager();
|
const persistenceManager = persistence || defaultPersistenceManager();
|
||||||
const mode = editorRenderMode || 'viewonly';
|
const mode = editorRenderMode || 'viewonly';
|
||||||
const options = DesignerOptionsBuilder.buildOptions({
|
const options = DesignerOptionsBuilder.buildOptions({
|
||||||
@ -61,10 +68,32 @@ class MindplotWebComponent extends HTMLElement {
|
|||||||
widgetManager,
|
widgetManager,
|
||||||
divContainer: this._shadowRoot.getElementById('mindplot'),
|
divContainer: this._shadowRoot.getElementById('mindplot'),
|
||||||
container: 'mindplot',
|
container: 'mindplot',
|
||||||
zoom: 0.85,
|
zoom: 1,
|
||||||
locale: 'en',
|
locale: locale || 'en',
|
||||||
});
|
});
|
||||||
this._designer = buildDesigner(options);
|
this._designer = buildDesigner(options);
|
||||||
|
this._designer.addEvent('modelUpdate', () => {
|
||||||
|
this.setSaveRequired(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.registerShortcuts();
|
||||||
|
}
|
||||||
|
|
||||||
|
private registerShortcuts() {
|
||||||
|
const designerKeyboard = DesignerKeyboard.getInstance();
|
||||||
|
if (designerKeyboard) {
|
||||||
|
designerKeyboard.addShortcut(['ctrl+s', 'meta+s'], () => {
|
||||||
|
this.save(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setSaveRequired(arg0: boolean) {
|
||||||
|
this.saveRequired = arg0;
|
||||||
|
}
|
||||||
|
|
||||||
|
getSaveRequired() {
|
||||||
|
return this.saveRequired;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -76,6 +105,64 @@ class MindplotWebComponent extends HTMLElement {
|
|||||||
this._mindmap = instance.load(id);
|
this._mindmap = instance.load(id);
|
||||||
this._designer.loadMap(this._mindmap);
|
this._designer.loadMap(this._mindmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* save the map
|
||||||
|
*/
|
||||||
|
save(saveHistory: boolean) {
|
||||||
|
if (!saveHistory && !this.getSaveRequired()) return;
|
||||||
|
console.log('Saving...');
|
||||||
|
// Load map content ...
|
||||||
|
const mindmap = this._designer.getMindmap();
|
||||||
|
const mindmapProp = this._designer.getMindmapProperties();
|
||||||
|
|
||||||
|
// Display save message ..
|
||||||
|
if (saveHistory) {
|
||||||
|
$notify($msg('SAVING'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call persistence manager for saving ...
|
||||||
|
const persistenceManager = PersistenceManager.getInstance();
|
||||||
|
persistenceManager.save(mindmap, mindmapProp, saveHistory, {
|
||||||
|
onSuccess() {
|
||||||
|
if (saveHistory) {
|
||||||
|
$notify($msg('SAVE_COMPLETE'));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onError(error) {
|
||||||
|
if (saveHistory) {
|
||||||
|
$notify(error.message);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
this.setSaveRequired(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
discardChanges() {
|
||||||
|
// Avoid autosave before leaving the page ....
|
||||||
|
// this.setRequireChange(false);
|
||||||
|
|
||||||
|
// Finally call discard function ...
|
||||||
|
const persistenceManager = PersistenceManager.getInstance();
|
||||||
|
const mindmap = this._designer.getMindmap();
|
||||||
|
persistenceManager.discardChanges(mindmap.getId());
|
||||||
|
|
||||||
|
// Unlock map ...
|
||||||
|
this.unlockMap();
|
||||||
|
|
||||||
|
// Reload the page ...
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
unlockMap() {
|
||||||
|
const mindmap = this._designer.getMindmap();
|
||||||
|
const persistenceManager = PersistenceManager.getInstance();
|
||||||
|
|
||||||
|
// If the map could not be loaded, partial map load could happen.
|
||||||
|
if (mindmap) {
|
||||||
|
persistenceManager.unlockMap(mindmap.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default MindplotWebComponent;
|
export default MindplotWebComponent;
|
||||||
|
@ -60,7 +60,7 @@ class WidgetManager {
|
|||||||
}
|
}
|
||||||
const targetRect = evt.target.getBoundingClientRect();
|
const targetRect = evt.target.getBoundingClientRect();
|
||||||
const newX = Math.max(0, targetRect.left + targetRect.width / 2 - tooltip.width() / 2);
|
const newX = Math.max(0, targetRect.left + targetRect.width / 2 - tooltip.width() / 2);
|
||||||
const newY = Math.max(0, targetRect.bottom + 10);
|
const newY = Math.max(0, targetRect.bottom);
|
||||||
tooltip.css({ top: newY, left: newX, position: 'absolute' });
|
tooltip.css({ top: newY, left: newX, position: 'absolute' });
|
||||||
tooltip.css({ display: 'block' });
|
tooltip.css({ display: 'block' });
|
||||||
evt.stopPropagation();
|
evt.stopPropagation();
|
||||||
|
@ -263,6 +263,10 @@ class Workspace {
|
|||||||
screenManager.addEvent('mousedown', mouseDownListener);
|
screenManager.addEvent('mousedown', mouseDownListener);
|
||||||
screenManager.addEvent('touchstart', mouseDownListener);
|
screenManager.addEvent('touchstart', mouseDownListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getZoom() {
|
||||||
|
return this._zoom;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Workspace;
|
export default Workspace;
|
||||||
|
@ -6,10 +6,14 @@ const DE = {
|
|||||||
TOPIC_DELETE: 'Thema löschen',
|
TOPIC_DELETE: 'Thema löschen',
|
||||||
TOPIC_ICON: 'Symbol hinzufügen',
|
TOPIC_ICON: 'Symbol hinzufügen',
|
||||||
TOPIC_LINK: 'Verbindung hinzufügen',
|
TOPIC_LINK: 'Verbindung hinzufügen',
|
||||||
TOPIC_RELATIONSHIP: 'Beziehung',
|
TOPIC_RELATIONSHIP: 'Beziehung hinzufügen',
|
||||||
TOPIC_COLOR: 'Themenfarbe',
|
TOPIC_COLOR: 'Themenfarbe',
|
||||||
TOPIC_BORDER_COLOR: 'Thema Randfarbe',
|
TOPIC_BORDER_COLOR: 'Thema Randfarbe',
|
||||||
TOPIC_NOTE: 'Notiz hinzufügen',
|
TOPIC_NOTE: 'Notiz hinzufügen',
|
||||||
|
TOPIC_SHAPE_RECTANGLE: 'Zweigform in Rechteck ändern',
|
||||||
|
TOPIC_SHAPE_ROUNDED: 'Zweigform in Rechteck mit abgerundeten Ecken ändern',
|
||||||
|
TOPIC_SHAPE_ELLIPSE: 'Zweigform in Ellipse ändern',
|
||||||
|
TOPIC_SHAPE_LINE: 'Zweigform in Linie ändern',
|
||||||
FONT_FAMILY: 'Schriftart',
|
FONT_FAMILY: 'Schriftart',
|
||||||
FONT_SIZE: 'Schriftgröße',
|
FONT_SIZE: 'Schriftgröße',
|
||||||
FONT_BOLD: 'Fett',
|
FONT_BOLD: 'Fett',
|
||||||
@ -86,6 +90,11 @@ const DE = {
|
|||||||
MOUSE_CLICK: 'Mausklick',
|
MOUSE_CLICK: 'Mausklick',
|
||||||
K_DELETE: 'Entf',
|
K_DELETE: 'Entf',
|
||||||
BACKSPACE: 'Backspace',
|
BACKSPACE: 'Backspace',
|
||||||
|
CENTER_POSITION: 'Passend zoomen',
|
||||||
|
MAP_INFO: 'Informationen',
|
||||||
|
FONT_FORMAT: 'Schriftformat',
|
||||||
|
FONT_INCREASE: 'Schriftgröße erhöhen',
|
||||||
|
FONT_DECREASE: 'Schriftgröße verringern',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default DE;
|
export default DE;
|
||||||
|
@ -6,10 +6,14 @@ const EN = {
|
|||||||
TOPIC_DELETE: 'Delete Topic',
|
TOPIC_DELETE: 'Delete Topic',
|
||||||
TOPIC_ICON: 'Add Icon',
|
TOPIC_ICON: 'Add Icon',
|
||||||
TOPIC_LINK: 'Add Link',
|
TOPIC_LINK: 'Add Link',
|
||||||
TOPIC_RELATIONSHIP: 'Relationship',
|
TOPIC_RELATIONSHIP: 'Add Relationship',
|
||||||
TOPIC_COLOR: 'Topic Color',
|
TOPIC_COLOR: 'Topic Color',
|
||||||
TOPIC_BORDER_COLOR: 'Topic Border Color',
|
TOPIC_BORDER_COLOR: 'Topic Border Color',
|
||||||
TOPIC_NOTE: 'Add Note',
|
TOPIC_NOTE: 'Add Note',
|
||||||
|
TOPIC_SHAPE_RECTANGLE: 'Change Topic Shape to Rectangle',
|
||||||
|
TOPIC_SHAPE_ROUNDED: 'Change Topic Shape to Rounded Corners Rectangle',
|
||||||
|
TOPIC_SHAPE_ELLIPSE: 'Change Topic Shape to Ellipse',
|
||||||
|
TOPIC_SHAPE_LINE: 'Change Topic Shape to Line',
|
||||||
FONT_FAMILY: 'Font Type',
|
FONT_FAMILY: 'Font Type',
|
||||||
FONT_SIZE: 'Text Size',
|
FONT_SIZE: 'Text Size',
|
||||||
FONT_BOLD: 'Text Bold',
|
FONT_BOLD: 'Text Bold',
|
||||||
@ -86,6 +90,11 @@ const EN = {
|
|||||||
MOUSE_CLICK: 'Mouse Click',
|
MOUSE_CLICK: 'Mouse Click',
|
||||||
K_DELETE: 'Delete',
|
K_DELETE: 'Delete',
|
||||||
BACKSPACE: 'Backspace',
|
BACKSPACE: 'Backspace',
|
||||||
|
CENTER_POSITION: 'Zoom To Fit',
|
||||||
|
MAP_INFO: 'Information',
|
||||||
|
FONT_FORMAT: 'Font Format',
|
||||||
|
FONT_INCREASE: 'Font Size Increase',
|
||||||
|
FONT_DECREASE: 'Font Size Decrease',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default EN;
|
export default EN;
|
||||||
|
@ -6,14 +6,18 @@ const ES = {
|
|||||||
TOPIC_DELETE: 'Borrar Tópico',
|
TOPIC_DELETE: 'Borrar Tópico',
|
||||||
TOPIC_ICON: 'Agregar Icono',
|
TOPIC_ICON: 'Agregar Icono',
|
||||||
TOPIC_LINK: 'Agregar Enlace',
|
TOPIC_LINK: 'Agregar Enlace',
|
||||||
TOPIC_RELATIONSHIP: 'Relación',
|
TOPIC_RELATIONSHIP: 'Agregar Relación',
|
||||||
TOPIC_COLOR: 'Color Tópico',
|
TOPIC_COLOR: 'Color del Tópico',
|
||||||
TOPIC_BORDER_COLOR: 'Color del Borde',
|
TOPIC_BORDER_COLOR: 'Color del Borde',
|
||||||
TOPIC_NOTE: 'Agregar Nota',
|
TOPIC_NOTE: 'Agregar Nota',
|
||||||
|
TOPIC_SHAPE_RECTANGLE: 'Cambiar Figura del Nodo a Rectángulo',
|
||||||
|
TOPIC_SHAPE_ROUNDED: 'Cambiar Figura a Esquinas Redondeadas',
|
||||||
|
TOPIC_SHAPE_ELLIPSE: 'Cambiar Figura a Elipse',
|
||||||
|
TOPIC_SHAPE_LINE: 'Cambiar Figura a Línea',
|
||||||
FONT_FAMILY: 'Tipo de Fuente',
|
FONT_FAMILY: 'Tipo de Fuente',
|
||||||
FONT_SIZE: 'Tamaño de Texto',
|
FONT_SIZE: 'Tamaño de Texto',
|
||||||
FONT_BOLD: 'Negrita',
|
FONT_BOLD: 'Negrita',
|
||||||
FONT_ITALIC: 'Italica',
|
FONT_ITALIC: 'Itálica',
|
||||||
UNDO: 'Rehacer',
|
UNDO: 'Rehacer',
|
||||||
REDO: 'Deshacer',
|
REDO: 'Deshacer',
|
||||||
INSERT: 'Insertar',
|
INSERT: 'Insertar',
|
||||||
@ -75,8 +79,8 @@ const ES = {
|
|||||||
DESELECT_ALL_TOPIC: 'Revertir Selección de Tópicos',
|
DESELECT_ALL_TOPIC: 'Revertir Selección de Tópicos',
|
||||||
COLLAPSE_CHILDREN: 'Colapsar Hijos',
|
COLLAPSE_CHILDREN: 'Colapsar Hijos',
|
||||||
KEYBOARD_SHORTCUTS_MSG: 'Los accesos directos pueden ayudarte a salvar tiempo permitiéndote no sacar las manos del teclado para usar el mouse.',
|
KEYBOARD_SHORTCUTS_MSG: 'Los accesos directos pueden ayudarte a salvar tiempo permitiéndote no sacar las manos del teclado para usar el mouse.',
|
||||||
COPY_AND_PASTE_TOPICS: 'Copier et coller les noeuds',
|
COPY_AND_PASTE_TOPICS: 'Copiar y pegar tópicos',
|
||||||
MULTIPLE_LINES: 'Ajouter plusieurs lignes de texte',
|
MULTIPLE_LINES: 'Agregar múltiples líneas de texto',
|
||||||
BACK_TO_MAP_LIST: 'Volver a la lista de mapas',
|
BACK_TO_MAP_LIST: 'Volver a la lista de mapas',
|
||||||
KEYBOARD_SHOTCUTS: 'Métodos abreviados de teclado',
|
KEYBOARD_SHOTCUTS: 'Métodos abreviados de teclado',
|
||||||
PASTE_URL_HERE: 'Copie la URL que desea aca:',
|
PASTE_URL_HERE: 'Copie la URL que desea aca:',
|
||||||
@ -86,6 +90,11 @@ const ES = {
|
|||||||
MOUSE_CLICK: 'Mouse Click',
|
MOUSE_CLICK: 'Mouse Click',
|
||||||
K_DELETE: 'Delete',
|
K_DELETE: 'Delete',
|
||||||
BACKSPACE: 'Backspace',
|
BACKSPACE: 'Backspace',
|
||||||
|
CENTER_POSITION: 'Ajustar el Zoom',
|
||||||
|
MAP_INFO: 'Información',
|
||||||
|
FONT_FORMAT: 'Formato de Fuente',
|
||||||
|
FONT_INCREASE: 'Incrementar Tamaño de Fuente',
|
||||||
|
FONT_DECREASE: 'Decrementar Tamaño de Fuente',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ES;
|
export default ES;
|
||||||
|
@ -6,10 +6,14 @@ const FR = {
|
|||||||
TOPIC_DELETE: 'Supprimer le noeud',
|
TOPIC_DELETE: 'Supprimer le noeud',
|
||||||
TOPIC_ICON: 'Ajouter une icône',
|
TOPIC_ICON: 'Ajouter une icône',
|
||||||
TOPIC_LINK: 'Ajouter un lien',
|
TOPIC_LINK: 'Ajouter un lien',
|
||||||
TOPIC_RELATIONSHIP: 'Relation du noeud',
|
TOPIC_RELATIONSHIP: 'Ajouter une relation',
|
||||||
TOPIC_COLOR: 'Couleur du noeud',
|
TOPIC_COLOR: 'Couleur du noeud',
|
||||||
TOPIC_BORDER_COLOR: 'Couleur de bordure du noeud',
|
TOPIC_BORDER_COLOR: 'Couleur de bordure du noeud',
|
||||||
TOPIC_NOTE: 'Ajouter une note',
|
TOPIC_NOTE: 'Ajouter une note',
|
||||||
|
TOPIC_SHAPE_RECTANGLE: 'Changer la forme du sujet en rectangle',
|
||||||
|
TOPIC_SHAPE_ROUNDED: 'Modifier la forme du sujet en rectangle aux coins arrondis',
|
||||||
|
TOPIC_SHAPE_ELLIPSE: 'Changer la forme du sujet en ellipse',
|
||||||
|
TOPIC_SHAPE_LINE: 'Changer la forme du sujet en ligne',
|
||||||
FONT_FAMILY: 'Type de police',
|
FONT_FAMILY: 'Type de police',
|
||||||
FONT_SIZE: 'Taille de police',
|
FONT_SIZE: 'Taille de police',
|
||||||
FONT_BOLD: 'Caractères gras',
|
FONT_BOLD: 'Caractères gras',
|
||||||
@ -86,6 +90,11 @@ const FR = {
|
|||||||
MOUSE_CLICK: 'Clic de Souris',
|
MOUSE_CLICK: 'Clic de Souris',
|
||||||
K_DELETE: 'Delete',
|
K_DELETE: 'Delete',
|
||||||
BACKSPACE: 'Backspace',
|
BACKSPACE: 'Backspace',
|
||||||
|
CENTER_POSITION: 'Centrer la carte',
|
||||||
|
MAP_INFO: 'Informations',
|
||||||
|
FONT_FORMAT: 'Format de la police',
|
||||||
|
FONT_INCREASE: 'Augmentation de la taille de la police',
|
||||||
|
FONT_DECREASE: 'Diminution de la taille de la police',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default FR;
|
export default FR;
|
||||||
|
@ -6,7 +6,7 @@ const EN = {
|
|||||||
TOPIC_DELETE: 'Delete Topic',
|
TOPIC_DELETE: 'Delete Topic',
|
||||||
TOPIC_ICON: 'Add Icon',
|
TOPIC_ICON: 'Add Icon',
|
||||||
TOPIC_LINK: 'Add Link',
|
TOPIC_LINK: 'Add Link',
|
||||||
TOPIC_RELATIONSHIP: 'Relationship',
|
TOPIC_RELATIONSHIP: 'Добавить связь',
|
||||||
TOPIC_COLOR: 'Topic Color',
|
TOPIC_COLOR: 'Topic Color',
|
||||||
TOPIC_BORDER_COLOR: 'Topic Border Color',
|
TOPIC_BORDER_COLOR: 'Topic Border Color',
|
||||||
TOPIC_NOTE: 'Add Note',
|
TOPIC_NOTE: 'Add Note',
|
||||||
@ -14,6 +14,10 @@ const EN = {
|
|||||||
FONT_SIZE: 'Text Size',
|
FONT_SIZE: 'Text Size',
|
||||||
FONT_BOLD: 'Text Bold',
|
FONT_BOLD: 'Text Bold',
|
||||||
FONT_ITALIC: 'Text Italic',
|
FONT_ITALIC: 'Text Italic',
|
||||||
|
TOPIC_SHAPE_RECTANGLE: 'Изменить форму темы на прямоугольник',
|
||||||
|
TOPIC_SHAPE_ROUNDED: 'Изменить форму темы на прямоугольник со скругленными углами',
|
||||||
|
TOPIC_SHAPE_ELLIPSE: 'Изменить форму темы на эллипс',
|
||||||
|
TOPIC_SHAPE_LINE: 'Изменить форму темы на линию',
|
||||||
UNDO: 'Undo',
|
UNDO: 'Undo',
|
||||||
REDO: 'Redo',
|
REDO: 'Redo',
|
||||||
INSERT: 'Insert',
|
INSERT: 'Insert',
|
||||||
@ -86,6 +90,11 @@ const EN = {
|
|||||||
MOUSE_CLICK: 'Mouse Click',
|
MOUSE_CLICK: 'Mouse Click',
|
||||||
K_DELETE: 'Delete',
|
K_DELETE: 'Delete',
|
||||||
BACKSPACE: 'Backspace',
|
BACKSPACE: 'Backspace',
|
||||||
|
CENTER_POSITION: 'Масштабировать по размеру',
|
||||||
|
MAP_INFO: 'Информация',
|
||||||
|
FONT_FORMAT: 'Формат шрифта',
|
||||||
|
FONT_INCREASE: 'Увеличение размера шрифта',
|
||||||
|
FONT_DECREASE: 'Уменьшение размера шрифта',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default EN;
|
export default EN;
|
||||||
|
@ -10,6 +10,10 @@ const ZH = {
|
|||||||
TOPIC_COLOR: '主题颜色',
|
TOPIC_COLOR: '主题颜色',
|
||||||
TOPIC_BORDER_COLOR: '主题边框颜色',
|
TOPIC_BORDER_COLOR: '主题边框颜色',
|
||||||
TOPIC_NOTE: '添加注释',
|
TOPIC_NOTE: '添加注释',
|
||||||
|
TOPIC_SHAPE_RECTANGLE: '改变主题形状为矩形',
|
||||||
|
TOPIC_SHAPE_ROUNDED: '改变主题形状为圆角矩形',
|
||||||
|
TOPIC_SHAPE_ELLIPSE: '改变主题形状为椭圆',
|
||||||
|
TOPIC_SHAPE_LINE: '将主题形状更改为线条',
|
||||||
FONT_FAMILY: '字体类型',
|
FONT_FAMILY: '字体类型',
|
||||||
FONT_SIZE: '文本大小',
|
FONT_SIZE: '文本大小',
|
||||||
FONT_BOLD: '粗体文本',
|
FONT_BOLD: '粗体文本',
|
||||||
@ -86,6 +90,11 @@ const ZH = {
|
|||||||
MOUSE_CLICK: 'Mouse Click',
|
MOUSE_CLICK: 'Mouse Click',
|
||||||
K_DELETE: 'Delete',
|
K_DELETE: 'Delete',
|
||||||
BACKSPACE: 'Backspace',
|
BACKSPACE: 'Backspace',
|
||||||
|
CENTER_POSITION: '地图居中',
|
||||||
|
MAP_INFO: '信息',
|
||||||
|
FONT_FORMAT: '字体格式',
|
||||||
|
FONT_INCREASE: '字体大小增加',
|
||||||
|
FONT_DECREASE: '字体大小减小',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ZH;
|
export default ZH;
|
||||||
|
@ -19,11 +19,11 @@ const mindplotStyles = `
|
|||||||
color: rgb(51, 51, 51);
|
color: rgb(51, 51, 51);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 1px;
|
padding: 1px;
|
||||||
border-radius: 6px;
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 999;
|
z-index: 999;
|
||||||
background-color: rgb(255, 255, 255);
|
background-color: rgb(255, 255, 255);
|
||||||
animation: fadeIn 0.4s;
|
animation: fadeIn 0.4s;
|
||||||
|
box-shadow: 0px 2px 4px -1px rgba(0,0,0,0.2),0px 4px 5px 0px rgba(0,0,0,0.14),0px 1px 10px 0px rgba(0,0,0,0.12);
|
||||||
}
|
}
|
||||||
|
|
||||||
.fade-in {
|
.fade-in {
|
||||||
@ -60,28 +60,27 @@ const mindplotStyles = `
|
|||||||
}
|
}
|
||||||
|
|
||||||
.mindplot-svg-tooltip-title {
|
.mindplot-svg-tooltip-title {
|
||||||
background-color: rgb(247, 247, 247);
|
background-color: #fff;
|
||||||
border-bottom-color: rgb(235, 235, 235);
|
font-size: small;
|
||||||
border-bottom-left-radius: 0px;
|
font-family: sans;
|
||||||
border-bottom-right-radius: 0px;
|
text-transform: uppercase;
|
||||||
border-bottom-style: solid;
|
|
||||||
border-bottom-width: 1px;
|
|
||||||
border-top-left-radius: 5px;
|
|
||||||
border-top-right-radius: 5px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
color: rgb(51, 51, 51);
|
|
||||||
cursor: default;
|
|
||||||
display: block;
|
|
||||||
padding: 8px 14px;
|
padding: 8px 14px;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
font-family: Arial;
|
font-family: sans-serif;
|
||||||
font-size: small;
|
font-weight: bold;
|
||||||
|
min-width: 200px;
|
||||||
|
background-color: rgba(0, 0, 0, 0.04);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mindplot-svg-tooltip-content {
|
.mindplot-svg-tooltip-content {
|
||||||
background-color: rgb(255, 255, 255);
|
background-color: rgb(255, 255, 255);
|
||||||
padding: 6px 4px;
|
padding: 6px 4px;
|
||||||
max-width: 250px;
|
max-width: 300px;
|
||||||
|
word-wrap: break-word;
|
||||||
|
text-align: left;
|
||||||
|
font-size: small;
|
||||||
|
font-family: sans-serif;
|
||||||
|
white-space: pre-line
|
||||||
}
|
}
|
||||||
|
|
||||||
.mindplot-svg-tooltip-content-link {
|
.mindplot-svg-tooltip-content-link {
|
||||||
@ -89,44 +88,8 @@ const mindplotStyles = `
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
font-size: smaller;
|
font-size: smaller;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-family: Arial;
|
|
||||||
font-size: small;
|
|
||||||
color: #428bca;
|
color: #428bca;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mindplot-svg-tooltip-content-note {
|
|
||||||
text-align: left;
|
|
||||||
font-family: Arial;
|
|
||||||
font-size: small;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mindplot-svg-tooltip:before {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
width: 0;
|
|
||||||
height: 0;
|
|
||||||
border-left: 10px solid transparent;
|
|
||||||
border-right: 10px solid transparent;
|
|
||||||
border-bottom: 10px solid #fff;
|
|
||||||
bottom: 100%;
|
|
||||||
right: 50%;
|
|
||||||
transform: translateX(50%);
|
|
||||||
z-index: 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mindplot-svg-tooltip:after {
|
|
||||||
content: "";
|
|
||||||
display: block;
|
|
||||||
position: absolute;
|
|
||||||
width: 0;
|
|
||||||
height: 0;
|
|
||||||
border-left: 10px solid transparent;
|
|
||||||
border-right: 10px solid transparent;
|
|
||||||
border-bottom: 10px solid rgb(247, 247, 247);
|
|
||||||
bottom: calc(1px + 100%);
|
|
||||||
right: 50%;
|
|
||||||
transform: translateX(50%);
|
|
||||||
}
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export default mindplotStyles;
|
export default mindplotStyles;
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
<div id="root"></div>
|
<div id="root" class="mindplot-root"></div>
|
||||||
<!--
|
<!--
|
||||||
This HTML file is a template.
|
This HTML file is a template.
|
||||||
If you open it directly in the browser, you will see an empty page.
|
If you open it directly in the browser, you will see an empty page.
|
||||||
|
@ -11,6 +11,8 @@ import ReactGA from 'react-ga4';
|
|||||||
import { fetchAccount, fetchMapById } from '../../redux/clientSlice';
|
import { fetchAccount, fetchMapById } from '../../redux/clientSlice';
|
||||||
import EditorOptionsBuilder from './EditorOptionsBuilder';
|
import EditorOptionsBuilder from './EditorOptionsBuilder';
|
||||||
import { buildPersistenceManagerForEditor } from './PersistenceManagerUtils';
|
import { buildPersistenceManagerForEditor } from './PersistenceManagerUtils';
|
||||||
|
import { useTheme } from '@mui/material/styles';
|
||||||
|
import AccountMenu from '../maps-page/account-menu';
|
||||||
|
|
||||||
export type EditorPropsType = {
|
export type EditorPropsType = {
|
||||||
isTryMode: boolean;
|
isTryMode: boolean;
|
||||||
@ -20,6 +22,7 @@ const EditorPage = ({ isTryMode }: EditorPropsType): React.ReactElement => {
|
|||||||
const [activeDialog, setActiveDialog] = React.useState<ActionType | null>(null);
|
const [activeDialog, setActiveDialog] = React.useState<ActionType | null>(null);
|
||||||
const hotkey = useSelector(hotkeysEnabled);
|
const hotkey = useSelector(hotkeysEnabled);
|
||||||
const userLocale = AppI18n.getUserLocale();
|
const userLocale = AppI18n.getUserLocale();
|
||||||
|
const theme = useTheme();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
ReactGA.send({ hitType: 'pageview', page: window.location.pathname, title: `Map Editor` });
|
ReactGA.send({ hitType: 'pageview', page: window.location.pathname, title: `Map Editor` });
|
||||||
@ -75,6 +78,15 @@ const EditorPage = ({ isTryMode }: EditorPropsType): React.ReactElement => {
|
|||||||
options={options}
|
options={options}
|
||||||
persistenceManager={persistence}
|
persistenceManager={persistence}
|
||||||
mapId={mapId}
|
mapId={mapId}
|
||||||
|
theme={theme}
|
||||||
|
accountConfiguration={
|
||||||
|
<IntlProvider
|
||||||
|
locale={userLocale.code}
|
||||||
|
messages={userLocale.message as Record<string, string>}
|
||||||
|
>
|
||||||
|
<AccountMenu></AccountMenu>
|
||||||
|
</IntlProvider>
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
{activeDialog && (
|
{activeDialog && (
|
||||||
<ActionDispatcher
|
<ActionDispatcher
|
||||||
|
@ -1,20 +1,10 @@
|
|||||||
import { adaptV4Theme, createTheme } from '@mui/material/styles';
|
import { createTheme } from '@mui/material/styles';
|
||||||
|
|
||||||
const theme = createTheme(
|
const theme = createTheme({
|
||||||
adaptV4Theme({
|
components: {
|
||||||
overrides: {
|
|
||||||
MuiCssBaseline: {
|
|
||||||
'@global': {
|
|
||||||
body: {
|
|
||||||
backgroundColor: 'white',
|
|
||||||
// Important: This size is the min to diplay all pages except maps list.
|
|
||||||
minWidth: '450px',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
MuiOutlinedInput: {
|
MuiOutlinedInput: {
|
||||||
|
styleOverrides: {
|
||||||
root: {
|
root: {
|
||||||
height: '53px',
|
|
||||||
borderRadius: '9px',
|
borderRadius: '9px',
|
||||||
fontSize: '14px',
|
fontSize: '14px',
|
||||||
'& fieldset': {
|
'& fieldset': {
|
||||||
@ -25,15 +15,20 @@ const theme = createTheme(
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
MuiInputLabel: {
|
MuiInputLabel: {
|
||||||
|
styleOverrides: {
|
||||||
root: {
|
root: {
|
||||||
color: '#f9a826',
|
color: '#f9a826',
|
||||||
},
|
},
|
||||||
|
|
||||||
outlined: {
|
outlined: {
|
||||||
zIndex: 'inherit',
|
zIndex: 'inherit',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
MuiButton: {
|
MuiButton: {
|
||||||
|
styleOverrides: {
|
||||||
root: {
|
root: {
|
||||||
fontSize: '15px',
|
fontSize: '15px',
|
||||||
fontWeight: 600,
|
fontWeight: 600,
|
||||||
@ -50,6 +45,7 @@ const theme = createTheme(
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
typography: {
|
typography: {
|
||||||
fontFamily: ['Montserrat'].join(','),
|
fontFamily: ['Montserrat'].join(','),
|
||||||
h4: {
|
h4: {
|
||||||
@ -75,7 +71,6 @@ const theme = createTheme(
|
|||||||
contrastText: '#FFFFFF',
|
contrastText: '#FFFFFF',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}),
|
});
|
||||||
);
|
|
||||||
|
|
||||||
export { theme };
|
export { theme };
|
||||||
|