From 50489d397e6c8315b71632d9e763b0557618337f Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Wed, 3 Jul 2024 17:02:25 +0300 Subject: [PATCH] UI: Improve elbow pipes fluid rendering. --- .../scada_symbols/bottom-right-elbow-pipe.svg | 16 ++++++++++++--- .../scada_symbols/left-bottom-elbow-pipe.svg | 20 ++++++++++++++----- .../scada_symbols/left-top-elbow-pipe.svg | 14 ++++++------- .../scada_symbols/top-right-elbow-pipe.svg | 16 ++++++++++++--- 4 files changed, 48 insertions(+), 18 deletions(-) diff --git a/application/src/main/data/json/system/scada_symbols/bottom-right-elbow-pipe.svg b/application/src/main/data/json/system/scada_symbols/bottom-right-elbow-pipe.svg index cb5ea96850..e27c2deee9 100644 --- a/application/src/main/data/json/system/scada_symbols/bottom-right-elbow-pipe.svg +++ b/application/src/main/data/json/system/scada_symbols/bottom-right-elbow-pipe.svg @@ -1,4 +1,4 @@ - + { "title": "Bottom right elbow pipe", "description": "Bottom right elbow pipe with fluid and leak visualizations.", @@ -8,8 +8,13 @@ ], "widgetSizeX": 1, "widgetSizeY": 1, - "stateRenderFunction": "var horizontalLiquidPattern = prepareLiquidPattern('horizontal-liquid', 'horizontal-fluid');\nvar verticalLiquidPattern = prepareLiquidPattern('vertical-liquid', 'vertical-fluid');\n\nvar fluid = ctx.values.fluid && !ctx.values.leak;\nvar flow = ctx.values.flow;\nvar flowDirection = ctx.values.flowDirection;\nvar flowAnimationSpeed = ctx.values.flowAnimationSpeed;\n \nif (horizontalLiquidPattern) {\n updateLiquidPatternAnimation(horizontalLiquidPattern, fluid, \n flow, flowDirection, flowAnimationSpeed);\n}\n\nif (verticalLiquidPattern) {\n updateLiquidPatternAnimation(verticalLiquidPattern, fluid, \n flow, flowDirection, flowAnimationSpeed);\n}\n\nfunction prepareLiquidPattern(patternId, fluidElementTag) {\n var liquidPattern = ctx.svg.defs().findOne('pattern#'+patternId);\n var fluidElements = ctx.tags[fluidElementTag];\n\n if (liquidPattern) {\n liquidPattern.id(ctx.api.generateElementId());\n for (var i=0;i<fluidElements.length;i++) {\n fluidElements[i].fill(liquidPattern);\n }\n } else {\n liquidPattern = fluidElements[0].reference('fill');\n }\n return liquidPattern;\n}\n\nfunction updateLiquidPatternAnimation(liquidPattern, fluid, flow, flowDirection, flowAnimationSpeed) {\n var elementFluid = liquidPattern.remember('fluid');\n var elementFlow = null;\n var elementFlowDirection = null;\n \n if (fluid !== elementFluid) {\n liquidPattern.remember('fluid', fluid);\n elementFlow = null;\n elementFlowDirection = null;\n } else {\n elementFlow = liquidPattern.remember('flow');\n elementFlowDirection = liquidPattern.remember('flowDirection');\n }\n \n if (fluid) {\n if (flow !== elementFlow) {\n liquidPattern.remember('flow', flow);\n if (flow) {\n liquidPattern.remember('flowDirection', flowDirection);\n animateFlow(liquidPattern, flowDirection);\n } else {\n ctx.api.resetAnimation(liquidPattern);\n }\n } else if (flow && elementFlowDirection !== flowDirection) {\n liquidPattern.remember('flowDirection', flowDirection);\n animateFlow(liquidPattern, flowDirection);\n }\n if (flow && liquidPattern) {\n liquidPattern.timeline().speed(flowAnimationSpeed);\n }\n } else {\n ctx.api.resetAnimation(liquidPattern);\n }\n}\n\nfunction animateFlow(liquidPattern, forwardElseReverse) {\n ctx.api.resetAnimation(liquidPattern);\n var deltaX = forwardElseReverse ? 172 : -172;\n liquidPattern.animate(1000).ease('-').relative(deltaX, 0).loop();\n}\n\n", + "stateRenderFunction": "var centerLiquidPattern = prepareLiquidPattern('center-liquid', 'center-fluid-background');\nvar horizontalLiquidPattern = prepareLiquidPattern('horizontal-liquid', 'horizontal-fluid');\n\ncenterLiquidPattern.attr({'xlink:href': '#'+horizontalLiquidPattern.id()});\n\nvar verticalLiquidPattern = prepareLiquidPattern('vertical-liquid', 'vertical-fluid');\n\nvar fluid = ctx.values.fluid && !ctx.values.leak;\nvar flow = ctx.values.flow;\nvar flowDirection = ctx.values.flowDirection;\nvar flowAnimationSpeed = ctx.values.flowAnimationSpeed;\n \nif (horizontalLiquidPattern) {\n updateLiquidPatternAnimation(horizontalLiquidPattern, fluid, \n flow, flowDirection, flowAnimationSpeed, false);\n}\n\nif (verticalLiquidPattern) {\n updateLiquidPatternAnimation(verticalLiquidPattern, fluid, \n flow, flowDirection, flowAnimationSpeed, false);\n}\n\nif (centerLiquidPattern) {\n updateLiquidPatternAnimation(centerLiquidPattern, fluid, \n flow, flowDirection, flowAnimationSpeed, true);\n}\n\nfunction prepareLiquidPattern(patternId, fluidElementTag) {\n var liquidPattern = ctx.svg.defs().findOne('pattern#'+patternId);\n var fluidElements = ctx.tags[fluidElementTag];\n\n if (liquidPattern) {\n liquidPattern.id(ctx.api.generateElementId());\n for (var i=0;i<fluidElements.length;i++) {\n fluidElements[i].fill(liquidPattern);\n }\n } else {\n liquidPattern = fluidElements[0].reference('fill');\n }\n return liquidPattern;\n}\n\nfunction updateLiquidPatternAnimation(liquidPattern, fluid, flow, flowDirection, flowAnimationSpeed, center) {\n var elementFluid = liquidPattern.remember('fluid');\n var elementFlow = null;\n var elementFlowDirection = null;\n \n if (fluid !== elementFluid) {\n liquidPattern.remember('fluid', fluid);\n elementFlow = null;\n elementFlowDirection = null;\n } else {\n elementFlow = liquidPattern.remember('flow');\n elementFlowDirection = liquidPattern.remember('flowDirection');\n }\n \n if (fluid) {\n if (flow !== elementFlow) {\n liquidPattern.remember('flow', flow);\n if (flow) {\n liquidPattern.remember('flowDirection', flowDirection);\n animateFlow(liquidPattern, flowDirection, center);\n } else {\n ctx.api.resetAnimation(liquidPattern);\n }\n } else if (flow && elementFlowDirection !== flowDirection) {\n liquidPattern.remember('flowDirection', flowDirection);\n animateFlow(liquidPattern, flowDirection, center);\n }\n if (flow && liquidPattern) {\n liquidPattern.timeline().speed(flowAnimationSpeed);\n }\n } else {\n ctx.api.resetAnimation(liquidPattern);\n }\n}\n\nfunction animateFlow(liquidPattern, forwardElseReverse, center) {\n ctx.api.resetAnimation(liquidPattern);\n var deltaX = forwardElseReverse ? 172 : -172;\n if (center) {\n var delta = deltaX * 1.17 * Math.cos(45*Math.PI/180);\n liquidPattern.animate(1000).ease('-').relative(-delta, delta).loop();\n } else {\n liquidPattern.animate(1000).ease('-').relative(deltaX, 0).loop();\n }\n}\n\n", "tags": [ + { + "tag": "center-fluid", + "stateRenderFunction": "var fluid = ctx.values.fluid && !ctx.values.leak;\n\nif (fluid) {\n element.show();\n} else {\n element.hide();\n}\n", + "actions": null + }, { "tag": "fluid-background", "stateRenderFunction": "var fluid = ctx.values.fluid && !ctx.values.leak;\nif (fluid) {\n var color = ctx.properties.fluidColor;\n element.attr({fill: color});\n element.show();\n} else {\n element.hide();\n}", @@ -400,7 +405,12 @@ <clipPath id="clipPath4208"> <rect width="200" height="200" fill="#fff"/> </clipPath> - </defs><rect x="136" y="64" width="50" height="72" fill="#1ec1f4" stroke-width="0" style="display: none;" tb:tag="fluid-background"/><rect transform="rotate(90)" x="136" y="-136" width="50" height="72" fill="#1ec1f4" stroke-width="0" style="display: none;" tb:tag="fluid-background"/><rect x="136" y="64" width="50" height="72" fill="url(#horizontal-liquid)" stroke-width="0" style="display: none;" tb:tag="horizontal-fluid"/><rect transform="rotate(-90)" x="-186" y="64" width="50" height="72" fill="url(#vertical-liquid)" stroke-width="0" style="display: none;" tb:tag="vertical-fluid"/><g transform="rotate(-90 100 100)" style="display: none;" tb:tag="leak"> + <pattern id="center-liquid" patternTransform="scale(1.17) rotate(-45)" patternUnits="userSpaceOnUse" xlink:href="#horizontal-liquid"/> + </defs><rect x="136" y="64" width="50" height="72" fill="#1ec1f4" stroke-width="0" style="display: none;" tb:tag="fluid-background"/><rect transform="rotate(90)" x="136" y="-136" width="50" height="72" fill="#1ec1f4" stroke-width="0" style="display: none;" tb:tag="fluid-background"/><rect x="136" y="64" width="50" height="72" fill="url(#horizontal-liquid)" stroke-width="0" style="display: none;" tb:tag="horizontal-fluid"/><rect transform="rotate(-90)" x="-186" y="64" width="50" height="72" fill="url(#vertical-liquid)" stroke-width="0" style="display: none;" tb:tag="vertical-fluid"/><path d="m136.05 136-72.05 0.1c0.09-0.87135 0.23117-2.1615 0.44675-3.6113 0.48513-3.2616 1.3459-7.8299 2.8468-13.038 3.0077-10.437 8.5533-23.332 18.689-33.468 10.136-10.136 23.03-15.682 33.467-18.689 5.2088-1.5014 9.7767-2.3619 13.039-2.847 1.4491-0.21538 2.6909-0.35652 3.5618-0.44748z" fill="#1ec1f4" stroke="#000" stroke-width="0" style="display: none;" tb:tag="fluid-background"/><g transform="matrix(-.99929 0 0 -.99919 199.91 199.9)" style="display: none;" tb:tag="center-fluid"> + <path d="m63.956 63.95 72.051-0.10008c-0.0901 0.87205-0.23133 2.1632-0.44707 3.6142-0.48547 3.2643-1.3469 7.8362-2.8488 13.048-3.0098 10.446-8.5594 23.351-18.702 33.495-10.143 10.145-23.046 15.695-33.491 18.704-5.2125 1.5026-9.7836 2.3638-13.048 2.8493-1.4501 0.21555-2.7428 0.3568-3.6144 0.44784z" fill="url(#center-liquid)" stroke="#000" stroke-width="0" tb:tag="center-fluid-background" style=""/> + <path d="m132.05 63.75s-0.0216 31.824-17.622 50.677c-17.142 17.939-50.576 17.628-50.576 17.628" fill="none" stroke="#727171" stroke-width="7.9" style=""/> + <path d="m63.956 63.954v-0.15398h7.8942v8.05h-8.0503v-7.896z" style="fill: rgb(114, 113, 113);"/> + </g><g transform="rotate(-90 100 100)" style="display: none;" tb:tag="leak"> <path d="m62.784 80.767c0.417 0.1391 0.9517 0.2463 1.3259 0.4603 1.326 0.4603 2.5556 1.2628 3.3039 2.386 0.2779 0.5563 0.5129 1.1873 0.6731 1.7756 0.4915 1.5723 1.0257 3.0697 1.5599 4.5672 0.545 1.3049 1.0792 2.8023 0.544 4.0855-0.1925-0.0107-0.3101 0.0213-0.5026 0.0105 0.3307 2.3744 2.2423 0.7354 6.5024 7.0127 2.2452 8.828 4.8752 21.579 4.8212 23.236-0.0323 0.578 0.0531 1.123 0.0636 1.626-0.011 0.887-0.0969 1.732-0.3752 2.566-0.1499 0.61-0.4924 1.209-0.7172 1.775-0.6315 1.626-1.1134 3.337-1.253 5.144 0.3745-0.481 0.749-0.962 1.1234-1.443 0 0 0.353-0.096 0.2353-0.064-0.1069-0.161 0.0216-0.385 0.182-0.492 0.3527 0.599 0.7055 1.198 0.9833 1.754 1.6139 2.91 3.185 5.894 4.478 9.017-0.7155-3.091-1.8588-6.128-3.2374-9.102-0.3099-0.674-0.6626-1.273-0.8121-2.054-0.4378-1.839 0.4398-3.721 1.4243-5.443l0.0428-0.075c0.0856-0.149 0.214-0.374 0.4065-0.363 0.2354-0.064 0.4919 0.182 0.6737 0.385 0.8659 1.091 1.7746 2.108 2.6833 3.124 1.1653 1.262 2.459 2.3 3.5814 3.637 1.0156 1.177 1.8708 2.461 2.6511 3.702 0.3527 0.599 0.7482 1.123 0.8656 1.786 0.1923 0.706 0.192 1.401 0.0742 2.128-0.1287 0.92-0.2146 1.765-0.4181 2.642-1.0925 5.036 4.1863 14.098 2.2917 18.974 1.1129-1.946 2.1938-4.009 3.3067-5.955 0.4161 2.919 1.6132 5.69 2.7672 8.535 0.342 0.791 0.684 1.583 0.865 2.481 0.192 0.706 0.224 1.519 0.224 2.214 0 1.391-0.119 2.813-0.878 3.968 0.577-0.663 1.006-1.412 1.316-2.128 0.182 0.203 0.438 0.449 0.62 0.652 1.604 1.712 3.25 3.349 4.779 5.018-0.374-0.909-0.984-1.754-1.636-2.525-0.908-1.016-2.063-1.776-2.651-3.006-0.695-1.39-0.448-3.037-0.629-4.631-0.245-2.524-1.464-4.909-2.49-7.284-1.026-2.374-2.4215-4.17-3.795-8.188-0.9898-2.895-2.4972-7.611-1.9831-9.9 0.1179-0.727 0.3534-1.486 0.6638-2.203 0.182-0.492 0.4389-0.941 0.7385-1.465 0.3424-0.599 0.642-1.123 0.9096-1.764 0.2141-0.374 0.3532-0.791 0.3748-1.176 0.0643-0.46-0.1387-0.974-0.3097-1.369-0.577-1.423-1.1541-2.846-1.7311-4.268 0.0641 0.235 0.1602 0.588 0.2243 0.823 0.5127 1.883 0.9506 3.722 0.6933 5.562-0.0216 0.385-0.1607 0.802-0.4068 1.058-0.0428 0.075-0.0856 0.15-0.1605 0.107-0.3637 0.289-1.0909 0.171-1.1442-0.257-0.5668-0.224-1.112-0.834-1.4754-1.241-2.6726-3.316-5.3023-6.707-7.8572-10.055-0.2886-0.364-0.5773-0.728-0.7803-1.241-0.203-0.514-0.2563-0.942-0.2669-1.444-0.2982-3.647-2.4962-15.905-3.458-18.422-1.5388-4.028-0.5464-4.267-2.5593-5.9434 0.0535-0.2674-6.9427-5.6276-6.8891-5.8949 0.3322-1.7966 1.584-3.4646 2.7823-4.8651 1.2483-1.1574 5.2035 1.7887 5.8127 1.8117 0.6917 0.0262 13.721 15.05 14.606 16.356 0.3527 0.599 0.2189 1.786 0.4355 2.02 0.0765 0.083 1.5882 0.445 0.3927-0.21-0.023 0.609 1.7337 6.612 1.497 10.847-0.0216 0.385-0.0859 0.845-0.2251 1.262-0.0535 0.268-0.1819 0.492-0.3852 0.674-0.0428 0.075-0.1605 0.107-0.2781 0.139-0.1177 0.032-0.1497-0.086-0.2246-0.129-2.6943-2.236-5.2814-5.006-8.8318-5.746 0.1069 0.161 0.1817 0.204 0.2886 0.364 0.0749 0.043 0.1069 0.161 0.2566 0.246 1.3898 1.391 3.261 2.461 4.3728 3.991 0.5024 0.684 0.962 1.444 1.6677 1.947 0.9302 0.631 2.3097 0.824 3.0367 1.637 0.3635 0.407 0.6414 0.963 0.7695 1.433 0.3525 1.295 0.4269 2.728 0.897 3.99 0.2351 0.631 0.6627 1.273 0.8974 1.904 0.032 0.118 0.107 0.16 0.139 0.278 0.577 1.423 3.497 6.167 3.411 7.707 0.075-1.348-2.706-5.814-2.438-7.151 1.465 1.434 2.855 2.825 4.234 4.408-0.919-1.519-1.999-2.931-3.239-4.236-0.62-0.653-1.24-1.305-1.7-2.065-0.8443-1.476-0.6511-3.551 0.825-4.395 0.161-0.107 0.321-0.214 0.513-0.203 0.985-0.331 2.097-0.192 3.134-0.095 3.027 0.439 5.893 0.986 8.908 1.618 2.214 0.471 4.385 1.017 6.288 2.205 0.15 0.086 0.257 0.246 0.171 0.396 0.599-0.353 1.241-0.085 1.797 0.332 0.598 0.342 1.111 0.835 1.667 1.252 0.482 0.374 0.963 0.749 1.444 1.123 2.256 1.787 4.469 3.649 6.479 5.692-0.78-1.241-1.796-2.418-3.058-3.338-0.887-0.706-1.86-1.262-2.63-2.001-0.844-0.781-1.368-1.775-2.213-2.556-0.406-0.332-0.887-0.707-1.251-1.113 1.123-0.053 2.203-0.031 3.326-0.084-0.802-0.161-1.604-0.322-2.406-0.483-0.994-0.171-1.946-0.417-2.898-0.664-2.352-0.749-4.544-2.301-6.993-2.708-0.193-0.011-0.385-0.021-0.578-0.032 0.107 0.16 0.257 0.246 0.364 0.406-0.118 0.033-0.268-0.053-0.385-0.021-2.161-0.044-4.374-0.515-6.427-1.093-1.829-0.45-3.807-0.985-5.005-2.365-0.363-0.407-0.684-0.888-1.047-1.295-0.364-0.406-1.0054-0.674-1.5508-0.589 0.2575-2.534 1.0086-5.312-0.4558-7.441-1.1438-1.647-0.6523-3.686-2.1639-4.048 0.5862 0.632 0.9484-0.88 0.3852-2.121-0.5632-1.242-11.812-19.078-21.406-19.814-1.5082 0.7267-2.7386 2.0097-3.3594 3.4425-0.0428 0.0749-0.0428 0.0749-0.0856 0.1497-0.951-2.3317-1.9341-4.7812-3.2381-7.0168-0.4275-0.6418-0.8123-1.3585-1.4431-1.8186-1.2832-0.5352-2.898-0.6641-4.438-0.7501z" clip-path="url(#clipPath4310)" fill="#5c5a5a" style=""/> <path d="m96.836 106.97c-0.1607 0.802-0.3972 1.217-0.1729 2.041 0.4486 1.647 1.0572 2.066 1.7411 3.649 0.6732 1.776 0.6698 2.683 0.7546 4.619 0.0211 1.005-0.0327 1.968-0.1614 2.887 0.7808-0.149 1.8421 1.436 2.3871 2.046 0.545 0.609 1.005 1.369 1.722 1.679 0.791 0.353 1.646 0.247 2.491 0.333 0.92 0.128 1.786 0.524 2.695 0.845 1.861 0.568 3.797 0.483 5.7 0.28-0.075-0.042-0.075-0.042-0.149-0.085-2.161-0.044-4.374-0.515-6.428-1.093-1.828-0.45-3.807-0.985-5.004-2.365-0.363-0.407-0.684-0.888-1.048-1.295-0.363-0.406-1.328-1.638-1.8737-1.553 0.2575-2.534 0.8497-4.297-0.615-6.426-1.1437-1.647-0.9919-2.182-1.5794-4.108-0.2138-0.321-0.374-0.909-0.4594-1.454z" clip-path="url(#clipPath4304)" fill="#8b8b8b" style=""/> <path d="m87.799 115.57c0.1069 0.161 0.1818 0.204 0.2887 0.364 0.0748 0.043 0.1069 0.161 0.2566 0.246l0.0748 0.043c0.5667 0.225 1.1335 0.449 1.6895 0.867 0.4491 0.257 0.9302 0.631 1.3365 0.963 1.7748 1.412 3.2928 3.273 5.3993 4.279 0.2997-0.523 0.5993-1.047 0.7064-1.582-0.0535 0.267-0.182 0.492-0.3852 0.674-0.0428 0.074-0.1605 0.106-0.2781 0.138-0.1177 0.033-0.1497-0.085-0.2246-0.128-2.6835-2.429-5.3135-5.125-8.8639-5.864z" clip-path="url(#clipPath4298)" fill="#8b8b8b" style=""/> diff --git a/application/src/main/data/json/system/scada_symbols/left-bottom-elbow-pipe.svg b/application/src/main/data/json/system/scada_symbols/left-bottom-elbow-pipe.svg index 78dc52c4d1..1109a8a54c 100644 --- a/application/src/main/data/json/system/scada_symbols/left-bottom-elbow-pipe.svg +++ b/application/src/main/data/json/system/scada_symbols/left-bottom-elbow-pipe.svg @@ -1,5 +1,4 @@ -<svg xmlns="http://www.w3.org/2000/svg" xmlns:tb="https://thingsboard.io/svg" width="200" height="200" fill="none" version="1.1" viewBox="0 0 200 200"> -<tb:metadata xmlns=""><![CDATA[{ +<svg xmlns="http://www.w3.org/2000/svg" xmlns:tb="https://thingsboard.io/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" fill="none" version="1.1" viewBox="0 0 200 200"><tb:metadata xmlns=""><![CDATA[{ "title": "Left bottom elbow pipe", "description": "Left bottom elbow pipe with fluid and leak visualizations.", "searchTags": [ @@ -8,8 +7,13 @@ ], "widgetSizeX": 1, "widgetSizeY": 1, - "stateRenderFunction": "var horizontalLiquidPattern = prepareLiquidPattern('horizontal-liquid', 'horizontal-fluid');\nvar verticalLiquidPattern = prepareLiquidPattern('vertical-liquid', 'vertical-fluid');\n\nvar fluid = ctx.values.fluid && !ctx.values.leak;\nvar flow = ctx.values.flow;\nvar flowDirection = ctx.values.flowDirection;\nvar flowAnimationSpeed = ctx.values.flowAnimationSpeed;\n \nif (horizontalLiquidPattern) {\n updateLiquidPatternAnimation(horizontalLiquidPattern, fluid, \n flow, flowDirection, flowAnimationSpeed);\n}\n\nif (verticalLiquidPattern) {\n updateLiquidPatternAnimation(verticalLiquidPattern, fluid, \n flow, flowDirection, flowAnimationSpeed);\n}\n\nfunction prepareLiquidPattern(patternId, fluidElementTag) {\n var liquidPattern = ctx.svg.defs().findOne('pattern#'+patternId);\n var fluidElements = ctx.tags[fluidElementTag];\n\n if (liquidPattern) {\n liquidPattern.id(ctx.api.generateElementId());\n for (var i=0;i<fluidElements.length;i++) {\n fluidElements[i].fill(liquidPattern);\n }\n } else {\n liquidPattern = fluidElements[0].reference('fill');\n }\n return liquidPattern;\n}\n\nfunction updateLiquidPatternAnimation(liquidPattern, fluid, flow, flowDirection, flowAnimationSpeed) {\n var elementFluid = liquidPattern.remember('fluid');\n var elementFlow = null;\n var elementFlowDirection = null;\n \n if (fluid !== elementFluid) {\n liquidPattern.remember('fluid', fluid);\n elementFlow = null;\n elementFlowDirection = null;\n } else {\n elementFlow = liquidPattern.remember('flow');\n elementFlowDirection = liquidPattern.remember('flowDirection');\n }\n \n if (fluid) {\n if (flow !== elementFlow) {\n liquidPattern.remember('flow', flow);\n if (flow) {\n liquidPattern.remember('flowDirection', flowDirection);\n animateFlow(liquidPattern, flowDirection);\n } else {\n ctx.api.resetAnimation(liquidPattern);\n }\n } else if (flow && elementFlowDirection !== flowDirection) {\n liquidPattern.remember('flowDirection', flowDirection);\n animateFlow(liquidPattern, flowDirection);\n }\n if (flow && liquidPattern) {\n liquidPattern.timeline().speed(flowAnimationSpeed);\n }\n } else {\n ctx.api.resetAnimation(liquidPattern);\n }\n}\n\nfunction animateFlow(liquidPattern, forwardElseReverse) {\n ctx.api.resetAnimation(liquidPattern);\n var deltaX = forwardElseReverse ? 172 : -172;\n liquidPattern.animate(1000).ease('-').relative(deltaX, 0).loop();\n}\n\n", + "stateRenderFunction": "var centerLiquidPattern = prepareLiquidPattern('center-liquid', 'center-fluid-background');\nvar horizontalLiquidPattern = prepareLiquidPattern('horizontal-liquid', 'horizontal-fluid');\n\ncenterLiquidPattern.attr({'xlink:href': '#'+horizontalLiquidPattern.id()});\n\nvar verticalLiquidPattern = prepareLiquidPattern('vertical-liquid', 'vertical-fluid');\n\nvar fluid = ctx.values.fluid && !ctx.values.leak;\nvar flow = ctx.values.flow;\nvar flowDirection = ctx.values.flowDirection;\nvar flowAnimationSpeed = ctx.values.flowAnimationSpeed;\n \nif (horizontalLiquidPattern) {\n updateLiquidPatternAnimation(horizontalLiquidPattern, fluid, \n flow, flowDirection, flowAnimationSpeed, false);\n}\n\nif (verticalLiquidPattern) {\n updateLiquidPatternAnimation(verticalLiquidPattern, fluid, \n flow, flowDirection, flowAnimationSpeed, false);\n}\n\nif (centerLiquidPattern) {\n updateLiquidPatternAnimation(centerLiquidPattern, fluid, \n flow, flowDirection, flowAnimationSpeed, true);\n}\n\nfunction prepareLiquidPattern(patternId, fluidElementTag) {\n var liquidPattern = ctx.svg.defs().findOne('pattern#'+patternId);\n var fluidElements = ctx.tags[fluidElementTag];\n\n if (liquidPattern) {\n liquidPattern.id(ctx.api.generateElementId());\n for (var i=0;i<fluidElements.length;i++) {\n fluidElements[i].fill(liquidPattern);\n }\n } else {\n liquidPattern = fluidElements[0].reference('fill');\n }\n return liquidPattern;\n}\n\nfunction updateLiquidPatternAnimation(liquidPattern, fluid, flow, flowDirection, flowAnimationSpeed, center) {\n var elementFluid = liquidPattern.remember('fluid');\n var elementFlow = null;\n var elementFlowDirection = null;\n \n if (fluid !== elementFluid) {\n liquidPattern.remember('fluid', fluid);\n elementFlow = null;\n elementFlowDirection = null;\n } else {\n elementFlow = liquidPattern.remember('flow');\n elementFlowDirection = liquidPattern.remember('flowDirection');\n }\n \n if (fluid) {\n if (flow !== elementFlow) {\n liquidPattern.remember('flow', flow);\n if (flow) {\n liquidPattern.remember('flowDirection', flowDirection);\n animateFlow(liquidPattern, flowDirection, center);\n } else {\n ctx.api.resetAnimation(liquidPattern);\n }\n } else if (flow && elementFlowDirection !== flowDirection) {\n liquidPattern.remember('flowDirection', flowDirection);\n animateFlow(liquidPattern, flowDirection, center);\n }\n if (flow && liquidPattern) {\n liquidPattern.timeline().speed(flowAnimationSpeed);\n }\n } else {\n ctx.api.resetAnimation(liquidPattern);\n }\n}\n\nfunction animateFlow(liquidPattern, forwardElseReverse, center) {\n ctx.api.resetAnimation(liquidPattern);\n var deltaX = forwardElseReverse ? 172 : -172;\n if (center) {\n var delta = deltaX * 1.17 * Math.cos(45*Math.PI/180);\n liquidPattern.animate(1000).ease('-').relative(-delta, delta).loop();\n } else {\n liquidPattern.animate(1000).ease('-').relative(deltaX, 0).loop();\n }\n}\n\n", "tags": [ + { + "tag": "center-fluid", + "stateRenderFunction": "var fluid = ctx.values.fluid && !ctx.values.leak;\n\nif (fluid) {\n element.show();\n} else {\n element.hide();\n}\n", + "actions": null + }, { "tag": "fluid-background", "stateRenderFunction": "var fluid = ctx.values.fluid && !ctx.values.leak;\nif (fluid) {\n var color = ctx.properties.fluidColor;\n element.attr({fill: color});\n element.show();\n} else {\n element.hide();\n}", @@ -121,7 +125,8 @@ "step": null } ] -} +}]]> + @@ -400,7 +405,12 @@ - + + + + + + diff --git a/application/src/main/data/json/system/scada_symbols/left-top-elbow-pipe.svg b/application/src/main/data/json/system/scada_symbols/left-top-elbow-pipe.svg index 816cdbf338..1b795935e1 100644 --- a/application/src/main/data/json/system/scada_symbols/left-top-elbow-pipe.svg +++ b/application/src/main/data/json/system/scada_symbols/left-top-elbow-pipe.svg @@ -1,5 +1,4 @@ - -{ +<svg xmlns="http://www.w3.org/2000/svg" xmlns:tb="https://thingsboard.io/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" fill="none" version="1.1" viewBox="0 0 200 200"><tb:metadata xmlns=""><![CDATA[{ "title": "Left top elbow pipe", "description": "Left top elbow pipe with fluid and leak visualizations.", "searchTags": [ @@ -126,7 +125,8 @@ "step": null } ] -} +}]]> + @@ -406,10 +406,10 @@ - - - - + + + + diff --git a/application/src/main/data/json/system/scada_symbols/top-right-elbow-pipe.svg b/application/src/main/data/json/system/scada_symbols/top-right-elbow-pipe.svg index b68ca82349..9513ee7fc2 100644 --- a/application/src/main/data/json/system/scada_symbols/top-right-elbow-pipe.svg +++ b/application/src/main/data/json/system/scada_symbols/top-right-elbow-pipe.svg @@ -1,4 +1,4 @@ -{ +<svg xmlns="http://www.w3.org/2000/svg" xmlns:tb="https://thingsboard.io/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" fill="none" version="1.1" viewBox="0 0 200 200"><tb:metadata xmlns=""><![CDATA[{ "title": "Top right elbow pipe", "description": "Top right elbow pipe with fluid and leak visualizations.", "searchTags": [ @@ -7,8 +7,13 @@ ], "widgetSizeX": 1, "widgetSizeY": 1, - "stateRenderFunction": "var horizontalLiquidPattern = prepareLiquidPattern('horizontal-liquid', 'horizontal-fluid');\nvar verticalLiquidPattern = prepareLiquidPattern('vertical-liquid', 'vertical-fluid');\n\nvar fluid = ctx.values.fluid && !ctx.values.leak;\nvar flow = ctx.values.flow;\nvar flowDirection = ctx.values.flowDirection;\nvar flowAnimationSpeed = ctx.values.flowAnimationSpeed;\n \nif (horizontalLiquidPattern) {\n updateLiquidPatternAnimation(horizontalLiquidPattern, fluid, \n flow, flowDirection, flowAnimationSpeed);\n}\n\nif (verticalLiquidPattern) {\n updateLiquidPatternAnimation(verticalLiquidPattern, fluid, \n flow, flowDirection, flowAnimationSpeed);\n}\n\nfunction prepareLiquidPattern(patternId, fluidElementTag) {\n var liquidPattern = ctx.svg.defs().findOne('pattern#'+patternId);\n var fluidElements = ctx.tags[fluidElementTag];\n\n if (liquidPattern) {\n liquidPattern.id(ctx.api.generateElementId());\n for (var i=0;i<fluidElements.length;i++) {\n fluidElements[i].fill(liquidPattern);\n }\n } else {\n liquidPattern = fluidElements[0].reference('fill');\n }\n return liquidPattern;\n}\n\nfunction updateLiquidPatternAnimation(liquidPattern, fluid, flow, flowDirection, flowAnimationSpeed) {\n var elementFluid = liquidPattern.remember('fluid');\n var elementFlow = null;\n var elementFlowDirection = null;\n \n if (fluid !== elementFluid) {\n liquidPattern.remember('fluid', fluid);\n elementFlow = null;\n elementFlowDirection = null;\n } else {\n elementFlow = liquidPattern.remember('flow');\n elementFlowDirection = liquidPattern.remember('flowDirection');\n }\n \n if (fluid) {\n if (flow !== elementFlow) {\n liquidPattern.remember('flow', flow);\n if (flow) {\n liquidPattern.remember('flowDirection', flowDirection);\n animateFlow(liquidPattern, flowDirection);\n } else {\n ctx.api.resetAnimation(liquidPattern);\n }\n } else if (flow && elementFlowDirection !== flowDirection) {\n liquidPattern.remember('flowDirection', flowDirection);\n animateFlow(liquidPattern, flowDirection);\n }\n if (flow && liquidPattern) {\n liquidPattern.timeline().speed(flowAnimationSpeed);\n }\n } else {\n ctx.api.resetAnimation(liquidPattern);\n }\n}\n\nfunction animateFlow(liquidPattern, forwardElseReverse) {\n ctx.api.resetAnimation(liquidPattern);\n var deltaX = forwardElseReverse ? 172 : -172;\n liquidPattern.animate(1000).ease('-').relative(deltaX, 0).loop();\n}\n\n", + "stateRenderFunction": "var centerLiquidPattern = prepareLiquidPattern('center-liquid', 'center-fluid-background');\nvar horizontalLiquidPattern = prepareLiquidPattern('horizontal-liquid', 'horizontal-fluid');\n\ncenterLiquidPattern.attr({'xlink:href': '#'+horizontalLiquidPattern.id()});\n\nvar verticalLiquidPattern = prepareLiquidPattern('vertical-liquid', 'vertical-fluid');\n\nvar fluid = ctx.values.fluid && !ctx.values.leak;\nvar flow = ctx.values.flow;\nvar flowDirection = ctx.values.flowDirection;\nvar flowAnimationSpeed = ctx.values.flowAnimationSpeed;\n \nif (horizontalLiquidPattern) {\n updateLiquidPatternAnimation(horizontalLiquidPattern, fluid, \n flow, flowDirection, flowAnimationSpeed, false);\n}\n\nif (verticalLiquidPattern) {\n updateLiquidPatternAnimation(verticalLiquidPattern, fluid, \n flow, flowDirection, flowAnimationSpeed, false);\n}\n\nif (centerLiquidPattern) {\n updateLiquidPatternAnimation(centerLiquidPattern, fluid, \n flow, flowDirection, flowAnimationSpeed, true);\n}\n\nfunction prepareLiquidPattern(patternId, fluidElementTag) {\n var liquidPattern = ctx.svg.defs().findOne('pattern#'+patternId);\n var fluidElements = ctx.tags[fluidElementTag];\n\n if (liquidPattern) {\n liquidPattern.id(ctx.api.generateElementId());\n for (var i=0;i<fluidElements.length;i++) {\n fluidElements[i].fill(liquidPattern);\n }\n } else {\n liquidPattern = fluidElements[0].reference('fill');\n }\n return liquidPattern;\n}\n\nfunction updateLiquidPatternAnimation(liquidPattern, fluid, flow, flowDirection, flowAnimationSpeed, center) {\n var elementFluid = liquidPattern.remember('fluid');\n var elementFlow = null;\n var elementFlowDirection = null;\n \n if (fluid !== elementFluid) {\n liquidPattern.remember('fluid', fluid);\n elementFlow = null;\n elementFlowDirection = null;\n } else {\n elementFlow = liquidPattern.remember('flow');\n elementFlowDirection = liquidPattern.remember('flowDirection');\n }\n \n if (fluid) {\n if (flow !== elementFlow) {\n liquidPattern.remember('flow', flow);\n if (flow) {\n liquidPattern.remember('flowDirection', flowDirection);\n animateFlow(liquidPattern, flowDirection, center);\n } else {\n ctx.api.resetAnimation(liquidPattern);\n }\n } else if (flow && elementFlowDirection !== flowDirection) {\n liquidPattern.remember('flowDirection', flowDirection);\n animateFlow(liquidPattern, flowDirection, center);\n }\n if (flow && liquidPattern) {\n liquidPattern.timeline().speed(flowAnimationSpeed);\n }\n } else {\n ctx.api.resetAnimation(liquidPattern);\n }\n}\n\nfunction animateFlow(liquidPattern, forwardElseReverse, center) {\n ctx.api.resetAnimation(liquidPattern);\n var deltaX = forwardElseReverse ? 172 : -172;\n if (center) {\n var delta = deltaX * 1.17 * Math.cos(45*Math.PI/180);\n liquidPattern.animate(1000).ease('-').relative(delta, -delta).loop();\n } else {\n liquidPattern.animate(1000).ease('-').relative(deltaX, 0).loop();\n }\n}\n\n", "tags": [ + { + "tag": "center-fluid", + "stateRenderFunction": "var fluid = ctx.values.fluid && !ctx.values.leak;\n\nif (fluid) {\n element.show();\n} else {\n element.hide();\n}\n", + "actions": null + }, { "tag": "fluid-background", "stateRenderFunction": "var fluid = ctx.values.fluid && !ctx.values.leak;\nif (fluid) {\n var color = ctx.properties.fluidColor;\n element.attr({fill: color});\n element.show();\n} else {\n element.hide();\n}", @@ -400,7 +405,12 @@ <clipPath id="clipPath4208"> <rect width="200" height="200" fill="#fff"/> </clipPath> - </defs><rect x="136" y="64" width="50" height="72" fill="#1ec1f4" stroke-width="0" style="display: none;" tb:tag="fluid-background"/><rect transform="rotate(90)" x="14" y="-136" width="50" height="72" fill="#1ec1f4" stroke-width="0" style="display: none;" tb:tag="fluid-background"/><rect x="136" y="64" width="50" height="72" fill="url(#horizontal-liquid)" stroke-width="0" style="display: none;" tb:tag="horizontal-fluid"/><rect transform="rotate(90)" x="14" y="-136" width="50" height="72" fill="url(#vertical-liquid)" stroke-width="0" style="display: none;" tb:tag="vertical-fluid"/><g transform="rotate(180 100 100)" style="display: none;" tb:tag="leak"> + <pattern id="center-liquid" patternTransform="scale(1.17) rotate(-45)" patternUnits="userSpaceOnUse" xlink:href="#horizontal-liquid"/> + </defs><rect x="136" y="64" width="50" height="72" fill="#1ec1f4" stroke-width="0" style="display: none;" tb:tag="fluid-background"/><rect transform="rotate(90)" x="14" y="-136" width="50" height="72" fill="#1ec1f4" stroke-width="0" style="display: none;" tb:tag="fluid-background"/><rect x="136" y="64" width="50" height="72" fill="url(#horizontal-liquid)" stroke-width="0" style="display: none;" tb:tag="horizontal-fluid"/><rect transform="rotate(90)" x="14" y="-136" width="50" height="72" fill="url(#vertical-liquid)" stroke-width="0" style="display: none;" tb:tag="vertical-fluid"/><path d="m136 63.85 0.1 72.05c-0.87135-0.09-2.1615-0.23117-3.6113-0.44675-3.2616-0.48513-7.8299-1.3459-13.038-2.8468-10.437-3.0077-23.332-8.5533-33.468-18.689-10.136-10.136-15.682-23.03-18.689-33.467-1.5014-5.2088-2.3619-9.7767-2.847-13.039-0.21538-1.4491-0.35652-2.6909-0.44748-3.5618z" fill="#1ec1f4" stroke="#000" stroke-width="0" style="display: none;" tb:tag="fluid-background"/><g transform="matrix(0 .99929 -.99919 0 199.9 .095299)" style="display: none;" tb:tag="center-fluid"> + <path d="m63.956 63.95 72.051-0.10008c-0.0901 0.87205-0.23133 2.1632-0.44707 3.6142-0.48547 3.2643-1.3469 7.8362-2.8488 13.048-3.0098 10.446-8.5594 23.351-18.702 33.495-10.143 10.145-23.046 15.695-33.491 18.704-5.2125 1.5026-9.7836 2.3638-13.048 2.8493-1.4501 0.21555-2.7428 0.3568-3.6144 0.44784z" fill="url(#center-liquid)" stroke="#000" stroke-width="0" tb:tag="center-fluid-background" style=""/> + <path d="m132.05 63.75s-0.0216 31.824-17.622 50.677c-17.814 17.618-50.678 17.628-50.678 17.628" fill="none" stroke="#727171" stroke-width="7.9" style=""/> + <path d="m63.95 63.954v-0.17285l7.9056-0.02731v8.1066h-8.2058v-7.9066z" style="fill: rgb(114, 113, 113); stroke-width: 1.007;"/> + </g><g transform="rotate(180 100 100)" style="display: none;" tb:tag="leak"> <path d="m62.784 80.767c0.417 0.1391 0.9517 0.2463 1.3259 0.4603 1.326 0.4603 2.5556 1.2628 3.3039 2.386 0.2779 0.5563 0.5129 1.1873 0.6731 1.7756 0.4915 1.5723 1.0257 3.0697 1.5599 4.5672 0.545 1.3049 1.0792 2.8023 0.544 4.0855-0.1925-0.0107-0.3101 0.0213-0.5026 0.0105 0.3307 2.3744 2.2423 0.7354 6.5024 7.0127 2.2452 8.828 4.8752 21.579 4.8212 23.236-0.0323 0.578 0.0531 1.123 0.0636 1.626-0.011 0.887-0.0969 1.732-0.3752 2.566-0.1499 0.61-0.4924 1.209-0.7172 1.775-0.6315 1.626-1.1134 3.337-1.253 5.144 0.3745-0.481 0.749-0.962 1.1234-1.443 0 0 0.353-0.096 0.2353-0.064-0.1069-0.161 0.0216-0.385 0.182-0.492 0.3527 0.599 0.7055 1.198 0.9833 1.754 1.6139 2.91 3.185 5.894 4.478 9.017-0.7155-3.091-1.8588-6.128-3.2374-9.102-0.3099-0.674-0.6626-1.273-0.8121-2.054-0.4378-1.839 0.4398-3.721 1.4243-5.443l0.0428-0.075c0.0856-0.149 0.214-0.374 0.4065-0.363 0.2354-0.064 0.4919 0.182 0.6737 0.385 0.8659 1.091 1.7746 2.108 2.6833 3.124 1.1653 1.262 2.459 2.3 3.5814 3.637 1.0156 1.177 1.8708 2.461 2.6511 3.702 0.3527 0.599 0.7482 1.123 0.8656 1.786 0.1923 0.706 0.192 1.401 0.0742 2.128-0.1287 0.92-0.2146 1.765-0.4181 2.642-1.0925 5.036 4.1863 14.098 2.2917 18.974 1.1129-1.946 2.1938-4.009 3.3067-5.955 0.4161 2.919 1.6132 5.69 2.7672 8.535 0.342 0.791 0.684 1.583 0.865 2.481 0.192 0.706 0.224 1.519 0.224 2.214 0 1.391-0.119 2.813-0.878 3.968 0.577-0.663 1.006-1.412 1.316-2.128 0.182 0.203 0.438 0.449 0.62 0.652 1.604 1.712 3.25 3.349 4.779 5.018-0.374-0.909-0.984-1.754-1.636-2.525-0.908-1.016-2.063-1.776-2.651-3.006-0.695-1.39-0.448-3.037-0.629-4.631-0.245-2.524-1.464-4.909-2.49-7.284-1.026-2.374-2.4215-4.17-3.795-8.188-0.9898-2.895-2.4972-7.611-1.9831-9.9 0.1179-0.727 0.3534-1.486 0.6638-2.203 0.182-0.492 0.4389-0.941 0.7385-1.465 0.3424-0.599 0.642-1.123 0.9096-1.764 0.2141-0.374 0.3532-0.791 0.3748-1.176 0.0643-0.46-0.1387-0.974-0.3097-1.369-0.577-1.423-1.1541-2.846-1.7311-4.268 0.0641 0.235 0.1602 0.588 0.2243 0.823 0.5127 1.883 0.9506 3.722 0.6933 5.562-0.0216 0.385-0.1607 0.802-0.4068 1.058-0.0428 0.075-0.0856 0.15-0.1605 0.107-0.3637 0.289-1.0909 0.171-1.1442-0.257-0.5668-0.224-1.112-0.834-1.4754-1.241-2.6726-3.316-5.3023-6.707-7.8572-10.055-0.2886-0.364-0.5773-0.728-0.7803-1.241-0.203-0.514-0.2563-0.942-0.2669-1.444-0.2982-3.647-2.4962-15.905-3.458-18.422-1.5388-4.028-0.5464-4.267-2.5593-5.9434 0.0535-0.2674-6.9427-5.6276-6.8891-5.8949 0.3322-1.7966 1.584-3.4646 2.7823-4.8651 1.2483-1.1574 5.2035 1.7887 5.8127 1.8117 0.6917 0.0262 13.721 15.05 14.606 16.356 0.3527 0.599 0.2189 1.786 0.4355 2.02 0.0765 0.083 1.5882 0.445 0.3927-0.21-0.023 0.609 1.7337 6.612 1.497 10.847-0.0216 0.385-0.0859 0.845-0.2251 1.262-0.0535 0.268-0.1819 0.492-0.3852 0.674-0.0428 0.075-0.1605 0.107-0.2781 0.139-0.1177 0.032-0.1497-0.086-0.2246-0.129-2.6943-2.236-5.2814-5.006-8.8318-5.746 0.1069 0.161 0.1817 0.204 0.2886 0.364 0.0749 0.043 0.1069 0.161 0.2566 0.246 1.3898 1.391 3.261 2.461 4.3728 3.991 0.5024 0.684 0.962 1.444 1.6677 1.947 0.9302 0.631 2.3097 0.824 3.0367 1.637 0.3635 0.407 0.6414 0.963 0.7695 1.433 0.3525 1.295 0.4269 2.728 0.897 3.99 0.2351 0.631 0.6627 1.273 0.8974 1.904 0.032 0.118 0.107 0.16 0.139 0.278 0.577 1.423 3.497 6.167 3.411 7.707 0.075-1.348-2.706-5.814-2.438-7.151 1.465 1.434 2.855 2.825 4.234 4.408-0.919-1.519-1.999-2.931-3.239-4.236-0.62-0.653-1.24-1.305-1.7-2.065-0.8443-1.476-0.6511-3.551 0.825-4.395 0.161-0.107 0.321-0.214 0.513-0.203 0.985-0.331 2.097-0.192 3.134-0.095 3.027 0.439 5.893 0.986 8.908 1.618 2.214 0.471 4.385 1.017 6.288 2.205 0.15 0.086 0.257 0.246 0.171 0.396 0.599-0.353 1.241-0.085 1.797 0.332 0.598 0.342 1.111 0.835 1.667 1.252 0.482 0.374 0.963 0.749 1.444 1.123 2.256 1.787 4.469 3.649 6.479 5.692-0.78-1.241-1.796-2.418-3.058-3.338-0.887-0.706-1.86-1.262-2.63-2.001-0.844-0.781-1.368-1.775-2.213-2.556-0.406-0.332-0.887-0.707-1.251-1.113 1.123-0.053 2.203-0.031 3.326-0.084-0.802-0.161-1.604-0.322-2.406-0.483-0.994-0.171-1.946-0.417-2.898-0.664-2.352-0.749-4.544-2.301-6.993-2.708-0.193-0.011-0.385-0.021-0.578-0.032 0.107 0.16 0.257 0.246 0.364 0.406-0.118 0.033-0.268-0.053-0.385-0.021-2.161-0.044-4.374-0.515-6.427-1.093-1.829-0.45-3.807-0.985-5.005-2.365-0.363-0.407-0.684-0.888-1.047-1.295-0.364-0.406-1.0054-0.674-1.5508-0.589 0.2575-2.534 1.0086-5.312-0.4558-7.441-1.1438-1.647-0.6523-3.686-2.1639-4.048 0.5862 0.632 0.9484-0.88 0.3852-2.121-0.5632-1.242-11.812-19.078-21.406-19.814-1.5082 0.7267-2.7386 2.0097-3.3594 3.4425-0.0428 0.0749-0.0428 0.0749-0.0856 0.1497-0.951-2.3317-1.9341-4.7812-3.2381-7.0168-0.4275-0.6418-0.8123-1.3585-1.4431-1.8186-1.2832-0.5352-2.898-0.6641-4.438-0.7501z" clip-path="url(#clipPath4310)" fill="#5c5a5a" style=""/> <path d="m96.836 106.97c-0.1607 0.802-0.3972 1.217-0.1729 2.041 0.4486 1.647 1.0572 2.066 1.7411 3.649 0.6732 1.776 0.6698 2.683 0.7546 4.619 0.0211 1.005-0.0327 1.968-0.1614 2.887 0.7808-0.149 1.8421 1.436 2.3871 2.046 0.545 0.609 1.005 1.369 1.722 1.679 0.791 0.353 1.646 0.247 2.491 0.333 0.92 0.128 1.786 0.524 2.695 0.845 1.861 0.568 3.797 0.483 5.7 0.28-0.075-0.042-0.075-0.042-0.149-0.085-2.161-0.044-4.374-0.515-6.428-1.093-1.828-0.45-3.807-0.985-5.004-2.365-0.363-0.407-0.684-0.888-1.048-1.295-0.363-0.406-1.328-1.638-1.8737-1.553 0.2575-2.534 0.8497-4.297-0.615-6.426-1.1437-1.647-0.9919-2.182-1.5794-4.108-0.2138-0.321-0.374-0.909-0.4594-1.454z" clip-path="url(#clipPath4304)" fill="#8b8b8b" style=""/> <path d="m87.799 115.57c0.1069 0.161 0.1818 0.204 0.2887 0.364 0.0748 0.043 0.1069 0.161 0.2566 0.246l0.0748 0.043c0.5667 0.225 1.1335 0.449 1.6895 0.867 0.4491 0.257 0.9302 0.631 1.3365 0.963 1.7748 1.412 3.2928 3.273 5.3993 4.279 0.2997-0.523 0.5993-1.047 0.7064-1.582-0.0535 0.267-0.182 0.492-0.3852 0.674-0.0428 0.074-0.1605 0.106-0.2781 0.138-0.1177 0.033-0.1497-0.085-0.2246-0.128-2.6835-2.429-5.3135-5.125-8.8639-5.864z" clip-path="url(#clipPath4298)" fill="#8b8b8b" style=""/>