add lisp packages

This commit is contained in:
2020-12-05 21:29:49 +01:00
parent 85e20365ae
commit a6e2395755
7272 changed files with 1363243 additions and 0 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,45 @@
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icon-css-br" width="512" height="512">
<g stroke-width="1pt">
<path fill="#229e45" fill-rule="evenodd" d="M0 0h512v512H0z"/>
<path fill="#f8e509" fill-rule="evenodd" d="M261.358 405.394L491.23 256.2 259.967 106.605 29.34 256.56l232.018 148.834z"/>
<path fill="#2b49a3" fill-rule="evenodd" d="M361.52 256.004c0 53.622-43.54 97.093-97.25 97.093s-97.248-43.47-97.248-97.093 43.54-97.093 97.25-97.093 97.248 43.47 97.248 97.094z"/>
<path fill="#ffffef" fill-rule="evenodd" d="M232.302 314.156l-3.004-1.734-3.12 1.544.698-3.468-2.41-2.542 3.446-.403 1.62-3.11 1.443 3.216 3.4.617-2.55 2.387m65.648 19.995l-3.005-1.734-3.12 1.544.698-3.468-2.41-2.54 3.446-.405 1.62-3.11 1.443 3.217 3.4.617-2.55 2.387m-27.613-22.869l-2.595-1.498-2.696 1.333.604-2.996-2.082-2.196 2.978-.348 1.398-2.687 1.248 2.78 2.937.533-2.203 2.062m66.231-6.462l-2.55-1.47-2.646 1.31.593-2.943-2.046-2.156 2.924-.343 1.373-2.638 1.226 2.728 2.884.523-2.163 2.026m-66.604-16.77l-3.005-1.734-3.12 1.545.698-3.468-2.41-2.542 3.447-.404 1.618-3.11 1.445 3.218 3.4.618-2.55 2.387M187.95 244.96l-3.005-1.735-3.12 1.544.698-3.47-2.41-2.54 3.447-.404 1.618-3.11 1.444 3.216 3.4.618-2.55 2.387m10.128 43.568l-3.005-1.734-3.12 1.544.698-3.468-2.41-2.542 3.447-.403 1.618-3.11 1.444 3.218 3.4.617-2.55 2.387m100.612-51.337l-2.654-1.53-2.757 1.363.617-3.065-2.13-2.245 3.046-.357 1.43-2.748 1.275 2.843 3.005.545-2.253 2.11m-5.083 29.158l-2.09-1.208-2.17 1.074.485-2.412-1.677-1.77 2.398-.28 1.126-2.164 1.005 2.24 2.366.428-1.775 1.66m-108.421 38.448l-2.006-1.158-2.083 1.03.467-2.314-1.61-1.697 2.302-.27 1.08-2.077.964 2.148 2.27.413-1.702 1.595m152.599 11.561l-1.634-.866-1.698.772.38-1.732-1.31-1.27 1.874-.2.88-1.555.786 1.607 1.85.31-1.387 1.19"/>
<path fill="#ffffef" fill-rule="evenodd" d="M183.477 292.296l-2.006-1.158-2.083 1.03.467-2.314-1.61-1.697 2.302-.27 1.08-2.077.964 2.148 2.27.413-1.702 1.595"/>
<path fill="#ffffef" fill-rule="evenodd" d="M183.477 292.296l-2.006-1.158-2.083 1.03.467-2.314-1.61-1.697 2.302-.27 1.08-2.077.964 2.148 2.27.413-1.702 1.595m32.251 2.322l-2.007-1.157-2.083 1.03.466-2.314-1.61-1.697 2.302-.27 1.08-2.077.965 2.148 2.27.413-1.703 1.594m-3.65 12.952l-2.004-1.157-2.084 1.03.466-2.314-1.61-1.698 2.302-.27 1.08-2.077.965 2.148 2.27.413-1.702 1.594m66.625-17.006l-2.006-1.157-2.083 1.03.465-2.315-1.61-1.696 2.302-.27 1.08-2.076.965 2.148 2.27.412-1.703 1.594m-19.138 2.323l-2.005-1.158-2.083 1.03.466-2.314-1.61-1.697 2.302-.27 1.08-2.077.965 2.15 2.27.41-1.703 1.595m-52.457-4.452l-1.257-.726-1.305.646.292-1.45-1.008-1.064 1.442-.17.676-1.3.604 1.345 1.423.258-1.067 1m127.97 34.606l-2.005-1.158-2.084 1.03.466-2.315-1.61-1.697 2.302-.27 1.08-2.076.965 2.148 2.27.413-1.703 1.593m-15.883 4.454l-1.662-.96-1.724.855.386-1.923-1.333-1.41 1.905-.223.895-1.725.8 1.783 1.88.343-1.41 1.324m7.907 1.752l-1.548-.894-1.608.796.36-1.788-1.242-1.31 1.775-.21.834-1.603.743 1.66 1.75.318-1.312 1.23m22.197-17.353l-1.49-.86-1.55.766.347-1.72-1.196-1.262 1.71-.2.804-1.543.717 1.596 1.687.305-1.265 1.185m-29.55 31.881l-1.946-1.063-2.022.947.453-2.126-1.562-1.557 2.233-.246 1.05-1.906.935 1.97 2.204.38-1.653 1.462m.418 10.861l-1.775-1.062-1.844.946.414-2.125-1.425-1.557 2.036-.247.957-1.906.853 1.97 2.01.38-1.508 1.463m-14.432-17.581l-1.49-.86-1.55.765.347-1.72-1.195-1.26 1.71-.202.803-1.543.717 1.596 1.687.306-1.265 1.184m-13.56 1.734l-1.49-.86-1.547.765.346-1.72-1.197-1.26 1.71-.202.803-1.543.717 1.596 1.687.306-1.265 1.184M265.07 291.38l-1.492-.86-1.548.766.347-1.72-1.196-1.26 1.71-.2.804-1.545.716 1.598 1.687.306-1.265 1.184m2.847 43.477l-1.264-.73-1.31.65.293-1.457-1.014-1.07 1.448-.17.68-1.306.607 1.352 1.43.26-1.072 1.002m-35.176-66.052l-3.004-1.734-3.12 1.545.698-3.468-2.41-2.542 3.446-.404 1.62-3.11 1.443 3.218 3.4.618-2.55 2.387"/>
<path fill="#fff" fill-rule="evenodd" d="M355.113 290.934c1.482-3.876 3.394-9.72 4.41-15.086-51.653-45.375-109.233-68.618-181.99-63.836-2.607 5-4.695 10.236-6.456 15.9 86.207-8.223 149.396 29.943 184.038 63.022z"/>
<path fill="#309e3a" d="M331.893 265.425l1.845 1.008c-.29.654-.367 1.226-.236 1.714.137.493.476.922 1.017 1.288.573.392 1.086.564 1.537.518.457-.046.797-.233 1.018-.56.14-.21.196-.43.17-.658-.02-.23-.146-.503-.377-.82-.16-.213-.548-.665-1.165-1.354-.794-.884-1.267-1.63-1.42-2.24-.212-.854-.083-1.63.39-2.332.304-.45.713-.786 1.228-1.005.524-.22 1.095-.27 1.71-.15.618.12 1.268.41 1.944.87 1.107.753 1.776 1.562 2.004 2.427.233.87.09 1.72-.43 2.55l-1.833-1.13c.23-.507.286-.944.166-1.313-.11-.37-.418-.725-.92-1.066-.517-.35-.994-.518-1.43-.504a.776.776 0 0 0-.654.357.833.833 0 0 0-.098.718c.098.343.51.91 1.24 1.704.726.793 1.222 1.44 1.486 1.943.27.5.393 1.02.367 1.562-.017.538-.216 1.087-.592 1.647a3.133 3.133 0 0 1-1.38 1.138c-.58.252-1.2.314-1.86.182-.657-.134-1.368-.462-2.133-.983-1.115-.756-1.8-1.596-2.05-2.517-.245-.924-.094-1.923.458-2.992zm-8.753-5.745l1.886.93c-.263.665-.318 1.24-.167 1.723.157.486.51.903 1.066 1.247.59.368 1.108.52 1.557.455.457-.066.79-.264.995-.6a.957.957 0 0 0 .146-.664c-.03-.228-.167-.497-.412-.805-.167-.207-.572-.64-1.218-1.306-.828-.853-1.33-1.58-1.508-2.18-.246-.848-.148-1.63.293-2.348a2.767 2.767 0 0 1 1.188-1.053c.515-.24 1.083-.316 1.702-.222.623.097 1.284.36 1.978.794 1.138.705 1.837 1.487 2.1 2.343.267.86.16 1.713-.326 2.566l-1.88-1.056c.21-.514.25-.954.115-1.317-.128-.366-.45-.708-.963-1.028-.532-.332-1.015-.48-1.45-.448a.773.773 0 0 0-.638.384c-.132.215-.156.453-.07.72.112.338.546.888 1.306 1.653.757.76 1.28 1.388 1.563 1.878.29.49.434 1.005.43 1.546.005.54-.173 1.096-.525 1.672-.322.52-.77.917-1.336 1.193-.568.275-1.186.36-1.85.256-.66-.108-1.384-.41-2.17-.897-1.144-.713-1.86-1.523-2.148-2.434-.285-.914-.174-1.916.335-3.006zm-10.83-2.903l5.547-9.123 6.738 4.13-.94 1.544-4.9-3.006-1.232 2.022 4.562 2.797-.935 1.537-4.562-2.795-1.51 2.483 5.077 3.11-.936 1.54-6.91-4.238zm-15.778-12.957l.823-1.6 4.118 2.13-1.94 3.785c-.603.182-1.36.225-2.275.13-.907-.1-1.75-.35-2.53-.753-.99-.512-1.746-1.163-2.268-1.96-.52-.8-.77-1.68-.743-2.647.03-.97.277-1.91.745-2.822.507-.99 1.167-1.76 1.976-2.317.805-.555 1.714-.83 2.72-.83.77-.004 1.605.232 2.51.696 1.175.61 1.965 1.332 2.366 2.17.41.836.486 1.738.227 2.71l-2.08-.626a2.226 2.226 0 0 0-.19-1.492c-.225-.462-.614-.835-1.163-1.12-.837-.433-1.637-.51-2.406-.233-.762.278-1.41.938-1.947 1.984-.58 1.128-.766 2.104-.557 2.93.212.817.72 1.437 1.532 1.857.4.207.84.336 1.32.387.486.05.93.037 1.335-.038l.62-1.207-2.19-1.132zm-68.807-17.062l1.55-10.574 3.182.47.856 7.494 2.944-6.933 3.192.47-1.55 10.576-1.976-.29 1.222-8.325-3.312 8.015-2.047-.303-.865-8.632-1.22 8.323-1.977-.29zm-10.757-1.25l.995-10.644 7.86.743-.166 1.8-5.72-.54-.223 2.36 5.32.502-.166 1.793-5.322-.502-.27 2.897 5.92.557-.166 1.795-8.062-.76z"/>
<g stroke-opacity=".502">
<path fill="#309e3a" d="M181.37 218.85c.03-1.087.216-1.997.56-2.726.257-.538.6-1.017 1.027-1.438.432-.42.9-.73 1.407-.924.67-.263 1.44-.384 2.304-.36 1.57.043 2.81.565 3.72 1.567.92 1.002 1.354 2.373 1.307 4.112-.047 1.724-.55 3.063-1.512 4.014-.96.946-2.222 1.398-3.784 1.355-1.585-.042-2.83-.56-3.737-1.552-.908-.998-1.34-2.347-1.292-4.047z"/>
<path fill="#f7ffff" d="M183.592 218.83c-.033 1.21.22 2.137.76 2.778.54.638 1.238.968 2.095.99.856.025 1.567-.265 2.13-.866.568-.608.87-1.53.903-2.77.033-1.224-.21-2.145-.73-2.762-.518-.617-1.218-.937-2.104-.962-.885-.024-1.607.263-2.167.86-.56.593-.856 1.504-.888 2.733z"/>
</g>
<g stroke-opacity=".502">
<path fill="#309e3a" d="M193.99 224.365l.125-10.688 4.524.054c1.137.015 1.96.12 2.472.322.516.195.926.54 1.23 1.035s.452 1.057.445 1.69c-.01.8-.252 1.462-.728 1.98-.476.516-1.182.835-2.12.96.463.278.844.582 1.14.91.3.33.702.913 1.206 1.75l1.276 2.1-2.57-.03-1.528-2.344c-.54-.837-.914-1.364-1.114-1.58a1.607 1.607 0 0 0-.642-.453c-.226-.084-.586-.13-1.08-.135l-.435-.006-.053 4.46-2.15-.025z"/>
<path fill="#fff" d="M196.22 218.223l1.59.02c1.032.012 1.676-.025 1.934-.11.257-.084.46-.232.607-.444s.224-.48.23-.8c.003-.36-.09-.65-.282-.87-.186-.227-.453-.372-.8-.434-.175-.026-.7-.044-1.57-.055l-1.677-.018-.03 2.71z"/>
</g>
<g stroke-opacity=".502">
<path fill="#309e3a" d="M206.153 214.207l3.924.2c.885.045 1.555.147 2.012.307.613.216 1.132.57 1.552 1.065.422.492.73 1.086.93 1.783.196.692.27 1.537.22 2.536-.044.878-.192 1.63-.44 2.255-.307.764-.717 1.372-1.236 1.828-.39.345-.907.603-1.55.775-.482.127-1.12.17-1.913.13l-4.038-.206.538-10.675z"/>
<path fill="#fff" d="M208.213 216.11l-.356 7.072 1.603.08c.6.033 1.034.02 1.303-.034.352-.07.648-.204.886-.4.242-.198.447-.53.615-1 .17-.47.276-1.12.318-1.945s0-1.464-.122-1.913c-.122-.45-.308-.803-.557-1.065a2.043 2.043 0 0 0-.967-.552c-.297-.084-.883-.148-1.758-.192l-.965-.05z"/>
</g>
<g stroke-opacity=".502">
<path fill="#309e3a" d="M258.478 233.293l2.486-10.393 3.355.81c1.27.305 2.086.557 2.447.755.556.298.97.758 1.246 1.38.275.615.313 1.337.116 2.164-.153.637-.396 1.146-.732 1.525-.333.38-.71.65-1.128.816a3.08 3.08 0 0 1-1.198.23c-.522-.022-1.257-.147-2.203-.375l-1.363-.33-.938 3.922-2.092-.504z"/>
<path fill="#fff" d="M262.64 225.16l-.707 2.95 1.144.275c.825.198 1.388.277 1.69.234.306-.043.562-.16.773-.354.215-.193.36-.443.433-.75.09-.38.055-.717-.107-1.016-.164-.3-.407-.52-.73-.663-.24-.108-.734-.252-1.487-.434l-1.01-.244z"/>
</g>
<g stroke-opacity=".502">
<path fill="#309e3a" d="M268.373 236.257l3.538-10.08 4.27 1.51c1.072.38 1.82.746 2.238 1.1.426.353.703.81.833 1.378s.09 1.148-.12 1.743c-.264.757-.705 1.303-1.322 1.642-.615.334-1.386.41-2.312.226.348.412.61.82.785 1.228.182.41.375 1.092.585 2.046l.536 2.4-2.424-.857-.695-2.712c-.245-.967-.428-1.585-.55-1.856a1.623 1.623 0 0 0-.462-.635c-.187-.155-.513-.313-.98-.48l-.41-.144-1.477 4.21-2.027-.72z"/>
<path fill="#fff" d="M272.438 231.163l1.5.53c.973.344 1.593.518 1.864.52.27.003.51-.07.72-.225.207-.152.363-.38.47-.683.118-.34.123-.645.013-.915-.104-.274-.31-.496-.62-.668-.157-.08-.646-.267-1.468-.557l-1.582-.56-.897 2.558z"/>
</g>
<g stroke-opacity=".502">
<path fill="#309e3a" d="M280.88 235.87c.323-1.04.75-1.863 1.276-2.47.394-.45.85-.817 1.378-1.105a4.166 4.166 0 0 1 1.602-.507c.718-.072 1.49.022 2.317.28 1.498.47 2.55 1.31 3.157 2.524.612 1.214.66 2.653.144 4.314-.51 1.648-1.358 2.798-2.54 3.452-1.18.65-2.516.74-4.01.272-1.51-.472-2.57-1.31-3.174-2.512-.605-1.208-.654-2.623-.15-4.247z"/>
<path fill="#fff" d="M283.027 236.47c-.36 1.154-.366 2.114-.02 2.88.348.76.93 1.267 1.75 1.524.817.255 1.578.17 2.283-.256.712-.428 1.252-1.235 1.62-2.418.362-1.17.376-2.122.04-2.86-.328-.733-.917-1.233-1.762-1.497-.846-.265-1.618-.186-2.317.237-.697.418-1.228 1.214-1.593 2.39z"/>
</g>
<g stroke-opacity=".502">
<path fill="#309e3a" d="M301.692 250.754l4.89-9.494 4.02 2.087c1.01.526 1.7.992 2.067 1.402.37.406.584.9.634 1.48s-.07 1.147-.358 1.71c-.367.71-.88 1.192-1.538 1.44-.655.247-1.427.214-2.32-.096.288.456.49.9.61 1.326.12.43.22 1.132.295 2.107l.2 2.45-2.283-1.184-.316-2.782c-.11-.993-.206-1.63-.29-1.914a1.611 1.611 0 0 0-.37-.694c-.163-.178-.466-.38-.904-.61l-.387-.2-2.04 3.963-1.91-.99z"/>
<path fill="#fff" d="M306.418 246.26l1.412.733c.916.477 1.508.734 1.776.775.267.04.516 0 .743-.123.226-.123.41-.327.56-.613.164-.32.21-.62.138-.903-.065-.287-.24-.537-.522-.75-.144-.1-.603-.353-1.378-.755l-1.488-.774-1.242 2.41z"/>
</g>
<g stroke-opacity=".502">
<path fill="#309e3a" d="M341.19 270.26c.607-.9 1.25-1.567 1.933-1.996a5.027 5.027 0 0 1 1.636-.658 4.17 4.17 0 0 1 1.678-.02c.708.14 1.42.453 2.138.94 1.3.883 2.065 1.993 2.298 3.33.237 1.34-.13 2.73-1.103 4.172-.962 1.428-2.102 2.286-3.42 2.57-1.318.278-2.623-.022-3.92-.9-1.31-.892-2.083-2-2.317-3.327-.232-1.33.127-2.7 1.077-4.11z"/>
<path fill="#fff" d="M343.073 271.443c-.675 1.003-.958 1.92-.847 2.752.115.83.526 1.483 1.235 1.966.712.483 1.465.622 2.263.42.805-.206 1.553-.82 2.245-1.848.683-1.014.97-1.923.86-2.724-.104-.8-.523-1.447-1.257-1.946s-1.495-.647-2.285-.444c-.79.198-1.525.807-2.212 1.825z"/>
</g>
<path fill="#309e3a" d="M246.427 228.95l1.714-7.504 5.543 1.278-.288 1.267-4.032-.927-.384 1.663 3.754.866-.29 1.262-3.75-.863-.47 2.042 4.176.962-.288 1.265-5.685-1.31z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -0,0 +1,11 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="flag-icon-css-cn" width="512" height="512">
<defs>
<path id="a" fill="#ffde00" d="M.95-.31L-.587.81 0-1 .588.81-.952-.31z"/>
</defs>
<path fill="#de2910" d="M0 0h512v512H0z"/>
<use width="30" height="20" transform="matrix(76.8 0 0 76.8 128 128)" xlink:href="#a"/>
<use width="30" height="20" transform="matrix(-13.1584 -21.9392 21.9392 -13.1584 256 51.2)" xlink:href="#a"/>
<use width="30" height="20" transform="rotate(-98.106 198.016 -82.078) scale(25.6)" xlink:href="#a"/>
<use width="30" height="20" transform="matrix(7.04 -24.6272 24.6272 7.04 307.2 179.2)" xlink:href="#a"/>
<use width="30" height="20" transform="matrix(16 -19.968 19.968 16 256 230.4)" xlink:href="#a"/>
</svg>

After

Width:  |  Height:  |  Size: 792 B

View File

@@ -0,0 +1,12 @@
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icon-css-cz" width="512" height="512">
<defs>
<clipPath id="a">
<path fill-opacity=".67" d="M102.42 0h708.66v708.66H102.42z"/>
</clipPath>
</defs>
<g fill-rule="evenodd" stroke-width="1pt" clip-path="url(#a)" transform="translate(-74) scale(.722)">
<path fill="#e80000" d="M0 0h1063v708.66H0z"/>
<path fill="#fff" d="M0 0h1063v354.33H0z"/>
<path fill="#00006f" d="M0 0l529.732 353.88L0 707.3V0z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 493 B

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icon-css-de" width="512" height="512">
<path fill="#ffce00" d="M0 341.338h512.005v170.67H0z"/>
<path d="M0 0h512.005v170.67H0z"/>
<path fill="#d00" d="M0 170.67h512.005v170.668H0z"/>
</svg>

After

Width:  |  Height:  |  Size: 245 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 144 KiB

View File

@@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icon-css-fr" width="512" height="512">
<g fill-rule="evenodd" stroke-width="1pt">
<path fill="#fff" d="M0 0h512.005v512H0z"/>
<path fill="#00267f" d="M0 0h170.667v512H0z"/>
<path fill="#f31830" d="M341.333 0H512v512H341.333z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 305 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icon-css-id" width="512" height="512">
<g fill-rule="evenodd" stroke-width="1pt">
<path fill="#e70011" d="M0 0h511.966v265.543H0z"/>
<path fill="#fff" d="M0 256h511.966v256H0z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 252 B

View File

@@ -0,0 +1,219 @@
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icon-css-ir" width="512" height="512">
<defs>
<clipPath id="a">
<path fill-opacity=".67" d="M185.98 0h496.06v496.06H185.98z"/>
</clipPath>
</defs>
<g fill-rule="evenodd" clip-path="url(#a)" transform="translate(-191.96) scale(1.0321)">
<path fill="#fff" d="M0 0h868.11v496.06H0z"/>
<path fill="#da0000" d="M0 333.13h868.11v162.93H0z"/>
<g fill="#fff" stroke-width="1pt">
<path d="M165.025 340.035h47.543v3.271h-47.543zm7.089 16.358h3.271v3.177h-3.271zm40.577-.103v3.271h-9.5v-3.271zm5.111-16.255h3.272v19.532h-3.272z"/>
<path d="M236.728 356.29v3.271h-18.006v-3.271zm-33.538-7.642h3.272v10.92h-3.272z"/>
<path d="M234.05 340.035h3.272v19.532h-3.272zm-8.18 0h3.273v19.532h-3.272zm-43.404 7.774v3.271h-17.352v-3.271zm38.076 0v3.271H203.19v-3.271z"/>
<path d="M203.19 348.648h3.272v10.92h-3.272z"/>
<path d="M203.19 348.648h3.272v10.92h-3.272z"/>
<path d="M203.19 348.648h3.272v10.92h-3.272zm-38.076 0h3.271v10.92h-3.271zm27.909 0h3.272v10.92h-3.272zm-13.827 0h3.272v10.92h-3.272z"/>
<path d="M195.319 356.29v3.271H180.65v-3.271zm.976-8.481v3.271h-9.3v-3.271z"/>
</g>
<g fill="#fff" stroke-width="1pt">
<path d="M86.94 340.035h47.543v3.271H86.94zm7.089 16.358H97.3v3.177h-3.27zm40.577-.103v3.271h-9.5v-3.271zm5.111-16.255h3.272v19.532h-3.272z"/>
<path d="M158.643 356.29v3.271h-18.006v-3.271zm-33.538-7.642h3.272v10.92h-3.272z"/>
<path d="M155.965 340.035h3.272v19.532h-3.272zm-8.179 0h3.272v19.532h-3.272zm-43.405 7.774v3.271H87.03v-3.271zm38.076 0v3.271h-17.352v-3.271z"/>
<path d="M125.105 348.648h3.272v10.92h-3.272z"/>
<path d="M125.105 348.648h3.272v10.92h-3.272z"/>
<path d="M125.105 348.648h3.272v10.92h-3.272zm-38.076 0H90.3v10.92h-3.27zm27.909 0h3.272v10.92h-3.272zm-13.828 0h3.273v10.92h-3.272z"/>
<path d="M117.234 356.29v3.271h-14.668v-3.271zm.976-8.481v3.271h-9.3v-3.271z"/>
</g>
<g fill="#fff" stroke-width="1pt">
<path d="M242.465 340.035h47.543v3.271h-47.543zm7.089 16.358h3.271v3.177h-3.271zm40.577-.103v3.271h-9.5v-3.271zm5.111-16.255h3.272v19.532h-3.272z"/>
<path d="M314.168 356.29v3.271h-18.006v-3.271zm-33.538-7.642h3.272v10.92h-3.272z"/>
<path d="M311.49 340.035h3.272v19.532h-3.272zm-8.18 0h3.273v19.532h-3.272zm-43.404 7.774v3.271h-17.352v-3.271zm38.076 0v3.271H280.63v-3.271z"/>
<path d="M280.63 348.648h3.272v10.92h-3.272z"/>
<path d="M280.63 348.648h3.272v10.92h-3.272z"/>
<path d="M280.63 348.648h3.272v10.92h-3.272zm-38.076 0h3.271v10.92h-3.271zm27.909 0h3.272v10.92h-3.272zm-13.827 0h3.272v10.92h-3.272z"/>
<path d="M272.759 356.29v3.271H258.09v-3.271zm.976-8.481v3.271h-9.3v-3.271z"/>
</g>
<g fill="#fff" stroke-width="1pt">
<path d="M789.275 340.035h47.543v3.271h-47.543zm7.089 16.358h3.271v3.177h-3.271zm40.577-.103v3.271h-9.5v-3.271zm5.111-16.255h3.272v19.532h-3.272z"/>
<path d="M860.978 356.29v3.271h-18.006v-3.271zm-33.538-7.642h3.272v10.92h-3.272z"/>
<path d="M858.3 340.035h3.272v19.532H858.3zm-8.18 0h3.273v19.532h-3.272zm-43.404 7.774v3.271h-17.352v-3.271zm38.076 0v3.271H827.44v-3.271z"/>
<path d="M827.44 348.648h3.272v10.92h-3.272z"/>
<path d="M827.44 348.648h3.272v10.92h-3.272z"/>
<path d="M827.44 348.648h3.272v10.92h-3.272zm-38.076 0h3.271v10.92h-3.271zm27.909 0h3.272v10.92h-3.272zm-13.827 0h3.272v10.92h-3.272z"/>
<path d="M819.569 356.29v3.271H804.9v-3.271zm.976-8.481v3.271h-9.3v-3.271z"/>
</g>
<g fill="#fff" stroke-width="1pt">
<path d="M320.405 340.035h47.543v3.271h-47.543zm7.089 16.358h3.271v3.177h-3.271zm40.577-.103v3.271h-9.5v-3.271zm5.111-16.255h3.272v19.532h-3.272z"/>
<path d="M392.108 356.29v3.271h-18.006v-3.271zm-33.538-7.642h3.272v10.92h-3.272z"/>
<path d="M389.43 340.035h3.272v19.532h-3.272zm-8.18 0h3.273v19.532h-3.272zm-43.404 7.774v3.271h-17.352v-3.271zm38.076 0v3.271H358.57v-3.271z"/>
<path d="M358.57 348.648h3.272v10.92h-3.272z"/>
<path d="M358.57 348.648h3.272v10.92h-3.272z"/>
<path d="M358.57 348.648h3.272v10.92h-3.272zm-38.076 0h3.271v10.92h-3.271zm27.909 0h3.272v10.92h-3.272zm-13.827 0h3.272v10.92h-3.272z"/>
<path d="M350.699 356.29v3.271H336.03v-3.271zm.976-8.481v3.271h-9.3v-3.271z"/>
</g>
<g fill="#fff" stroke-width="1pt">
<path d="M398.625 340.035h47.543v3.271h-47.543zm7.089 16.358h3.271v3.177h-3.271zm40.577-.103v3.271h-9.5v-3.271zm5.111-16.255h3.272v19.532h-3.272z"/>
<path d="M470.328 356.29v3.271h-18.006v-3.271zm-33.538-7.642h3.272v10.92h-3.272z"/>
<path d="M467.65 340.035h3.272v19.532h-3.272zm-8.18 0h3.273v19.532h-3.272zm-43.404 7.774v3.271h-17.352v-3.271zm38.076 0v3.271H436.79v-3.271z"/>
<path d="M436.79 348.648h3.272v10.92h-3.272z"/>
<path d="M436.79 348.648h3.272v10.92h-3.272z"/>
<path d="M436.79 348.648h3.272v10.92h-3.272zm-38.076 0h3.271v10.92h-3.271zm27.909 0h3.272v10.92h-3.272zm-13.827 0h3.272v10.92h-3.272z"/>
<path d="M428.919 356.29v3.271H414.25v-3.271zm.976-8.481v3.271h-9.3v-3.271z"/>
</g>
<path fill="#239f40" d="M0 0h868.11v162.93H0z"/>
<g fill="#fff" stroke-width="1pt">
<path d="M477.305 340.035h47.543v3.271h-47.543zm7.089 16.358h3.271v3.177h-3.271zm40.577-.103v3.271h-9.5v-3.271zm5.111-16.255h3.272v19.532h-3.272z"/>
<path d="M549.008 356.29v3.271h-18.006v-3.271zm-33.538-7.642h3.272v10.92h-3.272z"/>
<path d="M546.33 340.035h3.272v19.532h-3.272zm-8.18 0h3.273v19.532h-3.272zm-43.404 7.774v3.271h-17.352v-3.271zm38.076 0v3.271H515.47v-3.271z"/>
<path d="M515.47 348.648h3.272v10.92h-3.272z"/>
<path d="M515.47 348.648h3.272v10.92h-3.272z"/>
<path d="M515.47 348.648h3.272v10.92h-3.272zm-38.076 0h3.271v10.92h-3.271zm27.909 0h3.272v10.92h-3.272zm-13.827 0h3.272v10.92h-3.272z"/>
<path d="M507.599 356.29v3.271H492.93v-3.271zm.976-8.481v3.271h-9.3v-3.271z"/>
</g>
<g fill="#fff" stroke-width="1pt">
<path d="M555.535 340.035h47.543v3.271h-47.543zm7.089 16.358h3.271v3.177h-3.271zm40.577-.103v3.271h-9.5v-3.271zm5.111-16.255h3.272v19.532h-3.272z"/>
<path d="M627.238 356.29v3.271h-18.006v-3.271zm-33.538-7.642h3.272v10.92H593.7z"/>
<path d="M624.56 340.035h3.272v19.532h-3.272zm-8.18 0h3.273v19.532h-3.272zm-43.404 7.774v3.271h-17.352v-3.271zm38.076 0v3.271H593.7v-3.271z"/>
<path d="M593.7 348.648h3.272v10.92H593.7z"/>
<path d="M593.7 348.648h3.272v10.92H593.7z"/>
<path d="M593.7 348.648h3.272v10.92H593.7zm-38.076 0h3.271v10.92h-3.271zm27.909 0h3.272v10.92h-3.272zm-13.827 0h3.272v10.92h-3.272z"/>
<path d="M585.829 356.29v3.271H571.16v-3.271zm.976-8.481v3.271h-9.3v-3.271z"/>
</g>
<g fill="#fff" stroke-width="1pt">
<path d="M633.755 340.035h47.543v3.271h-47.543zm7.089 16.358h3.271v3.177h-3.271zm40.577-.103v3.271h-9.5v-3.271zm5.111-16.255h3.272v19.532h-3.272z"/>
<path d="M705.458 356.29v3.271h-18.006v-3.271zm-33.538-7.642h3.272v10.92h-3.272z"/>
<path d="M702.78 340.035h3.272v19.532h-3.272zm-8.18 0h3.273v19.532H694.6zm-43.404 7.774v3.271h-17.352v-3.271zm38.076 0v3.271H671.92v-3.271z"/>
<path d="M671.92 348.648h3.272v10.92h-3.272z"/>
<path d="M671.92 348.648h3.272v10.92h-3.272z"/>
<path d="M671.92 348.648h3.272v10.92h-3.272zm-38.076 0h3.271v10.92h-3.271zm27.909 0h3.272v10.92h-3.272zm-13.827 0h3.272v10.92h-3.272z"/>
<path d="M664.049 356.29v3.271H649.38v-3.271zm.976-8.481v3.271h-9.3v-3.271z"/>
</g>
<g fill="#fff" stroke-width="1pt">
<path d="M712.435 340.035h47.543v3.271h-47.543zm7.089 16.358h3.271v3.177h-3.271zm40.577-.103v3.271h-9.5v-3.271zm5.111-16.255h3.272v19.532h-3.272z"/>
<path d="M784.138 356.29v3.271h-18.006v-3.271zm-33.538-7.642h3.272v10.92H750.6z"/>
<path d="M781.46 340.035h3.272v19.532h-3.272zm-8.18 0h3.273v19.532h-3.272zm-43.404 7.774v3.271h-17.352v-3.271zm38.076 0v3.271H750.6v-3.271z"/>
<path d="M750.6 348.648h3.272v10.92H750.6z"/>
<path d="M750.6 348.648h3.272v10.92H750.6z"/>
<path d="M750.6 348.648h3.272v10.92H750.6zm-38.076 0h3.271v10.92h-3.271zm27.909 0h3.272v10.92h-3.272zm-13.827 0h3.272v10.92h-3.272z"/>
<path d="M742.729 356.29v3.271H728.06v-3.271zm.976-8.481v3.271h-9.3v-3.271z"/>
</g>
<g fill="#fff" stroke-width="1pt">
<path d="M7.92 340.035h47.542v3.271H7.919zm7.088 16.358h3.271v3.177h-3.271zm40.577-.103v3.271h-9.5v-3.271zm5.111-16.255h3.272v19.532h-3.272z"/>
<path d="M79.622 356.29v3.271H61.616v-3.271zm-33.538-7.642h3.272v10.92h-3.272z"/>
<path d="M76.944 340.035h3.272v19.532h-3.272zm-8.179 0h3.272v19.532h-3.272zm-43.405 7.774v3.271H8.008v-3.271zm38.076 0v3.271H46.084v-3.271z"/>
<path d="M46.084 348.648h3.272v10.92h-3.272z"/>
<path d="M46.084 348.648h3.272v10.92h-3.272z"/>
<path d="M46.084 348.648h3.272v10.92h-3.272zm-38.076 0h3.271v10.92H8.008zm27.909 0h3.272v10.92h-3.272zm-13.827 0h3.272v10.92H22.09z"/>
<path d="M38.213 356.29v3.271H23.545v-3.271zm.976-8.481v3.271h-9.3v-3.271z"/>
</g>
<g fill="#fff" stroke-width="1pt">
<path d="M165.025 138.975h47.543v3.271h-47.543zm7.089 16.358h3.271v3.177h-3.271zm40.577-.103v3.271h-9.5v-3.271zm5.111-16.255h3.272v19.532h-3.272z"/>
<path d="M236.728 155.23v3.271h-18.006v-3.271zm-33.538-7.642h3.272v10.92h-3.272z"/>
<path d="M234.05 138.975h3.272v19.532h-3.272zm-8.18 0h3.273v19.532h-3.272zm-43.404 7.774v3.271h-17.352v-3.271zm38.076 0v3.271H203.19v-3.271z"/>
<path d="M203.19 147.588h3.272v10.92h-3.272z"/>
<path d="M203.19 147.588h3.272v10.92h-3.272z"/>
<path d="M203.19 147.588h3.272v10.92h-3.272zm-38.076 0h3.271v10.92h-3.271zm27.909 0h3.272v10.92h-3.272zm-13.827 0h3.272v10.92h-3.272z"/>
<path d="M195.319 155.23v3.271H180.65v-3.271zm.976-8.481v3.271h-9.3v-3.271z"/>
</g>
<g fill="#fff" stroke-width="1pt">
<path d="M86.94 138.975h47.543v3.271H86.94zm7.089 16.358H97.3v3.177h-3.27zm40.577-.103v3.271h-9.5v-3.271zm5.111-16.255h3.272v19.532h-3.272z"/>
<path d="M158.643 155.23v3.271h-18.006v-3.271zm-33.538-7.642h3.272v10.92h-3.272z"/>
<path d="M155.965 138.975h3.272v19.532h-3.272zm-8.179 0h3.272v19.532h-3.272zm-43.405 7.774v3.271H87.03v-3.271zm38.076 0v3.271h-17.352v-3.271z"/>
<path d="M125.105 147.588h3.272v10.92h-3.272z"/>
<path d="M125.105 147.588h3.272v10.92h-3.272z"/>
<path d="M125.105 147.588h3.272v10.92h-3.272zm-38.076 0H90.3v10.92h-3.27zm27.909 0h3.272v10.92h-3.272zm-13.828 0h3.273v10.92h-3.272z"/>
<path d="M117.234 155.23v3.271h-14.668v-3.271zm.976-8.481v3.271h-9.3v-3.271z"/>
</g>
<g fill="#fff" stroke-width="1pt">
<path d="M242.465 138.975h47.543v3.271h-47.543zm7.089 16.358h3.271v3.177h-3.271zm40.577-.103v3.271h-9.5v-3.271zm5.111-16.255h3.272v19.532h-3.272z"/>
<path d="M314.168 155.23v3.271h-18.006v-3.271zm-33.538-7.642h3.272v10.92h-3.272z"/>
<path d="M311.49 138.975h3.272v19.532h-3.272zm-8.18 0h3.273v19.532h-3.272zm-43.404 7.774v3.271h-17.352v-3.271zm38.076 0v3.271H280.63v-3.271z"/>
<path d="M280.63 147.588h3.272v10.92h-3.272z"/>
<path d="M280.63 147.588h3.272v10.92h-3.272z"/>
<path d="M280.63 147.588h3.272v10.92h-3.272zm-38.076 0h3.271v10.92h-3.271zm27.909 0h3.272v10.92h-3.272zm-13.827 0h3.272v10.92h-3.272z"/>
<path d="M272.759 155.23v3.271H258.09v-3.271zm.976-8.481v3.271h-9.3v-3.271z"/>
</g>
<g fill="#fff" stroke-width="1pt">
<path d="M789.275 138.975h47.543v3.271h-47.543zm7.089 16.358h3.271v3.177h-3.271zm40.577-.103v3.271h-9.5v-3.271zm5.111-16.255h3.272v19.532h-3.272z"/>
<path d="M860.978 155.23v3.271h-18.006v-3.271zm-33.538-7.642h3.272v10.92h-3.272z"/>
<path d="M858.3 138.975h3.272v19.532H858.3zm-8.18 0h3.273v19.532h-3.272zm-43.404 7.774v3.271h-17.352v-3.271zm38.076 0v3.271H827.44v-3.271z"/>
<path d="M827.44 147.588h3.272v10.92h-3.272z"/>
<path d="M827.44 147.588h3.272v10.92h-3.272z"/>
<path d="M827.44 147.588h3.272v10.92h-3.272zm-38.076 0h3.271v10.92h-3.271zm27.909 0h3.272v10.92h-3.272zm-13.827 0h3.272v10.92h-3.272z"/>
<path d="M819.569 155.23v3.271H804.9v-3.271zm.976-8.481v3.271h-9.3v-3.271z"/>
</g>
<g fill="#fff" stroke-width="1pt">
<path d="M320.405 138.975h47.543v3.271h-47.543zm7.089 16.358h3.271v3.177h-3.271zm40.577-.103v3.271h-9.5v-3.271zm5.111-16.255h3.272v19.532h-3.272z"/>
<path d="M392.108 155.23v3.271h-18.006v-3.271zm-33.538-7.642h3.272v10.92h-3.272z"/>
<path d="M389.43 138.975h3.272v19.532h-3.272zm-8.18 0h3.273v19.532h-3.272zm-43.404 7.774v3.271h-17.352v-3.271zm38.076 0v3.271H358.57v-3.271z"/>
<path d="M358.57 147.588h3.272v10.92h-3.272z"/>
<path d="M358.57 147.588h3.272v10.92h-3.272z"/>
<path d="M358.57 147.588h3.272v10.92h-3.272zm-38.076 0h3.271v10.92h-3.271zm27.909 0h3.272v10.92h-3.272zm-13.827 0h3.272v10.92h-3.272z"/>
<path d="M350.699 155.23v3.271H336.03v-3.271zm.976-8.481v3.271h-9.3v-3.271z"/>
</g>
<g fill="#fff" stroke-width="1pt">
<path d="M398.625 138.975h47.543v3.271h-47.543zm7.089 16.358h3.271v3.177h-3.271zm40.577-.103v3.271h-9.5v-3.271zm5.111-16.255h3.272v19.532h-3.272z"/>
<path d="M470.328 155.23v3.271h-18.006v-3.271zm-33.538-7.642h3.272v10.92h-3.272z"/>
<path d="M467.65 138.975h3.272v19.532h-3.272zm-8.18 0h3.273v19.532h-3.272zm-43.404 7.774v3.271h-17.352v-3.271zm38.076 0v3.271H436.79v-3.271z"/>
<path d="M436.79 147.588h3.272v10.92h-3.272z"/>
<path d="M436.79 147.588h3.272v10.92h-3.272z"/>
<path d="M436.79 147.588h3.272v10.92h-3.272zm-38.076 0h3.271v10.92h-3.271zm27.909 0h3.272v10.92h-3.272zm-13.827 0h3.272v10.92h-3.272z"/>
<path d="M428.919 155.23v3.271H414.25v-3.271zm.976-8.481v3.271h-9.3v-3.271z"/>
</g>
<g fill="#fff" stroke-width="1pt">
<path d="M477.305 138.975h47.543v3.271h-47.543zm7.089 16.358h3.271v3.177h-3.271zm40.577-.103v3.271h-9.5v-3.271zm5.111-16.255h3.272v19.532h-3.272z"/>
<path d="M549.008 155.23v3.271h-18.006v-3.271zm-33.538-7.642h3.272v10.92h-3.272z"/>
<path d="M546.33 138.975h3.272v19.532h-3.272zm-8.18 0h3.273v19.532h-3.272zm-43.404 7.774v3.271h-17.352v-3.271zm38.076 0v3.271H515.47v-3.271z"/>
<path d="M515.47 147.588h3.272v10.92h-3.272z"/>
<path d="M515.47 147.588h3.272v10.92h-3.272z"/>
<path d="M515.47 147.588h3.272v10.92h-3.272zm-38.076 0h3.271v10.92h-3.271zm27.909 0h3.272v10.92h-3.272zm-13.827 0h3.272v10.92h-3.272z"/>
<path d="M507.599 155.23v3.271H492.93v-3.271zm.976-8.481v3.271h-9.3v-3.271z"/>
</g>
<g fill="#fff" stroke-width="1pt">
<path d="M555.535 138.975h47.543v3.271h-47.543zm7.089 16.358h3.271v3.177h-3.271zm40.577-.103v3.271h-9.5v-3.271zm5.111-16.255h3.272v19.532h-3.272z"/>
<path d="M627.238 155.23v3.271h-18.006v-3.271zm-33.538-7.642h3.272v10.92H593.7z"/>
<path d="M624.56 138.975h3.272v19.532h-3.272zm-8.18 0h3.273v19.532h-3.272zm-43.404 7.774v3.271h-17.352v-3.271zm38.076 0v3.271H593.7v-3.271z"/>
<path d="M593.7 147.588h3.272v10.92H593.7z"/>
<path d="M593.7 147.588h3.272v10.92H593.7z"/>
<path d="M593.7 147.588h3.272v10.92H593.7zm-38.076 0h3.271v10.92h-3.271zm27.909 0h3.272v10.92h-3.272zm-13.827 0h3.272v10.92h-3.272z"/>
<path d="M585.829 155.23v3.271H571.16v-3.271zm.976-8.481v3.271h-9.3v-3.271z"/>
</g>
<g fill="#fff" stroke-width="1pt">
<path d="M633.755 138.975h47.543v3.271h-47.543zm7.089 16.358h3.271v3.177h-3.271zm40.577-.103v3.271h-9.5v-3.271zm5.111-16.255h3.272v19.532h-3.272z"/>
<path d="M705.458 155.23v3.271h-18.006v-3.271zm-33.538-7.642h3.272v10.92h-3.272z"/>
<path d="M702.78 138.975h3.272v19.532h-3.272zm-8.18 0h3.273v19.532H694.6zm-43.404 7.774v3.271h-17.352v-3.271zm38.076 0v3.271H671.92v-3.271z"/>
<path d="M671.92 147.588h3.272v10.92h-3.272z"/>
<path d="M671.92 147.588h3.272v10.92h-3.272z"/>
<path d="M671.92 147.588h3.272v10.92h-3.272zm-38.076 0h3.271v10.92h-3.271zm27.909 0h3.272v10.92h-3.272zm-13.827 0h3.272v10.92h-3.272z"/>
<path d="M664.049 155.23v3.271H649.38v-3.271zm.976-8.481v3.271h-9.3v-3.271z"/>
</g>
<g fill="#fff" stroke-width="1pt">
<path d="M712.435 138.975h47.543v3.271h-47.543zm7.089 16.358h3.271v3.177h-3.271zm40.577-.103v3.271h-9.5v-3.271zm5.111-16.255h3.272v19.532h-3.272z"/>
<path d="M784.138 155.23v3.271h-18.006v-3.271zm-33.538-7.642h3.272v10.92H750.6z"/>
<path d="M781.46 138.975h3.272v19.532h-3.272zm-8.18 0h3.273v19.532h-3.272zm-43.404 7.774v3.271h-17.352v-3.271zm38.076 0v3.271H750.6v-3.271z"/>
<path d="M750.6 147.588h3.272v10.92H750.6z"/>
<path d="M750.6 147.588h3.272v10.92H750.6z"/>
<path d="M750.6 147.588h3.272v10.92H750.6zm-38.076 0h3.271v10.92h-3.271zm27.909 0h3.272v10.92h-3.272zm-13.827 0h3.272v10.92h-3.272z"/>
<path d="M742.729 155.23v3.271H728.06v-3.271zm.976-8.481v3.271h-9.3v-3.271z"/>
</g>
<g fill="#fff" stroke-width="1pt">
<path d="M7.92 138.975h47.542v3.271H7.919zm7.088 16.358h3.271v3.177h-3.271zm40.577-.103v3.271h-9.5v-3.271zm5.111-16.255h3.272v19.532h-3.272z"/>
<path d="M79.622 155.23v3.271H61.616v-3.271zm-33.538-7.642h3.272v10.92h-3.272z"/>
<path d="M76.944 138.975h3.272v19.532h-3.272zm-8.179 0h3.272v19.532h-3.272zm-43.405 7.774v3.271H8.008v-3.271zm38.076 0v3.271H46.084v-3.271z"/>
<path d="M46.084 147.588h3.272v10.92h-3.272z"/>
<path d="M46.084 147.588h3.272v10.92h-3.272z"/>
<path d="M46.084 147.588h3.272v10.92h-3.272zm-38.076 0h3.271v10.92H8.008zm27.909 0h3.272v10.92h-3.272zm-13.827 0h3.272v10.92H22.09z"/>
<path d="M38.213 155.23v3.271H23.545v-3.271zm.976-8.481v3.271h-9.3v-3.271z"/>
</g>
<path fill="#d90000" stroke-width="1pt" d="M119.3 328.94h5.86v10.178h-5.86zm155.54 0h5.86v10.178h-5.86zm-274.882 0h5.86v10.178h-5.86zm78.941 0h5.86v10.178h-5.86zm78.379 0h5.86v10.178h-5.86zm38.78 0h5.86v10.178h-5.86zm39.59 0h5.86v10.178h-5.86zm77.972 0h5.86v10.178h-5.86zm196.74 0h5.86v10.178h-5.86zm-157.152 0h5.86v10.178h-5.86zm38.79 0h5.86v10.178h-5.86zm39.18 0h5.86v10.178h-5.86zm39.19 0h5.86v10.178h-5.86zm313.092 0h5.86v10.178h-5.86zm-235.122 0h5.86v10.178h-5.86zm39.59 0h5.86v10.178h-5.86zm40 0h5.86v10.178h-5.86zm37.57 0h5.86v10.178h-5.86zm39.99 0h5.86v10.178h-5.86zm39.19 0h5.86v10.178h-5.86zm115.952 0h5.86v10.178h-5.86zm-37.572 0h5.86v10.178h-5.86zm-783.75 0h5.86v10.178h-5.86z"/>
<path fill="#239e3f" stroke-width="1pt" d="M119.3 157.55h5.86v10.178h-5.86zm155.54 0h5.86v10.178h-5.86zm-274.882 0h5.86v10.178h-5.86zm78.941 0h5.86v10.178h-5.86zm78.379 0h5.86v10.178h-5.86zm38.78 0h5.86v10.178h-5.86zm39.59 0h5.86v10.178h-5.86zm77.972 0h5.86v10.178h-5.86zm196.74 0h5.86v10.178h-5.86zm-157.152 0h5.86v10.178h-5.86zm38.79 0h5.86v10.178h-5.86zm39.18 0h5.86v10.178h-5.86zm39.19 0h5.86v10.178h-5.86zm313.092 0h5.86v10.178h-5.86zm-235.122 0h5.86v10.178h-5.86zm39.59 0h5.86v10.178h-5.86zm40 0h5.86v10.178h-5.86zm37.57 0h5.86v10.178h-5.86zm39.99 0h5.86v10.178h-5.86zm39.19 0h5.86v10.178h-5.86zm115.952 0h5.86v10.178h-5.86zm-37.572 0h5.86v10.178h-5.86zm-783.75 0h5.86v10.178h-5.86z"/>
<g fill="#da0000">
<path d="M457.079 191.36c8.19 10.039 33.438 65.548-15.241 101.91-22.884 17.223-8.714 18.093-8.037 20.988 36.785-19.539 48.799-46.013 48.52-69.727-.28-23.715-12.853-44.669-25.242-53.167z"/>
<path d="M461.949 188.78c18.166 9.301 57.701 56.079 15.149 108.85 26.439-5.868 60.053-83.729-15.149-108.85zm-55.79 0c-18.166 9.301-57.701 56.079-15.149 108.85-26.439-5.868-60.053-83.729 15.149-108.85z"/>
<path d="M410.959 191.36c-8.19 10.039-33.438 65.548 15.241 101.91 22.884 17.223 8.714 18.093 8.037 20.988-36.785-19.539-48.799-46.013-48.52-69.727.28-23.715 12.853-44.669 25.242-53.167z"/>
<path d="M480.719 309.2c-14.398.228-32.549-1.984-46.01-8.979 2.217 4.311 4.059 7.026 6.276 11.337 12.838 1.184 30.554 2.649 39.734-2.358zm-92.02 0c14.398.228 32.549-1.984 46.01-8.979-2.217 4.311-4.059 7.026-6.276 11.337-12.838 1.184-30.554 2.649-39.734-2.358zm26.41-134.4c2.917 7.753 10.57 8.88 18.762 4.315 5.97 3.582 15.202 3.809 18.386-3.94 2.421 19.169-17.736 14.634-18.487 10.882-7.504 7.254-21.475 3.064-18.661-11.257z"/>
<path d="M434.409 321.27l7.57-8.652 1.082-116.44-9.012-7.931-9.012 7.57 1.802 117.16 7.57 8.291z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 20 KiB

View File

@@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icon-css-it" width="512" height="512">
<g fill-rule="evenodd" stroke-width="1pt">
<path fill="#fff" d="M0 0h512.005v512H0z"/>
<path fill="#009246" d="M0 0h170.667v512H0z"/>
<path fill="#ce2b37" d="M341.333 0H512v512H341.333z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 305 B

View File

@@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icon-css-nl" width="512" height="512">
<g fill-rule="evenodd" stroke-width="1pt" transform="scale(.48166 .71932)">
<rect width="1063" height="708.66" fill="#fff" rx="0" ry="0"/>
<rect width="1063" height="236.22" y="475.56" fill="#21468b" rx="0" ry="0"/>
<path fill="#ae1c28" d="M0 0h1063v236.22H0z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 379 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icon-css-pl" width="512" height="512">
<g fill-rule="evenodd">
<path fill="#e9e8e7" d="M512 512H0V0h512z"/>
<path fill="#d4213d" d="M512 512H0V256h512z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 228 B

View File

@@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icon-css-ru" width="512" height="512">
<g fill-rule="evenodd" stroke-width="1pt">
<path fill="#fff" d="M0 0h512.005v512H0z"/>
<path fill="#0039a6" d="M0 170.667h512.005V512H0z"/>
<path fill="#d52b1e" d="M0 341.333h512.005V512H0z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 309 B

View File

@@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icon-css-th" width="512" height="512">
<g fill-rule="evenodd">
<path fill="#fff" d="M0 0h512v512H0z"/>
<path fill="#001b9a" d="M0 173.38h512v170.67H0z"/>
<path fill="#e70000" d="M0 .045h512v88H0zM0 426.67h512v85.333H0z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 299 B

View File

@@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icon-css-tr" width="512" height="512">
<g fill-rule="evenodd">
<path fill="#f31930" d="M0 0h512v512H0z"/>
<path fill="#fff" d="M348.772 263.97c0 70.63-58.247 127.883-130.1 127.883S88.572 334.6 88.572 263.97s58.247-127.88 130.1-127.88 130.1 57.254 130.1 127.88z"/>
<path fill="#f31830" d="M355.28 263.965c0 56.5-46.6 102.304-104.08 102.304s-104.08-45.804-104.08-102.305 46.598-102.303 104.08-102.303 104.08 45.803 104.08 102.303z"/>
<path fill="#fff" d="M374.104 204.23l-1.05 47.272-44.103 11.973 43.474 15.482-1.05 43.35 28.352-33.853 42.842 14.863-24.782-36.332 30.242-36.125-46.413 12.798-27.512-39.428z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 690 B

View File

@@ -0,0 +1,14 @@
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icon-css-tw" width="512" height="512">
<defs>
<clipPath id="a">
<path fill-opacity=".67" d="M0 0h496.06v496.06H0z"/>
</clipPath>
</defs>
<g fill-rule="evenodd" stroke-width="1pt" clip-path="url(#a)" transform="scale(1.0321)">
<path fill="#fe0000" d="M0 0h744.09v496.06H0z"/>
<path fill="#000095" d="M0 0h373.69v248.03H0z"/>
<path fill="#fff" d="M273.324 173.001l-45.86-9.43 9.77 45.79-35.01-31.09-14.44 44.54-14.77-44.44-34.77 31.36 9.43-45.86-45.79 9.76 31.09-35-44.539-14.44 44.43-14.77-31.35-34.773 45.86 9.427-9.76-45.792 35 31.095 14.44-44.54 14.77 44.432 34.77-31.354-9.43 45.863 45.79-9.767-31.09 35.01 44.54 14.43-44.43 14.77z"/>
<path fill="#000095" d="M231.045 169.48l-14.47 7.684-14.117 8.34-16.391-.564-16.392.191-13.914-8.663-14.298-8.017-7.706-14.442-8.362-14.069.556-16.347-.182-16.358 8.686-13.874 8.039-14.258 14.47-7.687 14.117-8.34 16.391.562 16.402-.186 13.914 8.66 14.288 8.018 7.706 14.438 8.362 14.069-.556 16.347.182 16.358-8.686 13.877z"/>
<path fill="#fff" d="M237.028 124.291c0 27.754-22.499 50.253-50.253 50.253s-50.253-22.499-50.253-50.253 22.5-50.253 50.253-50.253 50.253 22.5 50.253 50.253z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icon-css-us" width="512" height="512">
<g fill-rule="evenodd">
<g stroke-width="1pt">
<path fill="#bd3d44" d="M0 0h247v10H0zm0 20h247v10H0zm0 20h247v10H0zm0 20h247v10H0zm0 20h247v10H0zm0 20h247v10H0zm0 20h247v10H0z" transform="scale(3.9385)"/>
<path fill="#fff" d="M0 10h247v10H0zm0 20h247v10H0zm0 20h247v10H0zm0 20h247v10H0zm0 20h247v10H0zm0 20h247v10H0z" transform="scale(3.9385)"/>
</g>
<path fill="#192f5d" d="M0 0h98.8v70H0z" transform="scale(3.9385)"/>
<path fill="#fff" d="M8.233 2.996l.9 2.767h2.908l-2.353 1.71.899 2.766-2.354-1.71-2.353 1.71.899-2.766-2.354-1.71h2.91zm16.467 0l.899 2.767h2.909l-2.353 1.71.898 2.766L24.7 8.53l-2.353 1.71.898-2.766-2.353-1.71h2.909zm16.467 0l.899 2.767h2.909l-2.353 1.71.899 2.766-2.354-1.71-2.353 1.71.899-2.766-2.354-1.71h2.91zm16.466 0l.899 2.767h2.909l-2.353 1.71.899 2.766-2.354-1.71-2.353 1.71.899-2.766-2.354-1.71h2.91zm16.467 0l.899 2.767h2.909l-2.354 1.71.9 2.766L74.1 8.53l-2.353 1.71.898-2.766-2.353-1.71h2.909zm16.467 0l.899 2.767h2.909l-2.354 1.71.9 2.766-2.354-1.71-2.353 1.71.898-2.766-2.353-1.71h2.909zm-74.1 7l.899 2.767h2.909l-2.353 1.71.898 2.766-2.353-1.71-2.353 1.71.898-2.766-2.353-1.71h2.909zm16.466 0l.899 2.767h2.909l-2.353 1.71.899 2.766-2.354-1.71-2.353 1.71.899-2.766-2.354-1.71h2.91zm16.467 0l.899 2.767h2.909l-2.353 1.71.899 2.766-2.354-1.71-2.353 1.71.899-2.766-2.354-1.71h2.91zm16.467 0l.899 2.767h2.909l-2.353 1.71.898 2.766-2.353-1.71-2.353 1.71.899-2.766-2.354-1.71h2.91zm16.466 0l.899 2.767h2.909l-2.354 1.71.9 2.766-2.354-1.71-2.353 1.71.898-2.766-2.353-1.71h2.909zm-74.1 7l.9 2.767h2.908l-2.353 1.71.899 2.766-2.354-1.71-2.353 1.71.899-2.766-2.354-1.71h2.91zm16.467 0l.899 2.767h2.909l-2.353 1.71.898 2.766-2.353-1.71-2.353 1.71.898-2.766-2.353-1.71h2.909zm16.467 0l.899 2.767h2.909l-2.353 1.71.899 2.766-2.354-1.71-2.353 1.71.899-2.766-2.354-1.71h2.91zm16.466 0l.899 2.767h2.909l-2.353 1.71.899 2.766-2.354-1.71-2.353 1.71.899-2.766-2.354-1.71h2.91zm16.467 0l.899 2.767h2.909l-2.354 1.71.9 2.766-2.354-1.71-2.353 1.71.898-2.766-2.353-1.71h2.909zm16.467 0l.899 2.767h2.909l-2.354 1.71.9 2.766-2.354-1.71-2.353 1.71.898-2.766-2.353-1.71h2.909zm-74.1 7l.899 2.767h2.909l-2.353 1.71.898 2.766-2.353-1.71-2.353 1.71.898-2.766-2.353-1.71h2.909zm16.466 0l.899 2.767h2.909l-2.353 1.71.899 2.766-2.354-1.71-2.353 1.71.899-2.766-2.354-1.71h2.91zm16.467 0l.899 2.767h2.909l-2.353 1.71.899 2.766-2.354-1.71-2.353 1.71.899-2.766-2.354-1.71h2.91zm16.467 0l.899 2.767h2.909l-2.353 1.71.898 2.766-2.353-1.71-2.353 1.71.899-2.766-2.354-1.71h2.91zm16.466 0l.899 2.767h2.909l-2.354 1.71.9 2.766-2.354-1.71-2.353 1.71.898-2.766-2.353-1.71h2.909zm-74.1 7l.9 2.767h2.908l-2.353 1.71.899 2.766-2.354-1.71-2.353 1.71.899-2.766-2.354-1.71h2.91zm16.467 0l.899 2.767h2.909l-2.353 1.71.898 2.766-2.353-1.71-2.353 1.71.898-2.766-2.353-1.71h2.909zm16.467 0l.899 2.767h2.909l-2.353 1.71.899 2.766-2.354-1.71-2.353 1.71.899-2.766-2.354-1.71h2.91zm16.466 0l.899 2.767h2.909l-2.353 1.71.899 2.766-2.354-1.71-2.353 1.71.899-2.766-2.354-1.71h2.91zm16.467 0l.899 2.767h2.909l-2.354 1.71.9 2.766-2.354-1.71-2.353 1.71.898-2.766-2.353-1.71h2.909zm16.467 0l.899 2.767h2.909l-2.354 1.71.9 2.766-2.354-1.71-2.353 1.71.898-2.766-2.353-1.71h2.909zm-74.1 7l.899 2.767h2.909l-2.353 1.71.898 2.766-2.353-1.71-2.353 1.71.898-2.766-2.353-1.71h2.909zm16.466 0l.899 2.767h2.909l-2.353 1.71.899 2.766-2.354-1.71-2.353 1.71.899-2.766-2.354-1.71h2.91zm16.467 0l.899 2.767h2.909l-2.353 1.71.899 2.766-2.354-1.71-2.353 1.71.899-2.766-2.354-1.71h2.91zm16.467 0l.899 2.767h2.909l-2.353 1.71.898 2.766-2.353-1.71-2.353 1.71.899-2.766-2.354-1.71h2.91zm16.466 0l.899 2.767h2.909l-2.354 1.71.9 2.766-2.354-1.71-2.353 1.71.898-2.766-2.353-1.71h2.909zm-74.1 7l.9 2.767h2.908l-2.353 1.71.899 2.766-2.354-1.71-2.353 1.71.899-2.766-2.354-1.71h2.91zm16.467 0l.899 2.767h2.909l-2.353 1.71.898 2.766-2.353-1.71-2.353 1.71.898-2.766-2.353-1.71h2.909zm16.467 0l.899 2.767h2.909l-2.353 1.71.899 2.766-2.354-1.71-2.353 1.71.899-2.766-2.354-1.71h2.91zm16.466 0l.899 2.767h2.909l-2.353 1.71.899 2.766-2.354-1.71-2.353 1.71.899-2.766-2.354-1.71h2.91zm16.467 0l.899 2.767h2.909l-2.354 1.71.9 2.766-2.354-1.71-2.353 1.71.898-2.766-2.353-1.71h2.909zm16.467 0l.899 2.767h2.909l-2.354 1.71.9 2.766-2.354-1.71-2.353 1.71.898-2.766-2.353-1.71h2.909zm-74.1 7l.899 2.767h2.909l-2.353 1.71.898 2.766-2.353-1.71-2.353 1.71.898-2.766-2.353-1.71h2.909zm16.466 0l.899 2.767h2.909l-2.353 1.71.899 2.766-2.354-1.71-2.353 1.71.899-2.766-2.354-1.71h2.91zm16.467 0l.899 2.767h2.909l-2.353 1.71.899 2.766-2.354-1.71-2.353 1.71.899-2.766-2.354-1.71h2.91zm16.467 0l.899 2.767h2.909l-2.353 1.71.898 2.766-2.353-1.71-2.353 1.71.899-2.766-2.354-1.71h2.91zm16.466 0l.899 2.767h2.909l-2.354 1.71.9 2.766-2.354-1.71-2.353 1.71.898-2.766-2.353-1.71h2.909zm-74.1 7l.9 2.767h2.908l-2.353 1.71.899 2.766-2.354-1.71-2.353 1.71.899-2.766-2.354-1.71h2.91zm16.467 0l.899 2.767h2.909l-2.353 1.71.898 2.766-2.353-1.71-2.353 1.71.898-2.766-2.353-1.71h2.909zm16.467 0l.899 2.767h2.909l-2.353 1.71.899 2.766-2.354-1.71-2.353 1.71.899-2.766-2.354-1.71h2.91zm16.466 0l.899 2.767h2.909l-2.353 1.71.899 2.766-2.354-1.71-2.353 1.71.899-2.766-2.354-1.71h2.91zm16.467 0l.899 2.767h2.909l-2.354 1.71.9 2.766-2.354-1.71-2.353 1.71.898-2.766-2.353-1.71h2.909zm16.467 0l.899 2.767h2.909l-2.354 1.71.9 2.766-2.354-1.71-2.353 1.71.898-2.766-2.353-1.71h2.909z" transform="scale(3.9385)"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.3 KiB

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,82 @@
self.__precacheManifest = [
{
revision: "4eb7af0db693855a4f24cb119a73110d",
url: "flags/de.svg"
},
{
revision: "3b828f54c0e614e18db2c1816c9c2e84",
url: "index.html"
},
{
revision: "3b00bc3b62feafb50a2e",
url: "vendor.js"
},
{
revision: "8020fcd82cc09410f7bad1bc875c115a",
url: "flags/es.svg"
},
{
revision: "617c6a550519013aed310e0fe85bb088",
url: "flags/us.svg"
},
{
revision: "0f6e3867129940ef785c7c8720e0b56d",
url: "flags/ru.svg"
},
{
revision: "09ccf3b3b0a12dd5b3559acedc77858c",
url: "flags/nl.svg"
},
{
revision: "22084f478d0f401fa96288f7790ba8ef",
url: "flags/tw.svg"
},
{
revision: "4a936767fc2ac7335885d90b471d8629",
url: "flags/pl.svg"
},
{
revision: "60fb243496d39972a15bf5a78b6e50ee",
url: "flags/tr.svg"
},
{
revision: "a88d006ab7afa49d76ecd86dd1b11f77",
url: "flags/th.svg"
},
{
revision: "d5204a17fb30a59a4760b4109fbefe0b",
url: "flags/it.svg"
},
{
revision: "5e7a66fb0660b714f1a47859b90767e0",
url: "flags/ir.svg"
},
{
revision: "d107c3019844d2d1f0a4d179cbd8046e",
url: "flags/id.svg"
},
{
revision: "be1df903f0d7711ef8a4e96b6ca56dc0",
url: "flags/fr.svg"
},
{
revision: "5d1c62c220e3dcc85d70e206d44a9d4c",
url: "flags/cz.svg"
},
{
revision: "bedfd890b6c16afeb952546279242cf7",
url: "flags/cn.svg"
},
{
revision: "78de6acf30cc7fa4700207e205a52e88",
url: "flags/br.svg"
},
{
revision: "e1870e757b1b72d20d1f",
url: "app.js"
},
{
revision: "e1870e757b1b72d20d1f",
url: "app.css"
}
];

View File

@@ -0,0 +1,25 @@
/**
* Welcome to your Workbox-powered service worker!
*
* You'll need to register this file in your web app and you should
* disable HTTP caching for this file too.
* See https://goo.gl/nhQhGp
*
* The rest of the code is auto-generated. Please don't update this file
* directly; instead, make changes to your Workbox build configuration
* and re-run your build process.
* See https://goo.gl/2aRDsh
*/
importScripts("https://storage.googleapis.com/workbox-cdn/releases/3.4.1/workbox-sw.js");
importScripts("precache-manifest.b562a874cfed1a8c74df9b49e6f1c2cc.js");
/**
* The workboxSW.precacheAndRoute() method efficiently caches and responds to
* requests for URLs in the manifest.
* See https://goo.gl/S9QRab
*/
self.__precacheManifest = [].concat(self.__precacheManifest || []);
workbox.precaching.suppressWarnings();
workbox.precaching.precacheAndRoute(self.__precacheManifest, {});

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,341 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (C) 2018 Andy Stewart
#
# Author: Andy Stewart <lazycat.manatee@gmail.com>
# Maintainer: Andy Stewart <lazycat.manatee@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from PyQt5 import QtCore
from PyQt5.QtGui import QBrush, QColor
from PyQt5.QtWidgets import QGraphicsScene
from PyQt5.QtCore import Qt, QEvent
from PyQt5.QtGui import QKeyEvent
from PyQt5.QtWidgets import QApplication
from core.utils import interactive
import abc
import string
qt_key_dict = {}
# Build char event.
for char in string.ascii_lowercase:
upper_char = char.upper()
qt_key_dict[char] = eval("Qt.Key_{}".format(upper_char))
qt_key_dict[upper_char] = eval("Qt.Key_{}".format(upper_char))
# Build number event.
for number in range(0, 10):
qt_key_dict[str(number)] = eval("Qt.Key_{}".format(number))
qt_key_dict.update({
''':''': Qt.Key_Colon,
''';''': Qt.Key_Semicolon,
'''.''': Qt.Key_Period,
''',''': Qt.Key_Comma,
'''+''': Qt.Key_Plus,
'''-''': Qt.Key_Minus,
'''=''': Qt.Key_Equal,
'''_''': Qt.Key_Underscore,
'''[''': Qt.Key_BracketLeft,
''']''': Qt.Key_BracketRight,
'''(''': Qt.Key_BraceLeft,
''')''': Qt.Key_BraceRight,
'''{''': Qt.Key_ParenLeft,
'''}''': Qt.Key_ParenRight,
'''<''': Qt.Key_Less,
'''>''': Qt.Key_Greater,
'''@''': Qt.Key_At,
'''\\''': Qt.Key_Backslash,
'''|''': Qt.Key_Bar,
'''/''': Qt.Key_Slash,
'''#''': Qt.Key_NumberSign,
'''$''': Qt.Key_Dollar,
'''?''': Qt.Key_Question,
'''"''': Qt.Key_QuoteDbl,
'''`''': Qt.Key_QuoteLeft,
'''%''': Qt.Key_Percent,
'''^''': Qt.Key_AsciiCircum,
'''&''': Qt.Key_Ampersand,
'''*''': Qt.Key_Asterisk,
'''~''': Qt.Key_AsciiTilde,
'''!''': Qt.Key_Exclam,
'''\'''': Qt.Key_Apostrophe,
'''SPC''': Qt.Key_Space,
'''RET''': Qt.Key_Return,
'''DEL''': Qt.Key_Backspace,
'''TAB''': Qt.Key_Tab,
'''<backtab>''': Qt.Key_Backtab,
'''<home>''': Qt.Key_Home,
'''<end>''': Qt.Key_End,
'''<left>''': Qt.Key_Left,
'''<right>''': Qt.Key_Right,
'''<up>''': Qt.Key_Up,
'''<down>''': Qt.Key_Down,
'''<prior>''': Qt.Key_PageUp,
'''<next>''': Qt.Key_PageDown,
'''<delete>''': Qt.Key_Delete,
'''<backspace>''': Qt.Key_Backspace,
'''<return>''': Qt.Key_Return
})
qt_text_dict = {
"SPC": " "
}
class Buffer(QGraphicsScene):
__metaclass__ = abc.ABCMeta
update_buffer_details = QtCore.pyqtSignal(str, str, str)
open_url_in_new_tab = QtCore.pyqtSignal(str)
open_url_in_background_tab = QtCore.pyqtSignal(str)
translate_text = QtCore.pyqtSignal(str)
input_message = QtCore.pyqtSignal(str, str, str, str, str)
request_close_buffer = QtCore.pyqtSignal(str)
message_to_emacs = QtCore.pyqtSignal(str)
set_emacs_var = QtCore.pyqtSignal(str, str)
eval_in_emacs = QtCore.pyqtSignal(str)
goto_left_tab = QtCore.pyqtSignal()
goto_right_tab = QtCore.pyqtSignal()
aspect_ratio_change = QtCore.pyqtSignal()
enter_fullscreen_request = QtCore.pyqtSignal()
exit_fullscreen_request = QtCore.pyqtSignal()
def __init__(self, buffer_id, url, arguments, emacs_var_dict, module_path, fit_to_view):
super(QGraphicsScene, self).__init__()
self.buffer_id = buffer_id
self.url = url
self.arguments = arguments
self.emacs_var_dict = emacs_var_dict
self.module_path = module_path
self.fit_to_view = fit_to_view
if emacs_var_dict["eaf-emacs-theme-mode"] == "dark":
self.background_color = QColor(233, 129, 35, 255)
else:
self.background_color = QColor(255, 255, 255, 255)
self.setBackgroundBrush(QBrush(self.background_color))
self.title = ""
self.buffer_widget = None
self.is_fullscreen = False
self.current_event_string = ""
self.aspect_ratio = 0
self.vertical_padding_ratio = 1.0 / 8
self.enter_fullscreen_request.connect(self.enable_fullscreen)
self.exit_fullscreen_request.connect(self.disable_fullscreen)
def build_all_methods(self, origin_class):
''' Build all methods.'''
method_list = [func for func in dir(origin_class) if callable(getattr(origin_class, func)) and not func.startswith("__")]
for func_name in method_list:
func_attr = getattr(origin_class, func_name)
if hasattr(func_attr, "interactive"):
self.build_interactive_method(origin_class, func_name, getattr(func_attr, "new_name"), getattr(func_attr, "msg_emacs"), getattr(func_attr, "insert_or_do"))
def build_interactive_method(self, origin_class, class_method_name, new_method_name=None, msg_emacs=None, insert_or_do=False):
''' Build interactive methods.'''
new_name = class_method_name if new_method_name is None else new_method_name
self.__dict__.update({new_name: getattr(origin_class, class_method_name)})
if msg_emacs is not None:
self.message_to_emacs.emit(msg_emacs)
if insert_or_do:
self.build_insert_or_do(new_name)
def build_insert_or_do(self, method_name):
''' Build insert or do.'''
def _do ():
if self.is_focus():
self.fake_key_event(self.current_event_string)
else:
getattr(self, method_name)()
setattr(self, "insert_or_{}".format(method_name), _do)
def toggle_fullscreen(self):
''' Toggle full screen.'''
if self.is_fullscreen:
self.exit_fullscreen_request.emit()
else:
self.enter_fullscreen_request.emit()
def enable_fullscreen(self):
''' Enable full screen.'''
self.is_fullscreen = True
def disable_fullscreen(self):
''' Disable full screen.'''
self.is_fullscreen = False
def set_aspect_ratio(self, aspect_ratio):
''' Set aspect ratio.'''
self.aspect_ratio = aspect_ratio
self.aspect_ratio_change.emit()
def add_widget(self, widget):
''' Add widget.'''
self.buffer_widget = widget
self.addWidget(self.buffer_widget)
self.buffer_widget.installEventFilter(self)
self.buffer_widget.buffer = self
def destroy_buffer(self):
''' Destroy buffer.'''
if self.buffer_widget is not None:
self.buffer_widget.deleteLater()
def change_title(self, new_title):
''' Change title.'''
if new_title != "about:blank":
self.title = new_title
self.update_buffer_details.emit(self.buffer_id, new_title, self.url)
@interactive(insert_or_do=True)
def close_buffer(self):
''' Close buffer.'''
self.request_close_buffer.emit(self.buffer_id)
def all_views_hide(self):
pass
def some_view_show(self):
pass
def resize_view(self):
pass
def get_key_event_widgets(self):
''' Get key event widgets.'''
return [self.buffer_widget]
def send_input_message(self, message, callback_tag, input_type="string", initial_content=""):
''' Send input message.'''
self.input_message.emit(self.buffer_id, message, callback_tag, input_type, initial_content)
def handle_input_message(self, result_type, result_content):
pass
def action_quit(self):
pass
def cancel_input_message(self, result_type):
pass
def scroll_other_buffer(self, scroll_direction, scroll_type):
pass
def save_session_data(self):
return ""
def restore_session_data(self, session_data):
pass
def update_with_data(self, update_data):
pass
def execute_function(self, function_name):
''' Execute function.'''
getattr(self, function_name)()
def call_function(self, function_name):
''' Call function.'''
return getattr(self, function_name)()
def call_function_with_args(self, function_name, args_string):
''' Call function with arguments.'''
return getattr(self, function_name)(args_string)
def fake_key_event_filter(self, event_string):
pass
def fake_key_event(self, event_string):
''' Fake key event.'''
# Init.
text = event_string
modifier = Qt.NoModifier
# Get key text.
if event_string in qt_text_dict:
text = qt_text_dict[event_string]
if event_string in ["TAB", "<backtab>"]:
text = ""
if event_string == "<backtab>":
modifier = Qt.ShiftModifier
elif event_string.isupper():
modifier = Qt.ShiftModifier
# print("Press: ", event_string)
# NOTE: don't ignore text argument, otherwise QWebEngineView not respond key event.
try:
key_press = QKeyEvent(QEvent.KeyPress, qt_key_dict[event_string], modifier, text)
except:
key_press = QKeyEvent(QEvent.KeyPress, Qt.Key_unknown, modifier, text)
for widget in self.get_key_event_widgets():
QApplication.sendEvent(widget, key_press)
self.fake_key_event_filter(event_string)
def fake_key_sequence(self, event_string):
''' Fake key sequence.'''
event_list = event_string.split("-")
if len(event_list) > 1:
for widget in [self.buffer_widget.focusProxy()]:
last_char = event_list[-1]
last_key = last_char
if len(last_char) == 1:
last_key = last_char.lower()
modifiers = Qt.NoModifier
for modifier in event_list[0:-1]:
if modifier == "C":
modifiers |= Qt.ControlModifier
elif modifier == "M":
modifiers |= Qt.AltModifier
elif modifier == "S":
modifiers |= Qt.ShiftModifier
elif modifier == "s":
modifiers |= Qt.MetaModifier
QApplication.sendEvent(widget, QKeyEvent(QEvent.KeyPress, qt_key_dict[last_key], modifiers, last_key))
def get_url(self):
''' Get url.'''
return self.url
@interactive(insert_or_do=True)
def save_as_bookmark(self):
''' Save as bookmark.'''
self.eval_in_emacs.emit('''(bookmark-set)''')
@interactive(insert_or_do=True)
def select_left_tab(self):
''' Select left tab.'''
self.goto_left_tab.emit()
@interactive(insert_or_do=True)
def select_right_tab(self):
''' Select right tab.'''
self.goto_right_tab.emit()

View File

@@ -0,0 +1,4 @@
(function() {
const activeElement = document.activeElement;
activeElement.blur();
})();

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,46 @@
(function() {
function getVisibleElements(filter) {
var all = Array.from(document.documentElement.getElementsByTagName("*"));
var visibleElements = [];
for (var i = 0; i < all.length; i++) {
var e = all[i];
// include elements in a shadowRoot.
if (e.shadowRoot) {
var cc = e.shadowRoot.querySelectorAll('*');
for (var j = 0; j < cc.length; j++) {
all.push(cc[j]);
}
}
var rect = e.getBoundingClientRect();
if ( (rect.top <= window.innerHeight) && (rect.bottom >= 0)
&& (rect.left <= window.innerWidth) && (rect.right >= 0)
&& rect.height > 0
&& getComputedStyle(e).visibility !== 'hidden'
) {
filter(e, visibleElements);
}
}
return visibleElements;
}
var cssSelector = "input";
var elements = getVisibleElements(function(e, v) {
if (e.matches(cssSelector) && !e.disabled && !e.readOnly
&& (e.type === "text" || e.type === "search" || e.type === "password")) {
v.push(e);
}
});
if (elements.length === 0 && document.querySelector(cssSelector) !== null) {
document.querySelector(cssSelector).scrollIntoView();
elements = getVisibleElements(function(e, v) {
if (e.matches(cssSelector) && !e.disabled && !e.readOnly) {
v.push(e);
}
});
}
if (elements.length >= 1) {
elements[0].focus();
}
})();

View File

@@ -0,0 +1,3 @@
(function() {
return window.getComputedStyle(document.body, null).backgroundColor.toString();
})();

View File

@@ -0,0 +1,156 @@
(function() {
function cssSelector(el) {
let path = [], parent;
while (parent = el.parentNode) {
path.unshift(`${el.tagName}:nth-child(${[].indexOf.call(parent.children, el)+1})`);
el = parent;
}
return `${path.join(' > ')}`.toLowerCase();
}
function getCoords(link){
let rect = link.getBoundingClientRect();
return [ rect.top, rect.left, rect.right, rect.bottom, cssSelector(link) ];
}
function isElementOnScreen(rect){
let clientHeight = document.documentElement.clientHeight;
let clientWidth = document.documentElement.clientWidth;
return (rect[0] >= 0 && rect[0] <= clientHeight &&
rect[1] >= 0 && rect[1] <= clientWidth &&
rect[2] != 0 && rect[3] != 0);
}
function isElementOnTop(element, rect){
let topElement = document.elementFromPoint((rect[1] + rect[2])/2, (rect[0] + rect[3])/2);
return topElement != undefined && (element.isSameNode(topElement) || element.contains(topElement) || topElement.contains(element));
}
function hasCopy(validRects, rect){
for(let i = 0; i < validRects.length; i++) {
let each = validRects[i];
if(each[0] === rect[0] && each[1] === rect[1]){
return true;
}
}
return false;
}
function addElementToRects(validRects, elements){
let rect;
for(let i = 0; i < elements.length; i++) {
rect = getCoords(elements[i]);
if(!hasCopy(validRects, rect) &&
isElementOnScreen(rect) &&
isElementOnTop(elements[i], rect)){
validRects.push(rect);
}
}
}
function cAdd1(keyCounter, index, maxDigit){
if(keyCounter[index] + 1 == maxDigit){
keyCounter[index] = 0;
cAdd1(keyCounter, index + 1, maxDigit);
} else {
keyCounter[index]++;
}
}
function generateKeys(markerContainer) {
let lettersString = "%1";
let letters = lettersString.split("");
let linkNum = markerContainer.children.length;
let keyLen = linkNum == 1 ? 1 : Math.ceil(Math.log(linkNum)/Math.log(letters.length));
let keyCounter = [];
for(let i = 0; i < keyLen; i++) keyCounter[i] = 0;
for(let l = 0; l < linkNum; l++) {
let keyStr = '';
for(let k = 0; k < keyLen; k++) {
let mark = document.createElement('span');
mark.setAttribute('class', 'eaf-mark');
let key = letters[keyCounter[k]];
mark.textContent = key;
markerContainer.children[l].appendChild(mark);
keyStr += key;
cAdd1(keyCounter, 0, letters.length);
}
markerContainer.children[l].id = keyStr;
}
}
let style = document.createElement('style');
document.head.appendChild(style);
style.type = 'text/css';
style.setAttribute('class', 'eaf-style');
style.appendChild(document.createTextNode('\
.eaf-mark {\
background: none;\
border: none;\
bottom: auto;\
box-shadow: none;\
color: black !important;\
cursor: auto;\
display: inline;\
float: none;\
font-size: inherit;\
font-variant: normal;\
font-weight: bold;\
height: auto;\
left: auto;\
letter-spacing: 0;\
line-height: 100%;\
margin: 0;\
max-height: none;\
max-width: none;\
min-height: 0;\
min-width: 0;\
opacity: 1;\
padding: 0;\
position: static;\
right: auto;\
text-align: left;\
text-decoration: none;\
text-indent: 0;\
text-shadow: none;\
text-transform: none;\
top: auto;\
vertical-align: baseline;\
white-space: normal;\
width: auto;\
z-index: 100000;\
}'));
style.appendChild(document.createTextNode('\
.eaf-marker {\
position: fixed;\
display: block;\
white-space: nowrap;\
overflow: hidden;\
font-size: 11.5px;\
background: linear-gradient(to bottom, #ffdd6e 0%, #deb050 100%);\
padding-left: 3px;\
padding-right: 3px;\
border: 1px solid #c38a22;\
border-radius: 3px;\
box-shadow: 0px 3px 7px 0px rgba(0, 0, 0, 0.3);\
z-index: 100000;\
}'));
let validRects = [];
addElementToRects(validRects, document.querySelectorAll('pre'));
let body = document.querySelector('body');
let markerContainer = document.createElement('div');
markerContainer.setAttribute('class', 'eaf-marker-container');
body.insertAdjacentElement('afterend', markerContainer);
for(let i = 0; i < validRects.length; i++) {
let marker = document.createElement('div');
marker.setAttribute('class', 'eaf-marker');
marker.setAttribute('style', 'left: ' + validRects[i][1] + 'px; top: ' + validRects[i][0] + 'px;');
marker.setAttribute('pointed-link', validRects[i][4]);
markerContainer.appendChild(marker);
}
generateKeys(markerContainer);
})();

View File

@@ -0,0 +1,23 @@
(function() {
const activeElement = document.activeElement;
var inputs = ["input", "select", "textarea"];
var pageUrl = window.location.href;
var tagName = activeElement.tagName.toLowerCase();
if (pageUrl === "https://mail.qq.com/" && activeElement) {
// QQ mail have some security mechanism that we can't fetch value of activeElement.
// So we just return empty string make is_focus method works well in browser.py
return "";
} else if (activeElement && inputs.indexOf(tagName) !== -1) {
return activeElement.value;
} else {
if (pageUrl.startsWith("https://web.telegram.org/") && activeElement.hasAttribute("placeholder")) {
return activeElement.textContent;
} else if ((pageUrl.startsWith("https://console.cloud.google.com/") || pageUrl.startsWith("https://ssh.cloud.google.com/")) && tagName == "iframe") {
// Make user can type text in Terminal of Google Cloud.
return "";
} else {
return undefined;
}
}
})();

View File

@@ -0,0 +1,166 @@
(function() {
function cssSelector(el) {
let path = [], parent;
while (parent = el.parentNode) {
path.unshift(`${el.tagName}:nth-child(${[].indexOf.call(parent.children, el)+1})`);
el = parent;
}
return `${path.join(' > ')}`.toLowerCase();
}
function getCoords(link){
let rect = link.getBoundingClientRect();
return [ rect.top, rect.left, rect.right, rect.bottom, cssSelector(link) ];
}
function isElementOnScreen(rect){
let clientHeight = document.documentElement.clientHeight;
let clientWidth = document.documentElement.clientWidth;
return (rect[0] >= 0 && rect[0] <= clientHeight &&
rect[1] >= 0 && rect[1] <= clientWidth &&
rect[2] != 0 && rect[3] != 0);
}
function isElementOnTop(element, rect){
let topElement = document.elementFromPoint((rect[1] + rect[2])/2, (rect[0] + rect[3])/2);
return topElement != undefined && (element.isSameNode(topElement) || element.contains(topElement) || topElement.contains(element));
}
function hasCopy(validRects, rect){
for(let i = 0; i < validRects.length; i++) {
let each = validRects[i];
if(each[0] === rect[0] && each[1] === rect[1]){
return true;
}
}
return false;
}
function addElementToRects(validRects, elements){
let rect;
for(let i = 0; i < elements.length; i++) {
rect = getCoords(elements[i]);
if(!hasCopy(validRects, rect) &&
isElementOnScreen(rect) &&
isElementOnTop(elements[i], rect)){
validRects.push(rect);
}
}
}
function cAdd1(keyCounter, index, maxDigit){
if(keyCounter[index] + 1 == maxDigit){
keyCounter[index] = 0;
cAdd1(keyCounter, index + 1, maxDigit);
} else {
keyCounter[index]++;
}
}
function generateKeys(markerContainer) {
let lettersString = "%1";
let letters = lettersString.split("");
let linkNum = markerContainer.children.length;
let keyLen = linkNum == 1 ? 1 : Math.ceil(Math.log(linkNum)/Math.log(letters.length));
let keyCounter = [];
for(let i = 0; i < keyLen; i++) keyCounter[i] = 0;
for(let l = 0; l < linkNum; l++) {
let keyStr = '';
for(let k = 0; k < keyLen; k++) {
let mark = document.createElement('span');
mark.setAttribute('class', 'eaf-mark');
let key = letters[keyCounter[k]];
mark.textContent = key;
markerContainer.children[l].appendChild(mark);
keyStr += key;
cAdd1(keyCounter, 0, letters.length);
}
markerContainer.children[l].id = keyStr;
}
}
let style = document.createElement('style');
document.head.appendChild(style);
style.type = 'text/css';
style.setAttribute('class', 'eaf-style');
style.appendChild(document.createTextNode('\
.eaf-mark {\
background: none;\
border: none;\
bottom: auto;\
box-shadow: none;\
color: black !important;\
cursor: auto;\
display: inline;\
float: none;\
font-size: inherit;\
font-variant: normal;\
font-weight: bold;\
height: auto;\
left: auto;\
letter-spacing: 0;\
line-height: 100%;\
margin: 0;\
max-height: none;\
max-width: none;\
min-height: 0;\
min-width: 0;\
opacity: 1;\
padding: 0;\
position: static;\
right: auto;\
text-align: left;\
text-decoration: none;\
text-indent: 0;\
text-shadow: none;\
text-transform: none;\
top: auto;\
vertical-align: baseline;\
white-space: normal;\
width: auto;\
z-index: 100000;\
}'));
style.appendChild(document.createTextNode('\
.eaf-marker {\
position: fixed;\
display: block;\
white-space: nowrap;\
overflow: hidden;\
font-size: 11.5px;\
background: linear-gradient(to bottom, #ffdd6e 0%, #deb050 100%);\
padding-left: 3px;\
padding-right: 3px;\
border: 1px solid #c38a22;\
border-radius: 3px;\
box-shadow: 0px 3px 7px 0px rgba(0, 0, 0, 0.3);\
z-index: 100000;\
}'));
let validRects = [];
addElementToRects(validRects, document.links); // collect links
addElementToRects(validRects, document.querySelectorAll('a')); // collect <a> without href
addElementToRects(validRects, document.querySelectorAll('input')); // collect <input>
addElementToRects(validRects, document.querySelectorAll('button')); // collect <button>
addElementToRects(validRects, document.querySelectorAll('[class*="btn"]')); // collect class=btn buttons
addElementToRects(validRects, document.querySelectorAll('[aria-haspopup]')); // collect menu buttons
addElementToRects(validRects, document.querySelectorAll('[role="button"]')); // collect role="button"
addElementToRects(validRects, document.querySelectorAll('textarea')); // collect <textarea>
addElementToRects(validRects, document.querySelectorAll('select')); // collect <select>
addElementToRects(validRects, document.querySelectorAll('summary')); // collect <summary>
addElementToRects(validRects, document.querySelectorAll('[class="gap"]')); // collect class="gap"
let body = document.querySelector('body');
let markerContainer = document.createElement('div');
markerContainer.setAttribute('class', 'eaf-marker-container');
body.insertAdjacentElement('afterend', markerContainer);
for(let i = 0; i < validRects.length; i++) {
let marker = document.createElement('div');
marker.setAttribute('class', 'eaf-marker');
marker.setAttribute('style', 'left: ' + validRects[i][1] + 'px; top: ' + validRects[i][0] + 'px;');
marker.setAttribute('pointed-link', validRects[i][4]);
markerContainer.appendChild(marker);
}
generateKeys(markerContainer);
})();

View File

@@ -0,0 +1,3 @@
(function() {
return window.getSelection().toString().substr(0, 20);
})();

View File

@@ -0,0 +1,31 @@
(function() {
function moveCursorToEnd(el) {
if (typeof el.selectionStart == "number") {
el.selectionStart = el.selectionEnd = el.value.length;
} else if (typeof el.createTextRange != "undefined") {
el.focus();
var range = el.createTextRange();
range.collapse(false);
range.select();
}
}
let key = "%1";
let markers = document.querySelectorAll('.eaf-marker');
let match;
for(let i = 0; i < markers.length; i++) {
if(markers[i].id === key.toUpperCase()) {
match = markers[i];
break;
}
}
if(match != undefined){
let selector = match.getAttribute('pointed-link');
let link = document.querySelector(selector);
return link.textContent;
}
return "";
})();

View File

@@ -0,0 +1,55 @@
(function() {
function moveCursorToEnd(el) {
if (typeof el.selectionStart == "number") {
el.selectionStart = el.selectionEnd = el.value.length;
} else if (typeof el.createTextRange != "undefined") {
el.focus();
var range = el.createTextRange();
range.collapse(false);
range.select();
}
}
let key = "%1";
let markers = document.querySelectorAll('.eaf-marker');
let match;
for(let i = 0; i < markers.length; i++) {
if(markers[i].id === key.toUpperCase()) {
match = markers[i];
break;
}
}
if(match != undefined){
let selector = match.getAttribute('pointed-link');
let link = document.querySelector(selector);
if(link.nodeName.toLowerCase() === 'select'){
link.focus();
}else if(link.nodeName.toLowerCase() === 'input' ||
link.nodeName.toLowerCase() === 'textarea') {
if((link.getAttribute('type') === 'submit') ||
(link.getAttribute('type') === 'checkbox')){
link.click();
} else {
link.focus(); // focus
link.click(); // show blink cursor
moveCursorToEnd(link); // move cursor to the end of line after focus.
}
} else if((link.nodeName.toLowerCase() === 'button') || // normal button
(link.nodeName.toLowerCase() === 'summary') || // summary button
(link.hasAttribute('aria-haspopup')) || // menu button
(link.getAttribute('role') === 'button') || // role="button" buttons
(link.classList.contains('btn')) || // class="btn" buttons
(link.classList.contains('gap')) || // class="gap" links
(link.getAttribute('href') === '') || // special href button
(link.getAttribute('href') === '#')){ // special href # button
link.click();
} else if(link.href != undefined && link.href != '' && link.getAttribute('href') != ''){
return link.href;
} else if(link.nodeName.toLowerCase() === 'a') {
link.click(); // most general a tag without href
}
}
return "";
})();

View File

@@ -0,0 +1,5 @@
(function() {
const activeElement = document.activeElement;
activeElement.focus();
activeElement.select();
})();

View File

@@ -0,0 +1,16 @@
(function() {
let newText = "%1";
const activeElement = document.activeElement;
if (window.location.href.startsWith("https://web.telegram.org/")) {
activeElement.textContent = decodeURIComponent(escape(window.atob(newText)));
} else {
activeElement.value = decodeURIComponent(escape(window.atob(newText)));
}
// Note: simulate input event on active element after set focus text.
// Some website need input event before submit form.
var event = document.createEvent('Event');
event.initEvent('input', true, true);
activeElement.dispatchEvent(event);
})();

View File

@@ -0,0 +1,53 @@
#!/usr/bin/env python
# coding=utf-8
import json
import requests
class Jsonrpc(object):
MUTI_METHOD = 'system.multicall'
ADDURI_METHOD = 'aria2.addUri'
def __init__(self, host, port, token=None):
self._idCount = 0
self.host = host
self.port = port
self.serverUrl = "http://{host}:{port}/jsonrpc".format(**locals())
def _genParams(self, method , uris=None, options=None, cid=None):
p = {
'jsonrpc': '2.0',
'id': self._idCount,
'method': method,
'test': 'test',
'params': []
}
if uris:
p['params'].append(uris)
if options:
p['params'].append(options)
return p
def _post(self, action, params, onSuccess, onFail=None):
if onFail is None:
onFail = Jsonrpc._defaultErrorHandle
paramsObject = self._genParams(action, *params)
resp = requests.post(self.serverUrl, data=json.dumps(paramsObject))
result = resp.json()
if "error" in result:
return onFail(result["error"]["code"], result["error"]["message"])
else:
return onSuccess(resp)
def addUris(self, uri, options=None):
def success(response):
return response.text
return self._post(Jsonrpc.ADDURI_METHOD, [[uri,], options], success)
@staticmethod
def _defaultErrorHandle(code, message):
print ("ERROR: {},{}".format(code, message))
return None

View File

@@ -0,0 +1,141 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (C) 2018 Andy Stewart
#
# Author: Andy Stewart <lazycat.manatee@gmail.com>
# Maintainer: Andy Stewart <lazycat.manatee@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from PyQt5 import QtCore
import functools
import os
import socket
import sys
import base64
import threading
import subprocess
from functools import wraps
class PostGui(QtCore.QObject):
through_thread = QtCore.pyqtSignal(object, object)
def __init__(self, inclass=True):
super(PostGui, self).__init__()
self.through_thread.connect(self.on_signal_received)
self.inclass = inclass
def __call__(self, func):
self._func = func
@functools.wraps(func)
def obj_call(*args, **kwargs):
self.emit_signal(args, kwargs)
return obj_call
def emit_signal(self, args, kwargs):
self.through_thread.emit(args, kwargs)
def on_signal_received(self, args, kwargs):
if self.inclass:
obj, args = args[0], args[1:]
self._func(obj, *args, **kwargs)
else:
self._func(*args, **kwargs)
def touch(path):
if not os.path.exists(path):
basedir = os.path.dirname(path)
if not os.path.exists(basedir):
os.makedirs(basedir)
with open(path, 'a'):
os.utime(path)
def get_free_port():
"""
Determines a free port using sockets.
"""
free_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
free_socket.bind(('0.0.0.0', 0))
free_socket.listen(5)
port = free_socket.getsockname()[1]
free_socket.close()
return port
def is_port_in_use(port):
import socket
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
return s.connect_ex(('localhost', port)) == 0
def string_to_base64(text):
return str(base64.b64encode(text.encode("utf-8")), "utf-8")
def get_local_ip():
try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
return s.getsockname()[0]
except OSError:
print("Network is unreachable")
sys.exit()
def popen_and_call(popen_args, on_exit, stdout_file=None):
"""
Runs the given args in a subprocess.Popen, and then calls the function
on_exit when the subprocess completes.
on_exit is a callable object, and popen_args is a list/tuple of args that
would give to subprocess.Popen.
"""
def run_in_thread(on_exit, popen_args):
proc = subprocess.Popen(popen_args, stdout=stdout_file)
proc.wait()
on_exit()
return
thread = threading.Thread(target=run_in_thread, args=(on_exit, popen_args))
thread.start()
# returns immediately after the thread starts
return thread
def call_and_check_code(popen_args, on_exit, stdout_file=None):
"""
Runs the given args in a subprocess.Popen, and then calls the function
on_exit when the subprocess completes.
on_exit is a callable object, and popen_args is a list/tuple of args that
would give to subprocess.Popen.
"""
def run_in_thread(on_exit, popen_args):
retcode = subprocess.call(popen_args, stdout=stdout_file)
on_exit(retcode)
return
thread = threading.Thread(target=run_in_thread, args=(on_exit, popen_args))
thread.start()
# returns immediately after the thread starts
return thread
def interactive(insert_or_do = False, msg_emacs = None, new_name = None):
def wrap(f):
f.interactive = True
f.insert_or_do = insert_or_do
f.msg_emacs = msg_emacs
f.new_name = new_name
@wraps(f)
def wrapped_f(*args, **kwargs):
return f(*args, **kwargs)
return wrapped_f
return wrap

View File

@@ -0,0 +1,122 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (C) 2018 Andy Stewart
#
# Author: Andy Stewart <lazycat.manatee@gmail.com>
# Maintainer: Andy Stewart <lazycat.manatee@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from PyQt5 import QtCore
from PyQt5.QtCore import Qt, QEvent, QPoint
from PyQt5.QtGui import QPainter, QWindow
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QGraphicsView
class View(QWidget):
trigger_focus_event = QtCore.pyqtSignal(str)
def __init__(self, buffer, view_info):
super(View, self).__init__()
self.buffer = buffer
# Init widget attributes.
self.setWindowFlags(Qt.FramelessWindowHint)
self.setAttribute(Qt.WA_X11DoNotAcceptFocus, True)
self.setContentsMargins(0, 0, 0, 0)
self.installEventFilter(self)
# Init attributes.
self.view_info = view_info
(self.buffer_id, self.emacs_xid, self.x, self.y, self.width, self.height) = view_info.split(":")
self.emacs_xid = int(self.emacs_xid)
self.x = int(self.x)
self.y = int(self.y)
self.width = int(self.width)
self.height = int(self.height)
# Build QGraphicsView.
self.layout = QVBoxLayout(self)
self.layout.setContentsMargins(0, 0, 0, 0)
self.graphics_view = QGraphicsView(buffer, self)
self.graphics_view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.graphics_view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.graphics_view.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform | QPainter.TextAntialiasing)
# Remove damn border from QGraphicsView.
self.graphics_view.setFrameStyle(0)
self.graphics_view.setStyleSheet("QGraphicsView {background: transparent; border: 3px; outline: none;}")
self.layout.addWidget(self.graphics_view)
# NOTE: show function must start before resize to trigger *first* resizeEvent after show.
self.show()
# Resize after show to trigger fit view operation.
self.resize(self.width, self.height)
self.buffer.aspect_ratio_change.connect(self.adjust_aspect_ratio)
def resizeEvent(self, event):
# Fit content to view rect just when buffer fit_to_view option is enable.
if self.buffer.fit_to_view:
if event.oldSize().isValid():
self.graphics_view.fitInView(self.graphics_view.scene().sceneRect(), Qt.KeepAspectRatio)
QWidget.resizeEvent(self, event)
def adjust_aspect_ratio(self):
widget_width = self.width
widget_height = self.height
if self.buffer.aspect_ratio == 0:
self.buffer.buffer_widget.resize(self.width, self.height)
self.layout.setContentsMargins(0, 0, 0, 0)
else:
view_height = widget_height * (1 - 2 * self.buffer.vertical_padding_ratio)
view_width = view_height * self.buffer.aspect_ratio
horizontal_padding = (widget_width - view_width) / 2
vertical_padding = self.buffer.vertical_padding_ratio * widget_height
self.buffer.buffer_widget.resize(view_width, view_height)
self.layout.setContentsMargins(
horizontal_padding, vertical_padding,
horizontal_padding, vertical_padding)
def eventFilter(self, obj, event):
# Focus emacs buffer when user click view.
if event.type() in [QEvent.MouseButtonPress, QEvent.MouseButtonRelease,
QEvent.MouseButtonDblClick, QEvent.Wheel]:
self.trigger_focus_event.emit(self.buffer_id)
# Stop mouse event.
return True
return False
def showEvent(self, event):
# NOTE: we must reparent after widget show, otherwise reparent operation maybe failed.
self.reparent()
# Make graphics view at left-top corner after show.
self.graphics_view.verticalScrollBar().setValue(0)
self.graphics_view.horizontalScrollBar().setValue(0)
def reparent(self):
qwindow = self.windowHandle()
qwindow.setParent(QWindow.fromWinId(self.emacs_xid))
qwindow.setPosition(QPoint(self.x, self.y))
def destroy_view(self):
self.destroy()