combstruct 0.1.0a0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1089) hide show
  1. combstruct/__init__.py +60 -0
  2. combstruct/__main__.py +5 -0
  3. combstruct/catalog.py +293 -0
  4. combstruct/data/ecs00/ecs_0001.json +35 -0
  5. combstruct/data/ecs00/ecs_0002.json +37 -0
  6. combstruct/data/ecs00/ecs_0003.json +35 -0
  7. combstruct/data/ecs00/ecs_0004.json +35 -0
  8. combstruct/data/ecs00/ecs_0005.json +35 -0
  9. combstruct/data/ecs00/ecs_0006.json +39 -0
  10. combstruct/data/ecs00/ecs_0007.json +39 -0
  11. combstruct/data/ecs00/ecs_0008.json +39 -0
  12. combstruct/data/ecs00/ecs_0009.json +40 -0
  13. combstruct/data/ecs00/ecs_0010.json +38 -0
  14. combstruct/data/ecs00/ecs_0011.json +38 -0
  15. combstruct/data/ecs00/ecs_0012.json +38 -0
  16. combstruct/data/ecs00/ecs_0013.json +38 -0
  17. combstruct/data/ecs00/ecs_0014.json +38 -0
  18. combstruct/data/ecs00/ecs_0015.json +37 -0
  19. combstruct/data/ecs00/ecs_0016.json +35 -0
  20. combstruct/data/ecs00/ecs_0017.json +38 -0
  21. combstruct/data/ecs00/ecs_0018.json +37 -0
  22. combstruct/data/ecs00/ecs_0019.json +37 -0
  23. combstruct/data/ecs00/ecs_0020.json +40 -0
  24. combstruct/data/ecs00/ecs_0021.json +38 -0
  25. combstruct/data/ecs00/ecs_0022.json +38 -0
  26. combstruct/data/ecs00/ecs_0023.json +39 -0
  27. combstruct/data/ecs00/ecs_0024.json +37 -0
  28. combstruct/data/ecs00/ecs_0025.json +37 -0
  29. combstruct/data/ecs00/ecs_0026.json +37 -0
  30. combstruct/data/ecs00/ecs_0027.json +38 -0
  31. combstruct/data/ecs00/ecs_0028.json +37 -0
  32. combstruct/data/ecs00/ecs_0029.json +38 -0
  33. combstruct/data/ecs00/ecs_0030.json +38 -0
  34. combstruct/data/ecs00/ecs_0031.json +38 -0
  35. combstruct/data/ecs00/ecs_0032.json +38 -0
  36. combstruct/data/ecs00/ecs_0033.json +37 -0
  37. combstruct/data/ecs00/ecs_0034.json +37 -0
  38. combstruct/data/ecs00/ecs_0035.json +38 -0
  39. combstruct/data/ecs00/ecs_0036.json +36 -0
  40. combstruct/data/ecs00/ecs_0037.json +36 -0
  41. combstruct/data/ecs00/ecs_0038.json +38 -0
  42. combstruct/data/ecs00/ecs_0039.json +35 -0
  43. combstruct/data/ecs00/ecs_0040.json +37 -0
  44. combstruct/data/ecs00/ecs_0041.json +36 -0
  45. combstruct/data/ecs00/ecs_0042.json +37 -0
  46. combstruct/data/ecs00/ecs_0043.json +35 -0
  47. combstruct/data/ecs00/ecs_0044.json +35 -0
  48. combstruct/data/ecs00/ecs_0045.json +35 -0
  49. combstruct/data/ecs00/ecs_0046.json +38 -0
  50. combstruct/data/ecs00/ecs_0047.json +38 -0
  51. combstruct/data/ecs00/ecs_0048.json +41 -0
  52. combstruct/data/ecs00/ecs_0049.json +39 -0
  53. combstruct/data/ecs00/ecs_0050.json +38 -0
  54. combstruct/data/ecs00/ecs_0051.json +39 -0
  55. combstruct/data/ecs00/ecs_0052.json +42 -0
  56. combstruct/data/ecs00/ecs_0053.json +39 -0
  57. combstruct/data/ecs00/ecs_0054.json +38 -0
  58. combstruct/data/ecs00/ecs_0055.json +39 -0
  59. combstruct/data/ecs00/ecs_0056.json +35 -0
  60. combstruct/data/ecs00/ecs_0057.json +35 -0
  61. combstruct/data/ecs00/ecs_0058.json +35 -0
  62. combstruct/data/ecs00/ecs_0059.json +35 -0
  63. combstruct/data/ecs00/ecs_0060.json +35 -0
  64. combstruct/data/ecs00/ecs_0061.json +35 -0
  65. combstruct/data/ecs00/ecs_0062.json +35 -0
  66. combstruct/data/ecs00/ecs_0063.json +35 -0
  67. combstruct/data/ecs00/ecs_0064.json +37 -0
  68. combstruct/data/ecs00/ecs_0065.json +37 -0
  69. combstruct/data/ecs00/ecs_0066.json +35 -0
  70. combstruct/data/ecs00/ecs_0067.json +36 -0
  71. combstruct/data/ecs00/ecs_0068.json +39 -0
  72. combstruct/data/ecs00/ecs_0069.json +36 -0
  73. combstruct/data/ecs00/ecs_0070.json +35 -0
  74. combstruct/data/ecs00/ecs_0071.json +39 -0
  75. combstruct/data/ecs00/ecs_0072.json +39 -0
  76. combstruct/data/ecs00/ecs_0073.json +37 -0
  77. combstruct/data/ecs00/ecs_0074.json +35 -0
  78. combstruct/data/ecs00/ecs_0075.json +37 -0
  79. combstruct/data/ecs00/ecs_0076.json +40 -0
  80. combstruct/data/ecs00/ecs_0077.json +38 -0
  81. combstruct/data/ecs00/ecs_0078.json +36 -0
  82. combstruct/data/ecs00/ecs_0079.json +35 -0
  83. combstruct/data/ecs00/ecs_0080.json +38 -0
  84. combstruct/data/ecs00/ecs_0081.json +38 -0
  85. combstruct/data/ecs00/ecs_0082.json +38 -0
  86. combstruct/data/ecs00/ecs_0083.json +38 -0
  87. combstruct/data/ecs00/ecs_0084.json +38 -0
  88. combstruct/data/ecs00/ecs_0085.json +38 -0
  89. combstruct/data/ecs00/ecs_0086.json +38 -0
  90. combstruct/data/ecs00/ecs_0087.json +38 -0
  91. combstruct/data/ecs00/ecs_0088.json +38 -0
  92. combstruct/data/ecs00/ecs_0089.json +35 -0
  93. combstruct/data/ecs00/ecs_0090.json +35 -0
  94. combstruct/data/ecs00/ecs_0091.json +35 -0
  95. combstruct/data/ecs00/ecs_0092.json +37 -0
  96. combstruct/data/ecs00/ecs_0093.json +37 -0
  97. combstruct/data/ecs00/ecs_0094.json +37 -0
  98. combstruct/data/ecs00/ecs_0095.json +35 -0
  99. combstruct/data/ecs00/ecs_0096.json +35 -0
  100. combstruct/data/ecs00/ecs_0097.json +38 -0
  101. combstruct/data/ecs00/ecs_0098.json +38 -0
  102. combstruct/data/ecs00/ecs_0099.json +36 -0
  103. combstruct/data/ecs01/ecs_0100.json +35 -0
  104. combstruct/data/ecs01/ecs_0101.json +38 -0
  105. combstruct/data/ecs01/ecs_0102.json +35 -0
  106. combstruct/data/ecs01/ecs_0103.json +38 -0
  107. combstruct/data/ecs01/ecs_0104.json +38 -0
  108. combstruct/data/ecs01/ecs_0105.json +38 -0
  109. combstruct/data/ecs01/ecs_0106.json +38 -0
  110. combstruct/data/ecs01/ecs_0107.json +35 -0
  111. combstruct/data/ecs01/ecs_0108.json +35 -0
  112. combstruct/data/ecs01/ecs_0109.json +38 -0
  113. combstruct/data/ecs01/ecs_0110.json +36 -0
  114. combstruct/data/ecs01/ecs_0111.json +36 -0
  115. combstruct/data/ecs01/ecs_0112.json +38 -0
  116. combstruct/data/ecs01/ecs_0113.json +35 -0
  117. combstruct/data/ecs01/ecs_0114.json +38 -0
  118. combstruct/data/ecs01/ecs_0115.json +39 -0
  119. combstruct/data/ecs01/ecs_0116.json +38 -0
  120. combstruct/data/ecs01/ecs_0117.json +35 -0
  121. combstruct/data/ecs01/ecs_0118.json +35 -0
  122. combstruct/data/ecs01/ecs_0119.json +35 -0
  123. combstruct/data/ecs01/ecs_0120.json +36 -0
  124. combstruct/data/ecs01/ecs_0121.json +38 -0
  125. combstruct/data/ecs01/ecs_0122.json +36 -0
  126. combstruct/data/ecs01/ecs_0123.json +34 -0
  127. combstruct/data/ecs01/ecs_0124.json +37 -0
  128. combstruct/data/ecs01/ecs_0125.json +36 -0
  129. combstruct/data/ecs01/ecs_0126.json +35 -0
  130. combstruct/data/ecs01/ecs_0127.json +38 -0
  131. combstruct/data/ecs01/ecs_0128.json +35 -0
  132. combstruct/data/ecs01/ecs_0129.json +35 -0
  133. combstruct/data/ecs01/ecs_0130.json +36 -0
  134. combstruct/data/ecs01/ecs_0131.json +37 -0
  135. combstruct/data/ecs01/ecs_0132.json +38 -0
  136. combstruct/data/ecs01/ecs_0133.json +38 -0
  137. combstruct/data/ecs01/ecs_0134.json +38 -0
  138. combstruct/data/ecs01/ecs_0135.json +38 -0
  139. combstruct/data/ecs01/ecs_0136.json +38 -0
  140. combstruct/data/ecs01/ecs_0137.json +35 -0
  141. combstruct/data/ecs01/ecs_0138.json +39 -0
  142. combstruct/data/ecs01/ecs_0139.json +38 -0
  143. combstruct/data/ecs01/ecs_0140.json +38 -0
  144. combstruct/data/ecs01/ecs_0141.json +35 -0
  145. combstruct/data/ecs01/ecs_0142.json +38 -0
  146. combstruct/data/ecs01/ecs_0143.json +38 -0
  147. combstruct/data/ecs01/ecs_0144.json +34 -0
  148. combstruct/data/ecs01/ecs_0145.json +38 -0
  149. combstruct/data/ecs01/ecs_0146.json +38 -0
  150. combstruct/data/ecs01/ecs_0147.json +38 -0
  151. combstruct/data/ecs01/ecs_0148.json +35 -0
  152. combstruct/data/ecs01/ecs_0149.json +36 -0
  153. combstruct/data/ecs01/ecs_0150.json +38 -0
  154. combstruct/data/ecs01/ecs_0151.json +39 -0
  155. combstruct/data/ecs01/ecs_0152.json +35 -0
  156. combstruct/data/ecs01/ecs_0153.json +37 -0
  157. combstruct/data/ecs01/ecs_0154.json +36 -0
  158. combstruct/data/ecs01/ecs_0155.json +38 -0
  159. combstruct/data/ecs01/ecs_0156.json +37 -0
  160. combstruct/data/ecs01/ecs_0157.json +36 -0
  161. combstruct/data/ecs01/ecs_0158.json +38 -0
  162. combstruct/data/ecs01/ecs_0159.json +37 -0
  163. combstruct/data/ecs01/ecs_0160.json +36 -0
  164. combstruct/data/ecs01/ecs_0161.json +35 -0
  165. combstruct/data/ecs01/ecs_0162.json +35 -0
  166. combstruct/data/ecs01/ecs_0163.json +38 -0
  167. combstruct/data/ecs01/ecs_0164.json +38 -0
  168. combstruct/data/ecs01/ecs_0165.json +38 -0
  169. combstruct/data/ecs01/ecs_0166.json +35 -0
  170. combstruct/data/ecs01/ecs_0167.json +34 -0
  171. combstruct/data/ecs01/ecs_0168.json +38 -0
  172. combstruct/data/ecs01/ecs_0169.json +38 -0
  173. combstruct/data/ecs01/ecs_0170.json +38 -0
  174. combstruct/data/ecs01/ecs_0171.json +38 -0
  175. combstruct/data/ecs01/ecs_0172.json +36 -0
  176. combstruct/data/ecs01/ecs_0173.json +36 -0
  177. combstruct/data/ecs01/ecs_0174.json +38 -0
  178. combstruct/data/ecs01/ecs_0175.json +38 -0
  179. combstruct/data/ecs01/ecs_0176.json +38 -0
  180. combstruct/data/ecs01/ecs_0177.json +38 -0
  181. combstruct/data/ecs01/ecs_0178.json +38 -0
  182. combstruct/data/ecs01/ecs_0179.json +38 -0
  183. combstruct/data/ecs01/ecs_0180.json +38 -0
  184. combstruct/data/ecs01/ecs_0181.json +38 -0
  185. combstruct/data/ecs01/ecs_0182.json +38 -0
  186. combstruct/data/ecs01/ecs_0183.json +38 -0
  187. combstruct/data/ecs01/ecs_0184.json +38 -0
  188. combstruct/data/ecs01/ecs_0185.json +38 -0
  189. combstruct/data/ecs01/ecs_0186.json +38 -0
  190. combstruct/data/ecs01/ecs_0187.json +38 -0
  191. combstruct/data/ecs01/ecs_0188.json +38 -0
  192. combstruct/data/ecs01/ecs_0189.json +38 -0
  193. combstruct/data/ecs01/ecs_0190.json +38 -0
  194. combstruct/data/ecs01/ecs_0191.json +38 -0
  195. combstruct/data/ecs01/ecs_0192.json +38 -0
  196. combstruct/data/ecs01/ecs_0193.json +38 -0
  197. combstruct/data/ecs01/ecs_0194.json +38 -0
  198. combstruct/data/ecs01/ecs_0195.json +38 -0
  199. combstruct/data/ecs01/ecs_0196.json +38 -0
  200. combstruct/data/ecs01/ecs_0197.json +38 -0
  201. combstruct/data/ecs01/ecs_0198.json +38 -0
  202. combstruct/data/ecs01/ecs_0199.json +38 -0
  203. combstruct/data/ecs02/ecs_0200.json +38 -0
  204. combstruct/data/ecs02/ecs_0201.json +38 -0
  205. combstruct/data/ecs02/ecs_0202.json +39 -0
  206. combstruct/data/ecs02/ecs_0203.json +39 -0
  207. combstruct/data/ecs02/ecs_0204.json +38 -0
  208. combstruct/data/ecs02/ecs_0205.json +38 -0
  209. combstruct/data/ecs02/ecs_0206.json +38 -0
  210. combstruct/data/ecs02/ecs_0207.json +38 -0
  211. combstruct/data/ecs02/ecs_0208.json +38 -0
  212. combstruct/data/ecs02/ecs_0209.json +39 -0
  213. combstruct/data/ecs02/ecs_0210.json +38 -0
  214. combstruct/data/ecs02/ecs_0211.json +38 -0
  215. combstruct/data/ecs02/ecs_0212.json +39 -0
  216. combstruct/data/ecs02/ecs_0213.json +38 -0
  217. combstruct/data/ecs02/ecs_0214.json +38 -0
  218. combstruct/data/ecs02/ecs_0215.json +38 -0
  219. combstruct/data/ecs02/ecs_0216.json +38 -0
  220. combstruct/data/ecs02/ecs_0217.json +38 -0
  221. combstruct/data/ecs02/ecs_0218.json +38 -0
  222. combstruct/data/ecs02/ecs_0219.json +38 -0
  223. combstruct/data/ecs02/ecs_0220.json +38 -0
  224. combstruct/data/ecs02/ecs_0221.json +38 -0
  225. combstruct/data/ecs02/ecs_0222.json +38 -0
  226. combstruct/data/ecs02/ecs_0223.json +38 -0
  227. combstruct/data/ecs02/ecs_0224.json +38 -0
  228. combstruct/data/ecs02/ecs_0225.json +38 -0
  229. combstruct/data/ecs02/ecs_0226.json +38 -0
  230. combstruct/data/ecs02/ecs_0227.json +38 -0
  231. combstruct/data/ecs02/ecs_0228.json +38 -0
  232. combstruct/data/ecs02/ecs_0229.json +38 -0
  233. combstruct/data/ecs02/ecs_0230.json +38 -0
  234. combstruct/data/ecs02/ecs_0231.json +37 -0
  235. combstruct/data/ecs02/ecs_0232.json +39 -0
  236. combstruct/data/ecs02/ecs_0233.json +38 -0
  237. combstruct/data/ecs02/ecs_0234.json +38 -0
  238. combstruct/data/ecs02/ecs_0235.json +38 -0
  239. combstruct/data/ecs02/ecs_0236.json +38 -0
  240. combstruct/data/ecs02/ecs_0237.json +38 -0
  241. combstruct/data/ecs02/ecs_0238.json +38 -0
  242. combstruct/data/ecs02/ecs_0239.json +38 -0
  243. combstruct/data/ecs02/ecs_0240.json +38 -0
  244. combstruct/data/ecs02/ecs_0241.json +38 -0
  245. combstruct/data/ecs02/ecs_0242.json +38 -0
  246. combstruct/data/ecs02/ecs_0243.json +38 -0
  247. combstruct/data/ecs02/ecs_0244.json +38 -0
  248. combstruct/data/ecs02/ecs_0245.json +38 -0
  249. combstruct/data/ecs02/ecs_0246.json +38 -0
  250. combstruct/data/ecs02/ecs_0247.json +36 -0
  251. combstruct/data/ecs02/ecs_0248.json +38 -0
  252. combstruct/data/ecs02/ecs_0249.json +38 -0
  253. combstruct/data/ecs02/ecs_0250.json +38 -0
  254. combstruct/data/ecs02/ecs_0251.json +38 -0
  255. combstruct/data/ecs02/ecs_0252.json +38 -0
  256. combstruct/data/ecs02/ecs_0253.json +38 -0
  257. combstruct/data/ecs02/ecs_0254.json +39 -0
  258. combstruct/data/ecs02/ecs_0255.json +38 -0
  259. combstruct/data/ecs02/ecs_0256.json +38 -0
  260. combstruct/data/ecs02/ecs_0257.json +38 -0
  261. combstruct/data/ecs02/ecs_0258.json +38 -0
  262. combstruct/data/ecs02/ecs_0259.json +38 -0
  263. combstruct/data/ecs02/ecs_0260.json +38 -0
  264. combstruct/data/ecs02/ecs_0261.json +38 -0
  265. combstruct/data/ecs02/ecs_0262.json +38 -0
  266. combstruct/data/ecs02/ecs_0263.json +38 -0
  267. combstruct/data/ecs02/ecs_0264.json +37 -0
  268. combstruct/data/ecs02/ecs_0265.json +34 -0
  269. combstruct/data/ecs02/ecs_0266.json +37 -0
  270. combstruct/data/ecs02/ecs_0267.json +39 -0
  271. combstruct/data/ecs02/ecs_0268.json +39 -0
  272. combstruct/data/ecs02/ecs_0269.json +39 -0
  273. combstruct/data/ecs02/ecs_0270.json +38 -0
  274. combstruct/data/ecs02/ecs_0271.json +38 -0
  275. combstruct/data/ecs02/ecs_0272.json +38 -0
  276. combstruct/data/ecs02/ecs_0273.json +38 -0
  277. combstruct/data/ecs02/ecs_0274.json +38 -0
  278. combstruct/data/ecs02/ecs_0275.json +38 -0
  279. combstruct/data/ecs02/ecs_0276.json +38 -0
  280. combstruct/data/ecs02/ecs_0277.json +38 -0
  281. combstruct/data/ecs02/ecs_0278.json +38 -0
  282. combstruct/data/ecs02/ecs_0279.json +38 -0
  283. combstruct/data/ecs02/ecs_0280.json +38 -0
  284. combstruct/data/ecs02/ecs_0281.json +38 -0
  285. combstruct/data/ecs02/ecs_0282.json +38 -0
  286. combstruct/data/ecs02/ecs_0283.json +38 -0
  287. combstruct/data/ecs02/ecs_0284.json +38 -0
  288. combstruct/data/ecs02/ecs_0285.json +38 -0
  289. combstruct/data/ecs02/ecs_0286.json +38 -0
  290. combstruct/data/ecs02/ecs_0287.json +38 -0
  291. combstruct/data/ecs02/ecs_0288.json +38 -0
  292. combstruct/data/ecs02/ecs_0289.json +38 -0
  293. combstruct/data/ecs02/ecs_0290.json +38 -0
  294. combstruct/data/ecs02/ecs_0291.json +35 -0
  295. combstruct/data/ecs02/ecs_0292.json +35 -0
  296. combstruct/data/ecs02/ecs_0293.json +35 -0
  297. combstruct/data/ecs02/ecs_0294.json +35 -0
  298. combstruct/data/ecs02/ecs_0295.json +35 -0
  299. combstruct/data/ecs02/ecs_0296.json +35 -0
  300. combstruct/data/ecs02/ecs_0297.json +38 -0
  301. combstruct/data/ecs02/ecs_0298.json +37 -0
  302. combstruct/data/ecs02/ecs_0299.json +36 -0
  303. combstruct/data/ecs03/ecs_0300.json +36 -0
  304. combstruct/data/ecs03/ecs_0301.json +36 -0
  305. combstruct/data/ecs03/ecs_0302.json +36 -0
  306. combstruct/data/ecs03/ecs_0303.json +36 -0
  307. combstruct/data/ecs03/ecs_0304.json +38 -0
  308. combstruct/data/ecs03/ecs_0305.json +38 -0
  309. combstruct/data/ecs03/ecs_0306.json +38 -0
  310. combstruct/data/ecs03/ecs_0307.json +38 -0
  311. combstruct/data/ecs03/ecs_0308.json +38 -0
  312. combstruct/data/ecs03/ecs_0309.json +38 -0
  313. combstruct/data/ecs03/ecs_0310.json +38 -0
  314. combstruct/data/ecs03/ecs_0311.json +38 -0
  315. combstruct/data/ecs03/ecs_0312.json +38 -0
  316. combstruct/data/ecs03/ecs_0313.json +38 -0
  317. combstruct/data/ecs03/ecs_0314.json +38 -0
  318. combstruct/data/ecs03/ecs_0315.json +38 -0
  319. combstruct/data/ecs03/ecs_0316.json +38 -0
  320. combstruct/data/ecs03/ecs_0317.json +38 -0
  321. combstruct/data/ecs03/ecs_0318.json +38 -0
  322. combstruct/data/ecs03/ecs_0319.json +38 -0
  323. combstruct/data/ecs03/ecs_0320.json +38 -0
  324. combstruct/data/ecs03/ecs_0321.json +38 -0
  325. combstruct/data/ecs03/ecs_0322.json +38 -0
  326. combstruct/data/ecs03/ecs_0323.json +38 -0
  327. combstruct/data/ecs03/ecs_0324.json +38 -0
  328. combstruct/data/ecs03/ecs_0325.json +38 -0
  329. combstruct/data/ecs03/ecs_0326.json +38 -0
  330. combstruct/data/ecs03/ecs_0327.json +38 -0
  331. combstruct/data/ecs03/ecs_0328.json +38 -0
  332. combstruct/data/ecs03/ecs_0329.json +38 -0
  333. combstruct/data/ecs03/ecs_0330.json +38 -0
  334. combstruct/data/ecs03/ecs_0331.json +38 -0
  335. combstruct/data/ecs03/ecs_0332.json +38 -0
  336. combstruct/data/ecs03/ecs_0333.json +38 -0
  337. combstruct/data/ecs03/ecs_0334.json +38 -0
  338. combstruct/data/ecs03/ecs_0335.json +38 -0
  339. combstruct/data/ecs03/ecs_0336.json +38 -0
  340. combstruct/data/ecs03/ecs_0337.json +38 -0
  341. combstruct/data/ecs03/ecs_0338.json +38 -0
  342. combstruct/data/ecs03/ecs_0339.json +38 -0
  343. combstruct/data/ecs03/ecs_0340.json +38 -0
  344. combstruct/data/ecs03/ecs_0341.json +38 -0
  345. combstruct/data/ecs03/ecs_0342.json +38 -0
  346. combstruct/data/ecs03/ecs_0343.json +38 -0
  347. combstruct/data/ecs03/ecs_0344.json +38 -0
  348. combstruct/data/ecs03/ecs_0345.json +39 -0
  349. combstruct/data/ecs03/ecs_0346.json +38 -0
  350. combstruct/data/ecs03/ecs_0347.json +38 -0
  351. combstruct/data/ecs03/ecs_0348.json +38 -0
  352. combstruct/data/ecs03/ecs_0349.json +38 -0
  353. combstruct/data/ecs03/ecs_0350.json +38 -0
  354. combstruct/data/ecs03/ecs_0351.json +39 -0
  355. combstruct/data/ecs03/ecs_0352.json +38 -0
  356. combstruct/data/ecs03/ecs_0353.json +38 -0
  357. combstruct/data/ecs03/ecs_0354.json +38 -0
  358. combstruct/data/ecs03/ecs_0355.json +38 -0
  359. combstruct/data/ecs03/ecs_0356.json +38 -0
  360. combstruct/data/ecs03/ecs_0357.json +38 -0
  361. combstruct/data/ecs03/ecs_0358.json +38 -0
  362. combstruct/data/ecs03/ecs_0359.json +38 -0
  363. combstruct/data/ecs03/ecs_0360.json +38 -0
  364. combstruct/data/ecs03/ecs_0361.json +38 -0
  365. combstruct/data/ecs03/ecs_0362.json +38 -0
  366. combstruct/data/ecs03/ecs_0363.json +38 -0
  367. combstruct/data/ecs03/ecs_0364.json +38 -0
  368. combstruct/data/ecs03/ecs_0365.json +38 -0
  369. combstruct/data/ecs03/ecs_0366.json +38 -0
  370. combstruct/data/ecs03/ecs_0367.json +38 -0
  371. combstruct/data/ecs03/ecs_0368.json +38 -0
  372. combstruct/data/ecs03/ecs_0369.json +38 -0
  373. combstruct/data/ecs03/ecs_0370.json +38 -0
  374. combstruct/data/ecs03/ecs_0371.json +39 -0
  375. combstruct/data/ecs03/ecs_0372.json +38 -0
  376. combstruct/data/ecs03/ecs_0373.json +38 -0
  377. combstruct/data/ecs03/ecs_0374.json +38 -0
  378. combstruct/data/ecs03/ecs_0375.json +38 -0
  379. combstruct/data/ecs03/ecs_0376.json +38 -0
  380. combstruct/data/ecs03/ecs_0377.json +38 -0
  381. combstruct/data/ecs03/ecs_0378.json +38 -0
  382. combstruct/data/ecs03/ecs_0379.json +38 -0
  383. combstruct/data/ecs03/ecs_0380.json +38 -0
  384. combstruct/data/ecs03/ecs_0381.json +38 -0
  385. combstruct/data/ecs03/ecs_0382.json +38 -0
  386. combstruct/data/ecs03/ecs_0383.json +38 -0
  387. combstruct/data/ecs03/ecs_0384.json +38 -0
  388. combstruct/data/ecs03/ecs_0385.json +34 -0
  389. combstruct/data/ecs03/ecs_0386.json +38 -0
  390. combstruct/data/ecs03/ecs_0387.json +34 -0
  391. combstruct/data/ecs03/ecs_0388.json +38 -0
  392. combstruct/data/ecs03/ecs_0389.json +38 -0
  393. combstruct/data/ecs03/ecs_0390.json +35 -0
  394. combstruct/data/ecs03/ecs_0391.json +35 -0
  395. combstruct/data/ecs03/ecs_0392.json +38 -0
  396. combstruct/data/ecs03/ecs_0393.json +38 -0
  397. combstruct/data/ecs03/ecs_0394.json +38 -0
  398. combstruct/data/ecs03/ecs_0395.json +37 -0
  399. combstruct/data/ecs03/ecs_0396.json +37 -0
  400. combstruct/data/ecs03/ecs_0397.json +38 -0
  401. combstruct/data/ecs03/ecs_0398.json +38 -0
  402. combstruct/data/ecs03/ecs_0399.json +38 -0
  403. combstruct/data/ecs04/ecs_0400.json +37 -0
  404. combstruct/data/ecs04/ecs_0401.json +38 -0
  405. combstruct/data/ecs04/ecs_0402.json +38 -0
  406. combstruct/data/ecs04/ecs_0403.json +38 -0
  407. combstruct/data/ecs04/ecs_0404.json +34 -0
  408. combstruct/data/ecs04/ecs_0405.json +38 -0
  409. combstruct/data/ecs04/ecs_0406.json +38 -0
  410. combstruct/data/ecs04/ecs_0407.json +38 -0
  411. combstruct/data/ecs04/ecs_0408.json +38 -0
  412. combstruct/data/ecs04/ecs_0409.json +38 -0
  413. combstruct/data/ecs04/ecs_0410.json +38 -0
  414. combstruct/data/ecs04/ecs_0411.json +38 -0
  415. combstruct/data/ecs04/ecs_0412.json +38 -0
  416. combstruct/data/ecs04/ecs_0413.json +39 -0
  417. combstruct/data/ecs04/ecs_0414.json +38 -0
  418. combstruct/data/ecs04/ecs_0415.json +37 -0
  419. combstruct/data/ecs04/ecs_0416.json +37 -0
  420. combstruct/data/ecs04/ecs_0417.json +38 -0
  421. combstruct/data/ecs04/ecs_0418.json +38 -0
  422. combstruct/data/ecs04/ecs_0419.json +38 -0
  423. combstruct/data/ecs04/ecs_0420.json +38 -0
  424. combstruct/data/ecs04/ecs_0421.json +37 -0
  425. combstruct/data/ecs04/ecs_0422.json +38 -0
  426. combstruct/data/ecs04/ecs_0423.json +37 -0
  427. combstruct/data/ecs04/ecs_0424.json +38 -0
  428. combstruct/data/ecs04/ecs_0425.json +38 -0
  429. combstruct/data/ecs04/ecs_0426.json +38 -0
  430. combstruct/data/ecs04/ecs_0427.json +38 -0
  431. combstruct/data/ecs04/ecs_0428.json +34 -0
  432. combstruct/data/ecs04/ecs_0429.json +34 -0
  433. combstruct/data/ecs04/ecs_0430.json +34 -0
  434. combstruct/data/ecs04/ecs_0431.json +38 -0
  435. combstruct/data/ecs04/ecs_0432.json +38 -0
  436. combstruct/data/ecs04/ecs_0433.json +38 -0
  437. combstruct/data/ecs04/ecs_0434.json +38 -0
  438. combstruct/data/ecs04/ecs_0435.json +38 -0
  439. combstruct/data/ecs04/ecs_0436.json +38 -0
  440. combstruct/data/ecs04/ecs_0437.json +38 -0
  441. combstruct/data/ecs04/ecs_0438.json +38 -0
  442. combstruct/data/ecs04/ecs_0439.json +34 -0
  443. combstruct/data/ecs04/ecs_0440.json +38 -0
  444. combstruct/data/ecs04/ecs_0441.json +37 -0
  445. combstruct/data/ecs04/ecs_0442.json +38 -0
  446. combstruct/data/ecs04/ecs_0443.json +37 -0
  447. combstruct/data/ecs04/ecs_0444.json +38 -0
  448. combstruct/data/ecs04/ecs_0445.json +38 -0
  449. combstruct/data/ecs04/ecs_0446.json +35 -0
  450. combstruct/data/ecs04/ecs_0447.json +38 -0
  451. combstruct/data/ecs04/ecs_0448.json +36 -0
  452. combstruct/data/ecs04/ecs_0449.json +38 -0
  453. combstruct/data/ecs04/ecs_0450.json +36 -0
  454. combstruct/data/ecs04/ecs_0451.json +38 -0
  455. combstruct/data/ecs04/ecs_0452.json +38 -0
  456. combstruct/data/ecs04/ecs_0453.json +38 -0
  457. combstruct/data/ecs04/ecs_0454.json +38 -0
  458. combstruct/data/ecs04/ecs_0455.json +38 -0
  459. combstruct/data/ecs04/ecs_0456.json +38 -0
  460. combstruct/data/ecs04/ecs_0457.json +38 -0
  461. combstruct/data/ecs04/ecs_0458.json +38 -0
  462. combstruct/data/ecs04/ecs_0459.json +38 -0
  463. combstruct/data/ecs04/ecs_0460.json +38 -0
  464. combstruct/data/ecs04/ecs_0461.json +38 -0
  465. combstruct/data/ecs04/ecs_0462.json +38 -0
  466. combstruct/data/ecs04/ecs_0463.json +38 -0
  467. combstruct/data/ecs04/ecs_0464.json +38 -0
  468. combstruct/data/ecs04/ecs_0465.json +38 -0
  469. combstruct/data/ecs04/ecs_0466.json +38 -0
  470. combstruct/data/ecs04/ecs_0467.json +38 -0
  471. combstruct/data/ecs04/ecs_0468.json +38 -0
  472. combstruct/data/ecs04/ecs_0469.json +38 -0
  473. combstruct/data/ecs04/ecs_0470.json +38 -0
  474. combstruct/data/ecs04/ecs_0471.json +38 -0
  475. combstruct/data/ecs04/ecs_0472.json +38 -0
  476. combstruct/data/ecs04/ecs_0473.json +38 -0
  477. combstruct/data/ecs04/ecs_0474.json +38 -0
  478. combstruct/data/ecs04/ecs_0475.json +38 -0
  479. combstruct/data/ecs04/ecs_0476.json +38 -0
  480. combstruct/data/ecs04/ecs_0477.json +38 -0
  481. combstruct/data/ecs04/ecs_0478.json +38 -0
  482. combstruct/data/ecs04/ecs_0479.json +38 -0
  483. combstruct/data/ecs04/ecs_0480.json +38 -0
  484. combstruct/data/ecs04/ecs_0481.json +38 -0
  485. combstruct/data/ecs04/ecs_0482.json +38 -0
  486. combstruct/data/ecs04/ecs_0483.json +38 -0
  487. combstruct/data/ecs04/ecs_0484.json +38 -0
  488. combstruct/data/ecs04/ecs_0485.json +38 -0
  489. combstruct/data/ecs04/ecs_0486.json +38 -0
  490. combstruct/data/ecs04/ecs_0487.json +38 -0
  491. combstruct/data/ecs04/ecs_0488.json +38 -0
  492. combstruct/data/ecs04/ecs_0489.json +38 -0
  493. combstruct/data/ecs04/ecs_0490.json +38 -0
  494. combstruct/data/ecs04/ecs_0491.json +38 -0
  495. combstruct/data/ecs04/ecs_0492.json +38 -0
  496. combstruct/data/ecs04/ecs_0493.json +38 -0
  497. combstruct/data/ecs04/ecs_0494.json +38 -0
  498. combstruct/data/ecs04/ecs_0495.json +38 -0
  499. combstruct/data/ecs04/ecs_0496.json +38 -0
  500. combstruct/data/ecs04/ecs_0497.json +38 -0
  501. combstruct/data/ecs04/ecs_0498.json +38 -0
  502. combstruct/data/ecs04/ecs_0499.json +38 -0
  503. combstruct/data/ecs05/ecs_0500.json +38 -0
  504. combstruct/data/ecs05/ecs_0501.json +38 -0
  505. combstruct/data/ecs05/ecs_0502.json +38 -0
  506. combstruct/data/ecs05/ecs_0503.json +38 -0
  507. combstruct/data/ecs05/ecs_0504.json +38 -0
  508. combstruct/data/ecs05/ecs_0505.json +38 -0
  509. combstruct/data/ecs05/ecs_0506.json +38 -0
  510. combstruct/data/ecs05/ecs_0507.json +38 -0
  511. combstruct/data/ecs05/ecs_0508.json +38 -0
  512. combstruct/data/ecs05/ecs_0509.json +38 -0
  513. combstruct/data/ecs05/ecs_0510.json +38 -0
  514. combstruct/data/ecs05/ecs_0511.json +38 -0
  515. combstruct/data/ecs05/ecs_0512.json +38 -0
  516. combstruct/data/ecs05/ecs_0513.json +38 -0
  517. combstruct/data/ecs05/ecs_0514.json +38 -0
  518. combstruct/data/ecs05/ecs_0515.json +38 -0
  519. combstruct/data/ecs05/ecs_0516.json +38 -0
  520. combstruct/data/ecs05/ecs_0517.json +38 -0
  521. combstruct/data/ecs05/ecs_0518.json +38 -0
  522. combstruct/data/ecs05/ecs_0519.json +38 -0
  523. combstruct/data/ecs05/ecs_0520.json +38 -0
  524. combstruct/data/ecs05/ecs_0521.json +38 -0
  525. combstruct/data/ecs05/ecs_0522.json +38 -0
  526. combstruct/data/ecs05/ecs_0523.json +38 -0
  527. combstruct/data/ecs05/ecs_0524.json +38 -0
  528. combstruct/data/ecs05/ecs_0525.json +38 -0
  529. combstruct/data/ecs05/ecs_0526.json +38 -0
  530. combstruct/data/ecs05/ecs_0527.json +38 -0
  531. combstruct/data/ecs05/ecs_0528.json +38 -0
  532. combstruct/data/ecs05/ecs_0529.json +38 -0
  533. combstruct/data/ecs05/ecs_0530.json +38 -0
  534. combstruct/data/ecs05/ecs_0531.json +38 -0
  535. combstruct/data/ecs05/ecs_0532.json +38 -0
  536. combstruct/data/ecs05/ecs_0533.json +38 -0
  537. combstruct/data/ecs05/ecs_0534.json +38 -0
  538. combstruct/data/ecs05/ecs_0535.json +38 -0
  539. combstruct/data/ecs05/ecs_0536.json +38 -0
  540. combstruct/data/ecs05/ecs_0537.json +38 -0
  541. combstruct/data/ecs05/ecs_0538.json +38 -0
  542. combstruct/data/ecs05/ecs_0539.json +38 -0
  543. combstruct/data/ecs05/ecs_0540.json +38 -0
  544. combstruct/data/ecs05/ecs_0541.json +38 -0
  545. combstruct/data/ecs05/ecs_0542.json +38 -0
  546. combstruct/data/ecs05/ecs_0543.json +38 -0
  547. combstruct/data/ecs05/ecs_0544.json +38 -0
  548. combstruct/data/ecs05/ecs_0545.json +38 -0
  549. combstruct/data/ecs05/ecs_0546.json +38 -0
  550. combstruct/data/ecs05/ecs_0547.json +38 -0
  551. combstruct/data/ecs05/ecs_0548.json +38 -0
  552. combstruct/data/ecs05/ecs_0549.json +38 -0
  553. combstruct/data/ecs05/ecs_0550.json +38 -0
  554. combstruct/data/ecs05/ecs_0551.json +38 -0
  555. combstruct/data/ecs05/ecs_0552.json +38 -0
  556. combstruct/data/ecs05/ecs_0553.json +38 -0
  557. combstruct/data/ecs05/ecs_0554.json +38 -0
  558. combstruct/data/ecs05/ecs_0555.json +38 -0
  559. combstruct/data/ecs05/ecs_0556.json +38 -0
  560. combstruct/data/ecs05/ecs_0557.json +38 -0
  561. combstruct/data/ecs05/ecs_0558.json +38 -0
  562. combstruct/data/ecs05/ecs_0559.json +38 -0
  563. combstruct/data/ecs05/ecs_0560.json +38 -0
  564. combstruct/data/ecs05/ecs_0561.json +38 -0
  565. combstruct/data/ecs05/ecs_0562.json +38 -0
  566. combstruct/data/ecs05/ecs_0563.json +38 -0
  567. combstruct/data/ecs05/ecs_0564.json +38 -0
  568. combstruct/data/ecs05/ecs_0565.json +38 -0
  569. combstruct/data/ecs05/ecs_0566.json +38 -0
  570. combstruct/data/ecs05/ecs_0567.json +38 -0
  571. combstruct/data/ecs05/ecs_0568.json +38 -0
  572. combstruct/data/ecs05/ecs_0569.json +38 -0
  573. combstruct/data/ecs05/ecs_0570.json +38 -0
  574. combstruct/data/ecs05/ecs_0571.json +38 -0
  575. combstruct/data/ecs05/ecs_0572.json +38 -0
  576. combstruct/data/ecs05/ecs_0573.json +38 -0
  577. combstruct/data/ecs05/ecs_0574.json +38 -0
  578. combstruct/data/ecs05/ecs_0575.json +38 -0
  579. combstruct/data/ecs05/ecs_0576.json +38 -0
  580. combstruct/data/ecs05/ecs_0577.json +38 -0
  581. combstruct/data/ecs05/ecs_0578.json +38 -0
  582. combstruct/data/ecs05/ecs_0579.json +38 -0
  583. combstruct/data/ecs05/ecs_0580.json +38 -0
  584. combstruct/data/ecs05/ecs_0581.json +38 -0
  585. combstruct/data/ecs05/ecs_0582.json +38 -0
  586. combstruct/data/ecs05/ecs_0583.json +38 -0
  587. combstruct/data/ecs05/ecs_0584.json +38 -0
  588. combstruct/data/ecs05/ecs_0585.json +38 -0
  589. combstruct/data/ecs05/ecs_0586.json +38 -0
  590. combstruct/data/ecs05/ecs_0587.json +38 -0
  591. combstruct/data/ecs05/ecs_0588.json +38 -0
  592. combstruct/data/ecs05/ecs_0589.json +38 -0
  593. combstruct/data/ecs05/ecs_0590.json +38 -0
  594. combstruct/data/ecs05/ecs_0591.json +38 -0
  595. combstruct/data/ecs05/ecs_0592.json +38 -0
  596. combstruct/data/ecs05/ecs_0593.json +38 -0
  597. combstruct/data/ecs05/ecs_0594.json +38 -0
  598. combstruct/data/ecs05/ecs_0595.json +38 -0
  599. combstruct/data/ecs05/ecs_0596.json +38 -0
  600. combstruct/data/ecs05/ecs_0597.json +38 -0
  601. combstruct/data/ecs05/ecs_0598.json +38 -0
  602. combstruct/data/ecs05/ecs_0599.json +38 -0
  603. combstruct/data/ecs06/ecs_0600.json +38 -0
  604. combstruct/data/ecs06/ecs_0601.json +38 -0
  605. combstruct/data/ecs06/ecs_0602.json +38 -0
  606. combstruct/data/ecs06/ecs_0603.json +38 -0
  607. combstruct/data/ecs06/ecs_0604.json +38 -0
  608. combstruct/data/ecs06/ecs_0605.json +38 -0
  609. combstruct/data/ecs06/ecs_0606.json +38 -0
  610. combstruct/data/ecs06/ecs_0607.json +38 -0
  611. combstruct/data/ecs06/ecs_0608.json +38 -0
  612. combstruct/data/ecs06/ecs_0609.json +38 -0
  613. combstruct/data/ecs06/ecs_0610.json +38 -0
  614. combstruct/data/ecs06/ecs_0611.json +38 -0
  615. combstruct/data/ecs06/ecs_0612.json +38 -0
  616. combstruct/data/ecs06/ecs_0613.json +38 -0
  617. combstruct/data/ecs06/ecs_0614.json +38 -0
  618. combstruct/data/ecs06/ecs_0615.json +38 -0
  619. combstruct/data/ecs06/ecs_0616.json +38 -0
  620. combstruct/data/ecs06/ecs_0617.json +38 -0
  621. combstruct/data/ecs06/ecs_0618.json +38 -0
  622. combstruct/data/ecs06/ecs_0619.json +38 -0
  623. combstruct/data/ecs06/ecs_0620.json +38 -0
  624. combstruct/data/ecs06/ecs_0621.json +38 -0
  625. combstruct/data/ecs06/ecs_0622.json +38 -0
  626. combstruct/data/ecs06/ecs_0623.json +38 -0
  627. combstruct/data/ecs06/ecs_0624.json +38 -0
  628. combstruct/data/ecs06/ecs_0625.json +38 -0
  629. combstruct/data/ecs06/ecs_0626.json +38 -0
  630. combstruct/data/ecs06/ecs_0627.json +38 -0
  631. combstruct/data/ecs06/ecs_0628.json +38 -0
  632. combstruct/data/ecs06/ecs_0629.json +38 -0
  633. combstruct/data/ecs06/ecs_0630.json +38 -0
  634. combstruct/data/ecs06/ecs_0631.json +38 -0
  635. combstruct/data/ecs06/ecs_0632.json +38 -0
  636. combstruct/data/ecs06/ecs_0633.json +38 -0
  637. combstruct/data/ecs06/ecs_0634.json +38 -0
  638. combstruct/data/ecs06/ecs_0635.json +38 -0
  639. combstruct/data/ecs06/ecs_0636.json +38 -0
  640. combstruct/data/ecs06/ecs_0637.json +38 -0
  641. combstruct/data/ecs06/ecs_0638.json +38 -0
  642. combstruct/data/ecs06/ecs_0639.json +38 -0
  643. combstruct/data/ecs06/ecs_0640.json +38 -0
  644. combstruct/data/ecs06/ecs_0641.json +38 -0
  645. combstruct/data/ecs06/ecs_0642.json +38 -0
  646. combstruct/data/ecs06/ecs_0643.json +38 -0
  647. combstruct/data/ecs06/ecs_0644.json +38 -0
  648. combstruct/data/ecs06/ecs_0645.json +38 -0
  649. combstruct/data/ecs06/ecs_0646.json +38 -0
  650. combstruct/data/ecs06/ecs_0647.json +38 -0
  651. combstruct/data/ecs06/ecs_0648.json +38 -0
  652. combstruct/data/ecs06/ecs_0649.json +38 -0
  653. combstruct/data/ecs06/ecs_0650.json +38 -0
  654. combstruct/data/ecs06/ecs_0651.json +38 -0
  655. combstruct/data/ecs06/ecs_0652.json +38 -0
  656. combstruct/data/ecs06/ecs_0653.json +38 -0
  657. combstruct/data/ecs06/ecs_0654.json +37 -0
  658. combstruct/data/ecs06/ecs_0655.json +37 -0
  659. combstruct/data/ecs06/ecs_0656.json +37 -0
  660. combstruct/data/ecs06/ecs_0657.json +37 -0
  661. combstruct/data/ecs06/ecs_0658.json +38 -0
  662. combstruct/data/ecs06/ecs_0659.json +37 -0
  663. combstruct/data/ecs06/ecs_0660.json +37 -0
  664. combstruct/data/ecs06/ecs_0661.json +37 -0
  665. combstruct/data/ecs06/ecs_0662.json +38 -0
  666. combstruct/data/ecs06/ecs_0663.json +37 -0
  667. combstruct/data/ecs06/ecs_0664.json +37 -0
  668. combstruct/data/ecs06/ecs_0665.json +37 -0
  669. combstruct/data/ecs06/ecs_0666.json +37 -0
  670. combstruct/data/ecs06/ecs_0667.json +38 -0
  671. combstruct/data/ecs06/ecs_0668.json +38 -0
  672. combstruct/data/ecs06/ecs_0669.json +38 -0
  673. combstruct/data/ecs06/ecs_0670.json +38 -0
  674. combstruct/data/ecs06/ecs_0671.json +38 -0
  675. combstruct/data/ecs06/ecs_0672.json +37 -0
  676. combstruct/data/ecs06/ecs_0673.json +38 -0
  677. combstruct/data/ecs06/ecs_0674.json +38 -0
  678. combstruct/data/ecs06/ecs_0675.json +38 -0
  679. combstruct/data/ecs06/ecs_0676.json +38 -0
  680. combstruct/data/ecs06/ecs_0677.json +38 -0
  681. combstruct/data/ecs06/ecs_0678.json +38 -0
  682. combstruct/data/ecs06/ecs_0679.json +37 -0
  683. combstruct/data/ecs06/ecs_0680.json +37 -0
  684. combstruct/data/ecs06/ecs_0681.json +37 -0
  685. combstruct/data/ecs06/ecs_0682.json +37 -0
  686. combstruct/data/ecs06/ecs_0683.json +37 -0
  687. combstruct/data/ecs06/ecs_0684.json +37 -0
  688. combstruct/data/ecs06/ecs_0685.json +37 -0
  689. combstruct/data/ecs06/ecs_0686.json +37 -0
  690. combstruct/data/ecs06/ecs_0687.json +37 -0
  691. combstruct/data/ecs06/ecs_0688.json +38 -0
  692. combstruct/data/ecs06/ecs_0689.json +38 -0
  693. combstruct/data/ecs06/ecs_0690.json +38 -0
  694. combstruct/data/ecs06/ecs_0691.json +37 -0
  695. combstruct/data/ecs06/ecs_0692.json +37 -0
  696. combstruct/data/ecs06/ecs_0693.json +38 -0
  697. combstruct/data/ecs06/ecs_0694.json +37 -0
  698. combstruct/data/ecs06/ecs_0695.json +37 -0
  699. combstruct/data/ecs06/ecs_0696.json +37 -0
  700. combstruct/data/ecs06/ecs_0697.json +38 -0
  701. combstruct/data/ecs06/ecs_0698.json +37 -0
  702. combstruct/data/ecs06/ecs_0699.json +37 -0
  703. combstruct/data/ecs07/ecs_0700.json +37 -0
  704. combstruct/data/ecs07/ecs_0701.json +38 -0
  705. combstruct/data/ecs07/ecs_0702.json +36 -0
  706. combstruct/data/ecs07/ecs_0703.json +38 -0
  707. combstruct/data/ecs07/ecs_0704.json +38 -0
  708. combstruct/data/ecs07/ecs_0705.json +38 -0
  709. combstruct/data/ecs07/ecs_0706.json +36 -0
  710. combstruct/data/ecs07/ecs_0707.json +34 -0
  711. combstruct/data/ecs07/ecs_0708.json +36 -0
  712. combstruct/data/ecs07/ecs_0709.json +37 -0
  713. combstruct/data/ecs07/ecs_0710.json +38 -0
  714. combstruct/data/ecs07/ecs_0711.json +34 -0
  715. combstruct/data/ecs07/ecs_0712.json +36 -0
  716. combstruct/data/ecs07/ecs_0713.json +34 -0
  717. combstruct/data/ecs07/ecs_0714.json +38 -0
  718. combstruct/data/ecs07/ecs_0715.json +38 -0
  719. combstruct/data/ecs07/ecs_0716.json +38 -0
  720. combstruct/data/ecs07/ecs_0717.json +38 -0
  721. combstruct/data/ecs07/ecs_0718.json +38 -0
  722. combstruct/data/ecs07/ecs_0719.json +38 -0
  723. combstruct/data/ecs07/ecs_0720.json +34 -0
  724. combstruct/data/ecs07/ecs_0721.json +36 -0
  725. combstruct/data/ecs07/ecs_0722.json +38 -0
  726. combstruct/data/ecs07/ecs_0723.json +38 -0
  727. combstruct/data/ecs07/ecs_0724.json +37 -0
  728. combstruct/data/ecs07/ecs_0725.json +38 -0
  729. combstruct/data/ecs07/ecs_0726.json +38 -0
  730. combstruct/data/ecs07/ecs_0727.json +37 -0
  731. combstruct/data/ecs07/ecs_0728.json +38 -0
  732. combstruct/data/ecs07/ecs_0729.json +34 -0
  733. combstruct/data/ecs07/ecs_0730.json +34 -0
  734. combstruct/data/ecs07/ecs_0731.json +36 -0
  735. combstruct/data/ecs07/ecs_0732.json +34 -0
  736. combstruct/data/ecs07/ecs_0733.json +38 -0
  737. combstruct/data/ecs07/ecs_0734.json +38 -0
  738. combstruct/data/ecs07/ecs_0735.json +38 -0
  739. combstruct/data/ecs07/ecs_0736.json +37 -0
  740. combstruct/data/ecs07/ecs_0737.json +38 -0
  741. combstruct/data/ecs07/ecs_0738.json +34 -0
  742. combstruct/data/ecs07/ecs_0739.json +36 -0
  743. combstruct/data/ecs07/ecs_0740.json +37 -0
  744. combstruct/data/ecs07/ecs_0741.json +38 -0
  745. combstruct/data/ecs07/ecs_0742.json +38 -0
  746. combstruct/data/ecs07/ecs_0743.json +38 -0
  747. combstruct/data/ecs07/ecs_0744.json +38 -0
  748. combstruct/data/ecs07/ecs_0745.json +34 -0
  749. combstruct/data/ecs07/ecs_0746.json +36 -0
  750. combstruct/data/ecs07/ecs_0747.json +37 -0
  751. combstruct/data/ecs07/ecs_0748.json +38 -0
  752. combstruct/data/ecs07/ecs_0749.json +38 -0
  753. combstruct/data/ecs07/ecs_0750.json +38 -0
  754. combstruct/data/ecs07/ecs_0751.json +38 -0
  755. combstruct/data/ecs07/ecs_0752.json +38 -0
  756. combstruct/data/ecs07/ecs_0753.json +38 -0
  757. combstruct/data/ecs07/ecs_0754.json +34 -0
  758. combstruct/data/ecs07/ecs_0755.json +34 -0
  759. combstruct/data/ecs07/ecs_0756.json +38 -0
  760. combstruct/data/ecs07/ecs_0757.json +38 -0
  761. combstruct/data/ecs07/ecs_0758.json +38 -0
  762. combstruct/data/ecs07/ecs_0759.json +36 -0
  763. combstruct/data/ecs07/ecs_0760.json +34 -0
  764. combstruct/data/ecs07/ecs_0761.json +35 -0
  765. combstruct/data/ecs07/ecs_0762.json +36 -0
  766. combstruct/data/ecs07/ecs_0763.json +38 -0
  767. combstruct/data/ecs07/ecs_0764.json +35 -0
  768. combstruct/data/ecs07/ecs_0765.json +35 -0
  769. combstruct/data/ecs07/ecs_0766.json +35 -0
  770. combstruct/data/ecs07/ecs_0767.json +34 -0
  771. combstruct/data/ecs07/ecs_0768.json +34 -0
  772. combstruct/data/ecs07/ecs_0769.json +36 -0
  773. combstruct/data/ecs07/ecs_0770.json +36 -0
  774. combstruct/data/ecs07/ecs_0771.json +36 -0
  775. combstruct/data/ecs07/ecs_0772.json +35 -0
  776. combstruct/data/ecs07/ecs_0773.json +34 -0
  777. combstruct/data/ecs07/ecs_0774.json +35 -0
  778. combstruct/data/ecs07/ecs_0775.json +36 -0
  779. combstruct/data/ecs07/ecs_0776.json +35 -0
  780. combstruct/data/ecs07/ecs_0777.json +38 -0
  781. combstruct/data/ecs07/ecs_0778.json +36 -0
  782. combstruct/data/ecs07/ecs_0779.json +34 -0
  783. combstruct/data/ecs07/ecs_0780.json +34 -0
  784. combstruct/data/ecs07/ecs_0781.json +35 -0
  785. combstruct/data/ecs07/ecs_0782.json +34 -0
  786. combstruct/data/ecs07/ecs_0783.json +34 -0
  787. combstruct/data/ecs07/ecs_0784.json +34 -0
  788. combstruct/data/ecs07/ecs_0785.json +36 -0
  789. combstruct/data/ecs07/ecs_0786.json +35 -0
  790. combstruct/data/ecs07/ecs_0787.json +36 -0
  791. combstruct/data/ecs07/ecs_0788.json +35 -0
  792. combstruct/data/ecs07/ecs_0789.json +36 -0
  793. combstruct/data/ecs07/ecs_0790.json +35 -0
  794. combstruct/data/ecs07/ecs_0791.json +36 -0
  795. combstruct/data/ecs07/ecs_0792.json +34 -0
  796. combstruct/data/ecs07/ecs_0793.json +36 -0
  797. combstruct/data/ecs07/ecs_0794.json +34 -0
  798. combstruct/data/ecs07/ecs_0795.json +36 -0
  799. combstruct/data/ecs07/ecs_0796.json +34 -0
  800. combstruct/data/ecs07/ecs_0797.json +38 -0
  801. combstruct/data/ecs07/ecs_0798.json +35 -0
  802. combstruct/data/ecs07/ecs_0799.json +36 -0
  803. combstruct/data/ecs08/ecs_0800.json +35 -0
  804. combstruct/data/ecs08/ecs_0801.json +35 -0
  805. combstruct/data/ecs08/ecs_0802.json +36 -0
  806. combstruct/data/ecs08/ecs_0803.json +34 -0
  807. combstruct/data/ecs08/ecs_0804.json +35 -0
  808. combstruct/data/ecs08/ecs_0805.json +36 -0
  809. combstruct/data/ecs08/ecs_0806.json +35 -0
  810. combstruct/data/ecs08/ecs_0807.json +38 -0
  811. combstruct/data/ecs08/ecs_0808.json +36 -0
  812. combstruct/data/ecs08/ecs_0809.json +34 -0
  813. combstruct/data/ecs08/ecs_0810.json +36 -0
  814. combstruct/data/ecs08/ecs_0811.json +34 -0
  815. combstruct/data/ecs08/ecs_0812.json +37 -0
  816. combstruct/data/ecs08/ecs_0813.json +37 -0
  817. combstruct/data/ecs08/ecs_0814.json +36 -0
  818. combstruct/data/ecs08/ecs_0815.json +35 -0
  819. combstruct/data/ecs08/ecs_0816.json +36 -0
  820. combstruct/data/ecs08/ecs_0817.json +38 -0
  821. combstruct/data/ecs08/ecs_0818.json +38 -0
  822. combstruct/data/ecs08/ecs_0819.json +36 -0
  823. combstruct/data/ecs08/ecs_0820.json +37 -0
  824. combstruct/data/ecs08/ecs_0821.json +34 -0
  825. combstruct/data/ecs08/ecs_0822.json +35 -0
  826. combstruct/data/ecs08/ecs_0823.json +34 -0
  827. combstruct/data/ecs08/ecs_0824.json +36 -0
  828. combstruct/data/ecs08/ecs_0825.json +35 -0
  829. combstruct/data/ecs08/ecs_0826.json +36 -0
  830. combstruct/data/ecs08/ecs_0827.json +35 -0
  831. combstruct/data/ecs08/ecs_0828.json +36 -0
  832. combstruct/data/ecs08/ecs_0829.json +38 -0
  833. combstruct/data/ecs08/ecs_0830.json +36 -0
  834. combstruct/data/ecs08/ecs_0831.json +37 -0
  835. combstruct/data/ecs08/ecs_0832.json +36 -0
  836. combstruct/data/ecs08/ecs_0833.json +36 -0
  837. combstruct/data/ecs08/ecs_0834.json +38 -0
  838. combstruct/data/ecs08/ecs_0835.json +36 -0
  839. combstruct/data/ecs08/ecs_0836.json +38 -0
  840. combstruct/data/ecs08/ecs_0837.json +36 -0
  841. combstruct/data/ecs08/ecs_0838.json +38 -0
  842. combstruct/data/ecs08/ecs_0839.json +36 -0
  843. combstruct/data/ecs08/ecs_0840.json +34 -0
  844. combstruct/data/ecs08/ecs_0841.json +34 -0
  845. combstruct/data/ecs08/ecs_0842.json +36 -0
  846. combstruct/data/ecs08/ecs_0843.json +34 -0
  847. combstruct/data/ecs08/ecs_0844.json +35 -0
  848. combstruct/data/ecs08/ecs_0845.json +37 -0
  849. combstruct/data/ecs08/ecs_0846.json +36 -0
  850. combstruct/data/ecs08/ecs_0847.json +36 -0
  851. combstruct/data/ecs08/ecs_0848.json +36 -0
  852. combstruct/data/ecs08/ecs_0849.json +38 -0
  853. combstruct/data/ecs08/ecs_0850.json +34 -0
  854. combstruct/data/ecs08/ecs_0851.json +36 -0
  855. combstruct/data/ecs08/ecs_0852.json +35 -0
  856. combstruct/data/ecs08/ecs_0853.json +38 -0
  857. combstruct/data/ecs08/ecs_0854.json +36 -0
  858. combstruct/data/ecs08/ecs_0855.json +36 -0
  859. combstruct/data/ecs08/ecs_0856.json +37 -0
  860. combstruct/data/ecs08/ecs_0857.json +34 -0
  861. combstruct/data/ecs08/ecs_0858.json +35 -0
  862. combstruct/data/ecs08/ecs_0859.json +36 -0
  863. combstruct/data/ecs08/ecs_0860.json +37 -0
  864. combstruct/data/ecs08/ecs_0861.json +36 -0
  865. combstruct/data/ecs08/ecs_0862.json +34 -0
  866. combstruct/data/ecs08/ecs_0863.json +36 -0
  867. combstruct/data/ecs08/ecs_0864.json +36 -0
  868. combstruct/data/ecs08/ecs_0865.json +35 -0
  869. combstruct/data/ecs08/ecs_0866.json +34 -0
  870. combstruct/data/ecs08/ecs_0867.json +34 -0
  871. combstruct/data/ecs08/ecs_0868.json +36 -0
  872. combstruct/data/ecs08/ecs_0869.json +34 -0
  873. combstruct/data/ecs08/ecs_0870.json +36 -0
  874. combstruct/data/ecs08/ecs_0871.json +36 -0
  875. combstruct/data/ecs08/ecs_0872.json +35 -0
  876. combstruct/data/ecs08/ecs_0873.json +37 -0
  877. combstruct/data/ecs08/ecs_0874.json +38 -0
  878. combstruct/data/ecs08/ecs_0875.json +38 -0
  879. combstruct/data/ecs08/ecs_0876.json +38 -0
  880. combstruct/data/ecs08/ecs_0877.json +38 -0
  881. combstruct/data/ecs08/ecs_0878.json +38 -0
  882. combstruct/data/ecs08/ecs_0879.json +38 -0
  883. combstruct/data/ecs08/ecs_0880.json +38 -0
  884. combstruct/data/ecs08/ecs_0881.json +38 -0
  885. combstruct/data/ecs08/ecs_0882.json +38 -0
  886. combstruct/data/ecs08/ecs_0883.json +38 -0
  887. combstruct/data/ecs08/ecs_0884.json +38 -0
  888. combstruct/data/ecs08/ecs_0885.json +38 -0
  889. combstruct/data/ecs08/ecs_0886.json +38 -0
  890. combstruct/data/ecs08/ecs_0887.json +38 -0
  891. combstruct/data/ecs08/ecs_0888.json +38 -0
  892. combstruct/data/ecs08/ecs_0889.json +38 -0
  893. combstruct/data/ecs08/ecs_0890.json +38 -0
  894. combstruct/data/ecs08/ecs_0891.json +38 -0
  895. combstruct/data/ecs08/ecs_0892.json +38 -0
  896. combstruct/data/ecs08/ecs_0893.json +38 -0
  897. combstruct/data/ecs08/ecs_0894.json +38 -0
  898. combstruct/data/ecs08/ecs_0895.json +38 -0
  899. combstruct/data/ecs08/ecs_0896.json +38 -0
  900. combstruct/data/ecs08/ecs_0897.json +38 -0
  901. combstruct/data/ecs08/ecs_0898.json +38 -0
  902. combstruct/data/ecs08/ecs_0899.json +38 -0
  903. combstruct/data/ecs09/ecs_0900.json +38 -0
  904. combstruct/data/ecs09/ecs_0901.json +38 -0
  905. combstruct/data/ecs09/ecs_0902.json +38 -0
  906. combstruct/data/ecs09/ecs_0903.json +38 -0
  907. combstruct/data/ecs09/ecs_0904.json +38 -0
  908. combstruct/data/ecs09/ecs_0905.json +38 -0
  909. combstruct/data/ecs09/ecs_0906.json +38 -0
  910. combstruct/data/ecs09/ecs_0907.json +38 -0
  911. combstruct/data/ecs09/ecs_0908.json +38 -0
  912. combstruct/data/ecs09/ecs_0909.json +38 -0
  913. combstruct/data/ecs09/ecs_0910.json +38 -0
  914. combstruct/data/ecs09/ecs_0911.json +38 -0
  915. combstruct/data/ecs09/ecs_0912.json +38 -0
  916. combstruct/data/ecs09/ecs_0913.json +38 -0
  917. combstruct/data/ecs09/ecs_0914.json +38 -0
  918. combstruct/data/ecs09/ecs_0915.json +38 -0
  919. combstruct/data/ecs09/ecs_0916.json +38 -0
  920. combstruct/data/ecs09/ecs_0917.json +38 -0
  921. combstruct/data/ecs09/ecs_0918.json +38 -0
  922. combstruct/data/ecs09/ecs_0919.json +38 -0
  923. combstruct/data/ecs09/ecs_0920.json +38 -0
  924. combstruct/data/ecs09/ecs_0921.json +38 -0
  925. combstruct/data/ecs09/ecs_0922.json +38 -0
  926. combstruct/data/ecs09/ecs_0923.json +38 -0
  927. combstruct/data/ecs09/ecs_0924.json +38 -0
  928. combstruct/data/ecs09/ecs_0925.json +38 -0
  929. combstruct/data/ecs09/ecs_0926.json +38 -0
  930. combstruct/data/ecs09/ecs_0927.json +38 -0
  931. combstruct/data/ecs09/ecs_0928.json +38 -0
  932. combstruct/data/ecs09/ecs_0929.json +38 -0
  933. combstruct/data/ecs09/ecs_0930.json +38 -0
  934. combstruct/data/ecs09/ecs_0931.json +38 -0
  935. combstruct/data/ecs09/ecs_0932.json +38 -0
  936. combstruct/data/ecs09/ecs_0933.json +38 -0
  937. combstruct/data/ecs09/ecs_0934.json +38 -0
  938. combstruct/data/ecs09/ecs_0935.json +38 -0
  939. combstruct/data/ecs09/ecs_0936.json +38 -0
  940. combstruct/data/ecs09/ecs_0937.json +38 -0
  941. combstruct/data/ecs09/ecs_0938.json +38 -0
  942. combstruct/data/ecs09/ecs_0939.json +38 -0
  943. combstruct/data/ecs09/ecs_0940.json +38 -0
  944. combstruct/data/ecs09/ecs_0941.json +38 -0
  945. combstruct/data/ecs09/ecs_0942.json +38 -0
  946. combstruct/data/ecs09/ecs_0943.json +38 -0
  947. combstruct/data/ecs09/ecs_0944.json +38 -0
  948. combstruct/data/ecs09/ecs_0945.json +38 -0
  949. combstruct/data/ecs09/ecs_0946.json +38 -0
  950. combstruct/data/ecs09/ecs_0947.json +38 -0
  951. combstruct/data/ecs09/ecs_0948.json +38 -0
  952. combstruct/data/ecs09/ecs_0949.json +38 -0
  953. combstruct/data/ecs09/ecs_0950.json +38 -0
  954. combstruct/data/ecs09/ecs_0951.json +38 -0
  955. combstruct/data/ecs09/ecs_0952.json +38 -0
  956. combstruct/data/ecs09/ecs_0953.json +38 -0
  957. combstruct/data/ecs09/ecs_0954.json +38 -0
  958. combstruct/data/ecs09/ecs_0955.json +38 -0
  959. combstruct/data/ecs09/ecs_0956.json +38 -0
  960. combstruct/data/ecs09/ecs_0957.json +38 -0
  961. combstruct/data/ecs09/ecs_0958.json +38 -0
  962. combstruct/data/ecs09/ecs_0959.json +38 -0
  963. combstruct/data/ecs09/ecs_0960.json +38 -0
  964. combstruct/data/ecs09/ecs_0961.json +38 -0
  965. combstruct/data/ecs09/ecs_0962.json +38 -0
  966. combstruct/data/ecs09/ecs_0963.json +38 -0
  967. combstruct/data/ecs09/ecs_0964.json +38 -0
  968. combstruct/data/ecs09/ecs_0965.json +38 -0
  969. combstruct/data/ecs09/ecs_0966.json +38 -0
  970. combstruct/data/ecs09/ecs_0967.json +38 -0
  971. combstruct/data/ecs09/ecs_0968.json +38 -0
  972. combstruct/data/ecs09/ecs_0969.json +38 -0
  973. combstruct/data/ecs09/ecs_0970.json +38 -0
  974. combstruct/data/ecs09/ecs_0971.json +38 -0
  975. combstruct/data/ecs09/ecs_0972.json +38 -0
  976. combstruct/data/ecs09/ecs_0973.json +38 -0
  977. combstruct/data/ecs09/ecs_0974.json +38 -0
  978. combstruct/data/ecs09/ecs_0975.json +38 -0
  979. combstruct/data/ecs09/ecs_0976.json +38 -0
  980. combstruct/data/ecs09/ecs_0977.json +38 -0
  981. combstruct/data/ecs09/ecs_0978.json +38 -0
  982. combstruct/data/ecs09/ecs_0979.json +38 -0
  983. combstruct/data/ecs09/ecs_0980.json +38 -0
  984. combstruct/data/ecs09/ecs_0981.json +38 -0
  985. combstruct/data/ecs09/ecs_0982.json +38 -0
  986. combstruct/data/ecs09/ecs_0983.json +38 -0
  987. combstruct/data/ecs09/ecs_0984.json +38 -0
  988. combstruct/data/ecs09/ecs_0985.json +38 -0
  989. combstruct/data/ecs09/ecs_0986.json +38 -0
  990. combstruct/data/ecs09/ecs_0987.json +38 -0
  991. combstruct/data/ecs09/ecs_0988.json +38 -0
  992. combstruct/data/ecs09/ecs_0989.json +38 -0
  993. combstruct/data/ecs09/ecs_0990.json +38 -0
  994. combstruct/data/ecs09/ecs_0991.json +38 -0
  995. combstruct/data/ecs09/ecs_0992.json +38 -0
  996. combstruct/data/ecs09/ecs_0993.json +38 -0
  997. combstruct/data/ecs09/ecs_0994.json +38 -0
  998. combstruct/data/ecs09/ecs_0995.json +38 -0
  999. combstruct/data/ecs09/ecs_0996.json +38 -0
  1000. combstruct/data/ecs09/ecs_0997.json +38 -0
  1001. combstruct/data/ecs09/ecs_0998.json +38 -0
  1002. combstruct/data/ecs09/ecs_0999.json +38 -0
  1003. combstruct/data/ecs10/ecs_1000.json +38 -0
  1004. combstruct/data/ecs10/ecs_1001.json +38 -0
  1005. combstruct/data/ecs10/ecs_1002.json +38 -0
  1006. combstruct/data/ecs10/ecs_1003.json +38 -0
  1007. combstruct/data/ecs10/ecs_1004.json +38 -0
  1008. combstruct/data/ecs10/ecs_1005.json +38 -0
  1009. combstruct/data/ecs10/ecs_1006.json +38 -0
  1010. combstruct/data/ecs10/ecs_1007.json +38 -0
  1011. combstruct/data/ecs10/ecs_1008.json +38 -0
  1012. combstruct/data/ecs10/ecs_1009.json +38 -0
  1013. combstruct/data/ecs10/ecs_1010.json +38 -0
  1014. combstruct/data/ecs10/ecs_1011.json +38 -0
  1015. combstruct/data/ecs10/ecs_1012.json +38 -0
  1016. combstruct/data/ecs10/ecs_1013.json +38 -0
  1017. combstruct/data/ecs10/ecs_1014.json +38 -0
  1018. combstruct/data/ecs10/ecs_1015.json +38 -0
  1019. combstruct/data/ecs10/ecs_1016.json +38 -0
  1020. combstruct/data/ecs10/ecs_1017.json +38 -0
  1021. combstruct/data/ecs10/ecs_1018.json +38 -0
  1022. combstruct/data/ecs10/ecs_1019.json +38 -0
  1023. combstruct/data/ecs10/ecs_1020.json +38 -0
  1024. combstruct/data/ecs10/ecs_1021.json +38 -0
  1025. combstruct/data/ecs10/ecs_1022.json +38 -0
  1026. combstruct/data/ecs10/ecs_1023.json +38 -0
  1027. combstruct/data/ecs10/ecs_1024.json +38 -0
  1028. combstruct/data/ecs10/ecs_1025.json +38 -0
  1029. combstruct/data/ecs10/ecs_1026.json +38 -0
  1030. combstruct/data/ecs10/ecs_1027.json +38 -0
  1031. combstruct/data/ecs10/ecs_1028.json +38 -0
  1032. combstruct/data/ecs10/ecs_1029.json +38 -0
  1033. combstruct/data/ecs10/ecs_1030.json +38 -0
  1034. combstruct/data/ecs10/ecs_1031.json +38 -0
  1035. combstruct/data/ecs10/ecs_1032.json +38 -0
  1036. combstruct/data/ecs10/ecs_1033.json +38 -0
  1037. combstruct/data/ecs10/ecs_1034.json +38 -0
  1038. combstruct/data/ecs10/ecs_1035.json +38 -0
  1039. combstruct/data/ecs10/ecs_1036.json +38 -0
  1040. combstruct/data/ecs10/ecs_1037.json +38 -0
  1041. combstruct/data/ecs10/ecs_1038.json +38 -0
  1042. combstruct/data/ecs10/ecs_1039.json +38 -0
  1043. combstruct/data/ecs10/ecs_1040.json +38 -0
  1044. combstruct/data/ecs10/ecs_1041.json +38 -0
  1045. combstruct/data/ecs10/ecs_1042.json +38 -0
  1046. combstruct/data/ecs10/ecs_1043.json +38 -0
  1047. combstruct/data/ecs10/ecs_1044.json +38 -0
  1048. combstruct/data/ecs10/ecs_1045.json +38 -0
  1049. combstruct/data/ecs10/ecs_1046.json +38 -0
  1050. combstruct/data/ecs10/ecs_1047.json +38 -0
  1051. combstruct/data/ecs10/ecs_1048.json +38 -0
  1052. combstruct/data/ecs10/ecs_1049.json +38 -0
  1053. combstruct/data/ecs10/ecs_1050.json +38 -0
  1054. combstruct/data/ecs10/ecs_1051.json +38 -0
  1055. combstruct/data/ecs10/ecs_1052.json +38 -0
  1056. combstruct/data/ecs10/ecs_1053.json +38 -0
  1057. combstruct/data/ecs10/ecs_1054.json +38 -0
  1058. combstruct/data/ecs10/ecs_1055.json +38 -0
  1059. combstruct/data/ecs10/ecs_1056.json +38 -0
  1060. combstruct/data/ecs10/ecs_1057.json +38 -0
  1061. combstruct/data/ecs10/ecs_1058.json +38 -0
  1062. combstruct/data/ecs10/ecs_1059.json +38 -0
  1063. combstruct/data/ecs10/ecs_1060.json +38 -0
  1064. combstruct/data/ecs10/ecs_1061.json +38 -0
  1065. combstruct/data/ecs10/ecs_1062.json +38 -0
  1066. combstruct/data/ecs10/ecs_1063.json +38 -0
  1067. combstruct/data/ecs10/ecs_1064.json +38 -0
  1068. combstruct/data/ecs10/ecs_1065.json +38 -0
  1069. combstruct/data/ecs10/ecs_1066.json +38 -0
  1070. combstruct/data/ecs10/ecs_1067.json +38 -0
  1071. combstruct/data/ecs10/ecs_1068.json +38 -0
  1072. combstruct/data/ecs10/ecs_1069.json +38 -0
  1073. combstruct/data/ecs10/ecs_1070.json +38 -0
  1074. combstruct/data/ecs10/ecs_1071.json +38 -0
  1075. combstruct/data/ecs10/ecs_1072.json +38 -0
  1076. combstruct/data/ecs10/ecs_1073.json +38 -0
  1077. combstruct/data/ecs10/ecs_1074.json +38 -0
  1078. combstruct/data/ecs10/ecs_1075.json +38 -0
  1079. combstruct/py.typed +1 -0
  1080. combstruct/specification.py +180 -0
  1081. combstruct/terms.py +1034 -0
  1082. combstruct-0.1.0a0.dist-info/METADATA +230 -0
  1083. combstruct-0.1.0a0.dist-info/RECORD +1089 -0
  1084. combstruct-0.1.0a0.dist-info/WHEEL +5 -0
  1085. combstruct-0.1.0a0.dist-info/entry_points.txt +2 -0
  1086. combstruct-0.1.0a0.dist-info/licenses/LICENSE.md +494 -0
  1087. combstruct-0.1.0a0.dist-info/licenses/LICENSES/CC-BY-SA-4.0.txt +427 -0
  1088. combstruct-0.1.0a0.dist-info/licenses/NOTICE.md +55 -0
  1089. combstruct-0.1.0a0.dist-info/top_level.txt +1 -0
combstruct/terms.py ADDED
@@ -0,0 +1,1034 @@
1
+ #!/usr/bin/env python3
2
+ """Parse ECS specifications and compute their sequence terms.
3
+
4
+ The evaluator uses truncated ordinary generating functions for unlabelled
5
+ structures and exponential generating functions for labelled structures.
6
+ All arithmetic is exact.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import argparse
12
+ import json
13
+ import math
14
+ from collections.abc import Iterable, Sequence
15
+ from fractions import Fraction
16
+ from functools import cache
17
+ from pathlib import Path
18
+ from typing import Any
19
+
20
+ from . import specification as _specification
21
+ from .catalog import (
22
+ StructureNotFoundError,
23
+ _load_record,
24
+ default_dataset,
25
+ )
26
+ from .specification import (
27
+ Cardinality,
28
+ Expression,
29
+ Reference,
30
+ SpecificationError,
31
+ parse_specification,
32
+ )
33
+
34
+ # Historical imports from ``compute_terms.py`` remain available while the
35
+ # repository's maintenance scripts transition to the package-level API.
36
+ Constructor = _specification.Constructor
37
+ Parser = _specification.Parser
38
+ TOKEN_RE = _specification.TOKEN_RE
39
+
40
+
41
+ class UnsupportedConstruction(SpecificationError):
42
+ """The specification is valid but cannot be expanded safely by this evaluator."""
43
+
44
+
45
+ ExactNumber = int | Fraction
46
+ Series = list[Fraction]
47
+ CoefficientSeries = list[ExactNumber]
48
+
49
+ __all__ = [
50
+ "TOKEN_RE",
51
+ "Cardinality",
52
+ "CoefficientCompiler",
53
+ "CoefficientNode",
54
+ "Constructor",
55
+ "EulerSelectionNode",
56
+ "Evaluator",
57
+ "ExpNode",
58
+ "Expression",
59
+ "InverseOneMinusNode",
60
+ "LiteralNode",
61
+ "LogOneMinusNode",
62
+ "Parser",
63
+ "ProductNode",
64
+ "Reference",
65
+ "ReferenceNode",
66
+ "ScaleNode",
67
+ "Series",
68
+ "SpecificationError",
69
+ "SubstituteNode",
70
+ "SumNode",
71
+ "UnlabelledCycleNode",
72
+ "UnsupportedConstruction",
73
+ "add_series",
74
+ "atom_series",
75
+ "binomial_row",
76
+ "build_argument_parser",
77
+ "compact_number",
78
+ "component_bounds",
79
+ "compute_terms",
80
+ "decimal_digit_count",
81
+ "default_dataset",
82
+ "divide_exact",
83
+ "divisors",
84
+ "euler_totient",
85
+ "integer_value",
86
+ "is_nonnegative_integer",
87
+ "labelled_cycle_series",
88
+ "labelled_set_series",
89
+ "load_record",
90
+ "main",
91
+ "multiply_series",
92
+ "one_series",
93
+ "power_series",
94
+ "product_series",
95
+ "require_nonnegative_integers",
96
+ "scale_series",
97
+ "sequence_series",
98
+ "substitute_power",
99
+ "unlabelled_cycle_series",
100
+ "unlabelled_selection_series",
101
+ "zero_series",
102
+ ]
103
+
104
+
105
+ def zero_series(degree: int) -> Series:
106
+ return [Fraction(0) for _ in range(degree + 1)]
107
+
108
+
109
+ def one_series(degree: int) -> Series:
110
+ result = zero_series(degree)
111
+ result[0] = Fraction(1)
112
+ return result
113
+
114
+
115
+ def atom_series(degree: int) -> Series:
116
+ result = zero_series(degree)
117
+ if degree >= 1:
118
+ result[1] = Fraction(1)
119
+ return result
120
+
121
+
122
+ def add_series(*series: Series) -> Series:
123
+ if not series:
124
+ raise SpecificationError("Union requires at least one argument")
125
+ return [sum((value[index] for value in series), Fraction(0)) for index in range(len(series[0]))]
126
+
127
+
128
+ def multiply_series(left: Series, right: Series) -> Series:
129
+ degree = len(left) - 1
130
+ result = zero_series(degree)
131
+ for left_degree, left_coefficient in enumerate(left):
132
+ if not left_coefficient:
133
+ continue
134
+ for right_degree in range(degree - left_degree + 1):
135
+ right_coefficient = right[right_degree]
136
+ if right_coefficient:
137
+ result[left_degree + right_degree] += left_coefficient * right_coefficient
138
+ return result
139
+
140
+
141
+ def product_series(series: Sequence[Series], degree: int) -> Series:
142
+ result = one_series(degree)
143
+ for factor in series:
144
+ result = multiply_series(result, factor)
145
+ return result
146
+
147
+
148
+ def power_series(series: Series, exponent: int) -> Series:
149
+ degree = len(series) - 1
150
+ result = one_series(degree)
151
+ factor = series
152
+ remaining = exponent
153
+ while remaining:
154
+ if remaining & 1:
155
+ result = multiply_series(result, factor)
156
+ remaining //= 2
157
+ if remaining:
158
+ factor = multiply_series(factor, factor)
159
+ return result
160
+
161
+
162
+ def scale_series(series: Series, scalar: Fraction) -> Series:
163
+ return [scalar * coefficient for coefficient in series]
164
+
165
+
166
+ def substitute_power(series: Series, exponent: int) -> Series:
167
+ degree = len(series) - 1
168
+ result = zero_series(degree)
169
+ for index in range(degree // exponent + 1):
170
+ result[index * exponent] = series[index]
171
+ return result
172
+
173
+
174
+ def component_bounds(cardinality: Cardinality | None, degree: int) -> tuple[int, int]:
175
+ constraint = cardinality or Cardinality()
176
+ maximum = degree if constraint.maximum is None else constraint.maximum
177
+ return constraint.minimum, maximum
178
+
179
+
180
+ def sequence_series(component: Series, cardinality: Cardinality | None) -> Series:
181
+ degree = len(component) - 1
182
+ minimum, maximum = component_bounds(cardinality, degree)
183
+ if component[0] and (cardinality is None or cardinality.maximum is None):
184
+ raise UnsupportedConstruction("An unrestricted Sequence cannot contain size-zero objects")
185
+
186
+ result = zero_series(degree)
187
+ current = one_series(degree)
188
+ for count in range(maximum + 1):
189
+ if count >= minimum:
190
+ result = add_series(result, current)
191
+ current = multiply_series(current, component)
192
+ return result
193
+
194
+
195
+ def labelled_set_series(component: Series, cardinality: Cardinality | None) -> Series:
196
+ degree = len(component) - 1
197
+ minimum, maximum = component_bounds(cardinality, degree)
198
+ if component[0] and (cardinality is None or cardinality.maximum is None):
199
+ raise UnsupportedConstruction(
200
+ "An unrestricted labelled Set cannot contain size-zero objects"
201
+ )
202
+
203
+ result = zero_series(degree)
204
+ current = one_series(degree)
205
+ factorial = 1
206
+ for count in range(maximum + 1):
207
+ if count:
208
+ factorial *= count
209
+ if count >= minimum:
210
+ result = add_series(result, scale_series(current, Fraction(1, factorial)))
211
+ current = multiply_series(current, component)
212
+ return result
213
+
214
+
215
+ def require_nonnegative_integers(component: Series, construction: str) -> list[int]:
216
+ coefficients: list[int] = []
217
+ for coefficient in component:
218
+ if coefficient.denominator != 1 or coefficient < 0:
219
+ raise UnsupportedConstruction(
220
+ f"Unlabelled {construction} requires nonnegative integer component coefficients",
221
+ )
222
+ coefficients.append(coefficient.numerator)
223
+ return coefficients
224
+
225
+
226
+ def unlabelled_selection_series(
227
+ component: Series,
228
+ cardinality: Cardinality | None,
229
+ *,
230
+ distinct: bool,
231
+ ) -> Series:
232
+ """Evaluate an unlabelled multiset (Set) or distinct selection (PowerSet)."""
233
+
234
+ degree = len(component) - 1
235
+ coefficients = require_nonnegative_integers(component, "PowerSet" if distinct else "Set")
236
+ if coefficients[0]:
237
+ if not distinct:
238
+ raise UnsupportedConstruction("An unlabelled Set cannot contain size-zero objects")
239
+ if cardinality is not None:
240
+ raise UnsupportedConstruction("Cardinality constraints on PowerSet are not supported")
241
+
242
+ minimum, maximum = component_bounds(cardinality, degree)
243
+ table = [zero_series(degree) for _ in range(maximum + 1)]
244
+ table[0][0] = Fraction(2 ** coefficients[0] if distinct else 1)
245
+
246
+ for size, type_count in enumerate(coefficients[1:], 1):
247
+ if not type_count:
248
+ continue
249
+ updated = [zero_series(degree) for _ in range(maximum + 1)]
250
+ for old_count in range(maximum + 1):
251
+ for old_size, old_value in enumerate(table[old_count]):
252
+ if not old_value:
253
+ continue
254
+ limit = min(maximum - old_count, (degree - old_size) // size)
255
+ if distinct:
256
+ limit = min(limit, type_count)
257
+ for chosen in range(limit + 1):
258
+ ways = (
259
+ math.comb(type_count, chosen)
260
+ if distinct
261
+ else math.comb(type_count + chosen - 1, chosen)
262
+ )
263
+ updated[old_count + chosen][old_size + chosen * size] += old_value * ways
264
+ table = updated
265
+
266
+ result = zero_series(degree)
267
+ for count in range(minimum, maximum + 1):
268
+ result = add_series(result, table[count])
269
+ return result
270
+
271
+
272
+ def euler_totient(value: int) -> int:
273
+ result = value
274
+ factor = 2
275
+ remaining = value
276
+ while factor * factor <= remaining:
277
+ if remaining % factor == 0:
278
+ while remaining % factor == 0:
279
+ remaining //= factor
280
+ result -= result // factor
281
+ factor += 1
282
+ if remaining > 1:
283
+ result -= result // remaining
284
+ return result
285
+
286
+
287
+ def labelled_cycle_series(component: Series, cardinality: Cardinality | None) -> Series:
288
+ degree = len(component) - 1
289
+ minimum, maximum = component_bounds(cardinality or Cardinality(1), degree)
290
+ minimum = max(1, minimum)
291
+ if component[0] and (cardinality is None or cardinality.maximum is None):
292
+ raise UnsupportedConstruction(
293
+ "An unrestricted labelled Cycle cannot contain size-zero objects"
294
+ )
295
+
296
+ result = zero_series(degree)
297
+ current = one_series(degree)
298
+ for count in range(1, maximum + 1):
299
+ current = multiply_series(current, component)
300
+ if count >= minimum:
301
+ result = add_series(result, scale_series(current, Fraction(1, count)))
302
+ return result
303
+
304
+
305
+ def unlabelled_cycle_series(component: Series, cardinality: Cardinality | None) -> Series:
306
+ degree = len(component) - 1
307
+ if component[0]:
308
+ raise UnsupportedConstruction("An unlabelled Cycle cannot contain size-zero objects")
309
+ minimum, maximum = component_bounds(cardinality or Cardinality(1), degree)
310
+ minimum = max(1, minimum)
311
+ result = zero_series(degree)
312
+
313
+ for count in range(minimum, maximum + 1):
314
+ fixed_count = zero_series(degree)
315
+ for divisor in range(1, count + 1):
316
+ if count % divisor:
317
+ continue
318
+ substituted = substitute_power(component, divisor)
319
+ contribution = power_series(substituted, count // divisor)
320
+ fixed_count = add_series(
321
+ fixed_count,
322
+ scale_series(contribution, Fraction(euler_totient(divisor), count)),
323
+ )
324
+ result = add_series(result, fixed_count)
325
+ return result
326
+
327
+
328
+ class Evaluator:
329
+ def __init__(self, equations: dict[str, Expression], degree: int, labelled: bool):
330
+ self.equations = equations
331
+ self.degree = degree
332
+ self.labelled = labelled
333
+
334
+ def compute(self, symbol: str) -> Series:
335
+ if symbol not in self.equations:
336
+ raise SpecificationError(f"Specification does not define {symbol!r}")
337
+
338
+ values = {name: zero_series(self.degree) for name in self.equations}
339
+ iteration_limit = max(100, (self.degree + 1) * max(1, len(values)) * 4)
340
+ for _ in range(iteration_limit):
341
+ updated = {
342
+ name: self._evaluate(expression, values)
343
+ for name, expression in self.equations.items()
344
+ }
345
+ if updated == values:
346
+ return updated[symbol]
347
+ values = updated
348
+ raise UnsupportedConstruction(
349
+ f"The recursive system did not stabilize through degree {self.degree}; "
350
+ "it may not be well founded",
351
+ )
352
+
353
+ def _evaluate(self, expression: Expression, values: dict[str, Series]) -> Series:
354
+ if isinstance(expression, Reference):
355
+ if expression.name in ("Atom", "Z") and expression.name not in self.equations:
356
+ return atom_series(self.degree)
357
+ if expression.name == "Epsilon":
358
+ return one_series(self.degree)
359
+ if expression.name not in values:
360
+ raise SpecificationError(f"Undefined symbol {expression.name!r}")
361
+ return values[expression.name]
362
+
363
+ arguments = [self._evaluate(argument, values) for argument in expression.arguments]
364
+ name = expression.name.lower()
365
+ if name == "union":
366
+ if expression.cardinality is not None:
367
+ raise SpecificationError("Union does not accept a cardinality constraint")
368
+ return add_series(*arguments)
369
+ if name == "prod":
370
+ if expression.cardinality is not None:
371
+ raise SpecificationError("Prod does not accept a cardinality constraint")
372
+ return product_series(arguments, self.degree)
373
+ if len(arguments) != 1:
374
+ raise SpecificationError(f"{expression.name} requires exactly one component argument")
375
+
376
+ component = arguments[0]
377
+ if name == "sequence":
378
+ return sequence_series(component, expression.cardinality)
379
+ if name == "set":
380
+ if self.labelled:
381
+ return labelled_set_series(component, expression.cardinality)
382
+ return unlabelled_selection_series(
383
+ component,
384
+ expression.cardinality,
385
+ distinct=False,
386
+ )
387
+ if name == "cycle":
388
+ if self.labelled:
389
+ return labelled_cycle_series(component, expression.cardinality)
390
+ return unlabelled_cycle_series(component, expression.cardinality)
391
+ if name == "powerset":
392
+ if self.labelled:
393
+ raise UnsupportedConstruction("PowerSet is only defined for unlabelled structures")
394
+ if expression.cardinality is not None:
395
+ raise UnsupportedConstruction("PowerSet cardinality constraints are not supported")
396
+ return unlabelled_selection_series(component, None, distinct=True)
397
+ raise UnsupportedConstruction(f"Unsupported constructor {expression.name!r}")
398
+
399
+
400
+ class CoefficientNode:
401
+ def __init__(self, compiler: CoefficientCompiler):
402
+ self.compiler = compiler
403
+ self.coefficients: CoefficientSeries = [0 for _ in range(compiler.degree + 1)]
404
+ compiler.nodes.append(self)
405
+
406
+ def value(self, degree: int) -> ExactNumber:
407
+ raise NotImplementedError
408
+
409
+ def update(self, degree: int) -> bool:
410
+ value = compact_number(self.value(degree))
411
+ if value == self.coefficients[degree]:
412
+ return False
413
+ self.coefficients[degree] = value
414
+ return True
415
+
416
+
417
+ def compact_number(value: ExactNumber) -> ExactNumber:
418
+ if isinstance(value, Fraction) and value.denominator == 1:
419
+ return value.numerator
420
+ return value
421
+
422
+
423
+ def divide_exact(value: ExactNumber, divisor: int) -> ExactNumber:
424
+ if isinstance(value, int):
425
+ quotient, remainder = divmod(value, divisor)
426
+ return quotient if remainder == 0 else Fraction(value, divisor)
427
+ return compact_number(value / divisor)
428
+
429
+
430
+ def is_nonnegative_integer(value: ExactNumber) -> bool:
431
+ return value >= 0 and (isinstance(value, int) or value.denominator == 1)
432
+
433
+
434
+ def integer_value(value: ExactNumber) -> int:
435
+ return value if isinstance(value, int) else value.numerator
436
+
437
+
438
+ @cache
439
+ def binomial_row(degree: int) -> tuple[int, ...]:
440
+ row = [1]
441
+ for index in range(1, degree + 1):
442
+ row.append(row[-1] * (degree - index + 1) // index)
443
+ return tuple(row)
444
+
445
+
446
+ def decimal_digit_count(value: int) -> int:
447
+ value = abs(value)
448
+ if value == 0:
449
+ return 1
450
+ digits = int((value.bit_length() - 1) * math.log10(2)) + 1
451
+ if value >= 10**digits:
452
+ return digits + 1
453
+ if value < 10 ** (digits - 1):
454
+ return digits - 1
455
+ return digits
456
+
457
+
458
+ class LiteralNode(CoefficientNode):
459
+ def __init__(self, compiler: CoefficientCompiler, nonzero_degree: int | None):
460
+ self.nonzero_degree = nonzero_degree
461
+ super().__init__(compiler)
462
+
463
+ def value(self, degree: int) -> ExactNumber:
464
+ return int(degree == self.nonzero_degree)
465
+
466
+
467
+ class ReferenceNode(CoefficientNode):
468
+ def __init__(self, compiler: CoefficientCompiler, name: str):
469
+ self.name = name
470
+ super().__init__(compiler)
471
+
472
+ def value(self, degree: int) -> ExactNumber:
473
+ try:
474
+ return self.compiler.roots[self.name].coefficients[degree]
475
+ except KeyError as error:
476
+ raise SpecificationError(f"Undefined symbol {self.name!r}") from error
477
+
478
+
479
+ class SumNode(CoefficientNode):
480
+ def __init__(self, compiler: CoefficientCompiler, children: Sequence[CoefficientNode]):
481
+ self.children = tuple(children)
482
+ super().__init__(compiler)
483
+
484
+ def value(self, degree: int) -> ExactNumber:
485
+ return sum(child.coefficients[degree] for child in self.children)
486
+
487
+
488
+ class ProductNode(CoefficientNode):
489
+ def __init__(
490
+ self, compiler: CoefficientCompiler, left: CoefficientNode, right: CoefficientNode
491
+ ):
492
+ self.left = left
493
+ self.right = right
494
+ super().__init__(compiler)
495
+
496
+ def value(self, degree: int) -> ExactNumber:
497
+ weights = binomial_row(degree) if self.compiler.labelled else None
498
+ return sum(
499
+ (
500
+ (weights[index] if weights else 1)
501
+ * self.left.coefficients[index]
502
+ * self.right.coefficients[degree - index]
503
+ for index in range(degree + 1)
504
+ ),
505
+ 0,
506
+ )
507
+
508
+
509
+ class ScaleNode(CoefficientNode):
510
+ def __init__(self, compiler: CoefficientCompiler, child: CoefficientNode, scalar: Fraction):
511
+ self.child = child
512
+ self.scalar = scalar
513
+ super().__init__(compiler)
514
+
515
+ def value(self, degree: int) -> ExactNumber:
516
+ return self.scalar * self.child.coefficients[degree]
517
+
518
+
519
+ class SubstituteNode(CoefficientNode):
520
+ def __init__(self, compiler: CoefficientCompiler, child: CoefficientNode, exponent: int):
521
+ self.child = child
522
+ self.exponent = exponent
523
+ super().__init__(compiler)
524
+
525
+ def value(self, degree: int) -> ExactNumber:
526
+ if degree % self.exponent:
527
+ return 0
528
+ return self.child.coefficients[degree // self.exponent]
529
+
530
+
531
+ class InverseOneMinusNode(CoefficientNode):
532
+ def __init__(self, compiler: CoefficientCompiler, child: CoefficientNode):
533
+ self.child = child
534
+ super().__init__(compiler)
535
+
536
+ def value(self, degree: int) -> ExactNumber:
537
+ if self.child.coefficients[0]:
538
+ raise UnsupportedConstruction(
539
+ "An unrestricted Sequence cannot contain size-zero objects"
540
+ )
541
+ if degree == 0:
542
+ return 1
543
+ weights = binomial_row(degree) if self.compiler.labelled else None
544
+ return sum(
545
+ (
546
+ (weights[index] if weights else 1)
547
+ * self.child.coefficients[index]
548
+ * self.coefficients[degree - index]
549
+ for index in range(1, degree + 1)
550
+ ),
551
+ 0,
552
+ )
553
+
554
+
555
+ class ExpNode(CoefficientNode):
556
+ def __init__(self, compiler: CoefficientCompiler, child: CoefficientNode):
557
+ self.child = child
558
+ super().__init__(compiler)
559
+
560
+ def value(self, degree: int) -> ExactNumber:
561
+ if self.child.coefficients[0]:
562
+ raise UnsupportedConstruction(
563
+ "An exponential construction cannot contain size-zero objects"
564
+ )
565
+ if degree == 0:
566
+ return 1
567
+ if self.compiler.labelled:
568
+ weights = binomial_row(degree - 1)
569
+ return sum(
570
+ (
571
+ weights[index - 1]
572
+ * self.child.coefficients[index]
573
+ * self.coefficients[degree - index]
574
+ for index in range(1, degree + 1)
575
+ ),
576
+ 0,
577
+ )
578
+ total = sum(
579
+ (
580
+ index * self.child.coefficients[index] * self.coefficients[degree - index]
581
+ for index in range(1, degree + 1)
582
+ ),
583
+ 0,
584
+ )
585
+ return divide_exact(total, degree)
586
+
587
+
588
+ class LogOneMinusNode(CoefficientNode):
589
+ def __init__(self, compiler: CoefficientCompiler, child: CoefficientNode):
590
+ self.child = child
591
+ self.inverse = InverseOneMinusNode(compiler, child)
592
+ super().__init__(compiler)
593
+
594
+ def value(self, degree: int) -> ExactNumber:
595
+ if degree == 0:
596
+ return 0
597
+ if self.compiler.labelled:
598
+ weights = binomial_row(degree - 1)
599
+ return sum(
600
+ (
601
+ weights[index - 1]
602
+ * self.child.coefficients[index]
603
+ * self.inverse.coefficients[degree - index]
604
+ for index in range(1, degree + 1)
605
+ ),
606
+ 0,
607
+ )
608
+ total = sum(
609
+ (
610
+ index * self.child.coefficients[index] * self.inverse.coefficients[degree - index]
611
+ for index in range(1, degree + 1)
612
+ ),
613
+ 0,
614
+ )
615
+ return divide_exact(total, degree)
616
+
617
+
618
+ def divisors(value: int) -> list[int]:
619
+ small: list[int] = []
620
+ large: list[int] = []
621
+ candidate = 1
622
+ while candidate * candidate <= value:
623
+ if value % candidate == 0:
624
+ small.append(candidate)
625
+ if candidate * candidate != value:
626
+ large.append(value // candidate)
627
+ candidate += 1
628
+ return small + list(reversed(large))
629
+
630
+
631
+ class EulerSelectionNode(CoefficientNode):
632
+ """Unrestricted unlabelled Set or PowerSet via its logarithm."""
633
+
634
+ def __init__(self, compiler: CoefficientCompiler, child: CoefficientNode, distinct: bool):
635
+ self.child = child
636
+ self.distinct = distinct
637
+ self.log_coefficients: CoefficientSeries = [0 for _ in range(compiler.degree + 1)]
638
+ super().__init__(compiler)
639
+
640
+ def value(self, degree: int) -> ExactNumber:
641
+ constant = self.child.coefficients[0]
642
+ if not is_nonnegative_integer(constant):
643
+ raise UnsupportedConstruction(
644
+ "Unlabelled selections require nonnegative integer coefficients"
645
+ )
646
+ if constant and not self.distinct:
647
+ raise UnsupportedConstruction("An unlabelled Set cannot contain size-zero objects")
648
+ if degree == 0:
649
+ return 2 ** integer_value(constant) if self.distinct else 1
650
+
651
+ logarithm: ExactNumber = 0
652
+ for divisor in divisors(degree):
653
+ coefficient = self.child.coefficients[degree // divisor]
654
+ if not is_nonnegative_integer(coefficient):
655
+ raise UnsupportedConstruction(
656
+ "Unlabelled selections require nonnegative integer component coefficients",
657
+ )
658
+ sign = -1 if self.distinct and divisor % 2 == 0 else 1
659
+ logarithm += sign * Fraction(integer_value(coefficient), divisor)
660
+ self.log_coefficients[degree] = compact_number(logarithm)
661
+ total = sum(
662
+ (
663
+ index * self.log_coefficients[index] * self.coefficients[degree - index]
664
+ for index in range(1, degree + 1)
665
+ ),
666
+ 0,
667
+ )
668
+ return divide_exact(total, degree)
669
+
670
+
671
+ class UnlabelledCycleNode(CoefficientNode):
672
+ def __init__(self, compiler: CoefficientCompiler, child: CoefficientNode):
673
+ self.logarithm = LogOneMinusNode(compiler, child)
674
+ super().__init__(compiler)
675
+
676
+ def value(self, degree: int) -> ExactNumber:
677
+ if degree == 0:
678
+ return Fraction(0)
679
+ return sum(
680
+ (
681
+ Fraction(euler_totient(divisor), divisor)
682
+ * self.logarithm.coefficients[degree // divisor]
683
+ for divisor in divisors(degree)
684
+ ),
685
+ Fraction(0),
686
+ )
687
+
688
+
689
+ class CoefficientCompiler:
690
+ def __init__(self, equations: dict[str, Expression], degree: int, labelled: bool):
691
+ self.equations = equations
692
+ self.degree = degree
693
+ self.labelled = labelled
694
+ self.nodes: list[CoefficientNode] = []
695
+ self.roots: dict[str, CoefficientNode] = {}
696
+ self._powers: dict[tuple[int, int], CoefficientNode] = {}
697
+ self._fixed_msets: dict[tuple[int, int], CoefficientNode] = {}
698
+ self.zero = LiteralNode(self, None)
699
+ self.one = LiteralNode(self, 0)
700
+ self.atom = LiteralNode(self, 1)
701
+
702
+ def compute(self, symbol: str, max_digits: int | None = None) -> CoefficientSeries:
703
+ if symbol not in self.equations:
704
+ raise SpecificationError(f"Specification does not define {symbol!r}")
705
+ equation_order, recursive = self.equation_order()
706
+ for name in equation_order:
707
+ self.roots[name] = self.compile(self.equations[name])
708
+
709
+ for degree in range(self.degree + 1):
710
+ if not recursive:
711
+ for node in self.nodes:
712
+ node.update(degree)
713
+ else:
714
+ iteration_limit = max(100, len(self.nodes) * 4)
715
+ for _ in range(iteration_limit):
716
+ changed = False
717
+ for node in self.nodes:
718
+ changed = node.update(degree) or changed
719
+ if not changed:
720
+ break
721
+ else:
722
+ raise UnsupportedConstruction(
723
+ f"The recursive system did not stabilize at degree {degree}; "
724
+ "it may not be well founded",
725
+ )
726
+
727
+ if max_digits is not None:
728
+ value = self.roots[symbol].coefficients[degree]
729
+ if isinstance(value, Fraction) and value.denominator != 1:
730
+ raise UnsupportedConstruction(
731
+ f"Coefficient of size {degree} does not yield an integer count: {value}",
732
+ )
733
+ if decimal_digit_count(integer_value(value)) > max_digits:
734
+ return self.roots[symbol].coefficients[:degree]
735
+ return self.roots[symbol].coefficients
736
+
737
+ def equation_order(self) -> tuple[list[str], bool]:
738
+ dependencies = {
739
+ name: self.expression_references(expression) & self.equations.keys()
740
+ for name, expression in self.equations.items()
741
+ }
742
+ order: list[str] = []
743
+ temporary: set[str] = set()
744
+ permanent: set[str] = set()
745
+ recursive = False
746
+
747
+ def visit(name: str) -> None:
748
+ nonlocal recursive
749
+ if name in permanent:
750
+ return
751
+ if name in temporary:
752
+ recursive = True
753
+ return
754
+ temporary.add(name)
755
+ for dependency in dependencies[name]:
756
+ visit(dependency)
757
+ temporary.remove(name)
758
+ permanent.add(name)
759
+ order.append(name)
760
+
761
+ for name in self.equations:
762
+ visit(name)
763
+ return order, recursive
764
+
765
+ @classmethod
766
+ def expression_references(cls, expression: Expression) -> set[str]:
767
+ if isinstance(expression, Reference):
768
+ return {expression.name}
769
+ references: set[str] = set()
770
+ for argument in expression.arguments:
771
+ references.update(cls.expression_references(argument))
772
+ return references
773
+
774
+ def compile(self, expression: Expression) -> CoefficientNode:
775
+ if isinstance(expression, Reference):
776
+ if expression.name == "Epsilon":
777
+ return self.one
778
+ if expression.name in ("Atom", "Z") and expression.name not in self.equations:
779
+ return self.atom
780
+ return ReferenceNode(self, expression.name)
781
+
782
+ children = [self.compile(argument) for argument in expression.arguments]
783
+ name = expression.name.lower()
784
+ if name == "union":
785
+ if expression.cardinality is not None:
786
+ raise SpecificationError("Union does not accept a cardinality constraint")
787
+ return self.sum(children)
788
+ if name == "prod":
789
+ if expression.cardinality is not None:
790
+ raise SpecificationError("Prod does not accept a cardinality constraint")
791
+ return self.product(children)
792
+ if len(children) != 1:
793
+ raise SpecificationError(f"{expression.name} requires exactly one component argument")
794
+
795
+ child = children[0]
796
+ if name == "sequence":
797
+ return self.sequence(child, expression.cardinality)
798
+ if name == "set":
799
+ return (
800
+ self.labelled_set(child, expression.cardinality)
801
+ if self.labelled
802
+ else self.mset(
803
+ child,
804
+ expression.cardinality,
805
+ )
806
+ )
807
+ if name == "cycle":
808
+ return self.cycle(child, expression.cardinality)
809
+ if name == "powerset":
810
+ if self.labelled:
811
+ raise UnsupportedConstruction("PowerSet is only defined for unlabelled structures")
812
+ if expression.cardinality is not None:
813
+ raise UnsupportedConstruction("PowerSet cardinality constraints are not supported")
814
+ return EulerSelectionNode(self, child, distinct=True)
815
+ raise UnsupportedConstruction(f"Unsupported constructor {expression.name!r}")
816
+
817
+ def sum(self, children: Sequence[CoefficientNode]) -> CoefficientNode:
818
+ if not children:
819
+ return self.zero
820
+ if len(children) == 1:
821
+ return children[0]
822
+ return SumNode(self, children)
823
+
824
+ def product(self, children: Sequence[CoefficientNode]) -> CoefficientNode:
825
+ if not children:
826
+ return self.one
827
+ result: CoefficientNode = children[0]
828
+ for child in children[1:]:
829
+ result = ProductNode(self, result, child)
830
+ return result
831
+
832
+ def scale(self, child: CoefficientNode, scalar: Fraction) -> CoefficientNode:
833
+ return child if scalar == 1 else ScaleNode(self, child, scalar)
834
+
835
+ def power(self, child: CoefficientNode, exponent: int) -> CoefficientNode:
836
+ key = (id(child), exponent)
837
+ if key in self._powers:
838
+ return self._powers[key]
839
+ if exponent == 0:
840
+ result: CoefficientNode = self.one
841
+ else:
842
+ result = self.one
843
+ for _ in range(exponent):
844
+ result = ProductNode(self, result, child)
845
+ self._powers[key] = result
846
+ return result
847
+
848
+ @staticmethod
849
+ def bounds(cardinality: Cardinality | None, default_minimum: int = 0) -> tuple[int, int | None]:
850
+ if cardinality is None:
851
+ return default_minimum, None
852
+ return max(default_minimum, cardinality.minimum), cardinality.maximum
853
+
854
+ def sequence(self, child: CoefficientNode, cardinality: Cardinality | None) -> CoefficientNode:
855
+ minimum, maximum = self.bounds(cardinality)
856
+ if maximum is not None:
857
+ return self.sum([self.power(child, count) for count in range(minimum, maximum + 1)])
858
+ inverse = InverseOneMinusNode(self, child)
859
+ return self.product([self.power(child, minimum), inverse])
860
+
861
+ def labelled_set(
862
+ self, child: CoefficientNode, cardinality: Cardinality | None
863
+ ) -> CoefficientNode:
864
+ minimum, maximum = self.bounds(cardinality)
865
+ if maximum is not None:
866
+ return self.sum(
867
+ [
868
+ self.scale(self.power(child, count), Fraction(1, math.factorial(count)))
869
+ for count in range(minimum, maximum + 1)
870
+ ],
871
+ )
872
+ unrestricted = ExpNode(self, child)
873
+ excluded = self.sum(
874
+ [
875
+ self.scale(self.power(child, count), Fraction(1, math.factorial(count)))
876
+ for count in range(minimum)
877
+ ],
878
+ )
879
+ return self.sum([unrestricted, self.scale(excluded, Fraction(-1))])
880
+
881
+ def fixed_mset(self, child: CoefficientNode, count: int) -> CoefficientNode:
882
+ key = (id(child), count)
883
+ if key in self._fixed_msets:
884
+ return self._fixed_msets[key]
885
+ if count == 0:
886
+ result: CoefficientNode = self.one
887
+ else:
888
+ terms = []
889
+ for part in range(1, count + 1):
890
+ substituted = SubstituteNode(self, child, part)
891
+ terms.append(ProductNode(self, substituted, self.fixed_mset(child, count - part)))
892
+ result = self.scale(self.sum(terms), Fraction(1, count))
893
+ self._fixed_msets[key] = result
894
+ return result
895
+
896
+ def mset(self, child: CoefficientNode, cardinality: Cardinality | None) -> CoefficientNode:
897
+ minimum, maximum = self.bounds(cardinality)
898
+ if maximum is not None:
899
+ return self.sum(
900
+ [self.fixed_mset(child, count) for count in range(minimum, maximum + 1)]
901
+ )
902
+ unrestricted = EulerSelectionNode(self, child, distinct=False)
903
+ excluded = self.sum([self.fixed_mset(child, count) for count in range(minimum)])
904
+ return self.sum([unrestricted, self.scale(excluded, Fraction(-1))])
905
+
906
+ def fixed_cycle(self, child: CoefficientNode, count: int) -> CoefficientNode:
907
+ if self.labelled:
908
+ return self.scale(self.power(child, count), Fraction(1, count))
909
+ terms = []
910
+ for divisor in divisors(count):
911
+ substituted = SubstituteNode(self, child, divisor)
912
+ term = self.power(substituted, count // divisor)
913
+ terms.append(self.scale(term, Fraction(euler_totient(divisor), count)))
914
+ return self.sum(terms)
915
+
916
+ def cycle(self, child: CoefficientNode, cardinality: Cardinality | None) -> CoefficientNode:
917
+ minimum, maximum = self.bounds(cardinality, default_minimum=1)
918
+ if maximum is not None:
919
+ return self.sum(
920
+ [self.fixed_cycle(child, count) for count in range(minimum, maximum + 1)]
921
+ )
922
+ unrestricted = (
923
+ LogOneMinusNode(self, child) if self.labelled else UnlabelledCycleNode(self, child)
924
+ )
925
+ excluded = self.sum([self.fixed_cycle(child, count) for count in range(1, minimum)])
926
+ return self.sum([unrestricted, self.scale(excluded, Fraction(-1))])
927
+
928
+
929
+ def compute_terms(
930
+ specification: str,
931
+ *,
932
+ labelled: bool,
933
+ term_count: int,
934
+ symbol: str = "S",
935
+ max_digits: int | None = None,
936
+ ) -> list[int]:
937
+ """Return counts a(0) through a(term_count - 1) for a specification."""
938
+
939
+ if term_count <= 0:
940
+ raise ValueError("term_count must be positive")
941
+ equations = parse_specification(specification)
942
+ coefficients = CoefficientCompiler(equations, term_count - 1, labelled).compute(
943
+ symbol,
944
+ max_digits=max_digits,
945
+ )
946
+
947
+ terms: list[int] = []
948
+ for degree, coefficient in enumerate(coefficients):
949
+ count = coefficient
950
+ if isinstance(count, Fraction) and count.denominator != 1:
951
+ raise UnsupportedConstruction(
952
+ f"Coefficient of size {degree} does not yield an integer count: {count}",
953
+ )
954
+ terms.append(integer_value(count))
955
+ return terms
956
+
957
+
958
+ def load_record(dataset: Path, structure_id: int) -> dict[str, Any]:
959
+ try:
960
+ return _load_record(dataset, structure_id)
961
+ except StructureNotFoundError as error:
962
+ raise SpecificationError(str(error)) from error
963
+
964
+
965
+ def build_argument_parser() -> argparse.ArgumentParser:
966
+ parser = argparse.ArgumentParser(description=__doc__)
967
+ source = parser.add_mutually_exclusive_group(required=True)
968
+ source.add_argument("--id", type=int, help="ECS structure number to load from the dataset")
969
+ source.add_argument("--spec", help="Specification text, for example '{S = Sequence(Z)}'")
970
+ parser.add_argument("--dataset", type=Path, default=default_dataset())
971
+ parser.add_argument(
972
+ "--terms", type=int, default=20, help="number of terms, beginning with a(0)"
973
+ )
974
+ parser.add_argument("--symbol", default="S", help="root symbol to enumerate (default: S)")
975
+ parser.add_argument(
976
+ "--max-digits", type=int, help="stop before a term exceeds this many digits"
977
+ )
978
+ universe = parser.add_mutually_exclusive_group()
979
+ universe.add_argument("--labelled", action="store_true", help="use labelled/EGF semantics")
980
+ universe.add_argument("--unlabelled", action="store_true", help="use unlabelled/OGF semantics")
981
+ parser.add_argument(
982
+ "--plain", action="store_true", help="print comma-separated integers instead of JSON"
983
+ )
984
+ return parser
985
+
986
+
987
+ def main(argv: Iterable[str] | None = None) -> int:
988
+ parser = build_argument_parser()
989
+ arguments = parser.parse_args(argv)
990
+
991
+ record = None
992
+ if arguments.id is not None:
993
+ record = load_record(arguments.dataset, arguments.id)
994
+ specification = record["specification"]
995
+ labelled = bool(record["labeled"])
996
+ symbol = record.get("symbol") or arguments.symbol
997
+ else:
998
+ if not arguments.labelled and not arguments.unlabelled:
999
+ parser.error("--spec requires either --labelled or --unlabelled")
1000
+ specification = arguments.spec
1001
+ labelled = arguments.labelled
1002
+ symbol = arguments.symbol
1003
+
1004
+ try:
1005
+ terms = compute_terms(
1006
+ specification,
1007
+ labelled=labelled,
1008
+ term_count=arguments.terms,
1009
+ symbol=symbol,
1010
+ max_digits=arguments.max_digits,
1011
+ )
1012
+ except (SpecificationError, ValueError) as error:
1013
+ parser.exit(2, f"error: {error}\n")
1014
+
1015
+ if arguments.plain:
1016
+ print(", ".join(map(str, terms)))
1017
+ return 0
1018
+
1019
+ output = {
1020
+ "id": arguments.id,
1021
+ "symbol": symbol,
1022
+ "labelled": labelled,
1023
+ "terms": [str(term) for term in terms],
1024
+ }
1025
+ if record is not None:
1026
+ stored = [str(term) for term in record.get("terms", [])]
1027
+ overlap = min(len(stored), len(terms))
1028
+ output["matches_stored_prefix"] = stored[:overlap] == output["terms"][:overlap]
1029
+ print(json.dumps(output, indent=2))
1030
+ return 0
1031
+
1032
+
1033
+ if __name__ == "__main__":
1034
+ raise SystemExit(main())