fastled 1.2.5__py3-none-any.whl → 1.2.7__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.
fastled/__init__.py CHANGED
@@ -1,6 +1,7 @@
1
1
  """FastLED Wasm Compiler package."""
2
2
 
3
3
  # context
4
+ import subprocess
4
5
  from contextlib import contextmanager
5
6
  from pathlib import Path
6
7
  from typing import Generator
@@ -13,7 +14,7 @@ from .types import BuildMode, CompileResult, CompileServerError
13
14
  # IMPORTANT! There's a bug in github which will REJECT any version update
14
15
  # that has any other change in the repo. Please bump the version as the
15
16
  # ONLY change in a commit, or else the pypi update and the release will fail.
16
- __version__ = "1.2.5"
17
+ __version__ = "1.2.7"
17
18
 
18
19
 
19
20
  class Api:
@@ -131,17 +132,160 @@ class Docker:
131
132
  from fastled.docker_manager import DockerManager
132
133
  from fastled.settings import CONTAINER_NAME
133
134
 
134
- docker = DockerManager()
135
+ docker_mgr = DockerManager()
135
136
  container_name = container_name or CONTAINER_NAME
136
- return docker.is_container_running(container_name)
137
+ return docker_mgr.is_container_running(container_name)
137
138
 
138
139
  @staticmethod
139
140
  def purge() -> None:
140
141
  from fastled.docker_manager import DockerManager
141
- from fastled.settings import CONTAINER_NAME
142
+ from fastled.settings import IMAGE_NAME
143
+
144
+ docker_mgr = DockerManager()
145
+ docker_mgr.purge(image_name=IMAGE_NAME)
146
+
147
+ @staticmethod
148
+ def build_from_github(
149
+ url: str = "https://github.com/fastled/fastled",
150
+ output_dir: Path | str = Path(".cache/fastled"),
151
+ ) -> str:
152
+ """Build the FastLED WASM compiler Docker image from a GitHub repository.
153
+
154
+ Args:
155
+ url: GitHub repository URL (default: https://github.com/fastled/fastled)
156
+ output_dir: Directory to clone the repo into (default: .cache/fastled)
157
+
158
+ Returns:
159
+ Container name.
160
+ """
142
161
 
143
- docker = DockerManager()
144
- docker.purge(CONTAINER_NAME)
162
+ from fastled.docker_manager import DockerManager
163
+ from fastled.settings import CONTAINER_NAME, IMAGE_NAME
164
+
165
+ if isinstance(output_dir, str):
166
+ output_dir = Path(output_dir)
167
+
168
+ # Create output directory if it doesn't exist
169
+ output_dir.mkdir(parents=True, exist_ok=True)
170
+
171
+ # Clone or update the repository
172
+ if (output_dir / ".git").exists():
173
+ print(f"Updating existing repository in {output_dir}")
174
+ # Reset local changes and move HEAD back to handle force pushes
175
+ subprocess.run(
176
+ ["git", "reset", "--hard", "HEAD~10"],
177
+ cwd=output_dir,
178
+ check=True,
179
+ capture_output=True, # Suppress output of reset
180
+ )
181
+ subprocess.run(
182
+ ["git", "pull", "origin", "master"], cwd=output_dir, check=True
183
+ )
184
+ else:
185
+ print(f"Cloning {url} into {output_dir}")
186
+ subprocess.run(["git", "clone", url, str(output_dir)], check=True)
187
+
188
+ dockerfile_path = (
189
+ output_dir / "src" / "platforms" / "wasm" / "compiler" / "Dockerfile"
190
+ )
191
+
192
+ if not dockerfile_path.exists():
193
+ raise FileNotFoundError(
194
+ f"Dockerfile not found at {dockerfile_path}. "
195
+ "This may not be a valid FastLED repository."
196
+ )
197
+
198
+ docker_mgr = DockerManager()
199
+
200
+ platform_tag = ""
201
+ # if "arm" in docker_mgr.architecture():
202
+ if (
203
+ "arm"
204
+ in subprocess.run(["uname", "-m"], capture_output=True).stdout.decode()
205
+ ):
206
+ platform_tag = "-arm64"
207
+
208
+ # Build the image
209
+ docker_mgr.build_image(
210
+ image_name=IMAGE_NAME,
211
+ tag="main",
212
+ dockerfile_path=dockerfile_path,
213
+ build_context=output_dir,
214
+ build_args={"NO_PREWARM": "1"},
215
+ platform_tag=platform_tag,
216
+ )
217
+
218
+ # Run the container and return it
219
+ container = docker_mgr.run_container_detached(
220
+ image_name=IMAGE_NAME,
221
+ tag="main",
222
+ container_name=CONTAINER_NAME,
223
+ command=None, # Use default command from Dockerfile
224
+ volumes=None, # No volumes needed for build
225
+ ports=None, # No ports needed for build
226
+ remove_previous=True, # Remove any existing container
227
+ )
228
+
229
+ return container.name
230
+
231
+ @staticmethod
232
+ def build_from_fastled_repo(
233
+ project_root: Path | str = Path("."), platform_tag: str = ""
234
+ ) -> str:
235
+ """Build the FastLED WASM compiler Docker image, which will be tagged as "main".
236
+
237
+ Args:
238
+ project_root: Path to the FastLED project root directory
239
+ platform_tag: Optional platform tag (e.g. "-arm64" for ARM builds)
240
+
241
+ Returns:
242
+ The string name of the docker container.
243
+ """
244
+ from fastled.docker_manager import DockerManager
245
+ from fastled.settings import CONTAINER_NAME, IMAGE_NAME
246
+
247
+ if isinstance(project_root, str):
248
+ project_root = Path(project_root)
249
+
250
+ dockerfile_path = (
251
+ project_root / "src" / "platforms" / "wasm" / "compiler" / "Dockerfile"
252
+ )
253
+
254
+ docker_mgr = DockerManager()
255
+
256
+ platform_tag = ""
257
+ # if "arm" in docker_mgr.architecture():
258
+ if (
259
+ "arm"
260
+ in subprocess.run(["uname", "-m"], capture_output=True).stdout.decode()
261
+ ):
262
+ platform_tag = "-arm64"
263
+
264
+ # if image exists, remove it
265
+ docker_mgr.purge(image_name=IMAGE_NAME)
266
+
267
+ # Build the image
268
+ docker_mgr.build_image(
269
+ image_name=IMAGE_NAME,
270
+ tag="main",
271
+ dockerfile_path=dockerfile_path,
272
+ build_context=project_root,
273
+ build_args={"NO_PREWARM": "1"},
274
+ platform_tag=platform_tag,
275
+ )
276
+
277
+ # Run the container and return it
278
+ container = docker_mgr.run_container_detached(
279
+ image_name=IMAGE_NAME,
280
+ tag="main",
281
+ container_name=CONTAINER_NAME,
282
+ command=None, # Use default command from Dockerfile
283
+ volumes=None, # No volumes needed for build
284
+ ports=None, # No ports needed for build
285
+ remove_previous=True, # Remove any existing container
286
+ )
287
+ container_name = f"{container.name}"
288
+ return container_name
145
289
 
146
290
 
147
291
  class Test:
@@ -173,6 +317,7 @@ class Test:
173
317
  __all__ = [
174
318
  "Api",
175
319
  "Test",
320
+ "Build",
176
321
  "CompileServer",
177
322
  "CompileResult",
178
323
  "CompileServerError",
fastled/app.py CHANGED
@@ -51,6 +51,32 @@ def main() -> int:
51
51
  print("Finished updating.")
52
52
  return 0
53
53
 
54
+ if args.build:
55
+ try:
56
+ project_root = Path(".").absolute()
57
+ print(f"Building Docker image at {project_root}")
58
+ from fastled import Api, Docker
59
+
60
+ docker_image_name = Docker.build_from_fastled_repo(
61
+ project_root=project_root
62
+ )
63
+ print(f"Built Docker image: {docker_image_name}")
64
+ print("Running server")
65
+ with Api.server(
66
+ auto_updates=False, container_name=docker_image_name
67
+ ) as server:
68
+ print(f"Server started at {server.url()}")
69
+ sketch_dir = Path("examples/wasm")
70
+ with Api.live_client(
71
+ sketch_directory=sketch_dir, host=server
72
+ ) as client:
73
+ print(f"Client started at {client.url()}")
74
+ while True:
75
+ time.sleep(0.1)
76
+ except KeyboardInterrupt:
77
+ print("\nExiting from client...")
78
+ return 1
79
+
54
80
  if args.server:
55
81
  print("Running in server only mode.")
56
82
  return run_server(args)
fastled/docker_manager.py CHANGED
@@ -4,6 +4,7 @@ New abstraction for Docker management with improved Ctrl+C handling.
4
4
 
5
5
  import _thread
6
6
  import os
7
+ import platform
7
8
  import subprocess
8
9
  import sys
9
10
  import threading
@@ -97,10 +98,12 @@ class RunningContainer:
97
98
 
98
99
  class DockerManager:
99
100
  def __init__(self) -> None:
101
+ from docker.errors import DockerException
102
+
100
103
  try:
101
104
  self._client: DockerClient | None = None
102
105
  self.first_run = False
103
- except docker.errors.DockerException as e:
106
+ except DockerException as e:
104
107
  stack = traceback.format_exc()
105
108
  warnings.warn(f"Error initializing Docker client: {e}\n{stack}")
106
109
  raise
@@ -475,7 +478,7 @@ class DockerManager:
475
478
  print(
476
479
  f"Container {container_name} did not restart within {timeout} seconds."
477
480
  )
478
- container.stop()
481
+ container.stop(timeout=0)
479
482
  print(f"Container {container_name} has been stopped.")
480
483
  container.start()
481
484
  elif container.status == "paused":
@@ -501,6 +504,7 @@ class DockerManager:
501
504
  tty=True,
502
505
  volumes=volumes,
503
506
  ports=ports,
507
+ remove=True,
504
508
  )
505
509
  return container
506
510
 
@@ -552,6 +556,8 @@ class DockerManager:
552
556
  if isinstance(container, str):
553
557
  container = self.get_container(container)
554
558
 
559
+ assert container is not None, "Container not found."
560
+
555
561
  print(f"Attaching to container {container.name}...")
556
562
 
557
563
  first_run = self.first_run
@@ -570,7 +576,11 @@ class DockerManager:
570
576
  print(f"Could not put container {container_name} to sleep.")
571
577
  return
572
578
  try:
573
- container.pause()
579
+ if platform.system() == "Windows":
580
+ container.pause()
581
+ else:
582
+ container.stop()
583
+ container.remove()
574
584
  print(f"Container {container.name} has been suspended.")
575
585
  except KeyboardInterrupt:
576
586
  print(f"Container {container.name} interrupted by keyboard interrupt.")
@@ -583,21 +593,23 @@ class DockerManager:
583
593
  """
584
594
  if isinstance(container, str):
585
595
  container = self.get_container(container)
596
+ if not container:
597
+ print(f"Could not resume container {container}.")
598
+ return
586
599
  try:
587
600
  container.unpause()
588
601
  print(f"Container {container.name} has been resumed.")
589
602
  except Exception as e:
590
603
  print(f"Failed to resume container {container.name}: {e}")
591
604
 
592
- def get_container(self, container_name: str) -> Container:
605
+ def get_container(self, container_name: str) -> Container | None:
593
606
  """
594
607
  Get a container by name.
595
608
  """
596
609
  try:
597
610
  return self.client.containers.get(container_name)
598
611
  except docker.errors.NotFound:
599
- print(f"Container {container_name} not found.")
600
- raise
612
+ return None
601
613
 
602
614
  def is_container_running(self, container_name: str) -> bool:
603
615
  """
@@ -610,6 +622,67 @@ class DockerManager:
610
622
  print(f"Container {container_name} not found.")
611
623
  return False
612
624
 
625
+ def build_image(
626
+ self,
627
+ image_name: str,
628
+ tag: str,
629
+ dockerfile_path: Path,
630
+ build_context: Path,
631
+ build_args: dict[str, str] | None = None,
632
+ platform_tag: str = "",
633
+ ) -> None:
634
+ """
635
+ Build a Docker image from a Dockerfile.
636
+
637
+ Args:
638
+ image_name: Name for the image
639
+ tag: Tag for the image
640
+ dockerfile_path: Path to the Dockerfile
641
+ build_context: Path to the build context directory
642
+ build_args: Optional dictionary of build arguments
643
+ platform_tag: Optional platform tag (e.g. "-arm64")
644
+ """
645
+ if not dockerfile_path.exists():
646
+ raise FileNotFoundError(f"Dockerfile not found at {dockerfile_path}")
647
+
648
+ if not build_context.exists():
649
+ raise FileNotFoundError(
650
+ f"Build context directory not found at {build_context}"
651
+ )
652
+
653
+ print(f"Building Docker image {image_name}:{tag} from {dockerfile_path}")
654
+
655
+ # Prepare build arguments
656
+ buildargs = build_args or {}
657
+ if platform_tag:
658
+ buildargs["PLATFORM_TAG"] = platform_tag
659
+
660
+ try:
661
+ cmd_list = [
662
+ "docker",
663
+ "build",
664
+ "-t",
665
+ f"{image_name}:{tag}",
666
+ ]
667
+
668
+ # Add build args
669
+ for arg_name, arg_value in buildargs.items():
670
+ cmd_list.extend(["--build-arg", f"{arg_name}={arg_value}"])
671
+
672
+ # Add dockerfile and context paths
673
+ cmd_list.extend(["-f", str(dockerfile_path), str(build_context)])
674
+
675
+ cmd_str = subprocess.list2cmdline(cmd_list)
676
+ print(f"Running command: {cmd_str}")
677
+
678
+ # Run the build command
679
+ subprocess.run(cmd_list, check=True)
680
+ print(f"Successfully built image {image_name}:{tag}")
681
+
682
+ except subprocess.CalledProcessError as e:
683
+ print(f"Error building Docker image: {e}")
684
+ raise
685
+
613
686
  def purge(self, image_name: str) -> None:
614
687
  """
615
688
  Remove all containers and images associated with the given image name.
@@ -626,11 +699,13 @@ class DockerManager:
626
699
  if any(image_name in tag for tag in container.image.tags):
627
700
  print(f"Removing container {container.name}")
628
701
  container.remove(force=True)
702
+
629
703
  except Exception as e:
630
704
  print(f"Error removing containers: {e}")
631
705
 
632
706
  # Remove all images with this name
633
707
  try:
708
+ self.client.images.prune(filters={"dangling": False})
634
709
  images = self.client.images.list()
635
710
  for image in images:
636
711
  if any(image_name in tag for tag in image.tags):
fastled/keyboard.py CHANGED
@@ -6,12 +6,10 @@ import time
6
6
  from queue import Empty, Queue
7
7
  from threading import Thread
8
8
 
9
- _WHITE_SPACE = [" ", "\r", "\n"]
9
+ _WHITE_SPACE = {" ", "\n", "\r"} # Including Enter key as whitespace
10
10
 
11
11
 
12
- # Original space bar, but now also enter key.
13
12
  class SpaceBarWatcher:
14
-
15
13
  @classmethod
16
14
  def watch_space_bar_pressed(cls, timeout: float = 0) -> bool:
17
15
  watcher = cls()
@@ -32,9 +30,7 @@ class SpaceBarWatcher:
32
30
  self.process.start()
33
31
 
34
32
  def _watch_for_space(self) -> None:
35
- # Set stdin to non-blocking mode
36
33
  fd = sys.stdin.fileno()
37
-
38
34
  if os.name == "nt": # Windows
39
35
  import msvcrt
40
36
 
@@ -51,14 +47,13 @@ class SpaceBarWatcher:
51
47
  char = msvcrt.getch().decode() # type: ignore
52
48
  if char in _WHITE_SPACE:
53
49
  self.queue.put(ord(" "))
54
-
55
50
  else: # Unix-like systems
56
51
  import termios
57
52
  import tty
58
53
 
59
54
  old_settings = termios.tcgetattr(fd) # type: ignore
60
55
  try:
61
- tty.setraw(fd) # type: ignore
56
+ tty.setcbreak(fd) # Use cbreak mode to avoid console issues
62
57
  while True:
63
58
  # Check for cancel signal
64
59
  try:
@@ -70,21 +65,22 @@ class SpaceBarWatcher:
70
65
  # Check if there's input ready
71
66
  if select.select([sys.stdin], [], [], 0.1)[0]:
72
67
  char = sys.stdin.read(1)
73
- if ord(char) == 3: # ctrl+c on mac, maybe also linux?
68
+ if ord(char) == 3: # Ctrl+C
74
69
  _thread.interrupt_main()
75
70
  break
76
-
77
71
  if char in _WHITE_SPACE:
78
72
  self.queue.put(ord(" "))
79
73
  finally:
80
- termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) # type: ignore
74
+ termios.tcsetattr(
75
+ fd, termios.TCSADRAIN, old_settings
76
+ ) # Restore terminal settings
81
77
 
82
78
  def space_bar_pressed(self) -> bool:
83
79
  found = False
84
80
  while not self.queue.empty():
85
81
  try:
86
- key = self.queue.get(block=False, timeout=0.1)
87
- if key == ord(" "):
82
+ key = self.queue.get(block=False)
83
+ if key == ord(" "): # Spacebar
88
84
  found = True
89
85
  self.queue.task_done()
90
86
  except Empty:
fastled/live_client.py CHANGED
@@ -45,6 +45,17 @@ class LiveClient:
45
45
  )
46
46
  return rtn
47
47
 
48
+ def url(self) -> str:
49
+ """Get the URL of the server."""
50
+ if isinstance(self.host, CompileServer):
51
+ return self.host.url()
52
+ if self.host is None:
53
+ import warnings
54
+
55
+ warnings.warn("TODO: use the actual host.")
56
+ return "http://localhost:9021"
57
+ return self.host
58
+
48
59
  @property
49
60
  def running(self) -> bool:
50
61
  return self.thread is not None and self.thread.is_alive()
@@ -67,3 +78,9 @@ class LiveClient:
67
78
  """Finalize the client."""
68
79
  self.stop()
69
80
  self.thread = None
81
+
82
+ def __enter__(self) -> "LiveClient":
83
+ return self
84
+
85
+ def __exit__(self, exc_type, exc_value, traceback) -> None:
86
+ self.finalize()
fastled/open_browser.py CHANGED
@@ -17,7 +17,8 @@ def _open_browser_python(fastled_js: Path) -> None:
17
17
  subprocess.run(
18
18
  [sys.executable, "-m", "nodejs.npm", "install", "-g", "live-server"]
19
19
  )
20
- os.system(f"cd {fastled_js} && live-server")
20
+ proc = subprocess.Popen(["cd", fastled_js, "&&", "live-server"])
21
+ proc.wait()
21
22
 
22
23
 
23
24
  def _find_open_port(start_port: int) -> int:
fastled/parse_args.py CHANGED
@@ -79,6 +79,12 @@ def parse_args() -> argparse.Namespace:
79
79
  action="store_true",
80
80
  help="Use localhost for web compilation from an instance of fastled --server, creating it if necessary",
81
81
  )
82
+ parser.add_argument(
83
+ "--build",
84
+ "-b",
85
+ action="store_true",
86
+ help="Build the wasm compiler image from the FastLED repo",
87
+ )
82
88
  parser.add_argument(
83
89
  "--server",
84
90
  "-s",
fastled/site/build.py CHANGED
@@ -189,21 +189,53 @@ INDEX_TEMPLATE = """<!DOCTYPE html>
189
189
  const splashScreen = document.querySelector('.splash-screen');
190
190
  const splashText = document.querySelector('.splash-text');
191
191
 
192
- // Wait for font to load
193
- document.fonts.ready.then(() => {{
194
- // Fade in the text
195
- splashText.style.opacity = '1';
196
-
197
- // Wait for page load plus fade-in time before starting fade-out sequence
198
- window.addEventListener('load', () => {{
199
- setTimeout(() => {{
200
- splashScreen.style.opacity = '0';
201
- setTimeout(() => {{
202
- splashScreen.style.display = 'none';
203
- }}, 500); // Remove from DOM after fade completes
204
- }}, 1500); // Wait for load + 1.5s (giving time for fade-in)
192
+ // Ensure splash screen always gets removed
193
+ const removeSplashScreen = () => {{
194
+ splashScreen.style.opacity = '0';
195
+ setTimeout(() => {{
196
+ splashScreen.style.display = 'none';
197
+ }}, 500);
198
+ }};
199
+
200
+ // Set a maximum time the splash screen can stay
201
+ const maxSplashTime = setTimeout(removeSplashScreen, 2000); // Reduced from 5000ms to 2000ms
202
+
203
+ // Try to do nice fade-in/fade-out when possible
204
+ try {{
205
+ // Add a fallback timer in case font loading fails silently
206
+ const fontTimeout = setTimeout(() => {{
207
+ splashText.style.opacity = '1';
208
+ setTimeout(removeSplashScreen, 1000);
209
+ }}, 1000);
210
+
211
+ Promise.all([
212
+ // Wrap font loading in a timeout promise
213
+ Promise.race([
214
+ document.fonts.ready,
215
+ new Promise((_, reject) => setTimeout(reject, 1500))
216
+ ]),
217
+ new Promise(resolve => {{
218
+ if (document.readyState === 'complete') {{
219
+ resolve();
220
+ }} else {{
221
+ window.addEventListener('load', resolve);
222
+ }}
223
+ }})
224
+ ]).then(() => {{
225
+ clearTimeout(maxSplashTime);
226
+ clearTimeout(fontTimeout);
227
+ splashText.style.opacity = '1';
228
+ setTimeout(removeSplashScreen, 1500);
229
+ }}).catch(() => {{
230
+ // If either promise fails, ensure splash screen is removed
231
+ clearTimeout(maxSplashTime);
232
+ removeSplashScreen();
205
233
  }});
206
- }});
234
+ }} catch (e) {{
235
+ // Final fallback if anything goes wrong
236
+ console.warn('Splash screen error:', e);
237
+ removeSplashScreen();
238
+ }}
207
239
  const links = document.querySelectorAll('.example-link');
208
240
  const iframe = document.getElementById('example-frame');
209
241
  const navPane = document.querySelector('.nav-pane');
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fastled
3
- Version: 1.2.5
3
+ Version: 1.2.7
4
4
  Summary: FastLED Wasm Compiler
5
5
  Home-page: https://github.com/zackees/fastled-wasm
6
6
  Maintainer: Zachary Vorhies
@@ -186,6 +186,14 @@ with Api.server() as server:
186
186
  client.stop()
187
187
  ```
188
188
 
189
+ **Build Docker Image from a local copy of the FastLED repo**
190
+ ```python
191
+ from fastapi import Docker, Api
192
+ container_name: str = Docker.build_from_fastled_repo()
193
+ with Api.server(container_name=container_name) as server:
194
+ ...
195
+ ```
196
+
189
197
  # Features
190
198
 
191
199
  ## Hot reload by default
@@ -266,6 +274,8 @@ A: A big chunk of space is being used by unnecessary javascript `emscripten` bun
266
274
 
267
275
  # Revisions
268
276
 
277
+ * 1.2.7 - A bunch of fixes for MacOS and probably linux.
278
+ * 1.2.6 - Now builds image from the project root of FastLED.
269
279
  * 1.1.25 - Fix up paths for `--init`
270
280
  * 1.1.24 - Mac/Linux now properly responds to ctrl-c when waiting for a key event.
271
281
  * 1.1.23 - Fixes missing `live-server` on platforms that don't have it already.
@@ -1,15 +1,15 @@
1
- fastled/__init__.py,sha256=hCn09t7Zi2h6idcDO0tKMGRnEzotgPzIPaKh6PdEJLM,5300
2
- fastled/app.py,sha256=Y1Q5mx4zdQbZ2AaB43ZqJo-w_8ehAaWVNtvTyeCRSaE,1970
1
+ fastled/__init__.py,sha256=R6enLMDw9XKm6b_5ACKqjmSWjdXKCwLjk_1PfZuck0s,10260
2
+ fastled/app.py,sha256=H_uUI5YKF6_cjXN3P5PZwLrkQTlSwKVXvveLEK9Kt4c,2973
3
3
  fastled/cli.py,sha256=FjVr31ht0UPlAcmX-84NwfAGMQHTkrCe4o744jCAxiw,375
4
4
  fastled/client_server.py,sha256=8L62zNtkGtErDtWrr4XVNsv7ji2zoS5rlqfCnwI3VKU,13177
5
5
  fastled/compile_server.py,sha256=Z7rHFs3M6QPbSCsbgHAQDk6GTVAJMMPCXtD4Y0mu8RM,2659
6
6
  fastled/compile_server_impl.py,sha256=B_7zjdKHxX2JbNcx26hntwtk8-MyQTs6LMZlpOEuloM,8746
7
- fastled/docker_manager.py,sha256=J6epThU164XAKe8pDsquLs8ytFFn6QAch2PEVeRNY80,26538
7
+ fastled/docker_manager.py,sha256=Nf0x2BpwT1BvSsi63ZkDhQDMhjiWrjFiXxgowtQMrhM,28955
8
8
  fastled/filewatcher.py,sha256=LwEQJkqADsArZyY499RLAer6JjJyDwaQBcAvT7xmp3c,6708
9
- fastled/keyboard.py,sha256=Uwzfgd85BiZTi5D8f3HRQex9cvOuveagUqjULeTEHw4,3423
10
- fastled/live_client.py,sha256=_KvqmyUyyGpoYET1Z9CdeUVoIbFjIUWwPcTp5XCQuxY,2075
11
- fastled/open_browser.py,sha256=uhx_UkZ4URUcFn--ZOGMacjL6gFZHwnMu2qYyok2YzE,1620
12
- fastled/parse_args.py,sha256=nPHmmkr4_izLdrFYFO6_M3JEkL1uO8NThRi29mUPkKw,6707
9
+ fastled/keyboard.py,sha256=Tf_wJDAhaEWGguoBhWUu_9QRvMCPQEqNZckCsBERcGs,3423
10
+ fastled/live_client.py,sha256=b9mVJ-8w_zoEDwKIlAEUC5Q1La5W5rR6ct-exOcgJec,2561
11
+ fastled/open_browser.py,sha256=nlzNheruTXAYyhqafl2hSoBDL7IdE8P4w43GbwNIMaY,1656
12
+ fastled/parse_args.py,sha256=LD2PpSEhyq3ZqPWa_TJ90Fb-O-yldi7rnen2fWLOPjo,6868
13
13
  fastled/paths.py,sha256=VsPmgu0lNSCFOoEC0BsTYzDygXqy15AHUfN-tTuzDZA,99
14
14
  fastled/project_init.py,sha256=bBt4DwmW5hZkm9ICt9Qk-0Nr_0JQM7icCgH5Iv-bCQs,3984
15
15
  fastled/select_sketch_directory.py,sha256=TZdCjl1D7YMKjodMTvDRurPcpAmN3x0TcJxffER2NfM,1314
@@ -21,12 +21,12 @@ fastled/types.py,sha256=PpSEtzFCkWtSIEMC0QXGl966R97vLoryVl3yFW0YhTs,1475
21
21
  fastled/util.py,sha256=t4M3NFMhnCzfYbLvIyJi0RdFssZqbTN_vVIaej1WV-U,265
22
22
  fastled/web_compile.py,sha256=05PeLJ77QQC6PUKjDhsntBmyBola6QQIfF2k-zjYNE4,10261
23
23
  fastled/assets/example.txt,sha256=lTBovRjiz0_TgtAtbA1C5hNi2ffbqnNPqkKg6UiKCT8,54
24
- fastled/site/build.py,sha256=vb1np-3rX5lmPX1Be4OazGtlrsZQYnVDmR2sE4Km7Kw,12536
24
+ fastled/site/build.py,sha256=Eq_u3oRxP88twv5IskKfH3tMr6IuT3I5C5zl94TUECw,13854
25
25
  fastled/test/can_run_local_docker_tests.py,sha256=LEuUbHctRhNNFWcvnz2kEGmjDJeXO4c3kNpizm3yVJs,400
26
26
  fastled/test/examples.py,sha256=6xPwx_k9_XwYTpI1nk4SrYbsJKHJACd30GzD1epGqhY,1597
27
- fastled-1.2.5.dist-info/LICENSE,sha256=b6pOoifSXiUaz_lDS84vWlG3fr4yUKwB8fzkrH9R8bQ,1064
28
- fastled-1.2.5.dist-info/METADATA,sha256=oh6UGEkaee1i-kcAAoLjsj4nW3LAPrppoOhAIDroluo,19733
29
- fastled-1.2.5.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
30
- fastled-1.2.5.dist-info/entry_points.txt,sha256=RCwmzCSOS4-C2i9EziANq7Z2Zb4KFnEMR1FQC0bBwAw,101
31
- fastled-1.2.5.dist-info/top_level.txt,sha256=Bbv5kpJpZhWNCvDF4K0VcvtBSDMa8B7PTOrZa9CezHY,8
32
- fastled-1.2.5.dist-info/RECORD,,
27
+ fastled-1.2.7.dist-info/LICENSE,sha256=b6pOoifSXiUaz_lDS84vWlG3fr4yUKwB8fzkrH9R8bQ,1064
28
+ fastled-1.2.7.dist-info/METADATA,sha256=2BBOkJJEcFgY-aojh5RagyJHVwSIgLWKeGRof3bw5ms,20082
29
+ fastled-1.2.7.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
30
+ fastled-1.2.7.dist-info/entry_points.txt,sha256=RCwmzCSOS4-C2i9EziANq7Z2Zb4KFnEMR1FQC0bBwAw,101
31
+ fastled-1.2.7.dist-info/top_level.txt,sha256=Bbv5kpJpZhWNCvDF4K0VcvtBSDMa8B7PTOrZa9CezHY,8
32
+ fastled-1.2.7.dist-info/RECORD,,