crystalwindow 3.7.1b0__py3-none-any.whl → 3.8.1__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.
- crystalwindow/__init__.py +21 -5
- crystalwindow/assets.py +106 -28
- crystalwindow/sprites.py +66 -29
- crystalwindow/window.py +1 -1
- {crystalwindow-3.7.1b0.dist-info → crystalwindow-3.8.1.dist-info}/METADATA +1 -1
- {crystalwindow-3.7.1b0.dist-info → crystalwindow-3.8.1.dist-info}/RECORD +9 -9
- {crystalwindow-3.7.1b0.dist-info → crystalwindow-3.8.1.dist-info}/WHEEL +0 -0
- {crystalwindow-3.7.1b0.dist-info → crystalwindow-3.8.1.dist-info}/licenses/LICENSE +0 -0
- {crystalwindow-3.7.1b0.dist-info → crystalwindow-3.8.1.dist-info}/top_level.txt +0 -0
crystalwindow/__init__.py
CHANGED
|
@@ -12,7 +12,15 @@ from .FileHelper import FileHelper
|
|
|
12
12
|
from .math import Mathematics
|
|
13
13
|
|
|
14
14
|
# === Assets & Animation ===
|
|
15
|
-
from .assets import
|
|
15
|
+
from .assets import (
|
|
16
|
+
load_image,
|
|
17
|
+
load_folder_images,
|
|
18
|
+
load_music,
|
|
19
|
+
play_music,
|
|
20
|
+
flip_image,
|
|
21
|
+
flip_horizontal,
|
|
22
|
+
flip_vertical,
|
|
23
|
+
)
|
|
16
24
|
from .animation import Animation
|
|
17
25
|
|
|
18
26
|
# === Collision ===
|
|
@@ -23,7 +31,7 @@ from .gui import Button, Label, GUIManager, random_color, hex_to_rgb, Fade
|
|
|
23
31
|
from .gui_ext import Toggle, Slider
|
|
24
32
|
|
|
25
33
|
# === Time ===
|
|
26
|
-
from .clock import Clock
|
|
34
|
+
from .clock import Clock
|
|
27
35
|
|
|
28
36
|
# === Drawing Helpers ===
|
|
29
37
|
from .draw_helpers import gradient_rect, CameraShake
|
|
@@ -36,14 +44,22 @@ from .fun_helpers import random_name, DebugOverlay
|
|
|
36
44
|
from .camera import Camera
|
|
37
45
|
|
|
38
46
|
# === 3D Engine ===
|
|
39
|
-
from .crystal3d import CW3D
|
|
47
|
+
from .crystal3d import CW3D
|
|
48
|
+
|
|
40
49
|
|
|
41
50
|
__all__ = [
|
|
42
51
|
# --- Core ---
|
|
43
52
|
"Window", "Sprite", "TileMap", "Player", "Gravity", "FileHelper", "Mathematics",
|
|
44
53
|
|
|
45
54
|
# --- Assets & Animation ---
|
|
46
|
-
"load_image",
|
|
55
|
+
"load_image",
|
|
56
|
+
"load_folder_images",
|
|
57
|
+
"load_music",
|
|
58
|
+
"play_music",
|
|
59
|
+
"flip_image",
|
|
60
|
+
"flip_horizontal",
|
|
61
|
+
"flip_vertical",
|
|
62
|
+
"Animation",
|
|
47
63
|
|
|
48
64
|
# --- Collision ---
|
|
49
65
|
"check_collision", "resolve_collision",
|
|
@@ -64,5 +80,5 @@ __all__ = [
|
|
|
64
80
|
"random_name", "DebugOverlay", "Camera",
|
|
65
81
|
|
|
66
82
|
# --- 3D ---
|
|
67
|
-
"CW3D"
|
|
83
|
+
"CW3D",
|
|
68
84
|
]
|
crystalwindow/assets.py
CHANGED
|
@@ -1,28 +1,79 @@
|
|
|
1
|
+
# assets.py
|
|
1
2
|
import os
|
|
2
3
|
import random
|
|
3
4
|
from tkinter import PhotoImage
|
|
4
5
|
|
|
5
6
|
try:
|
|
6
|
-
from PIL import Image
|
|
7
|
-
except:
|
|
7
|
+
from PIL import Image, ImageTk
|
|
8
|
+
except ImportError:
|
|
8
9
|
Image = None
|
|
10
|
+
ImageTk = None
|
|
9
11
|
|
|
10
|
-
ASSETS = {}
|
|
12
|
+
ASSETS = {} # cache for all loaded images
|
|
11
13
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
|
|
15
|
+
# --------------------------------------------------------
|
|
16
|
+
# MAIN IMAGE LOADER
|
|
17
|
+
# --------------------------------------------------------
|
|
18
|
+
def load_image(path, flip_h=False, flip_v=False):
|
|
19
|
+
"""
|
|
20
|
+
Loads an image and returns a Tk PhotoImage.
|
|
21
|
+
Supports flipping using Pillow.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
key = f"{path}|h={flip_h}|v={flip_v}"
|
|
25
|
+
if key in ASSETS:
|
|
26
|
+
return ASSETS[key]
|
|
27
|
+
|
|
28
|
+
if not os.path.exists(path):
|
|
29
|
+
print(f"⚠️ Missing file: {path}")
|
|
30
|
+
img = generate_fallback(path)
|
|
31
|
+
ASSETS[key] = img
|
|
32
|
+
return img
|
|
33
|
+
|
|
34
|
+
# If Pillow is missing → load normal image
|
|
35
|
+
if Image is None or ImageTk is None:
|
|
15
36
|
try:
|
|
16
37
|
img = PhotoImage(file=path)
|
|
17
|
-
ASSETS[
|
|
38
|
+
ASSETS[key] = img
|
|
18
39
|
return img
|
|
19
40
|
except:
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
41
|
+
fb = generate_fallback(path)
|
|
42
|
+
ASSETS[key] = fb
|
|
43
|
+
return fb
|
|
44
|
+
|
|
45
|
+
# Load with PIL to allow flipping
|
|
46
|
+
try:
|
|
47
|
+
pil_img = Image.open(path)
|
|
48
|
+
|
|
49
|
+
if flip_h:
|
|
50
|
+
pil_img = pil_img.transpose(Image.FLIP_LEFT_RIGHT)
|
|
51
|
+
if flip_v:
|
|
52
|
+
pil_img = pil_img.transpose(Image.FLIP_TOP_BOTTOM)
|
|
53
|
+
|
|
54
|
+
tk_img = ImageTk.PhotoImage(pil_img)
|
|
55
|
+
ASSETS[key] = tk_img
|
|
56
|
+
return tk_img
|
|
57
|
+
|
|
58
|
+
except Exception as e:
|
|
59
|
+
print(f"⚠️ Error loading {path}: {e}")
|
|
60
|
+
fb = generate_fallback(path)
|
|
61
|
+
ASSETS[key] = fb
|
|
62
|
+
return fb
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
# --------------------------------------------------------
|
|
66
|
+
# FALLBACK NODE
|
|
67
|
+
# --------------------------------------------------------
|
|
68
|
+
def generate_fallback(path):
|
|
69
|
+
"""Fallback colored block used when an image is missing."""
|
|
70
|
+
rand_color = (
|
|
71
|
+
random.randint(50, 255),
|
|
72
|
+
random.randint(50, 255),
|
|
73
|
+
random.randint(50, 255),
|
|
74
|
+
)
|
|
23
75
|
|
|
24
|
-
|
|
25
|
-
if Image is not None:
|
|
76
|
+
if Image:
|
|
26
77
|
try:
|
|
27
78
|
pil_img = Image.open(path)
|
|
28
79
|
w, h = pil_img.size
|
|
@@ -31,13 +82,6 @@ def load_image(path):
|
|
|
31
82
|
else:
|
|
32
83
|
w, h = 64, 64
|
|
33
84
|
|
|
34
|
-
# RANDOM COLOR FALLBACK (chaos energy)
|
|
35
|
-
rand_color = (
|
|
36
|
-
random.randint(0, 255),
|
|
37
|
-
random.randint(0, 255),
|
|
38
|
-
random.randint(0, 255)
|
|
39
|
-
)
|
|
40
|
-
|
|
41
85
|
return {
|
|
42
86
|
"fallback": True,
|
|
43
87
|
"size": (w, h),
|
|
@@ -45,28 +89,62 @@ def load_image(path):
|
|
|
45
89
|
}
|
|
46
90
|
|
|
47
91
|
|
|
92
|
+
# --------------------------------------------------------
|
|
93
|
+
# PYGAME-STYLE FLIP HELPERS
|
|
94
|
+
# --------------------------------------------------------
|
|
95
|
+
def flip_image(img, flip_h=False, flip_v=False):
|
|
96
|
+
"""
|
|
97
|
+
Returns a NEW flipped PhotoImage.
|
|
98
|
+
Like pygame.transform.flip().
|
|
99
|
+
"""
|
|
100
|
+
if Image is None or ImageTk is None:
|
|
101
|
+
print("⚠️ Pillow not installed; cannot flip images.")
|
|
102
|
+
return img
|
|
103
|
+
|
|
104
|
+
pil_img = ImageTk.getimage(img)
|
|
105
|
+
|
|
106
|
+
if flip_h:
|
|
107
|
+
pil_img = pil_img.transpose(Image.FLIP_LEFT_RIGHT)
|
|
108
|
+
if flip_v:
|
|
109
|
+
pil_img = pil_img.transpose(Image.FLIP_TOP_BOTTOM)
|
|
110
|
+
|
|
111
|
+
return ImageTk.PhotoImage(pil_img)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def flip_horizontal(img):
|
|
115
|
+
return flip_image(img, flip_h=True)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def flip_vertical(img):
|
|
119
|
+
return flip_image(img, flip_v=True)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
# --------------------------------------------------------
|
|
123
|
+
# FOLDER LOADING
|
|
124
|
+
# --------------------------------------------------------
|
|
48
125
|
def load_folder_images(folder, nested=True):
|
|
49
126
|
if not os.path.exists(folder):
|
|
50
|
-
print(f"⚠️
|
|
127
|
+
print(f"⚠️ Folder not found: {folder}")
|
|
51
128
|
return {}
|
|
52
129
|
|
|
53
130
|
result = {}
|
|
54
131
|
for item in os.listdir(folder):
|
|
55
|
-
|
|
132
|
+
full = os.path.join(folder, item)
|
|
56
133
|
|
|
57
|
-
if os.path.isdir(
|
|
58
|
-
result[item] = load_folder_images(
|
|
134
|
+
if os.path.isdir(full) and nested:
|
|
135
|
+
result[item] = load_folder_images(full)
|
|
59
136
|
|
|
60
137
|
elif item.lower().endswith((".png", ".gif")):
|
|
61
|
-
result[item] = load_image(
|
|
138
|
+
result[item] = load_image(full)
|
|
62
139
|
|
|
63
140
|
return result
|
|
64
141
|
|
|
65
142
|
|
|
143
|
+
# --------------------------------------------------------
|
|
144
|
+
# MUSIC PLACEHOLDER
|
|
145
|
+
# --------------------------------------------------------
|
|
66
146
|
def load_music(path):
|
|
67
|
-
print(f"[assets] Music
|
|
68
|
-
return None
|
|
69
|
-
|
|
147
|
+
print(f"[assets] Music load not supported: {path}")
|
|
70
148
|
|
|
71
149
|
def play_music(loop=-1):
|
|
72
|
-
print("[assets] Music playback not supported
|
|
150
|
+
print("[assets] Music playback not supported.")
|
crystalwindow/sprites.py
CHANGED
|
@@ -1,50 +1,58 @@
|
|
|
1
|
-
|
|
1
|
+
# sprites.py
|
|
2
2
|
from tkinter import PhotoImage
|
|
3
|
+
from PIL import Image, ImageTk
|
|
4
|
+
|
|
3
5
|
|
|
4
6
|
class Sprite:
|
|
5
7
|
def __init__(self, pos, size=None, image=None, color=(255, 0, 0)):
|
|
6
|
-
"""
|
|
7
|
-
pos: (x, y)
|
|
8
|
-
size: (w, h) optional
|
|
9
|
-
image: PhotoImage (Tkinter)
|
|
10
|
-
color: fill color if no image
|
|
11
|
-
"""
|
|
12
|
-
self.pos = pos
|
|
13
8
|
self.x, self.y = pos
|
|
14
|
-
self.
|
|
9
|
+
self.pos = pos
|
|
10
|
+
|
|
11
|
+
self.image = None
|
|
15
12
|
self.color = color
|
|
16
13
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
self.height = image
|
|
14
|
+
# If fallback dict provided from assets
|
|
15
|
+
if isinstance(image, dict) and image.get("fallback"):
|
|
16
|
+
self.width, self.height = image["size"]
|
|
17
|
+
self.color = image["color"]
|
|
18
|
+
|
|
19
|
+
# Normal image
|
|
20
|
+
elif isinstance(image, PhotoImage):
|
|
21
|
+
self.set_image(image)
|
|
22
|
+
|
|
23
|
+
# Rectangle sprite
|
|
20
24
|
elif size is not None:
|
|
21
25
|
self.width, self.height = size
|
|
26
|
+
|
|
22
27
|
else:
|
|
23
|
-
raise ValueError("Sprite needs
|
|
28
|
+
raise ValueError("Sprite needs 'size' or 'image'")
|
|
24
29
|
|
|
25
|
-
#
|
|
30
|
+
# Movement physics
|
|
26
31
|
self.vel_x = 0
|
|
27
32
|
self.vel_y = 0
|
|
28
33
|
|
|
29
|
-
|
|
34
|
+
# Optional direction flag
|
|
35
|
+
self.facing_left = False
|
|
36
|
+
|
|
37
|
+
# --------------------------------------
|
|
38
|
+
# Constructors
|
|
39
|
+
# --------------------------------------
|
|
30
40
|
@classmethod
|
|
31
41
|
def image(cls, img, pos):
|
|
32
|
-
# fallback if img is missing
|
|
33
42
|
if isinstance(img, dict) and img.get("fallback"):
|
|
34
|
-
print("⚠️ Missing image, making RANDOM rect fallback.")
|
|
35
43
|
w, h = img["size"]
|
|
36
44
|
color = img["color"]
|
|
37
|
-
return cls
|
|
45
|
+
return cls(pos, size=(w, h), color=color)
|
|
38
46
|
return cls(pos, image=img)
|
|
39
47
|
|
|
40
48
|
@classmethod
|
|
41
49
|
def rect(cls, pos, w, h, color=(255, 0, 0)):
|
|
42
|
-
"""Create sprite using a plain colored rectangle"""
|
|
43
50
|
return cls(pos, size=(w, h), color=color)
|
|
44
51
|
|
|
45
|
-
#
|
|
52
|
+
# --------------------------------------
|
|
53
|
+
# Draw
|
|
54
|
+
# --------------------------------------
|
|
46
55
|
def draw(self, win, cam=None):
|
|
47
|
-
"""Draw sprite on a CrystalWindow or Tkinter canvas"""
|
|
48
56
|
if cam:
|
|
49
57
|
draw_x, draw_y = cam.apply(self)
|
|
50
58
|
else:
|
|
@@ -55,24 +63,53 @@ class Sprite:
|
|
|
55
63
|
else:
|
|
56
64
|
win.draw_rect(self.color, (draw_x, draw_y, self.width, self.height))
|
|
57
65
|
|
|
66
|
+
# --------------------------------------
|
|
67
|
+
# Movement
|
|
68
|
+
# --------------------------------------
|
|
58
69
|
def move(self, dx, dy):
|
|
59
|
-
"""Move sprite manually by dx/dy"""
|
|
60
70
|
self.x += dx
|
|
61
71
|
self.y += dy
|
|
62
72
|
self.pos = (self.x, self.y)
|
|
63
73
|
|
|
64
74
|
def apply_velocity(self, dt=1):
|
|
65
|
-
"""Apply vel_x/vel_y to x/y for physics"""
|
|
66
75
|
self.x += self.vel_x * dt
|
|
67
76
|
self.y += self.vel_y * dt
|
|
68
77
|
self.pos = (self.x, self.y)
|
|
69
78
|
|
|
70
|
-
#
|
|
79
|
+
# --------------------------------------
|
|
80
|
+
# Image setter
|
|
81
|
+
# --------------------------------------
|
|
82
|
+
def set_image(self, new_image):
|
|
83
|
+
"""Set sprite image and update size."""
|
|
84
|
+
self.image = new_image
|
|
85
|
+
self.width = new_image.width()
|
|
86
|
+
self.height = new_image.height()
|
|
87
|
+
|
|
88
|
+
# --------------------------------------
|
|
89
|
+
# In-place flipping (optional)
|
|
90
|
+
# --------------------------------------
|
|
91
|
+
def flip_horizontal(self):
|
|
92
|
+
if not self.image:
|
|
93
|
+
return
|
|
94
|
+
pil = ImageTk.getimage(self.image)
|
|
95
|
+
flipped = pil.transpose(Image.FLIP_LEFT_RIGHT)
|
|
96
|
+
self.set_image(ImageTk.PhotoImage(flipped))
|
|
97
|
+
self.facing_left = not self.facing_left
|
|
98
|
+
|
|
99
|
+
def flip_vertical(self):
|
|
100
|
+
if not self.image:
|
|
101
|
+
return
|
|
102
|
+
pil = ImageTk.getimage(self.image)
|
|
103
|
+
flipped = pil.transpose(Image.FLIP_TOP_BOTTOM)
|
|
104
|
+
self.set_image(ImageTk.PhotoImage(flipped))
|
|
105
|
+
|
|
106
|
+
# --------------------------------------
|
|
107
|
+
# Collision
|
|
108
|
+
# --------------------------------------
|
|
71
109
|
def colliderect(self, other):
|
|
72
|
-
"""Check if self collides with another sprite"""
|
|
73
110
|
return (
|
|
74
|
-
self.x < other.x +
|
|
75
|
-
self.x +
|
|
76
|
-
self.y < other.y +
|
|
77
|
-
self.y +
|
|
111
|
+
self.x < other.x + other.width and
|
|
112
|
+
self.x + self.width > other.x and
|
|
113
|
+
self.y < other.y + other.height and
|
|
114
|
+
self.y + self.height > other.y
|
|
78
115
|
)
|
crystalwindow/window.py
CHANGED
|
@@ -115,7 +115,7 @@ class Window:
|
|
|
115
115
|
self._bg_color = (20, 20, 50)
|
|
116
116
|
self.draw_calls = []
|
|
117
117
|
self._key_last = {} # new dict to store last press time per key
|
|
118
|
-
self._key_cooldown = 0.
|
|
118
|
+
self._key_cooldown = 0.00001 # seconds, tweak for faster/slower input
|
|
119
119
|
|
|
120
120
|
# === Event bindings ===
|
|
121
121
|
self.root.bind("<KeyPress>", self._on_keydown)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: crystalwindow
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.8.1
|
|
4
4
|
Summary: A Tkinter powered window + GUI toolkit made by Crystal (MEEEEEE)! Easier apps, smoother UI and all-in-one helpers!
|
|
5
5
|
Home-page: https://pypi.org/project/crystalwindow/
|
|
6
6
|
Author: CrystalBallyHereXD
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
crystalwindow/FileHelper.py,sha256=aUnnRG7UwvzJt-idjWjmpwy3RM6nqLlC3-7Bae6Yb94,5471
|
|
2
|
-
crystalwindow/__init__.py,sha256=
|
|
2
|
+
crystalwindow/__init__.py,sha256=1O0qUvD6dGRZEwCXZU5byqWQUdRNYhyUZ54SN_NM2Dk,2015
|
|
3
3
|
crystalwindow/animation.py,sha256=zHjrdBXQeyNaLAuaGPldJueX05OZ5j31YR8NizmR0uQ,427
|
|
4
|
-
crystalwindow/assets.py,sha256=
|
|
4
|
+
crystalwindow/assets.py,sha256=3FubtFHcemIFBiV5h79QyvKkHiLSUNBEPbGP4UyGRyI,3999
|
|
5
5
|
crystalwindow/camera.py,sha256=tbn4X-jxMIszAUg3Iu-89gJN5nij0mjPMEzGotcLbJI,712
|
|
6
6
|
crystalwindow/clock.py,sha256=iryeURnfXx6TIDyJhpxe0KkeSaHCdxrMckN6Tby00i0,461
|
|
7
7
|
crystalwindow/collision.py,sha256=hpkHTp_KparghVK-itp_rxuYdd2GbQMxICHlUBv0rSw,472
|
|
@@ -16,10 +16,10 @@ crystalwindow/gui.py,sha256=D-El18XUaZQR-XZoOr28hnhO7EEoGuypCHxPbPR_yng,3680
|
|
|
16
16
|
crystalwindow/gui_ext.py,sha256=ZhNgc5eK6Vzj-jUNeFzimuEbLnTmM7Bx594Z34_N0oM,2856
|
|
17
17
|
crystalwindow/math.py,sha256=slOY3KQZ99VDMUMxsSJabMyRtJcwVzEyxR2RoXspHho,963
|
|
18
18
|
crystalwindow/player.py,sha256=4wpIdUZLTlRXV8fDRQ11yVJRbx_cv8Ekpn2y7pQGgAQ,3442
|
|
19
|
-
crystalwindow/sprites.py,sha256=
|
|
19
|
+
crystalwindow/sprites.py,sha256=b_ErcbqoWduk4otxcETJhNsSNfpSUMmcjV4qL5gMf5g,3590
|
|
20
20
|
crystalwindow/tilemap.py,sha256=PHoKL1eWuNeHIf0w-Jh5MGdQGEgklVsxqqJOS-GNMKI,322
|
|
21
21
|
crystalwindow/ver_warner.py,sha256=qEN3ulc1NixBy15FFx2R3Zu0DhyJTVJwiESGAPwpynM,3373
|
|
22
|
-
crystalwindow/window.py,sha256=
|
|
22
|
+
crystalwindow/window.py,sha256=e6C8yIdVdjOduIeU0ZmlrNn8GmyvHuzKs473pRggkz0,18180
|
|
23
23
|
crystalwindow/Icons/default_icon.png,sha256=Loq27Pxb8Wb3Sz-XwtNF1RmlLNxR4TcfOWfK-1lWcII,7724
|
|
24
24
|
crystalwindow/docs/getting_started.md,sha256=e_XEhJk8eatS22MX0nRX7hQNkYkwN9both1ObabZSTw,5759
|
|
25
25
|
crystalwindow/docs/index.md,sha256=bd14uLWtRSeRBm28zngGyfGDI1J6bJRvHkQLDpYwgOE,747
|
|
@@ -31,8 +31,8 @@ crystalwindow/gametests/guitesting.py,sha256=SrOssY5peCQEV6TQ1AiOWtjb9phVGdRzW-Q
|
|
|
31
31
|
crystalwindow/gametests/sandbox.py,sha256=Oo2tU2N0y3BPVa6T5vs_h9N6islhQrjSrr_78XLut5I,1007
|
|
32
32
|
crystalwindow/gametests/squaremove.py,sha256=poP2Zjl2oc2HVvIAgIK34H2jVj6otL4jEdvAOR6L9sI,572
|
|
33
33
|
crystalwindow/gametests/windowtesting.py,sha256=_9X6wnV1-_X_PtNS-0zu-k209NtFIwAc4vpxLPp7V2o,97
|
|
34
|
-
crystalwindow-3.
|
|
35
|
-
crystalwindow-3.
|
|
36
|
-
crystalwindow-3.
|
|
37
|
-
crystalwindow-3.
|
|
38
|
-
crystalwindow-3.
|
|
34
|
+
crystalwindow-3.8.1.dist-info/licenses/LICENSE,sha256=7pvUgvRXL3ED5VVAZPH5oGn1CaIXcyoDC9gqox6sB0g,1079
|
|
35
|
+
crystalwindow-3.8.1.dist-info/METADATA,sha256=L7kncNlmZMHmJl0AeneiHfGYxt7UkJiYtBKeRXbVkhA,7340
|
|
36
|
+
crystalwindow-3.8.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
37
|
+
crystalwindow-3.8.1.dist-info/top_level.txt,sha256=PeQSld4b19XWT-zvbYkvE2Xg8sakIMbDzSzSdOSRN8o,14
|
|
38
|
+
crystalwindow-3.8.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|