diff --git a/logo/vector-logo-R2000.dxf b/logo/vector-logo-R2000.dxf new file mode 100644 index 0000000000000000000000000000000000000000..4b28e7a23db2faa41a63418905adaca995dbfa5e Binary files /dev/null and b/logo/vector-logo-R2000.dxf differ diff --git a/logo/vector-logo.svg b/logo/vector-logo.svg new file mode 100644 index 0000000000000000000000000000000000000000..d5fb7347d1515a4c888a96819bc47e88d7156889 --- /dev/null +++ b/logo/vector-logo.svg @@ -0,0 +1,523 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + version="1.1" + width="765.09448" + height="779.328" + id="svg2"> + <defs + id="defs4"> + <symbol + id="*Paper_Space0" /> + <symbol + id="*Paper_Space" /> + <symbol + id="*Model_Space" /> + <pattern + height="8" + id="Hatch" + patternUnits="userSpaceOnUse" + width="8" + x="0" + y="0"> + <path + d="M8 4 l-4,4" + linecap="square" + stroke="#000000" + stroke-width="0.25" + id="path3049" /> + <path + d="M6 2 l-4,4" + linecap="square" + stroke="#000000" + stroke-width="0.25" + id="path3051" /> + <path + d="M4 0 l-4,4" + linecap="square" + stroke="#000000" + stroke-width="0.25" + id="path3053" /> + </pattern> + <marker + refX="0" + refY="0" + orient="auto" + id="DistanceX" + style="overflow:visible"> + <path + d="M 3,-3 -3,3 M 0,-5 0,5" + id="path3046" + style="stroke:#000000;stroke-width:0.5" /> + </marker> + </defs> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + transform="translate(-1595.2072,-3900.1734)" + id="layer1"> + <g + transform="translate(1605.7072,3616.6359)" + id="g3058" /> + <g + transform="translate(1605.7072,3616.6359)" + id="g3060"> + <path + d="m 376.28676,565.33282 a 50.505437,50.505437 0 0 0 2.94079,-22.54604 4.006761,4.006761 0 1 0 -7.97559,0.77878 42.491917,42.491917 0 0 1 -2.47419,18.96875 4.0067627,4.0067627 0 0 0 7.50899,2.79851 z" + id="path3062" + style="fill:none;stroke:#00ff00" /> + <path + d="m 310.44438,550.74978 a 59.389614,59.389614 0 0 1 1.23877,-16.00076 4.0067628,4.0067628 0 0 1 7.83278,1.69238 51.376093,51.376093 0 0 0 -1.07162,13.84176 4.0067635,4.0067635 0 0 1 -7.99993,0.46662 z" + id="path3064" + style="fill:none;stroke:#00ff00" /> + <path + d="m 392.10618,427.13329 a 12.200345,12.200345 0 0 0 12.0626,-15.93766 22.471543,22.471543 0 0 0 -5.15835,-8.6452 11.14774,11.14774 0 0 0 -16.96297,10.95558 4.0067603,4.0067603 0 0 0 7.93984,-1.08418 3.13422,3.13422 0 0 1 4.03924,-3.41591 14.458023,14.458023 0 0 1 2.51573,4.64997 4.186825,4.186825 0 0 1 -4.13955,5.46937 4.0067602,4.0067602 0 0 0 -0.29654,8.00803 z" + id="path3066" + style="fill:none;stroke:#00ff00" /> + <path + d="m 371.77724,411.5205 a 15.711594,15.711594 0 0 0 -0.4822,-3.9744 3.414554,3.414554 0 0 0 -6.42324,-0.56196 8.601878,8.601878 0 0 0 3.73033,11.08591 4.00676,4.00676 0 0 1 -3.83196,7.03793 16.615399,16.615399 0 0 1 -7.20551,-21.41355 11.428075,11.428075 0 0 1 21.49777,1.88081 23.725114,23.725114 0 0 1 0.72814,6.0015 4.0067635,4.0067635 0 0 1 -8.01333,-0.0562 z" + id="path3068" + style="fill:none;stroke:#00ff00" /> + <path + d="m 379.3526,301.76746 a 23.936355,23.936355 0 0 0 -9.95309,7.37952 4.0067642,4.0067642 0 1 1 -6.27618,-4.98259 31.949875,31.949875 0 0 1 13.28523,-9.85006 4.0067605,4.0067605 0 0 1 2.94404,7.45313 z" + id="path3070" + style="fill:none;stroke:#00ff00" /> + <path + d="m 445.68236,329.11654 a 17.364203,17.364203 0 0 0 -11.77173,-12.76486 4.0067634,4.0067634 0 1 1 2.3854,-7.65026 25.377723,25.377723 0 0 1 17.20435,18.65581 4.0067633,4.0067633 0 0 1 -7.81802,1.75931 z" + id="path3072" + style="fill:none;stroke:#00ff00" /> + <path + d="m 573.77832,824.21829 a 231.49358,231.49358 0 0 0 42.29005,-25.76377 97.552014,97.552014 0 0 1 -10.48364,37.94069 29.283353,29.283353 0 0 1 -12.73834,12.73834 208.98141,208.98141 0 0 1 -37.85329,14.91063 102.01883,102.01883 0 0 0 18.78522,-39.82589 z" + id="path3074" + style="fill:none;stroke:#00ff00" /> + <path + d="m 409.47237,828.37833 a 223.48006,223.48006 0 0 0 206.73547,-40.24557 97.552014,97.552014 0 0 0 -0.19497,-3.41849 80.161845,80.161845 0 0 0 -11.72761,-36.13952 26.25055,26.25055 0 0 0 -21.76496,-12.45524 215.19714,215.19714 0 0 1 -186.57181,44.02404 217.80817,217.80817 0 0 0 13.52388,48.23478 z" + id="path3076" + style="fill:none;stroke:#00ff00" /> + <path + d="m 517.45426,842.3746 a 107.84051,107.84051 0 0 1 -13.06728,29.83277 381.1671,381.1671 0 0 0 15.49202,-1.3351 208.98141,208.98141 0 0 0 21.55961,-3.44895 94.005315,94.005315 0 0 0 22.97314,-39.0461 231.49358,231.49358 0 0 1 -46.95749,13.99738 z" + id="path3078" + style="fill:none;stroke:#00ff00" /> + <path + d="m 450.45349,871.92484 a 82.150232,82.150232 0 0 0 12.01617,-26.0055 231.49358,231.49358 0 0 0 46.23144,-2.09169 99.826988,99.826988 0 0 1 -14.33124,28.90521 381.1671,381.1671 0 0 1 -43.91637,-0.80802 z" + id="path3080" + style="fill:none;stroke:#00ff00" /> + <path + d="m 413.65999,837.94547 a 231.49358,231.49358 0 0 0 40.66298,7.38175 74.136712,74.136712 0 0 1 -12.82798,25.25052 39.270306,39.270306 0 0 1 -20.00183,-17.43165 217.80817,217.80817 0 0 1 -7.83317,-15.20062 z" + id="path3082" + style="fill:none;stroke:#00ff00" /> + <path + d="m 394.76071,771.6117 a 207.18362,207.18362 0 0 0 23.71188,4.47646 73.871194,73.871194 0 0 0 1.94716,-13.81518 232.6189,232.6189 0 0 1 -26.66931,-1.40174 217.80817,217.80817 0 0 0 1.01027,10.74046 z" + id="path3084" + style="fill:none;stroke:#00ff00" /> + <path + d="m 426.49583,776.96489 a 207.18362,207.18362 0 0 0 44.08456,-0.76029 79.152083,79.152083 0 0 0 9.83174,-22.10671 232.6189,232.6189 0 0 1 -51.96427,7.99697 81.884715,81.884715 0 0 1 -1.95203,14.87003 z" + id="path3086" + style="fill:none;stroke:#00ff00" /> + <path + d="m 489.28386,751.49075 a 87.165603,87.165603 0 0 1 -8.50621,23.18584 207.18362,207.18362 0 0 0 55.05061,-17.86255 77.758554,77.758554 0 0 0 2.10781,-27.07964 232.6189,232.6189 0 0 1 -48.65221,21.75635 z" + id="path3088" + style="fill:none;stroke:#00ff00" /> + <path + d="m 393.3415,752.76013 a 217.80817,217.80817 0 0 1 1.1775,-30.55375 283.78976,283.78976 0 0 1 1.37461,-10.69942 202.37681,202.37681 0 0 0 114.74785,-44.62022 l 13.46305,-9.42693 a 30.662014,30.662014 0 0 1 30.54534,-2.67237 43.31958,43.31958 0 0 1 24.50085,32.62626 224.60538,224.60538 0 0 1 -185.8092,65.34643 z" + id="path3090" + style="fill:none;stroke:#00ff00" /> + <path + d="m 397.2145,703.38787 a 194.36329,194.36329 0 0 0 108.49341,-42.81743 23.586902,23.586902 0 0 0 7.177,-26.78491 9.918601,9.918601 0 0 0 -9.0861,-6.36216 46.235274,46.235274 0 0 0 -20.07565,4.19848 368.58869,368.58869 0 0 0 -82.20858,51.76929 283.78976,283.78976 0 0 0 -4.30008,19.99673 z" + id="path3092" + style="fill:none;stroke:#00ff00" /> + <path + d="m 330.50955,405.93841 a 43.354257,43.354257 0 0 0 -21.50063,22.02808 209.96578,209.96578 0 0 0 -17.42053,85.99371 70.711924,70.711924 0 0 0 11.83735,38.4211 73.780204,73.780204 0 0 0 36.19311,28.46005 56.856184,56.856184 0 0 0 26.52196,2.98592 76.570466,76.570466 0 0 0 22.51248,-6.43214 134.78926,134.78926 0 0 0 31.95362,-20.63291 86.740478,86.740478 0 0 0 29.81077,-62.11513 288.53091,288.53091 0 0 0 -2.17155,-48.33622 33.216431,33.216431 0 0 0 -13.19493,-22.44209 85.769489,85.769489 0 0 1 -11.32318,18.65937 20.678757,20.678757 0 0 1 -29.15081,3.20659 l -12.48299,-10.06693 -5.83399,3.19814 a 20.393506,20.393506 0 0 1 -20.81496,1.9248 43.705101,43.705101 0 0 1 -23.03486,-26.94516 75.590657,75.590657 0 0 1 -1.90086,-7.90718 z" + id="path3094" + style="fill:none;stroke:#00ff00" /> + <path + d="m 382.94763,426.06136 16.66009,13.43555 a 12.665237,12.665237 0 0 0 17.85416,-1.96395 77.755969,77.755969 0 0 0 11.39889,-77.33361 16.166727,16.166727 0 0 0 -27.11236,-4.71923 57.567866,57.567866 0 0 0 -9.01787,14.03492 4.00676,4.00676 0 0 1 -7.47927,-2.8312 l 3.66419,-11.92814 a 20.187638,20.187638 0 0 0 -4.10085,-15.3254 13.55444,13.55444 0 0 0 -18.36656,-2.78633 67.577137,67.577137 0 0 0 -26.35813,74.91214 35.691581,35.691581 0 0 0 18.81131,22.00464 12.379986,12.379986 0 0 0 12.99693,-1.44218 l 11.04947,-6.05721 z" + id="path3096" + style="fill:none;stroke:#00ff00" /> + <path + d="m 179.88519,850.89001 a 143.93977,143.93977 0 0 0 -60.7871,11.41043 39.086677,39.086677 0 0 1 31.634,-33.28021 75.323314,75.323314 0 0 0 2.87715,2.61567 204.7432,204.7432 0 0 0 26.27595,19.25411 z" + id="path3098" + style="fill:none;stroke:#00ff00" /> + <path + d="m 180.7201,841.94194 a 63.377551,63.377551 0 0 1 -1.06614,-14.26533 168.39098,168.39098 0 0 0 36.56014,14.90295 79.890316,79.890316 0 0 0 10.90348,21.32858 196.72968,196.72968 0 0 1 -46.39748,-21.9662 z" + id="path3100" + style="fill:none;stroke:#00ff00" /> + <path + d="m 155.0269,736.60456 a 82.876006,82.876006 0 0 0 27.62666,25.09115 130.32087,130.32087 0 0 0 74.55456,16.14168 164.72099,164.72099 0 0 0 15.34776,62.39714 160.37746,160.37746 0 0 1 -136.796,-59.85916 67.309794,67.309794 0 0 1 -0.20129,-8.24674 45.220678,45.220678 0 0 1 19.46831,-35.52407 z" + id="path3102" + style="fill:none;stroke:#00ff00" /> + <path + d="m 139.14621,796.42854 a 168.39098,168.39098 0 0 0 32.78872,26.71342 71.391072,71.391072 0 0 0 -0.11078,12.70846 196.72968,196.72968 0 0 1 -12.97919,-10.28113 67.309794,67.309794 0 0 1 -19.69875,-29.14075 z" + id="path3104" + style="fill:none;stroke:#00ff00" /> + <path + d="m 341.4891,589.85722 a 55.435829,55.435829 0 0 0 -3.2324,14.50355 71.84369,71.84369 0 0 1 11.19892,-6.75508 18.566982,18.566982 0 0 1 23.47316,6.28961 55.133466,55.133466 0 0 1 9.2031,25.28531 115.24382,115.24382 0 0 1 -6.52826,51.71425 126.76861,126.76861 0 0 0 -6.84034,27.96367 258.78206,258.78206 0 0 0 9.55239,109.18435 88.989436,88.989436 0 0 0 27.4297,41.50727 115.2534,115.2534 0 0 0 7.14653,-5.382 225.82169,225.82169 0 0 1 -26.33907,-132.83166 291.80328,291.80328 0 0 1 25.82839,-92.10092 8852.0265,8852.0265 0 0 0 12.90415,-27.67305 271.41458,271.41458 0 0 0 20.23505,-62.43919 94.753998,94.753998 0 0 1 -19.66016,23.69024 142.80278,142.80278 0 0 1 -33.85334,21.85959 84.583986,84.583986 0 0 1 -24.86854,7.10529 64.869704,64.869704 0 0 1 -25.64928,-1.92123 z" + id="path3106" + style="fill:none;stroke:#00ff00" /> + <path + d="m 369.13833,815.32419 a 74.028904,74.028904 0 0 1 -95.89339,5.11915 156.70747,156.70747 0 0 0 7.87587,19.12 72.321745,72.321745 0 0 0 10.15696,15.35524 101.22787,101.22787 0 0 0 67.15775,-1.90467 4.00676,4.00676 0 1 1 2.87252,7.48098 109.24139,109.24139 0 0 1 -57.82815,5.65243 72.321745,72.321745 0 0 0 22.40696,10.97918 68.754331,68.754331 0 0 0 26.53851,2.32182 115.2534,115.2534 0 0 0 46.29388,-15.39035 97.002956,97.002956 0 0 1 -28.05765,-43.64199 266.79558,266.79558 0 0 1 -1.52326,-5.09179 z" + id="path3108" + style="fill:none;stroke:#00ff00" /> + <path + d="m 331.35491,621.89163 a 63.83017,63.83017 0 0 0 -6.26256,9.21212 593.88382,593.88382 0 0 0 -3.81437,6.93228 23.165032,23.165032 0 0 0 9.50587,5.45484 4.00676,4.00676 0 0 1 -2.23105,7.69668 31.178552,31.178552 0 0 1 -11.14625,-5.8833 593.88382,593.88382 0 0 0 -6.91493,13.6255 407.95821,407.95821 0 0 1 -4.08498,8.0845 48.659079,48.659079 0 0 0 46.84863,19.18747 4.0067617,4.0067617 0 1 1 1.2638,7.91324 56.672599,56.672599 0 0 1 -52.22496,-19.38464 407.95821,407.95821 0 0 1 -16.52659,27.58179 65.112051,65.112051 0 0 0 52.57372,21.39817 4.0067601,4.0067601 0 1 1 0.51631,7.99687 73.125571,73.125571 0 0 1 -57.61157,-22.48672 105.69968,105.69968 0 0 0 -14.77227,40.38221 82.248315,82.248315 0 0 0 75.51268,24.07677 4.00676,4.00676 0 0 1 1.54551,7.86307 90.261836,90.261836 0 0 1 -78.11221,-21.76739 156.70747,156.70747 0 0 0 3.66136,45.9627 66.015383,66.015383 0 0 0 97.64216,0.62811 266.79558,266.79558 0 0 1 -5.90981,-98.5153 134.78213,134.78213 0 0 1 7.27275,-29.73136 107.2303,107.2303 0 0 0 6.07431,-48.11829 47.119946,47.119946 0 0 0 -7.86545,-21.61014 10.553462,10.553462 0 0 0 -13.34213,-3.57501 63.83017,63.83017 0 0 0 -14.61804,9.78433 55.435829,55.435829 0 0 0 2.04764,10.34614 80.71878,80.71878 0 0 0 10.60797,22.29072 29.900833,29.900833 0 0 1 0,33.65259 4.0067602,4.0067602 0 0 1 -6.62426,-4.50951 21.887312,21.887312 0 0 0 1.95062,-21.10962 31.201566,31.201566 0 0 1 -14.27347,19.66503 4.0067611,4.0067611 0 0 1 -4.14047,-6.86098 23.188046,23.188046 0 0 0 9.62936,-28.26012 88.732301,88.732301 0 0 1 -4.82714,-12.57156 63.449349,63.449349 0 0 1 -1.35018,-5.35119 z" + id="path3110" + style="fill:none;stroke:#00ff00" /> + <path + d="m 269.57245,713.65446 a 113.7132,113.7132 0 0 0 -11.4262,37.77549 110.10404,110.10404 0 0 1 -96.97148,-61.264 49.107667,49.107667 0 0 1 17.58582,-15.78918 36.418066,36.418066 0 0 1 25.93358,-3.17223 30.817043,30.817043 0 0 0 2.53011,4.95806 72.633968,72.633968 0 0 0 22.72798,22.72798 103.55567,103.55567 0 0 0 39.62019,14.76388 z" + id="path3112" + style="fill:none;stroke:#00ff00" /> + <path + d="m 215.86437,750.95726 a 106.24555,106.24555 0 0 0 1.67841,15.89514 122.30735,122.30735 0 0 1 -30.97555,-12.14953 74.862486,74.862486 0 0 1 -7.75035,-4.98777 64.183337,64.183337 0 0 1 2.26887,-20.3627 118.11756,118.11756 0 0 0 34.77862,21.60486 z" + id="path3114" + style="fill:none;stroke:#00ff00" /> + <path + d="m 174.63302,723.11977 a 72.196858,72.196858 0 0 0 -3.81679,19.80765 74.862486,74.862486 0 0 1 -13.79039,-18.41208 28.198881,28.198881 0 0 1 -1.92017,-21.94772 49.107667,49.107667 0 0 1 1.46515,-3.93072 118.11756,118.11756 0 0 0 18.0622,24.48287 z" + id="path3116" + style="fill:none;stroke:#00ff00" /> + <path + d="m 273.73824,706.13565 a 95.542154,95.542154 0 0 1 -39.51377,-14.0248 64.620448,64.620448 0 0 1 -20.22046,-20.22046 22.803523,22.803523 0 0 1 26.02263,-33.94491 149.61449,149.61449 0 0 1 55.90254,31.71704 399.94469,399.94469 0 0 1 -19.33967,31.99615 113.7132,113.7132 0 0 0 -2.85127,4.47698 z" + id="path3118" + style="fill:none;stroke:#00ff00" /> + <path + d="m 545.05438,752.02278 a 85.772074,85.772074 0 0 0 0.38873,-26.93543 232.6189,232.6189 0 0 0 34.00718,-26.74347 119.25749,119.25749 0 0 1 -9.91732,37.83297 207.18362,207.18362 0 0 1 -24.47859,15.84593 z" + id="path3120" + style="fill:none;stroke:#00ff00" /> + <path + d="m 240.84019,867.78115 a 71.876795,71.876795 0 0 1 -15.21004,-22.88963 168.39098,168.39098 0 0 0 50.89266,3.05759 80.335265,80.335265 0 0 0 20.63345,23.4764 154.30544,154.30544 0 0 1 -49.09939,-2.03029 196.72968,196.72968 0 0 1 -7.21668,-1.61407 z" + id="path3122" + style="fill:none;stroke:#00ff00" /> + <path + d="m 224.02047,753.88817 a 118.11756,118.11756 0 0 0 33.39064,5.54325 164.72099,164.72099 0 0 0 -0.36757,10.377 122.30735,122.30735 0 0 1 -30.98247,-1.21337 98.23203,98.23203 0 0 1 -2.0406,-14.70688 z" + id="path3124" + style="fill:none;stroke:#00ff00" /> + <path + d="m 581.2891,728.10608 a 34.26407,34.26407 0 0 1 29.81506,16.25927 88.175365,88.175365 0 0 1 12.89998,39.75227 105.56553,105.56553 0 0 1 -11.28476,55.92633 37.296873,37.296873 0 0 1 -16.22425,16.22424 216.99493,216.99493 0 0 1 -75.76537,22.57231 389.18062,389.18062 0 0 1 -78.68798,0.40113 47.283826,47.283826 0 0 1 -24.9978,-18.12609 123.26692,123.26692 0 0 1 -63.75725,26.29987 76.767852,76.767852 0 0 1 -29.63164,-2.59243 80.335265,80.335265 0 0 1 -16.39729,-6.79646 162.31896,162.31896 0 0 1 -60.80272,-0.7795 204.7432,204.7432 0 0 1 -48.82219,-16.5864 135.92625,135.92625 0 0 0 -81.12913,11.60923 4.00676,4.00676 0 0 1 -5.7421,-3.49872 47.100197,47.100197 0 0 1 33.74161,-46.48812 75.323314,75.323314 0 0 1 -16.95274,-50.45011 53.234199,53.234199 0 0 1 23.22968,-42.03299 82.876006,82.876006 0 0 1 -0.83023,-1.5231 36.212402,36.212402 0 0 1 -2.46585,-28.18481 57.121187,57.121187 0 0 1 27.515,-32.79109 44.431586,44.431586 0 0 1 27.61588,-4.68162 30.817043,30.817043 0 0 1 39.77667,-32.33039 157.62801,157.62801 0 0 1 57.39495,32.08215 399.94469,399.94469 0 0 0 3.51298,-6.97563 601.89734,601.89734 0 0 1 14.79775,-28.20148 71.84369,71.84369 0 0 1 11.98838,-15.82569 63.449349,63.449349 0 0 1 3.83179,-24.13961 81.793724,81.793724 0 0 1 -37.16337,-30.40815 78.725445,78.725445 0 0 1 -13.17884,-42.77522 217.9793,217.9793 0 0 1 18.0854,-89.27573 51.367777,51.367777 0 0 1 27.79302,-27.10727 75.590657,75.590657 0 0 1 32.44045,-67.61214 21.56796,21.56796 0 0 1 29.22504,4.43363 28.201159,28.201159 0 0 1 5.85316,14.40068 24.180247,24.180247 0 0 1 39.32928,8.34011 85.769489,85.769489 0 0 1 1.73021,58.95357 41.229951,41.229951 0 0 1 18.16135,29.10313 296.54442,296.54442 0 0 1 2.23278,49.6552 279.4281,279.4281 0 0 1 -25.87209,110.0002 8860.04,8860.04 0 0 1 -12.91584,27.69811 283.78976,283.78976 0 0 0 -14.4139,37.46509 376.60221,376.60221 0 0 1 75.15967,-45.76261 54.248794,54.248794 0 0 1 23.55518,-4.92616 17.932121,17.932121 0 0 1 16.42701,11.50232 31.600422,31.600422 0 0 1 1.24923,18.60663 38.675535,38.675535 0 0 1 36.42124,-1.99531 51.333101,51.333101 0 0 1 29.44345,50.99757 127.27101,127.27101 0 0 1 -6.19086,29.58379 z" + id="path3126" + style="fill:none;stroke:#00ff00" /> + <path + d="m 8.01352,861.4055 0,50.1886 34.304866,12.48595 20.748018,-11.97887 a 4.00676,4.00676 0 0 1 4.00676,6.93991 l -14.92474,8.6168 6.564258,2.3892 20.748018,-11.97888 a 4.00676,4.00676 0 0 1 4.00676,6.93991 l -14.924741,8.61681 6.564258,2.38919 20.748018,-11.97887 a 4.0067603,4.0067603 0 0 1 4.006761,6.93991 l -14.924741,8.6168 6.564258,2.3892 20.748017,-11.97888 a 4.00676,4.00676 0 0 1 4.00676,6.93991 l -14.92474,8.61681 6.56426,2.38919 20.74802,-11.97887 a 4.00676,4.00676 0 0 1 4.00676,6.93991 l -14.92474,8.6168 6.56426,2.3892 20.74801,-11.97888 a 4.0067635,4.0067635 0 0 1 4.00676,6.93992 l -14.92474,8.6168 6.56426,2.38919 20.74802,-11.97887 a 4.0067603,4.0067603 0 0 1 4.00676,6.93991 l -14.92474,8.6168 6.56426,2.3892 20.74801,-11.97887 a 4.00676,4.00676 0 0 1 4.00676,6.93991 l -14.92474,8.6168 6.56426,2.38919 20.74802,-11.97887 a 4.00676,4.00676 0 0 1 4.00676,6.93991 l -14.92474,8.61681 6.56426,2.38919 20.74802,-11.97887 a 4.00676,4.00676 0 0 1 4.00676,6.93991 l -14.92475,8.6168 6.56426,2.3892 20.74802,-11.97888 a 4.0067635,4.0067635 0 0 1 4.00676,6.93992 l -14.92474,8.6168 6.56426,2.38919 20.74802,-11.97887 a 4.00676,4.00676 0 0 1 4.00676,6.93991 l -14.92474,8.6168 6.56425,2.3892 20.74802,-11.97888 a 4.0067635,4.0067635 0 0 1 4.00676,6.93992 l -14.92474,8.6168 6.56426,2.38918 20.74802,-11.97886 a 4.00676,4.00676 0 0 1 4.00676,6.93991 l -14.92474,8.61685 6.56426,2.3891 20.74801,-11.97883 a 4.0067678,4.0067678 0 0 1 4.00676,6.93993 l -14.92474,8.6168 6.56426,2.3892 20.74802,-11.9789 a 4.00676,4.00676 0 0 1 4.00676,6.9399 l -14.92474,8.6168 69.97762,25.4698 0,-50.1886 L 8.01352,861.4055 z" + id="path3128" + style="fill:none;stroke:#00ff00" /> + <path + d="m 736.08097,861.4055 0,50.1886 -34.30487,12.48595 -20.74802,-11.97887 a 4.00676,4.00676 0 0 0 -4.00676,6.93991 l 14.92474,8.6168 -6.56425,2.3892 -20.74802,-11.97888 a 4.0067603,4.0067603 0 0 0 -4.00676,6.93991 l 14.92474,8.61681 -6.56426,2.38919 -20.74802,-11.97887 a 4.00676,4.00676 0 0 0 -4.00676,6.93991 l 14.92474,8.6168 -6.56426,2.3892 -20.74801,-11.97888 a 4.00676,4.00676 0 0 0 -4.00676,6.93991 l 14.92474,8.61681 -6.56426,2.38919 -20.74802,-11.97887 a 4.00676,4.00676 0 0 0 -4.00676,6.93991 l 14.92474,8.6168 -6.56426,2.3892 -20.74801,-11.97888 a 4.006766,4.006766 0 0 0 -4.00677,6.93992 l 14.92475,8.6168 -6.56426,2.38919 -20.74802,-11.97887 a 4.00676,4.00676 0 0 0 -4.00676,6.93991 l 14.92474,8.6168 -6.56426,2.3892 -20.74802,-11.97887 a 4.00676,4.00676 0 0 0 -4.00676,6.93991 l 14.92474,8.6168 -6.56425,2.38919 -20.74802,-11.97887 a 4.00676,4.00676 0 0 0 -4.00676,6.93991 l 14.92474,8.61681 -6.56426,2.38919 -20.74802,-11.97887 a 4.0067603,4.0067603 0 0 0 -4.00676,6.93991 l 14.92474,8.6168 -6.56426,2.3892 -20.74801,-11.97888 a 4.0067635,4.0067635 0 0 0 -4.00676,6.93992 l 14.92474,8.6168 -6.56426,2.38919 -20.74802,-11.97887 a 4.00676,4.00676 0 0 0 -4.00676,6.93991 l 14.92474,8.6168 -6.56426,2.3892 -20.74802,-11.97888 a 4.006761,4.006761 0 0 0 -4.00675,6.93992 l 14.92474,8.6168 -6.56426,2.38918 -20.74802,-11.97886 a 4.0067603,4.0067603 0 0 0 -4.00676,6.93991 l 14.92474,8.61685 -6.56426,2.3891 -20.74802,-11.97883 a 4.0067678,4.0067678 0 0 0 -4.00676,6.93993 l 14.92474,8.6168 -6.56425,2.3892 -20.74802,-11.9789 a 4.00676,4.00676 0 0 0 -4.00676,6.9399 l 14.92474,8.6168 -69.97763,25.4698 0,-50.1886 360.02697,-131.0391 z" + id="path3130" + style="fill:none;stroke:#00ff00" /> + <path + d="m 0,914.39966 a 4.00676,4.00676 0 0 0 2.636367,3.76513 l 36.060572,13.12497 0,27.22772 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-24.31104 8.380775,3.05036 0,27.22771 a 4.0067605,4.0067605 0 0 0 8.013521,0 l 0,-24.31103 8.380775,3.05035 0,27.22772 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-24.31103 8.380776,3.05035 0,27.22772 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-24.31104 8.380774,3.05035 0,27.22772 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-24.31103 8.38078,3.05035 0,27.22772 a 4.0067605,4.0067605 0 0 0 8.01352,0 l 0,-24.31104 8.38077,3.05036 0,27.22771 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-24.31103 8.38078,3.05035 0,27.22769 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-24.31101 8.38077,3.05036 0,27.22775 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-24.31107 8.38078,3.05035 0,27.22772 a 4.0067605,4.0067605 0 0 0 8.01352,0 l 0,-24.31104 8.38078,3.05036 0,27.22768 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-24.311 8.38077,3.05035 0,27.22775 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-24.31106 8.38078,3.05036 0,27.2277 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-24.311 8.38077,3.0503 0,27.2277 a 4.0067605,4.0067605 0 0 0 8.01352,0 l 0,-24.311 8.38078,3.0504 0,27.2277 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-24.3111 8.38077,3.0504 0,27.2277 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-24.311 78.05196,28.4086 a 4.00676,4.00676 0 0 0 2.74079,0 l 78.05195,-28.4086 0,24.311 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-27.2277 8.38078,-3.0504 0,24.3111 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-27.2277 8.38078,-3.0504 0,24.311 a 4.00676,4.00676 0 0 0 8.01351,0 l 0,-27.2277 8.38078,-3.0503 0,24.311 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-27.2277 8.38078,-3.05036 0,24.31106 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-27.22775 8.38077,-3.05035 0,24.311 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-27.22768 8.38078,-3.05036 0,24.31104 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-27.22772 8.38077,-3.05035 0,24.31107 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-27.22775 8.38078,-3.05036 0,24.31101 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-27.22769 8.38077,-3.05035 0,24.31103 a 4.006765,4.006765 0 0 0 8.01353,0 l 0,-27.22771 8.38077,-3.05036 0,24.31104 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-27.22772 8.38078,-3.05035 0,24.31103 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-27.22772 8.38077,-3.05035 0,24.31104 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-27.22772 8.38078,-3.05035 0,24.31103 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-27.22772 8.38077,-3.05035 0,24.31103 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-27.22771 8.38078,-3.05036 0,24.31104 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-27.22772 36.06057,-13.12497 a 4.00676,4.00676 0 0 0 2.63637,-3.76513 l 0,-58.7164 a 4.00676,4.00676 0 0 0 -2.31343,-3.63136 L 637.06594,803.22244 a 4.0067602,4.0067602 0 0 0 -3.38666,7.26271 l 95.94824,44.7414 L 372.04724,985.37513 14.466964,855.22655 121.47719,805.32686 a 4.0067602,4.0067602 0 1 0 -3.38666,-7.26271 L 2.31343,852.0519 A 4.00676,4.00676 0 0 0 0,855.68326 l 0,58.7164 z" + id="path3132" + style="fill:none;stroke:#00ff00" /> + </g> + <g + transform="translate(1605.7072,3616.6359)" + id="g3210"> + <path + d="m 382.52092,430.86458 14.57154,11.75125 a 16.671997,16.671997 0 0 0 23.50249,-2.58528 81.762729,81.762729 0 0 0 11.98627,-81.3186 20.173487,20.173487 0 0 0 -33.84358,-5.87562 61.574626,61.574626 0 0 0 -9.65625,15.02408 l 3.75178,-12.2133 a 24.194398,24.194398 0 0 0 -4.86625,-18.69008 17.5612,17.5612 0 0 0 -23.7958,-3.60998 71.583897,71.583897 0 0 0 -27.92096,79.3538 39.698341,39.698341 0 0 0 20.92309,24.4749 16.386746,16.386746 0 0 0 16.9218,-1.69218 l 8.42587,-4.61899 z" + id="path3212" + style="fill:none;stroke:#0000ff" /> + <path + d="m 372.53226,563.93357 a 46.498677,46.498677 0 0 0 2.70749,-20.7574" + id="path3214" + style="fill:none;stroke:#0000ff" /> + <path + d="m 315.59954,535.59521 a 55.382854,55.382854 0 0 0 -1.1552,14.92126" + id="path3216" + style="fill:none;stroke:#0000ff" /> + <path + d="m 333.7265,400.35197 a 47.361017,47.361017 0 0 0 -28.39168,26.01605 213.97254,213.97254 0 0 0 -17.75297,87.63472 74.718685,74.718685 0 0 0 12.5081,40.59816 77.786964,77.786964 0 0 0 38.15864,30.00562 60.862944,60.862944 0 0 0 28.391,3.19634 80.577226,80.577226 0 0 0 23.69051,-6.76872 138.79602,138.79602 0 0 0 32.90348,-21.24625 90.747238,90.747238 0 0 0 31.18781,-64.98437 292.53766,292.53766 0 0 0 -2.20171,-49.00746 37.223191,37.223191 0 0 0 -19.05684,-27.8772" + id="path3218" + style="fill:none;stroke:#0000ff" /> + <path + d="M 341.21132,638.22132 A 27.194806,27.194806 0 0 1 329.9731,671.50499" + id="path3220" + style="fill:none;stroke:#0000ff" /> + <path + d="m 339.16702,584.93246 a 59.442589,59.442589 0 0 0 -2.62324,41.16208 84.725541,84.725541 0 0 0 11.13454,23.3972 25.894073,25.894073 0 0 1 0,29.14308" + id="path3222" + style="fill:none;stroke:#0000ff" /> + <path + d="M 543.44764,871.08733 A 98.012075,98.012075 0 0 0 570.2837,821.42548" + id="path3224" + style="fill:none;stroke:#0000ff" /> + <path + d="m 514.2071,838.88789 a 103.83375,103.83375 0 0 1 -17.74383,37.76773" + id="path3226" + style="fill:none;stroke:#0000ff" /> + <path + d="m 421.457,780.4836 a 77.877955,77.877955 0 0 0 3.04257,-22.27427" + id="path3228" + style="fill:none;stroke:#0000ff" /> + <path + d="m 472.9134,779.94366 a 83.158843,83.158843 0 0 0 12.90414,-31.57337" + id="path3230" + style="fill:none;stroke:#0000ff" /> + <path + d="m 539.22236,759.60757 a 81.765314,81.765314 0 0 0 1.84844,-36.48441" + id="path3232" + style="fill:none;stroke:#0000ff" /> + <path + d="m 391.12429,774.81454 a 211.19038,211.19038 0 0 0 189.93266,-42.69491 30.25731,30.25731 0 0 1 26.63776,14.35042 84.168605,84.168605 0 0 1 12.3138,37.94589 101.55877,101.55877 0 0 1 -10.85646,53.80364 33.290113,33.290113 0 0 1 -14.48129,14.48129 212.98817,212.98817 0 0 1 -74.36638,22.15551 385.17386,385.17386 0 0 1 -77.47265,0.43588 43.277066,43.277066 0 0 1 -24.83099,-20.18217 221.81493,221.81493 0 0 1 -27.46482,-133.33866 287.79652,287.79652 0 0 1 25.47373,-90.83627 8856.0333,8856.0333 0 0 0 12.91,-27.68558 275.42134,275.42134 0 0 0 25.50174,-108.44606" + id="path3234" + style="fill:none;stroke:#0000ff" /> + <path + d="m 392.25445,423.12927 a 8.193585,8.193585 0 0 0 8.10107,-10.70351 18.464783,18.464783 0 0 0 -3.87707,-6.71529 7.14098,7.14098 0 0 0 -10.46107,7.25345" + id="path3236" + style="fill:none;stroke:#0000ff" /> + <path + d="m 366.68615,421.58902 a 12.608639,12.608639 0 0 1 -5.46792,-16.24974 7.421314,7.421314 0 0 1 13.9605,1.22139 19.718354,19.718354 0 0 1 0.60517,4.98795" + id="path3238" + style="fill:none;stroke:#0000ff" /> + <path + d="M 389.47225,756.31817 A 228.61214,228.61214 0 0 0 583.37899,688.82115" + id="path3240" + style="fill:none;stroke:#0000ff" /> + <path + d="m 459.3636,841.71136 a 78.143472,78.143472 0 0 1 -16.53187,33.5809" + id="path3242" + style="fill:none;stroke:#0000ff" /> + <path + d="m 392.42787,707.68071 a 198.37005,198.37005 0 0 0 115.80144,-43.99632 27.593662,27.593662 0 0 0 8.39617,-31.33493 13.925361,13.925361 0 0 0 -12.75656,-8.93223 50.242034,50.242034 0 0 0 -21.81541,4.56232 372.59545,372.59545 0 0 0 -84.1007,53.16609" + id="path3244" + style="fill:none;stroke:#0000ff" /> + <path + d="m 508.22931,663.68439 13.57702,-9.50673 a 34.668775,34.668775 0 0 1 34.53685,-3.02158 47.326341,47.326341 0 0 1 27.14527,47.017 123.26425,123.26425 0 0 1 -10.72617,40.58526" + id="path3246" + style="fill:none;stroke:#0000ff" /> + <path + d="M 406.48872,831.64439 A 227.48682,227.48682 0 0 0 620.27078,789.98146" + id="path3248" + style="fill:none;stroke:#0000ff" /> + <path + d="M 449.59137,328.23689 A 21.370963,21.370963 0 0 0 435.10333,312.52655" + id="path3250" + style="fill:none;stroke:#0000ff" /> + <path + d="m 377.88058,298.04089 a 27.943115,27.943115 0 0 0 -11.61916,8.61479" + id="path3252" + style="fill:none;stroke:#0000ff" /> + <path + d="m 405.51281,864.5415 a 92.996196,92.996196 0 0 1 -31.02418,-45.31207 262.78882,262.78882 0 0 1 -9.70029,-110.87486 130.77537,130.77537 0 0 1 7.05655,-28.84752 111.23706,111.23706 0 0 0 6.30128,-49.91627 51.126706,51.126706 0 0 0 -8.53427,-23.44772 14.560222,14.560222 0 0 0 -18.40765,-4.93232 67.83693,67.83693 0 0 0 -29.60939,27.93811 597.89058,597.89058 0 0 0 -14.69925,28.01374 403.95145,403.95145 0 0 1 -26.97769,46.72672 109.70644,109.70644 0 0 0 -17.9377,49.28344 160.71423,160.71423 0 0 0 15.54459,88.15775 76.328505,76.328505 0 0 0 47.24616,39.64424 72.761092,72.761092 0 0 0 28.08507,2.45713 119.26016,119.26016 0 0 0 65.1447,-28.32178" + id="path3254" + style="fill:none;stroke:#0000ff" /> + <path + d="m 316.38638,638.66914 a 27.171792,27.171792 0 0 0 13.28194,8.67007" + id="path3256" + style="fill:none;stroke:#0000ff" /> + <path + d="m 301.72732,667.31527 a 52.665839,52.665839 0 0 0 52.15985,22.84307" + id="path3258" + style="fill:none;stroke:#0000ff" /> + <path + d="m 280.75734,702.63171 a 69.118811,69.118811 0 0 0 57.84206,25.07701" + id="path3260" + style="fill:none;stroke:#0000ff" /> + <path + d="m 262.24527,750.93628 a 86.255075,86.255075 0 0 0 80.51388,26.67467" + id="path3262" + style="fill:none;stroke:#0000ff" /> + <path + d="m 265.41082,807.63634 a 70.022143,70.022143 0 0 0 105.72256,-0.1937" + id="path3264" + style="fill:none;stroke:#0000ff" /> + <path + d="m 359.87178,856.7544 a 105.23463,105.23463 0 0 1 -70.88249,1.63225" + id="path3266" + style="fill:none;stroke:#0000ff" /> + <path + d="m 307.96308,873.8255 a 158.3122,158.3122 0 0 1 -60.70711,-0.50438 200.73644,200.73644 0 0 1 -91.02887,-44.71853 71.316554,71.316554 0 0 1 -24.67254,-56.62182 49.227439,49.227439 0 0 1 24.65824,-40.8605" + id="path3268" + style="fill:none;stroke:#0000ff" /> + <path + d="m 261.07655,773.42067 a 126.31411,126.31411 0 0 1 -76.46616,-15.22138 78.869246,78.869246 0 0 1 -31.12248,-31.80322 32.205641,32.205641 0 0 1 -2.19301,-25.06626 53.114427,53.114427 0 0 1 25.58496,-30.49097 40.424826,40.424826 0 0 1 30.8812,-2.93695" + id="path3270" + style="fill:none;stroke:#0000ff" /> + <path + d="m 275.88011,710.39411 a 99.548914,99.548914 0 0 1 -43.79174,-14.89339 68.627208,68.627208 0 0 1 -21.47423,-21.47423 26.810283,26.810283 0 0 1 30.59503,-39.9093 153.62125,153.62125 0 0 1 59.7228,34.69979" + id="path3272" + style="fill:none;stroke:#0000ff" /> + <path + d="M 278.74109,843.70013 A 164.38422,164.38422 0 0 1 131.88286,781.93476" + id="path3274" + style="fill:none;stroke:#0000ff" /> + <path + d="M 261.75187,755.43438 A 114.1108,114.1108 0 0 1 156.58875,689.88039" + id="path3276" + style="fill:none;stroke:#0000ff" /> + <path + d="m 198.87079,856.80555 a 139.93301,139.93301 0 0 0 -84.10393,11.85358 43.093437,43.093437 0 0 1 37.33346,-43.91361" + id="path3278" + style="fill:none;stroke:#0000ff" /> + <path + d="m 219.36836,839.27942 a 75.883556,75.883556 0 0 0 19.43078,32.12534" + id="path3280" + style="fill:none;stroke:#0000ff" /> + <path + d="m 176.21099,821.06404 a 67.384312,67.384312 0 0 0 0.91717,23.32019" + id="path3282" + style="fill:none;stroke:#0000ff" /> + <path + d="m 219.82446,748.19616 a 102.23879,102.23879 0 0 0 2.92741,23.87741" + id="path3284" + style="fill:none;stroke:#0000ff" /> + <path + d="M 179.26009,722.11589 A 68.190098,68.190098 0 0 0 174.935,751.80737" + id="path3286" + style="fill:none;stroke:#0000ff" /> + <path + d="m 372.04724,989.63904 0,58.71636" + id="path3288" + style="fill:none;stroke:#0000ff" /> + <path + d="m 310.98422,1005.0767 -22.36609,12.913 0,30.0333" + id="path3290" + style="fill:none;stroke:#0000ff" /> + <path + d="m 65.069784,915.57113 -22.366085,12.91307 0,30.03328" + id="path3292" + style="fill:none;stroke:#0000ff" /> + <path + d="m 294.58992,999.10963 -22.36608,12.91307 0,30.0333" + id="path3294" + style="fill:none;stroke:#0000ff" /> + <path + d="m 278.19563,993.1426 -22.36609,12.9131 0,30.0332" + id="path3296" + style="fill:none;stroke:#0000ff" /> + <path + d="m 261.80133,987.17556 -22.36608,12.91304 0,30.0333" + id="path3298" + style="fill:none;stroke:#0000ff" /> + <path + d="m 245.40704,981.20852 -22.36609,12.91307 0,30.03331" + id="path3300" + style="fill:none;stroke:#0000ff" /> + <path + d="m 229.01274,975.24149 -22.36608,12.91306 0,30.03325" + id="path3302" + style="fill:none;stroke:#0000ff" /> + <path + d="m 212.61845,969.27445 -22.36609,12.91307 0,30.03328" + id="path3304" + style="fill:none;stroke:#0000ff" /> + <path + d="m 196.22415,963.30742 -22.36609,12.91306 0,30.03332" + id="path3306" + style="fill:none;stroke:#0000ff" /> + <path + d="m 179.82985,957.34038 -22.36608,12.91307 0,30.03325" + id="path3308" + style="fill:none;stroke:#0000ff" /> + <path + d="m 163.43556,951.37335 -22.36609,12.91306 0,30.03328" + id="path3310" + style="fill:none;stroke:#0000ff" /> + <path + d="m 147.04126,945.40631 -22.36608,12.91307 0,30.03328" + id="path3312" + style="fill:none;stroke:#0000ff" /> + <path + d="m 130.64697,939.43927 -22.36609,12.91307 0,30.03328" + id="path3314" + style="fill:none;stroke:#0000ff" /> + <path + d="m 114.25267,933.47224 -22.366084,12.91306 0,30.03329" + id="path3316" + style="fill:none;stroke:#0000ff" /> + <path + d="m 97.858375,927.5052 -22.366085,12.91307 0,30.03328" + id="path3318" + style="fill:none;stroke:#0000ff" /> + <path + d="m 81.46408,921.53817 -22.366085,12.91306 0,30.03328" + id="path3320" + style="fill:none;stroke:#0000ff" /> + <path + d="m 433.11027,1005.0767 22.36608,12.913 0,30.0333" + id="path3322" + style="fill:none;stroke:#0000ff" /> + <path + d="m 465.89886,993.1426 22.36608,12.9131 0,30.0332" + id="path3324" + style="fill:none;stroke:#0000ff" /> + <path + d="m 449.50456,999.10963 22.36609,12.91307 0,30.0333" + id="path3326" + style="fill:none;stroke:#0000ff" /> + <path + d="m 515.08175,975.24149 22.36608,12.91306 0,30.03325" + id="path3328" + style="fill:none;stroke:#0000ff" /> + <path + d="m 498.68745,981.20852 22.36609,12.91307 0,30.03331" + id="path3330" + style="fill:none;stroke:#0000ff" /> + <path + d="m 482.29316,987.17556 22.36608,12.91304 0,30.0333" + id="path3332" + style="fill:none;stroke:#0000ff" /> + <path + d="m 547.87034,963.30742 22.36608,12.91306 0,30.03332" + id="path3334" + style="fill:none;stroke:#0000ff" /> + <path + d="m 531.47604,969.27445 22.36609,12.91307 0,30.03328" + id="path3336" + style="fill:none;stroke:#0000ff" /> + <path + d="m 597.05322,945.40631 22.36609,12.91307 0,30.03328" + id="path3338" + style="fill:none;stroke:#0000ff" /> + <path + d="m 564.26463,957.34038 22.36609,12.91307 0,30.03325" + id="path3340" + style="fill:none;stroke:#0000ff" /> + <path + d="m 580.65893,951.37335 22.36609,12.91306 0,30.03328" + id="path3342" + style="fill:none;stroke:#0000ff" /> + <path + d="m 679.0247,915.57113 22.36609,12.91307 0,30.03328" + id="path3344" + style="fill:none;stroke:#0000ff" /> + <path + d="m 613.44752,939.43927 22.36609,12.91307 0,30.03328" + id="path3346" + style="fill:none;stroke:#0000ff" /> + <path + d="m 629.84182,933.47224 22.36608,12.91306 0,30.03329" + id="path3348" + style="fill:none;stroke:#0000ff" /> + <path + d="m 646.23611,927.5052 22.36609,12.91307 0,30.03328" + id="path3350" + style="fill:none;stroke:#0000ff" /> + <path + d="m 662.63041,921.53817 22.36608,12.91306 0,30.03328" + id="path3352" + style="fill:none;stroke:#0000ff" /> + <path + d="m 740.08773,855.68326 0,58.7164 L 372.04724,1048.3554 4.00676,914.39966 l 0,-58.7164" + id="path3354" + style="fill:none;stroke:#0000ff" /> + <path + d="M 119.78386,801.69551 4.00676,855.68326 372.04724,989.63904 740.08773,855.68326 635.37261,806.85379" + id="path3356" + style="fill:none;stroke:#0000ff" /> + </g> + </g> +</svg> diff --git a/py/builtin.c b/py/builtin.c index 2b94163f166b1d351f4278cf0764e583c4ed8e38..d29a2bf8c3c92c96e7548c693f53c1d83a108807 100644 --- a/py/builtin.c +++ b/py/builtin.c @@ -16,30 +16,20 @@ mp_obj_t mp_builtin___build_class__(mp_obj_t o_class_fun, mp_obj_t o_class_name) { // we differ from CPython: we set the new __locals__ object here - mp_map_t *old_locals = rt_get_map_locals(); + mp_map_t *old_locals = rt_locals_get(); mp_map_t *class_locals = mp_map_new(MP_MAP_QSTR, 0); - rt_set_map_locals(class_locals); + rt_locals_set(class_locals); // call the class code rt_call_function_1(o_class_fun, (mp_obj_t)0xdeadbeef); // restore old __locals__ object - rt_set_map_locals(old_locals); + rt_locals_set(old_locals); // create and return the new class return mp_obj_new_class(class_locals); } -mp_obj_t mp_builtin___import__(int n, mp_obj_t *args) { - printf("import:\n"); - for (int i = 0; i < n; i++) { - printf(" "); - mp_obj_print(args[i]); - printf("\n"); - } - return mp_const_none; -} - mp_obj_t mp_builtin___repl_print__(mp_obj_t o) { if (o != mp_const_none) { mp_obj_print(o); diff --git a/py/builtinimport.c b/py/builtinimport.c new file mode 100644 index 0000000000000000000000000000000000000000..47dbf21216c450c81d0f7f3518da0c9f7d2be6ea --- /dev/null +++ b/py/builtinimport.c @@ -0,0 +1,84 @@ +#include <stdint.h> +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include <assert.h> + +#include "nlr.h" +#include "misc.h" +#include "mpconfig.h" +#include "lexer.h" +#include "lexerunix.h" +#include "parse.h" +#include "obj.h" +#include "compile.h" +#include "runtime0.h" +#include "runtime.h" +#include "map.h" +#include "builtin.h" + +mp_obj_t mp_builtin___import__(int n, mp_obj_t *args) { + /* + printf("import:\n"); + for (int i = 0; i < n; i++) { + printf(" "); + mp_obj_print(args[i]); + printf("\n"); + } + */ + + // find the file to import + qstr mod_name = mp_obj_get_qstr(args[0]); + mp_lexer_t *lex = mp_import_open_file(mod_name); + if (lex == NULL) { + // TODO handle lexer error correctly + return mp_const_none; + } + + // create a new module object + mp_obj_t module_obj = mp_obj_new_module(mp_obj_get_qstr(args[0])); + + // save the old context + mp_map_t *old_locals = rt_locals_get(); + mp_map_t *old_globals = rt_globals_get(); + + // set the new context + rt_locals_set(mp_obj_module_get_globals(module_obj)); + rt_globals_set(mp_obj_module_get_globals(module_obj)); + + // parse the imported script + mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT); + mp_lexer_free(lex); + + if (pn == MP_PARSE_NODE_NULL) { + // TODO handle parse error correctly + rt_locals_set(old_locals); + rt_globals_set(old_globals); + return mp_const_none; + } + + if (!mp_compile(pn, false)) { + // TODO handle compile error correctly + rt_locals_set(old_locals); + rt_globals_set(old_globals); + return mp_const_none; + } + + // complied successfully, execute it + mp_obj_t module_fun = rt_make_function_from_id(1); // TODO we should return from mp_compile the unique_code_id for the module + nlr_buf_t nlr; + if (nlr_push(&nlr) == 0) { + rt_call_function_0(module_fun); + nlr_pop(); + } else { + // exception; restore context and re-raise same exception + rt_locals_set(old_locals); + rt_globals_set(old_globals); + nlr_jump(nlr.ret_val); + } + rt_locals_set(old_locals); + rt_globals_set(old_globals); + + return module_obj; +} diff --git a/py/compile.c b/py/compile.c index b00ab7ef64aed2f1a4af362a37a9f27bcbd28c76..68ac20804de09b974bc50d4ef0cc7977fa19b6fd 100644 --- a/py/compile.c +++ b/py/compile.c @@ -10,9 +10,11 @@ #include "lexer.h" #include "parse.h" #include "scope.h" -#include "compile.h" #include "runtime0.h" #include "emit.h" +#include "obj.h" +#include "compile.h" +#include "runtime.h" // TODO need to mangle __attr names @@ -3016,7 +3018,7 @@ void compile_scope_compute_things(compiler_t *comp, scope_t *scope) { } } -bool mp_compile(mp_parse_node_t pn, bool is_repl) { +mp_obj_t mp_compile(mp_parse_node_t pn, bool is_repl) { compiler_t *comp = m_new(compiler_t, 1); comp->qstr___class__ = qstr_from_str_static("__class__"); @@ -3146,7 +3148,19 @@ bool mp_compile(mp_parse_node_t pn, bool is_repl) { } } + bool had_error = comp->had_error; m_del_obj(compiler_t, comp); - return !comp->had_error; + if (had_error) { + // TODO return a proper error message + return mp_const_none; + } else { +#if MICROPY_EMIT_CPYTHON + // can't create code, so just return true + return mp_const_true; +#else + // return function that executes the outer module + return rt_make_function_from_id(1); +#endif + } } diff --git a/py/compile.h b/py/compile.h index e283442bb066d465ead0c6bc4a410c58f6b47e71..770c2524dae39f40a23c6038ffc6901d3cfe8ae2 100644 --- a/py/compile.h +++ b/py/compile.h @@ -1 +1 @@ -bool mp_compile(mp_parse_node_t pn, bool is_repl); +mp_obj_t mp_compile(mp_parse_node_t pn, bool is_repl); diff --git a/py/emitbc.c b/py/emitbc.c index 790fe3e4e5f14b15210014469658ea704e798e7f..dc1988582c49e9802e5a5f5e46b16e1bc4d19f12 100644 --- a/py/emitbc.c +++ b/py/emitbc.c @@ -9,7 +9,6 @@ #include "mpconfig.h" #include "lexer.h" #include "parse.h" -#include "compile.h" #include "scope.h" #include "runtime0.h" #include "emit.h" diff --git a/py/emitcpy.c b/py/emitcpy.c index b107c0bf1151305d18cdd6f733d4647eb25a0fd3..652617cc88c2bf30916246910fd4949b7c548a5e 100644 --- a/py/emitcpy.c +++ b/py/emitcpy.c @@ -9,7 +9,6 @@ #include "mpconfig.h" #include "lexer.h" #include "parse.h" -#include "compile.h" #include "scope.h" #include "runtime0.h" #include "emit.h" diff --git a/py/emitpass1.c b/py/emitpass1.c index 4ed05497273645cb8cdf29aafd151427a2650a39..1c11241e0dd536ad1a6d6e18136728ca45eb59cd 100644 --- a/py/emitpass1.c +++ b/py/emitpass1.c @@ -9,7 +9,6 @@ #include "mpconfig.h" #include "lexer.h" #include "parse.h" -#include "compile.h" #include "scope.h" #include "runtime0.h" #include "emit.h" diff --git a/py/lexer.h b/py/lexer.h index f58a38e92b7c0f88aab0947c5f85bf96cb642fa0..27244fde96b64712acd3f1a0fdf17749d0906817 100644 --- a/py/lexer.h +++ b/py/lexer.h @@ -138,3 +138,6 @@ bool mp_lexer_opt_str(mp_lexer_t *lex, const char *str); */ bool mp_lexer_show_error(mp_lexer_t *lex, const char *msg); bool mp_lexer_show_error_pythonic(mp_lexer_t *lex, const char *msg); + +// used to import a module; must be implemented for a specific port +mp_lexer_t *mp_import_open_file(qstr mod_name); diff --git a/py/lexerunix.c b/py/lexerunix.c index 398cb792a7ace443dd3c712f0475fc12e35920dd..14c28c16d92d2302901916db50520e810e8b1402 100644 --- a/py/lexerunix.c +++ b/py/lexerunix.c @@ -58,3 +58,23 @@ mp_lexer_t *mp_lexer_new_from_file(const char *filename) { return mp_lexer_new_from_str_len(filename, data, size, true); } + +/******************************************************************************/ +/* unix implementation of import */ + +// TODO properly! + +static const char *import_base_dir = NULL; + +void mp_import_set_directory(const char *dir) { + import_base_dir = dir; +} + +mp_lexer_t *mp_import_open_file(qstr mod_name) { + vstr_t *vstr = vstr_new(); + if (import_base_dir != NULL) { + vstr_printf(vstr, "%s/", import_base_dir); + } + vstr_printf(vstr, "%s.py", qstr_str(mod_name)); + return mp_lexer_new_from_file(vstr_str(vstr)); // TODO does lexer need to copy the string? can we free it here? +} diff --git a/py/lexerunix.h b/py/lexerunix.h index d86f202d53b4a8cc350c3f2b24b6c67929412bc9..b422a43062d682e72209af6fc6d85411912d4313 100644 --- a/py/lexerunix.h +++ b/py/lexerunix.h @@ -1,2 +1,4 @@ mp_lexer_t *mp_lexer_new_from_str_len(const char *src_name, const char *str, uint len, bool free_str); mp_lexer_t *mp_lexer_new_from_file(const char *filename); + +void mp_import_set_directory(const char *dir); diff --git a/py/malloc.c b/py/malloc.c index c65d38a9687c43d96e76a0ddb85b176f4fafe991..4f01dc63f5208ccba6678b90fbf5f6a9999b4367 100644 --- a/py/malloc.c +++ b/py/malloc.c @@ -2,8 +2,15 @@ #include <stdlib.h> #include "misc.h" +#include "mpconfig.h" +#if MICROPY_MEM_STATS static int total_bytes_allocated = 0; +static int current_bytes_allocated = 0; +static int peak_bytes_allocated = 0; + +#define UPDATE_PEAK() { if (current_bytes_allocated > peak_bytes_allocated) peak_bytes_allocated = current_bytes_allocated; } +#endif void *m_malloc(int num_bytes) { if (num_bytes == 0) { @@ -14,7 +21,11 @@ void *m_malloc(int num_bytes) { printf("could not allocate memory, allocating %d bytes\n", num_bytes); return NULL; } +#if MICROPY_MEM_STATS total_bytes_allocated += num_bytes; + current_bytes_allocated += num_bytes; + UPDATE_PEAK(); +#endif return ptr; } @@ -27,7 +38,11 @@ void *m_malloc0(int num_bytes) { printf("could not allocate memory, allocating %d bytes\n", num_bytes); return NULL; } +#if MICROPY_MEM_STATS total_bytes_allocated += num_bytes; + current_bytes_allocated += num_bytes; + UPDATE_PEAK(); +#endif return ptr; } @@ -41,7 +56,17 @@ void *m_realloc(void *ptr, int old_num_bytes, int new_num_bytes) { printf("could not allocate memory, reallocating %d bytes\n", new_num_bytes); return NULL; } - total_bytes_allocated += new_num_bytes; +#if MICROPY_MEM_STATS + // At first thought, "Total bytes allocated" should only grow, + // after all, it's *total*. But consider for example 2K block + // shrunk to 1K and then grown to 2K again. It's still 2K + // allocated total. If we process only positive increments, + // we'll count 3K. + int diff = new_num_bytes - old_num_bytes; + total_bytes_allocated += diff; + current_bytes_allocated += diff; + UPDATE_PEAK(); +#endif return ptr; } @@ -49,8 +74,31 @@ void m_free(void *ptr, int num_bytes) { if (ptr != NULL) { free(ptr); } +#if MICROPY_MEM_STATS + current_bytes_allocated -= num_bytes; +#endif } int m_get_total_bytes_allocated(void) { +#if MICROPY_MEM_STATS return total_bytes_allocated; +#else + return -1; +#endif +} + +int m_get_current_bytes_allocated(void) { +#if MICROPY_MEM_STATS + return current_bytes_allocated; +#else + return -1; +#endif +} + +int m_get_peak_bytes_allocated(void) { +#if MICROPY_MEM_STATS + return peak_bytes_allocated; +#else + return -1; +#endif } diff --git a/py/map.h b/py/map.h index 8ee8429b5271ff4bf3584b8696f5682a580f110c..f8ca886aa49a8fbff56ac8c8fcb1fec6bd064857 100644 --- a/py/map.h +++ b/py/map.h @@ -23,10 +23,6 @@ typedef struct _mp_set_t { mp_obj_t *table; } mp_set_t; -// these are defined in runtime.c -mp_map_t *rt_get_map_locals(void); -void rt_set_map_locals(mp_map_t *m); - int get_doubling_prime_greater_or_equal_to(int x); void mp_map_init(mp_map_t *map, mp_map_kind_t kind, int n); mp_map_t *mp_map_new(mp_map_kind_t kind, int n); diff --git a/py/misc.h b/py/misc.h index 9f83ab526f0cb30022c9e6676f6af97506831329..153218ba2f8b6abf03eea3bb2b82d1d1a121cc1c 100644 --- a/py/misc.h +++ b/py/misc.h @@ -32,6 +32,8 @@ void *m_realloc(void *ptr, int old_num_bytes, int new_num_bytes); void m_free(void *ptr, int num_bytes); int m_get_total_bytes_allocated(void); +int m_get_current_bytes_allocated(void); +int m_get_peak_bytes_allocated(void); /** unichar / UTF-8 *********************************************/ diff --git a/py/mpconfig.h b/py/mpconfig.h new file mode 100644 index 0000000000000000000000000000000000000000..17c5a770c4967af083a5479cfece9d5c064653c4 --- /dev/null +++ b/py/mpconfig.h @@ -0,0 +1,13 @@ +// This file contains default configuration settings for MicroPython. +// You can override any of these options using mpconfigport.h file located +// in a directory of your port. + +#include <mpconfigport.h> + +// Any options not explicitly set in mpconfigport.h will get default +// values below. + +// Whether to collect memory allocation stats +#ifndef MICROPY_MEM_STATS +#define MICROPY_MEM_STATS (1) +#endif diff --git a/py/obj.h b/py/obj.h index 6a0cefd915aef777289ec4123af27995d18720db..7b4b0656f2f8ce94d9c35ca73cab0eae50abfb46 100644 --- a/py/obj.h +++ b/py/obj.h @@ -215,11 +215,14 @@ mp_obj_t mp_obj_dict_store(mp_obj_t self_in, mp_obj_t key, mp_obj_t value); void mp_obj_set_store(mp_obj_t self_in, mp_obj_t item); // functions -typedef struct _mp_obj_fun_native_t { // need this so we can define static objects +typedef struct _mp_obj_fun_native_t { // need this so we can define const objects (to go in ROM) mp_obj_base_t base; machine_uint_t n_args_min; // inclusive machine_uint_t n_args_max; // inclusive void *fun; + // TODO add mp_map_t *globals + // for const function objects, make an empty, const map + // such functions won't be able to access the global scope, but that's probably okay } mp_obj_fun_native_t; extern const mp_obj_type_t fun_native_type; extern const mp_obj_type_t fun_bc_type; diff --git a/py/objfun.c b/py/objfun.c index cefc9a95fe36888e4164dd4d3b36e523c51ac936..e998bd28d261d39610c853ec51cc3c2e2ce3969d 100644 --- a/py/objfun.c +++ b/py/objfun.c @@ -7,6 +7,7 @@ #include "misc.h" #include "mpconfig.h" #include "obj.h" +#include "map.h" #include "runtime.h" #include "bc.h" @@ -129,9 +130,10 @@ mp_obj_t rt_make_function_var_between(int n_args_min, int n_args_max, mp_fun_var typedef struct _mp_obj_fun_bc_t { mp_obj_base_t base; - int n_args; - uint n_state; - const byte *code; + mp_map_t *globals; // the context within which this function was defined + int n_args; // number of arguments this function takes + uint n_state; // total state size for the executing function (incl args, locals, stack) + const byte *bytecode; // bytecode for the function } mp_obj_fun_bc_t; // args are in reverse order in the array @@ -142,15 +144,17 @@ mp_obj_t fun_bc_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) { nlr_jump(mp_obj_new_exception_msg_2_args(rt_q_TypeError, "function takes %d positional arguments but %d were given", (const char*)(machine_int_t)self->n_args, (const char*)(machine_int_t)n_args)); } - return mp_execute_byte_code(self->code, args, n_args, self->n_state); -} - -void mp_obj_fun_bc_get(mp_obj_t self_in, int *n_args, uint *n_state, const byte **code) { - assert(MP_OBJ_IS_TYPE(self_in, &fun_bc_type)); - mp_obj_fun_bc_t *self = self_in; - *n_args = self->n_args; - *n_state = self->n_state; - *code = self->code; + // optimisation: allow the compiler to optimise this tail call for + // the common case when the globals don't need to be changed + mp_map_t *old_globals = rt_globals_get(); + if (self->globals == old_globals) { + return mp_execute_byte_code(self->bytecode, args, n_args, self->n_state); + } else { + rt_globals_set(self->globals); + mp_obj_t result = mp_execute_byte_code(self->bytecode, args, n_args, self->n_state); + rt_globals_set(old_globals); + return result; + } } const mp_obj_type_t fun_bc_type = { @@ -170,12 +174,21 @@ const mp_obj_type_t fun_bc_type = { mp_obj_t mp_obj_new_fun_bc(int n_args, uint n_state, const byte *code) { mp_obj_fun_bc_t *o = m_new_obj(mp_obj_fun_bc_t); o->base.type = &fun_bc_type; + o->globals = rt_globals_get(); o->n_args = n_args; o->n_state = n_state; - o->code = code; + o->bytecode = code; return o; } +void mp_obj_fun_bc_get(mp_obj_t self_in, int *n_args, uint *n_state, const byte **code) { + assert(MP_OBJ_IS_TYPE(self_in, &fun_bc_type)); + mp_obj_fun_bc_t *self = self_in; + *n_args = self->n_args; + *n_state = self->n_state; + *code = self->bytecode; +} + /******************************************************************************/ /* inline assembler functions */ diff --git a/py/runtime.c b/py/runtime.c index 3fae61f6fe91d64432fb29159f141f1cfe848e30..3144321f3a4cb55db25d5bbc0bb4c86f13830d08 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -281,14 +281,6 @@ void rt_assign_inline_asm_code(int unique_code_id, void *fun, uint len, int n_ar #endif } -mp_map_t *rt_get_map_locals(void) { - return map_locals; -} - -void rt_set_map_locals(mp_map_t *m) { - map_locals = m; -} - static bool fit_small_int(mp_small_int_t o) { return true; } @@ -479,6 +471,16 @@ mp_obj_t rt_unary_op(int op, mp_obj_t arg) { mp_obj_t rt_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) { DEBUG_OP_printf("binary %d %p %p\n", op, lhs, rhs); + + // TODO correctly distinguish inplace operators for mutable objects + // lookup logic that CPython uses for +=: + // check for implemented += + // then check for implemented + + // then check for implemented seq.inplace_concat + // then check for implemented seq.concat + // then fail + // note that list does not implement + or +=, so that inplace_concat is reached first for += + if (MP_OBJ_IS_SMALL_INT(lhs) && MP_OBJ_IS_SMALL_INT(rhs)) { mp_small_int_t lhs_val = MP_OBJ_SMALL_INT_VALUE(lhs); mp_small_int_t rhs_val = MP_OBJ_SMALL_INT_VALUE(rhs); @@ -786,6 +788,7 @@ mp_obj_t rt_load_attr(mp_obj_t base, qstr attr) { } else if (MP_OBJ_IS_TYPE(base, &instance_type)) { return mp_obj_instance_load_attr(base, attr); } else if (MP_OBJ_IS_TYPE(base, &module_type)) { + DEBUG_OP_printf("lookup module map %p\n", mp_obj_module_get_globals(base)); mp_map_elem_t *elem = mp_qstr_map_lookup(mp_obj_module_get_globals(base), attr, false); if (elem == NULL) { // TODO what about generic method lookup? @@ -913,6 +916,24 @@ mp_obj_t rt_import_from(mp_obj_t module, qstr name) { return x; } +mp_map_t *rt_locals_get(void) { + return map_locals; +} + +void rt_locals_set(mp_map_t *m) { + DEBUG_OP_printf("rt_locals_set(%p)\n", m); + map_locals = m; +} + +mp_map_t *rt_globals_get(void) { + return map_globals; +} + +void rt_globals_set(mp_map_t *m) { + DEBUG_OP_printf("rt_globals_set(%p)\n", m); + map_globals = m; +} + // these must correspond to the respective enum void *const rt_fun_table[RT_F_NUMBER_OF] = { rt_load_const_dec, diff --git a/py/runtime.h b/py/runtime.h index 37b036852fd49902192853731eaffa8cd3141039..cf9180275e449772303cdc0c193f8a636a04e716 100644 --- a/py/runtime.h +++ b/py/runtime.h @@ -57,3 +57,9 @@ mp_obj_t rt_getiter(mp_obj_t o); mp_obj_t rt_iternext(mp_obj_t o); mp_obj_t rt_import_name(qstr name, mp_obj_t fromlist, mp_obj_t level); mp_obj_t rt_import_from(mp_obj_t module, qstr name); + +struct _mp_map_t; +struct _mp_map_t *rt_locals_get(void); +void rt_locals_set(struct _mp_map_t *m); +struct _mp_map_t *rt_globals_get(void); +void rt_globals_set(struct _mp_map_t *m); diff --git a/py/showbc.c b/py/showbc.c index 15cd0564270a681041136f37d39f51018ad8cee2..a3bfa2833b191ae9efa0c10191166489e90ae2c9 100644 --- a/py/showbc.c +++ b/py/showbc.c @@ -142,12 +142,10 @@ void mp_show_byte_code(const byte *ip, int len) { printf("STORE_NAME %s", qstr_str(qstr)); break; - /* case MP_BC_STORE_GLOBAL: DECODE_QSTR; - rt_store_global(qstr, POP()); + printf("STORE_GLOBAL %s", qstr_str(qstr)); break; - */ case MP_BC_STORE_ATTR: DECODE_QSTR; @@ -343,6 +341,16 @@ void mp_show_byte_code(const byte *ip, int len) { printf("YIELD_VALUE"); break; + case MP_BC_IMPORT_NAME: + DECODE_QSTR; + printf("IMPORT NAME %s", qstr_str(qstr)); + break; + + case MP_BC_IMPORT_FROM: + DECODE_QSTR; + printf("IMPORT NAME %s", qstr_str(qstr)); + break; + default: printf("code %p, byte code 0x%02x not implemented\n", ip, op); assert(0); diff --git a/py/vstr.c b/py/vstr.c index 98cf0272505f516e6e654cdbfab15b92b62dd45a..80841b24cae972bb666048c09cdbe36d1233b198 100644 --- a/py/vstr.c +++ b/py/vstr.c @@ -167,8 +167,12 @@ void vstr_vprintf(vstr_t *vstr, const char *fmt, va_list ap) { while (1) { // try to print in the allocated space + // need to make a copy of the va_list because we may call vsnprintf multiple times int size = vstr->alloc - vstr->len; - int n = vsnprintf(vstr->buf + vstr->len, size, fmt, ap); + va_list ap2; + va_copy(ap2, ap); + int n = vsnprintf(vstr->buf + vstr->len, size, fmt, ap2); + va_end(ap2); // if that worked, return if (n > -1 && n < size) { diff --git a/stm/Makefile b/stm/Makefile index 6868f85ba7d66c23093b65bcb7a426c9e2b0c28f..d6c77e2bd7258b5f1317ca48998463c3b42ced8c 100644 --- a/stm/Makefile +++ b/stm/Makefile @@ -82,6 +82,7 @@ PY_O = \ objtuple.o \ objtype.o \ builtin.o \ + builtinimport.o \ vm.o \ repl.o \ @@ -147,7 +148,7 @@ OBJ = $(addprefix $(BUILD)/, $(SRC_C:.c=.o) $(SRC_S:.s=.o) $(PY_O) $(SRC_FATFS:. all: $(BUILD) $(BUILD)/flash.dfu $(BUILD)/flash.dfu: $(BUILD)/flash0.bin $(BUILD)/flash1.bin - python2 $(DFU) -b 0x08000000:$(BUILD)/flash0.bin -b 0x08020000:$(BUILD)/flash1.bin $@ + python $(DFU) -b 0x08000000:$(BUILD)/flash0.bin -b 0x08020000:$(BUILD)/flash1.bin $@ $(BUILD)/flash0.bin: $(BUILD)/flash.elf arm-none-eabi-objcopy -O binary -j .isr_vector $^ $@ @@ -186,7 +187,7 @@ $(BUILD)/%.o: $(PYSRC)/%.s $(BUILD)/%.o: $(PYSRC)/%.S $(CC) $(CFLAGS) -c -o $@ $< -$(BUILD)/%.o: $(PYSRC)/%.c mpconfig.h +$(BUILD)/%.o: $(PYSRC)/%.c mpconfigport.h $(CC) $(CFLAGS) -c -o $@ $< $(BUILD)/emitnthumb.o: $(PYSRC)/emitnative.c $(PYSRC)/emit.h diff --git a/stm/audio.c b/stm/audio.c index 38e0012b41222e4b8ee4902bd561fe41e5861318..34adefbcd6e02717e2b8cff8693f9016bd5f259d 100644 --- a/stm/audio.c +++ b/stm/audio.c @@ -8,7 +8,6 @@ #include "misc.h" #include "mpconfig.h" #include "parse.h" -#include "compile.h" #include "obj.h" #include "runtime.h" diff --git a/stm/lcd.c b/stm/lcd.c index 9f5a157d05a8fef7e17403f9d0f903e73be95ad9..70d1a26423e3acebf3de44559731d9dc460a218b 100644 --- a/stm/lcd.c +++ b/stm/lcd.c @@ -5,7 +5,6 @@ #include "misc.h" #include "mpconfig.h" #include "parse.h" -#include "compile.h" #include "obj.h" #include "runtime.h" diff --git a/stm/lexerstm.c b/stm/lexerstm.c index dfb84cca137370f452ca8260345cba7f23129d69..661dfb016032d08562ec4eb6758998ee9d9a700a 100644 --- a/stm/lexerstm.c +++ b/stm/lexerstm.c @@ -61,3 +61,8 @@ mp_lexer_t *mp_lexer_new_from_file(const char *filename, mp_lexer_file_buf_t *fb fb->pos = 0; return mp_lexer_new(filename, fb, (mp_lexer_stream_next_char_t)file_buf_next_char, (mp_lexer_stream_close_t)file_buf_close); } + +mp_lexer_t *mp_import_open_file(qstr mod_name) { + printf("import not implemented\n"); + return NULL; +} diff --git a/stm/main.c b/stm/main.c index f16ce252d2e1ff6e47e3abadbc3a01196caafafb..e8db2be2ca4d364098f54080d5ecf4b24329eb30 100644 --- a/stm/main.c +++ b/stm/main.c @@ -20,8 +20,8 @@ #include "lexer.h" #include "lexerstm.h" #include "parse.h" -#include "compile.h" #include "obj.h" +#include "compile.h" #include "runtime0.h" #include "runtime.h" #include "repl.h" @@ -489,25 +489,22 @@ void do_repl(void) { mp_lexer_free(lex); if (pn != MP_PARSE_NODE_NULL) { - bool comp_ok = mp_compile(pn, true); - if (comp_ok) { - mp_obj_t module_fun = rt_make_function_from_id(1); - if (module_fun != mp_const_none) { - nlr_buf_t nlr; - uint32_t start = sys_tick_counter; - if (nlr_push(&nlr) == 0) { - rt_call_function_0(module_fun); - nlr_pop(); - // optional timing - if (0) { - uint32_t ticks = sys_tick_counter - start; // TODO implement a function that does this properly - printf("(took %lu ms)\n", ticks); - } - } else { - // uncaught exception - mp_obj_print((mp_obj_t)nlr.ret_val); - printf("\n"); + mp_obj_t module_fun = mp_compile(pn, true); + if (module_fun != mp_const_none) { + nlr_buf_t nlr; + uint32_t start = sys_tick_counter; + if (nlr_push(&nlr) == 0) { + rt_call_function_0(module_fun); + nlr_pop(); + // optional timing + if (0) { + uint32_t ticks = sys_tick_counter - start; // TODO implement a function that does this properly + printf("(took %lu ms)\n", ticks); } + } else { + // uncaught exception + mp_obj_print((mp_obj_t)nlr.ret_val); + printf("\n"); } } } @@ -532,12 +529,7 @@ bool do_file(const char *filename) { return false; } - bool comp_ok = mp_compile(pn, false); - if (!comp_ok) { - return false; - } - - mp_obj_t module_fun = rt_make_function_from_id(1); + mp_obj_t module_fun = mp_compile(pn, false); if (module_fun == mp_const_none) { return false; } @@ -1133,17 +1125,15 @@ soft_reset: printf("pars;al=%u\n", m_get_total_bytes_allocated()); sys_tick_delay_ms(1000); //parse_node_show(pn, 0); - bool comp_ok = mp_compile(pn, false); + mp_obj_t module_fun = mp_compile(pn, false); printf("comp;al=%u\n", m_get_total_bytes_allocated()); sys_tick_delay_ms(1000); - if (!comp_ok) { + if (module_fun == mp_const_none) { printf("compile error\n"); } else { // execute it! - mp_obj_t module_fun = rt_make_function_from_id(1); - // flash once led_state(PYB_LED_G1, 1); sys_tick_delay_ms(100); diff --git a/stm/mpconfig.h b/stm/mpconfigport.h similarity index 96% rename from stm/mpconfig.h rename to stm/mpconfigport.h index 1f9529e11ba8df1afdb692e129061534878b9870..4cea332f3977f5c3206d5ee85523c5e8a08684e8 100644 --- a/stm/mpconfig.h +++ b/stm/mpconfigport.h @@ -1,3 +1,5 @@ +#include <stdint.h> + // options to control how Micro Python is built #define MICROPY_ENABLE_FLOAT (1) diff --git a/stm/pybwlan.c b/stm/pybwlan.c index 6341d0676b63b161f6e5b74011b3c164e2084903..6988f1c848167f742acdd329a1fb988ee25891a8 100644 --- a/stm/pybwlan.c +++ b/stm/pybwlan.c @@ -18,7 +18,6 @@ #include "misc.h" #include "lexer.h" #include "parse.h" -#include "compile.h" #include "obj.h" #include "map.h" #include "runtime.h" diff --git a/stm/timer.c b/stm/timer.c index 28148b0c1b91f44c1c786e613147a9fbaf086b24..2605d4b4bcc9dcd636102dba6508d7eb71a47046 100644 --- a/stm/timer.c +++ b/stm/timer.c @@ -9,7 +9,6 @@ #include "misc.h" #include "mpconfig.h" #include "parse.h" -#include "compile.h" #include "obj.h" #include "runtime.h" diff --git a/tests/basics/run-tests b/tests/basics/run-tests index 1b027c3e9ffadb943680b90c0ec4134b03abbeeb..72e69c2d8eff1cddfab9d83ebb76c8d91677140f 100755 --- a/tests/basics/run-tests +++ b/tests/basics/run-tests @@ -11,7 +11,7 @@ namefailed= for infile in tests/*.py do - basename=`basename $infile .c` + basename=`basename $infile .py` outfile=${basename}.out expfile=${basename}.exp diff --git a/tests/basics/tests/import1a.py b/tests/basics/tests/import1a.py new file mode 100644 index 0000000000000000000000000000000000000000..16b2d4d30f61c9170727a9a6d64969f01960a4a1 --- /dev/null +++ b/tests/basics/tests/import1a.py @@ -0,0 +1,2 @@ +import import1b +print(import1b.var) diff --git a/tests/basics/tests/import1b.py b/tests/basics/tests/import1b.py new file mode 100644 index 0000000000000000000000000000000000000000..80479088f0ee45b3b79a74e04e3e6fcf8eaabfad --- /dev/null +++ b/tests/basics/tests/import1b.py @@ -0,0 +1 @@ +var = 123 diff --git a/tools/dfu.py b/tools/dfu.py index 875cc5c6e9114cbc4fbf47125cec84ba848e93d1..54b602438b38119c87e8a3a834faf174c6e56efa 100755 --- a/tools/dfu.py +++ b/tools/dfu.py @@ -20,11 +20,11 @@ def compute_crc(data): return 0xFFFFFFFF & -zlib.crc32(data) -1 def parse(file,dump_images=False): - print 'File: "%s"' % file + print ('File: "%s"' % file) data = open(file,'rb').read() crc = compute_crc(data[:-4]) prefix, data = consume('<5sBIB',data,'signature version size targets') - print '%(signature)s v%(version)d, image size: %(size)d, targets: %(targets)d' % prefix + print ('%(signature)s v%(version)d, image size: %(size)d, targets: %(targets)d' % prefix) for t in range(prefix['targets']): tprefix, data = consume('<6sBI255s2I',data,'signature altsetting named name size elements') tprefix['num'] = t @@ -32,40 +32,40 @@ def parse(file,dump_images=False): tprefix['name'] = cstring(tprefix['name']) else: tprefix['name'] = '' - print '%(signature)s %(num)d, alt setting: %(altsetting)s, name: "%(name)s", size: %(size)d, elements: %(elements)d' % tprefix + print ('%(signature)s %(num)d, alt setting: %(altsetting)s, name: "%(name)s", size: %(size)d, elements: %(elements)d' % tprefix) tsize = tprefix['size'] target, data = data[:tsize], data[tsize:] for e in range(tprefix['elements']): eprefix, target = consume('<2I',target,'address size') eprefix['num'] = e - print ' %(num)d, address: 0x%(address)08x, size: %(size)d' % eprefix + print (' %(num)d, address: 0x%(address)08x, size: %(size)d' % eprefix) esize = eprefix['size'] image, target = target[:esize], target[esize:] if dump_images: out = '%s.target%d.image%d.bin' % (file,t,e) open(out,'wb').write(image) - print ' DUMPED IMAGE TO "%s"' % out + print (' DUMPED IMAGE TO "%s"' % out) if len(target): - print "target %d: PARSE ERROR" % t + print ("target %d: PARSE ERROR" % t) suffix = named(struct.unpack('<4H3sBI',data[:16]),'device product vendor dfu ufd len crc') - print 'usb: %(vendor)04x:%(product)04x, device: 0x%(device)04x, dfu: 0x%(dfu)04x, %(ufd)s, %(len)d, 0x%(crc)08x' % suffix + print ('usb: %(vendor)04x:%(product)04x, device: 0x%(device)04x, dfu: 0x%(dfu)04x, %(ufd)s, %(len)d, 0x%(crc)08x' % suffix) if crc != suffix['crc']: - print "CRC ERROR: computed crc32 is 0x%08x" % crc + print ("CRC ERROR: computed crc32 is 0x%08x" % crc) data = data[16:] if data: - print "PARSE ERROR" + print ("PARSE ERROR") def build(file,targets,device=DEFAULT_DEVICE): - data = '' + data = b'' for t,target in enumerate(targets): - tdata = '' + tdata = b'' for image in target: tdata += struct.pack('<2I',image['address'],len(image['data']))+image['data'] - tdata = struct.pack('<6sBI255s2I','Target',0,1,'ST...',len(tdata),len(target)) + tdata + tdata = struct.pack('<6sBI255s2I',b'Target',0,1, b'ST...',len(tdata),len(target)) + tdata data += tdata - data = struct.pack('<5sBIB','DfuSe',1,len(data)+11,len(targets)) + data + data = struct.pack('<5sBIB',b'DfuSe',1,len(data)+11,len(targets)) + data v,d=map(lambda x: int(x,0) & 0xFFFF, device.split(':',1)) - data += struct.pack('<4H3sB',0,d,v,0x011a,'UFD',16) + data += struct.pack('<4H3sB',0,d,v,0x011a,b'UFD',16) crc = compute_crc(data) data += struct.pack('<I',crc) open(file,'wb').write(data) @@ -89,15 +89,15 @@ if __name__=="__main__": try: address,binfile = arg.split(':',1) except ValueError: - print "Address:file couple '%s' invalid." % arg + print ("Address:file couple '%s' invalid." % arg) sys.exit(1) try: address = int(address,0) & 0xFFFFFFFF except ValueError: - print "Address %s invalid." % address + print ("Address %s invalid." % address) sys.exit(1) if not os.path.isfile(binfile): - print "Unreadable file '%s'." % binfile + print ("Unreadable file '%s'." % binfile) sys.exit(1) target.append({ 'address': address, 'data': open(binfile,'rb').read() }) outfile = args[0] @@ -107,13 +107,13 @@ if __name__=="__main__": try: v,d=map(lambda x: int(x,0) & 0xFFFF, device.split(':',1)) except: - print "Invalid device '%s'." % device + print ("Invalid device '%s'." % device) sys.exit(1) build(outfile,[target],device) elif len(args)==1: infile = args[0] if not os.path.isfile(infile): - print "Unreadable file '%s'." % infile + print ("Unreadable file '%s'." % infile) sys.exit(1) parse(infile, dump_images=options.dump_images) else: diff --git a/unix-cpy/Makefile b/unix-cpy/Makefile index 9399a765c3aa131ea2e7a213e8f9e8dffbd63408..48c31794600011cccbb833362fa36e2555b4fd59 100644 --- a/unix-cpy/Makefile +++ b/unix-cpy/Makefile @@ -47,6 +47,7 @@ PY_O = \ objtuple.o \ objtype.o \ builtin.o \ + builtinimport.o \ vm.o \ showbc.o \ repl.o \ @@ -67,7 +68,7 @@ $(BUILD)/%.o: %.c $(BUILD)/%.o: $(PYSRC)/%.S $(CC) $(CFLAGS) -c -o $@ $< -$(BUILD)/%.o: $(PYSRC)/%.c mpconfig.h +$(BUILD)/%.o: $(PYSRC)/%.c mpconfigport.h $(CC) $(CFLAGS) -c -o $@ $< $(BUILD)/emitnx64.o: $(PYSRC)/emitnative.c $(PYSRC)/emit.h @@ -80,7 +81,7 @@ $(BUILD)/emitnthumb.o: $(PYSRC)/emitnative.c $(PYSRC)/emit.h $(BUILD)/vm.o: $(PYSRC)/vm.c $(CC) $(CFLAGS) -O3 -c -o $@ $< -$(BUILD)/main.o: mpconfig.h +$(BUILD)/main.o: mpconfigport.h $(BUILD)/parse.o: $(PYSRC)/grammar.h $(BUILD)/compile.o: $(PYSRC)/grammar.h $(BUILD)/emitcpy.o: $(PYSRC)/emit.h diff --git a/unix-cpy/main.c b/unix-cpy/main.c index 2b59df4f374e09966a55cfbb78c3a79f166aff7a..eba97f527ba1e85b33c344e9181345a1d50bfb7a 100644 --- a/unix-cpy/main.c +++ b/unix-cpy/main.c @@ -8,8 +8,8 @@ #include "lexer.h" #include "lexerunix.h" #include "parse.h" -#include "compile.h" #include "obj.h" +#include "compile.h" #include "runtime0.h" #include "runtime.h" @@ -37,10 +37,10 @@ void do_file(const char *file) { //printf("----------------\n"); //parse_node_show(pn, 0); //printf("----------------\n"); - bool comp_ok = mp_compile(pn, false); + mp_obj_t module_fun = mp_compile(pn, false); //printf("----------------\n"); - if (!comp_ok) { + if (module_fun == mp_const_none) { printf("compile error\n"); } } diff --git a/unix-cpy/mpconfig.h b/unix-cpy/mpconfigport.h similarity index 100% rename from unix-cpy/mpconfig.h rename to unix-cpy/mpconfigport.h diff --git a/unix/Makefile b/unix/Makefile index b8955d11a834e3cfa172acd4d8555edfd65b77c8..fd5b6b43e0fc0928f7eb5be508e7fbaaa3fedcbb 100644 --- a/unix/Makefile +++ b/unix/Makefile @@ -54,6 +54,7 @@ PY_O = \ objtuple.o \ objtype.o \ builtin.o \ + builtinimport.o \ vm.o \ showbc.o \ repl.o \ @@ -78,7 +79,7 @@ $(BUILD)/%.o: %.c $(BUILD)/%.o: $(PYSRC)/%.S $(CC) $(CFLAGS) -c -o $@ $< -$(BUILD)/%.o: $(PYSRC)/%.c mpconfig.h +$(BUILD)/%.o: $(PYSRC)/%.c mpconfigport.h $(CC) $(CFLAGS) -c -o $@ $< $(BUILD)/emitnx64.o: $(PYSRC)/emitnative.c $(PYSRC)/emit.h @@ -91,7 +92,7 @@ $(BUILD)/emitnthumb.o: $(PYSRC)/emitnative.c $(PYSRC)/emit.h $(BUILD)/vm.o: $(PYSRC)/vm.c $(CC) $(CFLAGS) -O3 -c -o $@ $< -$(BUILD)/main.o: mpconfig.h +$(BUILD)/main.o: mpconfigport.h $(BUILD)/parse.o: $(PYSRC)/grammar.h $(BUILD)/compile.o: $(PYSRC)/grammar.h $(BUILD)/emitcpy.o: $(PYSRC)/emit.h diff --git a/unix/main.c b/unix/main.c index 376dbc0c045d3ab21d0ed93a9e4f52a37053d178..1aa3331202893ad5c69ed6c3eda25c7a026617ab 100644 --- a/unix/main.c +++ b/unix/main.c @@ -9,8 +9,8 @@ #include "lexer.h" #include "lexerunix.h" #include "parse.h" -#include "compile.h" #include "obj.h" +#include "compile.h" #include "runtime0.h" #include "runtime.h" #include "repl.h" @@ -85,19 +85,16 @@ static void do_repl(void) { if (pn != MP_PARSE_NODE_NULL) { //mp_parse_node_show(pn, 0); - bool comp_ok = mp_compile(pn, true); - if (comp_ok) { - mp_obj_t module_fun = rt_make_function_from_id(1); - if (module_fun != mp_const_none) { - nlr_buf_t nlr; - if (nlr_push(&nlr) == 0) { - rt_call_function_0(module_fun); - nlr_pop(); - } else { - // uncaught exception - mp_obj_print((mp_obj_t)nlr.ret_val); - printf("\n"); - } + mp_obj_t module_fun = mp_compile(pn, true); + if (module_fun != mp_const_none) { + nlr_buf_t nlr; + if (nlr_push(&nlr) == 0) { + rt_call_function_0(module_fun); + nlr_pop(); + } else { + // uncaught exception + mp_obj_print((mp_obj_t)nlr.ret_val); + printf("\n"); } } } @@ -105,6 +102,18 @@ static void do_repl(void) { } void do_file(const char *file) { + // hack: set dir for import based on where this file is + { + const char * s = strrchr(file, '/'); + if (s != NULL) { + int len = s - file; + char *dir = m_new(char, len + 1); + memcpy(dir, file, len); + dir[len] = '\0'; + mp_import_set_directory(dir); + } + } + mp_lexer_t *lex = mp_lexer_new_from_file(file); //const char *pysrc = "def f():\n x=x+1\n print(42)\n"; //mp_lexer_t *lex = mp_lexer_from_str_len("<>", pysrc, strlen(pysrc), false); @@ -130,7 +139,7 @@ void do_file(const char *file) { //printf("----------------\n"); //parse_node_show(pn, 0); //printf("----------------\n"); - bool comp_ok = mp_compile(pn, false); + mp_obj_t module_fun = mp_compile(pn, false); //printf("----------------\n"); #if MICROPY_EMIT_CPYTHON @@ -138,19 +147,16 @@ void do_file(const char *file) { printf("compile error\n"); } #else - if (1 && comp_ok) { + if (1 && module_fun != mp_const_none) { // execute it - mp_obj_t module_fun = rt_make_function_from_id(1); - if (module_fun != mp_const_none) { - nlr_buf_t nlr; - if (nlr_push(&nlr) == 0) { - rt_call_function_0(module_fun); - nlr_pop(); - } else { - // uncaught exception - mp_obj_print((mp_obj_t)nlr.ret_val); - printf("\n"); - } + nlr_buf_t nlr; + if (nlr_push(&nlr) == 0) { + rt_call_function_0(module_fun); + nlr_pop(); + } else { + // uncaught exception + mp_obj_print((mp_obj_t)nlr.ret_val); + printf("\n"); } } #endif diff --git a/unix/mpconfig.h b/unix/mpconfigport.h similarity index 100% rename from unix/mpconfig.h rename to unix/mpconfigport.h