1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593
6594
6595
6596
6597
6598
6599
6600
6601
6602
6603
6604
6605
6606
6607
6608
6609
6610
6611
6612
6613
6614
6615
6616
6617
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674
6675
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
6687
6688
6689
6690
6691
6692
6693
6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704
6705
6706
6707
6708
6709
6710
6711
6712
6713
6714
6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
6762
6763
6764
6765
6766
6767
6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807
6808
6809
6810
6811
6812
6813
6814
6815
6816
6817
6818
6819
6820
6821
6822
6823
6824
6825
6826
6827
6828
6829
6830
6831
6832
6833
6834
6835
6836
6837
6838
6839
6840
6841
6842
6843
6844
6845
6846
6847
6848
6849
6850
6851
6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
6862
6863
6864
6865
6866
6867
6868
6869
6870
6871
6872
6873
6874
6875
6876
6877
6878
6879
6880
6881
6882
6883
6884
6885
6886
6887
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
6913
6914
6915
6916
6917
6918
6919
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
6931
6932
6933
6934
6935
6936
6937
6938
6939
6940
6941
6942
6943
6944
6945
6946
6947
6948
6949
6950
6951
6952
6953
6954
6955
6956
6957
6958
6959
6960
6961
6962
6963
6964
6965
6966
6967
6968
6969
6970
6971
6972
6973
6974
6975
6976
6977
6978
6979
6980
6981
6982
6983
6984
6985
6986
6987
6988
6989
6990
6991
6992
6993
6994
6995
6996
6997
6998
6999
7000
7001
7002
7003
7004
7005
7006
7007
7008
7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
7028
7029
7030
7031
7032
7033
7034
7035
7036
7037
7038
7039
7040
7041
7042
7043
7044
7045
7046
7047
7048
7049
7050
7051
7052
7053
7054
7055
7056
7057
7058
7059
7060
7061
7062
7063
7064
7065
7066
7067
7068
7069
7070
7071
7072
7073
7074
7075
7076
7077
7078
7079
7080
7081
7082
7083
7084
7085
7086
7087
7088
7089
7090
7091
7092
7093
7094
7095
7096
7097
7098
7099
7100
7101
7102
7103
7104
7105
7106
7107
7108
7109
7110
7111
7112
7113
7114
7115
7116
7117
7118
7119
7120
7121
7122
7123
7124
7125
7126
7127
7128
7129
7130
7131
7132
7133
7134
7135
7136
7137
7138
7139
7140
7141
7142
7143
7144
7145
7146
7147
7148
7149
7150
7151
7152
7153
7154
7155
7156
7157
7158
7159
7160
7161
7162
7163
7164
7165
7166
7167
7168
7169
7170
7171
7172
7173
7174
7175
7176
7177
7178
7179
7180
7181
7182
7183
7184
7185
7186
7187
7188
7189
7190
7191
7192
7193
7194
7195
7196
7197
7198
7199
7200
7201
7202
7203
7204
7205
7206
7207
7208
7209
7210
7211
7212
7213
7214
7215
7216
7217
7218
7219
7220
7221
7222
7223
7224
7225
7226
7227
7228
7229
7230
7231
7232
7233
7234
7235
7236
7237
7238
7239
7240
7241
7242
7243
7244
7245
7246
7247
7248
7249
7250
7251
7252
7253
7254
7255
7256
7257
7258
7259
7260
7261
7262
7263
7264
7265
7266
7267
7268
7269
7270
7271
7272
7273
7274
7275
7276
7277
7278
7279
7280
7281
7282
7283
7284
7285
7286
7287
7288
7289
7290
7291
7292
7293
7294
7295
7296
7297
7298
7299
7300
7301
7302
7303
7304
7305
7306
7307
7308
7309
7310
7311
7312
7313
7314
7315
7316
7317
7318
7319
7320
7321
7322
7323
7324
7325
7326
7327
7328
7329
7330
7331
7332
7333
7334
7335
7336
7337
7338
7339
7340
7341
7342
7343
7344
7345
7346
7347
7348
7349
7350
7351
7352
7353
7354
7355
7356
7357
7358
7359
7360
7361
7362
7363
7364
7365
7366
7367
7368
7369
7370
7371
7372
7373
7374
7375
7376
7377
7378
7379
7380
7381
7382
7383
7384
7385
7386
7387
7388
7389
7390
7391
7392
7393
7394
7395
7396
7397
7398
7399
7400
7401
7402
7403
7404
7405
7406
7407
7408
7409
7410
7411
7412
7413
7414
7415
7416
7417
7418
7419
7420
7421
7422
7423
7424
7425
7426
7427
7428
7429
7430
7431
7432
7433
7434
7435
7436
7437
7438
7439
7440
7441
7442
7443
7444
7445
7446
7447
7448
7449
7450
7451
7452
7453
7454
7455
7456
7457
7458
7459
7460
7461
7462
7463
7464
7465
7466
7467
7468
7469
7470
7471
7472
7473
7474
7475
7476
7477
7478
7479
7480
7481
7482
7483
7484
7485
7486
7487
7488
7489
7490
7491
7492
7493
7494
7495
7496
7497
7498
7499
7500
7501
7502
7503
7504
7505
7506
7507
7508
7509
7510
7511
7512
7513
7514
7515
7516
7517
7518
7519
7520
7521
7522
7523
7524
7525
7526
7527
7528
7529
7530
7531
7532
7533
7534
7535
7536
7537
7538
7539
7540
7541
7542
7543
7544
7545
7546
7547
7548
7549
7550
7551
7552
7553
7554
7555
7556
7557
7558
7559
7560
7561
7562
7563
7564
7565
7566
7567
7568
7569
7570
7571
7572
7573
7574
7575
7576
7577
7578
7579
7580
7581
7582
7583
7584
7585
7586
7587
7588
7589
7590
7591
7592
7593
7594
7595
7596
7597
7598
7599
7600
7601
7602
7603
7604
7605
7606
7607
7608
7609
7610
7611
7612
7613
7614
7615
7616
7617
7618
7619
7620
7621
7622
7623
7624
7625
7626
7627
7628
7629
7630
7631
7632
7633
7634
7635
7636
7637
7638
7639
7640
7641
7642
7643
7644
7645
7646
7647
7648
7649
7650
7651
7652
7653
7654
7655
7656
7657
7658
7659
7660
7661
7662
7663
7664
7665
7666
7667
7668
7669
7670
7671
7672
7673
7674
7675
7676
7677
7678
7679
7680
7681
7682
7683
7684
7685
7686
7687
7688
7689
7690
7691
7692
7693
7694
7695
7696
7697
7698
7699
7700
7701
7702
7703
7704
7705
7706
7707
7708
7709
7710
7711
7712
7713
7714
7715
7716
7717
7718
7719
7720
7721
7722
7723
7724
7725
7726
7727
7728
7729
7730
7731
7732
7733
7734
7735
7736
7737
7738
7739
7740
7741
7742
7743
7744
7745
7746
7747
7748
7749
7750
7751
7752
7753
7754
7755
7756
7757
7758
7759
7760
7761
7762
7763
7764
7765
7766
7767
7768
7769
7770
7771
7772
7773
7774
7775
7776
7777
7778
7779
7780
7781
7782
7783
7784
7785
7786
7787
7788
7789
7790
7791
7792
7793
7794
7795
7796
7797
7798
7799
7800
7801
7802
7803
7804
7805
7806
7807
7808
7809
7810
7811
7812
7813
7814
7815
7816
7817
7818
7819
7820
7821
7822
7823
7824
7825
7826
7827
7828
7829
7830
7831
7832
7833
7834
7835
7836
7837
7838
7839
7840
7841
7842
7843
7844
7845
7846
7847
7848
7849
7850
7851
7852
7853
7854
7855
7856
7857
7858
7859
7860
7861
7862
7863
7864
7865
7866
7867
7868
7869
7870
7871
7872
7873
7874
7875
7876
7877
7878
7879
7880
7881
7882
7883
7884
7885
7886
7887
7888
7889
7890
7891
7892
7893
7894
7895
7896
7897
7898
7899
7900
7901
7902
7903
7904
7905
7906
7907
7908
7909
7910
7911
7912
7913
7914
7915
7916
7917
7918
7919
7920
7921
7922
7923
7924
7925
7926
7927
7928
7929
7930
7931
7932
7933
7934
7935
7936
7937
7938
7939
7940
7941
7942
7943
7944
7945
7946
7947
7948
7949
7950
7951
7952
7953
7954
7955
7956
7957
7958
7959
7960
7961
7962
7963
7964
7965
7966
7967
7968
7969
7970
7971
7972
7973
7974
7975
7976
7977
7978
7979
7980
7981
7982
7983
7984
7985
7986
7987
7988
7989
7990
7991
7992
7993
7994
7995
7996
7997
7998
7999
8000
8001
8002
8003
8004
8005
8006
8007
8008
8009
8010
8011
8012
8013
8014
8015
8016
8017
8018
8019
8020
8021
8022
8023
8024
8025
8026
8027
8028
8029
8030
8031
8032
8033
8034
8035
8036
8037
8038
8039
8040
8041
8042
8043
8044
8045
8046
8047
8048
8049
8050
8051
8052
8053
8054
8055
8056
8057
8058
8059
8060
8061
8062
8063
8064
8065
8066
8067
8068
8069
8070
8071
8072
8073
8074
8075
8076
8077
8078
8079
8080
8081
8082
8083
8084
8085
8086
8087
8088
8089
8090
8091
8092
8093
8094
8095
8096
8097
8098
8099
8100
8101
8102
8103
8104
8105
8106
8107
8108
8109
8110
8111
8112
8113
8114
8115
8116
8117
8118
8119
8120
8121
8122
8123
8124
8125
8126
8127
8128
8129
8130
8131
8132
8133
8134
8135
8136
8137
8138
8139
8140
8141
8142
8143
8144
8145
8146
8147
8148
8149
8150
8151
8152
8153
8154
8155
8156
8157
8158
8159
8160
8161
8162
8163
8164
8165
8166
8167
8168
8169
8170
8171
8172
8173
8174
8175
8176
8177
8178
8179
8180
8181
8182
8183
8184
8185
8186
8187
8188
8189
8190
8191
8192
8193
8194
8195
8196
8197
8198
8199
8200
8201
8202
8203
8204
8205
8206
8207
8208
8209
8210
8211
8212
8213
8214
8215
8216
8217
8218
8219
8220
8221
8222
8223
8224
8225
8226
8227
8228
8229
8230
8231
8232
8233
8234
8235
8236
8237
8238
8239
8240
8241
8242
8243
8244
8245
8246
8247
8248
8249
8250
8251
8252
8253
8254
8255
8256
8257
8258
8259
8260
8261
8262
8263
8264
8265
8266
8267
8268
8269
8270
8271
8272
8273
8274
8275
8276
8277
8278
8279
8280
8281
8282
8283
8284
8285
8286
8287
8288
8289
8290
8291
8292
8293
8294
8295
8296
8297
8298
8299
8300
8301
8302
8303
8304
8305
8306
8307
8308
8309
8310
8311
8312
8313
8314
8315
8316
8317
8318
8319
8320
8321
8322
8323
8324
8325
8326
8327
8328
8329
8330
8331
8332
8333
8334
8335
8336
8337
8338
8339
8340
8341
8342
8343
8344
8345
8346
8347
8348
8349
8350
8351
8352
8353
8354
8355
8356
8357
8358
8359
8360
8361
8362
8363
8364
8365
8366
8367
8368
8369
8370
8371
8372
8373
8374
8375
8376
8377
8378
8379
8380
8381
8382
8383
8384
8385
8386
8387
8388
8389
8390
8391
8392
8393
8394
8395
8396
8397
8398
8399
8400
8401
8402
8403
8404
8405
8406
8407
8408
8409
8410
8411
8412
8413
8414
8415
8416
8417
8418
8419
8420
8421
8422
8423
8424
8425
8426
8427
8428
8429
8430
8431
8432
8433
8434
8435
8436
8437
8438
8439
8440
8441
8442
8443
8444
8445
8446
8447
8448
8449
8450
8451
8452
8453
8454
8455
8456
8457
8458
8459
8460
8461
8462
8463
8464
8465
8466
8467
8468
8469
8470
8471
8472
8473
8474
8475
8476
8477
8478
8479
8480
8481
8482
8483
8484
8485
8486
8487
8488
8489
8490
8491
8492
8493
8494
8495
8496
8497
8498
8499
8500
8501
8502
8503
8504
8505
8506
8507
8508
8509
8510
8511
8512
8513
8514
8515
8516
8517
8518
8519
8520
8521
8522
8523
8524
8525
8526
8527
8528
8529
8530
8531
8532
8533
8534
8535
8536
8537
8538
8539
8540
8541
8542
8543
8544
8545
8546
8547
8548
8549
8550
8551
8552
8553
8554
8555
8556
8557
8558
8559
8560
8561
8562
8563
8564
8565
8566
8567
8568
8569
8570
8571
8572
8573
8574
8575
8576
8577
8578
8579
8580
8581
8582
8583
8584
8585
8586
8587
8588
8589
8590
8591
8592
8593
8594
8595
8596
8597
8598
8599
8600
8601
8602
8603
8604
8605
8606
8607
8608
8609
8610
8611
8612
8613
8614
8615
8616
8617
8618
8619
8620
8621
8622
8623
8624
8625
8626
8627
8628
8629
8630
8631
8632
8633
8634
8635
8636
8637
8638
8639
8640
8641
8642
8643
8644
8645
8646
8647
8648
8649
8650
8651
8652
8653
8654
8655
8656
8657
8658
8659
8660
8661
8662
8663
8664
8665
8666
8667
8668
8669
8670
8671
8672
8673
8674
8675
8676
8677
8678
8679
8680
8681
8682
8683
8684
8685
8686
8687
8688
8689
8690
8691
8692
8693
8694
8695
8696
8697
8698
8699
8700
8701
8702
8703
8704
8705
8706
8707
8708
8709
8710
8711
8712
8713
8714
8715
8716
8717
8718
8719
8720
8721
8722
8723
8724
8725
8726
8727
8728
8729
8730
8731
8732
8733
8734
8735
8736
8737
8738
8739
8740
8741
8742
8743
8744
8745
8746
8747
8748
8749
8750
8751
8752
8753
8754
8755
8756
8757
8758
8759
8760
8761
8762
8763
8764
8765
8766
8767
8768
8769
8770
8771
8772
8773
8774
8775
8776
8777
8778
8779
8780
8781
8782
8783
8784
8785
8786
8787
8788
8789
8790
8791
8792
8793
8794
8795
8796
8797
8798
8799
8800
8801
8802
8803
8804
8805
8806
8807
8808
8809
8810
8811
8812
8813
8814
8815
8816
8817
8818
8819
8820
8821
8822
8823
8824
8825
8826
8827
8828
8829
8830
8831
8832
8833
8834
8835
8836
8837
8838
8839
8840
8841
8842
8843
8844
8845
8846
8847
8848
8849
8850
8851
8852
8853
8854
8855
8856
8857
8858
8859
8860
8861
8862
8863
8864
8865
8866
8867
8868
8869
8870
8871
8872
8873
8874
8875
8876
8877
8878
8879
8880
8881
8882
8883
8884
8885
8886
8887
8888
8889
8890
8891
8892
8893
8894
8895
8896
8897
8898
8899
8900
8901
8902
8903
8904
8905
8906
8907
8908
8909
8910
8911
8912
8913
8914
8915
8916
8917
8918
8919
8920
8921
8922
8923
8924
8925
8926
8927
8928
8929
8930
8931
8932
8933
8934
8935
8936
8937
8938
8939
8940
8941
8942
8943
8944
8945
8946
8947
8948
8949
8950
8951
8952
8953
8954
8955
8956
8957
8958
8959
8960
8961
8962
8963
8964
8965
8966
8967
8968
8969
8970
8971
8972
8973
8974
8975
8976
8977
8978
8979
8980
8981
8982
8983
8984
8985
8986
8987
8988
8989
8990
8991
8992
8993
8994
8995
8996
8997
8998
8999
9000
9001
9002
9003
9004
9005
9006
9007
9008
9009
9010
9011
9012
9013
9014
9015
9016
9017
9018
9019
9020
9021
9022
9023
9024
9025
9026
9027
9028
9029
9030
9031
9032
9033
9034
9035
9036
9037
9038
9039
9040
9041
9042
9043
9044
9045
9046
9047
9048
9049
9050
9051
9052
9053
9054
9055
9056
9057
9058
9059
9060
9061
9062
9063
9064
9065
9066
9067
9068
9069
9070
9071
9072
9073
9074
9075
9076
9077
9078
9079
9080
9081
9082
9083
9084
9085
9086
9087
9088
9089
9090
9091
9092
9093
9094
9095
9096
9097
9098
9099
9100
9101
9102
9103
9104
9105
9106
9107
9108
9109
9110
9111
9112
9113
9114
9115
9116
9117
9118
9119
9120
9121
9122
9123
9124
9125
9126
9127
9128
9129
9130
9131
9132
9133
9134
9135
9136
9137
9138
9139
9140
9141
9142
9143
9144
9145
9146
9147
9148
9149
9150
9151
9152
9153
9154
9155
9156
9157
9158
9159
9160
9161
9162
9163
9164
9165
9166
9167
9168
9169
9170
9171
9172
9173
9174
9175
9176
9177
9178
9179
9180
9181
9182
9183
9184
9185
9186
9187
9188
9189
9190
9191
9192
9193
9194
9195
9196
9197
9198
9199
9200
9201
9202
9203
9204
9205
9206
9207
9208
9209
9210
9211
9212
9213
9214
9215
9216
9217
9218
9219
9220
9221
9222
9223
9224
9225
9226
9227
9228
9229
9230
9231
9232
9233
9234
9235
9236
9237
9238
9239
9240
9241
9242
9243
9244
9245
9246
9247
9248
9249
9250
9251
9252
9253
9254
9255
9256
9257
9258
9259
9260
9261
9262
9263
9264
9265
9266
9267
9268
9269
9270
9271
9272
9273
9274
9275
9276
9277
9278
9279
9280
9281
9282
9283
9284
9285
9286
9287
9288
9289
9290
9291
9292
9293
9294
9295
9296
9297
9298
9299
9300
9301
9302
9303
9304
9305
9306
9307
9308
9309
9310
9311
9312
9313
9314
9315
9316
9317
9318
9319
9320
9321
9322
9323
9324
9325
9326
9327
9328
9329
9330
9331
9332
9333
9334
9335
9336
9337
9338
9339
9340
9341
9342
9343
9344
9345
9346
9347
9348
9349
9350
9351
9352
9353
9354
9355
9356
9357
9358
9359
9360
9361
9362
9363
9364
9365
9366
9367
9368
9369
9370
9371
9372
9373
9374
9375
9376
9377
9378
9379
9380
9381
9382
9383
9384
9385
9386
9387
9388
9389
9390
9391
9392
9393
9394
9395
9396
9397
9398
9399
9400
9401
9402
9403
9404
9405
9406
9407
9408
9409
9410
9411
9412
9413
9414
9415
9416
9417
9418
9419
9420
9421
9422
9423
9424
9425
9426
9427
9428
9429
9430
9431
9432
9433
9434
9435
9436
9437
9438
9439
9440
9441
9442
9443
9444
9445
9446
9447
9448
9449
9450
9451
9452
9453
9454
9455
9456
9457
9458
9459
9460
9461
9462
9463
9464
9465
9466
9467
9468
9469
9470
9471
9472
9473
9474
9475
9476
9477
9478
9479
9480
9481
9482
9483
9484
9485
9486
9487
9488
9489
9490
9491
9492
9493
9494
9495
9496
9497
9498
9499
9500
9501
9502
9503
9504
9505
9506
9507
9508
9509
9510
9511
9512
9513
9514
9515
9516
9517
9518
9519
9520
9521
9522
9523
9524
9525
9526
9527
9528
9529
9530
9531
9532
9533
9534
9535
9536
9537
9538
9539
9540
9541
9542
9543
9544
9545
9546
9547
9548
9549
9550
9551
9552
9553
9554
9555
9556
9557
9558
9559
9560
9561
9562
9563
9564
9565
9566
9567
9568
9569
9570
9571
9572
9573
9574
9575
9576
9577
9578
9579
9580
9581
9582
9583
9584
9585
9586
9587
9588
9589
9590
9591
9592
9593
9594
9595
9596
9597
9598
9599
9600
9601
9602
9603
9604
9605
9606
9607
9608
9609
9610
9611
9612
9613
9614
9615
9616
9617
9618
9619
9620
9621
9622
9623
9624
9625
9626
9627
9628
9629
9630
9631
9632
9633
9634
9635
9636
9637
9638
9639
9640
9641
9642
9643
9644
9645
9646
9647
9648
9649
9650
9651
9652
9653
9654
9655
9656
9657
9658
9659
9660
9661
9662
9663
9664
9665
9666
9667
9668
9669
9670
9671
9672
9673
9674
9675
9676
9677
9678
9679
9680
9681
9682
9683
9684
9685
9686
9687
9688
9689
9690
9691
9692
9693
9694
9695
9696
9697
9698
9699
9700
9701
9702
9703
9704
9705
9706
9707
9708
9709
9710
9711
9712
9713
9714
9715
9716
9717
9718
9719
9720
9721
9722
9723
9724
9725
9726
9727
9728
9729
9730
9731
9732
9733
9734
9735
9736
9737
9738
9739
9740
9741
9742
9743
9744
9745
9746
9747
9748
9749
9750
9751
9752
9753
9754
9755
9756
9757
9758
9759
9760
9761
9762
9763
9764
9765
9766
9767
9768
9769
9770
9771
9772
9773
9774
9775
9776
9777
9778
9779
9780
9781
9782
9783
9784
9785
9786
9787
9788
9789
9790
9791
9792
9793
9794
9795
9796
9797
9798
9799
9800
9801
9802
9803
9804
9805
9806
9807
9808
9809
9810
9811
9812
9813
9814
9815
9816
9817
9818
9819
9820
9821
9822
9823
9824
9825
9826
9827
9828
9829
9830
9831
9832
9833
9834
9835
9836
9837
9838
9839
9840
9841
9842
9843
9844
9845
9846
9847
9848
9849
9850
9851
9852
9853
9854
9855
9856
9857
9858
9859
9860
9861
9862
9863
9864
9865
9866
9867
9868
9869
9870
9871
9872
9873
9874
9875
9876
9877
9878
9879
9880
9881
9882
9883
9884
9885
9886
9887
9888
9889
9890
9891
9892
9893
9894
9895
9896
9897
9898
9899
9900
9901
9902
9903
9904
9905
9906
9907
9908
9909
9910
9911
9912
9913
9914
9915
9916
9917
9918
9919
9920
9921
9922
9923
9924
9925
9926
9927
9928
9929
9930
9931
9932
9933
9934
9935
9936
9937
9938
9939
9940
9941
9942
9943
9944
9945
9946
9947
9948
9949
9950
9951
9952
9953
9954
9955
9956
9957
9958
9959
9960
9961
9962
9963
9964
9965
9966
9967
9968
9969
9970
9971
9972
9973
9974
9975
9976
9977
9978
9979
9980
9981
9982
9983
9984
9985
9986
9987
9988
9989
9990
9991
9992
9993
9994
9995
9996
9997
9998
9999
10000
10001
10002
10003
10004
10005
10006
10007
10008
10009
10010
10011
10012
10013
10014
10015
10016
10017
10018
10019
10020
10021
10022
10023
10024
10025
10026
10027
10028
10029
10030
10031
10032
10033
10034
10035
10036
10037
10038
10039
10040
10041
10042
10043
10044
10045
10046
10047
10048
10049
10050
10051
10052
10053
10054
10055
10056
10057
10058
10059
10060
10061
10062
10063
10064
10065
10066
10067
10068
10069
10070
10071
10072
10073
10074
10075
10076
10077
10078
10079
10080
10081
10082
10083
10084
10085
10086
10087
10088
10089
10090
10091
10092
10093
10094
10095
10096
10097
10098
10099
10100
10101
10102
10103
10104
10105
10106
10107
10108
10109
10110
10111
10112
10113
10114
10115
10116
10117
10118
10119
10120
10121
10122
10123
10124
10125
10126
10127
10128
10129
10130
10131
10132
10133
10134
10135
10136
10137
10138
10139
10140
10141
10142
10143
10144
10145
10146
10147
10148
10149
10150
10151
10152
10153
10154
10155
10156
10157
10158
10159
10160
10161
10162
10163
10164
10165
10166
10167
10168
10169
10170
10171
10172
10173
10174
10175
10176
10177
10178
10179
10180
10181
10182
10183
10184
10185
10186
10187
10188
10189
10190
10191
10192
10193
10194
10195
10196
10197
10198
10199
10200
10201
10202
10203
10204
10205
10206
10207
10208
10209
10210
10211
10212
10213
10214
10215
10216
10217
10218
10219
10220
10221
10222
10223
10224
10225
10226
10227
10228
10229
10230
10231
10232
10233
10234
10235
10236
10237
10238
10239
10240
10241
10242
10243
10244
10245
10246
10247
10248
10249
10250
10251
10252
10253
10254
10255
10256
10257
10258
10259
10260
10261
10262
10263
10264
10265
10266
10267
10268
10269
10270
10271
10272
10273
10274
10275
10276
10277
10278
10279
10280
10281
10282
10283
10284
10285
10286
10287
10288
10289
10290
10291
10292
10293
10294
10295
10296
10297
10298
10299
10300
10301
10302
10303
10304
10305
10306
10307
10308
10309
10310
10311
10312
10313
10314
10315
10316
10317
10318
10319
10320
10321
10322
10323
10324
10325
10326
10327
10328
10329
10330
10331
10332
10333
10334
10335
10336
10337
10338
10339
10340
10341
10342
10343
10344
10345
10346
10347
10348
10349
10350
10351
10352
10353
10354
10355
10356
10357
10358
10359
10360
10361
10362
10363
10364
10365
10366
10367
10368
10369
10370
10371
10372
10373
10374
10375
10376
10377
10378
10379
10380
10381
10382
10383
10384
10385
10386
10387
10388
10389
10390
10391
10392
10393
10394
10395
10396
10397
10398
10399
10400
10401
10402
10403
10404
10405
10406
10407
10408
10409
10410
10411
10412
10413
10414
10415
10416
10417
10418
10419
10420
10421
10422
10423
10424
10425
10426
10427
10428
10429
10430
10431
10432
10433
10434
10435
10436
10437
10438
10439
10440
10441
10442
10443
10444
10445
10446
10447
10448
10449
10450
10451
10452
10453
10454
10455
10456
10457
10458
10459
10460
10461
10462
10463
10464
10465
10466
10467
10468
10469
10470
10471
10472
10473
10474
10475
10476
10477
10478
10479
10480
10481
10482
10483
10484
10485
10486
10487
10488
10489
10490
10491
10492
10493
10494
10495
10496
10497
10498
10499
10500
10501
10502
10503
10504
10505
10506
10507
10508
10509
10510
10511
10512
10513
10514
10515
10516
10517
10518
10519
10520
10521
10522
10523
10524
10525
10526
10527
10528
10529
10530
10531
10532
10533
10534
10535
10536
10537
10538
10539
10540
10541
10542
10543
10544
10545
10546
10547
10548
10549
10550
10551
10552
10553
10554
10555
10556
10557
10558
10559
10560
10561
10562
10563
10564
10565
10566
10567
10568
10569
10570
10571
10572
10573
10574
10575
10576
10577
10578
10579
10580
10581
10582
10583
10584
10585
10586
10587
10588
10589
10590
10591
10592
10593
10594
10595
10596
10597
10598
10599
10600
10601
10602
10603
10604
10605
10606
10607
10608
10609
10610
10611
10612
10613
10614
10615
10616
10617
10618
10619
10620
10621
10622
10623
10624
10625
10626
10627
10628
10629
10630
10631
10632
10633
10634
10635
10636
10637
10638
10639
10640
10641
10642
10643
10644
10645
10646
10647
10648
10649
10650
10651
10652
10653
10654
10655
10656
10657
10658
10659
10660
10661
10662
10663
10664
10665
10666
10667
10668
10669
10670
10671
10672
10673
10674
10675
10676
10677
10678
10679
10680
10681
10682
10683
10684
10685
10686
10687
10688
10689
10690
10691
10692
10693
10694
10695
10696
10697
10698
10699
10700
10701
10702
10703
10704
10705
10706
10707
10708
10709
10710
10711
10712
10713
10714
10715
10716
10717
10718
10719
10720
10721
10722
10723
10724
10725
10726
10727
10728
10729
10730
10731
10732
10733
10734
10735
10736
10737
10738
10739
10740
10741
10742
10743
10744
10745
10746
10747
10748
10749
10750
10751
10752
10753
10754
10755
10756
10757
10758
10759
10760
10761
10762
10763
10764
10765
10766
10767
10768
10769
10770
10771
10772
10773
10774
10775
10776
10777
10778
10779
10780
10781
10782
10783
10784
10785
10786
10787
10788
10789
10790
10791
10792
10793
10794
10795
10796
10797
10798
10799
10800
10801
10802
10803
10804
10805
10806
10807
10808
10809
10810
10811
10812
10813
10814
10815
10816
10817
10818
10819
10820
10821
10822
10823
10824
10825
10826
10827
10828
10829
10830
10831
10832
10833
10834
10835
10836
10837
10838
10839
10840
10841
10842
10843
10844
10845
10846
10847
10848
10849
10850
10851
10852
10853
10854
10855
10856
10857
10858
10859
10860
10861
10862
10863
10864
10865
10866
10867
10868
10869
10870
10871
10872
10873
10874
10875
10876
10877
10878
10879
10880
10881
10882
10883
10884
10885
10886
10887
10888
10889
10890
10891
10892
10893
10894
10895
10896
10897
10898
10899
10900
10901
10902
10903
10904
10905
10906
10907
10908
10909
10910
10911
10912
10913
10914
10915
10916
10917
10918
10919
10920
10921
10922
10923
10924
10925
10926
10927
10928
10929
10930
10931
10932
10933
10934
10935
10936
10937
10938
10939
10940
10941
10942
10943
10944
10945
10946
10947
10948
10949
10950
10951
10952
10953
10954
10955
10956
10957
10958
10959
10960
10961
10962
10963
10964
10965
10966
10967
10968
10969
10970
10971
10972
10973
10974
10975
10976
10977
10978
10979
10980
10981
10982
10983
10984
10985
10986
10987
10988
10989
10990
10991
10992
10993
10994
10995
10996
10997
10998
10999
11000
11001
11002
11003
11004
11005
11006
11007
11008
11009
11010
11011
11012
11013
11014
11015
11016
11017
11018
11019
11020
11021
11022
11023
11024
11025
11026
11027
11028
11029
11030
11031
11032
11033
11034
11035
11036
11037
11038
11039
11040
11041
11042
11043
11044
11045
11046
11047
11048
11049
11050
11051
11052
11053
11054
11055
11056
11057
11058
11059
11060
11061
11062
11063
11064
11065
11066
11067
11068
11069
11070
11071
11072
11073
11074
11075
11076
11077
11078
11079
11080
11081
11082
11083
11084
11085
11086
11087
11088
11089
11090
11091
11092
11093
11094
11095
11096
11097
11098
11099
11100
11101
11102
11103
11104
11105
11106
11107
11108
11109
11110
11111
11112
11113
11114
11115
11116
11117
11118
11119
11120
11121
11122
11123
11124
11125
11126
11127
11128
11129
11130
11131
11132
11133
11134
11135
11136
11137
11138
11139
11140
11141
11142
11143
11144
11145
11146
11147
11148
11149
11150
11151
11152
11153
11154
11155
11156
11157
11158
11159
11160
11161
11162
11163
11164
11165
11166
11167
11168
11169
11170
11171
11172
11173
11174
11175
11176
11177
11178
11179
11180
11181
11182
11183
11184
11185
11186
11187
11188
11189
11190
11191
11192
11193
11194
11195
11196
11197
11198
11199
11200
11201
11202
11203
11204
11205
11206
11207
11208
11209
11210
11211
11212
11213
11214
11215
11216
11217
11218
11219
11220
11221
11222
11223
11224
11225
11226
11227
11228
11229
11230
11231
11232
11233
11234
11235
11236
11237
11238
11239
11240
11241
11242
11243
11244
11245
11246
11247
11248
11249
11250
11251
11252
11253
11254
11255
11256
11257
11258
11259
11260
11261
11262
11263
11264
11265
11266
11267
11268
11269
11270
11271
11272
11273
11274
11275
11276
11277
11278
11279
11280
11281
11282
11283
11284
11285
11286
11287
11288
11289
11290
11291
11292
11293
11294
11295
11296
11297
11298
11299
11300
11301
11302
11303
11304
11305
11306
11307
11308
11309
11310
11311
11312
11313
11314
11315
11316
11317
11318
11319
11320
11321
11322
11323
11324
11325
11326
11327
11328
11329
11330
11331
11332
11333
11334
11335
11336
11337
11338
11339
11340
11341
11342
11343
11344
11345
11346
11347
11348
11349
11350
11351
11352
11353
11354
11355
11356
11357
11358
11359
11360
11361
11362
11363
11364
11365
11366
11367
11368
11369
11370
11371
11372
11373
11374
11375
11376
11377
11378
11379
11380
11381
11382
11383
11384
11385
11386
11387
11388
11389
11390
11391
11392
11393
11394
11395
11396
11397
11398
11399
11400
11401
11402
11403
11404
11405
11406
11407
11408
11409
11410
11411
11412
11413
11414
11415
11416
11417
11418
11419
11420
11421
11422
11423
11424
11425
11426
11427
11428
11429
11430
11431
11432
11433
11434
11435
11436
11437
11438
11439
11440
11441
11442
11443
11444
11445
11446
11447
11448
11449
11450
11451
11452
11453
11454
11455
11456
11457
11458
11459
11460
11461
11462
11463
11464
11465
11466
11467
11468
11469
11470
11471
11472
11473
11474
11475
11476
11477
11478
11479
11480
11481
11482
11483
11484
11485
11486
11487
11488
11489
11490
11491
11492
11493
11494
11495
11496
11497
11498
11499
11500
11501
11502
11503
11504
11505
11506
11507
11508
11509
11510
11511
11512
11513
11514
11515
11516
11517
11518
11519
11520
11521
11522
11523
11524
11525
11526
11527
11528
11529
11530
11531
11532
11533
11534
11535
11536
11537
11538
11539
11540
11541
11542
11543
11544
11545
11546
11547
11548
11549
11550
11551
11552
11553
11554
11555
11556
11557
11558
11559
11560
11561
11562
11563
11564
11565
11566
11567
11568
11569
11570
11571
11572
11573
11574
11575
11576
11577
11578
11579
11580
11581
11582
11583
11584
11585
11586
11587
11588
11589
11590
11591
11592
11593
11594
11595
11596
11597
11598
11599
11600
11601
11602
11603
11604
11605
11606
11607
11608
11609
11610
11611
11612
11613
11614
11615
11616
11617
11618
11619
11620
11621
11622
11623
11624
11625
11626
11627
11628
11629
11630
11631
11632
11633
11634
11635
11636
11637
11638
11639
11640
11641
11642
11643
11644
11645
11646
11647
11648
11649
11650
11651
11652
11653
11654
11655
11656
11657
11658
11659
11660
11661
11662
11663
11664
11665
11666
11667
11668
11669
11670
11671
11672
11673
11674
11675
11676
11677
11678
11679
11680
11681
11682
11683
11684
11685
11686
11687
11688
11689
11690
11691
11692
11693
11694
11695
11696
11697
11698
11699
11700
11701
11702
11703
11704
11705
11706
11707
11708
11709
11710
11711
11712
11713
11714
11715
11716
11717
11718
11719
11720
11721
11722
11723
11724
11725
11726
11727
11728
11729
11730
11731
11732
11733
11734
11735
11736
11737
11738
11739
11740
11741
11742
11743
11744
11745
11746
11747
11748
11749
11750
11751
11752
11753
11754
11755
11756
11757
11758
11759
11760
11761
11762
11763
11764
11765
11766
11767
11768
11769
11770
11771
11772
11773
11774
11775
11776
11777
11778
11779
11780
11781
11782
11783
11784
11785
11786
11787
11788
11789
11790
11791
11792
11793
11794
11795
11796
11797
11798
11799
11800
11801
11802
11803
11804
11805
11806
11807
11808
11809
11810
11811
11812
11813
11814
11815
11816
11817
11818
11819
11820
11821
11822
11823
11824
11825
11826
11827
11828
11829
11830
11831
11832
11833
11834
11835
11836
11837
11838
11839
11840
11841
11842
11843
11844
11845
11846
11847
11848
11849
11850
11851
11852
11853
11854
11855
11856
11857
11858
11859
11860
11861
11862
11863
11864
11865
11866
11867
11868
11869
11870
11871
11872
11873
11874
11875
11876
11877
11878
11879
11880
11881
11882
11883
11884
11885
11886
11887
11888
11889
11890
11891
11892
11893
11894
11895
11896
11897
11898
11899
11900
11901
11902
11903
11904
11905
11906
11907
11908
11909
11910
11911
11912
11913
11914
11915
11916
11917
11918
11919
11920
11921
11922
11923
11924
11925
11926
11927
11928
11929
11930
11931
11932
11933
11934
11935
11936
11937
11938
11939
11940
11941
11942
11943
11944
11945
11946
11947
11948
11949
11950
11951
11952
11953
11954
11955
11956
11957
11958
11959
11960
11961
11962
11963
11964
11965
11966
11967
11968
11969
11970
11971
11972
11973
11974
11975
11976
11977
11978
11979
11980
11981
11982
11983
11984
11985
11986
11987
11988
11989
11990
11991
11992
11993
11994
11995
11996
11997
11998
11999
12000
12001
12002
12003
12004
12005
12006
12007
12008
12009
12010
12011
12012
12013
12014
12015
12016
12017
12018
12019
12020
12021
12022
12023
12024
12025
12026
12027
12028
12029
12030
12031
12032
12033
12034
12035
12036
12037
12038
12039
12040
12041
12042
12043
12044
12045
12046
12047
12048
12049
12050
12051
12052
12053
12054
12055
12056
12057
12058
12059
12060
12061
12062
12063
12064
12065
12066
12067
12068
12069
12070
12071
12072
12073
12074
12075
12076
12077
12078
12079
12080
12081
12082
12083
12084
12085
12086
12087
12088
12089
12090
12091
12092
12093
12094
12095
12096
12097
12098
12099
12100
12101
12102
12103
12104
12105
12106
12107
12108
12109
12110
12111
12112
12113
12114
12115
12116
12117
12118
12119
12120
12121
12122
12123
12124
12125
12126
12127
12128
12129
12130
12131
12132
12133
12134
12135
12136
12137
12138
12139
12140
12141
12142
12143
12144
12145
12146
12147
12148
12149
12150
12151
12152
12153
12154
12155
12156
12157
12158
12159
12160
12161
12162
12163
12164
12165
12166
12167
12168
12169
12170
12171
12172
12173
12174
12175
12176
12177
12178
12179
12180
12181
12182
12183
12184
12185
12186
12187
12188
12189
12190
12191
12192
12193
12194
12195
12196
12197
12198
12199
12200
12201
12202
12203
12204
12205
12206
12207
12208
12209
12210
12211
12212
12213
12214
12215
12216
12217
12218
12219
12220
12221
12222
12223
12224
12225
12226
12227
12228
12229
12230
12231
12232
12233
12234
12235
12236
12237
12238
12239
12240
12241
12242
12243
12244
12245
12246
12247
12248
12249
12250
12251
12252
12253
12254
12255
12256
12257
12258
12259
12260
12261
12262
12263
12264
12265
12266
12267
12268
12269
12270
12271
12272
12273
12274
12275
12276
12277
12278
12279
12280
12281
12282
12283
12284
12285
12286
12287
12288
12289
12290
12291
12292
12293
12294
12295
12296
12297
12298
12299
12300
12301
12302
12303
12304
12305
12306
12307
12308
12309
12310
12311
12312
12313
12314
12315
12316
12317
12318
12319
12320
12321
12322
12323
12324
12325
12326
12327
12328
12329
12330
12331
12332
12333
12334
12335
12336
12337
12338
12339
12340
12341
12342
12343
12344
12345
12346
12347
12348
12349
12350
12351
12352
12353
12354
12355
12356
12357
12358
12359
12360
12361
12362
12363
12364
12365
12366
12367
12368
12369
12370
12371
12372
12373
12374
12375
12376
12377
12378
12379
12380
12381
12382
12383
12384
12385
12386
12387
12388
12389
12390
12391
12392
12393
12394
12395
12396
12397
12398
12399
12400
12401
12402
12403
12404
12405
12406
12407
12408
12409
12410
12411
12412
12413
12414
12415
12416
12417
12418
12419
12420
12421
12422
12423
12424
12425
12426
12427
12428
12429
12430
12431
12432
12433
12434
12435
12436
12437
12438
12439
12440
12441
12442
12443
12444
12445
12446
12447
12448
12449
12450
12451
12452
12453
12454
12455
12456
12457
12458
12459
12460
12461
12462
12463
12464
12465
12466
12467
12468
12469
12470
12471
12472
12473
12474
12475
12476
12477
12478
12479
12480
12481
12482
12483
12484
12485
12486
12487
12488
12489
12490
12491
12492
12493
12494
12495
12496
12497
12498
12499
12500
12501
12502
12503
12504
12505
12506
12507
12508
12509
12510
12511
12512
12513
12514
12515
12516
12517
12518
12519
12520
12521
12522
12523
12524
12525
12526
12527
12528
12529
12530
12531
12532
12533
12534
12535
12536
12537
12538
12539
12540
12541
12542
12543
12544
12545
12546
12547
12548
12549
12550
12551
12552
12553
12554
12555
12556
12557
12558
12559
12560
12561
12562
12563
12564
12565
12566
12567
12568
12569
12570
12571
12572
12573
12574
12575
12576
12577
12578
12579
12580
12581
12582
12583
12584
12585
12586
12587
12588
12589
12590
12591
12592
12593
12594
12595
12596
12597
12598
12599
12600
12601
12602
12603
12604
12605
12606
12607
12608
12609
12610
12611
12612
12613
12614
12615
12616
12617
12618
12619
12620
12621
12622
12623
12624
12625
12626
12627
12628
12629
12630
12631
12632
12633
12634
12635
12636
12637
12638
12639
12640
12641
12642
12643
12644
12645
12646
12647
12648
12649
12650
12651
12652
12653
12654
12655
12656
12657
12658
12659
12660
12661
12662
12663
12664
12665
12666
12667
12668
12669
12670
12671
12672
12673
12674
12675
12676
12677
12678
12679
12680
12681
12682
12683
12684
12685
12686
12687
12688
12689
12690
12691
12692
12693
12694
12695
12696
12697
12698
12699
12700
12701
12702
12703
12704
12705
12706
12707
12708
12709
12710
12711
12712
12713
12714
12715
12716
12717
12718
12719
12720
12721
12722
12723
12724
12725
12726
12727
12728
12729
12730
12731
12732
12733
12734
12735
12736
12737
12738
12739
12740
12741
12742
12743
12744
12745
12746
12747
12748
12749
12750
12751
12752
12753
12754
12755
12756
12757
12758
12759
12760
12761
12762
12763
12764
12765
12766
12767
12768
12769
12770
12771
12772
12773
12774
12775
12776
12777
12778
12779
12780
12781
12782
12783
12784
12785
12786
12787
12788
12789
12790
12791
12792
12793
12794
12795
12796
12797
12798
12799
12800
12801
12802
12803
12804
12805
12806
12807
12808
12809
12810
12811
12812
12813
12814
12815
12816
12817
12818
12819
12820
12821
12822
12823
12824
12825
12826
12827
12828
12829
12830
12831
12832
12833
12834
12835
12836
12837
12838
12839
12840
12841
12842
12843
12844
12845
12846
12847
12848
12849
12850
12851
12852
12853
12854
12855
12856
12857
12858
12859
12860
12861
12862
12863
12864
12865
12866
12867
12868
12869
12870
12871
12872
12873
12874
12875
12876
12877
12878
12879
12880
12881
12882
12883
12884
12885
12886
12887
12888
12889
12890
12891
12892
12893
12894
12895
12896
12897
12898
12899
12900
12901
12902
12903
12904
12905
12906
12907
12908
12909
12910
12911
12912
12913
12914
12915
12916
12917
12918
12919
12920
12921
12922
12923
12924
12925
12926
12927
12928
12929
12930
12931
12932
12933
12934
12935
12936
12937
12938
12939
12940
12941
12942
12943
12944
12945
12946
12947
12948
12949
12950
12951
12952
12953
12954
12955
12956
12957
12958
12959
12960
12961
12962
12963
12964
12965
12966
12967
12968
12969
12970
12971
12972
12973
12974
12975
12976
12977
12978
12979
12980
12981
12982
12983
12984
12985
12986
12987
12988
12989
12990
12991
12992
12993
12994
12995
12996
12997
12998
12999
13000
13001
13002
13003
13004
13005
13006
13007
13008
13009
13010
13011
13012
13013
13014
13015
13016
13017
13018
13019
13020
13021
13022
13023
13024
13025
13026
13027
13028
13029
13030
13031
13032
13033
13034
13035
13036
13037
13038
13039
13040
13041
13042
13043
13044
13045
13046
13047
13048
13049
13050
13051
13052
13053
13054
13055
13056
13057
13058
13059
13060
13061
13062
13063
13064
13065
13066
13067
13068
13069
13070
13071
13072
13073
13074
13075
13076
13077
13078
13079
13080
13081
13082
13083
13084
13085
13086
13087
13088
13089
13090
13091
13092
13093
13094
13095
13096
13097
13098
13099
13100
13101
13102
13103
13104
13105
13106
13107
13108
13109
13110
13111
13112
13113
13114
13115
13116
13117
13118
13119
13120
13121
13122
13123
13124
13125
13126
13127
13128
13129
13130
13131
13132
13133
13134
13135
13136
13137
13138
13139
13140
13141
13142
13143
13144
13145
13146
13147
13148
13149
13150
13151
13152
13153
13154
13155
13156
13157
13158
13159
13160
13161
13162
13163
13164
13165
13166
13167
13168
13169
13170
13171
13172
13173
13174
13175
13176
13177
13178
13179
13180
13181
13182
13183
13184
13185
13186
13187
13188
13189
13190
13191
13192
13193
13194
13195
13196
13197
13198
13199
13200
13201
13202
13203
13204
13205
13206
13207
13208
13209
13210
13211
13212
13213
13214
13215
13216
13217
13218
13219
13220
13221
13222
13223
13224
13225
13226
13227
13228
13229
13230
13231
13232
13233
13234
13235
13236
13237
13238
13239
13240
13241
13242
13243
13244
13245
13246
13247
13248
13249
13250
13251
13252
13253
13254
13255
13256
13257
13258
13259
13260
13261
13262
13263
13264
13265
13266
13267
13268
13269
13270
13271
13272
13273
13274
13275
13276
13277
13278
13279
13280
13281
13282
13283
13284
13285
13286
13287
13288
13289
13290
13291
13292
13293
13294
13295
13296
13297
13298
13299
13300
13301
13302
13303
13304
13305
13306
13307
13308
13309
13310
13311
13312
13313
13314
13315
13316
13317
13318
13319
13320
13321
13322
13323
13324
13325
13326
13327
13328
13329
13330
13331
13332
13333
13334
13335
13336
13337
13338
13339
13340
13341
13342
13343
13344
13345
13346
13347
13348
13349
13350
13351
13352
13353
13354
13355
13356
13357
13358
13359
13360
13361
13362
13363
13364
13365
13366
13367
13368
13369
13370
13371
13372
13373
13374
13375
13376
13377
13378
13379
13380
13381
13382
13383
13384
13385
13386
13387
13388
13389
13390
13391
13392
13393
13394
13395
13396
13397
13398
13399
13400
13401
13402
13403
13404
13405
13406
13407
13408
13409
13410
13411
13412
13413
13414
13415
13416
13417
13418
13419
13420
13421
13422
13423
13424
13425
13426
13427
13428
13429
13430
13431
13432
13433
13434
13435
13436
13437
13438
13439
13440
13441
13442
13443
13444
13445
13446
13447
13448
13449
13450
13451
13452
13453
13454
13455
13456
13457
13458
13459
13460
13461
13462
13463
13464
13465
13466
13467
13468
13469
13470
13471
13472
13473
13474
13475
13476
13477
13478
13479
13480
13481
13482
13483
13484
13485
13486
13487
13488
13489
13490
13491
13492
13493
13494
13495
13496
13497
13498
13499
13500
13501
13502
13503
13504
13505
13506
13507
13508
13509
13510
13511
13512
13513
13514
13515
13516
13517
13518
13519
13520
13521
13522
13523
13524
13525
13526
13527
13528
13529
13530
13531
13532
13533
13534
13535
13536
13537
13538
13539
13540
13541
13542
13543
13544
13545
13546
13547
13548
13549
13550
13551
13552
13553
13554
13555
13556
13557
13558
13559
13560
13561
13562
13563
13564
13565
13566
13567
13568
13569
13570
13571
13572
13573
13574
13575
13576
13577
13578
13579
13580
13581
13582
13583
13584
13585
13586
13587
13588
13589
13590
13591
13592
13593
13594
13595
13596
13597
13598
13599
13600
13601
13602
13603
13604
13605
13606
13607
13608
13609
13610
13611
13612
13613
13614
13615
13616
13617
13618
13619
13620
13621
13622
13623
13624
13625
13626
13627
13628
13629
13630
13631
13632
13633
13634
13635
13636
13637
13638
13639
13640
13641
13642
13643
13644
13645
13646
13647
13648
13649
13650
13651
13652
13653
13654
13655
13656
13657
13658
13659
13660
13661
13662
13663
13664
13665
13666
13667
13668
13669
13670
13671
13672
13673
13674
13675
13676
13677
13678
13679
13680
13681
13682
13683
13684
13685
13686
13687
13688
13689
13690
13691
13692
13693
13694
13695
13696
13697
13698
13699
13700
13701
13702
13703
13704
13705
13706
13707
13708
13709
13710
13711
13712
13713
13714
13715
13716
13717
13718
13719
13720
13721
13722
13723
13724
13725
13726
13727
13728
13729
13730
13731
13732
13733
13734
13735
13736
13737
13738
13739
13740
13741
13742
13743
13744
13745
13746
13747
13748
13749
13750
13751
13752
13753
13754
13755
13756
13757
13758
13759
13760
13761
13762
13763
13764
13765
13766
13767
13768
13769
13770
13771
13772
13773
13774
13775
13776
13777
13778
13779
13780
13781
13782
13783
13784
13785
13786
13787
13788
13789
13790
13791
13792
13793
13794
13795
13796
13797
13798
13799
13800
13801
13802
13803
13804
13805
13806
13807
13808
13809
13810
13811
13812
13813
13814
13815
13816
13817
13818
13819
13820
13821
13822
13823
13824
13825
13826
13827
13828
13829
13830
13831
13832
13833
13834
13835
13836
13837
13838
13839
13840
13841
13842
13843
13844
13845
13846
13847
13848
13849
13850
13851
13852
13853
13854
13855
13856
13857
13858
13859
13860
13861
13862
13863
13864
13865
13866
13867
13868
13869
13870
13871
13872
13873
13874
13875
13876
13877
13878
13879
13880
13881
13882
13883
13884
13885
13886
13887
13888
13889
13890
13891
13892
13893
13894
13895
13896
13897
13898
13899
13900
13901
13902
13903
13904
13905
13906
13907
13908
13909
13910
13911
13912
13913
13914
13915
13916
13917
13918
13919
13920
13921
13922
13923
13924
13925
13926
13927
13928
13929
13930
13931
13932
13933
13934
13935
13936
13937
13938
13939
13940
13941
13942
13943
13944
13945
13946
13947
13948
13949
13950
13951
13952
13953
13954
13955
13956
13957
13958
13959
13960
13961
13962
13963
13964
13965
13966
13967
13968
13969
13970
13971
13972
13973
13974
13975
13976
13977
13978
13979
13980
13981
13982
13983
13984
13985
13986
13987
13988
13989
13990
13991
13992
13993
13994
13995
13996
13997
13998
13999
14000
14001
14002
14003
14004
14005
14006
14007
14008
14009
14010
14011
14012
14013
14014
14015
14016
14017
14018
14019
14020
14021
14022
14023
14024
14025
14026
14027
14028
14029
14030
14031
14032
14033
14034
14035
14036
14037
14038
14039
14040
14041
14042
14043
14044
14045
14046
14047
14048
14049
14050
14051
14052
14053
14054
14055
14056
14057
14058
14059
14060
14061
14062
14063
14064
14065
14066
14067
14068
14069
14070
14071
14072
14073
14074
14075
14076
14077
14078
14079
14080
14081
14082
14083
14084
14085
14086
14087
14088
14089
14090
14091
14092
14093
14094
14095
14096
14097
14098
14099
14100
14101
14102
14103
14104
14105
14106
14107
14108
14109
14110
14111
14112
14113
14114
14115
14116
14117
14118
14119
14120
14121
14122
14123
14124
14125
14126
14127
14128
14129
14130
14131
14132
14133
14134
14135
14136
14137
14138
14139
14140
14141
14142
14143
14144
14145
14146
14147
14148
14149
14150
14151
14152
14153
14154
14155
14156
14157
14158
14159
14160
14161
14162
14163
14164
14165
14166
14167
14168
14169
14170
14171
14172
14173
14174
14175
14176
14177
14178
14179
14180
14181
14182
14183
14184
14185
14186
14187
14188
14189
14190
14191
14192
14193
14194
14195
14196
14197
14198
14199
14200
14201
14202
14203
14204
14205
14206
14207
14208
14209
14210
14211
14212
14213
14214
14215
14216
14217
14218
14219
14220
14221
14222
14223
14224
14225
14226
14227
14228
14229
14230
14231
14232
14233
14234
14235
14236
14237
14238
14239
14240
14241
14242
14243
14244
14245
14246
14247
14248
14249
14250
14251
14252
14253
14254
14255
14256
14257
14258
14259
14260
14261
14262
14263
14264
14265
14266
14267
14268
14269
14270
14271
14272
14273
14274
14275
14276
14277
14278
14279
14280
14281
14282
14283
14284
14285
14286
14287
14288
14289
14290
14291
14292
14293
14294
14295
14296
14297
14298
14299
14300
14301
14302
14303
14304
14305
14306
14307
14308
14309
14310
14311
14312
14313
14314
14315
14316
14317
14318
14319
14320
14321
14322
14323
14324
14325
14326
14327
14328
14329
14330
14331
14332
14333
14334
14335
14336
14337
14338
14339
14340
14341
14342
14343
14344
14345
14346
14347
14348
14349
14350
14351
14352
14353
14354
14355
14356
14357
14358
14359
14360
14361
14362
14363
14364
14365
14366
14367
14368
14369
14370
14371
14372
14373
14374
14375
14376
14377
14378
14379
14380
14381
14382
14383
14384
14385
14386
14387
14388
14389
14390
14391
14392
14393
14394
14395
14396
14397
14398
14399
14400
14401
14402
14403
14404
14405
14406
14407
14408
14409
14410
14411
14412
14413
14414
14415
14416
14417
14418
14419
14420
14421
14422
14423
14424
14425
14426
14427
14428
14429
14430
14431
14432
14433
14434
14435
14436
14437
14438
14439
14440
14441
14442
14443
14444
14445
14446
14447
14448
14449
14450
14451
14452
14453
14454
14455
14456
14457
14458
14459
14460
14461
14462
14463
14464
14465
14466
14467
14468
14469
14470
14471
14472
14473
14474
14475
14476
14477
14478
14479
14480
14481
14482
14483
14484
14485
14486
14487
14488
14489
14490
14491
14492
14493
14494
14495
14496
14497
14498
14499
14500
14501
14502
14503
14504
14505
14506
14507
14508
14509
14510
14511
14512
14513
14514
14515
14516
14517
14518
14519
14520
14521
14522
14523
14524
14525
14526
14527
14528
14529
14530
14531
14532
14533
14534
14535
14536
14537
14538
14539
14540
14541
14542
14543
14544
14545
14546
14547
14548
14549
14550
14551
14552
14553
14554
14555
14556
14557
14558
14559
14560
14561
14562
14563
14564
14565
14566
14567
14568
14569
14570
14571
14572
14573
14574
14575
14576
14577
14578
14579
14580
14581
14582
14583
14584
14585
14586
14587
14588
14589
14590
14591
14592
14593
14594
14595
14596
14597
14598
14599
14600
14601
14602
14603
14604
14605
14606
14607
14608
14609
14610
14611
14612
14613
14614
14615
14616
14617
14618
14619
14620
14621
14622
14623
14624
14625
14626
14627
14628
14629
14630
14631
14632
14633
14634
14635
14636
14637
14638
14639
14640
14641
14642
14643
14644
14645
14646
14647
14648
14649
14650
14651
14652
14653
14654
14655
14656
14657
14658
14659
14660
14661
14662
14663
14664
14665
14666
14667
14668
14669
14670
14671
14672
14673
14674
14675
14676
14677
14678
14679
14680
14681
14682
14683
14684
14685
14686
14687
14688
14689
14690
14691
14692
14693
14694
14695
14696
14697
14698
14699
14700
14701
14702
14703
14704
14705
14706
14707
14708
14709
14710
14711
14712
14713
14714
14715
14716
14717
14718
14719
14720
14721
14722
14723
14724
14725
14726
14727
14728
14729
14730
14731
14732
14733
14734
14735
14736
14737
14738
14739
14740
14741
14742
14743
14744
14745
14746
14747
14748
14749
14750
14751
14752
14753
14754
14755
14756
14757
14758
14759
14760
14761
14762
14763
14764
14765
14766
14767
14768
14769
14770
14771
14772
14773
14774
14775
14776
14777
14778
14779
14780
14781
14782
14783
14784
14785
14786
14787
14788
14789
14790
14791
14792
14793
14794
14795
14796
14797
14798
14799
14800
14801
14802
14803
14804
14805
14806
14807
14808
14809
14810
14811
14812
14813
14814
14815
14816
14817
14818
14819
14820
14821
14822
14823
14824
14825
14826
14827
14828
14829
14830
14831
14832
14833
14834
14835
14836
14837
14838
14839
14840
14841
14842
14843
14844
14845
14846
14847
14848
14849
14850
14851
14852
14853
14854
14855
14856
14857
14858
14859
14860
14861
14862
14863
14864
14865
14866
14867
14868
14869
14870
14871
14872
14873
14874
14875
14876
14877
14878
14879
14880
14881
14882
14883
14884
14885
14886
14887
14888
14889
14890
14891
14892
14893
14894
14895
14896
14897
14898
14899
14900
14901
14902
14903
14904
14905
14906
14907
14908
14909
14910
14911
14912
14913
14914
14915
14916
14917
14918
14919
14920
14921
14922
14923
14924
14925
14926
14927
14928
14929
14930
14931
14932
14933
14934
14935
14936
14937
14938
14939
14940
14941
14942
14943
14944
14945
14946
14947
14948
14949
14950
14951
14952
14953
14954
14955
14956
14957
14958
14959
14960
14961
14962
14963
14964
14965
14966
14967
14968
14969
14970
14971
14972
14973
14974
14975
14976
14977
14978
14979
14980
14981
14982
14983
14984
14985
14986
14987
14988
14989
14990
14991
14992
14993
14994
14995
14996
14997
14998
14999
15000
15001
15002
15003
15004
15005
15006
15007
15008
15009
15010
15011
15012
15013
15014
15015
15016
15017
15018
15019
15020
15021
15022
15023
15024
15025
15026
15027
15028
15029
15030
15031
15032
15033
15034
15035
15036
15037
15038
15039
15040
15041
15042
15043
15044
15045
15046
15047
15048
15049
15050
15051
15052
15053
15054
15055
15056
15057
15058
15059
15060
15061
15062
15063
15064
15065
15066
15067
15068
15069
15070
15071
15072
15073
15074
15075
15076
15077
15078
15079
15080
15081
15082
15083
15084
15085
15086
15087
15088
15089
15090
15091
15092
15093
15094
15095
15096
15097
15098
15099
15100
15101
15102
15103
15104
15105
15106
15107
15108
15109
15110
15111
15112
15113
15114
15115
15116
15117
15118
15119
15120
15121
15122
15123
15124
15125
15126
15127
15128
15129
15130
15131
15132
15133
15134
15135
15136
15137
15138
15139
15140
15141
15142
15143
15144
15145
15146
15147
15148
15149
15150
15151
15152
15153
15154
15155
15156
15157
15158
15159
15160
15161
15162
15163
15164
15165
15166
15167
15168
15169
15170
15171
15172
15173
15174
15175
15176
15177
15178
15179
15180
15181
15182
15183
15184
15185
15186
15187
15188
15189
15190
15191
15192
15193
15194
15195
15196
15197
15198
15199
15200
15201
15202
15203
15204
15205
15206
15207
15208
15209
15210
15211
15212
15213
15214
15215
15216
15217
15218
15219
15220
15221
15222
15223
15224
15225
15226
15227
15228
15229
15230
15231
15232
15233
15234
15235
15236
15237
15238
15239
15240
15241
15242
15243
15244
15245
15246
15247
15248
15249
15250
15251
15252
15253
15254
15255
15256
15257
15258
15259
15260
15261
15262
15263
15264
15265
15266
15267
15268
15269
15270
15271
15272
15273
15274
15275
15276
15277
15278
15279
15280
15281
15282
15283
15284
15285
15286
15287
15288
15289
15290
15291
15292
15293
15294
15295
15296
15297
15298
15299
15300
15301
15302
15303
15304
15305
15306
15307
15308
15309
15310
15311
15312
15313
15314
15315
15316
15317
15318
15319
15320
15321
15322
15323
15324
15325
15326
15327
15328
15329
15330
15331
15332
15333
15334
15335
15336
15337
15338
15339
15340
15341
15342
15343
15344
15345
15346
15347
15348
15349
15350
15351
15352
15353
15354
15355
15356
15357
15358
15359
15360
15361
15362
15363
15364
15365
15366
15367
15368
15369
15370
15371
15372
15373
15374
15375
15376
15377
15378
15379
15380
15381
15382
15383
15384
15385
15386
15387
15388
15389
15390
15391
15392
15393
15394
15395
15396
15397
15398
15399
15400
15401
15402
15403
15404
15405
15406
15407
15408
15409
15410
15411
15412
15413
15414
15415
15416
15417
15418
15419
15420
15421
15422
15423
15424
15425
15426
15427
15428
15429
15430
15431
15432
15433
15434
15435
15436
15437
15438
15439
15440
15441
15442
15443
15444
15445
15446
15447
15448
15449
15450
15451
15452
15453
15454
15455
15456
15457
15458
15459
15460
15461
15462
15463
15464
15465
15466
15467
15468
15469
15470
15471
15472
15473
15474
15475
15476
15477
15478
15479
15480
15481
15482
15483
15484
15485
15486
15487
15488
15489
15490
15491
15492
15493
15494
15495
15496
15497
15498
15499
15500
15501
15502
15503
15504
15505
15506
15507
15508
15509
15510
15511
15512
15513
15514
15515
15516
15517
15518
15519
15520
15521
15522
15523
15524
15525
15526
15527
15528
15529
15530
15531
15532
15533
15534
15535
15536
15537
15538
15539
15540
15541
15542
15543
15544
15545
15546
15547
15548
15549
15550
15551
15552
15553
15554
15555
15556
15557
15558
15559
15560
15561
15562
15563
15564
15565
15566
15567
15568
15569
15570
15571
15572
15573
15574
15575
15576
15577
15578
15579
15580
15581
15582
15583
15584
15585
15586
15587
15588
15589
15590
15591
15592
15593
15594
15595
15596
15597
15598
15599
15600
15601
15602
15603
15604
15605
15606
15607
15608
15609
15610
15611
15612
15613
15614
15615
15616
15617
15618
15619
15620
15621
15622
15623
15624
15625
15626
15627
15628
15629
15630
15631
15632
15633
15634
15635
15636
15637
15638
15639
15640
15641
15642
15643
15644
15645
15646
15647
15648
15649
15650
15651
15652
15653
15654
15655
15656
15657
15658
15659
15660
15661
15662
15663
15664
15665
15666
15667
15668
15669
15670
15671
15672
15673
15674
15675
15676
15677
15678
15679
15680
15681
15682
15683
15684
15685
15686
15687
15688
15689
15690
15691
15692
15693
15694
15695
15696
15697
15698
15699
15700
15701
15702
15703
15704
15705
15706
15707
15708
15709
15710
15711
15712
15713
15714
15715
15716
15717
15718
15719
15720
15721
15722
15723
15724
15725
15726
15727
15728
15729
15730
15731
15732
15733
15734
15735
15736
15737
15738
15739
15740
15741
15742
15743
15744
15745
15746
15747
15748
15749
15750
15751
15752
15753
15754
15755
15756
15757
15758
15759
15760
15761
15762
15763
15764
15765
15766
15767
15768
15769
15770
15771
15772
15773
15774
15775
15776
15777
15778
15779
15780
15781
15782
15783
15784
15785
15786
15787
15788
15789
15790
15791
15792
15793
15794
15795
15796
15797
15798
15799
15800
15801
15802
15803
15804
15805
15806
15807
15808
15809
15810
15811
15812
15813
15814
15815
15816
15817
15818
15819
15820
15821
15822
15823
15824
15825
15826
15827
15828
15829
15830
15831
15832
15833
15834
15835
15836
15837
15838
15839
15840
15841
15842
15843
15844
15845
15846
15847
15848
15849
15850
15851
15852
15853
15854
15855
15856
15857
15858
15859
15860
15861
15862
15863
15864
15865
15866
15867
15868
15869
15870
15871
15872
15873
15874
15875
15876
15877
15878
15879
15880
15881
15882
15883
15884
15885
15886
15887
15888
15889
15890
15891
15892
15893
15894
15895
15896
15897
15898
15899
15900
15901
15902
15903
15904
15905
15906
15907
15908
15909
15910
15911
15912
15913
15914
15915
15916
15917
15918
15919
15920
15921
15922
15923
15924
15925
15926
15927
15928
15929
15930
15931
15932
15933
15934
15935
15936
15937
15938
15939
15940
15941
15942
15943
15944
15945
15946
15947
15948
15949
15950
15951
15952
15953
15954
15955
15956
15957
15958
15959
15960
15961
15962
15963
15964
15965
15966
15967
15968
15969
15970
15971
15972
15973
15974
15975
15976
15977
15978
15979
15980
15981
15982
15983
15984
15985
15986
15987
15988
15989
15990
15991
15992
15993
15994
15995
15996
15997
15998
15999
16000
16001
16002
16003
16004
16005
16006
16007
16008
16009
16010
16011
16012
16013
16014
16015
16016
16017
16018
16019
16020
16021
16022
16023
16024
16025
16026
16027
16028
16029
16030
16031
16032
16033
16034
16035
16036
16037
16038
16039
16040
16041
16042
16043
16044
16045
16046
16047
16048
16049
16050
16051
16052
16053
16054
16055
16056
16057
16058
16059
16060
16061
16062
16063
16064
16065
16066
16067
16068
16069
16070
16071
16072
16073
16074
16075
16076
16077
16078
16079
16080
16081
16082
16083
16084
16085
16086
16087
16088
16089
16090
16091
16092
16093
16094
16095
16096
16097
16098
16099
16100
16101
16102
16103
16104
16105
16106
16107
16108
16109
16110
16111
16112
16113
16114
16115
16116
16117
16118
16119
16120
16121
16122
16123
16124
16125
16126
16127
16128
16129
16130
16131
16132
16133
16134
16135
16136
16137
16138
16139
16140
16141
16142
16143
16144
16145
16146
16147
16148
16149
16150
16151
16152
16153
16154
16155
16156
16157
16158
16159
16160
16161
16162
16163
16164
16165
16166
16167
16168
16169
16170
16171
16172
16173
16174
16175
16176
16177
16178
16179
16180
16181
16182
16183
16184
16185
16186
16187
16188
16189
16190
16191
16192
16193
16194
16195
16196
16197
16198
16199
16200
16201
16202
16203
16204
16205
16206
16207
16208
16209
16210
16211
16212
16213
16214
16215
16216
16217
16218
16219
16220
16221
16222
16223
16224
16225
16226
16227
16228
16229
16230
16231
16232
16233
16234
16235
16236
16237
16238
16239
16240
16241
16242
16243
16244
16245
16246
16247
16248
16249
16250
16251
16252
16253
16254
16255
16256
16257
16258
16259
16260
16261
16262
16263
16264
16265
16266
16267
16268
16269
16270
16271
16272
16273
16274
16275
16276
16277
16278
16279
16280
16281
16282
16283
16284
16285
16286
16287
16288
16289
16290
16291
16292
16293
16294
16295
16296
16297
16298
16299
16300
16301
16302
16303
16304
16305
16306
16307
16308
16309
16310
16311
16312
16313
16314
16315
16316
16317
16318
16319
16320
16321
16322
16323
16324
16325
16326
16327
16328
16329
16330
16331
16332
16333
16334
16335
16336
16337
16338
16339
16340
16341
16342
16343
16344
16345
16346
16347
16348
16349
16350
16351
16352
16353
16354
16355
16356
16357
16358
16359
16360
16361
16362
16363
16364
16365
16366
16367
16368
16369
16370
16371
16372
16373
16374
16375
16376
16377
16378
16379
16380
16381
16382
16383
16384
16385
16386
16387
16388
16389
16390
16391
16392
16393
16394
16395
16396
16397
16398
16399
16400
16401
16402
16403
16404
16405
16406
16407
16408
16409
16410
16411
16412
16413
16414
16415
16416
16417
16418
16419
16420
16421
16422
16423
16424
16425
16426
16427
16428
16429
16430
16431
16432
16433
16434
16435
16436
16437
16438
16439
16440
16441
16442
16443
16444
16445
16446
16447
16448
16449
16450
16451
16452
16453
16454
16455
16456
16457
16458
16459
16460
16461
16462
16463
16464
16465
16466
16467
16468
16469
16470
16471
16472
16473
16474
16475
16476
16477
16478
16479
16480
16481
16482
16483
16484
16485
16486
16487
16488
16489
16490
16491
16492
16493
16494
16495
16496
16497
16498
16499
16500
16501
16502
16503
16504
16505
16506
16507
16508
16509
16510
16511
16512
16513
16514
16515
16516
16517
16518
16519
16520
16521
16522
16523
16524
16525
16526
16527
16528
16529
16530
16531
16532
16533
16534
16535
16536
16537
16538
16539
16540
16541
16542
16543
16544
16545
16546
16547
16548
16549
16550
16551
16552
16553
16554
16555
16556
16557
16558
16559
16560
16561
16562
16563
16564
16565
16566
16567
16568
16569
16570
16571
16572
16573
16574
16575
16576
16577
16578
16579
16580
16581
16582
16583
16584
16585
16586
16587
16588
16589
16590
16591
16592
16593
16594
16595
16596
16597
16598
16599
16600
16601
16602
16603
16604
16605
16606
16607
16608
16609
16610
16611
16612
16613
16614
16615
16616
16617
16618
16619
16620
16621
16622
16623
16624
16625
16626
16627
16628
16629
16630
16631
16632
16633
16634
16635
16636
16637
16638
16639
16640
16641
16642
16643
16644
16645
16646
16647
16648
16649
16650
16651
16652
16653
16654
16655
16656
16657
16658
16659
16660
16661
16662
16663
16664
16665
16666
16667
16668
16669
16670
16671
16672
16673
16674
16675
16676
16677
16678
16679
16680
16681
16682
16683
16684
16685
16686
16687
16688
16689
16690
16691
16692
16693
16694
16695
16696
16697
16698
16699
16700
16701
16702
16703
16704
16705
16706
16707
16708
16709
16710
16711
16712
16713
16714
16715
16716
16717
16718
16719
16720
16721
16722
16723
16724
16725
16726
16727
16728
16729
16730
16731
16732
16733
16734
16735
16736
16737
16738
16739
16740
16741
16742
16743
16744
16745
16746
16747
16748
16749
16750
16751
16752
16753
16754
16755
16756
16757
16758
16759
16760
16761
16762
16763
16764
16765
16766
16767
16768
16769
16770
16771
16772
16773
16774
16775
16776
16777
16778
16779
16780
16781
16782
16783
16784
16785
16786
16787
16788
16789
16790
16791
16792
16793
16794
16795
16796
16797
16798
16799
16800
16801
16802
16803
16804
16805
16806
16807
16808
16809
16810
16811
16812
16813
16814
16815
16816
16817
16818
16819
16820
16821
16822
16823
16824
16825
16826
16827
16828
16829
16830
16831
16832
16833
16834
16835
16836
16837
16838
16839
16840
16841
16842
16843
16844
16845
16846
16847
16848
16849
16850
16851
16852
16853
16854
16855
16856
16857
16858
16859
16860
16861
16862
16863
16864
16865
16866
16867
16868
16869
16870
16871
16872
16873
16874
16875
16876
16877
16878
16879
16880
16881
16882
16883
16884
16885
16886
16887
16888
16889
16890
16891
16892
16893
16894
16895
16896
16897
16898
16899
16900
16901
16902
16903
16904
16905
16906
16907
16908
16909
16910
16911
16912
16913
16914
16915
16916
16917
16918
16919
16920
16921
16922
16923
16924
16925
16926
16927
16928
16929
16930
16931
16932
16933
16934
16935
16936
16937
16938
16939
16940
16941
16942
16943
16944
16945
16946
16947
16948
16949
16950
16951
16952
16953
16954
16955
16956
16957
16958
16959
16960
16961
16962
16963
16964
16965
16966
16967
16968
16969
16970
16971
16972
16973
16974
16975
16976
16977
16978
16979
16980
16981
16982
16983
16984
16985
16986
16987
16988
16989
16990
16991
16992
16993
16994
16995
16996
16997
16998
16999
17000
17001
17002
17003
17004
17005
17006
17007
17008
17009
17010
17011
17012
17013
17014
17015
17016
17017
17018
17019
17020
17021
17022
17023
17024
17025
17026
17027
17028
17029
17030
17031
17032
17033
17034
17035
17036
17037
17038
17039
17040
17041
17042
17043
17044
17045
17046
17047
17048
17049
17050
17051
17052
17053
17054
17055
17056
17057
17058
17059
17060
17061
17062
17063
17064
17065
17066
17067
17068
17069
17070
17071
17072
17073
17074
17075
17076
17077
17078
17079
17080
17081
17082
17083
17084
17085
17086
17087
17088
17089
17090
17091
17092
17093
17094
17095
17096
17097
17098
17099
17100
17101
17102
17103
17104
17105
17106
17107
17108
17109
17110
17111
17112
17113
17114
17115
17116
17117
17118
17119
17120
17121
17122
17123
17124
17125
17126
17127
17128
17129
17130
17131
17132
17133
17134
17135
17136
17137
17138
17139
17140
17141
17142
17143
17144
17145
17146
17147
17148
17149
17150
17151
17152
17153
17154
17155
17156
17157
17158
17159
17160
17161
17162
17163
17164
17165
17166
17167
17168
17169
17170
17171
17172
17173
17174
17175
17176
17177
17178
17179
17180
17181
17182
17183
17184
17185
17186
17187
17188
17189
17190
17191
17192
17193
17194
17195
17196
17197
17198
17199
17200
17201
17202
17203
17204
17205
17206
17207
17208
17209
17210
17211
17212
17213
17214
17215
17216
17217
17218
17219
17220
17221
17222
17223
17224
17225
17226
17227
17228
17229
17230
17231
17232
17233
17234
17235
17236
17237
17238
17239
17240
17241
17242
17243
17244
17245
17246
17247
17248
17249
17250
17251
17252
17253
17254
17255
17256
17257
17258
17259
17260
17261
17262
17263
17264
17265
17266
17267
17268
17269
17270
17271
17272
17273
17274
17275
17276
17277
17278
17279
17280
17281
17282
17283
17284
17285
17286
17287
17288
17289
17290
17291
17292
17293
17294
17295
17296
17297
17298
17299
17300
17301
17302
17303
17304
17305
17306
17307
17308
17309
17310
17311
17312
17313
17314
17315
17316
17317
17318
17319
17320
17321
17322
17323
17324
17325
17326
17327
17328
17329
17330
17331
17332
17333
17334
17335
17336
17337
17338
17339
17340
17341
17342
17343
17344
17345
17346
17347
17348
17349
17350
17351
17352
17353
17354
17355
17356
17357
17358
17359
17360
17361
17362
17363
17364
17365
17366
17367
17368
17369
17370
17371
17372
17373
17374
17375
17376
17377
17378
17379
17380
17381
17382
17383
17384
17385
17386
17387
17388
17389
17390
17391
17392
17393
17394
17395
17396
17397
17398
17399
17400
17401
17402
17403
17404
17405
17406
17407
17408
17409
17410
17411
17412
17413
17414
17415
17416
17417
17418
17419
17420
17421
17422
17423
17424
17425
17426
17427
17428
17429
17430
17431
17432
17433
17434
17435
17436
17437
17438
17439
17440
17441
17442
17443
17444
17445
17446
17447
17448
17449
17450
17451
17452
17453
17454
17455
17456
17457
17458
17459
17460
17461
17462
17463
17464
17465
17466
17467
17468
17469
17470
17471
17472
17473
17474
17475
17476
17477
17478
17479
17480
17481
17482
17483
17484
17485
17486
17487
17488
17489
17490
17491
17492
17493
17494
17495
17496
17497
17498
17499
17500
17501
17502
17503
17504
17505
17506
17507
17508
17509
17510
17511
17512
17513
17514
17515
17516
17517
17518
17519
17520
17521
17522
17523
17524
17525
17526
17527
17528
17529
17530
17531
17532
17533
17534
17535
17536
17537
17538
17539
17540
17541
17542
17543
17544
17545
17546
17547
17548
17549
17550
17551
17552
17553
17554
17555
17556
17557
17558
17559
17560
17561
17562
17563
17564
17565
17566
17567
17568
17569
17570
17571
17572
17573
17574
17575
17576
17577
17578
17579
17580
17581
17582
17583
17584
17585
17586
17587
17588
17589
17590
17591
17592
17593
17594
17595
17596
17597
17598
17599
17600
17601
17602
17603
17604
17605
17606
17607
17608
17609
17610
17611
17612
17613
17614
17615
17616
17617
17618
17619
17620
17621
17622
17623
17624
17625
17626
17627
17628
17629
17630
17631
17632
17633
17634
17635
17636
17637
17638
17639
17640
17641
17642
17643
17644
17645
17646
17647
17648
17649
17650
17651
17652
17653
17654
17655
17656
17657
17658
17659
17660
17661
17662
17663
17664
17665
17666
17667
17668
17669
17670
17671
17672
17673
17674
17675
17676
17677
17678
17679
17680
17681
17682
17683
17684
17685
17686
17687
17688
17689
17690
17691
17692
17693
17694
17695
17696
17697
17698
17699
17700
17701
17702
17703
17704
17705
17706
17707
17708
17709
17710
17711
17712
17713
17714
17715
17716
17717
17718
17719
17720
17721
17722
17723
17724
17725
17726
17727
17728
17729
17730
17731
17732
17733
17734
17735
17736
17737
17738
17739
17740
17741
17742
17743
17744
17745
17746
17747
17748
17749
17750
17751
17752
17753
17754
17755
17756
17757
17758
17759
17760
17761
17762
17763
17764
17765
17766
17767
17768
17769
17770
17771
17772
17773
17774
17775
17776
17777
17778
17779
17780
17781
17782
17783
17784
17785
17786
17787
17788
17789
17790
17791
17792
17793
17794
17795
17796
17797
17798
17799
17800
17801
17802
17803
17804
17805
17806
17807
17808
17809
17810
17811
17812
17813
17814
17815
17816
17817
17818
17819
17820
17821
17822
17823
17824
17825
17826
17827
17828
17829
17830
17831
17832
17833
17834
17835
17836
17837
17838
17839
17840
17841
17842
17843
17844
17845
17846
17847
17848
17849
17850
17851
17852
17853
17854
17855
17856
17857
17858
17859
17860
17861
17862
17863
17864
17865
17866
17867
17868
17869
17870
17871
17872
17873
17874
17875
17876
17877
17878
17879
17880
17881
17882
17883
17884
17885
17886
17887
17888
17889
17890
17891
17892
17893
17894
17895
17896
17897
17898
17899
17900
17901
17902
17903
17904
17905
17906
17907
17908
17909
17910
17911
17912
17913
17914
17915
17916
17917
17918
17919
17920
17921
17922
17923
17924
17925
17926
17927
17928
17929
17930
17931
17932
17933
17934
17935
17936
17937
17938
17939
17940
17941
17942
17943
17944
17945
17946
17947
17948
17949
17950
17951
17952
17953
17954
17955
17956
17957
17958
17959
17960
17961
17962
17963
17964
17965
17966
17967
17968
17969
17970
17971
17972
17973
17974
17975
17976
17977
17978
17979
17980
17981
17982
17983
17984
17985
17986
17987
17988
17989
17990
17991
17992
17993
17994
17995
17996
17997
17998
17999
18000
18001
18002
18003
18004
18005
18006
18007
18008
18009
18010
18011
18012
18013
18014
18015
18016
18017
18018
18019
18020
18021
18022
18023
18024
18025
18026
18027
18028
18029
18030
18031
18032
18033
18034
18035
18036
18037
18038
18039
18040
18041
18042
18043
18044
18045
18046
18047
18048
18049
18050
18051
18052
18053
18054
18055
18056
18057
18058
18059
18060
18061
18062
18063
18064
18065
18066
18067
18068
18069
18070
18071
18072
18073
18074
18075
18076
18077
18078
18079
18080
18081
18082
18083
18084
18085
18086
18087
18088
18089
18090
18091
18092
18093
18094
18095
18096
18097
18098
18099
18100
18101
18102
18103
18104
18105
18106
18107
18108
18109
18110
18111
18112
18113
18114
18115
18116
18117
18118
18119
18120
18121
18122
18123
18124
18125
18126
18127
18128
18129
18130
18131
18132
18133
18134
18135
18136
18137
18138
18139
18140
18141
18142
18143
18144
18145
18146
18147
18148
18149
18150
18151
18152
18153
18154
18155
18156
18157
18158
18159
18160
18161
18162
18163
18164
18165
18166
18167
18168
18169
18170
18171
18172
18173
18174
18175
18176
18177
18178
18179
18180
18181
18182
18183
18184
18185
18186
18187
18188
18189
18190
18191
18192
18193
18194
18195
18196
18197
18198
18199
18200
18201
18202
18203
18204
18205
18206
18207
18208
18209
18210
18211
18212
18213
18214
18215
18216
18217
18218
18219
18220
18221
18222
18223
18224
18225
18226
18227
18228
18229
18230
18231
18232
18233
18234
18235
18236
18237
18238
18239
18240
18241
18242
18243
18244
18245
18246
18247
18248
18249
18250
18251
18252
18253
18254
18255
18256
18257
18258
18259
18260
18261
18262
18263
18264
18265
18266
18267
18268
18269
18270
18271
18272
18273
18274
18275
18276
18277
18278
18279
18280
18281
18282
18283
18284
18285
18286
18287
18288
18289
18290
18291
18292
18293
18294
18295
18296
18297
18298
18299
18300
18301
18302
18303
18304
18305
18306
18307
18308
18309
18310
18311
18312
18313
18314
18315
18316
18317
18318
18319
18320
18321
18322
18323
18324
18325
18326
18327
18328
18329
18330
18331
18332
18333
18334
18335
18336
18337
18338
18339
18340
18341
18342
18343
18344
18345
18346
18347
18348
18349
18350
18351
18352
18353
18354
18355
18356
18357
18358
18359
18360
18361
18362
18363
18364
18365
18366
18367
18368
18369
18370
18371
18372
18373
18374
18375
18376
18377
18378
18379
18380
18381
18382
18383
18384
18385
18386
18387
18388
18389
18390
18391
18392
18393
18394
18395
18396
18397
18398
18399
18400
18401
18402
18403
18404
18405
18406
18407
18408
18409
18410
18411
18412
18413
18414
18415
18416
18417
18418
18419
18420
18421
18422
18423
18424
18425
18426
18427
18428
18429
18430
18431
18432
18433
18434
18435
18436
18437
18438
18439
18440
18441
18442
18443
18444
18445
18446
18447
18448
18449
18450
18451
18452
18453
18454
18455
18456
18457
18458
18459
18460
18461
18462
18463
18464
18465
18466
18467
18468
18469
18470
18471
18472
18473
18474
18475
18476
18477
18478
18479
18480
18481
18482
18483
18484
18485
18486
18487
18488
18489
18490
18491
18492
18493
18494
18495
18496
18497
18498
18499
18500
18501
18502
18503
18504
18505
18506
18507
18508
18509
18510
18511
18512
18513
18514
18515
18516
18517
18518
18519
18520
18521
18522
18523
18524
18525
18526
18527
18528
18529
18530
18531
18532
18533
18534
18535
18536
18537
18538
18539
18540
18541
18542
18543
18544
18545
18546
18547
18548
18549
18550
18551
18552
18553
18554
18555
18556
18557
18558
18559
18560
18561
18562
18563
18564
18565
18566
18567
18568
18569
18570
18571
18572
18573
18574
18575
18576
18577
18578
18579
18580
18581
18582
18583
18584
18585
18586
18587
18588
18589
18590
18591
18592
18593
18594
18595
18596
18597
18598
18599
18600
18601
18602
18603
18604
18605
18606
18607
18608
18609
18610
18611
18612
18613
18614
18615
18616
18617
18618
18619
18620
18621
18622
18623
18624
18625
18626
18627
18628
18629
18630
18631
18632
18633
18634
18635
18636
18637
18638
18639
18640
18641
18642
18643
18644
18645
18646
18647
18648
18649
18650
18651
18652
18653
18654
18655
18656
18657
18658
18659
18660
18661
18662
18663
18664
18665
18666
18667
18668
18669
18670
18671
18672
18673
18674
18675
18676
18677
18678
18679
18680
18681
18682
18683
18684
18685
18686
18687
18688
18689
18690
18691
18692
18693
18694
18695
18696
18697
18698
18699
18700
18701
18702
18703
18704
18705
18706
18707
18708
18709
18710
18711
18712
18713
18714
18715
18716
18717
18718
18719
18720
18721
18722
18723
18724
18725
18726
18727
18728
18729
18730
18731
18732
18733
18734
18735
18736
18737
18738
18739
18740
18741
18742
18743
18744
18745
18746
18747
18748
18749
18750
18751
18752
18753
18754
18755
18756
18757
18758
18759
18760
18761
18762
18763
18764
18765
18766
18767
18768
18769
18770
18771
18772
18773
18774
18775
18776
18777
18778
18779
18780
18781
18782
18783
18784
18785
18786
18787
18788
18789
18790
18791
18792
18793
18794
18795
18796
18797
18798
18799
18800
18801
18802
18803
18804
18805
18806
18807
18808
18809
18810
18811
18812
18813
18814
18815
18816
18817
18818
18819
18820
18821
18822
18823
18824
18825
18826
18827
18828
18829
18830
18831
18832
18833
18834
18835
18836
18837
18838
18839
18840
18841
18842
18843
18844
18845
18846
18847
18848
18849
18850
18851
18852
18853
18854
18855
18856
18857
18858
18859
18860
18861
18862
18863
18864
18865
18866
18867
18868
18869
18870
18871
18872
18873
18874
18875
18876
18877
18878
18879
18880
18881
18882
18883
18884
18885
18886
18887
18888
18889
18890
18891
18892
18893
18894
18895
18896
18897
18898
18899
18900
18901
18902
18903
18904
18905
18906
18907
18908
18909
18910
18911
18912
18913
18914
18915
18916
18917
18918
18919
18920
18921
18922
18923
18924
18925
18926
18927
18928
18929
18930
18931
18932
18933
18934
18935
18936
18937
18938
18939
18940
18941
18942
18943
18944
18945
18946
18947
18948
18949
18950
18951
18952
18953
18954
18955
18956
18957
18958
18959
18960
18961
18962
18963
18964
18965
18966
18967
18968
18969
18970
18971
18972
18973
18974
18975
18976
18977
18978
18979
18980
18981
18982
18983
18984
18985
18986
18987
18988
18989
18990
18991
18992
18993
18994
18995
18996
18997
18998
18999
19000
19001
19002
19003
19004
19005
19006
19007
19008
19009
19010
19011
19012
19013
19014
19015
19016
19017
19018
19019
19020
19021
19022
19023
19024
19025
19026
19027
19028
19029
19030
19031
19032
19033
19034
19035
19036
19037
19038
19039
19040
19041
19042
19043
19044
19045
19046
19047
19048
19049
19050
19051
19052
19053
19054
19055
19056
19057
19058
19059
19060
19061
19062
19063
19064
19065
19066
19067
19068
19069
19070
19071
19072
19073
19074
19075
19076
19077
19078
19079
19080
19081
19082
19083
19084
19085
19086
19087
19088
19089
19090
19091
19092
19093
19094
19095
19096
19097
19098
19099
19100
19101
19102
19103
19104
19105
19106
19107
19108
19109
19110
19111
19112
19113
19114
19115
19116
19117
19118
19119
19120
19121
19122
19123
19124
19125
19126
19127
19128
19129
19130
19131
19132
19133
19134
19135
19136
19137
19138
19139
19140
19141
19142
19143
19144
19145
19146
19147
19148
19149
19150
19151
19152
19153
19154
19155
19156
19157
19158
19159
19160
19161
19162
19163
19164
19165
19166
19167
19168
19169
19170
19171
19172
19173
19174
19175
19176
19177
19178
19179
19180
19181
19182
19183
19184
19185
19186
19187
19188
19189
19190
19191
19192
19193
19194
19195
19196
19197
19198
19199
19200
19201
19202
19203
19204
19205
19206
19207
19208
19209
19210
19211
19212
19213
19214
19215
19216
19217
19218
19219
19220
19221
19222
19223
19224
19225
19226
19227
19228
19229
19230
19231
19232
19233
19234
19235
19236
19237
19238
19239
19240
19241
19242
19243
19244
19245
19246
19247
19248
19249
19250
19251
19252
19253
19254
19255
19256
19257
19258
19259
19260
19261
19262
19263
19264
19265
19266
19267
19268
19269
19270
19271
19272
19273
19274
19275
19276
19277
19278
19279
19280
19281
19282
19283
19284
19285
19286
19287
19288
19289
19290
19291
19292
19293
19294
19295
19296
19297
19298
19299
19300
19301
19302
19303
19304
19305
19306
19307
19308
19309
19310
19311
19312
19313
19314
19315
19316
19317
19318
19319
19320
19321
19322
19323
19324
19325
19326
19327
19328
19329
19330
19331
19332
19333
19334
19335
19336
19337
19338
19339
19340
19341
19342
19343
19344
19345
19346
19347
19348
19349
19350
19351
19352
19353
19354
19355
19356
19357
19358
19359
19360
19361
19362
19363
19364
19365
19366
19367
19368
19369
19370
19371
19372
19373
19374
19375
19376
19377
19378
19379
19380
19381
19382
19383
19384
19385
19386
19387
19388
19389
19390
19391
19392
19393
19394
19395
19396
19397
19398
19399
19400
19401
19402
19403
19404
19405
19406
19407
19408
19409
19410
19411
19412
19413
19414
19415
19416
19417
19418
19419
19420
19421
19422
19423
19424
19425
19426
19427
19428
19429
19430
19431
19432
19433
19434
19435
19436
19437
19438
19439
19440
19441
19442
19443
19444
19445
19446
19447
19448
19449
19450
19451
19452
19453
19454
19455
19456
19457
19458
19459
19460
19461
19462
19463
19464
19465
19466
19467
19468
19469
19470
19471
19472
19473
19474
19475
19476
19477
19478
19479
19480
19481
19482
19483
19484
19485
19486
19487
19488
19489
19490
19491
19492
19493
19494
19495
19496
19497
19498
19499
19500
19501
19502
19503
19504
19505
19506
19507
19508
19509
19510
19511
19512
19513
19514
19515
19516
19517
19518
19519
19520
19521
19522
19523
19524
19525
19526
19527
19528
19529
19530
19531
19532
19533
19534
19535
19536
19537
19538
19539
19540
19541
19542
19543
19544
19545
19546
19547
19548
19549
19550
19551
19552
19553
19554
19555
19556
19557
19558
19559
19560
19561
19562
19563
19564
19565
19566
19567
19568
19569
19570
19571
19572
19573
19574
19575
19576
19577
19578
19579
19580
19581
19582
19583
19584
19585
19586
19587
19588
19589
19590
19591
19592
19593
19594
19595
19596
19597
19598
19599
19600
19601
19602
19603
19604
19605
19606
19607
19608
19609
19610
19611
19612
19613
19614
19615
19616
19617
19618
19619
19620
19621
19622
19623
19624
19625
19626
19627
19628
19629
19630
19631
19632
19633
19634
19635
19636
19637
19638
19639
19640
19641
19642
19643
19644
19645
19646
19647
19648
19649
19650
19651
19652
19653
19654
19655
19656
19657
19658
19659
19660
19661
19662
19663
19664
19665
19666
19667
19668
19669
19670
19671
19672
19673
19674
19675
19676
19677
19678
19679
19680
19681
19682
19683
19684
19685
19686
19687
19688
19689
19690
19691
19692
19693
19694
19695
19696
19697
19698
19699
19700
19701
19702
19703
19704
19705
19706
19707
19708
19709
19710
19711
19712
19713
19714
19715
19716
19717
19718
19719
19720
19721
19722
19723
19724
19725
19726
19727
19728
19729
19730
19731
19732
19733
19734
19735
19736
19737
19738
19739
19740
19741
19742
19743
19744
19745
19746
19747
19748
19749
19750
19751
19752
19753
19754
19755
19756
19757
19758
19759
19760
19761
19762
19763
19764
19765
19766
19767
19768
19769
19770
19771
19772
19773
19774
19775
19776
19777
19778
19779
19780
19781
19782
19783
19784
19785
19786
19787
19788
19789
19790
19791
19792
19793
19794
19795
19796
19797
19798
19799
19800
19801
19802
19803
19804
19805
19806
19807
19808
19809
19810
19811
19812
19813
19814
19815
19816
19817
19818
19819
19820
19821
19822
19823
19824
19825
19826
19827
19828
19829
19830
19831
19832
19833
19834
19835
19836
19837
19838
19839
19840
19841
19842
19843
19844
19845
19846
19847
19848
19849
19850
19851
19852
19853
19854
19855
19856
19857
19858
19859
19860
19861
19862
19863
19864
19865
19866
19867
19868
19869
19870
19871
19872
19873
19874
19875
19876
19877
19878
19879
19880
19881
19882
19883
19884
19885
19886
19887
19888
19889
19890
19891
19892
19893
19894
19895
19896
19897
19898
19899
19900
19901
19902
19903
19904
19905
19906
19907
19908
19909
19910
19911
19912
19913
19914
19915
19916
19917
19918
19919
19920
19921
19922
19923
19924
19925
19926
19927
19928
19929
19930
19931
19932
19933
19934
19935
19936
19937
19938
19939
19940
19941
19942
19943
19944
19945
19946
19947
19948
19949
19950
19951
19952
19953
19954
19955
19956
19957
19958
19959
19960
19961
19962
19963
19964
19965
19966
19967
19968
19969
19970
19971
19972
19973
19974
19975
19976
19977
19978
19979
19980
19981
19982
19983
19984
19985
19986
19987
19988
19989
19990
19991
19992
19993
19994
19995
19996
19997
19998
19999
20000
20001
20002
20003
20004
20005
20006
20007
20008
20009
20010
20011
20012
20013
20014
20015
20016
20017
20018
20019
20020
20021
20022
20023
20024
20025
20026
20027
20028
20029
20030
20031
20032
20033
20034
20035
20036
20037
20038
20039
20040
20041
20042
20043
20044
20045
20046
20047
20048
20049
20050
20051
20052
20053
20054
20055
20056
20057
20058
20059
20060
20061
20062
20063
20064
20065
20066
20067
20068
20069
20070
20071
20072
20073
20074
20075
20076
20077
20078
20079
20080
20081
20082
20083
20084
20085
20086
20087
20088
20089
20090
20091
20092
20093
20094
20095
20096
20097
20098
20099
20100
20101
20102
20103
20104
20105
20106
20107
20108
20109
20110
20111
20112
20113
20114
20115
20116
20117
20118
20119
20120
20121
20122
20123
20124
20125
20126
20127
20128
20129
20130
20131
20132
20133
20134
20135
20136
20137
20138
20139
20140
20141
20142
20143
20144
20145
20146
20147
20148
20149
20150
20151
20152
20153
20154
20155
20156
20157
20158
20159
20160
20161
20162
20163
20164
20165
20166
20167
20168
20169
20170
20171
20172
20173
20174
20175
20176
20177
20178
20179
20180
20181
20182
20183
20184
20185
20186
20187
20188
20189
20190
20191
20192
20193
20194
20195
20196
20197
20198
20199
20200
20201
20202
20203
20204
20205
20206
20207
20208
20209
20210
20211
20212
20213
20214
20215
20216
20217
20218
20219
20220
20221
20222
20223
20224
20225
20226
20227
20228
20229
20230
20231
20232
20233
20234
20235
20236
20237
20238
20239
20240
20241
20242
20243
20244
20245
20246
20247
20248
20249
20250
20251
20252
20253
20254
20255
20256
20257
20258
20259
20260
20261
20262
20263
20264
20265
20266
20267
20268
20269
20270
20271
20272
20273
20274
20275
20276
20277
20278
20279
20280
20281
20282
20283
20284
20285
20286
20287
20288
20289
20290
20291
20292
20293
20294
20295
20296
20297
20298
20299
20300
20301
20302
20303
20304
20305
20306
20307
20308
20309
20310
20311
20312
20313
20314
20315
20316
20317
20318
20319
20320
20321
20322
20323
20324
20325
20326
20327
20328
20329
20330
20331
20332
20333
20334
20335
20336
20337
20338
20339
20340
20341
20342
20343
20344
20345
20346
20347
20348
20349
20350
20351
20352
20353
20354
20355
20356
20357
20358
20359
20360
20361
20362
20363
20364
20365
20366
20367
20368
20369
20370
20371
20372
20373
20374
20375
20376
20377
20378
20379
20380
20381
20382
20383
20384
20385
20386
20387
20388
20389
20390
20391
20392
20393
20394
20395
20396
20397
20398
20399
20400
20401
20402
20403
20404
20405
20406
20407
20408
20409
20410
20411
20412
20413
20414
20415
20416
20417
20418
20419
20420
20421
20422
20423
20424
20425
20426
20427
20428
20429
20430
20431
20432
20433
20434
20435
20436
20437
20438
20439
20440
20441
20442
20443
20444
20445
20446
20447
20448
20449
20450
20451
20452
20453
20454
20455
20456
20457
20458
20459
20460
20461
20462
20463
20464
20465
20466
20467
20468
20469
20470
20471
20472
20473
20474
20475
20476
20477
20478
20479
20480
20481
20482
20483
20484
20485
20486
20487
20488
20489
20490
20491
20492
20493
20494
20495
20496
20497
20498
20499
20500
20501
20502
20503
20504
20505
20506
20507
20508
20509
20510
20511
20512
20513
20514
20515
20516
20517
20518
20519
20520
20521
20522
20523
20524
20525
20526
20527
20528
20529
20530
20531
20532
20533
20534
20535
20536
20537
20538
20539
20540
20541
20542
20543
20544
20545
20546
20547
20548
20549
20550
20551
20552
20553
20554
20555
20556
20557
20558
20559
20560
20561
20562
20563
20564
20565
20566
20567
20568
20569
20570
20571
20572
20573
20574
20575
20576
20577
20578
20579
20580
20581
20582
20583
20584
20585
20586
20587
20588
20589
20590
20591
20592
20593
20594
20595
20596
20597
20598
20599
20600
20601
20602
20603
20604
20605
20606
20607
20608
20609
20610
20611
20612
20613
20614
20615
20616
20617
20618
20619
20620
20621
20622
20623
20624
20625
20626
20627
20628
20629
20630
20631
20632
20633
20634
20635
20636
20637
20638
20639
20640
20641
20642
20643
20644
20645
20646
20647
20648
20649
20650
20651
20652
20653
20654
20655
20656
20657
20658
20659
20660
20661
20662
20663
20664
20665
20666
20667
20668
20669
20670
20671
20672
20673
20674
20675
20676
20677
20678
20679
20680
20681
20682
20683
20684
20685
20686
20687
20688
20689
20690
20691
20692
20693
20694
20695
20696
20697
20698
20699
20700
20701
20702
20703
20704
20705
20706
20707
20708
20709
20710
20711
20712
20713
20714
20715
20716
20717
20718
20719
20720
20721
20722
20723
20724
20725
20726
20727
20728
20729
20730
20731
20732
20733
20734
20735
20736
20737
20738
20739
20740
20741
20742
20743
20744
20745
20746
20747
20748
20749
20750
20751
20752
20753
20754
20755
20756
20757
20758
20759
20760
20761
20762
20763
20764
20765
20766
20767
20768
20769
20770
20771
20772
20773
20774
20775
20776
20777
20778
20779
20780
20781
20782
20783
20784
20785
20786
20787
20788
20789
20790
20791
20792
20793
20794
20795
20796
20797
20798
20799
20800
20801
20802
20803
20804
20805
20806
20807
20808
20809
20810
20811
20812
20813
20814
20815
20816
20817
20818
20819
20820
20821
20822
20823
20824
20825
20826
20827
20828
20829
20830
20831
20832
20833
20834
20835
20836
20837
20838
20839
20840
20841
20842
20843
20844
20845
20846
20847
20848
20849
20850
20851
20852
20853
20854
20855
20856
20857
20858
20859
20860
20861
20862
20863
20864
20865
20866
20867
20868
20869
20870
20871
20872
20873
20874
20875
20876
20877
20878
20879
20880
20881
20882
20883
20884
20885
20886
20887
20888
20889
20890
20891
20892
20893
20894
20895
20896
20897
20898
20899
20900
20901
20902
20903
20904
20905
20906
20907
20908
20909
20910
20911
20912
20913
20914
20915
20916
20917
20918
20919
20920
20921
20922
20923
20924
20925
20926
20927
20928
20929
20930
20931
20932
20933
20934
20935
20936
20937
20938
20939
20940
20941
20942
20943
20944
20945
20946
20947
20948
20949
20950
20951
20952
20953
20954
20955
20956
20957
20958
20959
20960
20961
20962
20963
20964
20965
20966
20967
20968
20969
20970
20971
20972
20973
20974
20975
20976
20977
20978
20979
20980
20981
20982
20983
20984
20985
20986
20987
20988
20989
20990
20991
20992
20993
20994
20995
20996
20997
20998
20999
21000
21001
21002
21003
21004
21005
21006
21007
21008
21009
21010
21011
21012
21013
21014
21015
21016
21017
21018
21019
21020
21021
21022
21023
21024
21025
21026
21027
21028
21029
21030
21031
21032
21033
21034
21035
21036
21037
21038
21039
21040
21041
21042
21043
21044
21045
21046
21047
21048
21049
21050
21051
21052
21053
21054
21055
21056
21057
21058
21059
21060
21061
21062
21063
21064
21065
21066
21067
21068
21069
21070
21071
21072
21073
21074
21075
21076
21077
21078
21079
21080
21081
21082
21083
21084
21085
21086
21087
21088
21089
21090
21091
21092
21093
21094
21095
21096
21097
21098
21099
21100
21101
21102
21103
21104
21105
21106
21107
21108
21109
21110
21111
21112
21113
21114
21115
21116
21117
21118
21119
21120
21121
21122
21123
21124
21125
21126
21127
21128
21129
21130
21131
21132
21133
21134
21135
21136
21137
21138
21139
21140
21141
21142
21143
21144
21145
21146
21147
21148
21149
21150
21151
21152
21153
21154
21155
21156
21157
21158
21159
21160
21161
21162
21163
21164
21165
21166
21167
21168
21169
21170
21171
21172
21173
21174
21175
21176
21177
21178
21179
21180
21181
21182
21183
21184
21185
21186
21187
21188
21189
21190
21191
21192
21193
21194
21195
21196
21197
21198
21199
21200
21201
21202
21203
21204
21205
21206
21207
21208
21209
21210
21211
21212
21213
21214
21215
21216
21217
21218
21219
21220
21221
21222
21223
21224
21225
21226
21227
21228
21229
21230
21231
21232
21233
21234
21235
21236
21237
21238
21239
21240
21241
21242
21243
21244
21245
21246
21247
21248
21249
21250
21251
21252
21253
21254
21255
21256
21257
21258
21259
21260
21261
21262
21263
21264
21265
21266
21267
21268
21269
21270
21271
21272
21273
21274
21275
21276
21277
21278
21279
21280
21281
21282
21283
21284
21285
21286
21287
21288
21289
21290
21291
21292
21293
21294
21295
21296
21297
21298
21299
21300
21301
21302
21303
21304
21305
21306
21307
21308
21309
21310
21311
21312
21313
21314
21315
21316
21317
21318
21319
21320
21321
21322
21323
21324
21325
21326
21327
21328
21329
21330
21331
21332
21333
21334
21335
21336
21337
21338
21339
21340
21341
21342
21343
21344
21345
21346
21347
21348
21349
21350
21351
21352
21353
21354
21355
21356
21357
21358
21359
21360
21361
21362
21363
21364
21365
21366
21367
21368
21369
21370
21371
21372
21373
21374
21375
21376
21377
21378
21379
21380
21381
21382
21383
21384
21385
21386
21387
21388
21389
21390
21391
21392
21393
21394
21395
21396
21397
21398
21399
21400
21401
21402
21403
21404
21405
21406
21407
21408
21409
21410
21411
21412
21413
21414
21415
21416
21417
21418
21419
21420
21421
21422
21423
21424
21425
21426
21427
21428
21429
21430
21431
21432
21433
21434
21435
21436
21437
21438
21439
21440
21441
21442
21443
21444
21445
21446
21447
21448
21449
21450
21451
21452
21453
21454
21455
21456
21457
21458
21459
21460
21461
21462
21463
21464
21465
21466
21467
21468
21469
21470
21471
21472
21473
21474
21475
21476
21477
21478
21479
21480
21481
21482
21483
21484
21485
21486
21487
21488
21489
21490
21491
21492
21493
21494
21495
21496
21497
21498
21499
21500
21501
21502
21503
21504
21505
21506
21507
21508
21509
21510
21511
21512
21513
21514
21515
21516
21517
21518
21519
21520
21521
21522
21523
21524
21525
21526
21527
21528
21529
21530
21531
21532
21533
21534
21535
21536
21537
21538
21539
21540
21541
21542
21543
21544
21545
21546
21547
21548
21549
21550
21551
21552
21553
21554
21555
21556
21557
21558
21559
21560
21561
21562
21563
21564
21565
21566
21567
21568
21569
21570
21571
21572
21573
21574
21575
21576
21577
21578
21579
21580
21581
21582
21583
21584
21585
21586
21587
21588
21589
21590
21591
21592
21593
21594
21595
21596
21597
21598
21599
21600
21601
21602
21603
21604
21605
21606
21607
21608
21609
21610
21611
21612
21613
21614
21615
21616
21617
21618
21619
21620
21621
21622
21623
21624
21625
21626
21627
21628
21629
21630
21631
21632
21633
21634
21635
21636
21637
21638
21639
21640
21641
21642
21643
21644
21645
21646
21647
21648
21649
21650
21651
21652
21653
21654
21655
21656
21657
21658
21659
21660
21661
21662
21663
21664
21665
21666
21667
21668
21669
21670
21671
21672
21673
21674
21675
21676
21677
21678
21679
21680
21681
21682
21683
21684
21685
21686
21687
21688
21689
21690
21691
21692
21693
21694
21695
21696
21697
21698
21699
21700
21701
21702
21703
21704
21705
21706
21707
21708
21709
21710
21711
21712
21713
21714
21715
21716
21717
21718
21719
21720
21721
21722
21723
21724
21725
21726
21727
21728
21729
21730
21731
21732
21733
21734
21735
21736
21737
21738
21739
21740
21741
21742
21743
21744
21745
21746
21747
21748
21749
21750
21751
21752
21753
21754
21755
21756
21757
21758
21759
21760
21761
21762
21763
21764
21765
21766
21767
21768
21769
21770
21771
21772
21773
21774
21775
21776
21777
21778
21779
21780
21781
21782
21783
21784
21785
21786
21787
21788
21789
21790
21791
21792
21793
21794
21795
21796
21797
21798
21799
21800
21801
21802
21803
21804
21805
21806
21807
21808
21809
21810
21811
21812
21813
21814
21815
21816
21817
21818
21819
21820
21821
21822
21823
21824
21825
21826
21827
21828
21829
21830
21831
21832
21833
21834
21835
21836
21837
21838
21839
21840
21841
21842
21843
21844
21845
21846
21847
21848
21849
21850
21851
21852
21853
21854
21855
21856
21857
21858
21859
21860
21861
21862
21863
21864
21865
21866
21867
21868
21869
21870
21871
21872
21873
21874
21875
21876
21877
21878
21879
21880
21881
21882
21883
21884
21885
21886
21887
21888
21889
21890
21891
21892
21893
21894
21895
21896
21897
21898
21899
21900
21901
21902
21903
21904
21905
21906
21907
21908
21909
21910
21911
21912
21913
21914
21915
21916
21917
21918
21919
21920
21921
21922
21923
21924
21925
21926
21927
21928
21929
21930
21931
21932
21933
21934
21935
21936
21937
21938
21939
21940
21941
21942
21943
21944
21945
21946
21947
21948
21949
21950
21951
21952
21953
21954
21955
21956
21957
21958
21959
21960
21961
21962
21963
21964
21965
21966
21967
21968
21969
21970
21971
21972
21973
21974
21975
21976
21977
21978
21979
21980
21981
21982
21983
21984
21985
21986
21987
21988
21989
21990
21991
21992
21993
21994
21995
21996
21997
21998
21999
22000
22001
22002
22003
22004
22005
22006
22007
22008
22009
22010
22011
22012
22013
22014
22015
22016
22017
22018
22019
22020
22021
22022
22023
22024
22025
22026
22027
22028
22029
22030
22031
22032
22033
22034
22035
22036
22037
22038
22039
22040
22041
22042
22043
22044
22045
22046
22047
22048
22049
22050
22051
22052
22053
22054
22055
22056
22057
22058
22059
22060
22061
22062
22063
22064
22065
22066
22067
22068
22069
22070
22071
22072
22073
22074
22075
22076
22077
22078
22079
22080
22081
22082
22083
22084
22085
22086
22087
22088
22089
22090
22091
22092
22093
22094
22095
22096
22097
22098
22099
22100
22101
22102
22103
22104
22105
22106
22107
22108
22109
22110
22111
22112
22113
22114
22115
22116
22117
22118
22119
22120
22121
22122
22123
22124
22125
22126
22127
22128
22129
22130
22131
22132
22133
22134
22135
22136
22137
22138
22139
22140
22141
22142
22143
22144
22145
22146
22147
22148
22149
22150
22151
22152
22153
22154
22155
22156
22157
22158
22159
22160
22161
22162
22163
22164
22165
22166
22167
22168
22169
22170
22171
22172
22173
22174
22175
22176
22177
22178
22179
22180
22181
22182
22183
22184
22185
22186
22187
22188
22189
22190
22191
22192
22193
22194
22195
22196
22197
22198
22199
22200
22201
22202
22203
22204
22205
22206
22207
22208
22209
22210
22211
22212
22213
22214
22215
22216
22217
22218
22219
22220
22221
22222
22223
22224
22225
22226
22227
22228
22229
22230
22231
22232
22233
22234
22235
22236
22237
22238
22239
22240
22241
22242
22243
22244
22245
22246
22247
22248
22249
22250
22251
22252
22253
22254
22255
22256
22257
22258
22259
22260
22261
22262
22263
22264
22265
22266
22267
22268
22269
22270
22271
22272
22273
22274
22275
22276
22277
22278
22279
22280
22281
22282
22283
22284
22285
22286
22287
22288
22289
22290
22291
22292
22293
22294
22295
22296
22297
22298
22299
22300
22301
22302
22303
22304
22305
22306
22307
22308
22309
22310
22311
22312
22313
22314
22315
22316
22317
22318
22319
22320
22321
22322
22323
22324
22325
22326
22327
22328
22329
22330
22331
22332
22333
22334
22335
22336
22337
22338
22339
22340
22341
22342
22343
22344
22345
22346
22347
22348
22349
22350
22351
22352
22353
22354
22355
22356
22357
22358
22359
22360
22361
22362
22363
22364
22365
22366
22367
22368
22369
22370
22371
22372
22373
22374
22375
22376
22377
22378
22379
22380
22381
22382
22383
22384
22385
22386
22387
22388
22389
22390
22391
22392
22393
22394
22395
22396
22397
22398
22399
22400
22401
22402
22403
22404
22405
22406
22407
22408
22409
22410
22411
22412
22413
22414
22415
22416
22417
22418
22419
22420
22421
22422
22423
22424
22425
22426
22427
22428
22429
22430
22431
22432
22433
22434
22435
22436
22437
22438
22439
22440
22441
22442
22443
22444
22445
22446
22447
22448
22449
22450
22451
22452
22453
22454
22455
22456
22457
22458
22459
22460
22461
22462
22463
22464
22465
22466
22467
22468
22469
22470
22471
22472
22473
22474
22475
22476
22477
22478
22479
22480
22481
22482
22483
22484
22485
22486
22487
22488
22489
22490
22491
22492
22493
22494
22495
22496
22497
22498
22499
22500
22501
22502
22503
22504
22505
22506
22507
22508
22509
22510
22511
22512
22513
22514
22515
22516
22517
22518
22519
22520
22521
22522
22523
22524
22525
22526
22527
22528
22529
22530
22531
22532
22533
22534
22535
22536
22537
22538
22539
22540
22541
22542
22543
22544
22545
22546
22547
22548
22549
22550
22551
22552
22553
22554
22555
22556
22557
22558
22559
22560
22561
22562
22563
22564
22565
22566
22567
22568
22569
22570
22571
22572
22573
22574
22575
22576
22577
22578
22579
22580
22581
22582
22583
22584
22585
22586
22587
22588
22589
22590
22591
22592
22593
22594
22595
22596
22597
22598
22599
22600
22601
22602
22603
22604
22605
22606
22607
22608
22609
22610
22611
22612
22613
22614
22615
22616
22617
22618
22619
22620
22621
22622
22623
22624
22625
22626
22627
22628
22629
22630
22631
22632
22633
22634
22635
22636
22637
22638
22639
22640
22641
22642
22643
22644
22645
22646
22647
22648
22649
22650
22651
22652
22653
22654
22655
22656
22657
22658
22659
22660
22661
22662
22663
22664
22665
22666
22667
22668
22669
22670
22671
22672
22673
22674
22675
22676
22677
22678
22679
22680
22681
22682
22683
22684
22685
22686
22687
22688
22689
22690
22691
22692
22693
22694
22695
22696
22697
22698
22699
22700
22701
22702
22703
22704
22705
22706
22707
22708
22709
22710
22711
22712
22713
22714
22715
22716
22717
22718
22719
22720
22721
22722
22723
22724
22725
22726
22727
22728
22729
22730
22731
22732
22733
22734
22735
22736
22737
22738
22739
22740
22741
22742
22743
22744
22745
22746
22747
22748
22749
22750
22751
22752
22753
22754
22755
22756
22757
22758
22759
22760
22761
22762
22763
22764
22765
22766
22767
22768
22769
22770
22771
22772
22773
22774
22775
22776
22777
22778
22779
22780
22781
22782
22783
22784
22785
22786
22787
22788
22789
22790
22791
22792
22793
22794
22795
22796
22797
22798
22799
22800
22801
22802
22803
22804
22805
22806
22807
22808
22809
22810
22811
22812
22813
22814
22815
22816
22817
22818
22819
22820
22821
22822
22823
22824
22825
22826
22827
22828
22829
22830
22831
22832
22833
22834
22835
22836
22837
22838
22839
22840
22841
22842
22843
22844
22845
22846
22847
22848
22849
22850
22851
22852
22853
22854
22855
22856
22857
22858
22859
22860
22861
22862
22863
22864
22865
22866
22867
22868
22869
22870
22871
22872
22873
22874
22875
22876
22877
22878
22879
22880
22881
22882
22883
22884
22885
22886
22887
22888
22889
22890
22891
22892
22893
22894
22895
22896
22897
22898
22899
22900
22901
22902
22903
22904
22905
22906
22907
22908
22909
22910
22911
22912
22913
22914
22915
22916
22917
22918
22919
22920
22921
22922
22923
22924
22925
22926
22927
22928
22929
22930
22931
22932
22933
22934
22935
22936
22937
22938
22939
22940
22941
22942
22943
22944
22945
22946
22947
22948
22949
22950
22951
22952
22953
22954
22955
22956
22957
22958
22959
22960
22961
22962
22963
22964
22965
22966
22967
22968
22969
22970
22971
22972
22973
22974
22975
22976
22977
22978
22979
22980
22981
22982
22983
22984
22985
22986
22987
22988
22989
22990
22991
22992
22993
22994
22995
22996
22997
22998
22999
23000
23001
23002
23003
23004
23005
23006
23007
23008
23009
23010
23011
23012
23013
23014
23015
23016
23017
23018
23019
23020
23021
23022
23023
23024
23025
23026
23027
23028
23029
23030
23031
23032
23033
23034
23035
23036
23037
23038
23039
23040
23041
23042
23043
23044
23045
23046
23047
23048
23049
23050
23051
23052
23053
23054
23055
23056
23057
23058
23059
23060
23061
23062
23063
23064
23065
23066
23067
23068
23069
23070
23071
23072
23073
23074
23075
23076
23077
23078
23079
23080
23081
23082
23083
23084
23085
23086
23087
23088
23089
23090
23091
23092
23093
23094
23095
23096
23097
23098
23099
23100
23101
23102
23103
23104
23105
23106
23107
23108
23109
23110
23111
23112
23113
23114
23115
23116
23117
23118
23119
23120
23121
23122
23123
23124
23125
23126
23127
23128
23129
23130
23131
23132
23133
23134
23135
23136
23137
23138
23139
23140
23141
23142
23143
23144
23145
23146
23147
23148
23149
23150
23151
23152
23153
23154
23155
23156
23157
23158
23159
23160
23161
23162
23163
23164
23165
23166
23167
23168
23169
23170
23171
23172
23173
23174
23175
23176
23177
23178
23179
23180
23181
23182
23183
23184
23185
23186
23187
23188
23189
23190
23191
23192
23193
23194
23195
23196
23197
23198
23199
23200
23201
23202
23203
23204
23205
23206
23207
23208
23209
23210
23211
23212
23213
23214
23215
23216
23217
23218
23219
23220
23221
23222
23223
23224
23225
23226
23227
23228
23229
23230
23231
23232
23233
23234
23235
23236
23237
23238
23239
23240
23241
23242
23243
23244
23245
23246
23247
23248
23249
23250
23251
23252
23253
23254
23255
23256
23257
23258
23259
23260
23261
23262
23263
23264
23265
23266
23267
23268
23269
23270
23271
23272
23273
23274
23275
23276
23277
23278
23279
23280
23281
23282
23283
23284
23285
23286
23287
23288
23289
23290
23291
23292
23293
23294
23295
23296
23297
23298
23299
23300
23301
23302
23303
23304
23305
23306
23307
23308
23309
23310
23311
23312
23313
23314
23315
23316
23317
23318
23319
23320
23321
23322
23323
23324
23325
23326
23327
23328
23329
23330
23331
23332
23333
23334
23335
23336
23337
23338
23339
23340
23341
23342
23343
23344
23345
23346
23347
23348
23349
23350
23351
23352
23353
23354
23355
23356
23357
23358
23359
23360
23361
23362
23363
23364
23365
23366
23367
23368
23369
23370
23371
23372
23373
23374
23375
23376
23377
23378
23379
23380
23381
23382
23383
23384
23385
23386
23387
23388
23389
23390
23391
23392
23393
23394
23395
23396
23397
23398
23399
23400
23401
23402
23403
23404
23405
23406
23407
23408
23409
23410
23411
23412
23413
23414
23415
23416
23417
23418
23419
23420
23421
23422
23423
23424
23425
23426
23427
23428
23429
23430
23431
23432
23433
23434
23435
23436
23437
23438
23439
23440
23441
23442
23443
23444
23445
23446
23447
23448
23449
23450
23451
23452
23453
23454
23455
23456
23457
23458
23459
23460
23461
23462
23463
23464
23465
23466
23467
23468
23469
23470
23471
23472
23473
23474
23475
23476
23477
23478
23479
23480
23481
23482
23483
23484
23485
23486
23487
23488
23489
23490
23491
23492
23493
23494
23495
23496
23497
23498
23499
23500
23501
23502
23503
23504
23505
23506
23507
23508
23509
23510
23511
23512
23513
23514
23515
23516
23517
23518
23519
23520
23521
23522
23523
23524
23525
23526
23527
23528
23529
23530
23531
23532
23533
23534
23535
23536
23537
23538
23539
23540
23541
23542
23543
23544
23545
23546
23547
23548
23549
23550
23551
23552
23553
23554
23555
23556
23557
23558
23559
23560
23561
23562
23563
23564
23565
23566
23567
23568
23569
23570
23571
23572
23573
23574
23575
23576
23577
23578
23579
23580
23581
23582
23583
23584
23585
23586
23587
23588
23589
23590
23591
23592
23593
23594
23595
23596
23597
23598
23599
23600
23601
23602
23603
23604
23605
23606
23607
23608
23609
23610
23611
23612
23613
23614
23615
23616
23617
23618
23619
23620
23621
23622
23623
23624
23625
23626
23627
23628
23629
23630
23631
23632
23633
23634
23635
23636
23637
23638
23639
23640
23641
23642
23643
23644
23645
23646
23647
23648
23649
23650
23651
23652
23653
23654
23655
23656
23657
23658
23659
23660
23661
23662
23663
23664
23665
23666
23667
23668
23669
23670
23671
23672
23673
23674
23675
23676
23677
23678
23679
23680
23681
23682
23683
23684
23685
23686
23687
23688
23689
23690
23691
23692
23693
23694
23695
23696
23697
23698
23699
23700
23701
23702
23703
23704
23705
23706
23707
23708
23709
23710
23711
23712
23713
23714
23715
23716
23717
23718
23719
23720
23721
23722
23723
23724
23725
23726
23727
23728
23729
23730
23731
23732
23733
23734
23735
23736
23737
23738
23739
23740
23741
23742
23743
23744
23745
23746
23747
23748
23749
23750
23751
23752
23753
23754
23755
23756
23757
23758
23759
23760
23761
23762
23763
23764
23765
23766
23767
23768
23769
23770
23771
23772
23773
23774
23775
23776
23777
23778
23779
23780
23781
23782
23783
23784
23785
23786
23787
23788
23789
23790
23791
23792
23793
23794
23795
23796
23797
23798
23799
23800
23801
23802
23803
23804
23805
23806
23807
23808
23809
23810
23811
23812
23813
23814
23815
23816
23817
23818
23819
23820
23821
23822
23823
23824
23825
23826
23827
23828
23829
23830
23831
23832
23833
23834
23835
23836
23837
23838
23839
23840
23841
23842
23843
23844
23845
23846
23847
23848
23849
23850
23851
23852
23853
23854
23855
23856
23857
23858
23859
23860
23861
23862
23863
23864
23865
23866
23867
23868
23869
23870
23871
23872
23873
23874
23875
23876
23877
23878
23879
23880
23881
23882
23883
23884
23885
23886
23887
23888
23889
23890
23891
23892
23893
23894
23895
23896
23897
23898
23899
23900
23901
23902
23903
23904
23905
23906
23907
23908
23909
23910
23911
23912
23913
23914
23915
23916
23917
23918
23919
23920
23921
23922
23923
23924
23925
23926
23927
23928
23929
23930
23931
23932
23933
23934
23935
23936
23937
23938
23939
23940
23941
23942
23943
23944
23945
23946
23947
23948
23949
23950
23951
23952
23953
23954
23955
23956
23957
23958
23959
23960
23961
23962
23963
23964
23965
23966
23967
23968
23969
23970
23971
23972
23973
23974
23975
23976
23977
23978
23979
23980
23981
23982
23983
23984
23985
23986
23987
23988
23989
23990
23991
23992
23993
23994
23995
23996
23997
23998
23999
24000
24001
24002
24003
24004
24005
24006
24007
24008
24009
24010
24011
24012
24013
24014
24015
24016
24017
24018
24019
24020
24021
24022
24023
24024
24025
24026
24027
24028
24029
24030
24031
24032
24033
24034
24035
24036
24037
24038
24039
24040
24041
24042
24043
24044
24045
24046
24047
24048
24049
24050
24051
24052
24053
24054
24055
24056
24057
24058
24059
24060
24061
24062
24063
24064
24065
24066
24067
24068
24069
24070
24071
24072
24073
24074
24075
24076
24077
24078
24079
24080
24081
24082
24083
24084
24085
24086
24087
24088
24089
24090
24091
24092
24093
24094
24095
24096
24097
24098
24099
24100
24101
24102
24103
24104
24105
24106
24107
24108
24109
24110
24111
24112
24113
24114
24115
24116
24117
24118
24119
24120
24121
24122
24123
24124
24125
24126
24127
24128
24129
24130
24131
24132
24133
24134
24135
24136
24137
24138
24139
24140
24141
24142
24143
24144
24145
24146
24147
24148
24149
24150
24151
24152
24153
24154
24155
24156
24157
24158
24159
24160
24161
24162
24163
24164
24165
24166
24167
24168
24169
24170
24171
24172
24173
24174
24175
24176
24177
24178
24179
24180
24181
24182
24183
24184
24185
24186
24187
24188
24189
24190
24191
24192
24193
24194
24195
24196
24197
24198
24199
24200
24201
24202
24203
24204
24205
24206
24207
24208
24209
24210
24211
24212
24213
24214
24215
24216
24217
24218
24219
24220
24221
24222
24223
24224
24225
24226
24227
24228
24229
24230
24231
24232
24233
24234
24235
24236
24237
24238
24239
24240
24241
24242
24243
24244
24245
24246
24247
24248
24249
24250
24251
24252
24253
24254
24255
24256
24257
24258
24259
24260
24261
24262
24263
24264
24265
24266
24267
24268
24269
24270
24271
24272
24273
24274
24275
24276
24277
24278
24279
24280
24281
24282
24283
24284
24285
24286
24287
24288
24289
24290
24291
24292
24293
24294
24295
24296
24297
24298
24299
24300
24301
24302
24303
24304
24305
24306
24307
24308
24309
24310
24311
24312
24313
24314
24315
24316
24317
24318
24319
24320
24321
24322
24323
24324
24325
24326
24327
24328
24329
24330
24331
24332
24333
24334
24335
24336
24337
24338
24339
24340
24341
24342
24343
24344
24345
24346
24347
24348
24349
24350
24351
24352
24353
24354
24355
24356
24357
24358
24359
24360
24361
24362
24363
24364
24365
24366
24367
24368
24369
24370
24371
24372
24373
24374
24375
24376
24377
24378
24379
24380
24381
24382
24383
24384
24385
24386
24387
24388
24389
24390
24391
24392
24393
24394
24395
24396
24397
24398
24399
24400
24401
24402
24403
24404
24405
24406
24407
24408
24409
24410
24411
24412
24413
24414
24415
24416
24417
24418
24419
24420
24421
24422
24423
24424
24425
24426
24427
24428
24429
24430
24431
24432
24433
24434
24435
24436
24437
24438
24439
24440
24441
24442
24443
24444
24445
24446
24447
24448
24449
24450
24451
24452
24453
24454
24455
24456
24457
24458
24459
24460
24461
24462
24463
24464
24465
24466
24467
24468
24469
24470
24471
24472
24473
24474
24475
24476
24477
24478
24479
24480
24481
24482
24483
24484
24485
24486
24487
24488
24489
24490
24491
24492
24493
24494
24495
24496
24497
24498
24499
24500
24501
24502
24503
24504
24505
24506
24507
24508
24509
24510
24511
24512
24513
24514
24515
24516
24517
24518
24519
24520
24521
24522
24523
24524
24525
24526
24527
24528
24529
24530
24531
24532
24533
24534
24535
24536
24537
24538
24539
24540
24541
24542
24543
24544
24545
24546
24547
24548
24549
24550
24551
24552
24553
24554
24555
24556
24557
24558
24559
24560
24561
24562
24563
24564
24565
24566
24567
24568
24569
24570
24571
24572
24573
24574
24575
24576
24577
24578
24579
24580
24581
24582
24583
24584
24585
24586
24587
24588
24589
24590
24591
24592
24593
24594
24595
24596
24597
24598
24599
24600
24601
24602
24603
24604
24605
24606
24607
24608
24609
24610
24611
24612
24613
24614
24615
24616
24617
24618
24619
24620
24621
24622
24623
24624
24625
24626
24627
24628
24629
24630
24631
24632
24633
24634
24635
24636
24637
24638
24639
24640
24641
24642
24643
24644
24645
24646
24647
24648
24649
24650
24651
24652
24653
24654
24655
24656
24657
24658
24659
24660
24661
24662
24663
24664
24665
24666
24667
24668
24669
24670
24671
24672
24673
24674
24675
24676
24677
24678
24679
24680
24681
24682
24683
24684
24685
24686
24687
24688
24689
24690
24691
24692
24693
24694
24695
24696
24697
24698
24699
24700
24701
24702
24703
24704
24705
24706
24707
24708
24709
24710
24711
24712
24713
24714
24715
24716
24717
24718
24719
24720
24721
24722
24723
24724
24725
24726
24727
24728
24729
24730
24731
24732
24733
24734
24735
24736
24737
24738
24739
24740
24741
24742
24743
24744
24745
24746
24747
24748
24749
24750
24751
24752
24753
24754
24755
24756
24757
24758
24759
24760
24761
24762
24763
24764
24765
24766
24767
24768
24769
24770
24771
24772
24773
24774
24775
24776
24777
24778
24779
24780
24781
24782
24783
24784
24785
24786
24787
24788
24789
24790
24791
24792
24793
24794
24795
24796
24797
24798
24799
24800
24801
24802
24803
24804
24805
24806
24807
24808
24809
24810
24811
24812
24813
24814
24815
24816
24817
24818
24819
24820
24821
24822
24823
24824
24825
24826
24827
24828
24829
24830
24831
24832
24833
24834
24835
24836
24837
24838
24839
24840
24841
24842
24843
24844
24845
24846
24847
24848
24849
24850
24851
24852
24853
24854
24855
24856
24857
24858
24859
24860
24861
24862
24863
24864
24865
24866
24867
24868
24869
24870
24871
24872
24873
24874
24875
24876
24877
24878
24879
24880
24881
24882
24883
24884
24885
24886
24887
24888
24889
24890
24891
24892
24893
24894
24895
24896
24897
24898
24899
24900
24901
24902
24903
24904
24905
24906
24907
24908
24909
24910
24911
24912
24913
24914
24915
24916
24917
24918
24919
24920
24921
24922
24923
24924
24925
24926
24927
24928
24929
24930
24931
24932
24933
24934
24935
24936
24937
24938
24939
24940
24941
24942
24943
24944
24945
24946
24947
24948
24949
24950
24951
24952
24953
24954
24955
24956
24957
24958
24959
24960
24961
24962
24963
24964
24965
24966
24967
24968
24969
24970
24971
24972
24973
24974
24975
24976
24977
24978
24979
24980
24981
24982
24983
24984
24985
24986
24987
24988
24989
24990
24991
24992
24993
24994
24995
24996
24997
24998
24999
25000
25001
25002
25003
25004
25005
25006
25007
25008
25009
25010
25011
25012
25013
25014
25015
25016
25017
25018
25019
25020
25021
25022
25023
25024
25025
25026
25027
25028
25029
25030
25031
25032
25033
25034
25035
25036
25037
25038
25039
25040
25041
25042
25043
25044
25045
25046
25047
25048
25049
25050
25051
25052
25053
25054
25055
25056
25057
25058
25059
25060
25061
25062
25063
25064
25065
25066
25067
25068
25069
25070
25071
25072
25073
25074
25075
25076
25077
25078
25079
25080
25081
25082
25083
25084
25085
25086
25087
25088
25089
25090
25091
25092
25093
25094
25095
25096
25097
25098
25099
25100
25101
25102
25103
25104
25105
25106
25107
25108
25109
25110
25111
25112
25113
25114
25115
25116
25117
25118
25119
25120
25121
25122
25123
25124
25125
25126
25127
25128
25129
25130
25131
25132
25133
25134
25135
25136
25137
25138
25139
25140
25141
25142
25143
25144
25145
25146
25147
25148
25149
25150
25151
25152
25153
25154
25155
25156
25157
25158
25159
25160
25161
25162
25163
25164
25165
25166
25167
25168
25169
25170
25171
25172
25173
25174
25175
25176
25177
25178
25179
25180
25181
25182
25183
25184
25185
25186
25187
25188
25189
25190
25191
25192
25193
25194
25195
25196
25197
25198
25199
25200
25201
25202
25203
25204
25205
25206
25207
25208
25209
25210
25211
25212
25213
25214
25215
25216
25217
25218
25219
25220
25221
25222
25223
25224
25225
25226
25227
25228
25229
25230
25231
25232
25233
25234
25235
25236
25237
25238
25239
25240
25241
25242
25243
25244
25245
25246
25247
25248
25249
25250
25251
25252
25253
25254
25255
25256
25257
25258
25259
25260
25261
25262
25263
25264
25265
25266
25267
25268
25269
25270
25271
25272
25273
25274
25275
25276
25277
25278
25279
25280
25281
25282
25283
25284
25285
25286
25287
25288
25289
25290
25291
25292
25293
25294
25295
25296
25297
25298
25299
25300
25301
25302
25303
25304
25305
25306
25307
25308
25309
25310
25311
25312
25313
25314
25315
25316
25317
25318
25319
25320
25321
25322
25323
25324
25325
25326
25327
25328
25329
25330
25331
25332
25333
25334
25335
25336
25337
25338
25339
25340
25341
25342
25343
25344
25345
25346
25347
25348
25349
25350
25351
25352
25353
25354
25355
25356
25357
25358
25359
25360
25361
25362
25363
25364
25365
25366
25367
25368
25369
25370
25371
25372
25373
25374
25375
25376
25377
25378
25379
25380
25381
25382
25383
25384
25385
25386
25387
25388
25389
25390
25391
25392
25393
25394
25395
25396
25397
25398
25399
25400
25401
25402
25403
25404
25405
25406
25407
25408
25409
25410
25411
25412
25413
25414
25415
25416
25417
25418
25419
25420
25421
25422
25423
25424
25425
25426
25427
25428
25429
25430
25431
25432
25433
25434
25435
25436
25437
25438
25439
25440
25441
25442
25443
25444
25445
25446
25447
25448
25449
25450
25451
25452
25453
25454
25455
25456
25457
25458
25459
25460
25461
25462
25463
25464
25465
25466
25467
25468
25469
25470
25471
25472
25473
25474
25475
25476
25477
25478
25479
25480
25481
25482
25483
25484
25485
25486
25487
25488
25489
25490
25491
25492
25493
25494
25495
25496
25497
25498
25499
25500
25501
25502
25503
25504
25505
25506
25507
25508
25509
25510
25511
25512
25513
25514
25515
25516
25517
25518
25519
25520
25521
25522
25523
25524
25525
25526
25527
25528
25529
25530
25531
25532
25533
25534
25535
25536
25537
25538
25539
25540
25541
25542
25543
25544
25545
25546
25547
25548
25549
25550
25551
25552
25553
25554
25555
25556
25557
25558
25559
25560
25561
25562
25563
25564
25565
25566
25567
25568
25569
25570
25571
25572
25573
25574
25575
25576
25577
25578
25579
25580
25581
25582
25583
25584
25585
25586
25587
25588
25589
25590
25591
25592
25593
25594
25595
25596
25597
25598
25599
25600
25601
25602
25603
25604
25605
25606
25607
25608
25609
25610
25611
25612
25613
25614
25615
25616
25617
25618
25619
25620
25621
25622
25623
25624
25625
25626
25627
25628
25629
25630
25631
25632
25633
25634
25635
25636
25637
25638
25639
25640
25641
25642
25643
25644
25645
25646
25647
25648
25649
25650
25651
25652
25653
25654
25655
25656
25657
25658
25659
25660
25661
25662
25663
25664
25665
25666
25667
25668
25669
25670
25671
25672
25673
25674
25675
25676
25677
25678
25679
25680
25681
25682
25683
25684
25685
25686
25687
25688
25689
25690
25691
25692
25693
25694
25695
25696
25697
25698
25699
25700
25701
25702
25703
25704
25705
25706
25707
25708
25709
25710
25711
25712
25713
25714
25715
25716
25717
25718
25719
25720
25721
25722
25723
25724
25725
25726
25727
25728
25729
25730
25731
25732
25733
25734
25735
25736
25737
25738
25739
25740
25741
25742
25743
25744
25745
25746
25747
25748
25749
25750
25751
25752
25753
25754
25755
25756
25757
25758
25759
25760
25761
25762
25763
25764
25765
25766
25767
25768
25769
25770
25771
25772
25773
25774
25775
25776
25777
25778
25779
25780
25781
25782
25783
25784
25785
25786
25787
25788
25789
25790
25791
25792
25793
25794
25795
25796
25797
25798
25799
25800
25801
25802
25803
25804
25805
25806
25807
25808
25809
25810
25811
25812
25813
25814
25815
25816
25817
25818
25819
25820
25821
25822
25823
25824
25825
25826
25827
25828
25829
25830
25831
25832
25833
25834
25835
25836
25837
25838
25839
25840
25841
25842
25843
25844
25845
25846
25847
25848
25849
25850
25851
25852
25853
25854
25855
25856
25857
25858
25859
25860
25861
25862
25863
25864
25865
25866
25867
25868
25869
25870
25871
25872
25873
25874
25875
25876
25877
25878
25879
25880
25881
25882
25883
25884
25885
25886
25887
25888
25889
25890
25891
25892
25893
25894
25895
25896
25897
25898
25899
25900
25901
25902
25903
25904
25905
25906
25907
25908
25909
25910
25911
25912
25913
25914
25915
25916
25917
25918
25919
25920
25921
25922
25923
25924
25925
25926
25927
25928
25929
25930
25931
25932
25933
25934
25935
25936
25937
25938
25939
25940
25941
25942
25943
25944
25945
25946
25947
25948
25949
25950
25951
25952
25953
25954
25955
25956
25957
25958
25959
25960
25961
25962
25963
25964
25965
25966
25967
25968
25969
25970
25971
25972
25973
25974
25975
25976
25977
25978
25979
25980
25981
25982
25983
25984
25985
25986
25987
25988
25989
25990
25991
25992
25993
25994
25995
25996
25997
25998
25999
26000
26001
26002
26003
26004
26005
26006
26007
26008
26009
26010
26011
26012
26013
26014
26015
26016
26017
26018
26019
26020
26021
26022
26023
26024
26025
26026
26027
26028
26029
26030
26031
26032
26033
26034
26035
26036
26037
26038
26039
26040
26041
26042
26043
26044
26045
26046
26047
26048
26049
26050
26051
26052
26053
26054
26055
26056
26057
26058
26059
26060
26061
26062
26063
26064
26065
26066
26067
26068
26069
26070
26071
26072
26073
26074
26075
26076
26077
26078
26079
26080
26081
26082
26083
26084
26085
26086
26087
26088
26089
26090
26091
26092
26093
26094
26095
26096
26097
26098
26099
26100
26101
26102
26103
26104
26105
26106
26107
26108
26109
26110
26111
26112
26113
26114
26115
26116
26117
26118
26119
26120
26121
26122
26123
26124
26125
26126
26127
26128
26129
26130
26131
26132
26133
26134
26135
26136
26137
26138
26139
26140
26141
26142
26143
26144
26145
26146
26147
26148
26149
26150
26151
26152
26153
26154
26155
26156
26157
26158
26159
26160
26161
26162
26163
26164
26165
26166
26167
26168
26169
26170
26171
26172
26173
26174
26175
26176
26177
26178
26179
26180
26181
26182
26183
26184
26185
26186
26187
26188
26189
26190
26191
26192
26193
26194
26195
26196
26197
26198
26199
26200
26201
26202
26203
26204
26205
26206
26207
26208
26209
26210
26211
26212
26213
26214
26215
26216
26217
26218
26219
26220
26221
26222
26223
26224
26225
26226
26227
26228
26229
26230
26231
26232
26233
26234
26235
26236
26237
26238
26239
26240
26241
26242
26243
26244
26245
26246
26247
26248
26249
26250
26251
26252
26253
26254
26255
26256
26257
26258
26259
26260
26261
26262
26263
26264
26265
26266
26267
26268
26269
26270
26271
26272
26273
26274
26275
26276
26277
26278
26279
26280
26281
26282
26283
26284
26285
26286
26287
26288
26289
26290
26291
26292
26293
26294
26295
26296
26297
26298
26299
26300
26301
26302
26303
26304
26305
26306
26307
26308
26309
26310
26311
26312
26313
26314
26315
26316
26317
26318
26319
26320
26321
26322
26323
26324
26325
26326
26327
26328
26329
26330
26331
26332
26333
26334
26335
26336
26337
26338
26339
26340
26341
26342
26343
26344
26345
26346
26347
26348
26349
26350
26351
26352
26353
26354
26355
26356
26357
26358
26359
26360
26361
26362
26363
26364
26365
26366
26367
26368
26369
26370
26371
26372
26373
26374
26375
26376
26377
26378
26379
26380
26381
26382
26383
26384
26385
26386
26387
26388
26389
26390
26391
26392
26393
26394
26395
26396
26397
26398
26399
26400
26401
26402
26403
26404
26405
26406
26407
26408
26409
26410
26411
26412
26413
26414
26415
26416
26417
26418
26419
26420
26421
26422
26423
26424
26425
26426
26427
26428
26429
26430
26431
26432
26433
26434
26435
26436
26437
26438
26439
26440
26441
26442
26443
26444
26445
26446
26447
26448
26449
26450
26451
26452
26453
26454
26455
26456
26457
26458
26459
26460
26461
26462
26463
26464
26465
26466
26467
26468
26469
26470
26471
26472
26473
26474
26475
26476
26477
26478
26479
26480
26481
26482
26483
26484
26485
26486
26487
26488
26489
26490
26491
26492
26493
26494
26495
26496
26497
26498
26499
26500
26501
26502
26503
26504
26505
26506
26507
26508
26509
26510
26511
26512
26513
26514
26515
26516
26517
26518
26519
26520
26521
26522
26523
26524
26525
26526
26527
26528
26529
26530
26531
26532
26533
26534
26535
26536
26537
26538
26539
26540
26541
26542
26543
26544
26545
26546
26547
26548
26549
26550
26551
26552
26553
26554
26555
26556
26557
26558
26559
26560
26561
26562
26563
26564
26565
26566
26567
26568
26569
26570
26571
26572
26573
26574
26575
26576
26577
26578
26579
26580
26581
26582
26583
26584
26585
26586
26587
26588
26589
26590
26591
26592
26593
26594
26595
26596
26597
26598
26599
26600
26601
26602
26603
26604
26605
26606
26607
26608
26609
26610
26611
26612
26613
26614
26615
26616
26617
26618
26619
26620
26621
26622
26623
26624
26625
26626
26627
26628
26629
26630
26631
26632
26633
26634
26635
26636
26637
26638
26639
26640
26641
26642
26643
26644
26645
26646
26647
26648
26649
26650
26651
26652
26653
26654
26655
26656
26657
26658
26659
26660
26661
26662
26663
26664
26665
26666
26667
26668
26669
26670
26671
26672
26673
26674
26675
26676
26677
26678
26679
26680
26681
26682
26683
26684
26685
26686
26687
26688
26689
26690
26691
26692
26693
26694
26695
26696
26697
26698
26699
26700
26701
26702
26703
26704
26705
26706
26707
26708
26709
26710
26711
26712
26713
26714
26715
26716
26717
26718
26719
26720
26721
26722
26723
26724
26725
26726
26727
26728
26729
26730
26731
26732
26733
26734
26735
26736
26737
26738
26739
26740
26741
26742
26743
26744
26745
26746
26747
26748
26749
26750
26751
26752
26753
26754
26755
26756
26757
26758
26759
26760
26761
26762
26763
26764
26765
26766
26767
26768
26769
26770
26771
26772
26773
26774
26775
26776
26777
26778
26779
26780
26781
26782
26783
26784
26785
26786
26787
26788
26789
26790
26791
26792
26793
26794
26795
26796
26797
26798
26799
26800
26801
26802
26803
26804
26805
26806
26807
26808
26809
26810
26811
26812
26813
26814
26815
26816
26817
26818
26819
26820
26821
26822
26823
26824
26825
26826
26827
26828
26829
26830
26831
26832
26833
26834
26835
26836
26837
26838
26839
26840
26841
26842
26843
26844
26845
26846
26847
26848
26849
26850
26851
26852
26853
26854
26855
26856
26857
26858
26859
26860
26861
26862
26863
26864
26865
26866
26867
26868
26869
26870
26871
26872
26873
26874
26875
26876
26877
26878
26879
26880
26881
26882
26883
26884
26885
26886
26887
26888
26889
26890
26891
26892
26893
26894
26895
26896
26897
26898
26899
26900
26901
26902
26903
26904
26905
26906
26907
26908
26909
26910
26911
26912
26913
26914
26915
26916
26917
26918
26919
26920
26921
26922
26923
26924
26925
26926
26927
26928
26929
26930
26931
26932
26933
26934
26935
26936
26937
26938
26939
26940
26941
26942
26943
26944
26945
26946
26947
26948
26949
26950
26951
26952
26953
26954
26955
26956
26957
26958
26959
26960
26961
26962
26963
26964
26965
26966
26967
26968
26969
26970
26971
26972
26973
26974
26975
26976
26977
26978
26979
26980
26981
26982
26983
26984
26985
26986
26987
26988
26989
26990
26991
26992
26993
26994
26995
26996
26997
26998
26999
27000
27001
27002
27003
27004
27005
27006
27007
27008
27009
27010
27011
27012
27013
27014
27015
27016
27017
27018
27019
27020
27021
27022
27023
27024
27025
27026
27027
27028
27029
27030
27031
27032
27033
27034
27035
27036
27037
27038
27039
27040
27041
27042
27043
27044
27045
27046
27047
27048
27049
27050
27051
27052
27053
27054
27055
27056
27057
27058
27059
27060
27061
27062
27063
27064
27065
27066
27067
27068
27069
27070
27071
27072
27073
27074
27075
27076
27077
27078
27079
27080
27081
27082
27083
27084
27085
27086
27087
27088
27089
27090
27091
27092
27093
27094
27095
27096
27097
27098
27099
27100
27101
27102
27103
27104
27105
27106
27107
27108
27109
27110
27111
27112
27113
27114
27115
27116
27117
27118
27119
27120
27121
27122
27123
27124
27125
27126
27127
27128
27129
27130
27131
27132
27133
27134
27135
27136
27137
27138
27139
27140
27141
27142
27143
27144
27145
27146
27147
27148
27149
27150
27151
27152
27153
27154
27155
27156
27157
27158
27159
27160
27161
27162
27163
27164
27165
27166
27167
27168
27169
27170
27171
27172
27173
27174
27175
27176
27177
27178
27179
27180
27181
27182
27183
27184
27185
27186
27187
27188
27189
27190
27191
27192
27193
27194
27195
27196
27197
27198
27199
27200
27201
27202
27203
27204
27205
27206
27207
27208
27209
27210
27211
27212
27213
27214
27215
27216
27217
27218
27219
27220
27221
27222
27223
27224
27225
27226
27227
27228
27229
27230
27231
27232
27233
27234
27235
27236
27237
27238
27239
27240
27241
27242
27243
27244
27245
27246
27247
27248
27249
27250
27251
27252
27253
27254
27255
27256
27257
27258
27259
27260
27261
27262
27263
27264
27265
27266
27267
27268
27269
27270
27271
27272
27273
27274
27275
27276
27277
27278
27279
27280
27281
27282
27283
27284
27285
27286
27287
27288
27289
27290
27291
27292
27293
27294
27295
27296
27297
27298
27299
27300
27301
27302
27303
27304
27305
27306
27307
27308
27309
27310
27311
27312
27313
27314
27315
27316
27317
27318
27319
27320
27321
27322
27323
27324
27325
27326
27327
27328
27329
27330
27331
27332
27333
27334
27335
27336
27337
27338
27339
27340
27341
27342
27343
27344
27345
27346
27347
27348
27349
27350
27351
27352
27353
27354
27355
27356
27357
27358
27359
27360
27361
27362
27363
27364
27365
27366
27367
27368
27369
27370
27371
27372
27373
27374
27375
27376
27377
27378
27379
27380
27381
27382
27383
27384
27385
27386
27387
27388
27389
27390
27391
27392
27393
27394
27395
27396
27397
27398
27399
27400
27401
27402
27403
27404
27405
27406
27407
27408
27409
27410
27411
27412
27413
27414
27415
27416
27417
27418
27419
27420
27421
27422
27423
27424
27425
27426
27427
27428
27429
27430
27431
27432
27433
27434
27435
27436
27437
27438
27439
27440
27441
27442
27443
27444
27445
27446
27447
27448
27449
27450
27451
27452
27453
27454
27455
27456
27457
27458
27459
27460
27461
27462
27463
27464
27465
27466
27467
27468
27469
27470
27471
27472
27473
27474
27475
27476
27477
27478
27479
27480
27481
27482
27483
27484
27485
27486
27487
27488
27489
27490
27491
27492
27493
27494
27495
27496
27497
27498
27499
27500
27501
27502
27503
27504
27505
27506
27507
27508
27509
27510
27511
27512
27513
27514
27515
27516
27517
27518
27519
27520
27521
27522
27523
27524
27525
27526
27527
27528
27529
27530
27531
27532
27533
27534
27535
27536
27537
27538
27539
27540
27541
27542
27543
27544
27545
27546
27547
27548
27549
27550
27551
27552
27553
27554
27555
27556
27557
27558
27559
27560
27561
27562
27563
27564
27565
27566
27567
27568
27569
27570
27571
27572
27573
27574
27575
27576
27577
27578
27579
27580
27581
27582
27583
27584
27585
27586
27587
27588
27589
27590
27591
27592
27593
27594
27595
27596
27597
27598
27599
27600
27601
27602
27603
27604
27605
27606
27607
27608
27609
27610
27611
27612
27613
27614
27615
27616
27617
27618
27619
27620
27621
27622
27623
27624
27625
27626
27627
27628
27629
27630
27631
27632
27633
27634
27635
27636
27637
27638
27639
27640
27641
27642
27643
27644
27645
27646
27647
27648
27649
27650
27651
27652
27653
27654
27655
27656
27657
27658
27659
27660
27661
27662
27663
27664
27665
27666
27667
27668
27669
27670
27671
27672
27673
27674
27675
27676
27677
27678
27679
27680
27681
27682
27683
27684
27685
27686
27687
27688
27689
27690
27691
27692
27693
27694
27695
27696
27697
27698
27699
27700
27701
27702
27703
27704
27705
27706
27707
27708
27709
27710
27711
27712
27713
27714
27715
27716
27717
27718
27719
27720
27721
27722
27723
27724
27725
27726
27727
27728
27729
27730
27731
27732
27733
27734
27735
27736
27737
27738
27739
27740
27741
27742
27743
27744
27745
27746
27747
27748
27749
27750
27751
27752
27753
27754
27755
27756
27757
27758
27759
27760
27761
27762
27763
27764
27765
27766
27767
27768
27769
27770
27771
27772
27773
27774
27775
27776
27777
27778
27779
27780
27781
27782
27783
27784
27785
27786
27787
27788
27789
27790
27791
27792
27793
27794
27795
27796
27797
27798
27799
27800
27801
27802
27803
27804
27805
27806
27807
27808
27809
27810
27811
27812
27813
27814
27815
27816
27817
27818
27819
27820
27821
27822
27823
27824
27825
27826
27827
27828
27829
27830
27831
27832
27833
27834
27835
27836
27837
27838
27839
27840
27841
27842
27843
27844
27845
27846
27847
27848
27849
27850
27851
27852
27853
27854
27855
27856
27857
27858
27859
27860
27861
27862
27863
27864
27865
27866
27867
27868
27869
27870
27871
27872
27873
27874
27875
27876
27877
27878
27879
27880
27881
27882
27883
27884
27885
27886
27887
27888
27889
27890
27891
27892
27893
27894
27895
27896
27897
27898
27899
27900
27901
27902
27903
27904
27905
27906
27907
27908
27909
27910
27911
27912
27913
27914
27915
27916
27917
27918
27919
27920
27921
27922
27923
27924
27925
27926
27927
27928
27929
27930
27931
27932
27933
27934
27935
27936
27937
27938
27939
27940
27941
27942
27943
27944
27945
27946
27947
27948
27949
27950
27951
27952
27953
27954
27955
27956
27957
27958
27959
27960
27961
27962
27963
27964
27965
27966
27967
27968
27969
27970
27971
27972
27973
27974
27975
27976
27977
27978
27979
27980
27981
27982
27983
27984
27985
27986
27987
27988
27989
27990
27991
27992
27993
27994
27995
27996
27997
27998
27999
28000
28001
28002
28003
28004
28005
28006
28007
28008
28009
28010
28011
28012
28013
28014
28015
28016
28017
28018
28019
28020
28021
28022
28023
28024
28025
28026
28027
28028
28029
28030
28031
28032
28033
28034
28035
28036
28037
28038
28039
28040
28041
28042
28043
28044
28045
28046
28047
28048
28049
28050
28051
28052
28053
28054
28055
28056
28057
28058
28059
28060
28061
28062
28063
28064
28065
28066
28067
28068
28069
28070
28071
28072
28073
28074
28075
28076
28077
28078
28079
28080
28081
28082
28083
28084
28085
28086
28087
28088
28089
28090
28091
28092
28093
28094
28095
28096
28097
28098
28099
28100
28101
28102
28103
28104
28105
28106
28107
28108
28109
28110
28111
28112
28113
28114
28115
28116
28117
28118
28119
28120
28121
28122
28123
28124
28125
28126
28127
28128
28129
28130
28131
28132
28133
28134
28135
28136
28137
28138
28139
28140
28141
28142
28143
28144
28145
28146
28147
28148
28149
28150
28151
28152
28153
28154
28155
28156
28157
28158
28159
28160
28161
28162
28163
28164
28165
28166
28167
28168
28169
28170
28171
28172
28173
28174
28175
28176
28177
28178
28179
28180
28181
28182
28183
28184
28185
28186
28187
28188
28189
28190
28191
28192
28193
28194
28195
28196
28197
28198
28199
28200
28201
28202
28203
28204
28205
28206
28207
28208
28209
28210
28211
28212
28213
28214
28215
28216
28217
28218
28219
28220
28221
28222
28223
28224
28225
28226
28227
28228
28229
28230
28231
28232
28233
28234
28235
28236
28237
28238
28239
28240
28241
28242
28243
28244
28245
28246
28247
28248
28249
28250
28251
28252
28253
28254
28255
28256
28257
28258
28259
28260
28261
28262
28263
28264
28265
28266
28267
28268
28269
28270
28271
28272
28273
28274
28275
28276
28277
28278
28279
28280
28281
28282
28283
28284
28285
28286
28287
28288
28289
28290
28291
28292
28293
28294
28295
28296
28297
28298
28299
28300
28301
28302
28303
28304
28305
28306
28307
28308
28309
28310
28311
28312
28313
28314
28315
28316
28317
28318
28319
28320
28321
28322
28323
28324
28325
28326
28327
28328
28329
28330
28331
28332
28333
28334
28335
28336
28337
28338
28339
28340
28341
28342
28343
28344
28345
28346
28347
28348
28349
28350
28351
28352
28353
28354
28355
28356
28357
28358
28359
28360
28361
28362
28363
28364
28365
28366
28367
28368
28369
28370
28371
28372
28373
28374
28375
28376
28377
28378
28379
28380
28381
28382
28383
28384
28385
28386
28387
28388
28389
28390
28391
28392
28393
28394
28395
28396
28397
28398
28399
28400
28401
28402
28403
28404
28405
28406
28407
28408
28409
28410
28411
28412
28413
28414
28415
28416
28417
28418
28419
28420
28421
28422
28423
28424
28425
28426
28427
28428
28429
28430
28431
28432
28433
28434
28435
28436
28437
28438
28439
28440
28441
28442
28443
28444
28445
28446
28447
28448
28449
28450
28451
28452
28453
28454
28455
28456
28457
28458
28459
28460
28461
28462
28463
28464
28465
28466
28467
28468
28469
28470
28471
28472
28473
28474
28475
28476
28477
28478
28479
28480
28481
28482
28483
28484
28485
28486
28487
28488
28489
28490
28491
28492
28493
28494
28495
28496
28497
28498
28499
28500
28501
28502
28503
28504
28505
28506
28507
28508
28509
28510
28511
28512
28513
28514
28515
28516
28517
28518
28519
28520
28521
28522
28523
28524
28525
28526
28527
28528
28529
28530
28531
28532
28533
28534
28535
28536
28537
28538
28539
28540
28541
28542
28543
28544
28545
28546
28547
28548
28549
28550
28551
28552
28553
28554
28555
28556
28557
28558
28559
28560
28561
28562
28563
28564
28565
28566
28567
28568
28569
28570
28571
28572
28573
28574
28575
28576
28577
28578
28579
28580
28581
28582
28583
28584
28585
28586
28587
28588
28589
28590
28591
28592
28593
28594
28595
28596
28597
28598
28599
28600
28601
28602
28603
28604
28605
28606
28607
28608
28609
28610
28611
28612
28613
28614
28615
28616
28617
28618
28619
28620
28621
28622
28623
28624
28625
28626
28627
28628
28629
28630
28631
28632
28633
28634
28635
28636
28637
28638
28639
28640
28641
28642
28643
28644
28645
28646
28647
28648
28649
28650
28651
28652
28653
28654
28655
28656
28657
28658
28659
28660
28661
28662
28663
28664
28665
28666
28667
28668
28669
28670
28671
28672
28673
28674
28675
28676
28677
28678
28679
28680
28681
28682
28683
28684
28685
28686
28687
28688
28689
28690
28691
28692
28693
28694
28695
28696
28697
28698
28699
28700
28701
28702
28703
28704
28705
28706
28707
28708
28709
28710
28711
28712
28713
28714
28715
28716
28717
28718
28719
28720
28721
28722
28723
28724
28725
28726
28727
28728
28729
28730
28731
28732
28733
28734
28735
28736
28737
28738
28739
28740
28741
28742
28743
28744
28745
28746
28747
28748
28749
28750
28751
28752
28753
28754
28755
28756
28757
28758
28759
28760
28761
28762
28763
28764
28765
28766
28767
28768
28769
28770
28771
28772
28773
28774
28775
28776
28777
28778
28779
28780
28781
28782
28783
28784
28785
28786
28787
28788
28789
28790
28791
28792
28793
28794
28795
28796
28797
28798
28799
28800
28801
28802
28803
28804
28805
28806
28807
28808
28809
28810
28811
28812
28813
28814
28815
28816
28817
28818
28819
28820
28821
28822
28823
28824
28825
28826
28827
28828
28829
28830
28831
28832
28833
28834
28835
28836
28837
28838
28839
28840
28841
28842
28843
28844
28845
28846
28847
28848
28849
28850
28851
28852
28853
28854
28855
28856
28857
28858
28859
28860
28861
28862
28863
28864
28865
28866
28867
28868
28869
28870
28871
28872
28873
28874
28875
28876
28877
28878
28879
28880
28881
28882
28883
28884
28885
28886
28887
28888
28889
28890
28891
28892
28893
28894
28895
28896
28897
28898
28899
28900
28901
28902
28903
28904
28905
28906
28907
28908
28909
28910
28911
28912
28913
28914
28915
28916
28917
28918
28919
28920
28921
28922
28923
28924
28925
28926
28927
28928
28929
28930
28931
28932
28933
28934
28935
28936
28937
28938
28939
28940
28941
28942
28943
28944
28945
28946
28947
28948
28949
28950
28951
28952
28953
28954
28955
28956
28957
28958
28959
28960
28961
28962
28963
28964
28965
28966
28967
28968
28969
28970
28971
28972
28973
28974
28975
28976
28977
28978
28979
28980
28981
28982
28983
28984
28985
28986
28987
28988
28989
28990
28991
28992
28993
28994
28995
28996
28997
28998
28999
29000
29001
29002
29003
29004
29005
29006
29007
29008
29009
29010
29011
29012
29013
29014
29015
29016
29017
29018
29019
29020
29021
29022
29023
29024
29025
29026
29027
29028
29029
29030
29031
29032
29033
29034
29035
29036
29037
29038
29039
29040
29041
29042
29043
29044
29045
29046
29047
29048
29049
29050
29051
29052
29053
29054
29055
29056
29057
29058
29059
29060
29061
29062
29063
29064
29065
29066
29067
29068
29069
29070
29071
29072
29073
29074
29075
29076
29077
29078
29079
29080
29081
29082
29083
29084
29085
29086
29087
29088
29089
29090
29091
29092
29093
29094
29095
29096
29097
29098
29099
29100
29101
29102
29103
29104
29105
29106
29107
29108
29109
29110
29111
29112
29113
29114
29115
29116
29117
29118
29119
29120
29121
29122
29123
29124
29125
29126
29127
29128
29129
29130
29131
29132
29133
29134
29135
29136
29137
29138
29139
29140
29141
29142
29143
29144
29145
29146
29147
29148
29149
29150
29151
29152
29153
29154
29155
29156
29157
29158
29159
29160
29161
29162
29163
29164
29165
29166
29167
29168
29169
29170
29171
29172
29173
29174
29175
29176
29177
29178
29179
29180
29181
29182
29183
29184
29185
29186
29187
29188
29189
29190
29191
29192
29193
29194
29195
29196
29197
29198
29199
29200
29201
29202
29203
29204
29205
29206
29207
29208
29209
29210
29211
29212
29213
29214
29215
29216
29217
29218
29219
29220
29221
29222
29223
29224
29225
29226
29227
29228
29229
29230
29231
29232
29233
29234
29235
29236
29237
29238
29239
29240
29241
29242
29243
29244
29245
29246
29247
29248
29249
29250
29251
29252
29253
29254
29255
29256
29257
29258
29259
29260
29261
29262
29263
29264
29265
29266
29267
29268
29269
29270
29271
29272
29273
29274
29275
29276
29277
29278
29279
29280
29281
29282
29283
29284
29285
29286
29287
29288
29289
29290
29291
29292
29293
29294
29295
29296
29297
29298
29299
29300
29301
29302
29303
29304
29305
29306
29307
29308
29309
29310
29311
29312
29313
29314
29315
29316
29317
29318
29319
29320
29321
29322
29323
29324
29325
29326
29327
29328
29329
29330
29331
29332
29333
29334
29335
29336
29337
29338
29339
29340
29341
29342
29343
29344
29345
29346
29347
29348
29349
29350
29351
29352
29353
29354
29355
29356
29357
29358
29359
29360
29361
29362
29363
29364
29365
29366
29367
29368
29369
29370
29371
29372
29373
29374
29375
29376
29377
29378
29379
29380
29381
29382
29383
29384
29385
29386
29387
29388
29389
29390
29391
29392
29393
29394
29395
29396
29397
29398
29399
29400
29401
29402
29403
29404
29405
29406
29407
29408
29409
29410
29411
29412
29413
29414
29415
29416
29417
29418
29419
29420
29421
29422
29423
29424
29425
29426
29427
29428
29429
29430
29431
29432
29433
29434
29435
29436
29437
29438
29439
29440
29441
29442
29443
29444
29445
29446
29447
29448
29449
29450
29451
29452
29453
29454
29455
29456
29457
29458
29459
29460
29461
29462
29463
29464
29465
29466
29467
29468
29469
29470
29471
29472
29473
29474
29475
29476
29477
29478
29479
29480
29481
29482
29483
29484
29485
29486
29487
29488
29489
29490
29491
29492
29493
29494
29495
29496
29497
29498
29499
29500
29501
29502
29503
29504
29505
29506
29507
29508
29509
29510
29511
29512
29513
29514
29515
29516
29517
29518
29519
29520
29521
29522
29523
29524
29525
29526
29527
29528
29529
29530
29531
29532
29533
29534
29535
29536
29537
29538
29539
29540
29541
29542
29543
29544
29545
29546
29547
29548
29549
29550
29551
29552
29553
29554
29555
29556
29557
29558
29559
29560
29561
29562
29563
29564
29565
29566
29567
29568
29569
29570
29571
29572
29573
29574
29575
29576
29577
29578
29579
29580
29581
29582
29583
29584
29585
29586
29587
29588
29589
29590
29591
29592
29593
29594
29595
29596
29597
29598
29599
29600
29601
29602
29603
29604
29605
29606
29607
29608
29609
29610
29611
29612
29613
29614
29615
29616
29617
29618
29619
29620
29621
29622
29623
29624
29625
29626
29627
29628
29629
29630
29631
29632
29633
29634
29635
29636
29637
29638
29639
29640
29641
29642
29643
29644
29645
29646
29647
29648
29649
29650
29651
29652
29653
29654
29655
29656
29657
29658
29659
29660
29661
29662
29663
29664
29665
29666
29667
29668
29669
29670
29671
29672
29673
29674
29675
29676
29677
29678
29679
29680
29681
29682
29683
29684
29685
29686
29687
29688
29689
29690
29691
29692
29693
29694
29695
29696
29697
29698
29699
29700
29701
29702
29703
29704
29705
29706
29707
29708
29709
29710
29711
29712
29713
29714
29715
29716
29717
29718
29719
29720
29721
29722
29723
29724
29725
29726
29727
29728
29729
29730
29731
29732
29733
29734
29735
29736
29737
29738
29739
29740
29741
29742
29743
29744
29745
29746
29747
29748
29749
29750
29751
29752
29753
29754
29755
29756
29757
29758
29759
29760
29761
29762
29763
29764
29765
29766
29767
29768
29769
29770
29771
29772
29773
29774
29775
29776
29777
29778
29779
29780
29781
29782
29783
29784
29785
29786
29787
29788
29789
29790
29791
29792
29793
29794
29795
29796
29797
29798
29799
29800
29801
29802
29803
29804
29805
29806
29807
29808
29809
29810
29811
29812
29813
29814
29815
29816
29817
29818
29819
29820
29821
29822
29823
29824
29825
29826
29827
29828
29829
29830
29831
29832
29833
29834
29835
29836
29837
29838
29839
29840
29841
29842
29843
29844
29845
29846
29847
29848
29849
29850
29851
29852
29853
29854
29855
29856
29857
29858
29859
29860
29861
29862
29863
29864
29865
29866
29867
29868
29869
29870
29871
29872
29873
29874
29875
29876
29877
29878
29879
29880
29881
29882
29883
29884
29885
29886
29887
29888
29889
29890
29891
29892
29893
29894
29895
29896
29897
29898
29899
29900
29901
29902
29903
29904
29905
29906
29907
29908
29909
29910
29911
29912
29913
29914
29915
29916
29917
29918
29919
29920
29921
29922
29923
29924
29925
29926
29927
29928
29929
29930
29931
29932
29933
29934
29935
29936
29937
29938
29939
29940
29941
29942
29943
29944
29945
29946
29947
29948
29949
29950
29951
29952
29953
29954
29955
29956
29957
29958
29959
29960
29961
29962
29963
29964
29965
29966
29967
29968
29969
29970
29971
29972
29973
29974
29975
29976
29977
29978
29979
29980
29981
29982
29983
29984
29985
29986
29987
29988
29989
29990
29991
29992
29993
29994
29995
29996
29997
29998
29999
30000
30001
30002
30003
30004
30005
30006
30007
30008
30009
30010
30011
30012
30013
30014
30015
30016
30017
30018
30019
30020
30021
30022
30023
30024
30025
30026
30027
30028
30029
30030
30031
30032
30033
30034
30035
30036
30037
30038
30039
30040
30041
30042
30043
30044
30045
30046
30047
30048
30049
30050
30051
30052
30053
30054
30055
30056
30057
30058
30059
30060
30061
30062
30063
30064
30065
30066
30067
30068
30069
30070
30071
30072
30073
30074
30075
30076
30077
30078
30079
30080
30081
30082
30083
30084
30085
30086
30087
30088
30089
30090
30091
30092
30093
30094
30095
30096
30097
30098
30099
30100
30101
30102
30103
30104
30105
30106
30107
30108
30109
30110
30111
30112
30113
30114
30115
30116
30117
30118
30119
30120
30121
30122
30123
30124
30125
30126
30127
30128
30129
30130
30131
30132
30133
30134
30135
30136
30137
30138
30139
30140
30141
30142
30143
30144
30145
30146
30147
30148
30149
30150
30151
30152
30153
30154
30155
30156
30157
30158
30159
30160
30161
30162
30163
30164
30165
30166
30167
30168
30169
30170
30171
30172
30173
30174
30175
30176
30177
30178
30179
30180
30181
30182
30183
30184
30185
30186
30187
30188
30189
30190
30191
30192
30193
30194
30195
30196
30197
30198
30199
30200
30201
30202
30203
30204
30205
30206
30207
30208
30209
30210
30211
30212
30213
30214
30215
30216
30217
30218
30219
30220
30221
30222
30223
30224
30225
30226
30227
30228
30229
30230
30231
30232
30233
30234
30235
30236
30237
30238
30239
30240
30241
30242
30243
30244
30245
30246
30247
30248
30249
30250
30251
30252
30253
30254
30255
30256
30257
30258
30259
30260
30261
30262
30263
30264
30265
30266
30267
30268
30269
30270
30271
30272
30273
30274
30275
30276
30277
30278
30279
30280
30281
30282
30283
30284
30285
30286
30287
30288
30289
30290
30291
30292
30293
30294
30295
30296
30297
30298
30299
30300
30301
30302
30303
30304
30305
30306
30307
30308
30309
30310
30311
30312
30313
30314
30315
30316
30317
30318
30319
30320
30321
30322
30323
30324
30325
30326
30327
30328
30329
30330
30331
30332
30333
30334
30335
30336
30337
30338
30339
30340
30341
30342
30343
30344
30345
30346
30347
30348
30349
30350
30351
30352
30353
30354
30355
30356
30357
30358
30359
30360
30361
30362
30363
30364
30365
30366
30367
30368
30369
30370
30371
30372
30373
30374
30375
30376
30377
30378
30379
30380
30381
30382
30383
30384
30385
30386
30387
30388
30389
30390
30391
30392
30393
30394
30395
30396
30397
30398
30399
30400
30401
30402
30403
30404
30405
30406
30407
30408
30409
30410
30411
30412
30413
30414
30415
30416
30417
30418
30419
30420
30421
30422
30423
30424
30425
30426
30427
30428
30429
30430
30431
30432
30433
30434
30435
30436
30437
30438
30439
30440
30441
30442
30443
30444
30445
30446
30447
30448
30449
30450
30451
30452
30453
30454
30455
30456
30457
30458
30459
30460
30461
30462
30463
30464
30465
30466
30467
30468
30469
30470
30471
30472
30473
30474
30475
30476
30477
30478
30479
30480
30481
30482
30483
30484
30485
30486
30487
30488
30489
30490
30491
30492
30493
30494
30495
30496
30497
30498
30499
30500
30501
30502
30503
30504
30505
30506
30507
30508
30509
30510
30511
30512
30513
30514
30515
30516
30517
30518
30519
30520
30521
30522
30523
30524
30525
30526
30527
30528
30529
30530
30531
30532
30533
30534
30535
30536
30537
30538
30539
30540
30541
30542
30543
30544
30545
30546
30547
30548
30549
30550
30551
30552
30553
30554
30555
30556
30557
30558
30559
30560
30561
30562
30563
30564
30565
30566
30567
30568
30569
30570
30571
30572
30573
30574
30575
30576
30577
30578
30579
30580
30581
30582
30583
30584
30585
30586
30587
30588
30589
30590
30591
30592
30593
30594
30595
30596
30597
30598
30599
30600
30601
30602
30603
30604
30605
30606
30607
30608
30609
30610
30611
30612
30613
30614
30615
30616
30617
30618
30619
30620
30621
30622
30623
30624
30625
30626
30627
30628
30629
30630
30631
30632
30633
30634
30635
30636
30637
30638
30639
30640
30641
30642
30643
30644
30645
30646
30647
30648
30649
30650
30651
30652
30653
30654
30655
30656
30657
30658
30659
30660
30661
30662
30663
30664
30665
30666
30667
30668
30669
30670
30671
30672
30673
30674
30675
30676
30677
30678
30679
30680
30681
30682
30683
30684
30685
30686
30687
30688
30689
30690
30691
30692
30693
30694
30695
30696
30697
30698
30699
30700
30701
30702
30703
30704
30705
30706
30707
30708
30709
30710
30711
30712
30713
30714
30715
30716
30717
30718
30719
30720
30721
30722
30723
30724
30725
30726
30727
30728
30729
30730
30731
30732
30733
30734
30735
30736
30737
30738
30739
30740
30741
30742
30743
30744
30745
30746
30747
30748
30749
30750
30751
30752
30753
30754
30755
30756
30757
30758
30759
30760
30761
30762
30763
30764
30765
30766
30767
30768
30769
30770
30771
30772
30773
30774
30775
30776
30777
30778
30779
30780
30781
30782
30783
30784
30785
30786
30787
30788
30789
30790
30791
30792
30793
30794
30795
30796
30797
30798
30799
30800
30801
30802
30803
30804
30805
30806
30807
30808
30809
30810
30811
30812
30813
30814
30815
30816
30817
30818
30819
30820
30821
30822
30823
30824
30825
30826
30827
30828
30829
30830
30831
30832
30833
30834
30835
30836
30837
30838
30839
30840
30841
30842
30843
30844
30845
30846
30847
30848
30849
30850
30851
30852
30853
30854
30855
30856
30857
30858
30859
30860
30861
30862
30863
30864
30865
30866
30867
30868
30869
30870
30871
30872
30873
30874
30875
30876
30877
30878
30879
30880
30881
30882
30883
30884
30885
30886
30887
30888
30889
30890
30891
30892
30893
30894
30895
30896
30897
30898
30899
30900
30901
30902
30903
30904
30905
30906
30907
30908
30909
30910
30911
30912
30913
30914
30915
30916
30917
30918
30919
30920
30921
30922
30923
30924
30925
30926
30927
30928
30929
30930
30931
30932
30933
30934
30935
30936
30937
30938
30939
30940
30941
30942
30943
30944
30945
30946
30947
30948
30949
30950
30951
30952
30953
30954
30955
30956
30957
30958
30959
30960
30961
30962
30963
30964
30965
30966
30967
30968
30969
30970
30971
30972
30973
30974
30975
30976
30977
30978
30979
30980
30981
30982
30983
30984
30985
30986
30987
30988
30989
30990
30991
30992
30993
30994
30995
30996
30997
30998
30999
31000
31001
31002
31003
31004
31005
31006
31007
31008
31009
31010
31011
31012
31013
31014
31015
31016
31017
31018
31019
31020
31021
31022
31023
31024
31025
31026
31027
31028
31029
31030
31031
31032
31033
31034
31035
31036
31037
31038
31039
31040
31041
31042
31043
31044
31045
31046
31047
31048
31049
31050
31051
31052
31053
31054
31055
31056
31057
31058
31059
31060
31061
31062
31063
31064
31065
31066
31067
31068
31069
31070
31071
31072
31073
31074
31075
31076
31077
31078
31079
31080
31081
31082
31083
31084
31085
31086
31087
31088
31089
31090
31091
31092
31093
31094
31095
31096
31097
31098
31099
31100
31101
31102
31103
31104
31105
31106
31107
31108
31109
31110
31111
31112
31113
31114
31115
31116
31117
31118
31119
31120
31121
31122
31123
31124
31125
31126
31127
31128
31129
31130
31131
31132
31133
31134
31135
31136
31137
31138
31139
31140
31141
31142
31143
31144
31145
31146
31147
31148
31149
31150
31151
31152
31153
31154
31155
31156
31157
31158
31159
31160
31161
31162
31163
31164
31165
31166
31167
31168
31169
31170
31171
31172
31173
31174
31175
31176
31177
31178
31179
31180
31181
31182
31183
31184
31185
31186
31187
31188
31189
31190
31191
31192
31193
31194
31195
31196
31197
31198
31199
31200
31201
31202
31203
31204
31205
31206
31207
31208
31209
31210
31211
31212
31213
31214
31215
31216
31217
31218
31219
31220
31221
31222
31223
31224
31225
31226
31227
31228
31229
31230
31231
31232
31233
31234
31235
31236
31237
31238
31239
31240
31241
31242
31243
31244
31245
31246
31247
31248
31249
31250
31251
31252
31253
31254
31255
31256
31257
31258
31259
31260
31261
31262
31263
31264
31265
31266
31267
31268
31269
31270
31271
31272
31273
31274
31275
31276
31277
31278
31279
31280
31281
31282
31283
31284
31285
31286
31287
31288
31289
31290
31291
31292
31293
31294
31295
31296
31297
31298
31299
31300
31301
31302
31303
31304
31305
31306
31307
31308
31309
31310
31311
31312
31313
31314
31315
31316
31317
31318
31319
31320
31321
31322
31323
31324
31325
31326
31327
31328
31329
31330
31331
31332
31333
31334
31335
31336
31337
31338
31339
31340
31341
31342
31343
31344
31345
31346
31347
31348
31349
31350
31351
31352
31353
31354
31355
31356
31357
31358
31359
31360
31361
31362
31363
31364
31365
31366
31367
31368
31369
31370
31371
31372
31373
31374
31375
31376
31377
31378
31379
31380
31381
31382
31383
31384
31385
31386
31387
31388
31389
31390
31391
31392
31393
31394
31395
31396
31397
31398
31399
31400
31401
31402
31403
31404
31405
31406
31407
31408
31409
31410
31411
31412
31413
31414
31415
31416
31417
31418
31419
31420
31421
31422
31423
31424
31425
31426
31427
31428
31429
31430
31431
31432
31433
31434
31435
31436
31437
31438
31439
31440
31441
31442
31443
31444
31445
31446
31447
31448
31449
31450
31451
31452
31453
31454
31455
31456
31457
31458
31459
31460
31461
31462
31463
31464
31465
31466
31467
31468
31469
31470
31471
31472
31473
31474
31475
31476
31477
31478
31479
31480
31481
31482
31483
31484
31485
31486
31487
31488
31489
31490
31491
31492
31493
31494
31495
31496
31497
31498
31499
31500
31501
31502
31503
31504
31505
31506
31507
31508
31509
31510
31511
31512
31513
31514
31515
31516
31517
31518
31519
31520
31521
31522
31523
31524
31525
31526
31527
31528
31529
31530
31531
31532
31533
31534
31535
31536
31537
31538
31539
31540
31541
31542
31543
31544
31545
31546
31547
31548
31549
31550
31551
31552
31553
31554
31555
31556
31557
31558
31559
31560
31561
31562
31563
31564
31565
31566
31567
31568
31569
31570
31571
31572
31573
31574
31575
31576
31577
31578
31579
31580
31581
31582
31583
31584
31585
31586
31587
31588
31589
31590
31591
31592
31593
31594
31595
31596
31597
31598
31599
31600
31601
31602
31603
31604
31605
31606
31607
31608
31609
31610
31611
31612
31613
31614
31615
31616
31617
31618
31619
31620
31621
31622
31623
31624
31625
31626
31627
31628
31629
31630
31631
31632
31633
31634
31635
31636
31637
31638
31639
31640
31641
31642
31643
31644
31645
31646
31647
31648
31649
31650
31651
31652
31653
31654
31655
31656
31657
31658
31659
31660
31661
31662
31663
31664
31665
31666
31667
31668
31669
31670
31671
31672
31673
31674
31675
31676
31677
31678
31679
31680
31681
31682
31683
31684
31685
31686
31687
31688
31689
31690
31691
31692
31693
31694
31695
31696
31697
31698
31699
31700
31701
31702
31703
31704
31705
31706
31707
31708
31709
31710
31711
31712
31713
31714
31715
31716
31717
31718
31719
31720
31721
31722
31723
31724
31725
31726
31727
31728
31729
31730
31731
31732
31733
31734
31735
31736
31737
31738
31739
31740
31741
31742
31743
31744
31745
31746
31747
31748
31749
31750
31751
31752
31753
31754
31755
31756
31757
31758
31759
31760
31761
31762
31763
31764
31765
31766
31767
31768
31769
31770
31771
31772
31773
31774
31775
31776
31777
31778
31779
31780
31781
31782
31783
31784
31785
31786
31787
31788
31789
31790
31791
31792
31793
31794
31795
31796
31797
31798
31799
31800
31801
31802
31803
31804
31805
31806
31807
31808
31809
31810
31811
31812
31813
31814
31815
31816
31817
31818
31819
31820
31821
31822
31823
31824
31825
31826
31827
31828
31829
31830
31831
31832
31833
31834
31835
31836
31837
31838
31839
31840
31841
31842
31843
31844
31845
31846
31847
31848
31849
31850
31851
31852
31853
31854
31855
31856
31857
31858
31859
31860
31861
31862
31863
31864
31865
31866
31867
31868
31869
31870
31871
31872
31873
31874
31875
31876
31877
31878
31879
31880
31881
31882
31883
31884
31885
31886
31887
31888
31889
31890
31891
31892
31893
31894
31895
31896
31897
31898
31899
31900
31901
31902
31903
31904
31905
31906
31907
31908
31909
31910
31911
31912
31913
31914
31915
31916
31917
31918
31919
31920
31921
31922
31923
31924
31925
31926
31927
31928
31929
31930
31931
31932
31933
31934
31935
31936
31937
31938
31939
31940
31941
31942
31943
31944
31945
31946
31947
31948
31949
31950
31951
31952
31953
31954
31955
31956
31957
31958
31959
31960
31961
31962
31963
31964
31965
31966
31967
31968
31969
31970
31971
31972
31973
31974
31975
31976
31977
31978
31979
31980
31981
31982
31983
31984
31985
31986
31987
31988
31989
31990
31991
31992
31993
31994
31995
31996
31997
31998
31999
32000
32001
32002
32003
32004
32005
32006
32007
32008
32009
32010
32011
32012
32013
32014
32015
32016
32017
32018
32019
32020
32021
32022
32023
32024
32025
32026
32027
32028
32029
32030
32031
32032
32033
32034
32035
32036
32037
32038
32039
32040
32041
32042
32043
32044
32045
32046
32047
32048
32049
32050
32051
32052
32053
32054
32055
32056
32057
32058
32059
32060
32061
32062
32063
32064
32065
32066
32067
32068
32069
32070
32071
32072
32073
32074
32075
32076
32077
32078
32079
32080
32081
32082
32083
32084
32085
32086
32087
32088
32089
32090
32091
32092
32093
32094
32095
32096
32097
32098
32099
32100
32101
32102
32103
32104
32105
32106
32107
32108
32109
32110
32111
32112
32113
32114
32115
32116
32117
32118
32119
32120
32121
32122
32123
32124
32125
32126
32127
32128
32129
32130
32131
32132
32133
32134
32135
32136
32137
32138
32139
32140
32141
32142
32143
32144
32145
32146
32147
32148
32149
32150
32151
32152
32153
32154
32155
32156
32157
32158
32159
32160
32161
32162
32163
32164
32165
32166
32167
32168
32169
32170
32171
32172
32173
32174
32175
32176
32177
32178
32179
32180
32181
32182
32183
32184
32185
32186
32187
32188
32189
32190
32191
32192
32193
32194
32195
32196
32197
32198
32199
32200
32201
32202
32203
32204
32205
32206
32207
32208
32209
32210
32211
32212
32213
32214
32215
32216
32217
32218
32219
32220
32221
32222
32223
32224
32225
32226
32227
32228
32229
32230
32231
32232
32233
32234
32235
32236
32237
32238
32239
32240
32241
32242
32243
32244
32245
32246
32247
32248
32249
32250
32251
32252
32253
32254
32255
32256
32257
32258
32259
32260
32261
32262
32263
32264
32265
32266
32267
32268
32269
32270
32271
32272
32273
32274
32275
32276
32277
32278
32279
32280
32281
32282
32283
32284
32285
32286
32287
32288
32289
32290
32291
32292
32293
32294
32295
32296
32297
32298
32299
32300
32301
32302
32303
32304
32305
32306
32307
32308
32309
32310
32311
32312
32313
32314
32315
32316
32317
32318
32319
32320
32321
32322
32323
32324
32325
32326
32327
32328
32329
32330
32331
32332
32333
32334
32335
32336
32337
32338
32339
32340
32341
32342
32343
32344
32345
32346
32347
32348
32349
32350
32351
32352
32353
32354
32355
32356
32357
32358
32359
32360
32361
32362
32363
32364
32365
32366
32367
32368
32369
32370
32371
32372
32373
32374
32375
32376
32377
32378
32379
32380
32381
32382
32383
32384
32385
32386
32387
32388
32389
32390
32391
32392
32393
32394
32395
32396
32397
32398
32399
32400
32401
32402
32403
32404
32405
32406
32407
32408
32409
32410
32411
32412
32413
32414
32415
32416
32417
32418
32419
32420
32421
32422
32423
32424
32425
32426
32427
32428
32429
32430
32431
32432
32433
32434
32435
32436
32437
32438
32439
32440
32441
32442
32443
32444
32445
32446
32447
32448
32449
32450
32451
32452
32453
32454
32455
32456
32457
32458
32459
32460
32461
32462
32463
32464
32465
32466
32467
32468
32469
32470
32471
32472
32473
32474
32475
32476
32477
32478
32479
32480
32481
32482
32483
32484
32485
32486
32487
32488
32489
32490
32491
32492
32493
32494
32495
32496
32497
32498
32499
32500
32501
32502
32503
32504
32505
32506
32507
32508
32509
32510
32511
32512
32513
32514
32515
32516
32517
32518
32519
32520
32521
32522
32523
32524
32525
32526
32527
32528
32529
32530
32531
32532
32533
32534
32535
32536
32537
32538
32539
32540
32541
32542
32543
32544
32545
32546
32547
32548
32549
32550
32551
32552
32553
32554
32555
32556
32557
32558
32559
32560
32561
32562
32563
32564
32565
32566
32567
32568
32569
32570
32571
32572
32573
32574
32575
32576
32577
32578
32579
32580
32581
32582
32583
32584
32585
32586
32587
32588
32589
32590
32591
32592
32593
32594
32595
32596
32597
32598
32599
32600
32601
32602
32603
32604
32605
32606
32607
32608
32609
32610
32611
32612
32613
32614
32615
32616
32617
32618
32619
32620
32621
32622
32623
32624
32625
32626
32627
32628
32629
32630
32631
32632
32633
32634
32635
32636
32637
32638
32639
32640
32641
32642
32643
32644
32645
32646
32647
32648
32649
32650
32651
32652
32653
32654
32655
32656
32657
32658
32659
32660
32661
32662
32663
32664
32665
32666
32667
32668
32669
32670
32671
32672
32673
32674
32675
32676
32677
32678
32679
32680
32681
32682
32683
32684
32685
32686
32687
32688
32689
32690
32691
32692
32693
32694
32695
32696
32697
32698
32699
32700
32701
32702
32703
32704
32705
32706
32707
32708
32709
32710
32711
32712
32713
32714
32715
32716
32717
32718
32719
32720
32721
32722
32723
32724
32725
32726
32727
32728
32729
32730
32731
32732
32733
32734
32735
32736
32737
32738
32739
32740
32741
32742
32743
32744
32745
32746
32747
32748
32749
32750
32751
32752
32753
32754
32755
32756
32757
32758
32759
32760
32761
32762
32763
32764
32765
32766
32767
32768
32769
32770
32771
32772
32773
32774
32775
32776
32777
32778
32779
32780
32781
32782
32783
32784
32785
32786
32787
32788
32789
32790
32791
32792
32793
32794
32795
32796
32797
32798
32799
32800
32801
32802
32803
32804
32805
32806
32807
32808
32809
32810
32811
32812
32813
32814
32815
32816
32817
32818
32819
32820
32821
32822
32823
32824
32825
32826
32827
32828
32829
32830
32831
32832
32833
32834
32835
32836
32837
32838
32839
32840
32841
32842
32843
32844
32845
32846
32847
32848
32849
32850
32851
32852
32853
32854
32855
32856
32857
32858
32859
32860
32861
32862
32863
32864
32865
32866
32867
32868
32869
32870
32871
32872
32873
32874
32875
32876
32877
32878
32879
32880
32881
32882
32883
32884
32885
32886
32887
32888
32889
32890
32891
32892
32893
32894
32895
32896
32897
32898
32899
32900
32901
32902
32903
32904
32905
32906
32907
32908
32909
32910
32911
32912
32913
32914
32915
32916
32917
32918
32919
32920
32921
32922
32923
32924
32925
32926
32927
32928
32929
32930
32931
32932
32933
32934
32935
32936
32937
32938
32939
32940
32941
32942
32943
32944
32945
32946
32947
32948
32949
32950
32951
32952
32953
32954
32955
32956
32957
32958
32959
32960
32961
32962
32963
32964
32965
32966
32967
32968
32969
32970
32971
32972
32973
32974
32975
32976
32977
32978
32979
32980
32981
32982
32983
32984
32985
32986
32987
32988
32989
32990
32991
32992
32993
32994
32995
32996
32997
32998
32999
33000
33001
33002
33003
33004
33005
33006
33007
33008
33009
33010
33011
33012
33013
33014
33015
33016
33017
33018
33019
33020
33021
33022
33023
33024
33025
33026
33027
33028
33029
33030
33031
33032
33033
33034
33035
33036
33037
33038
33039
33040
33041
33042
33043
33044
33045
33046
33047
33048
33049
33050
33051
33052
33053
33054
33055
33056
33057
33058
33059
33060
33061
33062
33063
33064
33065
33066
33067
33068
33069
33070
33071
33072
33073
33074
33075
33076
33077
33078
33079
33080
33081
33082
33083
33084
33085
33086
33087
33088
33089
33090
33091
33092
33093
33094
33095
33096
33097
33098
33099
33100
33101
33102
33103
33104
33105
33106
33107
33108
33109
33110
33111
33112
33113
33114
33115
33116
33117
33118
33119
33120
33121
33122
33123
33124
33125
33126
33127
33128
33129
33130
33131
33132
33133
33134
33135
33136
33137
33138
33139
33140
33141
33142
33143
33144
33145
33146
33147
33148
33149
33150
33151
33152
33153
33154
33155
33156
33157
33158
33159
33160
33161
33162
33163
33164
33165
33166
33167
33168
33169
33170
33171
33172
33173
33174
33175
33176
33177
33178
33179
33180
33181
33182
33183
33184
33185
33186
33187
33188
33189
33190
33191
33192
33193
33194
33195
33196
33197
33198
33199
33200
33201
33202
33203
33204
33205
33206
33207
33208
33209
33210
33211
33212
33213
33214
33215
33216
33217
33218
33219
33220
33221
33222
33223
33224
33225
33226
33227
33228
33229
33230
33231
33232
33233
33234
33235
33236
33237
33238
33239
33240
33241
33242
33243
33244
33245
33246
33247
33248
33249
33250
33251
33252
33253
33254
33255
33256
33257
33258
33259
33260
33261
33262
33263
33264
33265
33266
33267
33268
33269
33270
33271
33272
33273
33274
33275
33276
33277
33278
33279
33280
33281
33282
33283
33284
33285
33286
33287
33288
33289
33290
33291
33292
33293
33294
33295
33296
33297
33298
33299
33300
33301
33302
33303
33304
33305
33306
33307
33308
33309
33310
33311
33312
33313
33314
33315
33316
33317
33318
33319
33320
33321
33322
33323
33324
33325
33326
33327
33328
33329
33330
33331
33332
33333
33334
33335
33336
33337
33338
33339
33340
33341
33342
33343
33344
33345
33346
33347
33348
33349
33350
33351
33352
33353
33354
33355
33356
33357
33358
33359
33360
33361
33362
33363
33364
33365
33366
33367
33368
33369
33370
33371
33372
33373
33374
33375
33376
33377
33378
33379
33380
33381
33382
33383
33384
33385
33386
33387
33388
33389
33390
33391
33392
33393
33394
33395
33396
33397
33398
33399
33400
33401
33402
33403
33404
33405
33406
33407
33408
33409
33410
33411
33412
33413
33414
33415
33416
33417
33418
33419
33420
33421
33422
33423
33424
33425
33426
33427
33428
33429
33430
33431
33432
33433
33434
33435
33436
33437
33438
33439
33440
33441
33442
33443
33444
33445
33446
33447
33448
33449
33450
33451
33452
33453
33454
33455
33456
33457
33458
33459
33460
33461
33462
33463
33464
33465
33466
33467
33468
33469
33470
33471
33472
33473
33474
33475
33476
33477
33478
33479
33480
33481
33482
33483
33484
33485
33486
33487
33488
33489
33490
33491
33492
33493
33494
33495
33496
33497
33498
33499
33500
33501
33502
33503
33504
33505
33506
33507
33508
33509
33510
33511
33512
33513
33514
33515
33516
33517
33518
33519
33520
33521
33522
33523
33524
33525
33526
33527
33528
33529
33530
33531
33532
33533
33534
33535
33536
33537
33538
33539
33540
33541
33542
33543
33544
33545
33546
33547
33548
33549
33550
33551
33552
33553
33554
33555
33556
33557
33558
33559
33560
33561
33562
33563
33564
33565
33566
33567
33568
33569
33570
33571
33572
33573
33574
33575
33576
33577
33578
33579
33580
33581
33582
33583
33584
33585
33586
33587
33588
33589
33590
33591
33592
33593
33594
33595
33596
33597
33598
33599
33600
33601
33602
33603
33604
33605
33606
33607
33608
33609
33610
33611
33612
33613
33614
33615
33616
33617
33618
33619
33620
33621
33622
33623
33624
33625
33626
33627
33628
33629
33630
33631
33632
33633
33634
33635
33636
33637
33638
33639
33640
33641
33642
33643
33644
33645
33646
33647
33648
33649
33650
33651
33652
33653
33654
33655
33656
33657
33658
33659
33660
33661
33662
33663
33664
33665
33666
33667
33668
33669
33670
33671
33672
33673
33674
33675
33676
33677
33678
33679
33680
33681
33682
33683
33684
33685
33686
33687
33688
33689
33690
33691
33692
33693
33694
33695
33696
33697
33698
33699
33700
33701
33702
33703
33704
33705
33706
33707
33708
33709
33710
33711
33712
33713
33714
33715
33716
33717
33718
33719
33720
33721
33722
33723
33724
33725
33726
33727
33728
33729
33730
33731
33732
33733
33734
33735
33736
33737
33738
33739
33740
33741
33742
33743
33744
33745
33746
33747
33748
33749
33750
33751
33752
33753
33754
33755
33756
33757
33758
33759
33760
33761
33762
33763
33764
33765
33766
33767
33768
33769
33770
33771
33772
33773
33774
33775
33776
33777
33778
33779
33780
33781
33782
33783
33784
33785
33786
33787
33788
33789
33790
33791
33792
33793
33794
33795
33796
33797
33798
33799
33800
33801
33802
33803
33804
33805
33806
33807
33808
33809
33810
33811
33812
33813
33814
33815
33816
33817
33818
33819
33820
33821
33822
33823
33824
33825
33826
33827
33828
33829
33830
33831
33832
33833
33834
33835
33836
33837
33838
33839
33840
33841
33842
33843
33844
33845
33846
33847
33848
33849
33850
33851
33852
33853
33854
33855
33856
33857
33858
33859
33860
33861
33862
33863
33864
33865
33866
33867
33868
33869
33870
33871
33872
33873
33874
33875
33876
33877
33878
33879
33880
33881
33882
33883
33884
33885
33886
33887
33888
33889
33890
33891
33892
33893
33894
33895
33896
33897
33898
33899
33900
33901
33902
33903
33904
33905
33906
33907
33908
33909
33910
33911
33912
33913
33914
33915
33916
33917
33918
33919
33920
33921
33922
33923
33924
33925
33926
33927
33928
33929
33930
33931
33932
33933
33934
33935
33936
33937
33938
33939
33940
33941
33942
33943
33944
33945
33946
33947
33948
33949
33950
33951
33952
33953
33954
33955
33956
33957
33958
33959
33960
33961
33962
33963
33964
33965
33966
33967
33968
33969
33970
33971
33972
33973
33974
33975
33976
33977
33978
33979
33980
33981
33982
33983
33984
33985
33986
33987
33988
33989
33990
33991
33992
33993
33994
33995
33996
33997
33998
33999
34000
34001
34002
34003
34004
34005
34006
34007
34008
34009
34010
34011
34012
34013
34014
34015
34016
34017
34018
34019
34020
34021
34022
34023
34024
34025
34026
34027
34028
34029
34030
34031
34032
34033
34034
34035
34036
34037
34038
34039
34040
34041
34042
34043
34044
34045
34046
34047
34048
34049
34050
34051
34052
34053
34054
34055
34056
34057
34058
34059
34060
34061
34062
34063
34064
34065
34066
34067
34068
34069
34070
34071
34072
34073
34074
34075
34076
34077
34078
34079
34080
34081
34082
34083
34084
34085
34086
34087
34088
34089
34090
34091
34092
34093
34094
34095
34096
34097
34098
34099
34100
34101
34102
34103
34104
34105
34106
34107
34108
34109
34110
34111
34112
34113
34114
34115
34116
34117
34118
34119
34120
34121
34122
34123
34124
34125
34126
34127
34128
34129
34130
34131
34132
34133
34134
34135
34136
34137
34138
34139
34140
34141
34142
34143
34144
34145
34146
34147
34148
34149
34150
34151
34152
34153
34154
34155
34156
34157
34158
34159
34160
34161
34162
34163
34164
34165
34166
34167
34168
34169
34170
34171
34172
34173
34174
34175
34176
34177
34178
34179
34180
34181
34182
34183
34184
34185
34186
34187
34188
34189
34190
34191
34192
34193
34194
34195
34196
34197
34198
34199
34200
34201
34202
34203
34204
34205
34206
34207
34208
34209
34210
34211
34212
34213
34214
34215
34216
34217
34218
34219
34220
34221
34222
34223
34224
34225
34226
34227
|
'From Cuis 6.0 [latest update: #6079] on 23 November 2023 at 5:52:33 pm'!
'Description '!
!provides: 'DrGeo' 1 655!
!requires: 'Gettext' 1 17 nil!
!requires: 'SVG' 1 16 nil!
!requires: 'YAXO' 1 19 nil!
!requires: 'UI-Widgets' 1 0 nil!
!requires: 'UI-Preference' 1 15 nil!
!requires: 'UI-Panel' 1 17 nil!
!requires: 'Erudite' 1 224 nil!
!requires: 'Commander' 1 4 nil!
!requires: 'Graphics-Files-Additional' 1 24 nil!
SystemOrganization addCategory: #'DrGeo-Model'!
SystemOrganization addCategory: #'DrGeo-Model-Smalltalk'!
SystemOrganization addCategory: #'DrGeo-Model-Item'!
SystemOrganization addCategory: #'DrGeo-Model-Macro'!
SystemOrganization addCategory: #'DrGeo-Model-Script'!
SystemOrganization addCategory: #'DrGeo-View'!
SystemOrganization addCategory: #'DrGeo-View-Dialog'!
SystemOrganization addCategory: #'DrGeo-View-Item'!
SystemOrganization addCategory: #'DrGeo-Presenter'!
SystemOrganization addCategory: #'DrGeo-Presenter-Builder'!
SystemOrganization addCategory: #'DrGeo-Presenter-Tool'!
SystemOrganization addCategory: #'DrGeo-Presenter-Command'!
SystemOrganization addCategory: #'DrGeo-Factories'!
SystemOrganization addCategory: #'DrGeo-File'!
SystemOrganization addCategory: #'DrGeo-Styles'!
SystemOrganization addCategory: #'DrGeo-System'!
SystemOrganization addCategory: #'DrGeo-Test'!
SystemOrganization addCategory: #DrGeo!
!classDefinition: #DrGeoDomain category: #'DrGeo-Model'!
ActiveModel subclass: #DrGeoDomain
instanceVariableNames: 'factory cmdManager pointNameIndex'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model'!
!classDefinition: 'DrGeoDomain class' category: #'DrGeo-Model'!
DrGeoDomain class
instanceVariableNames: ''!
!classDefinition: #DrGMathItemBuilder category: #'DrGeo-Presenter-Builder'!
ActiveModel subclass: #DrGMathItemBuilder
instanceVariableNames: 'point flyingItem flyingMorph movingPoint presenter'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGMathItemBuilder class' category: #'DrGeo-Presenter-Builder'!
DrGMathItemBuilder class
instanceVariableNames: ''!
!classDefinition: #DrGAngleGeometricBuilder category: #'DrGeo-Presenter-Builder'!
DrGMathItemBuilder subclass: #DrGAngleGeometricBuilder
instanceVariableNames: 'pointA pointB pointC'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGAngleGeometricBuilder class' category: #'DrGeo-Presenter-Builder'!
DrGAngleGeometricBuilder class
instanceVariableNames: ''!
!classDefinition: #DrGAngleOrientedBuilder category: #'DrGeo-Presenter-Builder'!
DrGAngleGeometricBuilder subclass: #DrGAngleOrientedBuilder
instanceVariableNames: 'vectorA vectorB'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGAngleOrientedBuilder class' category: #'DrGeo-Presenter-Builder'!
DrGAngleOrientedBuilder class
instanceVariableNames: ''!
!classDefinition: #DrGArcBuilder category: #'DrGeo-Presenter-Builder'!
DrGMathItemBuilder subclass: #DrGArcBuilder
instanceVariableNames: 'pointA pointB pointC'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGArcBuilder class' category: #'DrGeo-Presenter-Builder'!
DrGArcBuilder class
instanceVariableNames: ''!
!classDefinition: #DrGArcCenterBuilder category: #'DrGeo-Presenter-Builder'!
DrGMathItemBuilder subclass: #DrGArcCenterBuilder
instanceVariableNames: 'center origin extremity'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGArcCenterBuilder class' category: #'DrGeo-Presenter-Builder'!
DrGArcCenterBuilder class
instanceVariableNames: ''!
!classDefinition: #DrGBitmapBuilder category: #'DrGeo-Presenter-Builder'!
DrGMathItemBuilder subclass: #DrGBitmapBuilder
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGBitmapBuilder class' category: #'DrGeo-Presenter-Builder'!
DrGBitmapBuilder class
instanceVariableNames: ''!
!classDefinition: #DrGCloneBuilder category: #'DrGeo-Presenter-Builder'!
DrGMathItemBuilder subclass: #DrGCloneBuilder
instanceVariableNames: 'item'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGCloneBuilder class' category: #'DrGeo-Presenter-Builder'!
DrGCloneBuilder class
instanceVariableNames: ''!
!classDefinition: #DrGCoordinatesBuilder category: #'DrGeo-Presenter-Builder'!
DrGMathItemBuilder subclass: #DrGCoordinatesBuilder
instanceVariableNames: 'pointA vector circle line'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGCoordinatesBuilder class' category: #'DrGeo-Presenter-Builder'!
DrGCoordinatesBuilder class
instanceVariableNames: ''!
!classDefinition: #DrGDummyBuilder category: #'DrGeo-Presenter-Builder'!
DrGMathItemBuilder subclass: #DrGDummyBuilder
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGDummyBuilder class' category: #'DrGeo-Presenter-Builder'!
DrGDummyBuilder class
instanceVariableNames: ''!
!classDefinition: #DrGFlyPointBuilder category: #'DrGeo-Presenter-Builder'!
DrGMathItemBuilder subclass: #DrGFlyPointBuilder
instanceVariableNames: 'curveItemA curveItemB'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGFlyPointBuilder class' category: #'DrGeo-Presenter-Builder'!
DrGFlyPointBuilder class
instanceVariableNames: ''!
!classDefinition: #DrGFreePointBuilder category: #'DrGeo-Presenter-Builder'!
DrGMathItemBuilder subclass: #DrGFreePointBuilder
instanceVariableNames: 'curveItem'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGFreePointBuilder class' category: #'DrGeo-Presenter-Builder'!
DrGFreePointBuilder class
instanceVariableNames: ''!
!classDefinition: #DrGLocusBuilder category: #'DrGeo-Presenter-Builder'!
DrGMathItemBuilder subclass: #DrGLocusBuilder
instanceVariableNames: 'freePoint constrainedPoint'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGLocusBuilder class' category: #'DrGeo-Presenter-Builder'!
DrGLocusBuilder class
instanceVariableNames: ''!
!classDefinition: #DrGMacroBuilder category: #'DrGeo-Presenter-Builder'!
DrGMathItemBuilder subclass: #DrGMacroBuilder
instanceVariableNames: 'wizard input output description title'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGMacroBuilder class' category: #'DrGeo-Presenter-Builder'!
DrGMacroBuilder class
instanceVariableNames: ''!
!classDefinition: #DrGMacroPlayer category: #'DrGeo-Presenter-Builder'!
DrGMathItemBuilder subclass: #DrGMacroPlayer
instanceVariableNames: 'wizard selectedMacro input'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGMacroPlayer class' category: #'DrGeo-Presenter-Builder'!
DrGMacroPlayer class
instanceVariableNames: ''!
!classDefinition: #DrGMacroPlayerHeadless category: #'DrGeo-Presenter-Builder'!
DrGMacroPlayer subclass: #DrGMacroPlayerHeadless
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGMacroPlayerHeadless class' category: #'DrGeo-Presenter-Builder'!
DrGMacroPlayerHeadless class
instanceVariableNames: ''!
!classDefinition: #DrGMiddleBuilder category: #'DrGeo-Presenter-Builder'!
DrGMathItemBuilder subclass: #DrGMiddleBuilder
instanceVariableNames: 'pointA pointB segment'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGMiddleBuilder class' category: #'DrGeo-Presenter-Builder'!
DrGMiddleBuilder class
instanceVariableNames: ''!
!classDefinition: #DrGPointByCoordinatesBuilder category: #'DrGeo-Presenter-Builder'!
DrGMathItemBuilder subclass: #DrGPointByCoordinatesBuilder
instanceVariableNames: 'valueX valueY script'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGPointByCoordinatesBuilder class' category: #'DrGeo-Presenter-Builder'!
DrGPointByCoordinatesBuilder class
instanceVariableNames: ''!
!classDefinition: #DrGPointIntersectionBuilder category: #'DrGeo-Presenter-Builder'!
DrGMathItemBuilder subclass: #DrGPointIntersectionBuilder
instanceVariableNames: 'curveItemA curveItemB'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGPointIntersectionBuilder class' category: #'DrGeo-Presenter-Builder'!
DrGPointIntersectionBuilder class
instanceVariableNames: ''!
!classDefinition: #DrGPolygonBuilder category: #'DrGeo-Presenter-Builder'!
DrGMathItemBuilder subclass: #DrGPolygonBuilder
instanceVariableNames: 'points'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGPolygonBuilder class' category: #'DrGeo-Presenter-Builder'!
DrGPolygonBuilder class
instanceVariableNames: ''!
!classDefinition: #DrGPolygonRegularBuilder category: #'DrGeo-Presenter-Builder'!
DrGMathItemBuilder subclass: #DrGPolygonRegularBuilder
instanceVariableNames: 'center pointA value'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGPolygonRegularBuilder class' category: #'DrGeo-Presenter-Builder'!
DrGPolygonRegularBuilder class
instanceVariableNames: ''!
!classDefinition: #DrGScriptPlayer category: #'DrGeo-Presenter-Builder'!
DrGMathItemBuilder subclass: #DrGScriptPlayer
instanceVariableNames: 'wizard input scriptClass'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGScriptPlayer class' category: #'DrGeo-Presenter-Builder'!
DrGScriptPlayer class
instanceVariableNames: ''!
!classDefinition: #DrGScriptPlayerHeadless category: #'DrGeo-Presenter-Builder'!
DrGScriptPlayer subclass: #DrGScriptPlayerHeadless
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGScriptPlayerHeadless class' category: #'DrGeo-Presenter-Builder'!
DrGScriptPlayerHeadless class
instanceVariableNames: ''!
!classDefinition: #DrGSegmentBuilder category: #'DrGeo-Presenter-Builder'!
DrGMathItemBuilder subclass: #DrGSegmentBuilder
instanceVariableNames: 'pointA pointB'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGSegmentBuilder class' category: #'DrGeo-Presenter-Builder'!
DrGSegmentBuilder class
instanceVariableNames: ''!
!classDefinition: #DrGCircleBuilder category: #'DrGeo-Presenter-Builder'!
DrGSegmentBuilder subclass: #DrGCircleBuilder
instanceVariableNames: 'radius segment'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGCircleBuilder class' category: #'DrGeo-Presenter-Builder'!
DrGCircleBuilder class
instanceVariableNames: ''!
!classDefinition: #DrGLineBuilder category: #'DrGeo-Presenter-Builder'!
DrGSegmentBuilder subclass: #DrGLineBuilder
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGLineBuilder class' category: #'DrGeo-Presenter-Builder'!
DrGLineBuilder class
instanceVariableNames: ''!
!classDefinition: #DrGAngleBisectorBuilder category: #'DrGeo-Presenter-Builder'!
DrGLineBuilder subclass: #DrGAngleBisectorBuilder
instanceVariableNames: 'pointC angle'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGAngleBisectorBuilder class' category: #'DrGeo-Presenter-Builder'!
DrGAngleBisectorBuilder class
instanceVariableNames: ''!
!classDefinition: #DrGParallelBuilder category: #'DrGeo-Presenter-Builder'!
DrGLineBuilder subclass: #DrGParallelBuilder
instanceVariableNames: 'direction'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGParallelBuilder class' category: #'DrGeo-Presenter-Builder'!
DrGParallelBuilder class
instanceVariableNames: ''!
!classDefinition: #DrGPerpendicularBuilder category: #'DrGeo-Presenter-Builder'!
DrGParallelBuilder subclass: #DrGPerpendicularBuilder
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGPerpendicularBuilder class' category: #'DrGeo-Presenter-Builder'!
DrGPerpendicularBuilder class
instanceVariableNames: ''!
!classDefinition: #DrGPerpendicularBisectorBuilder category: #'DrGeo-Presenter-Builder'!
DrGLineBuilder subclass: #DrGPerpendicularBisectorBuilder
instanceVariableNames: 'segment'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGPerpendicularBisectorBuilder class' category: #'DrGeo-Presenter-Builder'!
DrGPerpendicularBisectorBuilder class
instanceVariableNames: ''!
!classDefinition: #DrGRayBuilder category: #'DrGeo-Presenter-Builder'!
DrGSegmentBuilder subclass: #DrGRayBuilder
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGRayBuilder class' category: #'DrGeo-Presenter-Builder'!
DrGRayBuilder class
instanceVariableNames: ''!
!classDefinition: #DrGVectorBuilder category: #'DrGeo-Presenter-Builder'!
DrGSegmentBuilder subclass: #DrGVectorBuilder
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGVectorBuilder class' category: #'DrGeo-Presenter-Builder'!
DrGVectorBuilder class
instanceVariableNames: ''!
!classDefinition: #DrGTextBuilder category: #'DrGeo-Presenter-Builder'!
DrGMathItemBuilder subclass: #DrGTextBuilder
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGTextBuilder class' category: #'DrGeo-Presenter-Builder'!
DrGTextBuilder class
instanceVariableNames: ''!
!classDefinition: #DrGTransformationBuilder category: #'DrGeo-Presenter-Builder'!
DrGMathItemBuilder subclass: #DrGTransformationBuilder
instanceVariableNames: 'mathItem'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGTransformationBuilder class' category: #'DrGeo-Presenter-Builder'!
DrGTransformationBuilder class
instanceVariableNames: ''!
!classDefinition: #DrGReflectionBuilder category: #'DrGeo-Presenter-Builder'!
DrGTransformationBuilder subclass: #DrGReflectionBuilder
instanceVariableNames: 'axe'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGReflectionBuilder class' category: #'DrGeo-Presenter-Builder'!
DrGReflectionBuilder class
instanceVariableNames: ''!
!classDefinition: #DrGRotationBuilder category: #'DrGeo-Presenter-Builder'!
DrGTransformationBuilder subclass: #DrGRotationBuilder
instanceVariableNames: 'center value'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGRotationBuilder class' category: #'DrGeo-Presenter-Builder'!
DrGRotationBuilder class
instanceVariableNames: ''!
!classDefinition: #DrGHomothetyBuilder category: #'DrGeo-Presenter-Builder'!
DrGRotationBuilder subclass: #DrGHomothetyBuilder
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGHomothetyBuilder class' category: #'DrGeo-Presenter-Builder'!
DrGHomothetyBuilder class
instanceVariableNames: ''!
!classDefinition: #DrGSymmetryBuilder category: #'DrGeo-Presenter-Builder'!
DrGTransformationBuilder subclass: #DrGSymmetryBuilder
instanceVariableNames: 'center'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGSymmetryBuilder class' category: #'DrGeo-Presenter-Builder'!
DrGSymmetryBuilder class
instanceVariableNames: ''!
!classDefinition: #DrGTranslationBuilder category: #'DrGeo-Presenter-Builder'!
DrGTransformationBuilder subclass: #DrGTranslationBuilder
instanceVariableNames: 'vector'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGTranslationBuilder class' category: #'DrGeo-Presenter-Builder'!
DrGTranslationBuilder class
instanceVariableNames: ''!
!classDefinition: #DrGValueBuilder category: #'DrGeo-Presenter-Builder'!
DrGMathItemBuilder subclass: #DrGValueBuilder
instanceVariableNames: 'curveItem pointA pointB'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Builder'!
!classDefinition: 'DrGValueBuilder class' category: #'DrGeo-Presenter-Builder'!
DrGValueBuilder class
instanceVariableNames: ''!
!classDefinition: #DrGCommandStack category: #'DrGeo-Presenter-Command'!
ReadWriteStream subclass: #DrGCommandStack
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Command'!
!classDefinition: 'DrGCommandStack class' category: #'DrGeo-Presenter-Command'!
DrGCommandStack class
instanceVariableNames: ''!
!classDefinition: #DrGLocusSample category: #'DrGeo-Model-Item'!
Link subclass: #DrGLocusSample
instanceVariableNames: 'abscissa pointScreen pointWorld offScreen exist'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGLocusSample class' category: #'DrGeo-Model-Item'!
DrGLocusSample class
instanceVariableNames: ''!
!classDefinition: #DrGeoMiniView category: #'DrGeo-View'!
LayoutMorph subclass: #DrGeoMiniView
instanceVariableNames: 'drawable presenter'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-View'!
!classDefinition: 'DrGeoMiniView class' category: #'DrGeo-View'!
DrGeoMiniView class
instanceVariableNames: ''!
!classDefinition: #DrGLabel category: #'DrGeo-View'!
LabelMorph subclass: #DrGLabel
instanceVariableNames: 'blink itemMorph'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-View'!
!classDefinition: 'DrGLabel class' category: #'DrGeo-View'!
DrGLabel class
instanceVariableNames: ''!
!classDefinition: #DrGDebuggerWindow category: #'DrGeo-View-Dialog'!
DebuggerWindow subclass: #DrGDebuggerWindow
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-View-Dialog'!
!classDefinition: 'DrGDebuggerWindow class' category: #'DrGeo-View-Dialog'!
DrGDebuggerWindow class
instanceVariableNames: ''!
!classDefinition: #DrGeoView category: #'DrGeo-View'!
SystemWindow subclass: #DrGeoView
instanceVariableNames: 'presenter drawable'
classVariableNames: ''
poolDictionaries: 'nil'
category: 'DrGeo-View'!
!classDefinition: 'DrGeoView class' category: #'DrGeo-View'!
DrGeoView class
instanceVariableNames: ''!
!classDefinition: #DrGWizardMacroBuild category: #'DrGeo-View-Dialog'!
WizardPanel subclass: #DrGWizardMacroBuild
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-View-Dialog'!
!classDefinition: 'DrGWizardMacroBuild class' category: #'DrGeo-View-Dialog'!
DrGWizardMacroBuild class
instanceVariableNames: ''!
!classDefinition: #DrGWizardMacroPlay category: #'DrGeo-View-Dialog'!
WizardPanel subclass: #DrGWizardMacroPlay
instanceVariableNames: 'macroFactories'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-View-Dialog'!
!classDefinition: 'DrGWizardMacroPlay class' category: #'DrGeo-View-Dialog'!
DrGWizardMacroPlay class
instanceVariableNames: ''!
!classDefinition: #DrGWizardScript category: #'DrGeo-View-Dialog'!
WizardPanel subclass: #DrGWizardScript
instanceVariableNames: 'scripts'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-View-Dialog'!
!classDefinition: 'DrGWizardScript class' category: #'DrGeo-View-Dialog'!
DrGWizardScript class
instanceVariableNames: ''!
!classDefinition: #DrGFileOpenMorph category: #'DrGeo-View-Dialog'!
DialogPanel subclass: #DrGFileOpenMorph
instanceVariableNames: 'previews panel'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-View-Dialog'!
!classDefinition: 'DrGFileOpenMorph class' category: #'DrGeo-View-Dialog'!
DrGFileOpenMorph class
instanceVariableNames: ''!
!classDefinition: #DrGScriptDesignerDialog category: #'DrGeo-View-Dialog'!
DialogPanel subclass: #DrGScriptDesignerDialog
instanceVariableNames: 'scriptName description argumentsMorph'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-View-Dialog'!
!classDefinition: 'DrGScriptDesignerDialog class' category: #'DrGeo-View-Dialog'!
DrGScriptDesignerDialog class
instanceVariableNames: ''!
!classDefinition: #DrGSmalltalkSketchBrowser category: #'DrGeo-View-Dialog'!
DialogPanel subclass: #DrGSmalltalkSketchBrowser
instanceVariableNames: 'selectedFile drgeoView codeView sketches sketchesListMorph pane'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-View-Dialog'!
!classDefinition: 'DrGSmalltalkSketchBrowser class' category: #'DrGeo-View-Dialog'!
DrGSmalltalkSketchBrowser class
instanceVariableNames: ''!
!classDefinition: #DrGSmalltalkSketchEditor category: #'DrGeo-View-Dialog'!
DialogPanel subclass: #DrGSmalltalkSketchEditor
instanceVariableNames: 'file drgeoView codeView pane sketchProcess playButton codeAndViewPanel debugger docView'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-View-Dialog'!
!classDefinition: 'DrGSmalltalkSketchEditor class' category: #'DrGeo-View-Dialog'!
DrGSmalltalkSketchEditor class
instanceVariableNames: ''!
!classDefinition: #DrGStylePanel category: #'DrGeo-View-Dialog'!
Panel subclass: #DrGStylePanel
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-View-Dialog'!
!classDefinition: 'DrGStylePanel class' category: #'DrGeo-View-Dialog'!
DrGStylePanel class
instanceVariableNames: ''!
!classDefinition: #DrGDrawableMenu category: #'DrGeo-View'!
MenuMorph subclass: #DrGDrawableMenu
instanceVariableNames: 'tool'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-View'!
!classDefinition: 'DrGDrawableMenu class' category: #'DrGeo-View'!
DrGDrawableMenu class
instanceVariableNames: ''!
!classDefinition: #DrGDrawable category: #'DrGeo-View'!
BoxedMorph subclass: #DrGDrawable
instanceVariableNames: 'balloonTarget tipOn selection ox oy scale underMouse prevMousePos valueItem dottedLines gridScale itemViews undoneViews lastView presenter'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-View'!
!classDefinition: 'DrGDrawable class' category: #'DrGeo-View'!
DrGDrawable class
instanceVariableNames: ''!
!classDefinition: #UnderMouseMorph category: #'DrGeo-View'!
Morph subclass: #UnderMouseMorph
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-View'!
!classDefinition: 'UnderMouseMorph class' category: #'DrGeo-View'!
UnderMouseMorph class
instanceVariableNames: ''!
!classDefinition: #DrGMorph category: #'DrGeo-View-Item'!
Morph subclass: #DrGMorph
instanceVariableNames: 'drawable mathItem color style labelMorph labelPositionDelta blink'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-View-Item'!
!classDefinition: 'DrGMorph class' category: #'DrGeo-View-Item'!
DrGMorph class
instanceVariableNames: ''!
!classDefinition: #DrGAngleGeometricMorph category: #'DrGeo-View-Item'!
DrGMorph subclass: #DrGAngleGeometricMorph
instanceVariableNames: 'origin length center vector1 vector2 screenCenter'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-View-Item'!
!classDefinition: 'DrGAngleGeometricMorph class' category: #'DrGeo-View-Item'!
DrGAngleGeometricMorph class
instanceVariableNames: ''!
!classDefinition: #DrGAngleOrientedMorph category: #'DrGeo-View-Item'!
DrGAngleGeometricMorph subclass: #DrGAngleOrientedMorph
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-View-Item'!
!classDefinition: 'DrGAngleOrientedMorph class' category: #'DrGeo-View-Item'!
DrGAngleOrientedMorph class
instanceVariableNames: ''!
!classDefinition: #DrGBitmapMorph category: #'DrGeo-View-Item'!
DrGMorph subclass: #DrGBitmapMorph
instanceVariableNames: 'previousScale previousMagnify paintResource'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-View-Item'!
!classDefinition: 'DrGBitmapMorph class' category: #'DrGeo-View-Item'!
DrGBitmapMorph class
instanceVariableNames: ''!
!classDefinition: #DrGCurveMorph category: #'DrGeo-View-Item'!
DrGMorph subclass: #DrGCurveMorph
instanceVariableNames: 'borderColor borderWidth anchorAbscissa dashedBorder'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-View-Item'!
!classDefinition: 'DrGCurveMorph class' category: #'DrGeo-View-Item'!
DrGCurveMorph class
instanceVariableNames: ''!
!classDefinition: #DrGArcMorph category: #'DrGeo-View-Item'!
DrGCurveMorph subclass: #DrGArcMorph
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-View-Item'!
!classDefinition: 'DrGArcMorph class' category: #'DrGeo-View-Item'!
DrGArcMorph class
instanceVariableNames: ''!
!classDefinition: #DrGCircleMorph category: #'DrGeo-View-Item'!
DrGCurveMorph subclass: #DrGCircleMorph
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-View-Item'!
!classDefinition: 'DrGCircleMorph class' category: #'DrGeo-View-Item'!
DrGCircleMorph class
instanceVariableNames: ''!
!classDefinition: #DrGPolylineMorph category: #'DrGeo-View-Item'!
DrGCurveMorph subclass: #DrGPolylineMorph
instanceVariableNames: 'vertices closed arrows'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-View-Item'!
!classDefinition: 'DrGPolylineMorph class' category: #'DrGeo-View-Item'!
DrGPolylineMorph class
instanceVariableNames: ''!
!classDefinition: #DrGCurveStraightMorph category: #'DrGeo-View-Item'!
DrGPolylineMorph subclass: #DrGCurveStraightMorph
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-View-Item'!
!classDefinition: 'DrGCurveStraightMorph class' category: #'DrGeo-View-Item'!
DrGCurveStraightMorph class
instanceVariableNames: ''!
!classDefinition: #DrGLineMorph category: #'DrGeo-View-Item'!
DrGCurveStraightMorph subclass: #DrGLineMorph
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-View-Item'!
!classDefinition: 'DrGLineMorph class' category: #'DrGeo-View-Item'!
DrGLineMorph class
instanceVariableNames: ''!
!classDefinition: #DrGRayMorph category: #'DrGeo-View-Item'!
DrGCurveStraightMorph subclass: #DrGRayMorph
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-View-Item'!
!classDefinition: 'DrGRayMorph class' category: #'DrGeo-View-Item'!
DrGRayMorph class
instanceVariableNames: ''!
!classDefinition: #DrGSegmentMorph category: #'DrGeo-View-Item'!
DrGCurveStraightMorph subclass: #DrGSegmentMorph
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-View-Item'!
!classDefinition: 'DrGSegmentMorph class' category: #'DrGeo-View-Item'!
DrGSegmentMorph class
instanceVariableNames: ''!
!classDefinition: #DrGIconSegmentMorph category: #'DrGeo-View'!
DrGSegmentMorph subclass: #DrGIconSegmentMorph
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-View'!
!classDefinition: 'DrGIconSegmentMorph class' category: #'DrGeo-View'!
DrGIconSegmentMorph class
instanceVariableNames: ''!
!classDefinition: #DrGVectorMorph category: #'DrGeo-View-Item'!
DrGCurveStraightMorph subclass: #DrGVectorMorph
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-View-Item'!
!classDefinition: 'DrGVectorMorph class' category: #'DrGeo-View-Item'!
DrGVectorMorph class
instanceVariableNames: ''!
!classDefinition: #DrGLocusMorph category: #'DrGeo-View-Item'!
DrGPolylineMorph subclass: #DrGLocusMorph
instanceVariableNames: 'free constrained minAbscissaDelta maxScreenDelta maxAbscissaDelta freeIndex constrainedIndex samples worldBound'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-View-Item'!
!classDefinition: 'DrGLocusMorph class' category: #'DrGeo-View-Item'!
DrGLocusMorph class
instanceVariableNames: ''!
!classDefinition: #DrGLocusTransformedMorph category: #'DrGeo-View-Item'!
DrGLocusMorph subclass: #DrGLocusTransformedMorph
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-View-Item'!
!classDefinition: 'DrGLocusTransformedMorph class' category: #'DrGeo-View-Item'!
DrGLocusTransformedMorph class
instanceVariableNames: ''!
!classDefinition: #DrGPolygonMorph category: #'DrGeo-View-Item'!
DrGPolylineMorph subclass: #DrGPolygonMorph
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-View-Item'!
!classDefinition: 'DrGPolygonMorph class' category: #'DrGeo-View-Item'!
DrGPolygonMorph class
instanceVariableNames: ''!
!classDefinition: #DrGPointMorph category: #'DrGeo-View-Item'!
DrGMorph subclass: #DrGPointMorph
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-View-Item'!
!classDefinition: 'DrGPointMorph class' category: #'DrGeo-View-Item'!
DrGPointMorph class
instanceVariableNames: ''!
!classDefinition: #DrGIconPointMorph category: #'DrGeo-View'!
DrGPointMorph subclass: #DrGIconPointMorph
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-View'!
!classDefinition: 'DrGIconPointMorph class' category: #'DrGeo-View'!
DrGIconPointMorph class
instanceVariableNames: ''!
!classDefinition: #DrGTextMorph category: #'DrGeo-View-Item'!
DrGMorph subclass: #DrGTextMorph
instanceVariableNames: 'textComposition extent'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-View-Item'!
!classDefinition: 'DrGTextMorph class' category: #'DrGeo-View-Item'!
DrGTextMorph class
instanceVariableNames: ''!
!classDefinition: #DrGValueMorph category: #'DrGeo-View-Item'!
DrGTextMorph subclass: #DrGValueMorph
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-View-Item'!
!classDefinition: 'DrGValueMorph class' category: #'DrGeo-View-Item'!
DrGValueMorph class
instanceVariableNames: ''!
!classDefinition: #DrGScriptMorph category: #'DrGeo-View-Item'!
DrGValueMorph subclass: #DrGScriptMorph
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-View-Item'!
!classDefinition: 'DrGScriptMorph class' category: #'DrGeo-View-Item'!
DrGScriptMorph class
instanceVariableNames: ''!
!classDefinition: #DrGeoTreeNode category: #'DrGeo-Model'!
ListItemWrapper subclass: #DrGeoTreeNode
instanceVariableNames: 'hasContents'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model'!
!classDefinition: 'DrGeoTreeNode class' category: #'DrGeo-Model'!
DrGeoTreeNode class
instanceVariableNames: ''!
!classDefinition: #DrGeoScriptTest category: #'DrGeo-Test'!
TestCase subclass: #DrGeoScriptTest
instanceVariableNames: 'sketch'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Test'!
!classDefinition: 'DrGeoScriptTest class' category: #'DrGeo-Test'!
DrGeoScriptTest class
instanceVariableNames: ''!
!classDefinition: #DrGeoSmalltalkSketchTest category: #'DrGeo-Test'!
TestCase subclass: #DrGeoSmalltalkSketchTest
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Test'!
!classDefinition: 'DrGeoSmalltalkSketchTest class' category: #'DrGeo-Test'!
DrGeoSmalltalkSketchTest class
instanceVariableNames: ''!
!classDefinition: #LanguageFontTest category: #'DrGeo-Test'!
TestCase subclass: #LanguageFontTest
instanceVariableNames: 'fontManager'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Test'!
!classDefinition: 'LanguageFontTest class' category: #'DrGeo-Test'!
LanguageFontTest class
instanceVariableNames: ''!
!classDefinition: #DrGeoScriptTestResource category: #'DrGeo-Test'!
TestResource subclass: #DrGeoScriptTestResource
instanceVariableNames: 'sketch'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Test'!
!classDefinition: 'DrGeoScriptTestResource class' category: #'DrGeo-Test'!
DrGeoScriptTestResource class
instanceVariableNames: ''!
!classDefinition: #DrGTypeArrow category: #'DrGeo-Styles'!
PreferenceType subclass: #DrGTypeArrow
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Styles'!
!classDefinition: 'DrGTypeArrow class' category: #'DrGeo-Styles'!
DrGTypeArrow class
instanceVariableNames: ''!
!classDefinition: #DrGTypeColor category: #'DrGeo-Styles'!
PreferenceType subclass: #DrGTypeColor
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Styles'!
!classDefinition: 'DrGTypeColor class' category: #'DrGeo-Styles'!
DrGTypeColor class
instanceVariableNames: ''!
!classDefinition: #DrGTypeMark category: #'DrGeo-Styles'!
PreferenceType subclass: #DrGTypeMark
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Styles'!
!classDefinition: 'DrGTypeMark class' category: #'DrGeo-Styles'!
DrGTypeMark class
instanceVariableNames: ''!
!classDefinition: #DrGTypePointShape category: #'DrGeo-Styles'!
PreferenceType subclass: #DrGTypePointShape
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Styles'!
!classDefinition: 'DrGTypePointShape class' category: #'DrGeo-Styles'!
DrGTypePointShape class
instanceVariableNames: ''!
!classDefinition: #DrGTypePointSize category: #'DrGeo-Styles'!
PreferenceType subclass: #DrGTypePointSize
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Styles'!
!classDefinition: 'DrGTypePointSize class' category: #'DrGeo-Styles'!
DrGTypePointSize class
instanceVariableNames: ''!
!classDefinition: #DrGTypeStyle category: #'DrGeo-Styles'!
PreferenceType subclass: #DrGTypeStyle
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Styles'!
!classDefinition: 'DrGTypeStyle class' category: #'DrGeo-Styles'!
DrGTypeStyle class
instanceVariableNames: ''!
!classDefinition: #DrGTypeThickness category: #'DrGeo-Styles'!
PreferenceType subclass: #DrGTypeThickness
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Styles'!
!classDefinition: 'DrGTypeThickness class' category: #'DrGeo-Styles'!
DrGTypeThickness class
instanceVariableNames: ''!
!classDefinition: #DrGeoTree category: #'DrGeo-Model'!
Object subclass: #DrGeoTree
instanceVariableNames: 'selectedItem presenter'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model'!
!classDefinition: 'DrGeoTree class' category: #'DrGeo-Model'!
DrGeoTree class
instanceVariableNames: ''!
!classDefinition: #DrGWrappedItem category: #'DrGeo-Model-Smalltalk'!
Object subclass: #DrGWrappedItem
instanceVariableNames: 'morph'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Smalltalk'!
!classDefinition: 'DrGWrappedItem class' category: #'DrGeo-Model-Smalltalk'!
DrGWrappedItem class
instanceVariableNames: ''!
!classDefinition: #DrGWrappedCurve category: #'DrGeo-Model-Smalltalk'!
DrGWrappedItem subclass: #DrGWrappedCurve
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Smalltalk'!
!classDefinition: 'DrGWrappedCurve class' category: #'DrGeo-Model-Smalltalk'!
DrGWrappedCurve class
instanceVariableNames: ''!
!classDefinition: #DrGWrappedFilledCurve category: #'DrGeo-Model-Smalltalk'!
DrGWrappedCurve subclass: #DrGWrappedFilledCurve
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Smalltalk'!
!classDefinition: 'DrGWrappedFilledCurve class' category: #'DrGeo-Model-Smalltalk'!
DrGWrappedFilledCurve class
instanceVariableNames: ''!
!classDefinition: #DrGWrappedFinitCurve category: #'DrGeo-Model-Smalltalk'!
DrGWrappedCurve subclass: #DrGWrappedFinitCurve
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Smalltalk'!
!classDefinition: 'DrGWrappedFinitCurve class' category: #'DrGeo-Model-Smalltalk'!
DrGWrappedFinitCurve class
instanceVariableNames: ''!
!classDefinition: #DrGWrappedSegment category: #'DrGeo-Model-Smalltalk'!
DrGWrappedFinitCurve subclass: #DrGWrappedSegment
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Smalltalk'!
!classDefinition: 'DrGWrappedSegment class' category: #'DrGeo-Model-Smalltalk'!
DrGWrappedSegment class
instanceVariableNames: ''!
!classDefinition: #DrGWrappedPoint category: #'DrGeo-Model-Smalltalk'!
DrGWrappedItem subclass: #DrGWrappedPoint
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Smalltalk'!
!classDefinition: 'DrGWrappedPoint class' category: #'DrGeo-Model-Smalltalk'!
DrGWrappedPoint class
instanceVariableNames: ''!
!classDefinition: #DrGWrappedText category: #'DrGeo-Model-Smalltalk'!
DrGWrappedItem subclass: #DrGWrappedText
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Smalltalk'!
!classDefinition: 'DrGWrappedText class' category: #'DrGeo-Model-Smalltalk'!
DrGWrappedText class
instanceVariableNames: ''!
!classDefinition: #DrGWrappedValue category: #'DrGeo-Model-Smalltalk'!
DrGWrappedItem subclass: #DrGWrappedValue
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Smalltalk'!
!classDefinition: 'DrGWrappedValue class' category: #'DrGeo-Model-Smalltalk'!
DrGWrappedValue class
instanceVariableNames: ''!
!classDefinition: #DrGeoSketch category: #'DrGeo-Model-Smalltalk'!
Object subclass: #DrGeoSketch
instanceVariableNames: 'presenter doProcess'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Smalltalk'!
!classDefinition: 'DrGeoSketch class' category: #'DrGeo-Model-Smalltalk'!
DrGeoSketch class
instanceVariableNames: ''!
!classDefinition: #DrGMathItem category: #'DrGeo-Model-Item'!
Object subclass: #DrGMathItem
instanceVariableNames: 'parents name exist id hash'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGMathItem class' category: #'DrGeo-Model-Item'!
DrGMathItem class
instanceVariableNames: ''!
!classDefinition: #DrGArcItem category: #'DrGeo-Model-Item'!
DrGMathItem subclass: #DrGArcItem
instanceVariableNames: 'radius center origin length'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGArcItem class' category: #'DrGeo-Model-Item'!
DrGArcItem class
instanceVariableNames: ''!
!classDefinition: #DrGArc3ptsItem category: #'DrGeo-Model-Item'!
DrGArcItem subclass: #DrGArc3ptsItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGArc3ptsItem class' category: #'DrGeo-Model-Item'!
DrGArc3ptsItem class
instanceVariableNames: ''!
!classDefinition: #DrGArcCenterAngleItem category: #'DrGeo-Model-Item'!
DrGArcItem subclass: #DrGArcCenterAngleItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGArcCenterAngleItem class' category: #'DrGeo-Model-Item'!
DrGArcCenterAngleItem class
instanceVariableNames: ''!
!classDefinition: #DrGArcHomothetyItem category: #'DrGeo-Model-Item'!
DrGArcItem subclass: #DrGArcHomothetyItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGArcHomothetyItem class' category: #'DrGeo-Model-Item'!
DrGArcHomothetyItem class
instanceVariableNames: ''!
!classDefinition: #DrGArcReflexionItem category: #'DrGeo-Model-Item'!
DrGArcItem subclass: #DrGArcReflexionItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGArcReflexionItem class' category: #'DrGeo-Model-Item'!
DrGArcReflexionItem class
instanceVariableNames: ''!
!classDefinition: #DrGArcRotationItem category: #'DrGeo-Model-Item'!
DrGArcItem subclass: #DrGArcRotationItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGArcRotationItem class' category: #'DrGeo-Model-Item'!
DrGArcRotationItem class
instanceVariableNames: ''!
!classDefinition: #DrGArcSymmetryItem category: #'DrGeo-Model-Item'!
DrGArcItem subclass: #DrGArcSymmetryItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGArcSymmetryItem class' category: #'DrGeo-Model-Item'!
DrGArcSymmetryItem class
instanceVariableNames: ''!
!classDefinition: #DrGArcTranslationItem category: #'DrGeo-Model-Item'!
DrGArcItem subclass: #DrGArcTranslationItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGArcTranslationItem class' category: #'DrGeo-Model-Item'!
DrGArcTranslationItem class
instanceVariableNames: ''!
!classDefinition: #DrGBitmapItem category: #'DrGeo-Model-Item'!
DrGMathItem subclass: #DrGBitmapItem
instanceVariableNames: 'data locked position canvasScaleAtInsertion magnifyBy'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGBitmapItem class' category: #'DrGeo-Model-Item'!
DrGBitmapItem class
instanceVariableNames: ''!
!classDefinition: #DrGCircleItem category: #'DrGeo-Model-Item'!
DrGMathItem subclass: #DrGCircleItem
instanceVariableNames: 'radius center'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGCircleItem class' category: #'DrGeo-Model-Item'!
DrGCircleItem class
instanceVariableNames: ''!
!classDefinition: #DrGCircle2ptsItem category: #'DrGeo-Model-Item'!
DrGCircleItem subclass: #DrGCircle2ptsItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGCircle2ptsItem class' category: #'DrGeo-Model-Item'!
DrGCircle2ptsItem class
instanceVariableNames: ''!
!classDefinition: #DrGCircleHomothetyItem category: #'DrGeo-Model-Item'!
DrGCircleItem subclass: #DrGCircleHomothetyItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGCircleHomothetyItem class' category: #'DrGeo-Model-Item'!
DrGCircleHomothetyItem class
instanceVariableNames: ''!
!classDefinition: #DrGCircleRadiusItem category: #'DrGeo-Model-Item'!
DrGCircleItem subclass: #DrGCircleRadiusItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGCircleRadiusItem class' category: #'DrGeo-Model-Item'!
DrGCircleRadiusItem class
instanceVariableNames: ''!
!classDefinition: #DrGCircleSegmentItem category: #'DrGeo-Model-Item'!
DrGCircleRadiusItem subclass: #DrGCircleSegmentItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGCircleSegmentItem class' category: #'DrGeo-Model-Item'!
DrGCircleSegmentItem class
instanceVariableNames: ''!
!classDefinition: #DrGCircleReflexionItem category: #'DrGeo-Model-Item'!
DrGCircleItem subclass: #DrGCircleReflexionItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGCircleReflexionItem class' category: #'DrGeo-Model-Item'!
DrGCircleReflexionItem class
instanceVariableNames: ''!
!classDefinition: #DrGCircleRotationItem category: #'DrGeo-Model-Item'!
DrGCircleItem subclass: #DrGCircleRotationItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGCircleRotationItem class' category: #'DrGeo-Model-Item'!
DrGCircleRotationItem class
instanceVariableNames: ''!
!classDefinition: #DrGCircleSymmetryItem category: #'DrGeo-Model-Item'!
DrGCircleItem subclass: #DrGCircleSymmetryItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGCircleSymmetryItem class' category: #'DrGeo-Model-Item'!
DrGCircleSymmetryItem class
instanceVariableNames: ''!
!classDefinition: #DrGCircleTranslationItem category: #'DrGeo-Model-Item'!
DrGCircleItem subclass: #DrGCircleTranslationItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGCircleTranslationItem class' category: #'DrGeo-Model-Item'!
DrGCircleTranslationItem class
instanceVariableNames: ''!
!classDefinition: #DrGCompositeItem category: #'DrGeo-Model-Item'!
DrGMathItem subclass: #DrGCompositeItem
instanceVariableNames: 'subItems'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGCompositeItem class' category: #'DrGeo-Model-Item'!
DrGCompositeItem class
instanceVariableNames: ''!
!classDefinition: #DrGDirectionItem category: #'DrGeo-Model-Item'!
DrGMathItem subclass: #DrGDirectionItem
instanceVariableNames: 'origin vector'
classVariableNames: 'Inv2Pi InvPi'
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGDirectionItem class' category: #'DrGeo-Model-Item'!
DrGDirectionItem class
instanceVariableNames: ''!
!classDefinition: #DrGLineItem category: #'DrGeo-Model-Item'!
DrGDirectionItem subclass: #DrGLineItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGLineItem class' category: #'DrGeo-Model-Item'!
DrGLineItem class
instanceVariableNames: ''!
!classDefinition: #DrGAngleBisector3ptsItem category: #'DrGeo-Model-Item'!
DrGLineItem subclass: #DrGAngleBisector3ptsItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGAngleBisector3ptsItem class' category: #'DrGeo-Model-Item'!
DrGAngleBisector3ptsItem class
instanceVariableNames: ''!
!classDefinition: #DrGLine2ptsItem category: #'DrGeo-Model-Item'!
DrGLineItem subclass: #DrGLine2ptsItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGLine2ptsItem class' category: #'DrGeo-Model-Item'!
DrGLine2ptsItem class
instanceVariableNames: ''!
!classDefinition: #DrGLineAngleBisectorItem category: #'DrGeo-Model-Item'!
DrGLineItem subclass: #DrGLineAngleBisectorItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGLineAngleBisectorItem class' category: #'DrGeo-Model-Item'!
DrGLineAngleBisectorItem class
instanceVariableNames: ''!
!classDefinition: #DrGLineHomothetyItem category: #'DrGeo-Model-Item'!
DrGLineItem subclass: #DrGLineHomothetyItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGLineHomothetyItem class' category: #'DrGeo-Model-Item'!
DrGLineHomothetyItem class
instanceVariableNames: ''!
!classDefinition: #DrGLineParallelItem category: #'DrGeo-Model-Item'!
DrGLineItem subclass: #DrGLineParallelItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGLineParallelItem class' category: #'DrGeo-Model-Item'!
DrGLineParallelItem class
instanceVariableNames: ''!
!classDefinition: #DrGLinePerpendicularItem category: #'DrGeo-Model-Item'!
DrGLineParallelItem subclass: #DrGLinePerpendicularItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGLinePerpendicularItem class' category: #'DrGeo-Model-Item'!
DrGLinePerpendicularItem class
instanceVariableNames: ''!
!classDefinition: #DrGLineReflexionItem category: #'DrGeo-Model-Item'!
DrGLineItem subclass: #DrGLineReflexionItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGLineReflexionItem class' category: #'DrGeo-Model-Item'!
DrGLineReflexionItem class
instanceVariableNames: ''!
!classDefinition: #DrGLineRotationItem category: #'DrGeo-Model-Item'!
DrGLineItem subclass: #DrGLineRotationItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGLineRotationItem class' category: #'DrGeo-Model-Item'!
DrGLineRotationItem class
instanceVariableNames: ''!
!classDefinition: #DrGLineSymmetryItem category: #'DrGeo-Model-Item'!
DrGLineItem subclass: #DrGLineSymmetryItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGLineSymmetryItem class' category: #'DrGeo-Model-Item'!
DrGLineSymmetryItem class
instanceVariableNames: ''!
!classDefinition: #DrGLineTranslationItem category: #'DrGeo-Model-Item'!
DrGLineItem subclass: #DrGLineTranslationItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGLineTranslationItem class' category: #'DrGeo-Model-Item'!
DrGLineTranslationItem class
instanceVariableNames: ''!
!classDefinition: #DrGPerpendicularBisectorItem category: #'DrGeo-Model-Item'!
DrGLineItem subclass: #DrGPerpendicularBisectorItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGPerpendicularBisectorItem class' category: #'DrGeo-Model-Item'!
DrGPerpendicularBisectorItem class
instanceVariableNames: ''!
!classDefinition: #DrGLinePerpendicularBisector2ptsItem category: #'DrGeo-Model-Item'!
DrGPerpendicularBisectorItem subclass: #DrGLinePerpendicularBisector2ptsItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGLinePerpendicularBisector2ptsItem class' category: #'DrGeo-Model-Item'!
DrGLinePerpendicularBisector2ptsItem class
instanceVariableNames: ''!
!classDefinition: #DrGRayItem category: #'DrGeo-Model-Item'!
DrGDirectionItem subclass: #DrGRayItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGRayItem class' category: #'DrGeo-Model-Item'!
DrGRayItem class
instanceVariableNames: ''!
!classDefinition: #DrGRay2ptsItem category: #'DrGeo-Model-Item'!
DrGRayItem subclass: #DrGRay2ptsItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGRay2ptsItem class' category: #'DrGeo-Model-Item'!
DrGRay2ptsItem class
instanceVariableNames: ''!
!classDefinition: #DrGRayHomothetyItem category: #'DrGeo-Model-Item'!
DrGRayItem subclass: #DrGRayHomothetyItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGRayHomothetyItem class' category: #'DrGeo-Model-Item'!
DrGRayHomothetyItem class
instanceVariableNames: ''!
!classDefinition: #DrGRayReflexionItem category: #'DrGeo-Model-Item'!
DrGRayItem subclass: #DrGRayReflexionItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGRayReflexionItem class' category: #'DrGeo-Model-Item'!
DrGRayReflexionItem class
instanceVariableNames: ''!
!classDefinition: #DrGRayRotationItem category: #'DrGeo-Model-Item'!
DrGRayItem subclass: #DrGRayRotationItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGRayRotationItem class' category: #'DrGeo-Model-Item'!
DrGRayRotationItem class
instanceVariableNames: ''!
!classDefinition: #DrGRaySymmetryItem category: #'DrGeo-Model-Item'!
DrGRayItem subclass: #DrGRaySymmetryItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGRaySymmetryItem class' category: #'DrGeo-Model-Item'!
DrGRaySymmetryItem class
instanceVariableNames: ''!
!classDefinition: #DrGRayTranslationItem category: #'DrGeo-Model-Item'!
DrGRayItem subclass: #DrGRayTranslationItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGRayTranslationItem class' category: #'DrGeo-Model-Item'!
DrGRayTranslationItem class
instanceVariableNames: ''!
!classDefinition: #DrGSegmentItem category: #'DrGeo-Model-Item'!
DrGDirectionItem subclass: #DrGSegmentItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGSegmentItem class' category: #'DrGeo-Model-Item'!
DrGSegmentItem class
instanceVariableNames: ''!
!classDefinition: #DrGSegment2ptsItem category: #'DrGeo-Model-Item'!
DrGSegmentItem subclass: #DrGSegment2ptsItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGSegment2ptsItem class' category: #'DrGeo-Model-Item'!
DrGSegment2ptsItem class
instanceVariableNames: ''!
!classDefinition: #DrGSegmentHomothetyItem category: #'DrGeo-Model-Item'!
DrGSegmentItem subclass: #DrGSegmentHomothetyItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGSegmentHomothetyItem class' category: #'DrGeo-Model-Item'!
DrGSegmentHomothetyItem class
instanceVariableNames: ''!
!classDefinition: #DrGSegmentReflexionItem category: #'DrGeo-Model-Item'!
DrGSegmentItem subclass: #DrGSegmentReflexionItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGSegmentReflexionItem class' category: #'DrGeo-Model-Item'!
DrGSegmentReflexionItem class
instanceVariableNames: ''!
!classDefinition: #DrGSegmentRotationItem category: #'DrGeo-Model-Item'!
DrGSegmentItem subclass: #DrGSegmentRotationItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGSegmentRotationItem class' category: #'DrGeo-Model-Item'!
DrGSegmentRotationItem class
instanceVariableNames: ''!
!classDefinition: #DrGSegmentSymmetryItem category: #'DrGeo-Model-Item'!
DrGSegmentItem subclass: #DrGSegmentSymmetryItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGSegmentSymmetryItem class' category: #'DrGeo-Model-Item'!
DrGSegmentSymmetryItem class
instanceVariableNames: ''!
!classDefinition: #DrGSegmentTranslationItem category: #'DrGeo-Model-Item'!
DrGSegmentItem subclass: #DrGSegmentTranslationItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGSegmentTranslationItem class' category: #'DrGeo-Model-Item'!
DrGSegmentTranslationItem class
instanceVariableNames: ''!
!classDefinition: #DrGVectorItem category: #'DrGeo-Model-Item'!
DrGSegmentItem subclass: #DrGVectorItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGVectorItem class' category: #'DrGeo-Model-Item'!
DrGVectorItem class
instanceVariableNames: ''!
!classDefinition: #DrGVector2ptsItem category: #'DrGeo-Model-Item'!
DrGVectorItem subclass: #DrGVector2ptsItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGVector2ptsItem class' category: #'DrGeo-Model-Item'!
DrGVector2ptsItem class
instanceVariableNames: ''!
!classDefinition: #DrGVectorHomothetyItem category: #'DrGeo-Model-Item'!
DrGVectorItem subclass: #DrGVectorHomothetyItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGVectorHomothetyItem class' category: #'DrGeo-Model-Item'!
DrGVectorHomothetyItem class
instanceVariableNames: ''!
!classDefinition: #DrGVectorReflexionItem category: #'DrGeo-Model-Item'!
DrGVectorItem subclass: #DrGVectorReflexionItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGVectorReflexionItem class' category: #'DrGeo-Model-Item'!
DrGVectorReflexionItem class
instanceVariableNames: ''!
!classDefinition: #DrGVectorRotationItem category: #'DrGeo-Model-Item'!
DrGVectorItem subclass: #DrGVectorRotationItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGVectorRotationItem class' category: #'DrGeo-Model-Item'!
DrGVectorRotationItem class
instanceVariableNames: ''!
!classDefinition: #DrGVectorSymmetryItem category: #'DrGeo-Model-Item'!
DrGVectorItem subclass: #DrGVectorSymmetryItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGVectorSymmetryItem class' category: #'DrGeo-Model-Item'!
DrGVectorSymmetryItem class
instanceVariableNames: ''!
!classDefinition: #DrGLocus2ptsItem category: #'DrGeo-Model-Item'!
DrGMathItem subclass: #DrGLocus2ptsItem
instanceVariableNames: 'samplesQty p'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGLocus2ptsItem class' category: #'DrGeo-Model-Item'!
DrGLocus2ptsItem class
instanceVariableNames: ''!
!classDefinition: #DrGLocusTranslationItem category: #'DrGeo-Model-Item'!
DrGLocus2ptsItem subclass: #DrGLocusTranslationItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGLocusTranslationItem class' category: #'DrGeo-Model-Item'!
DrGLocusTranslationItem class
instanceVariableNames: ''!
!classDefinition: #DrGLocusHomothetyItem category: #'DrGeo-Model-Item'!
DrGLocusTranslationItem subclass: #DrGLocusHomothetyItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGLocusHomothetyItem class' category: #'DrGeo-Model-Item'!
DrGLocusHomothetyItem class
instanceVariableNames: ''!
!classDefinition: #DrGLocusReflexionItem category: #'DrGeo-Model-Item'!
DrGLocusTranslationItem subclass: #DrGLocusReflexionItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGLocusReflexionItem class' category: #'DrGeo-Model-Item'!
DrGLocusReflexionItem class
instanceVariableNames: ''!
!classDefinition: #DrGLocusRotationItem category: #'DrGeo-Model-Item'!
DrGLocusTranslationItem subclass: #DrGLocusRotationItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGLocusRotationItem class' category: #'DrGeo-Model-Item'!
DrGLocusRotationItem class
instanceVariableNames: ''!
!classDefinition: #DrGLocusSymmetryItem category: #'DrGeo-Model-Item'!
DrGLocusTranslationItem subclass: #DrGLocusSymmetryItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGLocusSymmetryItem class' category: #'DrGeo-Model-Item'!
DrGLocusSymmetryItem class
instanceVariableNames: ''!
!classDefinition: #DrGPointItem category: #'DrGeo-Model-Item'!
DrGMathItem subclass: #DrGPointItem
instanceVariableNames: 'point'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGPointItem class' category: #'DrGeo-Model-Item'!
DrGPointItem class
instanceVariableNames: ''!
!classDefinition: #DrGPointCoordinateItem category: #'DrGeo-Model-Item'!
DrGPointItem subclass: #DrGPointCoordinateItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGPointCoordinateItem class' category: #'DrGeo-Model-Item'!
DrGPointCoordinateItem class
instanceVariableNames: ''!
!classDefinition: #DrGPointBlockItem category: #'DrGeo-Model-Item'!
DrGPointCoordinateItem subclass: #DrGPointBlockItem
instanceVariableNames: 'pointBlock'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGPointBlockItem class' category: #'DrGeo-Model-Item'!
DrGPointBlockItem class
instanceVariableNames: ''!
!classDefinition: #DrGPointScriptItem category: #'DrGeo-Model-Item'!
DrGPointCoordinateItem subclass: #DrGPointScriptItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGPointScriptItem class' category: #'DrGeo-Model-Item'!
DrGPointScriptItem class
instanceVariableNames: ''!
!classDefinition: #DrGPointFreeItem category: #'DrGeo-Model-Item'!
DrGPointItem subclass: #DrGPointFreeItem
instanceVariableNames: 'locked'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGPointFreeItem class' category: #'DrGeo-Model-Item'!
DrGPointFreeItem class
instanceVariableNames: ''!
!classDefinition: #DrGPointHomothetyItem category: #'DrGeo-Model-Item'!
DrGPointItem subclass: #DrGPointHomothetyItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGPointHomothetyItem class' category: #'DrGeo-Model-Item'!
DrGPointHomothetyItem class
instanceVariableNames: ''!
!classDefinition: #DrGPointIntersectionItem category: #'DrGeo-Model-Item'!
DrGPointItem subclass: #DrGPointIntersectionItem
instanceVariableNames: 'k'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGPointIntersectionItem class' category: #'DrGeo-Model-Item'!
DrGPointIntersectionItem class
instanceVariableNames: ''!
!classDefinition: #DrGPointMiddle2ptsItem category: #'DrGeo-Model-Item'!
DrGPointItem subclass: #DrGPointMiddle2ptsItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGPointMiddle2ptsItem class' category: #'DrGeo-Model-Item'!
DrGPointMiddle2ptsItem class
instanceVariableNames: ''!
!classDefinition: #DrGPointMiddlesegmentItem category: #'DrGeo-Model-Item'!
DrGPointMiddle2ptsItem subclass: #DrGPointMiddlesegmentItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGPointMiddlesegmentItem class' category: #'DrGeo-Model-Item'!
DrGPointMiddlesegmentItem class
instanceVariableNames: ''!
!classDefinition: #DrGPointOncurveItem category: #'DrGeo-Model-Item'!
DrGPointItem subclass: #DrGPointOncurveItem
instanceVariableNames: 'abscissa locked'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGPointOncurveItem class' category: #'DrGeo-Model-Item'!
DrGPointOncurveItem class
instanceVariableNames: ''!
!classDefinition: #DrGPointReflexionItem category: #'DrGeo-Model-Item'!
DrGPointItem subclass: #DrGPointReflexionItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGPointReflexionItem class' category: #'DrGeo-Model-Item'!
DrGPointReflexionItem class
instanceVariableNames: ''!
!classDefinition: #DrGPointRotationItem category: #'DrGeo-Model-Item'!
DrGPointItem subclass: #DrGPointRotationItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGPointRotationItem class' category: #'DrGeo-Model-Item'!
DrGPointRotationItem class
instanceVariableNames: ''!
!classDefinition: #DrGPointSymmetryItem category: #'DrGeo-Model-Item'!
DrGPointItem subclass: #DrGPointSymmetryItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGPointSymmetryItem class' category: #'DrGeo-Model-Item'!
DrGPointSymmetryItem class
instanceVariableNames: ''!
!classDefinition: #DrGPointTranslationItem category: #'DrGeo-Model-Item'!
DrGPointItem subclass: #DrGPointTranslationItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGPointTranslationItem class' category: #'DrGeo-Model-Item'!
DrGPointTranslationItem class
instanceVariableNames: ''!
!classDefinition: #DrGPolygonItem category: #'DrGeo-Model-Item'!
DrGMathItem subclass: #DrGPolygonItem
instanceVariableNames: 'points length sidesLength'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGPolygonItem class' category: #'DrGeo-Model-Item'!
DrGPolygonItem class
instanceVariableNames: ''!
!classDefinition: #DrGPolygonHomothetyItem category: #'DrGeo-Model-Item'!
DrGPolygonItem subclass: #DrGPolygonHomothetyItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGPolygonHomothetyItem class' category: #'DrGeo-Model-Item'!
DrGPolygonHomothetyItem class
instanceVariableNames: ''!
!classDefinition: #DrGPolygonNptsItem category: #'DrGeo-Model-Item'!
DrGPolygonItem subclass: #DrGPolygonNptsItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGPolygonNptsItem class' category: #'DrGeo-Model-Item'!
DrGPolygonNptsItem class
instanceVariableNames: ''!
!classDefinition: #DrGPolygonReflexionItem category: #'DrGeo-Model-Item'!
DrGPolygonItem subclass: #DrGPolygonReflexionItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGPolygonReflexionItem class' category: #'DrGeo-Model-Item'!
DrGPolygonReflexionItem class
instanceVariableNames: ''!
!classDefinition: #DrGPolygonRegularItem category: #'DrGeo-Model-Item'!
DrGPolygonItem subclass: #DrGPolygonRegularItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGPolygonRegularItem class' category: #'DrGeo-Model-Item'!
DrGPolygonRegularItem class
instanceVariableNames: ''!
!classDefinition: #DrGPolygonRotationItem category: #'DrGeo-Model-Item'!
DrGPolygonItem subclass: #DrGPolygonRotationItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGPolygonRotationItem class' category: #'DrGeo-Model-Item'!
DrGPolygonRotationItem class
instanceVariableNames: ''!
!classDefinition: #DrGPolygonSymmetryItem category: #'DrGeo-Model-Item'!
DrGPolygonItem subclass: #DrGPolygonSymmetryItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGPolygonSymmetryItem class' category: #'DrGeo-Model-Item'!
DrGPolygonSymmetryItem class
instanceVariableNames: ''!
!classDefinition: #DrGPolygonTranslationItem category: #'DrGeo-Model-Item'!
DrGPolygonItem subclass: #DrGPolygonTranslationItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGPolygonTranslationItem class' category: #'DrGeo-Model-Item'!
DrGPolygonTranslationItem class
instanceVariableNames: ''!
!classDefinition: #DrGTextItem category: #'DrGeo-Model-Item'!
DrGMathItem subclass: #DrGTextItem
instanceVariableNames: 'text position locked'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGTextItem class' category: #'DrGeo-Model-Item'!
DrGTextItem class
instanceVariableNames: ''!
!classDefinition: #DrGValueItem category: #'DrGeo-Model-Item'!
DrGMathItem subclass: #DrGValueItem
instanceVariableNames: 'value position locked'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGValueItem class' category: #'DrGeo-Model-Item'!
DrGValueItem class
instanceVariableNames: ''!
!classDefinition: #DrGAngleItem category: #'DrGeo-Model-Item'!
DrGValueItem subclass: #DrGAngleItem
instanceVariableNames: 'radianValue degreeValue'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGAngleItem class' category: #'DrGeo-Model-Item'!
DrGAngleItem class
instanceVariableNames: ''!
!classDefinition: #DrGAngle3ptsOrientedItem category: #'DrGeo-Model-Item'!
DrGAngleItem subclass: #DrGAngle3ptsOrientedItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGAngle3ptsOrientedItem class' category: #'DrGeo-Model-Item'!
DrGAngle3ptsOrientedItem class
instanceVariableNames: ''!
!classDefinition: #DrGAngle3ptsItem category: #'DrGeo-Model-Item'!
DrGAngle3ptsOrientedItem subclass: #DrGAngle3ptsItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGAngle3ptsItem class' category: #'DrGeo-Model-Item'!
DrGAngle3ptsItem class
instanceVariableNames: ''!
!classDefinition: #DrGAngleVectorsItem category: #'DrGeo-Model-Item'!
DrGAngleItem subclass: #DrGAngleVectorsItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGAngleVectorsItem class' category: #'DrGeo-Model-Item'!
DrGAngleVectorsItem class
instanceVariableNames: ''!
!classDefinition: #DrGComputedValueItem category: #'DrGeo-Model-Item'!
DrGValueItem subclass: #DrGComputedValueItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGComputedValueItem class' category: #'DrGeo-Model-Item'!
DrGComputedValueItem class
instanceVariableNames: ''!
!classDefinition: #DrGEquationItem category: #'DrGeo-Model-Item'!
DrGComputedValueItem subclass: #DrGEquationItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGEquationItem class' category: #'DrGeo-Model-Item'!
DrGEquationItem class
instanceVariableNames: ''!
!classDefinition: #DrGEquationCircleItem category: #'DrGeo-Model-Item'!
DrGEquationItem subclass: #DrGEquationCircleItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGEquationCircleItem class' category: #'DrGeo-Model-Item'!
DrGEquationCircleItem class
instanceVariableNames: ''!
!classDefinition: #DrGEquationLineItem category: #'DrGeo-Model-Item'!
DrGEquationItem subclass: #DrGEquationLineItem
instanceVariableNames: 'a b c'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGEquationLineItem class' category: #'DrGeo-Model-Item'!
DrGEquationLineItem class
instanceVariableNames: ''!
!classDefinition: #DrGValueArclengthItem category: #'DrGeo-Model-Item'!
DrGComputedValueItem subclass: #DrGValueArclengthItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGValueArclengthItem class' category: #'DrGeo-Model-Item'!
DrGValueArclengthItem class
instanceVariableNames: ''!
!classDefinition: #DrGValueCircleperimeterItem category: #'DrGeo-Model-Item'!
DrGComputedValueItem subclass: #DrGValueCircleperimeterItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGValueCircleperimeterItem class' category: #'DrGeo-Model-Item'!
DrGValueCircleperimeterItem class
instanceVariableNames: ''!
!classDefinition: #DrGValueDistance2ptsItem category: #'DrGeo-Model-Item'!
DrGComputedValueItem subclass: #DrGValueDistance2ptsItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGValueDistance2ptsItem class' category: #'DrGeo-Model-Item'!
DrGValueDistance2ptsItem class
instanceVariableNames: ''!
!classDefinition: #DrGValueDistanceptlineItem category: #'DrGeo-Model-Item'!
DrGComputedValueItem subclass: #DrGValueDistanceptlineItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGValueDistanceptlineItem class' category: #'DrGeo-Model-Item'!
DrGValueDistanceptlineItem class
instanceVariableNames: ''!
!classDefinition: #DrGValuePolygonperimeterItem category: #'DrGeo-Model-Item'!
DrGComputedValueItem subclass: #DrGValuePolygonperimeterItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGValuePolygonperimeterItem class' category: #'DrGeo-Model-Item'!
DrGValuePolygonperimeterItem class
instanceVariableNames: ''!
!classDefinition: #DrGValuePtabscissaItem category: #'DrGeo-Model-Item'!
DrGComputedValueItem subclass: #DrGValuePtabscissaItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGValuePtabscissaItem class' category: #'DrGeo-Model-Item'!
DrGValuePtabscissaItem class
instanceVariableNames: ''!
!classDefinition: #DrGValuePtordinateItem category: #'DrGeo-Model-Item'!
DrGComputedValueItem subclass: #DrGValuePtordinateItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGValuePtordinateItem class' category: #'DrGeo-Model-Item'!
DrGValuePtordinateItem class
instanceVariableNames: ''!
!classDefinition: #DrGValueSegmentlengthItem category: #'DrGeo-Model-Item'!
DrGComputedValueItem subclass: #DrGValueSegmentlengthItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGValueSegmentlengthItem class' category: #'DrGeo-Model-Item'!
DrGValueSegmentlengthItem class
instanceVariableNames: ''!
!classDefinition: #DrGValueVectornormItem category: #'DrGeo-Model-Item'!
DrGValueSegmentlengthItem subclass: #DrGValueVectornormItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGValueVectornormItem class' category: #'DrGeo-Model-Item'!
DrGValueVectornormItem class
instanceVariableNames: ''!
!classDefinition: #DrGValueSlopeItem category: #'DrGeo-Model-Item'!
DrGComputedValueItem subclass: #DrGValueSlopeItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGValueSlopeItem class' category: #'DrGeo-Model-Item'!
DrGValueSlopeItem class
instanceVariableNames: ''!
!classDefinition: #DrGValueVectorabscissaItem category: #'DrGeo-Model-Item'!
DrGComputedValueItem subclass: #DrGValueVectorabscissaItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGValueVectorabscissaItem class' category: #'DrGeo-Model-Item'!
DrGValueVectorabscissaItem class
instanceVariableNames: ''!
!classDefinition: #DrGValueVectorordinateItem category: #'DrGeo-Model-Item'!
DrGComputedValueItem subclass: #DrGValueVectorordinateItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGValueVectorordinateItem class' category: #'DrGeo-Model-Item'!
DrGValueVectorordinateItem class
instanceVariableNames: ''!
!classDefinition: #DrGValueScriptItem category: #'DrGeo-Model-Item'!
DrGValueItem subclass: #DrGValueScriptItem
instanceVariableNames: 'script parentMorphs'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGValueScriptItem class' category: #'DrGeo-Model-Item'!
DrGValueScriptItem class
instanceVariableNames: ''!
!classDefinition: #DrGValueValueItem category: #'DrGeo-Model-Item'!
DrGValueItem subclass: #DrGValueValueItem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Item'!
!classDefinition: 'DrGValueValueItem class' category: #'DrGeo-Model-Item'!
DrGValueValueItem class
instanceVariableNames: ''!
!classDefinition: #DrGMacro category: #'DrGeo-Model-Macro'!
Object subclass: #DrGMacro
instanceVariableNames: 'nodes title description saved'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Macro'!
!classDefinition: 'DrGMacro class' category: #'DrGeo-Model-Macro'!
DrGMacro class
instanceVariableNames: ''!
!classDefinition: #DrGMacroMathItem category: #'DrGeo-Model-Macro'!
Object subclass: #DrGMacroMathItem
instanceVariableNames: 'basicType id'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Macro'!
!classDefinition: 'DrGMacroMathItem class' category: #'DrGeo-Model-Macro'!
DrGMacroMathItem class
instanceVariableNames: ''!
!classDefinition: #DrGMacroNode category: #'DrGeo-Model-Macro'!
Object subclass: #DrGMacroNode
instanceVariableNames: 'itemTemplate'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Macro'!
!classDefinition: 'DrGMacroNode class' category: #'DrGeo-Model-Macro'!
DrGMacroNode class
instanceVariableNames: ''!
!classDefinition: #DrGMacroHiddenNode category: #'DrGeo-Model-Macro'!
DrGMacroNode subclass: #DrGMacroHiddenNode
instanceVariableNames: 'parentNodes'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Macro'!
!classDefinition: 'DrGMacroHiddenNode class' category: #'DrGeo-Model-Macro'!
DrGMacroHiddenNode class
instanceVariableNames: ''!
!classDefinition: #DrGMacroOutputNode category: #'DrGeo-Model-Macro'!
DrGMacroHiddenNode subclass: #DrGMacroOutputNode
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Macro'!
!classDefinition: 'DrGMacroOutputNode class' category: #'DrGeo-Model-Macro'!
DrGMacroOutputNode class
instanceVariableNames: ''!
!classDefinition: #DrGMacroInputNode category: #'DrGeo-Model-Macro'!
DrGMacroNode subclass: #DrGMacroInputNode
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Macro'!
!classDefinition: 'DrGMacroInputNode class' category: #'DrGeo-Model-Macro'!
DrGMacroInputNode class
instanceVariableNames: ''!
!classDefinition: #DrGeoUserScript category: #'DrGeo-Model-Script'!
Object subclass: #DrGeoUserScript
instanceVariableNames: 'arguments costume'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Script'!
!classDefinition: 'DrGeoUserScript class' category: #'DrGeo-Model-Script'!
DrGeoUserScript class
instanceVariableNames: 'argumentsType'!
!classDefinition: #DrGIcons category: #'DrGeo-View'!
Object subclass: #DrGIcons
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: 'nil'
category: 'DrGeo-View'!
!classDefinition: 'DrGIcons class' category: #'DrGeo-View'!
DrGIcons class
instanceVariableNames: 'forms'!
!classDefinition: #DrGUIControlsManager category: #'DrGeo-View'!
Object subclass: #DrGUIControlsManager
instanceVariableNames: 'presenter tools statusBar tree treeView editPanel quickToolbar view'
classVariableNames: ''
poolDictionaries: 'nil'
category: 'DrGeo-View'!
!classDefinition: 'DrGUIControlsManager class' category: #'DrGeo-View'!
DrGUIControlsManager class
instanceVariableNames: ''!
!classDefinition: #DrGUIMinimalControlsManager category: #'DrGeo-View'!
DrGUIControlsManager subclass: #DrGUIMinimalControlsManager
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-View'!
!classDefinition: 'DrGUIMinimalControlsManager class' category: #'DrGeo-View'!
DrGUIMinimalControlsManager class
instanceVariableNames: ''!
!classDefinition: #DrGeo category: #'DrGeo-Presenter'!
Object subclass: #DrGeo
instanceVariableNames: 'domain controlsManager tool gridStuck isCreateMultipleMode selectedTool selection sketchName exportImageName saved notInteractive stSketch'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter'!
!classDefinition: 'DrGeo class' category: #'DrGeo-Presenter'!
DrGeo class
instanceVariableNames: ''!
!classDefinition: #DrGTool category: #'DrGeo-Presenter-Tool'!
Object subclass: #DrGTool
instanceVariableNames: 'state presenter spot last morph mathItemUnderMouse'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Tool'!
!classDefinition: 'DrGTool class' category: #'DrGeo-Presenter-Tool'!
DrGTool class
instanceVariableNames: ''!
!classDefinition: #DrGAnimateTool category: #'DrGeo-Presenter-Tool'!
DrGTool subclass: #DrGAnimateTool
instanceVariableNames: 'animateStep'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Tool'!
!classDefinition: 'DrGAnimateTool class' category: #'DrGeo-Presenter-Tool'!
DrGAnimateTool class
instanceVariableNames: ''!
!classDefinition: #DrGBuildTool category: #'DrGeo-Presenter-Tool'!
DrGTool subclass: #DrGBuildTool
instanceVariableNames: 'selectedMorphs builder'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Tool'!
!classDefinition: 'DrGBuildTool class' category: #'DrGeo-Presenter-Tool'!
DrGBuildTool class
instanceVariableNames: ''!
!classDefinition: #DrGFlyPointBuildTool category: #'DrGeo-Presenter-Tool'!
DrGBuildTool subclass: #DrGFlyPointBuildTool
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Tool'!
!classDefinition: 'DrGFlyPointBuildTool class' category: #'DrGeo-Presenter-Tool'!
DrGFlyPointBuildTool class
instanceVariableNames: ''!
!classDefinition: #DrGMacroBuildTool category: #'DrGeo-Presenter-Tool'!
DrGBuildTool subclass: #DrGMacroBuildTool
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Tool'!
!classDefinition: 'DrGMacroBuildTool class' category: #'DrGeo-Presenter-Tool'!
DrGMacroBuildTool class
instanceVariableNames: ''!
!classDefinition: #DrGMacroPlayTool category: #'DrGeo-Presenter-Tool'!
DrGMacroBuildTool subclass: #DrGMacroPlayTool
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Tool'!
!classDefinition: 'DrGMacroPlayTool class' category: #'DrGeo-Presenter-Tool'!
DrGMacroPlayTool class
instanceVariableNames: ''!
!classDefinition: #DrGScriptPlayTool category: #'DrGeo-Presenter-Tool'!
DrGMacroBuildTool subclass: #DrGScriptPlayTool
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Tool'!
!classDefinition: 'DrGScriptPlayTool class' category: #'DrGeo-Presenter-Tool'!
DrGScriptPlayTool class
instanceVariableNames: ''!
!classDefinition: #DrGFlyBuildTool category: #'DrGeo-Presenter-Tool'!
DrGTool subclass: #DrGFlyBuildTool
instanceVariableNames: 'flyPointTool mathItemTool'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Tool'!
!classDefinition: 'DrGFlyBuildTool class' category: #'DrGeo-Presenter-Tool'!
DrGFlyBuildTool class
instanceVariableNames: ''!
!classDefinition: #DrGFlyBuildTouchTool category: #'DrGeo-Presenter-Tool'!
DrGFlyBuildTool subclass: #DrGFlyBuildTouchTool
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Tool'!
!classDefinition: 'DrGFlyBuildTouchTool class' category: #'DrGeo-Presenter-Tool'!
DrGFlyBuildTouchTool class
instanceVariableNames: ''!
!classDefinition: #DrGSelectTool category: #'DrGeo-Presenter-Tool'!
DrGTool subclass: #DrGSelectTool
instanceVariableNames: 'start mathItems morphs builder'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Tool'!
!classDefinition: 'DrGSelectTool class' category: #'DrGeo-Presenter-Tool'!
DrGSelectTool class
instanceVariableNames: ''!
!classDefinition: #DrGPropertyTool category: #'DrGeo-Presenter-Tool'!
DrGSelectTool subclass: #DrGPropertyTool
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Tool'!
!classDefinition: 'DrGPropertyTool class' category: #'DrGeo-Presenter-Tool'!
DrGPropertyTool class
instanceVariableNames: ''!
!classDefinition: #DrGStyleTool category: #'DrGeo-Presenter-Tool'!
DrGTool subclass: #DrGStyleTool
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Tool'!
!classDefinition: 'DrGStyleTool class' category: #'DrGeo-Presenter-Tool'!
DrGStyleTool class
instanceVariableNames: ''!
!classDefinition: #DrGDeleteTool category: #'DrGeo-Presenter-Tool'!
DrGStyleTool subclass: #DrGDeleteTool
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Tool'!
!classDefinition: 'DrGDeleteTool class' category: #'DrGeo-Presenter-Tool'!
DrGDeleteTool class
instanceVariableNames: ''!
!classDefinition: #DrGToolState category: #'DrGeo-Presenter-Tool'!
Object subclass: #DrGToolState
instanceVariableNames: 'context'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Tool'!
!classDefinition: 'DrGToolState class' category: #'DrGeo-Presenter-Tool'!
DrGToolState class
instanceVariableNames: ''!
!classDefinition: #DrGBuildToolState category: #'DrGeo-Presenter-Tool'!
DrGToolState subclass: #DrGBuildToolState
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Tool'!
!classDefinition: 'DrGBuildToolState class' category: #'DrGeo-Presenter-Tool'!
DrGBuildToolState class
instanceVariableNames: ''!
!classDefinition: #DrGFlyPointBuildToolState category: #'DrGeo-Presenter-Tool'!
DrGBuildToolState subclass: #DrGFlyPointBuildToolState
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Tool'!
!classDefinition: 'DrGFlyPointBuildToolState class' category: #'DrGeo-Presenter-Tool'!
DrGFlyPointBuildToolState class
instanceVariableNames: ''!
!classDefinition: #DrGMacroBuildToolStateInput category: #'DrGeo-Presenter-Tool'!
DrGBuildToolState subclass: #DrGMacroBuildToolStateInput
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Tool'!
!classDefinition: 'DrGMacroBuildToolStateInput class' category: #'DrGeo-Presenter-Tool'!
DrGMacroBuildToolStateInput class
instanceVariableNames: ''!
!classDefinition: #DrGMacroPlayToolStateSelect category: #'DrGeo-Presenter-Tool'!
DrGMacroBuildToolStateInput subclass: #DrGMacroPlayToolStateSelect
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Tool'!
!classDefinition: 'DrGMacroPlayToolStateSelect class' category: #'DrGeo-Presenter-Tool'!
DrGMacroPlayToolStateSelect class
instanceVariableNames: ''!
!classDefinition: #DrGMacroBuildToolStateOutput category: #'DrGeo-Presenter-Tool'!
DrGBuildToolState subclass: #DrGMacroBuildToolStateOutput
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Tool'!
!classDefinition: 'DrGMacroBuildToolStateOutput class' category: #'DrGeo-Presenter-Tool'!
DrGMacroBuildToolStateOutput class
instanceVariableNames: ''!
!classDefinition: #DrGFlyBuildToolState category: #'DrGeo-Presenter-Tool'!
DrGToolState subclass: #DrGFlyBuildToolState
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Tool'!
!classDefinition: 'DrGFlyBuildToolState class' category: #'DrGeo-Presenter-Tool'!
DrGFlyBuildToolState class
instanceVariableNames: ''!
!classDefinition: #DrGFlyBuildTouchToolState category: #'DrGeo-Presenter-Tool'!
DrGFlyBuildToolState subclass: #DrGFlyBuildTouchToolState
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Tool'!
!classDefinition: 'DrGFlyBuildTouchToolState class' category: #'DrGeo-Presenter-Tool'!
DrGFlyBuildTouchToolState class
instanceVariableNames: ''!
!classDefinition: #DrGFlyBuildTouchToolStateGrabbed category: #'DrGeo-Presenter-Tool'!
DrGFlyBuildTouchToolState subclass: #DrGFlyBuildTouchToolStateGrabbed
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Tool'!
!classDefinition: 'DrGFlyBuildTouchToolStateGrabbed class' category: #'DrGeo-Presenter-Tool'!
DrGFlyBuildTouchToolStateGrabbed class
instanceVariableNames: ''!
!classDefinition: #DrGFlyBuildTouchToolStateSlided category: #'DrGeo-Presenter-Tool'!
DrGFlyBuildTouchToolState subclass: #DrGFlyBuildTouchToolStateSlided
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Tool'!
!classDefinition: 'DrGFlyBuildTouchToolStateSlided class' category: #'DrGeo-Presenter-Tool'!
DrGFlyBuildTouchToolStateSlided class
instanceVariableNames: ''!
!classDefinition: #DrGMacroToolStateNeutral category: #'DrGeo-Presenter-Tool'!
DrGToolState subclass: #DrGMacroToolStateNeutral
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Tool'!
!classDefinition: 'DrGMacroToolStateNeutral class' category: #'DrGeo-Presenter-Tool'!
DrGMacroToolStateNeutral class
instanceVariableNames: ''!
!classDefinition: #DrGSelectToolState category: #'DrGeo-Presenter-Tool'!
DrGToolState subclass: #DrGSelectToolState
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Tool'!
!classDefinition: 'DrGSelectToolState class' category: #'DrGeo-Presenter-Tool'!
DrGSelectToolState class
instanceVariableNames: ''!
!classDefinition: #DrGSelectToolStateDragged category: #'DrGeo-Presenter-Tool'!
DrGSelectToolState subclass: #DrGSelectToolStateDragged
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Tool'!
!classDefinition: 'DrGSelectToolStateDragged class' category: #'DrGeo-Presenter-Tool'!
DrGSelectToolStateDragged class
instanceVariableNames: ''!
!classDefinition: #DrGMutatorToolStateDragged category: #'DrGeo-Presenter-Tool'!
DrGSelectToolStateDragged subclass: #DrGMutatorToolStateDragged
instanceVariableNames: 'mutator originalPointClass'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Tool'!
!classDefinition: 'DrGMutatorToolStateDragged class' category: #'DrGeo-Presenter-Tool'!
DrGMutatorToolStateDragged class
instanceVariableNames: ''!
!classDefinition: #DrGSelectToolStateDraggedBitmap category: #'DrGeo-Presenter-Tool'!
DrGSelectToolStateDragged subclass: #DrGSelectToolStateDraggedBitmap
instanceVariableNames: 'isDraggingCorner draggedCorner corner originalMagnifyBy'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Tool'!
!classDefinition: 'DrGSelectToolStateDraggedBitmap class' category: #'DrGeo-Presenter-Tool'!
DrGSelectToolStateDraggedBitmap class
instanceVariableNames: ''!
!classDefinition: #DrGSelectToolStateGrabbed category: #'DrGeo-Presenter-Tool'!
DrGSelectToolState subclass: #DrGSelectToolStateGrabbed
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Tool'!
!classDefinition: 'DrGSelectToolStateGrabbed class' category: #'DrGeo-Presenter-Tool'!
DrGSelectToolStateGrabbed class
instanceVariableNames: ''!
!classDefinition: #DrGMutatorToolStateGrabbed category: #'DrGeo-Presenter-Tool'!
DrGSelectToolStateGrabbed subclass: #DrGMutatorToolStateGrabbed
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Tool'!
!classDefinition: 'DrGMutatorToolStateGrabbed class' category: #'DrGeo-Presenter-Tool'!
DrGMutatorToolStateGrabbed class
instanceVariableNames: ''!
!classDefinition: #DrGSelectToolStateNeutral category: #'DrGeo-Presenter-Tool'!
DrGSelectToolState subclass: #DrGSelectToolStateNeutral
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Tool'!
!classDefinition: 'DrGSelectToolStateNeutral class' category: #'DrGeo-Presenter-Tool'!
DrGSelectToolStateNeutral class
instanceVariableNames: ''!
!classDefinition: #DrGSelectToolStateSelected category: #'DrGeo-Presenter-Tool'!
DrGSelectToolState subclass: #DrGSelectToolStateSelected
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Tool'!
!classDefinition: 'DrGSelectToolStateSelected class' category: #'DrGeo-Presenter-Tool'!
DrGSelectToolStateSelected class
instanceVariableNames: ''!
!classDefinition: #DrGMutatorToolStateSelected category: #'DrGeo-Presenter-Tool'!
DrGSelectToolStateSelected subclass: #DrGMutatorToolStateSelected
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Tool'!
!classDefinition: 'DrGMutatorToolStateSelected class' category: #'DrGeo-Presenter-Tool'!
DrGMutatorToolStateSelected class
instanceVariableNames: ''!
!classDefinition: #DrGStyleToolState category: #'DrGeo-Presenter-Tool'!
DrGSelectToolState subclass: #DrGStyleToolState
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Tool'!
!classDefinition: 'DrGStyleToolState class' category: #'DrGeo-Presenter-Tool'!
DrGStyleToolState class
instanceVariableNames: ''!
!classDefinition: #DrGAnimateToolState category: #'DrGeo-Presenter-Tool'!
DrGStyleToolState subclass: #DrGAnimateToolState
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Tool'!
!classDefinition: 'DrGAnimateToolState class' category: #'DrGeo-Presenter-Tool'!
DrGAnimateToolState class
instanceVariableNames: ''!
!classDefinition: #DrGAnimateToolStateSelected category: #'DrGeo-Presenter-Tool'!
DrGAnimateToolState subclass: #DrGAnimateToolStateSelected
instanceVariableNames: 'abscissa'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Tool'!
!classDefinition: 'DrGAnimateToolStateSelected class' category: #'DrGeo-Presenter-Tool'!
DrGAnimateToolStateSelected class
instanceVariableNames: ''!
!classDefinition: #DrGDeleteToolState category: #'DrGeo-Presenter-Tool'!
DrGStyleToolState subclass: #DrGDeleteToolState
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Tool'!
!classDefinition: 'DrGDeleteToolState class' category: #'DrGeo-Presenter-Tool'!
DrGDeleteToolState class
instanceVariableNames: ''!
!classDefinition: #DrGPropertyToolState category: #'DrGeo-Presenter-Tool'!
DrGStyleToolState subclass: #DrGPropertyToolState
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Tool'!
!classDefinition: 'DrGPropertyToolState class' category: #'DrGeo-Presenter-Tool'!
DrGPropertyToolState class
instanceVariableNames: ''!
!classDefinition: #DrGCommand category: #'DrGeo-Presenter-Command'!
Object subclass: #DrGCommand
instanceVariableNames: 'domain'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Command'!
!classDefinition: 'DrGCommand class' category: #'DrGeo-Presenter-Command'!
DrGCommand class
instanceVariableNames: ''!
!classDefinition: #DrGCompositeCommand category: #'DrGeo-Presenter-Command'!
DrGCommand subclass: #DrGCompositeCommand
instanceVariableNames: 'compositeItem mathItems'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Command'!
!classDefinition: 'DrGCompositeCommand class' category: #'DrGeo-Presenter-Command'!
DrGCompositeCommand class
instanceVariableNames: ''!
!classDefinition: #DrGDeleteCommand category: #'DrGeo-Presenter-Command'!
DrGCommand subclass: #DrGDeleteCommand
instanceVariableNames: 'mathItems'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Command'!
!classDefinition: 'DrGDeleteCommand class' category: #'DrGeo-Presenter-Command'!
DrGDeleteCommand class
instanceVariableNames: ''!
!classDefinition: #DrGMathItemCommand category: #'DrGeo-Presenter-Command'!
DrGCommand subclass: #DrGMathItemCommand
instanceVariableNames: 'mathItems'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Command'!
!classDefinition: 'DrGMathItemCommand class' category: #'DrGeo-Presenter-Command'!
DrGMathItemCommand class
instanceVariableNames: ''!
!classDefinition: #DrGMergeCommand category: #'DrGeo-Presenter-Command'!
DrGCommand subclass: #DrGMergeCommand
instanceVariableNames: 'mathItem target directChildren mathItemIndex'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Command'!
!classDefinition: 'DrGMergeCommand class' category: #'DrGeo-Presenter-Command'!
DrGMergeCommand class
instanceVariableNames: ''!
!classDefinition: #DrGMoveCommand category: #'DrGeo-Presenter-Command'!
DrGCommand subclass: #DrGMoveCommand
instanceVariableNames: 'vector mathItem'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Command'!
!classDefinition: 'DrGMoveCommand class' category: #'DrGeo-Presenter-Command'!
DrGMoveCommand class
instanceVariableNames: ''!
!classDefinition: #DrGPropertyCommand category: #'DrGeo-Presenter-Command'!
DrGCommand subclass: #DrGPropertyCommand
instanceVariableNames: 'property mathItem'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Command'!
!classDefinition: 'DrGPropertyCommand class' category: #'DrGeo-Presenter-Command'!
DrGPropertyCommand class
instanceVariableNames: ''!
!classDefinition: #DrGCommandManager category: #'DrGeo-Presenter-Command'!
Object subclass: #DrGCommandManager
instanceVariableNames: 'stack domain'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Presenter-Command'!
!classDefinition: 'DrGCommandManager class' category: #'DrGeo-Presenter-Command'!
DrGCommandManager class
instanceVariableNames: ''!
!classDefinition: #DrGFactory category: #'DrGeo-Factories'!
Object subclass: #DrGFactory
instanceVariableNames: 'pool last'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Factories'!
!classDefinition: 'DrGFactory class' category: #'DrGeo-Factories'!
DrGFactory class
instanceVariableNames: ''!
!classDefinition: #DrGMacroFactory category: #'DrGeo-Factories'!
DrGFactory subclass: #DrGMacroFactory
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Factories'!
!classDefinition: 'DrGMacroFactory class' category: #'DrGeo-Factories'!
DrGMacroFactory class
instanceVariableNames: 'uniqueInstance'!
!classDefinition: #DrGMathItemFactory category: #'DrGeo-Factories'!
DrGFactory subclass: #DrGMathItemFactory
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Factories'!
!classDefinition: 'DrGMathItemFactory class' category: #'DrGeo-Factories'!
DrGMathItemFactory class
instanceVariableNames: ''!
!classDefinition: #DrGSvgCanvas category: #'DrGeo-File'!
Object subclass: #DrGSvgCanvas
instanceVariableNames: 'presenter svgTree firstPoint currentPoint pathNode'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-File'!
!classDefinition: 'DrGSvgCanvas class' category: #'DrGeo-File'!
DrGSvgCanvas class
instanceVariableNames: ''!
!classDefinition: #DrGeoCommandLineHandler category: #'DrGeo-File'!
Object subclass: #DrGeoCommandLineHandler
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-File'!
!classDefinition: 'DrGeoCommandLineHandler class' category: #'DrGeo-File'!
DrGeoCommandLineHandler class
instanceVariableNames: ''!
!classDefinition: #DrGeoXml category: #'DrGeo-File'!
Object subclass: #DrGeoXml
instanceVariableNames: 'presenter'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-File'!
!classDefinition: 'DrGeoXml class' category: #'DrGeo-File'!
DrGeoXml class
instanceVariableNames: ''!
!classDefinition: #DrGStyle category: #'DrGeo-Styles'!
Object subclass: #DrGStyle
instanceVariableNames: 'morph color hidden feedback'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Styles'!
!classDefinition: 'DrGStyle class' category: #'DrGeo-Styles'!
DrGStyle class
instanceVariableNames: ''!
!classDefinition: #DrGCurveStyle category: #'DrGeo-Styles'!
DrGStyle subclass: #DrGCurveStyle
instanceVariableNames: 'thickness lineStyle'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Styles'!
!classDefinition: 'DrGCurveStyle class' category: #'DrGeo-Styles'!
DrGCurveStyle class
instanceVariableNames: ''!
!classDefinition: #DrGFinitCurveStyle category: #'DrGeo-Styles'!
DrGCurveStyle subclass: #DrGFinitCurveStyle
instanceVariableNames: 'arrow'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Styles'!
!classDefinition: 'DrGFinitCurveStyle class' category: #'DrGeo-Styles'!
DrGFinitCurveStyle class
instanceVariableNames: ''!
!classDefinition: #DrGCompositeStyle category: #'DrGeo-Styles'!
DrGFinitCurveStyle subclass: #DrGCompositeStyle
instanceVariableNames: 'shape'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Styles'!
!classDefinition: 'DrGCompositeStyle class' category: #'DrGeo-Styles'!
DrGCompositeStyle class
instanceVariableNames: ''!
!classDefinition: #DrGFilledStyle category: #'DrGeo-Styles'!
DrGFinitCurveStyle subclass: #DrGFilledStyle
instanceVariableNames: 'fill translucent'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Styles'!
!classDefinition: 'DrGFilledStyle class' category: #'DrGeo-Styles'!
DrGFilledStyle class
instanceVariableNames: ''!
!classDefinition: #DrGArcStyle category: #'DrGeo-Styles'!
DrGFilledStyle subclass: #DrGArcStyle
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Styles'!
!classDefinition: 'DrGArcStyle class' category: #'DrGeo-Styles'!
DrGArcStyle class
instanceVariableNames: ''!
!classDefinition: #DrGCircleStyle category: #'DrGeo-Styles'!
DrGFilledStyle subclass: #DrGCircleStyle
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Styles'!
!classDefinition: 'DrGCircleStyle class' category: #'DrGeo-Styles'!
DrGCircleStyle class
instanceVariableNames: ''!
!classDefinition: #DrGPolygonStyle category: #'DrGeo-Styles'!
DrGFilledStyle subclass: #DrGPolygonStyle
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Styles'!
!classDefinition: 'DrGPolygonStyle class' category: #'DrGeo-Styles'!
DrGPolygonStyle class
instanceVariableNames: ''!
!classDefinition: #DrGSegmentStyle category: #'DrGeo-Styles'!
DrGFinitCurveStyle subclass: #DrGSegmentStyle
instanceVariableNames: 'mark'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Styles'!
!classDefinition: 'DrGSegmentStyle class' category: #'DrGeo-Styles'!
DrGSegmentStyle class
instanceVariableNames: ''!
!classDefinition: #DrGLineStyle category: #'DrGeo-Styles'!
DrGCurveStyle subclass: #DrGLineStyle
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Styles'!
!classDefinition: 'DrGLineStyle class' category: #'DrGeo-Styles'!
DrGLineStyle class
instanceVariableNames: ''!
!classDefinition: #DrGLocusStyle category: #'DrGeo-Styles'!
DrGCurveStyle subclass: #DrGLocusStyle
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Styles'!
!classDefinition: 'DrGLocusStyle class' category: #'DrGeo-Styles'!
DrGLocusStyle class
instanceVariableNames: ''!
!classDefinition: #DrGRayStyle category: #'DrGeo-Styles'!
DrGCurveStyle subclass: #DrGRayStyle
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Styles'!
!classDefinition: 'DrGRayStyle class' category: #'DrGeo-Styles'!
DrGRayStyle class
instanceVariableNames: ''!
!classDefinition: #DrGVectorStyle category: #'DrGeo-Styles'!
DrGCurveStyle subclass: #DrGVectorStyle
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Styles'!
!classDefinition: 'DrGVectorStyle class' category: #'DrGeo-Styles'!
DrGVectorStyle class
instanceVariableNames: ''!
!classDefinition: #DrGPointStyle category: #'DrGeo-Styles'!
DrGStyle subclass: #DrGPointStyle
instanceVariableNames: 'shape pointSize'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Styles'!
!classDefinition: 'DrGPointStyle class' category: #'DrGeo-Styles'!
DrGPointStyle class
instanceVariableNames: ''!
!classDefinition: #DrGTextStyle category: #'DrGeo-Styles'!
DrGStyle subclass: #DrGTextStyle
instanceVariableNames: 'backgroundColor borderColor fontSize'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Styles'!
!classDefinition: 'DrGTextStyle class' category: #'DrGeo-Styles'!
DrGTextStyle class
instanceVariableNames: ''!
!classDefinition: #DrGValueStyle category: #'DrGeo-Styles'!
DrGTextStyle subclass: #DrGValueStyle
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Styles'!
!classDefinition: 'DrGValueStyle class' category: #'DrGeo-Styles'!
DrGValueStyle class
instanceVariableNames: ''!
!classDefinition: #DrGPlatform category: #'DrGeo-System'!
Object subclass: #DrGPlatform
instanceVariableNames: 'toolbarIconSize canWeDisplaySpinner preferences fontManager'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-System'!
!classDefinition: 'DrGPlatform class' category: #'DrGeo-System'!
DrGPlatform class
instanceVariableNames: ''!
!classDefinition: #DrGDevelopment category: #'DrGeo-System'!
DrGPlatform subclass: #DrGDevelopment
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-System'!
!classDefinition: 'DrGDevelopment class' category: #'DrGeo-System'!
DrGDevelopment class
instanceVariableNames: ''!
!classDefinition: #DrGWorkstation category: #'DrGeo-System'!
DrGPlatform subclass: #DrGWorkstation
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-System'!
!classDefinition: 'DrGWorkstation class' category: #'DrGeo-System'!
DrGWorkstation class
instanceVariableNames: ''!
!classDefinition: #DrGeoSystem category: #'DrGeo-System'!
Object subclass: #DrGeoSystem
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-System'!
!classDefinition: 'DrGeoSystem class' category: #'DrGeo-System'!
DrGeoSystem class
instanceVariableNames: 'platform'!
!classDefinition: #LanguageFont category: #'DrGeo-System'!
Object subclass: #LanguageFont
instanceVariableNames: 'locales family file'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-System'!
!classDefinition: 'LanguageFont class' category: #'DrGeo-System'!
LanguageFont class
instanceVariableNames: ''!
!classDefinition: #LanguageFontManager category: #'DrGeo-System'!
Object subclass: #LanguageFontManager
instanceVariableNames: 'languageFonts'
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-System'!
!classDefinition: 'LanguageFontManager class' category: #'DrGeo-System'!
LanguageFontManager class
instanceVariableNames: ''!
!DrGeoDomain commentStamp: '<historical>' prior: 0!
This is the domain object for DrGeo, aka the top level Model instance for one DrGeo instance.
It holds reference to the DrGeo geometric items factory and the cmdManager.!
!DrGMathItemBuilder commentStamp: '<historical>' prior: 0!
This is the root class of the MathBuilder hierarchy responsible to create new mathematic items.
A builder instance is specialized to build one type of object: free point, constrained point, line, segment, transformed mathItem...
To effectively build a new mathItem, the builder need to be fed with mathItem with
the add:at: message.
At any time it is possible to check wheter the build process is terminated or not with the readyToBuild message.
Related patterns: BUILD, TEMPLATE METHOD!
!DrGAngleGeometricBuilder commentStamp: '' prior: 0!
A builder for geometric angle defined by three points.!
!DrGAngleOrientedBuilder commentStamp: '' prior: 0!
A builder for oriented angle defined by three points or two vectors.!
!DrGArcCenterBuilder commentStamp: '' prior: 0!
A builder for arc defined by its center and origin, then an angle or an extremity
- angle is a float
- other items are point!
!DrGCloneBuilder commentStamp: '' prior: 0!
I can clone item!
!DrGCoordinatesBuilder commentStamp: '' prior: 0!
A builder for to build:
- the coordinates of a point
- the equation of a circle
- the equation of a line!
!DrGDummyBuilder commentStamp: '' prior: 0!
A Builder to build nothing. Used in the select mode!
!DrGFlyPointBuilder commentStamp: '' prior: 0!
To build free point and intersection point, it is also used to construct on the fly those point categories.!
!DrGMacroBuilder commentStamp: '' prior: 0!
A DrGMacroBuilder is builder to construct a macro-construction.
The builder needs an appropriate list of:
- input & output mathItems selected in the drawing area
- a macro-construction name & description
The builder checks the validity of the macro-construction, ie it checks if the outputs
items are deductible from the input items
Instance Variables
!
!DrGMacroPlayer commentStamp: '<historical>' prior: 0!
A DrGMacroPlayer is a builder used to play a macro-construction against a user provided list of input items.
It chekcs the validity of the input items against the macro-construction definition.
The input parameters type must be user selected in the same order as they appear in the macro inputNodes definition.!
!DrGMacroPlayerHeadless commentStamp: '' prior: 0!
This is the macro player activated when the user directly selects a macro from the macro-menu in the toolbar. This player does not show up the usual wizard to select the macro to play as it is already selected from the menu.!
!DrGPointIntersectionBuilder commentStamp: '' prior: 0!
The build the intersection between two curves. One or two output may be created!
!DrGParallelBuilder commentStamp: '' prior: 0!
pointA can accept a PointItem instance or just a Point instance.!
!DrGTransformationBuilder commentStamp: '' prior: 0!
Transformation builder can handle compositeItem, we need to specialize
its behavior.!
!DrGTranslationBuilder commentStamp: '' prior: 0!
curveItem : segment, vector, circle, arc!
!DrGLocusSample commentStamp: '<historical>' prior: 0!
I am a linked sample of a locus with:
- the curvilinear abscissa of the free point
- my screen coordinates
- my world coordinates
- offScreen is sample offScreen (the display device)
- exist does this sample exist for its abscissa !
!DrGeoMiniView commentStamp: 'hlsf 4/10/2022 17:17:52' prior: 0!
I am a DrGeo view without toolbar, I only come with the wheels and the top menu. I am used to display computed sketches (i.e. sketches constrcuted from Smalltalk code with the DrGeo API)!
!DrGLabel commentStamp: '<historical>' prior: 0!
I am label sticked arround a math object.
I can be dragged arround the objet and renammed from the Style tool.
- itemMorph is the view of a math Item I am attached too!
!DrGDebuggerWindow commentStamp: '<historical>' prior: 0!
A simplified Debugger window, with translated labels and helps.!
!DrGeoView commentStamp: '<historical>' prior: 0!
I am full featured view of a DrGeo app!
!DrGWizardMacroBuild commentStamp: 'hlsf 11/18/2021 21:23:19' prior: 0!
A wizard to define a macro-construction.
My model is a macro-construction builder (DrGMacroBuilder instance)!
!DrGWizardMacroPlay commentStamp: '<historical>' prior: 0!
A wizard to play (execute) a macro-construction.
My model is a macro-construction player (DrGMacroPlayer instance)!
!DrGWizardScript commentStamp: '<historical>' prior: 0!
A wizard to plug a script instance in the canvas.!
!DrGFileOpenMorph commentStamp: '<historical>' prior: 0!
I am a dialog window to browse, select and open a sketch.
My model is a DirectoryEntry instance.
Possible models are:
- DrGeoSystem examplesPath,
- DrGeoSystem mySketchesPath!
!DrGScriptDesignerDialog commentStamp: 'hlsf 8/4/2023 17:39:27' prior: 0!
I am a dialog to design a DrGeo script:
- my model is the presenter of my DrGeo app instance
- its name
- its description
- its attributes types (class of math items)!
!DrGSmalltalkSketchBrowser commentStamp: '<historical>' prior: 0!
A browser to visualize Smalltalk sketches
- model : DirectoryEntry where to find the Smallltalk sketch files
- selectedFile : the selected Smalltalk sketch file
- sketches : the name of the Smalltalk Sketches in the path (name file without extention)
- drgeoView : a DrGeo view of the smalltalkSketchFile, it is plugged in the browser
- codeView : a code view of the smalltalkSketchFile, it is plugged in the browser when check button code!
!DrGSmalltalkSketchEditor commentStamp: '<historical>' prior: 0!
An editor to edit Smalltalk sketch.
- There is an editor view to edit the Smalltalk code of the sketch and a DrGeo view where is rendered the sketch resulting from the compilation and execution of the Smalltalk code.
- There is a tool bar to load, save and execute the code.
- model : source code of the edited Smalltalk sketch
- file : file entry of the Smalltalk sketch
- drgeoView : a morph where to plug the view of the compiled model
- codeView : editor of the model
- docView : view of the Erudite DrGeo tutorial
- sketchProcess: the Smalltalk sketch is executed in its own thread
- playButton: the button to play and pause the Smalltalk sketch execution
!
!DrGStylePanel commentStamp: '<historical>' prior: 0!
A panel to edit the style of items in the DrGeo canvas (drawable)!
!DrGDrawableMenu commentStamp: '<historical>' prior: 0!
I am a contextual menu used when the user needs to select an items among several.!
!DrGDrawable commentStamp: '<historical>' prior: 0!
I represent the area/place where a Drgeo figure is drawn. It is a subpart of the GeometricView
- valueItem, dottedLines: we can display dotted line between a selected value and its parents
- itemViews, undoneViews, lastView: represent my submorph who are item's morphs!
!UnderMouseMorph commentStamp: '' prior: 0!
I display on the top left or right corner of my owner what is under the Active hand!
!DrGMorph commentStamp: '<historical>' prior: 0!
An abstract the view for DrGMathItem, model of a geometric object.
The user interact with the mathItem through its morph.
- mathItem: the model
- labelMorph: to display the object name, may be nil
- app: the DrGeo application this morph belong to
- color: additionnaly to style color, we need a color instance to blink a user selected morph
!
!DrGCurveMorph commentStamp: '<historical>' prior: 0!
An abstract class to represent curve. My only attribute is an anchorAbscissa in [0 ; 1]!
!DrGArcMorph commentStamp: '' prior: 0!
A DrGArcMorph is sampling an arc defined by
- its center
- its radius
- a starting point
- a signed length in radian!
!DrGCircleMorph commentStamp: 'hlsf 4/4/2021 19:19:06' prior: 0!
I am circle.
I can be drawn as a circle or a line when my radius goes toward the infinit!
!DrGPolylineMorph commentStamp: '<historical>' prior: 0!
A morph to represent polygon (closed) or polyline (open)!
!DrGLineMorph commentStamp: 'hlsf 5/16/2021 21:08:51' prior: 0!
A DrGLineMorph is extented to the boundary of its parent morph, a drawable in Dr. Geo jargon.
Its extend is virtually infinit.!
!DrGRayMorph commentStamp: '' prior: 0!
A DGRayMorph is extended in one 'sens' to the boundary of its parents morph, a drawable in Dr. Geo jargon.!
!DrGIconSegmentMorph commentStamp: '<historical>' prior: 0!
A morph to draw in an icon a line shape, depending on its style.!
!DrGLocusMorph commentStamp: '<historical>' prior: 0!
- free: the mobile point on a line
- constrainted: a point dependant to the free point, we want to compute its locus
- samples : a linked list of DrGLocusSample
- minAbscissaDelta : the minimum abscissa delta between two samples
- maxAbscissaDelta : the maximum abscissa delta between two samples
- maxScreenDelta : the maximum delta between two samples in the screen!
!DrGIconPointMorph commentStamp: '<historical>' prior: 0!
A morph to draw in an icon a point shape, depending on its style.!
!DrGeoScriptTest commentStamp: '' prior: 0!
These tests are based on the Smalltalk Sketch API to construct programmatically geometric sketches.!
!DrGeoSmalltalkSketchTest commentStamp: '' prior: 0!
I load and execute Smalltalk Sketch files. These sketches may have complex intricacies and should execute without error.!
!DrGeoScriptTestResource commentStamp: '' prior: 0!
I set up a canvas to use.!
!DrGTypeArrow commentStamp: '<historical>' prior: 0!
A preference type representing the different possible arrow set over a segment or arc.!
!DrGTypeColor commentStamp: '<historical>' prior: 0!
A preference type representing the different possible colors of an item in a sketch.!
!DrGTypeMark commentStamp: '<historical>' prior: 0!
A preference type representing the different possible mark set over a segment.!
!DrGTypePointShape commentStamp: '<historical>' prior: 0!
A preference type representing the different possible shapes of a point.!
!DrGTypePointSize commentStamp: '<historical>' prior: 0!
A preference type representing the different possible sizes of a point.!
!DrGTypeStyle commentStamp: '<historical>' prior: 0!
A preference type representing the different possible style of a line.!
!DrGTypeThickness commentStamp: '<historical>' prior: 0!
A preference type representing the different possible thickness of a line.!
!DrGeoTree commentStamp: 'hlsf 2/10/2022 11:29:00' prior: 0!
I am a model to present the constructed math item in a hierarchy list.
- app: the DrGeo instance!
!DrGWrappedItem commentStamp: '<historical>' prior: 0!
A class to encapsulate math item for user friendly use when doing Smalltalk figure!
!DrGeoSketch commentStamp: '' prior: 0!
Domain Specific Language (DSL) abstraction to construct programmatically interactive sketch.
| sketch a |
sketch _ DrGeoSketch new.
a _ sketch point: 1@1.
sketch line: a to: 0@0
!
!DrGMathItem commentStamp: '' prior: 0!
This is the root class of the mathematic items hierarchy.
The classes in this hierarchy are models of the mathematical items like point, line, circle.
These models will have different type of view depending on the ApplicationModel/View/Presenter.
id - unique id used when importing Dr. Geo 1.1 files / it is used to cache the index position in the factory pool
name - for example A, (AB), [AD], d
descriptiveName - 'this point A', 'this line (AB)'
longDescription - the point A, the symmetric of the point B in respect to O'
basicType - object familly the instance belong to (#point, #line,...), it is part of the class name
nodeType - the sub type the instance belong to (#2pts, #translation, #intersection), it is the value of XML 'type' attribute
!
!DrGArcItem commentStamp: '' prior: 0!
A DrGArcItem is an abstract arc item.
Instance Variables
center: the arc center
length: the arc angle, it can be negative
origin: the starting angle of the arc
radius: its radius!
!DrGArc3ptsItem commentStamp: '' prior: 0!
I am point defined by three points: a starting point, a point on the arc and an ending point.!
!DrGArcCenterAngleItem commentStamp: '' prior: 0!
I am an oriented (anti-clockwised) arc defined by its center, a startingPoint and endingPoint.
endingPoint is not necessary on the arc but it provides the arc angle!
!DrGBitmapItem commentStamp: '' prior: 0!
- data : an athens paint containing the original bitmap
- canvasScaleAtInsertion : the canvas scale at which the bitmap was dropped in the canvas. it is the scale reference for the rest of the bitmap life
- scale : a Float, bitmap can be scaled by this scale factor!
!DrGCircleItem commentStamp: '' prior: 0!
Instance variables radius and center are used to cache these values!
!DrGCompositeItem commentStamp: '' prior: 0!
I am the composite item, I represent a set of math items.!
!DrGAngleBisector3ptsItem commentStamp: '' prior: 0!
Angle bisector given three points!
!DrGLineAngleBisectorItem commentStamp: '' prior: 0!
Angle bisector given an angle defined by three points!
!DrGLineParallelItem commentStamp: '' prior: 0!
A DrGLineParallelItem is a parallel line.
parents first is a direction item
parents second is a point
!
!DrGPerpendicularBisectorItem commentStamp: '' prior: 0!
Perpendicular bisector given a segment!
!DrGLinePerpendicularBisector2ptsItem commentStamp: '' prior: 0!
Perpendicular bisector given two points, extremities of a segment!
!DrGPointBlockItem commentStamp: '' prior: 0!
Point item defined by a block closure!
!DrGPointScriptItem commentStamp: '' prior: 0!
A DrGPointByScriptItem is definied by the returned value of a script.
The script valueItem should understand asPoint.
Instance Variables
!
!DrGPointFreeItem commentStamp: '' prior: 0!
I represent a free point in the plane!
!DrGPointIntersectionItem commentStamp: '' prior: 0!
k - (-1) or 1 when they are 2 intersection points!
!DrGPolygonRegularItem commentStamp: '' prior: 0!
A regular polygon defined by its center, a vertex and a value (number of summit).!
!DrGAngle3ptsOrientedItem commentStamp: '' prior: 0!
Define an oriented angle in the range [0 ; 360[ given three points!
!DrGAngle3ptsItem commentStamp: '' prior: 0!
Define a geometric angle in the range [0 ; 180[ given three points!
!DrGAngleVectorsItem commentStamp: '' prior: 0!
Define an oriented angle, in the range ]-180 ; 180]!
!DrGEquationLineItem commentStamp: '' prior: 0!
a line equation:
- provide a and b for the reduced equation: y = a . x + b
- provide m otherwise for the equation x = m
!
!DrGValueScriptItem commentStamp: '<historical>' prior: 0!
Script
- script: a script class instance
- parents: a collection of morph (BEWARE, and not math item)!
!DrGValueValueItem commentStamp: '' prior: 0!
Free value!
!DrGMacro commentStamp: '' prior: 0!
A DrGMacro is a macro-construction definition
Instance Variables
nodes: <Object>
nodes
- xxxxx
!
!DrGMacroMathItem commentStamp: '' prior: 0!
A class to represent input math item template when reloading from a XML representation.!
!DrGMacroInputNode commentStamp: '' prior: 0!
A DrGMacroNode is a node in a macro-construction. It represents an abstracted math item in the macro-construction tree.
Instance Variables
!
!DrGeoUserScript commentStamp: '' prior: 0!
I am an abstract user script.
My subclass 'DrGeoScriptXXXXXXX' are created from the Dr. Geo script wizard, menu: Script>Create a Script.
From the wizard, the user set :
- the script name (script class side method #scriptName)
- the scritp description (script class side method #description)
- the argumentType (script sclass side method #newArgumentType)
Next, from the source code browser (class browser), the user write the scription computation in the script method #compute
A set of helpers are present to use in the #compute method:
- #arg1 to #arg4: to access first to fourth mathItem arguments as selected by the user
- #costume1 to #costume4: to access the first to fourth mathitem's costume
Instance Variables
- arguments : Array of DrGCostum, arguments this script uses in its computation
- cosutme : the costume representing this script on the canvas, access only from its #costume message.
!
!DrGIcons commentStamp: 'hlsf 4/26/2020 15:34:30' prior: 0!
I hold icons (in PNG format) and I can build dedicated graphics for the UI.
To access an icon at a given size, execute DrGIcons scaled: symbol to: integer
- forms a dictionnary, I hold a cache of the used icons.
I just execute-print something like:
(FileStream fileNamed: 'middle-.png') binary contents asByteArray
in the class message to get the string
!
!DrGUIControlsManager commentStamp: 'hlsf 4/10/2022 14:39:21' prior: 0!
A manager for the DrGeo user interface controls (main view, menu, button, tree, etc.).
- My subclasses may change how the tools are presented and accessed
- I hold the data and methods to build the UI
- I build the main Dr. Geo view (Window or simpler view)
!
!DrGeo commentStamp: 'hlsf 11/14/2023 00:18:25' prior: 0!
A presenter for the DrGeo app.
It is the interface to callback, state of the application
- notInteractive: indicates if the app is under the user interaction or is used by the system (for example to load a sketch), in that case no user interaction are authorized.
- saved: is the sketch saved
- stSketch: if not nil DrGeo was initialized from a Smalltalk Sketch!
!DrGTool commentStamp: '<historical>' prior: 0!
The root of the class hierarchy to handle tool. A tool is used to process the user inputs and to give appropriate feedbacks to the user depending on the operation the user can conduct. It works in close relation with a builder (see presenter-builder).
- state: state of the tool
- presenter: from which presenter is used this tool
- spot: xy-postition of the selected item when selecting one among several
- last: last mouse xy-position (used during drag)
- morph: a selected DrGMorph during the last multiple choice selection
- mathItemUnderMouse: mathItem under mouse
!
!DrGAnimateTool commentStamp: '' prior: 0!
A tool to animate a free point on a curve.
- animateSpeed: millisecond betwen to animation step!
!DrGFlyPointBuildTool commentStamp: '' prior: 0!
This tool lets the user create free point, point on curve and intersection point on the fly.
On the fly means create the point in one-clic operation.!
!DrGFlyBuildTool commentStamp: '' prior: 0!
This tool is designed with a flying object representing the object in construction.!
!DrGFlyBuildTouchTool commentStamp: '' prior: 0!
This tool is designed for touch screen, to construct line with sliding finger!
!DrGSelectTool commentStamp: '<historical>' prior: 0!
- start: the position where start the dragging
- mathItems: the mathItems impacted by the dragging operation
- morphs: the DrGMorphs impacted by the dragging opration
- builder: we have the clone builder, ready to serve, so we have to instantiate it.!
!DrGPropertyTool commentStamp: '' prior: 0!
A tool to edit the property of some object like free point, free point on curve, free value and script!
!DrGStyleTool commentStamp: '' prior: 0!
A tool to edit the style of the costume.!
!DrGDeleteTool commentStamp: '' prior: 0!
A tool to delete the mathItem. With subclass from StyleTool to have hidden costume to be display, so we can delete these ones aswell.!
!DrGToolState commentStamp: '<historical>' prior: 0!
I a represent the state of the user selected tool.
The context is the tool (selectTool, buildTool, ...) where the state operate.!
!DrGMacroBuildToolStateInput commentStamp: '' prior: 0!
When user selects input page, blink the cosumes related to this state. In this state the user can select items as input parameters for the macro. He can also unselect items.!
!DrGMacroBuildToolStateOutput commentStamp: '' prior: 0!
When user selects output page, blink the cosumes related to this state. In this state the user can select items as output parameters for the macro. He can also unselect items.!
!DrGFlyBuildTouchToolStateGrabbed commentStamp: '' prior: 0!
I am grabbing: i.e. the mouse move with bouton pressed or the user finger is moving on the touch screen!
!DrGMacroToolStateNeutral commentStamp: '' prior: 0!
When user switch to info pages (info and description pages), we unselect all selected costumes. In this state the user can't select any items.!
!DrGSelectToolState commentStamp: '' prior: 0!
An abstract state for the select tool and derivate.!
!DrGAnimateToolState commentStamp: '' prior: 0!
The neutral state for animate tool: when no free point on curve is selected yet.!
!DrGAnimateToolStateSelected commentStamp: '' prior: 0!
The selected state for animate tool: when a free point on curve is selected and it is animated.
- abscissa: the curvilinear abscissa of the selected point!
!DrGDeleteCommand commentStamp: '' prior: 0!
A command to delete a mathItem and its dependant.!
!DrGMathItemCommand commentStamp: '' prior: 0!
A command to record a mathItem construction!
!DrGMergeCommand commentStamp: '' prior: 0!
A command to merge 'mathItem' in 'target': all the direct children of mathItem will become direct children of target.
- directChildren : the children with the position of the mathItem in the parents collection.!
!DrGPropertyCommand commentStamp: '' prior: 0!
A command to record property editing!
!DrGFactory commentStamp: '<historical>' prior: 0!
The Factory is where are manufactured new mathematic or macro-constrcution items.
It owns a pool of the already manufactured items.
In last is the latested created (or recreated) item,
Carefull!! last may not be equal to 'pool last' when the user try
to instantiate an already created object, in this case last returns
the original copy somewhere in the pool.
When manufacturing a new item it checks for its unicity.
It works with the help of the MathItem and macro Builder.
Related patterns: flyweight.!
!DrGMacroFactory commentStamp: '' prior: 0!
DrGMacroFactory is a unique factory to hold macro construction definition.
Class Instance Variables:
uniqueInstance is the unique macro factory instance!
!DrGMathItemFactory commentStamp: '' prior: 0!
See superclass comments.
This factory interface in extended to handle mathItem specific action!
!DrGSvgCanvas commentStamp: '<historical>' prior: 0!
- app: a DrGeo instance
- firstPoint, current: initial/current point of a path
- pathNode : the XML node of the current path in construction
!
!DrGeoCommandLineHandler commentStamp: '' prior: 0!
Command line handler for Dr. Geo operations.
Usage: drgeo [ --sketch=<drgeo-file> ] [ --script=<drgeo-script> ]
--sketch Open a Dr. Geo sketch
--script Install a Dr. Geo Smalltalk script in a workspace and execute it
Example:
pharo drgeo.image drgeo --sketch=sketch.fgeo!
!DrGeoXml commentStamp: 'hlsf 3/15/2023 16:34:05' prior: 0!
A DrGeoXml is an helper to load or save as an XML representation a DrGeo instance, including export to SVG.
!
!DrGStyle commentStamp: '<historical>' prior: 0!
I am an abstract class to set a style to a morph item (DrGMorph hierarchy).!
!DrGCurveStyle commentStamp: 'hlsf 5/18/2021 21:24:01' prior: 0!
- color is a the optional fill color of the curve
- borderColor is its line color!
!DrGPlatform commentStamp: '' prior: 0!
I am an abstract class to modelise access to plateform preferences and information.
Pattern: strategy!
!DrGDevelopment commentStamp: '' prior: 0!
Preferences for a Dr. Geo development environment!
!DrGWorkstation commentStamp: '' prior: 0!
Preferences for workstation (Linux, Mac, Windows)!
!DrGeoSystem commentStamp: '<historical>' prior: 0!
I map settings/preferences to the underneath hardware/os plateform
Pattern: strategy!
!LanguageFont commentStamp: 'hlsf 11/17/2023 22:53:20' prior: 0!
Associate several LocaleIDs (fr_FR, zh_TW, zh_CN, ko) (with or without country code) with an appropriate font.
- locales : a collection of LocaleID
- family : a String, font family name
- file : a String, file name of the font!
!DrGeoDomain methodsFor: 'initialize-release' stamp: 'hlsf 3/9/2023 17:26:59'!
initialize
super initialize.
factory _ DrGMathItemFactory new.
cmdManager _ DrGCommandManager new domain: self.
pointNameIndex _ 0! !
!DrGeoDomain methodsFor: 'initialize-release' stamp: 'hlsf 4/24/2020 12:56:07'!
release
factory release.
cmdManager release.! !
!DrGeoDomain methodsFor: 'building'!
createCompositeItem: aMathItemSelection
cmdManager compositeCommandFor: aMathItemSelection.! !
!DrGeoDomain methodsFor: 'building'!
createFromMathItem: aMathItem
"return the mathItem (newly created or the one in the pool,
in case the caller want to do something with it"
(factory pushAsLastWhenInPool: aMathItem) ifTrue:
[^{factory last. false}].
"create a new command and execute it"
cmdManager buildCommandFor: aMathItem.
^{ aMathItem. true }! !
!DrGeoDomain methodsFor: 'building' stamp: 'hlsf 9/28/2022 17:26:57'!
createFromMathItemNoCommand: aMathItem
"Return the mathItem (newly created or an existing one in the factory)
No command in the undo/redo stack"
(factory pushAsLastWhenInPool: aMathItem) ifTrue: [^factory last].
factory add: aMathItem.
self triggerEvent: #newMathItem with: aMathItem.
^aMathItem! !
!DrGeoDomain methodsFor: 'building' stamp: 'hlsf 9/28/2022 17:24:10'!
createFromMathItemNoCommandNoFactoryCheck: aMathItem
"return the mathItem. we do not check in the facory pool, without command in the undo/redo stack"
factory add: aMathItem.
self triggerEvent: #newMathItem with: aMathItem.
^aMathItem! !
!DrGeoDomain methodsFor: 'building'!
createMacro: aBuilder
(DrGMacroFactory new pushAsLastWhenInPool: (aBuilder getItem: self)) ifFalse:
[ "Create macro and register it in the factory"
DrGMacroFactory new add: (aBuilder getItem: self) ]! !
!DrGeoDomain methodsFor: 'building'!
createMathItem: aBuilder
"return the mathItem (newly created or the one in the pool,
in case the caller want to do something with it"
(factory pushAsLastWhenInPool: aBuilder getItem first) ifTrue:
[ ^ { (factory last). false } ].
"create a new command and execute it"
^ { (cmdManager buildCommandWith: aBuilder). true }! !
!DrGeoDomain methodsFor: 'building'!
deleteMathItem: aMathItem
"create a delete command and execute it"
cmdManager deleteCommandFor: aMathItem! !
!DrGeoDomain methodsFor: 'building'!
in: macroTree replaceParent: item with: newItem
| index |
macroTree do: [ :anItem |
(anItem parents notNil and: [ (index _ anItem parents indexOf: item) ~= 0 ])
ifTrue: [anItem parents at: index put: newItem ] ]! !
!DrGeoDomain methodsFor: 'building'!
merge: aMathItem with: aTarget
"create a merge command"
cmdManager mergeCommandFor: aMathItem with: aTarget! !
!DrGeoDomain methodsFor: 'building' stamp: 'hlsf 2/10/2022 10:42:45'!
moveMathItem: aMathItem with: aPoint
"create a move command"
cmdManager moveCommandFor: aMathItem with: aPoint.
"We do not really need to update the canvas view, but still need to inform dependent for other kinds of view updating only when mouse button is released"
self triggerEvent: #updatedItems! !
!DrGeoDomain methodsFor: 'building' stamp: 'hlsf 8/4/2023 17:32:56'!
playMacro: aBuilder in: presenter
| answer macroTree |
macroTree := aBuilder getItem.
macroTree
with: aBuilder constructedNodes
do:
[ :item :node |
answer := self createFromMathItem: item.
answer last
ifTrue:
[ node isHiddenNode ifTrue:
[ (presenter drawable viewOf: item) ifNotNil:
[ :aMorph |
aMorph style hidden: true.
aMorph forcedVisibility: false ] ] ]
ifFalse:
[ "item twin in the factory, use it in the macro tree"
self
in: macroTree
replaceParent: item
with: answer first ] ]! !
!DrGeoDomain methodsFor: 'building'!
propertyCommandFor: aMathItem with: aProperty
"create a move command"
cmdManager propertyCommandFor: aMathItem with: aProperty ! !
!DrGeoDomain methodsFor: 'updating'!
moveEvent: aMathItem at: aPoint withDirty: mathItems
aMathItem moveAt: aPoint.
self updateDirty: mathItems! !
!DrGeoDomain methodsFor: 'updating' stamp: 'hlsf 2/10/2022 10:39:36'!
moveEvent: aMathItem inDirection: aPoint
aMathItem moveEvent: aPoint.
self updateAllMathItems ! !
!DrGeoDomain methodsFor: 'updating' stamp: 'hlsf 6/20/2021 10:48:45'!
moveEvent: aMathItem inDirection: aPoint withDirty: mathItems
aPoint isZero ifFalse: [
aMathItem moveEvent: aPoint.
self updateDirty: mathItems]! !
!DrGeoDomain methodsFor: 'updating'!
mutate: aPointItem asFreeOn: aCurveItem at: aPosition
|item|
item _ DrGPointOncurveItem newWith: {aCurveItem . aPosition}.
item name: aPointItem name.
item actionMap: aPointItem actionMap.
aPointItem become: item.
self updateAllMathItems ! !
!DrGeoDomain methodsFor: 'updating'!
mutate: aPointItem asIntersectionWith: curveA and: curveB at: aPosition
|item|
item _ DrGPointIntersectionItem newWith: {curveA. curveB. aPosition}.
item name: aPointItem name.
item actionMap: aPointItem actionMap.
aPointItem become: item.
self updateAllMathItems.! !
!DrGeoDomain methodsFor: 'updating'!
mutateAsFreePoint: aPointItem
|freePointItem|
(aPointItem isFreePointItem and: [aPointItem isPointItemOnCurve not]) ifTrue: [^aPointItem].
freePointItem _ DrGPointFreeItem new point: aPointItem point.
freePointItem name: aPointItem name.
freePointItem actionMap: aPointItem actionMap.
aPointItem become: freePointItem.
^ freePointItem! !
!DrGeoDomain methodsFor: 'updating' stamp: 'hlsf 4/14/2022 10:47:17'!
updateAllMathItems
factory updateAllMathItems.
self triggerEvent: #updatedItems! !
!DrGeoDomain methodsFor: 'updating'!
updateAllMathItemsButLocus
factory updateAllMathItemsButLocus.
"We don't need to update the costumem we just want updated mathiteem'"
"self triggerEvent: #updatedItems"! !
!DrGeoDomain methodsFor: 'updating' stamp: 'hlsf 5/17/2020 16:57:35'!
updateDirty: mathItems
mathItems do: [:item | item update].
self triggerEvent: #updatedDirtyItems! !
!DrGeoDomain methodsFor: 'accessing'!
factory
^factory! !
!DrGeoDomain methodsFor: 'accessing'!
labelString
^ 'Dr. Geo -- ', Date today asString! !
!DrGeoDomain methodsFor: 'accessing'!
redo
cmdManager redo! !
!DrGeoDomain methodsFor: 'accessing'!
undo
cmdManager undo! !
!DrGeoDomain methodsFor: 'autoname' stamp: 'hlsf 3/9/2023 16:14:08'!
autoname: aMathItem
(DrGeoSystem preferences at: #autoName) ifFalse: [^ self].
aMathItem isPointItem ifTrue: [self autonamePoint: aMathItem]! !
!DrGeoDomain methodsFor: 'autoname' stamp: 'hlsf 3/9/2023 17:36:01'!
autonamePoint: pointItem
| name letter index |
letter _ ((pointNameIndex \\ 26) + 65) asCharacter.
index _ pointNameIndex // 26.
pointNameIndex _ pointNameIndex + 1.
name _ index isZero
ifTrue: [letter asString]
ifFalse: [letter asString, index asString].
pointItem name: name
! !
!DrGMathItemBuilder methodsFor: 'testing' stamp: 'hlsf 8/4/2023 17:10:30'!
isNotInteractive
"Are we parsing the figure from a file"
^ presenter isNotInteractive! !
!DrGMathItemBuilder methodsFor: 'testing'!
isWanted: aMathItemCollection
"Check if the builder is interested by aMathItem"
self subclassResponsibility ! !
!DrGMathItemBuilder methodsFor: 'testing'!
isWanted: aMathItemCollection at: aPoint
"By default we don't need the point position of the click event'"
^ self isWanted: aMathItemCollection ! !
!DrGMathItemBuilder methodsFor: 'testing'!
readyToBuild
"Can the builder build the math item now?"
self subclassResponsibility ! !
!DrGMathItemBuilder methodsFor: 'accessing'!
arguments
"an argument list to give to the MathItem new method"
self subclassResponsibility ! !
!DrGMathItemBuilder methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 12:53:02'!
domain
^ presenter domain! !
!DrGMathItemBuilder methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 12:53:08'!
drawable
^ presenter drawable! !
!DrGMathItemBuilder methodsFor: 'accessing'!
factory
^ self domain factory! !
!DrGMathItemBuilder methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 12:52:44'!
presenter: aPresenter
presenter := aPresenter ! !
!DrGMathItemBuilder methodsFor: 'building'!
add: aMathItemCollection at: aPoint
"Add a math item in the selection list of the builder,
aPoint is the position where the action took place
Return true if mathItem accepted"
(self isWanted: aMathItemCollection at: aPoint) ifTrue:
[self addItem: aMathItemCollection at: aPoint.
"Are we done? If so notify our dependent"
self readyToBuild ifTrue:
[self triggerEvent: #readyToBuild].
^true].
^false
! !
!DrGMathItemBuilder methodsFor: 'building' stamp: 'hlsf 8/4/2023 17:16:46'!
buildItem
| itemDefinitions |
itemDefinitions := self mathItemClass.
^ itemDefinitions isCollection
ifFalse: [{itemDefinitions newWith: self arguments in: presenter}]
ifTrue: [point := point + (0.2@1.3).
itemDefinitions collect: [:class |
point := point - (0@0.5).
class newWith: self arguments in: presenter]]! !
!DrGMathItemBuilder methodsFor: 'building'!
getItem
"return an instantiated mathItem or nil if not possible"
self readyToBuild ifTrue:
[^ self buildItem].
^ nil.! !
!DrGMathItemBuilder methodsFor: 'flying objects' stamp: 'hlsf 6/20/2021 12:10:30'!
addToFlyingItem: anItem
"Add an item to the flying item representing the item built by this builder "
self isNotInteractive ifTrue: [^self].
movingPoint _ DrGPointFreeItem new point: point + (0.1 @ 0.1).
flyingItem _ self mathItemClass newWith: self flyingMathItemArguments.
self initializeFlyingMorph
! !
!DrGMathItemBuilder methodsFor: 'flying objects' stamp: 'hlsf 4/12/2021 22:14:28'!
flyingMathItemArguments
self subclassResponsibility ! !
!DrGMathItemBuilder methodsFor: 'flying objects' stamp: 'hlsf 4/12/2021 22:04:35'!
flyingMorphClass
self subclassResponsibility ! !
!DrGMathItemBuilder methodsFor: 'flying objects' stamp: 'hlsf 8/4/2023 17:15:29'!
initializeFlyingMorph
flyingMorph := self flyingMorphClass for: flyingItem in: presenter drawable.
flyingMorph style color: Color lightRed! !
!DrGMathItemBuilder methodsFor: 'flying objects' stamp: 'hlsf 10/14/2021 10:01:20'!
moveFlyingMorphAt: aPoint
flyingMorph ifNotNil: [
movingPoint moveAt: aPoint.
flyingItem update.
flyingMorph redrawNeeded]! !
!DrGMathItemBuilder methodsFor: 'flying objects' stamp: 'hlsf 10/14/2021 09:59:20'!
redrawFlyingMorph
flyingMorph ifNotNil: [flyingMorph redrawNeeded]! !
!DrGMathItemBuilder methodsFor: 'xml' stamp: 'hlsf 5/31/2021 18:57:45'!
basicItemFrom: node
| type itemClass item|
"build the item class name from the node description"
type _ ((node attributeAt: #type) copyWithoutAll: '_') capitalized.
itemClass _ Smalltalk
classNamed: ('DrG' , node tag capitalized , type , 'Item') asSymbol.
item _ itemClass new yourself.
self postProcess: item from: node.
^ item! !
!DrGMathItemBuilder methodsFor: 'xml' stamp: 'hlsf 9/28/2022 17:24:10'!
itemFrom: node
|item|
item _ self itemInstanceFrom: node.
self postProcess: item from: node.
^ {self domain createFromMathItemNoCommandNoFactoryCheck: item. true}! !
!DrGMathItemBuilder methodsFor: 'xml'!
itemInstanceFrom: node
"build an item from a XML description"
(self parentsById: node) do: [:each | self addItem: {each} at: 0@0].
^ self getItem first.
! !
!DrGMathItemBuilder methodsFor: 'xml'!
parentsById: node
"return a collection of the item parent given theirs id in the attribute
elements <parent id=xxx>"
|collection|
collection _ OrderedCollection new.
node elementsDo: [:each |
(each tag = #parent) ifTrue: [
collection add: (self factory findInPoolById: (each attributeAt: 'ref') asSymbol)]].
^collection ! !
!DrGMathItemBuilder methodsFor: 'xml'!
parseValuePosition: node
| x y |
x _ (node contentStringAt: #x) asNumber.
y _ (node contentStringAt: #y) asNumber.
^ x@y.! !
!DrGMathItemBuilder methodsFor: 'xml'!
parseValuePosition: node of: item
item position: (self parseValuePosition: node)! !
!DrGMathItemBuilder methodsFor: 'xml'!
postProcess: item from: node
item id: (node attributeAt: 'id') asSymbol.
(item respondsTo: #isLocked) ifTrue: [
(node attributeAt: #locked) = 'True'
ifTrue: [item locked: true]
ifFalse: [item locked: false]]! !
!DrGMathItemBuilder methodsFor: 'constant'!
mathItemClass
"Answer the MathItem class for this builder (i.e. self FreePointItem,...)"
self subclassResponsibility! !
!DrGMathItemBuilder methodsFor: 'updating' stamp: 'hlsf 4/12/2021 22:04:51'!
reset
point _ nil.
flyingMorph ifNotNil:
[flyingMorph release.
flyingMorph _ nil]! !
!DrGMathItemBuilder methodsFor: 'private'!
addItem: aMathItemCollection at: aPoint
point _ aPoint.! !
!DrGMathItemBuilder methodsFor: 'private'!
addToggleItem: aMathItemCollection in: aCollection
aCollection
remove: aMathItemCollection first
ifAbsent: [aCollection add: aMathItemCollection first]
! !
!DrGMathItemBuilder methodsFor: 'as yet unclassified' stamp: 'hlsf 6/20/2021 11:20:07'!
release
self releaseActionMap.
self reset.! !
!DrGMathItemBuilder class methodsFor: 'documentation'!
description
"A description how to use the tool"
self subclassResponsibility! !
!DrGMathItemBuilder class methodsFor: 'documentation'!
title
"One or two words describing the builder"
self subclassResponsibility ! !
!DrGMathItemBuilder class methodsFor: 'xml'!
basicItemFrom: node
"create a basic item (unitialised) from this node and add it to the domain, return an item partially initialized. Used for macro node"
| builder |
builder _ self new.
^ builder basicItemFrom: node! !
!DrGMathItemBuilder class methodsFor: 'xml' stamp: 'hlsf 8/4/2023 17:09:44'!
itemFrom: node in: aPresenter
"create an item from this node and add it to the domain, return a couple {item. boolean}"
| builder |
builder := self new presenter: aPresenter ; yourself.
^ builder itemFrom: node! !
!DrGAngleGeometricBuilder methodsFor: 'updating' stamp: 'hlsf 6/20/2021 11:22:39'!
reset
super reset.
pointA _ pointB _ pointC _ nil! !
!DrGAngleGeometricBuilder methodsFor: 'testing'!
isWanted: aMathItemCollection
^aMathItemCollection notEmpty
and: [(aMathItemCollection first isPointItem
and: [aMathItemCollection first ~= pointA
and: [aMathItemCollection first ~= pointB]] )]! !
!DrGAngleGeometricBuilder methodsFor: 'testing'!
readyToBuild
^ pointA notNil and: [pointB notNil and: [pointC notNil]]
! !
!DrGAngleGeometricBuilder methodsFor: 'private'!
addItem: aMathItemCollection at: aPoint
super addItem: aMathItemCollection at: aPoint.
aMathItemCollection first isPointItem
ifTrue:
[pointA ifNil:
[pointA _ aMathItemCollection first.
^self].
pointB ifNil:
[pointB _ aMathItemCollection first.
^self].
pointC _ aMathItemCollection first]! !
!DrGAngleGeometricBuilder methodsFor: 'constant'!
mathItemClass
^ DrGAngle3ptsItem ! !
!DrGAngleGeometricBuilder methodsFor: 'accessing'!
arguments
^ {pointA . pointB . pointC. point}! !
!DrGAngleGeometricBuilder class methodsFor: 'as yet unclassified'!
description
^ 'Geometric angle defined by three points, the second point is the vertex. Its measure belongs to [0 ; 180].' translated! !
!DrGAngleGeometricBuilder class methodsFor: 'as yet unclassified'!
title
^ 'Geometric angle' translated! !
!DrGAngleOrientedBuilder methodsFor: 'xml'!
postProcess: item from: node
super postProcess: item from: node.
(node attributeAt: #type) asSymbol == #vectors ifTrue: [
self parseValuePosition: node of: item]! !
!DrGAngleOrientedBuilder methodsFor: 'accessing'!
arguments
^pointA
ifNotNil: [{pointA . pointB . pointC. point}]
ifNil: [{vectorA . vectorB. point}]! !
!DrGAngleOrientedBuilder methodsFor: 'testing'!
isWanted: aMathItemCollection
^aMathItemCollection notEmpty
and: [(aMathItemCollection first isPointItem
and: [vectorA isNil
and: [aMathItemCollection first ~= pointA
and: [aMathItemCollection first ~= pointB]] ])
or: [aMathItemCollection first isVectorItem
and: [pointA isNil
and: [aMathItemCollection first ~= vectorA]]]]! !
!DrGAngleOrientedBuilder methodsFor: 'testing'!
readyToBuild
^ super readyToBuild or: [vectorA notNil and: [vectorB notNil]]
! !
!DrGAngleOrientedBuilder methodsFor: 'updating' stamp: 'hlsf 6/20/2021 11:22:42'!
reset
super reset.
vectorA _ vectorB _ nil! !
!DrGAngleOrientedBuilder methodsFor: 'private'!
addItem: aMathItemCollection at: aPoint
super addItem: aMathItemCollection at: aPoint. "it handles the case of adding a point to the selection"
aMathItemCollection first isPointItem
ifFalse:
[vectorA ifNil:
[vectorA _ aMathItemCollection first.
^self].
vectorB _ aMathItemCollection first]! !
!DrGAngleOrientedBuilder methodsFor: 'constant'!
mathItemClass
^pointA
ifNotNil: [DrGAngle3ptsOrientedItem]
ifNil: [DrGAngleVectorsItem]! !
!DrGAngleOrientedBuilder class methodsFor: 'documentation'!
description
^ 'Oriented angle defined by three points or two vectors. When defined from three points, the second point is the vertex. Its measure belongs to [0 ; 360[ or ]-180 ; 180]. ' translated! !
!DrGAngleOrientedBuilder class methodsFor: 'documentation'!
title
^ 'Oriented angle' translated! !
!DrGArcBuilder methodsFor: 'constant'!
mathItemClass
^DrGArc3ptsItem! !
!DrGArcBuilder methodsFor: 'accessing'!
arguments
^{pointA . pointB . pointC}! !
!DrGArcBuilder methodsFor: 'flying costume' stamp: 'hlsf 4/12/2021 22:14:28'!
flyingMathItemArguments
^{pointA. pointB. movingPoint}.
! !
!DrGArcBuilder methodsFor: 'flying costume' stamp: 'hlsf 4/12/2021 22:04:35'!
flyingMorphClass
^ DrGArcMorph! !
!DrGArcBuilder methodsFor: 'private'!
addItem: aMathItemCollection at: aPoint
super addItem: aMathItemCollection at: aPoint.
pointA ifNil: [^ pointA _ aMathItemCollection first].
pointB ifNil:
[pointB _ aMathItemCollection first.
^ self addToFlyingItem: pointB].
pointC ifNil: [pointC _ aMathItemCollection first].
! !
!DrGArcBuilder methodsFor: 'testing'!
isWanted: aMathItemCollection
^aMathItemCollection notEmpty
and: [aMathItemCollection first isPointItem
and: [aMathItemCollection first ~= pointA
and: [aMathItemCollection first ~= pointB]]]! !
!DrGArcBuilder methodsFor: 'testing'!
readyToBuild
^pointA notNil and: [pointB notNil and: [pointC notNil]]! !
!DrGArcBuilder methodsFor: 'updating' stamp: 'hlsf 6/20/2021 11:22:49'!
reset
super reset.
pointA _ pointB _ pointC _ nil! !
!DrGArcBuilder class methodsFor: 'documentation'!
description
^ 'Arc defined by three points.' translated! !
!DrGArcBuilder class methodsFor: 'documentation'!
title
^ 'Arc' translated! !
!DrGArcCenterBuilder methodsFor: 'constant'!
mathItemClass
^ DrGArcCenterAngleItem ! !
!DrGArcCenterBuilder methodsFor: 'testing'!
arguments
^ {center. origin. extremity}! !
!DrGArcCenterBuilder methodsFor: 'testing'!
isWanted: aMathItemCollection
| item |
^ aMathItemCollection notEmpty
and: [(item _ aMathItemCollection first) isPointItem
and: [item ~= center
and: [item ~= origin]]]! !
!DrGArcCenterBuilder methodsFor: 'testing'!
readyToBuild
^ origin notNil and: [center notNil and: [extremity notNil]]! !
!DrGArcCenterBuilder methodsFor: 'private'!
addItem: aMathItemCollection at: aPoint
super addItem: aMathItemCollection at: aPoint.
center ifNil: [^ center _ aMathItemCollection first].
origin ifNil: [
origin _ aMathItemCollection first.
^ self addToFlyingItem: origin].
extremity ifNil: [extremity _ aMathItemCollection first]! !
!DrGArcCenterBuilder methodsFor: 'updating' stamp: 'hlsf 6/20/2021 11:22:55'!
reset
super reset.
origin _ center _ extremity _ nil! !
!DrGArcCenterBuilder methodsFor: 'flying costume' stamp: 'hlsf 4/12/2021 22:14:28'!
flyingMathItemArguments
^{center. origin. movingPoint}.
! !
!DrGArcCenterBuilder methodsFor: 'flying costume' stamp: 'hlsf 4/12/2021 22:04:35'!
flyingMorphClass
^ DrGArcMorph! !
!DrGArcCenterBuilder class methodsFor: 'documentation'!
description
^ 'Arc defined by its center and two points.' translated! !
!DrGArcCenterBuilder class methodsFor: 'documentation'!
title
^'Arc (center)' translated! !
!DrGBitmapBuilder methodsFor: 'xml'!
itemInstanceFrom: node
self addItem: #() at: 0@0.
^ self getItem first.
! !
!DrGBitmapBuilder methodsFor: 'xml' stamp: 'hlsf 6/8/2021 19:34:12'!
postProcess: item from: node
| form |
super postProcess: item from: node.
self parseValuePosition: node of: item.
form _ PNGReadWriter formFromStream: (node contentStringAt: #data) base64Decoded asByteArray readStream.
item
insertAtScale: (node contentStringAt: #insertAtScale) asNumber;
magnifyBy: (node contentStringAt: #magnify) asNumber;
data: form
! !
!DrGBitmapBuilder methodsFor: 'testing'!
isWanted: aMathItemCollection
^ aMathItemCollection isEmpty! !
!DrGBitmapBuilder methodsFor: 'testing'!
readyToBuild
^ point notNil! !
!DrGBitmapBuilder methodsFor: 'accessing'!
arguments
^ {point}! !
!DrGBitmapBuilder methodsFor: 'constant'!
mathItemClass
^DrGBitmapItem ! !
!DrGBitmapBuilder class methodsFor: 'documentation'!
description
^'Picture: drag and drop a picture in the canvas. It can be moved and scaled.' translated! !
!DrGBitmapBuilder class methodsFor: 'documentation'!
title
^'Picture' translated! !
!DrGCloneBuilder methodsFor: 'updating'!
reset
super reset.
item _ nil! !
!DrGCloneBuilder methodsFor: 'testing'!
isWanted: aMathItemCollection
^ aMathItemCollection notEmpty
and: [aMathItemCollection first isCloneable]! !
!DrGCloneBuilder methodsFor: 'testing'!
readyToBuild
^ item notNil ! !
!DrGCloneBuilder methodsFor: 'private'!
addItem: aMathItemCollection at: aPoint
super addItem: aMathItemCollection at: aPoint.
item _ aMathItemCollection first! !
!DrGCloneBuilder methodsFor: 'building'!
buildItem
"clone myself with the necessary parents"
^ item clone! !
!DrGCoordinatesBuilder methodsFor: 'private'!
addItem: aMathItemCollection at: aPoint
| item |
point _ aPoint.
item _ aMathItemCollection first.
item isPointItem ifTrue: [^ pointA _ item].
item isCircleItem ifTrue: [^ circle _ item].
item isLineItem ifTrue: [^ line _ item].
item isVectorItem ifTrue: [^ vector _ item]! !
!DrGCoordinatesBuilder methodsFor: 'as yet unclassified'!
itemInstanceFrom: node
"build an item from a XML description"
"this builder can create multiple item at once (coordinates X and Y), so we need
to select the one we want"
| nodeType |
(self parentsById: node) do: [:each | self addItem: {each} at: 0@0].
nodeType _ (node attributeAt: #type) asSymbol.
^ self getItem detect: [:item | item nodeType = nodeType]
! !
!DrGCoordinatesBuilder methodsFor: 'xml'!
postProcess: item from: node
super postProcess: item from: node.
self parseValuePosition: node of: item.! !
!DrGCoordinatesBuilder methodsFor: 'accessing'!
arguments
^ Array with: ({pointA. vector . line . circle } detect: [:i | i isNil not] ifNone: [nil]) with: point! !
!DrGCoordinatesBuilder methodsFor: 'updating' stamp: 'hlsf 6/20/2021 11:23:04'!
reset
super reset.
pointA _ vector _ circle _ line _ nil! !
!DrGCoordinatesBuilder methodsFor: 'testing'!
isWanted: aMathItemCollection
^ aMathItemCollection notEmpty
and: [aMathItemCollection first isPointItem
or: [aMathItemCollection first isLineItem
or: [aMathItemCollection first isCircleItem
or: [aMathItemCollection first isVectorItem]]]]! !
!DrGCoordinatesBuilder methodsFor: 'testing'!
readyToBuild
^ {pointA. vector . line . circle } anySatisfy: [:i | i isNil not]
! !
!DrGCoordinatesBuilder methodsFor: 'constant'!
mathItemClass
pointA ifNotNil: [^{DrGValuePtabscissaItem . DrGValuePtordinateItem}].
vector ifNotNil: [^{DrGValueVectorabscissaItem . DrGValueVectorordinateItem}].
circle ifNotNil: [^ DrGEquationCircleItem].
line ifNotNil: [^ DrGEquationLineItem]! !
!DrGCoordinatesBuilder class methodsFor: 'documentation'!
description
^ 'Vector or point coordinates, circle or line equation.' translated! !
!DrGCoordinatesBuilder class methodsFor: 'documentation'!
title
^ 'Coordinates, equation' translated! !
!DrGDummyBuilder methodsFor: 'testing'!
isWanted: aMathItemCollection
^true! !
!DrGDummyBuilder methodsFor: 'testing'!
readyToBuild
^false! !
!DrGDummyBuilder methodsFor: 'private'!
addItem: aMathItemCollection at: aPoint
super addItem: aMathItemCollection at: aPoint! !
!DrGFlyPointBuilder methodsFor: 'accessing'!
arguments
(curveItemA notNil and: [curveItemB notNil])
ifTrue: [^{curveItemA . curveItemB . point}].
curveItemA ifNotNil: [^{curveItemA . point}].
^{point}
! !
!DrGFlyPointBuilder methodsFor: 'constant'!
mathItemClass
(curveItemA notNil and: [curveItemB notNil])
ifTrue: [^DrGPointIntersectionItem].
curveItemA ifNotNil: [^DrGPointOncurveItem].
point ifNotNil: [^DrGPointFreeItem].
self error: 'Should not be there!!'! !
!DrGFlyPointBuilder methodsFor: 'private'!
addItem: aMathItemCollection at: aPoint
"The behavior is a bit different as we send in the collection all the parent in one shot:
to create the interesection the user clicks on two curves at the same time"
super addItem: aMathItemCollection at: aPoint.
aMathItemCollection ifNotEmpty:
[curveItemA _ aMathItemCollection first].
aMathItemCollection size >= 2 ifTrue:
[curveItemB _ aMathItemCollection second]! !
!DrGFlyPointBuilder methodsFor: 'private'!
restoreState: anArray
curveItemA _ anArray first.
curveItemB _ anArray second.
point _ anArray third! !
!DrGFlyPointBuilder methodsFor: 'private'!
saveState
^Array with: curveItemA with: curveItemB with: point! !
!DrGFlyPointBuilder methodsFor: 'updating' stamp: 'hlsf 6/20/2021 11:20:49'!
reset
super reset.
curveItemA _ curveItemB _ nil! !
!DrGFlyPointBuilder methodsFor: 'xml'!
itemInstanceFrom: node
self shouldNotImplement! !
!DrGFlyPointBuilder methodsFor: 'testing'!
isCurveIntersectionValid: aCollection
| item state |
state _ self saveState.
self restoreState: aCollection.
[item _ self buildItem]
on: Error
do: [self restoreState: state.
^false].
self restoreState: state.
^ item anyOne exist
! !
!DrGFlyPointBuilder methodsFor: 'testing'!
isWanted: aMathItemCollection
^self isWanted: aMathItemCollection at: 0@0! !
!DrGFlyPointBuilder methodsFor: 'testing'!
isWanted: aMathItemCollection at: aPoint
"click on the background?"
aMathItemCollection ifEmpty: [^true].
"click on two curves?"
(aMathItemCollection size >= 2
and: [aMathItemCollection first isIntersectableItem
and: [aMathItemCollection second isIntersectableItem]])
ifTrue: [^ self isCurveIntersectionValid: {aMathItemCollection first. aMathItemCollection second. aPoint}].
"click on one curve?"
^aMathItemCollection first isCurveItem ! !
!DrGFlyPointBuilder methodsFor: 'testing'!
readyToBuild
^ curveItemA notNil or: [point notNil]! !
!DrGFlyPointBuilder class methodsFor: 'documentation'!
description
^ DrGeoSystem isTablet
ifTrue: ['Tap to create a point: free point on the background, on a curve or on two curves intersection.' translated]
ifFalse: ['Click to create a point: free point on the background, on a curve or on two curves intersection.' translated]! !
!DrGFlyPointBuilder class methodsFor: 'documentation'!
title
^ 'Point' translated! !
!DrGFreePointBuilder methodsFor: 'xml'!
itemInstanceFrom: node
"works both for free point and free point on a curve"
self addItem: (self parentsById: node) at: 0@0.
^ self getItem first.
! !
!DrGFreePointBuilder methodsFor: 'xml'!
postProcess: item from: node
super postProcess: item from: node.
(node attributeAt: #type) asSymbol == #Free
ifFalse: [
item setCurveAbscissa: (node contentStringAt: #value) asNumber]
ifTrue: [ |x y|
x _ (node contentStringAt: #x) asNumber.
y _ (node contentStringAt: #y) asNumber.
item point: x@y]
! !
!DrGFreePointBuilder methodsFor: 'updating'!
reset
super reset.
curveItem _ nil.! !
!DrGFreePointBuilder methodsFor: 'accessing'!
arguments
curveItem ifNotNil:
[^ OrderedCollection new
add: curveItem;
add: point;
yourself].
^ OrderedCollection new add: point; yourself! !
!DrGFreePointBuilder methodsFor: 'private'!
addItem: aMathItemCollection at: aPoint
super addItem: aMathItemCollection at: aPoint.
aMathItemCollection
ifNotEmpty: [curveItem _ aMathItemCollection first].! !
!DrGFreePointBuilder methodsFor: 'constant'!
mathItemClass
curveItem ifNotNil: [^DrGPointOncurveItem].
point ifNotNil: [^DrGPointFreeItem].
self error: 'Should not be there!!'! !
!DrGFreePointBuilder methodsFor: 'testing'!
isWanted: aMathItemCollection
"the user clicked on the background: we can build a free point"
aMathItemCollection ifEmpty: [^true].
^aMathItemCollection first isCurveItem.! !
!DrGFreePointBuilder methodsFor: 'testing'!
readyToBuild
^ curveItem ~= nil or: [point ~= nil]! !
!DrGLocusBuilder methodsFor: 'updating' stamp: 'hlsf 6/20/2021 11:20:58'!
reset
super reset.
freePoint _ constrainedPoint _ nil! !
!DrGLocusBuilder methodsFor: 'private'!
addItem: aMathItemCollection at: aPoint
super addItem: aMathItemCollection at: aPoint.
aMathItemCollection first isPointItemOnCurve
ifTrue: [freePoint
ifNil: [freePoint _ aMathItemCollection first.
^ self].
constrainedPoint
ifNil: [constrainedPoint _ aMathItemCollection first]]
ifFalse: [constrainedPoint
ifNil: [constrainedPoint _ aMathItemCollection first.
^ self].
freePoint
ifNil: [freePoint _ aMathItemCollection first]]! !
!DrGLocusBuilder methodsFor: 'constant'!
mathItemClass
^ DrGLocus2ptsItem! !
!DrGLocusBuilder methodsFor: 'accessing'!
arguments
^ {freePoint. constrainedPoint}! !
!DrGLocusBuilder methodsFor: 'testing'!
isWanted: aMathItemCollection
^ aMathItemCollection notEmpty
and: [(aMathItemCollection first isPointItemOnCurve
and: [aMathItemCollection first ~= freePoint
and: [aMathItemCollection first ~= constrainedPoint]])
or: [aMathItemCollection first isConstrainedPointItem
and: [aMathItemCollection first ~= freePoint
and: [aMathItemCollection first ~= constrainedPoint]]]]! !
!DrGLocusBuilder methodsFor: 'testing'!
readyToBuild
^ freePoint notNil
and: [constrainedPoint notNil]! !
!DrGLocusBuilder class methodsFor: 'documentation'!
description
^ 'Locus defined by a free point on a curve and a relative point.' translated! !
!DrGLocusBuilder class methodsFor: 'documentation'!
title
^ 'Locus' translated.! !
!DrGMacroBuilder methodsFor: 'testing'!
isDescriptionValid
^ ((title = self defaultTitle) | (description = self defaultDescription)) not! !
!DrGMacroBuilder methodsFor: 'testing'!
isInputMode
^ wizard isInputPage! !
!DrGMacroBuilder methodsFor: 'testing'!
isLogicValid
"check wheter a macro can be deduced from the input/output item collections"
^ DrGMacro
isValidWith: input
and: output! !
!DrGMacroBuilder methodsFor: 'testing'!
isMacroValid
^self isLogicValid & self isDescriptionValid ! !
!DrGMacroBuilder methodsFor: 'testing'!
isOutputMode
^ wizard isOutputPage! !
!DrGMacroBuilder methodsFor: 'testing'!
isWanted: aMathItemCollection
^ aMathItemCollection notEmpty and:
[ self isInputMode & (output includes: aMathItemCollection first) not or: [ self isOutputMode & (input includes: aMathItemCollection first) not ] ]! !
!DrGMacroBuilder methodsFor: 'testing'!
readyToBuild
"Only when the user clicks on the wizard 'apply' button,
the system checks wheter the macro can be instiated"
^false! !
!DrGMacroBuilder methodsFor: 'accessing'!
arguments
self shouldNotImplement! !
!DrGMacroBuilder methodsFor: 'accessing'!
description
^description ! !
!DrGMacroBuilder methodsFor: 'accessing'!
description: string
description _ string asString! !
!DrGMacroBuilder methodsFor: 'accessing'!
input
^input! !
!DrGMacroBuilder methodsFor: 'accessing' stamp: 'hlsf 11/3/2021 19:11:47'!
inputNames
^ self itemNames: input! !
!DrGMacroBuilder methodsFor: 'accessing' stamp: 'hlsf 11/3/2021 19:11:47'!
itemNames: aMathItemCollection
^aMathItemCollection collect: [:mathItem | mathItem descriptiveName]! !
!DrGMacroBuilder methodsFor: 'accessing'!
output
^output ! !
!DrGMacroBuilder methodsFor: 'accessing' stamp: 'hlsf 11/3/2021 19:11:47'!
outputNames
^ self itemNames: output! !
!DrGMacroBuilder methodsFor: 'accessing'!
title
^title! !
!DrGMacroBuilder methodsFor: 'accessing'!
title: string
title _ string! !
!DrGMacroBuilder methodsFor: 'private'!
addItem: aMathItemCollection at: aPoint
super addItem: aMathItemCollection at: aPoint.
self isInputMode ifTrue: [self addToggleItem: aMathItemCollection in: input].
self isOutputMode ifTrue: [self addToggleItem: aMathItemCollection in: output]! !
!DrGMacroBuilder methodsFor: 'callback'!
apply
"the user clicked the apply button, do we have all the needed information
to instantiate a new macro construction?"
DrGeoSystem showVirtualKeyboard: false.
self isMacroValid ifTrue:
[ "we can instantiate a macro"
self triggerEvent: #readyToBuild.
^self].
self isLogicValid ifFalse:
[self inform: 'Input and output items don''t match' translated].
self isDescriptionValid ifFalse:
[self inform: 'Please, enter a proper title and description' translated]! !
!DrGMacroBuilder methodsFor: 'callback'!
cancel
"the user withdrawn the macro-construction creation"
DrGeoSystem showVirtualKeyboard: false.
self triggerEvent: #cancel! !
!DrGMacroBuilder methodsFor: 'callback'!
page: integer
"we receive notification from the wizard the user change the wizard
current page"
| newState |
(integer = 1 or: [ integer = 4 ]) ifTrue: [ newState _ DrGMacroToolStateNeutral ].
integer = 2 ifTrue: [ newState _ DrGMacroBuildToolStateInput ].
integer = 3 ifTrue: [ newState _ DrGMacroBuildToolStateOutput ].
integer = 4 ifTrue: [DrGeoSystem showVirtualKeyboard: true].
self
triggerEvent: #changedState
with: newState! !
!DrGMacroBuilder methodsFor: 'building'!
buildItem
self shouldNotImplement! !
!DrGMacroBuilder methodsFor: 'building'!
buildItem: domain
| macro |
macro _ DrGMacro new
title: title; description: description.
macro from: input to: output in: domain.
^ macro! !
!DrGMacroBuilder methodsFor: 'building'!
getItem
self shouldNotImplement! !
!DrGMacroBuilder methodsFor: 'building'!
getItem: domain
self isMacroValid ifTrue:
[^self buildItem: domain].
^nil! !
!DrGMacroBuilder methodsFor: 'initialize-release' stamp: 'hlsf 4/6/2022 16:35:50'!
initialize
self reset.
wizard _ DrGWizardMacroBuild open: self ::
addPages;
openInWorld.
wizard morphPosition: 0@0.
wizard when: #page send: #page: to: self.
wizard when: #apply send: #apply to: self.
wizard when: #cancel send: #cancel to: self! !
!DrGMacroBuilder methodsFor: 'initialize-release' stamp: 'hlsf 12/27/2021 10:59:17'!
release
wizard removeActionsWithReceiver: self.
wizard delete.
wizard _ nil! !
!DrGMacroBuilder methodsFor: 'updating' stamp: 'hlsf 11/3/2021 19:07:55'!
reset
super reset.
input _ OrderedCollection new.
output _ OrderedCollection new.
title _ self defaultTitle.
description _ self defaultDescription.
self changed: #inputNames.
self changed: #ouputNames.
self changed: #title.
self changed: #description! !
!DrGMacroBuilder methodsFor: 'constant'!
defaultDescription
^'Write down your description there.' asText! !
!DrGMacroBuilder methodsFor: 'constant'!
defaultTitle
^'Macro name' asText! !
!DrGMacroBuilder methodsFor: 'constant'!
mathItemClass
self shouldNotImplement! !
!DrGMacroBuilder class methodsFor: 'documentation'!
description
^ 'Construct a macro-construction with input and output items.' translated! !
!DrGMacroBuilder class methodsFor: 'documentation'!
title
^ 'Build macro' translated.! !
!DrGMacroPlayer methodsFor: 'private'!
addItem: aMathItemCollection at: aPoint
super addItem: aMathItemCollection at: aPoint.
self addToggleItem: aMathItemCollection in: input! !
!DrGMacroPlayer methodsFor: 'callback'!
cancel
self triggerEvent: #cancel! !
!DrGMacroPlayer methodsFor: 'callback'!
page: integer
"we receive notification from the wizard the user change the wizard
current page"
| newState |
integer = 1
ifTrue: [ newState _ DrGMacroToolStateNeutral ]
ifFalse: [ newState _ DrGMacroPlayToolStateSelect].
self
triggerEvent: #changedState
with: newState! !
!DrGMacroPlayer methodsFor: 'building' stamp: 'hlsf 8/4/2023 17:12:55'!
buildItem
^selectedMacro execute: input in: presenter.! !
!DrGMacroPlayer methodsFor: 'accessing'!
constructedNodes
^ selectedMacro constructedNodes ! !
!DrGMacroPlayer methodsFor: 'accessing' stamp: 'hlsf 11/19/2021 10:57:19'!
description
^ selectedMacro ifNotNil: [selectedMacro description] ifNil: [^'']! !
!DrGMacroPlayer methodsFor: 'accessing'!
description: text
selectedMacro ifNotNil: [selectedMacro description: text asString]! !
!DrGMacroPlayer methodsFor: 'accessing'!
input
^input! !
!DrGMacroPlayer methodsFor: 'accessing'!
inputBasicType
^input collect: [:i | i basicType]! !
!DrGMacroPlayer methodsFor: 'accessing'!
selectedMacro
^selectedMacro ! !
!DrGMacroPlayer methodsFor: 'accessing'!
selectedMacro: aMacro
"Some cleaning are needed"
selectedMacro _ aMacro.
input _ OrderedCollection new.
self triggerEvent: #changedMacro.! !
!DrGMacroPlayer methodsFor: 'initialize-release' stamp: 'hlsf 4/6/2022 16:34:27'!
initialize
wizard _ DrGWizardMacroPlay open: self ::
addPages;
openInWorld.
wizard morphPosition: 0@0.
input _ OrderedCollection new.
wizard when: #page send: #page: to: self.
wizard when: #cancel send: #cancel to: self! !
!DrGMacroPlayer methodsFor: 'initialize-release' stamp: 'hlsf 12/27/2021 10:57:41'!
release
wizard removeActionsWithReceiver: self.
wizard delete.
wizard _ nil! !
!DrGMacroPlayer methodsFor: 'testing'!
isWanted: aMathItemCollection
selectedMacro isNil ifTrue: [^false].
^aMathItemCollection notEmpty and:
[(selectedMacro inputBasicType at: input size + 1 ) == aMathItemCollection first basicType]! !
!DrGMacroPlayer methodsFor: 'testing'!
readyToBuild
^ self inputBasicType = selectedMacro inputBasicType! !
!DrGMacroPlayer methodsFor: 'updating' stamp: 'hlsf 11/19/2021 11:01:22'!
reset
super reset.
input _ OrderedCollection new.
selectedMacro _ nil.
self changed: #description.
self flag: #drgeoTodo
"wizard changed: #selectedMacro"! !
!DrGMacroPlayer class methodsFor: 'documentation'!
description
^'Execute a pre-built macro-construction on selected input items. To edit a macro description, edit its text and apply with the keys [alt/ctrl]+s.' translated! !
!DrGMacroPlayer class methodsFor: 'documentation'!
title
^ 'Execute/edit macro' translated! !
!DrGMacroPlayerHeadless methodsFor: 'initialize-release'!
initialize
input _ OrderedCollection new.
! !
!DrGMacroPlayerHeadless methodsFor: 'initialize-release'!
release! !
!DrGMiddleBuilder methodsFor: 'updating' stamp: 'hlsf 6/20/2021 11:21:14'!
reset
super reset.
pointA _ pointB _ segment _ nil! !
!DrGMiddleBuilder methodsFor: 'accessing'!
arguments
segment ifNotNil: [^{segment}].
^{pointA . pointB}! !
!DrGMiddleBuilder methodsFor: 'testing'!
isWanted: aMathItemCollection
^ aMathItemCollection notEmpty
and: [(aMathItemCollection first isPointItem
and: [aMathItemCollection first ~= pointA])
or: [aMathItemCollection first isSegmentItem and: [pointA isNil]]]! !
!DrGMiddleBuilder methodsFor: 'testing'!
readyToBuild
^ segment notNil or: [pointA notNil and: [pointB notNil]]! !
!DrGMiddleBuilder methodsFor: 'constant'!
mathItemClass
segment ifNotNil: [^DrGPointMiddlesegmentItem].
^DrGPointMiddle2ptsItem! !
!DrGMiddleBuilder methodsFor: 'private'!
addItem: aMathItemCollection at: aPoint
super addItem: aMathItemCollection at: aPoint.
aMathItemCollection first isPointItem
ifTrue:
[pointA ifNil:
[pointA _ aMathItemCollection first.
^self].
pointB ifNil:
[pointB _ aMathItemCollection first.
^self]]
ifFalse: [segment _ aMathItemCollection first]! !
!DrGMiddleBuilder class methodsFor: 'documentation'!
description
^ 'The midpoint of a segment or between two points.' translated! !
!DrGMiddleBuilder class methodsFor: 'documentation'!
title
^ 'Middle' translated. ! !
!DrGPointByCoordinatesBuilder methodsFor: 'constant'!
mathItemClass
^script
ifNotNil: [DrGPointScriptItem ]
ifNil: [DrGPointCoordinateItem]! !
!DrGPointByCoordinatesBuilder methodsFor: 'private'!
addItem: aMathItemCollection at: aPoint
super addItem: aMathItemCollection at: aPoint.
aMathItemCollection first isScriptItem
ifTrue:
[script _ aMathItemCollection first]
ifFalse:
[valueX
ifNil: [valueX _ aMathItemCollection first.]
ifNotNil: [valueY ifNil: [valueY _ aMathItemCollection first]]]! !
!DrGPointByCoordinatesBuilder methodsFor: 'accessing'!
arguments
^script
ifNotNil: [{script}]
ifNil: [{valueX . valueY}]! !
!DrGPointByCoordinatesBuilder methodsFor: 'testing'!
isWanted: aMathItemCollection
^ aMathItemCollection notEmpty
and: [(aMathItemCollection first isScriptItem
and: [aMathItemCollection first ~= script])
or: [aMathItemCollection first isValueItem
and: [aMathItemCollection first ~= valueX
and: [aMathItemCollection first ~= valueY]]]]
! !
!DrGPointByCoordinatesBuilder methodsFor: 'testing'!
readyToBuild
^ (valueX notNil and: [valueY notNil])
or: [script notNil]! !
!DrGPointByCoordinatesBuilder methodsFor: 'updating' stamp: 'hlsf 6/20/2021 11:21:26'!
reset
super reset.
script _ valueX _ valueY _ nil! !
!DrGPointByCoordinatesBuilder class methodsFor: 'documentation'!
description
^ 'Point given its coordinates: select two numbers or a point coordinates (@).' translated! !
!DrGPointByCoordinatesBuilder class methodsFor: 'documentation'!
title
^ 'Coordinates' translated! !
!DrGPointIntersectionBuilder methodsFor: 'accessing'!
arguments
^{curveItemA . curveItemB. point}! !
!DrGPointIntersectionBuilder methodsFor: 'private'!
addItem: aMathItemCollection at: aPoint
super addItem: aMathItemCollection at: aPoint.
curveItemA ifNil: [
curveItemA _ aMathItemCollection first.
^self].
curveItemB ifNil: [curveItemB _ aMathItemCollection first]
! !
!DrGPointIntersectionBuilder methodsFor: 'testing'!
isArcSelected
"does the user selected two arcs ?"
^ (curveItemA isCircleItem or: [curveItemA isArcItem]) or: [
curveItemB isCircleItem or: [curveItemB isArcItem]]! !
!DrGPointIntersectionBuilder methodsFor: 'testing'!
isWanted: aMathItemCollection
aMathItemCollection ifEmpty: [^false].
^ aMathItemCollection first isIntersectableItem
and: [curveItemA isNil or: [curveItemB isNil]]! !
!DrGPointIntersectionBuilder methodsFor: 'testing'!
readyToBuild
^ curveItemA notNil & curveItemB notNil ! !
!DrGPointIntersectionBuilder methodsFor: 'constant'!
mathItemClass
^ DrGPointIntersectionItem! !
!DrGPointIntersectionBuilder methodsFor: 'as yet unclassified' stamp: 'hlsf 9/25/2021 14:44:41'!
postProcess: item from: node
|k|
super postProcess: item from: node.
k _ (node attributeAt: 'extra') asNumber = 0 ifTrue: [-1] ifFalse: [1].
item k: k! !
!DrGPointIntersectionBuilder methodsFor: 'updating'!
buildItem
^ self isArcSelected
ifFalse: [super buildItem]
ifTrue: [{
self mathItemClass newWith: self arguments k: 1.
self mathItemClass newWith: self arguments k: -1}]! !
!DrGPointIntersectionBuilder methodsFor: 'updating' stamp: 'hlsf 6/20/2021 11:21:30'!
reset
super reset.
curveItemA _ curveItemB _ nil! !
!DrGPointIntersectionBuilder methodsFor: 'xml' stamp: 'hlsf 9/25/2021 14:44:19'!
itemInstanceFrom: node
"We only want intersection point"
|arguments k|
arguments _ self parentsById: node.
"We by-pass the builder because it requires the user mouse position at intersection request "
k _ (node attributeAt: 'extra') asNumber = 0 ifTrue: [-1] ifFalse: [1].
^self mathItemClass newWith: arguments k: k.! !
!DrGPointIntersectionBuilder class methodsFor: 'documentation'!
description
^'Intersection(s) of two curves.' translated! !
!DrGPointIntersectionBuilder class methodsFor: 'documentation'!
title
^ 'Intersection' translated! !
!DrGPolygonBuilder methodsFor: 'flying costume' stamp: 'hlsf 6/20/2021 12:10:23'!
addToFlyingItem: anItem
self isNotInteractive ifTrue: [^self].
points size = 2 ifTrue: [
movingPoint _ DrGPointFreeItem new point: anItem point + (0.1 @ 0.1).
flyingItem _ self mathItemClass
newWith: ((OrderedCollection withAll: points) add: movingPoint; yourself).
self initializeFlyingMorph].
points size > 2 ifTrue: [
movingPoint _ DrGPointFreeItem new point: anItem point + (0.1 @ 0.1).
flyingItem parents: (flyingItem parents
add: movingPoint;
yourself).
flyingMorph redrawNeeded]! !
!DrGPolygonBuilder methodsFor: 'flying costume' stamp: 'hlsf 4/12/2021 22:04:35'!
flyingMorphClass
^ DrGPolygonMorph ! !
!DrGPolygonBuilder methodsFor: 'constant'!
mathItemClass
^DrGPolygonNptsItem! !
!DrGPolygonBuilder methodsFor: 'initialize-release'!
initialize
points _ OrderedCollection new.
! !
!DrGPolygonBuilder methodsFor: 'accessing'!
arguments
^points allButLast! !
!DrGPolygonBuilder methodsFor: 'testing'!
isWanted: aMathItemCollection
^aMathItemCollection notEmpty
and: [aMathItemCollection first isPointItem
and: [points isEmpty
or: [(points first = aMathItemCollection first and: [ points size > 2])
or: [(points includes: aMathItemCollection first) not]]]]! !
!DrGPolygonBuilder methodsFor: 'testing'!
readyToBuild
^ points size > 2 and: [points first = points last]! !
!DrGPolygonBuilder methodsFor: 'private'!
addItem: aMathItemCollection at: aPoint
super addItem: aMathItemCollection at: aPoint.
points add: aMathItemCollection first.
self addToFlyingItem: points last.! !
!DrGPolygonBuilder methodsFor: 'xml'!
parentsById: node
|arguments|
"To instantiate a polygon we need the first summit to be duplucated at the end of the point collection"
arguments _ super parentsById: node.
arguments addLast: arguments first.
^ arguments ! !
!DrGPolygonBuilder methodsFor: 'updating'!
reset
super reset.
points _ OrderedCollection new! !
!DrGPolygonBuilder class methodsFor: 'documentation'!
description
^ 'Polygon by n points: last point must be the initial point to terminate.' translated! !
!DrGPolygonBuilder class methodsFor: 'documentation'!
title
^ 'Polygon' translated! !
!DrGPolygonRegularBuilder methodsFor: 'private'!
addItem: aMathItemCollection at: aPoint
| item |
super addItem: aMathItemCollection at: aPoint.
item _ aMathItemCollection first.
item isPointItem ifTrue: [
center isNil ifTrue: [^ center _ item].
pointA isNil ifTrue: [^ pointA _ item]].
(item isValueItem and: [value isNil]) ifTrue: [
value _ item]! !
!DrGPolygonRegularBuilder methodsFor: 'accessing'!
arguments
^ {center. pointA. value}! !
!DrGPolygonRegularBuilder methodsFor: 'testing'!
isWanted: aMathItemCollection
^ aMathItemCollection notEmpty and: [
(aMathItemCollection first isPointItem and: [center isNil or: [pointA isNil]]) or: [
aMathItemCollection first isValueItem and: [value isNil]]]! !
!DrGPolygonRegularBuilder methodsFor: 'testing'!
readyToBuild
^(center notNil and: [pointA notNil and: [value notNil ]])! !
!DrGPolygonRegularBuilder methodsFor: 'updating' stamp: 'hlsf 6/20/2021 11:21:37'!
reset
super reset.
center _ pointA _ value _ nil! !
!DrGPolygonRegularBuilder methodsFor: 'constant'!
mathItemClass
^ DrGPolygonRegularItem ! !
!DrGPolygonRegularBuilder class methodsFor: 'documentation'!
description
^ 'Regular polygon defined by its center, a vertex and its sides number.' translated! !
!DrGPolygonRegularBuilder class methodsFor: 'documentation'!
title
^ 'Regular polygon' translated! !
!DrGScriptPlayer methodsFor: 'callback'!
cancel
self triggerEvent: #cancel! !
!DrGScriptPlayer methodsFor: 'callback'!
page: integer
"we receive notification from the wizard the user change the wizard
current page"
| newState |
integer = 1
ifTrue: [ newState _ DrGMacroToolStateNeutral ]
ifFalse: [ newState _ DrGMacroPlayToolStateSelect].
self
triggerEvent: #changedState
with: newState! !
!DrGScriptPlayer methodsFor: 'xml'!
basicItemFrom: node
"create a scrip item then set its script from the xml node information"
| item |
item _ super basicItemFrom: node.
item script: (node attributeAt: #class) asClass.
^ item! !
!DrGScriptPlayer methodsFor: 'xml' stamp: 'hlsf 9/25/2021 21:43:01'!
itemInstanceFrom: node
self scriptClass: (Smalltalk at: (node attributeAt: #class) asSymbol).
self add: #() at: 0@0.
(self parentsById: node) do: [:each | self addItem: {each} at: 0@0].
^ self getItem first.! !
!DrGScriptPlayer methodsFor: 'xml'!
postProcess: item from: node
super postProcess: item from: node.
self parseValuePosition: node of: item! !
!DrGScriptPlayer methodsFor: 'dependents access'!
release
self removeEvents.
wizard delete.
wizard _ nil! !
!DrGScriptPlayer methodsFor: 'private'!
addItem: aMathItemCollection at: aPoint
"Take the point position only when the user clic somewhere in the background"
aMathItemCollection ifEmpty:
[point _ aPoint.
^self].
input size < scriptClass argumentsType size
ifTrue: [self addToggleItem: aMathItemCollection in: input]
ifFalse: [input remove: aMathItemCollection first ifAbsent: []]! !
!DrGScriptPlayer methodsFor: 'testing'!
isWanted: aMathItemCollection
"We are now performing type checking for script, we are also interested
in empty aMathItemCollection, (ie: just get the clic position in the background)"
scriptClass ifNil: [^false].
aMathItemCollection ifEmpty: [ ^ true ].
^ input size = scriptClass argumentsType size
ifTrue:
[input includes: aMathItemCollection first]
ifFalse:
[aMathItemCollection first class includesBehavior: (scriptClass argumentsType at: input size + 1)]! !
!DrGScriptPlayer methodsFor: 'testing'!
mathItemClass
^DrGValueScriptItem ! !
!DrGScriptPlayer methodsFor: 'testing'!
readyToBuild
scriptClass ifNil: [^false].
^ input size = scriptClass argumentsType size and: [ point isNil not ]! !
!DrGScriptPlayer methodsFor: 'testing'!
reset
super reset.
input _ OrderedCollection new.! !
!DrGScriptPlayer methodsFor: 'accessing'!
arguments
^ (OrderedCollection withAll: input)
add: scriptClass;
add: point;
yourself! !
!DrGScriptPlayer methodsFor: 'accessing' stamp: 'hlsf 4/7/2022 15:41:45'!
description
| comment |
^ scriptClass
ifNil: ['']
ifNotNil:
[comment _ scriptClass description.
comment isEmpty
ifTrue: ['No description, write one in the description method of this script.' translated]
ifFalse: [comment]]! !
!DrGScriptPlayer methodsFor: 'accessing' stamp: 'hlsf 4/7/2022 15:24:54'!
description: aText
" Not yet implemented, should rewrite the description of the selected scriptClass "
self flag: #drgeoTodo! !
!DrGScriptPlayer methodsFor: 'accessing'!
input
^input! !
!DrGScriptPlayer methodsFor: 'accessing'!
scriptClass
^ scriptClass! !
!DrGScriptPlayer methodsFor: 'accessing'!
scriptClass: anObject
scriptClass _ anObject.
input _ OrderedCollection new.
self triggerEvent: #changedScript.! !
!DrGScriptPlayer methodsFor: 'initialize-release'!
basicInitialize
input _ OrderedCollection new.! !
!DrGScriptPlayer methodsFor: 'initialize-release' stamp: 'hlsf 4/6/2022 16:36:57'!
initialize
wizard _ DrGWizardScript open: self ::
addPages;
openInWorld.
input _ OrderedCollection new.
wizard when: #page send: #page: to: self.
wizard when: #cancel send: #cancel to: self.! !
!DrGScriptPlayer methodsFor: 'initialize-release'!
removeEvents
wizard removeActionsWithReceiver: self! !
!DrGScriptPlayer class methodsFor: 'xml'!
basicItemFrom: node
"create a basic item (unitialised) from this node and add it to the domain, return an item partially initialized. Use for macro node"
| builder |
builder _ self basicNew basicInitialize.
^ builder basicItemFrom: node! !
!DrGScriptPlayer class methodsFor: 'xml' stamp: 'hlsf 8/4/2023 17:29:25'!
itemFrom: node in: presenter
"create an item from this node and add it to the domain, return a couple {item. boolean}"
| builder |
builder := self basicNew basicInitialize; presenter: presenter; yourself.
^ builder itemFrom: node! !
!DrGScriptPlayer class methodsFor: 'documentation'!
description
^ 'Insert a Smalltalk script in the drawing area.' translated! !
!DrGScriptPlayer class methodsFor: 'documentation'!
title
^ 'Use a script' translated! !
!DrGScriptPlayerHeadless methodsFor: 'as yet unclassified'!
initialize
input _ OrderedCollection new.! !
!DrGScriptPlayerHeadless methodsFor: 'as yet unclassified'!
release! !
!DrGSegmentBuilder methodsFor: 'testing'!
isWanted: aMathItemCollection
^aMathItemCollection notEmpty
and: [aMathItemCollection first isPointItem
and: [aMathItemCollection first ~= pointA]]! !
!DrGSegmentBuilder methodsFor: 'testing'!
readyToBuild
^ pointA notNil and: [pointB notNil]! !
!DrGSegmentBuilder methodsFor: 'updating' stamp: 'hlsf 6/20/2021 11:21:41'!
reset
super reset.
pointA _ pointB _ nil! !
!DrGSegmentBuilder methodsFor: 'accessing'!
arguments
^{pointA . pointB}! !
!DrGSegmentBuilder methodsFor: 'constant'!
mathItemClass
^DrGSegment2ptsItem! !
!DrGSegmentBuilder methodsFor: 'flying costume' stamp: 'hlsf 4/12/2021 22:14:28'!
flyingMathItemArguments
^ {pointA. movingPoint}.
! !
!DrGSegmentBuilder methodsFor: 'flying costume' stamp: 'hlsf 4/12/2021 22:04:35'!
flyingMorphClass
^ DrGSegmentMorph! !
!DrGSegmentBuilder methodsFor: 'private' stamp: 'hlsf 8/4/2021 15:22:40'!
addItem: aMathItemCollection at: aPoint
super addItem: aMathItemCollection at: aPoint.
pointA ifNil:
[pointA _ aMathItemCollection first.
self addToFlyingItem: pointA.
^ self].
pointB ifNil: [ pointB _ aMathItemCollection first]
! !
!DrGSegmentBuilder class methodsFor: 'documentation'!
description
^ 'Segment defined by two points.' translated! !
!DrGSegmentBuilder class methodsFor: 'documentation'!
title
^ 'Segment' translated! !
!DrGCircleBuilder methodsFor: 'testing'!
isWanted: aMathItemCollection
^ aMathItemCollection notEmpty
and: [(aMathItemCollection first isPointItem
and: [aMathItemCollection first ~= pointA])
or: [(aMathItemCollection first isValueItem
and: [pointA isNil not
and: [aMathItemCollection first ~= radius]])
or: [aMathItemCollection first isSegmentItem
and: [pointA isNil not
and: [aMathItemCollection first ~= segment]]]]]! !
!DrGCircleBuilder methodsFor: 'testing'!
readyToBuild
^ (radius notNil and: [pointA notNil])
or: [(pointA notNil and: [pointB notNil])
or: [pointA notNil and: [segment notNil]]]! !
!DrGCircleBuilder methodsFor: 'private'!
addItem: aMathItemCollection at: aPoint
|item|
point _ aPoint.
(item _ aMathItemCollection first) isSegmentItem ifTrue: [
^ segment ifNil: [segment _ item]].
item isValueItem ifTrue: [
^ radius ifNil: [radius _ item]].
^ pointA
ifNil: [pointA _ item.
self addToFlyingItem: pointA]
ifNotNil: [pointB _ item]! !
!DrGCircleBuilder methodsFor: 'flying costume' stamp: 'hlsf 4/12/2021 22:04:35'!
flyingMorphClass
^ DrGCircleMorph! !
!DrGCircleBuilder methodsFor: 'accessing'!
arguments
pointB
ifNil:
[radius ifNotNil: [^{pointA. radius}].
segment ifNotNil: [^{pointA. segment}]]
ifNotNil: [^{pointA. pointB}]! !
!DrGCircleBuilder methodsFor: 'updating'!
reset
super reset.
radius _ nil.
segment _ nil.! !
!DrGCircleBuilder methodsFor: 'constant'!
mathItemClass
^ radius
ifNil: [
segment
ifNil: [DrGCircle2ptsItem]
ifNotNil: [DrGCircleSegmentItem]]
ifNotNil: [DrGCircleRadiusItem]! !
!DrGCircleBuilder class methodsFor: 'documentation'!
description
^ 'Circle defined by its center and a point or by its center and radius, a value.' translated! !
!DrGCircleBuilder class methodsFor: 'documentation'!
title
^ 'Circle' translated ! !
!DrGLineBuilder methodsFor: 'constant'!
mathItemClass
^DrGLine2ptsItem! !
!DrGLineBuilder methodsFor: 'flying costume' stamp: 'hlsf 4/12/2021 22:04:35'!
flyingMorphClass
^ DrGLineMorph! !
!DrGLineBuilder class methodsFor: 'documentation'!
description
^ 'Line defined by two points' translated! !
!DrGLineBuilder class methodsFor: 'documentation'!
title
^ 'Line' translated! !
!DrGAngleBisectorBuilder methodsFor: 'private'!
addItem: aMathItemCollection at: aPoint
| item |
point _ aPoint.
(item _ aMathItemCollection first) isAngleItem ifTrue: [^ angle ifNil: [angle := item]].
pointA
ifNil: [pointA _ item]
ifNotNil: [pointB
ifNil: [pointB _ item.
self addToFlyingItem: pointB]
ifNotNil: [pointC _ item]]! !
!DrGAngleBisectorBuilder methodsFor: 'accessing'!
arguments
^ angle
ifNotNil: [{angle}]
ifNil: [{pointA . pointB . pointC}]! !
!DrGAngleBisectorBuilder methodsFor: 'updating' stamp: 'hlsf 6/20/2021 11:21:47'!
reset
super reset.
pointC _ angle _ nil
! !
!DrGAngleBisectorBuilder methodsFor: 'constant'!
mathItemClass
^ angle
ifNotNil: [DrGLineAngleBisectorItem]
ifNil: [DrGAngleBisector3ptsItem]! !
!DrGAngleBisectorBuilder methodsFor: 'flying costume' stamp: 'hlsf 4/12/2021 22:14:28'!
flyingMathItemArguments
^ {pointA. pointB. movingPoint}.! !
!DrGAngleBisectorBuilder methodsFor: 'testing'!
isWanted: aMathItemCollection
| item |
^ aMathItemCollection notEmpty
and: [((item _ aMathItemCollection first) isPointItem
and: [item ~= pointA
and: [item ~= pointB]])
or: [item isAngleItem and: [pointA isNil and: [item nodeType = #'3pts']]]] ! !
!DrGAngleBisectorBuilder methodsFor: 'testing'!
readyToBuild
^ angle notNil or:
[pointA notNil and: [pointB notNil and: [pointC notNil]]]! !
!DrGAngleBisectorBuilder class methodsFor: 'documentation'!
description
^ 'Angle bisector defined by three points or an angle defined by three points.' translated! !
!DrGAngleBisectorBuilder class methodsFor: 'documentation'!
title
^ 'Angle bisector' translated! !
!DrGParallelBuilder methodsFor: 'constant'!
mathItemClass
^DrGLineParallelItem! !
!DrGParallelBuilder methodsFor: 'testing'!
isWanted: aMathItemCollection
aMathItemCollection ifEmpty: [^false].
^ (aMathItemCollection first isPointItem
and: [pointA isNil])
or: [aMathItemCollection first isDirectionItem and: [direction isNil]]
! !
!DrGParallelBuilder methodsFor: 'testing'!
readyToBuild
^pointA notNil and: [direction notNil]! !
!DrGParallelBuilder methodsFor: 'flying costume' stamp: 'hlsf 4/12/2021 22:14:28'!
flyingMathItemArguments
^{direction. movingPoint}.
! !
!DrGParallelBuilder methodsFor: 'updating' stamp: 'hlsf 6/20/2021 11:22:00'!
reset
super reset.
pointA _ direction _ nil! !
!DrGParallelBuilder methodsFor: 'private'!
addItem: aMathItemCollection at: aPoint
point _ aPoint.
aMathItemCollection first isPointItem
ifTrue: [pointA _ aMathItemCollection first].
aMathItemCollection first isDirectionItem
ifTrue:[direction _ aMathItemCollection first.
self addToFlyingItem: direction].
! !
!DrGParallelBuilder methodsFor: 'accessing'!
arguments
^{direction . pointA}! !
!DrGParallelBuilder class methodsFor: 'documentation'!
description
^ 'Line passing through one point and parallel to a line, half-line, etc.' translated! !
!DrGParallelBuilder class methodsFor: 'documentation'!
title
^ 'Parallel' translated! !
!DrGPerpendicularBuilder methodsFor: 'constant'!
mathItemClass
^DrGLinePerpendicularItem! !
!DrGPerpendicularBuilder class methodsFor: 'documentation'!
description
^ 'Line passing through one point and orthogonal to a line, half-line, etc.' translated! !
!DrGPerpendicularBuilder class methodsFor: 'documentation'!
title
^ 'Perpendicular' translated! !
!DrGPerpendicularBisectorBuilder methodsFor: 'testing'!
isWanted: aMathItemCollection
| item |
^ aMathItemCollection notEmpty
and: [((item _ aMathItemCollection first) isPointItem
and: [item ~= pointA])
or: [item isSegmentItem and: [pointA isNil]]]! !
!DrGPerpendicularBisectorBuilder methodsFor: 'testing'!
readyToBuild
^ segment notNil or:
[pointA notNil and: [pointB notNil]]! !
!DrGPerpendicularBisectorBuilder methodsFor: 'updating'!
reset
super reset.
segment _ nil! !
!DrGPerpendicularBisectorBuilder methodsFor: 'accessing'!
arguments
^ segment
ifNil: [{pointA . pointB}]
ifNotNil: [{segment}]! !
!DrGPerpendicularBisectorBuilder methodsFor: 'private'!
addItem: aMathItemCollection at: aPoint
| item |
point _ aPoint.
(item _ aMathItemCollection first) isSegmentItem ifTrue:
[^segment ifNil: [segment _ item]].
pointA
ifNil: [pointA _ item.
self addToFlyingItem: pointA.]
ifNotNil: [pointB _ item]
! !
!DrGPerpendicularBisectorBuilder methodsFor: 'constant'!
mathItemClass
^ segment
ifNotNil: [DrGPerpendicularBisectorItem]
ifNil: [DrGLinePerpendicularBisector2ptsItem].! !
!DrGPerpendicularBisectorBuilder class methodsFor: 'documentation'!
description
^ 'Perpendicular bisector defined by a segment or two points.' translated! !
!DrGPerpendicularBisectorBuilder class methodsFor: 'documentation'!
title
^ 'Perpendicular bisector' translated! !
!DrGRayBuilder methodsFor: 'constant'!
mathItemClass
^DrGRay2ptsItem! !
!DrGRayBuilder methodsFor: 'flying costume' stamp: 'hlsf 4/12/2021 22:04:35'!
flyingMorphClass
^ DrGRayMorph! !
!DrGRayBuilder class methodsFor: 'documentation'!
description
^ 'Half-Line defined by two points, the first selected point is the origin.' translated! !
!DrGRayBuilder class methodsFor: 'documentation'!
title
^'Ray' translated ! !
!DrGVectorBuilder methodsFor: 'flying costume' stamp: 'hlsf 4/12/2021 22:04:35'!
flyingMorphClass
^ DrGVectorMorph! !
!DrGVectorBuilder methodsFor: 'constant'!
mathItemClass
^DrGVector2ptsItem! !
!DrGVectorBuilder class methodsFor: 'documentation'!
description
^'Vector defined by two points.' translated! !
!DrGVectorBuilder class methodsFor: 'documentation'!
title
^'Vector' translated ! !
!DrGTextBuilder methodsFor: 'accessing'!
arguments
^ {point}! !
!DrGTextBuilder methodsFor: 'xml'!
itemInstanceFrom: node
self addItem: #() at: 0@0.
^ self getItem first.
! !
!DrGTextBuilder methodsFor: 'xml'!
postProcess: item from: node
super postProcess: item from: node.
self parseValuePosition: node of: item.
item text: (node contentStringAt: #contents)! !
!DrGTextBuilder methodsFor: 'constant'!
mathItemClass
^ DrGTextItem! !
!DrGTextBuilder methodsFor: 'testing'!
isWanted: aMathItemCollection
^ aMathItemCollection isEmpty! !
!DrGTextBuilder methodsFor: 'testing'!
readyToBuild
^ point notNil! !
!DrGTextBuilder class methodsFor: 'documentation'!
description
^ 'Free text you can edit and move around.' translated! !
!DrGTextBuilder class methodsFor: 'documentation'!
title
^ 'Text' translated! !
!DrGTransformationBuilder methodsFor: 'xml'!
parentsById: node
^ (super parentsById: node) reverse! !
!DrGTransformationBuilder methodsFor: 'accessing'!
arguments
^self arguments: mathItem! !
!DrGTransformationBuilder methodsFor: 'constant'!
mathItemClass
^ self mathItemClass: mathItem! !
!DrGTransformationBuilder methodsFor: 'building'!
buildItem
mathItem class = DrGCompositeItem
ifTrue:
[^ mathItem subItems collect: [:aMathItem|
(self mathItemClass: aMathItem)
newWith: (self arguments: aMathItem)]]
ifFalse:
[^super buildItem]! !
!DrGReflectionBuilder methodsFor: 'constant' stamp: 'hlsf 5/31/2021 18:57:50'!
mathItemClass: aMathItem
|className|
className _ 'DrG', aMathItem basicType capitalized, 'ReflexionItem'.
^(Smalltalk classNamed: className)! !
!DrGReflectionBuilder methodsFor: 'accessing'!
arguments: aMathItem
^{aMathItem . axe}! !
!DrGReflectionBuilder methodsFor: 'testing'!
isWanted: aMathItemCollection
^ aMathItemCollection notEmpty
and: [(aMathItemCollection first isLineItem
and: [axe isNil])
or: [aMathItemCollection first isGeometricItem
and: [mathItem isNil]]]! !
!DrGReflectionBuilder methodsFor: 'testing'!
readyToBuild
^axe notNil and: [mathItem notNil]! !
!DrGReflectionBuilder methodsFor: 'private'!
addItem: aMathItemCollection at: aPoint
super addItem: aMathItemCollection at: aPoint.
(aMathItemCollection first isLineItem and: [axe isNil])
ifTrue: [axe _ aMathItemCollection first]
ifFalse: [mathItem _ aMathItemCollection first]! !
!DrGReflectionBuilder methodsFor: 'updating' stamp: 'hlsf 6/20/2021 11:22:05'!
reset
super reset.
axe _ mathItem _ nil! !
!DrGReflectionBuilder class methodsFor: 'documentation'!
description
^ 'Reflexion: select a line and a geometric object. Reflexion axe is the first selected line.' translated! !
!DrGReflectionBuilder class methodsFor: 'documentation'!
title
^ 'Reflection' translated! !
!DrGRotationBuilder methodsFor: 'testing'!
isWanted: aMathItemCollection
^ aMathItemCollection notEmpty
and: [(aMathItemCollection first isPointItem and: [center isNil])
or: [(aMathItemCollection first isValueItem and: [value isNil])
or: [aMathItemCollection first isGeometricItem and: [mathItem isNil]]]]! !
!DrGRotationBuilder methodsFor: 'testing'!
readyToBuild
^center notNil and: [value notNil and: [mathItem notNil]]! !
!DrGRotationBuilder methodsFor: 'private'!
addItem: aMathItemCollection at: aPoint
super addItem: aMathItemCollection at: aPoint.
(aMathItemCollection first isPointItem and: [center isNil])
ifTrue: [center _ aMathItemCollection first. ^self].
(aMathItemCollection first isValueItem and: [value isNil])
ifTrue: [value _ aMathItemCollection first. ^self].
mathItem _ aMathItemCollection first! !
!DrGRotationBuilder methodsFor: 'accessing'!
arguments: aMathItem
^{aMathItem . center . value}! !
!DrGRotationBuilder methodsFor: 'updating' stamp: 'hlsf 6/20/2021 11:22:14'!
reset
super reset.
center _ value _ mathItem _ nil! !
!DrGRotationBuilder methodsFor: 'constant' stamp: 'hlsf 5/31/2021 18:57:54'!
mathItemClass: aMathItem
|className|
className _ 'DrG', aMathItem basicType capitalized, 'RotationItem'.
^(Smalltalk classNamed: className)! !
!DrGRotationBuilder class methodsFor: 'documentation'!
description
^ 'Rotation: select a point, a value and a geometric object. The first selected point is the rotation center.' translated! !
!DrGRotationBuilder class methodsFor: 'documentation'!
title
^ 'Rotation' translated! !
!DrGHomothetyBuilder methodsFor: 'constant' stamp: 'hlsf 5/31/2021 18:57:39'!
mathItemClass: aMathItem
|className|
className _ 'DrG', aMathItem basicType capitalized, 'HomothetyItem'.
^(Smalltalk classNamed: className)! !
!DrGHomothetyBuilder class methodsFor: 'documentation'!
description
^ 'Homothety: select a center, a value and a geometric object. The first selected point is the homothety center.' translated! !
!DrGHomothetyBuilder class methodsFor: 'documentation'!
title
^ 'Homothety (scale)' translated! !
!DrGSymmetryBuilder methodsFor: 'accessing'!
arguments: aMathItem
^{aMathItem . center}! !
!DrGSymmetryBuilder methodsFor: 'updating' stamp: 'hlsf 6/20/2021 11:22:17'!
reset
super reset.
mathItem _ center _ nil! !
!DrGSymmetryBuilder methodsFor: 'testing'!
isWanted: aMathItemCollection
^ aMathItemCollection notEmpty
and: [(aMathItemCollection first isPointItem
and: [center isNil])
or: [aMathItemCollection first isGeometricItem
and: [mathItem isNil]]]! !
!DrGSymmetryBuilder methodsFor: 'testing'!
readyToBuild
^center notNil and: [mathItem notNil]! !
!DrGSymmetryBuilder methodsFor: 'private'!
addItem: aMathItemCollection at: aPoint
super addItem: aMathItemCollection at: aPoint.
(aMathItemCollection first isPointItem and: [center isNil])
ifTrue: [center _ aMathItemCollection first]
ifFalse: [mathItem _ aMathItemCollection first]! !
!DrGSymmetryBuilder methodsFor: 'constant' stamp: 'hlsf 5/31/2021 18:58:02'!
mathItemClass: aMathItem
|className|
className _ 'DrG', aMathItem basicType capitalized, 'SymmetryItem'.
^(Smalltalk classNamed: className)! !
!DrGSymmetryBuilder class methodsFor: 'documentation'!
description
^ 'Symmetry: select a point and a geometric object. The first selected point is the symmetry center.' translated! !
!DrGSymmetryBuilder class methodsFor: 'documentation'!
title
^'Symmetry' translated ! !
!DrGTranslationBuilder methodsFor: 'constant' stamp: 'hlsf 5/31/2021 18:58:11'!
mathItemClass: aMathItem
|className|
className _ 'DrG', aMathItem basicType capitalized, 'TranslationItem'.
^(Smalltalk classNamed: className)! !
!DrGTranslationBuilder methodsFor: 'accessing'!
arguments: aMathItem
^{aMathItem . vector}! !
!DrGTranslationBuilder methodsFor: 'testing'!
isWanted: aMathItemCollection
^ aMathItemCollection notEmpty
and: [(aMathItemCollection first isVectorItem
and: [vector isNil])
or: [aMathItemCollection first isGeometricItem
and: [aMathItemCollection first isVectorItem not
and: [mathItem isNil]]]]! !
!DrGTranslationBuilder methodsFor: 'testing'!
readyToBuild
^vector notNil and: [mathItem notNil]! !
!DrGTranslationBuilder methodsFor: 'updating' stamp: 'hlsf 6/20/2021 11:22:22'!
reset
super reset.
vector _ mathItem _ nil.! !
!DrGTranslationBuilder methodsFor: 'private'!
addItem: aMathItemCollection at: aPoint
super addItem: aMathItemCollection at: aPoint.
(aMathItemCollection first isVectorItem and: [vector isNil])
ifTrue: [vector _ aMathItemCollection first]
ifFalse: [mathItem _ aMathItemCollection first]! !
!DrGTranslationBuilder class methodsFor: 'documentation'!
description
^ 'Translation: select a vector and a geometric object.' translated! !
!DrGTranslationBuilder class methodsFor: 'documentation'!
title
^ 'Translation' translated! !
!DrGValueBuilder methodsFor: 'accessing'!
arguments
(pointA notNil and: [curveItem notNil])
ifTrue: [^{pointA . curveItem. point}].
curveItem ifNotNil: [^{curveItem. point}].
pointB ifNotNil: [^{pointA . pointB. point}].
^{point}! !
!DrGValueBuilder methodsFor: 'private'!
addItem: aMathItemCollection at: aPoint
super addItem: aMathItemCollection at: aPoint.
aMathItemCollection ifEmpty: [^self].
aMathItemCollection first isPointItem
ifTrue:
[pointA ifNil:
[pointA _ aMathItemCollection first.
^self].
pointB ifNil:
[pointB _ aMathItemCollection first.
^self]]
ifFalse: [curveItem _ aMathItemCollection first]! !
!DrGValueBuilder methodsFor: 'xml'!
itemInstanceFrom: node
(self parentsById: node) do: [:each | self addItem: {each} at: 0@0].
"give a chance to a Free value (ValueValueItem) to be instantiated, otherwise it does not hurt"
self addItem: #() at: 0@0.
^ self getItem first.
! !
!DrGValueBuilder methodsFor: 'xml'!
postProcess: item from: node
super postProcess: item from: node.
self parseValuePosition: node of: item.
(node attributeAt: #type) asSymbol == #value
ifTrue: [item valueItem: (node contentStringAt: #value) asNumber]! !
!DrGValueBuilder methodsFor: 'constant'!
mathItemClass
pointA
ifNotNil: [curveItem
ifNotNil: [curveItem isLineItem
ifTrue: [^ DrGValueDistanceptlineItem]]].
curveItem
ifNotNil: [curveItem isLineItem
ifTrue: [^ DrGValueSlopeItem].
curveItem isSegmentItem
ifTrue: [^ DrGValueSegmentlengthItem].
curveItem isCircleItem
ifTrue: [^ DrGValueCircleperimeterItem].
curveItem isVectorItem
ifTrue: [^ DrGValueVectornormItem].
curveItem isArcItem
ifTrue: [^ DrGValueArclengthItem].
curveItem isPolygonItem
ifTrue: [ ^ DrGValuePolygonperimeterItem]
].
pointB
ifNotNil: [^ DrGValueDistance2ptsItem].
^ DrGValueValueItem! !
!DrGValueBuilder methodsFor: 'updating' stamp: 'hlsf 6/20/2021 11:22:28'!
reset
super reset.
pointA _ pointB _ curveItem _ nil! !
!DrGValueBuilder methodsFor: 'testing'!
isWanted: aMathItemCollection
aMathItemCollection
ifEmpty: [^ true].
aMathItemCollection first isPointItem
ifTrue: [^ true].
((aMathItemCollection first isLineItem
or: [aMathItemCollection first isSegmentItem
or: [aMathItemCollection first isVectorItem
or: [aMathItemCollection first isCircleItem
or: [aMathItemCollection first isArcItem
or: [aMathItemCollection first isPolygonItem] ]]]])
and: [pointA isNil])
ifTrue: [^ true].
(pointA notNil and: [aMathItemCollection first isLineItem])
ifTrue: [^ true].
^ false! !
!DrGValueBuilder methodsFor: 'testing'!
readyToBuild
^(point notNil
and: [curveItem isNil
and: [pointA isNil
and: [pointB isNil]]])
or: [pointB notNil
or: [curveItem notNil]]! !
!DrGValueBuilder class methodsFor: 'documentation'!
description
^ 'Distance between objects, curve length, free value.' translated! !
!DrGValueBuilder class methodsFor: 'documentation'!
title
^ 'Distance, length, value' translated! !
!DrGCommandStack methodsFor: 'private'!
truncate
|oldReadLimit|
oldReadLimit _ readLimit.
readLimit _ position.
oldReadLimit > readLimit ifTrue:
[readLimit to: oldReadLimit do:
[:index| collection at: index + 1 put: nil]]! !
!DrGCommandStack methodsFor: 'accessing'!
nextPut: aCommand
super nextPut: aCommand.
self truncate.
^ aCommand ! !
!DrGCommandStack methodsFor: 'accessing'!
previous
self position = 0 ifTrue: [^nil].
self position: self position - 1.
^self peek.! !
!DrGCommandStack class methodsFor: 'instance creation'!
new
^self on: Array new! !
!DrGLocusSample methodsFor: 'testing'!
isNotValid
^ exist not! !
!DrGLocusSample methodsFor: 'testing'!
isValid
^ exist! !
!DrGLocusSample methodsFor: 'testing'!
isValidAndOnScreen
^ exist and: [offScreen not]! !
!DrGLocusSample methodsFor: 'testing'!
offScreen
^ offScreen ! !
!DrGLocusSample methodsFor: 'accessing'!
isValid: aBoolean
^ exist _ aBoolean ! !
!DrGLocusSample methodsFor: 'accessing'!
offScreen: aBoolean
offScreen _ aBoolean ! !
!DrGLocusSample methodsFor: 'accessing'!
pointScreen
^ pointScreen! !
!DrGLocusSample methodsFor: 'accessing'!
pointScreen: anObject
pointScreen _ anObject! !
!DrGLocusSample methodsFor: 'accessing'!
pointWorld
^ pointWorld! !
!DrGLocusSample methodsFor: 'accessing'!
pointWorld: anObject
pointWorld _ anObject! !
!DrGLocusSample methodsFor: 'accessing'!
x
^ abscissa! !
!DrGLocusSample methodsFor: 'accessing'!
x: anObject
abscissa _ anObject! !
!DrGeoMiniView methodsFor: 'accessing' stamp: 'hlsf 6/19/2021 10:07:28'!
drawable
^ drawable! !
!DrGeoMiniView methodsFor: 'accessing' stamp: 'hlsf 4/10/2022 15:56:20'!
fullScreen
self
morphPosition: 0@0;
morphExtent: RealEstateAgent maximumUsableArea extent! !
!DrGeoMiniView methodsFor: 'accessing' stamp: 'hlsf 6/19/2021 11:02:21'!
label
^ 'A Dr. Geo sketch' translated! !
!DrGeoMiniView methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 13:05:34'!
presenter
^ presenter! !
!DrGeoMiniView methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 13:05:26'!
presenter: anObject
presenter := anObject! !
!DrGeoMiniView methodsFor: 'accessing' stamp: 'hlsf 6/5/2021 11:19:44'!
setLabel: aString
"There is not such things as a label for a minimal view"! !
!DrGeoMiniView methodsFor: 'menus' stamp: 'hlsf 10/21/2021 21:23:37'!
macroMenu: aMenuMorph
self flag: #drgeoTodo! !
!DrGeoMiniView methodsFor: 'menus' stamp: 'hlsf 10/21/2021 21:23:12'!
scriptMenu: aMenu
self flag: #drgeoTodo! !
!DrGeoMiniView methodsFor: 'initialize-release' stamp: 'hlsf 4/10/2022 17:18:04'!
defaultColor
^ `(Color r: 0.986 g: 0.986 b: 0.986)`! !
!DrGeoMiniView methodsFor: 'initialize-release'!
deleteWithoutConfirmation
self delete! !
!DrGeoMiniView methodsFor: 'initialize-release' stamp: 'hlsf 8/4/2023 17:43:30'!
initialize
super initialize.
self color: Color white.
drawable := DrGDrawable newOn: presenter .
self morphExtent: 750@500! !
!DrGeoMiniView methodsFor: 'initialize-release' stamp: 'hlsf 6/19/2021 10:01:18'!
installTools
self beColumn
addMorphUseAll: drawable! !
!DrGeoMiniView methodsFor: 'initialize-release' stamp: 'hlsf 8/4/2023 17:43:36'!
release
presenter := drawable := nil.! !
!DrGeoMiniView methodsFor: 'geometry testing' stamp: 'hlsf 6/5/2021 12:16:21'!
clipsSubmorphs
^ false! !
!DrGeoMiniView class methodsFor: 'instance creation' stamp: 'hlsf 8/4/2023 13:05:08'!
for: aPresenter
^ self basicNew ::
presenter: aPresenter ;
initialize;
beColumn;
yourself! !
!DrGeoMiniView class methodsFor: 'new-morph participation' stamp: 'hlsf 3/15/2022 21:34:31'!
includeInNewMorphMenu
^ false! !
!DrGLabel methodsFor: 'editing' stamp: 'hlsf 4/11/2021 11:49:05'!
acceptContents
itemMorph mathItem name: contents asString.! !
!DrGLabel methodsFor: 'event handling' stamp: 'hlsf 4/11/2021 11:56:51'!
handlesMouseDown: evt
^true! !
!DrGLabel methodsFor: 'event handling' stamp: 'hlsf 5/29/2021 17:19:46'!
mouseMove: evt localPosition: deltaVector
itemMorph ifNotNil:
["Inform the item about the new position we want in the drawable"
itemMorph constrainedLabelPosition: self morphPosition + deltaVector.
self morphPosition: itemMorph labelPosition].
! !
!DrGLabel methodsFor: 'initialization' stamp: 'hlsf 4/11/2021 11:56:54'!
initialize
super initialize.
blink _ false.
self font: DrGeoSystem canvasFont
! !
!DrGLabel methodsFor: 'accessing' stamp: 'hlsf 4/11/2021 11:56:58'!
morph: aDrGMorph
itemMorph _ aDrGMorph! !
!DrGLabel methodsFor: 'stepping and presenter' stamp: 'hlsf 4/11/2021 11:57:02'!
startBlinking
blink _ true.
self startStepping ! !
!DrGLabel methodsFor: 'stepping and presenter' stamp: 'hlsf 6/3/2022 11:37:32'!
step
blink ifFalse: [^self].
super step.
self color = DrGTypeColor blinkingColor
ifTrue: [self color: itemMorph style color]
ifFalse: [self color: DrGTypeColor blinkingColor]! !
!DrGLabel methodsFor: 'stepping and presenter' stamp: 'hlsf 4/11/2021 11:57:18'!
stopBlinking
blink _ false.
self stopStepping.! !
!DrGLabel methodsFor: 'stepping and presenter' stamp: 'hlsf 4/11/2021 11:57:23'!
stopStepping
super stopStepping.
self color: itemMorph style color.! !
!DrGLabel methodsFor: 'testing' stamp: 'hlsf 4/11/2021 11:57:27'!
stepTime
^500! !
!DrGLabel class methodsFor: 'new-morph participation' stamp: 'hlsf 3/15/2022 21:33:53'!
includeInNewMorphMenu
^ false! !
!DrGDebuggerWindow methodsFor: 'GUI building' stamp: 'hlsf 10/13/2022 15:09:14'!
buildLowerPanes
^ LayoutMorph newColumn ::
addMorph: self customButtonRow fixedHeight: self defaultButtonPaneHeight;
addMorph: self buildMorphicCodePane proportionalHeight: 1.0;
yourself! !
!DrGDebuggerWindow methodsFor: 'GUI building' stamp: 'hlsf 10/13/2022 19:58:26'!
buildMorphicWindow
"Open a full morphic debugger with the given label"
| bottomMorph |
self receiverInspector doubleClickSelector: #inspectSelection.
self contextVariableInspector doubleClickSelector: #inspectSelection.
"Instantiate, but not used on the GUI"
self receiverInspectorText.
bottomMorph _ LayoutMorph newRow.
bottomMorph
addAdjusterAndMorph: self contextVariableInspector proportionalWidth: 0.30;
addAdjusterAndMorph: self contextVariableInspectorText proportionalWidth: 0.70.
self layoutMorph
addAdjusterAndMorph: self buildLowerPanes proportionalHeight: 0.7;
addAdjusterAndMorph: bottomMorph proportionalHeight: 0.3.! !
!DrGDebuggerWindow methodsFor: 'GUI building' stamp: 'hlsf 10/13/2022 12:08:52'!
customButtonSpecs
"Answer an array of elements of the form wording, selector, help-message, that characterize the custom button row of a debugger."
^{
{'Restart' translated . # restart . 'Restart the step by step execution from its start.' translated } .
{'Step' translated . # doStep . 'Execute the current message and go to the next message.' translated } .
{'Step into' translated . #stepIntoBlock . 'Step into a block.' translated } .
{'Run to Cursor' translated . # runToCursor . 'Execute the code up to the cursor position.' translated }
}! !
!DrGDebuggerWindow methodsFor: 'GUI building' stamp: 'hlsf 10/13/2022 15:20:08'!
initialExtent
^ 600 @ 400! !
!DrGDebuggerWindow methodsFor: 'accessing' stamp: 'hlsf 10/13/2022 15:37:01'!
layerNumber
^ 50! !
!DrGDebuggerWindow class methodsFor: 'instance creation' stamp: 'hlsf 10/19/2022 21:20:35'!
open: model
^ self new ::
model: model;
buildMorphicWindow;
yourself
! !
!DrGeoView methodsFor: 'initialization' stamp: 'hlsf 8/4/2023 12:40:38'!
initialize
super initialize.
self model: self domain.
self setLabel: 'Dr. Geo -- ' , Date today yyyymmdd.
drawable := DrGDrawable newOn: presenter! !
!DrGeoView methodsFor: 'initialization' stamp: 'hlsf 8/4/2023 17:06:40'!
release
presenter ifNotNil: [presenter removeActionsWithReceiver: self].
drawable release.
drawable := nil.
presenter := nil! !
!DrGeoView methodsFor: 'stepping' stamp: 'hlsf 6/5/2021 11:00:04'!
step
DrGeoSystem ifTablet: [
"track device rotation"
self fullScreen].! !
!DrGeoView methodsFor: 'stepping'!
stepTime
^ 1000
! !
!DrGeoView methodsFor: 'stepping'!
wantsSteps
^ DrGeoSystem isTablet! !
!DrGeoView methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 12:40:16'!
domain
^ presenter domain ! !
!DrGeoView methodsFor: 'accessing' stamp: 'hlsf 6/19/2021 10:07:28'!
drawable
^ drawable! !
!DrGeoView methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 17:05:12'!
presenter
^ presenter! !
!DrGeoView methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 17:08:28'!
presenter: aPresenter
presenter := aPresenter ! !
!DrGeoView methodsFor: 'open/close' stamp: 'hlsf 8/4/2023 17:04:50'!
delete
super delete.
presenter ifNotNil: [presenter release]! !
!DrGeoView methodsFor: 'open/close' stamp: 'hlsf 8/4/2023 12:40:10'!
deleteWithoutConfirmation
super delete.
presenter ifNotNil: [presenter release]! !
!DrGeoView methodsFor: 'label' stamp: 'hlsf 3/28/2022 11:45:46'!
relabel
" Not authorized. Label is changed accordingly to the sketch name "! !
!DrGeoView class methodsFor: 'initialize-release' stamp: 'hlsf 8/4/2023 17:08:00'!
for: aPresenter
"A new model with an existing domain. For multiple MVP on a same
Domain "
^ super basicNew presenter: aPresenter ;
initialize! !
!DrGWizardMacroBuild methodsFor: 'pages' stamp: 'hlsf 12/27/2021 10:00:29'!
firstPage
^ (WizardPage firstPage: 'Build a macro-construction' translated on: self) contents:
'To build a macro-construction,
1. First select the input paramaters,
2. Next select the output parameters,
3. Next chose a name and a description,
4. Last apply the selection.' translated
! !
!DrGWizardMacroBuild methodsFor: 'pages' stamp: 'hlsf 8/3/2023 00:14:46'!
fourthPage
| pane row titleLabel descriptionLabel tMorph descrMorph labelsWidth |
pane := self emptyPane.
row := LayoutMorph newRow separation: 4.
titleLabel := LabelMorph contents: 'Title:' translated.
descriptionLabel := LabelMorph contents: 'Description:' translated.
labelsWidth := titleLabel morphWidth max: descriptionLabel morphWidth.
row addMorph: titleLabel fixedWidth: labelsWidth.
tMorph := TextModelMorph textProvider: model textGetter: #title textSetter: #title: ::
hideScrollBarsIndefinitely;
askBeforeDiscardingEdits: false.
tMorph scroller
setProperty: #keyStroke:
toValue: [:event |
tMorph scroller acceptContents.
self changed: #isReadyToApply].
row addMorphUseAll: tMorph.
pane addMorph: row fixedHeight: titleLabel morphHeight.
row := LayoutMorph newRow separation: 4.
row addMorph: descriptionLabel fixedWidth: labelsWidth .
descrMorph := TextModelMorph textProvider: model textGetter: #description textSetter: #description: ::
askBeforeDiscardingEdits: false.
descrMorph scroller
setProperty: #keyStroke:
toValue: [:event |
descrMorph scroller acceptContents.
self changed: #isReadyToApply].
row addMorphUseAll: descrMorph.
pane addMorphUseAll: row.
^(WizardPage applyPage: 'Give a name and a description' translated on: self)
contents: pane;
yourself! !
!DrGWizardMacroBuild methodsFor: 'pages' stamp: 'hlsf 12/27/2021 10:00:29'!
secondPage
| list pane |
list _ PluggableListMorph
model: model
listGetter: #inputNames
indexGetter: nil
indexSetter: nil.
pane _ self emptyPane
addMorphUseAll: list;
yourself.
^ (WizardPage standardPage: 'Select input parameters' translated on: self)
contents: pane;
yourself
! !
!DrGWizardMacroBuild methodsFor: 'pages' stamp: 'hlsf 12/27/2021 10:00:29'!
thirdPage
| list pane |
list _ PluggableListMorph
model: model
listGetter: #outputNames
indexGetter: nil
indexSetter: nil.
pane _ self emptyPane
addMorphUseAll: list;
yourself.
^ (WizardPage standardPage: 'Select output parameters' translated on: self)
contents: pane;
yourself
! !
!DrGWizardMacroBuild methodsFor: 'testing' stamp: 'hlsf 11/4/2021 19:30:31'!
isInputPage
^ currentPageIndex = 2! !
!DrGWizardMacroBuild methodsFor: 'testing' stamp: 'hlsf 11/4/2021 19:30:13'!
isOutputPage
^ currentPageIndex = 3! !
!DrGWizardMacroBuild methodsFor: 'testing' stamp: 'hlsf 11/19/2021 10:44:38'!
isReadyToApply
"Can we apply the macro-construction to the selected geometric items?"
^ model isMacroValid ! !
!DrGWizardMacroBuild methodsFor: 'initialize-release' stamp: 'hlsf 12/27/2021 11:03:49'!
addPages
self addPage: self firstPage;
addPage: self secondPage ;
addPage: self thirdPage ;
addPage: self fourthPage ! !
!DrGWizardMacroPlay methodsFor: 'initialize-release' stamp: 'hlsf 12/27/2021 11:03:07'!
addPages
^ self
addPage: self firstPage;
addPage: self secondPage! !
!DrGWizardMacroPlay methodsFor: 'initialize-release' stamp: 'hlsf 12/27/2021 11:03:24'!
initialize
super initialize.
macroFactories _ DrGMacroFactory new! !
!DrGWizardMacroPlay methodsFor: 'pages' stamp: 'hlsf 12/27/2021 10:00:29'!
firstPage
^ (WizardPage firstPage: 'Execute a macro-construction' translated on: self) contents:
'To execute a macro-construction,
1. First select a macro-construction from the list,
2. Select items on the figure. Only items relevant
to the selected macro-construction are selectable.
Once enough items are selected, the macro is
automaticly executed.
To start press the ''next'' button.' translated! !
!DrGWizardMacroPlay methodsFor: 'pages' stamp: 'hlsf 12/27/2021 10:00:29'!
secondPage
| pane morph |
morph _ PluggableListMorph
model: self
listGetter: #macroList
indexGetter: #selectedMacro
indexSetter: #selectedMacro:.
pane _ self emptyPane
addMorphKeepMorphHeight: (LabelMorph contents: 'Title:' translated);
addMorph: morph proportionalHeight: 0.3;
addMorphKeepMorphHeight: (LabelMorph contents: 'Description:' translated);
yourself.
morph _ TextModelMorph textProvider: model textGetter: #description textSetter: #description:.
morph hideScrollBarsIndefinitely; askBeforeDiscardingEdits: false.
pane addMorphUseAll: morph.
^ (WizardPage applyPage: 'Select a macro-construction then the figure items' translated on: self)
contents: pane;
yourself
! !
!DrGWizardMacroPlay methodsFor: 'accessing' stamp: 'hlsf 11/18/2021 21:31:41'!
macroList
^ macroFactories titles! !
!DrGWizardMacroPlay methodsFor: 'accessing' stamp: 'hlsf 11/18/2021 21:32:00'!
selectedMacro
^ macroFactories indexOf: model selectedMacro! !
!DrGWizardMacroPlay methodsFor: 'accessing' stamp: 'hlsf 11/18/2021 21:32:37'!
selectedMacro: anIndex
model selectedMacro: (macroFactories at: anIndex).
self changed: #selectedMacro.
model changed: #description.! !
!DrGWizardMacroPlay methodsFor: 'testing' stamp: 'hlsf 11/19/2021 10:50:20'!
isReadyToApply
"It is not relevant, apply button disabled"
^ false! !
!DrGWizardMacroPlay methodsFor: 'testing' stamp: 'hlsf 11/18/2021 21:31:31'!
isSelectPage
^ currentPageIndex = 2! !
!DrGWizardScript methodsFor: 'accessing' stamp: 'hlsf 4/7/2022 15:17:16'!
argumentsName
| labels |
^ model scriptClass
ifNil: [ #() ]
ifNotNil: [
labels _ DrGScriptDesignerDialog classesAndLabels.
model scriptClass argumentsType collect: [ :type | labels at: type ]
]! !
!DrGWizardScript methodsFor: 'accessing' stamp: 'hlsf 4/7/2022 15:40:01'!
scripts
^ scripts ifNil: [ scripts _ DrGWizardScript sortedScripts ]! !
!DrGWizardScript methodsFor: 'accessing' stamp: 'hlsf 4/6/2022 16:55:26'!
scriptsName
^ self scripts collect: [:class | class scriptName]! !
!DrGWizardScript methodsFor: 'accessing' stamp: 'hlsf 4/7/2022 15:18:28'!
selectedScript
^ model scriptClass
ifNil: [0]
ifNotNil: [self scripts indexOf: model scriptClass]! !
!DrGWizardScript methodsFor: 'accessing' stamp: 'hlsf 4/7/2022 15:19:44'!
selectedScript: anIndex
model scriptClass: (self scripts at: anIndex ifAbsent: [nil]).
self changed: #selectedScript.
self changed: #argumentsName.
model changed: #description! !
!DrGWizardScript methodsFor: 'pages' stamp: 'hlsf 4/7/2022 15:28:50'!
addPages
self addPage: self firstPage ;
addPage: self secondPage ! !
!DrGWizardScript methodsFor: 'pages' stamp: 'hlsf 4/7/2022 15:29:09'!
firstPage
^ (WizardPage firstPage: 'Use a script in the sketch' translated on: self) contents:
'To use a script,
1. First select a script from the list,
2. Select items in the sketch,
3. Click somewhere in the background.
Once enough items are selected, the script is
inserted in the sketch, at the user selected position.
To start press the ''next'' button.' translated! !
!DrGWizardScript methodsFor: 'pages' stamp: 'hlsf 4/7/2022 15:42:08'!
secondPage
| list argumentList page textMorph |
list _ PluggableListMorph
model: self listGetter: #scriptsName indexGetter: #selectedScript indexSetter: #selectedScript:.
argumentList _ PluggableListMorph
model: self listGetter: #argumentsName indexGetter: nil indexSetter: nil ::
setBalloonText: 'The arguments accepted by this script.' translated;
yourself.
textMorph _ TextModelMorph textProvider: model textGetter: #description textSetter: #description: ::
askBeforeDiscardingEdits: false;
yourself.
page _ LabelGroup with: {
'Script name' translated -> list.
'Description' translated -> textMorph.
'Arguments' translated -> argumentList}.
^ WizardPage applyPage: 'Select a script then items in the sketch' translated on: self ::
contents: page! !
!DrGWizardScript methodsFor: 'open/close' stamp: 'hlsf 4/7/2022 12:34:54'!
delete
super delete.
model _ nil! !
!DrGWizardScript methodsFor: 'navigation' stamp: 'hlsf 4/7/2022 15:54:58'!
goPage: integer
super goPage: integer.
self changed: #scriptsName! !
!DrGWizardScript class methodsFor: 'as yet unclassified' stamp: 'hlsf 4/7/2022 15:39:42'!
sortedScripts
" Return a list of the user script sorted by their scriptName "
^ DrGeoUserScript subclasses
sorted: [:script1 :script2 | script1 scriptName asLowercase < script2 scriptName asLowercase]! !
!DrGFileOpenMorph methodsFor: 'GUI building' stamp: 'hlsf 5/2/2023 20:51:08'!
buildPane
| sketches row |
DrGeoSystem startSpinner.
panel
ifNil: [panel := LayoutMorph newColumn]
ifNotNil: [ panel removeAllMorphs; morphExtent: panel minimumExtent ].
previews do: [:each | each breakDependents].
previews := OrderedCollection new.
sketches := ( model filesMatches: [:file | '*.fgeo' match: file name])
sort: [:f1 :f2 | f1 name asLowercase < f2 name asLowercase ].
sketches groupsOf: 3 atATimeDo: [:sketchesBy3 |
row := LayoutMorph newRow separation: 8; adoptWidgetsColor: self widgetsColor.
panel addMorph: row.
sketchesBy3 do: [:sketch |
row addMorph: (self previewMorphFor: sketch) ]] .
sketches size \\ 3 ifNotZero: ["there are some left over"
row := LayoutMorph newRow separation: 8; adoptWidgetsColor: self widgetsColor.
panel addMorph: row.
(sketches allButFirst: ( sketches size // 3 * 3)) do: [:sketch|
row addMorph: (self previewMorphFor: sketch )] ].
DrGeoSystem stopSpinner.
^ panel! !
!DrGFileOpenMorph methodsFor: 'GUI building' stamp: 'hlsf 11/23/2023 17:50:41'!
computePreviewFor: aSketchFile
| stream drgeo form |
stream := aSketchFile readStream.
[[drgeo := (DrGeoXml new loadOnlyFigureFrom: stream for: #service) first]
on: Error do: []]
ensure: [stream close].
drgeo
ifNil: [form := Form extent: 1@1]
ifNotNil: [drgeo previewOnFile: ((aSketchFile pathName allButLast: 4), 'png') asFileEntry ].
^ form! !
!DrGFileOpenMorph methodsFor: 'GUI building' stamp: 'hlsf 4/11/2022 21:24:20'!
newButtonArea
| rowLeft rowRight |
buttonArea _ LayoutMorph newRow ::
separation: 8@0;
yourself.
rowLeft _ LayoutMorph newRow.
rowLeft
axisEdgeWeight: #rowLeft;
addMorph: (PluggableButtonMorph
model: self
stateGetter: #isExamples
action: #switchToExamples
label: 'Examples' translated);
addMorph: (PluggableButtonMorph
model: self
stateGetter: #isMySketches
action: #switchToMySketches
label: 'My Sketches' translated).
rowRight _ LayoutMorph newRow.
rowRight
axisEdgeWeight: #rowRight;
addMorph: (PluggableButtonMorph
model: self
action: #ok
label: 'Open' translated).
rowRight
addMorph: (PluggableButtonMorph
model: self
action: #delete
label: 'Cancel' translated).
rowRight
addMorph: ((PluggableButtonMorph
model: self
action: #deleteSketch) icon: Theme current deleteIcon).
buttonArea
addMorph: rowLeft;
addMorph: rowRight.
^ buttonArea! !
!DrGFileOpenMorph methodsFor: 'GUI building' stamp: 'hlsf 12/25/2021 16:48:00'!
newPane
^ PluggableScrollPane new scroller: self buildPane;
scrollDeltaHeight: 80;
yourself! !
!DrGFileOpenMorph methodsFor: 'GUI building' stamp: 'hlsf 5/1/2023 17:14:43'!
previewFor: aSketchEntry
| imageFilename form |
imageFilename := ((aSketchEntry pathName allButLast: 4), 'png') asFileEntry.
imageFilename exists
ifTrue: [ form := Form fromFileEntry: imageFilename]
ifFalse: [form := self computePreviewFor: aSketchEntry ].
^ form magnifyBy: DrGeoSystem previewSize x / form width! !
!DrGFileOpenMorph methodsFor: 'GUI building' stamp: 'hlsf 5/4/2023 15:40:22'!
previewMorphFor: sketchEntry
| preview |
preview := FilePreviewMorph
file: sketchEntry
image: (self previewFor: sketchEntry )
buttons: nil ::
when: #selected send: #update: to: self;
when: #doubleClick send: #open: to: self.
previews add: preview.
preview layoutSpec offAxisEdgeWeight: #center.
^ preview
! !
!DrGFileOpenMorph methodsFor: 'accessing' stamp: 'hlsf 5/1/2023 17:13:25'!
selectedFile
^ self selectedPreview ifNotNil: [:aPreview | aPreview fileEntry]! !
!DrGFileOpenMorph methodsFor: 'accessing' stamp: 'hlsf 10/25/2021 10:01:23'!
selectedPreview
"Detect the selected preview morph, if any"
^ previews detect: [:preview | preview isSelected] ifFound: [:preview | preview] ifNone: [nil]! !
!DrGFileOpenMorph methodsFor: 'actions' stamp: 'hlsf 10/25/2021 10:04:45'!
deleteSketch
"Delete the selected sketch"
self canDelete ifTrue: [ | file |
file _ self selectedFile.
file delete.
((file pathName allButLast: 4), 'png') asFileEntry delete.
self selectedPreview delete ]
! !
!DrGFileOpenMorph methodsFor: 'actions' stamp: 'hlsf 8/8/2023 19:13:55'!
ok
"Open the selected sketch"
self selectedFile ifNotNil: [:selectedFile |
self delete.
DrGeo file: selectedFile]! !
!DrGFileOpenMorph methodsFor: 'actions' stamp: 'hlsf 8/8/2023 19:13:55'!
open: previewMorph
"Open the selected sketch"
self delete.
DrGeo file: previewMorph fileEntry! !
!DrGFileOpenMorph methodsFor: 'actions' stamp: 'hlsf 10/17/2021 12:29:46'!
switchToExamples
model _ DrGeoSystem examplesPath.
self updateButtonsAndPreviews ! !
!DrGFileOpenMorph methodsFor: 'actions' stamp: 'hlsf 10/17/2021 12:30:00'!
switchToMySketches
model _ DrGeoSystem mySketchesPath.
self updateButtonsAndPreviews ! !
!DrGFileOpenMorph methodsFor: 'states' stamp: 'hlsf 10/25/2021 09:46:28'!
canDelete
^ self isMySketches and: [self selectedFile notNil ]! !
!DrGFileOpenMorph methodsFor: 'states' stamp: 'hlsf 10/14/2021 21:13:20'!
isExamples
^ model asString includesSubString: 'examples'! !
!DrGFileOpenMorph methodsFor: 'states' stamp: 'hlsf 10/14/2021 21:13:57'!
isMySketches
^ model asString includesSubString: 'MySketches'! !
!DrGFileOpenMorph methodsFor: 'update' stamp: 'hlsf 10/25/2021 09:50:49'!
update: aPreview
"aPreview is now the user selected preview, update all the previews accordingly"
previews do: [:each | each selected: each == aPreview].
self redrawNeeded ! !
!DrGFileOpenMorph methodsFor: 'update' stamp: 'hlsf 12/25/2021 16:48:00'!
updateButtonsAndPreviews
self changed: #isExamples.
self changed: #isMySketches.
self buildPane! !
!DrGFileOpenMorph methodsFor: 'initialization' stamp: 'hlsf 10/29/2021 12:12:00'!
initialize
super initialize.
previews _ #()! !
!DrGFileOpenMorph methodsFor: 'geometry' stamp: 'hlsf 11/7/2023 14:21:35'!
minimumExtent
^ 1000@500! !
!DrGFileOpenMorph class methodsFor: 'instance creation' stamp: 'hlsf 10/14/2021 21:04:26'!
open
^ self open: DrGeoSystem examplesPath label: 'Open a sketch' translated! !
!DrGScriptDesignerDialog methodsFor: 'accessing' stamp: 'hlsf 4/4/2022 21:52:06'!
arguments
"The arguments as selected by the user"
|alignments|
alignments _ argumentsMorph submorphs select: [ :morph | morph class = LayoutMorph].
^ alignments reverse collect: [ :each | each submorphs first selectedItem].
! !
!DrGScriptDesignerDialog methodsFor: 'accessing' stamp: 'hlsf 4/5/2022 21:45:00'!
argumentsClass
"The arguments type as selected by the user, tpye=class from the MathItem hierarchy"
|dict|
dict _ self class labelsAndClasses .
^ self arguments collect: [:aLabel | dict at: aLabel]! !
!DrGScriptDesignerDialog methodsFor: 'accessing' stamp: 'hlsf 4/6/2022 14:52:28'!
description
^ description asString! !
!DrGScriptDesignerDialog methodsFor: 'accessing' stamp: 'hlsf 4/2/2022 09:10:06'!
description: aString
description _ aString ! !
!DrGScriptDesignerDialog methodsFor: 'accessing' stamp: 'hlsf 4/6/2022 14:52:35'!
scriptName
^ scriptName asString! !
!DrGScriptDesignerDialog methodsFor: 'accessing' stamp: 'hlsf 4/2/2022 09:09:41'!
scriptName: aString
scriptName _ aString ! !
!DrGScriptDesignerDialog methodsFor: 'GUI building' stamp: 'hlsf 4/4/2022 12:54:13'!
newAddArgumentButton
^ PluggableButtonMorph model: self action: #addArgument label: 'Add argument' translated ::
setBalloonText: 'Add an argument to this script.' translated;
yourself! !
!DrGScriptDesignerDialog methodsFor: 'GUI building' stamp: 'hlsf 5/27/2023 12:02:16'!
newArgumentMorph
^ LayoutMorph newRow
color: Color transparent ;
addMorph: self newAddArgumentButton;
separation: 4@0;
yourself! !
!DrGScriptDesignerDialog methodsFor: 'GUI building' stamp: 'hlsf 5/27/2023 12:01:53'!
newButtonArea
buttonArea := LayoutMorph newRow
separation: 8@0;
addMorph: (PluggableButtonMorph model: self action: #build label: 'Build' translated ::
enableSelector: #isValid;
setBalloonText: 'Build a script with these settings.' translated;
yourself)
layoutSpec: (LayoutSpec new ::
useMorphWidth ;
proportionalHeight: 1;
offAxisEdgeWeight: #center);
addMorph: (PluggableButtonMorph model: self action: #cancel label: 'Cancel' translated)
layoutSpec: (LayoutSpec new ::
useMorphWidth ;
proportionalHeight: 1;
offAxisEdgeWeight: #center);
axisEdgeWeight: #rowRight;
color: Color transparent.
^ buttonArea ! !
!DrGScriptDesignerDialog methodsFor: 'GUI building' stamp: 'hlsf 4/4/2022 20:10:51'!
newDescriptionMorph
| morph |
morph _ TextModelMorph textProvider: self textGetter: #description textSetter: #description: ::
askBeforeDiscardingEdits: false;
setBalloonText: 'A description of the script. To help the user, describe carefully what the script does and the input arguments to select to use it.' translated;
yourself .
morph scroller setProperty: #keyStroke: toValue: [:event |
morph scroller acceptContents.
self changed: #isValid].
^ morph! !
!DrGScriptDesignerDialog methodsFor: 'GUI building' stamp: 'hlsf 4/7/2022 11:53:31'!
newPane
^ LabelGroup with: {
'Name' translated -> self newScriptNameMorph .
'Description' translated -> self newDescriptionMorph .
'Arguments' translated -> (argumentsMorph _ self newArgumentMorph)
}! !
!DrGScriptDesignerDialog methodsFor: 'GUI building' stamp: 'hlsf 4/4/2022 20:10:48'!
newScriptNameMorph
| morph |
morph _ TextModelMorph textProvider: self textGetter: #scriptName textSetter: #scriptName: ::
hideScrollBarsIndefinitely;
askBeforeDiscardingEdits: false;
acceptOnCR: true;
morphHeight: FontFamily defaultPointSize;
setBalloonText: 'The name of the script.' translated;
yourself .
morph scroller setProperty: #keyStroke: toValue: [:event |
morph scroller acceptContents.
self changed: #isValid].
^ morph! !
!DrGScriptDesignerDialog methodsFor: 'initialization' stamp: 'hlsf 4/5/2022 21:02:25'!
initialize
super initialize.
scriptName _ ''.
description _ ''! !
!DrGScriptDesignerDialog methodsFor: 'action' stamp: 'hlsf 5/27/2023 12:12:17'!
addArgument
| newArgument |
newArgument := LayoutMorph newRow ::
adoptWidgetsColor: widgetsColor;
borderWidth: 1;
yourself.
newArgument addMorph: (PluggableButtonMorph model: self action: #removeArgument: ::
icon: Theme current deleteIcon;
actionArgument: newArgument;
borderWidth: 0;
color: Color transparent;
setBalloonText: 'Remove this script argument.' translated;
yourself);
addMorph: (DropDownListMorph
model: (ListModel with: self class labels)
listGetter: #list
indexGetter: #listIndex
indexSetter: #listIndex: ::
adoptWidgetsColor: widgetsColor ).
argumentsMorph addMorph: newArgument.
self morphExtent: self minimumExtent ! !
!DrGScriptDesignerDialog methodsFor: 'action' stamp: 'hlsf 8/4/2023 17:38:35'!
build
| scriptClass stream |
self delete.
"Build a new script from the user specification"
scriptClass := DrGeoUserScript
subclass: ('DrGeoScript', self scriptName hash printString) asSymbol
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'DrGeo-Model-Script'.
"name"
stream := WriteStream on: String new.
stream nextPutAll: 'scriptName';
newLineTab: 1 ;
nextPut: $^ ;
nextPutAll: self scriptName printString.
scriptClass class compile: stream contents classified: 'public'.
"description"
stream := WriteStream on: String new.
stream nextPutAll: 'description';
newLineTab: 1;
nextPut: $^ ;
nextPutAll: self description printString.
scriptClass class compile: stream contents classified: 'public'.
"argumentsType"
stream := WriteStream on: String new.
stream nextPutAll: 'newArgumentsType';
newLineTab: 1;
nextPut: $^; nextPut: ${.
self argumentsClass
do: [:aClass| stream nextPutAll: aClass printString]
separatedBy: [stream nextPut: $.].
stream nextPut: $}.
scriptClass class compile: stream contents classified: 'private'.
"compute"
stream := WriteStream on: String new.
stream nextPutAll: 'compute';
newLine;
nextPutAll: '"Edit me"';
newLineTab: 1;
nextPut: $^;
nextPutAll: '1+1'.
scriptClass compile: stream contents classified: 'public'.
"Browse the newly created script"
model editScript: scriptClass! !
!DrGScriptDesignerDialog methodsFor: 'action' stamp: 'hlsf 4/4/2022 18:50:59'!
cancel
self delete! !
!DrGScriptDesignerDialog methodsFor: 'action' stamp: 'hlsf 4/4/2022 19:28:41'!
isValid
"respond wheter the given input data is valid to build a script"
scriptName asString withBlanksCondensed isEmpty ifTrue: [ ^ false ].
description asString withBlanksCondensed isEmpty ifTrue: [ ^ false ].
(Smalltalk hasClassNamed: #DrGeoScript, scriptName asString hash printString) ifTrue: [ ^ false ].
^ true! !
!DrGScriptDesignerDialog methodsFor: 'action' stamp: 'hlsf 4/4/2022 21:49:52'!
removeArgument: aRowArgument
argumentsMorph removeMorph: aRowArgument .
self morphExtent: self minimumExtent ! !
!DrGScriptDesignerDialog class methodsFor: 'labels and classes' stamp: 'hlsf 4/2/2022 12:50:48'!
classesAndLabels
| dict |
dict _ Dictionary new.
self labelsAndClasses associationsDo: [ :assoc |
dict add: assoc value -> assoc key ].
^ dict
! !
!DrGScriptDesignerDialog class methodsFor: 'labels and classes' stamp: 'hlsf 4/2/2022 12:49:47'!
indexOfLabel: string
self labels withIndexDo: [:label :i |
label = string ifTrue: [ ^ i ]].
self errorNotFound: string! !
!DrGScriptDesignerDialog class methodsFor: 'labels and classes' stamp: 'hlsf 4/2/2022 12:49:05'!
labels
^ self labelsAndClasses keys sorted! !
!DrGScriptDesignerDialog class methodsFor: 'labels and classes' stamp: 'hlsf 4/7/2022 18:41:41'!
labelsAndClasses
^ Dictionary newFrom: {
'Any type' translated -> DrGMathItem.
'Point' translated -> DrGPointItem.
'Direction' translated -> DrGDirectionItem.
'Line' translated -> DrGLineItem.
'Ray' translated -> DrGRayItem.
'Segment' translated -> DrGSegmentItem.
'Polygon' translated -> DrGPolygonItem.
'Vector' translated -> DrGVectorItem.
'Circle' translated -> DrGCircleItem.
'Arc' translated -> DrGArcItem.
'Locus' translated -> DrGLocus2ptsItem.
'Value' translated -> DrGValueItem.
'Angle' translated -> DrGAngleItem}! !
!DrGSmalltalkSketchBrowser methodsFor: 'accessing' stamp: 'hlsf 5/25/2023 17:55:31'!
compiledSketch: aSketch
| oldView |
self releaseMiniView.
oldView := drgeoView.
drgeoView := aSketch view.
pane replaceSubmorph: oldView by: drgeoView.
self runningWorld doOneCycleNow.! !
!DrGSmalltalkSketchBrowser methodsFor: 'accessing' stamp: 'hlsf 4/11/2022 21:52:55'!
deleteSketch
self canDelete ifTrue: [
selectedFile delete.
self sketch: 0]! !
!DrGSmalltalkSketchBrowser methodsFor: 'accessing' stamp: 'hlsf 4/16/2022 11:43:15'!
edit
" Inform any interested party the user wants to edit the selected sketch "
self triggerEvent: #editSmalltalkSketch with: selectedFile.
self delete.! !
!DrGSmalltalkSketchBrowser methodsFor: 'accessing' stamp: 'hlsf 4/9/2022 11:05:19'!
model: aDirectoryEntry
model _ aDirectoryEntry .
sketches _ nil! !
!DrGSmalltalkSketchBrowser methodsFor: 'accessing' stamp: 'hlsf 4/12/2022 21:24:54'!
showCode: aCheckButtonMorph
| drgeoFraction |
aCheckButtonMorph isSelected
ifTrue: [
drgeoFraction _ 0.7.
pane addMorph: codeView proportionalHeight: 1 - drgeoFraction.
codeView adoptWidgetsColor: self widgetsColor ]
ifFalse: [
drgeoFraction _ 1.
pane removeMorph: codeView].
drgeoView layoutSpec: (LayoutSpec proportionalHeight: drgeoFraction)! !
!DrGSmalltalkSketchBrowser methodsFor: 'accessing' stamp: 'hlsf 4/11/2022 21:47:52'!
sketch
^ selectedFile
ifNil: [0]
ifNotNil: [ sketches indexOf: selectedFile baseName]! !
!DrGSmalltalkSketchBrowser methodsFor: 'accessing' stamp: 'hlsf 5/25/2023 15:34:46'!
sketch: anIndex
anIndex = 0
ifTrue: [ | oldView |
self releaseMiniView.
oldView := drgeoView.
drgeoView := self emptyView .
pane replaceSubmorph: oldView by: drgeoView.
selectedFile := nil.
self changed: #sourceCode]
ifFalse: [
selectedFile := model // ( (sketches at: anIndex) , '.st' ).
self changed: #sourceCode.
DrGeoSketch when: #newSmalltalkSketch send: #compiledSketch: to: self.
selectedFile readStream fileIn .
DrGeoSketch removeActionsWithReceiver: self ]! !
!DrGSmalltalkSketchBrowser methodsFor: 'accessing' stamp: 'hlsf 9/28/2022 16:32:35'!
sketches
" The skteches files in the current path"
^ sketches ifNil: [sketches _ (model files
select: [:aFile | aFile extension = 'st']
thenCollect: [:aFile | aFile baseName ]) sorted ]
! !
!DrGSmalltalkSketchBrowser methodsFor: 'accessing' stamp: 'hlsf 2/22/2023 11:28:15'!
sourceCode
^ selectedFile
ifNotNil: [ selectedFile fileContents]
ifNil: ['']! !
!DrGSmalltalkSketchBrowser methodsFor: 'accessing' stamp: 'hlsf 4/11/2022 21:54:35'!
switchToExamples
model _ DrGeoSystem smalltalkSketchesPath.
self updateButtonsAndPreviews! !
!DrGSmalltalkSketchBrowser methodsFor: 'accessing' stamp: 'hlsf 4/11/2022 21:55:43'!
switchToMySketches
model _ DrGeoSystem mySmalltalkSketchesPath.
self updateButtonsAndPreviews! !
!DrGSmalltalkSketchBrowser methodsFor: 'GUI building' stamp: 'hlsf 4/14/2022 15:16:01'!
buildMorphicWindow
super buildMorphicWindow.
titleMorph showButtonsNamed: #(close expand).! !
!DrGSmalltalkSketchBrowser methodsFor: 'GUI building' stamp: 'hlsf 7/9/2022 12:04:06'!
newButtonArea
| rowLeft rowRight |
buttonArea _ LayoutMorph newRow ::
separation: 8@0;
yourself.
rowLeft _ LayoutMorph newRow.
rowLeft
axisEdgeWeight: #rowLeft;
addMorph: (PluggableButtonMorph
model: self
stateGetter: #isExamples
action: #switchToExamples
label: 'Examples' translated);
addMorph: (PluggableButtonMorph
model: self
stateGetter: #isMySketches
action: #switchToMySketches
label: 'My Sketches' translated).
rowRight _ LayoutMorph newRow.
rowRight
axisEdgeWeight: #rowRight;
addMorph: ((PluggableButtonMorph
model: self
action: #edit
label: 'Edit' translated) enableSelector: #canEdit; yourself).
rowRight
addMorph: (PluggableButtonMorph
model: self
action: #delete
label: 'Cancel' translated).
rowRight
addMorph: ((PluggableButtonMorph
model: self
action: #deleteSketch
label: 'Delete' translated)
setBalloonText: 'Delete permanently this Smalltalk Sketch from disk.' translated;
enableSelector: #canDelete;
yourself).
buttonArea
addMorph: rowLeft;
addMorph: rowRight.
^ buttonArea! !
!DrGSmalltalkSketchBrowser methodsFor: 'GUI building' stamp: 'hlsf 4/12/2022 23:31:48'!
newDrGeoColumn
" the DrGeo view and an optional code view"
^ pane _ LayoutMorph newColumn ::
addMorph: drgeoView proportionalHeight: 1;
addAdjusterMorph ;
yourself! !
!DrGSmalltalkSketchBrowser methodsFor: 'GUI building' stamp: 'hlsf 4/12/2022 19:34:44'!
newPane
^ LayoutMorph newRow ::
separation: self defaultSeparation ;
addMorph: self newSketchesColumn layoutSpec: (LayoutSpec new useMorphWidth );
addMorphUseAll: self newDrGeoColumn;
yourself! !
!DrGSmalltalkSketchBrowser methodsFor: 'GUI building' stamp: 'hlsf 4/12/2022 19:27:49'!
newSketchesColumn
" The list of the sketch and an option to view the code"
| checkGtoup |
checkGtoup _ CheckGroup fromList: {'Code' translated}.
checkGtoup buttons first when: #checkSelection send: #showCode: to: self.
^ LayoutMorph newColumn ::
addMorph: sketchesListMorph layoutSpec: (LayoutSpec new useMorphWidth);
addMorphKeepMorphHeight: checkGtoup ;
yourself
! !
!DrGSmalltalkSketchBrowser methodsFor: 'initialization' stamp: 'hlsf 4/12/2022 18:56:10'!
emptyView
^ BoxedMorph new ::
color: self color;
borderWidth: 1;
layoutSpec: LayoutSpec useAll! !
!DrGSmalltalkSketchBrowser methodsFor: 'initialization' stamp: 'hlsf 2/22/2023 11:22:05'!
initialize
super initialize.
sketchesListMorph _ PluggableListMorph
model: self listGetter: #sketches indexGetter: #sketch indexSetter: #sketch:.
drgeoView _ self emptyView.
codeView _ TextModelMorph textProvider: self textGetter: #sourceCode ::
disableEditing;
yourself.! !
!DrGSmalltalkSketchBrowser methodsFor: 'geometry' stamp: 'hlsf 11/18/2023 16:33:38'!
minimumExtent
^ 800@600! !
!DrGSmalltalkSketchBrowser methodsFor: 'update' stamp: 'hlsf 7/9/2022 12:07:45'!
updateButtonsAndPreviews
sketches _ nil.
self changed: #isExamples.
self changed: #isMySketches.
self changed: #sketches.
self changed: #sourceCode.
self changed: #canDelete.
self sketch: 0! !
!DrGSmalltalkSketchBrowser methodsFor: 'states' stamp: 'hlsf 4/11/2022 21:56:14'!
canDelete
^ self isMySketches and: [selectedFile notNil ]! !
!DrGSmalltalkSketchBrowser methodsFor: 'states' stamp: 'hlsf 7/9/2022 11:55:01'!
canEdit
" Is there any editor listening to edit a selected Smalltalk Sketch? "
^ self actionMap includesKey: #editSmalltalkSketch! !
!DrGSmalltalkSketchBrowser methodsFor: 'states' stamp: 'hlsf 4/11/2022 21:57:32'!
isExamples
^ self isMySketches not! !
!DrGSmalltalkSketchBrowser methodsFor: 'states' stamp: 'hlsf 4/11/2022 21:57:17'!
isMySketches
^ model asString includesSubString: 'MySmalltalk'! !
!DrGSmalltalkSketchBrowser methodsFor: 'user interface support' stamp: 'hlsf 4/12/2022 23:28:08'!
shouldStyle: aText with: aSHTextStylerST80
^true! !
!DrGSmalltalkSketchBrowser methodsFor: 'user interface support' stamp: 'hlsf 11/23/2023 17:27:51'!
styleByParagraphs
^ false! !
!DrGSmalltalkSketchBrowser methodsFor: 'user interface support' stamp: 'hlsf 4/12/2022 23:25:32'!
textStylerClassFor: object
^ SHTextStylerST80 ! !
!DrGSmalltalkSketchBrowser methodsFor: 'menus' stamp: 'hlsf 4/23/2022 14:19:49'!
expand
super expand.
self fullScreen! !
!DrGSmalltalkSketchBrowser methodsFor: 'testing' stamp: 'hlsf 5/18/2023 17:09:55'!
shouldAutoHighlight
^ false! !
!DrGSmalltalkSketchBrowser methodsFor: 'testing' stamp: 'hlsf 5/18/2023 17:10:10'!
shoutMustKeepContentsSize
^ true! !
!DrGSmalltalkSketchBrowser methodsFor: 'submorphs-add/remove' stamp: 'hlsf 5/25/2023 15:33:56'!
delete
super delete.
self releaseMiniView ! !
!DrGSmalltalkSketchBrowser methodsFor: 'submorphs-add/remove' stamp: 'hlsf 8/4/2023 12:58:33'!
releaseMiniView
(drgeoView respondsTo: #presenter)
ifTrue: [drgeoView presenter ifNotNil: [:pres | pres release] ]! !
!DrGSmalltalkSketchEditor methodsFor: 'GUI building' stamp: 'hlsf 10/30/2022 20:53:10'!
buildMorphicWindow
super buildMorphicWindow.
titleMorph showButtonsNamed: #(close collapse expand).
self toggleHelp ! !
!DrGSmalltalkSketchEditor methodsFor: 'GUI building' stamp: 'hlsf 4/14/2022 16:36:45'!
button: iconSymbol action: actionSelector help: helpString
^ ButtonMorph model: self action: actionSelector ::
icon: (DrGIcons for: iconSymbol );
setBalloonText: helpString ;
color: DrGUIControlsManager buttonColor;
selectedColor: DrGUIControlsManager buttonSelectedColor;
borderColor: DrGUIControlsManager buttonColor muchDarker;
borderWidth: 2;
morphExtent: (DrGeoSystem toolbarIconSize + 4) asPoint;
yourself! !
!DrGSmalltalkSketchEditor methodsFor: 'GUI building' stamp: 'hlsf 10/28/2022 11:13:31'!
button: iconSymbol action: actionSelector state: getStateSel help: helpString
^ ButtonMorph model: self stateGetter: getStateSel action: actionSelector ::
icon: (DrGIcons for: iconSymbol );
setBalloonText: helpString ;
color: DrGUIControlsManager buttonColor;
selectedColor: DrGUIControlsManager buttonSelectedColor;
borderColor: DrGUIControlsManager buttonColor muchDarker;
borderWidth: 2;
morphExtent: (DrGeoSystem toolbarIconSize + 4) asPoint;
yourself! !
!DrGSmalltalkSketchEditor methodsFor: 'GUI building' stamp: 'hlsf 4/14/2022 16:43:31'!
newButtonArea
buttonArea _ LayoutMorph newRow ::
axisEdgeWeight: #rowRight;
addMorph: (PluggableButtonMorph
model: self
action: #delete
label: 'Cancel' translated).
^ buttonArea! !
!DrGSmalltalkSketchEditor methodsFor: 'GUI building' stamp: 'hlsf 11/2/2022 19:39:02'!
newCodeAndView
^ LayoutMorph newRow ::
separation: self defaultSeparation;
addMorph: (codeAndViewPanel _ LayoutMorph newColumn ::
addMorph: codeView proportionalHeight: 0.7;
addAdjusterMorph;
addMorph: docView proportionalHeight: 0.3)
proportionalWidth: 0.5;
addAdjusterMorph ;
addMorph: drgeoView proportionalWidth: 0.5;
yourself! !
!DrGSmalltalkSketchEditor methodsFor: 'GUI building' stamp: 'hlsf 10/19/2022 21:31:20'!
newPane
^ LayoutMorph newColumn ::
separation: self defaultSeparation ;
addMorphKeepMorphHeight: self newToolbar;
addMorphUseAll: self newCodeAndView;
yourself! !
!DrGSmalltalkSketchEditor methodsFor: 'GUI building' stamp: 'hlsf 10/28/2022 11:15:20'!
newToolbar
^ LayoutMorph newRow ::
separation: 5@0 ;
addMorph: (self button: #open action: #browseSketches help: 'Edit a Smalltalk sketch.' translated);
addMorph: (self button: #keep action: #keepSketch help: 'Save this Smalltalk sketch.' translated);
addMorph: (playButton _ self button: #play action: #executeSketch help: 'Play the Smalltalk sketch.' translated);
addMorph: (self button: #debug action: #debugSketch help: 'Debug the Smalltalk sketch.' translated);
addMorph: (self button: #stop action: #stopSketch help: 'Stop the execution of the Smalltalk sketch.' translated);
addMorph: self transparentMorph layoutSpec: (LayoutSpec proportionalWidth: 1.0);
addMorph: (self button: #doc action: #toggleHelp state: #isDocVisible help: 'Dr. Geo tutorial' translated)
yourself! !
!DrGSmalltalkSketchEditor methodsFor: 'GUI building' stamp: 'hlsf 10/6/2022 12:44:50'!
switchToPauseButton
"
Switch to pause sketch action
"
playButton
icon: (DrGIcons for: #pause);
action: #pauseSketch;
setBalloonText: 'Pause the Smalltalk sketch.' translated;
redrawNeeded ! !
!DrGSmalltalkSketchEditor methodsFor: 'GUI building' stamp: 'hlsf 10/6/2022 12:44:47'!
switchToPlayButton
"
Switch to play sketch action
"
playButton
icon: (DrGIcons for: #play);
action: #executeSketch;
setBalloonText: 'Play the Smalltalk sketch.' translated;
redrawNeeded ! !
!DrGSmalltalkSketchEditor methodsFor: 'GUI building' stamp: 'hlsf 10/6/2022 12:44:44'!
switchToResumeButton
"
Switch to resume sketch action
"
playButton
icon: (DrGIcons for: #resume);
action: #resumeSketch;
setBalloonText: 'Resume the Smalltalk sketch.' translated;
redrawNeeded ! !
!DrGSmalltalkSketchEditor methodsFor: 'GUI building' stamp: 'hlsf 10/26/2022 11:11:40'!
transparentMorph
^ BoxedMorph new
borderWidth: 0;
color: Color transparent;
yourself! !
!DrGSmalltalkSketchEditor methodsFor: 'initialization' stamp: 'hlsf 2/22/2023 11:29:52'!
initialize
| book |
super initialize.
book _ EruditeBookReaderMorph new.
docView _ book
model: DrGeoTutorial new;
buildMorphicWindow;
layoutMorph.
book when: #askToCopyCode send: #sourceCode: to: self.
codeView _ TextModelMorph textProvider: self textGetter: #sourceCode textSetter: #sourceCode: ::
askBeforeDiscardingEdits: false;
yourself.
drgeoView _ LayoutMorph new ::
color: self color;
borderWidth: 1;
layoutSpec: LayoutSpec useAll! !
!DrGSmalltalkSketchEditor methodsFor: 'accessing' stamp: 'hlsf 10/30/2022 20:39:21'!
isDocVisible
^ docView visible! !
!DrGSmalltalkSketchEditor methodsFor: 'accessing' stamp: 'hlsf 4/14/2022 16:35:00'!
model: sourceCode
"Set an initial source code (string)"
model _ sourceCode
! !
!DrGSmalltalkSketchEditor methodsFor: 'accessing' stamp: 'hlsf 10/30/2022 20:45:35'!
separator
"The adjuster/separator between the codeView and docView"
^ codeView owner submorphs second
! !
!DrGSmalltalkSketchEditor methodsFor: 'accessing' stamp: 'hlsf 4/15/2022 21:09:07'!
sketchName
^ file ifNil: [''] ifNotNil: [file baseName]! !
!DrGSmalltalkSketchEditor methodsFor: 'accessing' stamp: 'hlsf 4/14/2022 16:36:21'!
sourceCode
^ model
ifNotNil: [model]
ifNil: ['']! !
!DrGSmalltalkSketchEditor methodsFor: 'accessing' stamp: 'hlsf 5/25/2023 15:31:43'!
sourceCode: aText
self model: aText asString.
self changed: #clearUserEdits.
self changed: #acceptedContents.
self releaseMiniView.
drgeoView removeAllMorphs
! !
!DrGSmalltalkSketchEditor methodsFor: 'user interface support' stamp: 'hlsf 4/15/2022 15:12:50'!
autoCompleterClassFor: textGetter
^SmalltalkCompleter! !
!DrGSmalltalkSketchEditor methodsFor: 'user interface support' stamp: 'hlsf 12/22/2022 21:45:04'!
computeMessageEntriesIn: aDynamicTypingSmalltalkCompleter ofBlockArgNamed: aString
aDynamicTypingSmalltalkCompleter
computeMessageEntriesForClassOrNil: (DrGeoSystem preferences at: #programmingCodeCompletion)! !
!DrGSmalltalkSketchEditor methodsFor: 'user interface support' stamp: 'hlsf 12/22/2022 21:45:36'!
computeMessageEntriesIn: aDynamicTypingSmalltalkCompleter ofBlockTempVarNamed: aString
aDynamicTypingSmalltalkCompleter
computeMessageEntriesForClassOrNil: (DrGeoSystem preferences at: #programmingCodeCompletion)! !
!DrGSmalltalkSketchEditor methodsFor: 'user interface support' stamp: 'hlsf 12/22/2022 21:45:25'!
computeMessageEntriesIn: aDynamicTypingSmalltalkCompleter ofInstVarNamed: aString
aDynamicTypingSmalltalkCompleter
computeMessageEntriesForClassOrNil: (DrGeoSystem preferences at: #programmingCodeCompletion)! !
!DrGSmalltalkSketchEditor methodsFor: 'user interface support' stamp: 'hlsf 12/22/2022 21:40:20'!
computeMessageEntriesIn: aDynamicTypingSmalltalkCompleter ofTempVarNamed: aString
aDynamicTypingSmalltalkCompleter
computeMessageEntriesForClassOrNil: (DrGeoSystem preferences at: #programmingCodeCompletion)! !
!DrGSmalltalkSketchEditor methodsFor: 'user interface support' stamp: 'hlsf 4/15/2022 15:10:56'!
editorClassFor: textGetter
^SmalltalkEditor! !
!DrGSmalltalkSketchEditor methodsFor: 'user interface support' stamp: 'hlsf 4/14/2022 16:40:23'!
shouldStyle: aText with: aSHTextStylerST80
^true! !
!DrGSmalltalkSketchEditor methodsFor: 'user interface support' stamp: 'hlsf 11/23/2023 17:27:30'!
styleByParagraphs
^ false! !
!DrGSmalltalkSketchEditor methodsFor: 'user interface support' stamp: 'hlsf 4/14/2022 16:40:27'!
textStylerClassFor: object
^ SHTextStylerST80 ! !
!DrGSmalltalkSketchEditor methodsFor: 'actions' stamp: 'hlsf 5/18/2023 17:35:00'!
browseSketches
| browser |
self stopSketch.
browser := DrGSmalltalkSketchBrowser
open: DrGeoSystem smalltalkSketchesPath
label: 'Select a Smalltalk sketch' translated.
browser when: #editSmalltalkSketch send: #loadSketch: to: self.! !
!DrGSmalltalkSketchEditor methodsFor: 'actions' stamp: 'hlsf 5/25/2023 15:31:32'!
compiledSketch: aSketch
self releaseMiniView.
drgeoView
removeAllMorphs;
addMorph: aSketch view.! !
!DrGSmalltalkSketchEditor methodsFor: 'actions' stamp: 'hlsf 2/22/2023 22:10:10'!
debugSketch
model ifEmpty: [^ self].
self stopSketch.
self isDocVisible ifTrue: [self toggleHelp].
codeView scroller acceptContents.
DrGeoSketch when: #newSmalltalkSketch send: #compiledSketch: to: self.
codeView editor
afterCompiling: model
do: [ :compiler :method :receiver :context |
(method notNil and: [method isQuick not]) ifTrue: [
debugger _ Debugger
openMinimalDebugging: [
method
valueWithReceiver: receiver
arguments: (context ifNil: [ #() ] ifNotNil: [ { context } ])]
to: method.
debugger layoutMorph borderWidth: 1.
codeAndViewPanel replaceSubmorph: codeView by: debugger layoutMorph.
debugger model when: #closeViews send: #stopDebbuger to: self.
debugger contextVariableInspector selectionIndex: 3.]
]
ifFail: [].! !
!DrGSmalltalkSketchEditor methodsFor: 'actions' stamp: 'hlsf 10/19/2022 21:21:13'!
debugWindowSketch
self stopSketch.
codeView scroller acceptContents.
codeView editor
afterCompiling: model
do: [ :compiler :method :receiver :context | method ifNotNil: [ | window |
window _ Debugger
openMinimalDebugging: [
method
valueWithReceiver: receiver
arguments: (context ifNil: [ #() ] ifNotNil: [ { context } ])]
to: method
label: 'Execute step by step' translated.
window contextVariableInspector selectionIndex: 3.]
]
ifFail: [].! !
!DrGSmalltalkSketchEditor methodsFor: 'actions' stamp: 'hlsf 2/22/2023 11:55:13'!
executeSketch
self stopSketch.
codeView scroller acceptContents.
self switchToPauseButton.
DrGeoSketch when: #newSmalltalkSketch send: #compiledSketch: to: self.
sketchProcess _ [ | t |
t _ DateAndTime now.
Compiler evaluate: model.
" When we get there, sketch has been entirely executed, switch back to play button "
self switchToPlayButton.
Transcript show: DateAndTime now - t ;cr] newProcess.
sketchProcess
priority: Processor userSchedulingPriority ;
name: '[DrGeo] Smalltalk Sketch execution';
resume.! !
!DrGSmalltalkSketchEditor methodsFor: 'actions' stamp: 'hlsf 4/15/2022 21:31:52'!
keepSketch
| modelName |
DrGeoSystem showVirtualKeyboard: true.
codeView scroller acceptContents.
modelName _ ValueHolder with: self sketchName ::
action: [:aString |
self setLabel: aString.
file _ DrGeoSystem mySmalltalkSketchesPath // (aString, '.st').
file < model].
StringEntryPanel openWide: modelName label: 'Name the sketch to keep.' translated ::
morphCenter: self fullBoundsInOwner center;
setProperty: #layerNumber toValue: 20! !
!DrGSmalltalkSketchEditor methodsFor: 'actions' stamp: 'hlsf 2/22/2023 11:31:05'!
loadSketch: afileEntry
" we are informed by the browser we want a file "
file _ afileEntry.
self setLabel: self sketchName.
self sourceCode: file fileContents! !
!DrGSmalltalkSketchEditor methodsFor: 'actions' stamp: 'Install-DrGeoFrench 12/7/2022 16:12:01'!
pauseSketch
sketchProcess isTerminated ifTrue: [
self stopSketch.
^self ].
sketchProcess suspend.
self switchToResumeButton.! !
!DrGSmalltalkSketchEditor methodsFor: 'actions' stamp: 'hlsf 10/6/2022 12:28:58'!
resumeSketch
sketchProcess resume.
self switchToPauseButton! !
!DrGSmalltalkSketchEditor methodsFor: 'actions' stamp: 'hlsf 10/19/2022 21:35:07'!
stopDebbuger
debugger ifNotNil: [
codeAndViewPanel replaceSubmorph: debugger layoutMorph by: codeView.
debugger closeView.
debugger _ nil]
! !
!DrGSmalltalkSketchEditor methodsFor: 'actions' stamp: 'hlsf 5/18/2023 17:35:51'!
stopSketch
"DrGeoSketch removeActionsWithReceiver: self."
DrGeoSketch releaseActionMap .
sketchProcess ifNotNil: [
sketchProcess terminate.
sketchProcess := nil ].
self switchToPlayButton .
self stopDebbuger
! !
!DrGSmalltalkSketchEditor methodsFor: 'actions' stamp: 'hlsf 11/2/2022 19:48:07'!
toggleHelp
"Show/unshow the doc pane"
debugger ifNotNil: [^ self]. "No doc while debugging, the pane does not like it"
self isDocVisible ifTrue: [
docView hide.
codeView layoutSpec proportionalHeight: 1.0.
docView layoutSpec proportionalHeight: 0.
self separator hide ]
ifFalse: [
docView show.
docView layoutSpec proportionalHeight: 0.3.
codeView layoutSpec proportionalHeight: 0.7.
self separator show ].
self changed: #isDocVisible
! !
!DrGSmalltalkSketchEditor methodsFor: 'geometry' stamp: 'hlsf 4/23/2022 14:19:25'!
expand
super expand.
self fullScreen! !
!DrGSmalltalkSketchEditor methodsFor: 'geometry' stamp: 'hlsf 11/18/2023 16:35:19'!
minimumExtent
^ 800@600! !
!DrGSmalltalkSketchEditor methodsFor: 'testing' stamp: 'hlsf 5/18/2023 17:07:27'!
shouldAutoHighlight
^ false! !
!DrGSmalltalkSketchEditor methodsFor: 'testing' stamp: 'hlsf 5/18/2023 17:09:35'!
shoutMustKeepContentsSize
^ true! !
!DrGSmalltalkSketchEditor methodsFor: 'submorphs-add/remove' stamp: 'hlsf 5/25/2023 18:03:51'!
delete
self stopSketch .
super delete.
self releaseMiniView ! !
!DrGSmalltalkSketchEditor methodsFor: 'submorphs-add/remove' stamp: 'hlsf 8/4/2023 12:58:53'!
releaseMiniView
drgeoView submorphCount = 1 ifTrue: [
drgeoView firstSubmorph ifNotNil: [:miniView|
miniView presenter ifNotNil: [:p | p release] ]]! !
!DrGStylePanel methodsFor: 'GUI building' stamp: 'hlsf 2/14/2022 11:39:14'!
buildMorphicWindow
| labelWidth widgets |
titleMorph showButtonsNamed: #(#close).
self layoutMorph separation: 4 ;
axisEdgeWeight: #columnTop.
widgets _ model styleWidget.
labelWidth _ widgets max: [:rowOfMorph | (self searchLabelIn: rowOfMorph) morphWidth].
widgets do: [:rowOfMorph |
(self searchLabelIn: rowOfMorph) morphWidth: labelWidth.
self addMorph: rowOfMorph].
self morphExtent: self minimumExtent
! !
!DrGStylePanel methodsFor: 'GUI building' stamp: 'hlsf 2/14/2022 11:25:48'!
searchLabelIn: aMorph
" Dirty, search for the label morph "
(aMorph isKindOf: LabelMorph)
ifTrue: [^ aMorph]
ifFalse: [
aMorph submorphs do: [:each |
(self searchLabelIn: each) ifNotNil: [:found | ^ found ] ] ].
^ nil
! !
!DrGDrawableMenu methodsFor: 'events' stamp: 'hlsf 5/3/2020 23:43:15'!
initialize
super initialize.
self color: (self color alpha: 0.7).
self borderColor: (self borderColor alpha: 0.7).
! !
!DrGDrawableMenu methodsFor: 'events' stamp: 'hlsf 9/23/2021 12:04:49'!
mouseButton1Down: aMouseButtonEvent localPosition: localEventPosition
"click outside => step blinking the selected item "
(stayUp or: [(self coversLocalPoint:localEventPosition) or: [selectedItem isNil]])
ifFalse: [
selectedItem arguments first first stopBlinking.
tool reset].
super mouseButton1Down: aMouseButtonEvent localPosition: localEventPosition ! !
!DrGDrawableMenu methodsFor: 'control' stamp: 'hlsf 8/3/2021 13:00:14'!
selectItem: aMenuItem
selectedItem ifNotNil:[
selectedItem arguments first first stopBlinking].
aMenuItem ifNotNil:[
aMenuItem arguments first first startBlinking].
^ super selectItem: aMenuItem ! !
!DrGDrawableMenu methodsFor: 'accessing' stamp: 'hlsf 5/6/2020 14:17:28'!
tool: aDrGeoTool
tool _ aDrGeoTool ! !
!DrGDrawable methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 17:42:50'!
domain
^ presenter domain! !
!DrGDrawable methodsFor: 'accessing' stamp: 'hlsf 6/19/2021 10:08:59'!
labels
^ submorphs select: [:aMorph| aMorph class == DrGLabel].
! !
!DrGDrawable methodsFor: 'accessing' stamp: 'hlsf 6/19/2021 10:08:59'!
mostBehindLabel
^ submorphs reverse detect: [:aMorph| aMorph class == DrGLabel] ifNone: [nil].
! !
!DrGDrawable methodsFor: 'accessing'!
ox
"abscisa of the center of the visible canvas, in world coordinates, at start up it is equal 0"
^ ox! !
!DrGDrawable methodsFor: 'accessing'!
ox: integer
ox _ integer asNumber! !
!DrGDrawable methodsFor: 'accessing'!
oy
"ordinate of the center of the visible canvas, in world coordinates, at start up it is equal 0"
^ oy! !
!DrGDrawable methodsFor: 'accessing'!
oy: integer
oy _ integer asNumber! !
!DrGDrawable methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 12:44:35'!
presenter
^ presenter! !
!DrGDrawable methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 12:44:22'!
presenter: aPresenter
presenter := aPresenter ! !
!DrGDrawable methodsFor: 'accessing' stamp: 'hlsf 8/3/2023 21:35:04'!
preview
"Return a form preview"
^ self previewOn: ByteArray new writeStream! !
!DrGDrawable methodsFor: 'accessing' stamp: 'hlsf 8/3/2023 21:28:55'!
previewOn: aStream
"compute an PNG preiview, put it in the stream and return its form"
|form |
form := (self imageForm: 32) magnifyBy: DrGeoSystem previewSize x / self morphExtent x.
PNGReadWriter putForm: form onStream: aStream.
^ form! !
!DrGDrawable methodsFor: 'accessing'!
scale
^ scale! !
!DrGDrawable methodsFor: 'accessing' stamp: 'hlsf 8/5/2021 12:47:36'!
scale: increment
self scaleNoRedraw: increment.
self updateGrid.
self redrawNeeded ! !
!DrGDrawable methodsFor: 'accessing'!
scaleNoRedraw: increment
scale _ (scale + increment) .
scale < 1 ifTrue: [scale _ 1.0].
scale > 1000 ifTrue: [scale _ 1000.0].
! !
!DrGDrawable methodsFor: 'accessing' stamp: 'hlsf 4/16/2022 17:53:55'!
setScaleTo: number
scale _ number asNumber.
self updateGrid.
self redrawNeeded ! !
!DrGDrawable methodsFor: 'accessing'!
tool
^self presenter tool! !
!DrGDrawable methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 12:47:09'!
view
^presenter view! !
!DrGDrawable methodsFor: 'axes/grid' stamp: 'hlsf 6/19/2021 17:13:33'!
axesVisible
^ self valueOfProperty: #axesVisible ifAbsent: [false]! !
!DrGDrawable methodsFor: 'axes/grid' stamp: 'hlsf 6/19/2021 17:16:57'!
axesVisibleOnOff
self setProperty: #axesVisible toValue: self axesVisible not.
self updateGrid.
self redrawNeeded ! !
!DrGDrawable methodsFor: 'axes/grid' stamp: 'hlsf 6/19/2021 17:13:17'!
gridVisible
^ self valueOfProperty: #gridVisible ifAbsent: [false]
! !
!DrGDrawable methodsFor: 'axes/grid' stamp: 'hlsf 6/19/2021 17:16:48'!
gridVisibleOnOff
self setProperty: #gridVisible toValue: self gridVisible not.
self updateGrid.
self redrawNeeded ! !
!DrGDrawable methodsFor: 'callback' stamp: 'hlsf 5/1/2020 16:37:02'!
moveOx: increment
ox _ ox - increment.
self redrawNeeded! !
!DrGDrawable methodsFor: 'callback' stamp: 'hlsf 5/1/2020 16:34:10'!
moveOxy: pointIncrement
ox _ ox - pointIncrement x.
oy _ oy - pointIncrement y.
self redrawNeeded.! !
!DrGDrawable methodsFor: 'callback' stamp: 'hlsf 5/1/2020 16:34:27'!
moveOy: increment
oy _ oy + increment.
self redrawNeeded! !
!DrGDrawable methodsFor: 'callback' stamp: 'hlsf 8/5/2021 12:48:46'!
zoom: anExtent
scale _ (scale + ((anExtent x + anExtent y) / 5)) asInteger.
scale _ scale min: 200.
self updateGrid.
self redrawNeeded! !
!DrGDrawable methodsFor: 'coordinates' stamp: 'hlsf 5/1/2020 16:59:05'!
defaultScalePosition
ox _ oy := 0.0.
scale _ 34.0.
self updateGrid.
self redrawNeeded! !
!DrGDrawable methodsFor: 'coordinates' stamp: 'hlsf 4/25/2020 19:37:59'!
morphAbscissaToWorld: abscissa
"Transform abscissa from DrGeo-Morph to World system"
^ ox + ((abscissa - (extent x / 2.0)) / scale)
! !
!DrGDrawable methodsFor: 'coordinates' stamp: 'hlsf 4/25/2020 19:38:37'!
morphOrdinateToWorld: ordinate
"Transform point coordinate from DrGeo-Morph to World system"
^ oy - ((ordinate - (extent y / 2.0)) / scale)! !
!DrGDrawable methodsFor: 'coordinates'!
morphToVector: aPoint
"Transform vector coordinates in the morph system to the DrGeo system"
^ Point
x: aPoint x asFloat / scale
y: aPoint y negated asFloat / scale.
! !
!DrGDrawable methodsFor: 'coordinates'!
morphToWorld: aPoint
"Transform point coordinate from DrGeo-Morph to World system"
^ Point
x: (self morphAbscissaToWorld: aPoint x)
y: (self morphOrdinateToWorld: aPoint y)! !
!DrGDrawable methodsFor: 'coordinates'!
pixelToWorld: pixels
"Transform morph pixel unit to Dr. Geo world unit"
^ pixels asFloat / scale
! !
!DrGDrawable methodsFor: 'coordinates'!
pixelVectorToWorldVector: pixelVector
"Transform morph pixel unit to Dr. Geo world unit"
^ (pixelVector asFloatPoint / scale) * (1 @ -1)
! !
!DrGDrawable methodsFor: 'coordinates'!
vectorToMorph: aVector
"Transform vector coordinates in the Dr. Geo system to the morph system"
^ Point
x: aVector x asFloat * scale
y: aVector y negated asFloat * scale.
! !
!DrGDrawable methodsFor: 'coordinates' stamp: 'hlsf 2/17/2022 15:33:18'!
worldAbscissaToMorph: x
"Transform point abscissa from DrGeo-World to Morph system"
^extent x / 2.0 + (scale * (x - ox))! !
!DrGDrawable methodsFor: 'coordinates' stamp: 'hlsf 4/25/2020 19:33:08'!
worldBound
^ Rectangle
origin: (self morphToWorld: 0 @ extent y)
corner: (self morphToWorld: extent x @ 0)! !
!DrGDrawable methodsFor: 'coordinates' stamp: 'hlsf 8/5/2021 13:05:02'!
worldOrdinateToMorph: y
"Transform point ordinate from DrGeo-World to Morph system"
^ extent y / 2.0 + (scale * (oy - y))! !
!DrGDrawable methodsFor: 'coordinates'!
worldToMorph: aPoint
"Transform point coordinate from DrGeo-World to Morph system"
^ (self worldAbscissaToMorph: aPoint x) @ (self worldOrdinateToMorph: aPoint y)! !
!DrGDrawable methodsFor: 'coordinates'!
worldToPixel: aFloat
"Transform Dr. Geo world unit to morph unit"
^ aFloat * scale
! !
!DrGDrawable methodsFor: 'drawing' stamp: 'hlsf 8/4/2023 12:19:10'!
dottedLinesToParentsOf: anItem
| point pointWorld |
(anItem isValueItem not or: [anItem parents isEmptyOrNil]) ifTrue: [^self ].
valueItem := anItem.
point := (self viewOf: valueItem) morphCenter.
pointWorld := self morphToWorld: point.
dottedLines := valueItem parents collect: [:item |
(DrGPolylineMorph
from: point
to: (self worldToMorph: (item closestPointTo: pointWorld))
color: Color red
width: 0.5
in: self)
arrow: #forward;
dashedBorder: {1. 5};
yourself].
dottedLines do: [:line | self addMorphFront: line].! !
!DrGDrawable methodsFor: 'drawing' stamp: 'hlsf 4/24/2020 23:12:32'!
drawOn: aCanvas
super drawOn: aCanvas.
self gridVisible ifTrue: [self drawGridOn: aCanvas].
self axesVisible ifTrue: [ self drawAxesOn: aCanvas].! !
!DrGDrawable methodsFor: 'drawing'!
removeDottedLinesToParents
valueItem ifNil: [^self].
dottedLines do: [:line | self removeMorph: line].
dottedLines _ nil.
valueItem _ nil! !
!DrGDrawable methodsFor: 'drawing' stamp: 'hlsf 8/4/2023 12:19:10'!
updateDottedLinesToParents
| point pointWorld |
valueItem ifNil: [^self].
point := (self viewOf: valueItem) morphCenter.
pointWorld := self morphToWorld: point.
dottedLines with: valueItem parents do: [:line :parent|
line vertices: (
Array
with: point
with: (self worldToMorph: (parent closestPointTo: pointWorld)))]! !
!DrGDrawable methodsFor: 'drawing axes & grid' stamp: 'hlsf 3/17/2022 15:25:39'!
drawAxesOn: aCanvas
| origin worldBound font p start |
origin _ self worldToMorph: 0@0.
worldBound _ self worldBound.
font _ DrGeoSystem canvasFont.
"x-axis"
(origin y > 0 and: [origin y < extent y]) ifTrue: [
aCanvas line: 0 @ origin y to: extent x @ origin y width: 1 color: Color lightGray.
"x labels in [0 ; +inf["
start _ worldBound origin x > gridScale
ifTrue: [worldBound origin x roundUpTo: gridScale]
ifFalse: [gridScale].
start to: (worldBound corner x roundDownTo: gridScale) by: gridScale do: [:x |
self drawGradX: x origin: origin on: aCanvas font: font].
"x labels in ]-inf ; 0["
gridScale negated to: (worldBound origin x roundUpTo: gridScale) by: gridScale negated do: [:x |
self drawGradX: x origin: origin on: aCanvas font: font].
"orientation"
p _ extent x - 2 @ origin y.
aCanvas line: p to: p - `4 @ 4` width: 1 color: Color lightGray;
line: p to: p - `4 @ -4` width: 1 color: Color lightGray].
"y-axis"
(origin x > 0 and: [origin x < extent x]) ifTrue: [
aCanvas line: origin x @ 0 to: origin x @ extent y width: 1 color: Color lightGray.
"y labels in [0 ; +inf["
gridScale to: (worldBound corner y roundDownTo: gridScale) by: gridScale do: [:y |
self drawGradY: y origin: origin on: aCanvas font: font].
"y labels in ]-inf ; 0["
start _ worldBound corner y < gridScale negated
ifTrue: [worldBound corner y roundDownTo: gridScale]
ifFalse: [gridScale negated].
start to: (worldBound origin y roundUpTo: gridScale) by: gridScale negated do: [:y |
self drawGradY: y origin: origin on: aCanvas font: font].
"orientations"
p _ origin x @ 0.
aCanvas line: p to: p + `4 @ 4` width: 1 color: Color lightGray;
line: p to: p + `-4 @ 4` width: 1 color: Color lightGray].
"The origin"
(self morphLocalBounds containsPoint: origin) ifTrue: [
aCanvas drawString: '0' at: (origin + `2@2`) font: font color: Color lightGray].
! !
!DrGDrawable methodsFor: 'drawing axes & grid' stamp: 'hlsf 3/9/2022 22:11:11'!
drawGradX: x origin: origin on: canvas font: font
"Draw a tick on the (ox) axis with a graduation value"
| str pos shift |
pos _ (self worldAbscissaToMorph: x asFloat) @ origin y.
str _ self labelForAxes: x.
shift _ self gridVisible ifTrue: [2@6] ifFalse: [(font widthOfString: str) / -2.0 @6].
canvas drawString: str at: pos + shift font: font color: Color lightGray.
canvas line: pos - `0@2` to: pos + `0@2` width: 1.5 color: Color lightGray.! !
!DrGDrawable methodsFor: 'drawing axes & grid' stamp: 'hlsf 3/9/2022 22:11:23'!
drawGradY: y origin: origin on: canvas font: font
"Draw a tick on the (oy) axis with a graduation value"
| pos shift |
pos _ origin x @ (self worldOrdinateToMorph: y asFloat).
shift _ self gridVisible ifTrue: [5@2] ifFalse: [5 @ (font lineSpacing / -2.0)].
canvas
drawString: (self labelForAxes: y)
at: pos + shift
font: font
color: Color lightGray.
canvas line: pos - `2@0` to: pos + `2@0` width: 1.5 color: Color lightGray.! !
!DrGDrawable methodsFor: 'drawing axes & grid' stamp: 'hlsf 11/1/2022 20:30:25'!
drawGridOn: aCanvas
| worldBound end start length step |
worldBound _ self worldBound.
step _ self worldToPixel: gridScale.
"horizontal lines"
length _ extent x.
start _ self worldOrdinateToMorph: (worldBound corner y roundTo: gridScale).
start < 0 ifTrue: [start _ start + step].
end _ extent y.
start to: end by: step do: [:y |
aCanvas line: 0 @ y to: length @ y width: 0.4 color: Color lightGray].
""
"vertical lines"
length _ extent y.
start _ self worldAbscissaToMorph: (worldBound origin x roundTo: gridScale).
start < 0 ifTrue: [start _ start + step].
end _ extent x.
start to: end by: step do: [:x |
aCanvas line: x @ 0 to: x @ length width: 0.4 color: Color lightGray]! !
!DrGDrawable methodsFor: 'drawing axes & grid'!
labelForAxes: number
gridScale isFloat
ifTrue: [|integer|
integer _ number asInteger.
integer = number ifTrue: [^ integer printString]].
^ (number isInteger not and: [number isFraction])
ifTrue: [number printString allButFirst allButLast]
ifFalse: [ number printString]! !
!DrGDrawable methodsFor: 'dropping/grabbing' stamp: 'hlsf 6/8/2021 19:33:45'!
acceptDroppingMorph: dropped event: evt
"Here we encapsulated the image morph (dropped) in a DrGBitmapItem.
We do not really need a builder to do so but we have to process it in the command stack"
| item |
item _ (DrGBitmapItem newWith: {self morphToWorld: evt eventPosition})
data: (self resizeImage: dropped form);
insertAtScale: self scale.
self domain createFromMathItem: item.! !
!DrGDrawable methodsFor: 'dropping/grabbing'!
resizeImage: aForm
"Reszie the image to a maximum pixel number"
| resizedForm maxPixels size ratio |
maxPixels _ 250000.
size _ aForm extent x * aForm extent y.
size > maxPixels
ifTrue: [ratio _ (maxPixels / size) sqrt.
resizedForm _ aForm magnifyBy: ratio]
ifFalse: [resizedForm _ aForm].
^ resizedForm ! !
!DrGDrawable methodsFor: 'event handling testing' stamp: 'hlsf 5/1/2020 17:16:55'!
allowsSubmorphDrag
"We are managing by our self item dragging"
^ false! !
!DrGDrawable methodsFor: 'event handling testing' stamp: 'hlsf 4/28/2020 17:53:34'!
handlesKeyboard
^ true! !
!DrGDrawable methodsFor: 'event handling testing' stamp: 'hlsf 4/28/2020 11:18:17'!
handlesMouseDown: evt
^ true! !
!DrGDrawable methodsFor: 'event handling testing' stamp: 'hlsf 4/28/2020 12:13:20'!
handlesMouseHover
^ true! !
!DrGDrawable methodsFor: 'event handling testing'!
handlesMouseOver: evt
^ true! !
!DrGDrawable methodsFor: 'event handling testing' stamp: 'hlsf 4/28/2020 10:20:54'!
handlesMouseScroll: scrollEvent
^ true! !
!DrGDrawable methodsFor: 'event handling testing'!
handlesMouseStillDown: evt
^ true! !
!DrGDrawable methodsFor: 'events' stamp: 'hlsf 6/21/2021 21:38:07'!
mouseButton1Down: evt localPosition: localPosition
evt shiftPressed
ifTrue: [self tool handlePressShiftKey: localPosition ]
ifFalse: [self tool handlePress: localPosition].
self showUnderMouseMorph! !
!DrGDrawable methodsFor: 'events' stamp: 'hlsf 6/21/2021 21:38:15'!
mouseButton1Up: evt localPosition: localPosition
evt shiftPressed
ifTrue: [self tool handleReleaseShiftKey: localPosition]
ifFalse: [self tool handleRelease: localPosition ].
"underMouse hide." self flag: #drgeoTodo.
(self morphLocalBounds containsPoint: localPosition)
ifFalse: [Cursor normalCursorWithMask activateCursor.]
! !
!DrGDrawable methodsFor: 'events' stamp: 'hlsf 4/10/2022 15:00:10'!
mouseButton2Up: evt localPosition: localPosition
self presenter openTools! !
!DrGDrawable methodsFor: 'events' stamp: 'hlsf 7/3/2022 13:07:57'!
mouseEnter: evt
(Preferences at: #focusFollowsMouse) ifTrue: [
evt hand newKeyboardFocus: self.
self redrawNeeded ].! !
!DrGDrawable methodsFor: 'events' stamp: 'hlsf 8/4/2021 15:22:13'!
mouseHover: evt localPosition: localEventPosition
"handle mouse move with button up"
localEventPosition = prevMousePos ifTrue: [^ self]. "nothing to process"
evt shiftPressed
ifTrue: [self tool handleShiftKeyMouseAt: localEventPosition]
ifFalse: [self tool handleMouseAt: localEventPosition].
prevMousePos _ localEventPosition! !
!DrGDrawable methodsFor: 'events' stamp: 'hlsf 6/21/2021 21:27:06'!
mouseLeave: evt
super mouseLeave: evt.
Cursor normalCursorWithMask activateCursor.
! !
!DrGDrawable methodsFor: 'events' stamp: 'hlsf 6/21/2021 21:39:02'!
mouseMove: evt localPosition: localEventPosition
"Mouse move with pressed button"
evt shiftPressed
ifTrue: [self tool handleShiftKeyMouseAt: localEventPosition ]
ifFalse: [
((self tool handleMouseAt: localEventPosition) or: [self tool isBuilding])
ifFalse: [self mouseMoveOxy: localEventPosition]
].
self updateUnderMouseMorphPosition.
prevMousePos _ localEventPosition.
! !
!DrGDrawable methodsFor: 'events' stamp: 'hlsf 4/28/2020 12:21:19'!
mouseMoveOxy: newPosition
"move the whole sketch in the Oxy plane"
|delta|
delta _ newPosition - prevMousePos.
delta r < 100 ifTrue: "we need to check because in tablet mode, previous mouse position can be far away"
[self moveOxy: (self pixelVectorToWorldVector: delta)]! !
!DrGDrawable methodsFor: 'events' stamp: 'hlsf 8/5/2021 12:51:36'!
mouseScroll: evt localPosition: localEventPosition
| increment orginalWorldCursorPoint |
orginalWorldCursorPoint _ self morphToWorld: localEventPosition.
" WAIT for proper wheel event with modifier keys always on
increment _ evt shiftPressed ifTrue: [10] ifFalse: [2]."
increment _ 0.5.
evt direction == #down
ifTrue: [ self scaleNoRedraw: increment ].
evt direction == #up
ifTrue: [ self scaleNoRedraw: increment negated ].
"cursor point is at a constant world position"
self updateGrid.
self
moveOxy: (self morphToWorld: localEventPosition) - orginalWorldCursorPoint! !
!DrGDrawable methodsFor: 'events' stamp: 'hlsf 9/16/2021 13:52:11'!
mouseStillDown
self tool handleStillPress: prevMousePos! !
!DrGDrawable methodsFor: 'events'!
mouseStillDownThreshold
^ 1500! !
!DrGDrawable methodsFor: 'events' stamp: 'hlsf 9/16/2021 14:01:18'!
processMouseMove: aMouseMoveEvent localPosition: localEventPosition
"Overwritten to prevent superfluous mouseStillDown events"
aMouseMoveEvent wasHandled ifTrue: [ ^self ].
aMouseMoveEvent hand hasSubmorphs ifTrue: [ ^self ].
(aMouseMoveEvent anyButtonPressed and: [ self hasMouseFocus ]) ifFalse: [ ^self ].
aMouseMoveEvent wasHandled: true.
self mouseMove: aMouseMoveEvent localPosition: localEventPosition.! !
!DrGDrawable methodsFor: 'events' stamp: 'hlsf 9/16/2021 13:51:56'!
restartMouseStillDownHandle
"We reset the timer"
prevMousePos ifNotNil: [
self startStepping: #processMouseStillDown
in: 1500
stepTime: self mouseStillDownStepRate]! !
!DrGDrawable methodsFor: 'geometry testing' stamp: 'hlsf 6/13/2021 18:17:19'!
clipsSubmorphs
^ true! !
!DrGDrawable methodsFor: 'geometry testing' stamp: 'hlsf 11/2/2022 14:41:17'!
requiresVectorCanvas
^ true! !
!DrGDrawable methodsFor: 'gridding'!
gridPoint: ungriddedPoint
self presenter isGridded ifFalse: [^ungriddedPoint].
"do it the easy way"
^self worldToMorph: ((self morphToWorld: ungriddedPoint) roundTo: gridScale)! !
!DrGDrawable methodsFor: 'gridding'!
gridWorldPoint: ungriddedPoint
self presenter isGridded ifFalse: [^ self morphToWorld: ungriddedPoint].
"do it the easy way"
^(self morphToWorld: ungriddedPoint) roundTo: gridScale! !
!DrGDrawable methodsFor: 'gridding'!
gridWorldVector: ungriddedPoint
self presenter isGridded ifFalse: [^ self morphToVector: ungriddedPoint].
"do it the easy way"
^(self morphToVector: ungriddedPoint) roundTo: gridScale! !
!DrGDrawable methodsFor: 'gridding'!
updateGrid
self axesVisible
ifTrue: [ self updateGridScaleForAxes]
ifFalse: [ self updateGridScaleForGrid]! !
!DrGDrawable methodsFor: 'gridding' stamp: 'hlsf 4/30/2020 18:11:39'!
updateGridScaleForAxes
gridScale _ 50 / scale.
gridScale >= 1
ifTrue: [
gridScale _ gridScale roundTo: 0.5.
gridScale asInteger = gridScale ifTrue: [gridScale _ gridScale asInteger]]
ifFalse: [
gridScale _ 1 / ((1 / gridScale) rounded)]! !
!DrGDrawable methodsFor: 'gridding' stamp: 'hlsf 4/26/2020 14:46:44'!
updateGridScaleForGrid
gridScale _ 5! !
!DrGDrawable methodsFor: 'halos and balloon help' stamp: 'hlsf 6/21/2021 21:55:43'!
wantsHalo
^true! !
!DrGDrawable methodsFor: 'initialize-release' stamp: 'hlsf 8/4/2023 17:42:44'!
dismissMorph
super dismissMorph.
presenter view dismissMorph ! !
!DrGDrawable methodsFor: 'initialize-release' stamp: 'hlsf 8/4/2023 18:33:52'!
initialize
super initialize.
self color: Theme current background.
self color: Color white.
self borderWidth: 0.
tipOn := true.
self defaultScalePosition.
balloonTarget := BoxedMorph new
color: Color transparent;
borderWidth: 0;
morphExtent: 6 @ 6;
yourself.
itemViews := OrderedCollection new.
undoneViews := OrderedCollection new.
self registerEvents .
self flag: #drgeoTodo.
"For tablet to see what is under the finger"
"morphExtent: DrGeoSystem replicateDisplayWidth asPoint;
yourself.
self addMorphBack: underMouse.
underMouse
morphPosition: self morphPosition;
hide." ! !
!DrGDrawable methodsFor: 'initialize-release' stamp: 'hlsf 8/4/2023 12:17:03'!
registerEvents
self domain
when: #redoMathItem
send: #recoverViewOf:
to: self.
self domain
when: #newMathItem
send: #itemView:
to: self.
self domain
when: #updatedItems
send: #redrawNeeded
to: self.
self domain
when: #updatedDirtyItems
send: #redrawNeeded
to: self.! !
!DrGDrawable methodsFor: 'initialize-release' stamp: 'hlsf 8/4/2023 12:33:51'!
release
self domain removeActionsWithReceiver: self.
itemViews do: [:each | each release]! !
!DrGDrawable methodsFor: 'item-view' stamp: 'hlsf 8/4/2023 11:08:35'!
deleteItemView: aMorph
aMorph release.
undoneViews add: aMorph.
itemViews := itemViews copyWithout: aMorph.
! !
!DrGDrawable methodsFor: 'item-view' stamp: 'hlsf 8/4/2023 11:14:32'!
fastLastItemView
"Find the morph in the factory last mathItem, cahed version, may not update to date"
^ lastView ! !
!DrGDrawable methodsFor: 'item-view' stamp: 'hlsf 8/4/2023 11:43:49'!
forcedVisibility: aBoolean
"Force or not the visibility of hidden morph"
aBoolean ifTrue: [self redrawNeeded ].
itemViews do: [:morph |
morph forcedVisibility: aBoolean].! !
!DrGDrawable methodsFor: 'item-view' stamp: 'hlsf 8/4/2023 11:07:15'!
itemView: aMathItem
"new math item event : A new math item has been created, create its morph"
lastView := itemViews add: (DrGMorph for: aMathItem in: self)! !
!DrGDrawable methodsFor: 'item-view' stamp: 'hlsf 8/4/2023 11:37:26'!
itemViews
^ itemViews ! !
!DrGDrawable methodsFor: 'item-view' stamp: 'hlsf 8/4/2023 11:15:36'!
lastItemView
"Find the morph in the factory last mathItem"
| lastMathItem morph |
morph := itemViews last.
morph mathItem = self domain factory last ifTrue: [^ morph].
lastMathItem := self domain factory last.
^ itemViews
detect: [:aMorph | aMorph mathItem = lastMathItem]
ifFound: [ :aMorph | aMorph ]
ifNone: [ nil]! !
!DrGDrawable methodsFor: 'item-view' stamp: 'hlsf 8/4/2023 12:16:24'!
recoverViewOf: aMathItem
"a redo math item event : a math item has been recalled, find its morph "
| itemMorph |
itemMorph := undoneViews
detect: [:morph | morph mathItem == aMathItem]
ifFound: [:morph | morph ]
ifNone: [^ self itemView: aMathItem].
itemMorph mathItem: aMathItem.
itemMorph reInitialize.
undoneViews := undoneViews copyWithout: itemMorph.
itemViews add: itemMorph! !
!DrGDrawable methodsFor: 'item-view' stamp: 'hlsf 8/4/2023 18:19:41'!
redrawNeeded
"View resized, update the area without recomputing the items"
self updateGrid.
super redrawNeeded.
presenter tool ifNotNil: [:aTool | aTool redrawFlyingMorph ]! !
!DrGDrawable methodsFor: 'item-view' stamp: 'hlsf 8/4/2023 12:19:10'!
viewOf: aMathItem
"Find the view of the given mathItem"
^ itemViews
detect: [:morph | morph mathItem == aMathItem]
ifFound: [ :morph | morph ]
ifNone: [ nil]! !
!DrGDrawable methodsFor: 'item-view' stamp: 'hlsf 8/4/2023 12:19:10'!
viewsOf: aMathItemCollection
"Find the morphs of the given mathItem collection"
^ aMathItemCollection collect: [:aMathItem | self viewOf: aMathItem]
! !
!DrGDrawable methodsFor: 'stepping'!
step
self tool animate! !
!DrGDrawable methodsFor: 'stepping'!
stepTime
^ 300! !
!DrGDrawable methodsFor: 'stepping' stamp: 'hlsf 8/3/2021 13:55:28'!
wantsSteps
^ (self presenter isTool: #animate) and: [self tool isAnimating]! !
!DrGDrawable methodsFor: 'submorphs-add/remove' stamp: 'hlsf 6/19/2021 10:08:59'!
addMorph: newMorph
| aLabel |
newMorph class == DrGLabel ifTrue: [^ self addMorphFront: newMorph].
aLabel _ self mostBehindLabel.
aLabel
ifNil: [self addMorphFront: newMorph]
ifNotNil: [self addMorph: newMorph behind: aLabel]! !
!DrGDrawable methodsFor: 'tip'!
hideTip
balloonTarget deleteBalloon.
self removeMorph: balloonTarget.! !
!DrGDrawable methodsFor: 'tip' stamp: 'hlsf 6/12/2020 10:52:25'!
tip: aText at: aPoint
tipOn ifFalse: [^self].
self addMorphBack: balloonTarget.
DrGeoSystem isTablet
ifTrue: [balloonTarget morphCenter: aPoint + (40 @ -40)]
ifFalse: [balloonTarget morphCenter: aPoint].
balloonTarget setBalloonText: aText.
balloonTarget showBalloon: (balloonTarget balloonText)! !
!DrGDrawable methodsFor: 'tip'!
toggleTip
tipOn _ tipOn not! !
!DrGDrawable methodsFor: 'under mouse'!
showUnderMouseMorph
DrGeoSystem ifTablet: [
self updateUnderMouseMorphPosition.
underMouse
comeToFront;
show].! !
!DrGDrawable methodsFor: 'under mouse'!
updateUnderMouseMorph
DrGeoSystem ifTablet: [underMouse changed]! !
!DrGDrawable methodsFor: 'under mouse' stamp: 'hlsf 4/7/2022 12:02:20'!
updateUnderMouseMorphPosition
DrGeoSystem ifTablet:
[self activeHand morphPosition x - self morphPosition x > (self morphWidth // 2 )
ifTrue: [underMouse position: self morphPosition]
ifFalse: [underMouse position: (self morphWidth - underMouse width) @ self morphPosition y]]! !
!DrGDrawable class methodsFor: 'instance creation' stamp: 'hlsf 8/4/2023 12:40:52'!
newOn: aPresenter
^self basicNew presenter: aPresenter ; initialize ! !
!DrGDrawable class methodsFor: 'new-morph participation' stamp: 'hlsf 3/15/2022 21:33:11'!
includeInNewMorphMenu
^ false! !
!UnderMouseMorph methodsFor: 'drawing' stamp: 'hlsf 12/9/2022 22:09:19'!
drawOn: aCanvas
" | areaUnderHand |
super drawOn: aCanvas.
areaUnderHand _ Form fromDisplay: (Rectangle
center: ActiveHand position
extent: self extent - (self borderWidth * 2)).
aCanvas drawImage: areaUnderHand at: self position + self borderWidth"! !
!UnderMouseMorph class methodsFor: 'new-morph participation' stamp: 'hlsf 3/15/2022 21:32:29'!
includeInNewMorphMenu
^ false! !
!DrGMorph methodsFor: 'accessing' stamp: 'hlsf 5/23/2021 12:43:28'!
color: aColor
color _ aColor! !
!DrGMorph methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 11:00:13'!
domain
^ drawable domain! !
!DrGMorph methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 11:00:06'!
drawable
^ drawable ! !
!DrGMorph methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 11:00:30'!
drawable: aDrawable
drawable := aDrawable ! !
!DrGMorph methodsFor: 'accessing' stamp: 'hlsf 5/24/2023 19:16:26'!
fontSize: aSmallInteger
! !
!DrGMorph methodsFor: 'accessing' stamp: 'hlsf 3/30/2021 13:58:02'!
locked
^ mathItem isLocked! !
!DrGMorph methodsFor: 'accessing' stamp: 'hlsf 2/12/2022 11:36:06'!
locked: boolean
self isLockable ifTrue: [
mathItem locked: boolean.
self update: #locked:]! !
!DrGMorph methodsFor: 'accessing' stamp: 'hlsf 3/30/2021 13:54:57'!
mathItem
^ mathItem ! !
!DrGMorph methodsFor: 'accessing' stamp: 'hlsf 3/30/2021 13:55:46'!
mathItem: aMathItem
self removeEvents.
mathItem _ aMathItem.
self registerEvents.! !
!DrGMorph methodsFor: 'accessing' stamp: 'hlsf 8/5/2021 16:05:18'!
morphCenter
"Our center in our drawable"
^ self displayBounds center - self drawable basicDisplayBounds topLeft! !
!DrGMorph methodsFor: 'accessing' stamp: 'hlsf 3/30/2021 13:58:36'!
name
^ mathItem name ifNil: [ '' ]
! !
!DrGMorph methodsFor: 'accessing' stamp: 'hlsf 3/24/2022 12:14:26'!
name: aString
mathItem name: aString asString.
self labelMorph: mathItem name
! !
!DrGMorph methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 17:58:05'!
presenter
^ drawable presenter ! !
!DrGMorph methodsFor: 'accessing' stamp: 'hlsf 3/30/2021 13:56:00'!
style
^ style! !
!DrGMorph methodsFor: 'accessing' stamp: 'hlsf 3/30/2021 13:56:33'!
style: aStyle
style _ aStyle ! !
!DrGMorph methodsFor: 'accessing' stamp: 'hlsf 4/7/2021 19:52:49'!
styleClass
^DrGStyle! !
!DrGMorph methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 12:47:01'!
view
^ drawable view! !
!DrGMorph methodsFor: 'printing' stamp: 'hlsf 4/3/2021 15:17:35'!
asString
^ mathItem
ifNil: ['nil']
ifNotNil: [mathItem descriptiveName] ! !
!DrGMorph methodsFor: 'printing' stamp: 'hlsf 8/5/2021 12:27:48'!
printOn: aStream
aStream nextPutAll: 'View::'.
aStream print: mathItem.! !
!DrGMorph methodsFor: 'event handling'!
handlesMouseDown: evt
^ false! !
!DrGMorph methodsFor: 'initialize-release' stamp: 'hlsf 6/5/2021 12:03:16'!
addMyMorph
self isBitmap
ifTrue: [self drawable addMorphBack: self]
ifFalse: [self drawable addMorph: self]! !
!DrGMorph methodsFor: 'initialize-release' stamp: 'hlsf 3/9/2023 16:36:08'!
initialize
super initialize.
blink _ false.
labelPositionDelta _ 7@7.
self style: (self styleClass newWith: self).
self labelMorph: mathItem name.! !
!DrGMorph methodsFor: 'initialize-release' stamp: 'hlsf 5/29/2021 17:22:01'!
reInitialize
"we recover from an undo operation, so let's reInitialize some of my
aspect "
self registerEvents.
self addMyMorph.
self redrawNeeded.
self labelMorph: mathItem name.
self forcedVisibility: false! !
!DrGMorph methodsFor: 'initialize-release' stamp: 'hlsf 8/4/2023 11:08:03'!
registerEvents
mathItem
ifNotNil: [
mathItem
when: #deletedMathItem
send: #deleteItemView:
to: drawable
with: self.
mathItem
when: #updateMyView
send: #updateAllMathItems
to: self domain].
self flag: #drgeoEvent! !
!DrGMorph methodsFor: 'initialize-release' stamp: 'hlsf 5/27/2023 12:30:11'!
release
" Flying morph use it. Read DrGMathItemBuilder>>reset "
self drawable removeMorph: self.
self removeLabelMorph.
self flag: #drgeoEvent.
self removeEvents.! !
!DrGMorph methodsFor: 'initialize-release' stamp: 'hlsf 5/25/2023 15:36:49'!
removeEvents
mathItem ifNotNil:
[mathItem removeActionsWithReceiver: self].
self breakDependents ! !
!DrGMorph methodsFor: 'initialize-release' stamp: 'hlsf 4/3/2021 15:33:38'!
removeLabelMorph
labelMorph ifNotNil:
[self drawable removeMorph: labelMorph.
labelMorph _ nil]! !
!DrGMorph methodsFor: 'label' stamp: 'hlsf 3/14/2023 21:01:38'!
computeLabelPositionDelta: aVector
| distance |
labelMorph ifNil: [ ^ `0 @ 0` ].
"Authorized distance to the item"
distance _ aVector r min: 40.
labelPositionDelta _ aVector normalized * distance - labelMorph morphCenter! !
!DrGMorph methodsFor: 'label' stamp: 'hlsf 4/3/2021 15:16:31'!
constrainedLabelPosition: aVector
"Constrains the label arround an anchor object or position
aVector is a shifted direction from the center of the label morph"
self subclassResponsibility ! !
!DrGMorph methodsFor: 'label' stamp: 'hlsf 3/30/2021 13:57:07'!
labelMorph
^ labelMorph ! !
!DrGMorph methodsFor: 'label' stamp: 'hlsf 6/19/2021 10:08:59'!
labelMorph: aString
aString isEmptyOrNil
ifTrue: [self removeLabelMorph]
ifFalse: [labelMorph
ifNil: [labelMorph _ DrGLabel new contents: aString.
labelMorph morph: self.
self canBeDrawn ifTrue: [self drawable addMorph: labelMorph.
labelMorph morphPosition: self labelPosition]]
ifNotNil: [labelMorph contents: aString]]! !
!DrGMorph methodsFor: 'label' stamp: 'hlsf 4/3/2021 15:15:35'!
labelPosition
"get an up to date label position in the drawable world coordinates"
self subclassResponsibility! !
!DrGMorph methodsFor: 'label' stamp: 'hlsf 4/3/2021 15:15:02'!
labelPositionDelta: aPoint
"The position of the label from its math object"
labelPositionDelta _ aPoint! !
!DrGMorph methodsFor: 'label' stamp: 'hlsf 5/20/2023 10:36:17'!
updateLabelStatus
"Update position and visibility if needed"
labelMorph ifNotNil: [
labelMorph show.
labelMorph morphPosition: self labelPosition].! !
!DrGMorph methodsFor: 'stepping and presenter'!
startBlinking
blink _ true.
self startStepping ! !
!DrGMorph methodsFor: 'stepping and presenter' stamp: 'hlsf 6/3/2022 11:37:36'!
step
blink ifFalse: [^self].
super step.
color = DrGTypeColor blinkingColor
ifTrue: [color _ style color]
ifFalse: [color _ DrGTypeColor blinkingColor].
self redrawNeeded! !
!DrGMorph methodsFor: 'stepping and presenter'!
stepTime
^500! !
!DrGMorph methodsFor: 'stepping and presenter'!
stopBlinking
blink _ false.
self stopStepping.! !
!DrGMorph methodsFor: 'stepping and presenter' stamp: 'drgeo 9/10/2022 14:49:17'!
stopStepping
super stopStepping.
self restoreNormalColor.
self redrawNeeded ! !
!DrGMorph methodsFor: 'testing' stamp: 'hlsf 9/23/2021 11:44:49'!
canBeDrawn
^ self visible! !
!DrGMorph methodsFor: 'testing' stamp: 'hlsf 3/9/2023 12:37:27'!
containsPoint: localPoint
^self canBeDrawn and: [self isCloserThan: 5 toPixel: (self drawable morphPositionInWorld + localPoint)]! !
!DrGMorph methodsFor: 'testing' stamp: 'hlsf 3/9/2023 14:37:10'!
containsPointInWorld: localPoint
"General expensive version done in DrGeo coordinates. Only used with some morphs.
Other straight line morph use VectorGraphics detection, see contrainsPoint:"
| worldPoint closestPoint |
self canBeDrawn ifFalse: [^ false].
worldPoint _ self drawable morphToWorld: localPoint .
closestPoint _ mathItem closestPointTo: worldPoint.
^ (closestPoint squaredDistanceTo: worldPoint ) <= (self drawable pixelToWorld: 5) squared
! !
!DrGMorph methodsFor: 'testing' stamp: 'hlsf 8/5/2021 15:08:51'!
isDrawNeeded
^ self itemExist and: [style isNotHidden or: [self isForceVisible]]
! !
!DrGMorph methodsFor: 'testing' stamp: 'hlsf 4/3/2021 20:19:09'!
isForceVisible
^ self presenter isForceVisible ! !
!DrGMorph methodsFor: 'testing' stamp: 'hlsf 4/28/2021 20:02:05'!
isLockable
^mathItem
ifNil: [false]
ifNotNil: [mathItem isLockable]! !
!DrGMorph methodsFor: 'testing' stamp: 'hlsf 4/24/2021 20:15:16'!
isLocked
^ self isLockable and: [mathItem isLocked]! !
!DrGMorph methodsFor: 'testing' stamp: 'hlsf 5/24/2023 17:55:40'!
isNotForAway
"If not attached to a drawable, considers it not far away, likely used for an icon"
^ self drawable isNil! !
!DrGMorph methodsFor: 'testing' stamp: 'hlsf 8/5/2021 15:08:34'!
itemExist
"If there is not mathItem model, we just respond true"
^ mathItem
ifNil: [true]
ifNotNil: [mathItem exist]! !
!DrGMorph methodsFor: 'testing' stamp: 'hlsf 4/27/2021 20:59:19'!
requiresVectorCanvas
^ true! !
!DrGMorph methodsFor: 'testing' stamp: 'hlsf 8/4/2021 10:56:36'!
wantsContour
^ true! !
!DrGMorph methodsFor: 'testing type' stamp: 'hlsf 4/4/2021 14:20:32'!
isAngle
^ false! !
!DrGMorph methodsFor: 'testing type' stamp: 'hlsf 4/4/2021 14:20:36'!
isArc
^ false! !
!DrGMorph methodsFor: 'testing type' stamp: 'hlsf 4/4/2021 14:20:42'!
isBitmap
^ false! !
!DrGMorph methodsFor: 'testing type' stamp: 'hlsf 4/4/2021 14:20:47'!
isCircle
^ false! !
!DrGMorph methodsFor: 'testing type' stamp: 'hlsf 4/4/2021 14:20:52'!
isCurve
^ false! !
!DrGMorph methodsFor: 'testing type' stamp: 'hlsf 4/4/2021 14:20:56'!
isFinitCurve
^ false! !
!DrGMorph methodsFor: 'testing type' stamp: 'hlsf 4/4/2021 14:21:00'!
isLine
^ false! !
!DrGMorph methodsFor: 'testing type' stamp: 'hlsf 4/4/2021 14:21:09'!
isLocus
^ false! !
!DrGMorph methodsFor: 'testing type' stamp: 'hlsf 4/4/2021 14:21:13'!
isPoint
^ false! !
!DrGMorph methodsFor: 'testing type' stamp: 'hlsf 4/4/2021 14:19:20'!
isRay
^ false! !
!DrGMorph methodsFor: 'testing type' stamp: 'hlsf 4/4/2021 14:19:26'!
isSegment
^ false! !
!DrGMorph methodsFor: 'testing type' stamp: 'hlsf 4/6/2021 19:32:15'!
isText
^ false! !
!DrGMorph methodsFor: 'testing type' stamp: 'hlsf 4/4/2021 14:20:18'!
isValue
^ false! !
!DrGMorph methodsFor: 'testing type' stamp: 'hlsf 4/4/2021 14:20:23'!
isVector
^ false! !
!DrGMorph methodsFor: 'updating' stamp: 'drgeo 9/10/2022 14:43:34'!
forceHiddenColor
color _ DrGTypeColor hiddenColor.
! !
!DrGMorph methodsFor: 'updating' stamp: 'drgeo 9/10/2022 14:44:16'!
forcedVisibility: aBoolean
"We force this hidden morph to be visible.
Necessary when one wants to edit the style of an hidden morph
In the process we change its color to inform the user this is a hidden item temporaly set visible."
style isNotHidden ifTrue: [^false].
aBoolean
ifTrue:
[self forceHiddenColor.
self show]
ifFalse:
[self hide.
self restoreNormalColor].
^true! !
!DrGMorph methodsFor: 'updating' stamp: 'hlsf 4/13/2021 14:42:56'!
hide
super hide.
labelMorph ifNotNil: [labelMorph hide].! !
!DrGMorph methodsFor: 'updating' stamp: 'drgeo 9/10/2022 14:44:04'!
restoreNormalColor
color _ style color! !
!DrGMorph methodsFor: 'updating' stamp: 'hlsf 4/18/2021 08:50:14'!
show
super show.
labelMorph ifNotNil: [
labelMorph show.
labelMorph morphPosition: self labelPosition] ! !
!DrGMorph methodsFor: 'updating' stamp: 'hlsf 4/3/2021 20:04:44'!
toggleLocked
self isLockable ifTrue: [
mathItem locked: mathItem isLocked not]! !
!DrGMorph methodsFor: 'updating' stamp: 'hlsf 4/13/2021 14:41:36'!
unhide
"make this morph visible in case it was hidden"
style isHidden ifTrue: [
self forcedVisibility: true.
style hidden: false]! !
!DrGMorph methodsFor: 'updating' stamp: 'hlsf 8/3/2023 20:53:00'!
update: object
self presenter saved: false.
"morph or canvas redraw?"
self flag: #drgeoTodo.
self redrawNeeded ! !
!DrGMorph methodsFor: 'updating' stamp: 'hlsf 6/5/2021 11:53:08'!
updateToInvisible
self hide! !
!DrGMorph methodsFor: 'updating' stamp: 'hlsf 6/5/2021 11:53:16'!
updateToVisible
style isNotHidden ifTrue: [ self show ]! !
!DrGMorph methodsFor: 'xml writting' stamp: 'hlsf 3/28/2022 14:09:31'!
writeAsXmlTo: aNode
"We wrote from the morph because it knows the model, the view and the style"
self writeAttributesTo: (mathItem writeAsXmlTo: aNode)! !
!DrGMorph methodsFor: 'xml writting' stamp: 'hlsf 3/28/2022 14:10:27'!
writeAttributesTo: aNode
aNode attributeAt: #delta put: labelPositionDelta asString.
self isLockable ifTrue: [
aNode attributeAt: #locked put: mathItem isLocked asString capitalized].
style writeAttributesTo: aNode.
! !
!DrGMorph class methodsFor: 'instance creation' stamp: 'hlsf 8/4/2023 11:03:41'!
for: aMathItem in: aDrawable
^ (aMathItem morphClass basicNew)
drawable: aDrawable ;
mathItem: aMathItem;
initialize;
addMyMorph;
redrawNeeded;
yourself! !
!DrGMorph class methodsFor: 'new-morph participation' stamp: 'hlsf 3/15/2022 21:31:32'!
includeInNewMorphMenu
^ false! !
!DrGAngleGeometricMorph methodsFor: 'accessing' stamp: 'hlsf 9/25/2021 14:38:58'!
constrainedLabelPosition: aPoint
"Does nothing the label position is not user moveable"! !
!DrGAngleGeometricMorph methodsFor: 'accessing' stamp: 'hlsf 3/18/2023 19:45:14'!
labelMorph: object
"No label morph for angle"! !
!DrGAngleGeometricMorph methodsFor: 'accessing' stamp: 'hlsf 9/25/2021 14:34:05'!
length
^ length ifNil: [
self canComputeArcData.
length]! !
!DrGAngleGeometricMorph methodsFor: 'accessing' stamp: 'hlsf 4/7/2021 10:46:31'!
roundedValueString
^ mathItem degreeAngle rounded asString, '°'.! !
!DrGAngleGeometricMorph methodsFor: 'accessing' stamp: 'hlsf 6/5/2021 20:16:48'!
styleClass
^ DrGValueStyle ! !
!DrGAngleGeometricMorph methodsFor: 'testing type' stamp: 'hlsf 4/7/2021 10:46:20'!
isAngle
^ true! !
!DrGAngleGeometricMorph methodsFor: 'label' stamp: 'hlsf 9/25/2021 14:34:10'!
labelPosition
|angle|
angle _ self length negated / 2 + origin negated.
^ (self drawable worldToMorph: center) + (35 * (angle cos @ angle sin))! !
!DrGAngleGeometricMorph methodsFor: 'drawing' stamp: 'hlsf 5/15/2021 10:51:54'!
canComputeArcData
" Check the angle can be computed and compute its origin and length in radian "
| parents end |
parents _ mathItem parents.
center _ parents second point.
vector1 _ parents first point - center.
vector2 _ parents third point - center.
(vector1 = (0@0) or: [vector2 = (0@0)]) ifTrue: [^false].
origin _ vector1 y asFloat arcTan: vector1 x.
end _ vector2 y asFloat arcTan: vector2 x.
origin < 0 ifTrue: [origin _ origin + Float twoPi].
end < 0 ifTrue: [end _ end + Float twoPi].
length _ (end - origin) cos arcCos.
(end - origin > Float pi or: [end - origin < 0 and: [end - origin > Float pi negated]])
ifTrue: [length _ length negated].
^ true! !
!DrGAngleGeometricMorph methodsFor: 'drawing' stamp: 'hlsf 6/5/2021 10:01:36'!
drawArcOn: canvas
| radius |
radius _ self drawable pixelToWorld: 15.
vector1 _ self drawable worldToMorph: (center + (radius * vector1 / vector1 r)).
vector2 _ self drawable worldToMorph: (center + (radius * vector2 / vector2 r)).
canvas strokeWidth: 1 color: style color do: [
canvas moveTo: vector1.
canvas
arcTo: vector2
radius: 15
angleOfXAxis: 0
largeFlag: (length abs > `Float pi`)
sweepFlag: length negative ]! !
!DrGAngleGeometricMorph methodsFor: 'drawing' stamp: 'hlsf 6/5/2021 14:41:00'!
drawOn: canvas
| angleString font |
self isDrawNeeded ifFalse: [^ self].
self canComputeArcData ifFalse: [^ self].
self updateLabelStatus.
(mathItem radianAngle closeTo: Float halfPi)
ifTrue: [self drawRecOn: canvas]
ifFalse: [self drawArcOn: canvas].
font _ DrGeoSystem canvasFont.
angleString _ self roundedValueString.
canvas
drawString: angleString
at: self labelPosition - ((font widthOfString: angleString) @ font pointSize / 2.0)
font: font
color: color.! !
!DrGAngleGeometricMorph methodsFor: 'drawing' stamp: 'hlsf 6/5/2021 10:01:59'!
drawRecOn: canvas
| size p |
size _ self drawable pixelToWorld: 10.
vector1 _ self drawable vectorToMorph: (size * vector1 / vector1 r).
vector2 _ self drawable vectorToMorph: (size * vector2 / vector2 r).
screenCenter _ self drawable worldToMorph: center.
canvas strokeWidth: 1 color: style color do: [
p _ screenCenter + vector1.
canvas moveTo: p.
p _ p + vector2.
canvas lineTo: p.
p _ screenCenter + vector2.
canvas lineTo: p ]
! !
!DrGAngleOrientedMorph methodsFor: 'drawing' stamp: 'hlsf 5/15/2021 10:55:35'!
canComputeArcData
|parents |
parents _ mathItem parents.
center _ parents second point.
vector1 _ parents first point - center.
vector2 _ parents third point - center.
(vector1 = (0@0) or: [vector2 = (0@0)]) ifTrue: [^false].
origin _ vector1 y asFloat arcTan: vector1 x.
(length _ mathItem radianAngle) < 0 ifTrue: [ length _ length + Float twoPi].
^ true! !
!DrGBitmapMorph methodsFor: 'accessing'!
extent
"defined by my paint, cannot change"
self extent: paintResource getCheckedResource extent.
^ bounds extent! !
!DrGBitmapMorph methodsFor: 'accessing' stamp: 'hlsf 12/9/2022 22:18:01'!
extent: aPoint
" | newExtent |
newExtent _ (self borderWidth * 2) asPoint + (aPoint * costume myScale) asIntegerPoint.
(bounds extent closeTo: newExtent ) ifTrue: [ ^self ].
self changed.
bounds _ (bounds topLeft extent: newExtent).
self layoutChanged.
self changed."! !
!DrGBitmapMorph methodsFor: 'accessing' stamp: 'hlsf 4/6/2021 19:08:59'!
isAnyCornerIn: aPoint
"is aPoint belong to one of the corners of extent 24, if so return its symbole otherwise nil"
((self location extent: 24@24) containsPoint: aPoint) ifTrue: [^#topLeft].
((self topRight - (24@0) extent: 24@24) containsPoint: aPoint) ifTrue: [^#topRight].
((self bottomRight - 24 extent: 24@24) containsPoint: aPoint) ifTrue: [^ #bottomRight].
((self bottomLeft - (0@16) extent: 24@24) containsPoint: aPoint) ifTrue: [^ #bottomLeft].
^ nil! !
!DrGBitmapMorph methodsFor: 'accessing' stamp: 'hlsf 4/6/2021 19:07:08'!
myScale
^ self drawable scale * mathItem magnifiedScale! !
!DrGBitmapMorph methodsFor: 'accessing'!
paintResource: anAthensPaint
paintResource _ anAthensPaint .
self changed! !
!DrGBitmapMorph methodsFor: 'drawing' stamp: 'hlsf 4/6/2021 19:06:52'!
redraw
super redraw
ifFalse: [^self].
self center: (self drawable worldToMorph: mathItem position).! !
!DrGBitmapMorph methodsFor: 'label' stamp: 'hlsf 5/29/2021 17:18:41'!
constrainedLabelPosition: aVector
self computeLabelPositionDelta: aVector
! !
!DrGBitmapMorph methodsFor: 'label' stamp: 'hlsf 4/6/2021 19:07:19'!
labelPosition
^(self drawable worldToMorph: mathItem topCenter) + labelPositionDelta ! !
!DrGBitmapMorph methodsFor: 'initialize-release' stamp: 'hlsf 4/6/2021 19:10:01'!
initialize
super initialize.
previousScale _ mathItem insertAtScale.
previousMagnify _ mathItem magnifyBy.
style color: Color black! !
!DrGBitmapMorph methodsFor: 'testing type' stamp: 'hlsf 4/6/2021 19:10:42'!
isBitmap
^ true! !
!DrGCurveMorph methodsFor: 'accessing' stamp: 'hlsf 4/4/2021 19:06:06'!
anchorAbscissa: number
anchorAbscissa _ number ! !
!DrGCurveMorph methodsFor: 'accessing' stamp: 'hlsf 5/23/2021 13:13:59'!
borderColor: aColor
borderColor _ aColor ! !
!DrGCurveMorph methodsFor: 'accessing' stamp: 'hlsf 12/2/2021 10:53:50'!
borderWidth: pixels
borderWidth _ pixels! !
!DrGCurveMorph methodsFor: 'dashes' stamp: 'hlsf 8/5/2021 15:41:30'!
dashedBorder: dashSpec
dashedBorder _ dashSpec.! !
!DrGCurveMorph methodsFor: 'initialize-release' stamp: 'hlsf 8/5/2023 14:46:17'!
initialize
anchorAbscissa := 0.5.
super initialize.
borderColor := style borderColor.
borderWidth := style borderWidth.
color := style color! !
!DrGCurveMorph methodsFor: 'label' stamp: 'hlsf 5/29/2021 17:18:35'!
constrainedLabelPosition: aPosition
| center |
center _ mathItem closestPointTo: (self drawable morphToWorld: aPosition).
anchorAbscissa _ mathItem abscissaOf: center.
center _ self drawable worldToMorph: center.
self computeLabelPositionDelta: aPosition - center.
! !
!DrGCurveMorph methodsFor: 'label' stamp: 'hlsf 4/4/2021 19:08:17'!
labelPosition
^(self drawable worldToMorph: (mathItem pointAt: anchorAbscissa)) + labelPositionDelta! !
!DrGCurveMorph methodsFor: 'stepping and presenter' stamp: 'hlsf 6/3/2022 11:37:41'!
step
blink ifFalse: [^self].
super step.
borderColor = DrGTypeColor blinkingColor
ifTrue: [borderColor _ style borderColor]
ifFalse: [borderColor _ DrGTypeColor blinkingColor]! !
!DrGCurveMorph methodsFor: 'testing type' stamp: 'hlsf 4/4/2021 19:06:59'!
isCurve
^ true! !
!DrGCurveMorph methodsFor: 'testing type' stamp: 'hlsf 5/23/2021 13:06:53'!
styleClass
^ DrGCurveStyle! !
!DrGCurveMorph methodsFor: 'xml writting' stamp: 'hlsf 3/28/2022 14:12:04'!
writeAttributesTo: aNode
aNode attributeAt: #anchor put: anchorAbscissa asString.
super writeAttributesTo: aNode.
! !
!DrGCurveMorph methodsFor: 'updating' stamp: 'drgeo 9/10/2022 14:50:30'!
forceHiddenColor
color _ (style isFilled ifTrue: [DrGTypeColor hiddenColor] ifFalse: [Color transparent]).
borderColor _ DrGTypeColor hiddenColor.! !
!DrGCurveMorph methodsFor: 'updating' stamp: 'drgeo 9/10/2022 14:48:46'!
restoreNormalColor
color _ (style isFilled ifTrue: [style color] ifFalse: [Color transparent]).
borderColor _ style borderColor! !
!DrGArcMorph methodsFor: 'testing type' stamp: 'hlsf 4/4/2021 19:23:09'!
isArc
^ true! !
!DrGArcMorph methodsFor: 'accessing' stamp: 'hlsf 6/17/2021 17:58:25'!
arrow: aSymbol
self flag: #drgeo! !
!DrGArcMorph methodsFor: 'accessing' stamp: 'hlsf 4/7/2021 19:55:02'!
styleClass
^DrGArcStyle! !
!DrGArcMorph methodsFor: 'drawing' stamp: 'hlsf 5/31/2023 18:18:42'!
drawOn: canvas
| center start end mid r orientation alpha1 alpha2 largeFlag |
self isDrawNeeded ifFalse: [^ self].
self updateLabelStatus.
start := self drawable worldToMorph: (mathItem pointAt: 0).
mid := self drawable worldToMorph: (mathItem pointAt: 0.5).
end := self drawable worldToMorph: (mathItem pointAt: 1).
center := self drawable worldToMorph: mathItem center.
alpha1 := ((mid - center) theta radiansToDegrees - (start - center) theta radiansToDegrees) \\ 360.
alpha2 := ((end - center) theta radiansToDegrees - (start - center) theta radiansToDegrees) \\ 360.
r := self drawable worldToPixel: mathItem radius.
alpha1 > alpha2 ifTrue: [ alpha2 := alpha2 - 360].
orientation := mathItem length negative.
largeFlag := alpha2 abs > 180.
style isFilled
ifTrue: [
canvas strokeWidth: borderWidth color: borderColor fillColor: color do: [
canvas moveTo: start;
arcTo: end radius: r angleOfXAxis: 0
largeFlag: largeFlag sweepFlag: orientation ] ]
ifFalse: [
canvas strokeWidth: borderWidth color: borderColor
strokeDashArray: dashedBorder strokeDashArrayOffset: 0.0 do: [
canvas moveTo: start;
arcTo: end radius: r angleOfXAxis: 0
largeFlag: largeFlag sweepFlag: orientation ] ]! !
!DrGArcMorph methodsFor: 'drawing' stamp: 'hlsf 5/31/2023 16:55:35'!
drawOn: canvas from: start to: end radius: r lF: largeFlag sF: orientation
canvas moveTo: start;
arcTo: end radius: r angleOfXAxis: 0 largeFlag: largeFlag sweepFlag: orientation ! !
!DrGArcMorph methodsFor: 'testing' stamp: 'hlsf 3/9/2023 14:36:14'!
containsPoint: localPoint
^ self containsPointInWorld: localPoint! !
!DrGCircleMorph methodsFor: 'drawing' stamp: 'hlsf 5/31/2023 18:22:44'!
drawCircleOn: aCanvas
| center r |
center := self drawable worldToMorph: mathItem center.
r := self drawable worldToPixel: mathItem radius.
style isFilled
ifTrue: [
aCanvas strokeWidth: borderWidth color: borderColor fillColor: color do: [
aCanvas circleCenter: center radius: r] ]
ifFalse: [
aCanvas strokeWidth: borderWidth color: borderColor
strokeDashArray: dashedBorder strokeDashArrayOffset: 0.0 do: [
aCanvas circleCenter: center radius: r] ]! !
!DrGCircleMorph methodsFor: 'drawing' stamp: 'hlsf 5/31/2023 18:28:44'!
drawLineOn: aCanvas
| origin u points area |
area := self drawable.
origin := mathItem closestPointTo:
(area morphToWorld: self activeHand morphPosition - area morphPositionInWorld).
u := (mathItem pointAt: (mathItem abscissaOf: origin) + 0.01) - origin.
points := DrGLineMorph
extend: (area worldToMorph: origin)
inDirection: (area vectorToMorph: u)
toBorder: area morphExtent.
points size = 2 ifTrue: [
aCanvas strokeWidth: borderWidth color: borderColor
strokeDashArray: dashedBorder strokeDashArrayOffset: 0.0 do: [
aCanvas moveTo: points first; lineTo: points second ] ]! !
!DrGCircleMorph methodsFor: 'drawing' stamp: 'hlsf 3/9/2023 12:27:46'!
drawOn: aCanvas
self isDrawNeeded ifFalse: [^ self].
self updateLabelStatus.
self isDrawnAsCircle
ifTrue: [self drawCircleOn: aCanvas]
ifFalse: [self drawLineOn: aCanvas]
! !
!DrGCircleMorph methodsFor: 'accessing' stamp: 'hlsf 4/7/2021 19:55:13'!
styleClass
^DrGCircleStyle! !
!DrGCircleMorph methodsFor: 'testing' stamp: 'hlsf 3/9/2023 14:36:14'!
containsPoint: localPoint
^ self containsPointInWorld: localPoint! !
!DrGCircleMorph methodsFor: 'testing' stamp: 'hlsf 3/9/2023 12:27:08'!
isDrawnAsCircle
^ mathItem radius < 1e5 ! !
!DrGCircleMorph methodsFor: 'testing type' stamp: 'hlsf 4/4/2021 19:19:51'!
isCircle
^ true! !
!DrGPolylineMorph methodsFor: 'accessing' stamp: 'hlsf 5/30/2021 09:53:25'!
getVertices
"Write here how to fetch the vertices"! !
!DrGPolylineMorph methodsFor: 'accessing' stamp: 'hlsf 3/15/2023 17:56:01'!
labelMorph: aString
"Dirty. No label morph for Polyline morph, it is an abstract morph
May be create a sister class out of this hierarchy "
self class == DrGPolylineMorph ifFalse: [super labelMorph: aString]! !
!DrGPolylineMorph methodsFor: 'accessing' stamp: 'hlsf 7/3/2020 13:00:04'!
lineSegmentsDo: endPointsBlock
"Emit a sequence of segment endpoints into endPointsBlock."
| beginPoint |
vertices size < 1
ifTrue: [^ self].
"test too few vertices first"
beginPoint _ nil.
vertices do: [:vert |
beginPoint ifNotNil: [
endPointsBlock value: beginPoint value: vert].
beginPoint _ vert].
(closed or: [vertices size = 1]) ifTrue: [
endPointsBlock value: beginPoint value: vertices first].
! !
!DrGPolylineMorph methodsFor: 'accessing' stamp: 'hlsf 7/3/2020 13:00:34'!
nextToFirstPoint
"For arrow direction"
^ vertices second! !
!DrGPolylineMorph methodsFor: 'accessing' stamp: 'hlsf 7/3/2020 13:00:57'!
nextToLastPoint
"For arrow direction"
^ vertices at: vertices size - 1! !
!DrGPolylineMorph methodsFor: 'accessing'!
vertices
^ vertices! !
!DrGPolylineMorph methodsFor: 'accessing' stamp: 'hlsf 5/16/2021 21:24:17'!
vertices: newVertices
vertices _ newVertices.! !
!DrGPolylineMorph methodsFor: 'arrow' stamp: 'hlsf 2/12/2022 15:46:40'!
arrow: aSymbol
"Accepted values: #none #back #forward #both "
arrows _ aSymbol ! !
!DrGPolylineMorph methodsFor: 'arrow' stamp: 'hlsf 12/2/2021 10:48:25'!
arrowBoundsAt: endPoint from: priorPoint
"Answer a triangle oriented along the line from priorPoint to endPoint."
| d v angle wingBase arrowSpec length width |
v _ endPoint - priorPoint.
angle _ v degrees.
d _ borderWidth max: 1.
arrowSpec _ self valueOfProperty: #arrowSpec ifAbsent: [DrGPolylineMorph defaultArrowSpec].
length _ arrowSpec x abs. width _ arrowSpec y abs.
wingBase _ endPoint + (Point r: d * length degrees: angle + 180.0).
arrowSpec x >= 0
ifTrue: [^ { endPoint.
wingBase + (Point r: d * width degrees: angle + 125.0).
wingBase + (Point r: d * width degrees: angle - 125.0) }]
ifFalse: ["Negative length means concave base."
^ { endPoint.
wingBase + (Point r: d * width degrees: angle + 125.0).
wingBase.
wingBase + (Point r: d * width degrees: angle - 125.0) }]! !
!DrGPolylineMorph methodsFor: 'arrow' stamp: 'hlsf 7/4/2020 11:14:59'!
arrowSpec: specPt
"Specify a custom arrow for this line.
specPt x abs gives the length of the arrow (point to base) in terms of borderWidth.
If specPt x is negative, then the base of the arrow will be concave.
specPt y abs gives the width of the arrow.
The standard arrow is equivalent to arrowSpec: PolygonMorph defaultArrowSpec.
See arrowBoundsAt:From: for details."
self setProperty: #arrowSpec toValue: specPt! !
!DrGPolylineMorph methodsFor: 'arrow'!
hasArrows
"Are all the conditions meet for having arrows?"
^ (closed or: [arrows == #none or: [vertices size < 2]]) not! !
!DrGPolylineMorph methodsFor: 'arrow' stamp: 'hlsf 7/4/2020 11:14:14'!
standardArrows
self removeProperty: #arrowSpec.! !
!DrGPolylineMorph methodsFor: 'drawing' stamp: 'hlsf 7/4/2020 14:24:56'!
adjustSegmentPointsForArrows
" In the list of vertices, adjust first and last entry if this polygon uses arrows.
Returned the adjusted vertices, and if any the arrow bound"
| verts arrowsBound |
self hasArrows ifFalse: [ ^ Array with: vertices with: nil].
verts _ vertices copy.
arrowsBound _ Array new: 2.
(arrows == #back or: [ arrows == #both ])
ifTrue: [ | arrow |
arrow _ self arrowBoundsAt: verts first from: verts second.
arrowsBound at: 1 put: arrow.
arrow size = 4
ifTrue: [ verts at: 1 put: arrow third ]
ifFalse: [ verts at: 1 put: (arrow copyFrom: 2 to: 3) average ] ].
(arrows == #forward or: [ arrows == #both ])
ifTrue: [ | arrow |
arrow _ self arrowBoundsAt: verts last from: (verts at: (verts size - 1)).
arrowsBound at: 2 put: arrow.
arrow size = 4
ifTrue: [ verts at: verts size put: arrow third ]
ifFalse: [ verts at: verts size put: (arrow copyFrom: 2 to: 3) average ] ].
^ Array with: verts with: arrowsBound ! !
!DrGPolylineMorph methodsFor: 'drawing' stamp: 'hlsf 12/2/2021 10:48:34'!
drawArrow: pts on: aCanvas at: endPoint from: priorPoint
"Draw a triangle oriented along the line from priorPoint to
endPoint. Answer the wingBase."
| spec |
spec _ self valueOfProperty: #arrowSpec ifAbsent: [DrGPolylineMorph defaultArrowSpec].
spec x sign = spec y sign
ifTrue: [aCanvas fillColor: borderColor do: [aCanvas polyLine: pts]]
ifFalse:
[aCanvas strokeWidth: (borderWidth + 1) // 2 color: borderColor do: [aCanvas polyLine: pts]].! !
!DrGPolylineMorph methodsFor: 'drawing' stamp: 'hlsf 7/3/2020 22:16:34'!
drawArrows: arrowsBound on: aCanvas
"Answer (possibly modified) endpoints for border drawing"
"ArrowForms are computed only upon demand"
arrowsBound ifNil: [^ self ]. "No arrow"
"backward arrow?"
arrowsBound first ifNotNil: [:arrow |
self drawArrow: arrow on: aCanvas at: vertices first from: self nextToFirstPoint].
"forward arrow?"
arrowsBound second ifNotNil: [ :arrow |
self drawArrow: arrow on: aCanvas at: vertices last from: self nextToLastPoint].
! !
!DrGPolylineMorph methodsFor: 'drawing' stamp: 'hlsf 5/31/2023 19:00:19'!
drawOn: aCanvas
| verticesAndArrows |
self isDrawNeeded ifFalse: [^ false].
self getVertices.
self isNotForAway ifFalse: [
labelMorph ifNotNil: [labelMorph hide].
^ false].
self updateLabelStatus.
vertices size < 1
ifTrue: [self error: 'a polygon must have at least one point'].
verticesAndArrows := self adjustSegmentPointsForArrows.
style isFilled ifTrue: [
aCanvas
strokeWidth: borderWidth
color: borderColor
fillColor: color
do: [aCanvas polyLine: verticesAndArrows first]]
ifFalse: [
aCanvas
strokeWidth: borderWidth
color: borderColor
strokeDashArray: dashedBorder strokeDashArrayOffset: 0.0
do: [aCanvas polyLine: verticesAndArrows first]].
self drawArrows: verticesAndArrows second on: aCanvas.
^ true! !
!DrGPolylineMorph methodsFor: 'geometry' stamp: 'hlsf 8/5/2021 12:22:15'!
closestPointTo: aPoint
| closestPoint minDist |
closestPoint _ minDist _ nil.
self lineSegmentsDo:
[:p1 :p2 | | dist curvePoint |
curvePoint _ aPoint nearestPointOnLineFrom: p1 to: p2.
dist _ curvePoint squaredDistanceTo: aPoint.
(closestPoint isNil or: [dist < minDist])
ifTrue:
[closestPoint _ curvePoint.
minDist _ dist]].
^closestPoint! !
!DrGPolylineMorph methodsFor: 'geometry'!
closestSegmentTo: aPoint
"Answer the starting index of my (big) segment nearest to aPoint"
| closestPoint minDist vertexIndex closestVertexIndex |
vertexIndex _ 0.
closestVertexIndex _ 0.
closestPoint _ minDist _ nil.
self lineSegmentsDo:
[:p1 :p2 | | curvePoint dist |
(p1 = (self vertices at: vertexIndex + 1))
ifTrue: [ vertexIndex _ vertexIndex + 1 ].
curvePoint _ aPoint nearestPointOnLineFrom: p1 to: p2.
dist _ curvePoint distanceTo: aPoint.
(closestPoint isNil or: [dist < minDist])
ifTrue: [closestPoint _ curvePoint.
minDist _ dist.
closestVertexIndex _ vertexIndex. ]].
^ closestVertexIndex! !
!DrGPolylineMorph methodsFor: 'geometry' stamp: 'hlsf 7/4/2020 11:14:00'!
makeClosed
closed _ true! !
!DrGPolylineMorph methodsFor: 'geometry' stamp: 'hlsf 7/3/2020 23:17:40'!
makeOpen
closed _ false.! !
!DrGPolylineMorph methodsFor: 'initialization' stamp: 'hlsf 4/24/2021 19:56:19'!
initialize
super initialize.
closed _ false.
arrows _ #none! !
!DrGPolylineMorph methodsFor: 'initialization' stamp: 'hlsf 8/5/2021 15:35:30'!
vertices: verts color: aColor borderColor: anotherColor
color _ aColor.
borderColor _ anotherColor.
self vertices: verts.
closed _ vertices size > 2.! !
!DrGPolylineMorph methodsFor: 'initialization' stamp: 'hlsf 8/5/2021 15:35:40'!
vertices: verts color: aColor borderWidth: width borderColor: anotherColor
borderWidth _ width.
self vertices: verts color: aColor borderColor: anotherColor ! !
!DrGPolylineMorph methodsFor: 'testing' stamp: 'hlsf 5/24/2023 17:52:39'!
isNotForAway
" are all vertices in expanded screen area ?"
| expandedBound |
^ super isNotForAway or: [
expandedBound := self drawable morphLocalBounds expandBy: 10000.
vertices allSatisfy: [:v | expandedBound containsPoint: v ] ]! !
!DrGPolylineMorph class methodsFor: 'examples' stamp: 'hlsf 5/23/2021 13:07:37'!
example1
"self example1"
^ DrGPolylineMorph
vertices: {61@100. 88@219. 102@95. 22@50. 41@83}
color: Color blue
borderColor: Color black! !
!DrGPolylineMorph class methodsFor: 'examples' stamp: 'hlsf 5/23/2021 13:17:21'!
example2
"self example2"
^ DrGPolylineMorph
vertices: {61@100. 88@219. 102@95. 22@50. 41@83}
color: Color red
borderColor: Color black.! !
!DrGPolylineMorph class methodsFor: 'examples' stamp: 'hlsf 5/23/2021 13:07:44'!
example3
"self example3"
| poly |
poly _ DrGPolylineMorph
vertices: {61@100. 88@219. 102@95. 22@50. 41@83}
color: Color blue
borderColor: Color black.
poly makeOpen.
^ poly ! !
!DrGPolylineMorph class methodsFor: 'examples' stamp: 'hlsf 5/23/2021 13:07:50'!
example4
"self example4"
| poly |
poly _ (DrGPolylineMorph
vertices: {61@100. 88@219. 102@95. 22@50. 41@83}
color: Color blue
borderColor: Color black).
poly dashedBorder: { 5 .
5.
Color red.
50 .
0 }.
^ poly ! !
!DrGPolylineMorph class methodsFor: 'instance creation' stamp: 'hlsf 2/12/2022 15:48:22'!
arrowPrototype
"Answer an instance of the receiver that will serve as a prototypical arrow"
"DrGPolylineMorph arrowPrototype openInWorld"
| aa |
aa _ self vertices: (Array with: 0@0 with: 40@40)
color: Color black
borderWidth: 2
borderColor: Color black.
aa arrow: #forward.
^ aa! !
!DrGPolylineMorph class methodsFor: 'instance creation' stamp: 'hlsf 8/4/2023 11:02:11'!
from: start to: end color: lineColor width: width in: aDrawable
| instance |
instance := self new vertices: {start. end} color: nil borderWidth: width borderColor: lineColor.
instance drawable: aDrawable .
^ instance ! !
!DrGPolylineMorph class methodsFor: 'instance creation' stamp: 'hlsf 5/23/2021 13:19:38'!
vertices: verts color: c borderColor: bc
"(DrGPolylineMorph
vertices: {261@400. 388@519. 302@595. 222@500. 141@583. 34@444}
color: Color red
borderColor: Color yellow) openInWorld"
^ self new vertices: verts color: c borderColor: bc! !
!DrGPolylineMorph class methodsFor: 'settings'!
defaultArrowSpec
^ 5@4! !
!DrGCurveStraightMorph methodsFor: 'accessing' stamp: 'hlsf 7/4/2020 11:15:11'!
from: startPoint to: endPoint
vertices at: 1 put: startPoint.
vertices at: 2 put: endPoint.
! !
!DrGCurveStraightMorph methodsFor: 'initialization' stamp: 'hlsf 4/24/2021 20:16:46'!
initialize
super initialize.
vertices _ Array new: 2.! !
!DrGCurveStraightMorph class methodsFor: 'instance creation' stamp: 'hlsf 2/11/2022 10:37:09'!
from: start to: end color: color
^ self new ::
from: start to: end;
borderColor: color
! !
!DrGLineMorph methodsFor: 'accessing' stamp: 'hlsf 4/30/2021 22:14:15'!
from: origin direction: u
| points |
points _ self class extend: origin inDirection: u toBorder: self drawable morphExtent.
points size < 2
ifTrue: [self from: `-1 @0` to: `-1 @0` "off-limit, empy draw"]
ifFalse: [ self from: points first to: points second]! !
!DrGLineMorph methodsFor: 'accessing' stamp: 'hlsf 5/30/2021 09:54:00'!
getVertices
self
from: (self drawable worldToMorph: mathItem origin)
direction: (self drawable vectorToMorph: mathItem direction).
! !
!DrGLineMorph methodsFor: 'accessing' stamp: 'hlsf 4/7/2021 19:55:40'!
styleClass
^DrGLineStyle! !
!DrGLineMorph methodsFor: 'testing type' stamp: 'hlsf 4/4/2021 19:36:34'!
isLine
^ true! !
!DrGLineMorph class methodsFor: 'helper' stamp: 'hlsf 4/30/2021 22:13:01'!
extend: origin inDirection: u toBorder: extent
| points c ex ey coordinate |
points _ OrderedCollection new.
c _ (origin x * u y - (origin y * u x)) asFloat.
ex _ extent x.
ey _ extent y.
"Intersections with horizontal borders A, B"
"A"
[coordinate _ (extent y * u x + c) / u y] on: ZeroDivide do: [coordinate _ -1].
(coordinate between: 0 and: ex) ifTrue: [points add: coordinate @ ey].
"B"
[coordinate _ c / u y] on: ZeroDivide do: [coordinate _ -1].
(coordinate between: 0 and: ex) ifTrue: [points add: coordinate @ 0].
"Vertical borders P, Q"
"P"
[coordinate _ c negated / u x] on: ZeroDivide do: [coordinate _ -1].
(coordinate between: 0 and: ey) ifTrue: [points add: 0 @ coordinate].
"Q"
[coordinate _ (ex * u y) - c / u x] on: ZeroDivide do: [coordinate _ -1].
(coordinate between: 0 and: ey) ifTrue: [points add: ex @ coordinate].
^ points
! !
!DrGRayMorph methodsFor: 'accessing' stamp: 'hlsf 3/26/2022 10:43:58'!
extendFrom: origin direction: u
| border r borderY |
r _ u x asFloat / u y.
u y > 0
ifTrue: [
borderY _ self drawable morphExtent y.
border _ (borderY - origin y) * r + origin x @ borderY]
ifFalse: [ border _ (0 - origin y) * r + origin x @ 0].
self from: origin to: border! !
!DrGRayMorph methodsFor: 'accessing' stamp: 'hlsf 1/3/2022 10:02:31'!
extendHorizontally: origin direction: u
| border |
u x > 0
ifTrue: [ border _ self drawable morphExtent x @ origin y ]
ifFalse: [ border _ 0 @ origin y ].
self from: origin to: border! !
!DrGRayMorph methodsFor: 'accessing'!
from: aPoint direction: u
u y abs < 0.001
ifTrue: [self extendHorizontally: aPoint direction: u]
ifFalse: [self extendFrom: aPoint direction: u]! !
!DrGRayMorph methodsFor: 'accessing' stamp: 'hlsf 5/30/2021 09:55:25'!
getVertices
self
from: (self drawable worldToMorph: mathItem origin)
direction: (self drawable vectorToMorph: mathItem direction).
! !
!DrGRayMorph methodsFor: 'accessing' stamp: 'hlsf 4/7/2021 19:55:56'!
styleClass
^DrGRayStyle! !
!DrGRayMorph methodsFor: 'testing type' stamp: 'hlsf 4/5/2021 10:38:28'!
isRay
^ true! !
!DrGSegmentMorph methodsFor: 'accessing' stamp: 'hlsf 5/30/2021 09:56:14'!
getVertices
self
from: (self drawable worldToMorph: mathItem origin)
to: (self drawable worldToMorph: mathItem origin + mathItem direction).
! !
!DrGSegmentMorph methodsFor: 'accessing' stamp: 'hlsf 4/7/2021 19:55:32'!
styleClass
^DrGSegmentStyle! !
!DrGSegmentMorph methodsFor: 'drawing' stamp: 'hlsf 12/2/2021 10:48:46'!
drawCircleOn: aCanvas
| center |
center _ vertices first + vertices second / 2.0.
aCanvas strokeWidth: borderWidth color: borderColor do: [
aCanvas circleCenter: center radius: 2 + borderWidth]! !
!DrGSegmentMorph methodsFor: 'drawing' stamp: 'hlsf 12/2/2021 10:47:52'!
drawDiscOn: aCanvas
| center |
center _ vertices first + vertices second / 2.0.
aCanvas fillColor: borderColor do: [
aCanvas circleCenter: center radius: 2 + borderWidth]! !
!DrGSegmentMorph methodsFor: 'drawing' stamp: 'hlsf 12/2/2021 10:48:58'!
drawMark1On: aCanvas
|center vector u n startPoint endPoint |
startPoint _ vertices at: 1.
endPoint _ vertices at: 2.
(startPoint squaredDistanceTo: endPoint) < borderWidth squared ifTrue: [^ self].
center _ startPoint + endPoint / 2.0.
vector _ endPoint - startPoint.
[u _ vector normalized] on: ZeroDivide do: [u _ 0@1].
n _ u y @ u x negated.
vector _ (u + n ) normalized * (borderWidth + 1 * 3).
aCanvas
line: center - vector
to: center + vector
width: borderWidth
color: borderColor.! !
!DrGSegmentMorph methodsFor: 'drawing' stamp: 'hlsf 12/2/2021 10:49:13'!
drawMark2On: aCanvas
|center vector u n startPoint endPoint |
startPoint _ vertices at: 1.
endPoint _ vertices at: 2.
(startPoint squaredDistanceTo: endPoint) < (borderWidth * 4) squared ifTrue: [^ self].
vector _ endPoint - startPoint.
[u _ vector normalized] on: ZeroDivide do: [u _ 0@1].
n _ u y @ u x negated.
vector _ (u + n ) normalized * (borderWidth + 1 * 3).
center _ (startPoint + endPoint / 2) - (u * (borderWidth * 1.5)).
2 timesRepeat: [
aCanvas line: center - vector to: center + vector width: borderWidth color: borderColor.
center _ center + (u * (borderWidth * 3))].! !
!DrGSegmentMorph methodsFor: 'drawing' stamp: 'hlsf 12/2/2021 10:49:28'!
drawMark3On: aCanvas
|center vector u n startPoint endPoint |
startPoint _ vertices at: 1.
endPoint _ vertices at: 2.
(startPoint squaredDistanceTo: endPoint) < (borderWidth * 7) squared ifTrue: [^ self].
vector _ endPoint - startPoint.
[u _ vector normalized] on: ZeroDivide do: [u _ 0@1].
n _ u y @ u x negated.
vector _ (u + n ) normalized * (borderWidth + 1 * 3).
center _ (startPoint + endPoint / 2) - (u * (borderWidth * 3)).
3 timesRepeat: [
aCanvas line: center - vector to: center + vector width: borderWidth color: borderColor.
center _ center + (u * (borderWidth * 3))].! !
!DrGSegmentMorph methodsFor: 'drawing' stamp: 'hlsf 1/6/2022 19:56:25'!
drawMarkOn: aCanvas
|mark|
mark _ self style mark.
mark == #none ifTrue: [^self].
mark == #mark1 ifTrue: [^ self drawMark1On: aCanvas].
mark == #mark2 ifTrue: [^ self drawMark2On: aCanvas].
mark == #mark3 ifTrue: [^ self drawMark3On: aCanvas].
mark == #disc ifTrue: [^ self drawDiscOn: aCanvas].
mark == #circle ifTrue: [^ self drawCircleOn: aCanvas].
! !
!DrGSegmentMorph methodsFor: 'drawing' stamp: 'hlsf 1/6/2022 09:39:12'!
drawOn: aCanvas
(super drawOn: aCanvas) ifTrue: [ self drawMarkOn: aCanvas ]
! !
!DrGSegmentMorph methodsFor: 'testing type' stamp: 'hlsf 4/5/2021 11:33:18'!
isSegment
^ true! !
!DrGIconSegmentMorph methodsFor: 'accessing' stamp: 'hlsf 1/6/2022 19:56:50'!
forcedMark: symbol
self style mark: symbol! !
!DrGIconSegmentMorph methodsFor: 'accessing' stamp: 'hlsf 1/6/2022 19:53:52'!
getVertices
"No update of the vertices attributes, use its values as is"! !
!DrGIconSegmentMorph methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 14:56:20'!
initialize
super initialize.
style
mark: #none;
arrow: #none
! !
!DrGIconSegmentMorph methodsFor: 'accessing' stamp: 'hlsf 3/14/2023 21:02:46'!
labelMorph: anObject
"No label morph"! !
!DrGVectorMorph methodsFor: 'initializing' stamp: 'hlsf 2/12/2022 15:47:54'!
initialize
super initialize.
self arrow: #forward! !
!DrGVectorMorph methodsFor: 'testing type' stamp: 'hlsf 4/5/2021 11:36:15'!
isVector
^ true! !
!DrGVectorMorph methodsFor: 'accessing' stamp: 'hlsf 5/30/2021 09:58:05'!
getVertices
self
from: (self drawable worldToMorph: mathItem origin)
to: (self drawable worldToMorph: mathItem origin + mathItem direction).
! !
!DrGVectorMorph methodsFor: 'accessing' stamp: 'hlsf 4/7/2021 19:56:04'!
styleClass
^DrGVectorStyle! !
!DrGLocusMorph methodsFor: 'accessing' stamp: 'hlsf 5/30/2021 15:37:11'!
factory
^ self domain factory! !
!DrGLocusMorph methodsFor: 'accessing' stamp: 'hlsf 5/30/2021 12:31:35'!
getVertices
self free: mathItem freePoint constrained: mathItem constrainedPoint.! !
!DrGLocusMorph methodsFor: 'accessing' stamp: 'hlsf 4/7/2021 19:55:48'!
styleClass
^ DrGLocusStyle! !
!DrGLocusMorph methodsFor: 'initialization' stamp: 'hlsf 9/25/2021 18:18:52'!
initialize
super initialize.
minAbscissaDelta _ 1e-5.
maxScreenDelta _ 64.
maxAbscissaDelta _ 1e-1! !
!DrGLocusMorph methodsFor: 'drawing' stamp: 'hlsf 5/31/2023 20:01:53'!
drawOn: aCanvas
| prevPoint p |
self isDrawNeeded ifFalse: [^ self].
self getVertices.
self canBeDrawn ifFalse: [^ self].
self updateLabelStatus.
prevPoint := vertices first.
aCanvas strokeWidth: borderWidth color: borderColor
strokeDashArray: dashedBorder strokeDashArrayOffset: 0.0 do: [
aCanvas moveTo: prevPoint.
2 to: vertices size do: [:i |
p := vertices at: i.
(prevPoint squaredDistanceTo: p) < 900
ifTrue: [aCanvas lineTo: p]
ifFalse: [aCanvas moveTo: p].
prevPoint := p]
]
! !
!DrGLocusMorph methodsFor: 'sampling' stamp: 'hlsf 8/15/2021 16:20:40'!
free: freeItem constrained: constrainedItem
| link0 link1 x0 validSamples factory |
x0 _ freeItem abscissa.
factory _ self factory.
worldBound _ self drawable worldBound.
free _ freeItem.
constrained _ constrainedItem.
freeIndex _ factory indexOf: free.
constrainedIndex _ factory indexOf: constrained.
"maxAbscissaDelta _ self drawable scale > 100 ifTrue: [1e-4] ifFalse: [1e-3]."
samples _ LinkedList new.
link0 _ samples add: (self sample: minAbscissaDelta ).
link1 _ samples add: (self sample: 1 - minAbscissaDelta) afterLink: link0.
self samplingFrom: link0 to: link1.
validSamples _ self selectValidSamples.
free abscissa: x0.
factory updateAllMathItemsButLocusFrom: freeIndex to: constrainedIndex.
mathItem
points: (validSamples collect: [:s | s pointWorld]);
samplesQty: validSamples size.
vertices _ validSamples collect: [:s | s pointScreen].! !
!DrGLocusMorph methodsFor: 'sampling' stamp: 'hlsf 5/30/2021 15:37:34'!
sample: abscissa
"Create a new sample with the given curvilinear abscissa"
| sample |
sample _ DrGLocusSample new x: abscissa.
free abscissa: abscissa.
self factory updateAllMathItemsButLocusFrom: freeIndex to: constrainedIndex.
(sample isValid: constrained exist) ifTrue:
[sample pointWorld: constrained point;
pointScreen: (self drawable worldToMorph: constrained point);
offScreen: (worldBound containsPoint: constrained point) not].
^ sample! !
!DrGLocusMorph methodsFor: 'sampling' stamp: 'hlsf 9/25/2021 18:09:54'!
samplingFrom: sample1 to: sample2
| newSample screenSamplesDistance samplesDelta|
samplesDelta _ sample2 x - sample1 x.
screenSamplesDistance _ 10.
(samplesDelta > minAbscissaDelta
and: [(sample1 isNotValid or: [sample2 isNotValid])
or: [samplesDelta > maxAbscissaDelta
or: [(screenSamplesDistance _ sample1 pointScreen squaredDistanceTo: sample2 pointScreen) > maxScreenDelta]]])
ifTrue: [
(screenSamplesDistance < 2 and: [samplesDelta < maxAbscissaDelta] ) ifTrue: [^ self].
newSample _ self sample: sample1 x + sample2 x / 2.0.
samples add: newSample afterLink: sample1.
self samplingFrom: sample1 to: newSample.
self samplingFrom: newSample to: sample2 ]! !
!DrGLocusMorph methodsFor: 'sampling' stamp: 'hlsf 5/30/2021 15:46:46'!
selectValidSamples
| validSamples prevLink|
validSamples _ OrderedCollection new.
prevLink _ DrGLocusSample new isValid: false; yourself.
samples linksDo: [:sample |
sample isValidAndOnScreen
ifTrue: [validSamples add: sample]
ifFalse: [
"unvalid or offscreen, in case it is just offscreen check if next/prev sample is on-screen,
so we need this sample for the drawing"
sample isValid ifTrue: [
sample nextLink ifNotNil: [:nextSample |
nextSample isValidAndOnScreen
ifTrue: [validSamples add: sample]
ifFalse: [prevLink isValidAndOnScreen ifTrue: [validSamples add: sample]]
]
]
].
prevLink _ sample].
^ validSamples ! !
!DrGLocusMorph methodsFor: 'testing type' stamp: 'hlsf 4/5/2021 11:22:27'!
isLocus
^ true! !
!DrGLocusMorph methodsFor: 'testing' stamp: 'hlsf 6/5/2021 12:14:34'!
canBeDrawn
^ vertices isEmptyOrNil not! !
!DrGLocusMorph methodsFor: 'testing' stamp: 'hlsf 3/9/2023 14:36:14'!
containsPoint: localPoint
^ self containsPointInWorld: localPoint! !
!DrGLocusMorph methodsFor: 'label' stamp: 'hlsf 6/5/2021 15:05:07'!
updateLabelStatus
"In some circumstance, I may be unable to draw myself. So I need to update my label status accordingly"
labelMorph ifNotNil: [
self isDrawNeeded
ifTrue:[
labelMorph owner ifNil: [self drawable addMorph: labelMorph].
labelMorph show; morphPosition: self labelPosition]
ifFalse: [labelMorph hide] ]! !
!DrGLocusTransformedMorph methodsFor: 'accessing' stamp: 'hlsf 5/31/2021 18:24:46'!
getVertices
vertices _ mathItem points collect: [:point | self drawable worldToMorph: point].! !
!DrGPolygonMorph methodsFor: 'initialization'!
initialize
super initialize.
self makeClosed.! !
!DrGPolygonMorph methodsFor: 'label' stamp: 'hlsf 5/29/2021 17:18:24'!
constrainedLabelPosition: aPoint
|center vector answer|
answer _ mathItem closestPointInfoTo: (self drawable morphToWorld: aPoint).
center _ answer first.
anchorAbscissa _ answer second.
center _ self drawable worldToMorph: center.
vector _ aPoint - center.
self computeLabelPositionDelta: vector.
! !
!DrGPolygonMorph methodsFor: 'accessing' stamp: 'hlsf 5/31/2023 18:10:34'!
getVertices
vertices := mathItem points collect: [:point | self drawable worldToMorph: point].
vertices add: vertices first
! !
!DrGPolygonMorph methodsFor: 'accessing' stamp: 'hlsf 4/7/2021 19:55:22'!
styleClass
^DrGPolygonStyle ! !
!DrGPolygonMorph methodsFor: 'testing' stamp: 'hlsf 3/9/2023 14:36:14'!
containsPoint: localPoint
^ self containsPointInWorld: localPoint! !
!DrGPointMorph methodsFor: 'drawing' stamp: 'hlsf 5/24/2023 18:00:33'!
drawOn: aCanvas
| shape center |
self isDrawNeeded ifFalse: [^ self].
center := self morphCenter.
(self isNotForAway or: [self drawable morphLocalBounds containsPoint: center]) ifFalse: [
labelMorph ifNotNil: [labelMorph hide].
^ false].
self updateLabelStatus.
shape := style shape.
shape == #square ifTrue: [
aCanvas
fillRectangle: (Rectangle center: center extent: style pointExtent)
color: color.
^ self].
shape == #round ifTrue: [
aCanvas fillColor: color do: [ aCanvas circleCenter: center radius: style pointExtent x / 2.0].
^ self].
shape == #cross ifTrue:[ | e |
e := style pointExtent / 2.0.
aCanvas line: center - e to: center + e width: 1.5 color: color.
aCanvas line: center + (e * (-1@1)) to: center + (e * (1@ -1)) width: 1.5 color: color]! !
!DrGPointMorph methodsFor: 'label' stamp: 'hlsf 5/29/2021 17:17:00'!
constrainedLabelPosition: unconstrainedPosition
|center |
center _ self drawable worldToMorph: mathItem point.
self computeLabelPositionDelta: unconstrainedPosition - center
! !
!DrGPointMorph methodsFor: 'label' stamp: 'hlsf 4/5/2021 11:42:02'!
labelPosition
^(self drawable worldToMorph: mathItem point) + labelPositionDelta! !
!DrGPointMorph methodsFor: 'testing type' stamp: 'hlsf 4/5/2021 11:37:24'!
isPoint
^ true! !
!DrGPointMorph methodsFor: 'obselete' stamp: 'hlsf 8/5/2021 14:50:03'!
distanceTo: aPoint
^ self morphCenter dist: aPoint ! !
!DrGPointMorph methodsFor: 'accessing' stamp: 'hlsf 8/5/2021 14:53:56'!
morphCenter
^ self drawable worldToMorph: mathItem point! !
!DrGPointMorph methodsFor: 'accessing' stamp: 'hlsf 4/7/2021 19:56:13'!
styleClass
^DrGPointStyle! !
!DrGIconPointMorph methodsFor: 'accessing' stamp: 'hlsf 3/14/2023 21:02:53'!
labelMorph: anObject
"No label morph"! !
!DrGIconPointMorph methodsFor: 'accessing' stamp: 'hlsf 1/6/2022 21:57:28'!
morphCenter
^ 0@0! !
!DrGTextMorph methodsFor: 'drawing' stamp: 'hlsf 5/24/2023 18:12:07'!
drawFrame: rect on: aCanvas
aCanvas fillRectangle: (rect expandBy: 2)
color: style backgroundColor
borderWidth: 2
borderStyleSymbol: #simple
baseColorForBorder: style borderColor.! !
!DrGTextMorph methodsFor: 'drawing' stamp: 'hlsf 3/18/2023 21:29:52'!
drawOn: aCanvas
| r bound |
self isDrawNeeded ifFalse: [^ self].
self contents: mathItem text.
r := self labelPosition extent: extent.
self drawFrame: r on: aCanvas.
bound := r insetBy: 4.
aCanvas
drawTextComposition: textComposition
at: bound origin
extent: bound extent
color: color
selectionColor: `Color red`.! !
!DrGTextMorph methodsFor: 'accessing' stamp: 'hlsf 5/24/2023 18:41:11'!
compose: aStringOrText
textComposition
setModel: (TextModel withText: aStringOrText);
composeAll.
extent := textComposition usedExtent + 8! !
!DrGTextMorph methodsFor: 'accessing' stamp: 'hlsf 5/24/2023 18:42:11'!
contents: aStringOrText
textComposition textComposed ~= aStringOrText ifTrue: [
self compose: aStringOrText]! !
!DrGTextMorph methodsFor: 'accessing' stamp: 'hlsf 5/24/2023 19:20:10'!
fontSize: aSmallInteger
| text |
textComposition editor: (TextEditor new defaultFont: (DrGeoSystem fontOfSize: aSmallInteger)).
(text := textComposition textComposed) ifEmpty: [^ self].
self compose: text.
self redrawNeeded ! !
!DrGTextMorph methodsFor: 'accessing' stamp: 'hlsf 4/7/2021 19:56:23'!
styleClass
^ DrGTextStyle! !
!DrGTextMorph methodsFor: 'label' stamp: 'hlsf 3/24/2022 11:48:09'!
labelMorph: aString
"There is no label morph for text or value on the canvas"! !
!DrGTextMorph methodsFor: 'label' stamp: 'hlsf 3/24/2022 11:49:42'!
labelPosition
^self drawable worldToMorph: mathItem position! !
!DrGTextMorph methodsFor: 'initialize-release' stamp: 'FJG 11/13/2023 14:41:25'!
initialize
super initialize.
textComposition := TextComposition new.
textComposition
setModel: (TextModel withText: '');
extentForComposing: 9999999@9999999;
composeAll.
" Taken from DrGTextMorph >> #compose: "
extent := textComposition usedExtent + 8.! !
!DrGTextMorph methodsFor: 'testing type' stamp: 'hlsf 4/6/2021 19:24:39'!
isText
^ true! !
!DrGTextMorph methodsFor: 'geometry testing' stamp: 'hlsf 10/22/2021 22:59:16'!
wantsContour
^ false! !
!DrGTextMorph methodsFor: 'testing' stamp: 'hlsf 3/9/2023 12:38:52'!
containsPoint: localPoint
"We really want rectangle detection, more user friendly, otherwise it is pixel detecting on each character"
^ self canBeDrawn
and: [self displayBounds
ifNil: [false]
ifNotNil: [:d | d containsPoint: self drawable morphPositionInWorld + localPoint ]]
! !
!DrGValueMorph methodsFor: 'accessing' stamp: 'hlsf 7/9/2022 11:41:51'!
roundedValueString
^ (mathItem valueItem isPoint or: [mathItem valueItem isNumber])
ifTrue: [
mathItem valueItem isFraction
ifTrue: [mathItem valueItem printString]
ifFalse: [mathItem valueItem printShowingDecimalPlaces: (DrGeoSystem preferences at: #valueDecimal)]]
ifFalse: [mathItem valueItem asString]! !
!DrGValueMorph methodsFor: 'accessing' stamp: 'hlsf 4/7/2021 19:56:32'!
styleClass
^DrGValueStyle! !
!DrGValueMorph methodsFor: 'accessing' stamp: 'hlsf 4/6/2021 19:38:57'!
valueString
^mathItem valueItem asString! !
!DrGValueMorph methodsFor: 'drawing' stamp: 'hlsf 3/18/2023 21:36:30'!
drawOn: aCanvas
| r bound |
self isDrawNeeded ifFalse: [^ self].
(mathItem name isNil or: [mathItem name isEmpty])
ifTrue: [
(mathItem valueItem is: #Text)
ifTrue: [self contents: mathItem valueItem]
ifFalse: [self contents: self roundedValueString]]
ifFalse: [self contents: mathItem name , ' = ' , self roundedValueString].
r := self labelPosition extent: extent.
self drawFrame: r on: aCanvas .
bound := r insetBy: 4.
aCanvas
drawTextComposition: textComposition
at: bound origin
extent: bound extent
color: color
selectionColor: `Color red`.! !
!DrGValueMorph methodsFor: 'label' stamp: 'hlsf 4/6/2021 19:34:44'!
constrainedLabelPosition: aVector
^ aVector! !
!DrGValueMorph methodsFor: 'testing type' stamp: 'hlsf 4/6/2021 19:34:16'!
isValue
^ true! !
!DrGeoTreeNode methodsFor: 'as yet unclassified' stamp: 'hlsf 2/10/2022 17:06:51'!
contents
^ item parents
ifNotNil: [:array | array collect: [:each | DrGeoTreeNode with: each] ]
ifNil: [`#()`]! !
!DrGeoTreeNode methodsFor: 'as yet unclassified' stamp: 'hlsf 2/10/2022 17:12:39'!
hasContents
^ hasContents! !
!DrGeoTreeNode methodsFor: 'as yet unclassified' stamp: 'hlsf 2/10/2022 17:10:52'!
hasContents: boolean
hasContents _ boolean ! !
!DrGeoTreeNode methodsFor: 'initialization' stamp: 'hlsf 2/10/2022 17:09:34'!
initialize
super initialize.
hasContents _ false.! !
!DrGeoScriptTest methodsFor: 'testing-point'!
testPointByCoordinates
|x y p|
x _ sketch freeValue: 12.
y _ sketch freeValue: -18.
p _ sketch pointX: x Y: y.
self assert: p coordinates = (12 @ -18) ! !
!DrGeoScriptTest methodsFor: 'testing-point'!
testPointByCoordinatesUnicity
|x y p q|
x _ sketch freeValue: 12.
y _ sketch freeValue: -18.
p _ sketch pointX: x Y: y.
q _ sketch pointX: x Y: y.
self should: p mathItem == q mathItem.
q _ sketch pointX: x Y: (sketch freeValue: -18.1).
self shouldnt: p mathItem == q mathItem ! !
!DrGeoScriptTest methodsFor: 'testing-point'!
testPointFree
| a b |
a _ sketch point: 55 @ 5.
self assert: a coordinates = (55 @ 5).
b _ sketch point: -35 @ -45.
self assert: b coordinates = (-35 @ -45).
! !
!DrGeoScriptTest methodsFor: 'testing-point'!
testPointFreeUnicity
| a b |
a _ sketch point: 788@985.
b _ sketch point: 788@985.
self assert: a mathItem == b mathItem.
""
b _ sketch point: 788 @ 986.
b moveTo: 788@985.
sketch update.
self shouldnt: a mathItem == b mathItem.
self should: a coordinates = b coordinates.! !
!DrGeoScriptTest methodsFor: 'testing-point'!
testPointMiddle
| a b m s |
a _ sketch point: 5 @ 5.
b _ sketch point: -5 @ -5.
m _ sketch middleOf: a and: b.
self assert: m coordinates = (0 @ 0).
b _ sketch point: -13 @ 8.
m _ sketch middleOf: a and: b.
self assert: m coordinates = (-4 @ (13 / 2)).
s _ sketch
segment: (sketch point: 8 @ 7)
to: (sketch point: -15 @ -10).
m _ sketch middleOf: s.
self assert: m coordinates = (-7 / 2 @ (-3 / 2))! !
!DrGeoScriptTest methodsFor: 'testing-point'!
testPointMiddleUnicity
| a b s p q |
a _ sketch point: 5 @ 5.
b _ sketch point: -5 @ -5.
p _ sketch middleOf: a and: b.
q _ sketch middleOf: a and: b.
self should: p mathItem == q mathItem.
q _ sketch middleOf: b and: a.
self should: p mathItem == q mathItem.
""
s _ sketch segment: (sketch point: 8 @ 7) to: (sketch point: -15 @ -10).
p _ sketch middleOf: s.
q _ sketch middleOf: s.
self should: p mathItem == q mathItem ! !
!DrGeoScriptTest methodsFor: 'testing-point' stamp: 'HilaireFernandes 5/23/2019 11:11'!
testPointOnArc
| a b c curve p |
a _ sketch point: -5 @ 0.
b _ sketch point: 0 @ 5.
c _ sketch point: 5 @ 0.
curve _ sketch arc: a to: b to: c.
""
p _ sketch pointOnLine: curve at: 0.
self assert: (p coordinates closeTo: -5 @ 0).
""
p mathItem setCurveAbscissa: 0.5.
self assert: (p coordinates closeTo: 0 @ 5).
""
p mathItem setCurveAbscissa: 1.
self assert: (p coordinates closeTo: 5 @ 0).
""
p mathItem setCurveAbscissa: 1/3 .
self assert: (p coordinates closeTo: -2.5 @ 4.3301)! !
!DrGeoScriptTest methodsFor: 'testing-point' stamp: 'HilaireFernandes 5/23/2019 11:11'!
testPointOnArcUnicity
| a b c curve p q|
a _ sketch point: -5 @ 0.
b _ sketch point: 0 @ 5.
c _ sketch point: 5 @ 0.
curve _ sketch arc: a to: b to: c.
""
p _ sketch pointOnLine: curve at: 0.9.
q _ sketch pointOnLine: curve at: 0.9.
self should: p mathItem == q mathItem.
""
q _ sketch pointOnLine: curve at: 0.89.
self shouldnt: p mathItem == q mathItem
! !
!DrGeoScriptTest methodsFor: 'testing-point' stamp: 'HilaireFernandes 5/23/2019 11:11'!
testPointOnCircle
| a b curve p |
a _ sketch point: -5 @ -5.
b _ sketch point: 0 @ -5.
curve _ sketch circleCenter: a to: b.
""
p _ sketch pointOnLine: curve at: 0.
self assert: (p coordinates closeTo: 0 @ -5).
""
p _ sketch pointOnLine: curve at: 1/4.
self assert: (p coordinates closeTo: -5 @ 0).
""
p _ sketch pointOnLine: curve at: 1/2.
self assert: (p coordinates closeTo: -10 @ -5).
""
p _ sketch pointOnLine: curve at: 3/4.
self assert: (p coordinates closeTo: -5 @ -10).
""
p _ sketch pointOnLine: curve at: 3/8.
self assert: (p coordinates closeTo: -8.5355 @ -1.4645).
! !
!DrGeoScriptTest methodsFor: 'testing-point' stamp: 'HilaireFernandes 5/23/2019 11:11'!
testPointOnCircleUnicity
| a b curve p q |
a _ sketch point: -5 @ -5.
b _ sketch point: 0 @ -5.
curve _ sketch circleCenter: a to: b.
""
p _ sketch pointOnLine: curve at: 0.4.
q _ sketch pointOnLine: curve at: 0.4.
self should: p mathItem == q mathItem.
""
q _ sketch pointOnLine: curve at: 0.41.
self shouldnt: p mathItem == q mathItem
! !
!DrGeoScriptTest methodsFor: 'testing-point' stamp: 'HilaireFernandes 5/23/2019 11:11'!
testPointOnLine
| a b curve p |
a _ sketch point: -15 @ -45.
b _ sketch point: -13 @ -44.
curve _ sketch line: a to: b.
p _ sketch pointOnLine: curve at: 0.35.
self
assert: (p coordinates closeTo: -15.4557 @ -45.2279)! !
!DrGeoScriptTest methodsFor: 'testing-point' stamp: 'HilaireFernandes 5/23/2019 11:11'!
testPointOnLineUnicity
| a b curve p q|
a _ sketch point: -15 @ -45.
b _ sketch point: -13 @ -44.
curve _ sketch line: a to: b.
p _ sketch pointOnLine: curve at: 0.35.
q _ sketch pointOnLine: curve at: 0.35.
self should: p mathItem == q mathItem.
""
q _ sketch pointOnLine: curve at: 0.34.
self shouldnt: p mathItem == q mathItem.
! !
!DrGeoScriptTest methodsFor: 'testing-point' stamp: 'HilaireFernandes 5/23/2019 11:11'!
testPointOnRay
| a b curve p |
a _ sketch point: -15 @ -45.
b _ sketch point: -13 @ -44.
curve _ sketch ray: a to: b.
p _ sketch pointOnLine: curve at: 0.
self assert: p coordinates = (-15 @ -45).
""
p mathItem setCurveAbscissa: 0.5.
self
assert: (p coordinates closeTo: -14.1056 @ -44.5528)! !
!DrGeoScriptTest methodsFor: 'testing-point' stamp: 'HilaireFernandes 5/23/2019 11:11'!
testPointOnRayUnicity
| a b curve p q|
a _ sketch point: -15 @ -45.
b _ sketch point: -13 @ -44.
curve _ sketch ray: a to: b.
p _ sketch pointOnLine: curve at: 0.21.
q _ sketch pointOnLine: curve at: 0.21.
self should: p mathItem == q mathItem.
""
q _ sketch pointOnLine: curve at: 0.22.
self shouldnt: p mathItem == q mathItem ! !
!DrGeoScriptTest methodsFor: 'testing-point' stamp: 'HilaireFernandes 5/23/2019 11:11'!
testPointOnSegment
| a b curve p |
a _ sketch point: -5 @ -5.
b _ sketch point: 5 @ 5.
curve _ sketch segment: a to: b.
p _ sketch pointOnLine: curve at: 0.
self assert: p coordinates = (-5 @ -5).
p mathItem setCurveAbscissa: 1.
self assert: p coordinates = (5 @ 5).
p mathItem setCurveAbscissa: 0.5.
self assert: p coordinates = (0 @ 0).
p mathItem setCurveAbscissa: 1 / 3.
self assert: p coordinates = (-5 / 3 @ (-5 / 3)).
""
a mathItem moveTo: 0 @ 0.
sketch update.
self assert: p coordinates = (5 / 3 @ (5 / 3)).
"" ! !
!DrGeoScriptTest methodsFor: 'testing-point' stamp: 'HilaireFernandes 5/23/2019 11:11'!
testPointOnSegmentUnicity
| a b curve p q |
a _ sketch point: -25 @ -5.
b _ sketch point: 25 @ 5.
curve _ sketch segment: a to: b.
p _ sketch pointOnLine: curve at: 0.7.
q _ sketch pointOnLine: curve at: 0.7.
self should: p mathItem == q mathItem.
q _ sketch pointOnLine: curve at: 0.71.
self shouldnt: p mathItem = q mathItem ! !
!DrGeoScriptTest methodsFor: 'testing-point'!
testPointReflexion
| d a b|
d _ sketch line: (sketch point: 0@0) to: (sketch point: 1@2).
""
a _ sketch point: 1@0.
b _ sketch reflect: a axis: d.
self assert: (b coordinates closeTo: -0.6@0.8).
""
a _ sketch point: 1@2.
b _ sketch reflect: a axis: d.
self assert: (b coordinates = (1@2)).
""
a _ sketch point: 0@3.
b _ sketch reflect: a axis: d.
self assert: (b coordinates closeTo: 2.4@1.8).
! !
!DrGeoScriptTest methodsFor: 'testing-point'!
testPointRotation
| c v a b|
c _ sketch point: 1@1.
v _ sketch freeValue: Float pi / 3.
""
a _ sketch point: 2@1.
b _ sketch rotate: a center: c angle: v.
self assert: (b coordinates closeTo: 1.5@1.8660).
""
v _ sketch freeValue: (Float pi / 3) negated.
b _ sketch rotate: a center: c angle: v.
self assert: (b coordinates closeTo: 1.5@0.13397).
! !
!DrGeoScriptTest methodsFor: 'testing-point'!
testPointScale
| c k a b|
c _ sketch point: 1@1.
k _ sketch freeValue: 3.
""
a _ sketch point: 2@1.
b _ sketch scale: a center: c factor: k.
self assert: b coordinates = (4@1).
""
a _ sketch point: 3@2.
b _ sketch scale: a center: c factor: k.
self assert: b coordinates = (7@4).
""
a _ sketch point: 2@1.
k _ sketch freeValue: -3.
b _ sketch scale: a center: c factor: k.
self assert: b coordinates = (-2@1).
""
a _ sketch point: 3@2.
b _ sketch scale: a center: c factor: k.
self assert: b coordinates = (-5@ -2).
! !
!DrGeoScriptTest methodsFor: 'testing-point'!
testPointSymmetry
| c a b|
c _ sketch point: 2@2.
""
a _ sketch point: 4@2.
b _ sketch symmetry: a center: c.
self assert: b coordinates = (0@2).
""
a _ sketch point: 4@3.
b _ sketch symmetry: a center: c.
self assert: b coordinates = (0@1).
""
a _ sketch point: 4@4.
b _ sketch symmetry: a center: c.
self assert: b coordinates = (0@0)! !
!DrGeoScriptTest methodsFor: 'testing-point'!
testPointTranslation
| u a|
u _ sketch vector: (sketch point: 1@1) to: (sketch point: 3@2).
a _ sketch translate: (sketch point: 2@1) vector: u.
self assert: a coordinates = (4@2).
""
u _ sketch vector: (sketch point: 3@2) to: (sketch point: 1@1).
a _ sketch translate: (sketch point: 2@1) vector: u.
self assert: a coordinates = (0@0).
! !
!DrGeoScriptTest methodsFor: 'testing-value'!
testAbscissaOfPoint
| coordinate point |
point _ sketch point: 10@15.
coordinate _ sketch abscissaOf: point.
self should: (coordinate mathItem valueItem closeTo: 10).! !
!DrGeoScriptTest methodsFor: 'testing-value'!
testAbscissaOfVector
| coordinate vector |
vector _ sketch vector: 10@15.
coordinate _ sketch abscissaOf: vector.
self should: (coordinate mathItem valueItem closeTo: 10).! !
!DrGeoScriptTest methodsFor: 'testing-value'!
testAngleGeometric
| angle |
angle _ sketch geometricAngle: 1@0 to: 1@1 to: 0@1.
self assert: (angle mathItem degreeAngle closeTo: 90).
self assert: (angle mathItem radianAngle closeTo: Float pi / 2).
""
angle _ sketch geometricAngle: 2@1 to: 1@1 to: 2@2.
self assert: (angle mathItem degreeAngle closeTo: 45).
self assert: (angle mathItem radianAngle closeTo: Float pi / 4).
! !
!DrGeoScriptTest methodsFor: 'testing-value'!
testAngleOriented3Points
| angle |
angle _ sketch angle: 1@0 to: 1@1 to: 0@1.
self assert: (angle mathItem degreeAngle closeTo: 270).
self assert: (angle mathItem radianAngle closeTo: (Float pi / 2) negated ).
""
angle _ sketch angle: 2@1 to: 1@1 to: 2@2.
self assert: (angle mathItem degreeAngle closeTo: 45).
self assert: (angle mathItem radianAngle closeTo: Float pi / 4).
! !
!DrGeoScriptTest methodsFor: 'testing-value'!
testAngleOrientedVector
"Oriented angle from two vectors"
| angle |
angle _ sketch angle: 1@0 to: 0@1.
self assert: (angle mathItem degreeAngle closeTo: 90).
self assert: (angle mathItem radianAngle closeTo: Float pi / 2).
""
angle _ sketch angle: 0@1 to: 1@0.
self assert: (angle mathItem degreeAngle closeTo: 90 negated).
self assert: (angle mathItem radianAngle closeTo: Float pi negated / 2).
""
angle _ sketch angle: 1@1 to: -1@1.
self assert: (angle mathItem degreeAngle closeTo: 90).
self assert: (angle mathItem radianAngle closeTo: Float pi / 2).
""
angle _ sketch angle: -1@0 to: 1@1.
self assert: (angle mathItem degreeAngle closeTo: 135 negated).
self assert: (angle mathItem radianAngle closeTo: Float pi negated * 3 / 4).
! !
!DrGeoScriptTest methodsFor: 'testing-value'!
testDistancePointLine
| distance a d recomputed|
a _ sketch point: 10@15.
d _ sketch line: -5 @ -5 to: 2@3.
distance _ sketch distance: a to: d.
recomputed _ ((10@15 - (-5 @ -5)) dotProduct: (d mathItem normal)) abs.
self should: (distance mathItem valueItem closeTo: recomputed).! !
!DrGeoScriptTest methodsFor: 'testing-value'!
testDistancePoints
| distance a b |
a _ sketch point: 10@15.
b _ sketch point: -5 @ -5.
distance _ sketch distance: a to: b.
self should: (distance mathItem valueItem closeTo: (400 + 225) sqrt).! !
!DrGeoScriptTest methodsFor: 'testing-value'!
testLengthArc
| length arc |
arc _ sketch arc: 8@2 to: 6@6 to: 3@7.
length _ sketch lengthOf: arc.
self should: (length mathItem valueItem closeTo: 7.853981633974483).! !
!DrGeoScriptTest methodsFor: 'testing-value'!
testLengthCircle
| length circle |
circle _ sketch circleCenter: 8@2 to: 6@6.
length _ sketch lengthOf: circle.
self should: (length mathItem valueItem closeTo: 20 sqrt * 2 * Float pi).! !
!DrGeoScriptTest methodsFor: 'testing-value'!
testLengthPolygon
| length polygon |
polygon _ sketch regularPolygonCenter: 4@1 vertex: 3@2 sides: 4.
length _ sketch lengthOf: polygon.
self should: (length mathItem valueItem closeTo: 8).! !
!DrGeoScriptTest methodsFor: 'testing-value'!
testLengthSegment
| length segment |
segment _ sketch segment: 8@2 to: 6@6.
length _ sketch lengthOf: segment.
self should: (length mathItem valueItem closeTo: 20 sqrt).! !
!DrGeoScriptTest methodsFor: 'testing-value'!
testLengthVector
| length vector |
vector _ sketch segment: 8@2 to: 6@6.
length _ sketch lengthOf: vector.
self should: (length mathItem valueItem closeTo: 20 sqrt).! !
!DrGeoScriptTest methodsFor: 'testing-value'!
testOrdianteOfPoint
| coordinate point |
point _ sketch point: 10@15.
coordinate _ sketch ordinateOf: point.
self should: (coordinate mathItem valueItem closeTo: 15).! !
!DrGeoScriptTest methodsFor: 'testing-value'!
testOrdianteOfVector
| coordinate vector |
vector _ sketch vector: 10@15.
coordinate _ sketch ordinateOf: vector.
self should: (coordinate mathItem valueItem closeTo: 15).! !
!DrGeoScriptTest methodsFor: 'testing-value'!
testSlope
| slope recomputed|
slope _ sketch slopeOf: (sketch line: -5 @ -5 to: 2@3).
recomputed _ (3 - -5) / (2 - -5).
self should: (slope mathItem valueItem closeTo: recomputed).! !
!DrGeoScriptTest methodsFor: 'testing-value'!
testValueFree
| v |
v _ sketch freeValue: Float pi / 3.
self assert: (v mathItem valueItem closeTo: Float pi / 3).
""
v _ sketch freeValue: 0.00001.
self assert: (v mathItem valueItem closeTo: 0.00001).
! !
!DrGeoScriptTest methodsFor: 'testing-circle'!
testCircle
| c|
c _ sketch circleCenter: (sketch point: 3@2) to: (sketch point: 6@6).
self assert: c mathItem isCircleItem.
self assert: c mathItem isGeometricItem.
self assert: c mathItem isCurveItem.
""
self should: (c mathItem radius closeTo: 5).
self should: (c mathItem center = (3@2)).
self should: (c mathItem contains: 8@2) ! !
!DrGeoScriptTest methodsFor: 'testing-circle'!
testCircleRadius
| c |
c _ sketch circleCenter: (sketch point: 3@2) radius: (sketch freeValue: 5).
self assert: c mathItem isCircleItem.
self assert: c mathItem isGeometricItem.
self assert: c mathItem isCurveItem.
""
self should: (c mathItem radius closeTo: 5).
self should: (c mathItem center = (3@2)).
self should: (c mathItem contains: 8@2) ! !
!DrGeoScriptTest methodsFor: 'testing-circle'!
testCircleRadiusUnicity
| a r c1 c2|
a _ sketch point: 788@985.
r _ sketch freeValue: 5.
c1 _ sketch circleCenter: a radius: r.
c2 _ sketch circleCenter: a radius: r.
self assert: c1 mathItem == c2 mathItem.
""
r _ sketch freeValue: 5.
c2 _ sketch circleCenter: a radius: r.
self shouldnt: c1 mathItem == c2 mathItem.! !
!DrGeoScriptTest methodsFor: 'testing-circle'!
testCircleReflexion
| d c1 c2|
d _ sketch line: 0@0 to: 1@2.
c1 _ sketch circleCenter: 1@0 to: 6@0.
c2 _ sketch reflect: c1 axis: d.
""
self assert: c2 mathItem isCircleItem.
self assert: c2 mathItem isGeometricItem.
self assert: c2 mathItem isCurveItem.
""
self should: (c2 mathItem radius closeTo: 5).
self should: (c2 mathItem center closeTo: (-0.6@0.8)).
! !
!DrGeoScriptTest methodsFor: 'testing-circle'!
testCircleRotation
| c1 c2|
c1 _ sketch circleCenter: 3@2 to: 3@12.
c2 _ sketch rotate: c1 center: 1@1 angle: Float pi / 3.
""
self assert: c2 mathItem isCircleItem.
self assert: c2 mathItem isGeometricItem.
self assert: c2 mathItem isCurveItem.
""
self should: (c2 mathItem radius closeTo: 10).
self should: (c2 mathItem center closeTo: 1.13397@3.23205).
! !
!DrGeoScriptTest methodsFor: 'testing-circle'!
testCircleScale
| c1 c2|
c1 _ sketch circleCenter: 3@2 to: 3@12.
c2 _ sketch scale: c1 center: 1@1 factor: 3.
""
self assert: c2 mathItem isCircleItem.
self assert: c2 mathItem isGeometricItem.
self assert: c2 mathItem isCurveItem.
""
self should: (c2 mathItem radius closeTo: 30).
self should: (c2 mathItem center closeTo: 7@4).
""
c2 _ sketch scale: c1 center: 1@1 factor: -3.
self should: (c2 mathItem radius closeTo: 30).
self should: (c2 mathItem center closeTo: -5@ -2).
! !
!DrGeoScriptTest methodsFor: 'testing-circle'!
testCircleSegment
| c|
c _ sketch circleCenter: (sketch point: 3@2) segment: (sketch segment: 10@6 to: 20@6).
self assert: c mathItem isCircleItem.
self assert: c mathItem isGeometricItem.
self assert: c mathItem isCurveItem.
""
self should: (c mathItem radius closeTo: 10).
self should: (c mathItem center = (3@2)).
self should: (c mathItem contains: 13@2).
self should: (c mathItem contains: 3@12)! !
!DrGeoScriptTest methodsFor: 'testing-circle'!
testCircleSymmetry
| c1 c2|
c1 _ sketch circleCenter: 3@2 to: 3@12.
c2 _ sketch symmetry: c1 center: 2@2.
""
self assert: c2 mathItem isCircleItem.
self assert: c2 mathItem isGeometricItem.
self assert: c2 mathItem isCurveItem.
""
self should: (c2 mathItem radius closeTo: 10).
self should: (c2 mathItem center closeTo: 1@2).! !
!DrGeoScriptTest methodsFor: 'testing-circle'!
testCircleTranslation
| c1 c2|
c1 _ sketch circleCenter: 3@2 to: 3@12.
c2 _ sketch translate: c1 vector: 2@1.
""
self assert: c2 mathItem isCircleItem.
self assert: c2 mathItem isGeometricItem.
self assert: c2 mathItem isCurveItem.
""
self should: (c2 mathItem radius closeTo: 10).
self should: (c2 mathItem center closeTo: 5@3).
""
c2 _ sketch translate: c1 vector: -2@ -1.
self should: (c2 mathItem radius closeTo: 10).
self should: (c2 mathItem center closeTo: 1@1).
! !
!DrGeoScriptTest methodsFor: 'testing-circle'!
testCircleUnicity
| a b c1 c2|
a _ sketch point: 788@985.
b _ sketch point: 788@1085.
c1 _ sketch circleCenter: a to: b.
c2 _ sketch circleCenter: a to: b.
self assert: c1 mathItem == c2 mathItem.
""
c2 _ sketch circleCenter: b to: a.
self shouldnt: c1 mathItem == c2 mathItem.
""
b _ sketch point: 780 @ 900.
c2 _ sketch circleCenter: a to: b.
self shouldnt: c1 mathItem == c2 mathItem
! !
!DrGeoScriptTest methodsFor: 'testing-ray'!
testRay
| a b r|
a _ sketch point: 88@985.
b _ sketch point: 98@1085.
r _ sketch ray: a to: b.
self assert: r mathItem isCurveItem.
self assert: r mathItem isGeometricItem.
self assert: r mathItem isDirectionItem.
self assert: r mathItem isRayItem.
""
self should: (r mathItem contains: 89@995).
self should: (r mathItem contains: 188@1985).
self shouldnt: (r mathItem contains: 87@975).
self shouldnt: (r mathItem contains: 5 @4)! !
!DrGeoScriptTest methodsFor: 'testing-ray'!
testRayReflexion
| axe r1 r2 |
axe _ sketch line: (sketch point: 0 @ 0) to: (sketch point: 1 @ 2).
""
r1 _ sketch ray: (sketch point: 3@2) to: (sketch point: 2@4).
r2 _ sketch reflect: r1 axis: axe.
self assert:(r2 mathItem origin closeTo: -0.2@3.6).
self assert: (r2 mathItem direction closeTo: 2.2@0.4)
! !
!DrGeoScriptTest methodsFor: 'testing-ray'!
testRayRotation
| r1 r2 c k |
c _ sketch point: 1 @ 1.
k _ sketch freeValue: Float pi / 3.
""
r1 _ sketch ray: 3@2 to: 2@4.
r2 _ sketch rotate: r1 center: c angle: k.
self assert:(r2 mathItem origin closeTo: 1.13397@3.23205).
self assert: (r2 mathItem direction closeTo: -2.23205@0.133974)
! !
!DrGeoScriptTest methodsFor: 'testing-ray'!
testRayScale
| r1 r2 c k |
c _ sketch point: 1 @ 1.
k _ sketch freeValue: 3.
""
r1 _ sketch ray: (sketch point: 3@2) to: (sketch point: 2@4).
r2 _ sketch scale: r1 center: c factor: k.
self assert: (r2 mathItem origin closeTo: 7@4).
self assert: (r2 mathItem direction = (r1 mathItem direction * 3)).
""
k _ sketch freeValue: -3.
r2 _ sketch scale: r1 center: c factor: k.
self assert: (r2 mathItem origin closeTo: -5@ -2).
self assert: (r2 mathItem direction = (r1 mathItem direction * -3))
! !
!DrGeoScriptTest methodsFor: 'testing-ray'!
testRaySymmetry
| c r1 r2|
c _ sketch point: 2@2.
""
r1 _ sketch ray: (sketch point: 3@2) to: (sketch point: 2@4).
r2 _ sketch symmetry: r1 center: c.
self assert: r2 mathItem origin = (1@2).
self assert: r2 mathItem direction = r1 mathItem direction negated
! !
!DrGeoScriptTest methodsFor: 'testing-ray'!
testRayTranslation
| r1 r2 t |
r1 _ sketch ray: (sketch point: 3@2) to: (sketch point: 2@4).
t _ sketch vector: (sketch point: 1@1) to: (sketch point: 3@2).
""
r2 _ sketch translate: r1 vector: t.
self assert: r2 mathItem origin = (5@3).
self assert: r2 mathItem direction = r1 mathItem direction.
""
t _ sketch vector: (sketch point: 3@2) to: (sketch point: 1@1).
r2 _ sketch translate: r1 vector: t.
self assert: r2 mathItem origin = (1@1).
self assert: r2 mathItem direction = r1 mathItem direction.
! !
!DrGeoScriptTest methodsFor: 'testing-ray'!
testRayUnicity
| a b s1 s2|
a _ sketch point: 788@985.
b _ sketch point: 788@1085.
s1 _ sketch ray: a to: b.
s2 _ sketch ray: a to: b.
self assert: s1 mathItem == s2 mathItem.
""
s2 _ sketch ray: b to: a.
self shouldnt: s1 mathItem == s2 mathItem.
""
b _ sketch point: 780 @ 900.
s2 _ sketch ray: a to: b.
self shouldnt: s1 mathItem == s2 mathItem
! !
!DrGeoScriptTest methodsFor: 'testing-line'!
testAngleBisector
| bisector geometricAngle |
geometricAngle _ sketch angle: 1@0 to: 0@0 to: 0@1.
bisector _ sketch angleBisector: geometricAngle.
""
self assert: (bisector mathItem contains: 0@0).
self assert: (bisector mathItem contains: 1@1).
self assert: (bisector mathItem contains: -10@ -10).
self deny: (bisector mathItem contains: -1@ -10).
! !
!DrGeoScriptTest methodsFor: 'testing-line'!
testAngleBisector3Points
| bisector |
bisector _ sketch angleBisectorSummit: 0@0 side1: 1@0 side2: 0@1.
""
self assert: (bisector mathItem contains: 0@0).
self assert: (bisector mathItem contains: 1@1).
self assert: (bisector mathItem contains: -10@ -10).
self deny: (bisector mathItem contains: -1@ -10).
! !
!DrGeoScriptTest methodsFor: 'testing-line'!
testAngleBisectorVectors
"there is no such things as bisector to an angle formed with two vectors"
| orientedAngle |
orientedAngle _ sketch angle: 1@0 to: 0@1.
self should: [sketch angleBisector: orientedAngle] raise: MessageNotUnderstood.
! !
!DrGeoScriptTest methodsFor: 'testing-line'!
testLine
| a b l|
a _ sketch point: 88@985.
b _ sketch point: 98@1085.
l _ sketch line: a to: b.
self assert: l mathItem isCurveItem.
self assert: l mathItem isGeometricItem.
self assert: l mathItem isDirectionItem.
self assert: l mathItem isLineItem.
""
self should: (l mathItem contains: 89@995).
self should: (l mathItem contains: 87@975).
self should: (l mathItem contains: 188@1985).
self shouldnt: (l mathItem contains: 5 @4) ! !
!DrGeoScriptTest methodsFor: 'testing-line'!
testLineReflexion
| axe l1 l2 |
axe _ sketch line: (sketch point: 0 @ 0) to: (sketch point: 1 @ 2).
""
l1 _ sketch line: (sketch point: 3@2) to: (sketch point: 2@4).
l2 _ sketch reflect: l1 axis: axe.
self assert:(l2 mathItem origin closeTo: -0.2@3.6).
self assert: (l2 mathItem direction closeTo: 2.2@0.4)
! !
!DrGeoScriptTest methodsFor: 'testing-line'!
testLineRotation
| l1 l2 c k |
c _ sketch point: 1 @ 1.
k _ sketch freeValue: Float pi / 3.
""
l1 _ sketch line: (sketch point: 3@2) to: (sketch point: 2@4).
l2 _ sketch rotate: l1 center: c angle: k.
self assert:( l2 mathItem origin closeTo: 1.13397@3.23205).
self assert: (l2 mathItem direction closeTo: -2.23205@0.133974)
! !
!DrGeoScriptTest methodsFor: 'testing-line'!
testLineScale
| l1 l2 c k |
c _ sketch point: 1 @ 1.
k _ sketch freeValue: 3.
""
l1 _ sketch line: (sketch point: 3@2) to: (sketch point: 2@4).
l2 _ sketch scale: l1 center: c factor: k.
self assert: (l2 mathItem origin closeTo: 7@4).
self assert: (l2 mathItem direction = (l1 mathItem direction * 3)).
""
k _ sketch freeValue: -3.
l2 _ sketch scale: l1 center: c factor: k.
self assert: (l2 mathItem origin closeTo: -5@ -2).
self assert: (l2 mathItem direction = (l1 mathItem direction * -3))
! !
!DrGeoScriptTest methodsFor: 'testing-line'!
testLineSymmetry
| c l1 l2|
c _ sketch point: 2@2.
""
l1 _ sketch line: (sketch point: 3@2) to: (sketch point: 2@4).
l2 _ sketch symmetry: l1 center: c.
self assert: l2 mathItem origin = (1@2).
self assert: l2 mathItem direction = l1 mathItem direction negated
! !
!DrGeoScriptTest methodsFor: 'testing-line'!
testLineTranslation
| l1 l2 t |
l1 _ sketch line: (sketch point: 3@2) to: (sketch point: 2@4).
t _ sketch vector: (sketch point: 1@1) to: (sketch point: 3@2).
""
l2 _ sketch translate: l1 vector: t.
self assert: l2 mathItem origin = (5@3).
self assert: l2 mathItem direction = l1 mathItem direction.
""
t _ sketch vector: (sketch point: 3@2) to: (sketch point: 1@1).
l2 _ sketch translate: l1 vector: t.
self assert: l2 mathItem origin = (1@1).
self assert: l2 mathItem direction = l1 mathItem direction.
! !
!DrGeoScriptTest methodsFor: 'testing-line'!
testLineUnicity
| a b s1 s2|
a _ sketch point: 788@985.
b _ sketch point: 788@1085.
s1 _ sketch line: a to: b.
s2 _ sketch line: a to: b.
self assert: s1 mathItem == s2 mathItem.
"Lines are oriented"
s2 _ sketch line: b to: a.
self shouldnt: s1 mathItem == s2 mathItem.
""
b _ sketch point: 780 @ 900.
s2 _ sketch line: a to: b.
self shouldnt: s1 mathItem == s2 mathItem
! !
!DrGeoScriptTest methodsFor: 'testing-line'!
testParallelLine
| l p |
l _ sketch line: (sketch point: 3@2) to: (sketch point: 2@4).
p _ sketch parallel: l at: 2@2.
""
self assert: (p mathItem contains: 2@2).
self assert: ((p mathItem direction crossProduct: l mathItem direction) closeTo: 0).
""
! !
!DrGeoScriptTest methodsFor: 'testing-line'!
testParallelRay
| r p |
r _ sketch ray: (sketch point: 3@2) to: (sketch point: 2@4).
p _ sketch parallel: r at: 2@2.
""
self assert: (p mathItem contains: 2@2).
self assert: ((p mathItem direction crossProduct: r mathItem direction) closeTo: 0).
""
! !
!DrGeoScriptTest methodsFor: 'testing-line'!
testParallelSegment
| s p |
s _ sketch segment: (sketch point: 3@2) to: (sketch point: 2@4).
p _ sketch parallel: s at: 2@2.
""
self assert: (p mathItem contains: 2@2).
self assert: ((p mathItem direction crossProduct: s mathItem direction) closeTo: 0).
""
! !
!DrGeoScriptTest methodsFor: 'testing-line'!
testPerpendicularBisector
| s p |
s _ sketch segment: (sketch point: 3@2) to: (sketch point: 2@4).
p _ sketch perpendicularBisector: s.
""
self assert: (p mathItem contains: (3@2 + (2@4) / 2)).
self assert: ((p mathItem direction dotProduct: s mathItem direction) closeTo: 0).
! !
!DrGeoScriptTest methodsFor: 'testing-line'!
testPerpendicularBisector2Points
| p |
p _ sketch perpendicularBisector: 3@2 to: 2@4.
""
self assert: (p mathItem contains: (3@2 + (2@4) / 2)).
self assert: ((p mathItem direction dotProduct: (2@4 - (3@2))) closeTo: 0).
! !
!DrGeoScriptTest methodsFor: 'testing-line'!
testPerpendicularLine
| l p |
l _ sketch line: (sketch point: 3@2) to: (sketch point: 2@4).
p _ sketch perpendicular: l at: 2@2.
""
self assert: (p mathItem contains: 2@2).
self assert: ((p mathItem direction dotProduct: l mathItem direction) closeTo: 0).
""
! !
!DrGeoScriptTest methodsFor: 'testing-line'!
testPerpendicularRay
| r p |
r _ sketch ray: (sketch point: 3@2) to: (sketch point: 2@4).
p _ sketch perpendicular: r at: 2@2.
""
self assert: (p mathItem contains: 2@2).
self assert: ((p mathItem direction dotProduct: r mathItem direction) closeTo: 0).
! !
!DrGeoScriptTest methodsFor: 'testing-line'!
testPerpendicularSegment
| s p |
s _ sketch segment: (sketch point: 3@2) to: (sketch point: 2@4).
p _ sketch perpendicular: s at: 2@2.
""
self assert: (p mathItem contains: 2@2).
self assert: ((p mathItem direction dotProduct: s mathItem direction) closeTo: 0).
! !
!DrGeoScriptTest methodsFor: 'running'!
setUp
sketch _ DrGeoScriptTestResource current sketch! !
!DrGeoScriptTest methodsFor: 'running'!
tearDown
sketch _ nil! !
!DrGeoScriptTest methodsFor: 'testing-arc'!
testArc
| arc|
arc _ sketch arc: (sketch point: 8@2) to: (sketch point: 6@6) to: (sketch point: 3@7).
self assert: arc mathItem isArcItem.
self assert: arc mathItem isGeometricItem.
self assert: arc mathItem isCurveItem.
""
self should: (arc mathItem radius closeTo: 5).
self should: (arc mathItem center = (3@2)).
self should: (arc mathItem length closeTo: Float pi / 2 ).
self should: (arc mathItem contains: 8@2).
self shouldnt: (arc mathItem contains: 3@ -3).
self shouldnt: (arc mathItem contains: -2@ 2). ! !
!DrGeoScriptTest methodsFor: 'testing-arc'!
testArcReflexion
| arc1 arc2 d|
d _ sketch line: 0@0 to: 1@2.
arc1 _ sketch arc: 8@2 to: 6@6 to: 3@7.
arc2 _ sketch reflect: arc1 axis: d.
""
self should: (arc2 mathItem radius closeTo: 5).
self should: (arc2 mathItem center closeTo: (-0.2@3.6)).
self should: (arc1 mathItem length closeTo: Float pi / 2 ).
self should: (arc2 mathItem length closeTo: Float pi negated / 2 ).
self should: (arc2 mathItem contains: -3.2@7.6).
self should: (arc2 mathItem contains: 1.2@8.4).
self should: (arc2 mathItem contains: 3.8@6.6). ! !
!DrGeoScriptTest methodsFor: 'testing-arc'!
testArcRotation
| arc1 arc2 |
arc1 _ sketch arc: 8@2 to: 6@6 to: 3@7.
arc2 _ sketch rotate: arc1 center: 1@1 angle: Float pi / 3.
""
self should: (arc2 mathItem radius closeTo: 5).
self should: (arc2 mathItem center closeTo: (1.1339745962155614@3.232050807568877)).
self should: (arc1 mathItem length closeTo: Float pi / 2 ).
self should: (arc2 mathItem length closeTo: Float pi / 2 ).
self should: (arc2 mathItem contains: (3.6339745962155625@7.56217782649107)).
self should: (arc2 mathItem contains: (-0.8301270189221928@7.830127018922194)).
self should: (arc2 mathItem contains: (-3.196152422706631@5.7320508075688785)). ! !
!DrGeoScriptTest methodsFor: 'testing-arc'!
testArcScale
| arc1 arc2 |
arc1 _ sketch arc: 8@2 to: 6@6 to: 3@7.
arc2 _ sketch scale: arc1 center: 1@1 factor: 3.
""
self should: (arc2 mathItem radius closeTo: 5 * 3).
self should: (arc2 mathItem center closeTo: 7@4).
self should: (arc1 mathItem length closeTo: Float pi / 2 ).
self should: (arc2 mathItem length closeTo: Float pi / 2 ).
self should: (arc2 mathItem contains: 22@4).
self should: (arc2 mathItem contains: 16@16).
self should: (arc2 mathItem contains: 7@19).
! !
!DrGeoScriptTest methodsFor: 'testing-arc'!
testArcTranslation
| arc1 arc2 |
arc1 _ sketch arc: 8@2 to: 6@6 to: 3@7.
arc2 _ sketch translate: arc1 vector: 2@1.
""
self should: (arc2 mathItem radius closeTo: 5 ).
self should: (arc2 mathItem center closeTo: 5@3).
self should: (arc2 mathItem length closeTo: Float pi / 2 ).
self should: (arc2 mathItem contains: 10@3).
self should: (arc2 mathItem contains: 8@7).
self should: (arc2 mathItem contains: 5@8).
! !
!DrGeoScriptTest methodsFor: 'testing-arc'!
testArcUnicity
| arc1 arc2 a b c |
a _ sketch point: 788@985.
b _ sketch point: 700@980.
c _ sketch point: 650@900.
arc1 _ sketch arc: a to: b to: c.
arc2 _ sketch arc: a to: b to: c.
self assert: arc1 mathItem == arc2 mathItem.
""
arc2 _ sketch arc: c to: b to: a.
self assert: arc1 mathItem == arc2 mathItem.
""
arc2 _ sketch arc: a to: c to: b.
self shouldnt: arc1 mathItem == arc2 mathItem.
""
arc2 _ sketch arc: b to: a to: c.
self shouldnt: arc1 mathItem == arc2 mathItem.! !
!DrGeoScriptTest methodsFor: 'testing-polygon'!
testPolygon
| polygon summit |
summit _ Array withAll: {
sketch point: -3@ -3.
sketch point: -3@3.
sketch point: 3@3.
sketch point: 3@ -3}.
polygon _ sketch polygon: summit.
self assert: polygon mathItem isGeometricItem.
self assert: polygon mathItem isPolygonItem.
self assert: polygon mathItem isCurveItem.
self should: polygon mathItem length = 24. ! !
!DrGeoScriptTest methodsFor: 'testing-polygon'!
testPolygonReflexion
| p1 p2 |
p1 _ sketch regularPolygonCenter: 3@2 vertex: 2@4 sides: 4.
p2 _ sketch reflect: p1 axis: (sketch line: 0@0 to: 1@2).
""
self should: (p2 mathItem length closeTo: 4 * 10 sqrt).
self should: p2 mathItem points size = 4.
self should: (p2 mathItem points anySatisfy: [:aPoint | aPoint closeTo: -2.4@3.2]).
! !
!DrGeoScriptTest methodsFor: 'testing-polygon'!
testPolygonRegular
| polygon vertices|
"Test a square as a regular polygon"
polygon _ sketch regularPolygonCenter: 1@1 vertex: 0@2 sides: 4.
self assert: polygon mathItem isGeometricItem.
self assert: polygon mathItem isPolygonItem.
self assert: polygon mathItem isCurveItem.
self should: polygon mathItem length = 8.
""
vertices _ polygon mathItem points.
self should: vertices size = 4.
self should: (vertices anySatisfy: [:aPoint | aPoint closeTo: 0@2]).
self should: (vertices anySatisfy: [:aPoint | aPoint closeTo: 2@2]).
self should: (vertices anySatisfy: [:aPoint | aPoint closeTo: 2@0]).
self should: (vertices anySatisfy: [:aPoint | aPoint closeTo: 0@0]).
""
polygon _ sketch regularPolygonCenter: 3@2 vertex: 2@4 sides: 4.
self should: (polygon mathItem length closeTo: 4 * 10 sqrt).
vertices _ polygon mathItem points.
self should: (vertices anySatisfy: [:aPoint | aPoint closeTo: 2@4]).
self should: (vertices anySatisfy: [:aPoint | aPoint closeTo: 5@3]).
self should: (vertices anySatisfy: [:aPoint | aPoint closeTo: 4@0]).
self should: (vertices anySatisfy: [:aPoint | aPoint closeTo: 1@1]).! !
!DrGeoScriptTest methodsFor: 'testing-polygon'!
testPolygonRotation
| p1 p2 |
p1 _ sketch regularPolygonCenter: 4@1 vertex: 3@2 sides: 4.
p2 _ sketch rotate: p1 center: 1@1 angle: Float pi / 3.
""
self should: (p2 mathItem length closeTo: 8).
self should: p2 mathItem points size = 4.
self should: (p2 mathItem points anySatisfy: [:aPoint | aPoint closeTo: 1.13397@3.23205]).
! !
!DrGeoScriptTest methodsFor: 'testing-polygon'!
testPolygonSymmetry
| p1 p2 |
p1 _ sketch regularPolygonCenter: 4@1 vertex: 3@2 sides: 4.
p2 _ sketch symmetry: p1 center: 2@2.
""
self should: (p2 mathItem length closeTo: 8).
self should: p2 mathItem points size = 4.
self should: (p2 mathItem points anySatisfy: [:aPoint | aPoint closeTo: 1@2]).
! !
!DrGeoScriptTest methodsFor: 'testing-polygon'!
testPolygonTranslation
| p1 p2 |
p1 _ sketch regularPolygonCenter: 4@1 vertex: 3@2 sides: 4.
p2 _ sketch translate: p1 vector: 2@1.
""
self should: (p2 mathItem length closeTo: 8).
self should: p2 mathItem points size = 4.
self should: (p2 mathItem points anySatisfy: [:aPoint | aPoint closeTo: 5@3]).
! !
!DrGeoScriptTest methodsFor: 'testing-polygon'!
testPolygonUnicity
| p1 p2 summit |
summit _ Array withAll: {
sketch point: -3@ -3.
sketch point: -3@3.
sketch point: 3@3.
sketch point: 3@ -3}.
p1 _ sketch polygon: summit.
summit _ Array withAll: {
sketch point: 3@ -3.
sketch point: -3@ -3.
sketch point: -3@3.
sketch point: 3@3}.
p2 _ sketch polygon: summit.
"we not handle polygon unicity yet"
self deny: p1 mathItem == p2 mathItem.
""
summit _ Array withAll: {
sketch point: -3@3.
sketch point: -3@ -3.
sketch point: 3@3.
sketch point: 3@ -3}.
p2 _ sketch polygon: summit.
self deny: p1 mathItem == p2 mathItem ! !
!DrGeoScriptTest methodsFor: 'testing-direction'!
testDirectionCollinear
| d1 d2|
d1 _ sketch segment: (sketch point: 5@5) to: (sketch point: 8 @7).
d2 _ sketch segment: (sketch point: 5@5) to: (sketch point: 8 @13).
self shouldnt: (d1 mathItem isCollinearWith: d2 mathItem).
d2 _ sketch segment: (sketch point: 15@5) to: (sketch point: 18@7).
self should: (d1 mathItem isCollinearWith: d2 mathItem).
""
d2 _ sketch line: (sketch point: 6@5) to: (sketch point: 9@7) .
self should: (d1 mathItem isCollinearWith: d2 mathItem) .
""
d2 _ sketch ray: (sketch point: 6@4) to: (sketch point: 9@6) .
self should: (d1 mathItem isCollinearWith: d2 mathItem) .
""
d2 _ sketch vector: (sketch point: 3@2) to: (sketch point: 6@4) .
self should: (d1 mathItem isCollinearWith: d2 mathItem)
! !
!DrGeoScriptTest methodsFor: 'testing-direction'!
testDirectionDirection
| d n v |
d _ sketch segment: (sketch point: 5@5) to: (sketch point: 8 @7).
v _ d mathItem direction.
self should: v = (3@2).
n _ d mathItem normal.
self should: ((n dotProduct: v) closeTo: 0).
self should: (n x * n x + (n y * n y) closeTo: 1) ! !
!DrGeoScriptTest methodsFor: 'testing-direction'!
testDirectionIntersection
| d1 d2|
d1 _ sketch segment: (sketch point: -5@ -5) to: (sketch point: 5 @5).
d2 _ sketch segment: (sketch point: -5@5) to: (sketch point: 5@ -5).
"only test if not collinenear in fact"
self should: (((d1 mathItem intersectionWithDirection: d2 mathItem) closeTo: 0@0)).
""
d2 _ sketch segment: (sketch point: -4@ -5) to: (sketch point: 6@ 5).
self assert: (d1 mathItem intersectionWithDirection: d2 mathItem) isNil! !
!DrGeoScriptTest methodsFor: 'testing-vector'!
testVector
| a b v|
a _ sketch point: 88@985.
b _ sketch point: 98@1085.
v _ sketch vector: a to: b.
self deny: v mathItem isCurveItem.
self assert: v mathItem isGeometricItem.
self assert: v mathItem isDirectionItem.
self assert: v mathItem isVectorItem.
self deny: v mathItem isSegmentItem.
""
self should: (v mathItem direction = (10@100)).
""
v mathItem move: 5@4;
update.
self should: v mathItem direction = (10@100).
! !
!DrGeoScriptTest methodsFor: 'testing-vector'!
testVectorUnicity
| a b v u|
a _ sketch point: 2@5.
b _ sketch point: 4@8.
u _ sketch vector: a to: b.
v _ sketch vector: a to: b.
self assert: u mathItem == v mathItem.
""
v _ sketch vector: b to: a.
self deny: u mathItem == v mathItem.
""
a _ sketch point: -4@ -5.
b _ sketch point: -2@ -2.
v _ sketch vector: a to: b.
self deny: u mathItem == v mathItem.
self assert: u mathItem direction = v mathItem direction ! !
!DrGeoScriptTest methodsFor: 'testing-segment'!
testSegment
| a b s|
a _ sketch point: 88@985.
b _ sketch point: 98@1085.
s _ sketch segment: a to: b.
self assert: s mathItem isCurveItem.
self assert: s mathItem isGeometricItem.
self assert: s mathItem isDirectionItem.
self assert: s mathItem isSegmentItem.
""
self should: (s mathItem contains: 89@995).
self shouldnt: (s mathItem contains: 87@975).
self shouldnt: (s mathItem contains: 188@1095).
self shouldnt: (s mathItem contains: 5 @4) ! !
!DrGeoScriptTest methodsFor: 'testing-segment'!
testSegmentReflexion
| d u v|
d _ sketch
line: (sketch point: 0 @ 0)
to: (sketch point: 1 @ 2).
""
u _ sketch segment: (sketch point: 3@2) to: (sketch point: 2@4).
v _ sketch reflect: u axis: d.
self assert:( v mathItem origin closeTo: -0.2@3.6).
self assert: (v mathItem direction closeTo: 2.2@0.4)
! !
!DrGeoScriptTest methodsFor: 'testing-segment'!
testSegmentRotation
| u v c k |
c _ sketch point: 1 @ 1.
k _ sketch freeValue: Float pi / 3.
""
u _ sketch segment: (sketch point: 3@2) to: (sketch point: 2@4).
v _ sketch rotate: u center: c angle: k.
self assert:( v mathItem origin closeTo: 1.13397@3.23205).
self assert: (v mathItem direction closeTo: -2.23205@0.133974)
! !
!DrGeoScriptTest methodsFor: 'testing-segment'!
testSegmentScale
| u v c k |
c _ sketch point: 1 @ 1.
k _ sketch freeValue: 3.
""
u _ sketch segment: (sketch point: 3@2) to: (sketch point: 2@4).
v _ sketch scale: u center: c factor: k.
self assert: (v mathItem origin closeTo: 7@4).
self assert: (v mathItem direction = (u mathItem direction * 3)).
""
k _ sketch freeValue: -3.
v _ sketch scale: u center: c factor: k.
self assert: (v mathItem origin closeTo: -5@ -2).
self assert: (v mathItem direction = (u mathItem direction * -3))
! !
!DrGeoScriptTest methodsFor: 'testing-segment'!
testSegmentSymmetry
| c u v|
c _ sketch point: 2@2.
""
u _ sketch segment: (sketch point: 3@2) to: (sketch point: 2@4).
v _ sketch symmetry: u center: c.
self assert: v mathItem origin = (1@2).
self assert: v mathItem direction = u mathItem direction negated
! !
!DrGeoScriptTest methodsFor: 'testing-segment'!
testSegmentTranslation
| u v t |
u _ sketch segment: (sketch point: 3@2) to: (sketch point: 2@4).
t _ sketch vector: (sketch point: 1@1) to: (sketch point: 3@2).
""
v _ sketch translate: u vector: t.
self assert: v mathItem origin = (5@3).
self assert: v mathItem direction = u mathItem direction.
""
t _ sketch vector: (sketch point: 3@2) to: (sketch point: 1@1).
v _ sketch translate: u vector: t.
self assert: v mathItem origin = (1@1).
self assert: v mathItem direction = u mathItem direction.
! !
!DrGeoScriptTest methodsFor: 'testing-segment'!
testSegmentUnicity
| a b s1 s2|
a _ sketch point: 788@985.
b _ sketch point: 788@1085.
s1 _ sketch segment: a to: b.
"s2 _ canvas segment: a to: b.
self assert: s1 mathItem == s2 mathItem."
""
s2 _ sketch segment: b to: a.
self assert: s1 mathItem == s2 mathItem.
""
b _ sketch point: 780 @ 901.
s2 _ sketch segment: a to: b.
self deny: s1 mathItem == s2 mathItem
! !
!DrGeoScriptTest class methodsFor: 'as yet unclassified'!
resources
^ {DrGeoScriptTestResource}! !
!DrGeoSmalltalkSketchTest methodsFor: 'helpers' stamp: 'hlsf 4/8/2022 11:34:07'!
launchSketch: aScriptFile
"Launch a test"
(DrGeoSystem smalltalkSketchesPath // aScriptFile) readStream fileIn! !
!DrGeoSmalltalkSketchTest methodsFor: 'helpers' stamp: 'hlsf 4/10/2022 15:04:23'!
tearDown
(Delay forMilliseconds: 200) wait.
DrGeoSketch allInstancesDo: [:aSketch | aSketch terminateDo ].
DrGeoView allInstancesDo: [:drMorph | drMorph deleteWithoutConfirmation ].! !
!DrGeoSmalltalkSketchTest methodsFor: 'helpers' stamp: 'hlsf 6/13/2021 11:03:31'!
testOnSketch: aScriptFile
self
shouldnt: [self launchSketch: aScriptFile]
raise: Error
description: 'Fail on script ', aScriptFile. ! !
!DrGeoSmalltalkSketchTest methodsFor: 'tests' stamp: 'hlsf 6/13/2021 10:55:27'!
testArchimedesPI
self testOnSketch: 'Archimedes PI.st'! !
!DrGeoSmalltalkSketchTest methodsFor: 'tests' stamp: 'hlsf 6/13/2021 22:13:51'!
testArchimedesPIInterval
self testOnSketch: 'Archimedes PI Interval.st'! !
!DrGeoSmalltalkSketchTest methodsFor: 'tests'!
testArchimedesSpiral
self testOnSketch: 'Archimedes Spiral.st'! !
!DrGeoSmalltalkSketchTest methodsFor: 'tests' stamp: 'hlsf 6/13/2021 11:14:54'!
testBernouilliSpiral
self launchSketch: 'Bernouilli Spiral.st'! !
!DrGeoSmalltalkSketchTest methodsFor: 'tests'!
testBisection
self testOnSketch: 'Bisection.st'! !
!DrGeoSmalltalkSketchTest methodsFor: 'tests' stamp: 'hlsf 6/8/2021 21:12:18'!
testBranches
self testOnSketch: 'Branches.st'.! !
!DrGeoSmalltalkSketchTest methodsFor: 'tests'!
testCercleCirconscrit
self testOnSketch: 'Cercle circonscrit.st'! !
!DrGeoSmalltalkSketchTest methodsFor: 'tests'!
testChaoticSequence
self testOnSketch: 'Chaotic sequence.st'! !
!DrGeoSmalltalkSketchTest methodsFor: 'tests'!
testCobwebDiagram
self testOnSketch: 'Cobweb diagram.st'! !
!DrGeoSmalltalkSketchTest methodsFor: 'tests'!
testConwayTesselation
self testOnSketch: 'Conway tesselation.st'! !
!DrGeoSmalltalkSketchTest methodsFor: 'tests'!
testCotesSpiral
self testOnSketch: 'Cotes Spiral.st'! !
!DrGeoSmalltalkSketchTest methodsFor: 'tests'!
testDurer
self testOnSketch: 'Durer.st'! !
!DrGeoSmalltalkSketchTest methodsFor: 'tests'!
testFathauer
self testOnSketch: 'Fathauer.st'! !
!DrGeoSmalltalkSketchTest methodsFor: 'tests' stamp: 'hlsf 6/13/2021 11:50:26'!
testFermatSpiral
self testOnSketch: 'Fermat Spiral.st'! !
!DrGeoSmalltalkSketchTest methodsFor: 'tests'!
testFibonacciSpiral
self testOnSketch: 'Fibonacci Spiral.st'! !
!DrGeoSmalltalkSketchTest methodsFor: 'tests'!
testGalileoSpiral
self testOnSketch: 'Galileo Spiral.st'! !
!DrGeoSmalltalkSketchTest methodsFor: 'tests'!
testKoch
self testOnSketch: 'Koch.st'! !
!DrGeoSmalltalkSketchTest methodsFor: 'tests'!
testNewtonRaphson
self testOnSketch: 'Newton-Raphson.st'! !
!DrGeoSmalltalkSketchTest methodsFor: 'tests' stamp: 'hlsf 6/13/2021 12:06:36'!
testPIMontCarlo
self testOnSketch: 'PI-Mont-Carlo.st'! !
!DrGeoSmalltalkSketchTest methodsFor: 'tests'!
testSierpinski
self testOnSketch: 'sierpinski.st'! !
!DrGeoSmalltalkSketchTest methodsFor: 'tests'!
testSierpinskiDragon
self testOnSketch: 'Sierpinski Dragon.st'! !
!DrGeoSmalltalkSketchTest methodsFor: 'tests'!
testStats
self testOnSketch: 'stats.st'! !
!DrGeoSmalltalkSketchTest methodsFor: 'tests'!
testTree
self testOnSketch: 'Tree.st'! !
!DrGeoSmalltalkSketchTest methodsFor: 'tests'!
testWave
self testOnSketch: 'wave.st'! !
!LanguageFontTest methodsFor: 'setUp/tearDown' stamp: 'hlsf 11/17/2023 23:37:32'!
setUp
| font |
fontManager := LanguageFontManager new.
font := LanguageFont family: 'UnDotum' file: 'UnDotum.ttf'.
font addLocale: (LocaleID isoString: 'ko-KO');
addLocale: (LocaleID isoString: 'zh-TW').
fontManager add: font.
font := LanguageFont family: 'Klingon' file: 'Klingon.ttf'.
font addLocale: (LocaleID isoLanguage: 'kl').
fontManager add: font! !
!LanguageFontTest methodsFor: 'testing' stamp: 'hlsf 11/17/2023 22:05:46'!
testChinese
" No font for Mandarin in China "
| font |
font := fontManager languageFontFor: (LocaleID isoString: 'zh-CN').
self assert: font isNil! !
!LanguageFontTest methodsFor: 'testing' stamp: 'hlsf 11/17/2023 23:38:49'!
testEuropean
" European languages use the default font in Cuis "
self assert: (fontManager languageFontFor: (LocaleID isoString: 'fr-FR')) isNil.
self assert: (fontManager languageFontFor: (LocaleID isoLanguage: 'fr')) isNil! !
!LanguageFontTest methodsFor: 'testing' stamp: 'hlsf 11/17/2023 22:53:57'!
testKlingonOnEarth
" font for Klingo wathever the country "
| font |
font := fontManager languageFontFor: (LocaleID isoString: 'kl-SOL').
self assert: font notNil.
self assert: font family = 'Klingon'! !
!LanguageFontTest methodsFor: 'testing' stamp: 'hlsf 11/17/2023 23:38:19'!
testKorean
" Font for Korean in Korea "
| font |
font := fontManager languageFontFor: (LocaleID isoString: 'ko-KO').
self assert: font family = 'UnDotum'.
font := fontManager languageFontFor: (LocaleID isoLanguage: 'ko').
self assert: font notNil! !
!LanguageFontTest methodsFor: 'testing' stamp: 'hlsf 11/17/2023 22:07:09'!
testMandarin
" Font for Mandarin, whatever the country TW, HK, CN "
| font |
font := fontManager languageFontFor: (LocaleID isoLanguage: 'zh').
self assert: font family = 'UnDotum'! !
!LanguageFontTest methodsFor: 'testing' stamp: 'hlsf 11/17/2023 22:05:26'!
testTaiwan
" Font for Mandarin in Taiwan "
| font |
font := fontManager languageFontFor: (LocaleID isoString: 'zh-TW').
self assert: font family = 'UnDotum'! !
!LanguageFontTest methodsFor: 'testing' stamp: 'hlsf 11/17/2023 22:55:26'!
testThai
" No font for Thai, with and without country code "
| font |
font := fontManager languageFontFor: (LocaleID isoString: 'th-TH').
self assert: font isNil.
font := fontManager languageFontFor: (LocaleID isoLanguage: 'th').
self assert: font isNil! !
!DrGeoScriptTestResource methodsFor: 'running' stamp: 'hlsf 4/10/2022 19:24:35'!
setUp
sketch _ DrGeoSketch new! !
!DrGeoScriptTestResource methodsFor: 'running'!
tearDown
sketch release.
sketch _ nil! !
!DrGeoScriptTestResource methodsFor: 'accessing'!
sketch
^ sketch! !
!DrGeoScriptTestResource methodsFor: 'testing'!
isAvailable
^ sketch notNil! !
!DrGTypeArrow methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 14:40:15'!
arrowIndex
^ self class arrowIndexOf: self value! !
!DrGTypeArrow methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 14:43:11'!
arrowIndex: anIndex
self value: (self class arrowFor: anIndex).
self changed: #arrowIndex:! !
!DrGTypeArrow methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 14:39:54'!
arrowMorphCollection
^ self class arrowMorphCollection ! !
!DrGTypeArrow class methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 14:38:38'!
arrowFor: index
^ self arrowSymbols at: index! !
!DrGTypeArrow class methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 14:39:08'!
arrowIndexOf: aSymbol
^ self arrowSymbols indexOf: aSymbol! !
!DrGTypeArrow class methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 14:37:59'!
arrowMorphCollection
^ self arrowSymbols collect: [:symbol |
ImageMorph new image: (
DrGIcons
segment: (DrGTypeThickness widthFor: #small)
color: Color black
dash: (DrGTypeStyle styleDataFor: #plain)
arrow: symbol
)]! !
!DrGTypeArrow class methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 14:37:42'!
arrowSymbols
^ #(#none #back #forward #both) ! !
!DrGTypeColor methodsFor: 'accessing' stamp: 'hlsf 6/3/2022 22:05:04'!
colorIndex
^ self class colorIndexOf: self value! !
!DrGTypeColor methodsFor: 'accessing' stamp: 'hlsf 6/3/2022 22:06:22'!
colorIndex: index
self value: (self class colorFor: index).
self changed: #colorIndex:! !
!DrGTypeColor methodsFor: 'accessing' stamp: 'hlsf 6/3/2022 22:02:11'!
colorMorphCollection
^ self class colorMorphCollection! !
!DrGTypeColor class methodsFor: 'accessing' stamp: 'hlsf 6/3/2022 11:36:00'!
blinkingColor
^Color lightGray lighter lighter! !
!DrGTypeColor class methodsFor: 'accessing' stamp: 'hlsf 6/3/2022 11:36:08'!
colorFor: index
^ Color perform: (self colorSymbols at: index)! !
!DrGTypeColor class methodsFor: 'accessing' stamp: 'hlsf 6/3/2022 11:36:14'!
colorIndexOf: aColor
^self colors indexOf: (aColor alpha: 1)! !
!DrGTypeColor class methodsFor: 'accessing' stamp: 'hlsf 6/3/2022 11:36:21'!
colorMorphCollection
^ self colors collect: [:aColor |
ImageMorph new image: (DrGIcons colorForm: aColor )]! !
!DrGTypeColor class methodsFor: 'accessing' stamp: 'hlsf 6/3/2022 11:36:29'!
colorSymbols
^#(#black #blue #brown #green #magenta #orange #red #yellow #white)! !
!DrGTypeColor class methodsFor: 'accessing' stamp: 'hlsf 6/3/2022 11:36:35'!
colors
^ self colorSymbols collect: [:symbol | Color perform: symbol]! !
!DrGTypeColor class methodsFor: 'accessing' stamp: 'hlsf 6/3/2022 11:36:40'!
hiddenColor
^Color lightGray lighter lighter lighter! !
!DrGTypeMark methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 14:42:22'!
markIndex
^ self class markIndexOf: self value! !
!DrGTypeMark methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 14:26:46'!
markIndex: anIndex
self value: (self class markFor: anIndex).
self changed: #markIndex:! !
!DrGTypeMark methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 14:24:25'!
markMorphCollection
^ self class markMorphCollection ! !
!DrGTypeMark class methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 14:23:52'!
markFor: index
^ self markSymbols at: index! !
!DrGTypeMark class methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 14:23:49'!
markIndexOf: aMark
^ self markSymbols indexOf: aMark! !
!DrGTypeMark class methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 14:23:45'!
markMorphCollection
^ self markSymbols collect: [:symbol |
ImageMorph new image: (
DrGIcons
segment: (DrGTypeThickness widthFor: #small)
color: Color black mark: symbol
)]! !
!DrGTypeMark class methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 14:23:41'!
markSymbols
^ #(#none #mark1 #mark2 #mark3 #disc #circle)! !
!DrGTypePointShape methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 11:10:56'!
pointShapeIndex
^ self class pointShapeIndexOf: self value! !
!DrGTypePointShape methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 11:12:07'!
pointShapeIndex: anIndex
self value: (self class pointShapeFor: anIndex).
self changed: #pointShapeIndex:! !
!DrGTypePointShape methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 11:09:37'!
shapeMorphCollection
^ self class shapeMorphCollection ! !
!DrGTypePointShape class methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 10:51:10'!
pointShapeFor: index
^ self pointShapeSymbols at: index! !
!DrGTypePointShape class methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 10:54:52'!
pointShapeIndexOf: pointShape
^ self pointShapeSymbols indexOf: pointShape! !
!DrGTypePointShape class methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 12:01:43'!
pointShapeSymbols
^ `#(#cross #round #square)`! !
!DrGTypePointShape class methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 11:03:01'!
shapeMorphCollection
^ self pointShapeSymbols collect: [:symbol |
ImageMorph new
image: (DrGIcons point: (DrGTypePointSize pointExtentFor: #medium)
color: Color black shape: symbol) ].
! !
!DrGTypePointSize methodsFor: 'accessing' stamp: 'hlsf 6/4/2022 22:15:22'!
pointSizeIndex
^ self class pointSizeIndexOf: self value! !
!DrGTypePointSize methodsFor: 'accessing' stamp: 'hlsf 6/4/2022 22:38:08'!
pointSizeIndex: anIndex
self value: (self class pointSizeFor: anIndex).
self changed: #pointSizeIndex:! !
!DrGTypePointSize methodsFor: 'accessing' stamp: 'hlsf 6/4/2022 22:35:07'!
sizeMorphCollection
^ self class sizeMorphCollection: #square! !
!DrGTypePointSize class methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 11:01:19'!
pointExtentFor: pointSize
pointSize == #small ifTrue: [^ 6@6].
pointSize == #large ifTrue: [^ 10@10].
^ 8@8.! !
!DrGTypePointSize class methodsFor: 'accessing' stamp: 'hlsf 6/4/2022 14:55:59'!
pointSizeFor: index
^ self pointSizeSymbols at: index! !
!DrGTypePointSize class methodsFor: 'accessing' stamp: 'hlsf 6/4/2022 14:51:12'!
pointSizeIndexOf: aSize
^ self pointSizeSymbols indexOf: aSize! !
!DrGTypePointSize class methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 12:01:51'!
pointSizeSymbols
^ `#(#small #medium #large)`! !
!DrGTypePointSize class methodsFor: 'accessing' stamp: 'hlsf 6/4/2022 14:49:50'!
sizeMorphCollection: aShape
^ self pointSizeSymbols collect: [:symbol |
ImageMorph new image: (DrGIcons point: symbol color: Color black shape: aShape)].
! !
!DrGTypeStyle methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 12:50:56'!
styleIndex
^ self class styleIndexOf: self value! !
!DrGTypeStyle methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 14:51:35'!
styleIndex: anIndex
self value: (self class styleFor: anIndex).
self changed: #styleIndex:! !
!DrGTypeStyle methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 12:42:26'!
styleMorphCollection
^ self class styleMorphCollection ! !
!DrGTypeStyle class methodsFor: 'accessing' stamp: 'hlsf 6/24/2023 22:51:03'!
styleDataFor: aStyle
"possible lineStyle"
aStyle = #dot ifTrue: [^ #(2 6)].
aStyle = #dash ifTrue: [^ #(8 5)].
^ nil! !
!DrGTypeStyle class methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 12:41:21'!
styleFor: index
^ self styleSymbols at: index
! !
!DrGTypeStyle class methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 12:39:00'!
styleIndexOf: aLineStyle
^ self styleSymbols indexOf: aLineStyle! !
!DrGTypeStyle class methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 12:41:02'!
styleMorphCollection
^ self styleSymbols collect: [:symbol |
ImageMorph new image: (
DrGIcons
segment: (DrGTypeThickness widthFor: #small)
color: Color black dash: (DrGTypeStyle styleDataFor: symbol)
)]! !
!DrGTypeStyle class methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 12:38:39'!
styleSymbols
^ #(#dot #dash #plain) ! !
!DrGTypeThickness methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 12:22:49'!
thicknessIndex
^ self class thicknessIndexOf: self value! !
!DrGTypeThickness methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 12:28:53'!
thicknessIndex: anIndex
self value: (self class thicknessFor: anIndex).
self changed: #thicknessIndex:! !
!DrGTypeThickness methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 12:22:27'!
thicknessMorphCollection
^ self class thicknessMorphCollection ! !
!DrGTypeThickness class methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 12:07:24'!
thicknessFor: index
^ self thicknessSymbols at: index! !
!DrGTypeThickness class methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 12:06:44'!
thicknessIndexOf: thickness
^ self thicknessSymbols indexOf: thickness! !
!DrGTypeThickness class methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 12:05:55'!
thicknessMorphCollection
^ self thicknessSymbols collect: [:symbol |
ImageMorph new
image: (DrGIcons segment: (self widthFor: symbol) color: Color black dash: nil)]! !
!DrGTypeThickness class methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 12:01:35'!
thicknessSymbols
^ `#(#small #medium #large)`! !
!DrGTypeThickness class methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 12:02:59'!
widthFor: aThickness
"give the width"
aThickness = #small ifTrue: [^1].
aThickness = #medium ifTrue: [^2].
aThickness = #large ifTrue: [^3].
^ 1! !
!DrGeoTree methodsFor: 'accessing' stamp: 'hlsf 2/10/2022 11:51:56'!
mathItem: aMathItem
"select given a math item"
selectedItem _ self pool detect: [:wrappedItem | wrappedItem item == aMathItem] ifNone: [nil].
self changed: #selectedItem.! !
!DrGeoTree methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 12:50:29'!
pool
^ presenter drawable itemViews
select: [:aMorph | aMorph itemExist and: [aMorph style isNotHidden]]
thenCollect: [:aMorph |
DrGeoTreeNode with: aMorph mathItem ::
hasContents: aMorph mathItem parents isNil not ;
yourself]! !
!DrGeoTree methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 12:49:59'!
presenter: aPresenter
presenter := aPresenter .
presenter domain
when: #updatedItems
send: #changed:
to: self
with: #pool
! !
!DrGeoTree methodsFor: 'accessing' stamp: 'hlsf 2/10/2022 09:54:14'!
selectedItem
^ selectedItem! !
!DrGeoTree methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 12:50:06'!
selectedItem: anItemWrapper
selectedItem := anItemWrapper.
self changed: #selectedItem.
presenter updateSelection ! !
!DrGeoTree methodsFor: 'updating' stamp: 'hlsf 2/10/2022 09:23:20'!
update: symbol
"pass on the notified change"
self changed: symbol! !
!DrGeoTree class methodsFor: 'instance creation' stamp: 'hlsf 8/4/2023 12:49:23'!
on: aPresenter
^ self new ::
presenter: aPresenter ;
yourself! !
!DrGWrappedItem methodsFor: 'updating'!
color: aColor
self style color: aColor! !
!DrGWrappedItem methodsFor: 'updating' stamp: 'hlsf 4/13/2021 14:03:02'!
hide
self style hidden: true.
morph forcedVisibility: false.! !
!DrGWrappedItem methodsFor: 'updating' stamp: 'hlsf 4/12/2021 22:19:13'!
lock
morph locked: true! !
!DrGWrappedItem methodsFor: 'updating'!
moveTo: aPoint! !
!DrGWrappedItem methodsFor: 'updating' stamp: 'hlsf 4/12/2021 22:19:13'!
name: aString
morph name: aString asString! !
!DrGWrappedItem methodsFor: 'updating' stamp: 'hlsf 4/13/2021 14:03:02'!
show
morph forcedVisibility: true.
self style hidden: false! !
!DrGWrappedItem methodsFor: 'updating' stamp: 'hlsf 4/13/2021 14:03:02'!
unhide
self style hidden: false.
morph forcedVisibility: false.! !
!DrGWrappedItem methodsFor: 'updating' stamp: 'hlsf 4/12/2021 22:19:13'!
unlock
morph locked: false! !
!DrGWrappedItem methodsFor: 'accessing' stamp: 'hlsf 4/12/2021 22:19:13'!
mathItem
^ morph mathItem ! !
!DrGWrappedItem methodsFor: 'accessing' stamp: 'hlsf 4/12/2021 22:19:13'!
morph
^ morph! !
!DrGWrappedItem methodsFor: 'accessing' stamp: 'hlsf 4/12/2021 22:19:13'!
morph: aCostume
morph _ aCostume ! !
!DrGWrappedItem methodsFor: 'accessing' stamp: 'hlsf 6/13/2021 12:06:25'!
style
^ morph style! !
!DrGWrappedItem class methodsFor: 'as yet unclassified' stamp: 'hlsf 4/16/2022 22:44:00'!
wrap: aMorph
^ self new morph: aMorph! !
!DrGWrappedCurve methodsFor: 'updating'!
dashed
self style lineStyle: #dash
! !
!DrGWrappedCurve methodsFor: 'updating'!
dotted
self style lineStyle: #dot! !
!DrGWrappedCurve methodsFor: 'updating'!
large
self style thickness: #large! !
!DrGWrappedCurve methodsFor: 'updating'!
normal
self style thickness: #medium! !
!DrGWrappedCurve methodsFor: 'updating'!
plain
self style lineStyle: #plain
! !
!DrGWrappedCurve methodsFor: 'updating'!
small
self style thickness: #small! !
!DrGWrappedFilledCurve methodsFor: 'updating'!
filled
self style fill: true! !
!DrGWrappedFilledCurve methodsFor: 'updating'!
opaque
self style translucent: false! !
!DrGWrappedFilledCurve methodsFor: 'updating'!
translucent
self style translucent: true! !
!DrGWrappedFilledCurve methodsFor: 'updating'!
unfilled
self style fill: false! !
!DrGWrappedFinitCurve methodsFor: 'updating' stamp: 'hlsf 6/17/2021 17:54:02'!
backArrow
self style arrow: #back! !
!DrGWrappedFinitCurve methodsFor: 'updating' stamp: 'hlsf 6/17/2021 17:53:54'!
bothArrows
self style arrow: #both! !
!DrGWrappedFinitCurve methodsFor: 'updating' stamp: 'hlsf 6/17/2021 17:53:44'!
forwardArrow
self style arrow: #forward! !
!DrGWrappedSegment methodsFor: 'updating'!
circleMark
self style mark: #circle! !
!DrGWrappedSegment methodsFor: 'updating'!
discMark
self style mark: #disc! !
!DrGWrappedSegment methodsFor: 'updating'!
doubleMark
self style mark: #mark2! !
!DrGWrappedSegment methodsFor: 'updating'!
noMark
self style mark: #none! !
!DrGWrappedSegment methodsFor: 'updating'!
simpleMark
self style mark: #mark1! !
!DrGWrappedSegment methodsFor: 'updating'!
tripleMark
self style mark: #mark3! !
!DrGWrappedPoint methodsFor: 'accessing'!
coordinates
^ self mathItem point! !
!DrGWrappedPoint methodsFor: 'accessing'!
x
^ self coordinates x! !
!DrGWrappedPoint methodsFor: 'accessing'!
y
^ self coordinates y! !
!DrGWrappedPoint methodsFor: 'updating'!
cross
self style shape: #cross! !
!DrGWrappedPoint methodsFor: 'updating'!
large
self style pointSize: #large! !
!DrGWrappedPoint methodsFor: 'updating'!
medium
self style pointSize: #medium! !
!DrGWrappedPoint methodsFor: 'updating'!
moveTo: aPoint
self mathItem moveTo: aPoint ! !
!DrGWrappedPoint methodsFor: 'updating'!
round
self style shape: #round! !
!DrGWrappedPoint methodsFor: 'updating'!
small
self style pointSize: #small! !
!DrGWrappedPoint methodsFor: 'updating'!
square
self style shape: #square! !
!DrGWrappedText methodsFor: 'accessing'!
backgroundColor: aColor
self style backgroundColor: aColor! !
!DrGWrappedText methodsFor: 'updating' stamp: 'hlsf 4/14/2022 10:51:10'!
moveTo: aPoint
self mathItem position: aPoint.
morph redrawNeeded! !
!DrGWrappedText methodsFor: 'updating' stamp: 'hlsf 6/13/2021 14:20:11'!
text: aText
self mathItem text: aText asText.
morph redrawNeeded! !
!DrGWrappedValue methodsFor: 'updating'!
moveTo: aPoint
self mathItem position: aPoint ! !
!DrGWrappedValue methodsFor: 'updating' stamp: 'hlsf 5/29/2021 17:31:27'!
name: aString
morph mathItem name: aString.
morph redrawNeeded! !
!DrGWrappedValue methodsFor: 'updating'!
value: aNumber
(self mathItem respondsTo: #valueItem:)
ifTrue: [self mathItem valueItem: aNumber]! !
!DrGeoSketch methodsFor: 'curve filled' stamp: 'hlsf 4/16/2022 22:38:28'!
circleCenter: wrpCenter radius: wrpValue
^ self
finalizeFilledCurve: (DrGCircleRadiusItem newWith: {
(self wrappedPoint: wrpCenter) mathItem.
(self wrappedValue: wrpValue) mathItem})! !
!DrGeoSketch methodsFor: 'curve filled' stamp: 'hlsf 4/16/2022 22:38:32'!
circleCenter: wrpCenter segment: wrpSegment
^ self
finalizeFilledCurve: (DrGCircleSegmentItem newWith: {
(self wrappedPoint: wrpCenter) mathItem.
wrpSegment mathItem})! !
!DrGeoSketch methodsFor: 'curve filled' stamp: 'hlsf 4/16/2022 22:38:37'!
circleCenter: wrpCenter to: wrpPt
^ self
finalizeFilledCurve: (DrGCircle2ptsItem newWith: {
(self wrappedPoint: wrpCenter) mathItem.
(self wrappedPoint: wrpPt) mathItem})! !
!DrGeoSketch methodsFor: 'curve filled' stamp: 'hlsf 9/28/2022 17:31:02'!
finalizeFilledCurve: item
^ DrGWrappedFilledCurve wrap: (self morphOf: item)! !
!DrGeoSketch methodsFor: 'curve filled' stamp: 'hlsf 4/16/2022 22:40:27'!
polygon: arguments
^ self
finalizeFilledCurve: (DrGPolygonNptsItem newWith: (arguments collect: [:wrp |
(self wrappedPoint: wrp) mathItem]))! !
!DrGeoSketch methodsFor: 'curve filled' stamp: 'hlsf 4/16/2022 22:40:54'!
regularPolygonCenter: wrpCenter vertex: wrpVertex sides: wrpValue
^ self
finalizeFilledCurve: (DrGPolygonRegularItem newWith: {
(self wrappedPoint: wrpCenter) mathItem.
(self wrappedPoint: wrpVertex) mathItem.
(self wrappedValue: wrpValue) mathItem})! !
!DrGeoSketch methodsFor: 'point' stamp: 'hlsf 4/16/2022 22:37:56'!
altIntersectionOf: wrpCurve1 and: wrpCurve2
"use this one when you want the intersection point when non straight line are involved"
| item |
item _ DrGPointIntersectionItem newWith: {wrpCurve1 mathItem. wrpCurve2 mathItem. 0 @ 0}.
item k: 1.
^ self finalizePoint: item! !
!DrGeoSketch methodsFor: 'point' stamp: 'hlsf 9/28/2022 17:31:22'!
finalizePoint: item
| wrappedPoint |
wrappedPoint _ DrGWrappedPoint wrap: (self morphOf: item).
wrappedPoint square.
^ wrappedPoint! !
!DrGeoSketch methodsFor: 'point' stamp: 'hlsf 4/16/2022 22:39:17'!
intersectionOf: wrpCurve1 and: wrpCurve2
|item|
item _ DrGPointIntersectionItem newWith: {wrpCurve1 mathItem. wrpCurve2 mathItem. 0 @ 0}.
item k: -1.
^ self
finalizePoint: (item)! !
!DrGeoSketch methodsFor: 'point' stamp: 'hlsf 4/16/2022 22:39:36'!
middleOf: wrpSegment
^ self
finalizePoint: (DrGPointMiddlesegmentItem newWith: {wrpSegment mathItem})! !
!DrGeoSketch methodsFor: 'point' stamp: 'hlsf 4/16/2022 22:39:40'!
middleOf: wrappedPoint1 and: wrappedPoint2
^ self finalizePoint: (DrGPointMiddle2ptsItem newWith:
{(self wrappedPoint: wrappedPoint1) mathItem . (self wrappedPoint: wrappedPoint2) mathItem})! !
!DrGeoSketch methodsFor: 'point' stamp: 'hlsf 4/16/2022 22:40:07'!
point: aPointOrBlock
^ aPointOrBlock isPoint
ifTrue: [self finalizePoint: (DrGPointFreeItem newWith: {aPointOrBlock})]
ifFalse: [self finalizePoint: (DrGPointBlockItem newWith: (OrderedCollection with: aPointOrBlock) )]! !
!DrGeoSketch methodsFor: 'point' stamp: 'hlsf 4/16/2022 22:40:12'!
point: block parent: wrpValue
|collection|
collection _ OrderedCollection with: block.
collection add: wrpValue mathItem.
^ self finalizePoint: (DrGPointBlockItem newWith: collection)! !
!DrGeoSketch methodsFor: 'point' stamp: 'hlsf 4/16/2022 22:40:16'!
point: block parents: wrpValueArray
|collection|
collection _ OrderedCollection with: block.
collection addAll: (wrpValueArray collect: [:wrp | wrp mathItem]).
^ self finalizePoint: (DrGPointBlockItem newWith: collection)! !
!DrGeoSketch methodsFor: 'point' stamp: 'hlsf 9/28/2022 17:34:43'!
pointOnLine: wrpCurve at: abscissa
| item |
item _ DrGPointOncurveItem newWith: {wrpCurve mathItem. 0 @ 0}.
item setCurveAbscissa: abscissa.
^ self finalizePoint: item! !
!DrGeoSketch methodsFor: 'point' stamp: 'hlsf 4/16/2022 22:40:24'!
pointX: wrpValue1 Y: wrpValue2
^ self
finalizePoint: (DrGPointCoordinateItem newWith: {wrpValue1 mathItem . wrpValue2 mathItem })! !
!DrGeoSketch methodsFor: 'point'!
wrappedPoint: aPointOrWrappedPointItem
"ensure a wrapped point"
^ aPointOrWrappedPointItem isPoint
ifTrue: [(self point: aPointOrWrappedPointItem) hide]
ifFalse: [aPointOrWrappedPointItem]! !
!DrGeoSketch methodsFor: 'user interface' stamp: 'hlsf 8/4/2023 20:05:38'!
axesOn
presenter axesOnOff ! !
!DrGeoSketch methodsFor: 'user interface' stamp: 'hlsf 8/4/2023 20:05:38'!
centerTo: aPoint
"set the center of the visible canvas to this coordinate"
presenter drawable
ox: aPoint x;
oy: aPoint y;
redrawNeeded! !
!DrGeoSketch methodsFor: 'user interface' stamp: 'hlsf 8/4/2023 20:05:38'!
fullScreen
presenter view fullScreen! !
!DrGeoSketch methodsFor: 'user interface' stamp: 'hlsf 8/4/2023 20:05:38'!
gridOn
presenter gridOnOff ! !
!DrGeoSketch methodsFor: 'user interface' stamp: 'hlsf 8/4/2023 20:05:38'!
scale: anInteger
"set scale of the canvas"
presenter drawable
setScaleTo: anInteger! !
!DrGeoSketch methodsFor: 'accessing'!
aPosition
^ 10 atRandom - 5 @ (10 atRandom - 5)! !
!DrGeoSketch methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 20:05:38'!
domain
^ presenter domain! !
!DrGeoSketch methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 20:05:38'!
drawable
^ presenter drawable ! !
!DrGeoSketch methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 12:19:10'!
morphOf: item
| finalItem |
finalItem := self domain createFromMathItemNoCommand: item.
^ finalItem == item
ifTrue: [ self drawable lastItemView ] "We create a new one, get its morph just created"
ifFalse: [ self drawable viewOf: finalItem] "For twin items, search for the former item"! !
!DrGeoSketch methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 20:05:38'!
presenter
^ presenter ! !
!DrGeoSketch methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 20:05:38'!
view
^ presenter view! !
!DrGeoSketch methodsFor: 'transformations'!
canTransform: wrptItem
wrptItem mathItem isGeometricItem
ifFalse: [self error: 'Only geometric object can be transformed.' translated].! !
!DrGeoSketch methodsFor: 'transformations' stamp: 'hlsf 5/31/2021 18:57:29'!
finalizeTransformation: string with: arguments
| class item |
class _ Smalltalk classNamed: 'DrG', arguments first basicType capitalized, string, 'Item'.
item _ class newWith: arguments.
item isPointItem
ifTrue: [^ self finalizePoint: item].
^ self finalizeCurve: item! !
!DrGeoSketch methodsFor: 'transformations' stamp: 'hlsf 4/16/2022 22:40:44'!
reflect: wrpItem axis: wrpLine
self canTransform: wrpItem.
^ self finalizeTransformation: 'Reflexion' with: {wrpItem mathItem. wrpLine mathItem}! !
!DrGeoSketch methodsFor: 'transformations' stamp: 'hlsf 4/16/2022 22:40:58'!
rotate: wrpItem center: wrpCenter angle: wrpValue
self canTransform: wrpItem.
^ self finalizeTransformation: 'Rotation' with: {
wrpItem mathItem.
(self wrappedPoint: wrpCenter) mathItem.
(self wrappedValue: wrpValue) mathItem}.
! !
!DrGeoSketch methodsFor: 'transformations' stamp: 'hlsf 3/9/2023 15:14:31'!
rotate: wrpItem center: wrpCenter angleDegrees: wrpValue
"Only work when wrpVAlue is a number and not an already existing value item, otherwise it is ignored"
| convertedValue |
convertedValue _ wrpValue isNumber ifTrue: [wrpValue degreesToRadians] ifFalse: [wrpValue].
^ self rotate: wrpItem center: wrpCenter angle: convertedValue ! !
!DrGeoSketch methodsFor: 'transformations' stamp: 'hlsf 4/16/2022 22:41:02'!
scale: wrpItem center: wrpCenter factor: wrpValue
self canTransform: wrpItem.
^ self finalizeTransformation: 'Homothety' with: {
wrpItem mathItem.
(self wrappedPoint: wrpCenter) mathItem.
(self wrappedValue: wrpValue) mathItem}
! !
!DrGeoSketch methodsFor: 'transformations' stamp: 'hlsf 4/16/2022 22:41:14'!
symmetry: wrpItem center: wrpCenter
self canTransform: wrpItem.
^ self finalizeTransformation: 'Symmetry' with: {
wrpItem mathItem.
(self wrappedPoint: wrpCenter) mathItem}! !
!DrGeoSketch methodsFor: 'transformations' stamp: 'hlsf 4/16/2022 22:41:23'!
translate: wrpItem vector: wrpVector
self canTransform: wrpItem.
^ self finalizeTransformation: 'Translation' with:
{wrpItem mathItem.
(self wrappedVector: wrpVector) mathItem}! !
!DrGeoSketch methodsFor: 'helpers' stamp: 'hlsf 6/13/2021 22:22:33'!
do: aBlock
"Execute the given construction in a forked process so the user can see the on going construction or animation"
doProcess ifNotNil: [doProcess terminate].
doProcess _ aBlock newProcess.
doProcess priority: Processor userBackgroundPriority.
doProcess resume! !
!DrGeoSketch methodsFor: 'helpers' stamp: 'hlsf 8/4/2023 20:05:38'!
exportToImage: aFilename
"Export to a SVG file"
presenter exportToImage: aFilename! !
!DrGeoSketch methodsFor: 'helpers'!
float: value at: aPoint from: startValue to: endValue
^ self float: value at: aPoint from: startValue to: endValue name: ''! !
!DrGeoSketch methodsFor: 'helpers'!
float: aValue at: aPoint from: startValue to: endValue name: name
"A valueslider ranging between startValue and endValue"
^ self float: aValue at: aPoint from: startValue to: endValue name: name showValue: false! !
!DrGeoSketch methodsFor: 'helpers' stamp: 'hlsf 8/4/2023 20:05:38'!
float: aValue at: aPoint from: startValue to: endValue name: name showValue: isValueDisplay
"A valueslider ranging between startValue and endValue"
| segment mobile|
segment _ self segment: aPoint to: aPoint + (170 / presenter drawable scale @0).
mobile _ self pointOnLine: segment at: (aValue - startValue) / (endValue - startValue).
segment color: Color black; large.
mobile name: name;
color: Color black;
round;
large.
^ isValueDisplay
ifTrue: [[|value |
value _ mobile mathItem abscissa * ( endValue - startValue) + startValue.
mobile morph labelMorph contents: name, ' = ', (value printShowingDecimalPlaces: 2).
value]]
ifFalse: [[mobile mathItem abscissa * ( endValue - startValue) + startValue]]
! !
!DrGeoSketch methodsFor: 'helpers'!
integer: value at: aPoint from: startValue to: endValue
^ self integer: value at: aPoint from: startValue to: endValue name: ''! !
!DrGeoSketch methodsFor: 'helpers'!
integer: aValue at: aPoint from: startValue to: endValue name: name
"A valueslider ranging between startValue and endValue"
^ self integer: aValue at: aPoint from: startValue to: endValue name: name showValue: false! !
!DrGeoSketch methodsFor: 'helpers' stamp: 'hlsf 8/4/2023 20:05:38'!
integer: aValue at: aPoint from: startValue to: endValue name: name showValue: isValueDisplay
"A valueslider ranging between startValue and endValue"
| segment mobile|
segment _ self segment: aPoint to: aPoint + (170 / presenter drawable scale @0).
mobile _ self pointOnLine: segment at: (aValue - startValue) / (endValue - startValue).
segment color: Color black; large.
mobile name: name;
color: Color black;
round;
large.
^ isValueDisplay
ifTrue: [[|value |
value _ (mobile mathItem abscissa * ( endValue - startValue) + startValue) floor.
mobile morph labelMorph contents: name, ' = ', value printString.
value]]
ifFalse: [[(mobile mathItem abscissa * ( endValue - startValue) + startValue) floor]]
! !
!DrGeoSketch methodsFor: 'helpers'!
plot: f from: x0 to: x1
| mobile s pen|
s _ self segment: x0@0 to: x1@0.
mobile _ self pointOnLine: s at: 0.
pen _ self
point: [:item | item point x @ (f value: item point x)]
parent: mobile.
^ (self locusOf: pen when: mobile) color: Color blue
! !
!DrGeoSketch methodsFor: 'helpers' stamp: 'hlsf 6/13/2021 22:39:05'!
terminateDo
doProcess ifNotNil: [
doProcess terminate.
doProcess _ nil]! !
!DrGeoSketch methodsFor: 'curve finit' stamp: 'hlsf 4/16/2022 22:38:19'!
arc: wrpPt1 to: wrpPt2 to: wrpPt3
^ self
finalizeFinitCurve: (DrGArc3ptsItem newWith:
{(self wrappedPoint: wrpPt1) mathItem.
(self wrappedPoint: wrpPt2) mathItem.
(self wrappedPoint: wrpPt3) mathItem})! !
!DrGeoSketch methodsFor: 'curve finit' stamp: 'hlsf 4/16/2022 22:38:24'!
arcCenter: wrpPt1 from: wrpPt2 to: wrpPt3
^ self
finalizeFinitCurve: (DrGArcCenterAngleItem newWith:
{(self wrappedPoint: wrpPt1) mathItem.
(self wrappedPoint: wrpPt2) mathItem.
(self wrappedPoint: wrpPt3) mathItem})! !
!DrGeoSketch methodsFor: 'curve finit' stamp: 'hlsf 9/28/2022 17:31:11'!
finalizeFinitCurve: item
^ DrGWrappedFinitCurve wrap: (self morphOf: item)! !
!DrGeoSketch methodsFor: 'curve finit' stamp: 'hlsf 9/28/2022 17:31:32'!
finalizeSegment: item
^ DrGWrappedSegment wrap: (self morphOf: item)! !
!DrGeoSketch methodsFor: 'curve finit' stamp: 'hlsf 4/16/2022 22:41:06'!
segment: wrpPt1 to: wrpPt2
^ self
finalizeSegment: (DrGSegment2ptsItem newWith: {
(self wrappedPoint: wrpPt1) mathItem.
(self wrappedPoint: wrpPt2) mathItem})! !
!DrGeoSketch methodsFor: 'curve finit' stamp: 'hlsf 4/16/2022 22:41:27'!
vector: wrpPt
^ self
finalizeCurve: (DrGVector2ptsItem newWith: {
(self wrappedPoint: 0@0) mathItem.
(self wrappedPoint: wrpPt) mathItem})! !
!DrGeoSketch methodsFor: 'curve finit' stamp: 'hlsf 4/16/2022 22:41:32'!
vector: wrpPt1 to: wrpPt2
^ self
finalizeCurve: (DrGVector2ptsItem newWith: {
(self wrappedPoint: wrpPt1) mathItem.
(self wrappedPoint: wrpPt2) mathItem})! !
!DrGeoSketch methodsFor: 'curve finit'!
wrappedVector: aVectorOrWrappedVectorItem
"ensure a wrapped vector"
^ aVectorOrWrappedVectorItem isPoint
ifTrue: [(self vector: aVectorOrWrappedVectorItem) hide]
ifFalse: [aVectorOrWrappedVectorItem]! !
!DrGeoSketch methodsFor: 'curve' stamp: 'hlsf 4/16/2022 22:38:09'!
angleBisector: wrpAngle
^ self finalizeCurve:
(DrGLineAngleBisectorItem newWith: {wrpAngle mathItem})! !
!DrGeoSketch methodsFor: 'curve' stamp: 'hlsf 4/16/2022 22:38:14'!
angleBisectorSummit: wrpSummit side1: wrpPt1 side2: wrpPt2
^ self finalizeCurve:
(DrGAngleBisector3ptsItem newWith:
{(self wrappedPoint: wrpPt1) mathItem.
(self wrappedPoint: wrpSummit) mathItem.
(self wrappedPoint: wrpPt2) mathItem})! !
!DrGeoSketch methodsFor: 'curve' stamp: 'hlsf 9/28/2022 17:30:52'!
finalizeCurve: item
^ DrGWrappedCurve wrap: (self morphOf: item) ! !
!DrGeoSketch methodsFor: 'curve' stamp: 'hlsf 4/16/2022 22:39:27'!
line: wrpPt1 to: wrpPt2
^ self
finalizeCurve: (DrGLine2ptsItem newWith: {
(self wrappedPoint: wrpPt1) mathItem.
(self wrappedPoint: wrpPt2) mathItem })! !
!DrGeoSketch methodsFor: 'curve' stamp: 'hlsf 4/16/2022 22:39:32'!
locusOf: wrpPt1 when: wrpPt2
wrpPt2 mathItem isPointItemOnCurve
ifFalse: [self error: 'The second point provided in the call must be on a curve.'].
^ self
finalizeCurve: (DrGLocus2ptsItem newWith: {wrpPt2 mathItem. wrpPt1 mathItem})! !
!DrGeoSketch methodsFor: 'curve' stamp: 'hlsf 4/16/2022 22:39:48'!
parallel: wrpDirection at: wrpPtOrPoint
^ self
finalizeCurve: (DrGLineParallelItem newWith: {
wrpDirection mathItem.
(self wrappedPoint: wrpPtOrPoint) mathItem})! !
!DrGeoSketch methodsFor: 'curve' stamp: 'hlsf 4/16/2022 22:39:52'!
perpendicular: wrpDirection at: wrpPtOrPoint
^ self
finalizeCurve: (DrGLinePerpendicularItem newWith: {
wrpDirection mathItem.
(self wrappedPoint: wrpPtOrPoint) mathItem})! !
!DrGeoSketch methodsFor: 'curve' stamp: 'hlsf 4/16/2022 22:39:57'!
perpendicularBisector: wrpSegment
^ self finalizeCurve:
(DrGPerpendicularBisectorItem newWith: {wrpSegment mathItem})! !
!DrGeoSketch methodsFor: 'curve' stamp: 'hlsf 4/16/2022 22:40:01'!
perpendicularBisector: wrpPt1 to: wrpPt2
^ self
finalizeCurve: (DrGLinePerpendicularBisector2ptsItem newWith: {
(self wrappedPoint: wrpPt1) mathItem.
(self wrappedPoint: wrpPt2) mathItem})! !
!DrGeoSketch methodsFor: 'curve' stamp: 'hlsf 4/16/2022 22:40:39'!
ray: wrpPt1 to: wrpPt2
^ self
finalizeCurve: (DrGRay2ptsItem newWith: {
(self wrappedPoint: wrpPt1) mathItem.
(self wrappedPoint: wrpPt2) mathItem })! !
!DrGeoSketch methodsFor: 'value' stamp: 'hlsf 4/16/2022 22:37:51'!
abscissaOf: wrpPointOrWrpVectorOrPoint
| class wrapped|
wrapped _ self wrappedPoint: wrpPointOrWrpVectorOrPoint.
wrapped mathItem isPointItem
ifTrue: [class _ DrGValuePtabscissaItem].
wrapped mathItem isVectorItem
ifTrue: [class _ DrGValueVectorabscissaItem].
^ self
finalizeValue: (class newWith: {wrapped mathItem. self aPosition})! !
!DrGeoSketch methodsFor: 'value' stamp: 'hlsf 4/16/2022 22:38:00'!
angle: wrpVect1 to: wrpVect2
^ self
finalizeValue: (DrGAngleVectorsItem newWith: {
(self wrappedVector: wrpVect1) mathItem.
(self wrappedVector: wrpVect2) mathItem.
self aPosition})
hide: false! !
!DrGeoSketch methodsFor: 'value' stamp: 'hlsf 4/16/2022 22:38:04'!
angle: wrpPt1 to: wrpPt2 to: wrpPt3
^ self
finalizeValue: (DrGAngle3ptsOrientedItem newWith: {
(self wrappedPoint: wrpPt1) mathItem.
(self wrappedPoint: wrpPt2) mathItem.
(self wrappedPoint: wrpPt3) mathItem.
self aPosition})
hide: false! !
!DrGeoSketch methodsFor: 'value' stamp: 'hlsf 4/16/2022 22:38:48'!
distance: item1 to: item2
"Distance from a point to a line or another point"
| arg class wrpItem1 wrpItem2 |
"Try to wrap to point in case the user provided point coordinates"
wrpItem1 _ self wrappedPoint: item1.
wrpItem2 _ self wrappedPoint: item2.
arg _ OrderedCollection newFrom: {wrpItem1 mathItem. wrpItem2 mathItem}.
(arg first isLineItem or: [arg second isLineItem])
ifTrue: [class _ DrGValueDistanceptlineItem.
arg first isLineItem ifTrue: [arg _ arg reverse]]
ifFalse: [class _ DrGValueDistance2ptsItem].
arg addLast: self aPosition.
^ self finalizeValue: (class newWith: arg)! !
!DrGeoSketch methodsFor: 'value'!
finalizeValue: item
"By default we don't hide the value"
^ self finalizeValue: item hide: false! !
!DrGeoSketch methodsFor: 'value' stamp: 'hlsf 9/28/2022 17:31:52'!
finalizeValue: item hide: hide
"By default we hide the value"
| wrappedItem |
wrappedItem _ DrGWrappedValue wrap: (self morphOf: item).
hide ifTrue: [ wrappedItem hide ].
^ wrappedItem! !
!DrGeoSketch methodsFor: 'value'!
freeValue: aNumber
^ self freeValue: aNumber at: self aPosition! !
!DrGeoSketch methodsFor: 'value' stamp: 'hlsf 8/4/2023 20:05:38'!
freeValue: aNumber at: aPosition
| answer |
presenter notInteractive: true.
answer := self finalizeValue: ((DrGValueValueItem newWith: {aPosition}) valueItem: aNumber).
presenter notInteractive: false.
^ answer! !
!DrGeoSketch methodsFor: 'value' stamp: 'hlsf 4/16/2022 22:39:12'!
geometricAngle: wrpPt1 to: wrpPt2 to: wrpPt3
^ self
finalizeValue: (DrGAngle3ptsItem newWith: {
(self wrappedPoint: wrpPt1) mathItem.
(self wrappedPoint: wrpPt2) mathItem.
(self wrappedPoint: wrpPt3) mathItem.
self aPosition})
hide: false! !
!DrGeoSketch methodsFor: 'value' stamp: 'hlsf 4/16/2022 22:39:21'!
lengthOf: wrpSegmentOrCircleOrArcOrVectorOrPolygon
| class |
wrpSegmentOrCircleOrArcOrVectorOrPolygon mathItem isSegmentItem
ifTrue: [class _ DrGValueSegmentlengthItem].
wrpSegmentOrCircleOrArcOrVectorOrPolygon mathItem isCircleItem
ifTrue: [class _ DrGValueCircleperimeterItem].
wrpSegmentOrCircleOrArcOrVectorOrPolygon mathItem isArcItem
ifTrue: [class _ DrGValueArclengthItem].
wrpSegmentOrCircleOrArcOrVectorOrPolygon mathItem isVectorItem
ifTrue: [class _ DrGValueVectornormItem].
wrpSegmentOrCircleOrArcOrVectorOrPolygon mathItem isPolygonItem
ifTrue: [class _ DrGValuePolygonperimeterItem].
^ self
finalizeValue: (class newWith: {wrpSegmentOrCircleOrArcOrVectorOrPolygon mathItem. self aPosition})! !
!DrGeoSketch methodsFor: 'value' stamp: 'hlsf 4/16/2022 22:39:44'!
ordinateOf: wrpPointOrWrpVectorOrPoint
| class wrapped |
wrapped _ self wrappedPoint: wrpPointOrWrpVectorOrPoint.
wrapped mathItem isPointItem
ifTrue: [class _ DrGValuePtordinateItem].
wrapped mathItem isVectorItem
ifTrue: [class _ DrGValueVectorordinateItem].
^ self
finalizeValue: (class newWith: {wrapped mathItem. self aPosition})! !
!DrGeoSketch methodsFor: 'value' stamp: 'hlsf 4/16/2022 22:41:10'!
slopeOf: wrpLine
^ self
finalizeValue: (DrGValueSlopeItem newWith: {wrpLine mathItem. self aPosition})! !
!DrGeoSketch methodsFor: 'value'!
wrappedValue: aNumberOrWrappedValueItem
"ensure a wrapped value"
^ aNumberOrWrappedValueItem isNumber
ifTrue: [(self freeValue: aNumberOrWrappedValueItem ) hide]
ifFalse: [aNumberOrWrappedValueItem]! !
!DrGeoSketch methodsFor: 'equation' stamp: 'hlsf 4/16/2022 22:39:04'!
equationOf: wrpLineOrCircle
| class |
wrpLineOrCircle mathItem isLineItem
ifTrue: [class _ DrGEquationLineItem ].
wrpLineOrCircle mathItem isCircleItem
ifTrue: [class _ DrGEquationCircleItem].
^ self
finalizeValue: (class newWith: {wrpLineOrCircle mathItem. self aPosition})! !
!DrGeoSketch methodsFor: 'processing' stamp: 'hlsf 4/14/2022 10:46:54'!
update
self domain updateAllMathItems! !
!DrGeoSketch methodsFor: 'text' stamp: 'hlsf 9/28/2022 17:31:41'!
finalizeText: item
^ DrGWrappedText wrap: (self morphOf: item)! !
!DrGeoSketch methodsFor: 'text'!
text: aText
^ self text:aText at: self aPosition! !
!DrGeoSketch methodsFor: 'text' stamp: 'hlsf 8/4/2023 20:05:38'!
text: aText at: aPosition
| answer |
presenter notInteractive: true.
answer := self finalizeText: ((DrGTextItem newWith: {aPosition}) text: aText asText).
presenter notInteractive: false.
^ answer! !
!DrGeoSketch methodsFor: 'initialize-release' stamp: 'hlsf 9/25/2022 11:32:31'!
delete
self view deleteWithoutConfirmation.
self release! !
!DrGeoSketch methodsFor: 'initialize-release' stamp: 'hlsf 11/14/2023 00:19:49'!
initialize
presenter := DrGeo service
stSketch: self;
yourself .
DrGeoSketch triggerEvent: #newSmalltalkSketch with: self! !
!DrGeoSketch methodsFor: 'initialize-release' stamp: 'hlsf 8/4/2023 20:05:38'!
release
presenter ifNotNil: [presenter release].
presenter _ nil.
self terminateDo ! !
!DrGeoSketch methodsFor: 'obsolete' stamp: 'hlsf 4/10/2022 20:30:29'!
fullscreen
! !
!DrGMathItem methodsFor: 'accessing'!
basicType
^#mathItem! !
!DrGMathItem methodsFor: 'accessing' stamp: 'hlsf 5/4/2020 12:30:16'!
descriptiveName
^ self adaptiveDescriptiveName
copyReplaceAll: '%1'
with: self safeName! !
!DrGMathItem methodsFor: 'accessing'!
exist
^exist! !
!DrGMathItem methodsFor: 'accessing'!
exist: aBoolean
exist _ aBoolean! !
!DrGMathItem methodsFor: 'accessing' stamp: 'hlsf 2/11/2022 08:56:49'!
icon
^ nil! !
!DrGMathItem methodsFor: 'accessing'!
id
^id! !
!DrGMathItem methodsFor: 'accessing'!
id: aSymbol
id _ aSymbol! !
!DrGMathItem methodsFor: 'accessing' stamp: 'hlsf 4/12/2021 22:27:45'!
morphClass
^ DrGMorph! !
!DrGMathItem methodsFor: 'accessing'!
name
^name! !
!DrGMathItem methodsFor: 'accessing'!
name: aString
name _ aString ! !
!DrGMathItem methodsFor: 'accessing'!
parents
^ parents ! !
!DrGMathItem methodsFor: 'accessing'!
parents: aCollection
parents _ aCollection.! !
!DrGMathItem methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 17:11:29'!
parents: aCollection in: presenter
self parents: aCollection! !
!DrGMathItem methodsFor: 'accessing'!
position
self shouldBeImplemented.! !
!DrGMathItem methodsFor: 'accessing'!
safeName
| itsName |
itsName _ self name.
^ (itsName isNil or: [itsName isEmpty])
ifTrue: ['']
ifFalse: [itsName]! !
!DrGMathItem methodsFor: 'printing'!
printCoordinates: aPoint on: aStream
aPoint ifNotNil: [
aStream nextPut: $(.
self printDecimal: aPoint x on: aStream.
aStream nextPutAll: ' ; '.
self printDecimal: aPoint y on: aStream.
aStream nextPut: $)].
! !
!DrGMathItem methodsFor: 'printing' stamp: 'hlsf 5/2/2020 12:42:44'!
printDecimal: aValue on: aStream
aValue isInfinite
ifTrue: [aStream nextPutAll: 'inf.']
ifFalse: [
(aValue isInteger or: [aValue isFraction])
ifFalse: [aValue printOn: aStream fractionDigits: 1]
ifTrue: [aStream print: aValue]]! !
!DrGMathItem methodsFor: 'printing'!
printInteger: aValue on: aStream
aStream nextPutAll: aValue rounded asString! !
!DrGMathItem methodsFor: 'printing'!
printOn: aStream
aStream
nextPutAll: 'a ';
nextPutAll: self basicType capitalized;
nextPutAll: self nodeType capitalized;
nextPut: Character space.
! !
!DrGMathItem methodsFor: 'printing'!
printType: aString on: aStream
aStream nextPutAll: aString;
nextPut: Character space;
nextPutAll: self safeName! !
!DrGMathItem methodsFor: 'comparing'!
= aMathItem
^ aMathItem isMathItem
ifFalse: [false]
ifTrue: [self basicType == aMathItem basicType
and: [self nodeType == aMathItem nodeType
and: [self parentsEqual: aMathItem]]]! !
!DrGMathItem methodsFor: 'comparing'!
hash
^ hash! !
!DrGMathItem methodsFor: 'comparing'!
parentsEqual: aMathItem
^ parents = aMathItem parents! !
!DrGMathItem methodsFor: 'comparing'!
parentsIncludes: aMathItem
"An idendity comparaison"
^ parents notNil and: [parents anySatisfy: [:each | each == aMathItem]]! !
!DrGMathItem methodsFor: 'comparing'!
rehash
^ hash _ (parents hash bitXor: self nodeType hash) bitXor: self basicType hash! !
!DrGMathItem methodsFor: 'event' stamp: 'hlsf 5/4/2020 21:23:26'!
actionMap: anObject
'actionMap _ anObject '! !
!DrGMathItem methodsFor: 'initialize-release'!
initialize
parents _ nil.
exist _ true.! !
!DrGMathItem methodsFor: 'initialize-release'!
initialize: theParents
! !
!DrGMathItem methodsFor: 'initialize-release' stamp: 'hlsf 5/25/2023 18:58:03'!
release
self triggerEvent: #deletedMathItem.
"Do it last otherwise our deletedMathItem will never be sent"
self flag: #drgeoEvent! !
!DrGMathItem methodsFor: 'private'!
adaptiveDescriptiveName
^ 'This math item %1' translated! !
!DrGMathItem methodsFor: 'xml writing'!
nodeType
^ #mathItem! !
!DrGMathItem methodsFor: 'xml writing'!
writeAsXmlTo: aNode
"return the newly created element"
| node |
self rehash.
node _ XMLElement named: self basicType attributes: Dictionary new.
node attributeAt: #type put: self nodeType;
attributeAt: #name put: (name ifNil: ['']);
attributeAt: #id put: self hash asString.
self writeParentsAsXmlTo: node.
aNode addElement: node.
^node! !
!DrGMathItem methodsFor: 'xml writing'!
writeParents: collection asXmlTo: aNode
"write parents reference in the natural order"
|attr|
collection do: [:each |
attr _ Dictionary new.
attr at: #ref put: each hash asString.
aNode addElement: (XMLElement named: #parent attributes: attr)]! !
!DrGMathItem methodsFor: 'xml writing'!
writeParentsAsXmlTo: aNode
parents ifNotNil:
[self writeParents: parents asXmlTo: aNode]! !
!DrGMathItem methodsFor: 'computing'!
abscissaOf: aPoint
self subclassResponsibility! !
!DrGMathItem methodsFor: 'computing'!
clone
"Return a collection with the necessary parents (free points) and a clone of myself"
self shouldNotImplement! !
!DrGMathItem methodsFor: 'computing'!
closestPointTo: aPoint
self subclassResponsibility ! !
!DrGMathItem methodsFor: 'computing'!
intersectionWith: aCurveItem
^ Array
with: (self intersectionWith: aCurveItem flag: 1)
with: (self intersectionWith: aCurveItem flag: -1)! !
!DrGMathItem methodsFor: 'computing'!
intersectionWith: aCurveItem flag: aFlag
self subclassResponsibility ! !
!DrGMathItem methodsFor: 'computing'!
pointAt: anAbscissa
self subclassResponsibility ! !
!DrGMathItem methodsFor: 'updating' stamp: 'hlsf 3/19/2022 17:08:27'!
changed
self triggerEvent: #updateMyView! !
!DrGMathItem methodsFor: 'updating'!
move: aPoint
! !
!DrGMathItem methodsFor: 'updating'!
moveAt: aPoint
self shouldNotImplement! !
!DrGMathItem methodsFor: 'updating'!
moveEvent: aPoint
(self moveParent: aPoint)
ifFalse:
["parents are not moving, we can upate ourself"
self move: aPoint].
! !
!DrGMathItem methodsFor: 'updating'!
moveParent: aPoint
"By default we try reverse dragging (move parents).
This behaviour should be overridden for some mathItem, for example a free point on a curve should not reverse dragging the curve it belongs to.
Return true if we are doing reverse dragging, otherwise false"
parents ifNotNil:
[parents do: [:parent|
parent moveEvent: aPoint]].
^true.! !
!DrGMathItem methodsFor: 'updating'!
property
self subclassResponsibility ! !
!DrGMathItem methodsFor: 'updating'!
property: aProperty
self subclassResponsibility ! !
!DrGMathItem methodsFor: 'updating'!
update
! !
!DrGMathItem methodsFor: 'testing'!
contains: aPoint
self subclassResponsibility ! !
!DrGMathItem methodsFor: 'testing'!
doParentsExist
exist _ true.
parents
ifNotNil:
[parents do: [:parent |
parent exist ifFalse: [^ exist _ false]]]
ifNil: [exist _ false].
^exist
! !
!DrGMathItem methodsFor: 'testing'!
isCloneable
^ false! !
!DrGMathItem methodsFor: 'testing'!
isLockable
^ false! !
!DrGMathItem methodsFor: 'testing'!
isPropertyEditable
^ false! !
!DrGMathItem methodsFor: 'testing-model'!
isAngleItem
^false! !
!DrGMathItem methodsFor: 'testing-model'!
isArcItem
^false! !
!DrGMathItem methodsFor: 'testing-model' stamp: 'HilaireFernandes 2/27/2013 14:21'!
isBitmapItem
^false! !
!DrGMathItem methodsFor: 'testing-model'!
isCircleItem
^false! !
!DrGMathItem methodsFor: 'testing-model'!
isCompositeItem
^false! !
!DrGMathItem methodsFor: 'testing-model'!
isConstrainedPointItem
^false! !
!DrGMathItem methodsFor: 'testing-model' stamp: 'HilaireFernandes 2/24/2013 08:37'!
isCurveItem
"When true, free point can be constrained on this item line"
^false! !
!DrGMathItem methodsFor: 'testing-model' stamp: 'HilaireFernandes 2/24/2013 08:37'!
isDirectionItem
"When true, this item are straight line with normal and unit vector"
^false! !
!DrGMathItem methodsFor: 'testing-model' stamp: 'HilaireFernandes 8/2/2012 23:10'!
isEquation
^ false! !
!DrGMathItem methodsFor: 'testing-model'!
isFreePointItem
^false! !
!DrGMathItem methodsFor: 'testing-model' stamp: 'HilaireFernandes 7/24/2012 22:16'!
isFreePointOnPlaneItem
^false! !
!DrGMathItem methodsFor: 'testing-model'!
isGeometricItem
^false! !
!DrGMathItem methodsFor: 'testing-model' stamp: 'HilaireFernandes 2/24/2013 08:46'!
isIntersectableItem
"When true, this curve can be intersected"
^self isCurveItem! !
!DrGMathItem methodsFor: 'testing-model'!
isIntersectionPointItem
^false! !
!DrGMathItem methodsFor: 'testing-model'!
isLineItem
^false! !
!DrGMathItem methodsFor: 'testing-model'!
isLocusItem
^false! !
!DrGMathItem methodsFor: 'testing-model'!
isMathItem
^ true! !
!DrGMathItem methodsFor: 'testing-model'!
isNumberItem
^false! !
!DrGMathItem methodsFor: 'testing-model'!
isPointItem
^false! !
!DrGMathItem methodsFor: 'testing-model'!
isPointItemOnCurve
^false! !
!DrGMathItem methodsFor: 'testing-model'!
isPolygonItem
^false! !
!DrGMathItem methodsFor: 'testing-model'!
isRayItem
^false! !
!DrGMathItem methodsFor: 'testing-model'!
isScriptItem
^false! !
!DrGMathItem methodsFor: 'testing-model'!
isSegmentItem
^false! !
!DrGMathItem methodsFor: 'testing-model'!
isTextItem
^false! !
!DrGMathItem methodsFor: 'testing-model'!
isValueItem
^false! !
!DrGMathItem methodsFor: 'testing-model'!
isVectorItem
^false! !
!DrGMathItem class methodsFor: 'instance creation'!
newWith: theParents
"Instantiate this mathItem with these parents
Parents contains other MathItem instance, sometime it contains other object as Point"
^self new
parents: theParents;
initialize: theParents;
update;
rehash;
yourself! !
!DrGMathItem class methodsFor: 'instance creation' stamp: 'hlsf 8/4/2023 17:13:54'!
newWith: theParents in: aPresenter
"Instantiate this mathItem with these parents
Parents contains other MathItem instance, sometime it contains other object as Point"
^ self new
parents: theParents in: aPresenter;
initialize: theParents;
update;
rehash;
yourself ! !
!DrGArcItem methodsFor: 'printing'!
printOn: aStream
self printType: DrGArcBuilder title on: aStream.
aStream nextPut: Character space.
self printDecimal: (length * radius ) abs on: aStream.! !
!DrGArcItem methodsFor: 'private'!
adaptiveDescriptiveName
^ 'This Arc Circle %1' translated! !
!DrGArcItem methodsFor: 'private' stamp: 'hlsf 6/5/2021 20:18:05'!
angleOf: aPoint
"Compute the angle position of aPoint in the circle"
| angleM pointM |
pointM _ aPoint - center.
angleM _ (pointM y asFloat arcTan: pointM x) - origin.
length > 0
ifTrue: [
angleM < 0 ifTrue: [ angleM _ angleM + Float twoPi ].
angleM _ angleM min: length ]
ifFalse: [
angleM > 0 ifTrue: [ angleM _ angleM - Float twoPi ].
angleM _ angleM max: length ].
^ angleM! !
!DrGArcItem methodsFor: 'computing'!
clone
|pointA pointB pointC clone|
pointA _ DrGPointFreeItem newWith: {(self pointAt: 0) + (0.2@0.2)}.
pointB _ DrGPointFreeItem newWith: {(self pointAt: 0.5) + (0.2@0.2)}.
pointC _ DrGPointFreeItem newWith: {(self pointAt: 1) + (0.2@0.2)}.
clone _ DrGArc3ptsItem newWith: {pointA . pointB . pointC}.
^ {pointA . pointB . pointC. clone}! !
!DrGArcItem methodsFor: 'computing'!
closestPointTo: aPoint
| angle |
angle _ self angleOf: aPoint.
^center + (radius * ((origin + angle) cos @ (origin + angle) sin))! !
!DrGArcItem methodsFor: 'computing'!
intersectionWith: aCurveItem flag: aFlag
| aPoint |
aCurveItem isLineItem
ifTrue:
[aPoint _ self intersectionWithDirection: aCurveItem flag: aFlag.
aPoint ifNil: [^nil].
(self contains: aPoint)
ifTrue: [^aPoint]
ifFalse: [^nil]].
(aCurveItem isRayItem or: [aCurveItem isSegmentItem])
ifTrue:
[aPoint _ self intersectionWithDirection: aCurveItem flag: aFlag.
aPoint ifNil: [^nil].
((self contains: aPoint) and: [aCurveItem contains: aPoint])
ifTrue: [^aPoint]
ifFalse: [^nil]].
aCurveItem isCircleItem
ifTrue:
[aPoint _ self intersectionWithCircle: aCurveItem flag: aFlag.
aPoint ifNil: [^nil].
(self contains: aPoint)
ifTrue: [^aPoint]
ifFalse: [^nil]].
aCurveItem isArcItem
ifTrue:
[aPoint _ self intersectionWithCircle: aCurveItem flag: aFlag.
aPoint ifNil: [^nil].
((self contains: aPoint) and: [aCurveItem contains: aPoint])
ifTrue: [^aPoint]
ifFalse: [^nil]].
! !
!DrGArcItem methodsFor: 'computing'!
intersectionWithCircle: aCircleOrArcItem flag: aFlag
| circleItem |
circleItem _ (DrGCircleItem new)
center: self center;
radius: self radius.
^circleItem intersectionWithCircle: aCircleOrArcItem flag: aFlag! !
!DrGArcItem methodsFor: 'computing'!
intersectionWithDirection: aDirectionItem flag: aFlag
| circleItem |
circleItem _ (DrGCircleItem new)
center: self center;
radius: self radius.
^circleItem intersectionWithDirection: aDirectionItem flag: aFlag! !
!DrGArcItem methodsFor: 'computing'!
pointAt: anAbscissa
|angle|
angle _ origin + (anAbscissa * length).
^center + (radius * (angle cos @ angle sin))
! !
!DrGArcItem methodsFor: 'testing' stamp: 'hlsf 6/5/2021 20:17:40'!
contains: aPoint
| angleM pointM |
((center dist: aPoint) closeTo: radius) ifFalse: [^false].
pointM _ aPoint - center.
angleM _ (pointM y asFloat arcTan: pointM x) - origin.
^ length > 0
ifTrue:
[angleM < 0 ifTrue: [angleM _ angleM + Float twoPi].
length >= angleM]
ifFalse:
[angleM > 0 ifTrue: [angleM _ angleM - Float twoPi].
length <= angleM]! !
!DrGArcItem methodsFor: 'testing'!
isCloneable
^ true! !
!DrGArcItem methodsFor: 'accessing'!
abscissaOf: aPoint
^(self angleOf: aPoint) / length! !
!DrGArcItem methodsFor: 'accessing'!
basicType
^#arc! !
!DrGArcItem methodsFor: 'accessing'!
center
^center! !
!DrGArcItem methodsFor: 'accessing'!
center: aPoint
center _ aPoint ! !
!DrGArcItem methodsFor: 'accessing'!
length
"the arc length, in radius, can be negative"
^length! !
!DrGArcItem methodsFor: 'accessing'!
length: aFloat
length _ aFloat ! !
!DrGArcItem methodsFor: 'accessing' stamp: 'hlsf 4/12/2021 22:27:45'!
morphClass
^DrGArcMorph! !
!DrGArcItem methodsFor: 'accessing'!
origin
^origin! !
!DrGArcItem methodsFor: 'accessing'!
origin: aFloat
origin _ aFloat ! !
!DrGArcItem methodsFor: 'accessing'!
radius
^radius! !
!DrGArcItem methodsFor: 'accessing'!
radius: aFloat
radius _ aFloat! !
!DrGArcItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:22:39'!
isArcItem
^true! !
!DrGArcItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:23:03'!
isCurveItem
^true! !
!DrGArcItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:26:01'!
isGeometricItem
^ true! !
!DrGArc3ptsItem methodsFor: 'updating' stamp: 'hlsf 5/4/2021 20:46:58'!
update
| direction1 direction2 a b c ab |
self doParentsExist ifTrue:
[a _ parents first point.
b _ parents second point.
c _ parents third point.
(a = b or: [c = b]) ifTrue: [^exist _ false].
direction1 _ (DrGDirectionItem new)
origin: (a + b) / 2;
direction: (a - b) normal.
direction2 _ (DrGDirectionItem new)
origin: (b + c) / 2;
direction: (b - c) normal.
center _ direction1 intersectionWithDirection: direction2.
center ifNil: [^self updateAsSegmentOrRay].
a _ a - center.
b _ b - center.
c _ c - center.
radius _ a r.
origin _ a y asFloat arcTan: a x.
ab _ (b y asFloat arcTan: b x) - origin.
length _ (c y asFloat arcTan: c x) - origin.
length = 0 ifTrue: [^exist _ false].
(length < 0 and: [ab < length or: [ab > 0]]) ifTrue:
[^length _ length + Float twoPi].
(length > 0 and: [ab > length or: [ab < 0]]) ifTrue:
[length _ length - Float twoPi]].! !
!DrGArc3ptsItem methodsFor: 'updating'!
updateAsSegmentOrRay
"the three point are aligned, the arc is a segment"
exist _ false.! !
!DrGArc3ptsItem methodsFor: 'as yet unclassified'!
rehash
^ hash _ ((parents hash bitXor: parents reverse hash) bitXor: self nodeType hash) bitXor: self basicType hash! !
!DrGArc3ptsItem methodsFor: 'xml writing'!
nodeType
^#'3pts'! !
!DrGArc3ptsItem methodsFor: 'comparing'!
parentsEqual: aMathItem
^ parents = aMathItem parents
or: [parents reverse = aMathItem parents]! !
!DrGArcCenterAngleItem methodsFor: 'updating' stamp: 'hlsf 5/4/2021 20:41:50'!
update
| u v |
self doParentsExist ifTrue:
[center _ parents first point.
u _ parents second point - center.
v _ parents third point - center.
(u = (0@0) or: [v = (0@0)])
ifTrue: [exist _ false]
ifFalse:
[radius _ u r.
origin _ u y asFloat arcTan: u x.
length _ (u crossProduct: v) asFloat arcTan: (u dotProduct: v).
length < 0 ifTrue: [ length _ length + Float twoPi]]]! !
!DrGArcCenterAngleItem methodsFor: 'xml writing'!
nodeType
^ #centerAngle! !
!DrGArcHomothetyItem methodsFor: 'xml writing'!
nodeType
^#Scale! !
!DrGArcHomothetyItem methodsFor: 'updating'!
moveParent: aPoint
^false! !
!DrGArcHomothetyItem methodsFor: 'updating'!
update
|arcItem centerHomothety|
self doParentsExist ifTrue:
[arcItem _ parents first.
centerHomothety _ parents second point.
center _ centerHomothety +
(parents third valueItem * (arcItem center - centerHomothety)).
radius _ arcItem radius * parents third valueItem abs.
origin _ arcItem origin + (parents third valueItem sign -1 * Float halfPi).
length _ arcItem length].! !
!DrGArcReflexionItem methodsFor: 'xml writing'!
nodeType
^#Reflexion! !
!DrGArcReflexionItem methodsFor: 'updating'!
moveParent: aPoint
^false! !
!DrGArcReflexionItem methodsFor: 'updating' stamp: 'hlsf 6/5/2021 20:17:50'!
update
|pointA|
self doParentsExist ifTrue:
[origin _ parents first origin.
radius _ parents first radius.
center _ parents first center.
length _ parents first length negated.
pointA _ center + (radius * (origin cos @ origin sin)).
pointA _ pointA reflexionBy: parents second origin
direction: parents second direction.
center _ center reflexionBy: parents second origin
direction: parents second direction.
pointA _ pointA - center.
origin _ pointA y asFloat arcTan: pointA x].
! !
!DrGArcRotationItem methodsFor: 'xml writing'!
nodeType
^#Reflexion! !
!DrGArcRotationItem methodsFor: 'updating'!
moveParent: aPoint
^false! !
!DrGArcRotationItem methodsFor: 'updating'!
update
|arcItem|
self doParentsExist ifTrue:
[arcItem _ parents first.
center _ arcItem center
rotateBy: parents third valueItem negated
about: parents second point.
origin _ arcItem origin + parents third valueItem.
length _ arcItem length.
radius _ arcItem radius].
! !
!DrGArcSymmetryItem methodsFor: 'updating'!
moveParent: aPoint
^false! !
!DrGArcSymmetryItem methodsFor: 'updating'!
update
self doParentsExist
ifTrue:
[origin _ parents first origin + Float pi.
origin > Float pi ifTrue: [origin _ origin - Float twoPi].
radius _ parents first radius.
center _ 2 * parents second point - parents first center.
length _ parents first length].
! !
!DrGArcSymmetryItem methodsFor: 'xml writing'!
nodeType
^#Symmetry! !
!DrGArcTranslationItem methodsFor: 'xml writing'!
nodeType
^#Translation! !
!DrGArcTranslationItem methodsFor: 'updating'!
moveParent: aPoint
^false! !
!DrGArcTranslationItem methodsFor: 'updating'!
update
self doParentsExist ifTrue:
[origin _ parents first origin.
radius _ parents first radius.
center _ parents first center + parents second direction.
length _ parents first length].
! !
!DrGBitmapItem methodsFor: 'printing'!
printOn: aStream
self printType: 'Picture' translated on: aStream.
self printCoordinates: position on: aStream ! !
!DrGBitmapItem methodsFor: 'testing'!
doParentsExist
^ true! !
!DrGBitmapItem methodsFor: 'testing'!
isLockable
^ true! !
!DrGBitmapItem methodsFor: 'testing'!
isPropertyEditable
^ false! !
!DrGBitmapItem methodsFor: 'updating'!
move: aPoint
self isLocked ifFalse: [position _ position + aPoint]! !
!DrGBitmapItem methodsFor: 'updating'!
moveParent: aPoint
^ false! !
!DrGBitmapItem methodsFor: 'xml writing'!
nodeType
^#free! !
!DrGBitmapItem methodsFor: 'xml writing'!
writeAsXmlPositionTo: aNode
"return the newly created element"
aNode
addElement: ((XMLElement named: #x)
addContent: (XMLStringNode string: position x asString));
addElement: ((XMLElement named: #y)
addContent: (XMLStringNode string: position y asString)).
^ aNode! !
!DrGBitmapItem methodsFor: 'xml writing' stamp: 'hlsf 4/21/2020 21:33:52'!
writeAsXmlTo: aNode
|node stream |
stream _ ByteArray new writeStream.
PNGReadWriter putForm: data asForm onStream: stream.
DrGeoSystem stopSpinner.
node _ super writeAsXmlTo: aNode.
self writeAsXmlPositionTo: node.
node
addElement: ((XMLElement named: #insertAtScale)
addContent: (XMLStringNode string: canvasScaleAtInsertion asString));
addElement: ((XMLElement named: #magnify)
addContent: (XMLStringNode string: magnifyBy asString));
addElement: ((XMLElement named: #data)
addContent: (XMLStringNode string: stream contents base64Encoded)).
^ node
! !
!DrGBitmapItem methodsFor: 'comparing'!
= aMathItem
^ super = aMathItem
and: [position = aMathItem position and:
[data = aMathItem data]]! !
!DrGBitmapItem methodsFor: 'comparing'!
rehash
^ hash _ data hash bitXor: position hash! !
!DrGBitmapItem methodsFor: 'accessing'!
basicType
^ #bitmap! !
!DrGBitmapItem methodsFor: 'accessing'!
data
^ data! !
!DrGBitmapItem methodsFor: 'accessing'!
data: anAthensPaint
data _ anAthensPaint ! !
!DrGBitmapItem methodsFor: 'accessing'!
descriptiveName
^ self adaptiveDescriptiveName ! !
!DrGBitmapItem methodsFor: 'accessing'!
height
"height in the world coordinates system"
^ data extent y * self magnifiedScale ! !
!DrGBitmapItem methodsFor: 'accessing'!
insertAtScale
^ canvasScaleAtInsertion ! !
!DrGBitmapItem methodsFor: 'accessing'!
insertAtScale: aScale
canvasScaleAtInsertion _ aScale ! !
!DrGBitmapItem methodsFor: 'accessing'!
isLocked
^ locked ifNil: [locked _ false]! !
!DrGBitmapItem methodsFor: 'accessing'!
locked: aBoolean
locked _ aBoolean ! !
!DrGBitmapItem methodsFor: 'accessing'!
magnifiedScale
"Scale factor accordingly to the canvas scale at insertion and the magnify factor"
^ (magnifyBy / canvasScaleAtInsertion ) asFloat! !
!DrGBitmapItem methodsFor: 'accessing'!
magnifyBy
^ magnifyBy ! !
!DrGBitmapItem methodsFor: 'accessing'!
magnifyBy: aFloat
magnifyBy _ aFloat ! !
!DrGBitmapItem methodsFor: 'accessing' stamp: 'hlsf 4/12/2021 22:27:45'!
morphClass
^ DrGBitmapMorph! !
!DrGBitmapItem methodsFor: 'accessing'!
parents: aCollection
parents _ nil.
! !
!DrGBitmapItem methodsFor: 'accessing'!
position
^ position! !
!DrGBitmapItem methodsFor: 'accessing'!
position: aPoint
position _ aPoint.! !
!DrGBitmapItem methodsFor: 'accessing'!
topCenter
"top center position in the world coordinates system"
^ position + (0@(self height / 2))! !
!DrGBitmapItem methodsFor: 'initialize-release'!
initialize
super initialize.
magnifyBy _ 1.! !
!DrGBitmapItem methodsFor: 'initialize-release'!
initialize: theParents
super initialize: theParents.
self position: theParents last! !
!DrGBitmapItem methodsFor: 'private'!
adaptiveDescriptiveName
^ 'This picture' translated! !
!DrGBitmapItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:23:56'!
isBitmapItem
^ true! !
!DrGCircleItem methodsFor: 'printing'!
printOn: aStream
self printType: DrGCircleBuilder title on: aStream .
aStream nextPut: Character space.
self printCoordinates: center on: aStream.
aStream nextPut: Character space.
self printDecimal: radius on: aStream! !
!DrGCircleItem methodsFor: 'private'!
adaptiveDescriptiveName
^ 'This circle %1' translated! !
!DrGCircleItem methodsFor: 'testing'!
contains: aPoint
^ (center dist: aPoint) closeTo: radius ! !
!DrGCircleItem methodsFor: 'testing'!
isCloneable
^ true! !
!DrGCircleItem methodsFor: 'computing'!
clone
|pointA pointB clone|
pointA _ DrGPointFreeItem newWith: {self center + (0.2@0.2)}.
pointB _ DrGPointFreeItem newWith: {(self pointAt: 0) + (0.2@0.2)}.
clone _ DrGCircle2ptsItem newWith: {pointA . pointB}.
^ {pointA . pointB . clone}! !
!DrGCircleItem methodsFor: 'computing'!
intersectionWith: aCurveItem flag: aFlag
|aPoint|
aCurveItem isLineItem
ifTrue: [^self intersectionWithDirection: aCurveItem flag: aFlag].
(aCurveItem isSegmentItem or: [aCurveItem isRayItem])
ifTrue:
[aPoint _ self intersectionWithDirection: aCurveItem flag: aFlag.
aPoint ifNil: [^nil].
(aCurveItem contains: aPoint)
ifTrue: [^aPoint]
ifFalse: [^nil]].
aCurveItem isCircleItem
ifTrue: [^self intersectionWithCircle: aCurveItem flag: aFlag].
aCurveItem isArcItem
ifTrue: [^aCurveItem intersectionWith: self flag: aFlag]! !
!DrGCircleItem methodsFor: 'computing'!
intersectionWithCircle: aCircleItem flag: aFlag
| directionItem aVector aRadius x d |
directionItem _ DrGDirectionItem new.
aVector _ aCircleItem center - center.
aRadius _ aCircleItem radius.
d _ aVector dotProduct: aVector.
d = 0 ifTrue: [ ^ nil ].
x _ (d + radius squared - aRadius squared) / (2 * d).
directionItem direction: aVector normal.
directionItem origin: x * aVector + center.
^self intersectionWithDirection: directionItem flag: aFlag! !
!DrGCircleItem methodsFor: 'computing'!
intersectionWithDirection: aDirectionItem flag: aFlag
|a b c d k vector|
vector _ aDirectionItem direction.
a _ vector dotProduct: vector.
b _ vector dotProduct: (aDirectionItem origin - self center).
c _ (aDirectionItem origin squaredDistanceTo: self center) - self radius squared.
d _ b squared - (a * c).
(d < 0 or: [a = 0]) ifTrue: [^ nil].
k _ (b negated + (aFlag * d sqrt)) / a.
^ aDirectionItem origin + (k * vector)! !
!DrGCircleItem methodsFor: 'accessing'!
abscissaOf: aPoint
| angle vector |
vector _ aPoint - self center.
angle _ vector y arcTan: vector x.
angle < 0 ifTrue: [angle _ angle + (2 * Float pi)].
^angle * 0.5 * DrGDirectionItem invPi! !
!DrGCircleItem methodsFor: 'accessing'!
basicType
^#circle! !
!DrGCircleItem methodsFor: 'accessing'!
center
^center! !
!DrGCircleItem methodsFor: 'accessing'!
center: aPoint
center _ aPoint ! !
!DrGCircleItem methodsFor: 'accessing'!
closestPointTo: aPoint
| v |
[v _ (aPoint - self center) normalized] on: ZeroDivide do: [ v _ 0 @ 0 ].
^self center + (self radius * v)! !
!DrGCircleItem methodsFor: 'accessing' stamp: 'hlsf 4/12/2021 22:27:45'!
morphClass
^DrGCircleMorph! !
!DrGCircleItem methodsFor: 'accessing'!
pointAt: anAbscissa
|angle|
angle _ 2 * Float pi * anAbscissa.
^ (Point x: angle cos y: angle sin) * self radius + self center.! !
!DrGCircleItem methodsFor: 'accessing'!
radius
^radius! !
!DrGCircleItem methodsFor: 'accessing'!
radius: aFlaot
radius _ aFlaot ! !
!DrGCircleItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:24:23'!
isCircleItem
^ true! !
!DrGCircleItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:24:19'!
isCurveItem
^ true! !
!DrGCircleItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:26:10'!
isGeometricItem
^ true! !
!DrGCircle2ptsItem methodsFor: 'xml writing'!
nodeType
^#'2pts'! !
!DrGCircle2ptsItem methodsFor: 'updating'!
update
self doParentsExist
ifTrue: [center _ parents first point.
radius _ center dist: parents second point].! !
!DrGCircleHomothetyItem methodsFor: 'xml writing'!
nodeType
^#Scale! !
!DrGCircleHomothetyItem methodsFor: 'updating'!
moveParent: aPoint
^false! !
!DrGCircleHomothetyItem methodsFor: 'updating'!
update
|centerHomothety|
self doParentsExist ifTrue:
[centerHomothety _ parents second point.
radius _ parents first radius * parents third valueItem abs.
center _ centerHomothety +
(parents third valueItem * (parents first center - centerHomothety))].! !
!DrGCircleRadiusItem methodsFor: 'computing'!
clone
|pointA clone radiusItem |
pointA _ DrGPointFreeItem newWith: {self center + (0.2@0.2)}.
radiusItem _ parents second.
clone _ DrGCircleRadiusItem newWith: {pointA . radiusItem}.
^ {pointA . clone}! !
!DrGCircleRadiusItem methodsFor: 'updating'!
moveParent: aPoint
| thePoint |
(parents
noneSatisfy: [:item | item isValueItem or: [item isSegmentItem]])
ifTrue: [^ super moveParent: aPoint].
"we just want to move the center point, not the radius value"
thePoint _ parents first.
thePoint moveEvent: aPoint.
^ true! !
!DrGCircleRadiusItem methodsFor: 'updating'!
update
self doParentsExist
ifTrue: [center _ parents first point.
radius _ parents second valueItem abs].! !
!DrGCircleRadiusItem methodsFor: 'xml writing'!
nodeType
^ #radius! !
!DrGCircleSegmentItem methodsFor: 'computing'!
clone
|pointA clone segmentItem |
pointA _ DrGPointFreeItem newWith: {self center + (0.2@0.2)}.
segmentItem _ parents second.
clone _ DrGCircleSegmentItem newWith: {pointA . segmentItem}.
^ {pointA . clone}! !
!DrGCircleSegmentItem methodsFor: 'xml writing'!
nodeType
^ #segment! !
!DrGCircleSegmentItem methodsFor: 'updating'!
update
self doParentsExist
ifTrue: [center _ parents first point.
radius _ parents second direction r]! !
!DrGCircleReflexionItem methodsFor: 'xml writing'!
nodeType
^#Reflexion! !
!DrGCircleReflexionItem methodsFor: 'updating'!
moveParent: aPoint
^false! !
!DrGCircleReflexionItem methodsFor: 'updating'!
update
self doParentsExist ifTrue:
[self radius: parents first radius.
self center: (parents first center
reflexionBy: parents second origin
direction: parents second direction)].
! !
!DrGCircleRotationItem methodsFor: 'updating'!
moveParent: aPoint
^false! !
!DrGCircleRotationItem methodsFor: 'updating'!
update
self doParentsExist ifTrue:
[radius _ parents first radius.
center _ parents first center
rotateBy: parents third valueItem negated
about: parents second point].
! !
!DrGCircleRotationItem methodsFor: 'xml writing'!
nodeType
^#Rotation! !
!DrGCircleSymmetryItem methodsFor: 'xml writing'!
nodeType
^#Symmetry! !
!DrGCircleSymmetryItem methodsFor: 'updating'!
moveParent: aPoint
^false! !
!DrGCircleSymmetryItem methodsFor: 'updating'!
update
self doParentsExist ifTrue:
[self radius: parents first radius.
self center: (2 * parents second point) - parents first center].
! !
!DrGCircleTranslationItem methodsFor: 'xml writing'!
nodeType
^#Translation! !
!DrGCircleTranslationItem methodsFor: 'updating'!
moveParent: aPoint
^false! !
!DrGCircleTranslationItem methodsFor: 'updating'!
update
self doParentsExist ifTrue:
[self center: parents first center + parents second direction.
self radius: parents first radius].
! !
!DrGCompositeItem methodsFor: 'private'!
adaptiveDescriptiveName
^ 'This composite object %1' translated! !
!DrGCompositeItem methodsFor: 'comparing'!
= aMathItem
^ aMathItem
ifNil: [false]
ifNotNil: [self className = aMathItem className
and: [self subItems = aMathItem subItems]]! !
!DrGCompositeItem methodsFor: 'comparing'!
hash
^ self subItems hash bitXor: self className hash! !
!DrGCompositeItem methodsFor: 'accessing'!
subItems
^subItems ! !
!DrGCompositeItem methodsFor: 'accessing'!
subItems: theSubItems
subItems _ theSubItems ! !
!DrGCompositeItem methodsFor: 'updating'!
move: aPoint
subItems do: [:item|
(item class ~= DrGPointFreeItem
and: [item class ~= DrGPointOncurveItem])
ifTrue:
[item moveEvent: aPoint]].! !
!DrGCompositeItem methodsFor: 'updating'!
moveParent: aPoint
^false! !
!DrGCompositeItem methodsFor: 'as yet unclassified' stamp: 'hlsf 5/4/2020 18:24:59'!
isCompositeItem
^true! !
!DrGCompositeItem methodsFor: 'as yet unclassified' stamp: 'hlsf 5/4/2020 18:25:15'!
isGeometricItem
"if all subitem are geometric item, considere ourself as a geometric item"
subItems do: [:aMathItem |
(aMathItem isGeometricItem)
ifFalse: [^false]].
^true! !
!DrGCompositeItem class methodsFor: 'as yet unclassified'!
newWith: theSubItems
^self new
subItems: theSubItems! !
!DrGDirectionItem methodsFor: 'printing'!
printOn: aStream
self printCoordinates: origin on: aStream.
aStream nextPutAll: '->'.
self printCoordinates: vector on: aStream
! !
!DrGDirectionItem methodsFor: 'updating'!
homothetyUpdate
|center|
self doParentsExist ifTrue:
[center _ parents second point.
origin _ center +
(parents third valueItem * (parents first origin - center)).
vector _ parents first direction * parents third valueItem].! !
!DrGDirectionItem methodsFor: 'updating'!
reflexionUpdate
self doParentsExist ifTrue:
[self origin: (parents first origin
reflexionBy: parents second origin
direction: parents second direction).
self direction: (parents first direction
vectorReflexionBy: parents second direction)].! !
!DrGDirectionItem methodsFor: 'updating'!
rotationUpdate
self doParentsExist ifTrue:
[origin _ parents first origin
rotateBy: parents third valueItem negated
about: parents second point.
vector _ parents first direction
rotateVector: parents third valueItem].! !
!DrGDirectionItem methodsFor: 'updating'!
symmetryUpdate
self doParentsExist ifTrue:
[self origin: (2 * parents second point) - parents first origin.
self direction: parents first direction negated].! !
!DrGDirectionItem methodsFor: 'updating'!
translationUpdate
self doParentsExist ifTrue:
[self origin: parents first origin + parents second direction.
self direction: parents first direction].! !
!DrGDirectionItem methodsFor: 'updating'!
update
self doParentsExist ifTrue:
["default behavior for segment, line and ray defined by 2 points"
self origin: (parents at: 1) point.
self direction: (parents at: 2) point - (self origin).
self direction =( 0@0) ifTrue: [exist _ false]].! !
!DrGDirectionItem methodsFor: 'testing'!
isCloneable
^ true! !
!DrGDirectionItem methodsFor: 'testing'!
isCollinearWith: aDirection
^ (vector crossProduct: aDirection direction)
closeTo: 0! !
!DrGDirectionItem methodsFor: 'accessing'!
basicType
^#direction! !
!DrGDirectionItem methodsFor: 'accessing'!
direction
^vector ! !
!DrGDirectionItem methodsFor: 'accessing'!
direction: aDirection
vector _ aDirection ! !
!DrGDirectionItem methodsFor: 'accessing'!
normal
^ vector normal! !
!DrGDirectionItem methodsFor: 'accessing'!
origin
^origin ! !
!DrGDirectionItem methodsFor: 'accessing'!
origin: anOrigin
origin _ anOrigin ! !
!DrGDirectionItem methodsFor: 'computing' stamp: 'hlsf 3/23/2023 20:57:58'!
intersectionWithDirection: aDirectionItem
| det c1 c2 direction |
direction := aDirectionItem direction.
det := vector crossProduct: direction.
(det closeTo: 0) ifTrue: [^ nil].
c1 := origin crossProduct: vector.
c2 := aDirectionItem origin crossProduct: direction.
^ ((c2 * vector x - (c1 * direction x) ) / det) @ ((vector y * c2 - (direction y * c1)) / det)! !
!DrGDirectionItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:28:11'!
isCurveItem
^ true! !
!DrGDirectionItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:26:35'!
isDirectionItem
^ true! !
!DrGDirectionItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:26:18'!
isGeometricItem
^ true! !
!DrGDirectionItem class methodsFor: 'constants'!
inv2Pi
^Inv2Pi! !
!DrGDirectionItem class methodsFor: 'constants'!
invPi
^InvPi! !
!DrGDirectionItem class methodsFor: 'class initialization'!
initialize
InvPi _ 0.31830988618379067154.
Inv2Pi _ 0.636619772367581.! !
!DrGLineItem methodsFor: 'printing'!
printOn: aStream
self printType: DrGLineBuilder title on: aStream.! !
!DrGLineItem methodsFor: 'computing'!
abscissaOf: aPoint
| v |
[ v _ vector normalized ] on: ZeroDivide do: [ v _ 0 @ 0 ].
^(aPoint - origin dotProduct: v) arcTan
* DrGDirectionItem invPi + 0.5! !
!DrGLineItem methodsFor: 'computing'!
clone
|pointA pointB clone|
pointA _ DrGPointFreeItem newWith: {self origin + (0.2@0.2)}.
pointB _ DrGPointFreeItem newWith: {self origin + self direction + (0.2@0.2)}.
clone _ DrGLine2ptsItem newWith: {pointA . pointB}.
^ {pointA . pointB . clone}! !
!DrGLineItem methodsFor: 'computing'!
closestPointTo: aPoint
|unitVector|
[ unitVector _ vector normalized ] on: ZeroDivide do: [ unitVector _ 0 @ 0 ].
^origin + (((aPoint - origin) dotProduct: unitVector) * unitVector)! !
!DrGLineItem methodsFor: 'computing'!
contains: aPoint
^ (vector crossProduct: (aPoint - origin)) closeTo: 0! !
!DrGLineItem methodsFor: 'computing'!
intersectionWith: aCurveItem flag: aFlag
aCurveItem isLineItem
ifTrue: [^ self intersectionWithDirection: aCurveItem].
(aCurveItem isSegmentItem
or: [aCurveItem isRayItem
or: [aCurveItem isCircleItem
or: [aCurveItem isArcItem]]])
ifTrue: [^ aCurveItem intersectionWith: self flag: aFlag].! !
!DrGLineItem methodsFor: 'computing'!
pointAt: anAbscissa
|point abscissa v |
"In the interval [-0.5 ; 0.5]"
abscissa _ anAbscissa - 0.5.
(abscissa = 0.5 or: [abscissa = -0.5])
ifTrue:
[point _ abscissa * vector.
point x > 0
ifTrue: [point _ Float infinity @ point y]
ifFalse: [point _ 0 - Float infinity @ point y].
point y > 0
ifTrue: [point _ point x @ Float infinity]
ifFalse: [point _ point x @ (0 - Float infinity)]]
ifFalse:
[abscissa _ abscissa * Float pi.
[ v _ vector normalized ] on: ZeroDivide do: [ v _ 0 @ 0 ].
point _ origin + (abscissa tan * v)].
^point! !
!DrGLineItem methodsFor: 'accessing'!
basicType
^#line! !
!DrGLineItem methodsFor: 'accessing' stamp: 'hlsf 4/12/2021 22:27:45'!
morphClass
^ DrGLineMorph! !
!DrGLineItem methodsFor: 'private'!
adaptiveDescriptiveName
^ 'This line %1' translated! !
!DrGLineItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:26:55'!
isLineItem
^ true! !
!DrGAngleBisector3ptsItem methodsFor: 'xml writing'!
nodeType
^#'angleBisector3pts'! !
!DrGAngleBisector3ptsItem methodsFor: 'comparing'!
parentsEqual: aMathItem
^ parents = aMathItem parents
or: [parents reverse = aMathItem parents]! !
!DrGAngleBisector3ptsItem methodsFor: 'updating'!
update
self doParentsExist ifTrue: [
| v1 v2 |
self origin: parents second point.
((parents first point = origin) or: [parents third point = origin]) ifTrue: [^ exist _ false].
[ v1 _ (parents first point - origin) normalized ] on: ZeroDivide do: [ v1 _ 0 @ 0 ].
[ v2 _ (parents third point - origin) normalized ] on: ZeroDivide do: [ v2 _ 0 @ 0 ].
self direction: v1 + v2.
self direction = (0@0) ifTrue: [exist _ false]]! !
!DrGAngleBisector3ptsItem methodsFor: 'private'!
adaptiveDescriptiveName
^ 'This angle bisector %1' translated! !
!DrGLine2ptsItem methodsFor: 'xml writing'!
nodeType
^#'2pts'! !
!DrGLineAngleBisectorItem methodsFor: 'private'!
adaptiveDescriptiveName
^ 'This angle bisector %1' translated! !
!DrGLineAngleBisectorItem methodsFor: 'updating'!
update
self doParentsExist ifTrue: [
| angle v1 v2 |
angle _ parents first.
self origin: angle summit point.
[ v1 _ (angle side1 point - origin) normalized ] on: ZeroDivide do: [ v1 _ 0 @ 0 ].
[ v2 _ (angle side2 point - origin) normalized ] on: ZeroDivide do: [ v2 _ 0 @ 0 ].
self direction: v1+ v2.
self direction = (0@0) ifTrue: [exist _ false]]! !
!DrGLineAngleBisectorItem methodsFor: 'xml writing'!
nodeType
^ #angleBisector! !
!DrGLineHomothetyItem methodsFor: 'updating'!
moveParent: aPoint
^false! !
!DrGLineHomothetyItem methodsFor: 'updating'!
update
self homothetyUpdate ! !
!DrGLineHomothetyItem methodsFor: 'xml writing'!
nodeType
^#Scale! !
!DrGLineParallelItem methodsFor: 'xml writing'!
nodeType
^#parallel! !
!DrGLineParallelItem methodsFor: 'updating'!
move: aPoint
parents size = 1 ifTrue: [origin _ origin + aPoint].
! !
!DrGLineParallelItem methodsFor: 'updating'!
moveParent: aPoint
"Only move the origin parent if it is a PointItem instance"
parents isEmptyOrNil ifFalse: [parents second moveEvent: aPoint].
^true! !
!DrGLineParallelItem methodsFor: 'updating'!
update
self doParentsExist ifTrue:
[self direction: (parents at: 1) direction.
parents size = 2 ifTrue: [self origin: (parents at: 2) point]].
! !
!DrGLineParallelItem methodsFor: 'private'!
adaptiveDescriptiveName
^ 'This parallel line %1' translated! !
!DrGLinePerpendicularItem methodsFor: 'updating'!
update
self doParentsExist ifTrue:
[self direction: (parents at: 1) normal.
parents size = 2 ifTrue: [self origin: (parents at: 2) point]].
! !
!DrGLinePerpendicularItem methodsFor: 'xml writing'!
nodeType
^#perpendicular! !
!DrGLinePerpendicularItem methodsFor: 'private'!
adaptiveDescriptiveName
^ 'This perpendicular line %1' translated! !
!DrGLineReflexionItem methodsFor: 'updating'!
moveParent: aPoint
^false! !
!DrGLineReflexionItem methodsFor: 'updating'!
update
self reflexionUpdate! !
!DrGLineReflexionItem methodsFor: 'xml writing'!
nodeType
^#Reflexion! !
!DrGLineRotationItem methodsFor: 'updating'!
moveParent: aPoint
^false! !
!DrGLineRotationItem methodsFor: 'updating'!
update
self rotationUpdate ! !
!DrGLineRotationItem methodsFor: 'xml writing'!
nodeType
^#Rotation! !
!DrGLineSymmetryItem methodsFor: 'xml writing'!
nodeType
^#Symmetry! !
!DrGLineSymmetryItem methodsFor: 'updating'!
moveParent: aPoint
^false! !
!DrGLineSymmetryItem methodsFor: 'updating'!
update
self symmetryUpdate ! !
!DrGLineTranslationItem methodsFor: 'xml writing'!
nodeType
^#Translation! !
!DrGLineTranslationItem methodsFor: 'updating'!
moveParent: aPoint
^false! !
!DrGLineTranslationItem methodsFor: 'updating'!
update
self translationUpdate! !
!DrGPerpendicularBisectorItem methodsFor: 'comparing'!
= aMathItem
^ aMathItem isMathItem
ifFalse: [false]
ifTrue: [super = aMathItem or: [ self equalOtherNodeType: aMathItem ]]! !
!DrGPerpendicularBisectorItem methodsFor: 'comparing'!
equalOtherNodeType: aMathItem
^ aMathItem
ifNil: [false]
ifNotNil: [self basicType = aMathItem basicType
and: [aMathItem nodeType = #'perpendicularBisector2pts'
and: [(parents first extremity1 = aMathItem parents first point
and: [parents first extremity2 = aMathItem parents second point])
or: [parents first extremity1 = aMathItem parents second point
and: [parents first extremity2 = aMathItem parents first point]]]]]! !
!DrGPerpendicularBisectorItem methodsFor: 'updating'!
update
self doParentsExist ifTrue: [ |segment |
segment _ parents first.
self direction: segment normal.
self origin: segment middle]! !
!DrGPerpendicularBisectorItem methodsFor: 'xml writing'!
nodeType
^ #perpendicularBisector! !
!DrGPerpendicularBisectorItem methodsFor: 'private'!
adaptiveDescriptiveName
^ 'This perpendicular bisector %1' translated! !
!DrGLinePerpendicularBisector2ptsItem methodsFor: 'comparing'!
equalOtherNodeType: aMathItem
^ aMathItem
ifNil: [false]
ifNotNil: [self basicType = aMathItem basicType
and: [aMathItem nodeType = #perpendicularBisectorSegment
and: [(aMathItem parents first extremity1 = parents first point
and: [aMathItem parents first extremity2 = parents second point])
or: [aMathItem parents first extremity1 = parents second point
and: [aMathItem parents first extremity2 = parents first point]]]]]! !
!DrGLinePerpendicularBisector2ptsItem methodsFor: 'comparing'!
parentsEqual: aMathItem
" ^ self parents asSet = aMathItem parents asSet"
((parents first = aMathItem parents first) and: [parents second = aMathItem parents second])
ifTrue: [^true].
((parents first = aMathItem parents second) and: [parents second = aMathItem parents first])
ifTrue: [^true].
^ false
! !
!DrGLinePerpendicularBisector2ptsItem methodsFor: 'private'!
adaptiveDescriptiveName
^ 'This perpendicular bisector %1' translated! !
!DrGLinePerpendicularBisector2ptsItem methodsFor: 'updating' stamp: 'hlsf 2/22/2023 12:17:31'!
update
self doParentsExist ifTrue: [
(parents first point = parents second point)
ifFalse: [
self direction: (parents first point - parents second point) normal.
self origin: parents first point + parents second point / 2]
ifTrue: [exist _ false]
]! !
!DrGLinePerpendicularBisector2ptsItem methodsFor: 'xml writing'!
nodeType
^#'perpendicularBisector2pts'! !
!DrGRayItem methodsFor: 'printing'!
printOn: aStream
self printType: DrGRayBuilder title on: aStream.
self printCoordinates: origin on: aStream! !
!DrGRayItem methodsFor: 'private'!
adaptiveDescriptiveName
^ 'This half-line %1' translated! !
!DrGRayItem methodsFor: 'testing'!
contains: aPoint
^ ((vector crossProduct: (aPoint - origin)) closeTo: 0)
and: [((aPoint - origin) dotProduct: vector) >= 0]! !
!DrGRayItem methodsFor: 'accessing'!
basicType
^#ray! !
!DrGRayItem methodsFor: 'accessing' stamp: 'hlsf 4/12/2021 22:27:45'!
morphClass
^DrGRayMorph! !
!DrGRayItem methodsFor: 'computing'!
abscissaOf: aPoint
| v |
[ v _ vector normalized ] on: ZeroDivide do: [ v _ 0 @ 0 ].
^(aPoint - origin dotProduct: v) arcTan
* DrGDirectionItem inv2Pi! !
!DrGRayItem methodsFor: 'computing'!
clone
|pointA pointB clone|
pointA _ DrGPointFreeItem newWith: {self origin + (0.2@0.2)}.
pointB _ DrGPointFreeItem newWith: {self origin + self direction + (0.2@0.2)}.
clone _ DrGRay2ptsItem newWith: {pointA . pointB}.
^ {pointA . pointB . clone}! !
!DrGRayItem methodsFor: 'computing'!
closestPointTo: aPoint
|unitVector abscissa|
[ unitVector _ vector normalized ] on: ZeroDivide do: [ unitVector _ 0 @ 0 ].
abscissa _ aPoint - origin dotProduct: unitVector.
abscissa < 0 ifTrue: [abscissa _ 0].
^origin + (abscissa * unitVector)! !
!DrGRayItem methodsFor: 'computing'!
intersectionWith: aCurveItem flag: aFlag
|aPoint|
aCurveItem isLineItem
ifTrue:
[aPoint _ self intersectionWithDirection: aCurveItem.
(self contains: aPoint)
ifTrue: [^aPoint]
ifFalse: [^nil]].
(aCurveItem isSegmentItem or: [aCurveItem isRayItem])
ifTrue:
[aPoint _ self intersectionWithDirection: aCurveItem.
((self contains: aPoint) and: [aCurveItem contains: aPoint])
ifTrue: [^aPoint]
ifFalse: [^nil]].
(aCurveItem isCircleItem
or: [aCurveItem isArcItem])
ifTrue:
[^aCurveItem intersectionWith: self flag: aFlag].! !
!DrGRayItem methodsFor: 'computing'!
pointAt: anAbscissa
|point|
anAbscissa = 1
ifTrue:
[|infX infY|
point _ vector.
point x > 0
ifTrue: [infX _ Float infinity]
ifFalse: [infX _ 0 - Float infinity].
point y > 0
ifTrue: [infY _ Float infinity]
ifFalse: [infY _ 0 - Float infinity].
point _ infX@infY]
ifFalse:
[anAbscissa = 0
ifTrue: [point _ origin]
ifFalse:
[| v |
[ v _ vector normalized ] on: ZeroDivide do: [ v _ 0 @ 0 ].
point _ origin + ((anAbscissa * Float halfPi) tan * v)]].
^point
! !
!DrGRayItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:28:33'!
isRayItem
^ true! !
!DrGRay2ptsItem methodsFor: 'xml writing'!
nodeType
^#'2pts'! !
!DrGRayHomothetyItem methodsFor: 'updating'!
moveParent: aPoint
^false! !
!DrGRayHomothetyItem methodsFor: 'updating'!
update
self homothetyUpdate! !
!DrGRayHomothetyItem methodsFor: 'xml writing'!
nodeType
^#Scale! !
!DrGRayReflexionItem methodsFor: 'xml writing'!
nodeType
^#Reflexion! !
!DrGRayReflexionItem methodsFor: 'updating'!
moveParent: aPoint
^false! !
!DrGRayReflexionItem methodsFor: 'updating'!
update
self reflexionUpdate ! !
!DrGRayRotationItem methodsFor: 'updating'!
moveParent: aPoint
^false! !
!DrGRayRotationItem methodsFor: 'updating'!
update
self rotationUpdate ! !
!DrGRayRotationItem methodsFor: 'xml writing'!
nodeType
^#Rotation! !
!DrGRaySymmetryItem methodsFor: 'updating'!
moveParent: aPoint
^false! !
!DrGRaySymmetryItem methodsFor: 'updating'!
update
self symmetryUpdate ! !
!DrGRaySymmetryItem methodsFor: 'xml writing'!
nodeType
^#Symmetry! !
!DrGRayTranslationItem methodsFor: 'updating'!
moveParent: aPoint
^false! !
!DrGRayTranslationItem methodsFor: 'updating'!
update
self translationUpdate ! !
!DrGRayTranslationItem methodsFor: 'xml writing'!
nodeType
^#Translation! !
!DrGSegmentItem methodsFor: 'printing'!
printOn: aStream
self printType: DrGSegmentBuilder title on: aStream.
aStream nextPut: Character space.
self printDecimal: self length on: aStream.! !
!DrGSegmentItem methodsFor: 'testing'!
contains: aPoint
|anAbscissa|
^ ((vector crossProduct: (aPoint - origin)) closeTo: 0)
and: [(anAbscissa _ self abscissaOf: aPoint) >= 0
and: [anAbscissa <= 1]]! !
!DrGSegmentItem methodsFor: 'accessing'!
basicType
^#segment! !
!DrGSegmentItem methodsFor: 'accessing'!
extremity1
^ origin ! !
!DrGSegmentItem methodsFor: 'accessing'!
extremity2
^ self pointAt: 1! !
!DrGSegmentItem methodsFor: 'accessing'!
length
^ self direction r! !
!DrGSegmentItem methodsFor: 'accessing'!
middle
^ self extremity1 + self extremity2 / 2! !
!DrGSegmentItem methodsFor: 'accessing' stamp: 'hlsf 4/12/2021 22:27:45'!
morphClass
^DrGSegmentMorph! !
!DrGSegmentItem methodsFor: 'computing'!
abscissaOf: aPoint
^((aPoint - origin) dotProduct: vector) / (vector dotProduct: vector)! !
!DrGSegmentItem methodsFor: 'computing'!
clone
|pointA pointB clone|
pointA _ DrGPointFreeItem newWith: {self extremity1 + (0.2@0.2)}.
pointB _ DrGPointFreeItem newWith: {self extremity2 + (0.2@0.2)}.
clone _ DrGSegment2ptsItem newWith: {pointA . pointB}.
^ {pointA . pointB . clone}! !
!DrGSegmentItem methodsFor: 'computing' stamp: 'hlsf 6/20/2021 11:05:29'!
closestPointTo: aPoint
|abscissa squareNorm|
abscissa _ (aPoint - origin) dotProduct: vector.
squareNorm _ vector dotProduct: vector.
abscissa _ abscissa min: squareNorm max: 0.
^ [origin + (abscissa * vector / squareNorm asFloat)] on: ZeroDivide do: [origin]! !
!DrGSegmentItem methodsFor: 'computing'!
intersectionWith: aCurveItem flag: aFlag
|aPoint|
aCurveItem isLineItem
ifTrue:
[aPoint _ self intersectionWithDirection: aCurveItem.
aPoint ifNil: [^nil].
(self contains: aPoint)
ifTrue: [^aPoint]
ifFalse: [^nil]].
aCurveItem isSegmentItem
ifTrue:
[aPoint _ self intersectionWithDirection: aCurveItem.
aPoint ifNil: [^nil].
((self contains: aPoint) and: [aCurveItem contains: aPoint])
ifTrue: [^aPoint]
ifFalse: [^nil]].
(aCurveItem isRayItem
or: [aCurveItem isCircleItem
or: [aCurveItem isArcItem]])
ifTrue:
[^aCurveItem intersectionWith: self flag: aFlag].
! !
!DrGSegmentItem methodsFor: 'computing'!
pointAt: anAbscissa
^ origin + (anAbscissa * vector)! !
!DrGSegmentItem methodsFor: 'private'!
adaptiveDescriptiveName
^ 'This segment %1' translated! !
!DrGSegmentItem methodsFor: 'as yet unclassified' stamp: 'hlsf 5/4/2020 18:28:46'!
isSegmentItem
^ true! !
!DrGSegment2ptsItem methodsFor: 'comparing'!
parentsEqual: aMathItem
((parents first = aMathItem parents first) and: [parents second = aMathItem parents second])
ifTrue: [^true].
((parents first = aMathItem parents second) and: [parents second = aMathItem parents first])
ifTrue: [^true].
^ false
! !
!DrGSegment2ptsItem methodsFor: 'comparing'!
rehash
^ hash _ ((parents sorted: [:ptA :ptB | ptA point <= ptB point]) hash bitXor: self nodeType hash) bitXor: self basicType hash! !
!DrGSegment2ptsItem methodsFor: 'xml writing'!
nodeType
^#'2pts'! !
!DrGSegmentHomothetyItem methodsFor: 'updating'!
moveParent: aPoint
^false! !
!DrGSegmentHomothetyItem methodsFor: 'updating'!
update
self homothetyUpdate ! !
!DrGSegmentHomothetyItem methodsFor: 'xml writing'!
nodeType
^#Scale! !
!DrGSegmentReflexionItem methodsFor: 'xml writing'!
nodeType
^#Reflexion! !
!DrGSegmentReflexionItem methodsFor: 'updating'!
moveParent: aPoint
^false! !
!DrGSegmentReflexionItem methodsFor: 'updating'!
update
self reflexionUpdate ! !
!DrGSegmentRotationItem methodsFor: 'xml writing'!
nodeType
^#Rotation! !
!DrGSegmentRotationItem methodsFor: 'updating'!
moveParent: aPoint
^false! !
!DrGSegmentRotationItem methodsFor: 'updating'!
update
self rotationUpdate ! !
!DrGSegmentSymmetryItem methodsFor: 'updating'!
moveParent: aPoint
^false! !
!DrGSegmentSymmetryItem methodsFor: 'updating'!
update
self symmetryUpdate ! !
!DrGSegmentSymmetryItem methodsFor: 'xml writing'!
nodeType
^#Symmetry! !
!DrGSegmentTranslationItem methodsFor: 'xml writing'!
nodeType
^#Translation! !
!DrGSegmentTranslationItem methodsFor: 'updating'!
moveParent: aPoint
^false! !
!DrGSegmentTranslationItem methodsFor: 'updating'!
update
self translationUpdate ! !
!DrGVectorItem methodsFor: 'printing'!
printOn: aStream
self printType: DrGVectorBuilder title on: aStream.
self printCoordinates: vector on: aStream ! !
!DrGVectorItem methodsFor: 'xml writing'!
writeAsXmlTo: aNode
|node|
node _ super writeAsXmlTo: aNode.
node attributeAt: #origin put: origin asString.
^ node! !
!DrGVectorItem methodsFor: 'private'!
adaptiveDescriptiveName
^ 'This vector %1' translated! !
!DrGVectorItem methodsFor: 'computing'!
clone
|pointA pointB clone|
pointA _ DrGPointFreeItem newWith: {self origin + (0.2@0.2)}.
pointB _ DrGPointFreeItem newWith: {self origin + self direction + (0.2@0.2)}.
clone _ DrGVector2ptsItem newWith: {pointA . pointB}.
^ {pointA . pointB . clone}! !
!DrGVectorItem methodsFor: 'accessing'!
basicType
^#vector! !
!DrGVectorItem methodsFor: 'accessing' stamp: 'hlsf 4/12/2021 22:27:45'!
morphClass
^ DrGVectorMorph! !
!DrGVectorItem methodsFor: 'updating'!
move: aPoint
origin _ origin + aPoint.
! !
!DrGVectorItem methodsFor: 'updating'!
moveParent: aPoint
"We don't want to move the parents, as the whole vector representation can be move all arround"
^false! !
!DrGVectorItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:29:50'!
isCurveItem
^ false! !
!DrGVectorItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:29:58'!
isSegmentItem
^ false! !
!DrGVectorItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:30:07'!
isVectorItem
^ true! !
!DrGVector2ptsItem methodsFor: 'updating'!
update
self doParentsExist ifTrue:
[self direction: (parents at: 2) point - (parents at: 1) point].
! !
!DrGVector2ptsItem methodsFor: 'xml writing'!
nodeType
^#'2pts'! !
!DrGVector2ptsItem methodsFor: 'initialize-release'!
initialize: theParents
super initialize: theParents.
self origin: (theParents first point).! !
!DrGVectorHomothetyItem methodsFor: 'initialize-release'!
initialize: theParents
super initialize: theParents.
self origin: parents second point.! !
!DrGVectorHomothetyItem methodsFor: 'updating'!
moveParent: aPoint
^false! !
!DrGVectorHomothetyItem methodsFor: 'updating'!
update
self doParentsExist ifTrue:
[vector _ parents first direction * parents third valueItem].! !
!DrGVectorHomothetyItem methodsFor: 'xml writing'!
nodeType
^#Scale! !
!DrGVectorReflexionItem methodsFor: 'xml writing'!
nodeType
^#Reflexion! !
!DrGVectorReflexionItem methodsFor: 'updating'!
moveParent: aPoint
^false! !
!DrGVectorReflexionItem methodsFor: 'updating'!
update
self doParentsExist ifTrue:
[self direction: (parents first direction
vectorReflexionBy: parents second direction)].
! !
!DrGVectorReflexionItem methodsFor: 'initialize-release'!
initialize: theParents
super initialize: theParents.
self origin: parents first origin.! !
!DrGVectorRotationItem methodsFor: 'updating'!
moveParent: aPoint
^false! !
!DrGVectorRotationItem methodsFor: 'updating'!
update
self doParentsExist ifTrue:
[vector _ parents first direction
rotateVector: parents third valueItem].
! !
!DrGVectorRotationItem methodsFor: 'initialize-release'!
initialize: theParents
super initialize: theParents.
self origin: parents first origin.! !
!DrGVectorRotationItem methodsFor: 'xml writing'!
nodeType
^#Rotation! !
!DrGVectorSymmetryItem methodsFor: 'initialize-release'!
initialize: theParents
super initialize: theParents.
self origin: (parents first origin)! !
!DrGVectorSymmetryItem methodsFor: 'xml writing'!
nodeType
^#Symmetry! !
!DrGVectorSymmetryItem methodsFor: 'updating'!
moveParent: aPoint
^false! !
!DrGVectorSymmetryItem methodsFor: 'updating'!
update
self doParentsExist ifTrue:
[self direction: parents first direction negated].
! !
!DrGLocus2ptsItem methodsFor: 'printing'!
printOn: aStream
self printType: DrGLocusBuilder title on: aStream! !
!DrGLocus2ptsItem methodsFor: 'xml writing'!
nodeType
^#'2pts'! !
!DrGLocus2ptsItem methodsFor: 'private'!
adaptiveDescriptiveName
^ 'This locus %1' translated! !
!DrGLocus2ptsItem methodsFor: 'private'!
squareNorm: aPoint
^ aPoint x * aPoint x + (aPoint y * aPoint y)! !
!DrGLocus2ptsItem methodsFor: 'updating' stamp: 'hlsf 6/13/2021 11:30:46'!
update
"Special: update does not occure there but in the view.
Indeed, a Locus is sampled from its view, because it depends on the visible portion of the drawable"! !
!DrGLocus2ptsItem methodsFor: 'accessing' stamp: 'hlsf 6/13/2021 11:26:20'!
abscissaOf: aPoint
| i distance |
distance _ self squareNorm: aPoint - (p at: 1).
i _ 1.
2 to: samplesQty do: [:n |
(self squareNorm: (p at: n) - aPoint) < distance ifTrue:
[distance _ self squareNorm: aPoint - (p at: n).
i _ n]].
^ (i / samplesQty) asFloat! !
!DrGLocus2ptsItem methodsFor: 'accessing'!
basicType
^ #locus! !
!DrGLocus2ptsItem methodsFor: 'accessing' stamp: 'hlsf 6/13/2021 11:26:20'!
closestPointTo: aPoint
| distance d m |
m _ p at: 1.
distance _ self squareNorm: aPoint - m.
2 to: samplesQty do: [:n |
d _ self squareNorm: (p at: n) - aPoint.
d < distance ifTrue:
[m _ p at: n.
distance _ d]].
^ m! !
!DrGLocus2ptsItem methodsFor: 'accessing'!
constrainedPoint
^ parents second! !
!DrGLocus2ptsItem methodsFor: 'accessing'!
freePoint
^ parents first! !
!DrGLocus2ptsItem methodsFor: 'accessing' stamp: 'hlsf 4/12/2021 22:27:45'!
morphClass
^ DrGLocusMorph! !
!DrGLocus2ptsItem methodsFor: 'accessing' stamp: 'hlsf 6/13/2021 11:26:20'!
pointAt: anAbscissa
| m |
samplesQty ifNil: [^0@0].
m _ (anAbscissa * samplesQty) rounded.
m = 0 ifTrue: [m _ 1].
^ p at: m! !
!DrGLocus2ptsItem methodsFor: 'accessing'!
points
^ p! !
!DrGLocus2ptsItem methodsFor: 'accessing'!
points: aCollection
p _ aCollection! !
!DrGLocus2ptsItem methodsFor: 'accessing' stamp: 'hlsf 6/13/2021 11:26:20'!
samplesQty
^ samplesQty! !
!DrGLocus2ptsItem methodsFor: 'accessing' stamp: 'hlsf 6/13/2021 11:26:20'!
samplesQty: aNumber
samplesQty _ aNumber! !
!DrGLocus2ptsItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:30:31'!
isCurveItem
^ true! !
!DrGLocus2ptsItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:30:26'!
isGeometricItem
^ true! !
!DrGLocus2ptsItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:31:15'!
isIntersectableItem
^ false! !
!DrGLocus2ptsItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:30:36'!
isLocusItem
^ true! !
!DrGLocus2ptsItem methodsFor: 'testing' stamp: 'hlsf 6/13/2021 11:37:34'!
isSampled
^ samplesQty notNil! !
!DrGLocusTranslationItem methodsFor: 'xml writing'!
nodeType
^ #Translation! !
!DrGLocusTranslationItem methodsFor: 'updating' stamp: 'hlsf 6/13/2021 11:32:47'!
update
self doParentsExist ifTrue: [| locusPoints direction|
direction _ parents second direction.
locusPoints _ parents first points.
samplesQty _ parents first samplesQty.
p _ Array new: samplesQty.
1 to: samplesQty do: [:i |
p at: i put: (locusPoints at: i) + direction]]! !
!DrGLocusTranslationItem methodsFor: 'accessing'!
constrainedPoint
self shouldNotImplement ! !
!DrGLocusTranslationItem methodsFor: 'accessing'!
freePoint
self shouldNotImplement ! !
!DrGLocusTranslationItem methodsFor: 'accessing' stamp: 'hlsf 4/12/2021 22:27:45'!
morphClass
^ DrGLocusTransformedMorph! !
!DrGLocusTranslationItem methodsFor: 'accessing'!
points: aCollection
self shouldNotImplement ! !
!DrGLocusTranslationItem methodsFor: 'accessing' stamp: 'hlsf 6/13/2021 11:24:55'!
samplesQty: anInteger
self shouldNotImplement ! !
!DrGLocusTranslationItem methodsFor: 'testing' stamp: 'hlsf 6/13/2021 11:37:15'!
doParentsExist
"As a locus is sampled from its view, we need to check if the sampling occured in the view.
If not we will wait for the next round of view update"
^ exist _ super doParentsExist and: [parents first isSampled]! !
!DrGLocusHomothetyItem methodsFor: 'updating' stamp: 'hlsf 6/13/2021 11:26:20'!
update
self doParentsExist ifTrue: [| locusPoints center factor|
center _ parents second point.
factor _ parents third valueItem.
locusPoints _ parents first points.
samplesQty _ parents first samplesQty.
p _ Array new: samplesQty.
1 to: samplesQty do: [:i |
p at: i put: center + (factor * ((locusPoints at: i) - center))]]! !
!DrGLocusHomothetyItem methodsFor: 'xml writing'!
nodeType
^#Scale! !
!DrGLocusReflexionItem methodsFor: 'updating' stamp: 'hlsf 6/13/2021 11:26:20'!
update
self doParentsExist ifTrue: [| locusPoints axe|
axe _ parents second.
locusPoints _ parents first points.
samplesQty _ parents first samplesQty.
p _ Array new: samplesQty.
1 to: samplesQty do: [:i |
p at: i put: ((locusPoints at: i) reflexionBy: axe origin direction: axe direction)]]! !
!DrGLocusReflexionItem methodsFor: 'xml writing'!
nodeType
^#Reflexion! !
!DrGLocusRotationItem methodsFor: 'updating' stamp: 'hlsf 6/13/2021 11:26:20'!
update
self doParentsExist ifTrue: [| locusPoints center angle|
center _ parents second point.
angle _ parents third valueItem.
locusPoints _ parents first points.
samplesQty _ parents first samplesQty.
p _ Array new: samplesQty.
1 to: samplesQty do: [:i |
p at: i put: ((locusPoints at: i) rotateBy: angle about: center)]]! !
!DrGLocusRotationItem methodsFor: 'xml writing'!
nodeType
^#Rotation! !
!DrGLocusSymmetryItem methodsFor: 'updating' stamp: 'hlsf 6/13/2021 11:26:20'!
update
self doParentsExist ifTrue: [| locusPoints center|
center _ parents second point.
locusPoints _ parents first points.
samplesQty _ parents first samplesQty.
p _ Array new: samplesQty.
1 to: samplesQty do: [:i |
p at: i put: 2 * center - (locusPoints at: i)]]! !
!DrGLocusSymmetryItem methodsFor: 'xml writing'!
nodeType
^#Symmetry! !
!DrGPointItem methodsFor: 'printing'!
printOn: aStream
self printType: DrGFlyPointBuilder title on: aStream.
self printCoordinates: point on: aStream
! !
!DrGPointItem methodsFor: 'private'!
adaptiveDescriptiveName
^ 'This point %1' translated! !
!DrGPointItem methodsFor: 'updating'!
moveAt: aPoint
! !
!DrGPointItem methodsFor: 'updating'!
moveParent: aPoint
^false! !
!DrGPointItem methodsFor: 'testing'!
isPropertyEditable
^ self isFreePointItem ! !
!DrGPointItem methodsFor: 'computing'!
closestPointTo: aPoint
^ self point ! !
!DrGPointItem methodsFor: 'accessing'!
basicType
^#point! !
!DrGPointItem methodsFor: 'accessing' stamp: 'hlsf 4/12/2021 22:27:45'!
morphClass
^DrGPointMorph! !
!DrGPointItem methodsFor: 'accessing'!
point
^point ! !
!DrGPointItem methodsFor: 'accessing'!
point: aPoint
point _ aPoint .! !
!DrGPointItem methodsFor: 'accessing'!
x
^ point x ! !
!DrGPointItem methodsFor: 'accessing'!
y
^ point y! !
!DrGPointItem methodsFor: 'scripting'!
moveTo: aPoint
self moveAt: aPoint.
self update.
self rehash.! !
!DrGPointItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:32:24'!
isGeometricItem
^ true! !
!DrGPointItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:32:29'!
isPointItem
^ true! !
!DrGPointCoordinateItem methodsFor: 'updating' stamp: 'hlsf 8/4/2023 17:22:24'!
editPropertyIn: presenter
| holder |
holder := ValueHolder with: point.
holder action: [:newPoint | presenter domain propertyCommandFor: self with: newPoint].
^ PointEntryPanel open: holder label: 'Edit the coordinates' translated.! !
!DrGPointCoordinateItem methodsFor: 'updating'!
update
self doParentsExist ifTrue:
[self point: parents first valueItem @ parents second valueItem].
! !
!DrGPointCoordinateItem methodsFor: 'xml writing'!
nodeType
^#Coordinate! !
!DrGPointCoordinateItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:33:53'!
isConstrainedPointItem
^ true! !
!DrGPointBlockItem methodsFor: 'updating' stamp: 'hlsf 11/2/2022 23:11:07'!
update
| result |
self doParentsExist ifTrue:
[parents
ifEmpty: [result _ [ pointBlock value ] on: Error do: [exist _ false]]
ifNotEmpty: [
parents size = 1
ifTrue: [result _ [ pointBlock value: parents first ] on: Error do: [exist _ false]]
ifFalse: [result _ [pointBlock value: parents] on: Error do: [exist _ false]]
].
exist ifTrue: [ self point: result ].
]! !
!DrGPointBlockItem methodsFor: 'comparing'!
= aMathItem
^ super = aMathItem and: [ pointBlock = aMathItem pointBlock ]! !
!DrGPointBlockItem methodsFor: 'comparing'!
rehash
^ hash _ super rehash bitXor: pointBlock hash! !
!DrGPointBlockItem methodsFor: 'xml writing'!
nodeType
^#Block! !
!DrGPointBlockItem methodsFor: 'xml writing'!
writeAsXmlTo: aNode
|node|
node _ super writeAsXmlTo: aNode.
node addElement: ((XMLElement named: #code) addContent: (XMLStringNode string: pointBlock asString)).
^node! !
!DrGPointBlockItem methodsFor: 'accessing' stamp: 'hlsf 11/2/2022 23:04:49'!
parents: aCollection
aCollection isEmptyOrNil ifTrue: [
parents _ aCollection.
^ self].
aCollection first isBlock
ifTrue: [
self pointBlock: aCollection first.
parents _ aCollection allButFirst]
ifFalse: [parents _ aCollection].
! !
!DrGPointBlockItem methodsFor: 'accessing'!
pointBlock
^ pointBlock ! !
!DrGPointBlockItem methodsFor: 'accessing'!
pointBlock: aBlock
pointBlock _ aBlock ! !
!DrGPointBlockItem methodsFor: 'testing'!
doParentsExist
^ super doParentsExist and: [pointBlock isNil not]
! !
!DrGPointScriptItem methodsFor: 'updating'!
update
self doParentsExist ifTrue:
[self point: parents first valueItem asPoint].
! !
!DrGPointScriptItem methodsFor: 'xml writing'!
nodeType
^#Script! !
!DrGPointFreeItem methodsFor: 'accessing'!
isLocked
^ locked ifNil: [locked _ false]! !
!DrGPointFreeItem methodsFor: 'accessing'!
locked: aBoolean
locked _ aBoolean ! !
!DrGPointFreeItem methodsFor: 'accessing'!
parents: aCollection
parents _ nil.
! !
!DrGPointFreeItem methodsFor: 'accessing'!
point: aPoint
super point: aPoint.
self rehash ! !
!DrGPointFreeItem methodsFor: 'accessing'!
x: aNumber
self point: aNumber @ self point y
! !
!DrGPointFreeItem methodsFor: 'accessing'!
y: aNumber
self point: self point x @ aNumber
! !
!DrGPointFreeItem methodsFor: 'comparing'!
parentsEqual: aMathItem
^ self point = aMathItem point! !
!DrGPointFreeItem methodsFor: 'comparing'!
rehash
^hash _ super rehash bitXor: point hash! !
!DrGPointFreeItem methodsFor: 'initialize-release'!
initialize: theParents
super initialize: theParents.
self point: theParents first.! !
!DrGPointFreeItem methodsFor: 'xml writing'!
nodeType
^#Free! !
!DrGPointFreeItem methodsFor: 'xml writing'!
writeAsXmlTo: aNode
"It is important to return the node"
| node|
node _ super writeAsXmlTo: aNode.
node addElement: ((XMLElement named: #x) addContent: (XMLStringNode string: point x asString));
addElement: ((XMLElement named: #y) addContent: (XMLStringNode string: point y asString)).
^node! !
!DrGPointFreeItem methodsFor: 'updating' stamp: 'hlsf 8/4/2023 17:22:30'!
editPropertyIn: presenter
| holder |
holder := ValueHolder with: point.
holder action: [:newPoint | presenter domain propertyCommandFor: self with: newPoint].
^ PointEntryPanel open: holder label: 'Edit the coordinates' translated.! !
!DrGPointFreeItem methodsFor: 'updating'!
move: aPoint
self isLocked ifFalse: [
self point: point + aPoint]
! !
!DrGPointFreeItem methodsFor: 'updating'!
moveAt: aPoint
self isLocked ifFalse: [
self point: aPoint]
! !
!DrGPointFreeItem methodsFor: 'updating'!
property
^ self point! !
!DrGPointFreeItem methodsFor: 'updating'!
property: aProperty
self point: aProperty.! !
!DrGPointFreeItem methodsFor: 'testing'!
doParentsExist
^ true! !
!DrGPointFreeItem methodsFor: 'testing'!
isLockable
^ true! !
!DrGPointFreeItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:35:22'!
isFreePointItem
^true! !
!DrGPointFreeItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:35:31'!
isFreePointOnPlaneItem
^true! !
!DrGPointHomothetyItem methodsFor: 'updating'!
update
|center|
self doParentsExist ifTrue:
[center _ parents second point.
point _ center +
(parents third valueItem * (parents first point - center))].! !
!DrGPointHomothetyItem methodsFor: 'xml writing'!
nodeType
^#Scale! !
!DrGPointHomothetyItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:36:57'!
isConstrainedPointItem
^true! !
!DrGPointIntersectionItem methodsFor: 'updating'!
update
|aPoint|
self doParentsExist ifTrue:
[aPoint _ [(parents first intersectionWith: parents second flag: k)] on: Error do: [nil].
aPoint
ifNil: [exist _ false]
ifNotNil:
[exist _ true.
self point: aPoint]].! !
!DrGPointIntersectionItem methodsFor: 'accessing'!
k
^k! !
!DrGPointIntersectionItem methodsFor: 'accessing'!
k: integer
k _ integer.
self update.
self rehash! !
!DrGPointIntersectionItem methodsFor: 'accessing'!
parents: aCollection
"We only need the 1st and 2nd mathItem in the collection.
The 3rd one is a Point instance (position the user clicked) only used at initialization time"
aCollection isEmptyOrNil ifTrue:
[parents _ aCollection.
^self].
parents _ OrderedCollection new
add: aCollection first;
add: aCollection second;
yourself.
! !
!DrGPointIntersectionItem methodsFor: 'xml writing'!
nodeType
^#Intersection! !
!DrGPointIntersectionItem methodsFor: 'xml writing'!
writeAsXmlTo: aNode
| node |
node _ super writeAsXmlTo: aNode.
node
attributeAt: #extra
put: (k = 1
ifTrue: ['1']
ifFalse: ['0']).
^node! !
!DrGPointIntersectionItem methodsFor: 'initialize-release'!
initialize: theParents
"check for the right intersection point when one parent is a circle or an arc"
|pointA pointB clicPoint|
super initialize: theParents.
k _ 0. "0 when only one intersection"
(theParents first isCircleItem
or: [theParents second isCircleItem
or: [theParents first isArcItem
or: [theParents second isArcItem]]])
ifFalse: [^self].
pointA _ [theParents first intersectionWith: theParents second flag: -1] on: Error do: [nil].
pointB _ [theParents first intersectionWith: theParents second flag: 1] on: Error do: [nil].
pointA ifNil: [^ self k: 1].
pointB ifNil: [^ self k: -1].
clicPoint _ theParents third.
(pointA squaredDistanceTo: clicPoint) < (pointB squaredDistanceTo: clicPoint)
ifTrue: [self k: -1]
ifFalse: [self k: 1]! !
!DrGPointIntersectionItem methodsFor: 'comparing'!
= aMathItem
^ super = aMathItem and: [k = aMathItem k]! !
!DrGPointIntersectionItem methodsFor: 'comparing'!
rehash
^hash _ (super rehash bitXor: k ) bitXor: point hash ! !
!DrGPointIntersectionItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:37:52'!
isConstrainedPointItem
^true! !
!DrGPointIntersectionItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:38:59'!
isIntersectionPointItem
^true! !
!DrGPointIntersectionItem class methodsFor: 'as yet unclassified'!
newWith: theParents k: integer
"Instantiate this mathItem with these parents
Parents contains other MathItem instance, sometime it contains other object as Point"
^self new
parents: theParents;
k: integer;
update;
rehash;
yourself! !
!DrGPointMiddle2ptsItem methodsFor: 'xml writing'!
nodeType
^#'Middle_2pts'! !
!DrGPointMiddle2ptsItem methodsFor: 'comparing'!
parentsEqual: aMathItem
((parents first = aMathItem parents first) and: [parents second = aMathItem parents second])
ifTrue: [^true].
((parents first = aMathItem parents second) and: [parents second = aMathItem parents first])
ifTrue: [^true].
^ false
! !
!DrGPointMiddle2ptsItem methodsFor: 'comparing'!
rehash
^ hash _ ((parents sorted: [:ptA :ptB | ptA point <= ptB point]) hash bitXor: self nodeType hash) bitXor: self basicType hash! !
!DrGPointMiddle2ptsItem methodsFor: 'updating' stamp: 'hlsf 5/31/2021 18:45:16'!
update
self doParentsExist ifTrue:
[self point: (parents first point + parents second point) / 2.0].
! !
!DrGPointMiddle2ptsItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:37:58'!
isConstrainedPointItem
^true! !
!DrGPointMiddlesegmentItem methodsFor: 'updating' stamp: 'hlsf 5/31/2021 18:45:25'!
update
self doParentsExist ifTrue:
[self point: (parents first origin + (parents first direction / 2.0))].
! !
!DrGPointMiddlesegmentItem methodsFor: 'xml writing'!
nodeType
^ #'Middle_segment'! !
!DrGPointMiddlesegmentItem methodsFor: 'comparing'!
parentsEqual: aMathItem
^ parents first = aMathItem parents first! !
!DrGPointOncurveItem methodsFor: 'updating' stamp: 'hlsf 8/4/2023 17:22:02'!
editPropertyIn: presenter
| holder |
holder := ValueHolder with: abscissa.
holder action: [:newAbscissa | presenter domain propertyCommandFor: self with: newAbscissa].
^ RangeFloatEntryPanel
open: holder
between: 0 and: 1
label: 'Edit this curvilinear abscissa in [0;1]' translated
! !
!DrGPointOncurveItem methodsFor: 'updating' stamp: 'hlsf 6/20/2021 10:55:09'!
move: aVector
self isLocked ifFalse: [
self point: (parents first closestPointTo: point + aVector).
self abscissa: (parents first abscissaOf: self point)]
! !
!DrGPointOncurveItem methodsFor: 'updating'!
moveAt: aPoint
self isLocked ifFalse: [
self point: (parents first closestPointTo: aPoint).
self abscissa: (parents first abscissaOf: self point)]
! !
!DrGPointOncurveItem methodsFor: 'updating'!
update
self doParentsExist ifTrue:
[self point: (parents first pointAt: abscissa).
(point x isInfinite or: [point y isInfinite ]) ifTrue: [exist _ false]].
! !
!DrGPointOncurveItem methodsFor: 'testing'!
isLockable
^ true! !
!DrGPointOncurveItem methodsFor: 'initialize-release'!
initialize: theParents
super initialize: theParents.
self doParentsExist ifTrue:
[self point: (theParents first closestPointTo: theParents second).
self abscissa: (theParents first abscissaOf: self point)].
self rehash! !
!DrGPointOncurveItem methodsFor: 'accessing'!
abscissa
^abscissa! !
!DrGPointOncurveItem methodsFor: 'accessing'!
abscissa: anAbscissa
abscissa _ anAbscissa.
abscissa > 1 ifTrue: [abscissa _ 1].
abscissa < 0 ifTrue: [abscissa _ 0].
self rehash! !
!DrGPointOncurveItem methodsFor: 'accessing'!
isLocked
^ locked ifNil: [locked _ false]! !
!DrGPointOncurveItem methodsFor: 'accessing'!
locked: aBoolean
locked _ aBoolean ! !
!DrGPointOncurveItem methodsFor: 'accessing'!
parents: aCollection
"We only need the first mathItem in the collection.
The second one is a Point instance (position the user clicked) only used at initialization time"
aCollection isEmptyOrNil ifTrue:
[parents _ aCollection.
^self].
parents _ OrderedCollection new add: aCollection first;yourself.
! !
!DrGPointOncurveItem methodsFor: 'accessing'!
property
^ self abscissa ! !
!DrGPointOncurveItem methodsFor: 'accessing'!
property: aProperty
self setCurveAbscissa: aProperty.! !
!DrGPointOncurveItem methodsFor: 'comparing'!
= aMathItem
^ super = aMathItem
and: [self abscissa = aMathItem abscissa ]! !
!DrGPointOncurveItem methodsFor: 'comparing'!
rehash
^hash _ super rehash bitXor: abscissa hash! !
!DrGPointOncurveItem methodsFor: 'xml writing'!
nodeType
^#'On_curve'! !
!DrGPointOncurveItem methodsFor: 'xml writing'!
writeAsXmlTo: aNode
"It is important to return the node"
| node|
node _ super writeAsXmlTo: aNode.
node addElement: ((XMLElement named: #value) addContent: (XMLStringNode string: abscissa asString)).
^node! !
!DrGPointOncurveItem methodsFor: 'scripting'!
setCurveAbscissa: aFloat
self abscissa: aFloat.
self update! !
!DrGPointOncurveItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:39:32'!
isFreePointItem
^true! !
!DrGPointOncurveItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:40:14'!
isPointItemOnCurve
^true! !
!DrGPointReflexionItem methodsFor: 'xml writing'!
nodeType
^#Reflexion! !
!DrGPointReflexionItem methodsFor: 'updating' stamp: 'hlsf 5/31/2021 18:46:03'!
update
self doParentsExist ifTrue:
[self point: (parents first point
reflexionBy: parents second origin
direction: parents second direction)].
! !
!DrGPointReflexionItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:38:08'!
isConstrainedPointItem
^true! !
!DrGPointRotationItem methodsFor: 'updating' stamp: 'hlsf 5/31/2021 18:46:18'!
update
self doParentsExist ifTrue:
[self point: (parents first point
rotateBy: parents third valueItem negated
about: parents second point)].
! !
!DrGPointRotationItem methodsFor: 'xml writing'!
nodeType
^#Rotation! !
!DrGPointRotationItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:38:13'!
isConstrainedPointItem
^true! !
!DrGPointSymmetryItem methodsFor: 'updating'!
update
self doParentsExist ifTrue:
[self point: (2 * parents second point) - parents first point].
! !
!DrGPointSymmetryItem methodsFor: 'xml writing'!
nodeType
^#Symmetry! !
!DrGPointSymmetryItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:38:18'!
isConstrainedPointItem
^true! !
!DrGPointTranslationItem methodsFor: 'xml writing'!
nodeType
^#Translation! !
!DrGPointTranslationItem methodsFor: 'updating'!
update
self doParentsExist ifTrue:
[self point: parents first point + parents second direction].
! !
!DrGPointTranslationItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:38:23'!
isConstrainedPointItem
^true! !
!DrGPolygonItem methodsFor: 'printing'!
printOn: aStream
self printType: DrGPolygonBuilder title on: aStream.
aStream nextPutAll: ' edges=' translated;
nextPutAll: points size printString! !
!DrGPolygonItem methodsFor: 'accessing'!
basicType
^#polygon! !
!DrGPolygonItem methodsFor: 'accessing'!
length
^length ! !
!DrGPolygonItem methodsFor: 'accessing' stamp: 'hlsf 4/12/2021 22:27:45'!
morphClass
^ DrGPolygonMorph! !
!DrGPolygonItem methodsFor: 'accessing'!
points
^points! !
!DrGPolygonItem methodsFor: 'accessing'!
sidesLength
^ sidesLength ! !
!DrGPolygonItem methodsFor: 'testing'!
isCloneable
^ true! !
!DrGPolygonItem methodsFor: 'updating'!
computeLength
length _ 0.
sidesLength _ OrderedCollection new.
points withIndexDo: [:p :i |
length _ length +
(sidesLength add: (p dist: (points at: i + 1 ifAbsent: [points at: 1])))].
^length! !
!DrGPolygonItem methodsFor: 'private'!
adaptiveDescriptiveName
| sides |
sides _ self points size.
sides = 3 ifTrue: [^ 'This triangle %1' translated].
sides = 4 ifTrue: [^ 'This quadrilateral %1' translated].
^ 'This polygon %1' translated! !
!DrGPolygonItem methodsFor: 'computing'!
abscissaOf: aPoint
^ (self closestPointInfoTo: aPoint) second! !
!DrGPolygonItem methodsFor: 'computing'!
abscissaOf: aPoint in: side
"To speed up calculs, we better know the side where is the point"
|distanceToPoint|
distanceToPoint _ 0.
1 to: side - 1 do: [:i |
distanceToPoint _ distanceToPoint + (sidesLength at: i)].
distanceToPoint _ distanceToPoint + (aPoint dist: (points at: side)).
^ distanceToPoint / length! !
!DrGPolygonItem methodsFor: 'computing'!
clone
|clonedPoints clone|
clonedPoints _ points collect: [:aPoint | DrGPointFreeItem newWith: {aPoint + (0.2@0.2)}].
clone _ DrGPolygonNptsItem newWith: clonedPoints.
^ (OrderedCollection withAll: clonedPoints) add: clone; yourself! !
!DrGPolygonItem methodsFor: 'computing'!
closestPointInfoTo: aPoint
"the closest point on the polygon and its curvilinear abscissa in [0 ; 1]"
|closestPoint smallestDistance side|
smallestDistance _ 1e9.
points withIndexDo: [:p :i | | distance point |
point _ self closestPointTo: aPoint
from: p
to: (points at: i + 1 ifAbsent: [points at: 1]).
distance _ aPoint dist: point.
distance < smallestDistance
ifTrue:
[smallestDistance _ distance.
closestPoint _ point.
side _ i]].
^{closestPoint . self abscissaOf: closestPoint in: side}! !
!DrGPolygonItem methodsFor: 'computing'!
closestPointTo: aPoint
^ (self closestPointInfoTo: aPoint) first! !
!DrGPolygonItem methodsFor: 'computing'!
closestPointTo: aPoint from: pointA to: pointB
"the closest point to aPoint in [AB]"
|abscissa vector squareNorm|
vector _ pointB - pointA.
squareNorm _ vector dotProduct: vector.
abscissa _ (aPoint - pointA) dotProduct: vector.
abscissa < 0 ifTrue: [abscissa _ 0].
abscissa > squareNorm ifTrue:
[abscissa _ squareNorm].
^ pointA + (abscissa * vector / squareNorm asFloat)! !
!DrGPolygonItem methodsFor: 'computing'!
pointAt: anAbscissa
|distanceToPoint leftDistanceToPoint sum|
distanceToPoint _ leftDistanceToPoint _ anAbscissa * length.
sum _ 0.
sidesLength withIndexDo: [:s :i |
sum _ sum + s.
sum >= distanceToPoint
ifTrue:
["point is on this side"
|pointA pointB vector|
pointA _ points at: i.
pointB _ points at: i + 1 ifAbsent: [points at: 1].
pointA = pointB
ifTrue: [vector _ 0@0]
ifFalse: [vector _ (pointB - pointA) / (pointA dist: pointB)].
^pointA + (vector * leftDistanceToPoint)].
leftDistanceToPoint _ leftDistanceToPoint - s]! !
!DrGPolygonItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:40:51'!
isCurveItem
^ true! !
!DrGPolygonItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:41:01'!
isGeometricItem
^true! !
!DrGPolygonItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:41:13'!
isIntersectableItem
^ false! !
!DrGPolygonItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:41:22'!
isPolygonItem
^true! !
!DrGPolygonHomothetyItem methodsFor: 'xml writing'!
nodeType
^#Scale! !
!DrGPolygonHomothetyItem methodsFor: 'updating'!
moveParent: aPoint
^false! !
!DrGPolygonHomothetyItem methodsFor: 'updating' stamp: 'hlsf 5/31/2021 18:49:47'!
update
|center factor|
self doParentsExist ifTrue: [
center _ parents second point.
factor _ parents third valueItem.
points _ OrderedCollection new.
parents first points do: [:point | points add: (center + (factor * (point - center)))].
self computeLength].! !
!DrGPolygonNptsItem methodsFor: 'comparing'!
parentsEqual: aPolygon
|shiftedCollection|
parents size = aPolygon parents size ifFalse: [^false].
shiftedCollection _ parents.
shiftedCollection size timesRepeat: [
shiftedCollection = aPolygon parents ifTrue: [^true].
shiftedCollection _ shiftedCollection shiftRight].
shiftedCollection _ parents reverse.
shiftedCollection size timesRepeat: [
shiftedCollection = aPolygon parents ifTrue: [^true].
shiftedCollection _ shiftedCollection shiftRight].
^ false! !
!DrGPolygonNptsItem methodsFor: 'updating' stamp: 'hlsf 5/31/2021 18:47:01'!
update
self doParentsExist ifTrue: [
points _ OrderedCollection new.
parents do: [:pointItem | points add: pointItem point].
self computeLength].
! !
!DrGPolygonNptsItem methodsFor: 'xml writing'!
nodeType
^ #npts! !
!DrGPolygonReflexionItem methodsFor: 'xml writing'!
nodeType
^#Reflexion! !
!DrGPolygonReflexionItem methodsFor: 'updating'!
moveParent: aPoint
^false! !
!DrGPolygonReflexionItem methodsFor: 'updating' stamp: 'hlsf 5/31/2021 18:47:33'!
update
|axe|
self doParentsExist ifTrue: [
axe _ parents second.
points _ OrderedCollection new.
parents first points do: [:point |
points add: (point reflexionBy: axe origin direction: axe direction)].
self computeLength].
! !
!DrGPolygonRegularItem methodsFor: 'updating'!
moveParent: aPoint
"We only move center and the summit, not the value, number of summit."
parents first moveEvent: aPoint.
parents second moveEvent: aPoint.
^ true! !
!DrGPolygonRegularItem methodsFor: 'updating' stamp: 'hlsf 5/31/2021 18:48:02'!
update
|center pointA angle sides|
self doParentsExist ifTrue: [
center _ parents first point.
pointA _ parents second point.
sides _ parents third valueItem rounded abs.
sides < 3 ifTrue: [^ exist _ false].
angle _ Float twoPi / sides.
points _ OrderedCollection new.
sides timesRepeat: [ pointA _ points add: (pointA rotateBy: angle about: center)].
self computeLength]! !
!DrGPolygonRegularItem methodsFor: 'xml writing'!
nodeType
^ #Regular! !
!DrGPolygonRotationItem methodsFor: 'xml writing'!
nodeType
^#Rotation! !
!DrGPolygonRotationItem methodsFor: 'updating'!
moveParent: aPoint
^false! !
!DrGPolygonRotationItem methodsFor: 'updating' stamp: 'hlsf 5/31/2021 18:49:22'!
update
|center angle|
self doParentsExist ifTrue: [
center _ parents second point.
angle _ parents third valueItem negated.
points _ OrderedCollection new.
parents first points do: [:point | points add: (point rotateBy: angle about: center)].
self computeLength].
! !
!DrGPolygonSymmetryItem methodsFor: 'xml writing'!
nodeType
^#Symmetry! !
!DrGPolygonSymmetryItem methodsFor: 'updating'!
moveParent: aPoint
^false! !
!DrGPolygonSymmetryItem methodsFor: 'updating' stamp: 'hlsf 5/31/2021 18:49:09'!
update
|center|
self doParentsExist ifTrue: [
center _ parents second point.
points _ OrderedCollection new.
parents first points do: [:point | points add: (2 * center - point)].
self computeLength].
! !
!DrGPolygonTranslationItem methodsFor: 'updating'!
moveParent: aPoint
^false! !
!DrGPolygonTranslationItem methodsFor: 'updating' stamp: 'hlsf 5/31/2021 18:48:57'!
update
|translation|
self doParentsExist ifTrue: [
translation _ parents second direction.
points _ OrderedCollection new.
parents first points do: [:point | points add: point + translation].
self computeLength].
! !
!DrGPolygonTranslationItem methodsFor: 'xml writing'!
nodeType
^#Translation! !
!DrGTextItem methodsFor: 'printing'!
printOn: aStream
self printType: DrGTextBuilder title on: aStream ! !
!DrGTextItem methodsFor: 'initialize-release'!
initialize
super initialize.
text _ 'Edit me' translated! !
!DrGTextItem methodsFor: 'initialize-release'!
initialize: theParents
super initialize: theParents.
self position: theParents last! !
!DrGTextItem methodsFor: 'xml writing'!
nodeType
^#free! !
!DrGTextItem methodsFor: 'xml writing'!
writeAsXmlPositionTo: aNode
"return the newly created element"
aNode
addElement: ((XMLElement named: #x)
addContent: (XMLStringNode string: position x asString));
addElement: ((XMLElement named: #y)
addContent: (XMLStringNode string: position y asString)).
^ aNode! !
!DrGTextItem methodsFor: 'xml writing'!
writeAsXmlTo: aNode
|node|
node _ super writeAsXmlTo: aNode.
node addElement: ((XMLElement named: #contents) addContent: (XMLStringNode string: self text)).
^ self writeAsXmlPositionTo: node
! !
!DrGTextItem methodsFor: 'accessing'!
basicType
^#text! !
!DrGTextItem methodsFor: 'accessing'!
descriptiveName
^ self adaptiveDescriptiveName
! !
!DrGTextItem methodsFor: 'accessing'!
isLocked
^ locked ifNil: [locked _ false]! !
!DrGTextItem methodsFor: 'accessing'!
locked: aBoolean
locked _ aBoolean ! !
!DrGTextItem methodsFor: 'accessing' stamp: 'hlsf 4/12/2021 22:27:45'!
morphClass
^ DrGTextMorph! !
!DrGTextItem methodsFor: 'accessing'!
parents: aCollection
parents _ nil.
! !
!DrGTextItem methodsFor: 'accessing'!
position
^ position! !
!DrGTextItem methodsFor: 'accessing'!
position: aPoint
position _ aPoint.
self rehash! !
!DrGTextItem methodsFor: 'accessing'!
text
^ text! !
!DrGTextItem methodsFor: 'accessing'!
text: aText
text _ aText.
self rehash! !
!DrGTextItem methodsFor: 'updating' stamp: 'hlsf 8/4/2023 17:22:39'!
editPropertyIn: presenter
| holder |
holder := ValueHolder with: text.
holder action: [:newText | presenter domain propertyCommandFor: self with: newText].
^ TextEntryPanel open: holder label: 'Edit this text' translated! !
!DrGTextItem methodsFor: 'updating'!
move: aPoint
self isLocked ifFalse: [position _ position + aPoint]! !
!DrGTextItem methodsFor: 'updating'!
moveParent: aPoint
^ false! !
!DrGTextItem methodsFor: 'updating'!
property
^ self text! !
!DrGTextItem methodsFor: 'updating'!
property: aProperty
self text: aProperty ! !
!DrGTextItem methodsFor: 'computing'!
closestPointTo: aPoint
^ position! !
!DrGTextItem methodsFor: 'testing'!
doParentsExist
^ true! !
!DrGTextItem methodsFor: 'testing'!
isLockable
^ true! !
!DrGTextItem methodsFor: 'testing'!
isPropertyEditable
^ true! !
!DrGTextItem methodsFor: 'comparing'!
= aMathItem
^ super = aMathItem and: [text = aMathItem text and: [position = aMathItem position]]! !
!DrGTextItem methodsFor: 'comparing'!
rehash
^ hash _ (self basicType hash bitXor: text hash) bitXor: position hash! !
!DrGTextItem methodsFor: 'private'!
adaptiveDescriptiveName
^ 'This text' translated! !
!DrGTextItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:42:05'!
isTextItem
^ true! !
!DrGValueItem methodsFor: 'printing'!
printNameOn: aStream
aStream nextPutAll: 'Value ' translated.
! !
!DrGValueItem methodsFor: 'printing'!
printOn: aStream
self printTypeOn: aStream.
self printValueOn: aStream ! !
!DrGValueItem methodsFor: 'printing'!
printTypeOn: aStream
|safeName|
self printNameOn: aStream.
(safeName _ self safeName) ifNotEmpty: [
aStream nextPutAll: self safeName;
nextPutAll: ' = '].
! !
!DrGValueItem methodsFor: 'printing'!
printValueOn: aStream
self printDecimal: value on: aStream ! !
!DrGValueItem methodsFor: 'updating'!
move: aPoint
self isLocked ifFalse: [self position: position + aPoint].
! !
!DrGValueItem methodsFor: 'updating'!
moveParent: aPoint
"Don't move my parent"
^false! !
!DrGValueItem methodsFor: 'initialize-release'!
initialize
super initialize.
value _ 0! !
!DrGValueItem methodsFor: 'initialize-release'!
initialize: theParents
super initialize: theParents.
self position: theParents last! !
!DrGValueItem methodsFor: 'private'!
adaptiveDescriptiveName
^ 'This value %1' translated! !
!DrGValueItem methodsFor: 'xml writing'!
writeAsXmlPositionTo: aNode
"return the newly created element"
aNode
addElement: ((XMLElement named: #x)
addContent: (XMLStringNode string: position x asString));
addElement: ((XMLElement named: #y)
addContent: (XMLStringNode string: position y asString)).
^ aNode! !
!DrGValueItem methodsFor: 'computing'!
closestPointTo: aPoint
^ position! !
!DrGValueItem methodsFor: 'accessing'!
basicType
^#value! !
!DrGValueItem methodsFor: 'accessing'!
isLocked
^ locked ifNil: [locked _ false]! !
!DrGValueItem methodsFor: 'accessing'!
locked: aBoolean
locked _ aBoolean ! !
!DrGValueItem methodsFor: 'accessing' stamp: 'hlsf 4/12/2021 22:27:45'!
morphClass
^ DrGValueMorph! !
!DrGValueItem methodsFor: 'accessing'!
parents: aCollection
"last is the initial screen position of the value"
aCollection isEmptyOrNil ifTrue:
[ parents _ aCollection.
^ self ].
aCollection last isPoint
ifTrue: [ parents _ aCollection allButLast ]
ifFalse: [ parents _ aCollection ].
! !
!DrGValueItem methodsFor: 'accessing'!
position
^position! !
!DrGValueItem methodsFor: 'accessing'!
position: aPoint
position _ aPoint.! !
!DrGValueItem methodsFor: 'accessing'!
valueItem
^value! !
!DrGValueItem methodsFor: 'testing'!
isLockable
^ true! !
!DrGValueItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:42:49'!
isValueItem
^true! !
!DrGAngleItem methodsFor: 'printing' stamp: 'hlsf 8/3/2021 13:08:24'!
printOn: aStream
self printType: DrGAngleOrientedBuilder title on: aStream.
aStream nextPut: Character space.
self printInteger: self degreeAngle on: aStream.
aStream nextPutAll: '°'.! !
!DrGAngleItem methodsFor: 'accessing'!
basicType
^#angle! !
!DrGAngleItem methodsFor: 'accessing'!
degreeAngle
"return the angle in degree"
^degreeValue ! !
!DrGAngleItem methodsFor: 'accessing'!
radianAngle
"return the angle in radian"
^radianValue ! !
!DrGAngleItem methodsFor: 'private'!
adaptiveDescriptiveName
^ 'This oriented angle %1' translated! !
!DrGAngleItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:43:05'!
isAngleItem
^true! !
!DrGAngle3ptsOrientedItem methodsFor: 'updating'!
move: aPoint
"Don't move when user drag around"! !
!DrGAngle3ptsOrientedItem methodsFor: 'updating' stamp: 'hlsf 5/9/2021 16:54:56'!
update
|u v center|
self doParentsExist ifTrue:
[center _ parents second point.
u _ parents first point - center.
v _ parents third point - center.
(u = (0@0) or: [v = (0@0)])
ifTrue: [exist _ false]
ifFalse:
[radianValue _ value _ (u crossProduct: v) asFloat arcTan: (u dotProduct: v).
degreeValue _ radianValue radiansToDegrees + 360 \\ 360]].! !
!DrGAngle3ptsOrientedItem methodsFor: 'xml writing'!
nodeType
^ #'3ptsOriented'! !
!DrGAngle3ptsOrientedItem methodsFor: 'accessing' stamp: 'hlsf 4/12/2021 22:27:45'!
morphClass
^ DrGAngleOrientedMorph ! !
!DrGAngle3ptsOrientedItem methodsFor: 'accessing'!
position
^ self summit point! !
!DrGAngle3ptsOrientedItem methodsFor: 'accessing'!
side1
^ parents first! !
!DrGAngle3ptsOrientedItem methodsFor: 'accessing'!
side2
^ parents third! !
!DrGAngle3ptsOrientedItem methodsFor: 'accessing'!
summit
^ parents second! !
!DrGAngle3ptsOrientedItem methodsFor: 'testing'!
isLockable
^ false! !
!DrGAngle3ptsItem methodsFor: 'as yet unclassified' stamp: 'hlsf 8/3/2021 13:08:29'!
printOn: aStream
self printType: DrGAngleGeometricBuilder title on: aStream.
aStream nextPut: Character space.
self printInteger: self degreeAngle on: aStream.
aStream nextPutAll: '°'.! !
!DrGAngle3ptsItem methodsFor: 'updating' stamp: 'hlsf 5/9/2021 17:03:34'!
update
"Update for an angle in [0 ; 180]"
|u v center|
self doParentsExist ifTrue:
[center _ parents second point.
u _ parents first point - center.
v _ parents third point - center.
(u = (0@0) or: [v = (0@0)])
ifTrue: [exist _ false]
ifFalse:
[radianValue _ value _ ((u crossProduct: v) asFloat arcTan: (u dotProduct: v)) abs.
degreeValue _ radianValue radiansToDegrees]].! !
!DrGAngle3ptsItem methodsFor: 'accessing' stamp: 'hlsf 4/12/2021 22:27:45'!
morphClass
^ DrGAngleGeometricMorph! !
!DrGAngle3ptsItem methodsFor: 'xml writing'!
nodeType
^#'3pts'! !
!DrGAngle3ptsItem methodsFor: 'private'!
adaptiveDescriptiveName
^ 'This geometric angle %1' translated! !
!DrGAngleVectorsItem methodsFor: 'xml writing'!
nodeType
^ #vectors! !
!DrGAngleVectorsItem methodsFor: 'xml writing'!
writeAsXmlPositionTo: aNode
"return the newly created element"
aNode
addElement: ((XMLElement named: #x)
addContent: (XMLStringNode string: position x asString));
addElement: ((XMLElement named: #y)
addContent: (XMLStringNode string: position y asString)).
^ aNode! !
!DrGAngleVectorsItem methodsFor: 'xml writing'!
writeAsXmlTo: aNode
"return the newly created element"
| node |
node _ super writeAsXmlTo: aNode.
^ self writeAsXmlPositionTo: node.! !
!DrGAngleVectorsItem methodsFor: 'updating' stamp: 'hlsf 6/5/2021 20:17:23'!
update
|u v|
self doParentsExist ifTrue:
[u _ parents first direction.
v _ parents second direction.
(u = (0@0) or: [v = (0@0)])
ifTrue: [exist _ false]
ifFalse:
[radianValue _ value _ ((u crossProduct: v) asFloat arcTan: (u dotProduct: v)).
degreeValue _ radianValue radiansToDegrees]]. ! !
!DrGComputedValueItem methodsFor: 'xml writing'!
writeAsXmlTo: aNode
"return the newly created element"
| node |
node _ super writeAsXmlTo: aNode.
^ self writeAsXmlPositionTo: node.! !
!DrGComputedValueItem methodsFor: 'initialize-release' stamp: 'hlsf 10/19/2022 16:03:46'!
initialize
super initialize.
value _ ''! !
!DrGEquationItem methodsFor: 'printing'!
printOn: aStream
self printType: 'Equation' translated on: aStream.
self printValueOn: aStream ! !
!DrGEquationItem methodsFor: 'printing'!
printValueOn: aStream
aStream nextPutAll: value! !
!DrGEquationItem methodsFor: 'as yet unclassified' stamp: 'hlsf 5/4/2020 18:43:45'!
isEquationItem
^ true! !
!DrGEquationItem methodsFor: 'testing'!
isVerifiedBy: aPoint
self subclassResponsibility ! !
!DrGEquationItem methodsFor: 'accessing'!
basicType
^#equation! !
!DrGEquationItem methodsFor: 'accessing'!
equation
"a string representing the equation"
^ ''! !
!DrGEquationItem methodsFor: 'accessing'!
valueItem
^ self equation ! !
!DrGEquationItem methodsFor: 'private'!
adaptiveDescriptiveName
^ 'This equation %1' translated! !
!DrGEquationItem methodsFor: 'testing-model' stamp: 'hlsf 5/4/2020 18:43:37'!
isValueItem
^ false! !
!DrGEquationCircleItem methodsFor: 'accessing'!
equation
^ value! !
!DrGEquationCircleItem methodsFor: 'updating' stamp: 'hlsf 10/19/2022 16:34:38'!
update
self doParentsExist ifTrue: [| circle |
circle _ parents first.
value _ String streamContents: [:stream |
stream nextPutAll: '(x';
nextPut: (circle center x negated > 0 ifTrue: [$+] ifFalse: [$-]).
self printDecimal: circle center x abs on: stream.
stream nextPutAll: ')² + (y';
nextPut: (circle center y negated > 0 ifTrue: [$+] ifFalse: [$-]).
self printDecimal: circle center y abs on: stream.
stream nextPutAll: ')² = '.
self printDecimal: circle radius squared on: stream]]! !
!DrGEquationCircleItem methodsFor: 'testing'!
isVerifiedBy: aPoint
^ parents first contains: aPoint! !
!DrGEquationCircleItem methodsFor: 'xml writing'!
nodeType
^#circle! !
!DrGEquationLineItem methodsFor: 'updating' stamp: 'hlsf 12/21/2022 14:58:02'!
update
self doParentsExist ifTrue: [ |u origin|
u _ parents first direction.
origin _ parents first origin.
self a: u y.
self b: u x negated.
self c: origin y * u x - (origin x * u y)]! !
!DrGEquationLineItem methodsFor: 'xml writing'!
nodeType
^#line! !
!DrGEquationLineItem methodsFor: 'accessing'!
a
^ a! !
!DrGEquationLineItem methodsFor: 'accessing'!
a: aNumber
a _ aNumber! !
!DrGEquationLineItem methodsFor: 'accessing'!
b
^ b! !
!DrGEquationLineItem methodsFor: 'accessing'!
b: aNumber
b _ aNumber! !
!DrGEquationLineItem methodsFor: 'accessing'!
c
^ c! !
!DrGEquationLineItem methodsFor: 'accessing'!
c: aNumber
c _ aNumber! !
!DrGEquationLineItem methodsFor: 'accessing'!
equation
^ value _ self reducedEquation ! !
!DrGEquationLineItem methodsFor: 'accessing' stamp: 'hlsf 10/19/2022 16:13:37'!
originY
^ b isZero ifTrue: [nil] ifFalse: [c negated / b]! !
!DrGEquationLineItem methodsFor: 'accessing' stamp: 'hlsf 12/10/2022 18:21:04'!
reducedEquation
^ b isZero
ifTrue: [String streamContents: [:stream |
stream nextPutAll: 'x = '.
self printDecimal: c negated / a on: stream]]
ifFalse: [
| slope originY |
originY _ self originY.
String streamContents: [:stream |
stream nextPutAll: 'y = '.
a isZero
ifTrue: [originY printParenthesisOn: stream]
ifFalse: [
slope _ self slope.
slope printParenthesisOn: stream.
stream nextPutAll: ' * x'.
c isZero ifFalse: [
stream nextPutAll: ' + '.
originY printParenthesisOn: stream]]]]! !
!DrGEquationLineItem methodsFor: 'accessing' stamp: 'hlsf 10/19/2022 16:13:27'!
slope
^ b isZero ifTrue: [nil] ifFalse: [a negated / b]! !
!DrGEquationLineItem methodsFor: 'testing'!
isVerifiedBy: aPoint
^ parents first isCollinearWith: (parents first origin - aPoint)! !
!DrGValueArclengthItem methodsFor: 'updating'!
update
self doParentsExist ifTrue:
[value _ parents first length abs * parents first radius].
! !
!DrGValueArclengthItem methodsFor: 'xml writing'!
nodeType
^#'arc_length'! !
!DrGValueArclengthItem methodsFor: 'private'!
adaptiveDescriptiveName
^ 'This arc length %1' translated! !
!DrGValueCircleperimeterItem methodsFor: 'xml writing'!
nodeType
^#'circle_perimeter'! !
!DrGValueCircleperimeterItem methodsFor: 'updating'!
update
self doParentsExist ifTrue:
[value _ parents first radius * Float twoPi].
! !
!DrGValueCircleperimeterItem methodsFor: 'private'!
adaptiveDescriptiveName
^ 'This circle perimeter %1' translated! !
!DrGValueDistance2ptsItem methodsFor: 'accessing'!
name
"When my name is empty, I try to deduce a name from my parent's names if any"
^ name isEmptyOrNil
ifTrue: [
(parents first name isEmptyOrNil or: [ parents second name isEmptyOrNil])
ifFalse: [parents first name, parents second name]
ifTrue: [name]]
ifFalse: [name]
! !
!DrGValueDistance2ptsItem methodsFor: 'private'!
adaptiveDescriptiveName
^ 'This distance between two points %1' translated! !
!DrGValueDistance2ptsItem methodsFor: 'updating'!
update
self doParentsExist ifTrue:
[value _ parents first point dist: parents second point].
! !
!DrGValueDistance2ptsItem methodsFor: 'xml writing'!
nodeType
^#'distance_2pts'! !
!DrGValueDistanceptlineItem methodsFor: 'updating'!
update
self doParentsExist ifTrue:
[value _ ((parents first point - parents second origin)
dotProduct: parents second direction normal) abs].
! !
!DrGValueDistanceptlineItem methodsFor: 'private'!
adaptiveDescriptiveName
^ 'This point-line distance %1' translated! !
!DrGValueDistanceptlineItem methodsFor: 'xml writing'!
nodeType
^#'distance_pt_line'! !
!DrGValuePolygonperimeterItem methodsFor: 'private'!
adaptiveDescriptiveName
^ 'This polygon perimeter %1' translated! !
!DrGValuePolygonperimeterItem methodsFor: 'xml writing'!
nodeType
^#'polygon_perimeter'! !
!DrGValuePolygonperimeterItem methodsFor: 'updating'!
update
self doParentsExist ifTrue:
[value _ parents first length].
! !
!DrGValuePtabscissaItem methodsFor: 'private'!
adaptiveDescriptiveName
^ 'This point abscissa %1' translated! !
!DrGValuePtabscissaItem methodsFor: 'updating'!
update
self doParentsExist ifTrue: [
value _ parents first point x]! !
!DrGValuePtabscissaItem methodsFor: 'xml writing'!
nodeType
^#'pt_abscissa'! !
!DrGValuePtordinateItem methodsFor: 'private'!
adaptiveDescriptiveName
^ 'This point ordinate %1' translated! !
!DrGValuePtordinateItem methodsFor: 'updating'!
update
self doParentsExist ifTrue: [
value _ parents first point y]! !
!DrGValuePtordinateItem methodsFor: 'xml writing'!
nodeType
^#'pt_ordinate'! !
!DrGValueSegmentlengthItem methodsFor: 'xml writing'!
nodeType
^#'segment_length'! !
!DrGValueSegmentlengthItem methodsFor: 'updating'!
update
self doParentsExist ifTrue:
[value _ parents first direction r].
! !
!DrGValueSegmentlengthItem methodsFor: 'private'!
adaptiveDescriptiveName
^ 'This segment length %1' translated! !
!DrGValueVectornormItem methodsFor: 'private'!
adaptiveDescriptiveName
^ 'This Vector''s norm %1' translated! !
!DrGValueVectornormItem methodsFor: 'xml writing'!
nodeType
^#'vector_norm'! !
!DrGValueSlopeItem methodsFor: 'xml writing'!
nodeType
^#slope! !
!DrGValueSlopeItem methodsFor: 'private'!
adaptiveDescriptiveName
^ 'This line slope %1' translated! !
!DrGValueSlopeItem methodsFor: 'updating'!
update
|v|
self doParentsExist ifTrue:
[v _ parents first direction.
v x= 0 ifTrue: [exist _ false]
ifFalse: [value _ v y / v x.]].
! !
!DrGValueVectorabscissaItem methodsFor: 'xml writing'!
nodeType
^#'vector_abscissa'! !
!DrGValueVectorabscissaItem methodsFor: 'private'!
adaptiveDescriptiveName
^ 'This vector abscissa %1' translated! !
!DrGValueVectorabscissaItem methodsFor: 'updating'!
update
self doParentsExist ifTrue: [
value _ parents first direction x]! !
!DrGValueVectorordinateItem methodsFor: 'xml writing'!
nodeType
^ #'vector_ordinate'! !
!DrGValueVectorordinateItem methodsFor: 'updating'!
update
self doParentsExist ifTrue: [
value _ parents first direction y]! !
!DrGValueVectorordinateItem methodsFor: 'private'!
adaptiveDescriptiveName
^ 'This vector ordinate %1' translated! !
!DrGValueScriptItem methodsFor: 'initialization'!
initialize: theParentsCostume
super initialize: theParentsCostume.
self script: (theParentsCostume at: theParentsCostume size - 1)! !
!DrGValueScriptItem methodsFor: 'updating'!
update
self doParentsExist ifTrue: [ value _ script compute]! !
!DrGValueScriptItem methodsFor: 'printing'!
printNameOn: aStream
aStream nextPutAll: 'Script ' translated.
! !
!DrGValueScriptItem methodsFor: 'printing'!
printValueOn: aStream
value isNumber
ifTrue: [^ self printDecimal: value on: aStream].
value isPoint
ifTrue: [^ self printCoordinates: value on: aStream].
aStream print: value! !
!DrGValueScriptItem methodsFor: 'accessing'!
compute
"Do the script computation and return its result "
^ self script compute! !
!DrGValueScriptItem methodsFor: 'accessing' stamp: 'hlsf 4/12/2021 22:27:45'!
morphClass
^ DrGScriptMorph! !
!DrGValueScriptItem methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 11:35:48'!
morphs
^ parentMorphs ! !
!DrGValueScriptItem methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 11:35:48'!
parents: aCollection
"last is the initial screen position of the value, and previous last is the script class"
aCollection isEmptyOrNil ifTrue:
[parents _ aCollection.
parentMorphs _ aCollection.
^ self ].
aCollection last isPoint
ifTrue: [ parents _ aCollection allButLast: 2 ]
ifFalse:
[ "play nicely with macro"
parents _ aCollection ].
! !
!DrGValueScriptItem methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 17:11:23'!
parents: aCollection in: presenter
"last is the initial screen position of the value, and previous last is the script class"
self parents: aCollection.
parents ifNotNil: [parentMorphs := presenter drawable viewsOf: parents].
"reinject the argument in the script in cas it is already instanciated"
script ifNotNil: [script arguments: parentMorphs]! !
!DrGValueScriptItem methodsFor: 'accessing'!
script
^script! !
!DrGValueScriptItem methodsFor: 'accessing' stamp: 'hlsf 4/9/2021 19:50:40'!
script: aScriptClass
script _ aScriptClass new arguments: self morphs.
self rehash ! !
!DrGValueScriptItem methodsFor: 'xml writing'!
nodeType
^#script! !
!DrGValueScriptItem methodsFor: 'xml writing'!
writeAsXmlTo: aNode
|node|
node _ super writeAsXmlTo: aNode.
node attributeAt: #class put: script class printString.
node addElement: (
(XMLElement named: #code) addContent: (
XMLStringNode string: (String streamContents: [:out |script class fileOutOn: out]))).
^ self writeAsXmlPositionTo: node.! !
!DrGValueScriptItem methodsFor: 'comparing'!
= aScriptItem
^super = aScriptItem and: [self script class == aScriptItem script class]! !
!DrGValueScriptItem methodsFor: 'comparing'!
rehash
^hash _ super rehash bitXor: script class hash! !
!DrGValueScriptItem methodsFor: 'testing'!
isPropertyEditable
^ DrGeoSystem isTablet
ifTrue: [false]
ifFalse: [true]! !
!DrGValueScriptItem methodsFor: 'testing' stamp: 'hlsf 5/4/2020 18:44:32'!
isScriptItem
^true! !
!DrGValueScriptItem methodsFor: 'private'!
adaptiveDescriptiveName
| string |
parents size > 0
ifFalse: [string _ 'This script "{1}"' translated]
ifTrue:
[parents size = 1
ifTrue: [string _ 'This script "{1}" with argument: %2' translated]
ifFalse: [string _ 'This script "{1}" with arguments: %2' translated].
string _ string copyReplaceAll: '%2' with: self argumentsName].
^string format: {script class scriptName}.! !
!DrGValueScriptItem methodsFor: 'private'!
argumentsName
"collect parents name in a string as A, B, C"
| stream |
parents size = 0 ifTrue: [ ^ '' ].
stream _ ReadWriteStream on: String new.
parents allButLast do:
[ :item |
stream
nextPutAll: (item safeName ifEmpty: [item printString]);
nextPutAll: ', ' ].
stream nextPutAll: (parents last safeName ifEmpty: [parents last printString]).
^ stream contents! !
!DrGValueScriptItem methodsFor: 'as yet unclassified' stamp: 'hlsf 8/4/2023 17:22:48'!
editPropertyIn: presenter
^ presenter editScript: script class! !
!DrGValueValueItem methodsFor: 'xml writing'!
nodeType
^#value! !
!DrGValueValueItem methodsFor: 'xml writing'!
writeAsXmlTo: aNode
"return the newly created element"
| node |
node _ super writeAsXmlTo: aNode.
node addElement: ((XMLElement named: #value) addContent: (XMLStringNode string: value asFloat asString)).
^ self writeAsXmlPositionTo: node.! !
!DrGValueValueItem methodsFor: 'comparing'!
= aMathItem
^super = aMathItem
and: [self valueItem = aMathItem valueItem
and: [self position = aMathItem position]]! !
!DrGValueValueItem methodsFor: 'comparing'!
rehash
^ hash _ (super rehash bitXor: position hash) bitXor: value hash! !
!DrGValueValueItem methodsFor: 'updating' stamp: 'hlsf 8/4/2023 17:22:55'!
editPropertyIn: presenter
| holder |
holder := ValueHolder with: value.
holder action: [:newValue | presenter domain propertyCommandFor: self with: newValue].
^ FloatEntryPanel open: holder label: 'Edit this value' translated ! !
!DrGValueValueItem methodsFor: 'updating'!
property
^ self valueItem! !
!DrGValueValueItem methodsFor: 'updating'!
property: aProperty
self valueItem: aProperty ! !
!DrGValueValueItem methodsFor: 'accessing'!
position: aPoint
position _ aPoint.
self rehash! !
!DrGValueValueItem methodsFor: 'accessing'!
valueItem: aValue
value _ aValue.
self rehash! !
!DrGValueValueItem methodsFor: 'testing'!
doParentsExist
^ true! !
!DrGValueValueItem methodsFor: 'testing'!
isPropertyEditable
^ true! !
!DrGMacro methodsFor: 'xml writting'!
writeAsXmlTo: aNode
| node |
self saved: true.
self cleanNodes.
node _ XMLElement named: 'macro' attributes: Dictionary new.
node attributeAt: #name put: title asString.
node addElement: ((XMLElement named: #description) addContent: (XMLStringNode string: description asString)).
node
addElement: self writeInputAsXml;
addElement: self writeOutputAsXml.
aNode addElement: node.
^node
! !
!DrGMacro methodsFor: 'xml writting'!
writeInputAsXml
| element |
element _ XMLElement named: 'input'.
self inputNodes do: [:aMacroNode | aMacroNode writeAsXmlTo: element].
^ element ! !
!DrGMacro methodsFor: 'xml writting'!
writeOutputAsXml
| element |
element _ XMLElement named: 'output'.
self allButInputNodes do: [:aMacroNode | aMacroNode writeAsXmlTo: element].
^ element
! !
!DrGMacro methodsFor: 'as yet unclassified' stamp: 'hlsf 8/4/2023 17:11:41'!
execute: inputs in: presenter
self cleanNodes.
self inputNodes
with: inputs
do: [ :node :item | node itemTemplate: item ].
self allButInputNodes do: [:node |
node itemTemplate
parents: (node parentNodes collect: [:aNode | aNode itemTemplate])
in: presenter .
node itemTemplate update; rehash.].
^ self constructedNodes collect: [ :n | n itemTemplate ]! !
!DrGMacro methodsFor: 'accessing'!
addNode: aNode
nodes add: aNode! !
!DrGMacro methodsFor: 'accessing'!
allButInputNodes
^ nodes reject: [:node | node isInputNode]! !
!DrGMacro methodsFor: 'accessing'!
constructedNodes
^ nodes select: [:node | node isInputNode not]! !
!DrGMacro methodsFor: 'accessing'!
description
^ description! !
!DrGMacro methodsFor: 'accessing'!
description: anObject
description _ anObject.
self saved: false.! !
!DrGMacro methodsFor: 'accessing'!
detectId: anId
^ nodes detect: [:node | node isId: anId]! !
!DrGMacro methodsFor: 'accessing'!
hiddenNodes
^ nodes select: [:node | node isHiddenNode]! !
!DrGMacro methodsFor: 'accessing'!
inputBasicType
"The basic type of the input parameters"
^self inputNodes collect: [:n | n itemTemplate basicType]! !
!DrGMacro methodsFor: 'accessing'!
inputNodes
^ nodes select: [:node | node isInputNode]! !
!DrGMacro methodsFor: 'accessing'!
nodes
^nodes! !
!DrGMacro methodsFor: 'accessing'!
outputNodes
^ nodes select: [:node | node isOutputNode]! !
!DrGMacro methodsFor: 'accessing'!
saved: bool
saved _ bool.! !
!DrGMacro methodsFor: 'accessing'!
title
^ title! !
!DrGMacro methodsFor: 'accessing'!
title: anObject
title _ anObject! !
!DrGMacro methodsFor: 'private'!
cleanNodes
nodes do: [ :node |
node itemTemplate:
((node itemTemplate copy)
parents: nil;
yourself).
node itemTemplate releaseActionMap.]! !
!DrGMacro methodsFor: 'private' stamp: 'hlsf 11/18/2021 21:06:11'!
extractItemsFrom: inputs to: outputs in: domain
"extract the items to define the whole macro structure"
| items parents tmp |
items _ (Set withAll: inputs)
addAll: outputs;
yourself.
parents _ outputs.
[ (inputs includesAllOf: parents) | parents isEmpty ]
whileFalse: [ tmp _ parents.
parents _ Set new.
tmp
do: [ :item | item parents ifNotNil: [ parents addAll: item parents ] ].
items addAll: parents ].
^ domain factory ordered: items! !
!DrGMacro methodsFor: 'private'!
itemToNode: item
^ nodes detect: [:node |node itemTemplate = item]! !
!DrGMacro methodsFor: 'private'!
updateParentNodes
nodes do:
[ :node |
node isInputNode | node itemTemplate parents isNil ifFalse:
[ node parentNodes: (node itemTemplate parents collect: [ :item | self itemToNode: item ]) ] ]! !
!DrGMacro methodsFor: 'testing'!
isSaved
^ saved! !
!DrGMacro methodsFor: 'initialize-release'!
from: inputs to: outputs in: domain
"build the tree nodes"
| items |
items _ self
extractItemsFrom: inputs
to: outputs
in: domain.
nodes _ items collect:
[ :item |
DrGMacroNode
on: item
from: inputs
to: outputs ].
self updateParentNodes.
self cleanNodes! !
!DrGMacro methodsFor: 'initialize-release'!
initialize
nodes _ OrderedCollection new.
saved _ false! !
!DrGMacro methodsFor: 'initialize-release' stamp: 'hlsf 8/5/2023 14:35:47'!
release! !
!DrGMacro methodsFor: 'comparing'!
= aMacro
^ nodes size = aMacro nodes size
and:
[nodes with: aMacro nodes do: [:n1 :n2 |
n1 = n2 ifFalse: [^false]].
true]! !
!DrGMacro methodsFor: 'comparing'!
hash
^nodes hash! !
!DrGMacro class methodsFor: 'testing' stamp: 'hlsf 11/18/2021 21:05:19'!
isValidWith: inputs and: outputs
"check the validity of a macro defined with these input and output items"
| parents |
parents _ Set new.
outputs
do: [ :item |
(inputs includes: item)
ifTrue:
[ "item is an input, we don't go to parents, we keep it" parents add: item ]
ifFalse:
[ "item isn't an input, we go to its parents" item parents ifNotNil: [ parents addAll: item parents ] ] ].
parents isEmpty
ifTrue: [ ^ false ].
(inputs includesAllOf: parents)
ifTrue: [ ^ true ].
^ self isValidWith: inputs and: parents! !
!DrGMacroMathItem methodsFor: 'accessing'!
basicType
^ basicType ! !
!DrGMacroMathItem methodsFor: 'accessing'!
basicType: symbol
basicType _ symbol ! !
!DrGMacroMathItem methodsFor: 'accessing'!
id
^ id! !
!DrGMacroMathItem methodsFor: 'accessing'!
id: aSymbol
id _ aSymbol ! !
!DrGMacroMathItem methodsFor: 'accessing'!
parents
^ #()! !
!DrGMacroMathItem methodsFor: 'accessing'!
parents: object
! !
!DrGMacroMathItem methodsFor: 'xml writing'!
writeAsXmlTo: aNode
"return the newly created element"
| node |
node _ XMLElement named: self basicType attributes: Dictionary new.
node attributeAt: #type put: 'inputMacroMathItem';
attributeAt: #id put: self id.
aNode addElement: node.
^node! !
!DrGMacroNode methodsFor: 'testing'!
isHiddenNode
^false! !
!DrGMacroNode methodsFor: 'testing'!
isId: anID
^ itemTemplate id = anID ! !
!DrGMacroNode methodsFor: 'testing'!
isInputNode
^false! !
!DrGMacroNode methodsFor: 'testing'!
isOutputNode
^false! !
!DrGMacroNode methodsFor: 'accessing'!
basicType
^#macroNode! !
!DrGMacroNode methodsFor: 'accessing'!
itemTemplate
^itemTemplate! !
!DrGMacroNode methodsFor: 'accessing'!
itemTemplate: anItem
itemTemplate _ anItem! !
!DrGMacroNode methodsFor: 'xml writting'!
writeAsXmlTo: aNode
^ itemTemplate writeAsXmlTo: aNode! !
!DrGMacroNode methodsFor: 'comparing'!
= aNode
"This is what we expect for input item of the macro.
Handle carrefully when this is a script node"
| answer |
answer _ self basicType = aNode basicType
and: [itemTemplate basicType = aNode itemTemplate basicType
and: [itemTemplate nodeType = aNode itemTemplate nodeType]].
^ answer & itemTemplate isScriptItem
ifTrue: [itemTemplate script == aNode itemTemplate script]
ifFalse: [answer]
! !
!DrGMacroNode methodsFor: 'comparing'!
hash
| hash |
hash _ itemTemplate basicType hash bitXor:
(itemTemplate nodeType hash bitXor: self basicType hash).
itemTemplate isScriptItem ifTrue: [hash _ hash bitXor: itemTemplate script hash].
^ hash! !
!DrGMacroNode class methodsFor: 'as yet unclassified'!
on: item from: inputs to: outputs
"return the appropriate nodes depending on the item is an input, output or intermediate item"
| class |
class _ DrGMacroHiddenNode.
(inputs includes: item) ifTrue: [class _ DrGMacroInputNode].
(outputs includes: item) ifTrue: [class _ DrGMacroOutputNode].
^ class new itemTemplate: item! !
!DrGMacroHiddenNode methodsFor: 'initialize-release'!
initialize
super initialize.
parentNodes _ OrderedCollection new.! !
!DrGMacroHiddenNode methodsFor: 'xml writting'!
statusElement
^ XMLElement named: 'hidden'.
! !
!DrGMacroHiddenNode methodsFor: 'xml writting'!
writeAsXmlTo: aNode
| element statusElement|
statusElement _ self statusElement.
aNode addElement: statusElement.
itemTemplate parents: (parentNodes collect: [:each | each itemTemplate]).
element _ itemTemplate writeAsXmlTo: statusElement.
^ statusElement ! !
!DrGMacroHiddenNode methodsFor: 'accessing'!
basicType
^#hiddenMacroNode! !
!DrGMacroHiddenNode methodsFor: 'accessing'!
parentNodes
^ parentNodes! !
!DrGMacroHiddenNode methodsFor: 'accessing'!
parentNodes: anObject
parentNodes _ anObject! !
!DrGMacroHiddenNode methodsFor: 'testing'!
isHiddenNode
^true! !
!DrGMacroHiddenNode methodsFor: 'comparing'!
= aNode
^ super = aNode and:
[parentNodes = aNode parentNodes]! !
!DrGMacroHiddenNode methodsFor: 'comparing'!
hash
^(super hash) bitXor: parentNodes hash! !
!DrGMacroOutputNode methodsFor: 'accessing'!
basicType
^#outputMacroNode! !
!DrGMacroOutputNode methodsFor: 'testing'!
isHiddenNode
^false! !
!DrGMacroOutputNode methodsFor: 'testing'!
isOutputNode
^true! !
!DrGMacroOutputNode methodsFor: 'xml writting'!
statusElement
^ XMLElement named: 'final'.
! !
!DrGMacroInputNode methodsFor: 'testing'!
isInputNode
^true! !
!DrGMacroInputNode methodsFor: 'accessing'!
basicType
^#inputMacroNode! !
!DrGMacroInputNode methodsFor: 'comparing'!
= aNode
"this is what we expect for input item of the macro"
^ self basicType = aNode basicType
and: [itemTemplate basicType = aNode itemTemplate basicType]
! !
!DrGMacroInputNode methodsFor: 'comparing'!
hash
^ itemTemplate basicType hash bitXor: self basicType hash! !
!DrGeoUserScript methodsFor: 'helpers'!
arg1
^ arguments first mathItem! !
!DrGeoUserScript methodsFor: 'helpers'!
arg2
^ arguments second mathItem! !
!DrGeoUserScript methodsFor: 'helpers'!
arg3
^ arguments third mathItem! !
!DrGeoUserScript methodsFor: 'helpers'!
arg4
^ arguments fourth mathItem! !
!DrGeoUserScript methodsFor: 'helpers' stamp: 'hlsf 8/4/2023 18:14:55'!
costume
"Search for the morph of my instance, then cache its"
^ costume ifNil: [
DrGDrawable allInstances
detect: [ :aDrawable |
aDrawable itemViews
detect: [:aMorph | aMorph mathItem isScriptItem and: [ aMorph mathItem script == self] ]
ifFound: [ :theCostume | costume := theCostume. true]
ifNone: [ false ] ]
ifFound: [costume ]
ifNone: [ nil ]
]! !
!DrGeoUserScript methodsFor: 'helpers'!
costume1
^ arguments first! !
!DrGeoUserScript methodsFor: 'helpers'!
costume2
^ arguments second! !
!DrGeoUserScript methodsFor: 'helpers'!
costume3
^ arguments third! !
!DrGeoUserScript methodsFor: 'helpers'!
costume4
^ arguments fourth! !
!DrGeoUserScript methodsFor: 'helpers' stamp: 'hlsf 8/4/2023 13:04:00'!
presenter
"Access to the presenter handling my instance"
^ self costume ifNotNil: [ costume presenter ]! !
!DrGeoUserScript methodsFor: 'private'!
arguments: aCollectionOfCostume
arguments _ aCollectionOfCostume ! !
!DrGeoUserScript methodsFor: 'public'!
compute
"return a value, the returned value by the script"
self subclassResponsibility ! !
!DrGeoUserScript class methodsFor: 'private'!
argumentsType
"return a collection of Math item, one for each argument type for this script"
^ argumentsType ifNil: [ argumentsType _ self newArgumentsType ]! !
!DrGeoUserScript class methodsFor: 'private' stamp: 'hlsf 4/7/2022 15:12:50'!
newArgumentsType
"The arguments type I need to work"
self subclassResponsibility ! !
!DrGeoUserScript class methodsFor: 'private'!
reset
argumentsType _ nil.! !
!DrGeoUserScript class methodsFor: 'public'!
description
^ 'I am the description of this script. Please edit me.' translated! !
!DrGeoUserScript class methodsFor: 'public'!
scriptName
"I appear in the scripts menu"
^ 'A script' translated! !
!DrGIcons class methodsFor: 'accessing'!
angleGeometric
^self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 48 0 0 0 48 16 6 0 0 0 7 146 37 196 0 0 0 6 98 75 71 68 255 255 255 255 255 255 9 88 247 220 0 0 0 9 112 72 89 115 0 0 0 72 0 0 0 72 0 70 201 107 62 0 0 9 93 73 68 65 84 120 218 237 90 107 76 147 215 27 255 189 212 118 109 41 72 105 144 75 239 165 88 196 41 136 34 157 12 47 212 133 44 129 13 5 151 177 57 62 240 97 178 108 81 251 69 179 132 100 155 95 220 178 236 195 98 178 65 150 200 134 44 91 140 19 198 36 217 133 218 45 113 153 98 22 116 72 128 181 180 20 74 116 114 81 161 148 123 159 255 135 238 245 69 253 51 160 92 138 218 223 151 183 231 125 207 229 247 60 207 57 207 121 158 115 10 132 16 66 8 33 44 17 136 130 205 224 41 21 120 181 240 8 154 192 193 82 192 226 199 13 11 14 241 199 29 172 226 25 38 216 76 22 72 120 174 239 179 61 3 237 119 165 229 88 117 152 47 225 213 46 216 106 231 183 104 194 171 85 192 229 231 181 66 123 192 66 87 66 176 13 178 114 62 126 153 6 152 175 2 231 18 112 165 55 187 199 110 115 93 168 96 43 213 110 181 142 243 40 214 4 107 224 249 41 96 185 103 226 19 59 227 87 59 136 36 18 137 68 34 9 52 252 13 33 64 204 150 65 7 79 241 79 73 38 60 183 171 201 203 203 203 203 203 123 184 126 8 139 196 194 51 233 162 162 162 162 162 162 144 43 90 36 22 175 56 255 138 8 25 98 129 88 122 69 101 100 100 100 100 100 16 137 197 98 177 88 28 50 196 44 88 126 197 68 69 69 69 69 69 17 25 141 70 163 209 24 50 196 191 120 124 239 1 30 115 4 79 1 219 182 109 219 182 109 27 145 86 171 213 106 181 79 157 33 86 155 192 139 231 179 226 41 120 73 73 73 73 73 9 81 103 167 221 222 209 1 184 221 110 183 219 13 244 247 15 12 220 185 3 120 189 94 239 232 40 87 95 44 22 139 69 34 64 38 147 201 100 50 64 161 80 40 148 74 64 175 215 235 245 122 160 186 186 186 186 186 122 229 143 18 50 51 51 51 51 51 137 60 30 143 199 227 1 90 91 91 91 91 91 23 206 99 217 136 151 149 149 149 149 149 17 89 173 86 171 213 10 116 116 116 116 116 116 0 10 69 66 130 76 6 100 101 109 221 186 118 45 144 158 190 113 163 64 0 40 149 10 69 124 60 240 218 107 239 188 99 181 2 191 253 118 246 236 158 61 192 237 219 253 253 30 15 208 209 225 116 2 192 181 107 109 109 30 15 112 229 74 115 243 205 155 64 79 79 111 239 221 187 64 114 178 193 160 215 3 187 119 239 217 99 50 1 21 21 21 21 149 149 79 209 41 170 217 108 54 155 205 68 42 149 74 165 84 114 241 115 110 110 78 142 193 192 149 29 142 198 198 164 36 34 151 235 226 69 165 242 209 39 91 207 233 180 88 18 19 185 247 221 221 23 47 202 229 254 167 66 65 212 213 101 177 168 213 92 253 252 252 189 123 19 18 184 178 74 165 82 41 20 68 102 179 217 124 244 232 242 185 46 185 92 46 151 203 137 10 11 11 11 11 11 131 224 34 77 38 147 105 207 30 78 240 157 59 141 70 181 154 168 174 174 162 34 37 197 175 72 173 150 200 229 178 88 20 10 174 30 91 254 251 239 31 127 212 106 137 174 93 171 175 79 73 225 190 55 52 84 85 237 216 65 244 211 79 95 125 149 154 74 116 233 210 183 223 174 95 79 116 253 122 125 253 76 131 118 118 254 242 139 86 203 25 232 194 133 202 74 157 142 40 59 219 104 212 104 184 122 38 147 201 148 147 179 244 10 218 191 127 255 254 253 251 137 116 58 157 78 167 91 120 255 1 47 153 228 100 131 33 41 137 168 189 189 163 195 102 227 222 119 117 89 44 26 141 255 183 207 7 76 79 251 124 60 30 48 53 53 53 69 4 12 13 121 189 12 3 100 100 20 22 58 157 192 215 95 127 242 137 86 11 120 189 99 99 12 3 140 142 142 143 19 1 68 68 236 130 102 24 128 97 24 198 231 3 14 31 62 113 194 233 4 170 170 62 252 80 163 1 100 50 169 116 205 26 64 167 83 40 248 124 32 50 82 36 26 26 2 134 135 39 39 149 74 96 227 198 220 220 203 151 57 126 27 54 36 39 107 181 64 91 91 123 187 211 185 212 46 99 225 174 104 193 4 212 106 255 210 246 120 134 135 7 6 128 207 63 127 239 61 153 12 48 26 55 111 6 0 149 42 39 199 237 6 90 90 26 26 82 82 0 151 171 183 119 98 2 24 24 184 115 103 114 18 184 113 195 110 159 152 0 174 95 111 107 27 27 3 156 78 183 123 124 28 184 117 171 191 127 98 2 24 25 241 122 167 167 185 241 36 18 177 152 207 7 226 226 214 173 147 72 128 196 68 141 70 42 5 82 82 18 19 137 0 181 58 62 158 8 136 136 8 15 7 0 157 78 173 142 137 1 118 237 122 245 213 166 38 160 179 179 177 209 96 0 254 252 243 198 141 145 17 224 237 183 79 156 184 125 27 136 136 136 136 88 187 22 112 56 92 174 190 190 197 27 34 50 50 50 50 50 146 104 104 104 104 104 104 104 25 12 192 206 248 254 254 190 190 158 30 160 166 230 163 143 164 82 96 195 6 157 142 199 243 219 158 97 128 225 225 209 81 161 16 216 180 41 47 207 102 3 14 29 42 46 142 139 3 44 150 63 254 184 119 15 176 219 187 186 70 71 1 141 70 165 138 142 6 182 108 73 75 75 73 1 12 134 245 235 147 147 1 135 195 225 176 219 129 236 236 93 187 94 120 1 168 171 171 171 171 175 7 164 210 232 232 184 56 160 185 185 185 249 175 191 128 206 78 135 195 233 4 146 146 180 218 136 8 32 39 199 104 12 15 7 42 43 191 249 230 214 45 192 98 57 115 102 203 22 64 46 95 183 110 98 2 16 10 215 172 25 30 6 218 219 29 142 201 73 224 141 55 142 31 239 235 3 98 99 99 99 227 226 128 27 55 218 218 220 238 192 13 193 230 7 74 165 82 169 84 2 181 181 181 181 181 181 115 247 55 231 113 52 235 59 89 87 211 223 63 56 56 54 230 159 129 97 97 156 226 239 221 27 25 17 137 128 150 22 155 205 231 243 71 57 145 145 156 66 132 66 145 40 58 26 120 247 221 99 199 14 29 2 210 211 183 110 205 206 6 106 107 235 235 47 93 98 152 246 118 187 189 191 31 56 123 246 252 249 95 127 101 24 139 197 106 189 122 21 176 88 172 214 43 87 24 102 106 106 122 154 97 88 197 51 76 118 118 118 118 86 22 32 18 133 135 199 199 115 227 100 101 165 167 71 68 0 54 91 87 215 221 187 64 103 103 79 15 235 10 249 124 63 111 30 15 232 235 27 28 156 154 98 21 15 228 230 238 221 251 220 115 129 239 17 26 141 70 163 209 0 189 189 189 189 189 189 129 246 50 3 108 84 227 47 17 189 255 254 225 195 26 13 183 217 177 239 91 90 46 92 216 176 129 232 179 207 62 248 64 171 37 74 74 210 104 132 66 238 123 73 201 235 175 191 248 34 81 77 205 153 51 167 79 19 21 20 20 20 20 20 112 130 46 85 185 180 180 180 180 180 148 27 87 175 87 171 69 34 162 143 63 62 126 92 173 246 111 226 51 55 121 54 154 58 121 210 108 142 138 226 222 155 205 102 243 145 35 129 27 98 201 50 100 149 74 165 82 169 136 210 210 158 125 86 169 228 194 62 151 203 98 145 203 137 108 182 159 127 246 123 97 78 96 161 144 72 36 18 10 121 60 162 99 199 204 230 226 98 162 154 154 154 154 47 191 124 84 241 139 197 108 134 40 47 47 47 47 47 39 18 139 69 34 62 159 51 4 203 179 181 181 161 193 96 120 48 172 149 203 137 114 114 118 236 136 137 33 98 247 184 64 121 73 165 82 169 84 186 8 57 203 202 202 202 14 29 122 244 170 142 37 202 26 160 169 233 220 57 189 158 200 191 228 185 122 199 142 29 61 122 224 128 127 198 87 85 45 189 226 23 106 8 150 23 203 179 190 254 139 47 210 210 136 156 206 198 198 153 97 234 195 79 54 145 92 40 31 129 64 32 16 8 22 33 175 63 76 35 202 203 51 153 20 10 162 206 206 198 198 245 235 231 186 188 38 58 120 240 192 1 163 113 229 20 63 151 33 246 237 219 183 239 229 151 31 117 77 15 63 217 137 229 143 150 136 76 166 221 187 211 211 137 12 6 131 129 203 55 230 15 134 97 24 134 89 180 220 68 231 206 125 250 105 108 172 63 19 85 169 56 159 217 212 84 91 187 101 11 81 82 146 86 43 145 16 109 220 104 48 196 196 16 85 87 87 85 157 58 181 242 138 159 203 16 108 57 53 53 53 53 53 149 115 73 13 13 167 79 103 100 60 152 105 43 20 68 167 78 157 60 201 181 95 126 3 220 143 130 222 122 171 180 52 55 151 72 167 83 42 5 2 96 251 246 77 155 248 124 192 231 35 226 241 128 241 241 169 169 200 72 224 242 229 182 54 141 6 176 217 156 78 143 7 40 46 126 229 149 220 92 224 252 249 239 191 183 88 252 97 99 93 29 195 4 203 16 15 143 207 150 243 243 243 243 243 243 1 187 221 229 26 29 5 6 7 7 7 111 221 2 124 62 159 47 44 140 83 247 75 47 109 223 126 245 42 144 144 144 144 16 27 203 29 30 206 119 124 62 159 207 231 243 3 32 190 115 231 243 207 111 222 60 251 82 101 207 102 222 124 179 184 120 230 153 205 227 246 76 75 75 78 22 8 30 221 132 231 215 126 54 4 222 254 126 162 144 152 168 209 200 100 68 71 142 28 60 8 0 5 5 57 57 66 225 191 149 152 255 223 205 195 239 103 171 55 95 60 156 182 16 249 87 32 159 207 229 27 60 30 195 76 78 114 101 134 241 31 121 204 197 107 122 218 223 79 88 24 48 49 241 95 28 24 134 97 128 138 138 31 126 72 77 5 106 106 190 251 174 165 5 232 238 238 238 238 238 158 45 177 10 252 191 176 247 255 154 248 207 63 125 125 94 47 32 145 8 133 207 60 3 56 157 61 61 99 99 129 41 114 169 177 84 60 102 222 51 204 5 189 94 38 251 253 119 96 96 96 96 96 114 114 174 218 115 77 189 217 51 226 251 6 24 25 241 122 199 198 128 145 145 241 241 152 24 192 225 184 121 51 44 12 16 137 252 105 213 192 192 221 187 97 97 0 155 145 62 233 240 122 199 198 124 62 255 5 145 203 53 223 86 179 249 132 255 104 241 96 113 181 93 249 61 233 152 97 160 229 58 34 120 82 202 43 134 96 11 186 218 203 33 197 63 105 138 15 33 132 16 66 8 30 254 7 195 86 167 231 229 37 138 50 0 0 0 0 73 69 78 68 174 66 96 130)! !
!DrGIcons class methodsFor: 'accessing'!
arc
^self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 48 0 0 0 48 16 6 0 0 0 7 146 37 196 0 0 0 6 98 75 71 68 255 255 255 255 255 255 9 88 247 220 0 0 0 9 112 72 89 115 0 0 0 72 0 0 0 72 0 70 201 107 62 0 0 7 221 73 68 65 84 120 218 237 90 203 79 147 89 20 63 95 203 163 60 74 65 10 5 132 2 37 136 18 27 98 16 17 137 129 21 134 168 33 237 2 67 38 153 132 133 75 137 18 163 9 175 70 94 49 6 212 68 131 11 23 147 204 31 160 49 51 106 52 136 102 76 88 32 105 124 67 38 12 146 182 137 82 138 188 218 210 150 199 157 197 153 147 27 202 212 66 31 130 245 251 109 126 185 95 239 215 246 158 115 238 185 231 113 1 68 136 16 33 66 132 8 17 34 68 136 248 89 193 216 70 254 121 32 217 217 159 255 249 4 238 141 168 240 126 189 47 1 11 194 78 47 124 183 32 204 130 216 174 133 11 66 119 119 119 119 119 55 99 211 211 211 211 211 211 0 209 209 81 81 81 81 0 215 175 223 184 113 227 70 228 41 46 204 59 96 235 232 237 237 237 237 237 101 204 100 50 153 76 38 128 153 153 153 153 153 25 0 133 34 41 41 41 105 167 255 93 248 16 182 51 224 249 243 11 23 46 92 216 250 252 193 193 193 193 193 65 128 145 145 145 145 145 17 0 139 197 98 177 88 0 60 158 149 149 149 21 128 174 174 174 174 174 174 200 59 51 66 174 128 135 15 209 133 28 63 126 251 246 237 219 91 127 111 104 104 104 104 104 8 96 97 97 97 97 97 1 96 121 121 121 121 121 25 96 126 126 126 126 126 158 143 69 248 129 205 166 209 104 52 222 97 229 246 185 186 186 186 186 186 154 177 166 166 166 166 166 166 200 179 124 66 200 118 192 219 183 58 157 78 199 152 82 57 57 57 57 233 127 126 81 81 81 81 81 209 230 231 101 101 101 101 101 101 0 114 185 92 46 151 3 200 100 50 153 76 182 211 98 10 31 66 166 0 173 246 254 253 251 247 253 207 43 47 47 47 47 47 7 136 142 142 142 142 142 222 252 60 33 33 33 33 33 1 96 109 109 109 109 109 13 96 118 118 118 118 118 22 128 162 163 157 22 88 168 17 180 2 222 191 63 117 234 212 41 255 130 169 172 172 172 172 172 4 112 187 221 110 183 27 64 42 149 74 165 82 128 138 138 138 138 138 10 0 133 66 161 80 40 0 146 146 48 234 161 207 237 118 187 221 110 7 88 90 90 90 90 90 218 105 113 133 30 65 135 161 5 5 47 95 190 124 201 199 70 35 242 111 191 197 199 199 199 3 124 248 112 244 232 209 163 0 115 115 115 115 115 115 220 178 227 226 226 226 226 226 184 224 85 42 149 74 165 226 59 192 225 112 56 28 14 238 130 200 37 69 26 2 222 1 207 158 93 186 116 233 18 99 50 25 70 45 132 215 175 145 191 126 213 104 52 26 128 213 213 213 213 213 85 0 137 68 34 145 72 184 64 73 240 153 153 153 153 153 153 0 249 249 249 249 249 249 0 3 3 3 3 3 3 130 144 157 157 157 157 157 13 144 155 155 155 155 155 11 208 214 214 214 214 214 230 43 17 251 113 93 83 192 59 64 165 250 248 241 227 71 62 254 242 5 249 159 127 144 237 246 140 140 140 12 128 152 24 28 199 198 198 198 198 198 114 11 79 75 75 75 75 75 3 200 201 201 201 201 201 1 232 232 232 232 232 232 224 2 238 233 233 233 233 233 137 188 204 215 27 1 43 32 53 245 211 167 79 159 248 120 106 10 217 102 67 139 246 120 240 144 149 203 209 226 211 211 211 211 211 211 57 99 98 21 249 2 246 135 128 93 144 92 254 229 11 89 61 0 128 197 130 188 178 162 84 42 149 220 229 36 38 38 38 38 38 2 100 101 101 101 101 101 137 130 247 70 192 10 144 201 22 23 23 23 249 216 102 67 94 94 198 195 50 42 10 139 104 164 0 131 193 96 48 24 68 193 123 35 96 23 36 149 98 141 134 143 145 61 30 140 126 40 206 39 159 31 24 182 123 184 110 117 254 238 49 132 128 119 192 218 26 10 152 150 156 150 134 28 23 135 241 58 237 128 224 50 89 18 148 63 14 116 254 206 35 96 5 184 92 152 48 209 146 114 115 145 21 10 12 75 5 65 16 4 129 43 66 196 255 35 96 5 44 46 98 226 68 208 104 144 51 50 176 116 192 24 99 140 241 196 43 50 17 124 47 59 96 5 204 206 98 226 68 72 76 68 214 106 177 145 34 149 98 9 33 50 203 200 161 75 252 2 86 192 231 207 251 247 239 223 191 249 57 61 83 169 176 42 74 37 133 31 11 190 202 228 161 71 208 135 146 195 33 151 203 229 140 197 199 227 225 235 114 225 243 63 255 196 195 247 143 63 234 235 235 235 1 10 11 11 11 11 11 1 218 219 219 219 219 219 119 223 97 184 17 129 247 178 173 86 171 213 106 229 81 96 127 127 127 127 127 191 239 245 6 93 13 253 251 239 99 199 142 29 227 99 42 49 87 86 186 92 46 23 64 81 209 232 232 232 40 239 116 125 123 193 63 94 77 167 174 174 174 174 174 142 177 209 81 92 231 212 212 212 212 212 20 47 62 250 67 208 241 201 161 67 79 158 60 121 34 8 40 58 46 192 244 116 100 157 14 107 70 191 255 142 59 96 35 118 171 192 201 98 253 255 63 179 217 108 54 155 249 89 71 85 94 74 64 253 33 100 13 153 87 175 106 107 107 107 1 36 255 125 35 133 158 197 197 200 87 175 62 120 240 224 1 192 197 139 231 206 157 59 231 123 97 205 205 205 205 205 205 187 85 49 155 97 52 26 141 70 35 143 250 168 108 78 229 117 127 8 153 2 142 28 121 252 248 241 99 65 248 252 121 239 222 189 123 125 207 235 235 187 117 235 214 173 205 207 245 122 189 94 175 231 77 248 157 197 246 13 96 124 124 124 124 124 156 91 62 149 219 253 33 228 183 34 94 188 104 104 104 104 216 254 123 30 143 199 227 241 0 196 196 196 196 80 9 251 123 224 209 163 43 87 174 92 217 250 25 116 228 8 246 57 188 81 90 90 90 90 90 202 19 79 90 143 63 132 92 1 191 252 210 215 215 215 39 8 119 239 234 116 58 221 214 223 171 175 223 104 65 225 198 235 215 122 189 94 207 88 109 173 193 96 48 248 159 95 91 123 240 224 193 131 0 11 11 27 123 217 90 173 86 171 213 114 223 79 13 40 138 134 176 175 225 91 177 97 187 152 53 51 131 183 27 182 138 95 127 157 152 152 152 0 104 105 185 115 231 206 29 128 191 254 58 121 242 228 201 208 157 5 70 227 153 51 103 206 48 230 112 236 217 179 103 15 99 37 37 247 238 221 187 231 255 189 211 167 75 74 74 74 0 44 22 44 173 172 175 175 175 175 175 3 20 23 23 23 23 23 115 87 147 156 156 156 156 156 204 203 240 91 237 101 239 178 187 161 190 223 52 153 14 28 56 112 0 96 122 26 23 62 55 87 80 80 80 0 112 226 196 181 107 215 174 9 194 211 167 151 47 95 190 204 24 53 138 50 50 198 198 198 198 0 178 178 222 189 123 247 206 247 239 140 141 33 15 14 34 191 121 147 154 154 154 10 96 181 238 219 183 111 31 128 217 140 209 141 211 233 116 58 157 220 197 164 164 164 164 164 164 240 142 30 141 41 26 162 34 36 125 222 218 218 218 218 218 186 57 31 8 147 2 252 11 254 252 121 108 220 220 188 105 179 81 47 1 0 192 237 70 166 242 54 193 123 188 93 56 157 200 212 185 163 203 3 164 28 139 5 21 59 63 159 151 151 151 199 51 120 202 95 200 242 233 214 134 90 173 86 171 213 0 5 5 104 8 212 104 194 222 53 99 241 241 88 150 111 105 105 105 105 105 241 157 136 125 119 5 84 85 85 85 85 85 1 172 172 96 63 97 120 120 120 120 120 24 224 236 89 180 188 195 135 113 193 106 53 250 210 236 108 124 79 169 68 166 139 186 177 177 200 235 235 200 148 129 83 147 200 106 69 54 153 144 39 38 144 205 102 180 204 175 95 177 217 111 183 163 32 221 238 141 190 157 92 9 9 158 174 201 40 149 104 56 121 121 168 168 96 27 77 223 77 1 53 53 53 53 53 53 60 69 39 223 73 241 51 221 134 166 123 67 106 53 250 80 165 18 21 146 144 128 28 19 131 174 64 34 193 121 36 160 213 85 20 144 219 141 205 127 151 11 227 113 167 19 125 51 250 126 128 165 37 100 250 93 239 219 26 222 97 36 89 50 29 178 222 151 7 130 69 216 206 128 198 198 198 198 198 70 94 27 33 11 162 219 16 116 237 132 158 219 108 232 138 72 160 4 242 169 228 131 105 231 16 211 124 239 247 8 36 96 98 50 0 239 142 29 9 156 124 249 183 175 193 132 14 97 107 149 80 84 64 32 11 162 123 64 219 45 202 161 229 49 70 190 217 229 194 90 19 237 24 234 59 144 34 72 224 164 96 186 22 67 150 78 130 239 236 236 236 236 236 220 237 197 65 17 34 68 136 16 17 137 248 23 96 111 227 207 148 31 36 213 0 0 0 0 73 69 78 68 174 66 96 130)
! !
!DrGIcons class methodsFor: 'accessing'!
axialSymmetry
^self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 48 0 0 0 48 16 6 0 0 0 7 146 37 196 0 0 0 6 98 75 71 68 255 255 255 255 255 255 9 88 247 220 0 0 0 9 112 72 89 115 0 0 0 72 0 0 0 72 0 70 201 107 62 0 0 2 63 73 68 65 84 120 218 237 154 63 170 194 48 28 199 211 135 139 131 155 139 32 20 133 174 122 0 111 32 226 9 164 8 221 68 236 238 1 220 123 128 130 20 79 32 226 228 234 1 116 21 132 130 224 226 230 224 82 200 27 106 120 188 188 23 211 104 106 147 248 251 44 90 11 53 126 63 249 31 17 2 0 0 0 0 0 0 0 64 13 48 254 253 154 31 95 178 31 120 187 249 190 239 231 95 240 124 208 181 220 8 161 205 166 209 104 52 48 62 28 28 199 113 48 86 83 4 93 179 233 242 241 238 203 71 90 11 88 44 46 151 203 5 161 56 78 146 36 65 232 116 90 175 215 107 93 90 4 171 124 150 85 116 201 132 25 14 43 149 74 5 99 53 91 4 171 134 191 191 230 75 199 117 93 215 117 127 10 94 180 8 207 243 60 207 99 125 143 65 2 232 224 139 22 65 7 255 191 8 3 91 130 234 34 82 68 131 7 17 146 16 13 88 195 224 105 212 18 193 15 254 241 152 161 49 197 136 200 62 191 207 54 102 24 192 123 68 100 15 246 99 130 167 201 71 132 188 224 65 196 157 108 34 216 65 125 108 176 162 136 138 72 63 101 183 136 201 100 60 30 141 32 120 97 120 34 82 84 221 226 48 8 86 240 228 93 209 91 28 134 195 14 94 141 5 157 241 252 29 92 213 90 208 25 11 127 165 10 34 94 164 223 159 78 59 29 140 219 237 94 175 217 124 126 239 5 68 8 66 130 127 44 64 28 16 113 135 4 74 7 77 238 211 193 203 18 64 208 93 132 244 127 69 16 104 17 132 221 110 181 58 30 229 157 181 70 81 20 69 145 101 145 224 233 235 249 252 122 189 94 45 75 213 51 107 105 2 226 120 191 63 159 139 250 25 250 138 16 22 64 47 237 101 215 232 87 209 77 68 102 1 36 248 48 12 195 48 180 44 209 61 22 219 110 181 106 53 118 215 36 27 93 68 8 215 92 90 4 43 80 86 151 68 68 16 150 203 217 108 187 205 191 5 177 68 144 107 50 88 15 6 213 106 181 138 144 109 151 74 165 18 66 245 122 183 219 237 34 84 46 7 65 16 200 47 231 211 15 228 213 100 34 128 116 81 244 236 167 168 174 75 85 17 194 176 230 247 116 208 170 110 7 235 62 125 69 116 224 188 224 65 132 36 76 61 226 123 86 196 219 10 104 106 240 52 89 69 176 238 231 142 41 65 243 224 137 120 123 240 159 122 214 90 120 240 64 10 4 15 0 0 0 0 134 241 13 162 86 226 137 186 18 79 185 0 0 0 0 73 69 78 68 174 66 96 130)! !
!DrGIcons class methodsFor: 'accessing'!
blankFigure
^self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 48 0 0 0 48 8 6 0 0 0 87 2 249 135 0 0 0 1 115 82 71 66 0 174 206 28 233 0 0 0 6 98 75 71 68 0 255 0 255 0 255 160 189 167 147 0 0 0 9 112 72 89 115 0 0 11 19 0 0 11 19 1 0 154 156 24 0 0 0 7 116 73 77 69 7 219 6 29 6 15 22 238 223 233 130 0 0 7 58 73 68 65 84 104 222 237 153 91 76 148 233 25 199 127 223 105 142 200 97 0 135 81 131 39 96 100 55 210 210 208 44 106 54 81 183 222 184 132 52 110 77 140 214 100 107 44 171 92 88 172 122 177 166 27 165 224 213 154 232 133 9 89 111 32 219 84 47 188 88 143 27 21 131 46 198 83 151 18 87 84 16 28 79 227 238 202 65 164 226 56 51 31 243 125 111 47 102 24 134 173 117 65 7 210 52 60 201 155 239 155 153 204 188 255 255 243 252 159 231 125 158 111 96 202 166 108 202 166 108 202 166 108 242 76 196 86 210 76 154 68 224 236 221 187 23 128 237 219 183 39 109 111 117 178 128 231 230 230 98 24 17 158 63 31 196 229 114 209 223 223 207 255 26 129 184 52 100 89 38 47 47 143 170 170 42 102 207 158 141 97 24 8 97 98 154 42 86 171 149 37 75 22 115 226 196 73 145 140 40 72 111 11 120 250 244 233 0 172 94 189 154 146 146 18 102 204 240 32 68 148 139 105 154 152 166 136 93 77 132 16 152 166 65 111 111 47 155 54 109 78 138 140 222 40 2 57 57 57 98 207 158 61 76 155 150 130 44 203 168 170 138 205 102 143 178 18 195 75 196 136 68 151 36 17 123 45 145 157 61 157 252 252 124 186 186 186 222 58 236 242 155 120 190 177 177 17 159 207 135 207 119 143 193 193 23 132 66 33 194 225 16 145 200 16 134 97 96 24 70 130 247 197 40 66 146 20 13 222 134 13 127 32 25 21 105 188 4 196 173 91 183 72 77 157 134 166 105 60 126 252 152 135 15 31 18 12 134 208 245 33 34 17 3 195 136 32 132 153 112 53 98 210 17 241 232 0 20 20 20 144 153 153 57 169 17 16 13 13 13 216 108 54 116 125 136 178 178 50 158 61 235 39 20 10 161 235 97 194 225 48 145 72 4 195 48 137 68 12 76 83 96 24 6 32 226 250 143 255 144 136 202 127 219 182 109 111 29 133 49 19 240 120 60 148 148 148 32 203 50 178 44 99 179 217 8 133 194 232 186 78 48 24 149 144 174 135 19 228 147 40 161 145 92 16 194 140 203 200 235 245 190 117 20 198 90 5 196 145 35 71 88 180 104 17 23 47 54 211 216 216 72 111 111 31 233 233 233 184 92 46 114 115 115 113 58 157 88 44 22 172 86 43 86 171 5 144 144 101 9 144 226 250 143 230 128 132 36 17 187 74 116 116 116 240 233 167 59 223 184 34 141 185 10 157 57 115 134 99 199 142 17 12 6 17 66 144 149 149 69 90 90 26 170 170 34 203 50 146 20 5 42 203 114 28 139 36 69 9 68 43 16 152 230 136 223 36 41 250 157 119 222 121 151 172 172 44 250 250 250 38 86 66 247 238 221 99 254 252 249 228 229 229 145 159 159 143 219 237 198 102 179 225 118 187 81 20 5 77 83 177 90 45 88 44 26 170 170 162 105 26 138 162 162 170 42 138 162 198 164 39 161 40 50 138 34 199 165 40 66 33 254 188 101 203 27 231 194 88 9 72 29 29 29 164 165 165 49 119 238 28 156 78 7 110 183 27 171 213 138 221 110 199 225 112 96 181 218 120 248 240 17 131 131 47 80 213 40 161 68 160 170 170 161 170 35 164 84 85 193 8 135 152 125 226 28 25 146 138 215 235 157 216 131 172 187 187 155 66 89 230 95 233 25 56 28 78 12 195 32 51 211 133 170 170 124 255 253 15 236 219 183 15 93 215 217 188 121 51 30 143 39 174 241 104 226 14 159 204 35 78 190 113 35 141 166 166 34 254 113 237 67 86 217 30 177 113 163 198 142 29 59 198 221 94 140 153 128 97 24 4 114 114 248 213 201 147 180 125 240 1 170 203 21 43 137 2 167 211 137 215 235 165 184 248 151 20 21 21 197 115 34 74 128 56 129 39 79 94 208 220 92 192 185 115 110 180 161 32 107 3 245 252 46 120 159 182 208 70 188 222 66 10 11 11 105 111 111 159 184 86 34 50 52 132 235 254 125 10 30 251 249 193 227 129 88 226 206 156 57 147 161 161 33 190 248 226 32 69 69 191 32 35 35 157 96 48 136 205 102 67 211 44 124 243 77 58 95 127 157 205 131 7 14 138 139 7 216 178 229 1 165 246 127 146 251 183 211 52 149 252 154 223 150 189 196 52 237 236 218 181 139 53 107 214 140 43 10 227 34 160 88 173 4 150 44 97 65 237 30 148 154 26 250 23 47 198 52 13 108 54 27 5 5 5 44 88 176 128 204 204 76 122 123 123 169 175 175 39 28 246 242 221 119 21 204 153 147 197 202 149 125 188 247 94 7 169 169 42 226 233 83 22 174 223 78 79 89 25 5 197 197 4 148 104 130 231 228 184 249 236 179 191 80 83 83 59 102 18 227 106 37 254 126 232 16 189 229 229 244 127 252 49 169 61 61 200 64 74 202 52 82 83 83 41 44 44 100 96 96 0 128 214 214 86 78 159 62 141 221 222 67 93 93 128 186 186 7 148 151 7 200 206 118 96 177 104 104 167 78 97 166 164 224 95 189 154 240 188 121 40 138 26 91 10 43 86 172 32 59 59 107 194 218 105 225 247 251 121 242 237 183 204 107 108 36 48 119 46 47 203 203 1 208 117 61 86 50 21 12 35 194 249 243 23 48 77 147 165 75 151 198 115 33 162 235 56 91 91 153 94 87 199 163 247 223 39 252 251 117 241 19 123 248 160 51 77 147 206 206 78 54 108 216 48 38 124 227 38 224 243 249 112 216 237 240 252 57 174 149 43 209 23 46 228 217 206 157 232 25 25 72 138 50 42 105 163 247 102 124 54 120 122 215 199 187 159 127 78 160 168 136 222 53 107 48 237 246 248 140 48 12 222 48 162 109 72 69 69 5 183 111 223 150 146 42 33 128 190 190 62 236 14 7 90 86 22 61 91 183 98 185 123 23 247 186 117 184 14 31 38 52 248 28 69 81 98 117 94 141 221 107 40 161 48 153 245 13 20 239 216 142 229 199 31 9 174 248 13 74 106 42 138 162 196 150 138 44 43 200 178 18 63 232 106 107 107 198 116 184 141 155 192 241 227 199 227 39 173 99 237 90 2 7 15 162 151 151 147 242 229 151 228 253 177 2 75 91 27 154 166 161 170 202 8 137 151 47 113 158 61 203 192 159 170 120 244 213 87 24 222 5 177 207 149 81 135 93 116 69 137 120 60 51 104 104 168 255 89 18 227 110 160 102 205 154 37 124 62 95 194 224 98 16 137 24 60 185 122 149 252 234 106 228 142 14 244 178 50 132 197 130 94 82 130 118 245 42 182 83 167 120 89 94 206 227 138 10 108 30 79 66 183 58 188 70 58 216 97 9 133 195 97 90 90 90 168 170 170 122 45 206 55 233 0 69 87 87 87 124 88 79 4 18 238 237 193 121 232 48 242 253 251 40 29 29 16 8 16 252 232 35 2 171 86 33 92 174 81 96 135 129 190 138 76 115 243 69 106 107 107 69 79 79 207 95 129 221 201 30 234 197 217 179 103 89 190 124 121 60 241 18 151 16 130 72 36 130 20 10 18 209 44 9 195 189 249 95 61 63 76 166 189 189 157 202 202 74 186 187 187 171 99 123 237 158 144 167 18 165 165 165 226 242 229 203 241 106 147 24 137 97 82 163 201 25 175 241 184 73 91 219 13 62 249 100 83 34 240 68 75 122 4 98 149 82 140 42 153 81 208 230 107 129 38 122 253 217 179 1 90 91 91 89 191 126 125 245 207 236 53 49 4 154 154 154 88 182 108 217 168 55 127 10 244 85 100 58 59 59 185 126 253 58 149 149 149 213 227 216 111 119 210 159 204 157 63 127 254 63 8 68 167 177 209 254 25 30 33 143 30 61 202 129 3 7 104 105 105 169 30 231 86 19 18 129 81 50 250 169 13 123 251 230 205 155 92 184 112 129 173 91 183 38 21 116 210 158 141 190 42 10 126 191 159 75 151 46 177 127 255 126 174 93 187 86 157 108 192 73 125 188 94 90 90 42 174 92 185 130 223 239 231 206 157 59 52 55 55 83 83 83 83 61 145 128 147 253 255 192 238 137 246 240 100 252 193 177 123 178 192 78 217 148 77 217 255 161 253 27 58 98 17 74 10 213 30 16 0 0 0 0 73 69 78 68 174 66 96 130)! !
!DrGIcons class methodsFor: 'accessing'!
centralSymmetry
^self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 48 0 0 0 48 16 6 0 0 0 7 146 37 196 0 0 0 6 98 75 71 68 255 255 255 255 255 255 9 88 247 220 0 0 0 9 112 72 89 115 0 0 0 72 0 0 0 72 0 70 201 107 62 0 0 2 3 73 68 65 84 120 218 237 154 209 141 194 48 12 134 233 233 150 224 9 137 1 96 0 86 64 44 209 55 132 24 128 1 24 0 33 222 186 4 98 5 6 128 1 144 120 98 140 242 148 67 245 93 206 73 157 196 105 251 127 47 149 64 77 157 223 142 237 90 29 141 0 0 0 0 16 128 186 110 94 121 190 180 77 238 7 238 130 83 190 181 77 239 6 54 129 139 66 186 178 120 129 97 224 27 225 238 142 65 10 82 6 14 32 148 101 89 150 37 141 120 121 170 1 12 84 248 191 29 65 187 28 238 10 188 9 35 188 187 35 112 180 254 197 53 146 77 138 242 79 93 168 1 34 138 162 121 98 140 224 168 25 129 176 167 20 191 154 161 78 119 138 22 39 172 155 240 116 223 106 248 26 16 202 96 127 199 74 133 207 204 17 210 7 182 189 95 126 178 252 132 77 165 71 54 15 226 4 110 239 128 237 118 179 89 175 67 11 207 235 18 168 90 211 46 32 22 241 102 50 105 236 254 109 143 176 13 77 37 124 87 225 245 105 233 128 248 194 119 123 38 19 77 159 248 197 164 219 51 153 104 207 75 223 207 166 158 201 104 233 195 28 145 92 114 124 232 153 12 183 158 235 126 229 250 244 100 22 20 106 38 147 78 120 71 114 121 179 147 206 100 220 215 107 167 135 162 0 177 8 59 10 176 237 199 117 159 217 204 116 252 13 90 173 118 187 197 162 174 231 243 229 114 58 229 239 139 59 147 233 28 237 35 194 8 239 235 0 67 207 133 253 129 249 46 200 94 100 140 160 147 201 108 54 30 127 126 63 159 247 251 235 245 115 223 243 121 191 191 94 238 6 153 153 204 225 112 60 158 78 159 226 90 85 85 85 85 218 221 88 120 90 111 200 230 0 138 113 192 237 118 185 60 30 253 19 80 138 184 13 245 141 112 208 196 217 1 52 7 35 162 195 192 58 128 230 96 223 98 104 82 148 41 198 218 27 206 13 231 8 166 142 176 9 106 75 73 92 177 30 42 222 2 112 145 76 139 46 109 63 145 186 154 136 63 79 167 17 111 4 238 123 251 168 134 137 104 122 53 255 15 229 5 42 57 3 31 9 232 1 225 51 1 66 43 17 247 123 25 0 0 0 0 0 37 222 28 134 87 22 39 202 104 13 0 0 0 0 73 69 78 68 174 66 96 130)
! !
!DrGIcons class methodsFor: 'accessing'!
circle
^self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 48 0 0 0 48 16 6 0 0 0 7 146 37 196 0 0 0 6 98 75 71 68 255 255 255 255 255 255 9 88 247 220 0 0 0 9 112 72 89 115 0 0 0 72 0 0 0 72 0 70 201 107 62 0 0 11 6 73 68 65 84 120 218 237 90 89 76 84 247 23 62 195 62 3 195 54 80 96 216 226 64 21 172 136 49 77 80 145 64 92 74 77 120 16 77 109 40 47 188 25 18 86 31 36 225 161 66 99 2 24 21 100 107 66 82 19 107 31 140 90 104 19 105 155 136 177 46 149 132 88 75 193 34 9 160 172 14 21 134 25 134 1 134 97 185 125 56 249 114 203 181 83 96 24 168 252 255 243 189 124 222 59 227 112 239 57 191 223 89 190 243 35 114 192 1 7 28 112 192 1 7 28 112 192 129 77 135 236 191 126 0 107 184 119 239 236 217 179 103 5 33 40 168 171 171 171 139 72 165 122 245 234 213 43 34 165 114 116 116 116 148 200 195 195 104 52 26 137 156 157 231 231 231 231 137 22 23 93 93 93 93 137 204 102 111 111 111 111 34 163 49 40 40 40 136 72 167 219 182 109 219 54 162 209 209 216 216 216 88 162 163 71 47 94 188 120 81 246 206 190 247 166 227 219 111 175 92 185 114 69 16 158 63 79 75 75 75 19 132 217 89 31 31 31 31 65 16 4 34 162 213 243 210 210 234 190 55 61 173 84 42 149 130 240 219 111 169 169 169 169 130 112 243 230 229 203 151 47 243 167 255 87 232 232 72 79 79 79 95 217 96 90 45 115 107 43 243 173 91 204 95 126 201 220 208 192 220 212 196 252 236 25 179 193 192 188 176 176 156 173 253 157 182 182 99 199 142 29 219 124 71 108 218 86 108 110 62 127 254 252 121 65 72 72 184 122 245 234 85 34 149 234 229 203 151 47 197 207 77 38 230 158 30 230 246 118 230 190 62 230 241 241 144 144 144 16 162 249 249 128 128 128 0 162 217 89 165 82 169 36 178 88 20 10 133 130 72 46 159 154 154 154 34 242 241 153 156 156 156 36 10 14 214 233 116 58 162 184 184 177 177 177 49 162 152 24 254 157 200 72 102 87 215 229 207 231 228 196 172 213 134 134 134 134 18 61 124 152 153 153 153 73 148 145 113 225 194 133 11 27 23 178 54 220 1 247 239 23 22 22 22 10 66 82 82 109 109 109 173 24 179 129 174 46 230 159 127 102 238 238 246 244 244 244 36 210 235 53 26 141 134 200 100 98 195 91 44 46 46 46 46 68 50 153 76 38 147 17 185 184 240 181 171 43 199 126 92 227 115 65 224 213 237 236 108 50 153 76 68 65 65 236 240 253 251 153 19 19 205 102 179 153 232 189 247 254 217 17 139 139 252 123 141 141 236 136 79 63 189 118 237 218 53 251 59 98 195 28 0 195 167 164 84 86 86 86 138 247 167 166 152 31 63 102 126 244 136 121 96 96 215 174 93 187 136 38 39 35 35 35 35 255 110 64 103 103 103 103 34 119 119 119 119 119 119 34 133 130 87 188 167 39 59 10 44 151 203 229 114 185 248 253 197 197 197 197 197 69 162 217 217 217 217 217 89 162 233 233 233 233 233 105 145 119 236 120 250 244 233 83 162 244 116 78 242 97 97 252 28 10 197 242 247 48 26 153 155 154 50 50 50 50 136 102 103 19 19 19 19 137 114 114 114 114 114 114 214 239 16 187 59 0 161 38 53 181 180 180 180 84 92 241 35 35 252 249 79 63 49 183 181 169 84 42 21 145 193 16 23 23 23 71 100 50 177 97 177 130 97 104 31 31 31 31 31 31 34 95 95 95 95 95 95 241 26 134 119 115 115 115 115 115 179 110 144 218 218 218 218 218 90 65 176 88 44 22 139 69 116 192 228 36 135 42 23 151 158 158 158 30 162 228 228 7 15 30 60 32 218 191 223 96 48 24 136 188 188 248 255 47 46 50 247 245 177 99 155 155 179 178 178 178 136 220 221 227 227 227 227 137 242 242 242 242 242 242 108 119 132 221 29 48 62 174 209 104 52 130 128 24 143 21 127 243 38 243 227 199 225 225 225 225 68 19 19 187 119 239 222 77 180 176 192 43 29 161 4 6 14 12 12 12 12 12 36 10 8 224 152 175 84 114 204 183 215 202 131 99 166 166 56 119 232 245 92 222 126 252 113 99 99 99 35 81 98 226 208 208 208 16 145 179 51 127 127 102 134 185 165 133 159 231 215 95 79 159 62 125 154 40 36 132 67 164 173 207 101 55 7 160 170 137 139 107 106 226 138 132 241 227 143 204 223 125 199 43 126 116 116 223 190 125 251 68 195 99 165 171 84 252 121 80 16 215 239 184 206 207 207 207 207 207 223 248 186 189 186 186 186 186 186 90 16 12 6 118 68 86 86 67 67 67 3 81 120 248 248 248 248 184 184 19 116 58 230 111 190 217 179 103 207 30 162 169 169 227 199 143 31 39 42 41 41 41 41 41 89 251 115 58 173 247 193 81 199 75 13 143 228 138 24 143 80 35 53 60 12 30 25 201 177 31 43 106 179 12 15 32 148 4 6 242 14 189 119 239 212 169 83 167 222 254 158 74 197 28 31 223 222 222 222 78 100 52 246 245 245 245 17 85 84 84 84 84 84 172 189 140 93 247 11 162 129 250 224 131 59 119 238 220 17 203 201 175 191 102 254 229 23 78 174 6 67 68 68 68 132 24 106 130 131 131 131 131 131 69 195 23 23 23 23 23 23 191 123 29 234 195 135 71 142 28 57 34 8 73 73 45 45 45 45 226 78 24 24 96 254 234 171 152 152 152 24 34 139 37 45 45 45 141 40 34 130 223 115 181 185 97 221 59 32 42 234 209 35 172 114 34 177 142 71 57 137 170 6 201 21 49 30 43 223 207 207 207 207 207 239 191 54 179 117 252 241 199 201 147 39 79 18 25 141 44 113 32 39 160 106 210 104 88 34 209 233 184 239 48 26 89 34 89 45 108 118 0 180 26 15 15 174 38 0 52 80 168 227 81 78 34 228 32 185 34 198 103 103 103 103 103 103 175 119 229 111 92 7 139 231 235 236 76 78 78 78 22 239 195 17 161 161 115 115 115 115 68 110 110 189 189 189 189 68 122 189 94 175 215 19 213 212 212 212 212 212 172 252 92 54 59 0 34 25 48 58 202 140 206 213 100 226 16 131 186 28 43 31 85 205 102 199 248 245 98 112 240 208 161 67 135 222 190 143 157 32 151 191 126 253 250 181 88 222 206 204 204 204 160 114 250 55 216 236 0 168 147 64 127 63 51 36 3 139 133 99 61 26 40 212 241 40 39 183 26 62 251 172 176 176 176 80 38 27 28 100 85 21 59 32 32 128 217 211 147 251 7 105 195 183 18 108 118 0 100 97 96 120 152 25 90 141 181 134 202 94 117 252 127 133 63 255 220 185 115 231 78 241 218 219 155 217 213 149 87 252 252 60 55 158 112 0 250 13 107 191 103 179 3 160 199 3 227 227 204 16 201 160 205 160 99 133 35 182 58 244 250 168 168 168 40 241 218 221 157 217 201 137 115 1 28 96 54 179 214 132 107 107 112 177 245 65 164 162 26 182 36 212 73 148 155 112 0 66 209 218 176 214 228 186 218 239 219 190 3 33 14 2 60 135 32 90 90 90 90 90 90 18 121 110 142 29 2 77 202 26 108 222 1 152 64 225 149 3 3 153 33 11 99 7 120 120 120 120 120 120 216 26 122 240 253 149 216 214 239 175 29 210 208 107 54 51 47 44 112 177 1 7 192 240 184 182 187 3 48 250 195 43 65 103 135 30 47 149 141 255 87 32 45 62 16 134 231 230 150 239 112 24 30 101 184 53 216 236 0 204 92 1 141 134 25 131 16 252 225 149 182 224 86 67 112 240 139 23 47 94 136 215 111 222 48 155 205 203 171 59 39 39 39 39 39 39 113 33 90 131 205 14 192 176 27 128 124 139 9 20 6 33 208 227 87 170 6 222 117 220 186 197 207 175 86 119 118 118 118 138 247 7 7 153 103 102 184 204 134 225 209 255 224 218 26 108 118 128 86 203 26 136 20 184 135 9 20 202 49 206 1 248 214 214 115 132 84 114 65 147 213 219 203 60 61 237 239 239 239 47 26 28 69 7 28 97 13 54 71 231 143 62 186 116 233 210 37 153 12 167 12 20 10 78 190 200 5 24 253 125 242 201 242 142 121 99 176 241 125 197 142 29 119 239 222 189 43 94 163 241 28 26 226 34 99 106 138 29 224 225 177 188 248 64 53 104 13 235 22 227 60 61 217 240 48 129 92 206 140 153 235 86 71 123 251 137 19 39 78 8 130 66 49 49 49 49 33 222 231 211 23 68 19 19 203 71 168 152 208 161 252 94 169 250 91 183 3 172 65 173 254 231 251 101 101 101 101 101 101 111 223 175 170 170 170 170 170 18 4 240 230 152 215 58 126 248 161 180 180 180 84 16 226 227 121 66 6 32 1 35 15 152 76 44 63 35 244 72 103 213 43 97 211 11 68 157 142 69 171 242 242 242 242 242 114 65 64 195 210 215 199 131 13 108 89 56 162 160 160 160 160 160 96 243 165 11 28 159 1 176 250 91 90 152 135 135 89 146 48 155 209 241 115 200 129 228 178 218 206 223 78 59 96 245 6 74 77 189 125 251 246 109 162 145 17 54 120 127 127 127 127 127 63 209 200 200 200 200 200 8 145 193 192 162 22 134 232 155 141 161 161 189 123 247 238 21 4 127 255 129 1 12 93 136 136 248 96 24 81 71 7 107 93 147 147 92 5 98 229 123 121 121 121 121 121 137 162 99 110 110 110 110 110 238 38 12 100 214 138 163 71 181 90 173 150 40 47 239 198 141 27 55 136 148 202 238 238 238 110 209 224 136 161 43 37 47 123 1 161 70 167 139 140 140 140 20 132 176 176 103 207 16 223 137 136 158 60 97 190 127 159 171 25 131 129 39 124 136 249 8 53 144 217 177 3 86 11 59 133 160 181 199 236 247 223 231 228 45 8 173 173 173 173 68 215 175 71 71 71 71 19 117 116 112 121 107 155 118 180 122 32 185 198 199 159 59 119 238 220 219 159 195 240 223 127 207 60 50 146 144 144 144 64 52 51 195 161 5 11 5 131 37 12 154 214 122 76 101 195 39 81 159 127 126 224 192 129 3 68 95 124 241 228 9 94 138 136 136 207 106 138 64 173 172 215 243 138 122 254 60 37 37 37 133 104 104 232 240 225 195 135 137 50 51 207 156 57 115 102 237 185 0 13 20 234 120 148 147 210 170 6 255 70 168 193 138 135 225 141 70 14 45 168 235 177 226 49 211 182 245 84 196 134 37 225 186 186 186 186 186 58 162 158 30 62 248 68 196 14 184 126 157 147 149 78 199 101 42 78 25 64 174 240 243 227 198 45 41 169 185 185 185 153 136 136 249 224 193 216 216 216 88 65 128 30 15 89 24 234 36 68 50 104 53 144 12 212 234 191 55 128 111 3 85 13 146 43 98 60 66 13 86 60 12 143 25 182 90 173 86 171 213 162 35 108 197 6 237 0 153 172 190 190 190 190 190 94 16 6 6 56 153 117 117 113 67 166 213 114 14 56 120 144 147 111 90 26 159 187 129 172 129 17 159 180 123 252 183 110 114 53 64 231 138 6 10 113 30 229 36 170 26 36 87 105 93 47 53 60 14 21 172 247 100 220 58 119 128 245 63 140 83 2 99 99 172 13 45 44 44 44 44 44 136 73 171 173 109 251 246 237 219 137 126 255 157 87 112 116 52 151 167 31 126 200 106 106 68 4 127 31 14 193 42 195 4 10 249 1 82 47 154 62 168 147 16 201 160 213 64 50 64 231 138 6 10 117 252 220 28 39 125 188 17 170 26 233 129 49 172 248 119 246 108 104 101 101 101 101 101 165 32 32 244 12 15 15 15 15 15 139 19 34 233 17 68 172 52 56 10 125 65 68 4 139 121 1 1 236 16 79 79 102 55 55 30 253 97 2 5 217 23 122 60 100 97 168 147 16 201 160 213 64 50 192 223 69 25 9 233 0 51 107 105 114 45 42 42 42 42 42 178 127 63 98 247 28 128 17 28 84 80 200 209 120 65 188 80 88 88 88 88 88 152 24 91 113 95 58 192 48 153 248 119 222 188 89 62 115 5 75 39 81 82 192 192 96 185 156 23 128 116 98 135 5 129 80 227 237 205 243 142 245 134 152 77 119 0 98 38 26 18 0 199 199 113 244 16 91 25 231 110 164 114 53 12 106 237 120 57 118 148 116 244 135 255 39 149 133 81 214 98 33 72 37 3 116 174 171 109 160 236 133 13 251 67 144 18 208 96 97 197 21 22 242 241 14 91 127 23 142 66 78 1 75 39 80 24 132 192 17 152 204 129 183 250 233 12 7 28 112 192 1 59 224 47 137 64 226 59 103 178 13 148 0 0 0 0 73 69 78 68 174 66 96 130) ! !
!DrGIcons class methodsFor: 'accessing'!
coordinates
^self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 48 0 0 0 48 16 6 0 0 0 7 146 37 196 0 0 0 6 98 75 71 68 255 255 255 255 255 255 9 88 247 220 0 0 0 9 112 72 89 115 0 0 0 72 0 0 0 72 0 70 201 107 62 0 0 2 14 73 68 65 84 120 218 237 154 193 21 194 32 12 134 169 207 17 220 194 33 28 192 147 87 174 234 115 130 78 209 21 60 115 245 228 0 14 225 22 238 80 79 60 159 244 97 8 80 146 216 124 151 190 182 208 134 252 16 82 168 49 138 162 40 82 25 71 106 11 164 211 229 85 139 57 190 203 124 222 114 65 58 44 181 199 171 16 141 208 16 84 202 138 218 128 165 179 198 21 215 30 207 12 21 164 20 13 65 196 168 0 196 44 116 14 8 219 65 151 54 35 71 128 55 84 106 158 207 175 3 77 4 216 239 251 126 183 227 103 104 26 222 238 240 200 151 232 8 240 66 200 22 196 195 119 233 100 98 0 228 240 211 105 24 94 47 106 179 167 28 14 198 60 159 232 230 119 214 90 107 237 56 58 231 156 115 211 243 230 13 9 123 254 111 65 184 142 140 88 40 250 28 189 163 125 141 240 156 12 92 200 97 96 240 79 187 4 11 129 107 40 23 210 29 31 30 133 56 158 107 150 145 234 232 105 121 33 142 135 26 78 13 236 120 239 232 219 205 152 237 86 124 232 9 27 78 13 236 120 127 238 5 136 221 23 38 4 95 67 99 142 21 62 2 184 206 1 31 32 199 66 35 64 24 124 13 135 70 0 181 125 149 224 215 144 203 229 124 62 30 211 71 128 112 228 53 132 155 0 11 221 15 224 195 194 246 3 248 161 91 146 196 8 21 0 10 133 165 161 178 221 234 47 82 128 212 252 191 118 185 176 124 44 4 66 247 75 159 239 175 215 19 98 230 57 32 102 48 214 81 212 142 79 109 23 158 70 33 40 52 184 246 36 30 62 31 235 152 210 250 100 96 99 101 110 108 205 189 159 122 125 46 187 96 26 127 7 104 250 90 153 90 217 66 173 45 80 40 132 64 107 65 216 228 161 156 153 230 0 108 79 175 53 249 65 73 2 244 30 168 126 234 28 150 46 144 208 239 0 170 80 134 125 47 44 196 58 183 98 89 121 46 180 178 59 62 114 34 2 148 230 231 165 121 251 191 220 135 253 41 52 4 229 115 189 246 253 102 211 234 109 112 71 46 84 112 174 15 171 250 196 126 56 187 223 135 225 241 96 243 123 122 232 208 250 107 31 202 55 127 31 130 160 95 45 153 254 253 45 110 77 68 81 242 120 3 185 219 205 252 208 44 95 233 0 0 0 0 73 69 78 68 174 66 96 130)
! !
!DrGIcons class methodsFor: 'accessing'!
createAndMove
^self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 24 0 0 0 24 8 6 0 0 0 224 119 61 248 0 0 0 9 112 72 89 115 0 0 11 18 0 0 11 18 1 210 221 126 252 0 0 3 152 73 68 65 84 72 199 181 150 111 76 155 85 20 198 127 183 45 157 64 9 89 72 216 194 212 18 144 66 178 4 54 162 4 170 147 15 68 81 214 26 23 18 135 113 115 24 13 146 169 153 201 18 12 81 99 244 203 20 17 93 92 182 15 203 134 154 105 130 75 220 146 206 40 206 178 17 54 33 197 132 145 77 201 168 150 117 98 97 64 11 133 240 167 127 222 30 63 16 154 17 186 63 17 56 95 222 188 231 189 247 62 247 156 231 62 247 121 149 136 8 235 24 58 214 57 12 171 153 124 163 194 188 236 61 219 233 93 251 10 178 157 222 132 11 175 25 64 83 83 19 74 41 46 5 22 18 15 144 251 8 64 18 13 181 150 149 198 243 214 178 210 132 115 87 112 160 148 90 2 6 192 110 183 211 213 241 13 67 158 97 148 82 136 8 74 41 182 109 43 162 175 239 10 197 197 197 0 164 164 154 120 220 90 22 95 231 242 111 221 43 43 0 228 187 83 159 201 192 181 159 226 59 3 228 214 205 11 210 223 115 58 158 123 181 246 121 25 245 58 197 102 179 73 67 67 131 136 136 52 54 54 138 136 72 77 77 141 12 14 14 198 43 90 193 65 118 246 131 232 245 58 234 234 234 226 185 152 166 33 154 6 128 217 108 102 239 238 103 24 241 141 210 217 217 73 85 85 21 0 149 149 149 0 212 215 215 223 153 100 17 225 248 241 54 50 50 54 242 70 221 206 120 187 208 4 137 45 2 60 105 221 202 35 57 89 56 157 61 24 141 70 154 155 155 201 207 51 83 94 94 14 16 127 222 241 20 181 126 253 3 63 183 119 145 102 50 113 244 139 247 151 241 1 80 251 226 179 104 225 8 151 187 175 16 12 6 41 45 202 162 227 220 49 242 243 22 53 225 114 185 238 14 32 34 156 56 121 142 52 83 10 59 118 60 122 251 7 0 242 114 178 184 229 27 227 204 143 93 188 190 207 198 158 93 21 124 220 210 138 165 160 16 151 203 69 110 110 110 98 0 165 20 118 187 29 0 103 71 7 215 7 135 216 148 153 193 168 247 34 74 167 72 51 165 114 179 255 12 177 72 20 145 197 118 29 124 173 26 223 200 56 191 116 184 112 56 28 148 148 148 36 22 154 82 138 192 120 47 219 139 30 142 131 52 127 126 2 4 174 94 29 68 161 103 120 100 10 148 14 68 72 75 125 128 191 46 181 226 247 7 57 223 217 139 165 160 16 0 191 223 127 119 37 191 125 224 21 172 37 249 216 237 118 206 58 156 40 93 18 55 134 103 209 27 146 233 31 248 7 141 36 46 254 254 47 161 185 8 11 179 33 66 209 8 223 158 189 64 75 75 11 110 183 155 64 32 64 32 16 160 189 189 125 249 101 183 36 30 255 88 47 213 187 42 49 110 48 208 221 221 141 94 103 36 197 148 206 184 127 146 212 180 141 16 213 8 71 21 198 13 41 76 79 5 112 252 218 131 165 160 144 218 125 47 175 216 249 146 208 12 183 147 123 244 200 135 236 174 174 226 233 138 39 120 110 231 83 8 26 254 137 49 98 209 116 82 146 147 153 14 78 176 48 59 201 223 158 25 68 9 159 28 105 227 94 118 178 172 69 251 223 252 128 119 222 253 148 172 45 155 144 152 70 76 34 20 109 125 136 140 140 116 54 111 206 36 18 137 226 243 186 65 193 87 109 231 177 217 108 247 188 12 85 34 71 203 201 201 225 212 201 67 88 44 102 36 166 161 133 66 12 251 102 144 249 49 194 161 57 220 67 195 28 250 242 123 174 187 189 255 207 209 60 30 15 47 188 116 0 127 96 10 4 20 138 45 153 201 40 3 204 204 206 163 79 210 175 222 50 183 23 63 70 56 28 1 5 162 19 68 52 230 230 34 204 135 163 24 12 134 248 209 92 149 101 94 27 112 19 156 206 68 162 81 36 18 101 98 114 134 254 63 61 8 178 54 166 239 243 141 177 255 173 143 64 167 136 41 56 248 222 97 14 31 59 77 223 31 19 56 28 142 251 2 80 235 253 219 242 31 185 225 254 15 195 173 162 18 0 0 0 0 73 69 78 68 174 66 96 130)! !
!DrGIcons class methodsFor: 'accessing'!
createMultiple
^ self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 48 0 0 0 48 8 6 0 0 0 87 2 249 135 0 0 0 1 115 82 71 66 0 174 206 28 233 0 0 0 6 98 75 71 68 0 255 0 255 0 255 160 189 167 147 0 0 0 9 112 72 89 115 0 0 11 19 0 0 11 19 1 0 154 156 24 0 0 0 7 116 73 77 69 7 219 6 29 6 2 11 56 119 251 22 0 0 1 11 73 68 65 84 104 222 237 151 205 13 131 48 12 133 177 197 0 28 122 232 28 172 210 57 89 165 179 176 129 123 105 37 14 129 36 142 159 67 42 127 18 226 128 228 23 255 17 189 105 10 130 32 8 130 123 33 223 167 8 70 11 40 98 87 49 163 5 42 226 145 38 0 23 86 91 156 70 39 149 140 92 21 143 209 2 6 73 209 225 109 178 3 85 2 25 168 224 251 81 163 58 129 102 129 198 113 202 22 136 26 22 151 12 58 32 21 5 82 47 49 106 124 36 83 208 162 238 50 90 64 185 15 169 238 138 166 66 169 223 168 100 222 154 248 214 177 125 4 46 22 23 162 33 29 146 128 221 150 230 2 207 199 130 61 60 92 32 8 130 160 187 191 69 56 50 87 127 171 97 6 29 152 188 90 204 14 213 135 218 79 118 222 135 22 255 0 79 160 139 253 100 167 202 195 58 64 160 185 87 249 219 158 29 240 182 159 240 17 50 247 183 94 55 174 151 253 116 93 220 191 73 98 28 194 126 118 186 7 32 44 239 215 233 183 125 221 238 159 192 89 18 251 186 141 209 129 84 18 191 195 15 199 213 56 13 203 7 27 12 132 199 176 214 170 20 0 0 0 0 73 69 78 68 174 66 96 130)! !
!DrGIcons class methodsFor: 'accessing'!
distance
^self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 48 0 0 0 48 16 6 0 0 0 7 146 37 196 0 0 0 6 98 75 71 68 255 255 255 255 255 255 9 88 247 220 0 0 0 9 112 72 89 115 0 0 0 72 0 0 0 72 0 70 201 107 62 0 0 1 212 73 68 65 84 120 218 237 153 59 170 2 49 24 133 227 221 128 133 165 157 149 224 62 132 108 69 16 23 32 86 174 64 132 244 46 65 16 2 22 130 59 176 180 16 5 221 132 221 88 92 66 32 26 50 143 252 127 226 120 190 102 8 153 201 227 156 147 76 116 132 0 32 62 69 145 122 4 64 8 1 35 178 1 70 100 2 140 96 194 8 237 94 221 122 64 140 207 0 183 30 68 166 106 226 91 99 68 217 137 134 146 73 213 63 245 243 201 169 187 212 115 19 142 207 136 63 174 142 104 48 66 117 58 113 219 53 237 209 27 241 165 6 80 9 111 219 223 239 215 235 201 196 237 47 62 145 39 16 18 198 55 145 178 66 114 11 111 25 143 167 83 165 170 142 183 53 80 111 5 70 120 123 56 48 229 251 253 112 232 247 237 53 246 120 50 223 130 248 19 175 148 82 74 217 196 239 118 231 243 124 110 235 255 141 112 199 215 58 210 37 254 115 255 118 5 28 143 155 77 175 87 20 171 213 98 49 24 52 95 17 153 173 0 254 196 155 242 112 56 26 109 183 118 5 152 251 77 249 118 123 60 158 79 33 78 167 203 165 219 21 98 54 91 46 175 87 115 223 215 191 19 242 217 227 221 107 40 241 82 74 41 101 253 241 39 118 46 221 169 198 36 222 71 40 241 70 120 173 181 214 250 189 156 82 213 82 194 80 183 207 149 248 47 91 1 72 124 34 144 120 31 1 231 154 38 22 137 143 54 209 106 245 72 124 89 42 58 233 75 180 59 64 36 158 24 95 226 233 62 180 180 37 241 46 13 157 197 30 159 9 72 124 93 152 191 7 132 159 71 226 163 80 53 81 191 147 120 23 98 231 195 95 200 144 120 22 222 79 77 191 154 120 23 246 255 130 144 248 36 32 241 62 200 223 1 72 124 18 144 248 178 68 255 29 128 196 103 1 18 207 206 103 97 32 60 59 33 35 32 60 19 62 35 32 60 51 62 35 124 245 16 158 136 144 208 16 158 9 8 159 9 16 30 0 0 146 243 2 254 23 48 217 74 149 99 100 0 0 0 0 73 69 78 68 174 66 96 130)! !
!DrGIcons class methodsFor: 'accessing'!
drgeo
^self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 48 0 0 0 48 8 6 0 0 0 87 2 249 135 0 0 0 4 103 65 77 65 0 0 177 143 11 252 97 5 0 0 0 9 112 72 89 115 0 0 11 18 0 0 11 18 1 210 221 126 252 0 0 15 190 73 68 65 84 120 156 197 154 121 112 84 215 149 135 191 183 244 91 122 111 181 164 110 9 9 33 9 1 66 8 4 2 140 88 108 179 36 142 9 137 99 187 176 157 196 241 56 51 21 87 202 51 169 76 77 198 197 76 37 169 33 227 170 120 166 226 144 154 137 29 39 241 16 39 94 98 108 12 56 142 67 8 198 118 48 216 236 59 2 1 18 32 9 16 218 90 173 222 212 203 123 239 206 31 54 158 33 56 11 72 73 78 85 255 115 251 245 185 231 123 231 174 231 215 210 219 111 191 205 95 202 36 73 66 8 49 166 62 229 49 245 118 197 169 44 35 73 210 85 109 3 3 3 47 175 89 179 70 60 251 236 179 226 119 191 27 85 95 99 230 233 3 51 12 131 117 235 214 137 129 129 129 255 184 210 22 139 197 30 90 189 122 245 202 154 154 26 118 236 216 65 58 157 30 179 254 198 20 96 104 104 104 217 195 15 63 44 18 137 4 61 61 61 171 174 180 75 146 116 246 145 71 30 225 142 59 238 144 238 187 239 190 107 178 51 26 147 198 114 14 164 82 105 246 236 217 45 150 46 93 58 118 17 254 17 27 83 128 63 102 87 230 134 109 219 99 230 83 29 43 71 142 99 115 248 240 33 49 156 28 6 91 194 116 123 152 51 103 182 164 40 10 153 76 134 231 158 127 94 188 245 214 54 220 30 131 150 121 45 124 229 31 190 42 229 114 249 81 247 59 102 0 91 223 252 149 56 223 121 138 162 168 7 9 232 61 53 140 227 228 69 115 243 28 233 133 23 158 23 200 25 30 249 198 23 41 20 70 120 111 199 17 182 108 217 44 22 47 94 54 234 161 54 38 0 137 196 48 71 142 237 99 197 93 243 240 251 189 12 14 119 17 44 86 217 246 214 111 104 63 123 86 8 53 203 223 125 233 30 188 94 131 193 161 62 220 126 137 29 219 14 51 127 254 34 116 93 255 235 2 216 142 205 211 107 127 40 86 126 110 9 21 21 149 4 253 81 122 7 130 148 132 135 112 187 138 9 133 34 52 53 53 16 10 68 240 185 67 248 60 165 100 115 67 84 84 247 144 76 199 133 174 71 70 149 133 81 3 12 13 197 246 103 243 9 38 84 213 16 240 149 18 10 148 81 26 174 32 51 146 164 121 154 138 132 140 170 105 152 186 15 69 150 241 184 253 24 70 128 68 60 69 62 95 24 109 247 163 223 7 18 137 120 179 199 39 97 152 94 28 75 102 237 211 63 229 209 213 107 200 36 5 165 197 213 148 22 87 17 242 69 233 60 123 158 239 124 231 113 122 123 123 240 184 3 116 180 95 36 54 216 255 215 5 144 101 153 211 29 199 168 170 141 160 185 12 158 249 201 207 57 223 217 205 236 57 77 168 170 130 109 229 25 201 166 200 230 82 180 159 109 39 59 146 231 229 117 175 18 240 134 48 52 157 87 54 108 36 147 25 221 174 172 60 248 224 131 55 252 99 65 129 45 219 94 93 221 178 104 42 245 19 231 50 103 206 92 74 35 197 188 244 194 47 216 249 222 46 12 211 69 32 164 33 132 32 224 47 98 40 150 68 215 76 76 211 205 196 73 21 188 185 109 39 118 65 172 174 175 159 250 173 27 141 97 84 25 104 61 121 76 248 195 42 53 85 147 81 93 6 251 247 29 230 107 95 253 38 51 102 204 162 162 188 154 199 30 93 67 54 155 37 147 25 225 187 255 249 125 118 108 223 195 96 127 146 213 223 252 30 207 252 104 3 119 175 252 24 191 250 245 107 116 117 119 222 240 17 245 134 1 6 7 251 247 191 185 99 19 45 45 141 4 253 227 216 250 235 173 124 235 223 254 147 39 159 120 138 229 203 151 179 252 246 219 201 100 114 36 18 73 98 177 1 186 47 92 226 177 199 190 205 67 15 125 137 117 63 127 145 25 211 231 241 214 27 187 185 255 75 159 96 205 154 199 233 234 238 186 33 136 27 2 72 166 226 53 235 54 172 109 110 154 91 73 113 113 5 169 68 150 239 125 247 199 124 237 159 30 161 182 182 150 72 36 66 69 197 56 34 145 82 250 251 7 104 107 59 69 73 113 9 146 36 225 114 185 48 12 131 7 30 120 128 248 80 150 138 242 18 90 22 215 242 244 218 167 200 140 100 254 252 0 154 230 226 173 237 91 59 92 222 20 53 19 234 8 122 163 108 221 186 157 137 181 147 249 228 39 111 39 28 14 19 10 133 48 12 147 124 161 64 105 36 202 241 99 167 184 233 166 22 12 195 32 16 8 16 14 135 41 47 31 199 212 250 6 78 28 59 199 188 69 83 8 150 200 60 241 196 127 95 119 22 174 27 224 229 13 47 138 87 127 241 10 179 230 214 81 30 153 8 142 139 159 173 93 199 163 143 254 59 62 159 31 195 48 144 36 137 92 46 203 224 224 32 37 225 0 71 14 182 82 59 177 26 89 150 49 12 3 77 211 48 12 131 69 139 22 176 127 207 73 76 211 203 226 143 205 160 111 176 147 159 61 251 19 49 50 50 50 246 0 66 8 90 219 246 139 141 27 214 83 26 13 209 48 105 54 94 51 196 249 206 46 202 202 162 84 85 85 161 40 202 135 207 14 12 12 208 123 185 151 108 161 64 34 153 38 28 46 66 150 101 84 85 69 150 101 16 48 99 70 19 3 125 41 36 225 34 90 30 102 249 157 11 56 120 104 47 27 55 109 20 150 101 141 45 192 185 238 54 241 131 39 159 194 31 86 48 53 55 145 112 13 178 164 176 119 247 126 150 44 94 138 36 73 31 94 84 10 133 60 201 100 28 203 42 48 146 78 146 207 229 113 187 61 255 23 60 32 16 148 150 70 168 170 170 226 232 225 211 128 196 64 255 48 94 159 206 177 214 3 236 220 185 243 79 26 78 127 210 81 226 248 201 195 226 103 207 253 152 72 149 65 121 69 148 142 214 4 150 237 128 237 226 208 129 19 124 243 235 247 34 132 192 113 28 132 16 228 243 121 82 169 12 85 85 227 144 85 25 213 165 162 200 239 195 9 33 176 109 27 73 146 49 116 131 146 146 98 50 169 12 46 69 99 233 178 22 22 46 152 205 192 64 140 231 159 217 136 162 200 98 193 130 133 210 21 232 235 6 176 109 155 182 211 173 226 165 151 158 163 110 106 49 51 231 214 81 20 8 83 94 122 129 108 62 69 62 165 99 21 4 211 166 53 126 152 129 124 62 143 16 176 119 239 30 102 54 55 224 80 0 28 250 250 251 137 68 202 177 44 11 85 85 1 129 36 73 168 138 11 89 5 144 240 121 252 20 5 13 12 175 139 79 221 221 194 218 39 255 135 116 38 35 150 44 94 34 105 154 246 145 49 254 193 33 116 172 245 144 120 238 249 31 17 173 210 113 123 188 76 159 58 143 186 154 102 22 222 114 19 182 101 113 230 76 59 19 39 77 198 52 77 36 73 66 81 20 10 133 2 153 145 12 91 182 108 229 166 249 179 0 135 233 51 235 89 255 202 6 146 137 228 7 128 2 203 178 24 201 102 201 91 5 210 153 4 35 185 36 8 240 152 1 2 222 16 182 200 17 42 50 121 251 157 45 108 125 99 235 239 29 78 191 23 96 199 187 111 138 23 95 121 154 69 159 168 100 114 253 120 134 250 51 56 182 66 192 87 66 105 184 26 143 17 36 49 148 164 172 52 74 42 149 226 232 209 163 220 115 207 61 180 181 181 241 206 246 237 88 86 142 169 51 170 25 78 12 240 241 21 115 217 254 219 55 233 237 189 76 79 79 15 171 86 173 98 197 138 21 28 60 120 128 216 96 12 73 182 201 21 178 8 69 66 150 20 52 151 155 142 211 125 4 194 6 183 221 209 200 142 247 182 208 221 221 253 145 16 215 0 20 10 121 54 189 182 78 28 108 219 204 188 197 149 212 55 52 82 63 165 1 85 85 57 116 240 48 8 129 199 244 35 112 200 228 147 216 142 77 33 95 160 189 189 157 214 214 86 250 250 250 232 238 190 64 221 212 241 56 100 192 17 24 110 193 248 154 16 175 108 122 133 254 254 126 186 187 187 57 115 230 12 221 221 231 105 59 121 130 170 218 32 154 170 99 104 110 4 14 167 218 58 56 123 234 34 159 88 177 128 170 154 50 238 252 252 124 214 111 252 57 61 61 61 215 64 92 5 80 176 10 60 189 246 9 209 126 105 39 141 179 163 76 158 84 71 69 201 20 38 84 77 165 121 238 52 246 238 58 74 247 133 110 4 18 233 108 156 100 58 6 64 42 157 194 239 247 179 106 213 42 234 167 76 225 229 151 215 209 114 235 36 28 199 198 235 45 194 208 220 124 234 222 57 188 177 237 151 60 246 237 199 184 239 222 123 89 189 122 53 170 11 178 133 20 142 148 195 227 46 198 212 253 168 170 78 95 207 0 247 127 241 110 22 45 88 74 101 100 18 227 43 163 76 152 236 97 195 166 245 215 148 100 174 154 196 235 215 191 40 146 118 59 51 230 149 227 117 7 9 7 203 81 93 42 249 124 134 250 134 137 8 73 70 8 9 93 51 0 135 241 53 126 158 252 206 235 220 124 203 34 92 170 78 67 67 61 63 248 225 147 84 214 249 137 142 243 226 243 132 9 249 163 200 178 139 84 54 206 3 95 105 97 199 214 147 124 229 31 191 76 168 168 152 108 46 69 253 172 82 60 70 0 83 247 160 200 50 154 230 225 158 123 239 71 56 14 201 116 236 253 139 144 203 197 244 230 36 103 78 238 230 192 129 253 98 214 172 102 233 26 128 100 50 201 59 239 190 193 226 79 87 162 202 26 225 96 20 77 115 19 139 95 194 113 44 82 153 4 213 213 69 84 84 148 227 53 131 120 205 34 74 162 33 166 207 169 228 27 95 255 87 162 101 101 216 118 158 120 162 159 7 255 126 41 94 51 68 192 27 65 215 61 120 29 27 191 89 132 215 237 97 254 178 90 102 206 175 70 20 100 10 86 129 112 177 151 128 47 140 101 23 176 108 11 231 131 143 64 96 59 5 100 73 33 232 141 16 10 148 51 189 185 138 221 123 223 99 214 172 230 107 51 240 250 230 95 10 20 11 211 212 48 13 15 33 127 57 125 125 125 28 62 216 78 124 48 73 73 196 195 148 25 229 152 151 79 98 232 110 12 205 67 145 63 202 231 31 184 157 115 183 116 209 121 238 18 142 99 83 82 54 137 178 200 56 74 139 39 96 232 110 36 73 193 208 60 4 252 17 198 69 39 227 73 244 225 56 22 8 9 7 7 151 162 97 26 33 92 170 142 109 219 228 11 89 28 225 32 9 129 101 91 184 20 9 151 203 36 28 40 103 114 125 140 55 94 223 128 166 171 228 115 214 213 0 166 105 98 24 42 170 75 37 228 47 101 120 168 192 150 215 222 197 146 147 216 142 197 233 119 50 156 57 211 197 237 159 206 35 112 40 43 174 195 52 3 184 221 1 60 102 136 9 85 227 209 92 110 76 195 139 91 15 18 240 149 224 82 117 44 187 128 162 168 132 2 81 52 85 39 28 24 135 35 44 16 144 207 103 201 21 70 80 85 29 67 243 96 57 22 78 54 129 229 228 177 109 11 77 51 49 52 3 85 85 241 184 67 20 23 149 82 93 27 229 192 129 253 162 113 90 147 116 21 64 98 56 137 207 111 34 41 10 126 119 128 211 39 46 82 85 87 196 197 254 126 210 217 56 193 74 139 243 29 113 158 95 59 196 93 159 205 195 100 7 159 183 20 77 53 241 22 133 40 149 107 112 169 26 178 226 66 145 20 84 151 134 101 229 113 28 231 195 55 173 233 110 28 97 35 75 42 142 16 8 134 176 133 131 97 122 81 20 141 124 46 69 38 23 7 36 242 35 130 88 127 22 143 225 163 178 122 60 1 191 137 169 123 40 41 45 230 216 177 86 26 167 53 93 157 129 202 241 21 28 57 97 145 31 177 73 141 12 51 117 70 45 133 124 41 53 137 74 186 46 158 97 40 217 139 219 127 153 115 199 6 217 188 105 15 238 47 24 84 68 45 130 254 40 94 79 24 175 59 136 34 43 216 142 131 35 108 28 219 193 178 10 128 132 36 129 229 88 104 170 129 208 222 63 110 56 194 193 208 60 168 138 142 162 184 72 166 7 137 13 95 192 118 108 14 239 237 228 213 151 222 193 165 23 48 12 29 69 241 243 248 154 213 104 186 135 112 36 192 64 247 71 172 66 139 111 89 34 253 242 245 95 136 190 139 105 66 69 189 8 100 124 158 16 19 42 166 48 46 90 67 54 55 76 239 80 55 126 207 78 14 238 188 196 166 23 119 178 98 229 8 197 69 113 16 224 53 3 8 225 0 14 194 118 200 217 105 114 185 17 76 211 7 226 253 253 69 145 21 100 69 35 22 235 37 224 15 160 107 30 84 59 207 229 254 14 122 135 58 25 138 15 243 211 239 111 99 40 62 72 203 109 81 252 65 31 193 96 136 34 99 26 219 183 111 231 230 37 179 25 232 141 49 173 113 225 135 0 87 93 234 39 77 154 180 250 221 119 246 97 57 185 247 87 0 213 6 217 70 83 117 36 20 76 221 131 207 231 69 210 83 156 56 210 77 50 110 17 40 145 65 42 224 119 135 209 117 47 146 36 113 255 231 254 150 201 13 227 9 250 253 104 46 15 0 142 83 192 113 108 218 78 180 241 95 223 123 154 230 217 141 24 186 78 127 188 139 243 61 173 92 188 216 195 250 103 118 145 41 12 210 178 180 146 198 198 70 38 215 204 196 173 22 51 60 144 163 166 118 2 46 67 162 163 189 11 73 120 168 174 170 253 214 53 251 64 245 132 90 233 225 47 127 77 236 218 189 147 183 55 191 73 160 232 28 205 45 117 212 84 151 129 44 129 16 120 61 62 154 166 207 196 182 45 222 219 210 129 16 54 115 23 230 112 235 1 170 132 141 238 242 210 213 121 129 179 29 29 212 213 54 124 112 200 147 145 101 21 129 141 131 197 205 183 206 70 55 117 6 19 61 92 236 111 231 210 165 11 108 122 225 8 137 100 156 150 101 101 204 152 57 139 178 226 10 76 181 136 189 191 221 69 105 89 41 101 21 197 244 246 118 147 24 78 65 110 240 195 152 255 64 121 93 208 218 122 92 188 190 249 53 186 187 187 144 100 9 69 181 8 150 232 148 149 149 81 18 213 233 186 124 154 158 115 89 132 80 88 182 98 26 149 101 53 76 155 188 0 43 11 166 199 141 215 27 196 165 104 200 146 140 237 88 228 173 44 249 124 150 108 46 203 112 242 34 221 151 219 56 222 122 138 151 215 238 34 84 38 104 106 25 71 99 125 19 101 145 74 188 238 32 154 230 166 80 200 35 1 233 76 130 195 135 218 249 205 171 135 120 242 251 79 73 178 236 186 122 14 92 107 18 13 13 141 210 212 134 6 226 241 248 67 185 92 238 71 217 124 146 67 39 222 230 252 217 78 142 236 141 209 219 155 98 194 132 9 156 57 221 201 209 125 23 144 231 202 168 170 70 237 248 70 28 241 254 14 238 168 54 32 0 137 92 110 132 212 72 140 193 225 75 244 15 118 209 215 219 71 219 225 94 170 167 20 19 12 107 4 180 137 36 7 85 130 94 153 34 159 31 73 40 8 199 102 56 49 196 169 182 243 28 220 125 142 47 124 254 111 184 18 252 31 201 192 71 91 193 202 243 238 190 215 196 238 67 111 97 137 97 122 58 211 104 138 73 34 230 112 243 109 117 212 77 29 71 36 92 137 223 19 38 224 45 65 81 85 28 225 224 56 130 145 108 156 120 178 143 193 120 15 185 92 158 3 187 206 81 200 73 248 3 38 201 68 22 85 242 113 238 204 101 116 93 67 150 32 149 30 193 178 44 92 46 149 121 243 230 179 248 214 37 68 35 229 210 255 87 58 175 187 184 235 82 53 230 54 45 151 78 159 232 17 182 217 73 180 60 71 174 144 196 74 123 216 179 253 44 151 47 197 185 121 153 77 38 59 204 96 226 50 178 4 249 194 8 185 92 150 244 72 146 244 72 134 108 82 176 99 107 7 77 179 39 162 7 227 12 14 159 70 24 26 29 199 99 124 124 201 29 44 95 190 252 247 86 172 127 87 166 189 161 210 162 203 229 162 166 122 162 185 103 207 161 133 53 181 81 130 193 0 197 37 126 130 69 62 142 236 189 72 58 157 39 24 214 201 230 18 196 147 49 6 99 3 244 246 14 114 169 107 136 211 199 6 216 183 163 155 207 172 188 149 105 77 85 120 124 110 116 197 71 251 113 155 7 62 251 101 22 204 95 112 93 229 246 81 105 100 27 54 190 36 50 162 131 241 117 6 2 5 89 150 200 166 37 54 189 176 15 69 145 168 158 88 130 166 43 196 135 210 12 197 210 164 147 57 202 43 162 220 185 114 41 69 37 6 3 177 139 216 78 158 205 27 143 51 109 226 66 238 252 204 221 18 92 159 92 48 42 128 129 129 190 216 19 63 124 60 180 228 211 53 184 61 26 18 50 110 211 139 199 12 112 186 237 2 71 15 119 0 18 37 197 65 42 171 34 140 175 42 197 244 184 209 84 157 120 178 151 161 225 62 142 29 184 128 87 169 227 174 59 87 74 138 114 253 114 197 168 4 142 226 226 210 162 241 21 53 98 224 114 134 154 41 30 116 197 196 165 234 232 46 55 51 154 38 211 208 56 17 69 86 81 85 23 134 230 121 191 106 129 192 177 115 8 97 227 20 100 186 59 82 252 203 63 223 117 67 193 143 26 0 224 182 219 150 211 51 116 136 210 34 15 170 75 67 150 21 188 70 8 73 82 80 21 23 146 228 66 150 174 20 188 28 28 225 96 21 242 120 204 52 105 93 48 119 246 34 52 237 198 117 178 191 168 78 124 181 93 89 77 70 39 84 142 153 204 122 253 54 54 98 254 159 229 223 42 127 73 251 95 108 18 182 185 23 127 126 182 0 0 0 0 73 69 78 68 174 66 96 130)! !
!DrGIcons class methodsFor: 'accessing'!
eraser
^self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 48 0 0 0 48 16 6 0 0 0 7 146 37 196 0 0 0 6 98 75 71 68 255 255 255 255 255 255 9 88 247 220 0 0 0 9 112 72 89 115 0 0 0 72 0 0 0 72 0 70 201 107 62 0 0 9 239 73 68 65 84 120 218 237 90 91 76 92 85 27 93 231 54 55 152 2 214 182 64 165 23 27 72 109 129 137 144 106 133 146 42 84 45 137 6 155 246 129 55 83 245 193 7 180 49 26 77 154 152 244 197 24 19 125 52 49 233 19 154 152 38 53 40 15 42 38 26 172 166 25 40 49 150 166 173 45 246 70 129 82 58 148 12 12 157 203 185 109 31 190 255 251 247 204 80 34 197 78 161 237 172 4 14 251 156 189 55 103 214 218 123 125 223 222 123 128 60 242 200 35 143 60 242 200 35 143 60 242 200 35 143 60 242 120 152 160 44 245 11 204 135 221 187 119 239 126 249 101 33 250 250 250 250 126 255 125 169 223 6 136 70 163 209 104 84 185 235 124 45 59 1 246 236 217 179 103 223 62 33 82 41 211 92 181 10 168 174 174 174 110 110 6 132 160 31 134 101 89 150 227 0 66 184 174 101 1 182 237 186 174 11 56 142 109 11 1 40 138 108 67 127 187 174 227 200 246 174 75 189 101 223 87 20 69 81 20 192 113 132 72 165 128 174 174 163 71 63 252 48 119 2 168 75 77 56 163 181 181 181 181 181 85 136 222 222 222 222 159 127 6 170 171 107 106 154 155 1 215 101 98 29 199 113 0 203 178 109 38 222 113 232 190 16 146 120 215 117 28 219 166 50 61 183 109 203 146 253 240 53 155 120 134 16 66 8 1 12 14 254 249 231 79 63 229 254 115 47 185 0 7 14 28 56 112 224 128 16 225 112 56 28 14 3 29 29 111 191 221 217 121 59 98 120 36 19 65 92 6 84 85 85 1 85 165 146 162 168 170 166 205 157 49 11 197 216 216 216 216 153 51 192 35 143 148 148 148 151 231 254 243 47 185 0 157 157 157 157 157 157 192 59 239 188 247 222 215 95 203 251 76 164 162 48 181 124 63 243 135 159 26 134 97 80 125 178 16 85 101 97 52 77 215 101 125 22 48 27 60 51 38 39 35 145 75 151 128 141 27 55 109 218 182 237 1 22 160 184 184 184 184 184 88 136 215 94 123 253 245 79 62 1 52 77 81 104 84 51 129 153 126 75 116 166 11 65 53 52 77 211 52 77 122 186 166 209 125 238 135 173 198 117 133 112 221 249 223 103 116 116 100 164 175 15 168 168 168 168 168 173 5 10 11 11 10 124 190 220 243 160 223 107 226 219 219 219 219 219 219 133 16 66 81 54 108 0 86 174 124 244 209 245 235 165 151 43 10 224 186 146 64 121 117 93 46 3 233 22 67 191 229 172 96 233 92 151 37 35 226 89 80 110 37 132 162 0 211 211 211 211 99 99 192 173 91 241 120 44 6 212 214 214 214 110 221 10 152 166 101 217 118 238 249 184 103 51 160 163 163 163 163 163 67 136 158 158 158 158 158 30 250 160 207 62 75 65 147 9 33 106 136 182 116 139 73 31 251 60 19 88 24 38 54 187 44 99 2 205 16 69 81 20 77 227 62 164 48 103 207 158 57 211 211 3 212 215 215 215 191 248 34 160 105 186 174 40 148 101 89 214 3 36 192 241 227 199 143 159 58 5 116 116 188 245 214 225 195 233 132 18 45 76 180 28 201 154 150 62 162 165 167 83 59 69 33 193 164 101 105 26 181 167 145 205 245 185 63 182 42 77 211 117 77 3 70 70 174 94 253 227 15 96 211 166 202 202 167 159 6 130 193 96 176 168 8 72 36 18 9 203 2 226 241 120 124 102 230 1 16 32 20 10 133 154 155 133 216 177 163 169 169 189 29 240 251 3 129 96 48 189 70 118 72 36 33 152 64 77 35 33 184 156 253 92 8 114 255 249 130 43 11 195 87 33 92 55 149 2 70 71 71 71 79 159 6 182 108 121 226 137 237 219 1 211 52 77 74 79 169 159 104 52 26 189 113 227 62 22 96 255 254 253 251 247 239 23 162 170 170 170 170 174 14 40 45 45 43 123 252 241 219 213 204 14 182 50 185 164 17 76 115 68 215 117 157 5 97 43 161 214 50 216 210 58 128 130 45 7 101 238 207 227 209 117 93 7 6 7 7 7 127 252 17 216 182 237 169 167 218 218 50 179 38 0 176 109 219 118 93 224 216 177 95 127 253 226 11 160 178 178 178 178 178 242 62 20 224 220 185 243 231 35 17 160 166 38 20 106 105 89 192 139 252 143 0 182 34 190 74 194 217 162 50 45 137 5 20 130 131 181 140 10 220 175 174 3 215 174 141 141 157 61 11 20 20 20 20 20 21 1 171 87 175 94 189 110 29 165 159 0 144 74 165 82 150 37 189 127 235 214 234 234 93 187 128 129 129 129 129 129 129 187 191 2 206 153 0 85 85 85 85 79 62 41 68 75 75 75 203 171 175 74 11 89 240 11 169 183 15 194 210 146 200 195 179 211 80 77 203 204 154 120 228 235 58 89 207 185 115 231 206 253 242 11 80 87 87 87 183 107 151 252 127 108 57 241 120 60 110 154 192 55 223 28 61 250 193 7 192 198 141 27 54 20 20 0 109 109 109 109 109 109 139 89 210 45 12 119 45 13 13 133 66 161 29 59 132 104 104 104 108 220 183 239 118 94 255 111 200 76 19 21 133 214 5 236 236 186 78 22 98 219 182 109 219 153 158 158 30 140 53 205 48 12 67 182 159 152 24 31 63 127 30 88 183 110 253 250 80 136 250 241 120 0 219 182 44 215 5 18 137 100 50 149 154 155 245 196 98 177 88 52 10 116 119 119 119 119 119 47 227 25 208 212 212 212 244 202 43 66 212 214 134 66 205 205 192 99 143 85 84 108 222 44 159 115 126 47 61 250 118 59 48 115 133 72 183 154 244 167 60 163 116 157 102 134 174 27 70 250 125 190 222 184 49 49 113 225 2 112 226 196 137 19 93 93 64 77 77 77 77 99 163 220 196 75 165 76 211 178 164 245 124 251 109 87 215 193 131 192 206 157 59 119 238 220 41 137 207 245 12 88 180 178 188 146 205 213 139 253 87 172 89 179 102 77 105 41 176 121 243 230 205 47 188 64 155 123 13 13 68 184 227 208 194 43 149 2 174 95 31 31 31 26 2 188 94 143 103 108 12 56 114 228 200 145 175 190 146 196 231 122 6 252 103 11 234 237 125 243 205 131 7 129 217 217 120 60 30 151 158 204 150 192 150 33 199 62 239 241 240 182 175 101 153 102 122 90 73 121 188 162 144 197 112 62 147 93 214 52 42 235 58 197 4 85 165 25 243 238 187 199 143 255 240 3 112 242 228 153 51 167 79 3 207 61 215 210 82 83 35 131 173 244 252 217 217 217 89 224 242 229 75 151 194 97 224 228 201 147 39 143 29 155 75 252 161 67 135 14 29 58 36 4 93 239 190 16 119 44 0 143 252 149 43 11 11 131 65 242 202 217 89 73 168 105 90 86 50 9 88 150 227 88 150 36 84 85 105 133 169 235 114 43 64 8 18 136 77 201 178 136 88 195 0 52 77 8 190 79 2 8 145 105 70 170 74 94 79 105 231 244 116 42 101 154 192 216 216 196 196 245 235 178 150 207 231 245 122 60 210 202 226 241 68 194 52 129 161 161 191 255 254 237 183 249 137 231 114 174 136 95 180 0 140 206 206 189 123 223 120 99 238 72 54 12 195 208 117 32 16 8 4 252 126 34 138 151 246 142 3 24 6 237 78 186 46 29 164 56 14 187 120 230 246 155 16 142 147 190 48 50 12 175 151 219 1 233 231 3 212 239 151 95 14 14 246 247 3 229 229 229 229 229 229 64 36 50 57 57 57 73 239 99 24 178 221 236 108 44 54 53 5 248 253 62 159 162 200 44 39 155 248 92 91 15 99 209 65 152 211 62 30 149 193 96 48 88 88 40 137 103 139 160 92 132 136 231 116 146 218 19 49 154 70 130 249 124 62 159 199 3 148 148 172 88 177 98 5 80 82 82 84 84 84 4 20 23 83 57 24 244 251 3 1 96 197 138 194 194 64 0 8 4 168 126 32 16 8 4 2 64 56 124 241 226 249 243 192 199 31 63 255 252 222 189 233 66 146 101 205 204 204 204 196 227 192 240 240 240 240 224 32 189 175 105 206 13 182 217 214 147 107 1 22 60 3 216 122 250 251 223 127 255 163 143 0 219 166 244 205 113 40 157 99 41 88 16 199 81 85 215 165 160 103 154 116 196 7 0 94 111 230 74 214 182 229 238 165 109 147 69 80 44 201 76 43 29 135 44 200 227 161 25 164 170 126 191 174 3 87 174 68 163 55 111 210 127 86 20 160 162 98 237 218 244 131 148 100 210 52 77 19 152 154 154 154 154 156 36 65 98 177 249 137 191 87 214 115 199 2 52 54 110 223 254 204 51 64 48 232 245 22 20 0 138 226 243 21 22 206 221 26 96 200 147 43 69 73 183 18 0 184 93 125 18 13 176 109 211 164 35 71 110 79 87 185 25 199 91 20 36 208 247 223 247 247 247 246 2 189 189 159 125 246 249 231 128 235 70 163 177 88 186 0 228 249 87 174 92 190 124 226 4 16 14 135 195 223 125 55 63 241 247 202 122 238 88 128 210 82 211 36 34 2 1 159 15 112 28 191 223 48 36 65 138 66 158 205 87 41 4 121 53 91 145 244 122 185 128 250 255 203 232 228 245 148 5 81 16 230 45 6 106 153 254 70 20 188 7 6 134 135 47 92 0 20 133 118 49 45 107 122 122 118 86 214 26 31 191 118 237 175 191 128 181 107 43 42 54 110 4 218 218 86 175 94 14 196 51 22 28 3 182 108 41 45 173 168 32 66 57 173 164 223 68 168 227 144 199 243 209 158 116 123 143 199 235 5 92 151 60 219 117 41 109 116 93 143 71 215 1 199 49 12 143 71 182 119 28 154 31 150 69 177 193 113 232 234 186 30 15 157 245 82 48 22 194 239 247 122 129 161 161 241 241 209 81 192 52 147 201 68 2 152 152 32 171 97 68 34 145 200 197 139 128 101 165 82 67 67 75 239 249 217 88 240 12 176 109 202 227 109 155 22 48 201 228 212 212 244 52 61 35 139 161 145 234 186 84 143 13 71 211 232 32 132 211 80 222 163 231 153 160 170 180 53 144 157 231 243 186 129 251 179 109 90 185 242 174 102 60 78 49 163 189 189 190 190 161 1 184 121 115 98 226 198 13 96 102 38 22 75 183 160 178 178 178 50 85 93 62 158 191 104 1 70 70 110 222 140 68 104 223 60 145 144 249 59 125 101 132 238 155 38 144 76 38 147 201 36 221 231 44 136 199 149 16 128 174 123 60 134 33 133 224 249 194 66 102 30 35 146 240 188 14 224 5 89 122 12 73 36 40 200 143 143 15 15 95 189 10 148 148 148 148 148 148 200 231 255 70 252 82 89 207 29 11 224 243 145 149 156 58 53 58 58 50 2 172 90 101 24 100 45 252 61 155 204 19 42 199 225 163 196 116 138 129 84 138 206 90 169 13 45 184 210 219 101 7 95 69 161 172 135 173 143 131 176 215 75 11 172 91 183 82 169 68 2 8 4 10 11 11 10 128 151 94 58 124 248 211 79 229 23 169 150 43 241 140 59 126 129 229 190 7 180 80 226 115 189 197 144 51 100 239 14 222 239 229 251 22 75 77 220 67 75 124 54 150 154 200 135 150 248 60 242 200 35 143 60 242 200 35 143 60 242 88 60 254 1 118 124 0 146 139 47 157 2 0 0 0 0 73 69 78 68 174 66 96 130)! !
!DrGIcons class methodsFor: 'accessing' stamp: 'hlsf 2/11/2022 21:40:33'!
forms
^ forms ifNil: [forms _ Dictionary new]! !
!DrGIcons class methodsFor: 'accessing'!
freePoint
^self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 48 0 0 0 48 16 6 0 0 0 7 146 37 196 0 0 0 6 98 75 71 68 255 255 255 255 255 255 9 88 247 220 0 0 0 9 112 72 89 115 0 0 0 72 0 0 0 72 0 70 201 107 62 0 0 0 174 73 68 65 84 120 218 237 215 65 10 131 48 16 5 80 45 61 128 11 23 222 255 162 118 81 178 104 48 104 19 219 76 224 189 141 8 46 134 255 157 160 211 4 0 0 0 0 0 0 192 177 125 255 188 142 231 209 123 128 58 227 6 158 123 246 30 224 88 41 224 121 238 61 217 221 6 219 128 111 139 201 159 143 183 57 131 21 112 85 10 58 21 147 223 199 17 180 128 214 160 74 193 219 128 31 41 29 53 241 55 32 220 64 111 173 111 106 252 224 147 96 27 112 53 248 82 160 227 28 61 73 176 2 206 212 6 31 191 136 32 242 63 219 82 96 103 159 151 241 63 63 7 213 26 188 34 110 34 216 191 219 182 117 93 22 193 3 0 0 0 0 64 133 23 160 158 76 100 195 246 158 5 0 0 0 0 73 69 78 68 174 66 96 130)! !
!DrGIcons class methodsFor: 'accessing'!
grid
^ self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 48 0 0 0 48 8 6 0 0 0 87 2 249 135 0 0 0 1 115 82 71 66 0 174 206 28 233 0 0 0 6 98 75 71 68 0 255 0 255 0 255 160 189 167 147 0 0 0 9 112 72 89 115 0 0 11 19 0 0 11 19 1 0 154 156 24 0 0 0 7 116 73 77 69 7 218 8 3 11 29 16 179 58 226 95 0 0 0 90 73 68 65 84 104 222 237 213 177 9 0 49 12 4 65 157 251 239 89 46 193 153 145 96 20 127 50 152 251 77 119 215 230 59 181 252 0 198 1 146 116 146 231 48 166 124 183 254 5 226 47 4 0 0 0 0 160 196 74 108 3 0 0 0 0 74 172 196 54 0 0 0 0 0 160 196 74 108 3 0 0 0 0 74 172 196 54 240 241 46 99 58 68 173 164 85 224 244 0 0 0 0 73 69 78 68 174 66 96 130)! !
!DrGIcons class methodsFor: 'accessing'!
gridMagnet
^ self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 48 0 0 0 48 8 6 0 0 0 87 2 249 135 0 0 0 1 115 82 71 66 0 174 206 28 233 0 0 0 6 98 75 71 68 0 255 0 255 0 255 160 189 167 147 0 0 0 9 112 72 89 115 0 0 11 19 0 0 11 19 1 0 154 156 24 0 0 0 7 116 73 77 69 7 218 8 3 11 34 36 202 80 60 214 0 0 1 137 73 68 65 84 104 222 237 88 61 75 196 64 16 125 147 28 34 34 71 176 241 42 43 197 66 172 82 137 156 133 189 165 246 254 13 91 193 191 97 47 88 9 150 22 126 112 26 56 27 177 136 41 4 17 221 59 44 2 73 33 98 110 45 206 156 146 160 249 48 159 231 76 19 216 12 179 243 102 119 242 222 132 164 148 168 179 41 168 185 49 128 202 1 32 34 73 68 145 141 81 21 191 218 159 0 241 87 136 1 48 0 6 192 0 254 98 141 172 2 9 33 164 227 56 208 52 173 235 175 189 29 237 234 0 240 110 139 68 177 220 27 129 165 253 83 42 148 137 29 199 41 134 184 2 251 134 136 204 127 41 165 164 168 64 223 253 44 203 146 0 208 19 207 35 31 185 185 149 58 81 109 117 14 0 176 124 104 208 111 251 134 174 80 84 226 73 253 178 182 224 190 153 245 128 95 121 227 170 51 90 91 24 12 146 85 93 249 186 209 246 197 3 0 224 100 101 81 2 192 122 199 164 202 107 161 179 86 43 148 140 253 89 132 141 126 159 152 7 242 182 182 16 212 22 130 38 102 167 153 137 75 181 169 249 153 122 3 80 154 147 60 19 215 87 204 101 205 196 121 251 53 170 84 205 219 237 53 9 0 238 245 83 57 114 26 0 84 85 237 122 158 167 3 128 119 188 135 56 114 250 245 254 101 40 191 31 237 225 179 231 142 222 253 196 192 185 244 64 81 146 58 151 19 240 147 55 46 207 117 127 173 185 115 144 58 158 29 83 8 242 72 25 148 211 166 121 151 90 78 199 189 247 99 117 2 153 141 148 101 249 241 223 105 150 211 12 128 1 48 0 6 48 94 0 120 38 102 38 254 103 61 240 1 57 113 219 42 89 173 167 92 0 0 0 0 73 69 78 68 174 66 96 130)! !
!DrGIcons class methodsFor: 'accessing'!
group
^self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 24 0 0 0 24 8 2 0 0 0 111 21 170 175 0 0 0 9 112 72 89 115 0 0 11 19 0 0 11 19 1 0 154 156 24 0 0 1 13 73 68 65 84 56 203 173 85 65 106 133 48 20 156 212 224 33 220 231 44 66 90 193 75 40 180 123 93 181 171 118 231 82 104 241 30 173 224 70 240 28 185 129 17 92 199 77 186 248 16 196 95 53 166 153 85 120 129 121 147 153 199 11 209 90 195 7 40 128 199 231 119 66 136 51 133 214 250 231 235 141 2 32 132 124 127 190 58 19 61 189 124 0 120 128 39 80 115 202 243 124 28 199 101 89 76 37 8 130 40 138 154 166 185 70 36 165 172 170 138 49 102 42 66 136 162 40 46 43 82 74 173 89 0 48 198 140 192 44 203 164 148 7 122 169 101 195 105 154 142 245 218 154 125 172 215 103 106 187 68 125 223 167 105 10 128 115 206 57 7 144 36 73 215 117 231 102 111 80 215 245 159 166 196 113 124 162 40 12 67 33 132 189 41 187 138 230 121 46 203 82 41 245 223 201 30 134 97 125 113 243 229 0 66 8 74 233 185 71 123 48 13 40 165 235 157 113 153 168 109 219 107 241 123 155 163 77 136 247 166 216 206 209 125 136 27 83 108 137 54 33 186 63 205 101 142 180 214 183 189 235 188 252 1 16 95 223 209 47 26 227 127 226 181 183 68 199 0 0 0 0 73 69 78 68 174 66 96 130)! !
!DrGIcons class methodsFor: 'accessing' stamp: 'hlsf 2/11/2022 21:41:38'!
hatchForm
^ self forms
at: #hatch
ifAbsentPut: [Form
extent: 8@8
depth: 1
fromArray: #( 4026531840 4026531840 4026531840
4026531840 251658240 251658240 251658240 251658240)
offset: 0@0]! !
!DrGIcons class methodsFor: 'accessing'!
help
^ self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 48 0 0 0 48 8 6 0 0 0 87 2 249 135 0 0 0 4 115 66 73 84 8 8 8 8 124 8 100 136 0 0 0 9 112 72 89 115 0 0 13 215 0 0 13 215 1 66 40 155 120 0 0 0 25 116 69 88 116 83 111 102 116 119 97 114 101 0 119 119 119 46 105 110 107 115 99 97 112 101 46 111 114 103 155 238 60 26 0 0 0 18 116 69 88 116 84 105 116 108 101 0 72 101 108 112 32 66 114 111 119 115 101 114 107 56 239 133 0 0 0 23 116 69 88 116 65 117 116 104 111 114 0 84 117 111 109 97 115 32 75 117 111 115 109 97 110 101 110 26 211 135 76 0 0 0 24 116 69 88 116 67 114 101 97 116 105 111 110 32 84 105 109 101 0 50 48 48 53 45 49 49 45 48 54 53 58 0 201 0 0 0 24 116 69 88 116 83 111 117 114 99 101 0 104 116 116 112 58 47 47 116 105 103 101 114 116 46 99 111 109 22 191 81 211 0 0 0 73 116 69 88 116 67 111 112 121 114 105 103 104 116 0 80 117 98 108 105 99 32 68 111 109 97 105 110 32 104 116 116 112 58 47 47 99 114 101 97 116 105 118 101 99 111 109 109 111 110 115 46 111 114 103 47 108 105 99 101 110 115 101 115 47 112 117 98 108 105 99 100 111 109 97 105 110 47 89 195 254 202 0 0 13 76 73 68 65 84 104 129 213 90 125 116 85 85 118 255 237 115 238 203 75 222 203 247 7 9 65 72 72 248 16 12 132 96 4 65 200 32 148 113 144 48 56 56 51 107 141 22 91 90 101 141 157 50 51 178 90 109 97 254 104 103 181 56 214 214 25 203 178 44 173 51 213 177 29 187 6 5 20 5 21 21 16 197 65 62 4 34 68 49 36 33 49 137 249 126 121 121 121 95 185 231 156 254 113 63 222 189 47 121 68 43 107 102 205 89 107 175 115 242 238 125 231 252 126 123 239 179 207 62 251 133 148 82 248 99 110 236 15 13 224 171 182 63 122 2 218 181 154 168 98 221 35 213 144 248 54 160 22 129 80 10 69 147 20 33 11 74 17 129 130 32 234 129 82 157 0 62 0 195 11 205 251 31 58 119 45 214 165 175 178 7 166 175 221 177 128 24 251 129 82 248 214 244 210 130 180 213 55 207 240 207 155 57 153 21 230 250 81 148 231 71 97 174 15 0 208 31 8 163 55 48 130 190 193 17 52 52 117 203 67 191 187 52 210 220 209 31 39 98 123 149 212 159 104 121 117 219 217 223 43 129 138 181 255 92 6 240 199 139 242 253 127 178 177 190 214 183 242 166 74 170 152 146 15 208 23 159 163 165 99 0 135 79 54 171 103 95 57 21 238 29 8 189 165 4 126 212 114 240 239 90 191 44 150 47 69 96 230 237 59 189 130 133 31 245 165 167 109 218 124 231 98 223 198 250 26 150 225 245 184 222 137 197 117 244 5 194 232 31 50 180 78 32 20 230 250 76 241 35 205 195 93 239 71 99 58 254 251 192 135 242 201 221 239 71 70 162 241 103 185 244 111 253 244 192 150 216 53 39 80 177 126 71 49 116 126 104 205 242 235 103 109 255 203 91 189 249 57 62 251 89 87 239 48 142 157 189 130 247 27 218 112 161 185 23 128 2 17 129 64 46 171 16 8 115 43 138 176 100 222 84 220 82 61 13 147 11 179 236 103 131 193 8 118 252 234 112 236 213 119 26 47 129 139 213 205 47 109 235 190 102 4 42 214 236 152 79 26 123 227 71 119 45 47 188 111 195 34 78 100 160 234 234 27 198 127 189 124 6 135 79 55 131 136 192 136 129 24 129 8 46 2 22 7 99 41 101 247 95 91 56 29 247 172 93 128 146 130 76 251 249 47 247 158 148 63 255 205 59 125 106 84 172 110 62 184 237 252 87 38 80 177 102 199 252 244 12 239 177 71 31 88 155 189 106 209 12 128 0 93 72 60 189 239 20 246 29 109 132 148 10 140 49 48 70 96 68 32 98 96 204 32 0 24 100 236 166 0 101 18 80 74 65 41 5 70 132 117 117 179 177 169 190 6 156 27 81 253 200 169 102 108 125 236 149 96 116 36 186 124 34 18 87 37 48 243 246 135 139 36 167 134 127 127 240 142 98 11 124 32 24 193 63 60 245 54 46 180 244 130 91 192 237 222 34 145 16 92 141 128 84 144 74 65 74 137 57 229 69 216 190 169 14 57 89 233 54 137 31 60 188 183 155 9 57 239 211 3 127 223 155 10 99 202 131 172 182 246 41 143 78 134 219 88 224 155 59 6 112 255 207 94 198 197 214 94 104 156 129 107 12 154 198 161 217 253 248 226 49 37 121 236 148 79 218 250 241 227 159 31 68 107 103 0 0 176 162 182 2 15 252 233 215 138 4 99 111 212 214 62 229 73 133 51 37 129 129 146 129 199 110 95 126 253 156 251 54 44 226 150 230 183 63 113 8 253 193 8 56 231 224 156 67 227 28 26 119 128 231 110 208 90 18 88 23 112 235 93 206 236 121 6 135 163 248 199 167 143 96 40 20 5 0 220 123 71 45 171 175 155 59 103 160 100 224 177 84 56 199 117 161 202 111 62 50 45 35 205 115 241 141 93 247 250 243 115 124 208 133 196 223 252 226 32 46 182 244 154 192 25 56 103 134 11 89 61 35 20 231 103 98 214 180 2 44 152 89 140 226 124 63 178 124 105 240 104 28 163 186 192 208 72 12 189 131 97 188 123 190 29 23 91 251 32 133 130 84 18 82 42 72 169 32 164 132 20 18 66 74 92 95 86 136 127 250 254 74 112 206 16 24 142 98 245 247 159 26 9 133 226 85 227 157 19 227 166 18 74 168 199 54 223 121 115 134 21 42 127 185 239 20 46 54 247 130 107 14 240 156 131 51 139 8 225 167 155 87 160 48 39 3 62 47 135 71 99 176 34 149 213 79 46 240 99 246 212 60 84 207 152 132 222 161 8 158 121 245 60 90 187 2 144 164 32 73 130 8 16 0 64 192 199 87 250 240 235 3 231 240 23 235 106 144 155 149 142 251 191 179 52 227 95 127 125 244 23 0 238 152 208 133 102 212 239 168 42 202 207 188 109 99 125 13 3 140 80 185 239 104 163 173 105 3 52 55 128 107 204 220 11 28 133 57 25 200 240 40 48 82 118 132 177 54 50 99 198 50 74 41 248 188 12 101 147 252 248 171 13 11 49 41 223 15 77 51 190 207 121 194 181 56 103 56 112 252 83 124 62 48 2 2 112 215 154 5 172 56 63 115 213 244 181 59 22 76 72 64 64 219 178 177 254 70 191 117 194 62 179 255 12 164 130 173 109 155 8 55 193 155 123 1 148 208 182 165 121 11 60 37 69 38 41 37 10 178 210 176 233 246 106 219 37 19 150 53 68 41 224 55 175 27 17 52 195 171 225 207 190 89 235 39 210 238 159 144 0 65 109 88 121 83 37 1 198 9 123 248 116 139 17 38 185 225 231 214 2 26 99 224 140 219 127 147 25 47 57 231 8 199 37 130 17 29 109 61 33 116 15 70 48 28 30 117 175 65 4 41 5 38 23 250 145 238 245 24 22 213 18 115 89 243 190 119 174 13 159 15 132 0 0 183 222 84 73 4 181 33 25 175 107 15 84 172 123 164 186 188 52 207 91 113 93 62 0 224 221 115 87 192 200 240 113 67 152 219 18 60 97 9 198 8 81 29 104 184 210 135 195 31 126 134 158 64 24 74 1 68 192 226 185 147 113 199 210 74 104 238 52 8 68 64 105 97 38 218 123 130 32 1 64 25 162 184 225 110 82 41 156 248 168 3 235 235 102 163 124 114 46 166 95 87 224 173 88 247 72 181 51 21 119 89 128 20 54 124 125 201 44 59 201 121 191 161 221 113 80 89 86 48 45 193 156 38 231 56 120 162 21 59 247 156 197 243 111 125 130 158 64 24 140 18 225 181 189 59 132 232 168 176 247 134 21 249 8 128 144 176 35 90 194 2 100 127 118 178 177 211 198 247 141 91 102 251 160 212 157 41 45 160 136 22 86 205 40 225 0 16 31 21 184 216 210 107 107 215 18 62 6 188 33 239 95 232 116 0 72 16 37 2 110 153 55 5 62 47 55 85 156 104 186 4 2 161 24 56 227 0 55 13 160 20 24 83 96 74 129 49 194 165 182 126 196 71 5 210 60 28 85 149 37 156 136 22 59 231 112 239 1 165 166 22 229 249 1 0 125 1 35 2 24 73 154 145 168 49 98 9 107 140 99 9 141 59 15 51 6 143 198 177 106 225 52 44 168 44 0 65 185 44 64 196 208 212 17 176 191 203 44 205 187 44 109 4 128 254 96 4 0 80 152 231 3 64 165 169 9 0 197 9 2 97 51 138 16 136 185 173 144 144 196 98 201 22 209 56 199 218 155 167 99 201 156 98 104 204 13 158 115 142 158 224 40 222 56 213 62 174 213 24 37 132 136 48 96 17 200 245 3 80 147 82 187 16 144 83 96 30 94 253 67 17 51 53 78 76 100 247 99 92 106 172 37 234 230 151 162 170 44 23 156 164 43 251 36 34 12 69 36 94 60 118 25 186 149 201 154 238 146 44 100 246 131 65 35 181 200 207 206 128 146 42 59 37 129 100 31 77 196 110 115 108 77 236 112 43 74 114 43 206 25 230 150 231 163 118 86 33 24 4 164 116 207 55 20 145 120 225 88 11 66 81 29 156 49 40 110 68 27 198 12 33 166 192 152 116 41 204 149 209 18 185 64 186 163 16 104 168 127 40 108 154 203 103 239 1 155 4 220 7 18 141 163 53 206 24 230 149 231 195 67 114 76 212 9 197 129 125 191 107 67 48 50 234 216 228 110 119 97 4 247 26 100 104 30 48 110 109 68 52 156 146 0 128 238 190 65 147 64 142 47 113 178 218 147 186 45 147 188 24 51 73 77 202 77 135 174 235 144 82 58 8 48 156 110 234 71 40 170 143 235 42 46 75 35 161 121 2 217 4 250 2 97 16 208 147 218 2 68 237 125 129 17 131 64 158 15 26 103 182 230 93 68 204 177 245 132 28 68 52 206 0 16 4 121 160 195 3 29 26 116 104 24 85 12 67 97 221 21 93 108 65 2 188 117 7 181 214 229 156 161 32 59 3 0 161 127 40 12 5 213 233 196 236 222 3 74 157 185 112 185 123 205 202 69 149 60 77 227 152 91 81 132 198 214 126 216 120 157 68 144 68 196 92 84 74 224 185 183 155 224 77 211 224 209 52 251 48 19 66 34 20 137 27 86 130 3 172 169 128 132 22 221 46 63 187 172 0 30 143 113 72 92 184 220 45 148 82 39 82 18 80 132 61 175 29 255 228 129 45 223 91 154 5 0 139 230 94 103 19 24 219 148 123 203 43 35 4 48 34 220 181 162 18 30 205 121 169 55 250 215 78 119 162 107 32 236 248 222 56 215 217 164 143 22 206 42 177 199 7 222 109 12 131 232 69 231 115 151 11 53 239 127 232 92 107 199 64 172 181 115 16 0 176 248 134 41 32 115 70 163 144 96 142 149 99 29 43 68 90 12 160 224 225 4 21 15 67 141 134 161 226 97 200 248 8 32 116 48 34 72 229 60 19 156 223 119 84 45 204 49 65 97 225 108 131 64 91 119 0 205 159 13 196 146 75 146 99 178 81 5 218 115 228 84 179 2 128 146 130 76 44 91 80 102 71 17 235 168 7 220 149 5 11 140 52 19 48 235 61 231 38 86 74 65 72 5 41 18 183 48 43 97 75 108 116 107 94 99 181 197 55 76 129 117 176 30 61 221 162 20 97 79 50 222 49 4 24 244 157 207 190 124 106 36 26 215 1 0 119 125 125 158 17 175 147 192 90 99 11 128 148 210 22 56 192 91 159 41 40 8 41 32 132 132 16 137 119 149 52 8 41 7 41 165 20 56 99 216 176 226 122 0 70 181 239 87 123 63 24 81 66 223 53 33 129 166 87 182 125 212 51 24 122 253 127 95 111 144 0 80 156 239 199 154 165 51 220 154 118 46 104 246 182 8 105 150 78 146 5 16 186 132 110 222 123 133 144 16 210 180 138 83 17 102 191 242 198 50 187 56 188 251 205 143 100 207 224 240 91 227 21 129 199 175 74 16 182 254 199 111 223 139 12 141 24 37 202 187 111 155 135 89 211 10 220 26 119 138 169 77 33 36 116 41 49 170 43 48 111 38 40 205 15 102 10 72 67 52 62 10 93 8 8 93 216 36 18 150 75 40 164 178 52 23 27 86 204 6 0 12 143 196 176 243 249 99 17 49 170 126 60 46 212 84 133 173 138 250 127 217 185 254 214 27 238 123 120 203 109 94 2 48 52 18 195 79 158 60 140 224 72 124 108 237 199 170 84 88 183 42 150 168 84 56 83 1 171 152 37 164 65 90 23 18 66 8 232 186 213 11 100 102 120 176 237 158 37 200 242 121 1 165 240 147 93 135 98 123 223 108 248 207 166 253 15 110 25 15 103 202 186 80 254 231 185 91 95 58 114 161 241 217 87 206 8 0 200 201 76 199 223 222 189 20 121 89 233 14 151 73 148 66 12 141 10 8 11 140 16 24 213 13 80 99 196 4 43 132 176 173 32 132 68 182 63 13 127 125 231 141 200 246 121 1 0 207 29 56 39 247 188 217 208 152 219 149 187 53 21 206 9 75 139 74 99 13 187 182 127 187 184 174 166 12 32 66 112 36 134 157 187 79 226 114 103 192 204 253 173 139 189 153 215 59 181 207 18 167 172 21 134 165 2 148 148 182 21 132 105 133 242 146 28 220 183 174 26 89 190 52 40 0 199 207 183 97 243 79 119 119 99 84 92 181 180 248 133 138 187 25 254 244 99 143 63 184 62 123 121 77 57 0 64 8 137 23 14 55 226 237 51 109 0 144 84 39 50 239 9 148 32 224 114 33 147 128 85 204 2 1 117 243 175 195 250 101 51 193 25 153 224 219 177 229 103 123 131 225 80 228 171 21 119 173 86 190 106 251 66 205 159 125 240 193 63 95 89 120 79 125 13 179 146 188 190 64 24 251 222 185 132 83 31 119 37 46 54 142 203 79 242 111 4 174 16 44 37 106 102 21 99 237 146 74 20 230 100 152 207 129 255 121 237 156 124 248 233 67 253 145 254 246 245 29 199 159 56 169 148 210 255 223 4 136 136 3 200 0 144 158 59 125 217 148 188 57 223 120 254 91 171 22 84 62 180 105 69 90 78 102 186 253 94 95 32 140 15 47 117 227 124 115 15 90 186 130 70 174 99 222 172 224 112 33 2 48 125 114 14 170 42 10 81 93 57 201 6 14 24 65 226 209 103 142 198 95 60 116 166 165 175 225 165 141 193 246 147 93 0 162 0 34 0 162 74 41 241 165 8 16 17 51 193 103 0 72 7 144 225 241 228 102 150 44 219 252 80 110 65 201 186 31 222 93 151 254 221 213 85 204 155 102 164 83 86 2 22 215 5 2 161 24 134 66 49 4 66 81 0 132 220 76 175 41 233 240 104 238 184 17 27 21 216 253 230 5 249 248 115 71 98 131 253 157 7 187 142 61 249 111 186 62 60 236 4 111 246 97 53 14 216 171 17 208 156 224 157 100 50 75 231 151 23 204 89 251 195 210 210 210 154 123 191 179 212 91 87 83 78 83 139 115 92 68 38 106 159 245 4 113 236 108 171 122 242 183 239 197 59 58 58 206 247 95 120 117 215 200 231 13 173 73 160 35 142 191 195 227 89 225 106 4 40 9 124 186 163 79 7 144 158 93 190 116 110 78 217 162 117 30 127 209 226 202 169 69 158 250 21 85 105 85 51 74 88 65 142 15 5 57 25 200 53 127 172 8 12 71 49 16 140 160 127 40 140 143 154 122 228 254 35 231 227 151 219 123 244 248 112 207 201 161 43 39 14 12 95 57 241 177 9 210 146 72 210 216 114 163 47 110 129 36 18 78 241 58 122 75 210 178 203 111 158 229 159 92 189 204 235 207 159 201 52 111 30 152 150 13 112 211 201 69 20 74 15 42 61 54 24 13 245 55 133 58 207 30 31 190 242 65 19 128 56 128 152 217 71 205 113 204 49 182 8 196 198 3 63 33 129 20 68 210 44 208 14 241 192 184 91 88 194 97 28 146 73 63 48 65 194 168 162 235 14 137 3 24 53 123 139 144 77 36 21 240 47 69 32 137 12 51 1 91 36 146 129 91 224 83 17 176 72 56 137 56 9 140 42 165 28 181 140 9 240 92 139 127 183 49 45 196 198 1 111 141 45 224 201 36 228 68 26 158 168 253 31 117 83 9 157 111 115 43 45 0 0 0 0 73 69 78 68 174 66 96 130)! !
!DrGIcons class methodsFor: 'accessing'!
intersection
^ self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 48 0 0 0 48 16 6 0 0 0 7 146 37 196 0 0 0 6 98 75 71 68 255 255 255 255 255 255 9 88 247 220 0 0 0 9 112 72 89 115 0 0 0 72 0 0 0 72 0 70 201 107 62 0 0 11 48 73 68 65 84 120 218 237 91 91 76 84 231 22 94 123 102 24 174 51 80 112 0 47 132 80 165 197 20 4 163 216 24 19 53 68 171 181 1 155 244 73 49 177 16 105 26 193 32 134 6 212 86 130 137 138 66 50 76 100 30 154 84 211 135 19 209 135 182 52 37 16 155 166 218 23 99 172 161 42 180 160 92 172 145 84 164 168 204 48 195 48 215 125 30 214 249 206 150 61 103 156 97 152 1 60 229 123 217 217 123 246 236 203 250 254 127 253 107 125 107 109 162 69 252 147 32 138 243 253 4 11 13 138 249 126 128 127 58 22 9 152 103 44 18 48 207 152 49 1 54 91 101 101 101 101 160 190 28 231 201 207 247 117 124 17 62 241 211 79 25 25 25 25 162 216 223 159 153 153 153 41 138 179 35 98 209 240 128 16 232 137 31 127 172 209 104 52 162 184 111 223 146 37 75 150 16 165 167 171 84 42 21 209 138 21 187 118 237 218 69 20 29 109 48 24 12 130 143 235 249 50 184 224 243 254 63 252 112 246 236 217 179 162 168 213 62 125 250 244 41 81 92 220 179 103 207 158 17 69 69 77 76 76 76 16 69 68 76 77 77 77 17 41 20 110 183 219 77 228 241 40 149 74 37 145 211 25 21 21 21 69 100 179 105 52 26 13 145 197 146 152 152 152 72 100 54 167 166 166 166 18 21 21 213 212 212 212 8 1 191 247 130 33 32 180 68 120 255 254 203 47 71 142 28 57 34 138 201 201 131 131 131 131 146 129 67 13 135 35 50 50 50 146 104 100 36 35 35 35 131 168 160 224 85 207 27 126 4 124 227 61 123 246 236 217 179 71 20 91 91 91 91 91 91 5 97 118 68 0 210 204 24 24 216 177 99 199 14 239 51 94 188 224 17 254 244 169 203 229 114 17 141 141 241 214 100 242 120 60 30 34 149 138 207 211 106 21 10 133 130 40 37 133 159 35 53 53 34 34 34 130 40 42 138 143 3 10 31 171 222 208 80 86 86 86 22 209 123 239 205 45 33 126 111 36 55 124 176 68 124 243 141 193 96 48 136 226 71 31 85 86 86 86 122 223 167 167 103 251 246 237 219 137 254 250 203 233 116 58 137 6 7 29 14 135 131 232 201 19 222 55 153 216 165 136 34 111 93 174 232 232 232 104 34 183 91 173 86 171 137 212 106 187 221 110 39 138 142 230 153 19 31 63 57 57 57 73 148 158 206 251 105 105 76 136 78 199 207 167 82 9 194 203 102 6 49 47 94 104 181 90 45 209 253 251 235 214 173 91 71 180 111 95 109 109 109 109 248 8 9 122 6 248 34 226 235 175 217 71 203 241 224 1 19 242 214 91 29 29 29 29 222 191 55 55 111 220 184 113 35 209 240 48 143 88 155 77 167 211 233 136 236 118 54 136 219 205 62 30 80 169 96 72 222 42 149 252 187 32 176 97 69 81 20 69 145 72 161 96 98 52 154 177 177 177 49 162 204 76 147 201 100 34 122 231 29 190 79 124 252 244 235 130 8 183 155 127 191 125 59 47 47 47 143 168 184 248 204 153 51 103 66 79 196 140 47 232 143 8 62 43 240 40 231 243 207 243 243 243 243 137 158 63 95 182 108 217 50 162 169 169 164 164 164 164 151 13 200 134 128 161 35 35 217 135 199 198 198 198 198 198 74 251 216 226 124 143 135 93 148 221 206 4 96 59 53 197 51 34 37 229 241 227 199 143 137 222 125 247 249 243 231 207 137 116 58 38 66 173 158 238 178 108 54 190 206 173 91 185 185 185 185 68 101 101 77 77 77 77 161 35 34 232 11 189 154 136 192 175 243 233 167 197 197 197 197 68 118 59 187 18 32 42 138 163 25 181 154 143 107 52 236 122 180 90 158 17 209 209 236 130 14 29 58 116 232 208 33 255 6 57 127 254 252 249 243 231 69 17 4 88 173 86 171 213 74 36 8 28 101 173 94 253 240 225 195 135 68 89 89 188 230 96 237 240 120 120 32 140 140 48 17 191 253 182 126 253 250 245 68 85 85 13 13 13 13 179 39 98 214 23 144 19 113 231 206 222 189 123 247 138 98 94 222 165 75 151 46 249 255 127 73 73 73 73 73 137 52 194 49 130 221 110 54 68 106 42 135 143 216 86 84 84 84 84 84 132 110 4 234 245 122 189 94 47 138 102 51 207 132 188 188 158 158 158 30 162 183 223 102 130 20 10 118 105 14 7 19 112 231 14 175 37 143 30 109 218 180 105 19 209 241 227 199 143 31 63 30 252 243 132 236 69 174 95 175 174 174 174 22 197 21 43 186 187 187 187 137 86 173 186 122 245 234 213 192 255 95 89 201 139 179 201 196 62 26 68 164 167 167 167 167 167 19 213 213 213 213 213 213 133 63 58 105 108 60 125 250 244 105 81 220 188 249 214 173 91 183 136 146 146 108 54 155 141 200 227 225 223 39 38 120 96 92 191 206 65 135 203 181 118 237 218 181 68 53 53 193 229 23 33 211 130 130 53 60 96 48 24 12 6 131 228 171 225 195 205 102 179 217 108 38 106 108 108 108 108 108 12 127 6 253 217 103 199 142 29 59 38 8 191 255 206 62 95 14 141 134 215 138 244 244 39 79 158 60 33 178 90 71 71 71 71 137 154 155 155 155 155 155 103 254 124 179 38 0 9 84 160 134 47 43 43 43 43 43 243 62 206 18 7 209 197 139 201 201 201 201 210 12 152 156 228 112 210 102 227 145 56 87 40 45 173 175 175 175 23 132 251 247 87 173 90 181 202 59 127 64 190 161 84 14 13 13 13 17 141 143 143 143 143 143 207 252 62 179 38 0 153 171 255 23 42 45 45 45 37 234 235 235 235 235 235 147 142 115 248 74 244 232 17 39 88 195 195 28 166 26 141 124 28 139 111 76 76 76 76 76 76 152 173 254 63 240 193 7 70 163 209 40 8 54 27 162 44 62 142 168 73 167 227 181 3 51 181 169 169 169 169 169 41 240 153 16 52 1 208 106 252 73 6 88 100 123 123 123 123 123 123 137 214 172 89 179 102 205 26 162 252 124 14 63 223 120 227 192 129 3 7 136 254 245 47 142 211 229 68 212 215 179 75 170 174 174 174 174 174 158 63 201 96 120 120 229 202 149 43 95 50 220 127 22 231 196 68 142 146 148 74 118 69 22 139 197 98 177 4 126 221 160 9 128 72 6 252 250 235 182 109 219 182 17 157 56 193 134 45 43 219 191 127 255 126 41 49 202 206 206 206 206 206 38 234 234 234 234 234 234 34 218 178 101 203 150 45 91 136 250 251 251 251 251 251 137 56 129 19 4 95 68 204 76 125 13 61 222 127 95 175 215 235 189 7 0 102 130 74 197 193 3 194 219 64 215 132 160 9 128 58 9 64 171 153 152 136 143 143 143 39 114 185 166 39 80 9 9 9 9 9 9 68 133 133 133 133 133 133 68 3 3 3 3 3 3 68 237 237 237 237 237 237 82 30 177 208 137 120 246 44 37 37 37 69 114 69 90 45 18 56 94 171 144 103 96 27 54 2 32 11 3 16 201 60 158 184 184 184 56 105 228 35 97 210 233 88 90 56 118 140 163 140 182 182 182 182 182 54 239 76 122 161 19 97 54 51 1 64 76 12 191 167 82 201 174 210 233 100 237 42 236 4 200 125 63 212 73 232 241 208 102 176 120 130 8 57 124 73 26 11 149 8 171 149 227 127 201 14 60 211 5 129 159 11 9 36 194 233 150 150 150 150 150 22 223 207 23 52 1 40 132 0 144 133 161 78 202 181 27 127 146 193 235 66 196 135 31 202 19 46 94 132 69 145 7 32 242 23 151 11 30 129 247 67 78 0 42 80 0 244 120 200 194 136 227 161 229 4 138 133 78 196 247 223 159 59 119 238 156 116 125 135 131 9 192 154 7 17 17 51 33 108 4 56 157 60 178 1 36 38 208 227 65 0 92 209 76 177 80 137 208 104 56 238 7 172 86 16 192 239 15 128 8 127 8 154 0 155 141 85 73 0 21 40 20 66 192 188 191 17 240 186 17 161 213 142 140 140 140 72 251 38 19 223 207 233 156 62 211 17 132 132 141 0 20 187 1 200 183 168 64 41 149 92 209 194 98 52 91 44 20 34 18 18 88 3 2 70 71 217 213 56 157 92 159 248 175 97 21 88 156 95 77 68 208 4 152 76 211 195 49 0 165 63 84 160 64 0 244 248 215 149 136 159 127 174 173 173 173 149 254 103 183 243 204 70 9 213 110 231 104 15 6 199 26 224 207 21 5 77 192 238 221 92 43 69 151 129 164 145 176 47 68 233 15 34 90 160 113 241 66 37 162 160 160 161 161 161 65 82 123 145 120 254 253 55 27 220 110 231 25 128 232 15 4 32 47 8 57 1 0 218 59 0 20 187 81 115 77 77 29 30 30 30 150 82 244 80 99 110 136 240 254 125 96 128 93 236 228 228 244 18 170 188 54 29 54 23 4 248 234 171 65 177 27 53 87 148 254 80 129 154 27 34 164 138 157 47 34 184 107 67 110 104 81 252 246 219 87 63 231 159 127 50 1 14 7 175 133 48 52 124 127 68 4 187 98 127 97 120 200 212 197 31 127 228 145 244 230 155 44 55 35 242 65 41 239 143 63 152 144 190 190 13 27 54 108 32 58 113 226 228 201 147 39 195 173 110 250 238 200 243 215 197 225 11 122 61 119 111 60 120 192 25 241 212 20 111 97 112 108 147 147 185 174 225 175 146 23 178 138 24 26 154 208 87 131 53 1 93 6 40 118 231 230 114 229 12 165 191 153 25 114 166 91 223 215 195 140 152 233 123 14 13 241 136 134 225 49 242 33 185 204 180 126 17 242 246 116 52 52 161 175 6 64 152 138 98 55 106 174 23 47 214 213 213 213 249 51 24 12 53 211 173 239 235 193 53 125 247 93 115 115 115 115 224 239 103 179 45 93 186 116 233 203 239 197 218 23 164 7 172 117 216 159 115 2 208 73 134 134 38 244 213 160 189 3 133 12 20 187 55 111 190 121 243 230 77 162 246 246 131 7 15 30 12 151 132 32 17 3 195 127 242 73 90 90 90 26 81 78 78 103 103 103 103 224 87 250 234 171 203 151 47 95 246 238 87 66 233 20 97 55 154 11 252 173 121 97 251 64 3 157 100 104 104 66 95 13 214 4 172 17 216 102 101 113 105 179 187 187 168 168 168 72 20 59 59 171 170 170 170 102 75 136 52 19 16 199 127 241 5 90 21 239 222 189 123 55 248 38 130 11 23 46 92 184 112 65 42 69 202 219 106 16 118 251 171 101 207 89 137 79 175 103 3 232 116 247 238 221 187 71 180 122 53 71 17 232 50 0 124 53 207 162 16 2 61 126 114 146 125 240 238 221 172 78 66 36 131 86 3 201 64 158 185 2 129 26 30 53 107 249 98 205 225 43 81 77 13 207 108 52 140 97 6 32 250 89 178 132 159 179 170 170 170 170 170 202 219 53 206 121 141 245 212 169 83 167 78 157 18 197 168 40 94 140 209 222 1 49 15 37 62 184 42 127 196 4 10 100 174 72 160 10 10 174 93 187 118 205 247 249 185 185 60 115 151 47 95 190 124 249 114 162 142 14 206 27 248 67 21 239 38 228 47 191 228 227 24 249 144 225 125 25 126 222 8 0 206 158 229 162 62 250 106 208 222 129 46 3 20 187 65 8 74 127 168 64 161 16 2 61 30 178 48 212 73 136 100 208 106 32 25 140 141 241 255 206 157 187 113 227 198 13 239 231 66 179 64 78 78 78 78 78 14 81 119 55 15 20 16 226 114 93 185 114 229 10 209 236 218 242 23 0 1 0 138 215 232 171 129 79 69 151 1 138 221 168 185 162 244 135 10 20 10 33 208 227 33 11 187 92 60 2 29 14 14 7 161 213 64 50 144 55 255 34 126 71 229 14 134 223 186 117 235 214 173 91 137 110 222 228 96 97 231 206 157 59 119 238 36 186 125 251 232 209 163 71 103 79 132 202 191 137 194 139 195 135 15 31 62 124 88 122 80 244 213 88 44 236 83 17 214 89 44 60 181 161 173 200 11 30 190 68 47 121 134 170 86 243 76 130 193 17 70 202 227 120 142 94 4 33 49 49 49 49 49 81 20 209 60 16 23 23 23 23 23 39 138 151 47 191 156 71 72 223 71 176 179 146 36 14 127 68 204 251 12 240 7 204 16 121 183 1 22 59 196 219 114 245 17 134 135 54 35 47 145 194 240 216 202 7 130 28 193 126 168 146 153 217 223 223 223 255 26 19 224 11 70 163 209 104 52 138 162 220 240 114 2 228 68 148 151 151 151 151 151 7 47 129 204 236 67 149 133 243 49 224 255 29 96 120 95 251 139 152 35 44 26 254 53 199 191 1 200 20 199 16 138 17 10 59 0 0 0 0 73 69 78 68 174 66 96 130)! !
!DrGIcons class methodsFor: 'accessing'!
keep
^self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 48 0 0 0 48 8 6 0 0 0 87 2 249 135 0 0 0 1 115 82 71 66 0 174 206 28 233 0 0 0 6 98 75 71 68 0 255 0 255 0 255 160 189 167 147 0 0 0 9 112 72 89 115 0 0 11 19 0 0 11 19 1 0 154 156 24 0 0 0 7 116 73 77 69 7 219 8 3 7 48 6 165 130 39 32 0 0 10 122 73 68 65 84 104 222 237 153 123 108 92 85 126 199 63 231 220 153 59 47 143 103 252 72 108 39 118 220 96 231 229 216 236 6 26 18 2 41 109 104 96 11 37 2 90 88 22 181 162 149 90 169 42 143 86 72 84 244 189 84 229 31 170 106 89 118 23 45 21 15 117 89 161 21 219 64 23 136 132 182 11 137 67 30 198 36 177 157 196 118 136 99 27 59 30 63 102 226 177 199 243 186 119 230 222 123 250 199 157 216 134 93 90 59 36 20 85 249 74 71 231 92 221 115 175 126 223 223 235 254 206 239 10 150 7 177 104 173 248 10 64 252 111 27 206 130 79 65 117 123 40 20 77 249 253 193 235 76 51 144 243 120 82 246 236 108 66 65 174 27 50 79 129 245 149 35 208 12 190 191 130 77 183 55 52 220 81 190 97 195 206 76 69 69 149 174 105 254 50 159 175 204 200 231 243 230 220 220 120 126 106 106 56 27 139 157 24 136 199 223 249 61 24 251 202 16 120 30 86 174 175 175 223 85 219 214 246 96 195 154 53 191 25 168 171 43 147 32 148 109 131 174 131 109 43 164 68 21 10 142 25 139 165 166 7 7 255 43 61 50 242 250 177 145 145 35 127 12 147 255 167 4 94 133 186 173 215 92 243 200 234 235 175 127 80 111 104 88 37 53 77 39 157 134 98 209 221 224 56 32 4 72 9 161 16 68 163 202 114 28 149 75 38 135 82 111 191 253 179 131 163 163 223 249 35 136 125 89 4 180 197 23 123 32 124 95 67 195 67 141 219 183 255 89 160 169 169 94 228 114 30 230 230 192 178 64 41 119 44 134 101 65 177 40 164 215 43 124 107 214 84 4 34 145 141 101 62 159 186 229 252 249 193 159 66 234 75 37 112 31 104 127 174 105 183 55 93 119 221 227 145 166 166 102 230 230 36 134 1 126 63 4 131 16 14 187 90 119 28 119 128 107 9 77 3 33 16 182 45 60 141 141 254 96 117 245 250 96 60 30 216 50 61 221 253 22 228 190 52 2 223 134 234 77 235 214 61 82 179 109 219 78 41 132 78 161 0 145 8 118 40 84 52 149 74 57 134 145 23 62 159 146 213 213 26 66 128 105 138 121 139 232 58 120 60 8 165 132 103 245 234 178 160 215 187 198 201 100 6 94 154 158 30 0 236 75 201 126 75 133 231 226 34 84 94 254 245 200 218 181 59 101 40 228 39 147 129 186 58 85 72 38 179 163 61 61 135 6 98 177 247 2 201 100 188 174 162 98 195 234 182 182 61 254 13 27 214 123 124 62 157 169 41 215 141 12 195 181 18 32 12 67 248 175 189 182 54 52 59 123 239 99 103 207 118 61 7 3 0 175 131 118 11 172 176 161 62 9 99 173 151 41 216 47 18 208 107 66 161 173 161 166 166 58 233 245 74 85 85 133 157 78 91 201 206 206 125 51 189 189 207 236 207 229 250 247 64 241 92 34 17 152 155 153 249 224 154 153 153 191 168 220 177 227 54 17 137 72 82 41 151 64 62 239 6 181 109 35 170 170 188 181 45 45 55 223 223 210 242 141 135 251 250 114 85 161 80 139 30 137 220 224 105 106 218 158 235 235 139 38 167 167 159 228 114 18 216 11 85 117 171 86 125 205 91 95 31 192 178 80 154 102 39 142 28 233 57 126 226 196 139 119 219 118 23 160 190 227 238 79 255 99 34 241 243 223 237 236 44 115 234 235 235 171 27 26 90 132 101 73 114 57 200 231 81 166 137 8 135 193 178 136 52 55 215 110 222 184 241 17 61 26 189 211 211 214 182 78 108 218 180 198 209 52 235 194 203 47 191 254 202 244 244 217 203 234 66 6 4 236 138 138 106 41 132 80 193 160 178 19 9 51 55 57 185 175 203 182 15 126 182 100 120 10 156 177 76 230 253 63 56 125 122 109 69 85 213 223 120 106 107 35 76 76 184 241 96 154 110 80 43 133 39 24 148 225 251 239 111 82 154 182 78 248 253 66 248 253 42 215 217 57 53 58 59 251 142 23 102 47 23 1 9 16 2 175 45 165 215 17 110 108 25 195 195 99 185 120 252 200 83 80 248 85 15 189 4 51 51 39 79 182 171 145 145 243 132 66 174 235 248 124 96 219 110 134 10 4 16 150 37 132 174 75 169 148 16 166 137 74 165 84 166 183 183 47 62 49 209 249 111 80 188 24 204 81 63 27 87 148 177 85 150 100 209 4 190 101 91 160 25 18 86 44 118 216 60 124 184 205 145 114 58 113 242 228 235 231 19 137 19 191 234 129 65 136 84 193 6 35 26 221 161 138 69 93 8 161 8 135 5 134 225 10 111 154 8 175 23 188 94 112 28 129 166 129 223 143 49 60 108 166 123 123 143 60 95 48 140 230 42 190 181 54 202 125 245 97 118 215 53 172 42 179 109 155 137 216 84 194 171 81 166 9 2 189 113 190 127 248 60 143 46 153 64 43 36 255 179 183 247 123 190 193 193 83 159 120 189 115 31 164 211 31 253 45 92 184 184 105 63 148 109 134 245 254 218 218 237 162 177 241 6 79 115 243 13 129 134 134 70 185 122 181 31 81 50 155 174 187 31 58 203 66 41 229 146 80 10 28 7 5 196 123 186 46 252 96 166 111 119 203 215 121 114 91 164 220 119 253 238 221 108 191 227 14 242 217 44 63 121 230 25 34 229 193 21 235 182 108 97 232 212 41 202 83 115 77 203 78 163 119 195 56 134 241 26 134 33 1 103 177 155 69 96 167 83 89 249 168 190 107 215 54 237 182 219 42 132 166 9 146 73 200 100 22 74 12 41 93 129 139 69 55 43 133 195 238 135 78 215 49 38 199 233 254 248 112 195 230 123 111 106 184 241 158 61 180 238 216 193 248 208 16 255 241 236 179 204 77 79 115 239 163 143 178 101 215 46 132 16 60 251 240 195 28 25 248 240 228 178 9 44 130 243 217 235 126 232 160 88 36 55 58 58 178 242 232 209 59 245 214 214 90 161 105 30 33 165 64 136 133 50 67 8 215 141 50 25 84 101 37 66 215 193 239 167 48 50 200 141 143 255 41 43 239 218 73 54 149 226 71 255 244 247 244 30 61 198 3 79 60 193 245 187 119 35 176 32 125 12 50 93 196 71 134 72 230 56 121 73 181 208 231 225 13 48 94 40 20 206 5 70 71 59 42 187 186 134 69 177 136 208 180 74 189 186 58 36 162 81 65 161 176 80 228 129 75 38 26 69 4 131 168 120 156 76 172 15 255 111 175 32 192 41 94 253 231 167 233 63 118 142 199 95 120 129 13 91 183 34 242 103 33 254 19 200 157 165 224 132 217 251 114 59 199 39 248 118 222 34 126 217 8 92 196 33 200 191 168 212 153 77 177 216 71 7 134 63 174 44 76 12 183 148 235 62 221 87 187 10 225 247 131 109 33 28 199 37 16 14 35 194 101 100 207 157 38 31 236 32 178 46 137 70 134 55 127 124 138 223 248 253 7 184 238 214 91 97 122 31 164 59 92 49 180 32 147 241 0 251 223 254 176 208 17 227 113 165 126 201 19 150 236 66 255 115 222 21 136 189 245 230 191 54 68 204 123 102 242 89 236 49 31 109 90 145 202 112 13 190 154 58 48 13 200 230 192 52 113 76 147 66 106 128 178 27 43 209 67 85 204 165 10 92 152 152 97 251 157 119 130 157 134 194 56 104 17 16 26 8 141 225 115 179 204 26 244 219 206 210 79 120 203 38 240 181 26 158 104 140 114 79 203 246 237 252 201 211 79 227 215 138 100 143 255 156 236 161 15 41 14 86 227 175 220 128 167 102 21 132 130 88 137 73 148 158 36 208 84 79 60 110 242 234 119 223 163 126 253 122 42 107 107 33 63 8 90 216 21 30 13 132 228 227 158 110 166 151 225 255 151 68 224 215 162 220 189 162 190 158 199 158 123 14 145 122 31 210 125 148 55 73 10 117 53 228 123 211 100 79 31 195 123 174 14 255 154 54 138 83 131 196 203 114 188 253 195 118 186 14 245 211 122 243 77 60 244 216 95 186 47 42 76 129 86 182 64 64 11 50 208 221 199 180 113 101 9 4 117 141 234 45 187 118 33 164 0 99 196 213 162 244 160 71 61 232 55 175 34 187 209 96 224 167 61 152 191 232 34 254 201 24 29 229 89 54 239 190 133 191 123 237 31 168 105 108 116 223 98 198 192 201 185 4 144 32 36 249 66 136 153 120 156 68 150 163 87 138 64 8 228 77 66 58 129 178 72 4 236 76 73 131 30 16 30 28 37 121 235 71 237 252 226 141 195 212 172 169 227 218 109 191 78 219 35 15 112 215 45 55 151 14 66 38 20 38 160 152 4 107 22 180 208 188 235 128 100 176 119 4 203 33 55 149 161 243 10 17 208 154 65 248 52 225 120 188 62 31 40 11 60 229 37 2 26 123 127 184 143 51 221 35 60 249 202 43 212 175 223 8 202 6 59 5 230 8 216 179 224 24 11 2 203 64 41 112 101 201 2 26 93 237 31 49 153 225 144 163 230 235 164 203 77 64 249 65 32 193 227 213 245 18 39 55 8 135 251 207 211 117 184 159 191 254 247 31 19 174 172 112 93 171 48 233 30 188 46 10 42 131 37 127 151 139 4 119 103 219 145 28 123 255 16 227 25 14 92 242 137 108 9 13 12 89 170 24 52 175 223 239 10 87 114 131 131 251 58 217 253 135 15 17 174 172 132 66 28 172 36 72 255 167 5 254 140 208 139 215 159 244 15 97 100 179 140 207 177 255 146 202 233 37 90 192 41 17 240 186 22 144 32 67 152 5 73 255 241 62 118 220 181 199 221 98 205 184 46 162 5 92 18 154 191 68 102 241 236 115 135 208 65 234 116 188 123 128 76 129 79 226 89 62 188 146 22 48 1 60 2 143 230 241 148 122 67 1 142 183 119 114 195 55 126 7 95 32 224 6 168 244 254 146 134 221 18 99 209 60 191 22 204 38 102 57 252 214 59 156 185 192 203 151 210 111 93 134 5 156 66 169 157 160 205 87 33 210 71 199 187 7 249 173 111 126 211 213 190 147 255 180 134 165 15 164 14 226 226 92 26 210 11 194 139 227 104 188 246 47 223 165 88 180 204 143 147 188 242 133 186 18 75 128 41 5 218 124 75 68 72 226 177 11 148 87 85 83 177 114 165 91 26 72 189 116 123 65 195 159 94 151 134 144 140 13 12 177 247 251 207 211 123 180 195 126 111 136 111 101 205 75 235 173 46 199 133 10 82 40 239 194 165 198 169 163 39 184 245 193 7 93 237 43 27 132 247 115 4 22 243 233 114 232 84 47 251 94 124 137 211 71 142 96 88 36 14 141 242 240 240 44 111 126 225 190 208 82 44 160 73 225 89 236 125 10 193 218 214 86 55 199 11 207 188 118 23 250 86 174 208 177 193 33 186 15 180 211 125 224 0 163 103 206 160 192 58 61 197 247 142 79 240 84 193 254 98 45 200 229 16 40 104 40 109 113 86 93 219 218 182 112 254 17 222 121 2 150 229 48 216 211 67 247 129 118 122 14 30 100 122 124 156 124 145 100 44 205 193 243 115 252 44 54 199 187 185 226 229 109 108 45 41 136 165 230 241 2 164 103 102 112 108 135 181 155 55 3 2 195 176 25 58 121 146 129 19 93 156 235 238 102 248 244 105 12 163 96 78 100 69 207 88 74 236 31 75 243 102 50 183 252 20 121 217 93 40 95 80 169 162 67 238 131 55 222 8 122 117 157 209 51 103 24 232 234 98 236 236 89 114 69 39 157 200 136 51 147 25 209 51 153 161 61 158 227 93 219 81 23 174 244 159 168 101 54 89 181 93 13 229 106 231 166 21 234 246 160 151 138 164 193 249 169 140 236 139 103 56 58 99 56 199 64 77 2 217 175 212 63 178 207 108 143 128 92 235 86 166 106 14 84 28 212 133 207 233 64 95 197 85 92 197 85 92 197 85 92 197 255 123 252 55 116 190 108 56 154 203 241 187 0 0 0 0 73 69 78 68 174 66 96 130)! !
!DrGIcons class methodsFor: 'accessing'!
line
^self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 48 0 0 0 48 16 6 0 0 0 7 146 37 196 0 0 0 6 98 75 71 68 255 255 255 255 255 255 9 88 247 220 0 0 0 9 112 72 89 115 0 0 0 72 0 0 0 72 0 70 201 107 62 0 0 1 149 73 68 65 84 120 218 237 155 61 174 130 64 20 133 103 172 97 17 20 108 107 98 50 157 49 178 25 151 96 193 10 168 220 137 149 137 37 189 13 201 125 5 121 49 206 123 58 255 204 85 206 215 65 32 145 243 225 56 3 71 33 0 47 136 250 190 239 137 74 127 142 213 113 62 55 77 211 16 93 46 109 219 182 68 16 81 8 83 196 253 222 117 93 7 17 185 216 152 59 78 167 113 28 71 33 174 215 105 154 38 33 110 183 97 24 6 33 32 34 51 74 41 165 212 35 224 237 182 174 235 154 40 238 27 241 123 28 196 189 196 12 62 141 8 51 120 8 176 226 42 98 222 178 5 12 1 193 216 68 204 216 68 32 248 104 222 139 128 128 197 136 21 161 181 214 90 63 206 55 183 129 35 177 67 17 130 79 74 232 80 4 17 38 27 191 195 93 131 147 210 220 51 79 95 133 56 30 171 170 170 74 95 54 31 60 5 216 144 242 249 14 151 114 158 190 98 101 157 136 215 179 28 219 143 109 154 149 53 248 131 45 120 136 200 132 111 240 16 145 136 216 224 243 60 244 91 33 190 11 172 60 15 253 86 200 225 176 223 239 118 225 43 91 136 96 66 168 8 188 42 77 12 68 48 1 67 19 19 32 130 9 16 193 4 136 96 2 68 48 1 34 152 0 17 76 128 8 38 64 4 19 150 17 129 218 141 21 84 46 153 128 202 37 19 80 185 100 66 234 202 37 122 78 129 152 34 158 131 68 193 108 49 254 15 114 57 17 50 244 196 239 36 246 142 150 222 121 38 110 198 125 42 241 149 203 208 5 29 4 56 129 202 101 102 80 185 44 14 154 126 133 136 13 222 85 4 90 28 22 82 255 149 202 20 81 250 250 216 18 219 244 3 31 206 15 224 42 63 94 246 95 66 123 0 0 0 0 73 69 78 68 174 66 96 130)! !
!DrGIcons class methodsFor: 'accessing'!
locus
^self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 48 0 0 0 48 8 6 0 0 0 87 2 249 135 0 0 0 6 98 75 71 68 0 99 0 99 0 99 185 251 243 121 0 0 0 9 112 72 89 115 0 0 11 19 0 0 11 19 1 0 154 156 24 0 0 0 7 116 73 77 69 7 213 11 28 8 18 45 208 0 131 20 0 0 0 29 116 69 88 116 67 111 109 109 101 110 116 0 67 114 101 97 116 101 100 32 119 105 116 104 32 84 104 101 32 71 73 77 80 239 100 37 110 0 0 3 87 73 68 65 84 104 222 237 152 201 139 19 65 20 198 127 17 241 232 93 196 187 127 136 224 217 131 94 20 81 90 16 65 16 84 80 65 208 163 140 163 40 110 12 58 174 131 251 46 138 184 226 134 131 136 136 3 234 136 224 174 227 160 102 50 49 147 69 103 62 15 121 5 25 237 116 58 109 119 18 49 15 138 110 146 234 170 239 171 122 239 213 247 10 218 214 182 182 181 173 109 255 189 149 64 5 208 191 128 53 7 26 174 192 154 114 4 42 59 141 1 63 128 97 96 170 245 9 48 85 142 149 132 141 128 198 128 209 50 86 138 246 44 185 73 243 32 25 112 128 9 246 71 10 248 9 100 170 19 169 36 158 74 98 181 221 98 230 129 172 97 201 216 123 190 218 164 251 65 211 129 41 192 100 96 146 177 159 60 190 91 42 41 2 35 32 183 218 57 96 0 120 14 204 143 50 199 102 208 19 208 183 50 216 106 45 54 203 130 190 130 222 128 238 213 51 182 231 121 129 157 15 39 76 224 59 40 11 26 0 61 14 49 166 47 94 247 227 239 79 31 191 31 215 106 145 15 3 126 8 244 30 116 57 0 124 32 190 106 127 250 116 86 156 36 178 230 158 175 171 0 15 129 167 246 54 213 2 31 213 149 178 160 180 249 251 77 159 239 35 129 174 145 239 199 181 231 21 239 215 35 16 248 6 122 7 186 20 2 124 28 246 199 106 219 224 42 130 62 131 186 234 32 145 1 13 90 134 75 18 116 53 2 227 38 115 169 239 92 29 4 6 65 253 160 3 62 227 37 174 71 126 159 44 109 250 228 33 104 93 72 18 239 65 189 173 0 222 243 60 165 65 35 150 73 14 133 32 240 25 244 10 116 173 34 123 53 13 60 101 209 167 2 232 11 232 10 104 118 13 18 3 160 23 21 46 215 16 240 65 129 150 181 64 30 2 221 5 45 8 32 48 104 7 214 19 219 173 166 131 119 170 177 104 113 112 31 180 40 128 192 71 115 159 7 160 93 205 216 1 63 203 27 129 140 9 176 133 1 4 222 153 251 220 1 109 142 97 7 38 196 65 192 105 220 81 211 232 185 128 190 211 32 85 50 141 63 6 116 119 119 167 154 78 192 85 113 133 242 233 202 113 72 5 173 108 209 14 147 137 173 224 62 148 129 43 103 210 162 51 132 91 244 130 110 129 246 180 74 29 238 2 248 118 29 121 253 1 232 60 104 101 179 73 20 44 128 7 65 61 33 179 138 231 121 234 179 128 63 80 35 232 27 146 129 50 160 62 208 234 58 118 224 145 165 220 11 160 245 205 34 224 192 247 71 212 52 55 64 87 65 251 154 225 74 5 171 97 95 131 142 68 208 52 174 223 101 208 41 59 212 230 52 138 132 3 255 22 116 210 71 207 215 123 178 159 6 29 179 131 109 73 146 36 138 166 58 211 160 151 160 19 49 20 35 174 127 15 232 32 104 27 104 45 104 94 156 68 138 166 54 179 160 79 166 99 58 99 4 239 158 59 173 170 219 14 218 8 90 243 183 36 138 160 60 232 187 73 229 103 230 175 113 214 174 126 223 111 2 109 5 109 1 117 88 219 16 68 166 4 42 89 62 47 84 128 30 178 21 239 3 157 177 52 153 68 225 237 55 206 10 75 175 157 70 100 7 104 183 37 140 75 38 219 31 57 60 14 120 206 238 104 62 128 158 218 85 71 23 104 113 3 110 13 170 141 55 23 180 220 200 116 152 123 237 5 29 5 157 117 184 210 160 143 182 210 23 45 144 150 129 102 132 188 108 74 186 226 115 54 19 52 11 52 31 180 20 180 42 202 221 105 210 53 108 34 243 52 10 252 95 205 27 246 110 180 209 250 189 46 28 173 2 58 18 174 86 5 223 168 4 210 182 168 246 11 175 92 10 76 202 252 154 245 0 0 0 0 73 69 78 68 174 66 96 130)! !
!DrGIcons class methodsFor: 'accessing'!
macroBuild
^ self formFromGraphic: #(
137
80
78
71
13
10
26
10
0
0
0
13
73
72
68
82
0
0
0
48
0
0
0
48
16
6
0
0
0
7
146
37
196
0
0
0
6
98
75
71
68
255
255
255
255
255
255
9
88
247
220
0
0
0
9
112
72
89
115
0
0
0
72
0
0
0
72
0
70
201
107
62
0
0
16
223
73
68
65
84
120
218
237
90
123
80
84
231
21
255
221
221
187
187
44
203
99
129
229
177
203
35
192
138
32
10
10
40
104
89
17
43
160
213
196
198
154
76
195
24
107
211
214
209
38
182
206
244
49
157
206
116
226
180
51
109
30
181
173
147
56
182
102
106
219
212
8
141
160
81
51
2
106
70
81
20
34
6
80
43
6
20
17
129
240
208
229
177
60
118
97
95
95
255
56
249
230
2
134
65
35
15
147
122
102
244
114
247
222
251
221
239
59
231
252
126
231
247
157
93
224
137
61
177
39
54
105
198
216
232
227
215
197
166
110
93
194
228
78
112
220
215
76
210
123
166
219
166
126
93
147
236
152
175
75
32
166
111
29
83
228
144
175
106
32
166
127
222
83
236
136
175
74
32
102
110
158
178
169
93
216
227
226
224
199
119
254
211
236
160
241
50
109
166
2
53
243
243
153
98
4
60
234
194
30
85
246
61
236
243
211
159
8
211
28
128
241
22
58
214
81
147
173
183
39
26
127
230
168
242
49
225
232
169
42
130
143
191
8
152
33
4
112
155
233
29
243
76
191
127
198
2
48
243
11
127
92
230
35
206
204
107
39
170
1
51
53
143
39
54
198
166
91
5
61
177
255
59
155
49
8
38
38
38
38
38
37
49
22
26
26
30
30
29
13
248
248
248
248
4
4
0
173
173
45
45
245
245
0
99
110
183
195
1
148
151
151
151
151
151
79
76
21
161
161
161
161
161
161
140
133
132
232
245
97
97
244
188
32
0
22
139
197
210
219
11
180
180
180
180
52
54
2
169
169
169
169
105
105
192
249
243
231
207
151
149
205
60
5
77
123
13
8
15
15
15
15
15
103
108
233
210
101
203
86
175
6
102
205
154
61
59
49
17
144
203
229
114
185
28
232
239
239
239
79
77
5
246
237
251
219
223
94
127
125
226
241
182
108
217
178
101
203
22
198
42
42
202
203
47
93
2
182
110
125
229
149
29
59
128
190
62
114
188
203
229
118
59
157
64
71
71
123
123
107
43
240
175
127
237
219
183
115
231
248
227
205
157
59
119
238
220
185
140
13
13
13
13
13
13
241
115
224
216
177
99
199
142
29
155
252
128
125
105
21
180
113
227
198
141
27
55
50
22
31
31
31
31
31
207
88
112
112
72
136
193
192
216
143
126
180
121
243
214
173
227
115
111
76
76
76
76
124
60
112
243
102
67
67
93
29
80
87
87
91
91
83
3
244
247
247
245
89
44
128
74
165
84
170
213
192
130
5
201
201
139
23
3
217
217
217
217
217
217
227
143
215
208
208
208
208
208
0
196
198
198
197
37
36
72
227
12
14
14
14
14
12
0
78
167
195
225
116
2
90
173
175
175
159
31
32
147
201
100
10
197
253
227
228
230
230
230
230
230
50
102
181
90
173
86
43
33
37
35
3
80
171
53
26
63
63
32
41
41
41
41
57
153
177
184
184
184
184
184
56
198
114
114
114
114
114
114
30
189
198
60
112
68
55
111
222
188
121
243
102
198
138
139
139
139
139
139
129
144
144
144
144
208
80
96
237
218
103
159
125
233
37
192
108
238
238
238
236
4
14
30
204
207
223
187
23
48
153
76
166
244
116
160
176
176
160
160
160
64
202
156
196
196
249
243
147
146
24
211
106
253
252
12
6
96
217
178
204
204
85
171
0
15
15
15
15
79
79
114
144
76
6
168
84
42
149
90
13
92
187
246
223
255
86
86
2
183
110
221
186
85
87
7
216
237
195
195
195
195
192
189
123
247
238
181
183
3
203
151
47
95
190
102
13
16
27
59
103
206
252
249
0
207
92
128
74
48
71
86
91
219
103
159
181
180
0
133
133
7
15
190
243
14
160
84
42
149
226
8
252
107
181
126
126
58
29
176
102
205
51
207
188
248
34
160
215
235
245
17
17
128
74
229
225
225
225
1
200
229
52
47
171
213
102
179
90
129
63
252
225
183
191
253
201
79
128
89
179
98
98
140
70
160
172
172
172
236
203
80
218
132
15
240
204
56
119
238
220
185
243
231
1
157
46
56
56
52
20
216
182
109
219
182
29
59
128
254
254
129
1
139
5
176
90
41
227
42
43
47
94
44
45
5
44
150
158
158
123
247
0
187
221
225
176
217
128
206
206
206
206
206
78
192
233
116
58
157
78
32
51
147
28
183
112
225
162
69
25
25
128
219
237
118
187
221
128
211
233
114
57
157
128
32
48
230
118
3
114
185
66
161
84
2
54
155
213
58
56
8
244
246
90
44
221
221
128
167
39
33
69
167
11
10
10
14
6
6
7
109
182
193
65
226
126
64
10
164
76
38
151
203
100
128
66
161
80
120
120
0
102
179
217
220
222
14
216
108
116
191
70
163
209
120
123
3
190
190
62
62
90
45
48
60
76
1
230
243
49
155
205
230
206
78
224
192
129
127
255
123
247
110
96
222
188
196
196
148
20
96
201
146
37
75
50
51
129
252
252
247
222
219
179
7
184
117
171
177
177
161
97
10
2
144
145
145
145
145
145
193
88
86
214
202
149
185
185
64
73
73
81
81
97
33
81
200
167
159
2
155
54
109
218
180
125
59
16
20
20
28
172
215
3
130
32
8
124
193
74
37
32
138
162
40
138
128
82
169
82
121
120
144
99
228
114
224
220
185
179
103
139
139
129
207
62
107
109
109
106
2
122
123
187
187
239
222
5
26
26
110
222
188
126
29
80
171
61
61
61
60
104
28
181
26
112
185
92
46
0
240
240
208
104
84
42
64
163
161
204
116
185
156
78
135
3
24
24
24
28
164
0
0
50
25
57
210
102
3
100
50
65
96
12
240
242
242
242
242
241
1
162
163
141
198
57
115
0
133
66
169
244
244
4
210
211
77
166
236
108
64
173
86
171
61
61
1
171
149
2
45
8
130
32
8
64
93
93
93
221
213
171
192
225
195
5
5
127
255
59
176
115
231
174
93
121
121
20
56
31
31
224
205
55
95
123
237
167
63
5
210
210
82
83
83
83
129
210
210
179
103
203
203
249
58
38
14
200
132
55
164
167
167
167
167
167
51
246
253
239
255
240
135
191
254
53
101
176
219
13
156
60
121
226
196
161
67
128
40
202
229
162
8
36
39
47
92
104
50
1
14
135
195
97
183
143
120
193
231
11
113
58
201
133
127
252
227
235
175
255
226
23
192
240
48
81
197
142
29
191
251
221
91
111
1
158
158
106
181
151
23
57
194
195
3
8
8
208
233
244
122
10
156
66
1
132
134
234
245
58
29
16
23
23
27
27
25
9
248
248
120
123
139
34
64
249
14
220
186
213
208
112
247
46
208
222
126
247
110
119
55
48
56
56
48
96
181
2
29
29
132
60
179
153
40
75
20
229
114
165
18
200
203
59
112
96
239
94
160
186
186
170
170
188
28
120
238
185
231
159
255
193
15
168
246
124
227
27
0
99
132
37
62
255
75
151
42
43
203
202
36
53
101
183
219
237
195
195
132
252
254
126
105
189
27
55
110
218
244
227
31
3
251
247
191
251
238
95
255
58
113
32
38
84
65
114
185
40
170
84
64
113
113
81
81
65
1
16
20
20
20
20
30
78
153
44
138
64
124
252
220
185
201
201
128
151
151
183
183
143
143
196
209
78
39
101
166
203
69
148
35
8
130
32
151
3
105
105
139
23
103
102
2
151
47
87
87
151
151
3
71
143
30
57
178
127
63
113
181
82
73
114
242
169
167
40
51
159
126
154
206
195
194
164
226
201
19
192
110
119
56
104
134
84
8
25
147
201
24
3
148
74
133
66
161
0
218
219
45
150
158
30
224
234
213
154
154
202
74
160
162
162
188
252
204
25
66
164
92
14
220
188
121
227
198
181
107
192
188
121
9
9
201
201
64
112
176
193
16
30
46
173
155
49
26
87
165
82
169
84
42
32
43
43
39
231
217
103
169
118
168
84
210
125
78
167
211
105
183
75
181
199
219
155
252
48
48
208
223
223
221
253
8
20
20
18
18
18
18
18
194
88
88
24
233
244
13
27
190
247
189
237
219
73
38
246
244
80
113
172
174
6
174
92
169
169
249
248
99
130
180
74
69
106
195
215
151
138
98
82
18
16
21
21
21
21
23
71
84
34
138
128
40
114
78
167
204
113
185
24
115
185
168
102
116
119
3
21
21
23
46
20
21
1
55
110
220
184
209
208
64
84
50
178
168
138
162
40
42
149
128
32
200
100
110
55
101
180
66
65
212
97
179
1
196
250
68
67
140
73
212
104
50
45
91
182
114
37
16
31
63
103
78
98
34
33
213
229
146
138
189
219
237
118
187
92
128
195
97
183
219
237
180
30
165
18
184
115
231
246
237
250
122
224
244
233
51
103
142
31
31
73
81
244
207
100
90
186
52
43
11
136
143
143
143
95
184
16
104
111
239
236
108
106
2
222
121
103
207
158
55
222
32
164
216
237
227
35
224
190
11
92
246
53
53
53
53
53
53
17
247
202
100
18
39
207
158
29
19
147
152
8
168
84
106
181
70
3
132
133
69
68
68
69
17
50
66
67
129
210
210
211
167
143
29
163
0
85
85
1
171
87
175
89
243
194
11
64
120
56
221
199
152
219
77
234
132
215
6
10
156
90
237
233
169
209
144
26
82
171
73
117
200
229
18
165
13
15
19
228
121
77
81
171
169
6
48
70
52
100
179
89
173
67
67
228
126
185
92
66
6
47
194
110
183
203
69
69
158
144
57
52
52
52
100
179
73
1
118
185
168
248
51
70
185
207
85
217
63
255
249
143
127
236
220
73
251
129
133
11
129
148
148
69
139
150
46
5
46
95
190
124
185
188
28
104
107
107
109
109
110
6
250
251
9
113
109
109
109
109
183
111
3
222
222
180
177
124
104
10
58
117
234
212
169
83
167
4
129
111
72
222
124
243
207
127
62
120
16
248
217
207
182
111
127
225
5
160
166
166
166
166
162
2
120
235
173
61
123
242
243
129
150
150
230
230
230
102
138
180
195
65
16
212
106
137
27
7
7
129
136
136
200
200
89
179
200
241
148
177
68
1
54
27
45
188
182
246
218
181
170
42
224
211
79
105
63
96
54
155
205
29
29
128
32
144
35
77
166
244
244
172
44
96
206
156
121
243
82
82
0
133
66
20
21
10
192
98
33
23
115
135
113
213
35
151
211
245
214
214
59
119
26
27
129
43
87
174
94
173
172
4
46
94
172
168
56
125
154
50
29
0
22
45
74
77
93
186
20
200
204
92
177
226
153
103
40
160
35
145
192
229
107
114
114
114
178
201
4
52
55
55
55
223
186
37
81
147
94
31
18
18
21
5
204
154
101
52
38
36
0
255
249
79
94
222
158
61
192
119
191
155
155
187
101
11
80
84
116
252
120
97
225
196
20
116
95
0
56
2
218
218
218
218
218
218
36
142
251
230
55
87
172
88
189
154
168
68
46
39
71
80
166
1
46
151
164
110
62
250
232
228
201
163
71
129
236
236
149
43
215
173
3
2
3
3
3
131
131
137
186
250
250
128
174
46
146
117
101
101
165
165
197
197
36
99
251
250
128
164
164
228
228
37
75
136
194
252
253
129
161
33
170
37
71
143
126
240
193
190
125
36
63
205
102
96
217
178
229
203
215
174
165
140
118
58
9
65
74
165
116
180
88
122
122
122
122
128
195
135
63
248
224
221
119
105
188
128
0
96
195
134
23
95
124
229
21
82
81
26
13
112
254
124
105
105
73
9
80
83
243
201
39
23
46
72
28
207
29
239
112
80
237
138
138
50
26
99
99
165
117
37
36
36
36
52
54
74
129
230
148
60
182
38
60
168
77
136
0
128
56
154
23
87
0
32
14
166
162
202
101
167
74
165
82
41
149
64
87
87
87
87
103
39
112
242
100
73
201
161
67
64
99
35
201
85
95
95
63
63
127
127
192
229
114
56
28
14
32
50
50
58
218
104
4
230
205
155
55
47
57
89
82
61
60
80
50
25
169
43
139
197
98
89
183
142
84
72
105
41
144
157
157
147
243
220
115
0
165
2
81
5
151
171
74
37
112
249
242
149
43
151
46
73
153
186
122
245
211
79
63
255
60
224
235
235
235
171
211
209
248
189
189
192
252
249
164
118
46
95
38
68
31
63
254
225
135
249
249
64
79
79
111
175
217
12
52
53
53
54
222
188
73
136
112
58
1
131
193
96
8
11
35
255
28
57
2
172
93
251
237
111
111
216
48
122
227
71
148
39
147
61
204
110
96
66
4
48
54
186
107
238
112
16
213
8
2
233
107
190
84
190
41
247
243
243
243
11
12
36
121
185
123
55
181
10
174
95
151
40
166
178
146
28
249
210
75
155
55
191
255
62
201
79
141
134
118
182
189
189
18
231
187
92
180
176
192
192
160
32
189
30
184
113
163
190
254
218
53
137
178
56
215
139
34
169
49
183
91
16
220
110
224
234
213
234
234
139
23
1
157
78
167
11
12
4
22
44
88
176
32
53
21
168
175
175
175
175
173
149
184
95
173
86
171
189
189
169
120
38
39
3
167
78
157
56
113
248
48
240
242
203
219
182
253
234
87
128
40
82
109
10
15
15
13
141
136
160
158
146
203
5
236
220
249
198
27
175
190
42
213
42
155
141
118
198
220
184
106
156
68
4
124
177
113
21
64
81
167
64
240
0
120
123
3
70
163
209
56
107
22
81
131
66
1
164
165
165
165
101
102
74
250
89
162
14
42
170
60
211
120
6
57
28
14
7
237
132
69
81
38
3
60
61
61
61
125
124
168
200
81
209
235
235
235
235
147
174
43
149
164
142
184
40
168
171
171
171
187
114
5
208
106
253
253
253
253
1
167
147
28
200
119
184
110
55
117
91
249
121
104
104
120
120
68
4
144
144
48
127
254
194
133
64
79
79
119
119
87
151
244
220
192
0
245
152
134
134
236
118
155
77
218
31
140
53
198
232
254
71
70
0
111
29
140
118
185
116
36
45
67
231
132
18
250
156
23
69
126
116
56
168
25
198
101
163
221
78
25
238
118
147
158
151
203
61
61
73
50
114
210
24
141
56
202
107
96
254
124
114
204
214
173
47
191
252
203
95
74
77
55
9
125
244
191
183
183
143
143
175
47
176
113
99
110
110
78
142
20
24
106
75
72
142
115
187
233
125
92
6
187
92
78
39
201
80
162
72
142
68
174
186
248
123
100
159
183
47
121
49
31
107
46
23
169
173
7
181
251
186
161
28
1
252
92
46
39
25
199
51
158
191
96
164
195
8
5
84
132
165
137
72
170
135
22
79
181
130
38
15
48
70
174
21
4
82
47
35
199
34
105
201
51
149
138
188
195
225
116
218
108
180
193
25
24
0
122
123
123
123
123
122
232
216
219
43
245
253
135
134
108
54
155
77
234
57
241
13
35
47
174
163
223
66
243
18
4
66
210
232
235
247
167
30
79
48
186
95
46
255
34
4
140
125
203
68
54
46
2
6
7
7
7
173
86
224
230
205
250
250
235
215
1
141
198
203
203
219
27
176
217
134
134
172
86
234
133
120
121
17
229
4
4
124
62
216
23
236
171
185
60
20
4
162
22
158
57
252
11
19
94
204
185
35
70
135
149
238
228
1
226
71
250
91
66
34
253
117
63
18
57
21
140
108
41
240
55
112
170
227
72
96
204
229
26
249
102
183
155
183
245
248
58
4
65
20
169
59
170
86
3
62
62
212
222
238
239
31
24
24
217
138
80
42
169
119
245
165
3
192
17
144
150
150
150
182
120
49
99
175
189
246
251
223
255
252
231
128
201
148
145
145
149
69
197
45
36
4
168
170
170
170
170
168
0
78
159
254
232
163
163
71
41
51
123
123
239
215
229
252
40
229
56
133
128
23
53
198
36
46
229
8
161
59
249
167
99
29
52
58
64
220
73
114
57
33
204
229
162
251
36
10
148
40
129
198
31
141
84
190
63
225
189
170
209
244
55
50
179
9
33
29
29
237
237
183
111
3
231
207
159
61
123
228
8
96
48
132
133
205
158
77
45
150
101
203
128
253
251
247
239
223
179
135
84
227
131
200
209
113
17
192
3
145
146
146
146
178
104
17
99
37
37
69
69
135
14
145
156
243
245
5
172
214
129
129
174
46
250
10
177
177
145
54
104
213
213
130
96
52
26
141
70
35
45
159
103
56
45
156
115
239
200
28
3
212
106
234
146
106
52
164
207
221
110
169
186
144
204
37
80
75
148
55
26
248
60
79
71
214
36
122
150
90
20
162
72
45
16
127
127
127
127
157
78
250
188
171
139
18
163
175
175
191
223
98
145
2
205
17
33
133
159
183
64
104
156
216
216
216
216
216
88
32
50
242
169
167
12
6
160
168
136
122
100
45
45
45
45
205
205
146
250
234
236
236
232
104
107
155
88
144
142
91
3
120
32
170
170
170
170
46
93
18
4
147
201
100
50
153
128
142
142
142
142
142
14
65
232
234
234
234
106
111
151
28
159
149
149
149
149
149
197
24
47
90
162
200
101
34
231
86
90
24
239
158
218
108
36
7
47
93
250
228
147
138
10
32
63
63
47
111
239
94
224
196
137
146
146
130
2
10
108
67
131
212
178
224
27
159
145
249
57
178
120
243
240
140
252
66
71
165
2
202
202
206
156
57
113
2
120
251
237
93
187
126
243
27
32
63
255
192
129
191
252
5
168
168
40
43
43
42
162
98
59
60
76
251
8
133
66
170
85
92
102
250
249
105
181
1
1
18
82
188
188
188
188
188
188
128
218
218
218
218
218
90
234
89
213
215
75
254
161
64
72
254
123
100
4
140
119
94
82
82
82
82
82
114
255
117
189
94
175
215
235
25
59
126
252
248
241
130
2
96
213
170
111
125
235
59
223
145
90
8
190
190
90
173
191
63
125
55
187
123
55
16
28
28
18
162
211
209
247
12
135
15
19
226
82
82
24
235
234
50
155
91
91
201
17
90
173
212
28
147
40
137
103
42
167
48
58
242
162
219
215
71
148
152
151
247
222
123
111
191
13
92
191
126
253
250
181
107
247
207
55
43
43
59
91
173
102
44
48
48
48
208
96
160
12
14
10
2
238
220
105
110
110
108
4
118
237
250
211
159
94
125
21
232
236
188
123
183
189
157
118
214
222
222
36
115
235
234
198
247
207
88
49
243
208
54
54
130
15
123
190
98
197
138
21
43
86
48
198
247
19
81
81
81
81
209
209
140
5
4
4
4
4
4
48
182
126
253
250
245
235
215
143
255
124
102
102
102
102
102
38
99
179
103
207
158
61
103
14
99
43
87
174
90
181
110
29
99
199
142
21
21
93
189
202
88
97
225
145
35
31
127
204
216
251
239
23
22
94
184
192
88
126
254
193
131
231
206
49
118
228
200
135
31
86
87
51
70
148
246
224
243
53
24
12
6
131
129
126
85
161
215
51
22
25
25
17
17
29
45
93
207
201
201
201
89
185
242
203
251
99
202
2
49
217
129
27
123
30
29
29
29
29
29
205
24
255
53
5
71
152
78
167
211
233
116
140
105
181
90
173
86
203
88
80
80
80
80
80
16
99
70
163
209
24
19
195
88
100
100
100
100
100
36
99
147
61
159
105
115
252
84
7
238
97
207
199
254
10
225
255
214
177
147
237
248
201
30
111
186
17
251
216
218
100
79
124
170
29
245
149
117
244
116
219
215
38
67
159
216
19
123
98
79
108
230
237
127
37
64
140
158
47
166
2
126
0
0
0
0
73
69
78
68
174
66
96
130
)! !
!DrGIcons class methodsFor: 'accessing'!
macroExecute
^ self formFromGraphic: #(
137
80
78
71
13
10
26
10
0
0
0
13
73
72
68
82
0
0
0
48
0
0
0
48
16
6
0
0
0
7
146
37
196
0
0
0
6
98
75
71
68
255
255
255
255
255
255
9
88
247
220
0
0
0
9
112
72
89
115
0
0
0
72
0
0
0
72
0
70
201
107
62
0
0
20
29
73
68
65
84
120
218
237
91
123
80
84
231
221
126
14
123
99
129
133
133
93
46
203
45
192
202
93
80
64
193
148
5
73
92
208
106
98
99
77
166
161
9
53
73
107
77
147
180
206
52
189
206
180
201
52
51
109
46
181
109
154
56
182
185
181
77
141
210
168
49
106
70
192
152
49
70
16
34
6
188
20
17
4
87
4
228
230
2
187
44
123
191
188
223
31
191
239
157
131
90
199
92
208
164
223
199
111
70
215
179
231
236
57
231
253
93
158
223
243
62
239
43
48
103
115
54
103
115
54
103
55
219
202
202
202
202
202
202
24
139
137
137
137
137
137
97
236
203
126
31
110
194
151
253
2
183
202
162
163
163
163
181
90
198
188
94
159
207
235
5
178
178
114
115
211
211
1
169
52
40
72
161
0
154
154
142
28
57
122
84
184
229
254
248
210
2
112
239
189
53
53
43
86
48
118
225
130
201
116
241
34
48
49
97
54
91
173
64
72
136
74
165
80
0
126
191
207
23
8
0
193
193
74
165
92
14
56
157
14
135
219
13
200
229
50
153
92
14
120
60
46
215
204
243
81
81
26
141
90
13
248
124
94
47
99
128
74
21
26
170
82
1
117
117
251
246
125
240
129
32
132
133
169
84
33
33
140
189
246
218
187
239
254
250
215
128
223
79
85
176
113
227
183
191
253
194
11
64
110
110
78
78
110
46
112
228
200
71
31
53
53
221
186
64
220
180
7
61
244
208
35
143
212
212
48
54
60
60
54
214
223
15
152
76
38
83
95
31
160
80
40
149
50
25
16
27
155
152
168
86
3
69
69
165
165
89
89
64
70
70
94
94
98
34
16
8
8
2
99
128
84
42
8
18
9
224
245
6
2
62
31
224
241
120
189
110
55
32
8
64
80
16
160
80
200
100
50
153
248
60
159
207
239
15
4
128
64
128
177
64
0
168
171
219
182
237
216
49
160
183
183
163
99
120
24
184
112
161
167
103
96
0
120
237
181
253
251
127
241
11
128
49
198
4
129
2
233
245
2
63
251
217
186
117
155
55
139
129
14
9
9
9
9
13
5
38
39
39
38
38
39
111
94
64
102
253
198
121
121
11
22
228
230
50
150
158
158
155
27
31
15
76
78
90
44
22
11
176
106
85
117
117
73
9
160
84
170
213
148
193
228
80
198
128
64
0
240
249
2
1
143
7
8
4
252
126
191
159
28
77
142
165
239
1
186
142
49
65
16
4
64
34
97
76
38
3
130
130
40
80
140
9
130
223
15
72
36
130
64
223
3
82
41
48
54
54
56
232
112
0
111
189
181
121
115
125
61
240
228
147
155
54
221
119
159
248
59
110
140
5
2
130
0
120
189
110
183
199
3
188
250
234
51
207
28
56
0
92
186
116
241
226
232
40
224
116
58
157
78
231
236
7
66
58
91
55
90
184
176
160
32
63
159
177
236
236
194
194
228
100
192
104
92
179
102
225
66
202
104
159
15
176
88
236
246
203
151
129
137
9
155
109
116
20
240
251
201
209
62
31
7
3
126
236
241
80
38
123
189
228
112
198
24
3
4
129
28
47
8
65
65
220
97
0
32
145
72
165
244
13
55
186
78
38
35
168
106
106
58
112
224
236
89
64
46
87
42
37
18
192
229
10
4
166
167
1
175
215
227
113
185
0
175
215
229
242
249
0
192
235
245
251
1
198
130
130
4
1
8
4
168
242
110
150
227
103
61
0
163
163
99
99
35
35
128
209
168
215
207
159
15
216
108
14
199
228
36
224
112
120
60
102
51
96
181
78
77
77
79
3
140
249
124
140
1
19
19
163
163
118
59
208
217
249
201
39
35
35
192
229
203
151
46
77
77
1
86
235
248
184
211
9
168
213
26
141
74
69
16
225
243
1
26
77
116
116
100
36
32
151
43
20
50
25
112
249
242
232
232
196
4
160
84
134
134
42
20
128
66
161
80
72
165
228
88
191
31
240
120
60
30
159
15
232
235
235
233
185
116
9
48
24
238
185
39
51
19
112
58
109
54
155
13
112
187
109
54
183
27
240
120
28
14
159
15
216
189
251
245
215
219
219
129
168
168
232
232
136
8
192
100
58
119
110
112
240
230
247
130
89
11
128
195
97
183
59
157
64
120
120
92
156
32
0
253
253
151
46
153
76
192
217
179
109
109
67
67
64
103
103
107
235
208
16
48
53
53
49
225
114
1
145
145
106
181
90
13
100
100
100
101
165
167
3
205
205
29
29
221
221
226
128
199
198
134
135
45
22
241
254
125
125
189
189
195
195
159
253
189
162
162
98
98
84
42
198
10
11
13
134
228
100
192
233
156
156
116
58
129
237
219
255
252
231
99
199
168
82
100
50
160
191
191
183
119
124
92
16
232
243
102
187
125
22
173
172
172
172
204
96
96
44
58
58
38
70
163
97
236
254
251
191
255
125
163
145
49
189
62
55
55
62
158
49
163
113
245
234
146
146
47
143
119
199
196
232
116
26
13
99
149
149
107
215
46
92
200
88
86
86
65
65
66
194
87
103
30
48
11
3
164
137
77
126
126
126
126
94
30
99
21
21
119
222
89
94
254
213
25
96
118
118
78
78
86
22
99
139
23
47
89
82
80
240
213
121
175
57
155
179
57
155
179
57
155
179
47
77
11
202
207
207
207
47
40
96
44
33
33
41
41
45
13
8
15
15
15
215
104
128
193
193
129
129
238
110
154
104
121
189
64
115
115
115
115
115
243
141
249
120
66
66
66
66
66
2
99
113
113
58
93
98
162
56
179
181
90
173
86
139
5
24
24
24
24
48
153
128
226
226
226
226
146
18
160
169
169
169
169
177
241
214
139
111
87
219
172
205
3
62
173
37
37
37
37
37
37
49
86
86
182
116
233
202
149
192
188
121
25
25
249
249
128
68
34
145
72
36
128
205
102
179
21
23
3
111
188
241
215
191
62
247
220
141
239
183
97
195
134
13
27
54
48
214
210
210
220
124
252
56
240
232
163
143
63
254
244
211
192
212
20
57
222
239
167
25
237
200
200
240
240
224
32
240
143
127
188
241
198
166
77
215
191
95
110
110
110
110
110
46
99
46
151
203
229
114
241
99
96
223
190
125
251
246
237
155
253
128
5
125
222
31
214
212
212
212
212
212
48
150
147
147
147
147
147
195
88
108
108
92
92
124
60
99
223
251
222
250
245
143
62
122
125
186
151
158
158
158
158
147
3
244
244
244
246
118
117
1
93
93
103
206
156
56
1
216
108
83
83
86
43
160
80
200
229
74
37
176
112
97
97
225
146
37
64
101
101
101
101
101
229
245
239
215
219
219
219
219
219
11
100
102
102
101
229
229
137
247
177
219
237
246
233
105
82
71
125
62
64
173
142
136
136
140
4
130
130
130
130
102
138
120
220
170
171
171
171
171
171
25
115
56
28
14
135
131
42
165
188
156
102
218
145
145
64
65
65
65
65
97
33
99
89
89
89
89
89
89
140
85
85
85
85
85
85
125
113
90
251
169
35
186
126
253
250
245
235
215
51
86
95
95
95
95
95
15
196
197
197
197
37
36
0
171
87
223
115
207
195
15
3
102
243
196
196
232
40
176
99
71
109
237
43
175
0
6
131
193
80
90
10
236
218
181
115
231
206
157
98
230
228
231
47
88
80
80
192
152
90
29
25
25
31
15
44
93
90
81
177
98
5
16
28
28
28
28
18
66
14
34
181
83
161
80
42
129
142
142
127
255
187
181
21
56
127
254
252
249
174
46
192
227
113
187
221
110
224
242
229
203
151
135
135
129
59
238
184
227
142
85
171
128
204
204
236
236
5
11
0
158
185
0
9
125
188
178
134
134
46
93
26
24
0
118
237
218
177
227
213
87
1
185
92
46
151
206
168
127
181
58
50
82
171
5
86
173
186
251
238
7
31
4
116
58
157
46
57
25
80
40
130
131
131
131
1
137
132
222
203
225
112
58
29
14
224
119
191
251
205
111
126
248
67
96
222
188
244
116
189
30
104
108
108
108
252
60
144
118
195
31
240
204
56
114
228
200
145
166
38
64
171
141
141
77
72
0
158
120
226
137
39
158
126
26
176
217
166
167
173
86
146
34
166
167
129
214
214
99
199
14
31
6
172
214
201
201
203
151
73
245
116
58
129
209
209
209
209
209
81
192
231
243
249
124
62
160
162
130
28
183
104
209
226
197
229
229
36
126
145
42
234
247
251
124
128
32
144
220
38
145
144
168
230
116
58
28
118
59
96
177
88
173
19
19
64
72
8
85
138
86
27
19
19
27
11
216
237
78
167
221
46
138
116
60
144
65
65
18
73
80
16
73
14
193
193
128
217
108
54
15
15
147
200
102
183
3
161
161
180
110
16
17
17
30
174
86
3
110
55
5
152
191
143
217
108
54
143
142
2
219
182
253
243
159
155
55
3
243
231
231
231
23
21
1
183
223
126
251
237
21
21
64
109
237
91
111
109
217
2
156
63
111
50
245
246
222
132
0
148
151
151
151
151
151
51
102
52
46
95
94
93
13
52
52
212
213
237
218
69
16
114
246
44
176
110
221
186
117
27
55
2
49
49
177
177
58
29
105
145
124
192
114
57
32
149
74
165
82
41
137
104
193
193
228
24
137
132
22
62
234
235
129
75
151
6
7
251
250
0
139
101
98
98
108
12
232
237
237
233
233
236
4
148
202
144
144
224
96
186
143
82
201
181
82
32
56
152
196
183
208
80
202
76
191
159
86
184
166
167
237
118
10
0
73
209
110
183
219
237
116
146
236
204
24
16
22
22
22
22
30
14
164
165
233
245
217
217
128
76
38
151
135
132
0
165
165
6
67
101
37
160
84
42
149
33
33
128
195
65
129
230
234
107
87
87
87
215
233
211
192
238
221
59
119
190
254
58
176
105
211
139
47
110
223
78
129
11
15
7
94
120
225
217
103
127
244
35
160
164
164
184
184
184
24
56
124
248
163
143
154
155
249
56
110
28
144
27
94
80
90
90
90
90
90
202
216
67
15
125
247
187
191
252
37
101
112
32
0
188
255
254
129
3
239
188
3
72
165
18
137
84
10
20
22
46
90
100
48
0
94
175
215
203
245
123
64
28
136
207
71
46
252
253
239
159
123
238
39
63
1
220
110
130
138
167
159
126
230
153
151
94
2
66
66
148
202
176
48
114
68
112
48
160
209
104
181
58
157
168
126
38
36
232
116
90
45
144
149
149
153
153
146
2
132
135
171
84
82
41
173
17
0
192
249
243
189
189
99
99
192
240
240
216
216
196
4
96
183
79
79
59
28
192
200
8
85
158
217
76
144
37
149
74
36
114
57
176
125
251
182
109
175
188
2
180
183
183
181
53
55
3
247
222
123
223
125
143
60
66
189
231
107
95
35
25
60
16
16
223
255
248
241
214
214
198
70
145
77
121
60
30
143
219
77
149
111
179
137
227
173
169
89
183
238
7
63
0
182
110
125
243
205
191
252
229
198
129
184
33
11
146
72
164
82
133
2
168
175
175
171
219
185
147
180
159
164
36
202
100
169
20
200
201
201
205
45
44
4
194
194
84
170
240
112
17
163
125
62
202
76
191
159
32
71
16
104
1
164
164
100
201
146
138
10
224
228
201
246
246
230
102
96
239
222
61
123
182
110
37
172
150
203
137
78
222
118
27
101
230
93
119
209
113
98
162
216
60
121
2
120
60
94
47
189
33
53
66
198
130
130
24
163
37
75
153
12
24
30
182
90
39
39
129
211
167
79
156
104
109
5
90
90
154
155
63
252
144
42
82
34
1
122
122
206
157
235
232
0
230
207
207
203
43
44
4
98
99
227
227
147
146
196
113
211
42
4
245
34
133
2
48
26
171
170
238
185
135
122
135
66
33
94
231
243
249
124
30
143
216
123
84
42
242
195
244
180
205
54
49
241
5
32
40
46
46
46
46
46
142
177
196
68
226
233
15
60
240
157
239
108
220
72
52
113
114
146
154
99
123
59
112
234
212
137
19
31
127
76
37
173
80
16
219
136
136
160
166
88
80
0
164
166
166
166
102
101
17
148
72
165
128
84
202
49
157
50
199
239
103
204
239
167
158
49
49
1
180
180
28
61
90
87
7
156
59
119
238
92
111
47
65
201
204
166
42
149
74
165
114
57
45
204
4
2
148
209
50
25
65
135
211
9
16
234
19
12
49
38
66
163
193
176
116
233
242
229
64
78
78
118
118
126
62
85
170
223
47
54
251
64
32
16
240
251
105
61
193
227
161
241
200
229
192
197
139
23
46
116
119
3
135
14
125
248
225
254
253
51
33
138
254
24
12
101
101
70
35
144
147
147
147
179
104
17
48
60
60
58
218
215
7
188
250
234
150
45
207
63
79
149
226
241
92
191
2
174
57
193
105
95
95
95
95
95
95
31
97
111
80
144
136
201
25
25
233
233
249
249
180
182
27
26
10
36
38
38
39
167
166
82
101
36
36
0
135
15
31
58
180
111
31
5
168
173
13
88
185
114
213
170
251
239
7
146
146
232
58
198
2
1
98
39
188
55
80
224
148
74
90
131
13
14
14
14
86
42
137
117
208
154
48
65
154
219
77
37
207
123
138
82
73
61
128
47
105
58
157
14
135
203
69
238
167
165
70
202
96
222
132
3
1
90
51
230
149
233
114
185
92
78
167
24
96
191
159
154
63
95
129
227
172
236
239
127
255
219
223
54
109
162
249
192
162
69
64
81
209
226
197
101
101
192
201
147
39
79
54
55
3
67
67
131
131
253
253
128
205
70
21
55
52
52
52
116
225
2
160
82
209
196
242
51
67
208
193
131
7
15
30
60
40
8
124
66
242
194
11
127
252
227
142
29
192
143
127
188
113
227
253
247
3
39
78
156
56
209
210
2
188
244
210
150
45
181
181
192
192
64
127
127
127
63
69
218
235
165
18
84
171
9
27
237
118
32
57
57
37
101
222
60
114
60
101
44
65
128
211
73
3
63
115
166
163
163
173
13
56
123
150
230
3
102
179
217
60
50
2
8
2
57
210
96
40
45
53
26
129
236
236
249
243
139
138
0
153
76
42
149
201
0
171
149
92
204
29
198
89
143
68
66
231
7
7
47
94
52
153
128
83
167
78
159
110
109
5
142
29
107
105
57
116
136
50
29
0
22
47
46
46
46
43
3
42
42
150
45
187
251
110
10
232
204
74
224
244
181
176
176
176
208
96
0
250
251
251
251
207
159
23
161
73
167
139
139
75
77
5
230
205
211
235
243
242
128
127
253
107
251
246
45
91
128
111
125
171
186
122
195
6
160
174
110
255
254
93
187
110
12
65
215
4
128
87
192
208
208
208
208
208
144
136
113
119
222
185
108
217
202
149
4
37
18
9
57
130
47
106
251
253
34
187
249
224
131
247
223
223
187
23
168
172
92
190
124
205
26
218
143
19
27
75
208
53
53
5
140
143
19
173
107
108
60
124
184
190
158
104
236
212
20
80
80
80
88
120
251
237
4
97
81
81
128
203
69
189
100
239
222
119
223
125
227
13
162
159
102
51
176
116
233
29
119
172
94
77
25
237
243
81
5
201
229
226
167
213
58
57
57
57
9
236
222
253
238
187
111
190
73
247
211
104
128
7
30
120
240
193
199
31
39
22
21
26
10
52
53
29
62
220
208
0
156
56
241
201
39
71
143
138
24
207
29
239
245
82
239
74
77
213
235
51
51
197
113
229
229
229
229
153
76
98
160
57
36
95
221
19
62
173
221
176
2
0
194
104
222
92
1
128
48
152
154
42
167
157
10
133
66
33
151
3
227
227
227
227
163
163
192
251
239
55
52
188
243
14
96
50
17
93
141
136
136
140
140
138
2
252
126
175
215
235
5
82
82
210
210
244
122
96
254
252
249
243
11
11
69
214
195
3
21
20
68
236
202
106
181
90
215
172
33
22
114
248
48
80
89
89
85
117
239
189
0
165
2
65
5
167
171
114
57
112
242
228
169
83
199
143
139
153
186
114
229
93
119
221
119
31
16
17
17
17
161
213
210
253
45
22
96
193
2
98
59
39
79
82
69
239
223
255
222
123
181
181
180
139
195
108
6
250
250
76
166
158
30
113
113
62
62
62
62
62
49
145
252
179
103
15
176
122
245
55
190
241
192
3
87
78
252
8
242
104
81
255
115
7
224
234
10
160
29
9
226
121
175
151
160
70
16
136
95
243
161
242
73
121
100
100
100
100
116
52
209
203
205
155
73
42
232
236
20
33
166
181
149
28
249
240
195
235
215
191
253
54
209
207
208
80
154
217
90
44
34
230
251
253
52
176
232
232
152
24
157
14
56
119
174
187
187
163
67
132
44
142
245
82
41
177
177
64
64
16
2
1
224
244
233
246
246
99
199
0
173
86
171
141
142
6
22
46
92
184
176
184
24
232
238
238
238
62
115
70
196
126
165
82
169
84
169
168
121
22
22
2
7
15
30
56
176
123
55
240
216
99
79
60
241
243
159
3
82
41
245
166
164
164
132
132
228
100
210
148
252
126
96
211
166
231
159
127
234
41
177
87
57
157
52
51
230
198
89
227
44
86
192
127
54
206
2
40
234
20
8
30
0
149
10
208
235
245
250
121
243
8
26
100
50
160
164
164
164
164
162
66
228
207
34
116
80
83
229
153
198
51
200
235
165
109
41
124
219
73
72
72
72
72
120
56
53
57
106
122
83
83
83
83
226
121
185
156
216
17
39
5
93
93
93
93
167
78
1
106
117
84
84
84
20
237
47
242
251
197
25
110
32
64
106
43
63
78
72
72
74
74
78
166
125
77
139
22
209
134
172
241
113
241
119
211
211
164
49
185
92
30
143
211
41
206
15
174
54
198
232
250
47
92
1
92
58
184
210
229
226
39
113
25
58
230
251
118
120
61
204
108
142
94
47
137
97
156
54
122
60
148
225
129
0
241
121
137
36
36
132
40
35
7
141
43
43
142
242
26
88
176
128
28
243
232
163
143
61
246
211
159
138
162
155
88
125
244
183
74
21
30
30
17
1
212
212
84
87
87
85
137
129
33
89
66
116
92
32
64
207
227
52
216
239
247
249
136
134
18
68
242
74
228
172
139
63
135
239
65
226
205
252
106
243
251
137
109
125
90
187
70
13
229
21
192
143
37
18
162
113
60
227
249
3
102
58
140
170
128
154
176
248
34
34
235
161
193
243
45
85
226
14
55
154
105
18
123
153
121
47
162
150
60
83
169
201
123
189
62
159
211
73
19
156
233
105
192
98
177
88
38
39
233
211
98
17
117
127
151
203
233
116
58
69
205
137
79
24
121
115
189
242
41
244
94
180
211
78
36
21
87
219
204
132
224
91
26
37
18
137
228
63
85
192
213
79
185
145
93
183
2
236
118
187
221
225
0
122
122
186
187
59
59
129
208
208
176
48
149
10
112
58
93
46
135
131
180
144
176
48
130
28
141
230
127
111
246
31
230
213
156
30
10
130
184
227
140
6
66
11
38
188
153
115
71
92
25
86
186
146
7
136
127
210
191
197
74
164
127
93
91
137
28
10
102
74
10
252
9
28
234
120
37
48
198
119
232
241
223
112
89
143
143
67
16
164
82
82
71
149
74
32
60
156
228
109
155
109
122
122
166
20
33
151
147
118
245
185
3
192
43
160
164
164
164
100
201
18
198
158
125
246
183
191
125
242
73
192
96
40
47
55
26
169
185
197
197
1
109
109
109
109
45
45
192
161
67
31
124
176
119
47
101
166
197
114
45
47
231
159
98
142
83
8
120
83
227
123
61
105
144
51
115
147
127
123
181
131
174
12
16
119
146
68
66
21
230
247
211
117
34
4
138
144
64
247
191
178
82
249
252
132
107
85
87
194
223
204
204
166
10
25
25
25
30
190
112
1
104
106
250
232
163
61
123
128
248
248
196
196
140
12
146
88
150
46
5
182
110
221
186
117
203
22
98
141
159
134
142
94
183
2
120
32
138
138
138
138
22
47
102
172
161
161
174
238
157
119
136
206
69
68
0
14
199
244
244
248
56
45
33
154
76
52
65
107
111
23
4
189
94
175
215
235
105
248
60
195
105
224
28
123
103
230
24
160
84
146
74
26
26
74
252
60
16
16
187
11
209
92
42
106
17
242
174
44
124
158
167
51
123
18
253
150
36
10
169
148
36
144
168
168
168
40
173
86
252
126
124
156
18
99
106
202
102
179
90
197
64
243
138
16
195
207
37
16
186
79
102
102
102
102
102
38
144
146
114
219
109
241
241
64
93
29
105
100
3
3
3
3
253
253
34
251
26
29
29
25
25
26
186
49
33
189
110
15
224
129
104
107
107
107
59
126
92
16
12
6
131
193
96
0
70
70
70
70
70
70
4
97
124
124
124
124
120
88
116
188
209
104
52
26
141
140
241
166
37
149
114
154
200
177
149
6
198
213
83
167
147
232
224
241
227
159
124
210
210
2
212
214
110
223
254
202
43
192
129
3
13
13
59
119
82
96
123
123
69
201
130
79
124
102
230
231
204
230
205
195
51
115
65
71
161
0
26
27
63
252
240
192
1
224
229
151
95
124
241
87
191
2
106
107
183
109
251
211
159
128
150
150
198
198
186
58
106
182
110
183
184
69
145
247
42
78
51
35
35
213
106
141
70
172
148
176
176
176
176
176
48
224
204
153
51
103
206
156
33
205
170
187
91
244
15
5
66
244
223
23
174
128
235
29
55
52
52
52
52
52
92
123
94
167
211
233
116
58
198
246
239
223
191
127
231
78
96
197
138
175
127
253
155
223
20
37
132
136
8
181
58
42
138
214
102
55
111
6
98
99
227
226
180
90
90
103
216
189
155
42
174
168
136
177
241
113
179
121
112
144
28
161
86
139
226
152
8
73
87
238
154
230
21
198
155
238
212
20
65
226
246
237
111
189
245
242
203
64
103
103
103
103
71
199
181
239
107
52
86
86
42
149
140
69
71
71
71
199
199
83
6
199
196
0
23
47
246
247
155
76
192
139
47
254
225
15
79
61
69
155
143
135
135
105
102
173
82
17
205
237
234
186
190
127
174
38
51
159
217
174
142
224
103
61
94
182
108
217
178
101
203
24
227
243
137
212
212
212
212
180
52
198
52
26
141
70
163
97
108
237
218
181
107
215
174
189
254
239
43
42
42
42
42
42
24
203
200
200
200
200
206
102
108
249
242
21
43
214
172
97
108
223
190
186
186
211
167
25
219
181
107
207
158
143
63
102
236
237
183
119
237
58
122
148
177
218
218
29
59
142
28
97
108
207
158
247
222
107
111
103
140
32
237
211
191
111
124
124
124
124
124
60
237
170
208
233
24
75
73
73
78
78
75
19
207
87
85
85
85
45
95
254
249
253
113
211
2
49
219
129
187
250
56
45
45
45
45
45
141
49
190
155
130
87
152
86
171
213
106
181
140
169
213
106
181
90
45
254
231
59
189
94
175
79
79
103
44
37
37
37
37
37
133
177
217
126
159
91
230
248
155
29
184
207
122
124
245
46
132
255
183
142
157
109
199
207
246
253
110
117
197
126
101
109
182
95
252
102
59
234
191
214
209
183
218
254
207
100
232
156
205
217
156
205
217
151
111
255
3
80
244
143
206
188
145
181
235
0
0
0
0
73
69
78
68
174
66
96
130
)! !
!DrGIcons class methodsFor: 'accessing'!
middle
^self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 48 0 0 0 48 16 6 0 0 0 7 146 37 196 0 0 0 6 98 75 71 68 255 255 255 255 255 255 9 88 247 220 0 0 0 9 112 72 89 115 0 0 0 72 0 0 0 72 0 70 201 107 62 0 0 1 193 73 68 65 84 120 218 237 154 75 170 131 48 20 134 79 46 119 168 139 112 224 182 164 224 172 148 186 153 174 197 81 119 210 81 161 123 232 68 200 29 200 69 140 143 228 228 97 212 252 223 36 40 88 234 255 229 101 56 68 0 0 0 0 56 35 82 142 91 160 242 19 230 103 17 184 41 191 118 143 45 5 44 68 236 23 58 26 158 71 64 44 49 199 29 113 129 166 32 96 138 165 0 243 30 93 215 117 93 215 67 15 85 175 185 84 85 85 85 213 113 123 188 103 212 93 206 114 235 26 252 63 243 2 146 19 98 30 188 218 134 25 1 199 21 192 156 130 76 95 116 58 69 189 94 101 89 150 68 143 71 150 101 89 236 215 222 15 158 23 97 33 198 61 92 136 203 37 207 243 156 232 253 238 186 174 35 250 124 218 182 109 137 190 223 166 105 154 227 246 220 72 44 77 45 250 197 182 23 33 229 243 89 20 69 33 101 63 34 164 212 137 88 159 114 116 109 2 232 130 143 35 34 1 184 193 135 17 145 160 0 215 224 213 158 204 21 113 182 93 144 53 220 15 44 53 184 48 34 84 78 40 230 126 191 221 174 87 251 47 91 223 34 230 73 104 74 178 37 140 8 4 207 198 143 136 105 240 56 51 98 194 21 209 223 69 240 222 209 137 232 25 130 183 91 35 128 22 93 240 126 22 107 96 200 16 124 152 93 19 88 96 57 120 136 8 138 121 240 16 17 8 110 240 16 17 8 221 182 18 34 118 2 68 236 4 156 53 237 132 109 206 154 32 64 139 169 136 254 74 23 48 4 88 195 61 226 48 107 1 155 117 17 124 1 190 10 206 146 67 21 49 14 114 187 74 191 228 153 15 114 59 17 168 231 31 225 218 163 249 101 248 40 79 39 34 151 146 203 245 251 122 32 192 136 105 201 101 127 29 251 127 157 6 251 146 75 44 198 158 112 45 56 3 150 184 6 15 17 158 64 176 145 112 173 244 3 7 231 15 70 90 152 213 40 169 61 128 0 0 0 0 73 69 78 68 174 66 96 130)! !
!DrGIcons class methodsFor: 'accessing'!
move
^self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 48 0 0 0 48 16 6 0 0 0 7 146 37 196 0 0 0 6 98 75 71 68 255 255 255 255 255 255 9 88 247 220 0 0 0 9 112 72 89 115 0 0 0 72 0 0 0 72 0 70 201 107 62 0 0 1 153 73 68 65 84 120 218 237 155 73 110 195 48 12 69 227 162 183 211 9 180 11 130 220 77 39 208 249 210 77 181 8 81 69 19 39 169 255 109 12 35 137 197 255 105 81 244 144 219 13 0 0 0 0 0 116 16 66 8 33 188 94 214 113 120 99 214 151 111 238 1 115 206 57 231 235 178 54 68 10 238 19 112 58 1 189 1 238 158 16 233 25 255 37 117 224 221 141 215 210 193 158 128 83 140 215 210 181 156 0 26 216 169 139 180 155 210 218 50 184 124 126 74 34 122 245 204 234 101 207 224 41 221 145 150 14 49 67 118 77 132 118 220 98 93 208 168 64 107 172 226 18 63 19 91 194 172 103 132 117 124 106 194 117 132 210 227 215 143 103 109 124 65 173 4 181 4 173 149 128 254 223 121 49 190 160 190 6 212 4 126 22 94 12 163 91 173 241 229 112 219 141 188 51 106 184 223 46 139 162 62 3 164 137 49 198 24 253 117 89 219 241 183 145 181 82 180 94 154 192 47 212 248 247 253 209 45 152 102 205 120 36 130 137 182 193 159 19 5 22 233 53 158 126 31 48 209 54 190 181 15 8 189 247 215 71 141 174 25 127 218 243 137 105 168 17 53 99 164 140 247 154 8 183 119 67 139 177 41 165 148 210 117 209 125 233 241 181 16 187 18 158 21 254 124 62 30 247 251 186 241 173 113 122 227 148 70 237 145 100 175 33 210 120 139 207 205 237 232 255 22 71 129 45 16 60 3 158 163 123 6 140 214 74 239 198 207 198 201 189 102 12 151 32 26 128 155 23 150 22 105 189 96 38 181 88 31 211 206 113 163 165 151 109 17 182 110 231 118 213 193 222 5 237 154 8 171 184 217 254 31 176 123 9 114 255 146 177 187 128 224 3 0 0 0 0 192 198 252 0 102 116 72 96 211 171 62 8 0 0 0 0 73 69 78 68 174 66 96 130)! !
!DrGIcons class methodsFor: 'accessing'!
moveObject
^self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 24 0 0 0 24 8 2 0 0 0 111 21 170 175 0 0 0 9 112 72 89 115 0 0 11 19 0 0 11 19 1 0 154 156 24 0 0 3 197 73 68 65 84 56 203 205 149 219 107 28 85 28 199 127 51 231 204 206 236 165 201 54 187 221 100 215 166 209 104 188 164 165 193 75 189 165 40 74 109 73 74 8 40 136 79 17 250 32 69 240 81 241 193 23 255 13 125 146 22 4 219 162 105 170 62 72 17 74 235 173 52 77 27 67 211 244 146 205 50 187 217 251 236 206 204 206 204 185 205 241 33 208 37 65 155 60 244 193 207 243 151 15 191 239 57 156 223 81 164 148 240 40 80 225 17 129 119 152 59 250 209 124 143 30 211 176 202 5 56 140 249 150 109 123 246 245 243 199 186 9 185 3 222 154 249 253 212 108 213 44 147 142 207 93 143 175 21 131 175 207 20 15 189 119 233 233 163 103 31 100 182 23 189 48 117 254 199 75 245 82 149 84 155 180 209 98 213 38 45 85 137 89 14 190 255 101 253 153 137 179 185 131 95 110 196 30 86 237 205 183 243 134 210 84 227 70 58 169 149 107 76 195 10 194 32 56 48 46 153 16 153 221 26 235 248 156 213 182 57 163 241 241 149 190 30 45 26 21 133 102 121 238 215 194 232 72 191 142 84 69 129 48 148 52 12 5 97 11 203 117 65 44 230 175 63 76 52 54 182 208 211 151 192 88 134 216 114 156 149 31 102 229 226 232 176 107 94 185 124 225 243 227 51 95 165 250 95 42 212 189 252 106 149 249 235 204 41 255 167 104 242 113 48 98 17 61 136 128 130 72 39 17 58 229 6 15 232 13 59 29 156 243 8 71 8 31 152 248 54 112 37 101 21 226 175 113 97 253 187 104 98 64 244 15 160 38 173 135 24 252 48 17 18 136 134 189 245 218 181 192 94 213 163 46 8 14 0 141 252 13 9 156 122 197 192 94 22 172 189 85 116 226 139 139 157 133 199 162 195 123 244 148 164 5 51 38 4 81 153 8 152 161 140 170 116 201 181 255 220 181 63 199 125 27 0 28 235 55 224 140 179 150 160 14 245 204 77 162 153 79 127 238 77 196 219 54 142 233 160 42 42 230 110 195 206 235 200 17 4 179 0 18 202 225 80 211 24 51 65 208 233 169 201 217 185 159 84 188 75 48 123 235 19 121 247 227 115 42 86 49 82 73 199 226 224 217 190 18 215 211 129 115 183 221 250 187 233 220 33 158 213 114 254 176 91 115 217 108 22 84 24 25 26 12 5 15 185 83 171 86 18 241 216 38 17 37 65 200 67 46 66 139 221 243 220 82 187 99 101 244 215 148 48 225 186 183 3 111 193 37 75 46 185 224 216 246 228 228 59 32 229 129 103 135 1 148 207 62 57 153 78 167 79 126 248 193 233 211 167 186 213 28 171 162 27 8 69 52 137 42 101 47 136 42 54 129 190 92 98 202 164 134 229 93 21 180 14 0 29 167 37 165 20 180 99 54 218 194 107 228 134 246 57 173 154 145 76 155 166 217 157 200 106 220 179 42 69 199 169 169 189 194 229 55 235 244 74 213 191 220 38 215 176 150 233 143 140 247 168 99 0 64 41 221 221 19 167 190 119 228 141 215 87 110 47 77 31 63 86 41 21 78 188 63 29 215 194 238 68 110 179 196 57 37 180 19 207 238 105 212 60 187 115 87 1 13 88 60 20 10 227 62 13 171 8 192 247 188 231 159 27 94 47 87 51 201 56 165 20 243 78 181 92 77 166 50 149 82 177 43 162 196 246 138 101 215 50 141 88 58 154 74 33 22 247 218 235 156 23 4 35 146 10 33 85 0 200 23 10 139 11 243 47 31 28 17 82 18 223 87 85 5 35 124 245 250 197 59 247 215 54 68 202 198 134 236 27 216 79 2 11 33 61 18 77 98 205 64 88 231 196 35 190 37 67 209 110 220 7 128 39 247 13 142 31 126 117 111 110 96 111 54 29 248 68 215 35 24 161 191 230 23 191 249 238 12 167 178 43 2 128 100 102 132 6 118 40 184 162 34 140 12 85 139 168 42 182 42 203 15 46 56 149 76 190 114 232 197 236 64 63 132 52 106 232 102 217 186 121 235 86 97 53 207 55 12 114 199 32 13 48 64 2 33 3 64 7 0 128 167 158 24 66 26 108 191 143 182 32 25 84 204 130 237 56 148 50 35 166 71 227 137 220 208 224 70 175 77 213 254 47 191 200 63 151 156 177 64 253 10 252 215 0 0 0 0 73 69 78 68 174 66 96 130)! !
!DrGIcons class methodsFor: 'accessing'!
open
^self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 48 0 0 0 48 8 6 0 0 0 87 2 249 135 0 0 0 1 115 82 71 66 0 174 206 28 233 0 0 0 6 98 75 71 68 0 255 0 255 0 255 160 189 167 147 0 0 0 9 112 72 89 115 0 0 11 19 0 0 11 19 1 0 154 156 24 0 0 0 7 116 73 77 69 7 219 8 3 7 31 18 173 68 203 48 0 0 10 42 73 68 65 84 104 222 237 152 105 108 92 215 117 199 127 247 190 121 51 67 206 198 25 110 34 69 73 164 101 203 148 69 201 218 98 73 222 106 179 33 100 201 78 209 216 49 156 184 48 210 162 69 139 194 49 90 7 48 144 124 8 2 39 64 81 59 95 220 54 112 55 55 70 18 183 104 221 196 73 92 27 85 1 215 218 44 137 182 36 139 212 70 106 27 238 228 112 246 125 121 219 205 135 161 40 185 176 3 83 142 0 163 224 31 184 120 247 189 119 31 222 255 127 207 57 247 222 115 96 25 203 88 198 50 150 241 25 32 110 228 155 174 103 241 182 151 252 62 205 109 6 106 5 148 85 109 180 189 43 51 149 147 111 82 224 50 38 224 124 30 5 136 13 79 208 213 217 219 210 19 110 110 124 48 220 28 218 238 243 4 219 45 101 40 211 172 97 91 204 204 79 229 7 19 177 204 113 39 146 27 30 124 158 244 231 69 128 184 229 113 130 27 182 118 63 176 170 171 253 15 123 86 247 108 246 250 181 118 209 80 211 209 108 205 193 82 40 148 116 60 170 90 114 138 165 108 53 57 151 158 58 122 121 108 236 159 223 249 86 241 125 192 188 153 2 52 128 223 249 46 222 137 131 88 31 55 160 239 79 233 221 117 207 166 63 217 178 113 227 115 183 246 174 217 165 135 43 77 5 109 66 79 217 81 153 178 162 34 103 207 136 172 61 35 139 42 38 29 119 209 27 12 251 35 45 193 142 62 175 29 90 229 52 102 230 102 134 107 147 55 211 165 180 157 207 210 208 216 44 159 88 255 123 238 21 242 1 59 158 122 7 99 225 157 220 244 251 45 183 245 63 188 245 185 29 155 119 253 81 120 133 183 163 40 102 68 214 156 21 53 39 143 233 84 177 177 80 56 128 194 81 22 134 83 162 104 39 144 110 75 134 195 145 206 72 91 112 149 127 99 126 54 186 191 54 6 168 155 34 160 107 23 122 192 23 121 106 93 247 250 111 132 221 158 150 192 206 76 108 234 29 18 221 143 178 122 247 158 123 254 124 235 157 155 159 12 180 234 145 148 53 46 12 85 198 84 21 170 78 1 75 85 235 19 171 192 37 221 72 52 16 10 133 162 108 231 208 220 142 30 14 180 174 17 150 203 155 45 207 31 75 95 38 255 113 238 217 228 165 55 224 165 167 106 16 83 160 52 129 71 129 253 105 5 184 6 15 97 61 246 72 199 200 125 235 190 242 117 233 82 127 57 60 113 228 190 149 175 124 248 186 199 136 116 109 222 186 241 15 2 205 222 112 214 156 0 192 82 53 74 118 154 154 83 2 165 240 106 1 2 90 155 242 203 118 71 216 186 99 83 147 101 82 178 224 196 68 222 138 35 188 46 173 101 101 224 193 238 109 145 129 203 137 244 107 156 196 116 187 8 174 14 241 112 79 19 143 119 5 24 232 88 213 233 183 109 155 185 153 249 132 174 225 215 4 13 231 226 252 240 200 20 207 124 42 1 156 196 206 14 36 199 115 229 120 233 246 181 125 161 251 131 123 239 93 221 178 110 179 101 27 170 115 101 135 63 99 77 10 144 24 78 153 188 57 79 205 41 2 138 144 187 131 22 122 85 33 101 166 198 226 241 211 217 116 54 233 247 53 69 90 86 4 214 55 183 251 58 147 92 22 69 59 73 184 41 28 110 109 109 122 164 55 147 14 118 223 202 64 87 144 47 6 66 65 207 182 129 1 118 238 221 75 165 84 226 223 95 124 145 80 176 177 245 182 45 91 136 158 57 67 48 151 95 251 169 45 0 56 53 171 58 155 43 228 114 21 171 208 81 19 121 177 166 171 219 167 148 67 193 142 11 16 88 170 74 222 158 195 80 37 52 225 34 172 119 17 52 187 107 83 99 201 51 151 70 162 127 63 117 41 182 127 222 172 101 130 210 19 185 173 119 229 151 238 216 188 250 217 240 170 53 171 147 206 37 97 187 74 174 176 87 251 242 174 181 238 71 119 110 189 159 29 123 247 210 119 247 221 204 70 163 252 236 165 151 200 167 82 60 250 204 51 108 233 239 71 8 193 75 79 63 205 209 75 239 159 94 138 0 52 95 54 94 49 75 51 110 209 176 222 144 69 42 42 35 4 2 77 106 72 160 224 196 176 168 160 187 220 52 106 97 66 214 45 106 124 52 113 248 240 209 193 151 7 15 85 222 226 100 125 169 12 184 107 33 86 69 125 218 238 172 182 227 169 93 34 220 186 2 225 64 199 173 171 197 221 127 253 199 244 111 253 34 133 76 134 159 124 239 59 156 59 118 130 175 62 247 28 219 6 6 16 88 80 56 1 197 83 196 39 162 164 203 44 77 192 153 203 148 119 108 74 79 59 54 74 115 185 132 92 216 30 148 114 200 91 49 202 42 141 203 229 70 8 65 155 188 93 197 38 139 227 231 79 93 124 121 240 141 202 127 55 197 233 233 238 224 177 181 77 60 214 220 200 54 165 192 87 244 81 78 26 248 219 130 152 90 137 134 80 3 150 53 133 74 254 23 255 241 87 63 101 244 116 138 111 254 227 63 209 185 118 45 148 47 64 250 127 192 46 99 208 70 42 150 32 93 89 162 128 244 191 82 74 245 207 70 13 211 176 220 158 6 221 82 85 20 80 181 227 20 156 57 92 46 23 160 227 145 126 244 90 200 154 137 143 76 79 28 158 190 227 113 63 223 15 183 176 1 160 169 173 141 187 30 122 136 29 123 246 224 106 14 240 243 51 63 69 147 6 72 11 71 214 176 74 195 56 165 30 38 174 228 232 255 218 147 117 242 169 183 161 114 177 78 195 21 34 17 211 113 20 70 174 198 232 146 4 0 78 62 85 187 82 169 84 11 141 193 64 196 118 12 76 85 38 109 78 96 170 50 82 104 0 216 212 80 141 37 215 214 190 47 220 19 122 74 191 47 115 60 202 166 85 219 233 223 253 101 122 183 111 71 88 9 40 143 82 204 158 39 104 207 80 52 219 113 121 189 216 182 134 87 132 40 150 221 36 231 50 236 124 248 97 176 11 96 204 130 22 2 161 129 208 24 187 156 37 91 101 196 118 62 126 83 253 77 2 84 124 38 57 59 155 24 47 52 183 222 25 1 69 222 154 35 103 205 162 80 8 177 224 82 216 196 173 243 162 169 101 165 216 178 103 23 249 109 219 144 181 42 25 239 113 42 83 31 208 40 107 32 116 26 164 70 179 108 36 17 175 224 105 9 80 204 166 144 68 120 229 7 239 210 181 110 29 145 21 43 160 114 5 180 64 157 60 26 8 201 133 225 33 82 75 240 127 0 121 181 147 203 171 120 42 19 79 73 165 59 166 170 146 54 199 235 155 149 0 181 176 137 74 116 26 100 19 142 13 142 52 104 137 180 82 85 101 246 93 56 204 233 185 57 28 25 2 87 19 154 39 204 214 142 181 172 53 220 216 231 230 41 29 153 230 245 239 189 133 191 181 155 63 123 225 133 250 15 141 121 208 252 215 154 222 194 165 161 243 164 170 75 19 112 213 2 248 219 237 185 92 57 53 105 89 230 166 2 113 89 180 147 8 161 33 133 70 163 108 194 77 0 175 19 86 170 228 33 151 204 138 28 22 229 210 17 214 55 134 232 191 117 59 157 225 8 210 29 196 52 97 100 104 146 225 99 23 25 26 188 0 186 198 157 119 223 203 238 215 94 164 125 205 154 250 207 106 51 224 148 235 196 145 32 36 21 195 71 38 30 39 81 226 216 13 9 200 155 57 35 153 75 206 229 42 73 167 234 201 227 147 173 202 39 90 176 13 97 219 69 173 154 78 231 18 209 11 103 179 165 147 99 235 238 218 116 151 111 247 151 190 66 179 227 195 231 109 68 211 116 20 26 191 252 201 65 222 121 227 8 29 107 58 185 243 254 123 249 139 191 253 6 171 215 247 45 68 89 13 140 57 48 211 96 101 65 243 45 186 14 72 174 156 155 192 114 40 207 23 249 224 134 4 156 246 83 187 61 95 56 147 45 164 13 191 236 210 138 105 85 153 205 20 167 38 231 162 99 137 249 228 177 115 251 83 51 83 31 86 228 35 17 231 133 59 30 184 205 119 75 103 7 228 219 64 184 64 104 252 236 31 222 102 116 104 130 111 189 250 42 93 235 122 65 217 96 231 160 50 6 118 22 156 234 53 194 178 97 33 112 229 130 5 52 78 29 60 78 172 200 123 142 90 218 241 123 81 0 207 227 164 190 147 60 123 120 104 223 126 77 121 198 231 115 211 231 11 25 227 120 60 81 157 204 228 139 133 137 55 197 102 208 90 245 136 163 185 61 158 133 163 96 61 8 199 70 166 56 117 100 132 111 255 248 53 2 145 48 84 39 192 136 213 211 141 171 68 101 227 66 192 202 235 136 215 175 182 35 57 241 238 123 204 22 57 176 212 211 168 235 186 190 243 238 104 246 104 190 148 125 250 196 235 36 153 166 246 209 115 188 20 0 82 162 233 94 111 157 220 130 27 28 122 251 3 6 158 250 58 129 72 4 140 56 88 105 144 222 143 18 254 63 164 175 239 143 143 68 169 150 74 204 230 217 255 89 4 192 127 98 159 128 169 143 31 170 28 16 72 137 174 187 221 117 2 210 71 173 106 48 114 242 60 95 253 246 247 235 67 172 204 130 139 124 50 97 132 88 120 38 64 72 6 247 29 160 104 48 30 47 241 254 103 19 240 155 51 203 26 128 75 224 210 92 174 58 9 217 192 201 131 31 112 215 67 123 240 52 52 212 3 84 234 159 76 120 145 248 213 190 32 155 200 114 228 205 183 24 77 242 163 27 73 122 228 167 31 234 24 11 73 180 182 152 141 74 15 131 251 14 241 224 19 79 212 103 223 169 128 240 130 244 92 215 220 32 174 94 23 154 212 65 232 56 142 198 191 253 224 111 48 77 171 118 33 205 171 55 146 145 45 193 2 212 164 64 91 44 4 8 73 124 38 73 176 185 133 112 91 91 253 104 32 221 11 175 175 205 240 71 251 98 209 109 166 47 69 249 249 15 95 230 220 177 65 251 127 163 124 173 84 99 250 38 11 16 134 20 74 191 118 171 113 230 216 135 252 238 147 79 214 103 95 217 32 244 79 32 44 22 151 203 232 153 115 188 253 202 191 112 246 232 81 170 22 137 247 38 121 122 44 203 47 110 52 39 94 146 5 52 41 92 215 123 159 66 208 211 215 87 95 227 133 107 113 118 175 85 107 234 164 103 174 68 25 58 112 144 161 3 7 152 28 29 69 129 117 118 158 191 59 57 199 243 134 77 238 179 36 245 75 17 96 104 40 237 154 5 36 61 125 27 175 173 180 66 95 20 96 89 14 87 134 135 25 58 112 144 225 67 135 72 205 206 82 49 73 207 20 56 52 149 231 87 51 121 246 149 77 98 191 141 170 132 107 41 65 44 53 151 14 80 200 100 112 108 135 158 13 27 0 65 181 106 19 61 125 154 75 31 158 226 242 208 16 99 103 207 82 173 26 181 185 146 24 158 206 137 253 211 5 126 145 46 47 125 137 252 173 187 80 197 80 57 211 161 124 248 141 55 26 117 183 155 201 209 81 46 157 58 197 244 197 139 148 77 167 144 40 138 209 88 81 12 199 138 28 140 151 217 103 59 42 121 147 202 65 55 90 220 213 250 87 5 213 125 235 91 213 238 70 157 112 186 202 212 124 81 158 143 23 57 150 169 58 39 64 197 128 210 231 184 58 45 66 32 123 0 31 168 60 168 56 168 36 75 40 68 45 99 25 203 88 198 50 150 177 140 255 79 248 53 249 132 185 253 79 213 252 73 0 0 0 0 73 69 78 68 174 66 96 130)! !
!DrGIcons class methodsFor: 'accessing'!
parallel
^self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 48 0 0 0 48 16 6 0 0 0 7 146 37 196 0 0 0 6 98 75 71 68 255 255 255 255 255 255 9 88 247 220 0 0 0 9 112 72 89 115 0 0 0 72 0 0 0 72 0 70 201 107 62 0 0 1 160 73 68 65 84 120 218 237 217 33 142 194 64 20 198 241 233 250 17 40 116 69 19 36 2 138 168 196 115 3 154 106 18 210 27 204 45 240 156 1 13 178 130 130 64 146 112 2 20 2 129 124 136 221 102 67 147 102 187 48 125 125 109 191 191 33 164 1 166 239 151 161 98 148 66 8 49 182 94 39 201 102 67 84 247 58 164 244 197 245 67 243 185 49 203 37 81 154 158 78 199 35 32 178 216 0 14 135 36 217 239 149 186 223 175 215 219 77 41 64 124 231 112 255 224 96 48 157 250 62 209 120 28 4 147 137 82 90 247 251 189 158 82 190 63 28 142 70 74 69 81 16 204 102 14 251 186 234 138 109 7 24 99 140 49 68 231 243 110 151 166 142 131 29 193 84 54 248 162 247 217 142 200 158 17 139 197 106 101 12 17 32 44 7 8 33 189 14 62 255 10 136 138 43 26 60 17 118 4 107 197 131 7 196 79 143 71 28 199 177 237 27 204 127 95 241 224 59 11 177 221 186 174 235 18 93 46 158 231 121 68 118 32 202 127 190 243 16 81 164 181 214 68 118 32 222 31 8 32 62 130 176 55 128 206 65 132 97 24 134 225 239 194 255 7 81 221 13 183 30 34 63 248 207 32 170 11 16 128 224 9 16 66 2 132 144 0 33 36 64 8 9 16 66 2 132 144 0 33 36 64 8 9 16 66 2 132 144 154 9 209 194 51 107 217 16 29 58 179 110 10 4 254 154 88 33 236 159 89 215 61 223 210 213 11 97 255 204 186 232 186 248 120 33 170 59 179 110 220 224 243 85 11 193 119 102 221 248 236 66 240 157 89 183 46 89 15 235 14 7 8 33 1 66 72 128 16 18 32 132 244 46 68 221 235 110 93 101 33 138 174 35 75 253 5 129 193 51 133 193 11 9 131 71 47 61 1 49 101 139 124 116 26 58 40 0 0 0 0 73 69 78 68 174 66 96 130) ! !
!DrGIcons class methodsFor: 'accessing'!
perpendicular
^ self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 48 0 0 0 48 16 6 0 0 0 7 146 37 196 0 0 0 6 98 75 71 68 255 255 255 255 255 255 9 88 247 220 0 0 0 9 112 72 89 115 0 0 0 72 0 0 0 72 0 70 201 107 62 0 0 2 43 73 68 65 84 120 218 237 154 177 106 194 64 24 199 191 136 171 248 2 5 201 32 244 9 220 83 55 103 87 131 155 80 16 103 151 27 178 244 5 218 221 193 39 112 112 210 209 193 232 208 177 80 40 20 92 74 133 34 25 186 8 215 233 40 124 114 36 198 187 220 93 242 253 22 137 201 93 46 191 63 201 229 114 7 64 16 4 65 16 4 65 16 4 65 16 4 65 84 158 223 223 201 100 50 225 220 116 59 42 199 106 229 251 190 207 249 251 123 187 221 110 115 78 65 220 198 108 182 217 44 22 114 127 53 252 199 124 126 60 30 143 0 159 159 231 243 249 12 112 56 44 151 203 165 237 119 132 125 237 18 226 227 248 245 117 191 7 24 12 24 27 143 47 219 89 187 44 152 36 73 226 121 110 6 97 30 44 62 73 190 190 126 126 0 118 187 205 102 187 189 60 254 34 128 48 12 195 48 228 156 130 184 142 52 241 111 111 235 117 28 123 158 180 2 33 94 182 61 28 54 26 141 6 231 118 246 17 230 206 47 196 63 62 190 188 48 198 185 120 212 220 223 119 187 157 206 127 187 24 99 140 177 12 237 116 51 136 226 207 155 87 124 73 130 16 245 167 253 58 40 30 227 102 16 234 41 92 60 198 141 32 212 99 92 60 198 238 32 212 97 157 120 76 89 131 176 94 60 166 44 65 56 39 30 99 54 136 252 229 157 23 143 41 54 8 124 124 246 242 165 19 143 209 27 68 254 253 165 23 143 81 27 68 254 59 164 114 226 49 166 250 136 202 139 199 20 21 4 137 79 65 87 16 36 254 74 84 5 65 226 111 36 111 16 36 94 49 89 131 32 241 154 145 5 145 38 94 60 154 92 17 239 221 94 133 94 132 248 135 135 209 168 223 7 144 205 185 62 63 127 124 124 127 3 180 90 245 122 189 14 112 119 215 235 245 122 0 79 79 205 102 179 9 16 69 81 20 69 158 117 215 91 187 189 10 189 164 137 23 147 221 178 197 3 211 233 233 116 58 153 190 10 57 214 6 144 117 149 65 16 4 65 16 208 42 14 101 100 237 92 133 120 217 182 43 159 193 173 33 239 91 13 22 239 234 124 132 49 84 189 78 150 101 98 168 48 116 189 199 231 13 194 180 143 194 209 61 128 202 26 132 108 127 105 193 34 117 143 92 211 130 168 140 120 76 154 104 213 35 87 18 47 161 232 79 6 36 94 130 173 223 106 116 243 7 21 204 94 20 55 57 135 172 0 0 0 0 73 69 78 68 174 66 96 130)! !
!DrGIcons class methodsFor: 'accessing'!
pointDefinedByCoordinates
^self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 48 0 0 0 48 16 6 0 0 0 7 146 37 196 0 0 0 6 98 75 71 68 255 255 255 255 255 255 9 88 247 220 0 0 0 9 112 72 89 115 0 0 0 72 0 0 0 72 0 70 201 107 62 0 0 1 180 73 68 65 84 120 218 237 154 193 205 194 48 12 133 211 95 140 192 22 12 193 0 156 184 230 10 136 9 58 69 87 224 156 43 39 6 96 8 182 96 135 254 39 11 41 81 112 210 66 253 76 252 93 162 170 45 181 223 139 157 138 198 57 195 48 12 173 140 163 116 4 218 233 166 221 150 19 190 155 248 123 237 82 41 88 233 140 55 35 22 194 90 208 92 254 164 3 104 157 85 221 229 54 227 193 48 67 230 98 45 72 24 51 64 152 70 215 128 56 15 185 215 230 202 10 160 64 181 190 231 227 77 160 196 128 221 174 239 183 91 188 64 203 160 184 227 17 151 108 5 144 17 186 13 33 112 255 58 73 2 224 4 63 30 135 225 249 148 14 59 101 191 119 238 241 168 78 191 243 222 123 239 199 49 132 16 66 72 143 23 79 36 158 249 239 13 65 173 140 92 43 122 141 36 52 221 17 31 139 81 215 114 0 2 126 27 151 98 35 234 18 69 161 92 248 120 84 34 60 234 91 70 169 208 233 245 74 132 231 18 151 134 23 158 132 190 94 157 219 108 212 183 158 56 113 105 120 225 233 152 12 200 157 87 102 4 110 160 57 97 149 87 0 234 26 240 130 19 150 171 0 101 224 6 206 85 128 116 124 31 2 47 145 243 249 116 58 28 202 43 64 57 250 18 65 51 160 209 239 1 56 52 246 61 0 15 251 36 41 140 25 32 140 173 1 194 216 26 32 140 181 32 97 204 0 97 108 13 16 198 214 0 97 172 5 125 133 242 78 97 6 124 21 222 136 213 212 27 231 93 143 194 82 113 211 115 210 214 157 49 160 180 199 231 126 56 255 192 182 206 243 122 54 215 130 46 151 190 95 175 151 122 26 63 145 103 58 200 205 4 28 114 27 206 110 183 97 184 223 97 182 167 199 130 210 168 181 199 227 243 243 45 136 219 106 9 186 251 27 119 215 131 97 124 148 127 134 246 108 126 47 30 109 160 0 0 0 0 73 69 78 68 174 66 96 130)! !
!DrGIcons class methodsFor: 'accessing'!
polygon
^self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 48 0 0 0 48 16 6 0 0 0 7 146 37 196 0 0 0 6 98 75 71 68 255 255 255 255 255 255 9 88 247 220 0 0 0 9 112 72 89 115 0 0 0 72 0 0 0 72 0 70 201 107 62 0 0 9 92 73 68 65 84 120 218 237 91 107 76 155 101 27 190 74 129 210 195 91 218 66 143 208 150 114 42 39 41 200 32 50 220 208 56 141 75 22 77 22 157 51 51 131 4 231 70 68 102 166 176 17 127 204 68 127 105 162 46 152 37 102 25 78 101 33 217 146 109 49 100 51 134 140 48 53 49 147 127 75 212 132 31 99 39 206 231 210 183 156 74 253 113 231 249 234 247 242 189 225 208 246 165 240 113 253 121 211 62 240 230 121 238 235 62 223 79 129 29 236 64 74 212 214 114 28 199 5 131 236 185 217 251 137 219 236 13 72 5 161 192 11 11 149 74 165 18 184 126 61 43 43 43 43 24 28 25 57 122 244 232 81 233 9 137 223 108 193 68 11 98 26 158 153 153 152 152 152 8 228 230 38 37 37 37 1 46 151 94 175 215 3 193 224 236 236 236 172 244 251 220 182 4 8 161 84 202 229 114 57 224 241 168 213 106 53 224 114 89 44 22 11 160 209 208 103 133 66 165 82 169 164 223 215 182 33 64 76 227 51 50 116 58 157 14 40 40 144 201 100 50 192 225 32 193 3 28 199 113 192 159 127 62 120 240 224 1 80 90 74 150 33 53 182 124 12 88 45 152 122 60 9 9 9 9 64 81 17 9 62 35 163 172 172 172 12 248 226 139 187 119 239 222 5 30 62 244 251 253 126 192 231 27 24 24 24 0 252 254 198 198 198 70 233 98 193 150 37 64 76 240 121 121 228 82 94 125 53 53 53 53 21 40 46 166 207 147 147 46 151 203 5 124 248 225 139 47 126 245 85 232 239 103 102 22 23 23 23 1 158 39 34 252 254 225 225 225 97 233 206 177 229 8 16 19 60 203 106 158 121 134 124 121 81 145 195 225 112 0 28 71 130 111 107 123 227 141 239 191 7 2 129 154 154 212 84 96 121 121 255 254 253 251 129 191 255 38 193 243 60 123 83 48 40 101 46 180 101 8 16 19 188 209 72 46 166 164 132 8 72 75 75 75 75 75 3 244 122 147 201 100 2 90 90 106 107 175 94 253 31 7 143 187 117 235 214 173 208 231 193 193 249 249 249 121 128 231 39 39 39 39 165 59 87 204 19 32 38 120 143 135 130 104 117 53 165 145 78 167 213 106 181 2 41 41 54 155 205 6 156 62 253 230 155 237 237 33 141 103 79 185 252 187 239 198 198 66 79 134 161 33 114 69 126 255 227 199 143 31 3 62 95 125 125 125 125 244 109 33 102 9 16 19 124 101 165 70 163 209 0 79 61 165 213 106 181 64 65 1 9 222 110 175 168 168 168 0 154 154 200 213 172 23 127 252 225 243 249 124 128 207 183 188 188 188 12 44 44 76 77 77 77 69 255 156 49 151 134 138 251 120 242 237 89 89 164 249 110 183 193 96 48 0 106 53 249 250 134 134 231 158 251 252 243 144 166 51 8 53 93 108 157 125 207 243 129 64 32 0 0 148 182 70 27 49 67 128 152 224 159 126 154 178 152 138 10 18 124 90 90 118 118 118 54 160 84 146 207 111 106 122 237 181 111 191 141 220 62 88 44 112 58 165 201 134 54 157 0 49 193 187 221 212 42 200 207 39 65 155 205 233 233 233 233 128 86 75 193 245 212 169 87 94 249 230 155 141 107 188 216 250 232 232 210 210 210 18 192 243 79 158 60 121 2 120 189 199 142 29 59 22 12 114 220 133 11 23 46 68 222 38 54 141 0 49 193 239 221 155 156 156 156 12 216 237 164 241 6 3 249 124 151 171 187 187 187 91 38 171 171 187 118 109 126 62 122 193 241 247 223 169 39 84 89 73 193 61 16 160 52 53 90 144 156 0 161 224 19 19 201 197 60 251 44 245 106 152 111 183 90 73 211 83 83 11 11 11 11 129 186 186 150 150 95 127 13 6 35 173 241 98 235 60 79 174 40 24 140 110 93 32 89 22 36 20 124 106 106 74 74 74 10 224 118 211 1 115 114 40 171 97 189 26 135 163 171 171 171 75 38 123 239 189 234 234 207 62 147 106 151 33 12 12 44 44 44 44 0 60 79 45 138 104 33 234 22 32 222 50 160 188 187 172 140 136 176 90 243 242 242 242 128 143 62 122 235 173 142 14 160 174 238 196 9 64 58 141 23 98 98 130 178 33 191 127 124 124 124 60 122 242 137 154 5 8 5 111 52 82 26 201 242 248 146 18 210 120 163 49 35 35 35 3 224 56 42 160 98 5 191 253 230 245 122 189 192 232 40 41 202 240 112 116 6 54 17 183 128 149 174 38 62 62 62 30 40 47 167 118 175 203 69 77 50 139 133 130 236 217 179 111 191 125 253 122 232 255 165 214 248 213 214 167 167 89 16 102 245 65 140 18 176 82 227 89 254 78 189 26 183 155 124 187 217 76 149 235 233 211 221 221 221 221 128 92 30 249 67 69 18 172 48 91 90 162 22 69 164 17 54 1 66 193 179 1 136 221 78 27 207 205 165 180 210 106 37 23 115 230 76 77 205 149 43 128 92 94 91 11 196 158 198 11 43 227 153 25 106 77 248 253 228 146 34 141 13 199 0 161 224 61 30 242 241 121 121 113 113 113 113 64 101 165 217 108 54 3 54 91 65 65 65 1 208 212 116 251 246 237 219 145 63 64 180 49 60 204 230 5 244 156 157 61 126 252 248 241 200 197 130 117 91 128 80 240 102 51 185 24 155 141 158 133 133 228 227 245 122 106 11 159 57 115 248 240 15 63 0 114 249 225 195 64 236 106 188 216 250 95 127 81 12 216 189 155 10 180 197 197 200 90 194 154 45 64 40 120 135 131 130 106 85 21 5 83 54 0 97 249 125 75 11 249 248 237 130 241 113 114 169 62 95 100 99 193 170 22 32 20 124 102 38 5 87 54 196 206 201 161 30 141 201 68 4 52 53 189 254 250 165 75 128 92 126 226 4 16 123 26 189 209 117 175 151 98 193 220 220 220 220 220 92 228 8 16 181 0 161 224 139 138 40 111 207 207 87 40 20 10 32 39 135 122 37 38 147 221 110 183 3 167 78 117 118 118 118 70 110 99 177 134 135 15 217 196 140 231 121 62 114 195 251 21 22 32 20 124 121 57 107 134 81 87 210 237 166 30 141 78 231 116 58 157 255 214 248 67 135 128 216 209 216 72 173 51 244 245 145 230 79 79 211 224 134 231 7 7 7 7 195 21 255 191 44 64 204 199 103 101 177 155 100 148 199 127 242 201 189 123 247 238 1 31 124 176 189 53 158 225 210 37 175 215 235 13 181 161 167 166 40 22 204 205 141 140 140 140 132 255 126 153 80 240 121 121 164 233 101 101 76 243 73 211 63 253 180 183 183 183 119 243 53 114 179 215 247 237 163 186 166 178 146 92 175 197 82 90 90 90 10 168 213 231 207 159 63 191 254 121 193 138 24 80 89 73 233 99 97 97 113 113 113 49 96 50 101 102 102 102 134 203 243 246 65 87 215 244 244 244 52 192 243 51 51 51 51 64 92 28 165 223 27 197 138 24 48 62 78 21 107 110 46 5 155 184 56 114 61 194 10 145 97 179 53 82 170 245 139 23 15 30 84 40 100 255 241 24 83 83 36 31 159 239 209 163 71 143 194 32 128 249 56 246 226 31 127 188 115 231 206 29 64 161 160 193 136 197 210 223 223 223 15 52 55 247 246 86 85 1 106 117 73 73 73 9 160 82 145 165 40 149 61 61 205 205 128 82 121 238 220 185 115 50 89 172 220 187 143 52 132 231 154 157 141 204 237 137 21 62 75 76 128 123 246 80 193 101 50 81 119 211 96 160 167 94 79 62 145 227 232 169 80 80 157 192 110 43 188 251 110 123 123 123 123 232 61 98 26 37 92 103 136 53 139 96 120 225 5 58 239 238 221 116 78 155 173 188 188 188 60 164 136 107 37 96 133 11 18 70 125 38 160 95 126 17 43 193 71 71 71 71 129 67 135 168 2 214 104 232 58 135 193 208 215 215 215 7 156 61 203 130 20 213 17 9 9 87 175 214 214 2 95 127 125 242 228 201 147 193 96 125 125 91 91 91 91 232 109 140 152 104 207 126 195 197 253 251 148 150 150 148 208 77 186 96 112 99 237 234 176 167 252 171 185 156 151 94 34 77 97 105 173 90 77 4 105 181 228 226 52 26 106 79 199 199 83 129 167 80 80 129 215 208 208 209 209 209 177 249 26 47 182 110 177 80 240 61 112 128 206 231 118 123 60 30 15 96 52 222 184 113 227 70 24 22 176 94 8 45 70 72 204 207 63 83 214 32 68 85 21 5 177 204 204 177 177 177 49 64 167 163 3 113 28 205 136 155 155 119 237 218 181 11 48 24 174 93 171 171 3 146 146 136 184 247 223 15 119 199 145 193 226 34 237 211 239 167 231 70 111 79 72 112 247 235 191 177 214 32 253 242 203 52 87 112 56 168 46 209 235 201 66 212 106 170 79 216 173 103 185 156 214 27 27 175 92 161 57 131 52 49 128 225 249 231 201 181 238 217 67 163 85 171 149 20 103 173 177 64 242 107 41 98 22 195 192 8 250 233 39 202 46 172 86 42 253 157 78 34 192 96 32 159 107 181 14 13 13 13 1 58 29 37 7 31 127 76 67 125 165 242 226 197 131 7 1 173 150 110 208 5 2 71 142 28 57 2 52 52 92 190 124 249 114 248 251 23 166 227 161 30 17 197 194 64 96 125 205 58 201 45 96 189 88 205 98 138 139 105 16 148 158 78 49 70 175 167 251 69 70 35 89 6 199 145 37 41 149 244 119 42 21 197 28 133 130 146 6 161 166 174 55 43 99 120 231 29 163 209 104 4 114 114 168 128 93 107 44 136 121 2 196 32 70 140 78 71 4 104 52 244 100 87 27 141 70 150 54 211 247 201 201 44 9 160 160 159 144 64 4 169 213 212 98 80 169 90 91 91 91 67 2 100 89 153 24 1 53 53 68 64 126 62 89 162 197 114 243 230 205 155 219 152 0 49 172 102 49 108 130 231 116 146 197 184 221 68 16 203 206 146 147 201 213 105 52 212 17 72 74 34 31 239 247 83 125 51 49 65 159 91 91 247 237 251 242 203 144 69 84 87 211 247 213 213 235 139 5 219 142 0 49 172 53 248 23 21 17 33 46 23 17 97 179 209 147 227 104 93 163 161 118 60 35 136 253 182 248 254 253 137 137 137 9 32 59 155 234 1 187 189 167 167 167 231 255 208 2 54 138 213 8 98 191 79 48 155 201 149 49 130 180 90 102 49 116 25 65 163 161 236 204 108 238 236 236 236 220 33 32 108 172 213 114 246 238 101 173 26 114 109 7 14 244 247 247 247 75 241 19 143 29 236 96 43 227 31 155 227 168 4 251 87 97 42 0 0 0 0 73 69 78 68 174 66 96 130)! !
!DrGIcons class methodsFor: 'accessing'!
property
^self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 48 0 0 0 48 16 6 0 0 0 7 146 37 196 0 0 0 6 98 75 71 68 255 255 255 255 255 255 9 88 247 220 0 0 0 9 112 72 89 115 0 0 0 72 0 0 0 72 0 70 201 107 62 0 0 8 232 73 68 65 84 120 218 237 91 71 72 124 189 23 189 118 84 176 160 130 189 128 136 88 113 41 138 5 68 172 8 54 176 131 11 43 130 32 98 69 65 193 130 226 198 133 109 161 27 11 136 136 88 112 225 194 238 194 133 21 43 138 189 96 239 221 247 95 12 135 252 191 153 111 190 153 167 51 234 175 156 77 200 155 188 188 228 156 228 222 228 38 67 244 23 127 241 39 67 129 95 113 142 251 238 6 255 76 40 240 228 241 255 222 148 174 24 35 222 211 211 211 211 211 83 254 93 226 56 142 147 165 220 178 170 111 126 126 126 126 126 158 232 234 234 234 234 234 74 248 87 254 66 72 120 129 53 249 252 252 252 252 252 156 72 71 71 71 71 71 71 118 4 8 63 151 119 57 89 213 63 54 54 54 54 54 70 148 147 147 147 147 147 67 180 176 176 176 176 176 192 95 8 169 5 120 127 127 127 127 127 39 122 122 122 122 122 122 34 122 126 126 126 126 126 230 47 196 239 2 5 5 5 5 5 5 162 203 203 203 203 203 75 162 192 192 192 192 192 64 254 66 240 22 224 230 230 230 230 230 134 165 210 54 84 210 243 95 173 28 242 138 138 138 138 138 138 31 23 66 81 50 133 31 195 79 33 74 94 229 0 12 76 109 109 109 109 109 109 162 190 190 190 190 190 62 34 71 71 71 71 71 71 148 18 239 125 100 46 192 79 35 10 207 219 219 219 219 219 219 137 66 66 66 66 66 66 136 244 244 244 244 244 244 136 172 172 172 172 172 172 136 22 23 23 23 23 23 63 255 93 8 209 219 219 219 219 219 75 228 224 224 224 224 224 32 94 8 153 9 240 211 136 239 232 232 232 232 232 32 114 113 113 113 113 113 33 202 200 200 200 200 200 96 68 39 36 36 36 36 36 176 247 131 131 131 131 131 131 69 133 144 246 187 200 35 133 16 173 173 173 173 173 173 194 181 49 33 62 45 192 79 33 30 196 121 123 123 123 123 123 51 194 177 106 169 170 170 170 170 170 34 218 218 218 218 218 218 34 106 105 105 105 105 105 33 26 30 30 30 30 30 102 245 5 5 5 5 5 5 49 27 46 45 241 226 132 48 51 51 51 51 51 35 114 115 115 115 115 115 19 237 151 242 239 66 60 76 203 245 245 245 245 245 53 81 113 113 113 113 113 49 19 2 56 59 59 59 59 59 99 66 216 216 216 216 216 216 48 33 48 99 6 6 6 6 6 6 136 156 156 156 156 156 156 62 222 94 73 144 90 0 73 27 153 239 38 94 87 87 87 87 87 151 104 104 104 104 104 104 136 200 216 216 216 216 216 152 232 240 240 240 240 240 240 95 58 174 172 172 172 172 76 180 189 189 189 189 189 205 102 8 0 19 242 217 246 74 226 237 195 51 224 187 136 71 190 176 176 176 176 176 144 117 176 161 161 161 161 161 129 17 119 119 119 119 119 119 71 164 170 170 170 170 170 42 190 253 185 185 185 185 185 185 68 221 221 221 221 221 221 68 209 209 209 209 209 209 68 105 105 105 105 105 105 242 35 158 183 0 194 21 126 23 241 192 196 196 196 196 196 4 81 120 120 120 120 120 56 145 173 173 173 173 173 173 180 189 33 202 202 202 202 202 202 18 37 190 174 174 174 174 174 78 118 253 146 153 0 226 240 213 196 11 195 194 194 194 194 194 130 72 77 77 77 77 77 77 114 123 75 74 74 74 74 74 136 186 186 186 186 186 186 228 71 188 220 77 208 119 17 47 252 252 224 224 224 224 224 64 122 1 12 12 12 12 12 12 88 62 53 53 53 53 53 149 255 119 199 199 199 199 199 199 89 76 8 203 88 56 109 105 77 144 212 203 208 175 114 194 210 190 135 229 29 156 49 108 189 164 84 56 154 11 83 38 237 119 177 174 247 247 247 247 247 247 39 42 43 43 43 43 43 35 242 243 243 243 243 243 99 209 82 225 25 32 142 191 15 239 3 240 129 175 38 30 121 119 119 119 119 119 119 182 94 223 223 223 223 223 223 23 141 85 9 167 120 15 192 8 150 150 248 148 148 148 148 148 20 34 103 103 103 103 103 103 230 67 0 8 49 55 55 55 55 55 39 153 71 185 207 0 89 19 15 32 232 37 76 208 206 206 206 206 206 142 248 244 241 241 241 241 241 145 109 184 96 74 96 138 80 15 226 253 226 136 199 190 1 245 32 15 224 249 191 159 27 124 64 0 190 196 203 187 28 4 208 210 210 210 210 210 98 65 48 68 39 197 165 15 15 15 15 15 15 108 21 100 105 105 105 105 105 201 136 134 16 166 166 166 166 166 166 226 137 127 123 123 123 123 123 99 51 16 27 186 204 204 204 204 204 76 182 33 252 103 84 84 134 2 124 23 241 120 222 214 214 214 214 214 198 58 10 66 140 140 140 140 140 140 136 212 213 213 213 213 213 69 83 140 72 56 203 233 233 233 233 233 105 162 139 139 139 139 139 11 102 82 16 43 194 70 79 120 132 31 29 29 29 29 29 49 223 130 13 29 234 195 192 16 23 130 0 62 189 19 254 46 226 211 211 211 211 211 211 69 71 38 108 189 164 85 17 78 248 144 170 168 168 168 168 168 48 31 1 39 139 122 80 239 241 241 241 241 241 177 104 253 24 8 8 97 224 253 95 118 25 202 151 120 13 13 13 13 13 13 70 132 164 29 176 56 220 223 223 223 223 223 179 20 33 139 215 215 215 215 215 87 241 245 246 244 244 244 244 244 176 124 64 64 64 64 64 128 20 60 254 247 207 76 59 56 47 28 73 34 149 55 241 176 161 30 30 30 30 30 30 44 212 48 59 59 59 59 59 75 100 98 98 98 98 98 194 70 50 14 72 190 10 16 220 199 199 199 199 199 135 72 73 73 73 73 73 137 45 71 225 115 66 67 67 67 67 67 137 38 39 39 39 39 39 89 47 127 108 44 8 196 99 131 3 226 49 226 225 36 113 20 40 236 108 191 10 53 53 53 53 53 53 68 123 123 123 123 123 123 68 77 77 77 77 77 77 114 136 5 125 23 241 0 136 199 9 19 108 50 95 194 97 194 224 140 97 42 176 170 130 208 146 80 95 95 95 95 95 79 212 216 216 216 216 216 200 218 27 31 31 31 31 31 207 70 62 32 214 135 254 247 103 216 43 168 16 183 33 144 126 21 241 56 99 189 189 189 189 189 189 229 127 207 7 209 77 28 77 138 3 86 45 248 158 176 32 253 253 253 253 253 253 108 7 14 211 216 217 217 217 217 217 201 174 237 192 100 195 151 192 4 77 77 77 77 77 77 177 222 75 104 54 186 200 113 2 1 56 78 48 114 56 238 244 244 244 244 244 84 52 21 28 120 176 84 96 155 69 83 193 178 143 227 70 71 71 71 71 71 57 78 208 81 150 206 204 204 204 204 204 112 156 192 215 112 156 192 212 240 79 5 235 122 214 15 193 6 137 227 4 49 36 142 19 132 177 57 78 32 60 199 153 155 155 155 155 155 179 242 194 169 32 248 199 113 213 213 213 213 213 213 172 125 72 5 3 147 125 95 112 30 193 113 174 174 174 174 174 174 194 245 241 152 1 80 242 229 229 229 229 229 133 165 242 26 241 118 118 118 118 118 118 108 36 241 5 54 86 24 249 88 247 15 14 14 14 14 14 138 94 48 147 245 170 14 22 3 231 18 97 97 97 97 97 97 162 51 64 238 203 80 225 231 176 189 177 177 177 177 177 177 44 143 13 144 189 189 189 189 189 61 35 94 92 125 63 149 120 228 229 126 32 195 183 193 32 26 35 30 177 153 230 230 230 230 230 102 230 4 63 59 226 17 74 248 46 226 249 242 38 247 88 144 48 241 48 61 32 62 38 38 38 38 38 230 247 35 94 90 200 109 25 42 137 248 200 200 200 200 200 72 230 91 248 2 59 227 239 54 53 146 202 201 76 0 105 99 65 146 136 135 51 250 40 241 184 112 133 235 38 124 137 255 168 239 250 104 185 47 139 5 73 34 94 248 222 14 95 44 45 45 45 45 45 17 21 20 20 20 20 20 176 245 57 110 67 200 138 120 89 9 244 229 78 24 171 26 16 143 139 81 112 174 8 25 240 197 242 242 242 242 242 50 81 84 84 84 84 84 20 235 32 70 60 130 114 95 69 188 172 76 15 111 1 196 1 91 123 156 44 33 142 158 156 156 156 156 156 204 130 100 124 177 178 178 178 178 178 66 20 23 23 23 23 23 199 66 14 63 157 120 228 165 21 228 195 51 0 196 195 25 98 6 20 21 21 21 21 21 17 9 118 198 252 137 95 93 93 93 93 93 37 74 76 76 76 76 76 252 245 136 231 11 222 51 160 188 188 188 188 188 92 148 248 188 188 188 188 188 60 118 178 196 23 107 107 107 107 107 107 68 73 73 73 73 73 73 44 172 251 187 18 207 91 0 216 240 138 138 138 138 138 10 209 107 223 146 14 159 197 97 125 125 125 125 125 157 205 168 63 133 120 222 2 8 31 46 251 250 250 250 250 250 178 152 7 4 64 57 67 67 67 67 67 67 34 107 107 107 107 107 107 209 250 16 213 44 45 45 45 45 45 101 121 220 80 67 216 25 103 189 210 118 88 94 229 96 130 165 125 15 39 104 50 19 64 216 7 232 235 235 235 235 235 139 158 144 33 76 125 114 114 114 114 114 194 46 80 1 8 78 101 103 103 103 103 103 19 109 108 108 108 108 108 16 213 214 214 214 214 214 18 69 68 68 68 68 68 136 238 140 191 250 223 148 146 158 203 10 82 11 0 211 3 192 102 227 82 44 110 29 32 152 134 145 2 65 64 124 126 126 126 126 126 62 209 230 230 230 230 230 38 27 233 187 187 187 187 187 187 68 149 149 149 149 149 149 146 219 35 45 49 178 46 199 23 176 12 255 140 130 50 72 105 197 68 155 166 169 169 169 169 169 201 46 187 226 126 141 48 64 60 86 71 248 99 196 159 13 102 196 62 233 70 56 14 183 17 188 188 188 188 188 188 216 109 101 152 160 145 145 145 145 145 17 150 23 110 192 159 14 25 17 33 237 228 253 75 252 95 252 48 252 15 157 2 91 74 184 1 204 172 0 0 0 0 73 69 78 68 174 66 96 130)! !
!DrGIcons class methodsFor: 'accessing'!
quit
^ self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 48 0 0 0 48 8 6 0 0 0 87 2 249 135 0 0 9 65 73 68 65 84 104 129 237 153 77 140 28 197 21 199 127 85 93 221 211 158 221 153 157 53 96 214 75 108 175 119 253 177 107 28 136 109 226 72 129 196 124 68 202 129 68 33 7 4 138 80 100 37 145 64 138 100 41 68 185 113 8 145 144 34 37 202 1 34 114 136 18 114 8 65 202 1 18 46 32 229 3 69 56 50 182 185 0 254 54 172 237 93 44 99 123 87 242 126 204 206 76 127 84 229 208 93 61 189 227 153 221 157 93 43 39 158 244 212 211 61 93 93 255 255 123 175 170 94 189 18 220 2 49 198 72 64 2 62 80 76 175 62 224 165 207 101 250 170 78 53 0 234 192 66 122 173 3 90 8 161 187 237 91 173 21 124 78 60 18 240 21 96 61 80 78 239 189 150 247 2 18 224 55 114 170 73 72 116 45 2 224 7 63 60 248 251 122 163 254 61 109 186 54 0 82 8 28 71 81 40 120 178 183 183 76 165 82 161 82 169 200 190 114 31 190 239 75 207 243 16 66 0 160 181 38 12 67 106 245 154 158 157 153 225 198 141 27 122 102 102 70 75 41 255 244 235 95 253 230 39 64 96 223 93 169 40 128 90 189 246 163 239 63 117 144 233 233 105 174 93 187 70 24 134 68 81 68 28 199 4 65 64 28 199 132 97 72 28 199 196 113 156 253 23 199 49 198 24 164 148 120 174 71 209 239 161 212 83 102 125 229 54 30 123 236 59 72 233 32 132 192 98 50 6 140 49 104 29 103 237 27 141 6 207 255 226 231 207 0 63 237 218 122 228 66 200 24 67 28 199 104 173 209 90 103 64 237 239 164 227 228 63 251 219 24 131 49 6 0 199 113 112 93 23 223 247 41 149 74 20 10 133 20 188 32 117 52 96 210 54 42 235 203 117 93 104 142 17 73 18 78 221 19 112 93 23 165 20 82 74 164 148 40 165 50 128 22 100 254 94 41 149 145 115 28 7 165 20 74 41 60 207 195 247 253 20 188 76 173 159 15 11 129 49 58 11 43 33 64 74 153 39 209 149 100 4 242 32 44 96 107 101 11 94 41 149 118 42 136 227 56 107 103 213 117 221 204 16 22 28 228 67 72 0 230 166 231 116 25 247 109 9 216 142 29 199 185 41 60 172 68 81 148 17 176 106 199 128 245 158 227 56 169 69 23 91 61 165 128 16 201 88 184 217 51 183 128 128 37 209 26 50 86 236 239 166 251 155 4 172 7 109 8 174 92 196 90 28 208 36 160 148 106 75 160 21 112 62 124 236 53 111 249 86 2 107 1 215 21 1 11 208 18 200 131 238 36 121 15 180 146 248 127 73 219 149 216 113 28 140 49 217 213 74 222 35 214 19 150 172 5 222 156 58 87 47 175 194 102 3 151 128 190 167 96 118 69 4 242 3 211 222 91 171 90 240 246 89 20 69 139 194 76 8 129 227 56 139 136 172 5 188 227 121 71 101 169 68 125 122 186 194 50 4 22 245 148 39 209 170 249 248 182 211 166 157 181 242 106 189 176 26 121 125 96 96 200 81 234 232 87 94 120 97 160 127 231 206 21 229 70 25 129 165 192 119 34 212 142 220 106 193 255 243 192 129 205 225 244 244 145 251 158 123 110 160 255 238 187 87 220 110 17 129 213 16 105 37 179 154 49 80 152 155 99 250 200 145 255 236 125 246 217 219 43 35 35 232 249 121 76 24 118 71 160 19 137 165 238 243 237 58 253 183 156 212 38 39 217 243 198 155 220 251 244 211 183 247 111 223 46 23 142 31 71 47 44 96 244 202 82 162 155 102 33 41 37 58 215 120 169 123 107 253 114 185 204 240 240 48 81 20 117 21 70 11 19 19 252 247 145 111 176 247 241 199 89 63 58 42 171 199 142 65 28 99 130 128 40 138 124 9 151 94 109 191 79 80 6 212 83 32 110 90 7 236 117 37 30 176 235 128 49 6 215 117 169 84 42 185 44 116 121 240 239 62 252 8 219 30 124 144 59 198 118 81 125 239 61 136 34 112 28 132 227 176 255 208 33 0 12 248 89 254 145 170 49 134 119 14 29 138 168 215 111 94 200 86 163 213 106 149 195 135 15 179 123 247 110 198 198 198 114 30 104 207 98 97 98 130 119 190 126 128 145 253 251 185 125 87 2 222 132 97 6 126 230 237 183 155 75 184 49 160 117 18 82 113 140 137 99 202 143 62 10 16 65 155 16 90 45 137 254 254 126 250 250 250 80 74 49 59 219 121 234 174 94 186 196 191 30 248 26 67 187 119 39 224 143 30 197 4 65 2 94 74 140 148 144 243 182 177 150 207 147 8 195 228 217 173 36 176 113 227 70 134 134 134 152 156 156 164 88 44 118 6 127 255 3 108 26 30 230 142 93 187 168 30 59 134 169 215 19 240 74 97 164 68 164 4 22 229 193 54 173 215 26 19 69 152 70 35 91 72 59 18 232 230 190 84 42 49 58 58 202 197 139 23 153 159 159 167 92 46 119 0 127 63 27 7 6 216 176 107 23 213 227 199 49 181 26 40 149 88 62 138 146 171 16 73 248 228 67 200 198 126 234 1 221 104 100 223 237 88 149 88 41 17 165 20 123 246 236 225 202 149 43 76 76 76 48 48 48 144 165 31 86 194 153 25 222 28 30 102 235 142 29 12 220 115 15 11 239 191 143 174 213 18 203 199 113 98 121 199 193 8 129 144 146 184 90 69 207 205 37 64 163 40 9 41 207 67 22 139 200 117 235 48 141 70 231 16 202 131 91 105 232 92 191 126 157 241 241 113 42 149 138 221 227 46 18 213 211 67 113 112 144 234 244 52 225 212 20 70 107 116 173 134 112 93 112 28 140 214 152 70 3 93 173 18 207 206 98 210 141 83 7 203 178 110 255 126 76 154 202 175 153 192 229 203 151 113 28 135 66 161 128 82 170 237 66 38 148 226 209 51 103 248 247 67 15 241 201 145 35 108 29 27 35 154 154 34 152 156 76 94 104 217 249 45 41 198 44 90 232 218 166 141 107 77 39 218 137 92 231 243 213 183 222 66 111 217 194 133 83 167 240 54 111 198 29 24 232 14 188 229 144 243 80 199 188 119 181 179 209 98 2 182 56 144 212 151 180 235 178 231 141 215 9 55 109 226 194 233 211 120 155 54 37 36 186 149 28 129 37 75 139 43 25 200 237 8 231 197 24 178 34 86 24 134 196 202 101 236 181 191 112 242 137 39 25 63 123 150 173 219 183 3 16 126 246 89 214 70 246 244 100 211 105 174 131 230 55 211 248 7 212 146 179 208 114 68 172 182 110 37 147 20 195 190 173 137 99 171 73 49 203 120 5 134 254 248 7 62 57 120 144 11 231 206 177 117 100 4 140 33 188 122 21 128 226 190 125 132 141 6 113 20 65 126 97 19 2 164 164 30 4 73 138 1 114 217 105 116 185 152 79 204 160 178 205 141 148 50 205 143 52 54 149 48 70 167 247 52 255 43 248 108 124 249 101 46 63 243 12 231 207 158 101 251 142 29 24 99 136 174 93 67 87 171 124 116 226 4 81 163 49 5 4 2 116 106 62 157 84 150 154 21 188 21 133 80 43 240 188 135 164 148 184 174 75 161 80 192 117 221 108 203 121 254 252 199 244 247 87 168 84 42 45 223 36 109 39 80 61 69 54 188 244 34 39 158 120 18 121 250 116 48 188 99 135 151 198 28 2 130 95 194 119 79 37 213 235 128 36 247 9 90 84 47 185 121 109 7 222 110 41 45 104 223 247 51 181 4 226 56 102 110 110 150 43 87 174 240 241 199 159 52 219 59 18 233 72 28 229 224 40 7 165 92 220 82 47 239 62 124 128 233 48 28 191 112 238 92 224 110 216 0 169 23 189 230 217 65 144 187 90 50 17 16 173 136 128 13 23 187 15 246 60 47 171 129 90 245 60 47 43 201 84 23 170 212 235 117 170 11 11 212 235 53 98 173 145 142 131 35 37 202 81 77 85 14 158 231 129 87 224 181 109 219 158 152 110 52 206 93 56 127 62 176 131 180 39 57 71 176 218 142 204 242 7 28 150 132 235 186 89 238 159 175 1 217 248 47 20 60 26 141 6 115 115 115 57 162 46 219 70 134 137 162 100 123 40 29 137 66 161 141 198 160 73 206 35 12 142 114 152 189 237 182 169 223 249 254 183 127 92 175 255 157 211 167 71 137 99 214 55 193 235 188 213 201 85 176 151 157 133 172 245 109 249 36 31 74 82 74 124 223 167 209 168 243 89 58 13 58 142 67 169 92 102 240 174 141 220 57 112 39 202 81 89 77 213 26 64 72 145 18 212 144 86 167 119 238 220 185 240 214 248 248 141 191 214 235 143 60 25 4 255 48 240 165 225 38 129 69 160 243 210 49 149 176 224 173 180 18 88 183 110 29 181 90 141 75 151 46 18 69 33 202 117 25 220 56 200 208 208 22 250 251 251 147 54 177 38 140 131 100 50 50 205 239 104 99 207 28 52 82 36 253 189 242 202 43 243 64 36 132 88 248 22 220 95 132 231 251 97 170 19 240 142 4 44 248 214 89 199 18 40 22 139 4 97 192 185 243 231 168 86 231 233 237 237 101 120 100 152 161 161 45 248 190 15 64 16 5 205 239 217 169 148 92 193 88 167 167 52 58 38 142 181 221 99 107 219 247 211 137 213 127 182 20 240 142 4 242 224 243 218 211 211 67 20 69 156 62 115 146 235 215 167 24 28 28 228 190 125 123 25 252 194 93 72 145 144 12 130 160 221 231 72 25 100 52 178 211 158 56 38 214 122 81 209 160 91 89 118 83 95 42 149 144 82 242 225 71 31 242 233 167 147 108 223 177 157 111 238 219 67 95 185 12 66 100 3 116 165 210 60 229 209 233 145 149 185 117 4 242 82 46 151 241 125 159 15 62 248 128 203 87 62 101 108 108 148 251 190 188 39 205 247 5 141 160 59 224 77 49 233 6 75 231 200 24 232 242 108 172 45 1 33 146 205 121 111 111 47 39 79 158 224 234 181 171 140 142 237 228 222 189 95 76 199 161 33 8 151 8 147 149 225 199 164 36 154 135 126 205 114 254 154 8 148 203 37 198 199 199 57 115 246 20 35 219 182 50 188 109 11 2 65 180 86 208 173 98 154 131 26 211 44 219 175 70 50 2 115 243 179 76 76 94 100 195 157 119 208 183 126 27 66 8 162 120 137 173 221 45 16 11 92 74 185 234 65 160 0 252 130 251 183 151 126 251 226 99 157 94 90 173 123 91 165 147 165 123 138 61 127 190 37 29 124 46 159 75 247 242 63 81 5 144 78 154 113 137 92 0 0 0 0 73 69 78 68 174 66 96 130)! !
!DrGIcons class methodsFor: 'accessing'!
ray
^self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 48 0 0 0 48 16 6 0 0 0 7 146 37 196 0 0 0 6 98 75 71 68 255 255 255 255 255 255 9 88 247 220 0 0 0 9 112 72 89 115 0 0 0 72 0 0 0 72 0 70 201 107 62 0 0 1 149 73 68 65 84 120 218 237 154 61 14 130 48 24 134 91 103 56 4 3 215 106 76 186 25 35 151 241 8 14 156 128 201 155 56 153 56 178 187 144 212 161 49 198 250 83 104 191 210 79 121 159 173 4 18 120 31 126 90 242 10 1 120 97 76 219 182 173 49 185 207 99 113 28 143 85 85 85 198 156 78 117 93 215 198 64 68 38 92 17 215 107 211 52 13 68 164 98 229 110 56 28 250 190 239 133 56 159 135 97 24 132 184 92 186 174 235 132 128 136 196 40 165 148 82 143 128 215 235 178 44 75 99 226 158 136 251 126 16 247 17 55 120 26 17 110 240 16 224 101 172 8 59 242 5 12 1 193 248 68 88 124 34 16 124 52 223 69 64 192 108 196 138 208 90 107 173 31 199 187 99 48 146 216 87 17 130 39 37 244 85 4 17 46 171 105 187 143 13 78 74 119 139 157 190 10 177 223 23 69 81 228 190 108 62 76 20 224 67 202 231 59 92 74 59 125 197 202 154 136 207 179 28 223 199 150 102 101 13 94 240 5 15 17 137 152 26 60 68 16 17 27 124 154 159 126 11 100 234 2 43 205 79 191 5 178 219 109 183 155 77 248 202 22 34 152 0 17 76 128 8 38 64 4 19 66 69 160 197 65 12 158 8 38 64 4 19 32 130 9 16 193 4 136 96 2 68 48 1 34 152 48 143 8 212 110 188 160 114 201 4 84 46 153 128 202 37 19 168 43 151 232 57 5 226 138 120 14 18 5 179 217 120 31 228 124 34 100 232 129 255 73 236 29 45 39 231 73 220 140 251 85 194 43 151 223 183 251 129 128 81 188 86 46 237 56 247 121 253 13 225 149 75 124 140 137 136 45 156 129 64 98 131 135 8 34 16 108 38 98 155 126 224 199 185 1 85 109 241 171 221 62 127 106 0 0 0 0 73 69 78 68 174 66 96 130)! !
!DrGIcons class methodsFor: 'accessing'!
redo
^ self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 48 0 0 0 48 8 6 0 0 0 87 2 249 135 0 0 0 6 98 75 71 68 0 255 0 255 0 255 160 189 167 147 0 0 0 9 112 72 89 115 0 0 13 215 0 0 13 215 1 66 40 155 120 0 0 0 7 116 73 77 69 7 215 6 21 14 22 55 133 211 233 232 0 0 8 11 73 68 65 84 104 222 237 152 105 108 84 215 21 199 255 247 222 247 222 204 120 188 225 193 216 198 27 182 176 195 82 108 140 77 73 104 33 64 0 177 101 32 141 147 170 129 46 106 196 180 85 219 168 31 218 170 21 72 84 173 104 20 169 85 104 139 42 58 137 105 17 137 66 128 54 241 184 132 134 134 128 144 193 16 92 28 83 4 49 16 179 120 101 48 227 241 50 51 111 222 123 247 222 126 176 227 96 48 48 4 236 98 201 231 203 147 238 242 206 255 119 238 126 128 49 27 179 49 27 213 70 70 194 137 219 171 217 1 220 0 80 238 243 24 251 31 230 191 233 8 6 203 225 74 200 248 251 234 215 180 239 141 74 0 66 32 126 182 124 187 35 119 252 180 87 87 191 110 123 101 52 142 0 226 181 113 248 241 226 173 142 226 156 121 47 173 169 176 237 113 123 53 117 84 1 0 64 179 254 49 190 61 247 215 246 5 83 203 159 166 140 28 113 123 181 164 81 5 208 99 94 71 99 168 6 79 23 255 208 246 236 151 95 42 165 140 212 185 189 90 246 168 1 0 0 93 244 224 211 208 81 60 145 191 90 93 191 232 229 92 198 104 157 219 171 21 143 26 0 2 10 75 70 113 41 92 131 130 9 37 244 167 43 95 79 177 107 113 71 221 94 109 233 255 253 28 112 123 181 100 0 83 1 20 16 130 41 148 145 153 18 120 204 78 227 39 189 242 220 251 244 116 247 62 80 66 65 41 235 251 18 5 89 142 34 24 134 137 223 191 231 137 116 133 59 126 84 185 62 186 125 196 1 220 94 45 143 50 178 137 17 237 249 130 244 34 115 162 107 178 154 154 152 97 79 113 78 36 201 142 116 36 219 38 160 203 106 131 223 184 0 70 24 8 165 160 132 13 192 164 170 147 97 147 137 216 114 224 7 225 214 96 227 150 119 95 212 55 140 8 128 219 171 77 165 140 252 38 78 75 90 177 168 168 92 157 149 189 88 225 136 66 23 189 48 68 24 166 136 192 148 58 76 17 5 37 12 26 181 131 246 139 39 148 130 17 6 144 62 25 201 44 19 201 44 7 21 213 191 208 207 54 31 127 135 115 241 45 159 199 176 134 5 192 237 213 236 148 145 55 156 90 210 138 167 102 62 103 43 206 92 68 3 230 21 52 71 62 70 84 132 192 136 6 133 104 3 95 149 218 160 82 7 52 102 7 163 234 64 244 9 29 188 12 227 233 120 164 105 83 176 247 212 239 244 234 134 202 90 110 137 21 62 143 209 243 80 1 220 94 45 137 50 114 112 118 225 226 233 75 166 173 179 183 69 207 161 41 124 10 166 212 7 4 43 68 3 163 159 65 216 160 49 59 52 234 128 74 237 80 153 189 127 234 208 33 37 216 105 34 50 181 34 28 186 240 166 89 121 114 219 21 206 197 147 62 143 209 250 80 0 220 94 45 141 50 90 61 111 250 170 156 199 11 86 105 39 3 111 33 204 3 159 71 155 106 183 71 191 95 188 66 85 72 34 0 0 140 41 125 211 8 4 0 1 1 1 35 42 52 18 7 66 24 84 98 71 182 109 22 78 183 30 22 127 61 252 171 0 231 124 161 207 99 156 121 32 0 183 87 203 167 148 84 47 42 121 54 181 56 103 158 114 44 176 3 6 15 221 20 105 21 10 177 129 17 21 92 154 136 138 94 68 69 8 32 22 4 225 0 17 96 84 133 194 84 48 170 220 209 143 74 28 208 168 19 241 108 60 30 79 252 14 142 54 190 35 125 199 43 186 42 215 71 199 221 218 86 185 15 241 132 50 242 207 37 165 207 167 21 100 20 211 15 253 127 130 5 3 10 209 64 37 135 0 135 41 34 136 138 16 162 34 4 33 251 214 30 163 74 159 96 162 66 33 202 192 246 121 55 51 101 4 66 112 76 115 46 195 249 27 199 177 191 118 103 68 74 249 245 161 218 42 247 49 0 223 204 116 229 229 20 101 205 163 251 219 95 134 37 251 196 11 112 68 101 8 134 184 14 46 205 193 167 36 97 253 130 25 24 237 219 46 25 97 32 247 0 80 137 3 101 137 47 160 173 227 170 220 117 228 143 61 220 178 150 250 60 198 137 47 12 224 246 106 113 148 145 87 151 150 172 117 158 233 218 143 168 8 129 128 130 195 132 33 34 144 16 67 44 46 50 32 248 51 8 74 89 255 194 189 179 217 105 34 102 39 174 195 249 150 58 81 89 83 209 201 57 159 231 243 24 231 238 212 62 38 0 74 201 198 226 252 39 156 14 123 28 62 189 86 3 0 144 16 176 164 113 151 62 236 166 19 247 115 136 187 45 59 39 115 97 118 194 90 212 54 30 180 62 56 181 187 141 115 241 85 159 199 184 122 55 109 74 76 91 38 85 126 50 127 106 185 173 54 248 214 144 209 30 28 193 4 100 56 166 97 162 99 26 226 85 23 52 234 132 141 57 192 136 134 70 253 40 174 232 31 13 217 47 81 201 64 89 252 55 112 232 236 94 179 230 220 254 139 156 139 249 62 143 209 113 47 125 177 140 64 201 196 148 92 110 145 8 252 209 11 119 108 148 162 229 160 36 249 25 36 178 12 52 7 63 193 217 198 122 253 70 208 111 232 70 136 134 245 16 181 41 14 237 251 203 55 43 67 1 184 212 73 40 118 150 99 223 169 138 104 253 165 234 58 110 137 37 62 143 209 27 203 236 136 5 160 116 98 106 158 189 211 104 30 178 146 17 21 51 146 86 34 219 86 130 195 231 246 68 78 55 158 32 18 188 150 91 98 23 128 51 0 130 0 34 132 144 179 10 177 221 214 63 77 155 130 233 142 149 216 83 179 69 191 208 90 255 33 183 196 51 62 143 97 196 186 179 220 19 128 41 100 126 250 184 28 165 211 108 26 178 126 78 202 90 24 33 41 183 29 218 160 235 102 168 66 8 249 203 91 163 215 159 149 184 205 178 108 37 152 108 91 128 157 71 126 27 105 234 184 184 155 91 226 187 62 143 33 238 231 108 186 39 128 148 40 77 75 152 132 250 208 127 110 171 43 140 127 18 54 158 140 55 171 55 135 44 203 92 232 243 24 181 177 58 206 179 207 69 150 58 11 21 31 108 138 248 187 91 182 190 251 162 254 243 97 121 208 72 33 211 18 108 41 232 177 252 131 201 137 134 233 9 203 177 187 122 107 196 178 204 23 238 71 252 99 113 139 145 70 191 132 191 188 191 81 247 119 53 111 252 162 226 99 26 1 194 72 83 80 111 207 115 178 20 24 34 60 80 62 78 203 129 191 247 50 186 245 27 23 125 30 163 42 86 135 51 156 110 168 86 18 182 29 216 16 9 71 123 60 149 235 163 111 12 235 163 158 0 117 254 158 171 72 84 211 110 217 117 178 209 28 56 47 36 151 255 142 213 153 148 2 66 87 241 218 191 54 133 67 122 119 249 131 138 143 9 128 91 242 152 63 216 98 58 21 215 160 114 75 68 251 47 145 68 139 213 89 195 245 19 114 251 129 205 61 186 17 89 226 243 24 239 141 84 98 171 206 223 217 162 59 217 96 128 160 217 2 87 98 58 161 20 11 98 139 190 100 187 14 253 161 211 178 204 185 62 143 113 108 36 51 115 117 77 254 70 213 134 4 196 177 228 155 0 90 145 236 76 133 77 137 203 119 123 181 57 49 60 94 27 45 206 75 135 186 211 15 43 128 207 99 116 114 105 236 252 239 229 26 115 82 220 236 129 114 33 45 180 68 79 227 169 210 53 14 202 200 219 110 175 102 187 219 13 25 18 115 125 30 227 242 195 206 130 196 148 23 18 92 110 170 191 240 145 229 144 46 184 180 73 3 151 181 43 145 147 72 117 165 147 130 172 25 19 24 163 59 220 94 77 185 67 16 184 207 99 92 27 142 28 19 139 105 241 85 241 222 194 85 232 108 15 52 47 44 203 91 162 118 154 77 144 68 128 81 138 176 8 160 52 103 153 218 29 238 204 15 134 58 86 20 174 164 123 27 170 120 116 164 146 100 44 230 29 164 138 159 204 93 166 151 70 140 80 254 204 172 133 74 143 184 6 9 14 139 24 8 73 63 74 115 151 170 140 210 180 246 64 211 218 194 149 116 87 67 21 15 61 82 0 0 80 184 138 237 11 246 118 44 13 71 122 93 51 179 23 170 186 236 2 135 1 65 44 116 89 45 40 76 155 205 156 90 82 124 75 199 165 57 159 84 90 127 123 228 0 26 170 184 89 184 138 237 236 10 5 202 110 4 175 103 23 101 63 169 218 85 7 116 217 3 14 19 65 171 25 147 199 151 209 214 246 150 212 204 197 189 167 26 170 248 197 225 6 184 239 228 174 207 99 24 130 203 53 109 29 77 127 254 199 193 29 145 80 64 200 124 199 92 36 43 89 80 136 29 166 140 64 85 84 14 160 115 100 18 197 15 150 86 44 99 10 125 59 115 66 110 122 65 206 244 56 87 82 58 218 59 154 69 77 253 193 144 105 153 89 62 143 209 253 72 3 244 67 168 0 214 41 42 91 14 137 175 72 160 141 91 252 107 247 122 203 142 217 152 141 217 195 177 255 1 144 175 73 88 169 71 12 171 0 0 0 0 73 69 78 68 174 66 96 130)! !
!DrGIcons class methodsFor: 'accessing'!
rotation
^self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 48 0 0 0 48 16 6 0 0 0 7 146 37 196 0 0 0 6 98 75 71 68 255 255 255 255 255 255 9 88 247 220 0 0 0 9 112 72 89 115 0 0 0 72 0 0 0 72 0 70 201 107 62 0 0 3 12 73 68 65 84 120 218 237 155 189 106 181 64 16 134 85 210 89 88 167 144 64 26 193 194 52 22 66 238 64 66 106 123 187 16 115 1 185 128 128 157 96 237 77 132 220 66 192 54 22 150 129 96 145 43 176 246 43 14 131 100 206 217 111 221 31 221 245 231 105 68 61 174 235 59 179 51 235 142 199 48 14 14 14 180 97 24 254 110 183 143 165 186 3 39 246 35 56 230 106 153 219 144 4 54 77 213 2 168 134 83 0 154 199 98 97 89 61 124 63 134 97 28 1 32 228 126 4 154 155 137 57 96 186 240 105 154 166 105 138 61 254 48 24 39 211 67 7 22 254 178 33 240 44 135 182 221 61 236 66 200 17 126 63 134 160 132 6 209 152 63 85 64 104 127 127 161 75 241 123 128 105 254 29 49 32 56 54 200 110 71 136 232 3 146 5 227 205 25 69 81 20 69 177 121 225 177 0 211 161 9 59 77 120 124 255 97 240 60 207 243 188 113 63 8 130 32 8 54 111 8 121 179 32 62 67 144 67 77 24 134 97 24 142 231 227 56 142 227 88 119 131 48 247 79 254 8 224 187 63 249 250 44 203 178 44 211 125 100 144 28 139 249 66 50 47 47 207 207 79 79 178 132 103 239 71 158 231 121 158 15 131 109 219 182 109 235 102 136 5 12 160 11 96 8 232 63 95 104 162 229 36 210 113 218 136 93 32 4 233 2 14 77 114 158 91 154 176 162 29 89 15 144 172 217 66 146 232 8 144 198 250 13 128 67 146 216 115 139 94 207 204 250 13 0 192 123 68 146 36 73 146 208 158 107 57 3 104 82 146 156 159 40 138 162 40 50 140 182 109 219 182 149 221 58 127 8 210 212 0 242 99 170 239 251 190 239 27 70 215 117 93 215 209 126 77 90 4 164 29 199 91 233 130 204 45 212 252 139 109 150 101 89 150 165 79 104 157 56 2 72 203 197 152 169 231 119 179 154 73 133 49 4 201 50 196 212 223 203 27 202 48 27 114 28 199 113 28 89 173 138 195 153 3 104 194 232 87 72 129 228 235 186 174 235 186 170 123 51 34 57 9 143 194 235 86 156 175 235 186 174 235 49 25 111 22 221 138 243 124 47 98 27 64 77 113 158 92 55 208 107 117 116 113 88 5 22 93 68 27 6 177 197 184 233 60 62 190 190 222 223 15 195 221 221 195 195 237 237 106 95 196 104 197 121 118 202 178 44 203 210 48 78 203 209 242 123 12 194 171 80 139 3 209 226 60 110 135 124 159 203 5 25 246 145 0 30 13 66 99 193 177 231 107 55 2 176 71 159 246 225 236 232 241 85 85 85 85 117 190 127 185 85 210 231 42 227 249 190 239 251 190 55 205 166 105 154 166 145 191 68 64 242 252 175 175 143 143 239 111 13 166 223 243 20 231 105 200 143 245 216 179 241 72 16 141 253 179 35 183 56 207 10 187 65 72 253 155 219 0 210 67 16 20 231 217 66 139 108 104 95 216 1 227 113 220 223 169 119 186 185 9 130 235 107 254 164 172 62 102 41 225 92 40 200 81 96 8 146 160 63 63 77 243 251 123 222 34 24 2 120 127 127 123 251 252 164 59 220 206 12 64 255 103 15 205 147 193 0 144 116 113 8 98 77 198 11 253 71 108 189 96 143 7 129 213 132 214 29 128 103 63 216 195 213 78 46 54 204 50 211 229 131 51 14 225 53 225 16 90 17 243 126 84 124 112 112 240 127 254 1 239 98 79 150 168 109 20 16 0 0 0 0 73 69 78 68 174 66 96 130)! !
!DrGIcons class methodsFor: 'accessing'!
scale
^ self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 47 0 0 0 47 16 6 0 0 0 35 183 79 239 0 0 0 6 98 75 71 68 255 255 255 255 255 255 9 88 247 220 0 0 0 9 112 72 89 115 0 0 0 72 0 0 0 72 0 70 201 107 62 0 0 2 19 73 68 65 84 120 218 237 155 221 141 194 48 12 128 219 211 45 193 19 18 3 192 0 172 128 88 162 111 8 49 0 3 176 69 150 64 172 192 0 48 0 18 79 140 209 123 138 170 90 117 157 31 39 78 56 127 47 149 142 107 147 124 117 156 186 132 166 81 50 208 247 227 99 211 252 72 119 233 187 25 68 67 126 165 187 86 55 152 216 182 165 206 36 255 65 153 3 143 232 105 134 27 162 169 70 8 21 239 72 215 117 93 215 193 8 167 83 202 151 1 159 18 176 99 60 80 248 244 13 112 237 15 95 191 50 227 219 241 116 55 96 124 125 255 99 37 83 197 118 56 116 106 199 158 143 93 143 194 182 87 93 138 42 117 106 210 169 100 122 134 20 79 238 14 251 230 96 119 225 243 41 170 24 164 133 227 237 83 66 221 132 75 141 147 20 144 234 186 152 88 90 124 172 240 66 35 62 117 7 248 30 243 252 34 90 122 220 226 13 199 139 63 157 142 199 195 129 123 209 204 46 62 93 131 110 57 181 148 194 38 91 123 249 132 151 93 89 22 35 156 111 224 220 149 101 94 15 217 26 138 253 220 181 125 87 177 249 133 51 191 157 228 46 205 83 209 182 227 25 98 251 203 253 74 33 185 7 174 72 225 190 142 107 41 207 149 114 138 73 41 249 174 19 87 216 168 112 111 120 43 201 208 119 54 201 41 71 56 36 174 178 12 125 254 79 78 238 119 41 238 237 165 169 44 197 169 126 0 181 161 194 83 163 187 12 132 240 20 175 51 129 11 162 178 10 223 162 166 204 147 44 213 236 247 231 243 118 219 247 155 205 110 183 90 233 76 129 32 226 195 69 89 225 210 3 43 29 100 183 48 158 74 108 4 47 151 235 245 98 49 252 253 122 189 92 238 247 225 188 247 251 249 252 124 164 135 87 46 108 169 6 139 244 199 227 118 123 189 116 77 128 4 139 215 136 142 131 20 15 75 112 141 96 30 80 241 86 184 49 198 24 3 191 56 160 177 107 128 46 182 211 144 145 11 111 0 38 18 75 61 212 34 252 95 113 22 64 69 174 21 111 83 17 124 126 215 20 53 38 248 199 103 48 194 173 88 56 67 164 7 88 61 54 130 225 209 126 206 187 197 77 97 222 37 171 144 168 112 97 84 112 102 190 244 187 76 69 81 68 248 3 221 179 150 104 213 141 47 93 0 0 0 0 73 69 78 68 174 66 96 130)! !
!DrGIcons class methodsFor: 'accessing'!
segment
^self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 48 0 0 0 48 16 6 0 0 0 7 146 37 196 0 0 0 6 98 75 71 68 255 255 255 255 255 255 9 88 247 220 0 0 0 9 112 72 89 115 0 0 0 72 0 0 0 72 0 70 201 107 62 0 0 1 123 73 68 65 84 120 218 237 218 61 174 130 64 20 134 225 195 141 37 44 130 130 109 77 76 166 51 70 54 227 90 168 220 137 149 137 123 176 33 153 91 80 220 128 23 231 15 228 104 222 167 33 152 104 228 251 6 144 120 68 0 0 192 55 114 110 188 197 212 207 58 31 75 224 161 118 105 111 155 11 184 40 182 62 160 79 147 24 88 236 10 167 152 57 43 93 130 16 42 177 128 240 21 109 173 181 214 254 157 49 211 125 100 153 254 202 153 223 18 252 162 194 131 159 110 41 98 44 242 18 20 26 220 243 37 234 122 109 154 166 17 57 159 203 178 44 183 62 108 61 22 190 9 23 197 120 133 23 197 126 95 85 85 37 114 187 245 125 223 139 220 239 93 215 117 34 143 71 219 182 45 103 66 164 185 75 139 255 102 59 20 225 220 229 82 215 117 237 220 112 70 56 71 17 153 124 193 83 196 74 98 131 167 136 133 228 6 111 140 49 198 80 68 182 216 7 172 105 240 20 145 232 116 58 30 15 135 244 39 91 138 80 130 34 148 160 8 37 40 66 9 138 80 130 34 148 160 8 37 40 66 9 138 80 130 34 148 160 8 37 40 66 137 247 20 193 200 165 215 58 69 204 255 35 136 25 161 69 12 123 190 128 41 32 153 175 136 65 236 152 13 162 189 46 34 190 0 230 156 18 77 139 24 7 201 128 217 219 252 31 228 251 138 96 108 124 36 119 69 199 143 225 51 158 46 34 57 35 151 175 95 247 163 128 32 207 35 151 195 254 214 223 235 107 164 143 92 114 51 94 72 238 192 25 18 229 6 79 17 11 33 216 141 228 78 250 225 195 253 2 130 11 51 156 184 61 65 99 0 0 0 0 73 69 78 68 174 66 96 130)! !
!DrGIcons class methodsFor: 'accessing'!
style
^self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 48 0 0 0 48 16 6 0 0 0 7 146 37 196 0 0 0 6 98 75 71 68 255 255 255 255 255 255 9 88 247 220 0 0 0 9 112 72 89 115 0 0 0 72 0 0 0 72 0 70 201 107 62 0 0 12 96 73 68 65 84 120 218 237 155 93 108 83 231 29 198 127 254 78 236 99 39 118 18 199 78 26 39 77 8 36 144 16 88 10 101 172 104 131 169 163 21 157 4 148 125 73 211 54 42 173 163 157 52 169 218 197 180 155 169 149 216 214 74 211 46 182 21 181 218 84 58 84 237 134 177 93 180 97 85 183 174 148 22 10 11 4 200 23 249 78 252 17 219 241 71 142 125 252 253 113 236 93 28 101 233 202 118 81 8 132 66 158 27 203 199 246 123 254 239 243 188 239 255 253 191 207 121 13 107 88 195 26 214 176 134 53 172 97 13 247 35 84 183 246 243 114 121 181 59 112 119 65 245 169 249 212 222 234 45 143 31 223 177 227 201 39 87 174 11 135 15 95 184 112 234 20 124 247 187 175 191 254 203 95 174 92 187 127 252 227 247 190 247 211 159 194 231 62 247 242 203 199 142 173 92 187 3 3 63 252 225 179 207 222 252 239 213 43 23 202 26 110 6 107 2 172 50 214 4 88 101 172 9 176 202 88 19 96 149 113 203 85 208 103 21 133 130 40 46 46 66 58 61 61 61 51 3 26 141 201 100 50 129 32 116 118 118 118 222 185 56 238 187 25 32 203 217 108 54 11 129 192 169 83 167 78 193 182 109 178 28 143 67 48 216 215 215 215 7 201 228 196 196 248 248 157 139 231 190 19 32 18 57 113 226 248 113 248 246 183 119 237 234 238 134 39 158 232 234 170 173 133 245 235 237 118 139 5 36 105 100 100 116 244 206 197 115 223 9 240 200 35 205 205 102 51 124 243 155 143 62 186 125 59 216 237 86 171 201 4 62 95 48 24 137 64 69 69 93 93 93 221 157 139 231 190 177 34 186 186 90 91 235 235 225 39 63 121 250 233 253 251 161 162 66 163 41 151 97 108 108 106 202 227 129 159 255 252 181 215 222 125 23 178 217 66 161 80 184 217 187 124 122 43 226 150 5 248 232 163 35 71 30 127 124 229 136 250 252 231 95 121 229 111 127 131 183 222 26 29 125 251 237 155 111 71 146 98 49 73 130 55 222 248 197 47 126 247 59 248 254 247 31 123 236 161 135 96 227 70 69 136 247 222 251 240 195 203 151 161 175 239 210 165 185 57 40 151 183 109 251 202 87 160 171 107 255 254 3 7 192 231 187 122 245 234 85 200 102 37 73 146 160 178 210 106 173 174 134 230 230 222 222 135 30 90 190 207 209 163 61 61 221 221 55 47 192 61 151 130 100 89 150 101 25 94 121 229 133 23 126 243 27 120 230 153 3 7 118 239 134 141 27 91 90 234 234 96 120 248 250 245 153 25 16 197 68 34 157 6 183 59 155 53 24 160 187 251 192 129 131 7 193 227 185 124 249 210 165 101 226 255 67 148 90 163 209 222 134 154 241 158 19 224 79 127 122 249 229 55 222 128 47 127 121 243 230 150 22 104 107 107 106 178 219 193 239 95 88 136 197 192 227 153 159 95 88 128 15 62 152 154 138 199 97 251 246 35 71 158 125 22 226 241 64 32 16 128 124 62 149 74 167 151 219 83 169 212 106 149 10 108 54 151 203 229 90 249 120 239 25 1 66 33 133 88 163 49 155 149 36 248 210 151 182 110 221 184 17 10 133 76 38 145 128 201 201 217 217 217 89 8 4 98 177 108 22 114 185 150 150 238 110 176 219 55 108 232 232 128 104 84 249 252 147 168 173 109 109 109 109 5 147 201 102 179 217 64 165 42 151 101 121 229 226 190 103 4 56 126 252 165 151 94 125 21 158 124 114 215 174 222 94 104 104 168 171 51 155 33 26 141 68 194 97 152 159 95 88 16 69 56 123 214 239 47 22 97 199 142 31 252 224 200 17 16 69 159 207 235 5 89 254 239 197 87 163 209 233 116 58 101 228 55 55 3 148 203 229 178 82 118 168 87 144 181 207 188 0 191 255 253 139 47 190 250 42 236 222 189 126 125 109 45 180 180 212 215 87 85 65 34 17 143 139 34 76 77 121 189 11 11 240 246 219 231 207 143 143 67 103 231 183 190 245 157 239 64 54 155 72 72 18 132 195 83 83 211 211 55 182 107 179 53 55 187 92 74 10 250 111 194 85 170 79 191 212 254 127 124 102 5 240 122 103 102 188 94 176 88 178 217 88 12 190 250 213 71 31 221 181 11 244 122 189 94 163 129 177 177 137 137 185 57 184 120 241 250 245 249 121 24 31 119 187 195 97 176 219 59 58 58 59 97 102 230 220 185 243 231 33 26 157 155 155 157 133 96 112 124 124 108 12 146 201 104 52 26 5 65 168 171 179 219 149 113 175 20 219 43 75 252 18 238 122 47 40 149 74 36 82 41 56 117 234 181 215 78 158 92 190 30 10 77 77 205 206 194 11 47 28 57 242 141 111 128 205 86 93 109 50 193 216 216 232 232 208 16 120 60 126 127 48 8 217 172 78 103 52 66 44 150 76 102 50 240 206 59 47 189 244 226 139 48 53 117 246 236 153 51 80 42 41 244 118 117 237 219 247 196 19 96 48 152 76 70 35 120 189 87 174 92 185 2 109 109 59 119 238 220 249 241 136 238 147 25 176 84 78 30 63 254 171 95 253 225 15 176 103 143 203 37 8 80 89 153 203 37 18 112 248 240 161 67 123 246 64 83 147 211 89 83 3 145 72 32 224 118 67 52 42 138 241 56 140 143 135 66 233 52 24 12 14 135 211 185 220 174 40 94 188 248 254 251 176 110 157 221 46 8 208 208 96 54 107 181 112 253 250 95 254 114 242 36 232 116 21 21 149 149 80 44 42 158 81 38 19 143 199 227 183 175 159 119 237 12 120 243 205 19 39 254 250 87 216 191 191 171 171 190 30 214 173 107 109 109 110 134 116 58 147 41 22 97 231 206 246 118 167 19 74 165 100 50 28 134 120 92 153 41 147 147 74 170 121 231 157 243 231 135 135 97 243 102 149 202 100 2 151 203 225 176 217 192 225 104 111 111 111 135 206 78 155 77 167 131 124 62 155 77 38 225 253 247 7 7 231 231 111 140 163 88 204 231 243 121 184 107 83 208 210 206 117 165 81 81 225 241 40 139 230 129 3 143 63 14 193 96 44 86 40 192 250 245 46 87 125 61 104 181 122 125 85 21 92 187 54 50 210 223 15 181 181 85 85 38 19 244 247 143 140 184 221 160 215 43 21 139 203 37 203 137 4 236 219 119 248 240 99 143 41 52 170 84 240 222 123 23 46 12 13 65 56 28 143 167 82 224 243 249 124 11 11 240 231 63 255 248 199 207 61 183 242 253 185 109 2 44 46 142 142 62 255 252 202 5 212 216 184 117 235 209 163 176 119 239 222 189 123 247 130 94 111 177 56 157 96 54 231 243 225 48 244 244 108 218 180 121 51 164 82 146 20 139 65 169 84 42 21 139 144 205 230 114 217 44 252 232 71 79 63 253 245 175 67 177 152 74 197 227 48 56 56 51 19 141 130 199 163 148 161 209 232 226 98 36 2 115 115 161 80 34 1 225 112 42 85 44 130 209 104 177 88 44 240 212 83 71 143 62 255 60 24 141 102 179 217 12 237 237 189 189 91 183 130 213 106 183 219 237 55 198 123 232 144 195 113 43 27 180 187 110 13 56 120 112 247 238 238 110 168 170 50 155 13 6 72 165 210 233 108 22 218 218 26 26 204 102 144 229 114 185 84 2 143 103 118 118 108 12 212 106 101 68 59 28 74 217 216 217 217 210 226 116 66 79 79 79 207 150 45 160 209 148 74 217 44 140 140 76 76 76 78 194 249 243 202 12 73 38 75 37 173 22 218 219 29 14 65 128 13 27 122 122 54 109 130 107 215 206 156 57 123 86 17 182 84 130 217 217 193 193 225 225 219 215 223 187 102 13 88 92 140 197 210 105 232 234 234 234 218 180 9 156 206 182 182 222 94 152 159 31 31 191 120 17 212 234 124 94 163 1 189 222 96 88 183 14 76 38 131 65 163 1 131 193 106 181 88 64 16 170 170 26 26 64 20 131 65 143 7 74 165 66 193 239 135 142 142 166 38 155 13 250 250 254 249 207 92 14 58 59 187 187 183 108 129 109 219 218 218 172 86 200 231 115 185 92 14 250 251 99 49 173 22 252 126 191 63 28 94 142 107 233 243 123 94 128 191 255 253 204 153 169 41 104 109 117 185 214 173 131 108 54 147 145 36 104 105 105 106 106 108 132 138 138 170 42 101 209 45 151 139 69 176 88 4 193 104 84 4 49 26 193 96 168 174 126 224 1 240 249 46 93 58 119 14 106 106 20 235 96 195 134 142 142 13 27 224 183 191 253 217 207 154 154 224 244 233 115 231 198 199 193 235 117 187 61 30 152 153 9 4 162 81 184 122 213 235 77 36 224 145 71 14 30 220 191 255 99 4 105 149 29 241 237 194 170 167 32 89 150 229 82 9 244 122 149 74 175 7 181 90 167 171 172 132 82 73 146 252 126 133 248 186 58 208 104 42 43 205 102 80 236 50 208 235 117 58 173 22 4 193 225 104 111 135 133 133 217 217 225 97 48 26 141 70 189 30 26 27 93 174 214 86 208 106 203 229 124 30 202 101 89 206 231 193 233 180 88 202 101 37 21 205 205 193 191 254 53 52 52 55 7 22 139 66 115 127 127 95 223 233 211 203 241 217 108 78 167 195 113 15 11 144 203 229 114 178 172 152 101 209 40 152 76 149 149 58 29 84 84 64 38 3 6 131 217 108 183 67 46 39 138 138 103 147 207 103 50 32 8 141 141 93 93 144 201 68 34 110 55 24 141 229 114 44 6 245 245 181 181 181 181 160 86 235 245 38 19 4 2 162 152 201 192 224 224 228 100 32 0 225 112 161 96 48 128 70 35 8 22 11 180 180 56 157 86 43 216 237 213 213 149 149 80 46 231 114 169 212 114 124 161 144 199 227 245 66 38 147 74 125 252 250 74 97 213 83 208 204 140 199 19 141 130 221 94 95 95 83 3 235 215 183 180 52 52 128 32 84 87 215 213 41 35 87 150 149 156 174 8 98 177 56 28 144 201 136 162 207 167 8 146 76 130 78 103 52 86 87 131 217 108 181 186 92 224 118 79 78 14 12 64 36 18 14 43 213 83 87 87 71 135 178 40 167 211 96 179 233 245 178 12 115 115 110 247 252 60 164 211 202 142 217 235 125 247 221 171 87 111 140 51 153 20 197 88 12 42 43 149 211 19 43 133 85 159 1 199 142 189 254 250 71 31 193 190 125 123 246 124 241 139 74 7 5 1 180 90 133 208 92 46 145 8 133 148 7 34 58 29 20 10 233 244 226 34 20 10 202 117 173 214 100 178 217 150 133 73 38 253 254 161 33 16 4 37 165 212 213 89 173 130 0 165 82 62 47 73 240 225 135 74 202 17 69 133 208 37 135 115 124 60 24 76 167 225 193 7 123 123 183 111 191 49 78 163 209 98 81 82 224 202 98 213 102 128 36 37 18 217 44 20 10 197 98 169 4 106 117 38 19 143 131 86 91 83 211 220 12 197 98 46 151 76 42 126 190 40 42 199 73 148 247 74 46 215 106 43 42 204 102 208 235 109 182 166 38 136 197 102 103 7 6 96 201 54 14 4 22 22 162 81 200 231 139 69 89 86 170 172 84 10 22 22 124 190 249 121 101 231 156 201 64 36 34 203 90 45 36 147 90 173 82 247 111 222 188 252 136 17 108 54 135 163 190 30 76 38 101 159 112 207 8 112 225 194 192 128 199 3 79 61 117 240 224 23 190 176 124 125 105 68 150 203 178 92 44 66 46 39 73 161 16 40 142 61 84 84 212 212 180 180 64 62 175 88 4 201 164 219 125 229 10 132 66 225 240 226 34 84 87 91 173 85 85 48 63 31 10 137 34 148 74 202 147 90 73 74 36 146 73 240 122 131 65 81 4 48 26 5 1 166 166 210 105 131 1 106 107 27 27 107 107 193 106 85 8 95 170 126 30 124 80 41 139 111 23 86 253 84 196 201 147 191 254 245 51 207 192 195 15 63 252 240 142 29 160 211 85 86 86 85 45 167 158 76 70 146 194 97 8 6 23 23 51 25 104 106 114 56 172 86 240 122 125 62 191 31 172 214 170 42 65 128 43 87 6 7 39 38 32 145 40 20 74 37 16 197 120 60 153 92 174 150 174 93 27 30 158 155 131 145 145 185 185 64 0 70 70 102 102 66 161 101 55 116 133 232 188 211 127 208 184 85 123 170 92 222 178 165 163 163 185 25 52 26 131 65 16 148 148 19 143 67 161 144 74 45 46 130 86 171 209 104 52 240 192 3 117 117 130 0 233 116 42 149 76 42 150 130 36 65 127 255 208 208 244 52 132 66 209 168 36 129 32 40 251 131 37 55 117 116 116 98 194 235 133 179 103 175 93 155 153 129 96 48 26 77 38 151 18 213 237 176 215 238 168 0 55 143 166 38 197 157 212 235 5 161 182 86 89 36 211 105 200 229 226 241 64 224 198 239 23 10 197 98 177 8 243 243 129 64 56 12 211 211 94 111 32 160 16 13 96 54 11 130 193 160 216 209 137 4 124 240 193 192 192 228 36 132 195 177 88 50 9 129 64 36 146 76 174 62 225 159 196 170 9 240 181 175 237 221 187 109 27 168 84 202 113 143 124 94 25 241 159 196 146 205 188 176 16 14 139 34 204 206 250 124 225 176 146 58 84 42 229 81 227 200 8 228 114 133 130 44 131 86 171 156 98 80 171 149 87 159 47 20 146 164 187 143 248 37 172 154 0 59 119 110 217 210 214 182 188 177 82 169 212 106 141 230 198 239 229 114 185 92 62 15 94 175 226 209 44 157 74 184 126 125 122 218 239 7 183 59 16 88 92 4 183 59 24 140 197 238 94 162 255 31 86 109 31 112 232 208 115 207 29 59 166 82 201 242 210 206 83 113 57 63 137 104 84 20 37 105 121 68 7 2 145 136 36 193 137 19 167 79 95 190 172 82 125 86 137 95 194 170 111 196 202 229 255 125 206 38 157 206 100 178 89 48 24 244 122 157 78 89 100 227 113 248 199 63 46 94 28 27 91 237 168 215 176 134 53 172 12 254 13 220 222 31 79 192 215 34 195 0 0 0 0 73 69 78 68 174 66 96 130)! !
!DrGIcons class methodsFor: 'accessing'!
text
^ self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 48 0 0 0 48 8 6 0 0 0 87 2 249 135 0 0 0 6 98 75 71 68 0 255 0 255 0 255 160 189 167 147 0 0 0 9 112 72 89 115 0 0 11 19 0 0 11 19 1 0 154 156 24 0 0 0 7 116 73 77 69 7 211 10 23 10 27 53 45 18 57 201 0 0 0 29 116 69 88 116 67 111 109 109 101 110 116 0 67 114 101 97 116 101 100 32 119 105 116 104 32 84 104 101 32 71 73 77 80 239 100 37 110 0 0 7 2 73 68 65 84 120 218 213 153 109 108 83 231 21 199 127 247 250 58 14 37 47 34 162 137 26 8 8 200 232 218 32 85 244 3 74 149 130 131 189 9 146 2 91 165 189 181 27 211 84 74 181 181 171 196 246 161 149 234 177 124 25 234 62 172 133 161 118 221 75 187 85 69 41 41 74 211 109 140 81 66 67 92 84 4 10 66 17 162 82 149 208 208 166 149 105 154 242 22 47 241 181 125 95 158 125 240 181 99 59 126 185 118 46 176 61 210 163 35 251 185 47 231 252 159 255 57 231 57 247 192 255 249 144 138 172 203 214 53 210 77 214 67 100 77 71 198 47 114 60 216 241 185 114 229 202 43 77 77 77 239 0 143 2 75 128 133 22 112 243 26 50 32 70 71 71 197 205 30 145 72 68 12 15 15 139 93 187 118 37 141 90 6 84 217 53 34 31 53 92 128 46 68 249 187 105 247 94 195 48 208 52 13 85 85 185 112 225 2 237 237 237 0 119 3 95 0 51 128 89 12 233 114 124 195 177 161 235 58 227 227 227 212 213 213 177 118 237 90 142 30 61 10 48 2 220 5 220 81 108 39 228 255 133 72 162 105 26 0 53 53 53 172 91 183 142 190 190 62 60 30 207 8 208 88 204 136 124 72 43 128 150 78 131 129 129 129 146 148 242 249 124 182 40 22 139 197 56 121 242 36 155 54 109 194 52 77 100 89 102 108 108 140 51 103 78 243 228 147 79 17 14 135 239 6 46 3 145 98 116 202 54 160 108 199 52 77 115 206 52 12 35 231 156 153 153 22 71 142 28 17 66 8 17 139 197 132 174 235 66 8 33 206 158 61 43 186 187 187 147 142 189 218 138 78 210 77 165 144 16 34 195 121 147 191 51 29 90 100 252 47 4 168 170 202 213 171 87 25 26 26 98 120 120 152 99 199 142 161 170 42 205 205 171 232 233 233 1 120 6 88 12 84 228 66 218 214 40 68 161 92 17 103 174 210 153 235 126 191 63 149 14 132 16 236 220 185 147 72 36 130 16 102 10 232 134 134 122 182 108 217 10 176 3 248 11 16 6 180 116 42 217 246 129 82 67 165 105 154 121 147 110 242 54 33 4 209 104 20 73 146 56 119 238 28 147 147 147 68 34 51 76 78 126 197 141 27 55 8 135 195 140 140 140 112 252 248 113 128 135 128 243 192 151 128 94 242 14 148 18 227 139 161 159 88 79 252 121 234 212 41 58 58 58 50 214 15 29 122 139 229 203 55 48 53 53 69 48 88 147 52 192 147 75 95 71 40 148 174 84 66 217 108 165 179 255 159 93 239 236 236 228 189 127 244 113 254 189 126 154 174 125 65 141 167 146 205 223 251 62 211 211 211 128 64 211 244 130 108 177 109 64 130 179 249 209 46 85 130 224 196 137 65 218 218 218 184 62 254 9 202 7 239 242 177 41 209 177 170 41 195 217 237 156 121 230 125 92 152 69 223 190 20 66 208 217 217 201 190 192 179 252 251 119 123 240 40 110 58 86 53 177 120 243 183 211 34 152 189 120 95 50 133 242 163 74 94 180 179 41 213 219 251 54 109 109 109 76 124 50 198 198 134 90 46 199 117 170 214 220 207 235 35 159 149 116 150 42 153 66 133 169 145 143 235 115 101 103 231 67 124 254 241 40 163 67 167 185 254 200 207 240 93 251 146 5 171 191 206 238 31 237 164 247 79 47 219 54 66 41 143 46 133 80 46 46 247 238 221 71 115 115 51 166 219 67 237 234 22 180 186 6 234 151 47 163 223 218 229 111 254 224 135 57 18 224 60 12 16 66 48 48 48 80 132 50 246 35 80 32 16 96 232 216 235 168 103 118 240 233 231 17 54 248 188 92 17 219 121 236 231 79 243 219 103 126 73 48 24 196 235 245 58 67 161 36 18 62 159 175 44 180 179 229 190 125 191 199 239 247 51 29 158 160 38 237 61 7 14 28 0 224 167 207 237 46 232 95 101 25 96 95 206 85 56 251 154 64 32 192 233 127 237 103 209 204 63 249 208 66 223 93 123 15 207 63 255 99 246 60 251 68 73 202 219 164 80 66 153 217 40 148 63 41 21 91 239 235 235 195 239 247 179 184 202 196 152 153 189 227 149 131 31 1 208 242 64 7 193 96 16 16 172 95 191 1 16 5 142 36 182 119 128 57 20 42 236 200 249 175 217 186 117 43 195 239 247 96 76 188 154 66 255 74 229 118 158 251 213 189 244 254 249 101 188 94 111 234 122 211 52 83 211 1 10 149 207 249 164 28 28 12 226 247 251 185 62 249 41 11 114 112 223 255 221 71 82 239 50 77 129 105 26 232 186 225 148 1 185 40 148 139 50 137 5 171 48 207 64 127 219 182 109 121 185 255 198 107 47 100 212 8 134 97 96 24 6 186 174 99 24 134 51 62 224 243 109 44 27 253 96 48 88 144 251 91 30 254 9 66 36 80 55 12 19 93 215 208 52 221 146 218 252 125 160 52 165 69 14 244 191 197 135 31 252 13 35 212 157 66 191 122 69 130 251 111 247 188 146 66 221 52 77 98 177 24 241 120 28 77 139 163 235 6 170 170 222 26 31 200 231 184 99 99 151 240 251 253 212 214 52 50 19 154 125 238 139 251 95 3 192 251 141 239 164 232 18 141 70 137 199 99 68 163 49 52 45 14 72 40 138 226 12 133 202 221 133 195 135 15 211 210 210 194 64 239 95 185 171 225 107 84 47 128 234 21 219 9 116 221 75 239 193 63 160 235 58 154 22 71 85 163 196 227 113 84 85 69 8 129 44 203 200 178 132 44 203 78 100 98 24 28 60 145 133 118 250 119 217 92 232 39 86 187 186 186 24 232 217 203 165 139 49 0 54 60 250 116 10 125 141 69 244 247 247 19 143 199 137 70 163 214 103 21 23 146 4 173 173 173 184 92 46 92 46 151 51 62 208 222 190 177 44 31 0 136 68 84 154 150 46 165 110 81 53 99 151 198 9 116 189 192 137 119 15 81 191 244 30 84 53 66 60 174 161 40 74 26 234 46 20 69 113 198 128 98 201 201 142 252 234 63 58 245 75 86 80 219 188 140 213 107 188 244 255 253 85 106 239 92 201 212 212 20 146 36 161 40 110 20 101 86 105 183 91 65 8 129 219 237 198 227 241 56 69 161 65 219 71 137 108 231 62 63 26 226 190 170 70 182 172 241 242 199 23 119 243 209 248 52 198 165 247 45 101 43 80 20 151 133 182 140 44 187 144 101 137 7 31 92 143 44 75 78 80 40 153 156 188 101 214 190 112 229 218 117 30 219 241 56 7 223 60 192 146 165 203 144 36 137 202 202 74 60 30 15 110 183 146 218 1 73 146 113 185 18 78 43 73 137 26 222 1 39 46 45 108 166 135 94 93 79 100 209 238 131 135 120 233 165 253 212 55 52 82 81 81 65 117 117 181 69 153 10 20 69 70 146 18 220 7 9 73 74 188 51 41 29 58 141 38 178 105 118 132 41 20 129 132 16 86 44 135 61 123 126 67 107 235 3 120 60 21 44 92 88 149 66 91 146 64 150 93 41 96 102 149 23 206 213 196 201 7 37 43 164 82 234 2 211 52 184 124 57 132 16 38 134 97 166 56 158 173 112 182 191 101 3 115 11 11 154 76 154 73 146 140 162 72 8 225 66 81 210 105 40 89 40 219 15 197 243 174 137 157 168 206 74 247 35 7 107 226 114 191 64 148 47 29 246 1 167 107 99 123 210 94 59 53 239 184 120 241 98 201 159 12 243 161 154 116 80 251 50 161 67 40 20 42 127 7 38 38 38 44 35 110 207 8 133 66 132 195 225 204 152 109 115 184 128 95 115 11 58 245 54 103 15 176 217 234 90 42 118 186 148 50 80 67 162 107 222 8 44 184 149 189 227 57 153 20 84 171 83 249 153 213 102 42 218 98 2 112 91 157 193 59 44 171 111 167 1 186 213 102 157 177 122 100 216 49 32 185 19 210 109 84 62 243 136 155 163 79 252 95 25 186 111 33 126 22 55 5 0 0 0 0 73 69 78 68 174 66 96 130)! !
!DrGIcons class methodsFor: 'accessing'!
translation
^ self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 48 0 0 0 48 16 6 0 0 0 7 146 37 196 0 0 0 6 98 75 71 68 255 255 255 255 255 255 9 88 247 220 0 0 0 9 112 72 89 115 0 0 0 72 0 0 0 72 0 70 201 107 62 0 0 2 82 73 68 65 84 120 218 237 150 191 106 194 80 20 135 175 165 110 250 16 86 66 199 128 139 116 232 35 152 181 72 36 184 20 132 14 78 46 18 16 33 147 62 66 183 46 77 23 31 32 56 185 56 41 100 22 218 161 67 119 151 14 29 110 7 57 4 143 164 73 108 146 147 120 207 183 92 126 33 38 242 157 63 68 8 134 148 10 245 31 160 162 213 178 172 86 75 74 200 219 237 203 203 118 11 169 146 155 151 43 106 17 212 104 218 253 253 237 45 221 251 175 169 5 228 5 238 248 184 247 29 38 35 187 137 80 102 5 129 216 184 29 255 246 246 248 248 250 10 41 191 149 116 225 64 103 7 231 195 195 243 115 183 123 122 253 248 204 14 101 86 208 129 160 147 255 94 73 220 241 137 249 248 152 205 102 179 64 40 100 207 235 118 131 14 15 56 46 64 84 199 71 77 72 246 147 82 24 194 68 67 222 108 122 189 94 47 200 211 105 167 211 233 72 105 219 182 109 219 231 138 82 80 52 128 5 3 88 52 206 97 157 127 30 248 57 10 23 98 179 49 77 211 140 47 62 221 9 136 123 93 1 242 17 15 68 253 94 161 66 124 125 13 6 131 65 184 120 200 147 201 120 60 30 7 215 211 41 68 20 201 159 95 154 207 173 247 247 249 124 62 151 242 230 102 52 26 141 42 21 207 59 172 162 245 122 191 223 239 133 184 187 171 213 106 53 33 86 171 102 179 217 20 162 90 245 125 223 23 226 231 71 215 117 93 8 199 113 28 199 201 235 243 18 10 113 1 159 179 32 30 50 136 159 78 13 195 48 78 87 14 100 220 241 249 76 0 166 196 171 41 174 120 44 246 233 169 221 110 183 169 197 151 152 115 197 39 205 12 162 108 226 191 191 135 195 225 80 74 124 46 151 141 70 163 81 162 66 167 37 30 147 86 33 194 68 239 118 154 166 105 193 9 226 251 253 122 189 94 151 210 178 44 203 178 10 92 136 172 196 99 146 222 31 87 56 22 143 11 64 237 151 92 252 127 73 42 190 240 19 80 22 241 24 22 79 76 148 248 176 213 67 94 136 178 139 199 43 8 139 198 185 48 19 112 233 226 225 190 40 241 185 23 66 21 241 88 44 249 234 81 85 124 210 204 226 89 252 101 137 199 100 94 8 22 31 15 22 143 200 75 124 234 176 120 34 88 60 17 44 158 136 207 207 197 98 177 96 241 228 176 248 130 193 226 11 2 139 87 28 22 79 4 139 39 130 197 19 193 226 137 96 241 68 176 120 34 164 116 93 215 101 241 228 176 248 130 193 226 11 130 106 226 127 1 94 140 135 70 242 90 129 96 0 0 0 0 73 69 78 68 174 66 96 130)! !
!DrGIcons class methodsFor: 'accessing'!
undo
^ self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 48 0 0 0 48 8 6 0 0 0 87 2 249 135 0 0 0 6 98 75 71 68 0 255 0 255 0 255 160 189 167 147 0 0 0 9 112 72 89 115 0 0 13 215 0 0 13 215 1 66 40 155 120 0 0 0 7 116 73 77 69 7 215 6 21 14 22 33 113 7 92 185 0 0 7 60 73 68 65 84 104 222 237 89 107 108 20 215 21 254 238 157 153 125 122 237 181 177 215 15 176 193 177 113 32 161 113 29 40 33 102 72 8 105 72 34 138 148 168 65 233 35 49 83 210 170 106 165 72 105 127 164 162 74 164 86 85 155 164 74 11 149 104 162 40 73 181 38 52 13 105 107 42 34 145 166 136 38 38 107 48 21 41 208 96 108 48 182 99 27 227 7 182 215 235 245 122 119 102 238 220 219 31 187 80 199 216 142 141 119 183 137 228 35 141 102 164 189 115 231 251 238 61 247 156 239 156 5 22 108 193 22 236 11 109 36 85 19 7 252 120 16 32 127 1 196 34 85 67 44 85 223 161 169 152 180 161 150 124 223 225 41 254 43 32 156 169 222 129 164 19 56 246 134 244 130 39 175 114 87 229 131 117 78 66 8 79 53 1 57 137 46 163 72 146 252 102 78 241 189 95 43 191 227 5 7 145 92 105 57 3 52 73 224 179 36 89 62 186 248 150 237 91 203 239 124 209 1 222 158 182 67 44 39 1 124 177 36 201 245 101 107 127 186 36 119 233 54 69 152 231 0 30 1 148 47 0 129 128 31 149 84 146 143 220 114 207 158 108 79 222 58 42 140 51 128 48 210 26 70 229 121 128 223 44 219 220 117 183 109 174 117 57 50 74 72 28 188 149 246 60 112 67 4 26 106 201 14 155 203 183 231 182 205 251 156 138 205 9 97 52 1 16 147 70 9 72 74 38 129 24 111 106 252 35 206 91 140 157 22 66 180 0 104 5 208 172 106 24 249 191 36 178 99 111 72 191 116 121 203 159 186 117 147 223 69 201 56 192 58 167 89 154 18 128 228 128 25 87 96 198 250 97 140 247 136 232 104 103 44 60 212 98 6 47 159 80 0 243 109 139 177 159 171 26 58 210 66 32 224 135 44 73 242 94 111 209 250 135 43 170 119 57 32 250 0 214 55 195 27 102 226 110 3 72 252 34 196 1 16 39 132 144 49 124 233 239 172 227 212 171 166 197 70 15 89 204 124 86 213 208 156 50 2 1 63 60 146 44 31 42 172 216 182 166 184 114 167 3 172 13 176 130 51 188 193 1 48 64 152 16 194 188 246 124 237 78 156 32 202 114 128 248 48 210 123 152 183 127 244 138 206 204 208 33 139 153 143 205 85 118 144 89 128 47 146 100 185 190 180 234 169 165 190 242 26 69 152 205 0 31 251 140 183 174 2 54 33 196 36 240 19 126 3 177 3 114 5 32 149 160 231 220 107 177 203 231 235 154 44 198 238 85 53 132 146 66 32 224 199 42 42 73 239 175 216 240 171 156 172 130 77 84 232 167 33 68 44 30 109 196 56 32 24 0 1 1 145 56 196 2 16 28 32 18 8 20 0 28 2 102 28 240 213 11 137 93 185 74 66 24 32 52 11 212 181 5 253 109 117 70 215 199 111 117 89 22 83 85 13 253 243 38 208 80 75 130 55 173 254 110 86 238 178 175 19 22 122 21 156 13 64 240 49 64 68 103 185 60 87 253 222 14 66 221 0 205 72 4 190 56 240 107 46 38 12 16 234 130 156 249 77 12 117 253 147 117 156 222 119 133 91 92 85 53 180 207 119 7 54 75 178 237 192 10 245 71 46 135 203 1 99 228 181 249 39 42 34 131 16 119 156 16 177 1 194 128 16 70 124 94 98 131 205 187 3 35 125 167 121 251 169 55 207 115 75 220 170 106 215 197 231 57 159 129 59 168 68 255 177 124 237 14 143 219 91 68 98 67 187 33 120 36 73 213 136 18 39 2 154 32 162 131 16 59 156 190 95 160 245 196 174 200 232 149 142 31 170 26 246 38 35 10 173 164 148 124 88 90 245 104 118 86 254 42 26 27 250 13 196 140 81 232 6 52 37 81 18 231 130 67 113 223 3 33 175 67 211 251 207 13 115 142 98 85 195 248 188 212 168 170 161 153 115 113 123 199 169 183 122 134 186 143 51 103 238 78 80 185 32 137 4 56 32 244 68 248 5 204 72 61 20 187 19 190 210 117 110 74 241 76 210 50 113 192 143 92 42 225 104 65 217 221 229 133 21 15 41 177 161 221 224 230 212 153 88 113 127 21 138 103 11 32 24 132 136 2 60 10 110 13 193 210 207 194 138 157 133 224 163 51 126 75 178 175 128 146 249 4 206 28 222 25 229 140 21 78 23 90 231 164 133 84 13 131 1 63 214 246 181 213 31 102 122 164 170 248 75 63 182 235 193 151 97 233 45 215 141 181 101 62 140 166 250 231 25 183 162 134 108 115 114 197 230 230 206 204 60 155 183 224 203 14 151 239 219 16 86 15 244 208 159 192 141 169 149 132 165 183 192 70 34 240 228 44 181 66 3 109 85 0 62 72 138 152 83 53 140 5 252 184 123 240 210 201 3 166 17 217 84 122 251 15 28 102 168 22 44 246 239 73 206 233 68 44 220 77 132 64 149 30 129 19 128 119 164 191 101 213 64 199 135 223 16 144 215 248 150 126 69 20 221 252 164 211 210 255 5 99 180 110 202 232 198 141 78 120 22 149 56 66 3 109 171 167 35 112 67 21 153 170 193 224 22 182 134 6 154 247 95 60 177 59 170 100 62 14 217 181 97 186 225 93 170 134 51 170 134 122 85 195 239 239 124 12 27 56 99 121 3 29 199 95 255 248 200 179 81 93 95 36 236 217 79 76 125 50 204 78 184 50 75 100 73 198 93 73 47 41 85 13 188 250 113 104 99 195 29 123 90 26 126 29 149 220 91 161 100 60 48 235 93 172 174 193 147 166 30 185 171 181 241 149 136 101 229 66 201 184 239 122 55 50 59 225 200 92 6 33 176 58 101 53 113 117 13 158 142 134 123 159 105 174 127 62 70 108 42 108 153 219 230 178 8 39 45 198 190 117 161 241 229 168 146 241 80 92 27 77 172 40 88 63 20 123 30 4 71 126 74 139 250 245 53 248 173 17 29 254 222 185 250 231 162 156 84 192 238 253 206 92 72 188 195 98 131 23 245 72 39 36 91 233 167 67 164 148 11 51 214 11 74 209 157 242 190 208 250 237 216 103 234 145 71 154 143 190 56 110 154 217 115 203 2 28 135 35 193 11 156 42 203 62 13 78 46 64 44 220 9 16 156 74 75 99 75 213 112 136 153 250 125 45 129 223 133 195 87 26 196 28 68 189 141 16 65 38 71 34 42 251 48 62 218 195 44 134 99 105 235 204 169 26 142 89 150 85 221 218 248 135 160 16 144 102 37 36 40 54 58 60 5 196 154 148 20 137 156 135 72 240 114 20 72 211 14 76 32 113 150 115 177 26 248 108 57 28 23 139 238 155 236 174 92 112 243 210 4 255 95 4 1 47 66 131 29 74 218 9 36 72 124 2 160 122 66 113 60 21 120 59 165 216 191 172 242 126 167 21 61 145 208 67 137 12 235 170 198 96 215 113 19 220 216 171 106 8 166 188 55 58 13 137 254 153 154 4 148 162 54 187 240 102 159 59 43 151 232 35 7 255 183 170 182 50 112 228 163 183 237 61 198 57 126 150 150 230 238 92 123 169 84 194 187 217 249 101 149 75 86 110 116 154 225 131 137 242 20 32 82 22 100 231 70 92 60 249 78 68 88 198 211 170 134 222 207 21 129 128 31 249 84 66 99 97 89 85 81 94 73 165 205 28 59 0 206 6 18 224 189 80 50 182 160 231 66 32 22 29 235 127 111 253 118 188 148 182 246 250 172 75 23 9 251 23 47 95 183 36 167 104 137 108 140 254 249 90 117 71 229 124 200 174 77 232 110 57 30 29 233 107 63 195 45 212 164 165 59 61 199 213 127 192 233 41 90 147 93 84 34 27 225 191 37 20 40 133 228 168 4 145 203 241 201 127 62 24 15 7 123 143 112 11 143 168 26 140 207 29 1 0 65 42 201 22 248 24 8 117 131 72 197 144 236 43 17 30 30 18 221 205 7 99 156 233 47 113 142 159 168 26 102 253 207 78 186 9 52 71 66 151 73 112 96 49 207 240 170 52 26 30 196 112 235 71 227 225 225 222 62 110 225 81 85 195 201 148 55 119 147 224 70 37 84 66 29 128 66 66 208 96 49 188 11 96 159 170 77 159 47 22 108 193 22 108 122 251 47 1 167 63 47 137 31 193 98 0 0 0 0 73 69 78 68 174 66 96 130)! !
!DrGIcons class methodsFor: 'accessing'!
vector
^self formFromGraphic: #(137 80 78 71 13 10 26 10 0 0 0 13 73 72 68 82 0 0 0 48 0 0 0 48 16 6 0 0 0 7 146 37 196 0 0 0 6 98 75 71 68 255 255 255 255 255 255 9 88 247 220 0 0 0 9 112 72 89 115 0 0 0 72 0 0 0 72 0 70 201 107 62 0 0 1 73 73 68 65 84 120 218 237 213 49 142 130 64 20 128 225 113 59 11 14 65 193 77 188 0 23 152 120 3 206 194 13 204 196 130 154 130 202 214 83 88 16 19 75 58 10 27 34 86 47 36 99 8 236 46 227 51 248 127 141 25 108 204 255 230 161 49 0 0 0 0 0 0 111 179 209 254 1 159 226 126 207 178 44 235 123 255 249 249 92 150 101 105 204 110 87 215 117 189 89 188 215 215 13 96 44 244 237 86 85 85 53 156 175 215 174 235 58 99 142 199 166 105 26 99 30 143 52 77 83 99 156 115 206 185 229 6 177 250 1 204 13 46 36 188 144 1 28 14 109 219 182 203 111 192 143 118 160 208 182 219 60 207 243 33 220 220 240 62 107 173 181 246 117 144 255 181 250 13 240 93 46 73 146 36 67 200 177 240 161 95 61 98 245 27 48 102 234 198 11 9 31 106 3 190 102 0 99 255 5 114 211 199 206 18 62 212 6 172 158 132 151 87 207 233 20 199 113 220 247 251 125 20 69 209 48 16 57 203 167 127 227 67 109 192 106 205 13 239 135 157 250 30 19 254 26 254 183 103 120 8 175 100 169 240 62 6 49 33 84 120 31 225 61 239 10 15 15 225 149 16 94 9 225 149 16 94 9 225 149 16 94 9 225 149 16 94 9 225 149 16 94 9 225 149 16 94 9 225 149 244 125 81 20 5 225 213 17 254 195 16 254 67 16 30 0 0 0 175 158 187 58 229 157 66 156 78 5 0 0 0 0 73 69 78 68 174 66 96 130)! !
!DrGIcons class methodsFor: 'form' stamp: 'hlsf 2/11/2022 21:52:16'!
colorForm: aColor
| graphic |
graphic _ aColor isTransparent
ifFalse: [
BoxedMorph new ::
morphExtent: self menuExtent;
color: aColor;
borderWidth: 1;
borderColor: Color black;
yourself]
ifTrue: [Form extent: self menuExtent depth: 32 ::
fillShape: self hatchForm fillColor: `Color white`;
yourself].
^ self iconWithBackground: graphic! !
!DrGIcons class methodsFor: 'form'!
formFromGraphic: anArray
^ self formFromPNG: anArray
! !
!DrGIcons class methodsFor: 'form'!
formFromPNG: anArray
^ PNGReadWriter formFromStream: anArray asByteArray readStream
! !
!DrGIcons class methodsFor: 'form'!
iconWith: morphOrForm background: aColor
^ self iconWith: morphOrForm extent: self menuExtent inset: self menuInset background: aColor
! !
!DrGIcons class methodsFor: 'form' stamp: 'hlsf 7/6/2022 09:06:53'!
iconWith: morphOrForm extent: extent inset: inset background: aColor
| form imageForm |
(morphOrForm is: #Morph)
ifTrue: [ imageForm _ morphOrForm
imageForm: morphOrForm morphExtentInOwner + (0@1)
depth: 32.]
ifFalse: [imageForm _ morphOrForm].
form _ (Form extent: extent + (inset * 2) depth: 32) fillColor: aColor.
form
copy: imageForm boundingBox
from: imageForm
to: (extent - imageForm extent ) // 2 + inset
rule: Form blend .
^ form! !
!DrGIcons class methodsFor: 'form'!
iconWithBackground: morphOrForm
^ self iconWith: morphOrForm background: Color white! !
!DrGIcons class methodsFor: 'form' stamp: 'hlsf 6/5/2022 11:01:27'!
point: pointSize color: color shape: shape
^ self
iconWith: (self pointMorph: pointSize color: color shape: shape)
extent: (DrGTypePointSize pointExtentFor: pointSize)
inset: self menuInset
background: Color white.! !
!DrGIcons class methodsFor: 'form' stamp: 'hlsf 1/6/2022 21:55:51'!
pointMorph: sizeSymbol color: color shape: shapeSymbol
| morph |
morph _ DrGIconPointMorph new ::
color: color.
(morph style) shape: shapeSymbol ;
pointSize: sizeSymbol.
^ morph
! !
!DrGIcons class methodsFor: 'form'!
segment: thick color: color dash: dash
^ self iconWithBackground: (self segmentMorph: thick color: color dash: dash).
! !
!DrGIcons class methodsFor: 'form' stamp: 'hlsf 2/12/2022 15:50:25'!
segment: thick color: color dash: dash arrow: symbol
"#makeBackArrow #makeForwardArrow #makeBothArrows"
| morph |
morph _ self segmentMorph: thick color: color dash: dash.
morph arrow: symbol.
^ self iconWithBackground: morph
! !
!DrGIcons class methodsFor: 'form' stamp: 'hlsf 2/11/2022 10:42:11'!
segment: thick color: color mark: mark
" #none #mark1 #mark2 #mark3 #disc #circle "
| morph |
morph _ self segmentMorph: thick color: color dash: nil ::
forcedMark: mark;
yourself.
^ self iconWithBackground: morph.
! !
!DrGIcons class methodsFor: 'form' stamp: 'hlsf 5/31/2023 18:02:30'!
segmentMorph: thick color: color dash: dash
^ DrGIconSegmentMorph from: 0@0 to: self menuExtent x @0 color: color ::
borderWidth: thick;
dashedBorder: dash;
yourself! !
!DrGIcons class methodsFor: 'helpers' stamp: 'hlsf 10/19/2022 15:51:51'!
for: symbol
" Return a form representing the icon at the toolbar icon size "
^ self scale: symbol to: DrGeoSystem toolbarIconSize! !
!DrGIcons class methodsFor: 'helpers' stamp: 'hlsf 11/2/2022 19:57:47'!
iconUI: symbol
"The icons as display in the UI"
| finalForm iconForm |
iconForm _ DrGIcons for: symbol.
finalForm _ (Form extent: (DrGeoSystem toolbarIconSize + 4) asPoint depth: 32)
fillColor: DrGUIControlsManager buttonColor.
finalForm border: finalForm boundingBox width: 2 fillColor: DrGUIControlsManager buttonColor muchDarker.
finalForm
copy: iconForm boundingBox
from: iconForm
to: (finalForm extent - iconForm extent ) // 2
rule: Form blend .
^ finalForm ! !
!DrGIcons class methodsFor: 'helpers'!
menuExtent
^ 60@12! !
!DrGIcons class methodsFor: 'helpers'!
menuInset
^ 4! !
!DrGIcons class methodsFor: 'helpers' stamp: 'hlsf 10/19/2022 15:51:51'!
scale: symbol to: integer
| formSymbol |
formSymbol _ (symbol, integer asString) asSymbol.
^ self forms
at: formSymbol
ifAbsentPut: [ |svg |
svg _ [SVGMainMorph fromFile: DrGeoSystem iconsPath // (symbol, '.svg')]
on: SVGWarning
do: [:warning | warning resume].
svg imageForm: integer asPoint depth: 32]! !
!DrGIcons class methodsFor: 'initialize-release'!
reset
forms _ nil! !
!DrGUIControlsManager methodsFor: 'accessing'!
presenter: aPresenter
presenter _ aPresenter! !
!DrGUIControlsManager methodsFor: 'accessing' stamp: 'hlsf 4/10/2022 12:25:59'!
view
^ view! !
!DrGUIControlsManager methodsFor: 'initialization' stamp: 'hlsf 8/4/2023 12:37:57'!
installTools
" Install menu, toolbar, tree, wheels, statusbar "
| row col |
view := DrGeoView for: presenter.
view
addMorph: self quickToolbar layoutSpec: (LayoutSpec fixedHeight: DrGeoSystem toolbarIconSize + 4).
row := LayoutMorph newRow.
row
addMorph: self treeView proportionalWidth: 0.1;
addAdjusterMorph;
addMorphUseAll: view drawable.
"Install the wheels at the right"
col := LayoutMorph newColumn name: #wheelsYZ.
col addMorph: self zoomWheel layoutSpec: (
LayoutSpec fixedExtent: DrGeoSystem wheelWidth @ DrGeoSystem wheelHeight).
col addMorphUseAll: self transparentMorph.
col addMorph: self verticalWheel layoutSpec: (
LayoutSpec fixedExtent: DrGeoSystem wheelWidth @ DrGeoSystem wheelHeight).
""
row addMorph: col layoutSpec: (LayoutSpec fixedWidth: DrGeoSystem wheelWidth proportionalHeight: 1).
view addMorph: row.
"Install wheel at the bottom"
row := LayoutMorph newRow name: #wheelX; yourself.
row addMorphUseAll: (
PluggableScrollPane new scroller: self statusBar;
borderWidth: 2;
borderColor: Color transparent ;
yourself).
row addMorph:self horizontalWheel layoutSpec:
(LayoutSpec fixedExtent: DrGeoSystem wheelHeight @ DrGeoSystem wheelWidth).
row addMorph: self transparentMorph layoutSpec:
(LayoutSpec fixedExtent: DrGeoSystem wheelWidth asPoint) .
view addMorph: row layoutSpec: (LayoutSpec fixedHeight: DrGeoSystem wheelWidth)
! !
!DrGUIControlsManager methodsFor: 'initialization' stamp: 'hlsf 4/10/2022 14:48:23'!
release
presenter _ nil.
tools ifNotNil: [
tools delete.
tools _ nil].
view release.
view _ nil! !
!DrGUIControlsManager methodsFor: 'tools collections'!
animateTools
^ #(#animate1 #animate2 #animate3 #animate4)! !
!DrGUIControlsManager methodsFor: 'tools collections'!
curveTools
^ #(#line #parallel #perpendicular #perpendicularBisector #angleBisector #ray #segment #vector #circle #arc #arcCenter #polygon #polygonRegular #locus)! !
!DrGUIControlsManager methodsFor: 'tools collections'!
macroTools
^ #(#macroBuild #macroExecute)! !
!DrGUIControlsManager methodsFor: 'tools collections' stamp: 'hlsf 3/13/2023 21:12:26'!
miscTools
^ #(#new #open #keep #exportImage
#undo #redo
#axes #grid #magneticGrid
#multipleMode #move
#eraser #style #property)! !
!DrGUIControlsManager methodsFor: 'tools collections'!
numericTools
^ #(#distance #angleOriented #angleGeometric #coordinates #text)! !
!DrGUIControlsManager methodsFor: 'tools collections'!
pointTools
^ #(#freePoint #middle #intersection #pointByCoordinates)! !
!DrGUIControlsManager methodsFor: 'tools collections'!
scriptTools
^ #(#scriptRun #scriptEdit #scriptCreate)! !
!DrGUIControlsManager methodsFor: 'tools collections'!
transformationTools
^ #(#symmetry #reflection #translation #rotation #homothety)! !
!DrGUIControlsManager methodsFor: 'tools data'!
angleBisectorButtonData
^ {DrGAngleBisectorBuilder title. #angleBisector. #createAngleBisector. DrGAngleBisectorBuilder description}! !
!DrGUIControlsManager methodsFor: 'tools data' stamp: 'hlsf 12/4/2021 20:11:56'!
angleGeometricButtonData
^ {DrGAngleGeometricBuilder title. #geometricAngle. #createAngleGeometric. DrGAngleGeometricBuilder description}! !
!DrGUIControlsManager methodsFor: 'tools data' stamp: 'hlsf 12/4/2021 20:10:14'!
angleOrientedButtonData
^ {DrGAngleOrientedBuilder title. #orientedAngle. #createAngleOriented. DrGAngleOrientedBuilder description}! !
!DrGUIControlsManager methodsFor: 'tools data'!
animate1ButtonData
^ {'Animate x1' translated. #animate1. #animate1. 'Animate at speed 1.' translated}! !
!DrGUIControlsManager methodsFor: 'tools data'!
animate2ButtonData
^ {'Animate x2' translated. #animate2. #animate2. 'Animate at speed 2.' translated}! !
!DrGUIControlsManager methodsFor: 'tools data'!
animate3ButtonData
^ {'Animate x3' translated. #animate3. #animate3. 'Animate at speed 3.' translated}! !
!DrGUIControlsManager methodsFor: 'tools data' stamp: 'hlsf 12/4/2021 20:12:31'!
animate4ButtonData
^ {'Animate x4' translated. #animate3. #animate3. 'Animate at speed 4.' translated}! !
!DrGUIControlsManager methodsFor: 'tools data'!
arcButtonData
^ {DrGArcBuilder title. #arc. #createArc. DrGArcBuilder description}! !
!DrGUIControlsManager methodsFor: 'tools data'!
arcCenterButtonData
^ {DrGArcCenterBuilder title. #arcCenter. #createArcCenter. DrGArcCenterBuilder description}! !
!DrGUIControlsManager methodsFor: 'tools data' stamp: 'hlsf 12/4/2021 19:56:30'!
axesButtonData
^ {#axesWording. #axes. #axesOnOff. 'Show or hide the ox and oy axes.' translated. #isAxesVisible}! !
!DrGUIControlsManager methodsFor: 'tools data'!
circleButtonData
^ {DrGCircleBuilder title. #circle. #createCircle. DrGCircleBuilder description}! !
!DrGUIControlsManager methodsFor: 'tools data'!
coordinatesButtonData
^ {DrGCoordinatesBuilder title. #coordinates. #createCoordinates. DrGCoordinatesBuilder description}! !
!DrGUIControlsManager methodsFor: 'tools data'!
distanceButtonData
^ {DrGValueBuilder title. #distance. #createDistance. DrGValueBuilder description}! !
!DrGUIControlsManager methodsFor: 'tools data'!
eraserButtonData
^ {DrGDeleteTool title. #eraser. #eraser. DrGDeleteTool description}! !
!DrGUIControlsManager methodsFor: 'tools data' stamp: 'hlsf 3/13/2023 21:35:03'!
exportImageButtonData
^ {'Save as image' translated. #exportToImage. #exportToImageAs. 'Export this sketch as SVG image.' translated }! !
!DrGUIControlsManager methodsFor: 'tools data'!
freePointButtonData
^ {DrGFlyPointBuilder title. #freePoint. #createFreePoint. DrGFlyPointBuilder description}! !
!DrGUIControlsManager methodsFor: 'tools data' stamp: 'hlsf 10/10/2021 11:51:48'!
gridButtonData
^ {#gridWording. #grid. #gridOnOff. 'Show or hide grid.' translated. #isGridVisible}! !
!DrGUIControlsManager methodsFor: 'tools data'!
homothetyButtonData
^ {DrGHomothetyBuilder title. #scale. #createHomothety. DrGHomothetyBuilder description}! !
!DrGUIControlsManager methodsFor: 'tools data'!
intersectionButtonData
^ {DrGPointIntersectionBuilder title. #intersection. #createPointIntersection. DrGPointIntersectionBuilder description}! !
!DrGUIControlsManager methodsFor: 'tools data' stamp: 'hlsf 3/28/2022 11:06:18'!
keepButtonData
^ {'Save' translated. #keep. #saveSketch. 'Keep this sketch permanently.' translated}! !
!DrGUIControlsManager methodsFor: 'tools data'!
lineButtonData
^ {DrGLineBuilder title. #line. #createLine. DrGLineBuilder description}! !
!DrGUIControlsManager methodsFor: 'tools data'!
locusButtonData
^ {DrGLocusBuilder title. #locus. #createLocus. DrGLocusBuilder description}! !
!DrGUIControlsManager methodsFor: 'tools data'!
macroBuildButtonData
^ {DrGMacroBuilder title. #macroBuild. #createMacro. DrGMacroBuilder description}! !
!DrGUIControlsManager methodsFor: 'tools data'!
macroDeleteButtonData
^ {'Delete macro' translated.
#eraser .
#deleteMacro .
'Delete a macro-construction from the registry.' translated}! !
!DrGUIControlsManager methodsFor: 'tools data'!
macroExecuteButtonData
^ {DrGMacroPlayer title. #macroExecute. #executeMacro. DrGMacroPlayer description}! !
!DrGUIControlsManager methodsFor: 'tools data' stamp: 'hlsf 10/10/2021 11:50:26'!
magneticGridButtonData
^ {#magneticGridWording. #gridMagnet. #gridStuckOnOff. 'Snap to grid.' translated. #isGridded}! !
!DrGUIControlsManager methodsFor: 'tools data'!
menuButtonData
^ {'Menu' translated. nil . nil . 'An unobtrusive menu with all Dr. Geo tools.' translated}! !
!DrGUIControlsManager methodsFor: 'tools data'!
middleButtonData
^ {DrGMiddleBuilder title. #middle. #createMiddlePoint. DrGMiddleBuilder description}! !
!DrGUIControlsManager methodsFor: 'tools data'!
moveButtonData
^ {DrGSelectTool title. #move. #move. DrGSelectTool description}! !
!DrGUIControlsManager methodsFor: 'tools data' stamp: 'hlsf 10/10/2021 11:50:49'!
multipleModeButtonData
^ {#createMultipleModeWording. #createMultiple. #createMultipleOnOff. 'Toggle between the build of several geometric objects and the build of one geometric object then move it.' translated. #isCreateMultipleMode}! !
!DrGUIControlsManager methodsFor: 'tools data' stamp: 'hlsf 8/5/2023 14:25:21'!
newButtonData
^ {'New' translated. #newSketch. #newFigure. 'Open a new blank sketch.' translated}! !
!DrGUIControlsManager methodsFor: 'tools data'!
openButtonData
^ {'Open' translated. #open. #openFigureThumbnail. 'Open a sketch.' translated}! !
!DrGUIControlsManager methodsFor: 'tools data'!
parallelButtonData
^ {DrGParallelBuilder title. #parallel. #createParallel. DrGParallelBuilder description}! !
!DrGUIControlsManager methodsFor: 'tools data'!
perpendicularBisectorButtonData
^ {DrGPerpendicularBisectorBuilder title. #perpendicularBisector. #createPerpendicularBisector. DrGPerpendicularBisectorBuilder description}! !
!DrGUIControlsManager methodsFor: 'tools data'!
perpendicularButtonData
^ {DrGPerpendicularBuilder title. #perpendicular. #createPerpendicular. DrGPerpendicularBuilder description}! !
!DrGUIControlsManager methodsFor: 'tools data'!
pointByCoordinatesButtonData
^ {DrGPointByCoordinatesBuilder title. #pointDefinedByCoordinates. #createPointByCoordinates. DrGPointByCoordinatesBuilder description}! !
!DrGUIControlsManager methodsFor: 'tools data'!
polygonButtonData
^ {DrGPolygonBuilder title. #polygon. #createPolygon. DrGPolygonBuilder description}! !
!DrGUIControlsManager methodsFor: 'tools data'!
polygonRegularButtonData
^ {DrGPolygonRegularBuilder title. #polygonRegular. #createPolygonRegular. DrGPolygonRegularBuilder description}! !
!DrGUIControlsManager methodsFor: 'tools data'!
propertyButtonData
^ {DrGPropertyTool title.
#property .
#property .
DrGPropertyTool description}! !
!DrGUIControlsManager methodsFor: 'tools data'!
rayButtonData
^ {DrGRayBuilder title. #ray. #createRay. DrGRayBuilder description}! !
!DrGUIControlsManager methodsFor: 'tools data'!
redoButtonData
^ {'Redo' translated.
#redo .
#redo .
'Redo last action.' translated}! !
!DrGUIControlsManager methodsFor: 'tools data'!
reflectionButtonData
^ {DrGReflectionBuilder title. #axialSymmetry. #createReflection.DrGReflectionBuilder description}! !
!DrGUIControlsManager methodsFor: 'tools data'!
rotationButtonData
^ {DrGRotationBuilder title. #rotation. #createRotation. DrGRotationBuilder description}! !
!DrGUIControlsManager methodsFor: 'tools data'!
scriptCreateButtonData
^ {'Create a script' translated. #createScript . #createScript . 'Create a Smalltalk script.' translated}! !
!DrGUIControlsManager methodsFor: 'tools data'!
scriptEditButtonData
^ {'Edit a script' translated. #editScript. #editScript . 'Edit a Smalltalk script.' translated}! !
!DrGUIControlsManager methodsFor: 'tools data'!
scriptRunButtonData
^ {DrGScriptPlayer title. #useScript. #useScript. DrGScriptPlayer description}! !
!DrGUIControlsManager methodsFor: 'tools data'!
segmentButtonData
^ {DrGSegmentBuilder title. #segment. #createSegment. DrGSegmentBuilder description}! !
!DrGUIControlsManager methodsFor: 'tools data'!
styleButtonData
^ {DrGStyleTool title. #style. #style. DrGStyleTool description}! !
!DrGUIControlsManager methodsFor: 'tools data'!
symmetryButtonData
^ {DrGSymmetryBuilder title. #centralSymmetry. #createSymmetry. DrGSymmetryBuilder description}! !
!DrGUIControlsManager methodsFor: 'tools data'!
textButtonData
^ {DrGTextBuilder title. #text. #createText. DrGTextBuilder description}! !
!DrGUIControlsManager methodsFor: 'tools data'!
translationButtonData
^ {DrGTranslationBuilder title. #translation. #createTranslation. DrGTranslationBuilder description}! !
!DrGUIControlsManager methodsFor: 'tools data'!
treeButtonData
^ {'Construction tree' translated. nil . nil . 'The hierarchy tree presenting the visible constructed items.' translated}! !
!DrGUIControlsManager methodsFor: 'tools data'!
undoButtonData
^ {'Undo' translated.
#undo .
#undo .
'Undo last action' translated}! !
!DrGUIControlsManager methodsFor: 'tools data'!
vectorButtonData
^ {DrGVectorBuilder title. #vector. #createVector. DrGVectorBuilder description}! !
!DrGUIControlsManager methodsFor: 'tools data'!
wheelXButtonData
^ {'Horizontal wheel' translated. nil . #moveOx: . 'A wheel to move horizontally the sketch.' translated}! !
!DrGUIControlsManager methodsFor: 'tools data'!
wheelYButtonData
^ {'Vertical wheel' translated . nil . #moveOy: . 'A wheel to move vertically the sketch.' translated}! !
!DrGUIControlsManager methodsFor: 'tools data'!
wheelZButtonData
^ {'Zoom wheel' translated . nil . #scale: . 'A wheel to zoom in, zoom out the sketch.' translated}! !
!DrGUIControlsManager methodsFor: 'widget access' stamp: 'hlsf 3/30/2022 18:08:59'!
addChevron: symbolOrArray to: aToolbar
"array first = menu label or button label
array second = button form = selection mode
array third = symbol callback
array fourth = help string "
| array |
symbolOrArray isSymbol
ifTrue: [ array _ self perform: (symbolOrArray, #ButtonData) asSymbol]
ifFalse: [ array _ symbolOrArray].
^ (aToolbar addButton: (DrGIcons for: array second))
model: presenter;
action: array third;
state: (array at: 5 ifAbsent: [ #isTool: ]);
argument: array second;
setBalloonText: array fourth;
yourself ! !
!DrGUIControlsManager methodsFor: 'widget access' stamp: 'hlsf 8/15/2023 21:07:49'!
button: symbolOrArray
"array first = menu label or button label
array second = button form = selection mode
array third = symbol callback
array fourth = help string "
| array stateGetter |
array := self perform: (symbolOrArray, #ButtonData) asSymbol.
^ ButtonMorph
model: presenter
stateGetter: (stateGetter := array at: 5 ifAbsent: [ #isTool: ])
action: array third ::
stateArgument: (stateGetter isUnary ifTrue: [nil] ifFalse: [array second]);
icon: (DrGIcons for: array second);
setBalloonText: array fourth;
color: self buttonColor ;
selectedColor: self buttonSelectedColor ;
borderColor: self buttonColor muchDarker;
borderWidth: 2;
morphExtent: (DrGeoSystem toolbarIconSize + 4) asPoint;
yourself ! !
!DrGUIControlsManager methodsFor: 'widget access' stamp: 'hlsf 5/25/2023 17:45:34'!
horizontalWheel
| array |
array := self wheelXButtonData.
^ WheelMorph target: presenter actionSelector: array third ::
beHorizontal;
factor: 0.05;
setBalloonText: array first;
borderWidth: 3;
color: self buttonColor;
borderColor: self buttonColor muchDarker;
yourself! !
!DrGUIControlsManager methodsFor: 'widget access' stamp: 'hlsf 4/10/2022 14:49:15'!
openTools
" Open the toolbox to manipulate items in the canvas "
self tools
morphPosition: self activeHand morphPosition ;
openInWorld! !
!DrGUIControlsManager methodsFor: 'widget access' stamp: 'hlsf 8/4/2023 12:48:44'!
propertyFor: aMathItem
"Open a property Panel to edit the math item"
editPanel ifNotNil: [
editPanel delete.
editPanel := nil].
aMathItem ifNotNil: [
editPanel := aMathItem editPropertyIn: presenter.
self contextualEditingFor: editPanel]
! !
!DrGUIControlsManager methodsFor: 'widget access' stamp: 'hlsf 4/10/2022 14:48:13'!
quickToolbar
quickToolbar ifNotNil: [^ quickToolbar].
quickToolbar _ LayoutMorph newRow ::
separation: 5;
yourself.
self miscTools do: [:dataTool | quickToolbar addMorph: (self button: dataTool ) ].
^ quickToolbar
! !
!DrGUIControlsManager methodsFor: 'widget access' stamp: 'hlsf 4/9/2022 21:47:35'!
setStatusBarMessage: aString
statusBar ifNotNil: [
statusBar contents: aString;
adjustExtent ;
redrawNeeded]
! !
!DrGUIControlsManager methodsFor: 'widget access' stamp: 'hlsf 8/12/2023 14:05:45'!
statusBar
"A bar to print contextual information"
^ statusBar ifNil: [
statusBar := TextParagraphMorph new
color: Color transparent;
borderWidth: 0;
setHeightOnContent ;
yourself ]
! !
!DrGUIControlsManager methodsFor: 'widget access' stamp: 'hlsf 4/10/2022 14:46:03'!
stylerFor: aStyle
"Open a style Panel to edit aStyle"
editPanel ifNotNil: [
editPanel delete.
editPanel _ nil].
aStyle ifNotNil: [
editPanel _ DrGStylePanel open: aStyle label: 'Edit style' translated.
self contextualEditingFor: editPanel ]
! !
!DrGUIControlsManager methodsFor: 'widget access' stamp: 'hlsf 4/10/2022 14:49:15'!
tools
| toolsData dropDown |
tools ifNotNil: [^ tools].
toolsData _ OrderedCollection new
add: self pointTools; add: self curveTools; add: self transformationTools;
add: self numericTools; add: self scriptTools; add: self macroTools;
add: self animateTools; yourself.
tools _ CircularToolbarMorph new.
tools
color: self buttonColor;
selectedColor: self buttonSelectedColor;
buttonSize: DrGeoSystem toolbarIconSize.
toolsData do: [:dataTool |
dropDown _ (self addChevron: dataTool first to: tools) addDropDown.
dataTool do: [:tool | self addChevron: tool to: dropDown subtoolbar]].
^ tools
! !
!DrGUIControlsManager methodsFor: 'widget access' stamp: 'hlsf 8/4/2023 12:48:55'!
tree
" I am the model of a tree presenting the math item "
^ tree ifNil: [ tree := DrGeoTree on: presenter]! !
!DrGUIControlsManager methodsFor: 'widget access' stamp: 'hlsf 4/10/2022 12:07:48'!
treeView
^ treeView ifNil: [treeView _ HierarchicalListMorph
model: self tree
listGetter: #pool
indexGetter: #selectedItem
indexSetter: #selectedItem:
mainView: self view
menuGetter: nil
keystrokeAction: nil]! !
!DrGUIControlsManager methodsFor: 'widget access' stamp: 'hlsf 5/25/2023 17:45:17'!
verticalWheel
| array |
array := self wheelYButtonData.
^ WheelMorph target: presenter actionSelector: array third ::
beVertical;
factor: 0.05;
setBalloonText: array first;
borderWidth: 3;
color: self buttonColor;
borderColor: self buttonColor muchDarker ;
yourself
! !
!DrGUIControlsManager methodsFor: 'widget access' stamp: 'hlsf 5/25/2023 17:45:03'!
zoomWheel
| array |
array := self wheelZButtonData.
^ WheelMorph target: presenter actionSelector: array third ::
beVertical;
factor: 1;
setBalloonText: array first;
borderWidth: 3;
color: self buttonSelectedColor;
borderColor: self buttonSelectedColor muchDarker;
yourself! !
!DrGUIControlsManager methodsFor: 'widget helpers' stamp: 'hlsf 4/14/2022 16:00:10'!
buttonColor
^ self class buttonColor! !
!DrGUIControlsManager methodsFor: 'widget helpers' stamp: 'hlsf 4/14/2022 16:00:24'!
buttonSelectedColor
^ self class buttonSelectedColor ! !
!DrGUIControlsManager methodsFor: 'widget helpers' stamp: 'hlsf 4/7/2022 18:07:56'!
contextualEditingFor: panel
"Ensure the panel is located close to the user mouse action"
| mousePosition |
mousePosition _ self activeHand morphPosition.
mousePosition x > (self runningWorld morphWidth - panel morphWidth - 20)
ifTrue: [panel morphPosition: mousePosition
+ (-20 - panel morphWidth @ ((panel morphHeight // -2)))]
ifFalse: [panel morphPosition: mousePosition
+ (20@ (panel morphHeight // -2) )].
(panel respondsTo: #fitInWorld) ifTrue: [panel fitInWorld]! !
!DrGUIControlsManager methodsFor: 'widget helpers' stamp: 'hlsf 1/3/2022 08:50:34'!
transparentMorph
^ BoxedMorph new
borderWidth: 0;
color: Color transparent;
yourself! !
!DrGUIControlsManager methodsFor: 'widget helpers' stamp: 'hlsf 4/10/2022 14:45:47'!
updateStylerFor: aStyle
"Update the styler if any matching the given style"
(editPanel notNil and: [editPanel model == aStyle]) ifTrue: [ | position |
position _ editPanel morphPosition.
self stylerFor: aStyle.
editPanel morphPosition: position]
! !
!DrGUIControlsManager class methodsFor: 'instance creation' stamp: 'hlsf 10/19/2022 15:51:51'!
exportIconSet
"Export the icon set: name, description and icon as a PNG file
See addButton:to: for icon data description"
| buttons data path|
path _ '/tmp/DrGeoIcons/' asDirectoryEntry recursiveDelete assureExistence.
data _ self new.
buttons _ OrderedCollection new
addAll: data miscTools;
addAll: data pointTools; addAll: data curveTools; addAll: data transformationTools;
addAll: data numericTools; addAll: data scriptTools; addAll: data macroTools;
addAll: data animateTools; yourself.
buttons do: [:aButton | | iconDescription iconName |
iconDescription _ data perform: (aButton, #ButtonData) asSymbol.
iconName _ iconDescription second.
(path / iconName) assureExistence.
(path / iconName // 'description.txt') assureExistence
fileContents: iconDescription fourth.
PNGReadWriter
putForm: (DrGIcons scale: iconDescription second to: 48)
onFile: path / iconName // (iconName, '.png') ].
! !
!DrGUIControlsManager class methodsFor: 'instance creation' stamp: 'hlsf 8/4/2023 18:23:17'!
for: aPresenter
^ self basicNew ::
presenter: aPresenter;
initialize! !
!DrGUIControlsManager class methodsFor: 'constants' stamp: 'hlsf 4/14/2022 15:57:50'!
buttonColor
"Blue Ukraine"
^ Color fromHexString: '#0057b7'! !
!DrGUIControlsManager class methodsFor: 'constants' stamp: 'hlsf 4/14/2022 15:58:07'!
buttonSelectedColor
"Yellow Ukraine"
^ Color fromHexString: '#ffd700'! !
!DrGUIMinimalControlsManager methodsFor: 'menus' stamp: 'hlsf 4/10/2022 14:55:40'!
addMenuItem: toolSymbol to: menu
| array |
"access the buttonData method from the tool symbol"
array _ toolSymbol isSymbol
ifTrue: [ self perform: (toolSymbol , #ButtonData) asSymbol ]
ifFalse: [ toolSymbol ].
(menu add: array first action: array third) setBalloonText: array fourth.
"do we have an icon for this tool?"
(DrGIcons respondsTo: array second)
ifTrue: [ menu lastItem setIcon: (DrGIcons perform: array second) ]! !
!DrGUIMinimalControlsManager methodsFor: 'menus' stamp: 'hlsf 8/13/2023 15:06:36'!
addUpdatingMenuItem: array to: menu
(menu addUpdating: array first action: array third)
setBalloonText: array fourth.! !
!DrGUIMinimalControlsManager methodsFor: 'menus' stamp: 'hlsf 4/10/2022 14:55:54'!
animateMenu
| menu |
menu _ self newMenu.
self animateTools do: [ :symbol | self addMenuItem: symbol to: menu ].
^ menu
! !
!DrGUIMinimalControlsManager methodsFor: 'menus' stamp: 'hlsf 4/10/2022 14:55:59'!
curveMenu
| lineMenu |
lineMenu _ self newMenu.
self curveTools do: [ :symbol | self addMenuItem: symbol to: lineMenu ].
^ lineMenu! !
!DrGUIMinimalControlsManager methodsFor: 'menus' stamp: 'hlsf 4/10/2022 14:56:06'!
editMenu
| menu |
menu _ self newMenu.
self addMenuItem: self moveButtonData to: menu.
menu addLine.
self addMenuItem: self undoButtonData to: menu.
self addMenuItem: self redoButtonData to: menu.
menu addLine.
"Only work on X Window (GNU/Linux)"
self flag: #drgeoTodo.
menu add: 'Copy' translated
target: presenter
action: #exportToClipboard:
argument: false.
menu add: 'Copy with transparency' translated
target: presenter
action: #exportToClipboard:
argument: true.
menu addLine.
self addMenuItem: self eraserButtonData to: menu.
self addMenuItem: self styleButtonData to: menu.
self addMenuItem: self propertyButtonData to: menu.
menu addLine.
self addUpdatingMenuItem: self gridButtonData to: menu.
self addUpdatingMenuItem: self axesButtonData to: menu.
self addUpdatingMenuItem: self magneticGridButtonData to: menu.
^ menu
! !
!DrGUIMinimalControlsManager methodsFor: 'menus' stamp: 'hlsf 3/18/2023 21:26:28'!
fileMenu
| fileMenu |
fileMenu := self newMenu.
self addMenuItem: #new to: fileMenu.
self addMenuItem: #open to: fileMenu.
fileMenu add: 'Open at...' translated action: #openFigureAt.
self addMenuItem: #keep to: fileMenu.
(fileMenu add: 'Save as...' translated action: #saveSketchAs)
setBalloonText: 'Keep this sketch under a different name.' translated.
self addMenuItem: #exportImage to: fileMenu.
" fileMenu addLine.
fileMenu add: 'Close sketch' translated target: self window action: #delete.
self addMenuItem: #quit to: fileMenu."
^ fileMenu
! !
!DrGUIMinimalControlsManager methodsFor: 'menus' stamp: 'hlsf 4/10/2022 14:56:14'!
macroconstructionMenu
| menu |
self view macroMenu: (menu _ self newMenu).
self macroTools do: [ :symbol | self addMenuItem: symbol to: menu].
^ menu! !
!DrGUIMinimalControlsManager methodsFor: 'menus' stamp: 'hlsf 4/10/2022 14:56:18'!
mainMenu
| mainMenu menu |
mainMenu _ MenuMorph entitled: self view label.
" File menu "
menu _ mainMenu add: 'File' translated subMenu: self fileMenu.
menu setBalloonText: 'Load, save or export Dr. Geo figure.' translated.
" Edit menu "
menu _ mainMenu add: 'Edit' translated subMenu: self editMenu.
menu setBalloonText: 'Erase or edit style and properties of items.' translated.
" Points menu "
menu _ mainMenu add: 'Points' translated subMenu: self pointMenu.
menu setBalloonText: 'Create points: free, on curve, intersection or middle point.' translated.
" Lines menu "
menu _ mainMenu add: 'Lines' translated subMenu: self curveMenu.
menu setBalloonText: 'Create different curve types: line, half-line, segment, vector, circle...' translated.
" Transformations menu "
menu _ mainMenu add: 'Transformations' translated subMenu: self transformationMenu.
menu setBalloonText: 'Transform an object with a geometric transformation: symmetry, reflexion, rotation, translation or homothety (scale).' translated.
" Numerics and Text menu "
mainMenu add: 'Numerics & Text' translated subMenu: self numericMenu.
menu setBalloonText: 'Create several numeric objects: free value, distance, length, angle, coordinates, equation and text.' translated.
" Script menu "
menu _ mainMenu add: 'Script' translated subMenu: self scriptMenu.
menu setBalloonText: 'Script: use, edit or create script to plug in the sketch.' translated.
self flag: #drgeoTodo.
"menu on: #mouseEnter send: #updateScriptMenu to: self."
" Macro-construction menu "
menu _ mainMenu add: 'Macro-construction' translated subMenu: self macroconstructionMenu.
menu setBalloonText: 'Build or execute macro-construction. A macro is a construction template you can apply to items in the sketch area.' translated.
self flag: #drgeoTodo.
"menu on: #mouseEnter send: #updateMacroMenu to: self."
" Animation menu "
menu _ mainMenu add: 'Animate' translated subMenu: self animateMenu.
menu setBalloonText: 'Animate a free point on curve.' translated.
^ mainMenu
! !
!DrGUIMinimalControlsManager methodsFor: 'menus' stamp: 'hlsf 4/10/2022 14:56:21'!
newMenu
^ MenuMorph new
defaultTarget: presenter;
yourself! !
!DrGUIMinimalControlsManager methodsFor: 'menus' stamp: 'hlsf 4/10/2022 14:56:25'!
numericMenu
| menu |
menu _ self newMenu.
self numericTools do: [ :symbol | self addMenuItem: symbol to: menu ].
^ menu
! !
!DrGUIMinimalControlsManager methodsFor: 'menus' stamp: 'hlsf 4/10/2022 14:56:28'!
pointMenu
| pointMenu |
pointMenu _ self newMenu.
self pointTools do: [ :symbol | self addMenuItem: symbol to: pointMenu ].
^ pointMenu
! !
!DrGUIMinimalControlsManager methodsFor: 'menus' stamp: 'hlsf 4/10/2022 14:56:31'!
scriptMenu
| menu |
self view scriptMenu: (menu _ self newMenu).
self scriptTools do: [ :symbol | self addMenuItem: symbol to: menu].
^ menu
! !
!DrGUIMinimalControlsManager methodsFor: 'menus' stamp: 'hlsf 4/10/2022 14:56:36'!
transformationMenu
| menu |
menu _ self newMenu.
self transformationTools do: [ :symbol | self addMenuItem: symbol to: menu ].
^ menu
! !
!DrGUIMinimalControlsManager methodsFor: 'menus' stamp: 'hlsf 4/10/2022 14:56:40'!
updateMacroMenu
| macroMenu |
macroMenu _ self view macroMenu.
macroMenu removeAllMorphs.
self macroTools do: [ :symbol | self addMenuItem: symbol to: macroMenu].
DrGMacroFactory new pool ifNotEmpty: [ macroMenu addLine ].
DrGMacroFactory new pool do: [:aMacro |
macroMenu
add: aMacro title
target: presenter
selector: #executeMacro:
argument: aMacro.
macroMenu lastItem
setBalloonText: aMacro description]
! !
!DrGUIMinimalControlsManager methodsFor: 'menus' stamp: 'hlsf 4/10/2022 14:56:44'!
updateScriptMenu
| scripts scriptMenu |
scriptMenu _ self view scriptMenu.
scriptMenu removeAllMorphs.
self scriptTools do: [ :symbol | self addMenuItem: symbol to: scriptMenu].
scripts _ DrGeoUserScript subclasses sorted: [:script1 :script2 |
script1 scriptName asLowercase < script2 scriptName asLowercase].
scripts ifNotEmpty: [scriptMenu addLine].
scripts do: [:aScript |
scriptMenu
add: aScript scriptName
target: presenter
selector: #useScript:
argument: aScript.
scriptMenu lastItem
setBalloonText: aScript description]
! !
!DrGUIMinimalControlsManager methodsFor: 'initialization' stamp: 'hlsf 8/4/2023 13:04:38'!
installTools
" Install menu, toolbar, tree, wheels, statusbar "
| row col |
super initialize.
view := DrGeoMiniView for: presenter.
row := LayoutMorph newRow.
row addMorphUseAll: self view drawable.
"Install the wheels at the right"
col := LayoutMorph newColumn name: #wheelsYZ; color: view defaultColor; yourself.
col
addMorph: (self zoomWheel borderWidth: 2)
layoutSpec: ( LayoutSpec fixedExtent: DrGeoSystem wheelWidth / 1.5 @ DrGeoSystem wheelHeight);
addMorphUseAll: self transparentMorph;
addMorph: (self verticalWheel borderWidth: 2)
layoutSpec: ( LayoutSpec fixedExtent: DrGeoSystem wheelWidth / 1.5 @ DrGeoSystem wheelHeight).
""
row addMorph: col layoutSpec: (LayoutSpec fixedWidth: DrGeoSystem wheelWidth /1.5 proportionalHeight: 1).
view addMorph: row.
"Install wheel at the bottom"
row := LayoutMorph newRow name: #wheelX; color: view defaultColor; yourself.
row addMorphUseAll: self statusBar ;
addMorph: (self horizontalWheel borderWidth: 2)
layoutSpec: (LayoutSpec fixedExtent: DrGeoSystem wheelHeight @ (DrGeoSystem wheelWidth / 1.5));
addMorph: self transparentMorph
layoutSpec: (LayoutSpec fixedExtent: (DrGeoSystem wheelWidth / 1.5) asPoint) .
view addMorph: row layoutSpec: (LayoutSpec fixedHeight: (DrGeoSystem wheelWidth / 1.5))! !
!DrGUIMinimalControlsManager methodsFor: 'widget access' stamp: 'hlsf 4/10/2022 16:36:58'!
openTools
self tools popUpInWorld ! !
!DrGUIMinimalControlsManager methodsFor: 'widget access' stamp: 'hlsf 4/10/2022 17:10:29'!
setStatusBarMessage: aString
statusBar ifNotNil: [
statusBar contents: aString;
redrawNeeded]! !
!DrGUIMinimalControlsManager methodsFor: 'widget access' stamp: 'hlsf 4/10/2022 16:25:16'!
tools
^ tools ifNil: [tools _ self mainMenu]! !
!DrGeo methodsFor: 'accessing' stamp: 'hlsf 6/19/2021 15:18:35'!
axesWording
^self isAxesVisible
ifTrue: ['<yes> Axes' translated]
ifFalse: ['<no> Axes' translated]! !
!DrGeo methodsFor: 'accessing'!
controlsManager
^ controlsManager! !
!DrGeo methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 18:23:44'!
controlsManager: aClass
controlsManager := aClass for: self.
controlsManager installTools! !
!DrGeo methodsFor: 'accessing' stamp: 'hlsf 6/19/2021 14:52:52'!
createMultipleModeWording
^isCreateMultipleMode
ifTrue: ['<yes> Create Multiple' translated]
ifFalse: ['<no> Create Multiple' translated]! !
!DrGeo methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 12:38:49'!
domain
^ domain ! !
!DrGeo methodsFor: 'accessing' stamp: 'hlsf 6/19/2021 10:07:28'!
drawable
^ self view ifNotNil: [self view drawable]! !
!DrGeo methodsFor: 'accessing' stamp: 'hlsf 6/19/2021 15:16:09'!
gridWording
^self isGridVisible
ifTrue: ['<yes> Grid' translated]
ifFalse: ['<no> Grid' translated]! !
!DrGeo methodsFor: 'accessing' stamp: 'hlsf 6/19/2021 15:20:26'!
magneticGridWording
^self isGridded
ifTrue: ['<yes> Magnetic Grid' translated]
ifFalse: ['<no> Magnetic Grid' translated]! !
!DrGeo methodsFor: 'accessing' stamp: 'hlsf 8/3/2023 21:10:34'!
notInteractive: boolean
notInteractive := boolean! !
!DrGeo methodsFor: 'accessing' stamp: 'hlsf 8/3/2023 20:52:32'!
saved: bool
| title |
title := (sketchName ifNil: ['Dr. Geo -- ' , Date today yyyymmdd]) capitalized.
bool ifFalse: [title := '* ', title].
self view setLabel: title.
saved := bool.
! !
!DrGeo methodsFor: 'accessing'!
selection
^selection! !
!DrGeo methodsFor: 'accessing' stamp: 'hlsf 3/28/2022 14:22:25'!
sketchName
^ sketchName! !
!DrGeo methodsFor: 'accessing' stamp: 'hlsf 11/14/2023 00:17:46'!
stSketch: aDrGeoSketch
stSketch := aDrGeoSketch ! !
!DrGeo methodsFor: 'accessing'!
tool
^tool! !
!DrGeo methodsFor: 'accessing' stamp: 'hlsf 4/9/2022 21:48:04'!
tool: aTool
tool ifNotNil: [tool release].
tool _ aTool.
tool ifNotNil: [tool registerDependant: self].
(tool notNil and: [self view notNil]) ifTrue: [
controlsManager setStatusBarMessage: tool description]! !
!DrGeo methodsFor: 'accessing' stamp: 'hlsf 4/10/2022 12:42:08'!
view
^ controlsManager view! !
!DrGeo methodsFor: 'callback UI' stamp: 'hlsf 12/9/2022 22:10:35'!
exportToClipboard: isBackgroundTransparent
" | command |
self
exportToBitmap: (DrGeoSystem myExportsPath / 'clipboard.png') ensureDelete binaryWriteStream
transparent: isBackgroundTransparent.
command _ String streamContents: [ :str |
str << 'xclip -selection clipboard -t image/png '
<< (DrGeoSystem myExportsPath / 'clipboard.png') pathString].
OSPlatform current runCommand: command."! !
!DrGeo methodsFor: 'callback UI' stamp: 'hlsf 8/4/2023 17:24:20'!
exportToImage: aFilename
| stream |
[stream := (DrGeoSystem myExportsPath // (aFilename, '.svg')) forceWriteStream.
DrGeoXml new
presenter: self;
exportToSvg: stream
] ensure: [stream close]
"
[self saveWithinLimitedTime: [
DrGeoSystem startSpinner.
stream := (DrGeoSystem myExportsPath // (aFilename, '.svg')) forceWriteStream.
DrGeoXml new
app: self app;
exportToSvg: stream].
stream close]
on: Error
do: [:ex | DrGeoSystem stopSpinner.
stream ifNotNil: [stream close].
Transcript show: ex.
PopUpMenu inform: 'I can''t export the sketch.
Check the local resource or the server.' translated].
DrGeoSystem stopSpinner.
"! !
!DrGeo methodsFor: 'callback UI' stamp: 'hlsf 3/15/2023 16:29:55'!
exportToImageAs
| model |
DrGeoSystem showVirtualKeyboard: true.
model := ValueHolder with: (exportImageName ifNotNil: [:name | name] ifNil: ['']) ::
action: [:aString |
exportImageName := aString.
self exportToImage: exportImageName ].
StringEntryPanel openWide: model label: 'Name the image to keep.' translated ::
morphCenter: self view fullBoundsInOwner center;
setProperty: #layerNumber toValue: 20! !
!DrGeo methodsFor: 'callback UI' stamp: 'hlsf 8/8/2023 19:13:55'!
newFigure
DrGeo new! !
!DrGeo methodsFor: 'callback UI' stamp: 'hlsf 12/2/2021 10:00:04'!
openFigureThumbnail
DrGFileOpenMorph open! !
!DrGeo methodsFor: 'callback UI' stamp: 'hlsf 8/4/2023 17:25:03'!
save
"Save the sketch with the current filename"
| stream |
[self saveWithinLimitedTime: [
DrGeoSystem startSpinner.
stream := (DrGeoSystem mySketchesPath // (sketchName, '.fgeo')) forceWriteStream.
DrGeoXml new
presenter: self;
saveOn: stream.
self previewOnFile: DrGeoSystem mySketchesPath // (sketchName, '.png')].
self saved: true.
stream close]
on: Error
do: [:ex | DrGeoSystem stopSpinner.
stream ifNotNil: [stream close].
Transcript show: ex.
PopUpMenu inform: 'I can''t save the sketch.
Check the local resource or the server.' translated].
DrGeoSystem stopSpinner.! !
!DrGeo methodsFor: 'callback UI' stamp: 'hlsf 3/28/2022 11:24:20'!
saveSketch
sketchName
ifNil: [self saveSketchAs]
ifNotNil: [ self save]
! !
!DrGeo methodsFor: 'callback UI' stamp: 'hlsf 3/28/2022 16:49:08'!
saveSketchAs
| model |
DrGeoSystem showVirtualKeyboard: true.
model _ ValueHolder with:'' ::
action: [:aString |
sketchName _ aString.
self saveSketch].
StringEntryPanel openWide: model label: 'Name the sketch to keep.' translated ::
morphCenter: self view fullBoundsInOwner center;
setProperty: #layerNumber toValue: 20! !
!DrGeo methodsFor: 'callback UI' stamp: 'hlsf 3/27/2022 13:51:01'!
saveWithinLimitedTime: aBlock
[aBlock value]
valueWithin: 10 seconds
onTimeout:
[DrGeoSystem stopSpinner..
PopUpMenu inform: 'I can''t save the sketch.
Check the local resource or the server.' translated].! !
!DrGeo methodsFor: 'callback canvas' stamp: 'hlsf 4/5/2022 21:00:01'!
animate
selectedTool == #animate ifFalse: [
self selectTool: DrGAnimateTool.
selectedTool _ #animate].
self changed! !
!DrGeo methodsFor: 'callback canvas'!
animate1
self animate.
self tool animateStep: 0.01.
! !
!DrGeo methodsFor: 'callback canvas'!
animate2
self animate.
self tool animateStep: 0.043.
! !
!DrGeo methodsFor: 'callback canvas'!
animate3
self animate.
self tool animateStep: 0.076.
! !
!DrGeo methodsFor: 'callback canvas'!
animate4
self animate.
self tool animateStep: 0.1
! !
!DrGeo methodsFor: 'callback canvas' stamp: 'hlsf 6/19/2021 17:15:55'!
axesOnOff
self drawable axesVisibleOnOff
! !
!DrGeo methodsFor: 'callback canvas' stamp: 'hlsf 6/19/2021 16:57:23'!
createMultipleOnOff
isCreateMultipleMode _ isCreateMultipleMode not! !
!DrGeo methodsFor: 'callback canvas' stamp: 'hlsf 6/19/2021 17:15:21'!
gridOnOff
self drawable gridVisibleOnOff! !
!DrGeo methodsFor: 'callback canvas' stamp: 'hlsf 6/19/2021 16:57:50'!
gridStuckOnOff
gridStuck _ gridStuck not.! !
!DrGeo methodsFor: 'callback canvas'!
move
self selectTool: DrGSelectTool.
selectedTool _ #move.
self changed! !
!DrGeo methodsFor: 'callback canvas' stamp: 'hlsf 6/19/2021 10:07:28'!
moveOx: increment
self drawable moveOx: increment.! !
!DrGeo methodsFor: 'callback canvas' stamp: 'hlsf 6/19/2021 10:07:28'!
moveOy: increment
self drawable moveOy: increment negated.! !
!DrGeo methodsFor: 'callback canvas' stamp: 'hlsf 8/3/2023 20:53:22'!
redo
self domain redo.
self domain updateAllMathItems.
self saved: false! !
!DrGeo methodsFor: 'callback canvas' stamp: 'hlsf 6/19/2021 10:07:28'!
scale: increment
self drawable scale: increment negated.! !
!DrGeo methodsFor: 'callback canvas' stamp: 'hlsf 8/4/2023 11:43:07'!
style
selectedTool := #style.
self selectTool: DrGStyleTool.
self changed: #selectedTool.
self drawable redrawNeeded .
! !
!DrGeo methodsFor: 'callback canvas' stamp: 'hlsf 8/3/2023 20:53:36'!
undo
self tool resetForFreshStart.
self domain undo.
self domain updateAllMathItems.
self saved: false! !
!DrGeo methodsFor: 'callback create'!
createAngleBisector
self selectTool: DrGFlyBuildTool with: DrGAngleBisectorBuilder.
selectedTool _ #angleBisector.
self changed! !
!DrGeo methodsFor: 'callback create' stamp: 'hlsf 12/9/2021 15:59:49'!
createAngleGeometric
self selectTool: DrGBuildTool with: DrGAngleGeometricBuilder.
selectedTool _ #geometricAngle.
self changed! !
!DrGeo methodsFor: 'callback create' stamp: 'hlsf 12/9/2021 15:59:16'!
createAngleOriented
self selectTool: DrGBuildTool with: DrGAngleOrientedBuilder.
selectedTool _ #orientedAngle.
self changed! !
!DrGeo methodsFor: 'callback create'!
createArc
self selectTool: DrGFlyBuildTool with: DrGArcBuilder.
selectedTool _ #arc.
self changed! !
!DrGeo methodsFor: 'callback create'!
createArcCenter
self selectTool: DrGFlyBuildTool with: DrGArcCenterBuilder.
selectedTool _ #arcCenter.
self changed! !
!DrGeo methodsFor: 'callback create' stamp: 'hlsf 9/23/2021 11:50:33'!
createCircle
self selectTool: DrGFlyBuildTouchTool with: DrGCircleBuilder.
selectedTool _ #circle.
self changed! !
!DrGeo methodsFor: 'callback create'!
createCoordinatePoint
self selectTool: DrGBuildTool with: DrGPointByCoordinatesBuilder.
selectedTool _ #pointDefinedByCoordindates.
self changed! !
!DrGeo methodsFor: 'callback create'!
createCoordinates
self selectTool: DrGBuildTool with: DrGCoordinatesBuilder.
selectedTool _ #coordinates.
self changed
! !
!DrGeo methodsFor: 'callback create'!
createDistance
self selectTool: DrGBuildTool with: DrGValueBuilder.
selectedTool _ #distance.
self changed! !
!DrGeo methodsFor: 'callback create'!
createFreePoint
self selectTool: DrGFlyPointBuildTool with: DrGFlyPointBuilder.
selectedTool _ #freePoint.
self changed! !
!DrGeo methodsFor: 'callback create'!
createHomothety
self selectTool: DrGBuildTool with: DrGHomothetyBuilder.
selectedTool _ #scale.
self changed! !
!DrGeo methodsFor: 'callback create'!
createLine
self selectTool: DrGFlyBuildTouchTool with: DrGLineBuilder.
selectedTool _ #line.
self changed! !
!DrGeo methodsFor: 'callback create'!
createLocus
self selectTool: DrGBuildTool with: DrGLocusBuilder.
selectedTool _ #locus.
self changed! !
!DrGeo methodsFor: 'callback create'!
createMacro
self selectTool: DrGMacroBuildTool with: DrGMacroBuilder.
selectedTool _ #macroBuild.
self changed! !
!DrGeo methodsFor: 'callback create'!
createMiddlePoint
self selectTool: DrGBuildTool with: DrGMiddleBuilder.
selectedTool _ #middle.
self changed! !
!DrGeo methodsFor: 'callback create' stamp: 'hlsf 9/23/2021 11:50:28'!
createParallel
self selectTool: DrGFlyBuildTouchTool with: DrGParallelBuilder.
selectedTool _ #parallel.
self changed! !
!DrGeo methodsFor: 'callback create' stamp: 'hlsf 9/23/2021 11:50:42'!
createPerpendicular
self selectTool: DrGFlyBuildTouchTool with: DrGPerpendicularBuilder.
selectedTool _ #perpendicular.
self changed! !
!DrGeo methodsFor: 'callback create'!
createPerpendicularBisector
self selectTool: DrGFlyBuildTouchTool with: DrGPerpendicularBisectorBuilder.
selectedTool _ #perpendicularBisector.
self changed! !
!DrGeo methodsFor: 'callback create'!
createPointByCoordinates
self selectTool: DrGBuildTool with: DrGPointByCoordinatesBuilder.
selectedTool _ #pointDefinedByCoordinates.
self changed! !
!DrGeo methodsFor: 'callback create'!
createPointIntersection
self selectTool: DrGBuildTool with: DrGPointIntersectionBuilder.
selectedTool _ #intersection.
self changed! !
!DrGeo methodsFor: 'callback create'!
createPolygon
self selectTool: DrGFlyBuildTool with: DrGPolygonBuilder.
selectedTool _ #polygon.
self changed! !
!DrGeo methodsFor: 'callback create'!
createPolygonRegular
self selectTool: DrGFlyBuildTool with: DrGPolygonRegularBuilder.
selectedTool _ #polygonRegular.
self changed! !
!DrGeo methodsFor: 'callback create'!
createRay
self selectTool: DrGFlyBuildTouchTool with: DrGRayBuilder.
selectedTool _ #ray.
self changed! !
!DrGeo methodsFor: 'callback create'!
createReflection
self selectTool: DrGBuildTool with: DrGReflectionBuilder.
selectedTool _ #axialSymmetry.
self changed! !
!DrGeo methodsFor: 'callback create'!
createRotation
self selectTool: DrGBuildTool with: DrGRotationBuilder.
selectedTool _ #rotation.
self changed! !
!DrGeo methodsFor: 'callback create' stamp: 'hlsf 8/4/2023 17:38:21'!
createScript
"We force to select/move mode as we do not interact with the sketch"
self move.
self changed.
DrGScriptDesignerDialog open: self label: 'Build a new script' translated! !
!DrGeo methodsFor: 'callback create' stamp: 'hlsf 8/4/2021 12:10:22'!
createSegment
self selectTool: DrGFlyBuildTouchTool with: DrGSegmentBuilder.
selectedTool _ #segment.
self changed! !
!DrGeo methodsFor: 'callback create'!
createSymmetry
self selectTool: DrGBuildTool with: DrGSymmetryBuilder.
selectedTool _ #centralSymmetry.
self changed! !
!DrGeo methodsFor: 'callback create'!
createText
self selectTool: DrGBuildTool with: DrGTextBuilder.
selectedTool _ #text.
self changed! !
!DrGeo methodsFor: 'callback create'!
createTranslation
self selectTool: DrGBuildTool with: DrGTranslationBuilder.
selectedTool _ #translation.
self changed! !
!DrGeo methodsFor: 'callback create'!
createVector
self selectTool: DrGFlyBuildTouchTool with: DrGVectorBuilder.
selectedTool _ #vector.
self changed! !
!DrGeo methodsFor: 'callback create'!
deleteMacro
self selectTool: DrGSelectTool.
selectedTool _ #deleteMacro.
self changed! !
!DrGeo methodsFor: 'callback create' stamp: 'hlsf 4/7/2022 15:40:15'!
editScript
| menu |
"We force to select mode, then open a browser on the script classes"
self move.
menu _ MenuMorph entitled: 'Edit or create scripts' translated.
DrGWizardScript sortedScripts do: [:aScriptClass |
menu
add: aScriptClass scriptName
target: self
action: #editScript:
argument: aScriptClass ::
setBalloonText: aScriptClass description].
menu popUpInWorld.
self changed! !
!DrGeo methodsFor: 'callback create' stamp: 'hlsf 4/7/2022 18:05:34'!
editScript: aScriptClass
| browser |
browser _ Browser new setClass: aScriptClass selector: #compute.
browser when: #annotationChanged send: #updateAllMathItems to: self domain.
^ MessageSetWindow new model: browser ::
buildNoSysCatMorphicWindow;
setLabel: 'Edit or create scripts' translated;
openInWorld;
morphExtent: 600@500;
yourself
! !
!DrGeo methodsFor: 'callback create' stamp: 'hlsf 8/4/2023 11:42:31'!
eraser
selectedTool := #eraser.
self selectTool: DrGDeleteTool.
self changed: #selectedTool.
self drawable redrawNeeded .! !
!DrGeo methodsFor: 'callback create'!
executeMacro
self selectTool: DrGMacroPlayTool with: DrGMacroPlayer.
selectedTool _ #macroExecute.
self changed! !
!DrGeo methodsFor: 'callback create'!
executeMacro: aMacro
self selectTool: DrGMacroPlayTool with: DrGMacroPlayerHeadless.
selectedTool _ #macroExecute.
self tool builder selectedMacro: aMacro.
self tool switchState: DrGMacroPlayToolStateSelect.
self changed! !
!DrGeo methodsFor: 'callback create'!
property
self selectTool: DrGPropertyTool.
selectedTool _ #property.
self changed! !
!DrGeo methodsFor: 'callback create'!
useScript
self selectTool: DrGScriptPlayTool with: DrGScriptPlayer.
selectedTool _ #useScript.
self changed! !
!DrGeo methodsFor: 'callback create'!
useScript: aScript
self selectTool: DrGScriptPlayTool with: DrGScriptPlayerHeadless.
selectedTool _ #useScript.
self tool builder scriptClass: aScript.
self tool switchState: DrGMacroPlayToolStateSelect.
self changed! !
!DrGeo methodsFor: 'canvas' stamp: 'hlsf 8/3/2023 23:22:11'!
previewOnFile: aFileEntry
"compute a preview and save it in the file entry"
| stream |
[ [stream := aFileEntry forceWriteStream.
self drawable previewOn: stream]
on: Error
do:[: e| self halt.]
]
ensure: [ stream close]
! !
!DrGeo methodsFor: 'initialize-release' stamp: 'hlsf 8/4/2023 18:17:09'!
initialize
self initializeBasic.
self controlsManager: DrGUIControlsManager.
self move.
self view openInWorld ! !
!DrGeo methodsFor: 'initialize-release' stamp: 'hlsf 8/4/2023 18:16:58'!
initializeBasic
super initialize.
isCreateMultipleMode := false.
gridStuck := false.
"because empty at initialize, no save is needed, so we marked as saved"
saved := true.
notInteractive := false.
domain := DrGeoDomain new.! !
!DrGeo methodsFor: 'initialize-release' stamp: 'hlsf 8/4/2023 18:17:15'!
initializeService
self initializeBasic.
self controlsManager: DrGUIMinimalControlsManager.
self move.! !
!DrGeo methodsFor: 'initialize-release' stamp: 'hlsf 11/14/2023 00:18:55'!
release
tool release.
self drawable ifNotNil: [:dr | dr release].
self domain release.
stSketch ifNotNil: [stSketch terminateDo].
controlsManager release.
domain := nil.
controlsManager := nil.
sketchName := nil! !
!DrGeo methodsFor: 'testing' stamp: 'hlsf 6/19/2021 10:07:28'!
isAxesVisible
^ self drawable
ifNotNil: [self drawable axesVisible]
ifNil: [false]! !
!DrGeo methodsFor: 'testing'!
isCreateMultipleMode
^isCreateMultipleMode! !
!DrGeo methodsFor: 'testing'!
isForceVisible
"We force unvisible costume to be visible when in style mode only"
^ (self isTool: #style) or: [self isTool: #eraser]! !
!DrGeo methodsFor: 'testing' stamp: 'hlsf 6/19/2021 10:07:28'!
isGridVisible
^ self drawable
ifNotNil: [self drawable gridVisible]
ifNil: [false]! !
!DrGeo methodsFor: 'testing'!
isGridded
^ gridStuck! !
!DrGeo methodsFor: 'testing' stamp: 'hlsf 8/3/2023 21:21:36'!
isNotInteractive
^ notInteractive ! !
!DrGeo methodsFor: 'testing' stamp: 'hlsf 8/3/2023 20:51:22'!
isSaved
^ saved! !
!DrGeo methodsFor: 'testing'!
isTool: symbolTool
"Do we have this symbolTool selected"
^ selectedTool == symbolTool ! !
!DrGeo methodsFor: 'tool' stamp: 'hlsf 4/10/2022 14:59:57'!
openTools
controlsManager openTools! !
!DrGeo methodsFor: 'tool' stamp: 'hlsf 4/5/2022 20:59:11'!
selectTool: aToolClassName
self tool: nil.
self tool: (aToolClassName presenter: self)! !
!DrGeo methodsFor: 'tool' stamp: 'hlsf 4/5/2022 20:59:06'!
selectTool: aToolClassName with: aBuilderClass
self tool: (aToolClassName builder: aBuilderClass presenter: self).
self domain changed: #selectedTool! !
!DrGeo methodsFor: 'tool' stamp: 'hlsf 6/19/2021 14:53:45'!
selectToolAfterBuilding
self isCreateMultipleMode
ifFalse: [self move]! !
!DrGeo methodsFor: 'tool'!
selectionCleanUp
|createdItem|
"a mathItem is just been created, do some clean up"
self tool reset.
createdItem _ self domain factory last.
"eventually if not in createMultipleMode we escape from this tool"
(createdItem isFreePointItem
or: [createdItem isIntersectionPointItem
or: [createdItem isPointItemOnCurve]])
ifFalse: [self selectToolAfterBuilding].
((tool class = DrGFlyPointBuildTool) or: [selectedTool = #intersection]) ifTrue: [
self selectToolAfterBuilding].
! !
!DrGeo methodsFor: 'updating'!
deleteMathItem: aCostume
self domain deleteMathItem: aCostume mathItem.
self domain updateAllMathItems! !
!DrGeo methodsFor: 'updating' stamp: 'hlsf 8/4/2023 12:19:10'!
readyToBuild
|answer|
"readyToBuild event, the builder is ready to build, request to the domain the construction of the math item under the builder"
answer := self domain createMathItem: self tool builder.
self flag: #drgeoTodo. "Pourquoi faut-il unhide ?"
answer last ifFalse: [(self drawable viewOf: answer first) unhide].
self selectionCleanUp.
self domain updateAllMathItems.
self saved: false.! !
!DrGeo methodsFor: 'updating'!
readyToBuildClone
|answer|
"readyToBuild event sent from the SelectTool. The builder is ready to clone an items and its parents,
request to the domain the construction of the math item under the builder"
answer _ self domain createMathItem: self tool builder.
self tool grabClone: answer first last.! !
!DrGeo methodsFor: 'updating'!
readyToBuildMacro
"readyToBuild event, the builder is ready to build a macro, request to the domain the construction of the math item under the builder"
self domain createMacro: self tool builder.
self move! !
!DrGeo methodsFor: 'updating' stamp: 'hlsf 8/4/2023 17:33:11'!
readyToPlayMacro
"readyToBuild event, the builder is ready to play a macro (enought input items), request to the domain the construction of the math items under the builder"
self domain playMacro: self tool builder in: self.
self move! !
!DrGeo methodsFor: 'updating' stamp: 'hlsf 8/4/2023 12:19:10'!
updateSelection
(self isTool: #move) ifTrue: [|aMathItem|
aMathItem := controlsManager tree selectedItem withoutListWrapper.
aMathItem isNil
ifTrue: [self tool morph: nil]
ifFalse: [ self tool morph: (self drawable viewOf: aMathItem)]]! !
!DrGeo class methodsFor: 'file' stamp: 'hlsf 8/4/2023 18:07:28'!
file: fileEntry
|answer|
DrGeoSystem startSpinner.
answer := DrGeoXml new load: fileEntry for: #new.
DrGeoSystem stopSpinner.
^ answer! !
!DrGeo class methodsFor: 'file' stamp: 'hlsf 8/4/2023 18:07:41'!
serviceXml: fileEntry
^ DrGeoXml new load: fileEntry for: #service
! !
!DrGeo class methodsFor: 'instance creation' stamp: 'hlsf 8/4/2023 18:03:35'!
service
"instanciate a DrGeo service, to embbed in third party Morph. It is just the canvas without surounding menu and icon"
^ self basicNew ::
initializeService;
yourself! !
!DrGeo class methodsFor: 'saved status' stamp: 'hlsf 8/4/2023 17:40:53'!
figuresArray
|items activeViews|
activeViews := OrderedCollection new.
DrGeoView allInstances do: [:each |
each owner isNil ifFalse: [activeViews add: each]].
items := OrderedCollection new.
activeViews do: [:aView |
items add: (Array
with: aView
with: 'Fig. - ' translated, aView label
with: (ValueHolder with: aView presenter isSaved not))].
^ items
! !
!DrGeo class methodsFor: 'saved status' stamp: 'hlsf 8/3/2023 21:40:18'!
macrosArray
|items|
items := OrderedCollection new.
DrGMacroFactory new pool do: [:macro |
items add: (Array
with: macro
with: 'Macro - ' translated, macro title
with: (ValueHolder with: macro isSaved not) )].
^ items! !
!DrGeo class methodsFor: 'saved status' stamp: 'hlsf 8/3/2023 21:40:27'!
unsavedData
"Answer a collection of unsaved data"
| unsavedData |
unsavedData := OrderedCollection new.
unsavedData
addAll: (self figuresArray select: [:each | each third propertyValue]);
addAll: (self macrosArray select: [:each | each third propertyValue]).
^ unsavedData! !
!DrGeo class methodsFor: 'user interface' stamp: 'hlsf 8/3/2023 21:46:41'!
aboutDrgeo
UISupervisor whenUIinSafeState: [
(PopUpMenu labels: ' Ok ' icons: {DrGIcons drgeo})
startUpNonModalWithCaption: self drgeoInformationString ]! !
!DrGeo class methodsFor: 'user interface' stamp: 'hlsf 8/3/2023 21:46:06'!
drgeoCopyright
^ 'Source code application: Copyright 1996-2023 Hilaire Fernandes
Icons: Copyright 1999 Frédéric Toussaint
Icons: Copyright 2021-2022 David Caula (imppao)'! !
!DrGeo class methodsFor: 'user interface' stamp: 'hlsf 8/3/2023 21:45:47'!
drgeoInformationString
|text |
text := 'Dr. Geo is about interactive geometry and programming.
{1}
It allows one to create geometric figure plus the interactive manipulation
It is usable in teaching situation, in mathematics, physics and
programming, with students from primary school to university levels.
It is simple and effective with some unique features as Smalltalk scripts
and programmed interactive sketches.
{2}
LICENSE: GPL' translated format: {self drgeoVersion. self drgeoCopyright}.
^ text! !
!DrGeo class methodsFor: 'user interface' stamp: 'hlsf 8/5/2023 14:26:39'!
drgeoVersion
^ 'Installed version: ' translated,
'23.12a beta (code revision ',
(String streamContents: [:str | (CodePackage installedPackages at: 'DrGeo') featureSpec provides printVersionRevisionOn: str]),
')'! !
!DrGeo class methodsFor: 'user interface' stamp: 'hlsf 8/3/2023 21:47:35'!
getMenuIn: aWorld at: aHand
| menu |
menu := (CommandBuilder on: #drgeoWorldMenu) getMenu.
menu addStayUpIcons ;
addTitle: 'System menu' translated.
^ menu! !
!DrGeo class methodsFor: 'user interface' stamp: 'hlsf 8/3/2023 21:44:17'!
quit
self unsavedData isEmpty ifFalse: [
(self confirm: 'There is unsaved data!!
Are you sure to quit Dr. Geo environment?' translated) ifFalse: [ ^ self]].
Smalltalk quitPrimitive! !
!DrGeo class methodsFor: 'user interface' stamp: 'hlsf 8/3/2023 21:48:27'!
toolsMenu: builder
<drgeoWorldMenu>
builder newEntry: 'System Browser' translated in: 'Tools' translated ::
icon: #developmentIcon;
action: [HierarchyBrowserWindow onClass: DrGeoSketch selector: nil];
help:'A source code browser to view, edit and save Dr. Geo code. I open the browser on the DrGeoSketch class you can study to design your own Smalltalk sketch.' translated;
order: 40.
builder newEntry: 'Smalltalk Sketch Editor' translated in: 'Tools' translated ::
icon: #textEditorIcon;
help: 'An editor to write and to test new Smalltalk sketch.' translated;
action: [DrGSmalltalkSketchEditor open: '' label: 'Edit Smalltalk Sketch' translated.];
order: 20.
builder newEntry: 'Browse Smalltalk Sketches' translated in: 'Tools' translated ::
icon: #scriptIcon;
help: 'A tool to browse and to test both system and personal Smalltalk Sketches.' translated;
action: [DrGSmalltalkSketchBrowser open: DrGeoSystem smalltalkSketchesPath label: 'Browse' translated.];
order: 10.
builder newEntry: 'Workspace' translated in: 'Tools' translated ::
icon: #terminalIcon;
action: [Workspace openWorkspace ];
help: 'A window used as a scratchpad area where fragments of Cuis-Smalltalk code can be entered, stored, edited, and evaluated.' translated;
order: 30.
builder newEntry: 'Open a file' translated in: 'Tools' translated ::
icon: #systemFileManagerIcon;
action: [FileListWindow openFileList];
help: 'Open the filer on your personal sketches collection.' translated;
order: 50.
builder newEntry: 'Save session' translated in: 'Tools' translated ::
order: 999;
action: [Smalltalk saveImage];
icon: #saveIcon;
help: 'Save this Dr. Geo session.' translated! !
!DrGeo class methodsFor: 'user interface' stamp: 'hlsf 8/8/2023 19:13:55'!
worldMenu: builder
<drgeoWorldMenu>
builder newEntry: 'New sketch' translated ::
icon: #newIcon;
action: [DrGeo new];
order: 0.
builder newEntry: 'Open a sketch' translated ::
icon: #openIcon;
action: [DrGFileOpenMorph open];
order: 1.
builder newEntry: 'Toggle full screen mode' translated ::
icon: #viewFullscreenIcon;
action: [DrGeoSystem toggleFullscreen];
help: 'Turn full screen mode on when it is off, off when it is on.' translated;
order: 2.
builder newEntry: 'Settings' translated ::
icon: #preferencesIcon;
action: [PreferenceBrowser open: DrGeoSystem preferences label: 'Dr. Geo Preferences' translated.];
order: 3.
builder newEntry: 'Tools' translated ::
icon: #systemIcon.
builder newEntry: 'About' translated ::
action: [ DrGeo aboutDrgeo ];
order: 7.
builder newEntry: 'Quit' translated ::
action: [ DrGeo quit ];
icon: #quitIcon;
order: 999! !
!DrGTool methodsFor: 'handling' stamp: 'hlsf 4/11/2021 12:04:52'!
chooseMorph: morphs
self chooseMorph: morphs title: 'Select an object' translated.! !
!DrGTool methodsFor: 'handling' stamp: 'hlsf 8/3/2021 13:00:01'!
chooseMorph: morphs title: aTitle
| menu |
menu _ DrGDrawableMenu entitled: aTitle.
menu tool: self.
morphs do: [ :aMorph |
menu add: aMorph asString target: self action: #handleChoice: argument: {aMorph}].
menu popUpInWorld. ! !
!DrGTool methodsFor: 'handling' stamp: 'hlsf 4/11/2021 12:05:08'!
handleChoice: aMorphCollection
^ self state handleChoice: aMorphCollection ! !
!DrGTool methodsFor: 'handling' stamp: 'hlsf 6/20/2021 16:52:25'!
handleMouseAt: aPoint
^self state handleMouseAt: aPoint! !
!DrGTool methodsFor: 'handling' stamp: 'hlsf 6/20/2021 22:08:39'!
handlePress: aPoint
^self state handlePress: aPoint ! !
!DrGTool methodsFor: 'handling'!
handlePressShiftKey: aPoint
^self state handlePressShiftKey: aPoint ! !
!DrGTool methodsFor: 'handling' stamp: 'hlsf 6/20/2021 22:42:51'!
handleRelease: aPoint
self state handleRelease: aPoint ! !
!DrGTool methodsFor: 'handling'!
handleReleaseShiftKey: aPoint
self state handleReleaseShiftKey: aPoint ! !
!DrGTool methodsFor: 'handling'!
handleShiftKey: aPoint
^self state handleShiftKey: aPoint ! !
!DrGTool methodsFor: 'handling'!
handleShiftKeyMouseAt: aPoint
^self state handleShiftKeyMouseAt: aPoint! !
!DrGTool methodsFor: 'handling'!
handleStillPress: aPoint
self state handleStillPress: aPoint! !
!DrGTool methodsFor: 'updating' stamp: 'hlsf 6/19/2021 10:07:28'!
gridPoint: ungriddedPoint
^ self drawable gridPoint: ungriddedPoint.! !
!DrGTool methodsFor: 'updating' stamp: 'hlsf 4/11/2021 12:06:31'!
redrawFlyingMorph! !
!DrGTool methodsFor: 'updating'!
switchState: aStateClass
self state: (aStateClass new context: self)! !
!DrGTool methodsFor: 'initialize-release' stamp: 'hlsf 4/11/2021 12:03:29'!
initialize
morph _ nil.
self last: 0@0.! !
!DrGTool methodsFor: 'initialize-release'!
registerDependant: anObject! !
!DrGTool methodsFor: 'initialize-release' stamp: 'hlsf 4/24/2020 12:02:18'!
release
self reset.! !
!DrGTool methodsFor: 'initialize-release' stamp: 'hlsf 4/9/2021 19:52:53'!
reset
self morph: nil;
last: nil;
spot: nil.
mathItemUnderMouse _ nil! !
!DrGTool methodsFor: 'initialize-release'!
resetForFreshStart
self reset.! !
!DrGTool methodsFor: 'accessing'!
description
^ self subclassResponsibility! !
!DrGTool methodsFor: 'accessing'!
domain
^presenter domain! !
!DrGTool methodsFor: 'accessing' stamp: 'hlsf 6/19/2021 10:07:28'!
drawable
^presenter drawable! !
!DrGTool methodsFor: 'accessing'!
factory
^self domain factory! !
!DrGTool methodsFor: 'accessing'!
last
^last! !
!DrGTool methodsFor: 'accessing'!
last: aPoint
last _ aPoint! !
!DrGTool methodsFor: 'accessing' stamp: 'hlsf 4/11/2021 12:46:23'!
mathItem
^self morph mathItem! !
!DrGTool methodsFor: 'accessing' stamp: 'hlsf 4/11/2021 12:46:23'!
morph
^morph ! !
!DrGTool methodsFor: 'accessing' stamp: 'hlsf 2/10/2022 11:53:09'!
morph: aMorph
morph ifNotNil: [
morph stopBlinking.
presenter controlsManager tree ifNotNil: [:aTree | aTree mathItem: nil]].
morph _ aMorph.
morph ifNotNil: [
morph startBlinking.
presenter controlsManager tree ifNotNil: [:aTree | aTree mathItem: morph mathItem]
]
! !
!DrGTool methodsFor: 'accessing'!
presenter
^presenter ! !
!DrGTool methodsFor: 'accessing'!
presenter: aPresenter
presenter _ aPresenter ! !
!DrGTool methodsFor: 'accessing' stamp: 'hlsf 6/23/2021 15:47:53'!
relevantMorphsNear: aPoint
"return the list of morphs at position aPoint relevant to me, override if needed"
^self myMorphsNear: aPoint ! !
!DrGTool methodsFor: 'accessing'!
spot
^spot! !
!DrGTool methodsFor: 'accessing'!
spot: aPoint
spot _ aPoint ! !
!DrGTool methodsFor: 'accessing'!
state
^state! !
!DrGTool methodsFor: 'accessing'!
state: aState
state _ aState ! !
!DrGTool methodsFor: 'private' stamp: 'hlsf 8/4/2023 11:39:29'!
myMorphsNear: aPoint
"Only morphs where feedback and action are wished, not hidden, wanted and under mouse cursor"
^self drawable itemViews select: [:aMorph |
aMorph style isNotHidden
and: [(self isWanted: {aMorph mathItem})
and: [aMorph containsPoint: aPoint]]]! !
!DrGTool methodsFor: 'private' stamp: 'hlsf 6/23/2021 15:47:53'!
pointMorphsFirstNear: aPoint
"When the user moves the mouse over a collection of geometric items, if there
are any point items, we discard all the other geometric items"
| myMorphs pointMorphs |
myMorphs _ self myMorphsNear: aPoint.
pointMorphs _ myMorphs select: [:aMorph | aMorph isPoint].
pointMorphs ifNotEmpty: [ ^ pointMorphs ].
^ myMorphs! !
!DrGTool methodsFor: 'private' stamp: 'hlsf 6/23/2021 15:47:53'!
pointMorphsNear: aPoint
"List of point under the mouse cursor"
^ (self myMorphsNear: aPoint) select: [:aMorph | aMorph isPoint].! !
!DrGTool methodsFor: 'testing' stamp: 'hlsf 6/20/2021 17:15:14'!
isBuilding
"does the tool build new object ?"
^ true! !
!DrGTool methodsFor: 'testing'!
isCloning
^ false! !
!DrGTool methodsFor: 'testing'!
isGridded
^presenter isGridded! !
!DrGTool methodsFor: 'testing'!
isWanted: aMathItem
^true! !
!DrGTool class methodsFor: 'instance creation' stamp: 'hlsf 2/13/2022 11:06:59'!
new
self error: 'Instanciate with #presenter: message'! !
!DrGTool class methodsFor: 'instance creation' stamp: 'hlsf 2/13/2022 11:06:20'!
presenter: aPresenter
^ self basicNew ::
presenter: aPresenter;
initialize;
yourself! !
!DrGAnimateTool methodsFor: 'accessing'!
animateStep
^ animateStep! !
!DrGAnimateTool methodsFor: 'accessing'!
animateStep: aFloat
animateStep _ aFloat ! !
!DrGAnimateTool methodsFor: 'accessing'!
description
^ self class description! !
!DrGAnimateTool methodsFor: 'accessing'!
isAnimating
^ self state isAnimating ! !
!DrGAnimateTool methodsFor: 'accessing' stamp: 'hlsf 6/23/2021 15:43:01'!
relevantMorphsNear: aPoint
^ (self pointMorphsNear: aPoint) select: [:aMorph | aMorph mathItem isPointItemOnCurve]! !
!DrGAnimateTool methodsFor: 'as yet unclassified'!
animate
state animate! !
!DrGAnimateTool methodsFor: 'initialize-release'!
initialize
super initialize.
self reset! !
!DrGAnimateTool methodsFor: 'initialize-release'!
reset
state ifNotNil: [state stopAnimating].
super reset.
self switchState: DrGAnimateToolState.
! !
!DrGAnimateTool class methodsFor: 'as yet unclassified'!
description
^'Select a free point on a curve to animate it.' translated! !
!DrGAnimateTool class methodsFor: 'as yet unclassified'!
title
^ 'Animate' translated! !
!DrGBuildTool methodsFor: 'testing'!
isWanted: aMathItemCollection
^builder isWanted: aMathItemCollection ! !
!DrGBuildTool methodsFor: 'adding' stamp: 'hlsf 8/4/2021 12:34:24'!
add: aMorph
self stopBlinking.
selectedMorphs add: aMorph.
self startBlinking.! !
!DrGBuildTool methodsFor: 'initialize-release' stamp: 'hlsf 4/11/2021 12:28:10'!
initialize
super initialize.
self switchState: DrGBuildToolState.
selectedMorphs _ OrderedCollection new! !
!DrGBuildTool methodsFor: 'initialize-release'!
registerDependant: anObject
builder when: #readyToBuild send: #readyToBuild to: anObject! !
!DrGBuildTool methodsFor: 'initialize-release'!
release
super release.
builder release.
self releaseActionMap. ! !
!DrGBuildTool methodsFor: 'updating' stamp: 'hlsf 4/11/2021 12:06:31'!
redrawFlyingMorph
builder redrawFlyingMorph ! !
!DrGBuildTool methodsFor: 'updating' stamp: 'hlsf 4/11/2021 12:28:10'!
reset
super reset.
self stopBlinking.
self builder reset.
selectedMorphs _ OrderedCollection new! !
!DrGBuildTool methodsFor: 'updating' stamp: 'hlsf 4/11/2021 12:28:26'!
startBlinking
selectedMorphs do: [ :aMorph | aMorph startBlinking ]! !
!DrGBuildTool methodsFor: 'updating' stamp: 'hlsf 4/11/2021 12:28:32'!
stopBlinking
selectedMorphs do: [ :aMorph | aMorph stopBlinking ]! !
!DrGBuildTool methodsFor: 'accessing'!
builder
^builder! !
!DrGBuildTool methodsFor: 'accessing'!
builder: aBuilder
builder _ aBuilder ! !
!DrGBuildTool methodsFor: 'accessing'!
description
^ builder class description! !
!DrGBuildTool methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 17:25:21'!
presenter: aPresenter
super presenter: aPresenter.
builder presenter: aPresenter .! !
!DrGBuildTool class methodsFor: 'instance creation' stamp: 'hlsf 2/13/2022 11:09:38'!
builder: aBuilderClassName presenter: aPresenter
^self basicNew ::
builder: aBuilderClassName new;
presenter: aPresenter;
initialize;
yourself! !
!DrGFlyPointBuildTool methodsFor: 'initialize'!
initialize
super initialize.
self switchState: DrGFlyPointBuildToolState! !
!DrGFlyPointBuildTool methodsFor: 'accessing'!
intersectableCurves: aCollection at: aPoint
"As long as we can't get proper intersection with the first two, we remove the first one an try again "
aCollection size <= 1 ifTrue: [ ^ aCollection ].
^ ( DrGFlyPointBuilder new isCurveIntersectionValid: {
(aCollection first mathItem).
(aCollection second mathItem).
aPoint})
ifTrue: [ aCollection ]
ifFalse: [self intersectableCurves: aCollection allButFirst at: aPoint ]! !
!DrGFlyPointBuildTool methodsFor: 'accessing' stamp: 'hlsf 6/23/2021 15:47:53'!
relevantMorphsNear: aPoint
| intersectables curves |
intersectables _ self
intersectableCurves: (
(self myMorphsNear: aPoint) select: [:aMorph | aMorph mathItem isIntersectableItem])
at: aPoint.
"if no intersectable, return the non intersectable only if one, otherwise it is considered for interesction"
^ intersectables ifEmpty: [
curves _ (self myMorphsNear: aPoint) select: [:aMorph | aMorph isCurve].
curves size > 1
ifTrue: [ #() ]
ifFalse: [ curves]]! !
!DrGMacroBuildTool methodsFor: 'accessing' stamp: 'hlsf 6/23/2021 15:52:50'!
relevantMorphsNear: aPoint
^self pointMorphsFirstNear: aPoint ! !
!DrGMacroBuildTool methodsFor: 'accessing' stamp: 'hlsf 4/11/2021 13:52:07'!
selectInputMorph
self selectMorphsFrom: builder input! !
!DrGMacroBuildTool methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 12:18:22'!
selectMorphsFrom: aMathItemCollection
presenter ifNil: [^self].
self stopBlinking.
selectedMorphs := self drawable viewsOf: aMathItemCollection.
self startBlinking! !
!DrGMacroBuildTool methodsFor: 'accessing' stamp: 'hlsf 4/11/2021 12:31:09'!
selectNoMorph
self selectMorphsFrom: OrderedCollection new! !
!DrGMacroBuildTool methodsFor: 'accessing' stamp: 'hlsf 4/11/2021 12:31:25'!
selectOutputMorph
self selectMorphsFrom: builder output! !
!DrGMacroBuildTool methodsFor: 'updating'!
cancel
"the builder informs us the user wants to cancel the macro building process"
presenter move.! !
!DrGMacroBuildTool methodsFor: 'initialize-release'!
initialize
super initialize.
self switchState: DrGMacroToolStateNeutral ! !
!DrGMacroBuildTool methodsFor: 'initialize-release'!
registerDependant: anObject
builder when: #changedState send: #switchState: to: self.
builder when: #cancel send: #cancel to: self.
builder when: #readyToBuild send: #readyToBuildMacro to: anObject! !
!DrGMacroPlayTool methodsFor: 'updating' stamp: 'hlsf 4/11/2021 12:31:09'!
changedMacro
" the builder inform us the user selected another macro-construction,
do some cleaning"
self selectNoMorph! !
!DrGMacroPlayTool methodsFor: 'accessing' stamp: 'hlsf 8/3/2023 21:18:06'!
presenter: aPresenter
super presenter: aPresenter.
presenter notInteractive: true.! !
!DrGMacroPlayTool methodsFor: 'initialize-release'!
registerDependant: anObject
builder when: #changedState send: #switchState: to: self.
builder when: #cancel send: #cancel to: self.
builder when: #readyToBuild send: #readyToPlayMacro to: anObject.
builder when: #changedMacro send: #changedMacro to: self! !
!DrGMacroPlayTool methodsFor: 'initialize-release' stamp: 'hlsf 8/3/2023 21:18:23'!
release
super release.
presenter notInteractive: false! !
!DrGScriptPlayTool methodsFor: 'initialize-release'!
registerDependant: anObject
builder when: #changedState send: #switchState: to: self.
builder when: #cancel send: #cancel to: self.
builder when: #readyToBuild send: #readyToBuild to: anObject.
builder when: #changedScript send: #changedScript to: self! !
!DrGScriptPlayTool methodsFor: 'updating' stamp: 'hlsf 4/11/2021 12:31:09'!
changedScript
" the builder inform us the user selected another script,
do some cleaning"
self selectNoMorph! !
!DrGFlyBuildTool methodsFor: 'adding' stamp: 'hlsf 4/11/2021 12:32:36'!
add: aMorph
mathItemTool add: aMorph ! !
!DrGFlyBuildTool methodsFor: 'initialize-release' stamp: 'hlsf 8/4/2023 17:25:59'!
initialize
super initialize.
self switchState: DrGFlyBuildToolState.
flyPointTool := DrGFlyPointBuildTool builder: DrGFlyPointBuilder presenter: presenter.
mathItemTool presenter: presenter.
flyPointTool presenter: presenter.
mathItemTool builder presenter: presenter ! !
!DrGFlyBuildTool methodsFor: 'initialize-release' stamp: 'hlsf 8/4/2021 11:22:35'!
registerDependant: anObject
mathItemTool registerDependant: anObject.
flyPointTool registerDependant: anObject! !
!DrGFlyBuildTool methodsFor: 'initialize-release' stamp: 'hlsf 8/4/2021 11:22:35'!
release
super release
mathItemTool release.
flyPointTool release.! !
!DrGFlyBuildTool methodsFor: 'updating' stamp: 'hlsf 4/11/2021 12:06:31'!
redrawFlyingMorph
mathItemTool builder redrawFlyingMorph ! !
!DrGFlyBuildTool methodsFor: 'updating' stamp: 'hlsf 8/4/2021 11:22:35'!
reset
"Why do we reset?"
"because intermediate point where created"
flyPointTool builder readyToBuild ifTrue: [flyPointTool reset].
"or the final mathItem was created"
mathItemTool builder readyToBuild ifTrue:
[self resetForFreshStart].
! !
!DrGFlyBuildTool methodsFor: 'updating' stamp: 'hlsf 8/4/2021 11:22:35'!
resetForFreshStart
"Reset to restart over the user build process"
mathItemTool reset.
flyPointTool reset.! !
!DrGFlyBuildTool methodsFor: 'testing'!
isWanted: aMathItem
^mathItemTool isWanted: aMathItem! !
!DrGFlyBuildTool methodsFor: 'accessing' stamp: 'hlsf 8/4/2021 11:22:35'!
builder
"We have two builder, the flyPointBuilder and the other one (line, segment,...)"
flyPointTool builder readyToBuild
ifTrue: [^flyPointTool builder]
ifFalse: [^mathItemTool builder]! !
!DrGFlyBuildTool methodsFor: 'accessing'!
builder: aBuilder
mathItemTool builder: aBuilder.! !
!DrGFlyBuildTool methodsFor: 'accessing'!
description
^ mathItemTool builder class description ! !
!DrGFlyBuildTool methodsFor: 'accessing' stamp: 'hlsf 8/4/2021 11:22:35'!
flyPointTool
^flyPointTool! !
!DrGFlyBuildTool methodsFor: 'accessing'!
mathItemTool
^mathItemTool! !
!DrGFlyBuildTool methodsFor: 'accessing' stamp: 'hlsf 2/13/2022 11:13:01'!
mathItemTool: aBuilderClassName
mathItemTool ifNil:
[mathItemTool _ DrGBuildTool builder: aBuilderClassName presenter: presenter] ! !
!DrGFlyBuildTool class methodsFor: 'as yet unclassified' stamp: 'hlsf 2/13/2022 11:18:03'!
builder: aBuilderClass presenter: aPresenter
^self basicNew ::
presenter: aPresenter ;
mathItemTool: aBuilderClass ;
initialize ;
yourself! !
!DrGFlyBuildTool class methodsFor: 'as yet unclassified' stamp: 'hlsf 8/4/2021 11:26:34'!
with: aBuilderClass
^self new mathItemTool: aBuilderClass! !
!DrGFlyBuildTouchTool methodsFor: 'initialize-release'!
initialize
super initialize.
self switchState: DrGFlyBuildTouchToolState.! !
!DrGSelectTool methodsFor: 'testing' stamp: 'hlsf 6/20/2021 17:15:36'!
isBuilding
^ false! !
!DrGSelectTool methodsFor: 'testing'!
isCloning
^ builder readyToBuild ! !
!DrGSelectTool methodsFor: 'initialize-release'!
initialize
self reset.
builder _ DrGCloneBuilder new.! !
!DrGSelectTool methodsFor: 'initialize-release'!
registerDependant: anObject
builder when: #readyToBuild send: #readyToBuildClone to: anObject! !
!DrGSelectTool methodsFor: 'accessing'!
builder
^ builder! !
!DrGSelectTool methodsFor: 'accessing' stamp: 'hlsf 6/23/2021 15:47:53'!
curvesToMutatePointIntoNear: aPoint
"Search for the curves the point can mutate into. In priority intersectable curves, then curves."
| curves intersectables |
curves _ (self myMorphsNear: aPoint) select: [:aMorph | aMorph mathItem isCurveItem
and: [self domain factory is: aMorph mathItem before: self mathItem]].
"if several curves check for the intersectables"
^ curves size > 1
ifTrue: [
intersectables _ curves select: [ :aMorph | aMorph mathItem isIntersectableItem].
intersectables size > 1
ifTrue: [intersectables]
ifFalse: [#()]]
ifFalse: [ curves ]! !
!DrGSelectTool methodsFor: 'accessing'!
description
^ self class description! !
!DrGSelectTool methodsFor: 'accessing'!
mathItems
^ mathItems ! !
!DrGSelectTool methodsFor: 'accessing' stamp: 'hlsf 4/11/2021 12:35:13'!
morphs
^ morphs ! !
!DrGSelectTool methodsFor: 'accessing' stamp: 'hlsf 6/23/2021 15:39:01'!
mutableMorphsAt: aPoint
"select the morph we can mutate"
^ (self relevantMorphsNear: aPoint) select: [:aMorph | |item|
item _ aMorph mathItem.
item isFreePointOnPlaneItem
or: [(item isPointItemOnCurve and: [(self factory is: item parentWithTest: #isLocusItem) not])
or: [item isIntersectionPointItem]]]! !
!DrGSelectTool methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 17:34:16'!
pointMorphToMergeWithAt: aPoint
"A collection of point we can merge with. Only free point on plane are merge-able, and the merger should not depend on the initial point as well"
| dependents myMorphs |
^ morph mathItem isFreePointOnPlaneItem
ifTrue: [
myMorphs := self pointMorphsNear: aPoint.
myMorphs ifEmpty: [^ #()].
dependents := self domain factory dependentMathItem: morph mathItem.
myMorphs select: [:aMorph | aMorph mathItem ~~ morph mathItem
and: [(dependents includes: aMorph mathItem) not]]]
ifFalse: [#()]! !
!DrGSelectTool methodsFor: 'accessing' stamp: 'hlsf 6/23/2021 15:43:20'!
relevantMorphsNear: aPoint
^ self pointMorphsFirstNear: aPoint! !
!DrGSelectTool methodsFor: 'accessing'!
start
^start! !
!DrGSelectTool methodsFor: 'accessing'!
start: aPoint
start _ aPoint ! !
!DrGSelectTool methodsFor: 'updating' stamp: 'hlsf 8/4/2023 12:19:10'!
grabClone: clone
"We cloned!! We want to grab the clone to let the user move it somewhere in the canvas"
self morph: (self drawable viewOf: clone).
builder reset.
self switchState: DrGSelectToolStateDragged.
! !
!DrGSelectTool methodsFor: 'updating' stamp: 'hlsf 5/6/2020 14:23:57'!
reset
super reset.
start _ nil.
self switchState: DrGSelectToolStateNeutral.
mathItems _ nil.
builder ifNotNil: [builder reset].! !
!DrGSelectTool methodsFor: 'updating' stamp: 'hlsf 8/4/2023 11:39:39'!
updateDirtyItemsList
"Dirty items are the one needing update, both model and view. Don't try to be smart, update all of them."
mathItems := self factory pool.
morphs := self drawable itemViews ! !
!DrGSelectTool class methodsFor: 'documentation'!
description
^ 'Select and move an object.' translated! !
!DrGSelectTool class methodsFor: 'documentation'!
title
^ 'Select and Move' translated! !
!DrGPropertyTool methodsFor: 'testing'!
isWanted: aMathItemCollection
" only items whose property are editable "
^ aMathItemCollection first isPropertyEditable! !
!DrGPropertyTool methodsFor: 'updating' stamp: 'hlsf 3/19/2022 16:19:20'!
reset
super reset.
presenter controlsManager propertyFor: nil.
self switchState: DrGPropertyToolState! !
!DrGPropertyTool methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 11:25:09'!
presenter: aPresenter
super presenter: aPresenter.
self drawable forcedVisibility: false.! !
!DrGPropertyTool class methodsFor: 'documentation'!
description
^ 'Edit an item''s property' translated! !
!DrGPropertyTool class methodsFor: 'documentation'!
title
^ 'Property' translated! !
!DrGStyleTool methodsFor: 'updating' stamp: 'hlsf 2/13/2022 11:26:27'!
reset
super reset.
presenter controlsManager stylerFor: nil.
self switchState: DrGStyleToolState.! !
!DrGStyleTool methodsFor: 'initialize-release'!
initialize
super initialize.
self reset.! !
!DrGStyleTool methodsFor: 'initialize-release' stamp: 'hlsf 8/4/2023 11:25:26'!
release
self drawable forcedVisibility: false.
self presenter controlsManager stylerFor: nil.
DrGeoSystem showVirtualKeyboard: false.
super release.! !
!DrGStyleTool methodsFor: 'accessing'!
description
^ self class description! !
!DrGStyleTool methodsFor: 'accessing' stamp: 'hlsf 4/11/2021 12:52:56'!
morphStyle
^ self morph style! !
!DrGStyleTool methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 11:25:16'!
presenter: aPresenter
super presenter: aPresenter.
self drawable forcedVisibility: true.! !
!DrGStyleTool methodsFor: 'accessing' stamp: 'hlsf 6/23/2021 15:52:55'!
relevantMorphsNear: aPoint
^self pointMorphsFirstNear: aPoint ! !
!DrGStyleTool methodsFor: 'private' stamp: 'hlsf 8/4/2023 11:39:51'!
myMorphsNear: aPoint
"return the list of morph at position aPoint"
^self drawable itemViews select: [:aMorph |
(self isWanted: aMorph mathItem) and: [aMorph containsPoint: aPoint]]! !
!DrGStyleTool methodsFor: 'testing' stamp: 'hlsf 6/20/2021 17:15:50'!
isBuilding
^ false! !
!DrGStyleTool class methodsFor: 'documentation'!
description
^ 'Edit an object style.' translated! !
!DrGStyleTool class methodsFor: 'documentation'!
title
^ 'Edit Style' translated! !
!DrGDeleteTool methodsFor: 'updating'!
reset
super reset.
self switchState: DrGDeleteToolState! !
!DrGDeleteTool methodsFor: 'accessing' stamp: 'hlsf 6/23/2021 15:47:53'!
relevantMorphsNear: aPoint
^self myMorphsNear: aPoint ! !
!DrGDeleteTool class methodsFor: 'documentation'!
description
^'Erase an object and all its depedencies.' translated! !
!DrGDeleteTool class methodsFor: 'documentation'!
title
^'Eraser' translated ! !
!DrGToolState methodsFor: 'handling' stamp: 'hlsf 8/4/2021 11:47:54'!
handleChoice: aMorphCollection! !
!DrGToolState methodsFor: 'handling' stamp: 'hlsf 6/23/2021 15:39:01'!
handleMouseAt: aPoint
"Return true if we can process something or we are over something"
| morphs aTip feedback |
feedback _ true.
morphs _ self context relevantMorphsNear: aPoint.
morphs size = 1
ifTrue: [
aTip _ morphs first mathItem descriptiveName.
feedback _ morphs first style isFeedback].
morphs size > 1
ifTrue: [aTip _ 'Several objects can be selected. Please, choose one.' translated. ].
(aTip isNil or: [ feedback not ])
ifTrue: [self drawable hideTip]
ifFalse: [self drawable tip: aTip at: aPoint].
^ aTip notNil! !
!DrGToolState methodsFor: 'handling'!
handlePress: aPoint
^ false! !
!DrGToolState methodsFor: 'handling'!
handlePressShiftKey: aPoint
"handle pressed mouse bouton with shift key, by default just handle mouse button press"
^ self handlePress: aPoint! !
!DrGToolState methodsFor: 'handling'!
handleRelease: aPoint
! !
!DrGToolState methodsFor: 'handling'!
handleReleaseShiftKey: aPoint
" handle mouse bouton release while shift key down, by default only handle release"
self handleRelease: aPoint! !
!DrGToolState methodsFor: 'handling'!
handleShiftKey: aPoint
"handle shift key down, do nothing by default"
^ false! !
!DrGToolState methodsFor: 'handling'!
handleShiftKeyMouseAt: aPoint
"handle moved mouse while shift key down, by default just handle mouse at"
^ self handleMouseAt: aPoint! !
!DrGToolState methodsFor: 'handling'!
handleStillPress: aPoint
"A 2s mouse down evt, by default do nothing"! !
!DrGToolState methodsFor: 'state'!
switchState: aStateClass
self context switchState: aStateClass! !
!DrGToolState methodsFor: 'accessing'!
context
^context! !
!DrGToolState methodsFor: 'accessing'!
context: aContext
context _ aContext ! !
!DrGToolState methodsFor: 'accessing' stamp: 'hlsf 6/19/2021 10:07:28'!
drawable
^self context drawable! !
!DrGToolState methodsFor: 'accessing' stamp: 'hlsf 8/3/2023 20:55:47'!
presenter
^self context presenter! !
!DrGToolState methodsFor: 'accessing'!
view
^self context presenter view! !
!DrGBuildToolState methodsFor: 'handling' stamp: 'hlsf 8/4/2021 11:48:00'!
handleChoice: aMorphCollection
|aMathItemCollection|
aMathItemCollection _ OrderedCollection new.
aMorphCollection do: [:aMorph|
aMathItemCollection add: aMorph mathItem.
self context add: aMorph].
self context builder
add: aMathItemCollection
at: (self drawable gridWorldPoint: self context last).! !
!DrGBuildToolState methodsFor: 'handling' stamp: 'hlsf 6/23/2021 15:39:01'!
handlePress: aPoint
"return true if we process something (including additional user choice)"
| morphs |
self drawable hideTip.
self context last: aPoint.
morphs _ self context relevantMorphsNear: aPoint.
morphs size = 1 ifTrue: [
self handleChoice: morphs.
^true].
(morphs size = 0 and: [self context isWanted: #() ]) ifTrue: [
self handleChoice: morphs.
^true].
"More than one math item under mouse, user must choose one item"
morphs size >= 2 ifTrue: [
"Display a pop-up menu to select one item"
self context chooseMorph: morphs.
^true].
^false! !
!DrGFlyPointBuildToolState methodsFor: 'handling' stamp: 'hlsf 6/23/2021 15:39:01'!
handleMouseAt: aPoint
| morphs aTip |
morphs _ self context relevantMorphsNear: aPoint.
morphs size = 1
ifTrue: [aTip _ morphs first mathItem descriptiveName].
morphs size > 1
ifTrue: [aTip _ 'This intersection' translated].
aTip
ifNil: [self drawable hideTip]
ifNotNil: [self drawable tip: aTip at: aPoint].
^ aTip notNil! !
!DrGFlyPointBuildToolState methodsFor: 'handling' stamp: 'hlsf 8/4/2021 11:43:09'!
handlePress: aPoint
"return true as we always do something in this context."
self drawable hideTip.
self context last: (self context gridPoint: aPoint).
"user clicked in the background or in one or several curve item, handle it immediately"
self handleChoice: (self context relevantMorphsNear: aPoint).
^ true! !
!DrGMacroBuildToolStateInput methodsFor: 'handling' stamp: 'hlsf 11/3/2021 19:08:00'!
handleChoice: aMorphCollection
self context builder
add: (aMorphCollection collect: [ :c | c mathItem ])
at: (self drawable gridWorldPoint: self context last);
changed: #inputNames.
self context selectInputMorph! !
!DrGMacroBuildToolStateInput methodsFor: 'accessing' stamp: 'hlsf 4/11/2021 13:52:07'!
context: aContext
super context: aContext.
self context selectInputMorph ! !
!DrGMacroPlayToolStateSelect methodsFor: 'handling' stamp: 'hlsf 6/19/2021 10:07:28'!
handleChoice: aMorphCollection
self context builder
add: (aMorphCollection collect: [ :c | c mathItem ])
at: (self drawable gridWorldPoint: self context last).
self context selectInputMorph! !
!DrGMacroBuildToolStateOutput methodsFor: 'handling' stamp: 'hlsf 4/11/2021 12:31:25'!
context: aContext
super context: aContext.
self context selectOutputMorph ! !
!DrGMacroBuildToolStateOutput methodsFor: 'handling' stamp: 'hlsf 11/3/2021 19:10:22'!
handleChoice: aMorphCollection
self context builder
add: (aMorphCollection collect: [ :c | c mathItem ])
at: (self drawable gridWorldPoint: self context last);
changed: #outputNames.
self context selectOutputMorph! !
!DrGFlyBuildToolState methodsFor: 'processing' stamp: 'hlsf 8/4/2023 11:17:16'!
addFlyingPointToBuiltItemAt: aPoint
self context mathItemTool
add: self context drawable lastItemView.
self context mathItemTool builder
add: {self context domain factory last}
at: (self drawable morphToWorld: aPoint).! !
!DrGFlyBuildToolState methodsFor: 'testing' stamp: 'hlsf 8/4/2021 11:50:00'!
isFlyingPointConstructedAt: aPoint
"return true whenever a flypoint is constructed, the new point instance is then
ready to use, from the flyPointTool builder"
^ (self context mathItemTool builder isWanted: { (DrGPointItem new) })
and: [self context flyPointTool handlePress: aPoint]! !
!DrGFlyBuildToolState methodsFor: 'testing'!
isFlyingPointWantedAt: aPoint
"are we interested by a point at position aPoint"
^ (self context mathItemTool builder isWanted: { (DrGPointItem new) })
ifTrue: [self context flyPointTool handleMouseAt: aPoint]
ifFalse: [false]! !
!DrGFlyBuildToolState methodsFor: 'handling' stamp: 'hlsf 6/20/2021 17:10:31'!
handleMouseAt: aPoint
self context builder moveFlyingMorphAt: (self drawable morphToWorld: aPoint).
self context last: aPoint.
self drawable updateUnderMouseMorph.
"dispatch handleMouseAt"
^ (self context mathItemTool handleMouseAt: aPoint)
ifFalse: [self isFlyingPointWantedAt: aPoint]
ifTrue: [true]! !
!DrGFlyBuildToolState methodsFor: 'handling' stamp: 'hlsf 6/21/2021 21:23:09'!
handlePress: aPoint
self context last: aPoint.
"do we select an item underneath? If so we are done"
(self context mathItemTool handlePress: aPoint) ifTrue: [^true].
"do we want a flyingPoint ?"
(self isFlyingPointConstructedAt: aPoint) ifFalse: [^false].
self addFlyingPointToBuiltItemAt: aPoint.
^ true! !
!DrGFlyBuildToolState methodsFor: 'handling'!
handleRelease: aPoint
self context mathItemTool handleRelease: aPoint.
self context flyPointTool handleRelease: aPoint.! !
!DrGFlyBuildTouchToolState methodsFor: 'handling' stamp: 'hlsf 8/4/2021 15:06:04'!
handlePress: aPoint
| answer |
answer _ super handlePress: aPoint.
answer ifTrue: [ self switchState: DrGFlyBuildTouchToolStateGrabbed].
^ answer! !
!DrGFlyBuildTouchToolStateGrabbed methodsFor: 'handling' stamp: 'hlsf 8/4/2021 15:22:19'!
handleMouseAt: aPoint
self switchState: DrGFlyBuildTouchToolStateSlided.
^ true! !
!DrGFlyBuildTouchToolStateGrabbed methodsFor: 'handling' stamp: 'hlsf 8/4/2021 12:17:21'!
handlePress: aPoint
"We cannot clic again as the finger is stuck on the screen"
^ false! !
!DrGFlyBuildTouchToolStateGrabbed methodsFor: 'handling' stamp: 'hlsf 8/4/2021 12:23:43'!
handleRelease: aPoint
self switchState: DrGFlyBuildTouchToolState! !
!DrGFlyBuildTouchToolStateSlided methodsFor: 'handling' stamp: 'hlsf 8/4/2021 11:43:38'!
handlePress: aPoint
"the finger is stuck on the screen, we cannot clic again, can't do anything"
^ false! !
!DrGFlyBuildTouchToolStateSlided methodsFor: 'handling' stamp: 'hlsf 6/21/2021 20:11:06'!
handleRelease: aPoint
self switchState: DrGFlyBuildTouchToolState.
self context last: aPoint.
"do we select an item underneath?"
(self context mathItemTool handlePress: aPoint) ifTrue: [^true].
"do we want a flyingPoint ?"
(self isFlyingPointConstructedAt: aPoint) ifFalse: [^false].
self addFlyingPointToBuiltItemAt: aPoint.
^ true! !
!DrGMacroToolStateNeutral methodsFor: 'as yet unclassified'!
handleMouseAt: aPoint
^false! !
!DrGMacroToolStateNeutral methodsFor: 'accessing' stamp: 'hlsf 4/11/2021 12:31:09'!
context: aContext
super context: aContext.
self context selectNoMorph! !
!DrGSelectToolState methodsFor: 'accessing'!
mathItem
"the selected math item"
^ self context mathItem ! !
!DrGSelectToolState methodsFor: 'handling' stamp: 'hlsf 4/11/2021 13:55:12'!
handleChoice: aMorphCollection
aMorphCollection
ifNotEmpty:
[self context morph: aMorphCollection first.
self switchState: DrGSelectToolStateSelected.
^true]
ifEmpty:
[self context reset.
^false]! !
!DrGSelectToolStateDragged methodsFor: 'handling' stamp: 'hlsf 8/3/2023 20:55:54'!
handleChoice: aMorphCollection
"In this state, handle a choice to merge two points"
aMorphCollection ifNotEmpty: [
aMorphCollection do: [:aCostume | aCostume stopBlinking].
self context mathItem point: (self drawable morphToWorld: self context start).
self context domain
merge: self context mathItem with: aMorphCollection first mathItem.
self presenter saved: false].
self context reset.! !
!DrGSelectToolStateDragged methodsFor: 'handling' stamp: 'hlsf 12/2/2021 10:57:14'!
handleMouseAt: aPoint
|gridded|
(self context isGridded and: [self mathItem isFreePointItem])
ifFalse: [gridded _ self drawable gridWorldVector: aPoint - self context last.
self context domain
moveEvent: self mathItem
inDirection: gridded
withDirty: self context mathItems.
"If no movement, keep previous last position in reference"
(gridded closeTo: 0@0) ifFalse: [self context last: (self context gridPoint: aPoint)]]
ifTrue: [gridded _ self context gridPoint: aPoint.
self context domain
moveEvent: self mathItem
at: (self drawable gridWorldPoint: gridded)
withDirty: self context mathItems.
self context last: gridded.].
self drawable updateDottedLinesToParents.
self drawable restartMouseStillDownHandle.
^ true! !
!DrGSelectToolStateDragged methodsFor: 'handling' stamp: 'hlsf 8/3/2023 20:56:00'!
handleRelease: aPoint
self switchState: DrGSelectToolStateNeutral.
"issue a moveCommand"
self context domain
moveMathItem: self mathItem
with: (self drawable gridWorldVector: self context last - self context start).
self drawable removeDottedLinesToParents.
self context reset.
self presenter saved: false! !
!DrGSelectToolStateDragged methodsFor: 'handling' stamp: 'hlsf 4/11/2021 12:50:56'!
handleStillPress: aPoint
|merger|
(merger _ self context pointMorphToMergeWithAt: aPoint) notEmpty ifTrue:
["I keep pressing while holding a free point"
merger size = 1
ifTrue: [self handleChoice: merger]
ifFalse: [self context chooseMorph: merger title: 'Select a point to merge with' translated]]! !
!DrGMutatorToolStateDragged methodsFor: 'as yet unclassified'!
isMutantFreePoint
^ originalPointClass = DrGPointFreeItem! !
!DrGMutatorToolStateDragged methodsFor: 'handling' stamp: 'hlsf 6/23/2021 15:47:10'!
handleMouseAt: aPoint
| morphs aTip|
"First handle the redraw"
super handleMouseAt: aPoint.
"Detect for mutation candidate"
morphs _ self context curvesToMutatePointIntoNear: aPoint.
(morphs isEmpty and: [self isMutantFreePoint not]) ifTrue: [
aTip _ 'Change as a free point on the plane.' translated].
morphs size = 1 ifTrue: [
aTip _ 'Change as a free point on this curve.' translated].
morphs size > 1 ifTrue: [
aTip _ 'Change as this intersection.' translated].
aTip
ifNil: [self drawable hideTip]
ifNotNil: [self drawable tip: aTip at: aPoint].
^ aTip isNil not! !
!DrGMutatorToolStateDragged methodsFor: 'handling' stamp: 'hlsf 8/3/2023 20:56:08'!
handleRelease: aPoint
| morphs |
self drawable hideTip.
"Detect for mutation candidate"
morphs := self context curvesToMutatePointIntoNear: aPoint.
morphs size = 1 ifTrue: [
self context domain
mutate: self mathItem
asFreeOn: morphs first mathItem
at: (self drawable gridWorldPoint: aPoint)].
morphs size > 1 ifTrue: [
self context domain
mutate: self mathItem
asIntersectionWith: morphs first mathItem
and: morphs second mathItem
at: (self drawable gridWorldPoint: aPoint)].
self presenter saved: false.
self switchState: DrGSelectToolStateNeutral.
self context reset
! !
!DrGMutatorToolStateDragged methodsFor: 'accessing'!
context: aContext
super context: aContext.
originalPointClass _ context mathItem class.! !
!DrGSelectToolStateDraggedBitmap methodsFor: 'accessing' stamp: 'hlsf 4/11/2021 12:46:23'!
context: aContext
super context: aContext.
draggedCorner _ self context morph isAnyCornerIn: self context start.! !
!DrGSelectToolStateDraggedBitmap methodsFor: 'handling' stamp: 'hlsf 6/19/2021 09:35:00'!
handleMouseAt: aPoint
| processSomething |
draggedCorner
ifNil: [processSomething _ super handleMouseAt: aPoint]
ifNotNil: [self magnifyBitmap: aPoint.
processSomething _ true].
^ processSomething
! !
!DrGSelectToolStateDraggedBitmap methodsFor: 'handling' stamp: 'hlsf 4/11/2021 12:46:23'!
magnifyBitmap: aPoint
| displacement unitVector image factor griddedPoint |
griddedPoint _ self context gridPoint: aPoint.
displacement _ griddedPoint - self context start.
image _ self context morph morph.
draggedCorner = #topLeft ifTrue: [
corner ifNil: [corner _ image position].
[unitVector _ (image center - corner) normalized] on: ZeroDivide do: [unitVector := 0@0]].
draggedCorner =#bottomRight ifTrue: [
corner ifNil: [corner _ image position].
[unitVector _ (corner - image center) normalized] on: ZeroDivide do: [unitVector := 0@0]].
draggedCorner = #topRight ifTrue: [
corner ifNil: [corner _ image topRight].
[unitVector _ (image center - corner) normalized] on: ZeroDivide do: [unitVector := 0@0]].
draggedCorner = #bottomLeft ifTrue: [
corner ifNil: [corner _ image topRight].
[unitVector _ (corner - image center) normalized] on: ZeroDivide do: [unitVector := 0@0]].
factor _ (displacement dotProduct: unitVector) / (corner dist: image center).
factor > 1 ifTrue: [factor _ 0.9].
originalMagnifyBy ifNil: [originalMagnifyBy _ self context mathItem magnifyBy].
self context mathItem magnifyBy: (1 - factor) * originalMagnifyBy.
self context domain updateAllMathItems.
self context last: griddedPoint.! !
!DrGSelectToolStateGrabbed methodsFor: 'handling' stamp: 'hlsf 6/19/2021 10:07:28'!
handleMouseAt: aPoint
"The user is moving, switch to dragging state"
self context
start: aPoint;
last: aPoint.
self context morph isBitmap
ifTrue: [self switchState: DrGSelectToolStateDraggedBitmap]
ifFalse: [self drawable dottedLinesToParentsOf: self mathItem.
self switchState: DrGSelectToolStateDragged].
^ true! !
!DrGSelectToolStateGrabbed methodsFor: 'handling'!
handleRelease: aPoint
self switchState: DrGSelectToolStateNeutral.
self context reset.
self context factory rehash. "After move event rehash the the free positionnable item"! !
!DrGSelectToolStateGrabbed methodsFor: 'handling'!
handleStillPress: aPoint
"The user keeps pressing without moving, he wants a clone"
self context
start: aPoint;
last: aPoint.
self context builder
add: {self context mathItem}
at: aPoint.! !
!DrGMutatorToolStateGrabbed methodsFor: 'handling'!
handleMouseAt: aPoint
"The user is moving, detach the point as a free point and switch to dragging state"
|griddedPoint|
self switchState: DrGMutatorToolStateDragged.
griddedPoint _ self context gridPoint: aPoint.
self context
start: griddedPoint;
last: griddedPoint.
self context domain mutateAsFreePoint: self mathItem.
^ true
! !
!DrGSelectToolStateNeutral methodsFor: 'handling' stamp: 'hlsf 6/21/2021 21:26:29'!
handleMouseAt: aPoint
| processSomething |
(processSomething _ super handleMouseAt: aPoint)
ifTrue: [ Cursor webLinkCursor activateCursor]
ifFalse: [Cursor normalCursorWithMask activateCursor].
^ processSomething ! !
!DrGSelectToolStateNeutral methodsFor: 'handling' stamp: 'hlsf 6/23/2021 15:39:01'!
handlePress: aPoint
| morphs griddedPoint|
self drawable hideTip.
griddedPoint _ self context gridPoint: aPoint.
morphs _ self context relevantMorphsNear: aPoint.
morphs size = 1
ifTrue:
[self context last: griddedPoint.
self context morph: morphs first.
self context updateDirtyItemsList.
self switchState: DrGSelectToolStateGrabbed.
^true].
"More than one math item under mouse"
morphs size > 1
ifTrue:
[self context last: griddedPoint.
self context chooseMorph: morphs.
^true].
"The user clicked in the background, clear the selection"
self context reset.
^false! !
!DrGSelectToolStateNeutral methodsFor: 'handling' stamp: 'hlsf 6/19/2021 10:07:28'!
handlePressShiftKey: aPoint
| morphs griddedPoint|
self drawable hideTip.
griddedPoint _ self context gridPoint: aPoint.
morphs _ self context mutableMorphsAt: aPoint.
morphs size = 1
ifTrue:
[self context last: griddedPoint.
self context morph: morphs first.
self context updateDirtyItemsList.
self switchState: DrGMutatorToolStateGrabbed.
^true].
"More than one math item under mouse"
morphs size > 1
ifTrue:
[self context last: griddedPoint.
(self context chooseMorph: morphs)
ifTrue: [self switchState: DrGMutatorToolStateSelected].
^true].
"The user clicked in the background, clear the selection"
self context reset.
^false! !
!DrGSelectToolStateNeutral methodsFor: 'handling' stamp: 'hlsf 6/19/2021 10:07:28'!
handleShiftKeyMouseAt: aPoint
"Let's inform about the mutate mode"
| morphs aTip |
morphs _ self context mutableMorphsAt: aPoint.
morphs ifEmpty: [
aTip _ 'Pressing down the [Shift] key you can drag and change the nature of free point or intersection point.' translated].
morphs size = 1 ifTrue: [
aTip _ 'Drag this point to change its nature.' translated].
morphs size > 1 ifTrue: [
aTip _ 'Several objects can be selected. Please, select one clicking the mouse.' translated. ].
self drawable tip: aTip at: aPoint.
^ aTip notNil! !
!DrGSelectToolStateNeutral methodsFor: 'testing'!
isSelectNeutral
^ true! !
!DrGSelectToolStateSelected methodsFor: 'handling' stamp: 'hlsf 6/23/2021 15:39:01'!
handleMouseAt: aPoint
| morphs |
morphs _ self context relevantMorphsNear: aPoint.
^ (morphs includes: self context morph)
ifTrue:
[self drawable tip: self mathItem descriptiveName at: aPoint.
true]
ifFalse:
[self drawable hideTip.
false]! !
!DrGSelectToolStateSelected methodsFor: 'handling' stamp: 'hlsf 6/23/2021 15:39:01'!
handlePress: aPoint
self drawable hideTip.
((self context relevantMorphsNear: aPoint) includes: self context morph)
ifTrue: [
self context updateDirtyItemsList.
self switchState: DrGSelectToolStateGrabbed.
^true]
ifFalse: [
self context reset.
^false]! !
!DrGMutatorToolStateSelected methodsFor: 'handling' stamp: 'hlsf 6/23/2021 15:39:01'!
handlePress: aPoint
self drawable hideTip.
((self context relevantMorphsNear: aPoint) includes: self context morph)
ifTrue: [
self context updateDirtyItemsList.
self switchState: DrGMutatorToolStateGrabbed.
^true]
ifFalse: [
self context reset.
^false]! !
!DrGStyleToolState methodsFor: 'as yet unclassified' stamp: 'hlsf 4/11/2021 12:52:56'!
morphStyle
^ self context morphStyle! !
!DrGStyleToolState methodsFor: 'handling' stamp: 'hlsf 2/13/2022 11:25:34'!
handleChoice: aMorphCollection
aMorphCollection
ifNotEmpty:
[self context morph: aMorphCollection first.
context presenter controlsManager stylerFor: self morphStyle]
ifEmpty: [self context reset]! !
!DrGStyleToolState methodsFor: 'handling' stamp: 'hlsf 6/23/2021 15:39:01'!
handlePress: aPoint
|costumes|
self drawable hideTip.
costumes _ self context relevantMorphsNear: aPoint.
costumes size = 1 ifTrue:
[self context last: aPoint.
self handleChoice: costumes.
^true].
"More than one math item under mouse"
costumes size > 1 ifTrue:
[self context last: aPoint.
self context chooseMorph: costumes.
^true].
"The user clicked in the background, clear the selection"
self context reset.
^false! !
!DrGAnimateToolState methodsFor: 'handling' stamp: 'hlsf 4/11/2021 13:53:04'!
handleChoice: aMorphCollection
aMorphCollection
ifNotEmpty: [
self stopAnimating.
self context morph: aMorphCollection first.
self switchState: DrGAnimateToolStateSelected.
self context state startAnimating.
^ true]
ifEmpty: [
self context reset.
^ false]! !
!DrGAnimateToolState methodsFor: 'testing'!
isAnimating
^ false! !
!DrGAnimateToolState methodsFor: 'accessing'!
animateStep
^ self context animateStep ! !
!DrGAnimateToolState methodsFor: 'accessing'!
mathItem
^ self context mathItem ! !
!DrGAnimateToolState methodsFor: 'animate'!
animate
self shouldNotImplement! !
!DrGAnimateToolState methodsFor: 'animate'!
stopAnimating
"we are not animating in this state, do nothing"! !
!DrGAnimateToolStateSelected methodsFor: 'animate'!
animate
| a |
a _ self mathItem abscissa + self animateStep.
a > 1.0 ifTrue: [a _ 0].
self mathItem abscissa: a.
self context domain updateAllMathItems ! !
!DrGAnimateToolStateSelected methodsFor: 'animate' stamp: 'hlsf 6/19/2021 10:07:28'!
startAnimating
abscissa _ self mathItem abscissa.
self drawable arrangeToStartStepping.! !
!DrGAnimateToolStateSelected methodsFor: 'animate' stamp: 'hlsf 6/19/2021 10:07:28'!
stopAnimating
self drawable stopStepping.
self mathItem abscissa: abscissa.
self context domain updateAllMathItems! !
!DrGAnimateToolStateSelected methodsFor: 'accessing' stamp: 'hlsf 6/19/2021 10:07:28'!
context: aContext
super context: aContext.
self drawable arrangeToStartStepping.! !
!DrGAnimateToolStateSelected methodsFor: 'testing'!
isAnimating
^ true! !
!DrGDeleteToolState methodsFor: 'handling' stamp: 'hlsf 4/11/2021 14:02:01'!
handleChoice: aMorphCollection
aMorphCollection ifNotEmpty:
[self context presenter
deleteMathItem: aMorphCollection first;
selectToolAfterBuilding].
self context reset! !
!DrGPropertyToolState methodsFor: 'handling' stamp: 'hlsf 3/19/2022 16:27:21'!
handleChoice: aMorphCollection
aMorphCollection
ifNotEmpty:
[self context morph: aMorphCollection first.
context presenter controlsManager propertyFor: context mathItem]
! !
!DrGCommand methodsFor: 'command'!
execute
self subclassResponsibility ! !
!DrGCommand methodsFor: 'command'!
unexecute
self subclassResponsibility ! !
!DrGCommand methodsFor: 'accessing'!
domain: aDomain
domain _ aDomain.! !
!DrGCommand methodsFor: 'as yet unclassified' stamp: 'hlsf 5/2/2020 00:06:31'!
release
"Let my child do some clean up"! !
!DrGCompositeCommand methodsFor: 'as yet unclassified'!
compileComposite: theMathItems
mathItems _ theMathItems.
compositeItem _ DrGCompositeItem newWith: theMathItems.! !
!DrGCompositeCommand methodsFor: 'as yet unclassified'!
execute
domain triggerEvent: #groupCostumes with: compositeItem.! !
!DrGCompositeCommand methodsFor: 'as yet unclassified' stamp: 'hlsf 4/29/2020 23:55:00'!
release
compositeItem release.
! !
!DrGCompositeCommand methodsFor: 'as yet unclassified'!
unexecute
domain triggerEvent: #ungroupCostumes with: compositeItem.! !
!DrGCompositeCommand class methodsFor: 'as yet unclassified'!
with: theMathItems in: aDomain
^self new
domain: aDomain ;
compileComposite: theMathItems! !
!DrGDeleteCommand methodsFor: 'as yet unclassified'!
deleteMathItem: aMathItem
mathItems _ domain factory orderedDependentMathItem: aMathItem.! !
!DrGDeleteCommand methodsFor: 'as yet unclassified' stamp: 'hlsf 4/29/2020 23:55:22'!
release
mathItems do: [:m | m release].! !
!DrGDeleteCommand methodsFor: 'command' stamp: 'hlsf 2/10/2022 10:17:17'!
execute
domain factory
remove: mathItems! !
!DrGDeleteCommand methodsFor: 'command' stamp: 'hlsf 2/10/2022 10:05:42'!
unexecute
mathItems do: [:aMathItem|
domain factory add: aMathItem.
domain triggerEvent: #redoMathItem with: aMathItem].
domain factory changed: #pool
! !
!DrGDeleteCommand class methodsFor: 'as yet unclassified'!
for: aMathItem in: aDomain
^self new
domain: aDomain;
deleteMathItem: aMathItem.! !
!DrGMathItemCommand methodsFor: 'accessing' stamp: 'hlsf 3/9/2023 17:24:03'!
createMathItem: aBuilder
mathItems _ aBuilder getItem.
mathItems do: [:each | domain autoname: each]
! !
!DrGMathItemCommand methodsFor: 'accessing'!
fromMathItem: aMathItem
mathItems _ {aMathItem}.
! !
!DrGMathItemCommand methodsFor: 'dependents access' stamp: 'hlsf 4/29/2020 23:56:37'!
release
mathItems do: [:m | m release]! !
!DrGMathItemCommand methodsFor: 'command' stamp: 'hlsf 2/10/2022 10:16:35'!
execute
"Remove any previous dependant"
mathItems do: [:aMathItem|
"record the mathItem in the factory"
domain factory add: aMathItem.
domain triggerEvent: #redoMathItem with: aMathItem].
^mathItems! !
!DrGMathItemCommand methodsFor: 'command' stamp: 'hlsf 2/10/2022 10:16:41'!
unexecute
"remove the mathItem in the factory"
domain factory
remove: mathItems! !
!DrGMathItemCommand class methodsFor: 'as yet unclassified'!
for: aMathItem in: aDomain
^self new
domain: aDomain;
fromMathItem: aMathItem .! !
!DrGMathItemCommand class methodsFor: 'as yet unclassified'!
with: aBuilder in: aDomain
^self new
domain: aDomain;
createMathItem: aBuilder.! !
!DrGMergeCommand methodsFor: 'command'!
execute
"replace mathItem as target in the parent item"
directChildren do: [:array |
array first parents
at: array second
put: target].
domain factory remove: {mathItem}.
domain updateAllMathItems.! !
!DrGMergeCommand methodsFor: 'command'!
unexecute
"unmerge target and mathItem"
domain factory add: mathItem beforeIndex: mathItemIndex.
domain triggerEvent: #redoMathItem with: mathItem.
directChildren do: [:array |
array first parents
at: array second
put: mathItem].
domain updateAllMathItems.! !
!DrGMergeCommand methodsFor: 'initialize-release'!
merge: aMathItem with: aTarget
|children|
mathItem _ aMathItem.
target _ aTarget.
mathItemIndex _ domain factory indexOf: mathItem.
children _ domain factory directChildrenOf: mathItem.
directChildren _ OrderedCollection new.
children do:[:aChild |
directChildren add: (
Array
with: aChild
with: (aChild parents indexOf: mathItem))]! !
!DrGMergeCommand class methodsFor: 'as yet unclassified'!
merge: aMathItem with: aTarget in: aDomain
^ self new
domain: aDomain;
merge: aMathItem with: aTarget ! !
!DrGMoveCommand methodsFor: 'command' stamp: 'hlsf 2/10/2022 10:16:21'!
execute
domain moveEvent: mathItem inDirection: vector! !
!DrGMoveCommand methodsFor: 'command' stamp: 'hlsf 2/10/2022 10:16:25'!
unexecute
domain moveEvent: mathItem inDirection: vector negated! !
!DrGMoveCommand methodsFor: 'accessing'!
mathItem: aMathItem
mathItem _ aMathItem ! !
!DrGMoveCommand methodsFor: 'accessing'!
vector: aPoint
vector _ aPoint
! !
!DrGMoveCommand class methodsFor: 'as yet unclassified'!
for: aMathItem with: aPoint in: aDomain
^self new
domain: aDomain;
mathItem: aMathItem;
vector: aPoint! !
!DrGPropertyCommand methodsFor: 'accessing'!
mathItem: aMathItem
mathItem _ aMathItem ! !
!DrGPropertyCommand methodsFor: 'accessing'!
property: aProperty
property _ aProperty ! !
!DrGPropertyCommand methodsFor: 'command'!
execute
|temp|
temp _ mathItem property.
mathItem property: property.
property _ temp.
mathItem changed! !
!DrGPropertyCommand methodsFor: 'command'!
unexecute
self execute! !
!DrGPropertyCommand class methodsFor: 'as yet unclassified'!
for: aMathItem with: aProperty in: aDomain
^self new
domain: aDomain;
mathItem: aMathItem;
property: aProperty! !
!DrGCommandManager methodsFor: 'dependents access' stamp: 'hlsf 4/24/2020 12:56:20'!
release
stack contents do: [:c | c release].! !
!DrGCommandManager methodsFor: 'initialization'!
initialize
stack _ DrGCommandStack new! !
!DrGCommandManager methodsFor: 'command exec'!
buildCommandFor: aMathItem
|command|
command _ stack nextPut: (DrGMathItemCommand for: aMathItem in: domain).
^command execute! !
!DrGCommandManager methodsFor: 'command exec'!
buildCommandWith: aBuilder
|command|
command _ stack nextPut: (DrGMathItemCommand with: aBuilder in: domain).
^command execute! !
!DrGCommandManager methodsFor: 'command exec'!
compositeCommandFor: aMathItemSelection
|command|
command _ stack nextPut: (DrGCompositeCommand with: aMathItemSelection in: domain).
command execute.! !
!DrGCommandManager methodsFor: 'command exec'!
deleteCommandFor: aMathItem
|command|
command _ stack nextPut: (DrGDeleteCommand for: aMathItem in: domain).
command execute! !
!DrGCommandManager methodsFor: 'command exec'!
mergeCommandFor: aMathItem with: aTarget
"create a merge command"
|command|
command _ stack nextPut: (DrGMergeCommand merge: aMathItem with: aTarget in: domain).
command execute! !
!DrGCommandManager methodsFor: 'command exec'!
moveCommandFor: aMathItem with: aPoint
stack nextPut: (DrGMoveCommand for: aMathItem with: aPoint in: domain).! !
!DrGCommandManager methodsFor: 'command exec'!
propertyCommandFor: aMathItem with: aProperty
|command|
command _ stack nextPut: (DrGPropertyCommand for: aMathItem with: aProperty in: domain).
command execute! !
!DrGCommandManager methodsFor: 'command exec'!
redo
|command|
command _ stack next.
command ifNotNil: [command execute]! !
!DrGCommandManager methodsFor: 'command exec'!
undo
|command|
command _ stack previous.
command ifNotNil: [command unexecute]! !
!DrGCommandManager methodsFor: 'accessing'!
domain: aDomain
domain _ aDomain! !
!DrGFactory methodsFor: 'accessing' stamp: 'hlsf 2/10/2022 10:03:01'!
add: item
self last: item.
pool addLast: item.
^ item! !
!DrGFactory methodsFor: 'accessing' stamp: 'hlsf 2/10/2022 10:04:11'!
add: anObject beforeIndex: index
^ pool add: anObject beforeIndex: index! !
!DrGFactory methodsFor: 'accessing'!
at: integer
^ self pool at: integer ifAbsent: [nil]! !
!DrGFactory methodsFor: 'accessing'!
findInPool: item
"Try to find a twin of this mathItem, if so return the twin, otherwise nil"
^ self at: (self indexOf: item)! !
!DrGFactory methodsFor: 'accessing'!
indexOf: anItem
^ self indexOf: anItem in: pool! !
!DrGFactory methodsFor: 'accessing'!
indexOf: anItem in: aPool
"No identity equality but hashed value to detect duplicated object we must consider as equal"
^ anItem
ifNil: [0]
ifNotNil: [aPool findFirst: [ :each |
each hash = anItem hash
and: ["double check when hash is equal (can be a collision)"
each = anItem ]
]
]! !
!DrGFactory methodsFor: 'accessing'!
last
^last! !
!DrGFactory methodsFor: 'accessing'!
last: item
"push item as the last instantiated item in the pool, purelly artificial however
as the items order in the pool is not changed"
last _ item! !
!DrGFactory methodsFor: 'accessing'!
pool
^pool ! !
!DrGFactory methodsFor: 'accessing'!
subPool: item
"The items comming after me in the pool"
^ self subPool: item from: pool! !
!DrGFactory methodsFor: 'accessing'!
subPool: item from: aPool
"The items comming after me in aPool"
^ aPool allButFirst: (self indexOf: item in: aPool)! !
!DrGFactory methodsFor: 'removing' stamp: 'hlsf 2/10/2022 09:03:23'!
purge
pool do: [ :aMathItem | aMathItem release].
pool _ OrderedCollection new.
self changed: #pool! !
!DrGFactory methodsFor: 'removing' stamp: 'hlsf 5/25/2023 18:59:55'!
remove: itemCollection
pool := pool copyWithoutAll: itemCollection.
itemCollection do: [ :aMathItem | aMathItem release ].
self flag: #drgeoEvent! !
!DrGFactory methodsFor: 'removing' stamp: 'hlsf 2/10/2022 10:05:07'!
removeAt: index
| item |
item _ self at: index.
last = item ifTrue: [last _ nil].
pool removeAt: index! !
!DrGFactory methodsFor: 'enumerating'!
from: item do: aBlock
(self indexOf: item)
to: pool size
do: [:index | aBlock value: (pool at: index)]! !
!DrGFactory methodsFor: 'initialize-release'!
initialize
super initialize.
pool _ OrderedCollection new.
! !
!DrGFactory methodsFor: 'initialize-release' stamp: 'hlsf 4/24/2020 12:56:14'!
release
pool do: [ :item | item release].! !
!DrGFactory methodsFor: 'updating'!
pushAsLastWhenInPool: anItem
"if this item has a twin in the pool, push as last this last one and
return true, otherwise return false"
^ (self findInPool: anItem)
ifNotNil: [ :item |
self last: item.
true ]
ifNil: [ false ]! !
!DrGFactory methodsFor: 'testing'!
is: item1 before: item2
^ (self indexOf: item1) < (self indexOf: item2)! !
!DrGFactory methodsFor: 'testing'!
isAnyInPool: itemList
^itemList anySatisfy: [:item | (self findInPool: item) isNil not].! !
!DrGFactory methodsFor: 'testing'!
isInPool: item
^ (self findInPool: item) isNil not! !
!DrGMacroFactory methodsFor: 'accessing'!
addUnique: aMacro
^ (self findInPool: aMacro)
ifNil: [self add: aMacro].! !
!DrGMacroFactory methodsFor: 'accessing'!
titles
^ self pool collect: [:m | m title]! !
!DrGMacroFactory class methodsFor: 'as yet unclassified'!
purge
"self purge"
self new purge! !
!DrGMacroFactory class methodsFor: 'instance creation'!
new
^ uniqueInstance ifNil: [uniqueInstance _ super new]! !
!DrGMathItemFactory methodsFor: 'testing'!
is: item parentWithTest: testSelector
self from: item do: [:aChild |
((aChild perform: testSelector)
and: [aChild parents includes: item]) ifTrue: [^ true]].
^ false! !
!DrGMathItemFactory methodsFor: 'accessing'!
childrenOf: mathItemIndex
|children directChildren|
directChildren _ OrderedCollection withAll: (self directChildrenOf: mathItemIndex).
children _ Set new addAll: directChildren; yourself.
directChildren do: [:childIndex | children addAll: (self childrenOf: childIndex)].
^ children! !
!DrGMathItemFactory methodsFor: 'accessing'!
dependentMathItem: theMathItem
"Return a collection of the dependents items of theMathItem,
Caution: it is not following the creation order, further traitment is need for that"
^ self dependentMathItem: theMathItem in: (self subPool: theMathItem )! !
!DrGMathItemFactory methodsFor: 'accessing' stamp: 'hlsf 6/20/2021 10:32:58'!
dependentMathItem: dependentItem in: subPool
"Return a collection of the dependents items of theMathItem in a subpool"
| dependents |
dependents _ IdentitySet with: dependentItem.
subPool do: [:aMathItem |
(aMathItem parentsIncludes: dependentItem) ifTrue:
[dependents addAll:
(self dependentMathItem: aMathItem in: (self subPool: aMathItem from: subPool))]].
^ dependents! !
!DrGMathItemFactory methodsFor: 'accessing'!
directChildrenOf: parent
"return the collection of my direct child"
^ pool select: [:item| | parents|
parents _ item parents.
parents notNil and: [(parents anySatisfy: [:aParent | aParent = parent])]].
! !
!DrGMathItemFactory methodsFor: 'accessing'!
findInPoolById: anID
"Try to find an item given its unique ID, it used to load Dr. Geo 1.1 file"
^ pool detect: [:each | each id = anID ]
! !
!DrGMathItemFactory methodsFor: 'accessing'!
moveableParentsOf: theMathItem in: parents
"Return a collection of the parents items of theMathItem, sensidble to reverse dragging
Caution: we may have duplicated item"
| safeParents areParentsMoveable |
safeParents _ theMathItem parents.
theMathItem parents: #().
areParentsMoveable _ theMathItem moveParent: 0@0.
theMathItem parents: safeParents.
areParentsMoveable ifTrue: [
(parents addAll: safeParents) do: [:aParent |
self moveableParentsOf: aParent in: parents]].
! !
!DrGMathItemFactory methodsFor: 'accessing'!
ordered: aMathItemCollection
"sort the the math item according to the pool order"
^ pool select: [:item | aMathItemCollection includes: item]! !
!DrGMathItemFactory methodsFor: 'accessing'!
orderedDependentMathItem: aMathItem
^self ordered: (self dependentMathItem: aMathItem )! !
!DrGMathItemFactory methodsFor: 'updating'!
rehash
pool do: [:mathIten | mathIten rehash]! !
!DrGMathItemFactory methodsFor: 'updating' stamp: 'hlsf 5/4/2020 21:28:54'!
updateAllMathItems
"stupidly update all math item"
pool
do: [:aMathItem | aMathItem update]! !
!DrGMathItemFactory methodsFor: 'updating'!
updateAllMathItemsButLocus
"stupidly update all math item but the loci ones"
pool
do: [:aMathItem | aMathItem isLocusItem not ifTrue: [ aMathItem update]]! !
!DrGMathItemFactory methodsFor: 'updating'!
updateAllMathItemsButLocusFrom: startIndex to: endIndex
"stupidly update math item in the given range"
pool
from: startIndex
to: endIndex
do: [:aMathItem | aMathItem isLocusItem not
ifTrue: [aMathItem update]]! !
!DrGMathItemFactory methodsFor: 'updating'!
updateDirtyMathItems: aCollection
"update the collection"
aCollection
do: [:aMathItem | aMathItem update]! !
!DrGSvgCanvas methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 17:47:51'!
drawable
^presenter drawable ! !
!DrGSvgCanvas methodsFor: 'accessing' stamp: 'hlsf 3/18/2023 15:28:18'!
engine
"In case the Morph uses directly the VectorGraphics engine.
We are our own engine, there is no such things as a SVG engine"
^ self! !
!DrGSvgCanvas methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 17:48:33'!
presenter: aPresenter
presenter := aPresenter ! !
!DrGSvgCanvas methodsFor: 'accessing' stamp: 'hlsf 3/18/2023 10:14:12'!
topNode: xmlNode
svgTree := xmlNode ! !
!DrGSvgCanvas methodsFor: 'path' stamp: 'hlsf 3/18/2023 15:30:10'!
fillColor: fillColor do: pathCommandsBlock
self pathStrokeWidth: nil color: nil fillColor: fillColor.
self doPath: pathCommandsBlock ensureClosePath: true! !
!DrGSvgCanvas methodsFor: 'path' stamp: 'hlsf 3/18/2023 16:55:17'!
strokeWidth: strokeWidth color: strokeColor do: pathCommandsBlock
self pathStrokeWidth: strokeWidth color: strokeColor fillColor: nil.
self doPath: pathCommandsBlock ensureClosePath: false! !
!DrGSvgCanvas methodsFor: 'path' stamp: 'hlsf 3/18/2023 15:30:10'!
strokeWidth: strokeWidth color: strokeColor fillColor: fillColor do: pathCommandsBlock
self pathStrokeWidth: strokeWidth color: strokeColor fillColor: fillColor.
self doPath: pathCommandsBlock ensureClosePath: true! !
!DrGSvgCanvas methodsFor: 'path' stamp: 'hlsf 5/31/2023 19:49:40'!
strokeWidth: strokeWidth color: strokeColor strokeDashArray: sda strokeDashArrayOffset: sdao do: pathCommandsBlock
self pathStrokeWidth: strokeWidth color: strokeColor strokeDashArray: sda strokeDashArrayOffset: sdao fillColor: nil.
self doPath: pathCommandsBlock ensureClosePath: false! !
!DrGSvgCanvas methodsFor: 'drawing' stamp: 'hlsf 3/18/2023 16:03:56'!
arcTo: point radius: radius angleOfXAxis: theta largeFlag: doLargerArc sweepFlag: useIncreasingAngles
self addPathCommands: ( String streamContents: [:str |
str nextPutAll: 'A ';
nextPutAll: radius asPoint printMini; nextPut: Character space;
nextPutAll: theta asString; nextPut: Character space;
nextPutAll: (doLargerArc ifTrue: ['1 '] ifFalse: ['0 ']);
nextPutAll: (useIncreasingAngles ifTrue: ['1 '] ifFalse: ['0 ']);
nextPutAll: point printMini ]).
currentPoint := point! !
!DrGSvgCanvas methodsFor: 'drawing' stamp: 'hlsf 3/18/2023 15:29:10'!
circleCenter: c radius: r
pathNode ifNil: [^ self]. "This method must be called in the context of a xxxxx:do: method"
pathNode name: #circle.
pathNode attributeAt: #cx put: c x asString.
pathNode attributeAt: #cy put: c y asString.
pathNode attributeAt: #r put: r asString.! !
!DrGSvgCanvas methodsFor: 'drawing' stamp: 'hlsf 3/18/2023 11:01:54'!
drawString: s at: pt font: fontOrNil color: aColor
| text fontSize zoom |
zoom := 1.4.
fontSize := fontOrNil ifNil: [10] ifNotNil: [fontOrNil pointSize].
text := XMLElement
named: #text
attributes: {
#x -> pt x asString . #y -> (pt y + fontSize + 1) asString .
#'font-size' -> (fontSize * zoom) asString .
#fill -> aColor hexHtml } asDictionary.
text addContent: (XMLStringNode string: s).
svgTree addElement: text
! !
!DrGSvgCanvas methodsFor: 'drawing' stamp: 'hlsf 3/18/2023 19:39:23'!
drawTextComposition: aTextComposition at: aPoint extent: anEextent color: c selectionColor: sc
self
drawString: aTextComposition textComposed asString
at: aPoint
font: aTextComposition defaultFont
color: c! !
!DrGSvgCanvas methodsFor: 'drawing' stamp: 'hlsf 3/18/2023 19:21:23'!
ellipseCenter: center radius: radius borderWidth: bw borderColor: bc fillColor: fillColor
| ellipse |
ellipse := XMLElement
named: #ellipse
attributes: {
#cx -> center x asString . #cy -> center y asString .
#rx -> radius asPoint x asString . #ry -> radius asPoint y asString} asDictionary.
self styleOf: ellipse StrokeWidth: bw color: bc fillColor: fillColor.
svgTree addElement: ellipse ! !
!DrGSvgCanvas methodsFor: 'drawing' stamp: 'hlsf 3/18/2023 19:16:46'!
fillRectangle: rect color: fillColor
| rectNode |
rectNode := self rectangle: rect.
self styleOf: rectNode StrokeWidth: nil color: nil fillColor: fillColor.
svgTree addElement: rectNode! !
!DrGSvgCanvas methodsFor: 'drawing' stamp: 'hlsf 5/25/2023 19:21:05'!
fillRectangle: aRectangle color: fillColor borderWidth: bw borderStyleSymbol: aSymbol baseColorForBorder: bc
| rect |
rect := self rectangle: aRectangle .
self styleOf: rect StrokeWidth: bw color: bc fillColor: fillColor.
svgTree addElement: rect! !
!DrGSvgCanvas methodsFor: 'drawing' stamp: 'hlsf 3/18/2023 19:21:49'!
frameRectangle: aRectangle color: bc borderWidth: bw borderStyleSymbol: aSymbol
| rect |
rect := self rectangle: aRectangle.
self styleOf: rect StrokeWidth: bw color: bc fillColor: nil.
svgTree addElement: rect! !
!DrGSvgCanvas methodsFor: 'drawing' stamp: 'hlsf 11/7/2023 20:19:32'!
line: pt1 to: pt2 width: w color: c
| line |
line := XMLElement
named: #line
attributes: {
#x1 -> pt1 x asString . #y1 -> pt1 y asString .
#x2 -> pt2 x asString . #y2 -> pt2 y asString .
#'stroke-width' -> w asString. #stroke -> c hexHtml .
#'stroke-linecap' -> 'round' } asDictionary.
svgTree addElement: line
! !
!DrGSvgCanvas methodsFor: 'drawing' stamp: 'hlsf 3/18/2023 16:43:29'!
lineTo: point
firstPoint ifNil: [^ self].
self addPathCommands: 'L ', point printMini.
currentPoint := point ! !
!DrGSvgCanvas methodsFor: 'drawing' stamp: 'hlsf 3/18/2023 15:52:42'!
moveTo: point
firstPoint ifNil: [firstPoint := point].
self addPathCommands: 'M ', point printMini.
currentPoint := point ! !
!DrGSvgCanvas methodsFor: 'drawing' stamp: 'hlsf 3/18/2023 16:27:03'!
polyLine: vertices
| coordinates |
pathNode name: #polyline.
firstPoint := vertices first. "In case we need to close the polyline"
coordinates := String streamContents: [:str |
vertices do: [:point | point printCoupleOn: str] separatedBy: [str nextPut: Character space] ].
pathNode attributeAt: #points put: coordinates
! !
!DrGSvgCanvas methodsFor: 'rendering' stamp: 'hlsf 8/4/2023 17:48:04'!
renderAxes
self drawable axesVisible ifTrue: [self drawable drawAxesOn: self]! !
!DrGSvgCanvas methodsFor: 'rendering' stamp: 'hlsf 8/4/2023 17:48:11'!
renderGrid
self drawable gridVisible ifTrue: [self drawable drawGridOn: self]! !
!DrGSvgCanvas methodsFor: 'rendering' stamp: 'hlsf 3/16/2023 21:27:03'!
renderLabelOf: aMorph
aMorph labelMorph ifNotNil: [
self drawString: aMorph mathItem name
at: aMorph labelPosition
font: DrGeoSystem canvasFont
color: Color black]! !
!DrGSvgCanvas methodsFor: 'private' stamp: 'hlsf 3/18/2023 16:36:21'!
add: addArg toAttribute: symbol
"
Append the arguments (addArg) to the existing ones of the current pathNode
"
| prevArg newArg |
prevArg := pathNode attributeAt: symbol ifAbsent: [''].
newArg := String streamContents: [:str |
str nextPutAll: prevArg ;
nextPut: Character space;
nextPutAll: addArg ].
pathNode attributeAt: symbol put: newArg .
^ addArg
! !
!DrGSvgCanvas methodsFor: 'private' stamp: 'hlsf 3/18/2023 16:24:26'!
addPathCommands: cmds
"
Append the commands (cmds) to the existing ones of the current pathNode
"
^ self add: cmds toAttribute: #d
! !
!DrGSvgCanvas methodsFor: 'private' stamp: 'hlsf 3/18/2023 11:32:23'!
doPath: pathCommandsBlock ensureClosePath: ensureClosePath
"Evaluate a sequence of path commands"
self initializePath.
pathCommandsBlock valueWithPossibleArgument:self.
self finalizePath: ensureClosePath! !
!DrGSvgCanvas methodsFor: 'private' stamp: 'hlsf 3/18/2023 16:36:30'!
finalizePath: ensureClosePath
ensureClosePath ifTrue: [
pathNode name caseOf: {
[#path] -> [ self lineTo: firstPoint] .
[#polyline] -> [self add: firstPoint printCouple toAttribute: #points]
} otherwise: []].
svgTree addElement: pathNode.
pathNode := nil! !
!DrGSvgCanvas methodsFor: 'private' stamp: 'hlsf 3/18/2023 10:31:46'!
initializePath
"Perform any initialization needed before starting a Path"
firstPoint := nil.
currentPoint := `0.0@0.0`.
! !
!DrGSvgCanvas methodsFor: 'private' stamp: 'hlsf 5/31/2023 19:46:06'!
pathStrokeWidth: strokeWidth color: strokeColor fillColor: fillColor
self pathStrokeWidth: strokeWidth color: strokeColor
strokeDashArray: nil strokeDashArrayOffset: nil fillColor: fillColor ! !
!DrGSvgCanvas methodsFor: 'private' stamp: 'hlsf 5/31/2023 19:45:35'!
pathStrokeWidth: strokeWidth color: strokeColor strokeDashArray: sda strokeDashArrayOffset: sdao fillColor: fillColor
pathNode := XMLElement named: #path.
self styleOf: pathNode StrokeWidth: strokeWidth color: strokeColor strokeDashArray: sda strokeDashArrayOffset: sdao fillColor: fillColor.
^ pathNode
! !
!DrGSvgCanvas methodsFor: 'private' stamp: 'hlsf 3/18/2023 19:15:59'!
rectangle: rect
| rectNode |
rectNode := XMLElement
named: #rect
attributes: {
#x -> rect topLeft x asString . #y -> rect topLeft y asString .
#width -> rect width asString . #height -> rect height asString } asDictionary.
^ rectNode! !
!DrGSvgCanvas methodsFor: 'private' stamp: 'hlsf 5/31/2023 19:44:29'!
styleOf: element StrokeWidth: strokeWidth color: strokeColor fillColor: fillColor
self styleOf: element StrokeWidth: strokeWidth color: strokeColor
strokeDashArray: nil strokeDashArrayOffset: nil fillColor: fillColor ! !
!DrGSvgCanvas methodsFor: 'private' stamp: 'hlsf 11/7/2023 20:59:19'!
styleOf: element StrokeWidth: strokeWidth color: strokeColor strokeDashArray: sda strokeDashArrayOffset: sdao fillColor: fillColor
"
Apply style to a given element (node)
"
strokeWidth ifNotNil: [element attributeAt: #'stroke-width' put: strokeWidth asString].
strokeColor ifNotNil: [ element attributeAt: #stroke put:
(strokeColor isTransparent ifTrue: ['transparent'] ifFalse: strokeColor hexHtml)].
sda ifNotNil: [
element
attributeAt: #'stroke-dasharray'
put: (String streamContents: [:s | sda do: [:e | s store: e] separatedBy: [ s space]])].
sdao ifNotNil: [element attributeAt: #'stroke-dashoffset' put: sdao asString].
fillColor
ifNotNil: [
element attributeAt: #fill put: fillColor hexHtml.
fillColor isOpaque ifFalse: [element attributeAt: #'fill-opacity' put: fillColor alpha asString] ]
ifNil: [element attributeAt: #fill put: 'none']
! !
!DrGeoCommandLineHandler methodsFor: 'as yet unclassified'!
activate
self activateHelp ifTrue: [ ^ self].
(self hasOption: 'sketch') ifTrue: [ ^ self loadSketch: (self optionAt: 'sketch')].
(self hasOption: 'script') ifTrue: [ ^ self loadScript: (self optionAt: 'script')].
self printHelp.
self exitFailure: 'Wrong arguments'.! !
!DrGeoCommandLineHandler methodsFor: 'as yet unclassified'!
checkForFile: aString
aString asFileReference exists
ifFalse: [ ^ self exitFailure: aString, ' does not exist!!' ]! !
!DrGeoCommandLineHandler methodsFor: 'as yet unclassified' stamp: 'hlsf 12/9/2022 22:12:01'!
loadScript: aString
" | workspace utfString |
utfString _ aString convertFromWithConverter: UTF8TextConverter new.
self checkForFile: utfString.
workspace _ Workspace openContents: utfString asFileReference contents.
workspace containingWindow fullscreen.
Smalltalk compiler evaluate: workspace contents"! !
!DrGeoCommandLineHandler methodsFor: 'as yet unclassified' stamp: 'hlsf 12/9/2022 22:12:09'!
loadSketch: aString
" | utfString |
utfString _ aString convertFromWithConverter: UTF8TextConverter new.
self checkForFile: utfString.
DrGeo fileFullscreen: utfString"! !
!DrGeoCommandLineHandler class methodsFor: 'accessing'!
commandName
^ 'drgeo'! !
!DrGeoCommandLineHandler class methodsFor: 'accessing'!
description
^ 'Command line for Dr. Geo'! !
!DrGeoCommandLineHandler class methodsFor: 'accessing' stamp: 'hlsf 12/9/2022 22:11:07'!
priority
" ^ STCommandLineHandler priority + 1"! !
!DrGeoXml methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 17:48:55'!
domain
^ presenter domain! !
!DrGeoXml methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 17:49:02'!
drawable
^ presenter drawable! !
!DrGeoXml methodsFor: 'accessing'!
factory
^ self domain factory! !
!DrGeoXml methodsFor: 'accessing' stamp: 'hlsf 6/19/2021 10:07:28'!
ox
^ self drawable ox! !
!DrGeoXml methodsFor: 'accessing' stamp: 'hlsf 6/19/2021 10:07:28'!
ox: aNumber
self drawable ox: aNumber! !
!DrGeoXml methodsFor: 'accessing' stamp: 'hlsf 6/19/2021 10:07:28'!
oy
^ self drawable oy! !
!DrGeoXml methodsFor: 'accessing' stamp: 'hlsf 6/19/2021 10:07:28'!
oy: aNumber
self drawable oy: aNumber! !
!DrGeoXml methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 19:52:24'!
presenter: aDrGeoPresenter
presenter := aDrGeoPresenter! !
!DrGeoXml methodsFor: 'accessing' stamp: 'hlsf 6/19/2021 10:07:28'!
scale
^ self drawable scale! !
!DrGeoXml methodsFor: 'accessing' stamp: 'hlsf 6/19/2021 10:07:28'!
setScaleTo: aNumber
self drawable setScaleTo: aNumber! !
!DrGeoXml methodsFor: 'accessing' stamp: 'hlsf 8/4/2023 17:50:55'!
view
^ presenter view! !
!DrGeoXml methodsFor: 'parse item'!
parentsById: aNode
"return a collection of the item parent given theirs id in the attribute
elements <parent id=xxx>"
|collection|
collection _ OrderedCollection new.
aNode elementsDo: [:each | (each tag = #parent) ifTrue: [collection
add: (self factory findInPoolById: (each attributeAt: 'ref') asSymbol)]].
^collection ! !
!DrGeoXml methodsFor: 'parse item'!
parseAngle3pts: aNode
^ self parseItem: aNode with: DrGAngleGeometricBuilder.! !
!DrGeoXml methodsFor: 'parse item'!
parseAngle3ptsOriented: aNode
^ self parseItem: aNode with: DrGAngleOrientedBuilder.! !
!DrGeoXml methodsFor: 'parse item'!
parseAngleVectors: aNode
^ self parseItem: aNode with: DrGAngleOrientedBuilder.
! !
!DrGeoXml methodsFor: 'parse item'!
parseArc3pts: aNode
^ self parseItem: aNode with: DrGArcBuilder.! !
!DrGeoXml methodsFor: 'parse item'!
parseArcCenterAngle: aNode
^ self parseItem: aNode with: DrGArcCenterBuilder.! !
!DrGeoXml methodsFor: 'parse item'!
parseArcCircle3pts: aNode
"Dr.Geo 1.1 compatibility"
^ self parseArc3pts: aNode! !
!DrGeoXml methodsFor: 'parse item'!
parseArcCircleReflexion: aNode
"Dr.Geo 1.1 compatibility"
^ self parseArcReflexion: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseArcCircleRotation: aNode
"Dr.Geo 1.1 compatibility"
^ self parseArcRotation: aNode! !
!DrGeoXml methodsFor: 'parse item'!
parseArcCircleScale: aNode
"Dr.Geo 1.1 compatibility"
^self parseArcHomothety: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseArcCircleSymmetry: aNode
"Dr.Geo 1.1 compatibility"
^ self parseArcSymmetry: aNode! !
!DrGeoXml methodsFor: 'parse item'!
parseArcCircleTranslation: aNode
"Dr.Geo 1.1 compatibility"
^self parseArcTranslation: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseArcHomothety: aNode
^self parseHomothety: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseArcReflexion: aNode
^ self parseReflexion: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseArcRotation: aNode
^ self parseRotation: aNode! !
!DrGeoXml methodsFor: 'parse item'!
parseArcSymmetry: aNode
^ self parseSymmetry: aNode! !
!DrGeoXml methodsFor: 'parse item'!
parseArcTranslation: aNode
^self parseTranslation: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseBitmapFree: aNode
"We do not have a builder yet for free bitmap"
^ self parseItem: aNode with: DrGBitmapBuilder
! !
!DrGeoXml methodsFor: 'parse item'!
parseCircle2pts: aNode
^ self parseItem: aNode with: DrGCircleBuilder.! !
!DrGeoXml methodsFor: 'parse item'!
parseCircleHomothety: aNode
^self parseHomothety: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseCircleRadius: aNode
^ self parseItem: aNode with: DrGCircleBuilder.! !
!DrGeoXml methodsFor: 'parse item'!
parseCircleReflexion: aNode
^ self parseReflexion: aNode! !
!DrGeoXml methodsFor: 'parse item'!
parseCircleRotation: aNode
^ self parseRotation: aNode! !
!DrGeoXml methodsFor: 'parse item'!
parseCircleScale: aNode
"Dr.Geo 1.1 compatibility"
^self parseCircleHomothety: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseCircleSegment: aNode
^ self parseItem: aNode with: DrGCircleBuilder.! !
!DrGeoXml methodsFor: 'parse item'!
parseCircleSymmetry: aNode
^ self parseSymmetry: aNode! !
!DrGeoXml methodsFor: 'parse item'!
parseCircleTranslation: aNode
^ self parseTranslation: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseCoordinates: aNode
^ self parseItem: aNode with: DrGCoordinatesBuilder.! !
!DrGeoXml methodsFor: 'parse item'!
parseEquationCircle: aNode
^ self parseCoordinates: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseEquationLine: aNode
^ self parseCoordinates: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseHalfLine2pts: aNode
"Dr.Geo 1.1 compatibility"
^self parseRay2pts: aNode! !
!DrGeoXml methodsFor: 'parse item'!
parseHalfLineReflexion: aNode
"Dr.Geo 1.1 compatibility"
^self parseRayReflexion: aNode! !
!DrGeoXml methodsFor: 'parse item'!
parseHalfLineRotation: aNode
"Dr.Geo 1.1 compatibility"
^self parseRayRotation: aNode! !
!DrGeoXml methodsFor: 'parse item'!
parseHalfLineScale: aNode
"Dr.Geo 1.1 compatibility"
^self parseRayHomothety: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseHalfLineSymmetry: aNode
"Dr.Geo 1.1 compatibility"
^self parseRaySymmetry: aNode! !
!DrGeoXml methodsFor: 'parse item'!
parseHalfLineTranslation:aNode
"Dr.Geo 1.1 compatibility"
^ self parseRayTranslation: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseHomothety: aNode
^ self parseItem: aNode with: DrGHomothetyBuilder! !
!DrGeoXml methodsFor: 'parse item' stamp: 'hlsf 8/4/2023 17:31:20'!
parseItem: aNode with: builderClass
^ self isCreatingMacro
ifFalse: [builderClass itemFrom: aNode in: presenter "an itemStatut"]
ifTrue: [builderClass basicItemFrom: aNode "an item"].
! !
!DrGeoXml methodsFor: 'parse item'!
parseLine2pts: aNode
^self parseItem: aNode with: DrGLineBuilder.! !
!DrGeoXml methodsFor: 'parse item'!
parseLineAngleBisector3pts: aNode
^ self parseItem: aNode with: DrGAngleBisectorBuilder! !
!DrGeoXml methodsFor: 'parse item'!
parseLineAngleBisector: aNode
^ self parseItem: aNode with: DrGAngleBisectorBuilder! !
!DrGeoXml methodsFor: 'parse item'!
parseLineHomothety: aNode
^self parseHomothety: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseLineParallel: aNode
^self parseItem: aNode with: DrGParallelBuilder.! !
!DrGeoXml methodsFor: 'parse item'!
parseLinePerpendicular: aNode
^ self parseItem: aNode with: DrGPerpendicularBuilder.
! !
!DrGeoXml methodsFor: 'parse item'!
parseLinePerpendicularBisector2pts: aNode
^ self parseItem: aNode with: DrGPerpendicularBisectorBuilder! !
!DrGeoXml methodsFor: 'parse item'!
parseLinePerpendicularBisector: aNode
^ self parseItem: aNode with: DrGPerpendicularBisectorBuilder! !
!DrGeoXml methodsFor: 'parse item'!
parseLineReflexion: aNode
^ self parseItem: aNode with: DrGReflectionBuilder.
! !
!DrGeoXml methodsFor: 'parse item'!
parseLineRotation: aNode
^self parseRotation: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseLineScale: aNode
"Dr.Geo 1.1 compatibility"
^self parseLineHomothety: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseLineSymmetry: aNode
^ self parseSymmetry: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseLineTranslation: aNode
^self parseTranslation: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseLocus2pts: aNode
^ self parseItem: aNode with: DrGLocusBuilder.! !
!DrGeoXml methodsFor: 'parse item'!
parseLocusHomothety: aNode
^ self parseItem: aNode with: DrGHomothetyBuilder ! !
!DrGeoXml methodsFor: 'parse item'!
parseLocusNone: aNode
"DrGeo 1.1 compatibility"
^ self parseLocus2pts: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseLocusReflexion: aNode
^ self parseReflexion: aNode! !
!DrGeoXml methodsFor: 'parse item'!
parseLocusRotation: aNode
^ self parseItem: aNode with: DrGRotationBuilder! !
!DrGeoXml methodsFor: 'parse item'!
parseLocusScale: aNode
^ self parseLocusHomothety: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseLocusSymmetry: aNode
^ self parseItem: aNode with: DrGSymmetryBuilder! !
!DrGeoXml methodsFor: 'parse item'!
parseLocusTranslation: aNode
^self parseTranslation: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseNumericArclength: aNode
"Dr.Geo 1.1 compatibility"
^ self parseValueArclength: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseNumericCircleperimeter: aNode
"Dr.Geo 1.1 compatibility"
^ self parseValueCircleperimeter: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseNumericDistance2pts: aNode
"Dr.Geo 1.1 compatibility"
^ self parseValueDistance2pts: aNode! !
!DrGeoXml methodsFor: 'parse item'!
parseNumericDistanceptline: aNode
"Dr.Geo 1.1 compatibility"
^ self parseValueDistanceptline: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseNumericSegmentlength: aNode
"Dr.Geo 1.1 compatibility"
^ self parseValueSegmentlength: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseNumericSlope: aNode
"Dr.Geo 1.1 compatibility"
^ self parseValueSlope: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseNumericValue: aNode
"Dr.Geo 1.1 compatibility"
^ self parseValueValue: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseNumericVectornorm: aNode
"Dr.Geo 1.1 compatibility"
^ self parseValueVectornorm: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parsePointBlock: aNode
self notYetImplemented.
"^ self parseItem: aNode with: DrGPointBlockBuilder."! !
!DrGeoXml methodsFor: 'parse item'!
parsePointCoordinate: aNode
^ self parseItem: aNode with: DrGPointByCoordinatesBuilder.! !
!DrGeoXml methodsFor: 'parse item'!
parsePointFree: aNode
^ self parseItem: aNode with: DrGFreePointBuilder
! !
!DrGeoXml methodsFor: 'parse item'!
parsePointHomothety: aNode
^ self parseItem: aNode with: DrGHomothetyBuilder ! !
!DrGeoXml methodsFor: 'parse item'!
parsePointIntersection: aNode
^ self parseItem: aNode with: DrGPointIntersectionBuilder! !
!DrGeoXml methodsFor: 'parse item'!
parsePointMiddle2pts: aNode
^ self parseItem: aNode with: DrGMiddleBuilder.! !
!DrGeoXml methodsFor: 'parse item'!
parsePointMiddlesegment: aNode
^self parseItem: aNode with: DrGMiddleBuilder.! !
!DrGeoXml methodsFor: 'parse item'!
parsePointOncurve: aNode
^ self parseItem: aNode with: DrGFreePointBuilder ! !
!DrGeoXml methodsFor: 'parse item'!
parsePointReflexion: aNode
^ self parseReflexion: aNode! !
!DrGeoXml methodsFor: 'parse item'!
parsePointRotation: aNode
^ self parseItem: aNode with: DrGRotationBuilder! !
!DrGeoXml methodsFor: 'parse item'!
parsePointScale: aNode
"Dr.Geo 1.1 compatibility"
^ self parsePointHomothety: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parsePointScript: aNode
^ self parseItem: aNode with: DrGPointByCoordinatesBuilder.! !
!DrGeoXml methodsFor: 'parse item'!
parsePointSymmetry: aNode
^ self parseItem: aNode with: DrGSymmetryBuilder! !
!DrGeoXml methodsFor: 'parse item'!
parsePointTranslation: aNode
^self parseTranslation: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parsePolygonHomothety: aNode
^self parseHomothety: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parsePolygonNpts: aNode
^ self parseItem: aNode with: DrGPolygonBuilder! !
!DrGeoXml methodsFor: 'parse item'!
parsePolygonReflexion: aNode
^ self parseReflexion: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parsePolygonRegular: aNode
^ self parseItem: aNode with: DrGPolygonRegularBuilder! !
!DrGeoXml methodsFor: 'parse item'!
parsePolygonRotation: aNode
^ self parseRotation: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parsePolygonScale: aNode
"Dr.Geo 1.1 compatibility"
^self parsePolygonHomothety: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parsePolygonSymmetry: aNode
^self parseSymmetry: aNode! !
!DrGeoXml methodsFor: 'parse item'!
parsePolygonTranslation: aNode
^self parseTranslation: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseRay2pts: aNode
^self parseItem: aNode with: DrGRayBuilder.! !
!DrGeoXml methodsFor: 'parse item'!
parseRayHomothety: aNode
^self parseHomothety: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseRayReflexion: aNode
^self parseReflexion: aNode! !
!DrGeoXml methodsFor: 'parse item'!
parseRayRotation: aNode
^self parseRotation: aNode! !
!DrGeoXml methodsFor: 'parse item'!
parseRaySymmetry: aNode
^self parseSymmetry: aNode! !
!DrGeoXml methodsFor: 'parse item'!
parseRayTranslation:aNode
^ self parseTranslation: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseReflexion: aNode
^ self parseItem: aNode with: DrGReflectionBuilder! !
!DrGeoXml methodsFor: 'parse item'!
parseRotation: aNode
^ self parseItem: aNode with: DrGRotationBuilder! !
!DrGeoXml methodsFor: 'parse item'!
parseScriptNitems: aNode
"Do nothing!!, compatibility for Dr. Geo 1.1
See method parseValueScript:"! !
!DrGeoXml methodsFor: 'parse item'!
parseSegment2pts: aNode
^ self parseItem: aNode with: DrGSegmentBuilder! !
!DrGeoXml methodsFor: 'parse item'!
parseSegmentHomothety: aNode
^self parseHomothety: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseSegmentReflexion: aNode
^ self parseReflexion: aNode! !
!DrGeoXml methodsFor: 'parse item'!
parseSegmentRotation: aNode
^self parseRotation: aNode! !
!DrGeoXml methodsFor: 'parse item'!
parseSegmentScale: aNode
"Dr.Geo 1.1 compatibility"
^self parseSegmentHomothety: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseSegmentSymmetry: aNode
^self parseSymmetry: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseSegmentTranslation: aNode
^self parseTranslation: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseSymmetry: aNode
^ self parseItem: aNode with: DrGSymmetryBuilder! !
!DrGeoXml methodsFor: 'parse item'!
parseTextFree: aNode
^ self parseItem: aNode with: DrGTextBuilder! !
!DrGeoXml methodsFor: 'parse item'!
parseTranslation: aNode
^ self parseItem: aNode with: DrGTranslationBuilder! !
!DrGeoXml methodsFor: 'parse item'!
parseValueArclength: aNode
^ self parseValueComputation: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseValueCircleperimeter: aNode
^ self parseValueComputation: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseValueComputation: aNode
^ self parseItem: aNode with: DrGValueBuilder.! !
!DrGeoXml methodsFor: 'parse item'!
parseValueDistance2pts: aNode
^ self parseValueComputation: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseValueDistanceptline: aNode
^ self parseValueComputation: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseValuePolygonperimeter: aNode
^ self parseValueComputation: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseValuePtabscissa: aNode
^ self parseCoordinates: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseValuePtordinate: aNode
^ self parseCoordinates: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseValueScript: aNode
^ self parseItem: aNode with: DrGScriptPlayer.! !
!DrGeoXml methodsFor: 'parse item'!
parseValueSegmentlength: aNode
^ self parseValueComputation: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseValueSlope: aNode
^ self parseValueComputation: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseValueValue: aNode
^ self parseValueComputation: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseValueVectorabscissa: aNode
^ self parseCoordinates: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseValueVectornorm: aNode
^ self parseValueComputation: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseValueVectorordinate: aNode
^ self parseCoordinates: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseVector2pts: aNode
^self parseItem: aNode with: DrGVectorBuilder.! !
!DrGeoXml methodsFor: 'parse item'!
parseVectorHomothety: aNode
^self parseHomothety: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseVectorReflexion: aNode
^self parseReflexion: aNode! !
!DrGeoXml methodsFor: 'parse item'!
parseVectorRotation: aNode
^self parseRotation: aNode! !
!DrGeoXml methodsFor: 'parse item'!
parseVectorScale: aNode
"Dr.Geo 1.1 compatibility"
^self parseVectorHomothety: aNode ! !
!DrGeoXml methodsFor: 'parse item'!
parseVectorSymmetry: aNode
^ self parseSymmetry: aNode! !
!DrGeoXml methodsFor: 'parse style' stamp: 'drgeo 9/10/2022 21:22:36'!
parseArrowWith: aNode
| arrow |
arrow _ (aNode attributeAt: #arrow ifAbsent: [#none]) asSymbol.
"Compatible with version <= 19.09"
^ arrow
caseOf: {
[#makeForwardArrow] -> [#forward] .
[#makeBackArrow] -> [#back] .
[#makeBothArrows] -> [#both].
[#makeNoArrows] -> [#none] }
otherwise: [arrow].
! !
!DrGeoXml methodsFor: 'parse style'!
parseColorAt: colorAttribute with: aNode
| attribute |
attribute _ (aNode attributeAt: colorAttribute ifAbsent: ['Transparent']) asLowercase.
(attribute = 'darkgrey' or: [attribute = 'darkgray']) ifTrue: [attribute _ #darkGray].
(attribute = 'grey' or: [attribute = 'gray']) ifTrue: [attribute _ #gray].
attribute = 'darkgreen' ifTrue: [attribute _ #green].
attribute = 'darkblue' ifTrue: [attribute _ #blue].
attribute = 'bordeaux' ifTrue: [attribute _ #red].
^ Color perform: attribute asSymbol! !
!DrGeoXml methodsFor: 'parse style' stamp: 'hlsf 9/25/2021 14:31:47'!
parseStyleOf: costume with: aNode
costume name: (aNode attributeAt: #name).
costume labelPositionDelta: (Point readFrom: (aNode attributeAt: #delta ifAbsent: ['7@7'])).
costume style hidden: (aNode attributeAt: #masked) = 'True'.
costume style feedback: (aNode attributeAt: #feedback ifAbsent: ['True']) = 'True'.
costume style color: (self parseColorAt: #color with: aNode).! !
!DrGeoXml methodsFor: 'parse style'!
parseStyleOfAngle: item with: aNode
self parseStyleOfNumeric: item with: aNode ! !
!DrGeoXml methodsFor: 'parse style' stamp: 'drgeo 9/10/2022 21:24:05'!
parseStyleOfArc: item with: aNode
|costume|
costume _ self parseStyleOfCurve: item with: aNode.
costume style arrow: (self parseArrowWith: aNode).
self parseStyleOfFilledCircle: costume with: aNode! !
!DrGeoXml methodsFor: 'parse style'!
parseStyleOfArcCircle: item with: aNode
self parseStyleOfArc: item with: aNode! !
!DrGeoXml methodsFor: 'parse style' stamp: 'hlsf 8/4/2023 11:13:03'!
parseStyleOfBitmap: item with: aNode
| morph |
morph := self drawable fastLastItemView .
self parseStyleOf: morph with: aNode! !
!DrGeoXml methodsFor: 'parse style'!
parseStyleOfCircle: item with: aNode
|costume|
costume _ self parseStyleOfCurve: item with: aNode.
self parseStyleOfFilledCircle: costume with: aNode! !
!DrGeoXml methodsFor: 'parse style' stamp: 'hlsf 8/4/2023 11:13:07'!
parseStyleOfCurve: item with: aNode
| morph attribute |
morph := self drawable fastLastItemView .
self parseStyleOf: morph with: aNode.
morph anchorAbscissa: (aNode attributeAt: #anchor ifAbsent: ['0.5']) asNumber.
attribute := aNode attributeAt: #thickness.
(DrGTypeThickness thicknessSymbols includes: attribute asSymbol)
ifTrue: [morph style thickness: attribute asSymbol]
ifFalse: ["DrGeo 1.1"
attribute = 'Dashed' ifTrue: [morph style lineStyle: #dash.].
attribute = 'Thick' ifTrue: [morph style thickness: #medium]].
attribute := aNode attributeAt: #style ifAbsent: [^ morph].
morph style lineStyle: attribute.
^ morph! !
!DrGeoXml methodsFor: 'parse style' stamp: 'hlsf 8/4/2023 11:11:18'!
parseStyleOfEquation: item with: aNode
| morph |
morph := self drawable fastLastMorph .
self parseStyleOf: morph with: aNode.! !
!DrGeoXml methodsFor: 'parse style'!
parseStyleOfFilledCircle: costume with: aNode
costume style fill: (aNode attributeAt: #filled ifAbsent: ['False']) = 'True'.
costume style translucent: (aNode attributeAt: #translucent ifAbsent: ['True']) = 'True'.
! !
!DrGeoXml methodsFor: 'parse style'!
parseStyleOfFilledPolygon: costume with: aNode
costume style fill: (aNode attributeAt: #filled ifAbsent: ['True']) = 'True'.
costume style translucent: (aNode attributeAt: #translucent ifAbsent: ['True']) = 'True'.
! !
!DrGeoXml methodsFor: 'parse style'!
parseStyleOfHalfLine: item with: aNode
"DrGeo 1.1 xml compatibility"
self parseStyleOfRay: item with: aNode! !
!DrGeoXml methodsFor: 'parse style'!
parseStyleOfLine: item with: aNode
self parseStyleOfCurve: item with: aNode! !
!DrGeoXml methodsFor: 'parse style'!
parseStyleOfLocus: item with: aNode
self parseStyleOfCurve: item with: aNode! !
!DrGeoXml methodsFor: 'parse style'!
parseStyleOfNumeric: item with: aNode
"DrGeo 1.1 xml compatibility"
self parseStyleOfValue: item with: aNode! !
!DrGeoXml methodsFor: 'parse style' stamp: 'hlsf 8/4/2023 19:52:53'!
parseStyleOfPoint: item with: aNode
| morph attribute |
morph := self drawable fastLastItemView .
self parseStyleOf: morph with: aNode.
attribute := aNode attributeAt: #thickness.
attribute = 'Dashed'
ifTrue: [attribute := #small].
attribute = 'Normal'
ifTrue: [attribute := #medium].
attribute = 'Thick'
ifTrue: [attribute := #large].
morph style pointSize: attribute.
attribute := aNode attributeAt: #style.
(#('Rectangular' 'RectangularEmpty' ) includes: attribute)
ifTrue: [attribute := #square].
attribute = 'RoundEmpty'
ifTrue: [attribute := #round].
morph style shape: attribute asLowercase asSymbol! !
!DrGeoXml methodsFor: 'parse style'!
parseStyleOfPolygon: item with: aNode
| costume |
costume _ self parseStyleOfCurve: item with: aNode.
self parseStyleOfFilledPolygon: costume with: aNode! !
!DrGeoXml methodsFor: 'parse style'!
parseStyleOfRay: item with: aNode
self parseStyleOfCurve: item with: aNode! !
!DrGeoXml methodsFor: 'parse style' stamp: 'drgeo 9/10/2022 21:23:07'!
parseStyleOfSegment: item with: aNode
| costume |
costume _ self parseStyleOfCurve: item with: aNode.
costume style mark: (aNode attributeAt: #mark ifAbsent: [#none]) asSymbol.
costume style arrow: (self parseArrowWith: aNode)! !
!DrGeoXml methodsFor: 'parse style' stamp: 'hlsf 8/4/2023 11:12:55'!
parseStyleOfText: item with: aNode
| morph |
morph := self drawable fastLastItemView .
self parseStyleOf: morph with: aNode.
morph style
setTranslucent: (self parseColorAt: #background with: aNode).
morph style
borderColor: (self parseColorAt: #border with: aNode).
morph style
fontSize: (aNode attributeAt: #fontSize ifAbsent: DrGeoSystem canvasFontSize) asNumber.! !
!DrGeoXml methodsFor: 'parse style' stamp: 'hlsf 5/24/2023 19:14:39'!
parseStyleOfValue: item with: aNode
self parseStyleOfText: item with: aNode! !
!DrGeoXml methodsFor: 'parse style' stamp: 'hlsf 9/26/2021 10:44:41'!
parseStyleOfVector: item with: aNode
self parseStyleOfCurve: item with: aNode.
item origin: (Point readFrom: (aNode attributeAt: #origin ifAbsent: [^self]))! !
!DrGeoXml methodsFor: 'svg write' stamp: 'hlsf 11/7/2023 20:21:08'!
exportToSvg: stream
| doc writer root canvas |
doc := XMLDocument new.
writer := XMLWriter on: stream.
root := XMLElement
named: #svg
attributes: {
#version -> '1.1'.
#width -> self drawable morphExtent x asString.
#height -> self drawable morphExtent y asString.
#xmlns -> 'http://www.w3.org/2000/svg' } asDictionary.
canvas := DrGSvgCanvas new
presenter: presenter;
topNode: root;
renderGrid;
renderAxes;
yourself.
self factory pool do: [:item | | aMorph |
aMorph := self drawable viewOf: item.
aMorph isDrawNeeded ifTrue: [
aMorph drawOn: canvas.
canvas renderLabelOf: aMorph]
].
doc addElement: root.
doc printXMLOn: writer.! !
!DrGeoXml methodsFor: 'testing' stamp: 'hlsf 8/4/2023 17:50:15'!
isCreatingMacro
^ presenter isNil! !
!DrGeoXml methodsFor: 'xml read' stamp: 'hlsf 4/9/2022 11:21:33'!
load: fileEntry for: constructor
^ self
loadFrom: (fileEntry readStream)
for: constructor ! !
!DrGeoXml methodsFor: 'xml read'!
loadFigureFrom: doc for: constructor
"One XML document may contain several drgeo figure instances, parse it all,
and return a DrGeo for each one"
|instances |
instances _ OrderedCollection new.
(doc elementAt: #drgenius) ifNil: [^nil].
(doc elementAt: #drgenius)
tagsNamed: #drgeo
do: [:each | instances add: (self parseOneFigure: each for: constructor)].
^ instances! !
!DrGeoXml methodsFor: 'xml read'!
loadFrom: stream for: constructor
"One XML document may contain several drgeo figure instances, parse it all,
and return a DrGeo for each one"
| doc instances |
doc _ XMLDOMParser parseDocumentFrom: stream.
stream close.
self loadMacroFrom: doc.
^ self loadFigureFrom: doc for: constructor.! !
!DrGeoXml methodsFor: 'xml read'!
loadMacroFrom: doc
(doc elementAt: #drgenius) ifNil: [^self].
(doc elementAt: #drgenius)
tagsNamed: #macro
do: [:each | DrGMacroFactory new addUnique: (self parseOneMacro: each)].
! !
!DrGeoXml methodsFor: 'xml read'!
loadOnlyFigureFrom: stream for: constructor
"One XML document may contain several drgeo figure instances, parse it all,
and return a DrGeo for each one"
| doc |
doc _ XMLDOMParser parseDocumentFrom: stream.
stream close.
^ self loadFigureFrom: doc for: constructor! !
!DrGeoXml methodsFor: 'xml read' stamp: 'hlsf 8/4/2023 18:08:40'!
parseFigureFrom: drgeoNode
"We parse from the view, because only the view knows both the domain and the view"
| itemStatut |
self setScaleTo: (drgeoNode attributeAt: #scale ifAbsent: [self scale]).
self ox: (drgeoNode attributeAt: #'origin_x' ifAbsent: [self ox]).
self oy: (drgeoNode attributeAt: #'origin_y' ifAbsent: [self oy]).
self view setLabel: (drgeoNode attributeAt: 'name' ifAbsent: ['no name' translated]).
(drgeoNode attributeAt: #grid) = 'True' ifTrue: [presenter gridOnOff].
(drgeoNode attributeAt: #axes) = 'True' ifTrue: [presenter axesOnOff].
(drgeoNode attributeAt: #gridded) = 'True' ifTrue: [presenter gridStuckOnOff].
self parseScript: drgeoNode.
drgeoNode elementsDo: [:aNode |
aNode name ~= #controls ifTrue: [
itemStatut := self instantiateItemFrom: aNode.
itemStatut second ifTrue: [self instantiateStyle: aNode for: itemStatut first]
]
].! !
!DrGeoXml methodsFor: 'xml read' stamp: 'hlsf 8/8/2023 19:13:55'!
parseOneFigure: node for: constructor
" Instantiate this node in a DrGeo app and return it"
self presenter: (DrGeo perform: constructor).
presenter notInteractive: true.
self parseFigureFrom: node.
self drawable forcedVisibility: false.
presenter notInteractive: false.
self drawable redrawNeeded .
presenter saved: true.
^ presenter! !
!DrGeoXml methodsFor: 'xml read' stamp: 'hlsf 9/27/2021 22:57:06'!
parseScript: drgeoNode
"First do one pass to compile all the script Smalltalk source code"
drgeoNode elementsDo: [: node |
(node tag = #value and: [(node attributeAt: #type) = #script]) ifTrue:
[(node contentStringAt: #code) readStream fileInAnnouncing: 'Compile']]! !
!DrGeoXml methodsFor: 'xml read item'!
instantiateItemFrom: aNode
"instantiate an item from this node"
^ self
perform: (self methodToParse: aNode)
with: aNode.! !
!DrGeoXml methodsFor: 'xml read item'!
instantiateStyle: aNode for: item
"instantiate the style for this item"
self
perform: (#parseStyleOf , aNode tag capitalized , #':with:') asSymbol
with: item
with: aNode! !
!DrGeoXml methodsFor: 'xml read item'!
methodToParse: aNode
"find which method to use to parse this node"
|type|
type _ ((aNode attributeAt: #type) copyWithoutAll: '_' ) capitalized asSymbol.
^(#parse , aNode tag capitalized , type , #':') asSymbol ! !
!DrGeoXml methodsFor: 'xml read macro'!
parentMacroNodesIn: macro from: aNode
"return a collection of parent macro nodes given theirs id in the attribute
elements <parent id=xxx>"
|collection|
collection _ OrderedCollection new.
aNode elementsDo: [:each |
(each tag = #parent) ifTrue: [
collection add: (macro detectId: (each attributeAt: 'ref') asSymbol)]].
^collection ! !
!DrGeoXml methodsFor: 'xml read macro'!
parseInput: node inMacro: macro
(node elementAt: #input) elementsDo: [:each | |item|
item _ DrGMacroMathItem new
id: (each attributeAt: #id) asSymbol;
basicType: each tag;
yourself.
macro addNode: (DrGMacroInputNode new itemTemplate: item; yourself)]! !
!DrGeoXml methodsFor: 'xml read macro'!
parseOneMacro: node
" parse one macro and return it"
| macro|
macro _ DrGMacro new.
macro title: (node attributeAt: #name).
macro description: (node contentStringAt: #description).
self parseInput: node inMacro: macro.
self parseOutput: node inMacro: macro.
macro saved: true. "We just load this macro, nothing to save"
^ macro! !
!DrGeoXml methodsFor: 'xml read macro'!
parseOutput: node inMacro: macro
(node elementAt: #output) elementsDo: [:aNode | |macroNodeClass|
aNode tag = #hidden ifTrue: [macroNodeClass _ DrGMacroHiddenNode].
aNode tag = #final ifTrue: [macroNodeClass _ DrGMacroOutputNode].
aNode elementsDo: [:child |
macro addNode: (
macroNodeClass new
itemTemplate: (self instantiateItemFrom: child);
parentNodes: (self parentMacroNodesIn: macro from: child);
yourself)]]! !
!DrGeoXml methodsFor: 'xml write' stamp: 'hlsf 8/4/2023 17:28:58'!
saveMultiple: sketchesAndMacros on: stream
| doc writer root |
doc := XMLDocument new version: '1.0'.
writer := XMLWriter on: stream.
root := XMLElement named: #drgenius.
(sketchesAndMacros select: [:each | each class = DrGeoView]) do: [:view |
self presenter: view presenter.
self writeFigureAsXmlTo: root].
(sketchesAndMacros select: [:each | each class = DrGMacro]) do: [:macro |
macro writeAsXmlTo: root].
doc addElement: root.
doc printXMLOn: writer.! !
!DrGeoXml methodsFor: 'xml write'!
saveOn: stream
| doc writer root |
doc _ XMLDocument new version: '1.0'.
writer _ XMLWriter on: stream.
root _ XMLElement named: #drgenius.
self writeFigureAsXmlTo: root.
doc addElement: root.
doc printXMLOn: writer.! !
!DrGeoXml methodsFor: 'xml write' stamp: 'hlsf 8/4/2023 17:52:03'!
writeFigureAsXmlTo: aNode
| drgeoNode attr |
attr := Dictionary new.
attr at: #scale put: self scale asString;
at: #'origin_x' put: self ox asString;
at: #'origin_y' put: self oy asString;
at: #grid put: presenter isGridVisible asString capitalized;
at: #gridded put: presenter isGridded asString capitalized;
at: #axes put: presenter isAxesVisible asString capitalized;
at: #name put: presenter sketchName. "Can't be nil, it's the base name for the file name"
drgeoNode := XMLElement named: #drgeo attributes: attr.
"Write the items"
self factory pool do: [:anItem |
(self drawable viewOf: anItem) writeAsXmlTo: drgeoNode].
aNode addElement: drgeoNode! !
!DrGStyle methodsFor: 'accessing'!
baseColor
"Answer color whatever it is hidden or not"
^ color alpha: 1! !
!DrGStyle methodsFor: 'accessing'!
borderColor
self shouldNotImplement ! !
!DrGStyle methodsFor: 'accessing' stamp: 'hlsf 6/3/2022 11:39:17'!
color
"Answer the value of color"
^hidden ifTrue: [DrGTypeColor hiddenColor] ifFalse: [color]! !
!DrGStyle methodsFor: 'accessing' stamp: 'hlsf 5/23/2021 12:46:18'!
color: anObject
"Set the value of color"
color _ anObject.
morph
color: self color;
redrawNeeded! !
!DrGStyle methodsFor: 'accessing'!
feedback
^ feedback! !
!DrGStyle methodsFor: 'accessing' stamp: 'hlsf 2/12/2022 11:37:46'!
feedback: aBoolean
" Do I provide feedback when mouse over me?"
feedback _ aBoolean.
self changed: #feedback:! !
!DrGStyle methodsFor: 'accessing'!
hidden
^ self isHidden! !
!DrGStyle methodsFor: 'accessing' stamp: 'hlsf 2/16/2022 23:14:39'!
hidden: anObject
"Set the value to isHidden"
hidden _ anObject.
hidden ifFalse: [morph color: self color].
morph redrawNeeded.
self changed: #hidden:! !
!DrGStyle methodsFor: 'accessing'!
isHidden
"Answer the value of isHidden"
^ hidden ifNil: [hidden _ false]! !
!DrGStyle methodsFor: 'accessing' stamp: 'hlsf 4/7/2021 19:49:44'!
mathItem
^ morph mathItem! !
!DrGStyle methodsFor: 'accessing' stamp: 'hlsf 4/7/2021 19:50:19'!
morph
^ morph! !
!DrGStyle methodsFor: 'accessing' stamp: 'hlsf 4/7/2021 19:51:37'!
morph: aMorph
morph _ aMorph ! !
!DrGStyle methodsFor: 'accessing' stamp: 'hlsf 4/7/2021 19:49:44'!
view
^ morph view! !
!DrGStyle methodsFor: 'initialize-release' stamp: 'hlsf 5/23/2021 13:16:46'!
initialize
feedback _ true.
hidden _ false.
color _ Color black! !
!DrGStyle methodsFor: 'testing'!
isFeedback
^ feedback ! !
!DrGStyle methodsFor: 'testing'!
isFilled
^ false! !
!DrGStyle methodsFor: 'testing'!
isNotHidden
"Answer the value of isHidden"
^ hidden not! !
!DrGStyle methodsFor: 'testing'!
isTranslucent
^ false! !
!DrGStyle methodsFor: 'widget' stamp: 'hlsf 6/3/2022 11:38:08'!
colorIndex
^ DrGTypeColor colorIndexOf: self baseColor! !
!DrGStyle methodsFor: 'widget' stamp: 'hlsf 6/3/2022 11:37:52'!
colorIndex: index
self color: (DrGTypeColor colorFor: index).
self changed: #colorIndex:! !
!DrGStyle methodsFor: 'widget' stamp: 'hlsf 6/3/2022 11:38:19'!
colorMorphCollection
^ DrGTypeColor colorMorphCollection! !
!DrGStyle methodsFor: 'widget' stamp: 'hlsf 3/24/2022 11:13:24'!
colorWidget
^ self widget: (
DropDownButtonMorph
model: self
listGetter: #colorMorphCollection
indexGetter: #colorIndex
indexSetter: #colorIndex: ::
autoDeselect: false;
yourself)
named: 'Colour' translated
help: 'Set the colour.' translated! !
!DrGStyle methodsFor: 'widget' stamp: 'hlsf 2/12/2022 14:42:43'!
feedbackWidget
^ PluggableCheckboxMorph
model: self
getSelected: #feedback
setSelected: #feedback:
label: 'Feedback' translated
::
setBalloonText: 'Toggle to provide feedback and interaction when the mouse cursor is over the object.' translated;
yourself! !
!DrGStyle methodsFor: 'widget' stamp: 'hlsf 2/12/2022 14:43:09'!
hiddenWidget
^ PluggableCheckboxMorph
model: self
getSelected: #hidden
setSelected: #hidden:
label: 'Hide' translated
::
setBalloonText: 'Toggle to hide the object.' translated;
yourself! !
!DrGStyle methodsFor: 'widget' stamp: 'hlsf 2/12/2022 14:43:28'!
lockedWidget
^ PluggableCheckboxMorph
model: morph
getSelected: #locked
setSelected: #locked:
label: 'Lock' translated
::
setBalloonText: 'Toggle to lock the object to its position.' translated;
yourself! !
!DrGStyle methodsFor: 'widget'!
myWidgets
"overwrite to add specific widget to edit specific style"
^ OrderedCollection new! !
!DrGStyle methodsFor: 'widget' stamp: 'hlsf 3/24/2022 11:56:27'!
nameWidget
| inputWidget |
inputWidget _ TextModelMorph textProvider: morph textGetter: #name textSetter: #name: ::
hideScrollBarsIndefinitely;
askBeforeDiscardingEdits: false;
acceptOnCR: true;
yourself .
inputWidget scroller setProperty: #keyStroke: toValue: [:event | inputWidget scroller acceptContents].
^ self
widget: inputWidget
named: 'Name' translated
help: 'Rename this object.' translated ! !
!DrGStyle methodsFor: 'widget' stamp: 'hlsf 2/12/2022 23:59:23'!
styleWidget
| controls |
controls _ OrderedCollection new
add: self nameWidget;
add: self colorWidget;
yourself.
controls addAll: self myWidgets.
controls add: self feedbackWidget.
controls add: self hiddenWidget.
morph isLockable ifTrue: [controls add: self lockedWidget].
^controls! !
!DrGStyle methodsFor: 'widget' stamp: 'hlsf 2/14/2022 09:01:21'!
widget: aWidget named: aLabel help: aString
| label |
^ LayoutMorph newRow ::
separation: 5;
color: Color transparent;
axisEdgeWeight: #rowLeft;
addMorph: (label _ LabelMorph contents: aLabel);
addMorph: aWidget layoutSpec: (LayoutSpec fixedHeight: label morphHeight) ;
setBalloonText: aString;
yourself.
! !
!DrGStyle methodsFor: 'xml writing' stamp: 'hlsf 3/28/2022 14:47:22'!
writeAttributesTo: aNode
aNode
attributeAt: #color put: self baseColor colorName asString capitalized;
attributeAt: #masked put: hidden asString capitalized;
attributeAt: #feedback put: feedback asString capitalized! !
!DrGStyle class methodsFor: 'instance creation' stamp: 'hlsf 4/24/2021 19:49:58'!
newWith: aMorph
^self basicNew morph: aMorph; initialize! !
!DrGCurveStyle methodsFor: 'widget' stamp: 'hlsf 6/5/2022 12:39:00'!
lineStyleIndex
"Answer the index of lineStyle"
^ DrGTypeStyle styleIndexOf: lineStyle! !
!DrGCurveStyle methodsFor: 'widget' stamp: 'hlsf 6/5/2022 12:38:39'!
lineStyleIndex: integer
"Set the value of lineStyle"
self lineStyle: (DrGTypeStyle styleSymbols at: integer).
self changed: #lineStyleIndex:
! !
!DrGCurveStyle methodsFor: 'widget' stamp: 'hlsf 6/5/2022 12:38:11'!
lineWidget
^ self widget: (
DropDownButtonMorph
model: self
listGetter: #styleMorphCollection
indexGetter: #lineStyleIndex
indexSetter: #lineStyleIndex: ::
autoDeselect: false;
yourself)
named: 'Style' translated
help: 'Set the style of the line.' translated! !
!DrGCurveStyle methodsFor: 'widget'!
myWidgets
^ super myWidgets addAll: {self lineWidget . self thicknessWidget}; yourself! !
!DrGCurveStyle methodsFor: 'widget' stamp: 'hlsf 6/5/2022 12:38:11'!
styleMorphCollection
^ DrGTypeStyle styleMorphCollection! !
!DrGCurveStyle methodsFor: 'widget' stamp: 'hlsf 6/5/2022 12:20:51'!
thicknessIndex
"Answer the index of thickness"
^DrGTypeThickness thicknessIndexOf: thickness! !
!DrGCurveStyle methodsFor: 'widget' stamp: 'hlsf 6/5/2022 12:20:51'!
thicknessIndex: integer
"Set the value of thickness"
self thickness: (DrGTypeThickness thicknessFor: integer).
self changed: #thicknessIndex:! !
!DrGCurveStyle methodsFor: 'widget' stamp: 'hlsf 6/5/2022 12:20:51'!
thicknessMorphCollection
^ DrGTypeThickness thicknessMorphCollection! !
!DrGCurveStyle methodsFor: 'widget' stamp: 'hlsf 3/24/2022 11:13:49'!
thicknessWidget
^ self widget: (
DropDownButtonMorph
model: self
listGetter: #thicknessMorphCollection
indexGetter: #thicknessIndex
indexSetter: #thicknessIndex: ::
autoDeselect: false;
yourself)
named: 'Thickness' translated
help: 'Set the thickness of the line.' translated! !
!DrGCurveStyle methodsFor: 'accessing' stamp: 'hlsf 6/3/2022 11:39:21'!
borderColor
"Answer the value of border color"
^hidden ifTrue: [DrGTypeColor hiddenColor] ifFalse: [self baseColor]! !
!DrGCurveStyle methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 12:20:51'!
borderWidth
"give the border width"
^ DrGTypeThickness widthFor: thickness! !
!DrGCurveStyle methodsFor: 'accessing' stamp: 'hlsf 5/18/2021 21:24:38'!
color
"Answer the fill color"
^self isFilled ifTrue: [color] ifFalse: [Color transparent]! !
!DrGCurveStyle methodsFor: 'accessing' stamp: 'hlsf 5/23/2021 12:53:09'!
color: aColor
"Set the value of fill color and border color"
color _ self isTranslucent ifTrue: [aColor alpha: 0.3] ifFalse: [aColor alpha: 1].
morph
borderColor: self borderColor;
color: self color;
redrawNeeded! !
!DrGCurveStyle methodsFor: 'accessing'!
lineStyle
"Answer the value of lineStyle"
^ lineStyle! !
!DrGCurveStyle methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 12:41:02'!
lineStyle: aSymbol
"Set the value of lineStyle"
lineStyle _ aSymbol.
morph dashedBorder: (DrGTypeStyle styleDataFor: aSymbol).
morph redrawNeeded! !
!DrGCurveStyle methodsFor: 'accessing'!
thickness
"Answer the value of thickness"
^ thickness! !
!DrGCurveStyle methodsFor: 'accessing' stamp: 'hlsf 12/2/2021 10:46:49'!
thickness: anObject
"Set the value of thickness"
thickness _ anObject.
morph borderWidth: self borderWidth.
morph redrawNeeded! !
!DrGCurveStyle methodsFor: 'xml writing'!
writeAttributesTo: aNode
super writeAttributesTo: aNode.
aNode attributeAt: #style put: self lineStyle.
aNode attributeAt: #thickness put: self thickness.! !
!DrGFinitCurveStyle methodsFor: 'accessing'!
arrow
"Answer the value of arrows"
^ arrow! !
!DrGFinitCurveStyle methodsFor: 'accessing' stamp: 'hlsf 6/17/2021 17:50:00'!
arrow: anObject
"Set the value of arrows"
arrow _ anObject.
morph arrow: anObject;
redrawNeeded ! !
!DrGFinitCurveStyle methodsFor: 'xml writing' stamp: 'hlsf 4/11/2021 12:22:39'!
writeAttributesTo: aNode
super writeAttributesTo: aNode.
morph isCircle ifFalse: [aNode attributeAt: #arrow put: self arrow.]! !
!DrGFinitCurveStyle methodsFor: 'widget' stamp: 'hlsf 6/5/2022 14:39:22'!
arrowIndex
"Answer the index of arrows"
^ DrGTypeArrow arrowIndexOf: arrow! !
!DrGFinitCurveStyle methodsFor: 'widget' stamp: 'hlsf 6/5/2022 14:38:56'!
arrowIndex: index
"Set the value of arrows"
self arrow: (DrGTypeArrow arrowFor: index).
self changed: #arrowIndex:! !
!DrGFinitCurveStyle methodsFor: 'widget' stamp: 'hlsf 6/5/2022 14:38:24'!
arrowMorphCollection
^ DrGTypeArrow arrowMorphCollection! !
!DrGFinitCurveStyle methodsFor: 'widget' stamp: 'hlsf 3/24/2022 11:13:55'!
arrowWidget
^ self widget: (
DropDownButtonMorph
model: self
listGetter: #arrowMorphCollection
indexGetter: #arrowIndex
indexSetter: #arrowIndex: ::
autoDeselect: false;
yourself)
named: 'Arrow' translated
help: 'Set arrow(s) to the line.' translated! !
!DrGFinitCurveStyle methodsFor: 'widget' stamp: 'hlsf 4/11/2021 12:25:24'!
myWidgets
^ (morph isSegment or: [morph isArc])
ifTrue: [super myWidgets addAll: {self arrowWidget}; yourself]
ifFalse: [super myWidgets]! !
!DrGCompositeStyle methodsFor: 'accessing'!
shape
^shape! !
!DrGCompositeStyle methodsFor: 'accessing' stamp: 'hlsf 4/7/2021 19:49:44'!
shape: anObject
shape _ anObject.
morph shape: anObject! !
!DrGFilledStyle methodsFor: 'xml writing'!
writeAttributesTo: aNode
super writeAttributesTo: aNode.
aNode attributeAt: #filled put: self isFilled asString capitalized.
aNode attributeAt: #translucent put: self isTranslucent asString capitalized! !
!DrGFilledStyle methodsFor: 'widget' stamp: 'hlsf 2/12/2022 15:59:50'!
fillWidget
^ PluggableCheckboxMorph
model: self
getSelected: #fill
setSelected: #fill:
label: 'Fill' translated
::
setBalloonText: 'Toggle to fill the object.' translated;
yourself! !
!DrGFilledStyle methodsFor: 'widget'!
myWidgets
^ super myWidgets addAll: {self fillWidget. self translucentWidget}; yourself! !
!DrGFilledStyle methodsFor: 'widget' stamp: 'hlsf 2/12/2022 15:58:11'!
translucentWidget
^ PluggableCheckboxMorph
model: self
getSelected: #translucent
setSelected: #translucent:
label: 'Translucent' translated
::
setBalloonText: 'Toggle the translucency of the object.' translated;
yourself! !
!DrGFilledStyle methodsFor: 'accessing'!
fill
^ self isFilled! !
!DrGFilledStyle methodsFor: 'accessing' stamp: 'hlsf 5/18/2023 17:55:33'!
fill: boolean
fill := boolean.
self color: color.
self changed: #fill:.
morph redrawNeeded.! !
!DrGFilledStyle methodsFor: 'accessing' stamp: 'hlsf 6/17/2021 18:10:25'!
isFilled
^ fill ifNil: [fill _ true]! !
!DrGFilledStyle methodsFor: 'accessing' stamp: 'hlsf 6/17/2021 18:10:10'!
isTranslucent
^ translucent ifNil: [translucent _ true]! !
!DrGFilledStyle methodsFor: 'accessing'!
toggleFilled
self fill: fill not.
self changed! !
!DrGFilledStyle methodsFor: 'accessing' stamp: 'hlsf 5/18/2021 21:33:44'!
toggleTranslucent
self translucent: translucent not! !
!DrGFilledStyle methodsFor: 'accessing'!
translucent
^ self isTranslucent ! !
!DrGFilledStyle methodsFor: 'accessing' stamp: 'hlsf 2/13/2022 22:35:25'!
translucent: boolean
translucent _ boolean.
self color: color.
self changed: #translucent:.
morph redrawNeeded! !
!DrGArcStyle methodsFor: 'accessing' stamp: 'hlsf 2/13/2022 10:26:41'!
fill: boolean
(fill _ boolean)
ifTrue: ["morph morph makeClosed"]
ifFalse: ["morph morph makeOpen"].
self changed: #fill:.
morph redrawNeeded! !
!DrGArcStyle methodsFor: 'initialize-release' stamp: 'hlsf 7/6/2022 09:23:33'!
initialize
super initialize.
self color: (DrGeoSystem preferences at: #arcColor).
self lineStyle: (DrGeoSystem preferences at: #arcStyle).
self thickness: (DrGeoSystem preferences at: #arcThickness).
self arrow: (DrGeoSystem preferences at: #arcArrow).
self fill: (DrGeoSystem preferences at: #arcFilled).
self translucent: (DrGeoSystem preferences at: #arcTranslucent).! !
!DrGCircleStyle methodsFor: 'initialize-release' stamp: 'hlsf 7/6/2022 09:01:16'!
initialize
super initialize.
self color: (DrGeoSystem preferences at: #circleColor).
self lineStyle: (DrGeoSystem preferences at: #circleStyle).
self thickness: (DrGeoSystem preferences at: #circleThickness).
self fill: (DrGeoSystem preferences at: #circleFilled).
self translucent:(DrGeoSystem preferences at: #circleTranslucent).! !
!DrGPolygonStyle methodsFor: 'initialize-release' stamp: 'hlsf 7/6/2022 09:34:28'!
initialize
super initialize.
self color: (DrGeoSystem preferences at: #polygonColor).
self lineStyle: (DrGeoSystem preferences at: #polygonStyle).
self thickness: (DrGeoSystem preferences at: #polygonThickness).
self fill: (DrGeoSystem preferences at: #polygonFilled).
self translucent: (DrGeoSystem preferences at: #polygonTranslucent).
self arrow: #none! !
!DrGSegmentStyle methodsFor: 'xml writing'!
writeAttributesTo: aNode
super writeAttributesTo: aNode.
aNode attributeAt: #mark put: self mark! !
!DrGSegmentStyle methodsFor: 'widget' stamp: 'hlsf 6/5/2022 14:14:37'!
markIndex
mark ifNil: [mark _ #none].
^DrGTypeMark markIndexOf: mark! !
!DrGSegmentStyle methodsFor: 'widget' stamp: 'hlsf 6/5/2022 14:14:02'!
markIndex: index
self mark: (DrGTypeMark markFor: index).
self changed: #markIndex:.! !
!DrGSegmentStyle methodsFor: 'widget' stamp: 'hlsf 6/5/2022 14:15:16'!
markMorphCollection
^ DrGTypeMark markMorphCollection! !
!DrGSegmentStyle methodsFor: 'widget' stamp: 'hlsf 3/24/2022 11:14:22'!
markWidget
^ self widget: (
DropDownButtonMorph
model: self
listGetter: #markMorphCollection
indexGetter: #markIndex
indexSetter: #markIndex: ::
autoDeselect: false;
yourself)
named: 'Mark' translated
help: 'Set a mark to the segment.' translated! !
!DrGSegmentStyle methodsFor: 'widget'!
myWidgets
^ super myWidgets addAll: {self markWidget}; yourself! !
!DrGSegmentStyle methodsFor: 'accessing'!
mark
^ mark ifNil: [mark _ #none]! !
!DrGSegmentStyle methodsFor: 'accessing' stamp: 'hlsf 2/13/2022 10:27:22'!
mark: aSymbol
mark _ aSymbol.
morph redrawNeeded! !
!DrGSegmentStyle methodsFor: 'initialize-release' stamp: 'hlsf 7/3/2022 22:44:29'!
initialize
super initialize.
self color: (DrGeoSystem preferences at: #segmentColor).
self lineStyle: (DrGeoSystem preferences at: #segmentStyle).
self thickness: (DrGeoSystem preferences at: #segmentThickness).
self mark: (DrGeoSystem preferences at: #segmentMark).
self arrow: (DrGeoSystem preferences at: #segmentArrow)! !
!DrGLineStyle methodsFor: 'initialize-release' stamp: 'hlsf 7/6/2022 08:58:03'!
initialize
super initialize.
self color: (DrGeoSystem preferences at: #lineColor).
self lineStyle: (DrGeoSystem preferences at: #lineStyle).
self thickness: (DrGeoSystem preferences at: #lineThickness)! !
!DrGLocusStyle methodsFor: 'initialize-release' stamp: 'hlsf 7/6/2022 09:50:19'!
initialize
super initialize.
self color: (DrGeoSystem preferences at: #locusColor).
self lineStyle: (DrGeoSystem preferences at: #locusStyle).
self thickness: (DrGeoSystem preferences at: #locusThickness)! !
!DrGRayStyle methodsFor: 'initialize-release' stamp: 'hlsf 7/6/2022 09:00:27'!
initialize
super initialize.
self color: (DrGeoSystem preferences at: #rayColor).
self lineStyle: (DrGeoSystem preferences at: #rayStyle).
self thickness: (DrGeoSystem preferences at: #rayThickness)! !
!DrGVectorStyle methodsFor: 'initialize-release' stamp: 'hlsf 7/6/2022 09:38:17'!
initialize
super initialize.
self color: (DrGeoSystem preferences at: #vectorColor).
self lineStyle:(DrGeoSystem preferences at: #vectorStyle).
self thickness: (DrGeoSystem preferences at: #vectorThickness)! !
!DrGPointStyle methodsFor: 'widget'!
myWidgets
^ super myWidgets addAll: {self shapeWidget. self sizeWidget}; yourself! !
!DrGPointStyle methodsFor: 'widget' stamp: 'hlsf 6/5/2022 11:00:28'!
shapeMorphCollection
^ DrGTypePointShape shapeMorphCollection ! !
!DrGPointStyle methodsFor: 'widget' stamp: 'hlsf 3/24/2022 11:14:43'!
shapeWidget
^ self widget: (
DropDownButtonMorph
model: self
listGetter: #shapeMorphCollection
indexGetter: #shapeIndex
indexSetter: #shapeIndex: ::
autoDeselect: false;
yourself)
named: 'Shape' translated
help: 'Set the shape of the point.' translated! !
!DrGPointStyle methodsFor: 'widget' stamp: 'hlsf 6/4/2022 14:50:31'!
sizeMorphCollection
^ DrGTypePointSize sizeMorphCollection: shape! !
!DrGPointStyle methodsFor: 'widget' stamp: 'hlsf 3/24/2022 11:14:49'!
sizeWidget
^ self widget: (
DropDownButtonMorph
model: self
listGetter: #sizeMorphCollection
indexGetter: #pointSizeIndex
indexSetter: #pointSizeIndex: ::
autoDeselect: false;
yourself)
named: 'Size' translated
help: 'Set the size of the point.' translated! !
!DrGPointStyle methodsFor: 'widget' stamp: 'hlsf 2/14/2022 09:32:31'!
updateStylePanel
self view presenter controlsManager updateStylerFor: self! !
!DrGPointStyle methodsFor: 'initialize-release' stamp: 'hlsf 7/3/2022 22:53:48'!
initialize
super initialize.
self color: (DrGeoSystem preferences at: #pointColor).
self pointSize: (DrGeoSystem preferences at: #pointSize).
self shape: (DrGeoSystem preferences at: #pointShape)! !
!DrGPointStyle methodsFor: 'accessing'!
abscissa
^ self mathItem point x asString! !
!DrGPointStyle methodsFor: 'accessing'!
abscissa: aText
|number|
[number _ aText asString asNumber]
on: Error
do: [^ false].
self mathItem x: number.
self changed.
^ true! !
!DrGPointStyle methodsFor: 'accessing'!
curvilinearAbscissa
^ self mathItem abscissa asString! !
!DrGPointStyle methodsFor: 'accessing'!
curvilinearAbscissa: aText
|number|
[number _ aText asString asNumber]
on: Error
do: [^ false].
self mathItem abscissa: number.
self changed.
^ true! !
!DrGPointStyle methodsFor: 'accessing'!
ordinate
^ self mathItem point y asString! !
!DrGPointStyle methodsFor: 'accessing'!
ordinate: aText
|number|
[number _ aText asString asNumber]
on: Error
do: [^ false].
self mathItem y: number.
self changed.
^ true! !
!DrGPointStyle methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 11:01:45'!
pointExtent
^ DrGTypePointSize pointExtentFor: pointSize.! !
!DrGPointStyle methodsFor: 'accessing'!
pointSize
"Answer the value of thickness"
^ pointSize! !
!DrGPointStyle methodsFor: 'accessing' stamp: 'hlsf 5/18/2021 21:34:43'!
pointSize: anObject
"Set the value of thickness"
pointSize _ anObject.
morph redrawNeeded
! !
!DrGPointStyle methodsFor: 'accessing' stamp: 'hlsf 6/4/2022 14:51:28'!
pointSizeIndex
"Answer the index of thickness"
^DrGTypePointSize pointSizeIndexOf: pointSize! !
!DrGPointStyle methodsFor: 'accessing' stamp: 'hlsf 6/4/2022 14:55:37'!
pointSizeIndex: index
"Set the value of thickness"
self pointSize: (DrGTypePointSize pointSizeFor: index).
self changed: #pointSizeIndex:! !
!DrGPointStyle methodsFor: 'accessing'!
shape
"Answer the value of shape"
^ shape! !
!DrGPointStyle methodsFor: 'accessing' stamp: 'hlsf 2/14/2022 09:20:45'!
shape: anObject
"Set the value of shape"
shape _ anObject.
morph redrawNeeded! !
!DrGPointStyle methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 10:54:33'!
shapeIndex
"Answer the index of the shape"
^ DrGTypePointShape pointShapeIndexOf: shape! !
!DrGPointStyle methodsFor: 'accessing' stamp: 'hlsf 6/5/2022 10:51:32'!
shapeIndex: index
"Set the value of shape"
self shape: (DrGTypePointShape pointShapeFor: index).
self changed: #shapeIndex:.
self updateStylePanel ! !
!DrGPointStyle methodsFor: 'xml writing'!
writeAttributesTo: aNode
|attr|
super writeAttributesTo: aNode.
self pointSize = #small ifTrue: [attr _ 'Dashed'].
self pointSize = #medium ifTrue: [attr _ 'Normal'].
self pointSize = #large ifTrue: [attr _ 'Thick'].
aNode attributeAt: #thickness put: attr.
attr _ self shape asString capitalized.
self shape = #square ifTrue: [attr _ 'Rectangular'].
self shape = #round ifTrue: [attr _ 'Round'].
aNode attributeAt: #style put: attr! !
!DrGTextStyle methodsFor: 'accessing'!
backgroundColor
^ backgroundColor ! !
!DrGTextStyle methodsFor: 'accessing' stamp: 'hlsf 5/15/2021 21:38:26'!
backgroundColor: aColor
backgroundColor _ aColor.
self changed! !
!DrGTextStyle methodsFor: 'accessing'!
backgroundColorIndex
^ self class backgroundColors indexOf: self baseBackgroundColor
! !
!DrGTextStyle methodsFor: 'accessing' stamp: 'hlsf 2/13/2022 10:29:08'!
backgroundColorIndex: index
| aColor |
aColor _ Color perform: (self class backgroundColorSymbols at: index).
self setTranslucent: aColor.
self changed: #backgroundColorIndex:
! !
!DrGTextStyle methodsFor: 'accessing'!
baseBackgroundColor
"This color whithout transparency"
^ backgroundColor isTransparent
ifFalse: [backgroundColor alpha: 1.0]
ifTrue: [backgroundColor]! !
!DrGTextStyle methodsFor: 'accessing'!
borderColor
^ borderColor ! !
!DrGTextStyle methodsFor: 'accessing' stamp: 'hlsf 5/18/2021 21:26:36'!
borderColor: aColor
borderColor _ aColor.
morph redrawNeeded! !
!DrGTextStyle methodsFor: 'accessing'!
borderColorIndex
^ self class backgroundColors indexOf: borderColor! !
!DrGTextStyle methodsFor: 'accessing' stamp: 'hlsf 2/13/2022 10:29:24'!
borderColorIndex: index
| aColor |
aColor _ Color perform: (self class backgroundColorSymbols at: index).
self borderColor: aColor.
self changed: #borderColorIndex:
! !
!DrGTextStyle methodsFor: 'accessing' stamp: 'hlsf 5/24/2023 18:43:58'!
fontSize: integer
fontSize := integer.
morph fontSize: integer.
self changed! !
!DrGTextStyle methodsFor: 'accessing' stamp: 'hlsf 2/12/2022 23:36:04'!
fontSizeIndex
^ self fontSizesCollection indexOf: fontSize
! !
!DrGTextStyle methodsFor: 'accessing' stamp: 'hlsf 2/13/2022 10:29:41'!
fontSizeIndex: index
self fontSize: (self fontSizesCollection at: index).
self changed: #fontSizeIndex:
! !
!DrGTextStyle methodsFor: 'accessing' stamp: 'hlsf 3/24/2022 16:54:27'!
setTranslucent: aColor
aColor isTransparent
ifFalse: [self backgroundColor: (aColor alpha: 0.6)]
ifTrue: [self backgroundColor: aColor]
! !
!DrGTextStyle methodsFor: 'widget' stamp: 'hlsf 4/26/2020 15:41:25'!
backgroundMorphCollection
^ self class backgroundColors collect: [:aColor |
ImageMorph new image: (DrGIcons colorForm: aColor)]! !
!DrGTextStyle methodsFor: 'widget' stamp: 'hlsf 3/24/2022 11:14:58'!
backgroundWidget
^ self widget: (
DropDownButtonMorph
model: self
listGetter: #backgroundMorphCollection
indexGetter: #backgroundColorIndex
indexSetter: #backgroundColorIndex: ::
autoDeselect: false;
yourself)
named: 'Background' translated
help: 'Set the background colour.' translated! !
!DrGTextStyle methodsFor: 'widget' stamp: 'hlsf 3/24/2022 11:15:31'!
borderWidget
^ self widget: (
DropDownButtonMorph
model: self
listGetter: #backgroundMorphCollection
indexGetter: #borderColorIndex
indexSetter: #borderColorIndex: ::
autoDeselect: false;
yourself)
named: 'Border' translated
help: 'Set the border colour.' translated! !
!DrGTextStyle methodsFor: 'widget' stamp: 'hlsf 3/24/2022 11:37:47'!
fontSizeWidget
^ self widget: (
DropDownButtonMorph
model: self
listGetter: #fontSizesMorphCollection
indexGetter: #fontSizeIndex
indexSetter: #fontSizeIndex: ::
autoDeselect: false;
yourself)
named: 'Font size' translated
help: 'Set the font size.' translated! !
!DrGTextStyle methodsFor: 'widget' stamp: 'hlsf 3/24/2022 11:37:26'!
fontSizesCollection
^#(9 10 12 14 16)! !
!DrGTextStyle methodsFor: 'widget' stamp: 'hlsf 3/24/2022 11:37:40'!
fontSizesMorphCollection
^ self fontSizesCollection collect: [:pt |
LabelMorph
contents: pt asString
font: (FontFamily familyName: FontFamily defaultFamilyName pointSize: pt)]! !
!DrGTextStyle methodsFor: 'widget'!
myWidgets
^ super myWidgets
addAll: {self backgroundWidget . self borderWidget . self fontSizeWidget};
yourself! !
!DrGTextStyle methodsFor: 'widget' stamp: 'hlsf 3/24/2022 17:04:13'!
styleWidget
| controls |
" There is no name for text object"
controls _ OrderedCollection new
add: self colorWidget;
yourself.
controls addAll: self myWidgets.
controls add: self feedbackWidget.
controls add: self hiddenWidget.
morph isLockable ifTrue: [controls add: self lockedWidget].
^controls! !
!DrGTextStyle methodsFor: 'initialize-release' stamp: 'hlsf 5/24/2023 19:32:40'!
initialize
super initialize.
self color: (DrGeoSystem preferences at: #textColor).
self setTranslucent: (DrGeoSystem preferences at: #textBackgroundColor).
self borderColor: (DrGeoSystem preferences at: #textBorderColor).
fontSize := 12 .! !
!DrGTextStyle methodsFor: 'xml writing' stamp: 'drgeo 9/10/2022 12:06:57'!
writeAttributesTo: aNode
super writeAttributesTo: aNode.
aNode attributeAt: #background put: self baseBackgroundColor colorName asString capitalized.
aNode attributeAt: #border put: self borderColor colorName asString capitalized.
aNode attributeAt: #fontSize put: fontSize asString! !
!DrGTextStyle class methodsFor: 'as yet unclassified' stamp: 'hlsf 6/3/2022 11:38:45'!
backgroundColorSymbols
^ OrderedCollection new
add: #transparent;
addAll: DrGTypeColor colorSymbols;
yourself ! !
!DrGTextStyle class methodsFor: 'as yet unclassified'!
backgroundColors
^ self backgroundColorSymbols collect: [:symbol | Color perform: symbol]! !
!DrGValueStyle methodsFor: 'accessing' stamp: 'hlsf 5/29/2021 17:31:15'!
rename
|answer|
"Not the responsability of this object"
self flag: #drgeoTodo.
DrGeoSystem showVirtualKeyboard: true.
self mathItem name
ifNotNil: [
answer _ self view
textEntry: 'Rename this value' translated
title: 'Rename this value' translated
entryText: self mathItem name.]
ifNil: [
answer _ self view
textEntry: 'Name this value' translated
title: 'Name this value' translated].
answer ifNil: [^self].
answer isEmpty ifTrue: [answer _ nil].
self mathItem name: answer.
morph redrawNeeded.
self changed! !
!DrGValueStyle methodsFor: 'initialize-release' stamp: 'hlsf 7/6/2022 10:06:19'!
initialize
super initialize.
self color: (DrGeoSystem preferences at: #valueColor)
! !
!DrGValueStyle methodsFor: 'widget' stamp: 'hlsf 3/24/2022 16:59:01'!
styleWidget
| controls |
controls _ OrderedCollection new
add: self nameWidget;
add: self colorWidget;
yourself.
controls addAll: self myWidgets.
controls add: self feedbackWidget.
controls add: self hiddenWidget.
morph isLockable ifTrue: [controls add: self lockedWidget].
^controls! !
!DrGPlatform methodsFor: 'default preferences' stamp: 'hlsf 9/25/2022 10:22:26'!
arcPreferences
" name - description - category - type - value "
| category |
category _ #arc translated asSymbol.
^ {
{#arcColor. 'Colour' translated. category. DrGTypeColor with: #arcColor in: preferences. Color black} .
{#arcThickness. 'Thickness' translated. category. DrGTypeThickness with: #arcThickness in: preferences. #small}.
{#arcStyle. 'Style' translated. category. DrGTypeStyle with: #arcStyle in: preferences. #plain}.
{#arcArrow. 'Arrow' translated. category. DrGTypeArrow with: #arcArrow in: preferences. #none }.
{#arcFilled. 'Fill' translated. category. Boolean. false} .
{#arcTranslucent. 'Translucent' translated. category. Boolean. false}
}! !
!DrGPlatform methodsFor: 'default preferences' stamp: 'hlsf 9/25/2022 10:23:10'!
circlePreferences
" name - description - category - type - value "
| category |
category _ #circle translated asSymbol.
^ {
{#circleColor. 'Colour' translated. category. DrGTypeColor with: #circleColor in: preferences. Color black} .
{#circleThickness. 'Thickness' translated. category. DrGTypeThickness with: #circleThickness in: preferences. #small} .
{#circleStyle. 'Style' translated. category. DrGTypeStyle with: #circleStyle in: preferences. #plain} .
{#circleFilled. 'Fill' translated. category. Boolean. false} .
{#circleTranslucent. 'Translucent' translated. category. Boolean. false}
}! !
!DrGPlatform methodsFor: 'default preferences' stamp: 'hlsf 9/25/2022 10:23:49'!
linePreferences
" name - description - category - type - value "
| category |
category _ #line translated asSymbol.
^ {
{#lineColor. 'Colour' translated. category. DrGTypeColor with: #lineColor in: preferences. Color black} .
{#lineThickness. 'Thickness' translated. category. DrGTypeThickness with: #lineThickness in: preferences. #small} .
{#lineStyle. 'Style' translated. category. DrGTypeStyle with: #lineStyle in: preferences. #plain}
}! !
!DrGPlatform methodsFor: 'default preferences' stamp: 'hlsf 9/25/2022 10:25:16'!
locusPreferences
" name - description - category - type - value "
| category |
category _ #locus translated asSymbol.
^ {
{#locusColor. 'Colour' translated. category. DrGTypeColor with: #locusColor in: preferences. Color black} .
{#locusThickness. 'Thickness' translated. category. DrGTypeThickness with: #locusThickness in: preferences. #small} .
{#locusStyle. 'Style' translated. category. DrGTypeStyle with: #locusStyle in: preferences. #plain}
}! !
!DrGPlatform methodsFor: 'default preferences' stamp: 'hlsf 3/9/2023 15:56:08'!
miscPreferences
" name - description - category - type - value "
| category |
category _ #miscellaneous translated asSymbol.
^ {
{#userPath. 'Path for user created resources as sketches, Smalltalk sketches, exported image. An empty path locates these resources in the Dr. Geo application folder. Relative path accepted, home/user directory is then prepended' translated. category. nil. ''} .
{#autoName. 'Autoname new object' translated. category. Boolean. false}
}! !
!DrGPlatform methodsFor: 'default preferences' stamp: 'hlsf 9/25/2022 10:25:11'!
pointPreferences
" name - description - category - type - value "
| category |
category _ #point translated asSymbol.
^ {
{#pointColor. 'Colour' translated. category. DrGTypeColor with: #pointColor in: preferences. Color red} .
{#pointSize. 'Size' translated. category. DrGTypePointSize with: #pointSize in: preferences. #small} .
{#pointShape. 'Shape' translated. category. DrGTypePointShape with: #pointShape in: preferences. #cross}
}! !
!DrGPlatform methodsFor: 'default preferences' stamp: 'hlsf 9/25/2022 10:24:59'!
polygonPreferences
" name - description - category - type - value "
| category |
category _ #polygon translated asSymbol.
^ {
{#polygonColor. 'Colour' translated. category. DrGTypeColor with: #polygonColor in: preferences. Color black} .
{#polygonThickness. 'Thickness' translated. category. DrGTypeThickness with: #polygonThickness in: preferences. #small} .
{#polygonStyle. 'Style' translated. category. DrGTypeStyle with: #polygonStyle in: preferences. #plain} .
{#polygonFilled. 'Fill' translated. category. Boolean. false} .
{#polygonTranslucent. 'Translucent' translated. category. Boolean. false}
}! !
!DrGPlatform methodsFor: 'default preferences' stamp: 'hlsf 9/25/2022 10:25:46'!
programmingPreferences
" name - description - category - type - value "
| category |
category _ #programming translated asSymbol.
^ {
{#programmingCodeCompletion. 'Code completion on' translated. category. nil . DrGeoSketch}
}! !
!DrGPlatform methodsFor: 'default preferences' stamp: 'hlsf 9/25/2022 10:26:19'!
rayPreferences
" name - description - category - type - value "
| category |
category _ #ray translated asSymbol.
^ {
{#rayColor. 'Colour' translated. category. DrGTypeColor with: #rayColor in: preferences. Color black}.
{#rayThickness. 'Thickness' translated. category. DrGTypeThickness with: #rayThickness in: preferences. #small} .
{#rayStyle. 'Style' translated. category. DrGTypeStyle with: #rayStyle in: preferences. #plain}
}! !
!DrGPlatform methodsFor: 'default preferences' stamp: 'hlsf 9/25/2022 10:26:51'!
segmentPreferences
" name - description - category - type - value "
| category |
category _ #segment translated asSymbol.
^ {
{#segmentColor. 'Colour' translated. category. DrGTypeColor with: #segmentColor in: preferences. Color black} .
{#segmentThickness. 'Thickness' translated. category. DrGTypeThickness with: #segmentThickness in: preferences. #small} .
{#segmentStyle. 'Style' translated. category. DrGTypeStyle with: #segmentStyle in: preferences. #plain} .
{#segmentMark. 'Mark' translated. category. DrGTypeMark with: #segmentMark in: preferences. #none} .
{#segmentArrow. 'Arrow' translated. category. DrGTypeArrow with: #segmentArrow in: preferences. #none }
}! !
!DrGPlatform methodsFor: 'default preferences' stamp: 'hlsf 9/25/2022 10:27:20'!
textPreferences
" name - description - category - type - value "
| category |
category _ #text translated asSymbol.
^ {
{#textColor. 'Colour' translated. category. DrGTypeColor with: #textColor in: preferences. Color black} .
{#textBackgroundColor. 'Background' translated. category. DrGTypeColor with: #textBackgroundColor in: preferences. Color white }.
{#textBorderColor. 'Border' translated. category. DrGTypeColor with: #textBorderColor in: preferences. Color white }.
}! !
!DrGPlatform methodsFor: 'default preferences' stamp: 'hlsf 9/25/2022 10:27:40'!
valuePreferences
" name - description - category - type - value "
| category |
category _ #value translated asSymbol.
^ {
{#valueColor. 'Colour' translated. category. DrGTypeColor with: #valueColor in: preferences. Color black} .
{#valueDecimal. 'Number of decimal' translated. category. (0 to: 9) asArray. 2}
}! !
!DrGPlatform methodsFor: 'default preferences' stamp: 'hlsf 9/25/2022 10:28:12'!
vectorPreferences
" name - description - category - type - value "
| category |
category _ #vector translated asSymbol.
^ {
{#vectorColor. 'Colour' translated. category. DrGTypeColor with: #vectorColor in: preferences. Color black} .
{#vectorThickness. 'Thickness' translated. category. DrGTypeThickness with: #vectorThickness in: preferences. #small} .
{#vectorStyle. 'Style' translated. category. DrGTypeStyle with: #vectorStyle in: preferences. #plain}
}! !
!DrGPlatform methodsFor: 'initialize-release' stamp: 'hlsf 5/25/2023 14:50:40'!
backgroundImage
WorldMorph allInstances first backgroundImageData:
(DrGeoSystem backgroundsPath files
atRandom: (Random seed: Time now nanoSecond)) binaryContents ! !
!DrGPlatform methodsFor: 'initialize-release' stamp: 'hlsf 4/8/2022 11:38:24'!
checkForPaths
self mySketchesPath assureExistence.
self mySmalltalkSketchesPath assureExistence ! !
!DrGPlatform methodsFor: 'initialize-release' stamp: 'hlsf 7/6/2022 09:25:01'!
reset
toolbarIconSize _ nil.
preferences _ nil! !
!DrGPlatform methodsFor: 'initialize-release' stamp: 'hlsf 12/22/2022 09:26:07'!
setCodeCompletion
| class |
class _ Locale current isoLanguage asSymbol
caseOf: {
[#fr] -> [DrGeoFigure]
}
otherwise: [DrGeoSketch].
DrGeoSystem preferences at: #programmingCodeCompletion put: class! !
!DrGPlatform methodsFor: 'initialize-release' stamp: 'hlsf 2/23/2023 11:35:38'!
setDefaultPreferences
preferences _ PreferenceSet new.
#(pointPreferences linePreferences rayPreferences segmentPreferences circlePreferences
arcPreferences polygonPreferences vectorPreferences locusPreferences
textPreferences valuePreferences programmingPreferences miscPreferences) do: [:preferencesData|
(self perform: preferencesData) do: [:data |
preferences
name: data first
description: data second
category: data third
type: data fourth
value: data fifth ] ].
^ preferences! !
!DrGPlatform methodsFor: 'initialize-release' stamp: 'hlsf 8/16/2022 12:30:47'!
splash
| splash copy background position |
splash _ ImageReadWriter formFromFileEntry: (DrGeoSystem iconsPath // 'splash.bmp').
position _ Display center - (splash extent // 2).
background _ Form fromDisplay: (position extent: splash extent).
0.0 to: 1.0 by: 0.2 do: [:t |
copy _ background copy.
copy copyBits: splash at: 0@0 translucent: t.
copy displayAt: position.
(Delay forMilliseconds: 100) wait].
(Delay forSeconds: 2) wait.
background displayAt: position! !
!DrGPlatform methodsFor: 'initialize-release' stamp: 'hlsf 12/22/2022 09:23:44'!
startUp
self setFontPreferences.
Transcript show: '[DrGeo] Font installed'; cr.
self checkForPaths.
Transcript show: '[DrGeo] Paths checked'; cr.
self setCodeCompletion! !
!DrGPlatform methodsFor: 'path' stamp: 'hlsf 5/24/2023 16:14:37'!
backgroundsPath
^ self iconsPath / 'backgrounds'! !
!DrGPlatform methodsFor: 'path' stamp: 'drgeo 9/10/2022 16:16:25'!
examplesPath
^ self resourcesPath / 'Sketches'! !
!DrGPlatform methodsFor: 'path' stamp: 'hlsf 8/16/2022 11:34:26'!
fontPath
^ self resourcesPath / 'fonts'! !
!DrGPlatform methodsFor: 'path' stamp: 'hlsf 8/16/2022 11:34:14'!
iconsPath
^ self resourcesPath / 'icons'! !
!DrGPlatform methodsFor: 'path' stamp: 'hlsf 2/23/2023 10:49:39'!
myExportsPath
^ self userPath / 'MyExports'! !
!DrGPlatform methodsFor: 'path' stamp: 'hlsf 2/23/2023 10:49:45'!
mySketchesPath
^self userPath / 'MySketches'! !
!DrGPlatform methodsFor: 'path' stamp: 'hlsf 2/23/2023 10:49:52'!
mySmalltalkSketchesPath
^self userPath / 'MySmalltalkSketches'! !
!DrGPlatform methodsFor: 'path' stamp: 'hlsf 2/23/2023 10:47:05'!
resourcesPath
"Where are located folders for icons, fonts, sketches, scripts, documentation, images, user created resources"
^ self rootPath / 'Resources'! !
!DrGPlatform methodsFor: 'path' stamp: 'hlsf 6/8/2021 19:42:01'!
rootPath
"When deployed, the DrGeo/ directory"
^ DirectoryEntry smalltalkImageDirectory parent parent! !
!DrGPlatform methodsFor: 'path' stamp: 'hlsf 8/16/2022 11:36:11'!
smalltalkSketchesPath
^self resourcesPath / 'SmalltalkSketches'! !
!DrGPlatform methodsFor: 'path' stamp: 'hlsf 2/23/2023 15:21:41'!
userPath
"Where are located user created resources as sketch, Smalltalk sketch and exported sketch to image"
^ (self preferences at: #userPath)
ifNotEmpty: [:userPath | | userDirectoryEntry |
userDirectoryEntry _ userPath asDirectoryEntry .
" Check if it is a relative path or an absolute path "
userDirectoryEntry pathName = userPath
ifTrue: [userDirectoryEntry "Absolute path"]
ifFalse: ["Relative path, append the home/user directory if any"
Smalltalk at: #home
ifPresent: [:home | home / userPath]
ifAbsent: [userDirectoryEntry ] ] ]
ifEmpty: [self resourcesPath]
! !
!DrGPlatform methodsFor: 'user interface'!
showVirtualKeyboard: boolean
! !
!DrGPlatform methodsFor: 'user interface' stamp: 'hlsf 8/4/2022 23:06:44'!
toggleFullscreen
| isFullscreen |
isFullscreen _ [ Preferences at: #fullscreen ]
on: Error
do: [Preferences name: #fullscreen category: #gui value: true.
true].
Preferences at: #fullscreen put: isFullscreen not.
Display fullScreenMode: isFullscreen not! !
!DrGPlatform methodsFor: 'user interface' stamp: 'hlsf 10/19/2022 16:04:57'!
toolbarIconSize
^ 50! !
!DrGPlatform methodsFor: 'user interface' stamp: 'hlsf 9/23/2021 11:01:16'!
wheelHeight
^ 120! !
!DrGPlatform methodsFor: 'user interface' stamp: 'hlsf 5/25/2023 17:42:25'!
wheelWidth
^ 25! !
!DrGPlatform methodsFor: 'testing'!
isAndroid
^ false! !
!DrGPlatform methodsFor: 'testing'!
isSystem
"Preferences for a DrGeo development environment"
^ false! !
!DrGPlatform methodsFor: 'testing'!
isWorkstation
"Preferences for Windows/Linux/Mac workstation"
^ false! !
!DrGPlatform methodsFor: 'testing'!
isiPad
^ false! !
!DrGPlatform methodsFor: 'accessing' stamp: 'hlsf 4/21/2020 21:32:20'!
canWeDisplaySpinner
^ canWeDisplaySpinner! !
!DrGPlatform methodsFor: 'accessing' stamp: 'hlsf 7/3/2022 12:54:50'!
preferences
^ preferences ifNil: [self setDefaultPreferences]! !
!DrGPlatform methodsFor: 'font'!
canvasFontSize
^ 9! !
!DrGPlatform methodsFor: 'font' stamp: 'hlsf 11/18/2023 16:21:30'!
fontManager
^ fontManager ifNil: [fontManager := self initFontManager]! !
!DrGPlatform methodsFor: 'font' stamp: 'hlsf 11/19/2023 21:56:09'!
initFontManager
| font |
fontManager := LanguageFontManager new.
font := LanguageFont family: 'UnDotum' file: 'UnDotum.ttf'.
font addLocale: (LocaleID isoLanguage: 'ko').
fontManager add: font.
font := LanguageFont family: 'IPAexGothic' file: 'ipaexg.ttf'.
font addLocale: (LocaleID isoLanguage: 'ja').
fontManager add: font.
font := LanguageFont family: 'WenQuanYi Micro Hei' file: 'wqy-microhei.ttc'.
font addLocale:(LocaleID isoLanguage: 'zh').
fontManager add: font! !
!DrGPlatform methodsFor: 'font' stamp: 'hlsf 11/19/2023 20:57:11'!
setFontPreferences
| languageFont |
" Pick an appropriate font file for the current locale, if necessary "
languageFont := self fontManager languageFontFor: Locale current.
languageFont ifNotNil: [
TrueTypeFontFamily readTrueTypeFontEntry: self fontPath // languageFont file.
PreferenceSet setDefaultFont: languageFont family ].
Preferences at: #defaultFontSize put: 12! !
!DrGDevelopment methodsFor: 'initialization' stamp: 'hlsf 11/18/2023 16:18:27'!
initialize
self initFontManager.
canWeDisplaySpinner := false.
self flag: #drgeoTodo.
Preferences
at: #fullScreenLeavesDeskMargins put: true;
at: #defaultFontSize put: 12;
at: #worldMenu put: TheWorldMenu.! !
!DrGDevelopment methodsFor: 'testing'!
isSystem
"I hold the Dr. Geo development environment preferences"
^ true! !
!DrGDevelopment methodsFor: 'path' stamp: 'hlsf 5/24/2023 16:15:16'!
backgroundsPath
^ self resourcesPath / 'graphics' / 'backgrounds'! !
!DrGDevelopment methodsFor: 'path' stamp: 'hlsf 8/17/2022 15:13:41'!
iconsPath
^ self resourcesPath / 'graphics' / 'iconsSVG'! !
!DrGDevelopment methodsFor: 'path' stamp: 'hlsf 8/17/2022 15:13:13'!
resourcesPath
" The resources are in the Dr. Geo source code local repository "
^ self rootPath / 'drgeo' / 'resources'! !
!DrGDevelopment methodsFor: 'path' stamp: 'hlsf 8/16/2022 11:40:41'!
rootPath
" Regarding the development environement, we consider the root path to be
Cuis-Smalltalk-Dev from where is taking place the DrGeo development "
^ DirectoryEntry smalltalkImageDirectory! !
!DrGDevelopment methodsFor: 'font' stamp: 'hlsf 8/12/2023 14:05:12'!
setFontPreferences
PreferenceSet setDefaultFont: 'DejaVu Sans'.
Preferences at: #defaultFontSize put: 11.
! !
!DrGWorkstation methodsFor: 'initialize-release' stamp: 'hlsf 8/17/2022 15:25:28'!
checkForPaths
super checkForPaths.
self myExportsPath assureExistence ! !
!DrGWorkstation methodsFor: 'initialize-release' stamp: 'hlsf 11/18/2023 16:18:38'!
initialize
self initFontManager.
canWeDisplaySpinner := true.
Preferences
at: #worldMenu put: DrGeo;
at: #fullScreenLeavesDeskMargins put: false;
at: #defaultFontSize put: 12.
UISupervisor ui taskbar scale: 1/2.! !
!DrGWorkstation methodsFor: 'initialize-release' stamp: 'hlsf 6/24/2023 22:32:43'!
startUp
super startUp.
Utilities setAuthorName: 'DrGeoUser' initials: 'drgeo'.
"self backgroundImage.
Transcript show: '[DrGeo] Background done'; cr."
self splash.
Transcript show: '[DrGeo] Splash done'; cr.! !
!DrGWorkstation methodsFor: 'testing'!
isWorkstation
^ true! !
!DrGWorkstation methodsFor: 'as yet unclassified' stamp: 'drgeo 8/17/2022 17:14:00'!
rootPath
" Test purpose, point to the bundle "
" ^ DirectoryEntry smalltalkImageDirectory / 'drgeo' / 'build' / 'bundles' / 'gnulinux' / 'DrGeo'"
^ super rootPath! !
!DrGeoSystem class methodsFor: 'system startup'!
addStartUp
Smalltalk addToStartUpList: self! !
!DrGeoSystem class methodsFor: 'system startup' stamp: 'hlsf 8/16/2022 21:54:17'!
removeStartUp
"self removeStartUp"
Smalltalk removeFromStartUpList: self! !
!DrGeoSystem class methodsFor: 'system startup' stamp: 'hlsf 11/19/2023 13:33:50'!
startUp
Transcript show: '[DrGeo] Init startUp'; cr.
platform startUp
! !
!DrGeoSystem class methodsFor: 'class initialization' stamp: 'hlsf 3/12/2022 16:30:26'!
beDevelopment
"Be like the Cuis environment as the DrGeo development environment"
"self beDevelopment"
platform _ DrGDevelopment new.
self removeStartUp.
platform startUp. "manual startUp for additional initialization occuring at system start up"! !
!DrGeoSystem class methodsFor: 'class initialization' stamp: 'drgeo 8/27/2022 15:56:59'!
beWorkstation
"self beWorkstation"
platform _ DrGWorkstation new.
self addStartUp! !
!DrGeoSystem class methodsFor: 'class initialization' stamp: 'Install-DrGeoFrench 12/7/2022 16:16:08'!
initialize
"Erudite extention for Dr. Geo"
EruditeMarkupGrammar addCodeAction: 'withDrGeoActions'! !
!DrGeoSystem class methodsFor: 'class initialization' stamp: 'hlsf 7/3/2022 12:50:46'!
reset
platform reset.
DrGIcons reset. "flush icons cach"! !
!DrGeoSystem class methodsFor: 'user interface' stamp: 'hlsf 7/3/2022 13:36:53'!
preferences
^ platform preferences ! !
!DrGeoSystem class methodsFor: 'user interface' stamp: 'hlsf 3/27/2022 14:20:50'!
previewSize
^ 300@200! !
!DrGeoSystem class methodsFor: 'user interface' stamp: 'hlsf 4/24/2020 11:43:31'!
replicateDisplayWidth
"the sensible extent area width under mouse"
^ 80! !
!DrGeoSystem class methodsFor: 'user interface' stamp: 'hlsf 8/4/2021 10:49:08'!
showVirtualKeyboard: boolean
platform ifNotNil: [
platform showVirtualKeyboard: boolean]! !
!DrGeoSystem class methodsFor: 'user interface' stamp: 'hlsf 4/21/2020 21:31:40'!
startSpinner
self canWeDisplaySpinner ifTrue: [WaitSpinner start]! !
!DrGeoSystem class methodsFor: 'user interface' stamp: 'hlsf 4/21/2020 21:31:02'!
stopSpinner
WaitSpinner stop! !
!DrGeoSystem class methodsFor: 'user interface' stamp: 'hlsf 8/4/2022 22:55:40'!
toggleFullscreen
platform toggleFullscreen ! !
!DrGeoSystem class methodsFor: 'user interface'!
toolbarIconSize
^ platform toolbarIconSize ! !
!DrGeoSystem class methodsFor: 'user interface'!
wheelHeight
^ platform wheelHeight ! !
!DrGeoSystem class methodsFor: 'user interface'!
wheelWidth
^ platform wheelWidth! !
!DrGeoSystem class methodsFor: 'font' stamp: 'hlsf 3/11/2022 23:07:10'!
canvasFont
^ self fontOfSize: self canvasFontSize! !
!DrGeoSystem class methodsFor: 'font'!
canvasFontSize
^ platform canvasFontSize! !
!DrGeoSystem class methodsFor: 'font' stamp: 'hlsf 12/10/2022 17:27:50'!
fontOfSize: anInteger
^ FontFamily defaultFamilyPointSize: anInteger! !
!DrGeoSystem class methodsFor: 'path' stamp: 'hlsf 5/24/2023 16:13:51'!
backgroundsPath
^ platform backgroundsPath! !
!DrGeoSystem class methodsFor: 'path'!
examplesPath
^ platform examplesPath! !
!DrGeoSystem class methodsFor: 'path' stamp: 'hlsf 12/4/2021 19:40:05'!
iconsPath
^ platform iconsPath! !
!DrGeoSystem class methodsFor: 'path'!
myExportsPath
^ platform myExportsPath! !
!DrGeoSystem class methodsFor: 'path'!
mySketchesPath
"Access to the my Sketch files. There are descirption in XML of geometry sketches."
^ platform mySketchesPath! !
!DrGeoSystem class methodsFor: 'path' stamp: 'hlsf 4/11/2022 21:44:20'!
mySmalltalkSketchesPath
"Access to my Script files. There are Smalltalk scripts computing geometry sketches."
^ platform mySmalltalkSketchesPath ! !
!DrGeoSystem class methodsFor: 'path' stamp: 'hlsf 4/11/2022 21:44:47'!
smalltalkSketchesPath
"Path to the Smalltalk sketches examples. There are written with Smalltalk code."
^ platform smalltalkSketchesPath ! !
!DrGeoSystem class methodsFor: 'testing' stamp: 'hlsf 4/21/2020 21:31:40'!
canWeDisplaySpinner
^ platform canWeDisplaySpinner! !
!DrGeoSystem class methodsFor: 'testing'!
ifNotTablet: aBlock
^ self isTablet ifFalse: [aBlock value]! !
!DrGeoSystem class methodsFor: 'testing'!
ifNotiPad: aBlock
^ platform isiPad ifFalse: [aBlock value]! !
!DrGeoSystem class methodsFor: 'testing'!
ifTablet: aBlock
^ self isTablet ifTrue: [aBlock value]! !
!DrGeoSystem class methodsFor: 'testing'!
isAndroid
^ platform isAndroid! !
!DrGeoSystem class methodsFor: 'testing'!
isSystem
"Are we in the DrGeo development environment"
^ platform isSystem! !
!DrGeoSystem class methodsFor: 'testing'!
isTablet
^ platform isAndroid or: [platform isiPad]! !
!DrGeoSystem class methodsFor: 'testing'!
isWorkstation
"Are we workstation version of DrGeo"
^ platform isWorkstation! !
!DrGeoSystem class methodsFor: 'testing'!
isiPad
^ platform isiPad! !
!DrGeoSystem class methodsFor: 'install' stamp: 'hlsf 8/7/2022 13:18:13'!
cleanUp
"Smalltalk reduceCuis "! !
!DrGeoSystem class methodsFor: 'install' stamp: 'hlsf 11/2/2023 17:00:49'!
install
| world |
"Report by any mean installation and run time"
Transcript
showOnDisplay: false;
logToFile: true;
logToStdout: true.
Smalltalk at: #LogStartupDebugAids put: true.
'Installing updates...' print.
ChangeSet installNewUpdates.
Smalltalk condenseChanges.
"Focus does not follow mouse, it is annoying when editing Smalltalk sketch"
Preferences at: #focusFollowsMouse put: false.
"Adjust font size"
Preferences at: #defaultFontSize put: 12.
'Font preferences set' print.
"Preferences at: #logDebuggerStackToFile put: true."
Preferences at: #autoNumberUserChanges put: false.
"Set Locale and text domains"
Preferences at: #useLocale put: true.
TextDomainManager registerCategoryPrefix: 'DrGeo' domain: 'drgeo'.
TextDomainManager registerCategoryPrefix: 'cuis' domain: 'cuis'.
"Set a default name for authoring"
Utilities setAuthorName: 'Dr. Geo User' initials: 'drgeo'.
'Finalizing installation...' print.
world := UISupervisor ui.
[
(Delay forSeconds: 1) wait.
UISupervisor whenUIinSafeState: [
"Adjust taskbar size"
world taskbar scale: 1/2.
'Task bar rescaled' print.
Display fullScreenMode: true.
"Be quiet"
self cleanUp.
self beWorkstation.
"Remove all morphs"
(world submorphs reject: [:aMorph | aMorph is: #TaskbarMorph])
do: [:each | each delete].
'Morphs deleted' print.
Smalltalk garbageCollect.
'Image cleaned' print.
'Installation ended' print.
'Saving image...' print.
Smalltalk saveAndQuit ]
] fork
! !
!LanguageFont methodsFor: 'accessing' stamp: 'hlsf 11/16/2023 23:00:43'!
addLocale: aLocaleID
locales add: aLocaleID ! !
!LanguageFont methodsFor: 'accessing' stamp: 'hlsf 11/16/2023 23:29:35'!
family
^ family! !
!LanguageFont methodsFor: 'accessing' stamp: 'hlsf 11/16/2023 23:28:48'!
family: aFamilyFont
family := aFamilyFont ! !
!LanguageFont methodsFor: 'accessing' stamp: 'hlsf 11/16/2023 23:29:41'!
file
^ file ! !
!LanguageFont methodsFor: 'accessing' stamp: 'hlsf 11/16/2023 23:29:11'!
file: aFontFile
file := aFontFile ! !
!LanguageFont methodsFor: 'accessing' stamp: 'hlsf 11/17/2023 22:46:50'!
handles: aLocaleID
^ aLocaleID isoCountry
ifNotNil: [
(locales includes: aLocaleID) or: [
"may be some locale indicate not country, check if it is a match for aLocaleID "
locales anySatisfy: [:each |
each isoCountry isNil and: [each isoLanguage = aLocaleID isoLanguage] ] ]
]
ifNil: [locales anySatisfy: [:each | each isoLanguage = aLocaleID isoLanguage] ].
! !
!LanguageFont methodsFor: 'initialization' stamp: 'hlsf 11/16/2023 23:01:36'!
initialize
super initialize.
locales := OrderedCollection new! !
!LanguageFont methodsFor: 'printing' stamp: 'hlsf 11/16/2023 23:47:01'!
printOn: str
str nextPutAll: 'LanguageFont for '.
locales
do: [:each |str nextPutAll: each isoString]
separatedBy: [str nextPut: Character space]
! !
!LanguageFont class methodsFor: 'instance creation' stamp: 'hlsf 11/16/2023 23:30:43'!
family: aString1 file: aString2
^ self new
family: aString1;
file: aString2 ;
yourself! !
!LanguageFontManager methodsFor: 'accessing' stamp: 'hlsf 11/16/2023 23:28:15'!
add: aLanguageFont
languageFonts add: aLanguageFont ! !
!LanguageFontManager methodsFor: 'accessing' stamp: 'hlsf 11/16/2023 23:13:02'!
europeanLang
^ `#(#ast #ca #cs #da #de #en #es #fi #fr #it #nl #pt #ru #sv #tr #uk)`! !
!LanguageFontManager methodsFor: 'accessing' stamp: 'hlsf 11/16/2023 23:21:55'!
languageFontFor: aLocaleID
(self europeanLang includes: aLocaleID isoLanguage asSymbol) ifTrue: [^ nil]. "Use Deja Vu font within Cuis"
^ languageFonts detect: [:each | each handles: aLocaleID] ifNone: [nil]! !
!LanguageFontManager methodsFor: 'initialization' stamp: 'hlsf 11/16/2023 23:07:06'!
initialize
super initialize.
languageFonts := OrderedCollection new! !
!Object methodsFor: '*DrGeo' stamp: 'hlsf 6/20/2021 11:37:54'!
isAngleItem
^false! !
!Object methodsFor: '*DrGeo' stamp: 'hlsf 6/20/2021 11:38:03'!
isArcItem
^false! !
!Object methodsFor: '*DrGeo' stamp: 'hlsf 6/20/2021 11:38:10'!
isBitmapItem
^false! !
!Object methodsFor: '*DrGeo' stamp: 'hlsf 6/20/2021 11:38:15'!
isCircleItem
^false! !
!Object methodsFor: '*DrGeo' stamp: 'hlsf 6/20/2021 11:39:10'!
isCompositeItem
^false! !
!Object methodsFor: '*DrGeo' stamp: 'hlsf 6/20/2021 11:39:16'!
isConstrainedPointItem
^false! !
!Object methodsFor: '*DrGeo' stamp: 'hlsf 6/20/2021 11:39:24'!
isCurveItem
"When true, free point can be constrained on this item line"
^false! !
!Object methodsFor: '*DrGeo' stamp: 'hlsf 6/20/2021 11:39:38'!
isDirectionItem
"When true, this item are straight line with normal and unit vector"
^false! !
!Object methodsFor: '*DrGeo' stamp: 'hlsf 6/20/2021 11:39:45'!
isEquation
^ false! !
!Object methodsFor: '*DrGeo' stamp: 'hlsf 6/20/2021 11:39:50'!
isFreePointItem
^false! !
!Object methodsFor: '*DrGeo' stamp: 'hlsf 6/20/2021 11:39:56'!
isFreePointOnPlaneItem
^false! !
!Object methodsFor: '*DrGeo' stamp: 'hlsf 6/20/2021 11:40:02'!
isGeometricItem
^false! !
!Object methodsFor: '*DrGeo' stamp: 'hlsf 6/20/2021 11:40:10'!
isIntersectableItem
"When true, this curve can be intersected"
^self isCurveItem! !
!Object methodsFor: '*DrGeo' stamp: 'hlsf 6/20/2021 11:40:15'!
isIntersectionPointItem
^false! !
!Object methodsFor: '*DrGeo' stamp: 'hlsf 6/20/2021 11:40:21'!
isLineItem
^false! !
!Object methodsFor: '*DrGeo' stamp: 'hlsf 6/20/2021 11:40:26'!
isLocusItem
^false! !
!Object methodsFor: '*DrGeo' stamp: 'hlsf 6/20/2021 11:40:32'!
isMathItem
^false! !
!Object methodsFor: '*DrGeo' stamp: 'hlsf 6/20/2021 11:40:38'!
isNumberItem
^false! !
!Object methodsFor: '*DrGeo' stamp: 'hlsf 6/20/2021 11:40:43'!
isPointItem
^false! !
!Object methodsFor: '*DrGeo' stamp: 'hlsf 6/20/2021 11:40:49'!
isPointItemOnCurve
^false! !
!Object methodsFor: '*DrGeo' stamp: 'hlsf 6/20/2021 11:40:54'!
isPolygonItem
^false! !
!Object methodsFor: '*DrGeo' stamp: 'hlsf 6/20/2021 11:40:59'!
isRayItem
^false! !
!Object methodsFor: '*DrGeo' stamp: 'hlsf 6/20/2021 11:41:04'!
isScriptItem
^false! !
!Object methodsFor: '*DrGeo' stamp: 'hlsf 6/20/2021 11:41:09'!
isSegmentItem
^false! !
!Object methodsFor: '*DrGeo' stamp: 'hlsf 6/20/2021 11:41:16'!
isTextItem
^false! !
!Object methodsFor: '*DrGeo' stamp: 'hlsf 6/20/2021 11:41:32'!
isValueItem
^false! !
!Object methodsFor: '*DrGeo' stamp: 'hlsf 6/20/2021 11:41:37'!
isVectorItem
^false! !
!Debugger methodsFor: '*DrGeo' stamp: 'hlsf 10/19/2022 21:20:23'!
openMinimalMorphic
"Open a panel debugger"
| oldContextStackIndex window |
oldContextStackIndex _ contextStackIndex.
self expandStack. "Sets contextStackIndex to zero."
window _ DrGDebuggerWindow open: self .
self toggleContextStackIndex: oldContextStackIndex.
^ window! !
!Debugger methodsFor: '*DrGeo' stamp: 'hlsf 10/19/2022 21:16:36'!
openMinimalMorphicLabel: aLabelString
"Open a morphic debugger with the given label"
| oldContextStackIndex window |
oldContextStackIndex _ contextStackIndex.
self expandStack. "Sets contextStackIndex to zero."
window _ DrGDebuggerWindow open: self label: aLabelString.
self toggleContextStackIndex: oldContextStackIndex.
^ window! !
!Debugger class methodsFor: '*DrGeo' stamp: 'hlsf 10/19/2022 21:20:06'!
openMinimalDebugging: aBlock to: aCompiledMethod
"Create a new process to debug aBlock, and step into it."
| processToDebug debugger window |
debugger _ self new.
processToDebug _ aBlock newProcess name: 'debugIt'.
debugger process: processToDebug context: processToDebug suspendedContext.
window _ debugger openMinimalMorphic.
[debugger interruptedContext method == aCompiledMethod]
whileFalse: [debugger send].
^ window ! !
!Debugger class methodsFor: '*DrGeo' stamp: 'hlsf 10/13/2022 20:04:34'!
openMinimalDebugging: aBlock to: aCompiledMethod label: aString
"Create a new process to debug aBlock, and step into it."
| processToDebug debugger window |
debugger _ self new.
processToDebug _ aBlock newProcess name: 'debugIt'.
debugger process: processToDebug context: processToDebug suspendedContext.
window _ debugger openMinimalMorphicLabel: aString.
[debugger interruptedContext method == aCompiledMethod]
whileFalse: [debugger send].
^ window ! !
!Number methodsFor: '*DrGeo' stamp: 'hlsf 5/1/2020 23:32:17'!
closeTo: num
"Tell whether the receiver and arguments are close from each."
num isFloat ifTrue: [ ^ num closeTo: self asFloat ].
^ [ self = num ] ifError: [ false ]! !
!Number methodsFor: '*DrGeo' stamp: 'hlsf 5/1/2020 23:31:58'!
closeTo: num precision: aPrecision
"are these two numbers close?"
num isFloat ifTrue: [ ^ num closeTo: self asFloat precision: aPrecision ].
^ [ self = num ] ifError: [ false ]! !
!Number methodsFor: '*DrGeo' stamp: 'hlsf 10/19/2022 17:11:44'!
printParenthesisOn: aStream
"Add parenthesis when the value is negative"
self < 0
ifTrue: [aStream nextPut: $(.
self printOn: aStream.
aStream nextPut: $)]
ifFalse: [self printOn: aStream]! !
!Number methodsFor: '*DrGeo' stamp: 'hlsf 5/2/2020 12:52:46'!
printShowingDecimalPlaces: digits
^ String
streamContents: [:str | self printOn: str fractionDigits: digits]
estimatedSize: 10 + digits! !
!Float methodsFor: '*DrGeo' stamp: 'hlsf 5/1/2020 23:30:53'!
closeTo: num
"Tell whether the receiver and arguments are close from each."
^ self closeTo: num precision: 0.0001! !
!Float methodsFor: '*DrGeo' stamp: 'hlsf 5/1/2020 23:29:55'!
closeTo: num precision: aPrecision
"Tell whether the receiver and arguments are close from each other given a precision"
num isNumber ifFalse: [ ^ [self = num] ifError: [false]].
self = 0.0 ifTrue: [^ num abs < aPrecision].
num = 0 ifTrue: [^self abs < aPrecision].
^self = num asFloat
or: [(self - num) abs / (self abs max: num abs) < aPrecision]! !
!Float methodsFor: '*DrGeo' stamp: 'hlsf 10/19/2022 17:14:12'!
printParenthesisOn: aStream
"Add parenthesis when the value is negative"
self < 0
ifTrue: [aStream nextPut: $(.
self printOn: aStream fractionDigits: 1.
aStream nextPut: $)]
ifFalse: [self printOn: aStream fractionDigits: 1]! !
!Fraction methodsFor: '*DrGeo' stamp: 'hlsf 10/19/2022 17:15:34'!
printParenthesisOn: aStream
"No need to add parenthesis, it is handled by Fraction>>printOn:"
self printOn: aStream ! !
!Color methodsFor: '*DrGeo' stamp: 'hlsf 3/18/2023 11:00:59'!
hexHtml
^ '#', self hexStringRGB ! !
!Class methodsFor: '*DrGeo-subclass creation' stamp: 'hlsf 4/18/2020 21:29:40'!
subclass: t instanceVariableNames: f classVariableNames: d package: cat
"This is a hack to import DrGeo Pharo code"
| answer |
answer _ ClassBuilder new
superclass: self
subclass: t
instanceVariableNames: f
classVariableNames: d
poolDictionaries: nil
category: cat.
Smalltalk
logChange: answer definition
preamble: answer definitionPreamble.
^answer
! !
!SequenceableCollection methodsFor: '*DrGeo' stamp: 'hlsf 2/24/2022 22:32:55'!
shiftRight
^ self allButFirst, (Array with: self first)! !
!LinkedList methodsFor: '*DrGeo-Link' stamp: 'hlsf 5/30/2021 12:04:40'!
add: aLink afterLink: otherLink
"Add otherLink after link in the list. Answer aLink."
| savedLink |
lastLink == otherLink ifTrue: [^ self addLast: aLink].
savedLink _ otherLink nextLink.
otherLink nextLink: aLink.
aLink nextLink: savedLink.
^aLink.! !
!LinkedList methodsFor: '*DrGeo-Link' stamp: 'hlsf 5/30/2021 11:57:04'!
linksDo: aBlock
| aLink |
aLink _ firstLink.
[aLink == nil ] whileFalse: [
aBlock value: aLink.
aLink _ aLink nextLink]! !
!RealEstateAgent class methodsFor: '*DrGeo' stamp: 'hlsf 4/24/2020 12:36:51'!
leftMaximumUsableArea
"Return the left half of the usable area"
| rectangle |
rectangle _ self maximumUsableArea.
^ rectangle origin corner: rectangle bottomCenter! !
!RealEstateAgent class methodsFor: '*DrGeo' stamp: 'hlsf 4/24/2020 12:36:28'!
rightMaximumUsableArea
"Return the left half of the usable area"
| rectangle |
rectangle _ self maximumUsableArea.
^ rectangle topCenter corner: rectangle corner! !
!Point methodsFor: '*DrGeo' stamp: 'hlsf 5/1/2020 23:35:38'!
closeTo: aPoint
^ (x closeTo: aPoint x) and: [ y closeTo: aPoint y ]! !
!Point methodsFor: '*DrGeo' stamp: 'hlsf 3/18/2023 16:31:42'!
printCouple
^ String streamContents: [:str | self printCoupleOn: str]
! !
!Point methodsFor: '*DrGeo' stamp: 'hlsf 3/18/2023 14:17:55'!
printCoupleOn: aStream
" print as 'x,y' "
x printOn: aStream.
aStream nextPut: $,.
y printOn: aStream! !
!Point methodsFor: '*DrGeo' stamp: 'hlsf 3/18/2023 15:52:02'!
printMini
^ String streamContents: [:str | self printMinimumOn: str]
! !
!Point methodsFor: '*DrGeo' stamp: 'hlsf 3/18/2023 15:51:01'!
printMinimumOn: aStream
" print as 'x,y' "
x printOn: aStream.
aStream nextPut: Character space.
y printOn: aStream! !
!Point methodsFor: '*DrGeo' stamp: 'hlsf 5/31/2021 18:40:16'!
printShowingDecimalPlaces: placeDesired
"do not round when coordinate is a fraction"
|stringX stringY|
x isFraction
ifTrue: [stringX _ x printString]
ifFalse: [stringX _ x printShowingDecimalPlaces: placeDesired].
y isFraction
ifTrue: [stringY _ y printString]
ifFalse: [stringY _ y printShowingDecimalPlaces: placeDesired].
^ stringX, '@', stringY! !
!Point methodsFor: '*DrGeo' stamp: 'hlsf 5/31/2021 18:38:18'!
reflexionBy: aPoint direction: aDirection
"the reflected point according to the axe defined by aPoint and aDirection"
^ ((self - aPoint) vectorReflexionBy: aDirection) + aPoint! !
!Point methodsFor: '*DrGeo' stamp: 'hlsf 5/31/2021 18:44:12'!
rotateBy: angle about: center
"This method returns the point obtained after rotating myself (counter clockwise)
around the #center point of an #angle given as parameter. The #angle provided as
parameter is interpreted as being in radian."
| p r theta |
p _ self - center.
r _ p r.
theta _ angle asFloat - p theta.
^ (center x asFloat + (r * theta cos)) @ (center y asFloat - (r * theta sin))! !
!Point methodsFor: '*DrGeo' stamp: 'hlsf 5/31/2021 18:39:43'!
rotateVector: anAngle
|cosa sina|
cosa _ anAngle cos.
sina _ anAngle sin.
^ (x * cosa - (y * sina))@(x * sina + (y * cosa))! !
!Point methodsFor: '*DrGeo' stamp: 'hlsf 8/4/2021 12:08:01'!
roundTo: quantum
^ (x roundTo: quantum) @ (y roundTo: quantum)! !
!Point methodsFor: '*DrGeo' stamp: 'hlsf 5/31/2021 18:37:51'!
vectorReflexionBy: aDirection
"the reflected vector according to the direction"
| unit normal |
[unit _ aDirection normalized.
normal _ unit normal]
on: ZeroDivide
do: [ unit _ 0@0.
normal _ 0@0].
^((self dotProduct: unit) * unit) - ((self dotProduct: normal) * normal)
! !
!BoxedMorph methodsFor: '*DrGeo' stamp: 'hlsf 1/3/2022 09:57:24'!
morphCenter
^ extent // 2! !
!BoxedMorph methodsFor: '*DrGeo' stamp: 'hlsf 1/3/2022 08:55:19'!
morphCenter: aPoint
"Positionning centered in its owner, according to its extent"
self morphPosition: aPoint - (extent // 2) + (`1@1`)! !
!MenuItemMorph methodsFor: '*DrGeo' stamp: 'hlsf 1/3/2022 09:01:34'!
arguments
^ arguments! !
!MorphicEruditeDocRenderer methodsFor: '*DrGeo' stamp: 'MM 10/27/2022 11:00:56'!
createButton: aForm action: aBlock balloonText: balloonText
| button |
button _ ImageMorph new image: aForm; yourself.
button setBalloonText: balloonText.
button setProperty: #handlesMouseDown: toValue: true.
button setProperty: #'mouseButton1Down:localPosition:' toValue: [:keyEvent :pos | aBlock value].
^ button
! !
!MorphicEruditeDocRenderer methodsFor: '*DrGeo' stamp: 'hlsf 10/27/2022 23:43:29'!
renderCodeCopyToDrGeo: aDocCode
self deprecatedMethod.
self renderCodeWithDrGeoActions: aDocCode ! !
!MorphicEruditeDocRenderer methodsFor: '*DrGeo' stamp: 'hlsf 12/14/2022 15:39:08'!
renderCodeWithDrGeoActions: aDocCode
|text button textModel |
text _ Text string: aDocCode code. .
textModel _ EruditeSmalltalkTextModel withText: text.
textModel formatAndStyle.
stream nextPut: textModel actualContents.
stream nextPut: ' '.
"Add as many buttons as you need here: "
button _ self createButton: Theme current openIcon
action: [requestor triggerEvent: #askToCopyCode with: aDocCode code]
balloonText: 'Copy to the code editor.' translated.
stream nextPut: (Text streamContents: [:s | button printOn: s]).
stream nextPut: ' '. "separation between buttons"
" No additional DrGeo action for now...
button _ self createButton: Theme current imageIcon
action: [ self someDrGeoAction: aDocCode]
balloonText: 'Preview the resulting Sketch when this code is executed.' translated.
stream nextPut: (Text streamContents: [:s | button printOn: s]).
"! !
!MorphicEruditeDocRenderer methodsFor: '*DrGeo' stamp: 'hlsf 12/14/2022 15:38:23'!
someDrGeoAction: aDocCode
^ self shouldBeImplemented ! !
!PreferenceBrowserVisitor methodsFor: '*DrGeo-visitors type' stamp: 'hlsf 7/6/2022 10:53:34'!
visitDrGTypeArrowPreference: aPref
| listMorph |
listMorph _ DropDownButtonMorph
model: aPref type
listGetter: #arrowMorphCollection
indexGetter: #arrowIndex
indexSetter: #arrowIndex: ::
autoDeselect: false;
setBalloonText: aPref description.
views at: aPref nameDetailed put: listMorph! !
!PreferenceBrowserVisitor methodsFor: '*DrGeo-visitors type' stamp: 'hlsf 7/6/2022 10:53:40'!
visitDrGTypeColorPreference: aPref
| listMorph |
listMorph _ DropDownButtonMorph
model: aPref type
listGetter: #colorMorphCollection
indexGetter: #colorIndex
indexSetter: #colorIndex: ::
autoDeselect: false;
setBalloonText: aPref description.
views at: aPref nameDetailed put: listMorph! !
!PreferenceBrowserVisitor methodsFor: '*DrGeo-visitors type' stamp: 'hlsf 7/6/2022 10:53:46'!
visitDrGTypeMarkPreference: aPref
| listMorph |
listMorph _ DropDownButtonMorph
model: aPref type
listGetter: #markMorphCollection
indexGetter: #markIndex
indexSetter: #markIndex: ::
autoDeselect: false;
setBalloonText: aPref description.
views at: aPref nameDetailed put: listMorph! !
!PreferenceBrowserVisitor methodsFor: '*DrGeo-visitors type' stamp: 'hlsf 7/6/2022 10:53:51'!
visitDrGTypePointShapePreference: aPref
| listMorph |
listMorph _ DropDownButtonMorph
model: aPref type
listGetter: #shapeMorphCollection
indexGetter: #pointShapeIndex
indexSetter: #pointShapeIndex: ::
autoDeselect: false;
setBalloonText: aPref description.
views at: aPref nameDetailed put: listMorph! !
!PreferenceBrowserVisitor methodsFor: '*DrGeo-visitors type' stamp: 'hlsf 7/6/2022 10:53:58'!
visitDrGTypePointSizePreference: aPref
| listMorph |
listMorph _ DropDownButtonMorph
model: aPref type
listGetter: #sizeMorphCollection
indexGetter: #pointSizeIndex
indexSetter: #pointSizeIndex: ::
autoDeselect: false;
setBalloonText: aPref description.
views at: aPref nameDetailed put: listMorph! !
!PreferenceBrowserVisitor methodsFor: '*DrGeo-visitors type' stamp: 'hlsf 7/6/2022 10:54:04'!
visitDrGTypeStylePreference: aPref
| listMorph |
listMorph _ DropDownButtonMorph
model: aPref type
listGetter: #styleMorphCollection
indexGetter: #styleIndex
indexSetter: #styleIndex: ::
autoDeselect: false;
setBalloonText: aPref description.
views at: aPref nameDetailed put: listMorph! !
!PreferenceBrowserVisitor methodsFor: '*DrGeo-visitors type' stamp: 'hlsf 7/6/2022 10:54:09'!
visitDrGTypeThicknessPreference: aPref
| listMorph |
listMorph _ DropDownButtonMorph
model: aPref type
listGetter: #thicknessMorphCollection
indexGetter: #thicknessIndex
indexSetter: #thicknessIndex: ::
autoDeselect: false;
setBalloonText: aPref description.
views at: aPref nameDetailed put: listMorph! !
DrGDirectionItem initialize!
DrGeoSystem initialize!
|