tkfluent 0.0.2__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.
tkflu/thememanager.py ADDED
@@ -0,0 +1,27 @@
1
+ from .window import FluWindow
2
+
3
+
4
+ class FluThemeManager(object):
5
+ def __init__(self, window: FluWindow = None, mode: str = "light"):
6
+ if window:
7
+ self._window = window
8
+ else:
9
+ from tkinter import _default_root
10
+ self._window = _default_root
11
+ self._mode = mode
12
+ self.mode(self._mode)
13
+ self._window.after(100, lambda: self.mode(self._mode))
14
+
15
+ def mode(self, mode: str):
16
+ self._mode = mode
17
+ if hasattr(self._window, "theme"):
18
+ self._window.theme(mode=mode)
19
+ if hasattr(self._window, "_draw"):
20
+ self._window._draw()
21
+ self._window.update()
22
+ for widget in self._window.winfo_children():
23
+ if hasattr(widget, "theme"):
24
+ widget.theme(mode=mode)
25
+ if hasattr(widget, "_draw"):
26
+ widget._draw()
27
+ widget.update()
tkflu/togglebutton.py ADDED
@@ -0,0 +1,341 @@
1
+ from tkdeft.windows.draw import DSvgDraw
2
+ from tkdeft.windows.canvas import DCanvas
3
+ from tkdeft.windows.drawwidget import DDrawWidget
4
+
5
+
6
+ class FluToggleButtonDraw(DSvgDraw):
7
+ def create_roundrect(self,
8
+ x1, y1, x2, y2, radius, radiusy=None, temppath=None,
9
+ fill="transparent", outline="black", outline2="black", width=1
10
+ ):
11
+ if radiusy:
12
+ _rx = radius
13
+ _ry = radiusy
14
+ else:
15
+ _rx, _ry = radius, radius
16
+ drawing = self.create_drawing(x2 - x1, y2 - y1, temppath=temppath)
17
+ border = drawing[1].linearGradient(start=(x1, y1), end=(x1, y2), id="DToggleButton.Border")
18
+ border.add_stop_color("0%", outline)
19
+ border.add_stop_color("100%", outline2)
20
+ drawing[1].defs.add(border)
21
+ drawing[1].add(
22
+ drawing[1].rect(
23
+ (x1, y1), (x2 - x1, y2 - y1), _rx, _ry,
24
+ fill=fill, stroke_width=width,
25
+ stroke=f"url(#{border.get_id()})",
26
+ )
27
+ )
28
+ drawing[1].save()
29
+ return drawing[0]
30
+
31
+
32
+ class FluToggleButtonCanvas(DCanvas):
33
+ draw = FluToggleButtonDraw
34
+
35
+ def create_round_rectangle(self,
36
+ x1, y1, x2, y2, r1, r2=None, temppath=None,
37
+ fill="transparent", outline="black", outline2="black", width=1
38
+ ):
39
+ self._img = self.svgdraw.create_roundrect(
40
+ x1, y1, x2, y2, r1, r2, temppath=temppath,
41
+ fill=fill, outline=outline, outline2=outline2, width=width
42
+ )
43
+ self._tkimg = self.svgdraw.create_tksvg_image(self._img)
44
+ return self.create_image(x1, y1, anchor="nw", image=self._tkimg)
45
+
46
+ create_roundrect = create_round_rectangle
47
+
48
+
49
+ class FluToggleButton(FluToggleButtonCanvas, DDrawWidget):
50
+ def __init__(self, *args,
51
+ text="",
52
+ width=120,
53
+ height=32,
54
+ command=None,
55
+ font=None,
56
+ mode="light",
57
+ style="standard",
58
+ **kwargs):
59
+ self._init(mode)
60
+
61
+ super().__init__(*args, width=width, height=height, **kwargs)
62
+
63
+ if command is None:
64
+ def empty(): pass
65
+
66
+ command = empty
67
+
68
+ self.dconfigure(
69
+ text=text,
70
+ command=command
71
+ )
72
+
73
+ self.bind("<<Clicked>>", lambda event=None: self.toggle(), add="+")
74
+ self.bind("<<Clicked>>", lambda event=None: self.focus_set(), add="+")
75
+ self.bind("<<Clicked>>", lambda event=None: self.attributes.command(), add="+")
76
+
77
+ self.bind("<Return>", lambda event=None: self.attributes.command(), add="+") # 可以使用回车键模拟点击
78
+ self.bind("<Return>", lambda event=None: self.toggle(), add="+") # 可以使用回车键模拟点击
79
+
80
+ if font is None:
81
+ from tkdeft.utility.fonts import SegoeFont
82
+ self.attributes.font = SegoeFont()
83
+
84
+ def _init(self, mode):
85
+
86
+ from easydict import EasyDict
87
+
88
+ self.attributes = EasyDict(
89
+ {
90
+ "text": "",
91
+ "command": None,
92
+ "font": None,
93
+ "checked": False,
94
+
95
+ "uncheck": {
96
+ "rest": {
97
+ "back_color": None,
98
+ "border_color": None,
99
+ "border_color2": None,
100
+ "border_width": None,
101
+ "radius": None,
102
+ "text_color": None,
103
+ },
104
+ "hover": {
105
+ "back_color": None,
106
+ "border_color": None,
107
+ "border_color2": None,
108
+ "border_width": None,
109
+ "radius": None,
110
+ "text_color": None,
111
+ },
112
+ "pressed": {
113
+ "back_color": None,
114
+ "border_color": None,
115
+ "border_color2": None,
116
+ "border_width": None,
117
+ "radius": None,
118
+ "text_color": None,
119
+ }
120
+ },
121
+
122
+ "check": {
123
+ "rest": {
124
+ "back_color": None,
125
+ "border_color": None,
126
+ "border_color2": None,
127
+ "border_width": None,
128
+ "radius": None,
129
+ "text_color": None,
130
+ },
131
+ "hover": {
132
+ "back_color": None,
133
+ "border_color": None,
134
+ "border_color2": None,
135
+ "border_width": None,
136
+ "radius": None,
137
+ "text_color": None,
138
+ },
139
+ "pressed": {
140
+ "back_color": None,
141
+ "border_color": None,
142
+ "border_color2": None,
143
+ "border_width": None,
144
+ "radius": None,
145
+ "text_color": None,
146
+ }
147
+ }
148
+ }
149
+ )
150
+
151
+ self.theme(mode=mode)
152
+
153
+ def _draw(self, event=None):
154
+ super()._draw(event)
155
+
156
+ self.delete("all")
157
+
158
+ if not self.attributes.checked:
159
+ if self.enter:
160
+ if self.button1:
161
+ _back_color = self.attributes.uncheck.pressed.back_color
162
+ _border_color = self.attributes.uncheck.pressed.border_color
163
+ _border_color2 = self.attributes.uncheck.pressed.border_color2
164
+ _border_width = self.attributes.uncheck.pressed.border_width
165
+ _radius = self.attributes.uncheck.pressed.radius
166
+ _text_color = self.attributes.uncheck.pressed.text_color
167
+ else:
168
+ _back_color = self.attributes.uncheck.hover.back_color
169
+ _border_color = self.attributes.uncheck.hover.border_color
170
+ _border_color2 = self.attributes.uncheck.hover.border_color2
171
+ _border_width = self.attributes.uncheck.hover.border_width
172
+ _radius = self.attributes.uncheck.hover.radius
173
+ _text_color = self.attributes.uncheck.hover.text_color
174
+ else:
175
+ _back_color = self.attributes.uncheck.rest.back_color
176
+ _border_color = self.attributes.uncheck.rest.border_color
177
+ _border_color2 = self.attributes.uncheck.rest.border_color2
178
+ _border_width = self.attributes.uncheck.rest.border_width
179
+ _radius = self.attributes.uncheck.rest.radius
180
+ _text_color = self.attributes.uncheck.rest.text_color
181
+ else:
182
+ if self.enter:
183
+ if self.button1:
184
+ _back_color = self.attributes.check.pressed.back_color
185
+ _border_color = self.attributes.check.pressed.border_color
186
+ _border_color2 = self.attributes.check.pressed.border_color2
187
+ _border_width = self.attributes.check.pressed.border_width
188
+ _radius = self.attributes.check.pressed.radius
189
+ _text_color = self.attributes.check.pressed.text_color
190
+ else:
191
+ _back_color = self.attributes.check.hover.back_color
192
+ _border_color = self.attributes.check.hover.border_color
193
+ _border_color2 = self.attributes.check.hover.border_color2
194
+ _border_width = self.attributes.check.hover.border_width
195
+ _radius = self.attributes.check.hover.radius
196
+ _text_color = self.attributes.check.hover.text_color
197
+ else:
198
+ _back_color = self.attributes.check.rest.back_color
199
+ _border_color = self.attributes.check.rest.border_color
200
+ _border_color2 = self.attributes.check.rest.border_color2
201
+ _border_width = self.attributes.check.rest.border_width
202
+ _radius = self.attributes.check.rest.radius
203
+ _text_color = self.attributes.check.rest.text_color
204
+
205
+ self.element_border = self.create_round_rectangle(
206
+ 0, 0, self.winfo_width(), self.winfo_height(), _radius, temppath=self.temppath,
207
+ fill=_back_color, outline=_border_color, outline2=_border_color2, width=_border_width
208
+ )
209
+ self.element_text = self.create_text(
210
+ self.winfo_width() / 2, self.winfo_height() / 2, anchor="center",
211
+ fill=_text_color, text=self.attributes.text, font=self.attributes.font
212
+ )
213
+
214
+ def theme(self, mode="light"):
215
+ self.mode = mode
216
+ if mode.lower() == "dark":
217
+ self._dark()
218
+ else:
219
+ self._light()
220
+
221
+ def _light(self):
222
+ self.dconfigure(
223
+ uncheck={
224
+ "rest": {
225
+ "back_color": "#ffffff",
226
+ "border_color": "#f0f0f0",
227
+ "border_color2": "#d6d6d6",
228
+ "border_width": 1,
229
+ "radius": 6,
230
+ "text_color": "#1b1b1b",
231
+ },
232
+ "hover": {
233
+ "back_color": "#fcfcfc",
234
+ "border_color": "#f0f0f0",
235
+ "border_color2": "#d6d6d6",
236
+ "border_width": 1,
237
+ "radius": 6,
238
+ "text_color": "#1b1b1b",
239
+ },
240
+ "pressed": {
241
+ "back_color": "#fdfdfd",
242
+ "border_color": "#f0f0f0",
243
+ "border_color2": "#f0f0f0",
244
+ "border_width": 1,
245
+ "radius": 6,
246
+ "text_color": "#636363",
247
+ }
248
+ },
249
+ check={
250
+ "rest": {
251
+ "back_color": "#005fb8",
252
+ "border_color": "#146cbe",
253
+ "border_color2": "#00396e",
254
+ "border_width": 1,
255
+ "radius": 6,
256
+ "text_color": "#ffffff",
257
+ },
258
+ "hover": {
259
+ "back_color": "#0359a9",
260
+ "border_color": "#1766b0",
261
+ "border_color2": "#0f4373",
262
+ "border_width": 1,
263
+ "radius": 6,
264
+ "text_color": "#ffffff",
265
+ },
266
+ "pressed": {
267
+ "back_color": "#005fb8",
268
+ "border_color": "#4389ca",
269
+ "border_color2": "#4389ca",
270
+ "border_width": 1,
271
+ "radius": 6,
272
+ "text_color": "#b4cbe0",
273
+ }
274
+ }
275
+ )
276
+
277
+ def _dark(self):
278
+ self.dconfigure(
279
+ uncheck={
280
+ "rest": {
281
+ "back_color": "#272727",
282
+ "border_color": "#303030",
283
+ "border_color2": "#262626",
284
+ "border_width": 1,
285
+ "radius": 6,
286
+ "text_color": "#ffffff",
287
+ },
288
+ "hover": {
289
+ "back_color": "#2d2d2d",
290
+ "border_color": "#303030",
291
+ "border_color2": "#262626",
292
+ "border_width": 1,
293
+ "radius": 6,
294
+ "text_color": "#ffffff",
295
+ },
296
+ "pressed": {
297
+ "back_color": "#212121",
298
+ "border_color": "#2a2a2a",
299
+ "border_color2": "#262626",
300
+ "border_width": 1,
301
+ "radius": 6,
302
+ "text_color": "#cfcfcf",
303
+ }
304
+ },
305
+ check={
306
+ "rest": {
307
+ "back_color": "#60cdff",
308
+ "border_color": "#6cd1ff",
309
+ "border_color2": "#56b4df",
310
+ "border_width": 1,
311
+ "radius": 6,
312
+ "text_color": "#000000",
313
+ },
314
+ "hover": {
315
+ "back_color": "#5abce9",
316
+ "border_color": "#67c1eb",
317
+ "border_color2": "#50a5cc",
318
+ "border_width": 1,
319
+ "radius": 6,
320
+ "text_color": "#000000",
321
+ },
322
+ "pressed": {
323
+ "back_color": "#52a9d1",
324
+ "border_color": "#60b0d5",
325
+ "border_color2": "#60b0d5",
326
+ "border_width": 1,
327
+ "radius": 6,
328
+ "text_color": "#295468",
329
+ }
330
+ }
331
+ )
332
+
333
+ def invoke(self):
334
+ self.attributes.command()
335
+
336
+ def toggle(self):
337
+ if self.attributes.checked:
338
+ self.attributes.checked = False
339
+ else:
340
+ self.attributes.checked = True
341
+ self._draw(None)
tkflu/window.py ADDED
@@ -0,0 +1,197 @@
1
+ from tkinter import Tk
2
+ from tkdeft.object import DObject
3
+
4
+
5
+ class FluWindow(Tk, DObject):
6
+
7
+ """Fluent设计的主窗口"""
8
+
9
+ def __init__(self, *args, className="tkdeft", mode="light", **kwargs):
10
+
11
+ """
12
+ 初始化类
13
+
14
+ :param args: 参照tkinter.TK.__init__
15
+ :param className: 参照tkinter.TK.__init__
16
+ :param mode: Fluent主题模式 分为 “light” “dark”
17
+ :param kwargs: 参照tkinter.TK.__init__
18
+ """
19
+
20
+ self._init(mode)
21
+
22
+ self.custom = False
23
+
24
+ super().__init__(*args, className=className, **kwargs)
25
+
26
+ self.bind("<Configure>", self._event_configure)
27
+
28
+ def _draw(self, event=None):
29
+
30
+ """
31
+ 重新绘制窗口及自定义的窗口组件
32
+
33
+ :param event:
34
+ """
35
+
36
+ self.configure(background=self.attributes.back_color)
37
+ if self.custom:
38
+ if hasattr(self, "titlebar"):
39
+ self.titlebar.configure(background=self.attributes.back_color)
40
+ self.titlebar.update()
41
+ if hasattr(self, "titlelabel"):
42
+ self.titlelabel.dconfigure(text_color=self.attributes.text_color)
43
+ self.titlelabel._draw()
44
+ if hasattr(self, "closebutton"):
45
+ self.closebutton.dconfigure(
46
+ rest={
47
+ "back_color": self.titlebar.cget("background"),
48
+ "border_color": "#f0f0f0",
49
+ "border_color2": "#d6d6d6",
50
+ "border_width": 0,
51
+ "radius": 0,
52
+ "text_color": self.attributes.closebutton.text_color,
53
+ },
54
+ hover={
55
+ "back_color": self.attributes.closebutton.back_color,
56
+ "border_color": "#f0f0f0",
57
+ "border_color2": "#d6d6d6",
58
+ "border_width": 0,
59
+ "radius": 0,
60
+ "text_color": self.attributes.closebutton.text_hover_color,
61
+ },
62
+ pressed={
63
+ "back_color": self.attributes.closebutton.back_color,
64
+ "border_color": "#f0f0f0",
65
+ "border_color2": "#f0f0f0",
66
+ "border_width": 0,
67
+ "radius": 0,
68
+ "text_color": self.attributes.closebutton.text_hover_color,
69
+ }
70
+ )
71
+ self.closebutton._draw()
72
+
73
+ def _event_configure(self, event=None):
74
+
75
+ """
76
+ 触发 `<Configure>` 事件
77
+
78
+ :param event:
79
+ :return:
80
+ """
81
+
82
+ self._draw()
83
+
84
+ def _init(self, mode):
85
+ from easydict import EasyDict
86
+ self.attributes = EasyDict(
87
+ {
88
+ "back_color": None,
89
+ "text_color": None,
90
+ "closebutton": {
91
+ "back_color": None,
92
+ "text_color": None,
93
+ "text_hover_color": None
94
+ }
95
+ }
96
+ )
97
+
98
+ self.theme(mode)
99
+
100
+ def theme(self, mode: str):
101
+
102
+ """
103
+ 同 `theme_myself`
104
+
105
+ :param mode:
106
+ :return:
107
+ """
108
+
109
+ self.theme_myself(mode=mode)
110
+
111
+ def theme_myself(self, mode: str):
112
+
113
+ """
114
+ 修改该窗口的Fluent主题
115
+
116
+ :param mode:
117
+ :return:
118
+ """
119
+
120
+ self.mode = mode
121
+ if mode.lower() == "dark":
122
+ self._dark()
123
+ else:
124
+ self._light()
125
+
126
+ def _light(self):
127
+ self.dconfigure(
128
+ back_color="#ffffff",
129
+ text_color="#000000",
130
+ closebutton={
131
+ "back_color": "red",
132
+ "text_color": "#000000",
133
+ "text_hover_color": "#ffffff"
134
+ }
135
+ )
136
+
137
+ def _dark(self):
138
+ self.dconfigure(
139
+ back_color="#202020",
140
+ text_color="#ffffff",
141
+ closebutton={
142
+ "back_color": "red",
143
+ "text_color": "#ffffff",
144
+ "text_hover_color": "#000000"
145
+ }
146
+ )
147
+
148
+ def wincustom(self, wait=200, way=1):
149
+
150
+ """
151
+ 自定义窗口 仅限`Windows系统`
152
+
153
+ :param wait: 直接执行自定义窗口容易出错误 需要一点时间等待才能执行 同`after()`中的`ms`
154
+ :param way: 取0时保留原版边框,但稳定性很差,容易崩溃。取1时不保留原版边框,但稳定性较好。
155
+ :return:
156
+ """
157
+
158
+ from sys import platform
159
+ from .button import FluButton
160
+ from .label import FluLabel
161
+ from tkinter import Frame
162
+ self.titlebar = Frame(self, width=180, height=35, background=self.attributes.back_color)
163
+ self.titlelabel = FluLabel(self.titlebar, text=self.title(), width=50)
164
+ self.titlelabel.pack(fill="y", side="left")
165
+ self.closebutton = FluButton(self.titlebar, text="", width=32, height=32, command=lambda: self.quit())
166
+ self.closebutton.pack(fill="y", side="right")
167
+ self.titlebar.pack(fill="x", side="top")
168
+
169
+ if platform == "win32":
170
+ if way == 0:
171
+ from .customwindow import CustomWindow
172
+ self.customwindow = CustomWindow(self, wait=wait)
173
+ self.customwindow.bind_drag(self.titlebar)
174
+ self.customwindow.bind_drag(self.titlelabel)
175
+ else:
176
+ self.overrideredirect(True)
177
+ try:
178
+ from win32gui import GetParent, GetWindowLong, SetWindowLong
179
+ from win32con import GWL_EXSTYLE, WS_EX_APPWINDOW, WS_EX_TOOLWINDOW
180
+ hwnd = GetParent(self.winfo_id())
181
+ style = GetWindowLong(hwnd, GWL_EXSTYLE)
182
+ style = style & ~WS_EX_TOOLWINDOW
183
+ style = style | WS_EX_APPWINDOW
184
+ SetWindowLong(hwnd, GWL_EXSTYLE, style)
185
+ self.after(30, lambda: self.withdraw())
186
+ self.after(60, lambda: self.deiconify())
187
+ except:
188
+ pass
189
+
190
+ self.wm_attributes("-topmost", True)
191
+
192
+ from .customwindow2 import WindowDragArea
193
+ self.dragarea = WindowDragArea(self)
194
+ self.dragarea.bind(self.titlebar)
195
+ self.dragarea.bind(self.titlelabel)
196
+
197
+ self.custom = True
@@ -0,0 +1,23 @@
1
+ Metadata-Version: 2.1
2
+ Name: tkfluent
3
+ Version: 0.0.2
4
+ Summary: Fluent Design for Tkinter
5
+ Author: XiangQinxi
6
+ Author-email: xiangqinxi@outlook.com
7
+ Classifier: Programming Language :: Python :: 2
8
+ Classifier: Programming Language :: Python :: 2.7
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3.4
11
+ Classifier: Programming Language :: Python :: 3.5
12
+ Classifier: Programming Language :: Python :: 3.6
13
+ Classifier: Programming Language :: Python :: 3.7
14
+ Classifier: Programming Language :: Python :: 3.8
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Requires-Dist: tkdeft (>=0.0.7,<0.0.8)
20
+ Project-URL: Documentation, https://tkfluent.netlify.app
21
+ Description-Content-Type: text/markdown
22
+
23
+ # tkfluent
@@ -0,0 +1,21 @@
1
+ tkflu/__init__.py,sha256=ZkeXXJhoEwjNUes12oBZHovvKFCuZiaoZj-NCeFvVYg,530
2
+ tkflu/__main__.py,sha256=7qALQjQaw9-cEB_9UhWUuQYZSfh9eONftFx16PlosCE,1317
3
+ tkflu/badge.py,sha256=3Yw5EwlA2UvRLVMK8jdsAv_R6RtrSbC5dQTk9gr2sv4,4882
4
+ tkflu/button.py,sha256=2_XxwkauewTL_Z6YIafJRXAQg8jyrPGhLdRJMaZ1QFY,9987
5
+ tkflu/checkbox.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ tkflu/customwindow.py,sha256=Fr4CF0vKwj36tYzgX9_5F7OwcD59z9LfOW20Ugm2Hxc,3761
7
+ tkflu/customwindow2.py,sha256=nyNEMoGVnOYXCPbdvxZFUH-VlpAtjjEGI8Ul9VDvgAs,2109
8
+ tkflu/entry.py,sha256=5tQqhGzqwSiRIJQdZz52afDtVAWKKfWNeLgGDzeRXNk,6416
9
+ tkflu/frame.py,sha256=noQhnU-4d6UnvjVMeLYTuS5F-pFBx9-iSJCFXH02B2c,7075
10
+ tkflu/image.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ tkflu/label.py,sha256=m9HEXlM0ribh8y4B6vfp3HEVH8ElyuVPyG-2BwzdGVo,1598
12
+ tkflu/listbox.py,sha256=gD_oNNWVZtm5qXQ8bVBNRqJL6CGiIYtvhxztM9huzew,9991
13
+ tkflu/litenav.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
+ tkflu/scrollbar.py,sha256=1hbu5n1mx4KyiF_M3sohpJJPux1zu5Jlw9V6LfQQs1Y,7293
15
+ tkflu/text.py,sha256=uwpW2omhd6kKQyEVMH-GSSozeMxP3zBUY_RPW5fvuao,6525
16
+ tkflu/thememanager.py,sha256=10Pp4nRyEjdbX4wmh4HayIZomc_iz_vxxSrhIh2SR6s,941
17
+ tkflu/togglebutton.py,sha256=hcAYh8XYaireQuGLHKWxJDLm2wMYHt3GlJnE8TjjbIY,13436
18
+ tkflu/window.py,sha256=pc5M9jIgUj98cFJNR7Q4i3Sll3HxIsDKA8dHL2DxWXg,6581
19
+ tkfluent-0.0.2.dist-info/METADATA,sha256=5UKzRl5OML8VJkXCB1TNd_TB1h5ofkavnxHsDQEhCVM,890
20
+ tkfluent-0.0.2.dist-info/WHEEL,sha256=IrRNNNJ-uuL1ggO5qMvT1GGhQVdQU54d6ZpYqEZfEWo,92
21
+ tkfluent-0.0.2.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: poetry-core 1.9.0
3
+ Root-Is-Purelib: true
4
+ Tag: py2.py3-none-any