@eaprelsky/nocturna-wheel 4.0.1 → 4.0.3
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.
- package/dist/nocturna-wheel.bundle.js +139 -139
- package/dist/nocturna-wheel.bundle.js.map +1 -1
- package/dist/nocturna-wheel.es.js +139 -139
- package/dist/nocturna-wheel.es.js.map +1 -1
- package/dist/nocturna-wheel.min.js +1 -1
- package/dist/nocturna-wheel.min.js.map +1 -1
- package/dist/nocturna-wheel.umd.js +139 -139
- package/dist/nocturna-wheel.umd.js.map +1 -1
- package/package.json +1 -1
|
@@ -287,7 +287,7 @@ class IconProvider {
|
|
|
287
287
|
/**
|
|
288
288
|
* IconData.js
|
|
289
289
|
* Auto-generated module containing inline SVG icons as data URLs
|
|
290
|
-
* Generated at: 2025-
|
|
290
|
+
* Generated at: 2025-12-21T15:10:29.083Z
|
|
291
291
|
*
|
|
292
292
|
* This file is automatically generated by the build process.
|
|
293
293
|
* Do not edit manually - changes will be overwritten.
|
|
@@ -2331,41 +2331,26 @@ class HouseRenderer extends BaseRenderer {
|
|
|
2331
2331
|
// Offset needed to place Ascendant (house 1 cusp) at 0 degrees (top side)
|
|
2332
2332
|
ascendantAlignmentOffset = (360 - ascendantLon) % 360;
|
|
2333
2333
|
}
|
|
2334
|
-
|
|
2335
|
-
//
|
|
2336
|
-
|
|
2334
|
+
|
|
2335
|
+
// Render house numbers at the CENTER of each house sector.
|
|
2336
|
+
// If house cusp data is available, compute the midpoint between cusp[i] and cusp[i+1] (with proper 0/360 wrap).
|
|
2337
|
+
// Otherwise, fall back to equal 30° houses.
|
|
2337
2338
|
for (let i = 0; i < 12; i++) {
|
|
2338
|
-
|
|
2339
|
+
const houseNumber = i + 1;
|
|
2340
|
+
|
|
2341
|
+
let midAngle;
|
|
2339
2342
|
if (this.houseData && this.houseData.length >= 12) {
|
|
2340
|
-
|
|
2343
|
+
const startLon = this.getHouseLongitude(this.houseData[i]);
|
|
2344
|
+
const endLon = this.getHouseLongitude(this.houseData[(i + 1) % 12]);
|
|
2345
|
+
const arc = (endLon - startLon + 360) % 360; // always move forward through the zodiac
|
|
2346
|
+
const midLon = (startLon + arc / 2) % 360;
|
|
2347
|
+
midAngle = (midLon + ascendantAlignmentOffset + rotationAngle) % 360;
|
|
2341
2348
|
} else {
|
|
2342
|
-
|
|
2349
|
+
// Equal houses: center of each 30° segment
|
|
2350
|
+
midAngle = (i * 30 + 15 + rotationAngle) % 360;
|
|
2343
2351
|
}
|
|
2344
|
-
const rotatedAngle = (baseAngle + ascendantAlignmentOffset + rotationAngle) % 360;
|
|
2345
2352
|
|
|
2346
|
-
|
|
2347
|
-
originalIndex: i,
|
|
2348
|
-
baseAngle: baseAngle,
|
|
2349
|
-
rotatedAngle: rotatedAngle
|
|
2350
|
-
});
|
|
2351
|
-
}
|
|
2352
|
-
|
|
2353
|
-
// Sort by rotated angle to determine visual order
|
|
2354
|
-
housesWithAngles.sort((a, b) => a.rotatedAngle - b.rotatedAngle);
|
|
2355
|
-
|
|
2356
|
-
// Find which house is Ascendant (originally index 0) after rotation
|
|
2357
|
-
const ascendantVisualIndex = housesWithAngles.findIndex(h => h.originalIndex === 0);
|
|
2358
|
-
|
|
2359
|
-
// Render houses with correct numbering based on visual position
|
|
2360
|
-
housesWithAngles.forEach((house, visualIndex) => {
|
|
2361
|
-
const houseAngle = house.rotatedAngle;
|
|
2362
|
-
|
|
2363
|
-
// Calculate house number based on position relative to Ascendant
|
|
2364
|
-
// Counter-clockwise from Ascendant
|
|
2365
|
-
const houseNumber = ((visualIndex - ascendantVisualIndex + 12) % 12) + 1;
|
|
2366
|
-
|
|
2367
|
-
// Offset text from house line clockwise
|
|
2368
|
-
const angle = (houseAngle + 15) % 360; // Place in middle of house segment, apply modulo
|
|
2353
|
+
const angle = midAngle;
|
|
2369
2354
|
|
|
2370
2355
|
// Calculate position for house number
|
|
2371
2356
|
const point = this.svgUtils.pointOnCircle(this.centerX, this.centerY, this.numberRadius, angle);
|
|
@@ -2406,7 +2391,7 @@ class HouseRenderer extends BaseRenderer {
|
|
|
2406
2391
|
|
|
2407
2392
|
parentGroup.appendChild(text);
|
|
2408
2393
|
elements.push(text);
|
|
2409
|
-
}
|
|
2394
|
+
}
|
|
2410
2395
|
|
|
2411
2396
|
return elements;
|
|
2412
2397
|
}
|
|
@@ -2759,6 +2744,16 @@ class PlanetSymbolRenderer extends BasePlanetRenderer {
|
|
|
2759
2744
|
*/
|
|
2760
2745
|
|
|
2761
2746
|
class PlanetPositionCalculator {
|
|
2747
|
+
static _normalizeAngle(angle) {
|
|
2748
|
+
return ((angle % 360) + 360) % 360;
|
|
2749
|
+
}
|
|
2750
|
+
|
|
2751
|
+
static _getAngle(position) {
|
|
2752
|
+
return position && position.adjustedLongitude !== undefined
|
|
2753
|
+
? position.adjustedLongitude
|
|
2754
|
+
: position.longitude;
|
|
2755
|
+
}
|
|
2756
|
+
|
|
2762
2757
|
/**
|
|
2763
2758
|
* Calculate position for a planet on a circle
|
|
2764
2759
|
* @param {Object} params - Position parameters
|
|
@@ -2843,7 +2838,8 @@ class PlanetPositionCalculator {
|
|
|
2843
2838
|
centerX,
|
|
2844
2839
|
centerY,
|
|
2845
2840
|
baseRadius,
|
|
2846
|
-
iconSize = 24
|
|
2841
|
+
iconSize = 24,
|
|
2842
|
+
maxIterations = 5
|
|
2847
2843
|
} = options;
|
|
2848
2844
|
|
|
2849
2845
|
if (!positions || positions.length <= 1) {
|
|
@@ -2857,72 +2853,51 @@ class PlanetPositionCalculator {
|
|
|
2857
2853
|
|
|
2858
2854
|
console.log(`PlanetPositionCalculator: Adjusting overlaps for ${positions.length} positions`);
|
|
2859
2855
|
|
|
2860
|
-
// Make a copy to not modify originals
|
|
2861
|
-
const adjustedPositions =
|
|
2856
|
+
// Make a copy to not modify originals (also ensures we can add fields safely)
|
|
2857
|
+
const adjustedPositions = positions.map(p => ({ ...p }));
|
|
2862
2858
|
|
|
2863
2859
|
// The minimum angular distance needed to prevent overlap at base radius
|
|
2864
|
-
//
|
|
2865
|
-
const minAngularDistance = (minDistance / baseRadius) * (180 / Math.PI)
|
|
2860
|
+
// minDistance already includes the desired spacing (iconSize * 1.5)
|
|
2861
|
+
const minAngularDistance = (minDistance / baseRadius) * (180 / Math.PI);
|
|
2866
2862
|
console.log(`PlanetPositionCalculator: Minimum angular distance: ${minAngularDistance.toFixed(2)}°`);
|
|
2867
|
-
|
|
2868
|
-
//
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
const sortedPositions = sortedPositionIndices.map(item => ({
|
|
2874
|
-
...adjustedPositions[item.idx],
|
|
2875
|
-
originalIndex: item.idx
|
|
2876
|
-
}));
|
|
2877
|
-
|
|
2878
|
-
// Find clusters of planets that are too close angularly
|
|
2879
|
-
const clusters = this._findOverlappingClusters(sortedPositions, minAngularDistance);
|
|
2880
|
-
console.log(`PlanetPositionCalculator: Found ${clusters.length} clusters of overlapping positions`);
|
|
2881
|
-
clusters.forEach((cluster, i) => {
|
|
2882
|
-
console.log(`PlanetPositionCalculator: Cluster ${i+1} has ${cluster.length} positions`);
|
|
2883
|
-
});
|
|
2884
|
-
|
|
2885
|
-
// Process each cluster
|
|
2886
|
-
clusters.forEach((cluster, clusterIndex) => {
|
|
2887
|
-
console.log(`PlanetPositionCalculator: Processing cluster ${clusterIndex+1}`);
|
|
2888
|
-
|
|
2889
|
-
if (cluster.length <= 1) {
|
|
2890
|
-
// Single planet - just place at exact base radius with no angle change
|
|
2891
|
-
const planet = cluster[0];
|
|
2892
|
-
console.log(`PlanetPositionCalculator: Single position in cluster, keeping at original longitude ${planet.longitude.toFixed(2)}°`);
|
|
2893
|
-
this._setExactPosition(planet, planet.longitude, baseRadius, centerX, centerY, iconSize);
|
|
2894
|
-
} else {
|
|
2895
|
-
// Handle cluster with multiple planets - distribute by angle
|
|
2896
|
-
console.log(`PlanetPositionCalculator: Distributing ${cluster.length} positions in cluster`);
|
|
2897
|
-
this._distributeClusterByAngle(cluster, baseRadius, minAngularDistance, centerX, centerY, iconSize);
|
|
2898
|
-
|
|
2899
|
-
// Log the distributions
|
|
2900
|
-
cluster.forEach((pos, i) => {
|
|
2901
|
-
console.log(`PlanetPositionCalculator: Position ${i+1} in cluster ${clusterIndex+1} adjusted from ${pos.longitude.toFixed(2)}° to ${pos.adjustedLongitude.toFixed(2)}°`);
|
|
2902
|
-
});
|
|
2863
|
+
|
|
2864
|
+
// Initialize adjustedLongitude for all positions
|
|
2865
|
+
adjustedPositions.forEach(pos => {
|
|
2866
|
+
if (pos.adjustedLongitude === undefined) {
|
|
2867
|
+
pos.adjustedLongitude = pos.longitude;
|
|
2903
2868
|
}
|
|
2869
|
+
this._setExactPosition(pos, this._getAngle(pos), baseRadius, centerX, centerY, iconSize);
|
|
2904
2870
|
});
|
|
2905
|
-
|
|
2906
|
-
//
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
adjustedPositions[origIndex].adjustedLongitude = pos.adjustedLongitude;
|
|
2922
|
-
}
|
|
2871
|
+
|
|
2872
|
+
// Iteratively resolve overlaps. This avoids "new overlaps" created after distributing a cluster.
|
|
2873
|
+
for (let iteration = 0; iteration < maxIterations; iteration++) {
|
|
2874
|
+
// Sort by current (possibly adjusted) angle for overlap detection
|
|
2875
|
+
const sortedPositions = [...adjustedPositions].sort(
|
|
2876
|
+
(a, b) => this._getAngle(a) - this._getAngle(b)
|
|
2877
|
+
);
|
|
2878
|
+
|
|
2879
|
+
// Find clusters of planets that are too close angularly
|
|
2880
|
+
const clusters = this._findOverlappingClusters(sortedPositions, minAngularDistance);
|
|
2881
|
+
console.log(`PlanetPositionCalculator: Iteration ${iteration + 1}/${maxIterations}, clusters: ${clusters.length}`);
|
|
2882
|
+
|
|
2883
|
+
// No overlaps -> done
|
|
2884
|
+
const hasRealClusters = clusters.some(c => c.length > 1);
|
|
2885
|
+
if (!hasRealClusters) {
|
|
2886
|
+
break;
|
|
2923
2887
|
}
|
|
2924
|
-
|
|
2925
|
-
|
|
2888
|
+
|
|
2889
|
+
// Process each cluster
|
|
2890
|
+
clusters.forEach(cluster => {
|
|
2891
|
+
if (cluster.length <= 1) {
|
|
2892
|
+
const planet = cluster[0];
|
|
2893
|
+
this._setExactPosition(planet, this._getAngle(planet), baseRadius, centerX, centerY, iconSize);
|
|
2894
|
+
return;
|
|
2895
|
+
}
|
|
2896
|
+
|
|
2897
|
+
this._distributeClusterByPush(cluster, baseRadius, minAngularDistance, centerX, centerY, iconSize);
|
|
2898
|
+
});
|
|
2899
|
+
}
|
|
2900
|
+
|
|
2926
2901
|
return adjustedPositions;
|
|
2927
2902
|
}
|
|
2928
2903
|
|
|
@@ -2952,7 +2927,9 @@ class PlanetPositionCalculator {
|
|
|
2952
2927
|
const currPosition = sortedPositions[i];
|
|
2953
2928
|
|
|
2954
2929
|
// Check angular distance, considering wrap-around at 360°
|
|
2955
|
-
|
|
2930
|
+
const prevAngle = this._getAngle(prevPosition);
|
|
2931
|
+
const currAngle = this._getAngle(currPosition);
|
|
2932
|
+
let angleDiff = currAngle - prevAngle;
|
|
2956
2933
|
if (angleDiff < 0) angleDiff += 360;
|
|
2957
2934
|
|
|
2958
2935
|
if (angleDiff < minAngularDistance) {
|
|
@@ -2976,7 +2953,9 @@ class PlanetPositionCalculator {
|
|
|
2976
2953
|
const lastPlanet = sortedPositions[posCount - 1];
|
|
2977
2954
|
const firstPlanetOriginal = sortedPositions[0];
|
|
2978
2955
|
|
|
2979
|
-
|
|
2956
|
+
const lastAngle = this._getAngle(lastPlanet);
|
|
2957
|
+
const firstAngle = this._getAngle(firstPlanetOriginal);
|
|
2958
|
+
let wrapDiff = (firstAngle + 360) - lastAngle;
|
|
2980
2959
|
if (wrapDiff < 0) wrapDiff += 360;
|
|
2981
2960
|
|
|
2982
2961
|
if (wrapDiff < minAngularDistance) {
|
|
@@ -3000,7 +2979,8 @@ class PlanetPositionCalculator {
|
|
|
3000
2979
|
}
|
|
3001
2980
|
|
|
3002
2981
|
/**
|
|
3003
|
-
* Distribute positions in a cluster
|
|
2982
|
+
* Distribute positions in a cluster using a "push-apart" algorithm.
|
|
2983
|
+
* This keeps adjustments as small as possible while ensuring minimum spacing.
|
|
3004
2984
|
* @private
|
|
3005
2985
|
* @param {Array} positions - Array of positions in the cluster
|
|
3006
2986
|
* @param {number} radius - The exact radius to place all positions
|
|
@@ -3009,49 +2989,62 @@ class PlanetPositionCalculator {
|
|
|
3009
2989
|
* @param {number} centerY - Y coordinate of center
|
|
3010
2990
|
* @param {number} iconSize - Size of the icon
|
|
3011
2991
|
*/
|
|
3012
|
-
static
|
|
2992
|
+
static _distributeClusterByPush(positions, radius, minAngularDistance, centerX, centerY, iconSize) {
|
|
3013
2993
|
const n = positions.length;
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
this._setExactPosition(positions[0], positions[0].longitude, radius, centerX, centerY, iconSize);
|
|
2994
|
+
if (n <= 1) {
|
|
2995
|
+
const p = positions[0];
|
|
2996
|
+
this._setExactPosition(p, this._getAngle(p), radius, centerX, centerY, iconSize);
|
|
3018
2997
|
return;
|
|
3019
2998
|
}
|
|
3020
|
-
|
|
3021
|
-
//
|
|
3022
|
-
positions.
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
const
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
//
|
|
3030
|
-
|
|
3031
|
-
|
|
2999
|
+
|
|
3000
|
+
// Unwrap angles if cluster spans the 0°/360° boundary
|
|
3001
|
+
const baseAngles = positions.map(p => this._getAngle(p));
|
|
3002
|
+
const min = Math.min(...baseAngles);
|
|
3003
|
+
const max = Math.max(...baseAngles);
|
|
3004
|
+
const unwrappedAngles = (max - min > 180)
|
|
3005
|
+
? baseAngles.map(a => (a < 180 ? a + 360 : a))
|
|
3006
|
+
: baseAngles;
|
|
3007
|
+
|
|
3008
|
+
// Sort by unwrapped angle
|
|
3009
|
+
const items = positions
|
|
3010
|
+
.map((p, idx) => ({ p, orig: unwrappedAngles[idx] }))
|
|
3011
|
+
.sort((a, b) => a.orig - b.orig);
|
|
3012
|
+
|
|
3013
|
+
const origAngles = items.map(it => it.orig);
|
|
3014
|
+
let adjusted = [...origAngles];
|
|
3015
|
+
|
|
3016
|
+
// Forward pass: enforce minimum distance
|
|
3017
|
+
for (let i = 1; i < n; i++) {
|
|
3018
|
+
const minAllowed = adjusted[i - 1] + minAngularDistance;
|
|
3019
|
+
if (adjusted[i] < minAllowed) {
|
|
3020
|
+
adjusted[i] = minAllowed;
|
|
3021
|
+
}
|
|
3032
3022
|
}
|
|
3033
|
-
|
|
3034
|
-
//
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3023
|
+
|
|
3024
|
+
// Shift the whole cluster to keep it centered around the original mean angle
|
|
3025
|
+
const origCenter = origAngles.reduce((s, a) => s + a, 0) / n;
|
|
3026
|
+
const adjustedCenter = adjusted.reduce((s, a) => s + a, 0) / n;
|
|
3027
|
+
const shift = origCenter - adjustedCenter;
|
|
3028
|
+
adjusted = adjusted.map(a => a + shift);
|
|
3029
|
+
|
|
3030
|
+
// Re-enforce constraints after shifting
|
|
3031
|
+
for (let i = 1; i < n; i++) {
|
|
3032
|
+
const minAllowed = adjusted[i - 1] + minAngularDistance;
|
|
3033
|
+
if (adjusted[i] < minAllowed) {
|
|
3034
|
+
adjusted[i] = minAllowed;
|
|
3035
|
+
}
|
|
3038
3036
|
}
|
|
3039
|
-
let
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
// Calculate start angle (center - half of span)
|
|
3049
|
-
const startAngle = (centerAngle - spanToUse/2 + 360) % 360;
|
|
3050
|
-
|
|
3051
|
-
// Distribute planets evenly from the start angle
|
|
3037
|
+
for (let i = n - 2; i >= 0; i--) {
|
|
3038
|
+
const maxAllowed = adjusted[i + 1] - minAngularDistance;
|
|
3039
|
+
if (adjusted[i] > maxAllowed) {
|
|
3040
|
+
adjusted[i] = maxAllowed;
|
|
3041
|
+
}
|
|
3042
|
+
}
|
|
3043
|
+
|
|
3044
|
+
// Apply results
|
|
3052
3045
|
for (let i = 0; i < n; i++) {
|
|
3053
|
-
const angle = (
|
|
3054
|
-
this._setExactPosition(
|
|
3046
|
+
const angle = this._normalizeAngle(adjusted[i]);
|
|
3047
|
+
this._setExactPosition(items[i].p, angle, radius, centerX, centerY, iconSize);
|
|
3055
3048
|
}
|
|
3056
3049
|
}
|
|
3057
3050
|
|
|
@@ -3128,7 +3121,8 @@ class PrimaryPlanetRenderer extends BasePlanetRenderer {
|
|
|
3128
3121
|
// Define parameters for collision detection and distribution
|
|
3129
3122
|
const iconSize = 24;
|
|
3130
3123
|
const baseRadius = planets[0].iconRadius; // Use the iconRadius from the first planet
|
|
3131
|
-
|
|
3124
|
+
// Minimum distance = icon diameter + half diameter (0.5 * iconSize spacing between icons)
|
|
3125
|
+
const minDistance = iconSize * 1.5;
|
|
3132
3126
|
|
|
3133
3127
|
// Prepare planets array in format expected by PlanetPositionCalculator
|
|
3134
3128
|
const positions = planets.map((planet, index) => ({
|
|
@@ -3250,7 +3244,7 @@ class PrimaryPlanetRenderer extends BasePlanetRenderer {
|
|
|
3250
3244
|
this.symbolRenderer.addPlanetTooltip(planetGroup, planet);
|
|
3251
3245
|
|
|
3252
3246
|
// Render connector if needed
|
|
3253
|
-
const connector = this.symbolRenderer.renderConnector(planetGroup, planet, iconSize);
|
|
3247
|
+
const connector = this.symbolRenderer.renderConnector(planetGroup, planet, iconSize, 0.9);
|
|
3254
3248
|
if (connector) {
|
|
3255
3249
|
planetGroup.appendChild(connector);
|
|
3256
3250
|
}
|
|
@@ -3310,7 +3304,8 @@ class SecondaryPlanetRenderer extends BasePlanetRenderer {
|
|
|
3310
3304
|
// Define parameters for collision detection and distribution
|
|
3311
3305
|
const iconSize = 18; // Smaller size for secondary planets
|
|
3312
3306
|
const baseRadius = planets[0].iconRadius; // Use the iconRadius from the first planet
|
|
3313
|
-
|
|
3307
|
+
// Minimum distance = icon diameter + half diameter (0.5 * iconSize spacing between icons)
|
|
3308
|
+
const minDistance = iconSize * 1.5;
|
|
3314
3309
|
|
|
3315
3310
|
// Prepare planets array in format expected by PlanetPositionCalculator
|
|
3316
3311
|
const positions = planets.map((planet, index) => ({
|
|
@@ -3431,7 +3426,7 @@ class SecondaryPlanetRenderer extends BasePlanetRenderer {
|
|
|
3431
3426
|
this.symbolRenderer.addPlanetTooltip(planetGroup, planet);
|
|
3432
3427
|
|
|
3433
3428
|
// Render connector if needed
|
|
3434
|
-
const connector = this.symbolRenderer.renderConnector(planetGroup, planet, iconSize);
|
|
3429
|
+
const connector = this.symbolRenderer.renderConnector(planetGroup, planet, iconSize, 0.9);
|
|
3435
3430
|
if (connector) {
|
|
3436
3431
|
planetGroup.appendChild(connector);
|
|
3437
3432
|
}
|
|
@@ -5470,8 +5465,13 @@ class ChartRenderer {
|
|
|
5470
5465
|
const centerY = this.chart.config.svg.center.y;
|
|
5471
5466
|
const c3Radius = this.chart.config.radius.innermost; // C3
|
|
5472
5467
|
|
|
5473
|
-
// Only draw the innermost circle if secondary planets are enabled
|
|
5474
|
-
|
|
5468
|
+
// Only draw the innermost circle if secondary planets are enabled AND we actually have secondary data
|
|
5469
|
+
const hasSecondaryPlanetsData =
|
|
5470
|
+
this.chart?.secondaryPlanets &&
|
|
5471
|
+
typeof this.chart.secondaryPlanets === 'object' &&
|
|
5472
|
+
Object.keys(this.chart.secondaryPlanets).length > 0;
|
|
5473
|
+
|
|
5474
|
+
if (this.chart.config.planetSettings.secondaryEnabled !== false && hasSecondaryPlanetsData) {
|
|
5475
5475
|
this.drawInnermostCircle(zodiacGroup, this.svgUtils, centerX, centerY, c3Radius);
|
|
5476
5476
|
}
|
|
5477
5477
|
|