mapFolding 0.15.2__py3-none-any.whl → 0.15.4__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 (57) hide show
  1. mapFolding/__init__.py +15 -11
  2. mapFolding/_theSSOT.py +56 -63
  3. mapFolding/_theTypes.py +67 -5
  4. mapFolding/algorithms/__init__.py +1 -0
  5. mapFolding/algorithms/matrixMeanders.py +348 -0
  6. mapFolding/algorithms/oeisIDbyFormula.py +113 -0
  7. mapFolding/basecamp.py +105 -67
  8. mapFolding/oeis.py +40 -54
  9. mapFolding/reference/meandersDumpingGround/matrixMeanders64retired.py +160 -0
  10. mapFolding/{_oeisFormulas/matrixMeanders.py → reference/meandersDumpingGround/matrixMeandersBaselineV2.py} +28 -21
  11. mapFolding/someAssemblyRequired/A007822rawMaterials.py +1 -1
  12. mapFolding/someAssemblyRequired/makeAllModules.py +5 -5
  13. mapFolding/someAssemblyRequired/makeJobTheorem2codon.py +5 -4
  14. mapFolding/syntheticModules/algorithmA007822.py +1 -1
  15. mapFolding/syntheticModules/algorithmA007822Numba.py +5 -3
  16. mapFolding/syntheticModules/dataPacking.py +2 -4
  17. mapFolding/syntheticModules/dataPackingA007822.py +2 -4
  18. mapFolding/syntheticModules/initializeStateA007822.py +1 -1
  19. mapFolding/syntheticModules/theorem2A007822.py +1 -1
  20. mapFolding/syntheticModules/theorem2A007822Numba.py +1 -1
  21. mapFolding/syntheticModules/theorem2A007822Trimmed.py +1 -1
  22. mapFolding/tests/conftest.py +30 -10
  23. mapFolding/tests/test_computations.py +75 -46
  24. mapFolding/tests/test_oeis.py +2 -20
  25. {mapfolding-0.15.2.dist-info → mapfolding-0.15.4.dist-info}/METADATA +2 -1
  26. mapfolding-0.15.4.dist-info/RECORD +78 -0
  27. {mapfolding-0.15.2.dist-info → mapfolding-0.15.4.dist-info}/entry_points.txt +0 -1
  28. mapFolding/_oeisFormulas/A000136.py +0 -4
  29. mapFolding/_oeisFormulas/A000560.py +0 -4
  30. mapFolding/_oeisFormulas/A000682.py +0 -17
  31. mapFolding/_oeisFormulas/A001010.py +0 -19
  32. mapFolding/_oeisFormulas/A001011.py +0 -5
  33. mapFolding/_oeisFormulas/A005315.py +0 -4
  34. mapFolding/_oeisFormulas/A005316.py +0 -10
  35. mapFolding/_oeisFormulas/A223094.py +0 -7
  36. mapFolding/_oeisFormulas/A259702.py +0 -4
  37. mapFolding/_oeisFormulas/A301620.py +0 -6
  38. mapFolding/_oeisFormulas/Z0Z_aOFn.py +0 -33
  39. mapFolding/_oeisFormulas/Z0Z_oeisMeanders.py +0 -52
  40. mapFolding/_oeisFormulas/__init__.py +0 -1
  41. mapFolding/_oeisFormulas/matrixMeandersAnnex.py +0 -84
  42. mapfolding-0.15.2.dist-info/RECORD +0 -88
  43. /mapFolding/{daoOfMapFolding.py → algorithms/daoOfMapFolding.py} +0 -0
  44. /mapFolding/reference/{A005316JavaPort.py → meandersDumpingGround/A005316JavaPort.py} +0 -0
  45. /mapFolding/reference/{A005316imperative.py → meandersDumpingGround/A005316imperative.py} +0 -0
  46. /mapFolding/reference/{A005316intOptimized.py → meandersDumpingGround/A005316intOptimized.py} +0 -0
  47. /mapFolding/reference/{A005316optimized128bit.py → meandersDumpingGround/A005316optimized128bit.py} +0 -0
  48. /mapFolding/reference/{A005316primitiveOptimized.py → meandersDumpingGround/A005316primitiveOptimized.py} +0 -0
  49. /mapFolding/reference/{A005316redis.py → meandersDumpingGround/A005316redis.py} +0 -0
  50. /mapFolding/reference/{A005316write2disk.py → meandersDumpingGround/A005316write2disk.py} +0 -0
  51. /mapFolding/reference/{matrixMeandersBaseline.py → meandersDumpingGround/matrixMeandersBaseline.py} +0 -0
  52. /mapFolding/reference/{matrixMeandersBaselineAnnex.py → meandersDumpingGround/matrixMeandersBaselineAnnex.py} +0 -0
  53. /mapFolding/reference/{matrixMeandersSimpleQueue.py → meandersDumpingGround/matrixMeandersSimpleQueue.py} +0 -0
  54. /mapFolding/reference/{matrixMeandersSlicePop.py → meandersDumpingGround/matrixMeandersSlicePop.py} +0 -0
  55. {mapfolding-0.15.2.dist-info → mapfolding-0.15.4.dist-info}/WHEEL +0 -0
  56. {mapfolding-0.15.2.dist-info → mapfolding-0.15.4.dist-info}/licenses/LICENSE +0 -0
  57. {mapfolding-0.15.2.dist-info → mapfolding-0.15.4.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,160 @@
1
+ # ruff: noqa
2
+ import numpy
3
+
4
+ indexDistinctCrossings = int(0) # noqa: RUF046, UP018
5
+ indexBifurcationAlpha = int(1) # noqa: RUF046, UP018
6
+ indexBifurcationZulu = int(2) # noqa: RUF046, UP018
7
+ indexCurveLocations = int(3) # noqa: RUF046, UP018
8
+
9
+ def make1array(listArrays: list[numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.uint64]]]) -> numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.uint64]]:
10
+ arrayCurveLocations: numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.uint64]] = numpy.fromiter({element for stupidSystem in listArrays for element in stupidSystem[:, 1]}, dtype=numpy.uint64)
11
+
12
+ arrayOut = numpy.column_stack((
13
+ numpy.zeros(len(arrayCurveLocations), dtype=numpy.uint64)
14
+ , arrayCurveLocations & numpy.uint64(0x5555555555555555)
15
+ , (arrayCurveLocations & numpy.uint64(0xaaaaaaaaaaaaaaaa)) >> numpy.uint64(1)
16
+ , arrayCurveLocations
17
+ ))
18
+ for arrayCurveLocations in listArrays:
19
+ arrayOut[:, indexDistinctCrossings] += numpy.sum(arrayCurveLocations[:, 0] * (arrayCurveLocations[:, -1][:, numpy.newaxis] == arrayOut[:, indexCurveLocations]).T, axis=1)
20
+
21
+ return arrayOut # The next `arrayBifurcations`
22
+
23
+ def convertDictionaryToNumPy(dictionaryIn: dict[int, int]) -> numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.uint64]]:
24
+ arrayKeys: numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.uint64]] = numpy.fromiter(dictionaryIn.keys(), dtype=numpy.uint64)
25
+
26
+ return numpy.column_stack((
27
+ numpy.fromiter(dictionaryIn.values(), dtype=numpy.uint64)
28
+ , arrayKeys & numpy.uint64(0x5555555555555555)
29
+ , (arrayKeys & numpy.uint64(0xaaaaaaaaaaaaaaaa)) >> numpy.uint64(1)
30
+ , arrayKeys
31
+ ))
32
+
33
+ def count(bridges: int, startingCurveLocations: dict[int, int]) -> int:
34
+ arrayBifurcations: numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.uint64]] = convertDictionaryToNumPy(startingCurveLocations)
35
+
36
+ while bridges > 0:
37
+ bridges -= 1
38
+
39
+ listArrayCurveLocationsAnalyzed: list[numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.uint64]]] = []
40
+
41
+ # Selector-adjacent
42
+ curveLocationsMAXIMUM: numpy.uint64 = numpy.uint64(1) << numpy.uint64(2 * bridges + 4)
43
+ # Selectors, general
44
+ selectBifurcationAlphaCurves: numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.bool_]] = arrayBifurcations[:, indexBifurcationAlpha] != numpy.uint64(1)
45
+ selectBifurcationAlphaEven: numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.bool_]] = (arrayBifurcations[:, indexBifurcationAlpha] & numpy.uint64(1)) == numpy.uint64(0)
46
+ selectBifurcationZuluCurves: numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.bool_]] = arrayBifurcations[:, indexBifurcationZulu] != numpy.uint64(1)
47
+ selectBifurcationZuluEven: numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.bool_]] = (arrayBifurcations[:, indexBifurcationZulu] & numpy.uint64(1)) == numpy.uint64(0)
48
+
49
+ # bridgesSimple
50
+ selector: numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.bool_]] = arrayBifurcations[:, indexDistinctCrossings] >= numpy.uint64(0) # This had better always be `True`.
51
+ curveLocations: numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.uint64]] = (((arrayBifurcations[selector, indexBifurcationAlpha] | (arrayBifurcations[selector, indexBifurcationZulu] << numpy.uint64(1))) << numpy.uint64(2)) | numpy.uint64(3))
52
+ listArrayCurveLocationsAnalyzed.append(numpy.column_stack((arrayBifurcations[selector, indexDistinctCrossings][curveLocations < curveLocationsMAXIMUM], curveLocations[curveLocations < curveLocationsMAXIMUM])))
53
+
54
+ # bifurcationAlphaCurves
55
+ this = numpy.bitwise_or.reduce((
56
+ arrayBifurcations[arrayBifurcations[:, indexBifurcationAlpha] != numpy.uint64(1), indexBifurcationAlpha] >> numpy.uint64(2)
57
+ , arrayBifurcations[arrayBifurcations[:, indexBifurcationAlpha] != numpy.uint64(1), indexBifurcationZulu] << numpy.uint64(3)
58
+ , (numpy.uint64(1) - (arrayBifurcations[arrayBifurcations[:, indexBifurcationAlpha] != numpy.uint64(1), indexBifurcationAlpha] & numpy.uint64(1))) << numpy.uint64(1)
59
+ ))
60
+ curveLocations: numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.uint64]] = numpy.where(this < curveLocationsMAXIMUM, this, numpy.uint64(0))
61
+ # print(curveLocations.astype(numpy.bool_))
62
+ print(curveLocations)
63
+ distinctCrossings = arrayBifurcations[arrayBifurcations[:, indexBifurcationAlpha] != numpy.uint64(1), indexDistinctCrossings]
64
+ print(distinctCrossings)
65
+ listArrayCurveLocationsAnalyzed.append(
66
+ numpy.column_stack((distinctCrossings, curveLocations))
67
+ )
68
+ # print(arrayBifurcations)
69
+ # print(listArrayCurveLocationsAnalyzed[-1])
70
+
71
+ # bifurcationZuluCurves
72
+ selector = selectBifurcationZuluCurves
73
+ curveLocations: numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.uint64]] = numpy.bitwise_or.reduce((
74
+ arrayBifurcations[selector, indexBifurcationZulu] >> numpy.uint64(1)
75
+ , arrayBifurcations[selector, indexBifurcationAlpha] << numpy.uint64(2)
76
+ , (numpy.uint64(1) - (arrayBifurcations[selector, indexBifurcationZulu] & numpy.uint64(1)))
77
+ ))
78
+ listArrayCurveLocationsAnalyzed.append(numpy.column_stack((arrayBifurcations[selector, indexDistinctCrossings][curveLocations < curveLocationsMAXIMUM], curveLocations[curveLocations < curveLocationsMAXIMUM])))
79
+
80
+ # Z0Z_bridgesBifurcationAlphaToRepair
81
+ selector: numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.bool_]] = numpy.logical_and.reduce((
82
+ selectBifurcationAlphaCurves, selectBifurcationZuluCurves, selectBifurcationAlphaEven, ~selectBifurcationZuluEven
83
+ ))
84
+
85
+ # Initialize
86
+ XOrHere2makePair = numpy.uint64(1)
87
+
88
+ while selector.any():
89
+ XOrHere2makePair <<= numpy.uint64(2)
90
+
91
+ selectUnpaired_0b1: numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.bool_]] = (arrayBifurcations[:, indexBifurcationAlpha] & XOrHere2makePair) == numpy.uint64(0)
92
+ selectorUnified: numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.bool_]] = numpy.logical_and.reduce((selector, selectUnpaired_0b1))
93
+
94
+ # Modify in place
95
+ arrayBifurcations[selectorUnified, indexBifurcationAlpha] ^= XOrHere2makePair
96
+
97
+ # Remove the modified elements
98
+ selector: numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.bool_]] = numpy.logical_and.reduce((selector, ~selectorUnified))
99
+
100
+ selector: numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.bool_]] = numpy.logical_and.reduce((
101
+ selectBifurcationAlphaCurves, selectBifurcationZuluCurves, selectBifurcationAlphaEven, ~selectBifurcationZuluEven
102
+ ))
103
+ curveLocations: numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.uint64]] = (
104
+ ((arrayBifurcations[selector, indexBifurcationZulu] >> numpy.uint64(2)) << numpy.uint64(1))
105
+ | (arrayBifurcations[selector, indexBifurcationAlpha] >> numpy.uint64(2))
106
+ )
107
+
108
+ listArrayCurveLocationsAnalyzed.append(numpy.column_stack((arrayBifurcations[selector, indexDistinctCrossings][curveLocations < curveLocationsMAXIMUM], curveLocations[curveLocations < curveLocationsMAXIMUM])))
109
+
110
+ # Z0Z_bridgesBifurcationZuluToRepair
111
+ selector: numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.bool_]] = numpy.logical_and.reduce((
112
+ selectBifurcationAlphaCurves, selectBifurcationZuluCurves, ~selectBifurcationAlphaEven, selectBifurcationZuluEven
113
+ ))
114
+
115
+ # Initialize
116
+ XOrHere2makePair: numpy.uint64 = numpy.uint64(1)
117
+
118
+ while selector.any():
119
+ XOrHere2makePair <<= numpy.uint64(2)
120
+
121
+ # New condition
122
+ selectUnpaired_0b1: numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.bool_]] = (arrayBifurcations[:, indexBifurcationZulu] & XOrHere2makePair) == numpy.uint64(0)
123
+ selectorUnified: numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.bool_]] = numpy.logical_and.reduce((selector, selectUnpaired_0b1))
124
+
125
+ # Modify in place
126
+ arrayBifurcations[selectorUnified, indexBifurcationZulu] ^= XOrHere2makePair
127
+
128
+ # Remove the modified elements from the selector
129
+ selector: numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.bool_]] = numpy.logical_and.reduce((selector, ~selectorUnified))
130
+
131
+ selector: numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.bool_]] = numpy.logical_and.reduce((
132
+ selectBifurcationAlphaCurves, selectBifurcationZuluCurves, ~selectBifurcationAlphaEven, selectBifurcationZuluEven
133
+ ))
134
+
135
+ curveLocations: numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.uint64]] = (
136
+ ((arrayBifurcations[selector, indexBifurcationZulu] >> numpy.uint64(2)) << numpy.uint64(1))
137
+ | (arrayBifurcations[selector, indexBifurcationAlpha] >> numpy.uint64(2))
138
+ )
139
+
140
+ listArrayCurveLocationsAnalyzed.append(numpy.column_stack((arrayBifurcations[selector, indexDistinctCrossings][curveLocations < curveLocationsMAXIMUM], curveLocations[curveLocations < curveLocationsMAXIMUM])))
141
+
142
+ # Z0Z_bridgesAligned
143
+ selector: numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.bool_]] = numpy.logical_and.reduce((
144
+ selectBifurcationAlphaCurves, selectBifurcationZuluCurves, selectBifurcationAlphaEven, selectBifurcationZuluEven
145
+ ))
146
+
147
+ curveLocations: numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.uint64]] = (
148
+ ((arrayBifurcations[selector, indexBifurcationZulu] >> numpy.uint64(2)) << numpy.uint64(1))
149
+ | (arrayBifurcations[selector, indexBifurcationAlpha] >> numpy.uint64(2))
150
+ )
151
+
152
+ listArrayCurveLocationsAnalyzed.append(numpy.column_stack((arrayBifurcations[selector, indexDistinctCrossings][curveLocations < curveLocationsMAXIMUM], curveLocations[curveLocations < curveLocationsMAXIMUM])))
153
+
154
+ arrayBifurcations = make1array(listArrayCurveLocationsAnalyzed)
155
+
156
+ listArrayCurveLocationsAnalyzed.clear()
157
+
158
+ # print(int(sum(arrayBifurcations[:, 0])))
159
+ return int(sum(arrayBifurcations[:, 0]))
160
+
@@ -13,7 +13,7 @@ def count(bridges: int, startingCurveLocations: dict[int, int]) -> int:
13
13
  (0x1555555, 0x2aaaaaa, 0x1000000),
14
14
  (0x5555555, 0xaaaaaaa, 0x4000000),
15
15
  (0x15555555, 0x2aaaaaaa, 0x10000000),
16
- (0x55555555, 0xaaaaaaaa, 0x40000000),
16
+ (0x55555555, 0xaaaaaaaa, 0x40000000), # `bridges = 13`, 0xaaaaaaaa.bit_length() = 32
17
17
  (0x155555555, 0x2aaaaaaaa, 0x100000000),
18
18
  (0x555555555, 0xaaaaaaaaa, 0x400000000),
19
19
  (0x1555555555, 0x2aaaaaaaaa, 0x1000000000),
@@ -29,7 +29,7 @@ def count(bridges: int, startingCurveLocations: dict[int, int]) -> int:
29
29
  (0x155555555555555, 0x2aaaaaaaaaaaaaa, 0x100000000000000),
30
30
  (0x555555555555555, 0xaaaaaaaaaaaaaaa, 0x400000000000000),
31
31
  (0x1555555555555555, 0x2aaaaaaaaaaaaaaa, 0x1000000000000000),
32
- (0x5555555555555555, 0xaaaaaaaaaaaaaaaa, 0x4000000000000000),
32
+ (0x5555555555555555, 0xaaaaaaaaaaaaaaaa, 0x4000000000000000), # 0x5000000000000000.bit_length() = 63; 0xaaaaaaaaaaaaaaaa.bit_length() = 64; 0x5555555555555555.bit_length() = 63
33
33
  (0x15555555555555555, 0x2aaaaaaaaaaaaaaaa, 0x10000000000000000),
34
34
  (0x55555555555555555, 0xaaaaaaaaaaaaaaaaa, 0x40000000000000000),
35
35
  (0x155555555555555555, 0x2aaaaaaaaaaaaaaaaa, 0x100000000000000000),
@@ -63,6 +63,11 @@ def count(bridges: int, startingCurveLocations: dict[int, int]) -> int:
63
63
  (0x15555555555555555555555555555555, 0x2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, 0x10000000000000000000000000000000),
64
64
  (0x55555555555555555555555555555555, 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, 0x40000000000000000000000000000000),
65
65
  ]
66
+ """`bridges = 29`
67
+ 0x5000000000000000.bit_length() = 63;
68
+ 0xaaaaaaaaaaaaaaaa.bit_length() = 64;
69
+ 0x5555555555555555.bit_length() = 63"""
70
+
66
71
  listCurveMaximums = listCurveMaximums[0:bridges]
67
72
 
68
73
  dictionaryCurveLocations: dict[int, int] = {}
@@ -70,6 +75,7 @@ def count(bridges: int, startingCurveLocations: dict[int, int]) -> int:
70
75
  bridges -= 1
71
76
 
72
77
  bifurcationAlphaLocator, bifurcationZuluLocator, curveLocationsMAXIMUM = listCurveMaximums[bridges]
78
+
73
79
  for curveLocations, distinctCrossings in startingCurveLocations.items():
74
80
  bifurcationAlpha = (curveLocations & bifurcationAlphaLocator)
75
81
  bifurcationZulu = (curveLocations & bifurcationZuluLocator) >> 1
@@ -77,41 +83,41 @@ def count(bridges: int, startingCurveLocations: dict[int, int]) -> int:
77
83
  bifurcationAlphaHasCurves = bifurcationAlpha != 1
78
84
  bifurcationZuluHasCurves = bifurcationZulu != 1
79
85
 
80
- # Curve location analysis
86
+ # Z0Z_simpleBridges
81
87
  curveLocationAnalysis = ((bifurcationAlpha | (bifurcationZulu << 1)) << 2) | 3
82
88
  if curveLocationAnalysis < curveLocationsMAXIMUM:
83
89
  dictionaryCurveLocations[curveLocationAnalysis] = dictionaryCurveLocations.get(curveLocationAnalysis, 0) + distinctCrossings
84
90
 
85
- # Curve location analysis, conditional
86
- if bifurcationZuluHasCurves:
87
- curveLocationAnalysis = (bifurcationZulu >> 1) | (bifurcationAlpha << 2) | (bifurcationZuluIsEven := not (bifurcationZulu & 1))
91
+ # bifurcationAlphaCurves
92
+ if bifurcationAlphaHasCurves:
93
+ curveLocationAnalysis = (bifurcationAlphaShiftRight2 := bifurcationAlpha >> 2) | (bifurcationZulu << 3) | ((bifurcationAlphaIsEven := 1 - (bifurcationAlpha & 0b1)) << 1)
88
94
  if curveLocationAnalysis < curveLocationsMAXIMUM:
89
95
  dictionaryCurveLocations[curveLocationAnalysis] = dictionaryCurveLocations.get(curveLocationAnalysis, 0) + distinctCrossings
90
96
 
91
- # Curve location analysis, conditional
92
- if bifurcationAlphaHasCurves:
93
- curveLocationAnalysis = (bifurcationAlphaShiftRight2 := bifurcationAlpha >> 2) | (bifurcationZulu << 3) | ((bifurcationAlphaIsEven := 1 - (bifurcationAlpha & 0b1)) << 1)
97
+ # bifurcationZuluCurves
98
+ if bifurcationZuluHasCurves:
99
+ curveLocationAnalysis = (bifurcationZulu >> 1) | (bifurcationAlpha << 2) | (bifurcationZuluIsEven := 1 - (bifurcationZulu & 1))
94
100
  if curveLocationAnalysis < curveLocationsMAXIMUM:
95
101
  dictionaryCurveLocations[curveLocationAnalysis] = dictionaryCurveLocations.get(curveLocationAnalysis, 0) + distinctCrossings
96
102
 
97
- # Curve location analysis, uber-conditional
103
+ # Z0Z_alignedBridges
98
104
  if bifurcationZuluHasCurves and bifurcationAlphaHasCurves:
99
105
  # One Truth-check to select a code path
100
- finalZeroCombination = (bifurcationZuluIsEven << 1) | bifurcationAlphaIsEven # pyright: ignore[reportPossiblyUnboundVariable]
106
+ bifurcationsCanBePairedTogether = (bifurcationZuluIsEven << 1) | bifurcationAlphaIsEven # pyright: ignore[reportPossiblyUnboundVariable]
101
107
 
102
- if finalZeroCombination != 0: # Case 0 (False, False)
108
+ if bifurcationsCanBePairedTogether != 0: # Case 0 (False, False)
103
109
  XOrHere2makePair = 0b1
104
- findUnpairedBinary1 = 0
110
+ findUnpaired_0b1 = 0
105
111
 
106
- if finalZeroCombination == 1: # Case 1: (False, True)
107
- while findUnpairedBinary1 >= 0:
112
+ if bifurcationsCanBePairedTogether == 1: # Case 1: (False, True)
113
+ while findUnpaired_0b1 >= 0:
108
114
  XOrHere2makePair <<= 2
109
- findUnpairedBinary1 += 1 if (bifurcationAlpha & XOrHere2makePair) == 0 else -1
115
+ findUnpaired_0b1 += 1 if (bifurcationAlpha & XOrHere2makePair) == 0 else -1
110
116
  bifurcationAlphaShiftRight2 = (bifurcationAlpha ^ XOrHere2makePair) >> 2
111
- elif finalZeroCombination == 2: # Case 2: (True, False)
112
- while findUnpairedBinary1 >= 0:
117
+ elif bifurcationsCanBePairedTogether == 2: # Case 2: (True, False)
118
+ while findUnpaired_0b1 >= 0:
113
119
  XOrHere2makePair <<= 2
114
- findUnpairedBinary1 += 1 if (bifurcationZulu & XOrHere2makePair) == 0 else -1
120
+ findUnpaired_0b1 += 1 if (bifurcationZulu & XOrHere2makePair) == 0 else -1
115
121
  bifurcationZulu ^= XOrHere2makePair
116
122
 
117
123
  # Cases 1, 2, and 3 all compute curveLocationAnalysis
@@ -120,7 +126,8 @@ def count(bridges: int, startingCurveLocations: dict[int, int]) -> int:
120
126
  if curveLocationAnalysis < curveLocationsMAXIMUM:
121
127
  dictionaryCurveLocations[curveLocationAnalysis] = dictionaryCurveLocations.get(curveLocationAnalysis, 0) + distinctCrossings
122
128
 
123
- startingCurveLocations = dictionaryCurveLocations.copy()
124
- dictionaryCurveLocations = {}
129
+ startingCurveLocations.clear()
130
+ startingCurveLocations, dictionaryCurveLocations = dictionaryCurveLocations, startingCurveLocations
125
131
 
126
132
  return sum(startingCurveLocations.values())
133
+
@@ -21,7 +21,7 @@ def {Z0Z_identifier}(state: MapFoldingState) -> MapFoldingState:
21
21
  ImaSymmetricFold = True
22
22
  leafConnectee = 0
23
23
  while leafConnectee < indexInMiddle:
24
- if state.leafComparison[(state.indexMiniGap + leafConnectee) % (state.leavesTotal + 1)] != state.leafComparison[(state.indexMiniGap + state.leavesTotal + 1 - 2 - leafConnectee) % (state.leavesTotal + 1)]:
24
+ if state.leafComparison[(state.indexMiniGap + leafConnectee) % (state.leavesTotal + 1)] != state.leafComparison[(state.indexMiniGap + state.leavesTotal - 1 - leafConnectee) % (state.leavesTotal + 1)]:
25
25
  ImaSymmetricFold = False
26
26
  break
27
27
  leafConnectee += 1
@@ -711,16 +711,16 @@ def trimTheorem2(astModule: ast.Module, moduleIdentifier: str, callableIdentifie
711
711
  return pathFilename
712
712
 
713
713
  if __name__ == '__main__':
714
- astModule = _getModule(logicalPathInfix=None)
714
+ astModule = _getModule(logicalPathInfix='algorithms')
715
715
  pathFilename: PurePath = makeDaoOfMapFoldingNumba(astModule, 'daoOfMapFoldingNumba', None, logicalPathInfixDEFAULT, sourceCallableDispatcherDEFAULT)
716
716
 
717
- astModule = _getModule(logicalPathInfix=None)
717
+ astModule = _getModule(logicalPathInfix='algorithms')
718
718
  pathFilename = makeDaoOfMapFoldingParallelNumba(astModule, 'countParallelNumba', None, logicalPathInfixDEFAULT, sourceCallableDispatcherDEFAULT)
719
719
 
720
- astModule: ast.Module = _getModule(logicalPathInfix=None)
720
+ astModule: ast.Module = _getModule(logicalPathInfix='algorithms')
721
721
  makeInitializeState(astModule, 'initializeState', 'transitionOnGroupsOfFolds', logicalPathInfixDEFAULT)
722
722
 
723
- astModule = _getModule(logicalPathInfix=None)
723
+ astModule = _getModule(logicalPathInfix='algorithms')
724
724
  pathFilename = makeTheorem2(astModule, 'theorem2', None, logicalPathInfixDEFAULT, None)
725
725
 
726
726
  astModule = parsePathFilename2astModule(pathFilename)
@@ -733,7 +733,7 @@ if __name__ == '__main__':
733
733
  makeUnRePackDataclass(astImportFrom)
734
734
 
735
735
  # A007822 -----------------------------------------------------------
736
- astModule = _getModule(logicalPathInfix=None)
736
+ astModule = _getModule(logicalPathInfix='algorithms')
737
737
  pathFilename = addSymmetryCheck(astModule, 'algorithmA007822', None, logicalPathInfixDEFAULT, None)
738
738
 
739
739
  astModule = _getModule(moduleIdentifier='algorithmA007822')
@@ -5,13 +5,13 @@ https://docs.exaloop.io/start/install/
5
5
 
6
6
  from astToolkit import (
7
7
  Be, DOT, extractFunctionDef, Grab, identifierDotAttribute, IngredientsFunction, IngredientsModule, Make, NodeChanger,
8
- NodeTourist, Then)
8
+ NodeTourist, parseLogicalPath2astModule, Then)
9
9
  from astToolkit.transformationTools import removeUnusedParameters, write_astModule
10
10
  from hunterMakesPy import autoDecodingRLE, raiseIfNone
11
11
  from mapFolding import DatatypeLeavesTotal, getPathFilenameFoldsTotal, MapFoldingState
12
12
  from mapFolding.someAssemblyRequired import IfThis
13
13
  from mapFolding.someAssemblyRequired.RecipeJob import RecipeJobTheorem2
14
- from mapFolding.syntheticModules.initializeState import transitionOnGroupsOfFolds
14
+ from mapFolding.syntheticModules.initializeStateA007822 import transitionOnGroupsOfFolds
15
15
  from pathlib import Path, PurePosixPath
16
16
  from typing import cast, NamedTuple, TYPE_CHECKING
17
17
  import ast
@@ -214,11 +214,12 @@ def fromMapShape(mapShape: tuple[DatatypeLeavesTotal, ...]) -> None:
214
214
  """
215
215
  state = transitionOnGroupsOfFolds(MapFoldingState(mapShape))
216
216
  pathModule = PurePosixPath(Path.home(), 'mapFolding', 'jobs')
217
+ source_astModule = parseLogicalPath2astModule('mapFolding.syntheticModules.theorem2A007822Numba')
217
218
  pathFilenameFoldsTotal = PurePosixPath(getPathFilenameFoldsTotal(state.mapShape, pathModule))
218
- aJob = RecipeJobTheorem2(state, pathModule=pathModule, pathFilenameFoldsTotal=pathFilenameFoldsTotal)
219
+ aJob = RecipeJobTheorem2(state, source_astModule=source_astModule, pathModule=pathModule, pathFilenameFoldsTotal=pathFilenameFoldsTotal)
219
220
  makeJob(aJob)
220
221
 
221
222
  if __name__ == '__main__':
222
- mapShape = (2, 21)
223
+ mapShape = (1, 15)
223
224
  fromMapShape(mapShape)
224
225
 
@@ -14,7 +14,7 @@ def filterAsymmetricFolds(state: MapFoldingState) -> MapFoldingState:
14
14
  ImaSymmetricFold = True
15
15
  leafConnectee = 0
16
16
  while leafConnectee < indexInMiddle:
17
- if state.leafComparison[(state.indexMiniGap + leafConnectee) % (state.leavesTotal + 1)] != state.leafComparison[(state.indexMiniGap + state.leavesTotal + 1 - 2 - leafConnectee) % (state.leavesTotal + 1)]:
17
+ if state.leafComparison[(state.indexMiniGap + leafConnectee) % (state.leavesTotal + 1)] != state.leafComparison[(state.indexMiniGap + state.leavesTotal - 1 - leafConnectee) % (state.leavesTotal + 1)]:
18
18
  ImaSymmetricFold = False
19
19
  break
20
20
  leafConnectee += 1
@@ -1,4 +1,6 @@
1
- from mapFolding.dataBaskets import Array1DElephino, Array1DLeavesTotal, Array3DLeavesTotal, DatatypeElephino, DatatypeFoldsTotal, DatatypeLeavesTotal, MapFoldingState
1
+ from mapFolding.dataBaskets import (
2
+ Array1DElephino, Array1DLeavesTotal, Array3DLeavesTotal, DatatypeElephino, DatatypeFoldsTotal, DatatypeLeavesTotal,
3
+ MapFoldingState)
2
4
  from numba import jit
3
5
 
4
6
  @jit(cache=True, error_model='numpy', fastmath=True, forceinline=True)
@@ -19,7 +21,7 @@ def count(groupsOfFolds: DatatypeFoldsTotal, gap1ndex: DatatypeElephino, gap1nde
19
21
  ImaSymmetricFold = True
20
22
  leafConnectee = 0
21
23
  while leafConnectee < indexInMiddle:
22
- if leafComparison[(indexMiniGap + leafConnectee) % (leavesTotal + 1)] != leafComparison[(indexMiniGap + leavesTotal + 1 - 2 - leafConnectee) % (leavesTotal + 1)]:
24
+ if leafComparison[(indexMiniGap + leafConnectee) % (leavesTotal + 1)] != leafComparison[(indexMiniGap + leavesTotal - 1 - leafConnectee) % (leavesTotal + 1)]:
23
25
  ImaSymmetricFold = False
24
26
  break
25
27
  leafConnectee += 1
@@ -92,4 +94,4 @@ def doTheNeedful(state: MapFoldingState) -> MapFoldingState:
92
94
  leavesTotal: DatatypeLeavesTotal = state.leavesTotal
93
95
  groupsOfFolds, gap1ndex, gap1ndexCeiling, indexDimension, indexLeaf, indexMiniGap, leaf1ndex, leafConnectee, dimensionsUnconstrained, countDimensionsGapped, gapRangeStart, gapsWhere, leafAbove, leafBelow, leafComparison, connectionGraph, dimensionsTotal, leavesTotal = count(groupsOfFolds, gap1ndex, gap1ndexCeiling, indexDimension, indexLeaf, indexMiniGap, leaf1ndex, leafConnectee, dimensionsUnconstrained, countDimensionsGapped, gapRangeStart, gapsWhere, leafAbove, leafBelow, leafComparison, connectionGraph, dimensionsTotal, leavesTotal)
94
96
  state = MapFoldingState(mapShape=mapShape, groupsOfFolds=groupsOfFolds, gap1ndex=gap1ndex, gap1ndexCeiling=gap1ndexCeiling, indexDimension=indexDimension, indexLeaf=indexLeaf, indexMiniGap=indexMiniGap, leaf1ndex=leaf1ndex, leafConnectee=leafConnectee, dimensionsUnconstrained=dimensionsUnconstrained, countDimensionsGapped=countDimensionsGapped, gapRangeStart=gapRangeStart, gapsWhere=gapsWhere, leafAbove=leafAbove, leafBelow=leafBelow, leafComparison=leafComparison)
95
- return state
97
+ return state
@@ -1,6 +1,4 @@
1
- from mapFolding.dataBaskets import (
2
- Array1DElephino, Array1DLeavesTotal, Array3DLeavesTotal, DatatypeElephino, DatatypeFoldsTotal, DatatypeLeavesTotal,
3
- MapFoldingState)
1
+ from mapFolding.dataBaskets import Array1DElephino, Array1DLeavesTotal, Array3DLeavesTotal, DatatypeElephino, DatatypeFoldsTotal, DatatypeLeavesTotal, MapFoldingState
4
2
  from mapFolding.syntheticModules.theorem2Numba import count
5
3
 
6
4
  def sequential(state: MapFoldingState) -> MapFoldingState:
@@ -25,4 +23,4 @@ def sequential(state: MapFoldingState) -> MapFoldingState:
25
23
  leavesTotal: DatatypeLeavesTotal = state.leavesTotal
26
24
  groupsOfFolds, gap1ndex, gap1ndexCeiling, indexDimension, indexMiniGap, leaf1ndex, leafConnectee, dimensionsUnconstrained, countDimensionsGapped, gapRangeStart, gapsWhere, leafAbove, leafBelow, connectionGraph, dimensionsTotal, leavesTotal = count(groupsOfFolds, gap1ndex, gap1ndexCeiling, indexDimension, indexMiniGap, leaf1ndex, leafConnectee, dimensionsUnconstrained, countDimensionsGapped, gapRangeStart, gapsWhere, leafAbove, leafBelow, connectionGraph, dimensionsTotal, leavesTotal)
27
25
  state = MapFoldingState(mapShape=mapShape, groupsOfFolds=groupsOfFolds, gap1ndex=gap1ndex, gap1ndexCeiling=gap1ndexCeiling, indexDimension=indexDimension, indexLeaf=indexLeaf, indexMiniGap=indexMiniGap, leaf1ndex=leaf1ndex, leafConnectee=leafConnectee, dimensionsUnconstrained=dimensionsUnconstrained, countDimensionsGapped=countDimensionsGapped, gapRangeStart=gapRangeStart, gapsWhere=gapsWhere, leafAbove=leafAbove, leafBelow=leafBelow, leafComparison=leafComparison)
28
- return state
26
+ return state
@@ -1,6 +1,4 @@
1
- from mapFolding.dataBaskets import (
2
- Array1DElephino, Array1DLeavesTotal, Array3DLeavesTotal, DatatypeElephino, DatatypeFoldsTotal, DatatypeLeavesTotal,
3
- MapFoldingState)
1
+ from mapFolding.dataBaskets import Array1DElephino, Array1DLeavesTotal, Array3DLeavesTotal, DatatypeElephino, DatatypeFoldsTotal, DatatypeLeavesTotal, MapFoldingState
4
2
  from mapFolding.syntheticModules.theorem2A007822Numba import count
5
3
 
6
4
  def sequential(state: MapFoldingState) -> MapFoldingState:
@@ -25,4 +23,4 @@ def sequential(state: MapFoldingState) -> MapFoldingState:
25
23
  leavesTotal: DatatypeLeavesTotal = state.leavesTotal
26
24
  groupsOfFolds, gap1ndex, gap1ndexCeiling, indexDimension, indexLeaf, indexMiniGap, leaf1ndex, leafConnectee, dimensionsUnconstrained, countDimensionsGapped, gapRangeStart, gapsWhere, leafAbove, leafBelow, leafComparison, connectionGraph, dimensionsTotal, leavesTotal = count(groupsOfFolds, gap1ndex, gap1ndexCeiling, indexDimension, indexLeaf, indexMiniGap, leaf1ndex, leafConnectee, dimensionsUnconstrained, countDimensionsGapped, gapRangeStart, gapsWhere, leafAbove, leafBelow, leafComparison, connectionGraph, dimensionsTotal, leavesTotal)
27
25
  state = MapFoldingState(mapShape=mapShape, groupsOfFolds=groupsOfFolds, gap1ndex=gap1ndex, gap1ndexCeiling=gap1ndexCeiling, indexDimension=indexDimension, indexLeaf=indexLeaf, indexMiniGap=indexMiniGap, leaf1ndex=leaf1ndex, leafConnectee=leafConnectee, dimensionsUnconstrained=dimensionsUnconstrained, countDimensionsGapped=countDimensionsGapped, gapRangeStart=gapRangeStart, gapsWhere=gapsWhere, leafAbove=leafAbove, leafBelow=leafBelow, leafComparison=leafComparison)
28
- return state
26
+ return state
@@ -17,7 +17,7 @@ def transitionOnGroupsOfFolds(state: MapFoldingState) -> MapFoldingState:
17
17
  ImaSymmetricFold = True
18
18
  leafConnectee = 0
19
19
  while leafConnectee < indexInMiddle:
20
- if state.leafComparison[(state.indexMiniGap + leafConnectee) % (state.leavesTotal + 1)] != state.leafComparison[(state.indexMiniGap + state.leavesTotal + 1 - 2 - leafConnectee) % (state.leavesTotal + 1)]:
20
+ if state.leafComparison[(state.indexMiniGap + leafConnectee) % (state.leavesTotal + 1)] != state.leafComparison[(state.indexMiniGap + state.leavesTotal - 1 - leafConnectee) % (state.leavesTotal + 1)]:
21
21
  ImaSymmetricFold = False
22
22
  break
23
23
  leafConnectee += 1
@@ -17,7 +17,7 @@ def count(state: MapFoldingState) -> MapFoldingState:
17
17
  ImaSymmetricFold = True
18
18
  leafConnectee = 0
19
19
  while leafConnectee < indexInMiddle:
20
- if state.leafComparison[(state.indexMiniGap + leafConnectee) % (state.leavesTotal + 1)] != state.leafComparison[(state.indexMiniGap + state.leavesTotal + 1 - 2 - leafConnectee) % (state.leavesTotal + 1)]:
20
+ if state.leafComparison[(state.indexMiniGap + leafConnectee) % (state.leavesTotal + 1)] != state.leafComparison[(state.indexMiniGap + state.leavesTotal - 1 - leafConnectee) % (state.leavesTotal + 1)]:
21
21
  ImaSymmetricFold = False
22
22
  break
23
23
  leafConnectee += 1
@@ -19,7 +19,7 @@ def count(groupsOfFolds: DatatypeFoldsTotal, gap1ndex: DatatypeElephino, gap1nde
19
19
  ImaSymmetricFold = True
20
20
  leafConnectee = 0
21
21
  while leafConnectee < indexInMiddle:
22
- if leafComparison[(indexMiniGap + leafConnectee) % (leavesTotal + 1)] != leafComparison[(indexMiniGap + leavesTotal + 1 - 2 - leafConnectee) % (leavesTotal + 1)]:
22
+ if leafComparison[(indexMiniGap + leafConnectee) % (leavesTotal + 1)] != leafComparison[(indexMiniGap + leavesTotal - 1 - leafConnectee) % (leavesTotal + 1)]:
23
23
  ImaSymmetricFold = False
24
24
  break
25
25
  leafConnectee += 1
@@ -17,7 +17,7 @@ def count(state: MapFoldingState) -> MapFoldingState:
17
17
  ImaSymmetricFold = True
18
18
  leafConnectee = 0
19
19
  while leafConnectee < indexInMiddle:
20
- if state.leafComparison[(state.indexMiniGap + leafConnectee) % (state.leavesTotal + 1)] != state.leafComparison[(state.indexMiniGap + state.leavesTotal + 1 - 2 - leafConnectee) % (state.leavesTotal + 1)]:
20
+ if state.leafComparison[(state.indexMiniGap + leafConnectee) % (state.leavesTotal + 1)] != state.leafComparison[(state.indexMiniGap + state.leavesTotal - 1 - leafConnectee) % (state.leavesTotal + 1)]:
21
21
  ImaSymmetricFold = False
22
22
  break
23
23
  leafConnectee += 1
@@ -25,7 +25,7 @@ research domain.
25
25
 
26
26
  from collections.abc import Callable, Generator, Sequence
27
27
  from mapFolding import _theSSOT, getLeavesTotal, makeDataContainer, packageSettings, validateListDimensions
28
- from mapFolding.oeis import dictionaryOEIS, oeisIDsImplemented
28
+ from mapFolding.oeis import dictionaryOEISMapFolding, dictionaryOEISMeanders, oeisIDsImplemented
29
29
  from pathlib import Path
30
30
  from typing import Any
31
31
  import numpy
@@ -212,10 +212,10 @@ def oneTestCuzTestsOverwritingTests(oeisID_1random: str) -> tuple[int, ...]:
212
212
 
213
213
  """
214
214
  while True:
215
- n = random.choice(dictionaryOEIS[oeisID_1random]['valuesTestValidation'])
215
+ n = random.choice(dictionaryOEISMapFolding[oeisID_1random]['valuesTestValidation'])
216
216
  if n < 2:
217
217
  continue
218
- listDimensionsCandidate = list(dictionaryOEIS[oeisID_1random]['getMapShape'](n))
218
+ listDimensionsCandidate = list(dictionaryOEISMapFolding[oeisID_1random]['getMapShape'](n))
219
219
 
220
220
  try:
221
221
  return validateListDimensions(listDimensionsCandidate)
@@ -224,7 +224,8 @@ def oneTestCuzTestsOverwritingTests(oeisID_1random: str) -> tuple[int, ...]:
224
224
 
225
225
  @pytest.fixture
226
226
  def mapShapeTestCountFolds(oeisID: str) -> tuple[int, ...]:
227
- """For each `oeisID` from the `pytest.fixture`, returns `listDimensions` from `valuesTestValidation` if `validateListDimensions` approves. Each `listDimensions` is suitable for testing counts.
227
+ """For each `oeisID` from the `pytest.fixture`, returns `listDimensions` from `valuesTestValidation` if
228
+ `validateListDimensions` approves. Each `listDimensions` is suitable for testing counts.
228
229
 
229
230
  Parameters
230
231
  ----------
@@ -238,10 +239,10 @@ def mapShapeTestCountFolds(oeisID: str) -> tuple[int, ...]:
238
239
 
239
240
  """
240
241
  while True:
241
- n = random.choice(dictionaryOEIS[oeisID]['valuesTestValidation'])
242
+ n = random.choice(dictionaryOEISMapFolding[oeisID]['valuesTestValidation'])
242
243
  if n < 2:
243
244
  continue
244
- listDimensionsCandidate = list(dictionaryOEIS[oeisID]['getMapShape'](n))
245
+ listDimensionsCandidate = list(dictionaryOEISMapFolding[oeisID]['getMapShape'](n))
245
246
 
246
247
  try:
247
248
  return validateListDimensions(listDimensionsCandidate)
@@ -266,10 +267,10 @@ def mapShapeTestFunctionality(oeisID_1random: str) -> tuple[int, ...]:
266
267
 
267
268
  """
268
269
  while True:
269
- n = random.choice(dictionaryOEIS[oeisID_1random]['valuesTestValidation'])
270
+ n = random.choice(dictionaryOEISMapFolding[oeisID_1random]['valuesTestValidation'])
270
271
  if n < 2:
271
272
  continue
272
- listDimensionsCandidate = list(dictionaryOEIS[oeisID_1random]['getMapShape'](n))
273
+ listDimensionsCandidate = list(dictionaryOEISMapFolding[oeisID_1random]['getMapShape'](n))
273
274
 
274
275
  try:
275
276
  return validateListDimensions(listDimensionsCandidate)
@@ -291,8 +292,8 @@ def mapShapeTestParallelization(oeisID: str) -> tuple[int, ...]:
291
292
  Map dimensions suitable for testing parallelization features.
292
293
 
293
294
  """
294
- n = random.choice(dictionaryOEIS[oeisID]['valuesTestParallelization'])
295
- return dictionaryOEIS[oeisID]['getMapShape'](n)
295
+ n = random.choice(dictionaryOEISMapFolding[oeisID]['valuesTestParallelization'])
296
+ return dictionaryOEISMapFolding[oeisID]['getMapShape'](n)
296
297
 
297
298
  @pytest.fixture
298
299
  def mockBenchmarkTimer() -> Generator[unittest.mock.MagicMock | unittest.mock.AsyncMock, Any, None]:
@@ -349,6 +350,25 @@ def oeisID(request: pytest.FixtureRequest) -> Any:
349
350
  """
350
351
  return request.param
351
352
 
353
+ @pytest.fixture(params=tuple(dictionaryOEISMeanders.keys()))
354
+ def oeisIDMeanders(request: pytest.FixtureRequest) -> Any:
355
+ """Parametrized fixture providing all implemented Meanders OEIS sequence identifiers.
356
+
357
+ (AI generated docstring)
358
+
359
+ Parameters
360
+ ----------
361
+ request : pytest.FixtureRequest
362
+ The pytest request object containing the current parameter value.
363
+
364
+ Returns
365
+ -------
366
+ sequenceIdentifier : Any
367
+ OEIS sequence identifier for testing across all implemented Meanders sequences.
368
+
369
+ """
370
+ return request.param
371
+
352
372
  @pytest.fixture
353
373
  def oeisID_1random() -> str:
354
374
  """Return one random valid OEIS ID.