{"id":29707286,"url":"https://github.com/davjcosby/sled","last_synced_at":"2025-07-23T17:08:50.250Z","repository":{"id":186662042,"uuid":"362951738","full_name":"DavJCosby/sled","owner":"DavJCosby","description":"Spatial LED: a library to help you get the coolest effects possible out of your bedroom LED strips.","archived":false,"fork":false,"pushed_at":"2024-12-18T01:35:13.000Z","size":45731,"stargazers_count":110,"open_issues_count":4,"forks_count":4,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-09T10:47:08.207Z","etag":null,"topics":["led-strips","raspberry-pi","rust","rust-lang"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DavJCosby.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2021-04-29T21:28:36.000Z","updated_at":"2025-04-09T00:22:30.000Z","dependencies_parsed_at":"2023-11-28T21:35:37.850Z","dependency_job_id":"4deeaaaa-370e-4302-8115-137467447171","html_url":"https://github.com/DavJCosby/sled","commit_stats":null,"previous_names":["davjcosby/slc"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/DavJCosby/sled","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DavJCosby%2Fsled","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DavJCosby%2Fsled/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DavJCosby%2Fsled/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DavJCosby%2Fsled/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DavJCosby","download_url":"https://codeload.github.com/DavJCosby/sled/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DavJCosby%2Fsled/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266717708,"owners_count":23973384,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-23T02:00:09.312Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["led-strips","raspberry-pi","rust","rust-lang"],"created_at":"2025-07-23T17:08:49.530Z","updated_at":"2025-07-23T17:08:50.234Z","avatar_url":"https://github.com/DavJCosby.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Crates.io](https://img.shields.io/crates/v/spatial_led.svg)](https://crates.io/crates/spatial_led)\n[![License](https://img.shields.io/badge/license-MIT%2FApache-blue.svg)](https://github.com/DavJCosby/sled#License)\n[![Docs](https://docs.rs/spatial_led/badge.svg)](https://docs.rs/spatial_led/latest/spatial_led/)\n[![Build and Run Tests](https://github.com/DavJCosby/sled/actions/workflows/rust.yml/badge.svg?branch=master)](https://github.com/DavJCosby/sled/actions/workflows/rust.yml)\n\n# Spatial LED (Sled)\n\u003cdiv\u003e \u003cimg src=\"https://github.com/DavJCosby/sled/blob/master/resources/ripples-demo.gif?raw=true\" width=\"49%\" title=\"cargo run --example ripples\"\u003e \u003cimg src=\"https://github.com/DavJCosby/sled/blob/master/resources/warpspeed-demo.gif?raw=true\" width=\"49%\" title=\"cargo run --example warpspeed\"\u003e\n \u003c/div\u003e\nSled is an ergonomic rust library that maps out the shape of your LED strips in 2D space to help you create stunning lighting effects.\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eWhat Sled does:\u003c/strong\u003e\u003c/summary\u003e\n\n- It exposes an API that lets you:\n\t- Compute colors depending on each LED's position, distance, direction, line segment, etc;\n\t- Output colors via a simple, contiguous iterator for your own usage;\n\t- Filter LEDs by spatial properties to predefine important sets and regions for faster computation;\n- Additionally, some tools are provided to help you build functional apps faster (you may opt-out via [compiler features](https://doc.rust-lang.org/cargo/reference/features.html)):\n\t- [Driver](#drivers) - Pack draw/compute logic into a Driver to simplify the process of swapping between effects, or changing effect settings at runtime. \n\t- [Scheduler](#scheduler) - Lightweight tool to schedule redraws at a fixed rate, powered by [spin_sleep](https://github.com/alexheretic/spin-sleep).\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\n\u003csummary\u003e\u003cstrong\u003eWhat Sled does \u003cins\u003enot\u003cins\u003e do:\u003c/strong\u003e\u003c/summary\u003e\n\n- It does not interface directly with your GPIO pins to control your LED hardware. Each project will be different, so it's up to you to bring your own glue. Check out the [Raspberry Pi example](https://github.com/DavJCosby/spatial_led_examples/tree/main/raspberry_pi) to get an idea what that might look like.\n- It does not allow you to represent your LEDs in 3D space. Could be a fun idea in the future, but it's just not planned for the time being.\n\n\u003c/details\u003e\n\nSee the [spatial_led_examples](https://github.com/DavJCosby/spatial_led_examples) repository for examples of Sled in action!\n\n\u003cdetails open\u003e\n\u003csummary\u003e\u003ch1\u003eThe Basics\u003c/h1\u003e\u003c/summary\u003e\n\nIn absence of an official guide, this will serve as a basic introduction. From here, you can consult the [docs](https://docs.rs/spatial_led/latest/spatial_led/) to learn what else Sled can do.\n\u003cdetails open\u003e\n\u003csummary\u003e\u003ch2\u003eSetup\u003c/h2\u003e\u003c/summary\u003e\n\nTo create a Sled struct, you need to create a configuration file and provide its path to the constructor:\n```rust\nuse spatial_led::\u003cSled, SledError\u003e;\nuse palette::rgb::Rgb;\nfn main() -\u003e Result\u003c(), SledError\u003e {\n    let mut sled = Sled::\u003cRgb\u003e::new(\"/path/to/config.yap\")?;\n    Ok(())\n}\n```\n\nA configuration file explains the layout of your LED strips in 2D space. This is used to pre-calculate some important information, speeding up complex draw calls.\n\n Example config file:\n ```\ncenter: (0.0, 0.5)\ndensity: 30.0\n--segments--\n(-2, 0) --\u003e (0.5, -1) --\u003e (3.5, 0) --\u003e\n(2, 2) --\u003e (-2, 2) --\u003e (-2, 0)\n ```\n \u003e For more information on how to write config files in this format, check out the [docs](https://docs.rs/spatial_led/latest/spatial_led/struct.Sled.html#method.new).\n\nNote the `::\u003cRgb\u003e` in the constructor. In previous versions of Sled, [palette's Rgb struct](https://docs.rs/palette/latest/palette/rgb/struct.Rgb.html) was used interally for all color computation. Now, the choice is 100% yours! You just have to specify what data type you'd like to use.\n\n```rust\n#[derive(Debug)]\nstruct RGBW {\n    r: f32,\n    g: f32,\n    b: f32,\n    w: f32\n}\nlet mut u8_sled = Sled::\u003c(u8, u8, u8)\u003e::new(\"/path/to/config.yap\")?;\nlet mut rgbw_sled = Sled::\u003cRGBW\u003e::new(\"/path/to/config.yap\")?;\n\nu8_sled.set(4, (255, 0, 0))?; // set 5th led to red\nrgbw_sled.set_all(RGBW {\n    r: 0.0,\n    g: 1.0,\n    b: 0.0,\n    w: 0.0\n});\n```\n\nFor all further examples we'll use palette's Rgb struct as our backing color format (we really do highly recommend it and encourage its use wherever it makes sense), but just know that you can use any data type that implements `Debug`, `Default`, and `Copy`.\n\n\u003c/details\u003e\n\n\u003cdetails open\u003e\n\u003csummary\u003e\u003ch2\u003eDrawing\u003c/h2\u003e\u003c/summary\u003e\n\nOnce you have your Sled struct, you can start drawing to it right away! Here’s a taste of some of the things Sled lets you do:\n\n**Set all vertices to white:**\n```rust\nsled.set_vertices(Rgb::new(1.0, 1.0, 1.0));\n```\n![Set all Vertices](resources/vertices.png)\n\u003e Note that this is a custom terminal UI visualization that is not packaged as part of the sled library. It is ultimately up to you to decide how to visualize your LEDs; Sled just handles the computation.\n\n**Set all LEDs 2 units away from the `center_point` to red:**\n```rust\nsled.set_at_dist(2.0, Rgb::new(1.0, 0.0, 0.0));\n// or relative to any other point using:\n// sled.set_at_dist_from(distance, pos, color)\n```\n\n![Set at Distance](resources/at_distance.png)\n\n**Set each LED using a function of its direction from point `(2, 1)`:**\n```rust\nsled.map_by_dir_from(Vec2::new(2.0, 1.0), |dir| {\n    let red = (dir.x + 1.0) * 0.5;\n    let green = (dir.y + 1.0) * 0.5;\n    Rgb::new(red, green, 0.5)\n});\n```\n![Map by Direction](resources/dir_map.png)\n\n**Dim one of the walls by 75%:**\n```rust\nsled.modulate_segment(3, |led| led.color * 0.25)?;\n```\n![Modulate Segment](resources/segment_modulate.png)\n\n**Set all LEDs within the overlapping areas of two different circles to blue:**\n```rust\nlet circle_1: Filter = sled.within_dist_from(\n    2.0,\n    Vec2::new(1.0, 0.5)\n);\n    \nlet circle_2: Filter = sled.within_dist_from(\n\t2.5,\n\tVec2::new(-1.0, 1.5)\n);\n\nlet overlap = circle_1.and(\u0026circle_2);\nsled.set_filter(\u0026overlap, Rgb::new(0.0, 0.0, 1.0));\n```\n![Set Overlapping Areas](resources/filter_and.png)\nFor more examples, see the documentation comments on the Sled struct.\n\n\u003c/details\u003e\n\n\u003cdetails open\u003e\n\u003csummary\u003e\u003ch2\u003eOutput\u003c/h2\u003e\u003c/summary\u003e\n\nOnce you’re ready to display these colors, you’ll probably want them packed in a nice contiguous array of RGB values. There are a few methods available to pack the information you need.\n\n```rust\nlet colors_f32 = sled.colors();\n// An Iterator of Rgbs, 32-bits/channel\n\nfor color in colors_f32 {\n    let red: f32 = color.red;\n    // -snip- //\n}\n```\n\nA few other handy output methods:\n```rust\nlet leds = sled.leds();\n// An Iterator of Led structs (holds color, position, distance/angle relative from center, etc)\n\nlet positions = sled.positions();\n// An Iterator of whatever type you chose to represent colors in.\n\nlet positions = sled.positions();\n// An Iterator of Vec2s, representing the position of each LED\n\nlet colors_and_positions = sled.colors_and_positions();\n// An Iterator of (COLOR_TYPE, Vec2) tuple pairs representing each LEDs color and position.\n```\n\u003c/details\u003e\n\u003c/details\u003e\n\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ch1\u003eAdvanced Features\u003c/h1\u003e\u003c/summary\u003e\n\nFor basic applications, the Sled struct gives you plenty of power. Odds are though, you'll want to create more advanced effects that might be time or user-input driven. A few optional (enabled by default, opt-out by disabling their compiler features) tools are provided to streamline that process.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ch2\u003eDrivers\u003c/h2\u003e\u003c/summary\u003e\n\nDrivers are useful for encapsulating everything you need to drive a lighting effect all in one place. Here's an example of what a simple one might look like:\n\n```rust\nlet mut driver = Driver::\u003cRgb\u003e::new(); // often auto-inferred\n\ndriver.set_startup_commands(|_sled, data| {\n    data.set::\u003cVec\u003cRgb\u003e\u003e(\"colors\", vec![\n        Rgb::new(1.0, 0.0, 0.0),\n        Rgb::new(0.0, 1.0, 0.0),\n        Rgb::new(0.0, 0.0, 1.0),\n    ]);\n    Ok(())\n});\n\ndriver.set_draw_commands(|sled, data, time| {\n    let elapsed = time.elapsed.as_secs_f32();\n    let colors = data.get::\u003cVec\u003cRgb\u003e\u003e(\"colors\")?;\n    let num_colors = colors.len();\n    // clear our canvas each frame\n    sled.set_all(Rgb::new(0.0, 0.0, 0.0));\n\n    for i in 0..num_colors {\n        let alpha = i as f32 / num_colors as f32;\n        let angle = elapsed + (2.0 * PI * alpha);\n        sled.set_at_angle(angle, colors[i]);\n    }\n    Ok(())\n});\n```\nTo start using the Driver, give it ownership over a Sled using `.mount()` and use `.step()` to manually refresh it.\n```rust\nlet sled = Sled::\u003cRgb\u003e::new(\"path/to/config.yap\")?;\ndriver.mount(sled); // sled gets moved into driver here.\n\nloop {\n    driver.step();\n    let colors = driver.colors();\n    // display those colors however you want\n}\n```\n![Basic Time-Driven Effect](resources/driver1.gif)\n\n\n`.set_startup_commands()` - Define a function or closure to run when `driver.mount()` is called. Grants mutable control over Sled and Data.\n\n`set_draw_commands()` - Define a function or closure to run every time `driver.step()` is called. Grants mutable control over Sled, and immutable access to Data and Time.\n\n`set_compute_commands()` - Define a function or closure to run every time `driver.step()` is called, scheduled right before draw commands. Grants immutable access to Sled and Time, and mutable control over Data.\n\nIf you need to retrieve ownership of your sled later, you can do:\n```rust\nlet sled = driver.dismount();\n```\n\n\u003e If you don't need Drivers for your project, you can shed a dependency or two by disabling the `drivers` compiler feature.\n\nFor more examples of ways to use drivers, see the [driver_examples folder](https://github.com/DavJCosby/spatial_led_examples/tree/main/driver_examples) in the spatial_led_examples repository.\n\n\n\u003cdetails open\u003e\n\u003csummary\u003e\u003ch3\u003e Driver Data \u003c/h3\u003e\u003c/summary\u003e\n\nA driver exposes a data structure called `Data`. This struct essentially acts as a HashMap of `\u0026str` keys to values of any type you choose to instantiate. This is particularly useful for passing important data and settings in to the effect.\n\nIt's best practice to first use startup commands to initialize your data, and then modify them either through compute commands or from outside the driver depending on your needs.\n\n```rust\nfn startup(sled: \u0026mut Sled, data: \u0026mut Data) -\u003e SledResult {\n    data.set::\u003cVec\u003cbool\u003e\u003e(\"wall_toggles\", vec![true, false, true]);\n    data.set::\u003cRgb\u003e(\"room_color\", Rgb::new(1.0, 0.0, 0.0));\n    data.set(\"important_data\", CustomDataType::new());\n    // the compiler can usually infer the data type\n    Ok(())\n}\n\ndriver.set_startup_commands(startup);\n```\n\nTo access driver data externally, just do:\n```rust\nlet data: \u0026Data = driver.data();\n// or\nlet data: \u0026mut Data = driver.data_mut();\n```\n\nUsing that data is relatively straightforward.\n```rust\nlet draw_commands = |sled, data, _time| {\n    let wall_toggles = data.get::\u003cVec\u003cbool\u003e\u003e(\"wall_toggles\")?;\n    let color = data.get::\u003cRgb\u003e(\"room_color\")?;\n    let important_data: \u0026CustomDataType = data.get(\"important_data\")?;\n\n    for i in 0..wall_toggles.len() {\n        if wall_toggles[i] == true {\n            sled.set_segment(i, *color)?;\n        } else {\n            sled.set_segment(i, Rgb::new(0.0, 0.0, 0.0))?;\n        }\n    }\n    \n    Ok(())\n}\n```\n\nIf you need to mutate data:\n```rust\n// Mutable reference to the whole vector\nlet walls_mut = data.get_mut::\u003cVec\u003cbool\u003e\u003e(\"wall_toggles\")?;\nwalls_mut[1] = true;\n```\n\u003c/details\u003e\n\n\u003cdetails open\u003e\n\u003csummary\u003e\u003ch3\u003eFilters\u003c/h3\u003e\u003c/summary\u003e\n\nFor exceptionally performance-sensitive scenarios, Filters can be used to predefine important LED regions. They act as sets, containing only the indicies of the LEDs captured in the set. When we want to perform an operation on that set, we pass the Filter back to the Sled like this:\n\n```rust\nlet all_due_north: Filter = sled.at_dir(Vec2::new(0.0, 1.0));\nsled.for_each_in_filter(\u0026all_due_north, |led| {\n    led.color = Rgb::new(1.0, 1.0, 1.0);\n});\n```\n\u003e Note that other methods exist like `.set_filter(filter, color)`, `.modulate_filter(filter, color_rule)`, and `.map_filter(filter, map)`\n\nOnce you've created a Filter, you can save it to `Data` for use in draw/compute stages. Using this pattern, we can pre-compute important sets at startup and then store them to the driver for later usage.\n\nA slightly better example would be to imagine that we have an incredibly expensive mapping function that will only have a visible impact on the LEDs within some radius $R$ from a given point $P$. Rather than checking the distance of each LED from that point every frame, we can instead do something like this:\n\n```rust\ndriver.set_startup_commands(|sled, data| {\n     let area: Filter = sled.within_dist_from(\n         5.0, Vec2::new(-0.25, 1.5)\n     );\n\n    data.set(\"area_of_effect\", area);\n     Ok(())\n });\n driver.set_draw_commands(|sled, data, _| {\n     let area_filter = data.get(\"area_of_effect\")?;\n     sled.map_filter(area_filter, |led| {\n         // expensive computation\n     });\n     Ok(())\n });\n```\nMost getter-type methods on sled will return a Filter, but if you need more precise control you can do something like this:\n```rust\nlet even_filter = sled.filter(|led| led.index() % 2 == 0);\n```\n\nLastly, Filters support a few basic boolean operations, which can be used to combine multiple filters in interesting ways. \n\n```rust\nlet circle_a = sled.within_dist_from(\n    5.0, Vec2::new(-0.25, 1.5)\n);\n\nlet circle_b = sled.within_dist_from(\n    4.0, Vec2::new(0.5, 0.5)\n);\n\nlet ab_overlap = circle_a.and(\u0026circle_b);\nlet ab_union = circle_a.or(\u0026circle_b);\n```\n\n\u003c/details\u003e\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ch2\u003eScheduler\u003c/h2\u003e\u003c/summary\u003e\n\nThe Scheduler struct makes it super easy to schedule redraws at a fixed rate.\n\n```rust\nlet mut scheduler = Scheduler::new(120.0);\n\nscheduler.loop_forever(|| {\n    driver.step();\n});\n```\nScheduler, by default, utilizes [spin_sleep](https://crates.io/crates/spin_sleep/) to minimize the high CPU usage you typically see when you spin to wait for the next update by default.\n\nHere are a few other methods that you might also consider:\n\n```rust\n// loops until false is returned\nscheduler.loop_while_true(|| {\n    // -snip- //\n    return true;\n});\n\n// loops until an error of any type is returned\nscheduler.loop_until_err(|| {\n    // -snip- //\n    Ok(())\n});\n\n// best for times when you don't want to pass everything through a closure\nloop {\n    // -snip- //\n    scheduler.sleep_until_next_frame();\n}\n```\nYou can define your own `CustomScheduler` backed by whatever sleeping method you prefer if you wish. If you'd like to trim away the `spin_sleep` dependency, you can also disable the `spin_sleep` feature flag.\n\nIf you don't need the Scheduler struct in general, you can disable the `scheduler` and `spin_sleep` flags.\n\n\u003c/details\u003e\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ch1\u003e\u003ccode\u003eno_std\u003c/code\u003e Support\u003c/h1\u003e\u003c/summary\u003e\n\nSpatial LED is now usable in `no_std` environments as of 0.2.0 (though `alloc` is still required), thanks to some [awesome contributions](https://github.com/DavJCosby/sled/pull/86) by [Claudio Mattera](https://github.com/claudiomattera).\n\nTo do this, disable the `std` flag and enable the `libm` flag (for use by glam).\n\nUsers on the nightly toolchain can also enable the `core-simd` feature flag for some extra performance if you know your target platform supports SIMD instructions.\n\n## Drivers\nThe default Driver implementation depends on `std::time::Instant` to track elapsed time between driver steps. For `no_std` environments, you must provide your own struct that implements the `crate::time::Instant` trait.\n\nOnce you have that, building a `CustomDriver` becomes as easy as:\n```rust\nuse spatial_led::driver::CustomDriver;\n\nlet mut driver = CustomDriver\u003cMyCustomInstant\u003e::new();\ndriver.mount(sled);\n```\n\n## Schedulers\nSimilarly, the default Scheduler relies on Instants, as well as methods only available through the standard library to handle sleeping. Thus, to build a Scheduler in `no_std` environments, you'll need to provide custom implementations of the `spatial_led::time::Instant` and `spatial_led::time::Sleeper` traits.\n\n```rust\nuse spatial_led::driver::CustomDriver;\n\nlet scheduler = CustomScheduler\u003cMyCustomInstant, MyCustomSleeper\u003e::new(120.0);\n\n scheduler.loop_forever(|| {\n     println!(\"tick!\");\n });\n ```\n\n As embassy is gaining popularity in the embedded Rust scene, Claudio has also provided an async interface via the `AsyncCustomScheduler` struct.\n\n ## Feedback and Contributions\n The author of this crate does not own any hardware that would allow him test `spatial_led` on real `no_std` environments, so bug reports and PRs are very appreciated!\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ch1\u003eFeature Flags\u003c/h1\u003e\u003c/summary\u003e\n\nEnabled by Default:\n- `std`\n- `drivers` : Enables Drivers\n- `scheduler` : Enables Schedulers\n- `spin_sleep` : If `std` is enabled, sets the default Scheduler to use [spin_sleep](https://crates.io/crates/spin_sleep) to schedule tasks.\n\nOpt-in:\n- `libm` : Needed for some `no_std` environments.\n- `core-simd` (Nightly) : Allows the vector math library used by the crate to take advantage of SIMD instructions when `std::simd` isn't available.\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ch1\u003eLicense\u003c/h1\u003e\u003c/summary\u003e\n\nLicensed under either of\n* Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)\n* MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)\n  \nat your option.\n\u003c/details\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavjcosby%2Fsled","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdavjcosby%2Fsled","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavjcosby%2Fsled/lists"}