<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://makerspace.cc/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=JaneParson</id>
	<title>Makerpedia - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://makerspace.cc/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=JaneParson"/>
	<link rel="alternate" type="text/html" href="https://makerspace.cc/Special:Contributions/JaneParson"/>
	<updated>2026-05-06T14:14:49Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.42.7</generator>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=DND_Whiteboard_Grid&amp;diff=9819</id>
		<title>DND Whiteboard Grid</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=DND_Whiteboard_Grid&amp;diff=9819"/>
		<updated>2026-02-10T17:54:30Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Simply download the template [https://drive.google.com/file/d/1qmBE-32nIOOMVXH5DTE3zcoOG3Z3oePv/view?usp=sharing HERE] and cut it on the back laser cutter using the &#039;medium density fiberboard&#039; setting.  &lt;br /&gt;
&lt;br /&gt;
Cut as many grid pieces as you like out of whiteboard, and make pegs to stick in using .2 inch thick wood, .2 inch across and .2 inch deep on the peg! &lt;br /&gt;
[[File:Photo of grid tiles in action..jpg|thumb]]&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=DND_Whiteboard_Grid&amp;diff=9818</id>
		<title>DND Whiteboard Grid</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=DND_Whiteboard_Grid&amp;diff=9818"/>
		<updated>2026-02-10T17:54:02Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: Created page with &amp;quot;Simply download the template [https://drive.google.com/file/d/1qmBE-32nIOOMVXH5DTE3zcoOG3Z3oePv/view?usp=sharing HERE] and cut it on the back laser cutter using the &amp;#039;medium density fiberboard setting. Cut as many grid pieces as you like out of whiteboard, and make pegs to stick in using .2 inch thick wood, .2 inch across and .2 inch deep on the peg!  thumb&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Simply download the template [https://drive.google.com/file/d/1qmBE-32nIOOMVXH5DTE3zcoOG3Z3oePv/view?usp=sharing HERE] and cut it on the back laser cutter using the &#039;medium density fiberboard setting. Cut as many grid pieces as you like out of whiteboard, and make pegs to stick in using .2 inch thick wood, .2 inch across and .2 inch deep on the peg! &lt;br /&gt;
[[File:Photo of grid tiles in action..jpg|thumb]]&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=File:Photo_of_grid_tiles_in_action..jpg&amp;diff=9817</id>
		<title>File:Photo of grid tiles in action..jpg</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=File:Photo_of_grid_tiles_in_action..jpg&amp;diff=9817"/>
		<updated>2026-02-10T17:49:37Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Photo of grid tiles in action. Walls are placed in the slats, and the base is a whiteboard that can be drawn on.&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Vertical_Mill&amp;diff=9627</id>
		<title>Vertical Mill</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Vertical_Mill&amp;diff=9627"/>
		<updated>2025-08-11T15:13:19Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;[https://docs.google.com/document/d/1is302Ng1zG3TQNPJhbKPeCzcgT9LHHvT/edit?tab=t.0 Before Use, Consult the Safety Check Sheet]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{{DISPLAYTITLE:Vertical Mill}}&lt;br /&gt;
[[CATEGORY:Tools]]&lt;br /&gt;
&amp;lt;div class=&#039;introBox&#039;&amp;gt;&lt;br /&gt;
=== Introduction to Milling Machines ===&lt;br /&gt;
While the milling machine may just look like a very complicated drill, its uses span much more than simply drilling very precise holes. The milling machine can be used to make holes, slots and grooves to a precision upwards of thousandths of an inch. Additionally, the Mill can be used to remove material allowing it to flatten and smooth out edges and surfaces. Milling machines are used to machine components made of metal or plastic.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{#Widget:yt|id=MYRDJN72oB8}}&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
[[File:Bridgeport Vertical Mill.jpg|alt=A photo of the Bridgeport vertical mill in the Student Machine Shop.|thumb|A photo of the Bridgeport vertical mill in the Student Machine Shop.]]&lt;br /&gt;
&lt;br /&gt;
== Terminology ==&lt;br /&gt;
# Motor&lt;br /&gt;
# Head&lt;br /&gt;
# Quill&lt;br /&gt;
# Spindle&lt;br /&gt;
# Table&lt;br /&gt;
# Ways&lt;br /&gt;
# Power feed&lt;br /&gt;
# Digital Readout (DRO)&lt;br /&gt;
# Traverse Crank Handle&lt;br /&gt;
# Motor Switch&lt;br /&gt;
# Knee&lt;br /&gt;
# Locks&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&#039;cautionBox&#039;&amp;gt;&lt;br /&gt;
== Safety Considerations ==&lt;br /&gt;
The main safety concerns on a Milling Machine are the rotating components driving the actual cutting, and the flying debris the cutting can create. The motor, drive belts, spindle, chuck and bit all pose pinch and entanglement hazards and the bit itself is sharp. While the motor and drive belts can and should be covered with proper guarding, the spindle, chuck and bit must be exposed for proper machine operation. Because of this, it is very important to tie back all loose clothing and hair and remove any jewelry that could increase the risk of entanglement in these spinning components. Additionally safety glasses are required to protect the eyes from flying chips or other debris.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== User Guide ==&lt;br /&gt;
Before starting a project with the Milling Machine, you must complete the safety training detailed above and consult with Aaron.&lt;br /&gt;
&lt;br /&gt;
Each time you use the Milling Machine you must follow the following checklists.&lt;br /&gt;
&lt;br /&gt;
===== Before use: =====&lt;br /&gt;
&lt;br /&gt;
* Ensure everything is in neutral position: x-axis feed off, spindle direction off, z-axis feed off.&lt;br /&gt;
* Check settings for your operation: Set belts, gearing, power feed speed, z feed stop.&lt;br /&gt;
* Turn on machine power (in rear of mill).&lt;br /&gt;
* Turn on work lighting.&lt;br /&gt;
* Position and fixture workpiece&lt;br /&gt;
* Zero the DRO with edge-finder.&lt;br /&gt;
* Install tooling&lt;br /&gt;
* Properly position work guarding&lt;br /&gt;
&lt;br /&gt;
===== After use: =====&lt;br /&gt;
&lt;br /&gt;
* Return fixturing to default&lt;br /&gt;
* Return milling head to 0-positions&lt;br /&gt;
* Return spindle to front gear&lt;br /&gt;
* Remove tooling and workpiece&lt;br /&gt;
* Clean work area of chips&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&#039;introBox&#039;&amp;gt;&lt;br /&gt;
== Manuals and Documentation ==&lt;br /&gt;
For more information on the use and maintenance of the Milling Machine, see the following resources:&lt;br /&gt;
&lt;br /&gt;
* [https://drive.google.com/open?id=11Q9A4iDZoSPqkcbESbzLrpqdZliBF9Bk Owner&#039;s Manual]&lt;br /&gt;
* [https://drive.google.com/open?id=1pZn_XVBgCeTslCcy01KqodApIv9ibADENAVybWCJdIE Tool Data Sheet]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;div class=&#039;introBox&amp;gt;&lt;br /&gt;
== Training videos and quiz ==&lt;br /&gt;
{{#Widget:yt|id=ytwHWrodt1U}}&lt;br /&gt;
&lt;br /&gt;
[https://forms.gle/Y1CaMKesJPCcezwE7 Click here to take the quiz.]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
[[Category:Machine Shop Tools]]&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Vertical_Bandsaw&amp;diff=9626</id>
		<title>Vertical Bandsaw</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Vertical_Bandsaw&amp;diff=9626"/>
		<updated>2025-08-11T15:03:56Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;[https://docs.google.com/document/d/1q929uBtNJGbk1Ryjktoar6UfoyyMS6em/edit?tab=t.0#heading=h.gjdgxs Before Use, Consult the Safety Check Sheet]&#039;&#039;&#039;&lt;br /&gt;
[[CATEGORY:Tools]]&lt;br /&gt;
[[File:Vertical Bandsaw.jpg|thumb]]&lt;br /&gt;
&lt;br /&gt;
== Introduction to the Band Saw ==&lt;br /&gt;
{{#Widget:yt|id=wrHBjSUa7lQ}}&lt;br /&gt;
&lt;br /&gt;
== Terminology ==&lt;br /&gt;
&lt;br /&gt;
== Safety Considerations ==&lt;br /&gt;
&lt;br /&gt;
== User Guide ==&lt;br /&gt;
Before starting a project with the Drill Press, you must complete the safety training detailed above and consult with Aaron.&lt;br /&gt;
&lt;br /&gt;
Each time you use the Drill Press you must follow the following checklists.&lt;br /&gt;
&lt;br /&gt;
===== Before Use =====&lt;br /&gt;
&lt;br /&gt;
* Turn on work lighting&lt;br /&gt;
* Set guard height as low as possible&lt;br /&gt;
* Ensure guide blocks are contacting blade&lt;br /&gt;
* Set table tilt as necessary&lt;br /&gt;
* Fixture small work-pieces in clamp&lt;br /&gt;
* Turn on machine power&lt;br /&gt;
* Set feed rate&lt;br /&gt;
&lt;br /&gt;
===== After use =====&lt;br /&gt;
&lt;br /&gt;
* Reset table tilt&lt;br /&gt;
* Clean workspace of chips&lt;br /&gt;
* Turn off work lighting&lt;br /&gt;
&lt;br /&gt;
== Manuals and Documentation ==&lt;br /&gt;
For more information on the use and maintenance of the Band Saw, see the following resources:&lt;br /&gt;
&lt;br /&gt;
* [https://drive.google.com/open?id=1cHNldQ37PiTtHKSHMyfLGtk-p6YDLZQRIKlfgzwRMeQ Tool Data Sheet]&lt;br /&gt;
* [https://drive.google.com/open?id=1_tp9yvU4MtslA-ES8egcHCgqSNnbhSxX Owner&#039;s Manual]&lt;br /&gt;
[[Category:Machine Shop Tools]]&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=TRAK_DPM2_Mill&amp;diff=9625</id>
		<title>TRAK DPM2 Mill</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=TRAK_DPM2_Mill&amp;diff=9625"/>
		<updated>2025-08-11T15:03:20Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;[https://docs.google.com/document/d/1is302Ng1zG3TQNPJhbKPeCzcgT9LHHvT/edit?tab=t.0 Before Use, Consult the Safety Check Sheet]&#039;&#039;&#039;[[File:TRAK DPM2 Mill.jpg|alt=A photo of the TRAK DPM2 mill in the Instrument Shop.|thumb|A photo of the TRAK DPM2 mill in the Instrument Shop.]]&lt;br /&gt;
The TRAK DPM2 Mill is located in the Instrument Shop.&lt;br /&gt;
[[Category:Tools]]&lt;br /&gt;
[[Category:Instrument Shop Tools]]&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=TIG_Welder&amp;diff=9624</id>
		<title>TIG Welder</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=TIG_Welder&amp;diff=9624"/>
		<updated>2025-08-11T15:01:52Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;[https://docs.google.com/document/d/1_qjIn3VyxVKDM2mYrTmbQ4eHXo8VX3In/edit?tab=t.0 Before Use, Consult the Safety Check Sheet]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;DO NOT USE THIS TOOL WITHOUT TRAINING FROM CARLETON AFILLIATED INSTRUCTORS&#039;&#039;&#039;[[File:Miller Synchrowave 250 TIG Welder.jpg|alt=A photo of the Miller Synchrowave 250 TIG welder in the Instrument Shop.|thumb|A photo of the Miller Synchrowave 250 TIG welder in the Instrument Shop.]]&lt;br /&gt;
The Miller Synchrowave 250 TIG welder is located in the Instrument Shop.&lt;br /&gt;
[[Category:Tools]]&lt;br /&gt;
[[Category:Instrument Shop Tools]]&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=TIG_Welder&amp;diff=9623</id>
		<title>TIG Welder</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=TIG_Welder&amp;diff=9623"/>
		<updated>2025-08-11T15:01:04Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;[https://docs.google.com/document/d/1B207QdyrW1AerIea9pF_y1QUyMAfWFtD/edit?tab=t.0 Before Use, Consult the Safety Check Sheet]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;DO NOT USE THIS TOOL WITHOUT TRAINING FROM CARLETON AFILLIATED INSTRUCTORS&#039;&#039;&#039;[[File:Miller Synchrowave 250 TIG Welder.jpg|alt=A photo of the Miller Synchrowave 250 TIG welder in the Instrument Shop.|thumb|A photo of the Miller Synchrowave 250 TIG welder in the Instrument Shop.]]&lt;br /&gt;
The Miller Synchrowave 250 TIG welder is located in the Instrument Shop.&lt;br /&gt;
[[Category:Tools]]&lt;br /&gt;
[[Category:Instrument Shop Tools]]&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=SawStop_ICS31230-36&amp;diff=9622</id>
		<title>SawStop ICS31230-36</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=SawStop_ICS31230-36&amp;diff=9622"/>
		<updated>2025-08-11T14:57:49Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:SawStop ICS31230-36 Table Saw .jpg|alt=A photo of the SawStop ICS31230-36 table saw in the Wood Shop.|thumb|A photo of the SawStop ICS31230-36 table saw in the Wood Shop.]]&lt;br /&gt;
&#039;&#039;&#039;[https://docs.google.com/document/d/1swoX9bzl-2xkQjqm1mr4BK7yZx4HblAK/edit?tab=t.0 Before Use, Consult the Safety Check Sheet]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The SawStop ICS31230-36 table saw is located in the Wood Shop.&lt;br /&gt;
[[Category:Tools]]&lt;br /&gt;
[[Category:Wood Shop Tools]]&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Milwaukee_6480-20&amp;diff=9621</id>
		<title>Milwaukee 6480-20</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Milwaukee_6480-20&amp;diff=9621"/>
		<updated>2025-08-11T14:47:45Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;[https://docs.google.com/document/d/1ERGMIVY9BFtj77y3cbFPn8qvR7bxnRTO/edit?tab=t.0 Before Use, Consult the Safety Check Sheet]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The Milwaukee 6480-20 panel saw is located in the Wood Shop.&lt;br /&gt;
[[File:Milwaukee 6480-20 Panel Saw.jpg|alt=A photo of the Milwaukee 6480-20 panel saw in the Wood Shop.|thumb|A photo of the Milwaukee 6480-20 panel saw in the Wood Shop.]]&lt;br /&gt;
[[Category:Tools]]&lt;br /&gt;
[[Category:Wood Shop Tools]]&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=MIG_Welder&amp;diff=9620</id>
		<title>MIG Welder</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=MIG_Welder&amp;diff=9620"/>
		<updated>2025-08-11T14:45:46Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;[https://docs.google.com/document/d/1B207QdyrW1AerIea9pF_y1QUyMAfWFtD/edit?tab=t.0 Before Use, Consult the Safety Check Sheet]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;DO NOT USE THIS TOOL WITHOUT TRAINING FROM CARLETON AFILLIATED INSTRUCTORS&#039;&#039;&#039;[[File:Miller Millermatic 252 MIG Welder.jpg|alt=A photo of the Miller Millermatic 252 MIG Welder in the Instrument Shop.|thumb|A photo of the Miller Millermatic 252 MIG Welder in the Instrument Shop.]]&lt;br /&gt;
The Miller Millermatic 252 MIG Welder is located in the Instrument Shop.&lt;br /&gt;
[[Category:Tools]]&lt;br /&gt;
[[Category:Instrument Shop Tools]]&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Metalworking_Lathes&amp;diff=9619</id>
		<title>Metalworking Lathes</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Metalworking_Lathes&amp;diff=9619"/>
		<updated>2025-08-11T14:37:16Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[CATEGORY:Tools]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[https://docs.google.com/document/d/1mqP2QI9Afz7ZTww-LfN5ZqqYVE1arMqa/edit?tab=t.0 Before Use, Consult the Safety Check Sheet]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{{#Widget:yt|id=ScBOSpDT5D4}}&lt;br /&gt;
&lt;br /&gt;
== Introduction to the Lathe ==&lt;br /&gt;
[[File:Enco 110-2079.jpg|alt=A photo of the Enco 110-2079 lathe in the Student Machine Shop.|thumb|A photo of the Enco 110-2079 lathe in the Student Machine Shop.]]&lt;br /&gt;
&lt;br /&gt;
[[File:Smithy Granite 1324.jpg|alt=A photo of the Smithy Granite 1324 lathe in the Student Machine Shop.|thumb|A photo of the Smithy Granite 1324 lathe in the Student Machine Shop.]]&lt;br /&gt;
&lt;br /&gt;
The Lathe Machine allows for the creation of rotationally symmetric parts such as shafts, standoffs, or parts with variable diameter, and features such as groves, threading or bearing nests. Lathe Machines should be used with metal or plastic stock that is nominally rotationally symmetrical.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Terminology ==&lt;br /&gt;
Bed&lt;br /&gt;
&lt;br /&gt;
Carriage&lt;br /&gt;
&lt;br /&gt;
Ways&lt;br /&gt;
&lt;br /&gt;
Feed Shaft&lt;br /&gt;
&lt;br /&gt;
Head Stock&lt;br /&gt;
&lt;br /&gt;
Spindle&lt;br /&gt;
&lt;br /&gt;
Chuck&lt;br /&gt;
&lt;br /&gt;
Tail Stock&lt;br /&gt;
&lt;br /&gt;
Tool Post&lt;br /&gt;
&lt;br /&gt;
== Safety Considerations ==&lt;br /&gt;
&lt;br /&gt;
== User Guide ==&lt;br /&gt;
Before Starting a Project on a Lathe Machine, you must complete the safety training detailed above and consult with Aaron.&lt;br /&gt;
&lt;br /&gt;
Each time you use the Lathe Machine you must follow the following checklists:&lt;br /&gt;
&lt;br /&gt;
===== Before use =====&lt;br /&gt;
&lt;br /&gt;
* Ensure ways are clear of debris&lt;br /&gt;
* Ensure sled is clear of rotating jaws&lt;br /&gt;
* Unlock all axies/make sure they are moving smoothly&lt;br /&gt;
* Ensure tail stock is retracted&lt;br /&gt;
* Fixture work-piece in jaws or collet DO NOT LEAVE CHUCK KEY IN MACHINE&lt;br /&gt;
* Set power feed as necessary&lt;br /&gt;
* Set spindle speed&lt;br /&gt;
* Position cutter on the tool post or tail stock, ensure it is locked in place&lt;br /&gt;
* Turn on work lighting&lt;br /&gt;
* Lock x-axis if necessary&lt;br /&gt;
* Position work guarding&lt;br /&gt;
* Disengage E-stop&lt;br /&gt;
* Turn on machine power&lt;br /&gt;
* Engage spindle clutch&lt;br /&gt;
&lt;br /&gt;
===== After use =====&lt;br /&gt;
&lt;br /&gt;
* Disengage spindle clutch, turn off machine power.&lt;br /&gt;
* Lift guarding&lt;br /&gt;
* Remove work-piece&lt;br /&gt;
* Engage E-stop&lt;br /&gt;
* Turn off work lighting&lt;br /&gt;
* Remove and put away tooling&lt;br /&gt;
* Clean work space of chips&lt;br /&gt;
&lt;br /&gt;
== Manuals and Documentation ==&lt;br /&gt;
For more information on the use and maintenance of the Lathe Machines see the following resources:&lt;br /&gt;
&lt;br /&gt;
ENCO Lathe:&lt;br /&gt;
&lt;br /&gt;
* [https://drive.google.com/open?id=1iHGNDiItr3neaGk_t5ug7SLdShAaV25x1lxbRNVMiF8 Tool Data Sheet]&lt;br /&gt;
* [https://drive.google.com/open?id=0BwN_k1g_K7NddWlUcEhRZDhXQzZ6MXlwVXpNUmR5bUFJeXp3 Owner&#039;s Manual]&lt;br /&gt;
* [https://drive.google.com/open?id=0BwN_k1g_K7NdN0RQWDdJR0h3M2JVWDBWVkFfMXlkV1dISHNn Part List]&lt;br /&gt;
&lt;br /&gt;
Smithy Lathe:&lt;br /&gt;
&lt;br /&gt;
* [https://drive.google.com/open?id=1DWgZN_2brvPzybIewCuglMI4asaomEVnUZ09H_rNJ-0 Tool Data Sheet]&lt;br /&gt;
* [https://drive.google.com/open?id=1bB0R1p0gJuPKjxbSeZdMrMZVDBILa6J4 Owner&#039;s Manual]&lt;br /&gt;
* [https://docs.google.com/document/d/1mqP2QI9Afz7ZTww-LfN5ZqqYVE1arMqa/edit?tab=t.0 Safety Check Sheet]&lt;br /&gt;
[[Category:Machine Shop Tools]]&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Horizontal_Bandsaw&amp;diff=9618</id>
		<title>Horizontal Bandsaw</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Horizontal_Bandsaw&amp;diff=9618"/>
		<updated>2025-08-11T14:36:20Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;[https://docs.google.com/document/d/1qs-HVt2Dm_L4mgqAncnmIfyjGVMaBsK4/edit?tab=t.0 Before Use, Consult the Safety Check Sheet]&#039;&#039;&#039;&lt;br /&gt;
[[CATEGORY:Tools]]&lt;br /&gt;
[[File:Ellis.jpg|thumb]]&lt;br /&gt;
&lt;br /&gt;
== Introduction to the Band Saw ==&lt;br /&gt;
{{#Widget:yt|id=A3p03UKkqXQ}}&lt;br /&gt;
&lt;br /&gt;
== Terminology ==&lt;br /&gt;
&lt;br /&gt;
== Safety Considerations ==&lt;br /&gt;
&lt;br /&gt;
== User Guide ==&lt;br /&gt;
Before starting a project with the Horizontal Band Saw, you must complete the safety training detailed above and consult with Aaron.&lt;br /&gt;
&lt;br /&gt;
Each time you use the Horizontal Band Saw you must follow the following checklists.&lt;br /&gt;
&lt;br /&gt;
===== Before use =====&lt;br /&gt;
&lt;br /&gt;
* Ensure bed is free of chips&lt;br /&gt;
* Position work on bed&lt;br /&gt;
* Set work-piece guides as necessary&lt;br /&gt;
* Set miter angle as necessary&lt;br /&gt;
* Position clamp on work piece and fixture piece&lt;br /&gt;
* Adjust blade guides if necessary&lt;br /&gt;
* Ensure E-stop is disengaged&lt;br /&gt;
* Position blade near work-piece&lt;br /&gt;
* Turn on machine power&lt;br /&gt;
* Set down feed rate&lt;br /&gt;
&lt;br /&gt;
===== After use =====&lt;br /&gt;
&lt;br /&gt;
* Reset miter angle to 0 degrees&lt;br /&gt;
* Clear chips from bed&lt;br /&gt;
* Discard unusably short scrap&lt;br /&gt;
&lt;br /&gt;
== Manuals and Documentation ==&lt;br /&gt;
&lt;br /&gt;
* [https://drive.google.com/open?id=1_FNq0K-_5BH6pichPBqoZh0gQ6xKuj97pPTVApX3eb4 Tool Data Sheet]&lt;br /&gt;
* [https://drive.google.com/open?id=1XluxY8ZuUMfXifsqNU_ZtYYxQ8K10cte Owner&#039;s Manual]&lt;br /&gt;
[[Category:Machine Shop Tools]]&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Harrison_Lathe&amp;diff=9617</id>
		<title>Harrison Lathe</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Harrison_Lathe&amp;diff=9617"/>
		<updated>2025-08-11T14:34:19Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;[https://docs.google.com/document/d/1mqP2QI9Afz7ZTww-LfN5ZqqYVE1arMqa/edit?tab=t.0 Before Use, Consult the Safety Check Sheet]&#039;&#039;&#039;[[File:Harrison Lathe.jpg|alt=A photo of the Harrison lathe in the Instrument Shop.|thumb|A photo of the Harrison lathe in the Instrument Shop.]]&lt;br /&gt;
The Harrison lathe is located in the Instrument Shop.&lt;br /&gt;
[[Category:Tools]]&lt;br /&gt;
[[Category:Instrument Shop Tools]]&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Hardinge_Toolroom_Lathe&amp;diff=9616</id>
		<title>Hardinge Toolroom Lathe</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Hardinge_Toolroom_Lathe&amp;diff=9616"/>
		<updated>2025-08-11T14:33:55Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;[https://docs.google.com/document/d/1mqP2QI9Afz7ZTww-LfN5ZqqYVE1arMqa/edit?tab=t.0 Before Use, Consult the Safety Check Sheet]&#039;&#039;&#039;[[File:Hardinge Toolroom Lathe.jpg|alt=A photo of the Hardinge Toolroom lathe in the Instrument Shop.|thumb|A photo of the Hardinge Toolroom lathe in the Instrument Shop.]]&lt;br /&gt;
The Hardinge Toolroom lathe is located in the Instrument Shop.&lt;br /&gt;
[[Category:Tools]]&lt;br /&gt;
[[Category:Instrument Shop Tools]]&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Drill_Press&amp;diff=9615</id>
		<title>Drill Press</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Drill_Press&amp;diff=9615"/>
		<updated>2025-08-11T14:32:11Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: /* Manuals and Documentation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[CATEGORY:Tools]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[https://docs.google.com/document/d/1Y-5kPmlW4v0Dxaty6ous9aWc-i_B8EUJ/edit?tab=t.0 Before Use, Consult the Safety Check Sheet]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{{#Widget:yt|id=DVAXD4sY-eU}}&lt;br /&gt;
&lt;br /&gt;
== Introduction to the Drill Press ==&lt;br /&gt;
[[File:Drill Press.jpg|thumb|A photo of the Powermatic drill press in the Wood Shop.]]&lt;br /&gt;
[[File:Enco Drill Press.jpg|alt=A photo of the Enco drill press in the Student Machine Shop.|thumb|A photo of the Enco drill press in the Student Machine Shop.]]&lt;br /&gt;
The Drill Press is similar to a Hand Drill, but is much more repeatable. Like the hand drill, the Drill Press is used to make holes in plastic or metal, but the drill press automatically ensures that the hole is straight vertically, and vises and clamping jigs allow work to be held securely and safely.&lt;br /&gt;
&lt;br /&gt;
== Terminology ==&lt;br /&gt;
Motor&lt;br /&gt;
&lt;br /&gt;
Speed Adjustment handle&lt;br /&gt;
&lt;br /&gt;
Vertical Handle&lt;br /&gt;
&lt;br /&gt;
Spindle&lt;br /&gt;
&lt;br /&gt;
Chuck&lt;br /&gt;
&lt;br /&gt;
Table&lt;br /&gt;
&lt;br /&gt;
Vice&lt;br /&gt;
&lt;br /&gt;
== Safety Considerations ==&lt;br /&gt;
&lt;br /&gt;
== User Guide ==&lt;br /&gt;
Before starting a project using the Drill Press, you must complete the safety training detailed above and consult with Aaron.&lt;br /&gt;
&lt;br /&gt;
Each time you use the Milling Machine you must follow the following checklists.&lt;br /&gt;
&lt;br /&gt;
===== Before use =====&lt;br /&gt;
&lt;br /&gt;
* Fixture work-piece&lt;br /&gt;
* Secure bit in chuck&lt;br /&gt;
* Align piece to bit and lock in fixturing&lt;br /&gt;
* Ensure proper cutting fluid is available&lt;br /&gt;
* Ensure proper position of vertical stop&lt;br /&gt;
* Adjust bed height as necessary&lt;br /&gt;
* Ensure bed is locked&lt;br /&gt;
* Turn on machine&lt;br /&gt;
* Adjust speed to proper settings based on bit size and workpiece material&lt;br /&gt;
&lt;br /&gt;
===== After use =====&lt;br /&gt;
&lt;br /&gt;
* Remove pit and workpiece&lt;br /&gt;
* Clean up excess cutting fluid&lt;br /&gt;
* Remove chips from the workspace&lt;br /&gt;
&lt;br /&gt;
== Manuals and Documentation ==&lt;br /&gt;
For more information on the use and maintenance of the Drill Press, see the following resources:&lt;br /&gt;
&lt;br /&gt;
* [https://drive.google.com/open?id=1iq8EqGFErKn4d5dm2l04s-W4O8HvmY-r Owner&#039;s Manual]&lt;br /&gt;
* [https://drive.google.com/open?id=1WweS3qproqfQ1ZY83HtveZpsWn6DiLGBo4oYdsuoOJc Tool Data Sheet]&lt;br /&gt;
* [https://docs.google.com/document/d/1Y-5kPmlW4v0Dxaty6ous9aWc-i_B8EUJ/edit?tab=t.0 Safety Check Sheet]&lt;br /&gt;
[[Category:Wood Shop Tools]]&lt;br /&gt;
[[Category:Machine Shop Tools]]&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Drill_Press&amp;diff=9614</id>
		<title>Drill Press</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Drill_Press&amp;diff=9614"/>
		<updated>2025-08-11T14:30:42Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[CATEGORY:Tools]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[https://docs.google.com/document/d/1Y-5kPmlW4v0Dxaty6ous9aWc-i_B8EUJ/edit?tab=t.0 Before Use, Consult the Safety Check Sheet]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{{#Widget:yt|id=DVAXD4sY-eU}}&lt;br /&gt;
&lt;br /&gt;
== Introduction to the Drill Press ==&lt;br /&gt;
[[File:Drill Press.jpg|thumb|A photo of the Powermatic drill press in the Wood Shop.]]&lt;br /&gt;
[[File:Enco Drill Press.jpg|alt=A photo of the Enco drill press in the Student Machine Shop.|thumb|A photo of the Enco drill press in the Student Machine Shop.]]&lt;br /&gt;
The Drill Press is similar to a Hand Drill, but is much more repeatable. Like the hand drill, the Drill Press is used to make holes in plastic or metal, but the drill press automatically ensures that the hole is straight vertically, and vises and clamping jigs allow work to be held securely and safely.&lt;br /&gt;
&lt;br /&gt;
== Terminology ==&lt;br /&gt;
Motor&lt;br /&gt;
&lt;br /&gt;
Speed Adjustment handle&lt;br /&gt;
&lt;br /&gt;
Vertical Handle&lt;br /&gt;
&lt;br /&gt;
Spindle&lt;br /&gt;
&lt;br /&gt;
Chuck&lt;br /&gt;
&lt;br /&gt;
Table&lt;br /&gt;
&lt;br /&gt;
Vice&lt;br /&gt;
&lt;br /&gt;
== Safety Considerations ==&lt;br /&gt;
&lt;br /&gt;
== User Guide ==&lt;br /&gt;
Before starting a project using the Drill Press, you must complete the safety training detailed above and consult with Aaron.&lt;br /&gt;
&lt;br /&gt;
Each time you use the Milling Machine you must follow the following checklists.&lt;br /&gt;
&lt;br /&gt;
===== Before use =====&lt;br /&gt;
&lt;br /&gt;
* Fixture work-piece&lt;br /&gt;
* Secure bit in chuck&lt;br /&gt;
* Align piece to bit and lock in fixturing&lt;br /&gt;
* Ensure proper cutting fluid is available&lt;br /&gt;
* Ensure proper position of vertical stop&lt;br /&gt;
* Adjust bed height as necessary&lt;br /&gt;
* Ensure bed is locked&lt;br /&gt;
* Turn on machine&lt;br /&gt;
* Adjust speed to proper settings based on bit size and workpiece material&lt;br /&gt;
&lt;br /&gt;
===== After use =====&lt;br /&gt;
&lt;br /&gt;
* Remove pit and workpiece&lt;br /&gt;
* Clean up excess cutting fluid&lt;br /&gt;
* Remove chips from the workspace&lt;br /&gt;
&lt;br /&gt;
== Manuals and Documentation ==&lt;br /&gt;
For more information on the use and maintenance of the Drill Press, see the following resources:&lt;br /&gt;
&lt;br /&gt;
* [https://drive.google.com/open?id=1iq8EqGFErKn4d5dm2l04s-W4O8HvmY-r Owner&#039;s Manual]&lt;br /&gt;
* [https://drive.google.com/open?id=1WweS3qproqfQ1ZY83HtveZpsWn6DiLGBo4oYdsuoOJc Tool Data Sheet]&lt;br /&gt;
[[Category:Wood Shop Tools]]&lt;br /&gt;
[[Category:Machine Shop Tools]]&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=DeWalt_DW735&amp;diff=9613</id>
		<title>DeWalt DW735</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=DeWalt_DW735&amp;diff=9613"/>
		<updated>2025-08-11T14:29:39Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;[https://docs.google.com/document/d/1daj10iXFdVGF2Jcv5UEsTTg8snI9x3_f/edit?tab=t.0 Before Use, Consult the Safety Check Sheet]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The DeWalt DW735 planer is located in the Wood Shop.&lt;br /&gt;
[[File:DeWalt DW735 Planer.jpg|alt=A photo of the DeWalt DW735 planer in the Wood Shop.|thumb|A photo of the DeWalt DW735 planer in the Wood Shop.]]&lt;br /&gt;
[[Category:Tools]]&lt;br /&gt;
[[Category:Wood Shop Tools]]&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Bosch_CM10GD_Miter_Saw&amp;diff=9612</id>
		<title>Bosch CM10GD Miter Saw</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Bosch_CM10GD_Miter_Saw&amp;diff=9612"/>
		<updated>2025-08-11T14:26:16Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;[https://docs.google.com/document/d/1g-NBUAodj-Q81Zl-Jq8RW0aYNwMWGbWi/edit?tab=t.0 Before Use, Consult the Safety Check Sheet]&#039;&#039;&#039;&lt;br /&gt;
*[[File:Bosch CM10GD Compact Miter Saw.jpg|alt=A photo of the Bosch CM10GD compact miter saw in the Wood Shop.|thumb|A photo of the Bosch CM10GD compact miter saw in the Wood Shop.]]&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Standard Operating Procedure for the Bosch CM10GD Miter Saw&#039;&#039;&#039;&lt;br /&gt;
*# &#039;&#039;&#039;Safety Precautions&#039;&#039;&#039;&lt;br /&gt;
*#* Before using the miter saw, read and understand the owner&#039;s manual.&lt;br /&gt;
*#* Always wear safety glasses when operating the miter saw.&lt;br /&gt;
*#* Make sure the work surface is stable and level.&lt;br /&gt;
*#* Clamp the workpiece securely to the work surface.&lt;br /&gt;
*#* Do not overreach when operating the miter saw.&lt;br /&gt;
*#* Keep bystanders away from the work area.&lt;br /&gt;
*# &#039;&#039;&#039;Operating the Miter Saw&#039;&#039;&#039;&lt;br /&gt;
*#* Turn on the miter saw and allow it to reach full speed.&lt;br /&gt;
*#* Set the desired cutting angle and blade size.&lt;br /&gt;
*#* Place the workpiece against the fence and align the blade with the cutting line.&lt;br /&gt;
*#* Slowly lower the blade until it makes contact with the workpiece.&lt;br /&gt;
*#* Apply light pressure to the workpiece and slowly feed it through the blade.&lt;br /&gt;
*#* Raise the blade and turn off the miter saw.&lt;br /&gt;
*# &#039;&#039;&#039;Maintenance and Storage&#039;&#039;&#039;&lt;br /&gt;
*#* After each use, clean the miter saw with a dry cloth.&lt;br /&gt;
*#* Inspect the miter saw for any damage.&lt;br /&gt;
*#* If necessary, replace worn or damaged parts.&lt;br /&gt;
*#* Store the miter saw in a cool, dry place.&lt;br /&gt;
*# &#039;&#039;&#039;Troubleshooting&#039;&#039;&#039;&lt;br /&gt;
*#* If the miter saw is not working properly, refer to the owner&#039;s manual for troubleshooting tips.&lt;br /&gt;
*#* If you are unable to troubleshoot the problem, contact a qualified service technician.&lt;br /&gt;
[[Category:Tools]]&lt;br /&gt;
[[Category:Wood Shop Tools]]&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Belt_Sander&amp;diff=9611</id>
		<title>Belt Sander</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Belt_Sander&amp;diff=9611"/>
		<updated>2025-08-11T14:23:00Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Dayton Belt Sander.jpg|alt=A photo of the Dayton Belt Sander in the Wood Shop.|thumb|A photo of the Dayton Belt Sander in the Wood Shop.]]&lt;br /&gt;
The Dayton belt sander is located in the Wood Shop.&lt;br /&gt;
&lt;br /&gt;
[https://docs.google.com/document/d/1EEww1xYzphcUlJdphHGt8UdLONc5v_rP/edit?tab=t.0 &#039;&#039;&#039;Before Use, Consult the Safety Check Sheet&#039;&#039;&#039;]&lt;br /&gt;
[[Category:Tools]]&lt;br /&gt;
[[Category:Wood Shop Tools]]&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Clamp_lab&amp;diff=9608</id>
		<title>Clamp lab</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Clamp_lab&amp;diff=9608"/>
		<updated>2025-08-05T20:21:52Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Clamp Lab serves as an onboarding tutorial for physics students to learn and understand the Makerspace Shop. Through making a metal clamp out of aluminum and brass, participants use many of the tools in the shop, with tutorials on their function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{#Widget:yt|id=A3p03UKkqXQ}}&lt;br /&gt;
&lt;br /&gt;
{{#Widget:yt|id=wrHBjSUa7lQ}}&lt;br /&gt;
&lt;br /&gt;
{{#Widget:yt|id=MYRDJN72oB8}}&lt;br /&gt;
&lt;br /&gt;
{{#Widget:yt|id=DVAXD4sY-eU}}&lt;br /&gt;
&lt;br /&gt;
{{#Widget:yt|id=ScBOSpDT5D4}}&lt;br /&gt;
&lt;br /&gt;
{{#Widget:yt|id=C6hD1LjHM_E}}&lt;br /&gt;
&lt;br /&gt;
{{#Widget:yt|id=WAaviuBKZNw}}&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Clamp_lab&amp;diff=9604</id>
		<title>Clamp lab</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Clamp_lab&amp;diff=9604"/>
		<updated>2025-07-28T17:10:04Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{#Widget:yt|id=A3p03UKkqXQ}}&lt;br /&gt;
&lt;br /&gt;
{{#Widget:yt|id=wrHBjSUa7lQ}}&lt;br /&gt;
&lt;br /&gt;
{{#Widget:yt|id=MYRDJN72oB8}}&lt;br /&gt;
&lt;br /&gt;
{{#Widget:yt|id=DVAXD4sY-eU}}&lt;br /&gt;
&lt;br /&gt;
{{#Widget:yt|id=ScBOSpDT5D4}}&lt;br /&gt;
&lt;br /&gt;
{{#Widget:yt|id=C6hD1LjHM_E}}&lt;br /&gt;
&lt;br /&gt;
{{#Widget:yt|id=WAaviuBKZNw}}&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Clamp_lab&amp;diff=9603</id>
		<title>Clamp lab</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Clamp_lab&amp;diff=9603"/>
		<updated>2025-07-28T17:07:13Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: Created page with &amp;quot;{{#Widget:yt|id=PLzwHzUOjEDnKAKxzoSyGt2Vix_X-2U8m4}}&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{#Widget:yt|id=PLzwHzUOjEDnKAKxzoSyGt2Vix_X-2U8m4}}&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Metalworking_Lathes&amp;diff=9602</id>
		<title>Metalworking Lathes</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Metalworking_Lathes&amp;diff=9602"/>
		<updated>2025-07-28T17:00:55Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[CATEGORY:Tools]]&lt;br /&gt;
&lt;br /&gt;
{{#Widget:yt|id=ScBOSpDT5D4}}&lt;br /&gt;
&lt;br /&gt;
== Introduction to the Lathe ==&lt;br /&gt;
[[File:Enco 110-2079.jpg|alt=A photo of the Enco 110-2079 lathe in the Student Machine Shop.|thumb|A photo of the Enco 110-2079 lathe in the Student Machine Shop.]]&lt;br /&gt;
&lt;br /&gt;
[[File:Smithy Granite 1324.jpg|alt=A photo of the Smithy Granite 1324 lathe in the Student Machine Shop.|thumb|A photo of the Smithy Granite 1324 lathe in the Student Machine Shop.]]&lt;br /&gt;
&lt;br /&gt;
The Lathe Machine allows for the creation of rotationally symmetric parts such as shafts, standoffs, or parts with variable diameter, and features such as groves, threading or bearing nests. Lathe Machines should be used with metal or plastic stock that is nominally rotationally symmetrical.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Terminology ==&lt;br /&gt;
Bed&lt;br /&gt;
&lt;br /&gt;
Carriage&lt;br /&gt;
&lt;br /&gt;
Ways&lt;br /&gt;
&lt;br /&gt;
Feed Shaft&lt;br /&gt;
&lt;br /&gt;
Head Stock&lt;br /&gt;
&lt;br /&gt;
Spindle&lt;br /&gt;
&lt;br /&gt;
Chuck&lt;br /&gt;
&lt;br /&gt;
Tail Stock&lt;br /&gt;
&lt;br /&gt;
Tool Post&lt;br /&gt;
&lt;br /&gt;
== Safety Considerations ==&lt;br /&gt;
&lt;br /&gt;
== User Guide ==&lt;br /&gt;
Before Starting a Project on a Lathe Machine, you must complete the safety training detailed above and consult with Aaron.&lt;br /&gt;
&lt;br /&gt;
Each time you use the Lathe Machine you must follow the following checklists:&lt;br /&gt;
&lt;br /&gt;
===== Before use =====&lt;br /&gt;
&lt;br /&gt;
* Ensure ways are clear of debris&lt;br /&gt;
* Ensure sled is clear of rotating jaws&lt;br /&gt;
* Unlock all axies/make sure they are moving smoothly&lt;br /&gt;
* Ensure tail stock is retracted&lt;br /&gt;
* Fixture work-piece in jaws or collet DO NOT LEAVE CHUCK KEY IN MACHINE&lt;br /&gt;
* Set power feed as necessary&lt;br /&gt;
* Set spindle speed&lt;br /&gt;
* Position cutter on the tool post or tail stock, ensure it is locked in place&lt;br /&gt;
* Turn on work lighting&lt;br /&gt;
* Lock x-axis if necessary&lt;br /&gt;
* Position work guarding&lt;br /&gt;
* Disengage E-stop&lt;br /&gt;
* Turn on machine power&lt;br /&gt;
* Engage spindle clutch&lt;br /&gt;
&lt;br /&gt;
===== After use =====&lt;br /&gt;
&lt;br /&gt;
* Disengage spindle clutch, turn off machine power.&lt;br /&gt;
* Lift guarding&lt;br /&gt;
* Remove work-piece&lt;br /&gt;
* Engage E-stop&lt;br /&gt;
* Turn off work lighting&lt;br /&gt;
* Remove and put away tooling&lt;br /&gt;
* Clean work space of chips&lt;br /&gt;
&lt;br /&gt;
== Manuals and Documentation ==&lt;br /&gt;
For more information on the use and maintenance of the Lathe Machines see the following resources:&lt;br /&gt;
&lt;br /&gt;
ENCO Lathe:&lt;br /&gt;
&lt;br /&gt;
* [https://drive.google.com/open?id=1iHGNDiItr3neaGk_t5ug7SLdShAaV25x1lxbRNVMiF8 Tool Data Sheet]&lt;br /&gt;
* [https://drive.google.com/open?id=0BwN_k1g_K7NddWlUcEhRZDhXQzZ6MXlwVXpNUmR5bUFJeXp3 Owner&#039;s Manual]&lt;br /&gt;
* [https://drive.google.com/open?id=0BwN_k1g_K7NdN0RQWDdJR0h3M2JVWDBWVkFfMXlkV1dISHNn Part List]&lt;br /&gt;
&lt;br /&gt;
Smithy Lathe:&lt;br /&gt;
&lt;br /&gt;
* [https://drive.google.com/open?id=1DWgZN_2brvPzybIewCuglMI4asaomEVnUZ09H_rNJ-0 Tool Data Sheet]&lt;br /&gt;
* [https://drive.google.com/open?id=1bB0R1p0gJuPKjxbSeZdMrMZVDBILa6J4 Owner&#039;s Manual]&lt;br /&gt;
[[Category:Machine Shop Tools]]&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Drill_Press&amp;diff=9601</id>
		<title>Drill Press</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Drill_Press&amp;diff=9601"/>
		<updated>2025-07-28T16:59:46Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[CATEGORY:Tools]]&lt;br /&gt;
&lt;br /&gt;
{{#Widget:yt|id=DVAXD4sY-eU}}&lt;br /&gt;
&lt;br /&gt;
== Introduction to the Drill Press ==&lt;br /&gt;
[[File:Drill Press.jpg|thumb|A photo of the Powermatic drill press in the Wood Shop.]]&lt;br /&gt;
[[File:Enco Drill Press.jpg|alt=A photo of the Enco drill press in the Student Machine Shop.|thumb|A photo of the Enco drill press in the Student Machine Shop.]]&lt;br /&gt;
The Drill Press is similar to a Hand Drill, but is much more repeatable. Like the hand drill, the Drill Press is used to make holes in plastic or metal, but the drill press automatically ensures that the hole is straight vertically, and vises and clamping jigs allow work to be held securely and safely.&lt;br /&gt;
&lt;br /&gt;
== Terminology ==&lt;br /&gt;
Motor&lt;br /&gt;
&lt;br /&gt;
Speed Adjustment handle&lt;br /&gt;
&lt;br /&gt;
Vertical Handle&lt;br /&gt;
&lt;br /&gt;
Spindle&lt;br /&gt;
&lt;br /&gt;
Chuck&lt;br /&gt;
&lt;br /&gt;
Table&lt;br /&gt;
&lt;br /&gt;
Vice&lt;br /&gt;
&lt;br /&gt;
== Safety Considerations ==&lt;br /&gt;
&lt;br /&gt;
== User Guide ==&lt;br /&gt;
Before starting a project using the Drill Press, you must complete the safety training detailed above and consult with Aaron.&lt;br /&gt;
&lt;br /&gt;
Each time you use the Milling Machine you must follow the following checklists.&lt;br /&gt;
&lt;br /&gt;
===== Before use =====&lt;br /&gt;
&lt;br /&gt;
* Fixture work-piece&lt;br /&gt;
* Secure bit in chuck&lt;br /&gt;
* Align piece to bit and lock in fixturing&lt;br /&gt;
* Ensure proper cutting fluid is available&lt;br /&gt;
* Ensure proper position of vertical stop&lt;br /&gt;
* Adjust bed height as necessary&lt;br /&gt;
* Ensure bed is locked&lt;br /&gt;
* Turn on machine&lt;br /&gt;
* Adjust speed to proper settings based on bit size and workpiece material&lt;br /&gt;
&lt;br /&gt;
===== After use =====&lt;br /&gt;
&lt;br /&gt;
* Remove pit and workpiece&lt;br /&gt;
* Clean up excess cutting fluid&lt;br /&gt;
* Remove chips from the workspace&lt;br /&gt;
&lt;br /&gt;
== Manuals and Documentation ==&lt;br /&gt;
For more information on the use and maintenance of the Drill Press, see the following resources:&lt;br /&gt;
&lt;br /&gt;
* [https://drive.google.com/open?id=1iq8EqGFErKn4d5dm2l04s-W4O8HvmY-r Owner&#039;s Manual]&lt;br /&gt;
* [https://drive.google.com/open?id=1WweS3qproqfQ1ZY83HtveZpsWn6DiLGBo4oYdsuoOJc Tool Data Sheet]&lt;br /&gt;
[[Category:Wood Shop Tools]]&lt;br /&gt;
[[Category:Machine Shop Tools]]&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Horizontal_Bandsaw&amp;diff=9600</id>
		<title>Horizontal Bandsaw</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Horizontal_Bandsaw&amp;diff=9600"/>
		<updated>2025-07-28T16:58:54Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: /* Introduction to the Band Saw */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[CATEGORY:Tools]]&lt;br /&gt;
[[File:Ellis.jpg|thumb]]&lt;br /&gt;
&lt;br /&gt;
== Introduction to the Band Saw ==&lt;br /&gt;
{{#Widget:yt|id=A3p03UKkqXQ}}&lt;br /&gt;
&lt;br /&gt;
== Terminology ==&lt;br /&gt;
&lt;br /&gt;
== Safety Considerations ==&lt;br /&gt;
&lt;br /&gt;
== User Guide ==&lt;br /&gt;
Before starting a project with the Horizontal Band Saw, you must complete the safety training detailed above and consult with Aaron.&lt;br /&gt;
&lt;br /&gt;
Each time you use the Horizontal Band Saw you must follow the following checklists.&lt;br /&gt;
&lt;br /&gt;
===== Before use =====&lt;br /&gt;
&lt;br /&gt;
* Ensure bed is free of chips&lt;br /&gt;
* Position work on bed&lt;br /&gt;
* Set work-piece guides as necessary&lt;br /&gt;
* Set miter angle as necessary&lt;br /&gt;
* Position clamp on work piece and fixture piece&lt;br /&gt;
* Adjust blade guides if necessary&lt;br /&gt;
* Ensure E-stop is disengaged&lt;br /&gt;
* Position blade near work-piece&lt;br /&gt;
* Turn on machine power&lt;br /&gt;
* Set down feed rate&lt;br /&gt;
&lt;br /&gt;
===== After use =====&lt;br /&gt;
&lt;br /&gt;
* Reset miter angle to 0 degrees&lt;br /&gt;
* Clear chips from bed&lt;br /&gt;
* Discard unusably short scrap&lt;br /&gt;
&lt;br /&gt;
== Manuals and Documentation ==&lt;br /&gt;
&lt;br /&gt;
* [https://drive.google.com/open?id=1_FNq0K-_5BH6pichPBqoZh0gQ6xKuj97pPTVApX3eb4 Tool Data Sheet]&lt;br /&gt;
* [https://drive.google.com/open?id=1XluxY8ZuUMfXifsqNU_ZtYYxQ8K10cte Owner&#039;s Manual]&lt;br /&gt;
[[Category:Machine Shop Tools]]&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Vertical_Mill&amp;diff=9599</id>
		<title>Vertical Mill</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Vertical_Mill&amp;diff=9599"/>
		<updated>2025-07-28T16:58:07Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:Vertical Mill}}&lt;br /&gt;
[[CATEGORY:Tools]]&lt;br /&gt;
&amp;lt;div class=&#039;introBox&#039;&amp;gt;&lt;br /&gt;
=== Introduction to Milling Machines ===&lt;br /&gt;
While the milling machine may just look like a very complicated drill, its uses span much more than simply drilling very precise holes. The milling machine can be used to make holes, slots and grooves to a precision upwards of thousandths of an inch. Additionally, the Mill can be used to remove material allowing it to flatten and smooth out edges and surfaces. Milling machines are used to machine components made of metal or plastic.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{#Widget:yt|id=MYRDJN72oB8}}&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
[[File:Bridgeport Vertical Mill.jpg|alt=A photo of the Bridgeport vertical mill in the Student Machine Shop.|thumb|A photo of the Bridgeport vertical mill in the Student Machine Shop.]]&lt;br /&gt;
&lt;br /&gt;
== Terminology ==&lt;br /&gt;
# Motor&lt;br /&gt;
# Head&lt;br /&gt;
# Quill&lt;br /&gt;
# Spindle&lt;br /&gt;
# Table&lt;br /&gt;
# Ways&lt;br /&gt;
# Power feed&lt;br /&gt;
# Digital Readout (DRO)&lt;br /&gt;
# Traverse Crank Handle&lt;br /&gt;
# Motor Switch&lt;br /&gt;
# Knee&lt;br /&gt;
# Locks&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&#039;cautionBox&#039;&amp;gt;&lt;br /&gt;
== Safety Considerations ==&lt;br /&gt;
The main safety concerns on a Milling Machine are the rotating components driving the actual cutting, and the flying debris the cutting can create. The motor, drive belts, spindle, chuck and bit all pose pinch and entanglement hazards and the bit itself is sharp. While the motor and drive belts can and should be covered with proper guarding, the spindle, chuck and bit must be exposed for proper machine operation. Because of this, it is very important to tie back all loose clothing and hair and remove any jewelry that could increase the risk of entanglement in these spinning components. Additionally safety glasses are required to protect the eyes from flying chips or other debris.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== User Guide ==&lt;br /&gt;
Before starting a project with the Milling Machine, you must complete the safety training detailed above and consult with Aaron.&lt;br /&gt;
&lt;br /&gt;
Each time you use the Milling Machine you must follow the following checklists.&lt;br /&gt;
&lt;br /&gt;
===== Before use: =====&lt;br /&gt;
&lt;br /&gt;
* Ensure everything is in neutral position: x-axis feed off, spindle direction off, z-axis feed off.&lt;br /&gt;
* Check settings for your operation: Set belts, gearing, power feed speed, z feed stop.&lt;br /&gt;
* Turn on machine power (in rear of mill).&lt;br /&gt;
* Turn on work lighting.&lt;br /&gt;
* Position and fixture workpiece&lt;br /&gt;
* Zero the DRO with edge-finder.&lt;br /&gt;
* Install tooling&lt;br /&gt;
* Properly position work guarding&lt;br /&gt;
&lt;br /&gt;
===== After use: =====&lt;br /&gt;
&lt;br /&gt;
* Return fixturing to default&lt;br /&gt;
* Return milling head to 0-positions&lt;br /&gt;
* Return spindle to front gear&lt;br /&gt;
* Remove tooling and workpiece&lt;br /&gt;
* Clean work area of chips&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&#039;introBox&#039;&amp;gt;&lt;br /&gt;
== Manuals and Documentation ==&lt;br /&gt;
For more information on the use and maintenance of the Milling Machine, see the following resources:&lt;br /&gt;
&lt;br /&gt;
* [https://drive.google.com/open?id=11Q9A4iDZoSPqkcbESbzLrpqdZliBF9Bk Owner&#039;s Manual]&lt;br /&gt;
* [https://drive.google.com/open?id=1pZn_XVBgCeTslCcy01KqodApIv9ibADENAVybWCJdIE Tool Data Sheet]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;div class=&#039;introBox&amp;gt;&lt;br /&gt;
== Training videos and quiz ==&lt;br /&gt;
{{#Widget:yt|id=ytwHWrodt1U}}&lt;br /&gt;
&lt;br /&gt;
[https://forms.gle/Y1CaMKesJPCcezwE7 Click here to take the quiz.]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
[[Category:Machine Shop Tools]]&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Vertical_Bandsaw&amp;diff=9598</id>
		<title>Vertical Bandsaw</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Vertical_Bandsaw&amp;diff=9598"/>
		<updated>2025-07-28T16:57:28Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: /* Introduction to the Band Saw */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[CATEGORY:Tools]]&lt;br /&gt;
[[File:Vertical Bandsaw.jpg|thumb]]&lt;br /&gt;
&lt;br /&gt;
== Introduction to the Band Saw ==&lt;br /&gt;
{{#Widget:yt|id=wrHBjSUa7lQ}}&lt;br /&gt;
&lt;br /&gt;
== Terminology ==&lt;br /&gt;
&lt;br /&gt;
== Safety Considerations ==&lt;br /&gt;
&lt;br /&gt;
== User Guide ==&lt;br /&gt;
Before starting a project with the Drill Press, you must complete the safety training detailed above and consult with Aaron.&lt;br /&gt;
&lt;br /&gt;
Each time you use the Drill Press you must follow the following checklists.&lt;br /&gt;
&lt;br /&gt;
===== Before Use =====&lt;br /&gt;
&lt;br /&gt;
* Turn on work lighting&lt;br /&gt;
* Set guard height as low as possible&lt;br /&gt;
* Ensure guide blocks are contacting blade&lt;br /&gt;
* Set table tilt as necessary&lt;br /&gt;
* Fixture small work-pieces in clamp&lt;br /&gt;
* Turn on machine power&lt;br /&gt;
* Set feed rate&lt;br /&gt;
&lt;br /&gt;
===== After use =====&lt;br /&gt;
&lt;br /&gt;
* Reset table tilt&lt;br /&gt;
* Clean workspace of chips&lt;br /&gt;
* Turn off work lighting&lt;br /&gt;
&lt;br /&gt;
== Manuals and Documentation ==&lt;br /&gt;
For more information on the use and maintenance of the Band Saw, see the following resources:&lt;br /&gt;
&lt;br /&gt;
* [https://drive.google.com/open?id=1cHNldQ37PiTtHKSHMyfLGtk-p6YDLZQRIKlfgzwRMeQ Tool Data Sheet]&lt;br /&gt;
* [https://drive.google.com/open?id=1_tp9yvU4MtslA-ES8egcHCgqSNnbhSxX Owner&#039;s Manual]&lt;br /&gt;
[[Category:Machine Shop Tools]]&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Glowforge_Pro&amp;diff=9597</id>
		<title>Glowforge Pro</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Glowforge_Pro&amp;diff=9597"/>
		<updated>2025-07-28T16:56:11Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Makerspace has a Glowforge Pro laser cutter machine. &lt;br /&gt;
&lt;br /&gt;
{{#Widget:yt|id=9TAkUx6DiN8}}&lt;br /&gt;
&lt;br /&gt;
==== How to Prepare Files ====&lt;br /&gt;
[[File:Glowforge Pro Laser Cutter.jpg|alt=A photo of the Glowforge Pro Laser Cutter in the Makerspace.|thumb|A photo of the Glowforge Pro laser cutter in the Makerspace.]]&lt;br /&gt;
&lt;br /&gt;
# Open Adobe Illustrator and create a new document.&lt;br /&gt;
# Set the document size to match the size of the work area of the laser (11&amp;quot;x19&amp;quot;).&lt;br /&gt;
# Design your project using any shapes, text, or images you like.&lt;br /&gt;
# Once you are finished designing, select all objects of the same operation type (ie, cutting, engraving, etching) and go to Object &amp;gt; Group to group them together.&lt;br /&gt;
# Next, you need to convert your design to an SVG file. To do this, go to File &amp;gt; Export &amp;gt; Export As.&lt;br /&gt;
# In the Export As window, select SVG (.svg) from the Format dropdown menu.&lt;br /&gt;
# Click Export and save your file to your computer.&lt;br /&gt;
&lt;br /&gt;
==== How to Use a Glowforge Pro Laser Cutter ====&lt;br /&gt;
&lt;br /&gt;
# Place your material on the Glowforge bed and secure it with masking tape or honeycomb pins.&lt;br /&gt;
# Open the [https://app.glowforge.com/ Glowforge app] and upload your SVG file.&lt;br /&gt;
# Select the appropriate settings for your material and project.&lt;br /&gt;
# Press the small remote on top of the laser cutter to turn on air filtration.&lt;br /&gt;
# Click the Print button to start cutting.&lt;br /&gt;
&lt;br /&gt;
==== Additional tips for using Adobe Illustrator ====&lt;br /&gt;
&lt;br /&gt;
* Use hairlines for all of your cut lines. Hairlines are the thinnest stroke weight in Illustrator and will produce the cleanest cuts.&lt;br /&gt;
* Make sure that all of your objects are closed paths. If an object is not a closed path, the laser will not be able to cut it correctly.&lt;br /&gt;
* If you are cutting text, make sure that it is converted to outlines. To do this, select the text and go to Type &amp;gt; Create Outlines.&lt;br /&gt;
* If you are engraving an image, make sure that it is converted to grayscale. To do this, select the image and go to Image &amp;gt; Mode &amp;gt; Grayscale.&lt;br /&gt;
&lt;br /&gt;
==== Additional tips for using the Glowforge Pro ====&lt;br /&gt;
&lt;br /&gt;
* Always wear safety glasses when operating the laser cutter.&lt;br /&gt;
* Clean the laser bed after each use to remove any residue.&lt;br /&gt;
* Never leave the laser cutter unattended while it is in operation.&lt;br /&gt;
&lt;br /&gt;
== Laser Cart Reservations ==&lt;br /&gt;
This cart can be reserved for Curricular and Workshop use. Please use [https://calendar.google.com/calendar/u/0/appointments/schedules/AcZssZ1-vPlqj_oNaDHiYwhOFlrtxbSPYq47mOHy3rKk3J1610r5GhaaIVRLE2VTK740tHNkFTvo424G this calendar] to make a reservation.&lt;br /&gt;
[[Category:Tools]]&lt;br /&gt;
[[Category:Makerspace Tools]]&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Button_Maker&amp;diff=9596</id>
		<title>Button Maker</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Button_Maker&amp;diff=9596"/>
		<updated>2025-07-28T16:54:56Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Button Makers.jpg|alt=A photo of the button makers in the Makerspace.|thumb|A photo of the button makers in the Makerspace.]]&lt;br /&gt;
A button maker is a large metal tool used to press together the individual portions of a button.&lt;br /&gt;
&lt;br /&gt;
{{#Widget:yt|id=83CKYkWvBk8}}&lt;br /&gt;
&lt;br /&gt;
== HOW TO USE THE BUTTON MAKER ==&lt;br /&gt;
&lt;br /&gt;
== Step 1: Create design ==&lt;br /&gt;
&lt;br /&gt;
# To start, create a circular design either 1&amp;quot; or 3&amp;quot; (Depending on the button press you&#039;ve chosen)&lt;br /&gt;
## &#039;&#039;&#039;Make sure to put important information in the centre of your design!&#039;&#039;&#039; The edges will be cut off.&lt;br /&gt;
# Print this design out in a grid formation on standard letter paper.&lt;br /&gt;
## Or be fancy with it and make them shiny or something. I&#039;m not your mom.&lt;br /&gt;
# Then, cut them out using one of the button punchers stored in the &amp;quot;Pin Making&amp;quot; box (Bottom Rightmost in the shelves)[[File:Button Cutter.png|thumb|A button being cut from a sheet]]&lt;br /&gt;
&lt;br /&gt;
== Step 2: Make the Button. ==&lt;br /&gt;
&lt;br /&gt;
# Your final button should consist of four parts. Make sure they&#039;re the same size!&lt;br /&gt;
## The plastic pin backing.&lt;br /&gt;
## The metal shell&lt;br /&gt;
## Your paper design&lt;br /&gt;
## The plastic protection&lt;br /&gt;
# Place the metal shell in the left chamber of the button press.&lt;br /&gt;
# Place your design and the plastic protection on top of that.&lt;br /&gt;
## KCHUNK IT, BABY!&lt;br /&gt;
# Place your plastic back in the right chamber&lt;br /&gt;
## KCHUNK IT AGAIN!&lt;br /&gt;
# Enjoy your delightful new button.&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
[[File:Button Press.jpg|thumb|The button press, prepared on the left]]&lt;br /&gt;
[[File:Button Parts.jpg|thumb|From left to right - The plastic back, the metal shell, the paper design, and the plastic protective sheet.]]&lt;br /&gt;
[[Button Maker Tutorial|Button Maker Tutorial - Makerpedia (makerspace.cc)]]&lt;br /&gt;
[[Category:Projects]]&lt;br /&gt;
[[Category:Button Pressing]]&lt;br /&gt;
[[Category:Tools]]&lt;br /&gt;
[[Category:Makerspace Tools]]&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Kitchen_Lithography&amp;diff=9595</id>
		<title>Kitchen Lithography</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Kitchen_Lithography&amp;diff=9595"/>
		<updated>2025-07-28T16:53:39Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Kitchen Litho Jar Example.jpg|alt=A sketchily drawn print of a jar of olives|thumb|184x184px|An example of a print using pencil]]&lt;br /&gt;
Kitchen Lithography is a type of printmaking that is a nontoxic and more accessible alternative to traditional lithography. It uses cola to etch aluminum foil, and a [[Reprovisioned Press]] to do the actual printing.  &lt;br /&gt;
&lt;br /&gt;
{{#Widget:yt|id=gOkVfEeHrMA}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Supplies:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
* Coca-Cola (or any other cola)&lt;br /&gt;
* Heavy duty aluminum foil&lt;br /&gt;
* Some sort of plate to wrap foil around&lt;br /&gt;
* Oil based ink (Litho or etching ink)&lt;br /&gt;
* Optional: Magnesium carbonate or cornstarch to stiffen ink&lt;br /&gt;
* Plexiglass to roll out ink&lt;br /&gt;
* Brayer&lt;br /&gt;
* Paintbrush&lt;br /&gt;
* Sharpie (or pastels, crayons, pencil, fingers, anything oily/waxy)&lt;br /&gt;
* Sponge/paper towels&lt;br /&gt;
* Printing press (or a wooden spoon or another brayer)&lt;br /&gt;
* Paper&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Preparing the plate:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
First, you need to wrap your foil around the plate. It is very important that you do not touch the dull side of the foil even with gloved hands. The dull side of the foil should face outward on the plate as this is what you will draw on. Getting the plate slightly damp makes the foil stick to the plate as you wrap the sides around. Tape also works but water does the job just as well with less hassle.  &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Drawing your image:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Next, you have to draw your image with sharpie or anything oily or waxy. You can even add fingerprints. Remember that the final image will be mirrored so any text has to be backwards. If you are using sharpie, wait a minute or two for it to dry.  &lt;br /&gt;
&lt;br /&gt;
[[File:Kitchen litho drawing options.jpg|alt=Kitchen litho print showing the different mark-making options: sharpie, crayon, oil pastel, 8B pencil, HB pencil, fingerprints. Sharpie is the darkest and the pencils are the lightest.|none|thumb|351x351px|Material options for drawing on your plate]]&lt;br /&gt;
[[File:Kitchen litho jar drawing on plate.jpg|alt=A pencil drawing of an olive jar on the foil plate|none|thumb|249x249px|A pencil drawing on the foil plate]] &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Etching:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Prepare a bath of coca-cola. Submerge your plate in it. When the cola is fresh it will only need a few seconds but it might start needing more time as you use the cola. While the plate is still in the bath, use the paintbrush to very gently go across the whole surface of the plate. This ensures that the cola etches everywhere you want it. Take the plate out of the cola and rinse it off a few times with water. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Inking:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Roll out a slab of ink on the plexiglass with the brayer. For better results, thicken the ink by adding about 1/3 cornstarch or magnesium carbonate to the ink by volume. The ink should have a velvet texture. If it looks like an orange peel it is too thick. Next, wipe down your plate with a damp paper towel or sponge. It shouldn&#039;t be dripping but there should be water everywhere. You can tell because when the foil is slightly wet it is a lighter color. Quickly, before it dries, ink up the plate a couple times. Then add more water and then more ink and repeat quite a few times until the ink has built up. The first print will likely be pretty light and then you can go back and add more ink and they will get darker. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Printing:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To use the [[Reprovisioned Press|Makerspace printing press]], make sure that there are enough boards or sheets of paper raising the surface of the bed of the press so that when you place your plate down, it is level with the edge. Place your paper over your plate and then a piece of felt, and then roll the roller over your print. There should be enough pressure that you need to use a little effort to get the roller over the plate but not so much that the wood of the roller bends. &lt;br /&gt;
[[Category:Printmaking]]&lt;br /&gt;
[[Category:Projects]]&lt;br /&gt;
[[Category:Crafting]]&lt;br /&gt;
[[Category:SimpleProjects]]&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=3D_Scanner&amp;diff=9593</id>
		<title>3D Scanner</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=3D_Scanner&amp;diff=9593"/>
		<updated>2025-07-23T21:32:23Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:Peel 2 3D Scanner}}&lt;br /&gt;
[[Category:Tools]]&lt;br /&gt;
[[File:Peel 2 3D Scanner.jpg|alt=A photo of the Peel 2 3D scanner in the Makerspace.|thumb|A photo of the Peel 2 3D scanner in the Makerspace.]]&lt;br /&gt;
{{#Widget:yt|id=Jvokv3pA58Y}}&lt;br /&gt;
[[Category:Projects]]&lt;br /&gt;
[[Category:3D Modeling]]&lt;br /&gt;
[[Category:Makerspace Tools]]&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Nomai_Mask_-_EVA_foam_(Project_0057)&amp;diff=9592</id>
		<title>Nomai Mask - EVA foam (Project 0057)</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Nomai_Mask_-_EVA_foam_(Project_0057)&amp;diff=9592"/>
		<updated>2025-07-23T21:08:46Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;small&amp;gt;by Jane Parson&amp;lt;/small&amp;gt;&lt;br /&gt;
-----&lt;br /&gt;
__NOTOC__&lt;br /&gt;
{{DISPLAYTITLE:Nomai Mask - EVA foam}}&lt;br /&gt;
[[Category:Projects|Nomai Mask - EVA foam]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&#039;overview&#039;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Project Overview ==&lt;br /&gt;
&lt;br /&gt;
Making a foam mask using makerspace materials, following online tutorials&lt;br /&gt;
&lt;br /&gt;
{{#widget:gallery|img1=https://drive.google.com/thumbnail?id=18yR8_0-d-lWCkUR8RRQ5svG5aoCPnN10&amp;amp;sz=w1000|img2=https://drive.google.com/thumbnail?id=1KqPLc89MDbz66cIfMbN49_AstTQR23bW&amp;amp;sz=w1000|img3=https://drive.google.com/thumbnail?id=1Qujc3sXUgBEmneQU_66JsTRfiuYjWxVU&amp;amp;sz=w1000|img4=https://drive.google.com/thumbnail?id=1CVl6ONSYFjMs9LPQKpUSlCwA4JlzbW8B&amp;amp;sz=w1000|img5=https://drive.google.com/thumbnail?id=1waPAiUTIM5Xm_5dDSDiHJaD1G0ec3uTX&amp;amp;sz=w1000|num=6}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tools and Materials ==&lt;br /&gt;
* &#039;&#039;&#039;MATERIALS&#039;&#039;&#039;&lt;br /&gt;
** Structure&lt;br /&gt;
*** EVA Foam (6mm)&lt;br /&gt;
*** Insulation Foam (24mm)&lt;br /&gt;
** Paint&lt;br /&gt;
*** Gold / Bronze Airbrush&lt;br /&gt;
*** Black Primer&lt;br /&gt;
*** Grey Airbrush&lt;br /&gt;
*** Sandstone Airbrush (Acrylic with thinner works)&lt;br /&gt;
** Glues&lt;br /&gt;
*** Hot Glue&lt;br /&gt;
*** Contact Cement&lt;br /&gt;
** Electronics&lt;br /&gt;
*** 3 x Blue LEDS&lt;br /&gt;
*** 9v dock&lt;br /&gt;
*** Power Switch&lt;br /&gt;
*** 1000 ohm resistor.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;files&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Project Files==&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&#039;sxs&#039;&amp;gt;&lt;br /&gt;
== Step-by-Step Instructions ==&lt;br /&gt;
&lt;br /&gt;
{{#widget:ProjectStep|inst=Download / Print Image Reference - At https://www.punishedprops.com/2021/02/08/nomai-mask/, download the pdf files and print them out.|show=none|src=none}}&lt;br /&gt;
{{#widget:ProjectStep|inst=Cut out your foam-&lt;br /&gt;
This tutorial uses 4, 8, 12, and 24 mm EVA foam. The makerspace exclusively uses 6 mm, so convert 4 and 8 to 6, and glue two layers together for 12. For 24, insulator foam sheets in the repair layer serve well (though they degrade on contact with hot glue, contact cement, and paint! Be warbed.)&lt;br /&gt;
&lt;br /&gt;
To bend the fins, blast with a hot air gun, then bend and hold- they&#039;ll warp into place. Additionally, you can mark the edges of the hexagon patterns with an exacto knife, to paint later. DON&#039;T USE THE HOT KNIFE HERE, it&#039;s too deep. Using the hot knife to smooth edges works well, though. |show=none|src=none}}&lt;br /&gt;
{{#widget:ProjectStep|inst=GLUE FOAM&lt;br /&gt;
glue your foam together using contact cement- paint both sides of the joint, let it air dry for 5-10 minutes, then stick them together. This instantly welds the materials, keeping them stuck. For the fins, hot glue might be necessary. At this point, you can also use a dremel to buzz down any edges or bumps.|show=none|src=none}}&lt;br /&gt;
{{#widget:ProjectStep|inst=PAINTING&lt;br /&gt;
&lt;br /&gt;
To paint the mask, you&#039;ll need patience. Lots of it- our airbrush is finnicky and slow, and you&#039;ll need many coats. if you&#039;re using acryllic in place of airbrush paint, mix it 50/50 or even 60/40 with airbrush thinner. Use tape to layer over for second and third coats.&lt;br /&gt;
&lt;br /&gt;
NOTE- PAINT THE HEXAGONS BEFORE BENDING THE FINS. USE A TEMPLATE.|show=none|src=none}}&lt;br /&gt;
{{#widget:ProjectStep|inst=WIRING:&lt;br /&gt;
&lt;br /&gt;
Optional final step- run three blue LEDS in circut with a 9v, power switch, and 1000ohm resistor (optional). Push them through the mask eyes with red gel paper in front, to make a purple glow. push the switch through the foam somewhere hidden if you&#039;d like.|show=none|src=none}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Nomai_Mask_-_EVA_foam_(Project_0057)&amp;diff=9591</id>
		<title>Nomai Mask - EVA foam (Project 0057)</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Nomai_Mask_-_EVA_foam_(Project_0057)&amp;diff=9591"/>
		<updated>2025-07-23T20:59:43Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;small&amp;gt;by Jane Parson&amp;lt;/small&amp;gt;&lt;br /&gt;
-----&lt;br /&gt;
__NOTOC__&lt;br /&gt;
{{DISPLAYTITLE:Nomai Mask - EVA foam}}&lt;br /&gt;
[[Category:Projects|Nomai Mask - EVA foam]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&#039;overview&#039;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Project Overview ==&lt;br /&gt;
&lt;br /&gt;
Making a foam mask using makerspace materials, following online tutorials&lt;br /&gt;
&lt;br /&gt;
{{#widget:gallery|img1=https://drive.google.com/thumbnail?id=18yR8_0-d-lWCkUR8RRQ5svG5aoCPnN10&amp;amp;sz=w1000|img2=https://drive.google.com/thumbnail?id=1KqPLc89MDbz66cIfMbN49_AstTQR23bW&amp;amp;sz=w1000|img3=https://drive.google.com/thumbnail?id=1Qujc3sXUgBEmneQU_66JsTRfiuYjWxVU&amp;amp;sz=w1000|img4=https://drive.google.com/thumbnail?id=1CVl6ONSYFjMs9LPQKpUSlCwA4JlzbW8B&amp;amp;sz=w1000|img5=https://drive.google.com/thumbnail?id=1waPAiUTIM5Xm_5dDSDiHJaD1G0ec3uTX&amp;amp;sz=w1000|num=6}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tools and Materials ==&lt;br /&gt;
* &#039;&#039;&#039;MATERIALS&#039;&#039;&#039;&lt;br /&gt;
** Structure&lt;br /&gt;
*** EVA Foam (6mm)&lt;br /&gt;
*** Insulation Foam (24mm)&lt;br /&gt;
** Paint&lt;br /&gt;
*** Gold / Bronze Airbrush&lt;br /&gt;
*** Black Primer&lt;br /&gt;
*** Grey Airbrush&lt;br /&gt;
*** Sandstone Airbrush (Acrylic with thinner works)&lt;br /&gt;
** Glues&lt;br /&gt;
*** Hot Glue&lt;br /&gt;
*** Contact Cement&lt;br /&gt;
** Electronics&lt;br /&gt;
*** 3 x Blue LEDS&lt;br /&gt;
*** 9v dock&lt;br /&gt;
*** Power Switch&lt;br /&gt;
*** 1000 ohm resistor.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;files&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Project Files==&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&#039;sxs&#039;&amp;gt;&lt;br /&gt;
== Step-by-Step Instructions ==&lt;br /&gt;
&lt;br /&gt;
{{#widget:ProjectStep|inst=Download / Print Image Reference - At https://www.punishedprops.com/2021/02/08/nomai-mask/, download the pdf files and print them out.|show=none|src=none}}&lt;br /&gt;
{{#widget:ProjectStep|inst=Cut out foam |show=none|src=none}}&lt;br /&gt;
{{#widget:ProjectStep|inst=Glue foam together|show=none|src=none}}&lt;br /&gt;
{{#widget:ProjectStep|inst=paint mask|show=none|src=none}}&lt;br /&gt;
{{#widget:ProjectStep|inst=add in wires|show=none|src=none}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Widget:CardGallery&amp;diff=9573</id>
		<title>Widget:CardGallery</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Widget:CardGallery&amp;diff=9573"/>
		<updated>2025-06-21T16:18:36Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;script&amp;gt;&lt;br /&gt;
var cardWidget = {};&lt;br /&gt;
&lt;br /&gt;
cardWidgetStart = function () {&lt;br /&gt;
    $(document).ready(function () {&lt;br /&gt;
        var sortCats = window[&amp;quot;&amp;lt;!--{$category|escape:&#039;url&#039;}--&amp;gt;&amp;quot;];&lt;br /&gt;
        var superCats = Array.from(new Set(sortCats.map(x=&amp;gt;x.super)));&lt;br /&gt;
        var Category = pageParams[&#039;filter&#039;] ? pageParams[&#039;filter&#039;] : &amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;; // If no filter query in url, use default category type&lt;br /&gt;
        var galleryContainer = $(&#039;#card-gallery&#039;);&lt;br /&gt;
        galleryContainer.before(&#039;&amp;lt;div id=&amp;quot;category-filter&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
        var addFilterButton = (cat) =&amp;gt; {&lt;br /&gt;
          var nextBut = µ(&#039;+button&#039;,µ(&#039;#category-filter&#039;));&lt;br /&gt;
          nextBut.id = cat+&#039;-filter-btn&#039;;&lt;br /&gt;
          nextBut.textContent = cat;&lt;br /&gt;
          nextBut.className = &#039;filter-btn&#039;;&lt;br /&gt;
          nextBut.setAttribute(&#039;data-filter&#039;,cat);&lt;br /&gt;
          sortCats.forEach((el,ind)=&amp;gt;{&lt;br /&gt;
            if(el.super == cat &amp;amp;&amp;amp; el.image) µ(&#039;+img&#039;, nextBut).src = el.image;&lt;br /&gt;
          });&lt;br /&gt;
          return nextBut;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var allBut = addFilterButton(&amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;);&lt;br /&gt;
        allBut.textContent = &#039;Show All&#039;;&lt;br /&gt;
&lt;br /&gt;
        superCats.forEach(el=&amp;gt;{&lt;br /&gt;
          addFilterButton(el);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        function hideSpinner(){ $(&#039;#card-gallery .loadDial&#039;).hide()};&lt;br /&gt;
&lt;br /&gt;
        function loadCategory(category,offset){&lt;br /&gt;
            new mw.Api().get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                list: &#039;categorymembers&#039;,&lt;br /&gt;
                cmtitle: &#039;Category:&#039; + category.name,&lt;br /&gt;
                cmlimit: 5,&lt;br /&gt;
                cmcontinue: offset,&lt;br /&gt;
                format: &#039;json&#039;&lt;br /&gt;
            }).done(function (data) {&lt;br /&gt;
                var pages = data.query.categorymembers;&lt;br /&gt;
                var galleryHtml = &#039;&#039;;&lt;br /&gt;
                //console.log(data);&lt;br /&gt;
                if(data.continue) loadCategory(category, data.continue.cmcontinue);&lt;br /&gt;
                pages.forEach(function (page) {&lt;br /&gt;
                    var pageUrl = mw.util.getUrl(page.title);&lt;br /&gt;
                    var imgUrl = &#039;&#039;;&lt;br /&gt;
                    $(&#039;.gallery-container&#039;).append(generateGalleryItem(pageUrl, page.title, imgUrl, category));&lt;br /&gt;
                    //pageTitles.push(page.title);&lt;br /&gt;
                    hideSpinner();&lt;br /&gt;
                    let card = µ(&#039;.gallery-container .gallery-item:last-child img&#039;)[0];&lt;br /&gt;
                    new mw.Api().get({&lt;br /&gt;
                        action: &#039;parse&#039;,&lt;br /&gt;
                        page: page.title&lt;br /&gt;
                    }).done(function (pageData) {&lt;br /&gt;
                        //const parser = new DOMParser();&lt;br /&gt;
                        //const htmlDoc = parser.parseFromString(pageData.parse.text[&#039;*&#039;], &#039;text/xml&#039;);&lt;br /&gt;
                        console.log(pageData.parse.text[&#039;*&#039;]);&lt;br /&gt;
                        let src = /&amp;lt;(?:img|figure).*?src=(?:&#039;|&amp;quot;)([^&amp;quot;&#039;&amp;lt;&amp;gt;]*?)(?&amp;lt;!null)(?:&#039;|&amp;quot;).*?&amp;gt;/.exec(pageData.parse.text[&#039;*&#039;])&lt;br /&gt;
                        console.log(src);&lt;br /&gt;
                        if(src != null){ &lt;br /&gt;
                                if(src[1] != &#039;null&#039; &amp;amp;&amp;amp; card.src.includes(&amp;quot;No-Image&amp;quot;)) return card.src = src[1];&lt;br /&gt;
                        }&lt;br /&gt;
                        //card.src = µ(&#039;figure img&#039;,htmlDoc)[0].getAttribute(&#039;src&#039;);&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // load gallery based on category&lt;br /&gt;
        function loadGallery(category) {&lt;br /&gt;
            &lt;br /&gt;
            let pageTitles = [];&lt;br /&gt;
&lt;br /&gt;
            galleryContainer.html(&amp;quot;&amp;lt;div class=&#039;loadDial&#039;&amp;gt;&amp;lt;p&amp;gt;Retrieving Data...&amp;lt;/p&amp;gt;&amp;lt;div class=&#039;loadSpinner&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;);&lt;br /&gt;
            // insert projects corresponding to each skill under broader category filter selected&lt;br /&gt;
            var filterCats = sortCats.filter(el=&amp;gt;el.super == category);&lt;br /&gt;
            if(category == &amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;) filterCats = [{name:&amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;}];&lt;br /&gt;
            filterCats.forEach(function(cat) {&lt;br /&gt;
                loadCategory(cat,0);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // generate a gallery&lt;br /&gt;
        function generateGalleryItem(pageUrl, title, imgUrl, category) {&lt;br /&gt;
            return `&lt;br /&gt;
                &amp;lt;div class=&amp;quot;gallery-item ${category}&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;a href=&amp;quot;${pageUrl}&amp;quot;&amp;gt;&lt;br /&gt;
                        ${imgUrl ? `&amp;lt;img class=&amp;quot;thumbs&amp;quot; src=&amp;quot;${imgUrl}&amp;quot; alt=&amp;quot;${title}&amp;quot;&amp;gt;` : `&amp;lt;img src=&amp;quot;https://upload.wikimedia.org/wikipedia/commons/6/65/No-Image-Placeholder.svg&amp;quot; alt=&amp;quot;No Image Available&amp;quot;&amp;gt;`}&lt;br /&gt;
&lt;br /&gt;
                    &amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;gallery-caption&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a href=&amp;quot;${pageUrl}&amp;quot;&amp;gt;${title}&amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            `;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        loadGallery(Category);&lt;br /&gt;
&lt;br /&gt;
        // find filter button corresponding to selected category and add css class &#039;selected-filter&#039;&lt;br /&gt;
        $(&amp;quot;.filter-btn&amp;quot;).each(function () { $(this).data(&amp;quot;filter&amp;quot;) === Category ? $(this).addClass(&#039;selected-filter&#039;) : null});&lt;br /&gt;
&lt;br /&gt;
        // when filter button is clicked, load projects for that category, deselect current filtered button, and select newly clicked filter button&lt;br /&gt;
        $(&amp;quot;.filter-btn&amp;quot;).click(function () {&lt;br /&gt;
            var selectedCategory = $(this).data(&amp;quot;filter&amp;quot;);&lt;br /&gt;
            loadGallery(selectedCategory);&lt;br /&gt;
            &lt;br /&gt;
            $(&#039;.filter-btn.selected-filter&#039;).each((i, elem) =&amp;gt; $(elem).removeClass(&#039;selected-filter&#039;));&lt;br /&gt;
            $(this).addClass(&#039;selected-filter&#039;);&lt;br /&gt;
        });&lt;br /&gt;
    });&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
if(!window.widgets) window.widgets = [];&lt;br /&gt;
window.widgets.push(cardWidgetStart);&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
  .filter-btn img{&lt;br /&gt;
    height:1.5em;&lt;br /&gt;
    padding-left:.4em;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
.gallery-item {&lt;br /&gt;
    width: 20%;&lt;br /&gt;
    min-width:200px;&lt;br /&gt;
    max-width: 30vw;&lt;br /&gt;
    margin: 10px;&lt;br /&gt;
    flex-grow: 2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.loadDial {&lt;br /&gt;
  width: 100%;&lt;br /&gt;
  text-align: center;&lt;br /&gt;
  p {&lt;br /&gt;
    font-weight: bolder;&lt;br /&gt;
    font-size: x-large;&lt;br /&gt;
    color: #666;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;card-gallery&amp;quot; class=&amp;quot;gallery-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Widget:CardGallery&amp;diff=9572</id>
		<title>Widget:CardGallery</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Widget:CardGallery&amp;diff=9572"/>
		<updated>2025-06-21T16:12:27Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;script&amp;gt;&lt;br /&gt;
var cardWidget = {};&lt;br /&gt;
&lt;br /&gt;
cardWidgetStart = function () {&lt;br /&gt;
    $(document).ready(function () {&lt;br /&gt;
        var sortCats = window[&amp;quot;&amp;lt;!--{$category|escape:&#039;url&#039;}--&amp;gt;&amp;quot;];&lt;br /&gt;
        var superCats = Array.from(new Set(sortCats.map(x=&amp;gt;x.super)));&lt;br /&gt;
        var Category = pageParams[&#039;filter&#039;] ? pageParams[&#039;filter&#039;] : &amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;; // If no filter query in url, use default category type&lt;br /&gt;
        var galleryContainer = $(&#039;#card-gallery&#039;);&lt;br /&gt;
        galleryContainer.before(&#039;&amp;lt;div id=&amp;quot;category-filter&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
        var addFilterButton = (cat) =&amp;gt; {&lt;br /&gt;
          var nextBut = µ(&#039;+button&#039;,µ(&#039;#category-filter&#039;));&lt;br /&gt;
          nextBut.id = cat+&#039;-filter-btn&#039;;&lt;br /&gt;
          nextBut.textContent = cat;&lt;br /&gt;
          nextBut.className = &#039;filter-btn&#039;;&lt;br /&gt;
          nextBut.setAttribute(&#039;data-filter&#039;,cat);&lt;br /&gt;
          sortCats.forEach((el,ind)=&amp;gt;{&lt;br /&gt;
            if(el.super == cat &amp;amp;&amp;amp; el.image) µ(&#039;+img&#039;, nextBut).src = el.image;&lt;br /&gt;
          });&lt;br /&gt;
          return nextBut;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var allBut = addFilterButton(&amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;);&lt;br /&gt;
        allBut.textContent = &#039;Show All&#039;;&lt;br /&gt;
&lt;br /&gt;
        superCats.forEach(el=&amp;gt;{&lt;br /&gt;
          addFilterButton(el);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        function hideSpinner(){ $(&#039;#card-gallery .loadDial&#039;).hide()};&lt;br /&gt;
&lt;br /&gt;
        function loadCategory(category,offset){&lt;br /&gt;
            new mw.Api().get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                list: &#039;categorymembers&#039;,&lt;br /&gt;
                cmtitle: &#039;Category:&#039; + category.name,&lt;br /&gt;
                cmlimit: 5,&lt;br /&gt;
                cmcontinue: offset,&lt;br /&gt;
                format: &#039;json&#039;&lt;br /&gt;
            }).done(function (data) {&lt;br /&gt;
                var pages = data.query.categorymembers;&lt;br /&gt;
                var galleryHtml = &#039;&#039;;&lt;br /&gt;
                //console.log(data);&lt;br /&gt;
                if(data.continue) loadCategory(category, data.continue.cmcontinue);&lt;br /&gt;
                pages.forEach(function (page) {&lt;br /&gt;
                    var pageUrl = mw.util.getUrl(page.title);&lt;br /&gt;
                    var imgUrl = &#039;&#039;;&lt;br /&gt;
                    $(&#039;.gallery-container&#039;).append(generateGalleryItem(pageUrl, page.title, imgUrl, category));&lt;br /&gt;
                    //pageTitles.push(page.title);&lt;br /&gt;
                    hideSpinner();&lt;br /&gt;
                    let card = µ(&#039;.gallery-container .gallery-item:last-child img&#039;)[0];&lt;br /&gt;
                    new mw.Api().get({&lt;br /&gt;
                        action: &#039;parse&#039;,&lt;br /&gt;
                        page: page.title&lt;br /&gt;
                    }).done(function (pageData) {&lt;br /&gt;
                        //const parser = new DOMParser();&lt;br /&gt;
                        //const htmlDoc = parser.parseFromString(pageData.parse.text[&#039;*&#039;], &#039;text/xml&#039;);&lt;br /&gt;
                        console.log(pageData.parse.text[&#039;*&#039;]);&lt;br /&gt;
                        let src = /&amp;lt;(?:img|figure).*?src=&amp;quot;([^&amp;quot;&#039;&amp;lt;&amp;gt;]*?)(?&amp;lt;!null)&amp;quot;.*?&amp;gt;/.exec(pageData.parse.text[&#039;*&#039;])&lt;br /&gt;
                        console.log(src);&lt;br /&gt;
                        if(src != null){ &lt;br /&gt;
                                if(src[1] != &#039;null&#039; &amp;amp;&amp;amp; card.src.includes(&amp;quot;No-Image&amp;quot;)) return card.src = src[1];&lt;br /&gt;
                        }&lt;br /&gt;
                        //card.src = µ(&#039;figure img&#039;,htmlDoc)[0].getAttribute(&#039;src&#039;);&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // load gallery based on category&lt;br /&gt;
        function loadGallery(category) {&lt;br /&gt;
            &lt;br /&gt;
            let pageTitles = [];&lt;br /&gt;
&lt;br /&gt;
            galleryContainer.html(&amp;quot;&amp;lt;div class=&#039;loadDial&#039;&amp;gt;&amp;lt;p&amp;gt;Retrieving Data...&amp;lt;/p&amp;gt;&amp;lt;div class=&#039;loadSpinner&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;);&lt;br /&gt;
            // insert projects corresponding to each skill under broader category filter selected&lt;br /&gt;
            var filterCats = sortCats.filter(el=&amp;gt;el.super == category);&lt;br /&gt;
            if(category == &amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;) filterCats = [{name:&amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;}];&lt;br /&gt;
            filterCats.forEach(function(cat) {&lt;br /&gt;
                loadCategory(cat,0);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // generate a gallery&lt;br /&gt;
        function generateGalleryItem(pageUrl, title, imgUrl, category) {&lt;br /&gt;
            return `&lt;br /&gt;
                &amp;lt;div class=&amp;quot;gallery-item ${category}&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;a href=&amp;quot;${pageUrl}&amp;quot;&amp;gt;&lt;br /&gt;
                        ${imgUrl ? `&amp;lt;img class=&amp;quot;thumbs&amp;quot; src=&amp;quot;${imgUrl}&amp;quot; alt=&amp;quot;${title}&amp;quot;&amp;gt;` : `&amp;lt;img src=&amp;quot;https://upload.wikimedia.org/wikipedia/commons/6/65/No-Image-Placeholder.svg&amp;quot; alt=&amp;quot;No Image Available&amp;quot;&amp;gt;`}&lt;br /&gt;
&lt;br /&gt;
                    &amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;gallery-caption&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a href=&amp;quot;${pageUrl}&amp;quot;&amp;gt;${title}&amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            `;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        loadGallery(Category);&lt;br /&gt;
&lt;br /&gt;
        // find filter button corresponding to selected category and add css class &#039;selected-filter&#039;&lt;br /&gt;
        $(&amp;quot;.filter-btn&amp;quot;).each(function () { $(this).data(&amp;quot;filter&amp;quot;) === Category ? $(this).addClass(&#039;selected-filter&#039;) : null});&lt;br /&gt;
&lt;br /&gt;
        // when filter button is clicked, load projects for that category, deselect current filtered button, and select newly clicked filter button&lt;br /&gt;
        $(&amp;quot;.filter-btn&amp;quot;).click(function () {&lt;br /&gt;
            var selectedCategory = $(this).data(&amp;quot;filter&amp;quot;);&lt;br /&gt;
            loadGallery(selectedCategory);&lt;br /&gt;
            &lt;br /&gt;
            $(&#039;.filter-btn.selected-filter&#039;).each((i, elem) =&amp;gt; $(elem).removeClass(&#039;selected-filter&#039;));&lt;br /&gt;
            $(this).addClass(&#039;selected-filter&#039;);&lt;br /&gt;
        });&lt;br /&gt;
    });&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
if(!window.widgets) window.widgets = [];&lt;br /&gt;
window.widgets.push(cardWidgetStart);&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
  .filter-btn img{&lt;br /&gt;
    height:1.5em;&lt;br /&gt;
    padding-left:.4em;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
.gallery-item {&lt;br /&gt;
    width: 20%;&lt;br /&gt;
    min-width:200px;&lt;br /&gt;
    max-width: 30vw;&lt;br /&gt;
    margin: 10px;&lt;br /&gt;
    flex-grow: 2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.loadDial {&lt;br /&gt;
  width: 100%;&lt;br /&gt;
  text-align: center;&lt;br /&gt;
  p {&lt;br /&gt;
    font-weight: bolder;&lt;br /&gt;
    font-size: x-large;&lt;br /&gt;
    color: #666;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;card-gallery&amp;quot; class=&amp;quot;gallery-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Widget:CardGallery&amp;diff=9571</id>
		<title>Widget:CardGallery</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Widget:CardGallery&amp;diff=9571"/>
		<updated>2025-06-21T16:00:14Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;script&amp;gt;&lt;br /&gt;
var cardWidget = {};&lt;br /&gt;
&lt;br /&gt;
cardWidgetStart = function () {&lt;br /&gt;
    $(document).ready(function () {&lt;br /&gt;
        var sortCats = window[&amp;quot;&amp;lt;!--{$category|escape:&#039;url&#039;}--&amp;gt;&amp;quot;];&lt;br /&gt;
        var superCats = Array.from(new Set(sortCats.map(x=&amp;gt;x.super)));&lt;br /&gt;
        var Category = pageParams[&#039;filter&#039;] ? pageParams[&#039;filter&#039;] : &amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;; // If no filter query in url, use default category type&lt;br /&gt;
        var galleryContainer = $(&#039;#card-gallery&#039;);&lt;br /&gt;
        galleryContainer.before(&#039;&amp;lt;div id=&amp;quot;category-filter&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
        var addFilterButton = (cat) =&amp;gt; {&lt;br /&gt;
          var nextBut = µ(&#039;+button&#039;,µ(&#039;#category-filter&#039;));&lt;br /&gt;
          nextBut.id = cat+&#039;-filter-btn&#039;;&lt;br /&gt;
          nextBut.textContent = cat;&lt;br /&gt;
          nextBut.className = &#039;filter-btn&#039;;&lt;br /&gt;
          nextBut.setAttribute(&#039;data-filter&#039;,cat);&lt;br /&gt;
          sortCats.forEach((el,ind)=&amp;gt;{&lt;br /&gt;
            if(el.super == cat &amp;amp;&amp;amp; el.image) µ(&#039;+img&#039;, nextBut).src = el.image;&lt;br /&gt;
          });&lt;br /&gt;
          return nextBut;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var allBut = addFilterButton(&amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;);&lt;br /&gt;
        allBut.textContent = &#039;Show All&#039;;&lt;br /&gt;
&lt;br /&gt;
        superCats.forEach(el=&amp;gt;{&lt;br /&gt;
          addFilterButton(el);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        function hideSpinner(){ $(&#039;#card-gallery .loadDial&#039;).hide()};&lt;br /&gt;
&lt;br /&gt;
        function loadCategory(category,offset){&lt;br /&gt;
            new mw.Api().get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                list: &#039;categorymembers&#039;,&lt;br /&gt;
                cmtitle: &#039;Category:&#039; + category.name,&lt;br /&gt;
                cmlimit: 5,&lt;br /&gt;
                cmcontinue: offset,&lt;br /&gt;
                format: &#039;json&#039;&lt;br /&gt;
            }).done(function (data) {&lt;br /&gt;
                var pages = data.query.categorymembers;&lt;br /&gt;
                var galleryHtml = &#039;&#039;;&lt;br /&gt;
                //console.log(data);&lt;br /&gt;
                if(data.continue) loadCategory(category, data.continue.cmcontinue);&lt;br /&gt;
                pages.forEach(function (page) {&lt;br /&gt;
                    var pageUrl = mw.util.getUrl(page.title);&lt;br /&gt;
                    var imgUrl = &#039;&#039;;&lt;br /&gt;
                    $(&#039;.gallery-container&#039;).append(generateGalleryItem(pageUrl, page.title, imgUrl, category));&lt;br /&gt;
                    //pageTitles.push(page.title);&lt;br /&gt;
                    hideSpinner();&lt;br /&gt;
                    let card = µ(&#039;.gallery-container .gallery-item:last-child img&#039;)[0];&lt;br /&gt;
                    new mw.Api().get({&lt;br /&gt;
                        action: &#039;parse&#039;,&lt;br /&gt;
                        page: page.title&lt;br /&gt;
                    }).done(function (pageData) {&lt;br /&gt;
                        //const parser = new DOMParser();&lt;br /&gt;
                        //const htmlDoc = parser.parseFromString(pageData.parse.text[&#039;*&#039;], &#039;text/xml&#039;);&lt;br /&gt;
                        console.log(pageData.parse.text[&#039;*&#039;]);&lt;br /&gt;
                        let src = /(?:img|figure).*?src=&amp;quot;([^&amp;quot;&#039;]*?)&amp;quot;/.exec(pageData.parse.text[&#039;*&#039;])&lt;br /&gt;
                        console.log(src);&lt;br /&gt;
                        if(src != null){ &lt;br /&gt;
                                if(src[1] != &#039;null&#039; &amp;amp;&amp;amp; card.src.includes(&amp;quot;No-Image&amp;quot;)) return card.src = src[1];&lt;br /&gt;
                        }&lt;br /&gt;
                        //card.src = µ(&#039;figure img&#039;,htmlDoc)[0].getAttribute(&#039;src&#039;);&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // load gallery based on category&lt;br /&gt;
        function loadGallery(category) {&lt;br /&gt;
            &lt;br /&gt;
            let pageTitles = [];&lt;br /&gt;
&lt;br /&gt;
            galleryContainer.html(&amp;quot;&amp;lt;div class=&#039;loadDial&#039;&amp;gt;&amp;lt;p&amp;gt;Retrieving Data...&amp;lt;/p&amp;gt;&amp;lt;div class=&#039;loadSpinner&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;);&lt;br /&gt;
            // insert projects corresponding to each skill under broader category filter selected&lt;br /&gt;
            var filterCats = sortCats.filter(el=&amp;gt;el.super == category);&lt;br /&gt;
            if(category == &amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;) filterCats = [{name:&amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;}];&lt;br /&gt;
            filterCats.forEach(function(cat) {&lt;br /&gt;
                loadCategory(cat,0);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // generate a gallery&lt;br /&gt;
        function generateGalleryItem(pageUrl, title, imgUrl, category) {&lt;br /&gt;
            return `&lt;br /&gt;
                &amp;lt;div class=&amp;quot;gallery-item ${category}&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;a href=&amp;quot;${pageUrl}&amp;quot;&amp;gt;&lt;br /&gt;
                        ${imgUrl ? `&amp;lt;img class=&amp;quot;thumbs&amp;quot; src=&amp;quot;${imgUrl}&amp;quot; alt=&amp;quot;${title}&amp;quot;&amp;gt;` : `&amp;lt;img src=&amp;quot;https://upload.wikimedia.org/wikipedia/commons/6/65/No-Image-Placeholder.svg&amp;quot; alt=&amp;quot;No Image Available&amp;quot;&amp;gt;`}&lt;br /&gt;
&lt;br /&gt;
                    &amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;gallery-caption&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a href=&amp;quot;${pageUrl}&amp;quot;&amp;gt;${title}&amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            `;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        loadGallery(Category);&lt;br /&gt;
&lt;br /&gt;
        // find filter button corresponding to selected category and add css class &#039;selected-filter&#039;&lt;br /&gt;
        $(&amp;quot;.filter-btn&amp;quot;).each(function () { $(this).data(&amp;quot;filter&amp;quot;) === Category ? $(this).addClass(&#039;selected-filter&#039;) : null});&lt;br /&gt;
&lt;br /&gt;
        // when filter button is clicked, load projects for that category, deselect current filtered button, and select newly clicked filter button&lt;br /&gt;
        $(&amp;quot;.filter-btn&amp;quot;).click(function () {&lt;br /&gt;
            var selectedCategory = $(this).data(&amp;quot;filter&amp;quot;);&lt;br /&gt;
            loadGallery(selectedCategory);&lt;br /&gt;
            &lt;br /&gt;
            $(&#039;.filter-btn.selected-filter&#039;).each((i, elem) =&amp;gt; $(elem).removeClass(&#039;selected-filter&#039;));&lt;br /&gt;
            $(this).addClass(&#039;selected-filter&#039;);&lt;br /&gt;
        });&lt;br /&gt;
    });&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
if(!window.widgets) window.widgets = [];&lt;br /&gt;
window.widgets.push(cardWidgetStart);&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
  .filter-btn img{&lt;br /&gt;
    height:1.5em;&lt;br /&gt;
    padding-left:.4em;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
.gallery-item {&lt;br /&gt;
    width: 20%;&lt;br /&gt;
    min-width:200px;&lt;br /&gt;
    max-width: 30vw;&lt;br /&gt;
    margin: 10px;&lt;br /&gt;
    flex-grow: 2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.loadDial {&lt;br /&gt;
  width: 100%;&lt;br /&gt;
  text-align: center;&lt;br /&gt;
  p {&lt;br /&gt;
    font-weight: bolder;&lt;br /&gt;
    font-size: x-large;&lt;br /&gt;
    color: #666;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;card-gallery&amp;quot; class=&amp;quot;gallery-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Widget:CardGallery&amp;diff=9570</id>
		<title>Widget:CardGallery</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Widget:CardGallery&amp;diff=9570"/>
		<updated>2025-06-21T15:58:59Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;script&amp;gt;&lt;br /&gt;
var cardWidget = {};&lt;br /&gt;
&lt;br /&gt;
cardWidgetStart = function () {&lt;br /&gt;
    $(document).ready(function () {&lt;br /&gt;
        var sortCats = window[&amp;quot;&amp;lt;!--{$category|escape:&#039;url&#039;}--&amp;gt;&amp;quot;];&lt;br /&gt;
        var superCats = Array.from(new Set(sortCats.map(x=&amp;gt;x.super)));&lt;br /&gt;
        var Category = pageParams[&#039;filter&#039;] ? pageParams[&#039;filter&#039;] : &amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;; // If no filter query in url, use default category type&lt;br /&gt;
        var galleryContainer = $(&#039;#card-gallery&#039;);&lt;br /&gt;
        galleryContainer.before(&#039;&amp;lt;div id=&amp;quot;category-filter&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
        var addFilterButton = (cat) =&amp;gt; {&lt;br /&gt;
          var nextBut = µ(&#039;+button&#039;,µ(&#039;#category-filter&#039;));&lt;br /&gt;
          nextBut.id = cat+&#039;-filter-btn&#039;;&lt;br /&gt;
          nextBut.textContent = cat;&lt;br /&gt;
          nextBut.className = &#039;filter-btn&#039;;&lt;br /&gt;
          nextBut.setAttribute(&#039;data-filter&#039;,cat);&lt;br /&gt;
          sortCats.forEach((el,ind)=&amp;gt;{&lt;br /&gt;
            if(el.super == cat &amp;amp;&amp;amp; el.image) µ(&#039;+img&#039;, nextBut).src = el.image;&lt;br /&gt;
          });&lt;br /&gt;
          return nextBut;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var allBut = addFilterButton(&amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;);&lt;br /&gt;
        allBut.textContent = &#039;Show All&#039;;&lt;br /&gt;
&lt;br /&gt;
        superCats.forEach(el=&amp;gt;{&lt;br /&gt;
          addFilterButton(el);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        function hideSpinner(){ $(&#039;#card-gallery .loadDial&#039;).hide()};&lt;br /&gt;
&lt;br /&gt;
        function loadCategory(category,offset){&lt;br /&gt;
            new mw.Api().get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                list: &#039;categorymembers&#039;,&lt;br /&gt;
                cmtitle: &#039;Category:&#039; + category.name,&lt;br /&gt;
                cmlimit: 5,&lt;br /&gt;
                cmcontinue: offset,&lt;br /&gt;
                format: &#039;json&#039;&lt;br /&gt;
            }).done(function (data) {&lt;br /&gt;
                var pages = data.query.categorymembers;&lt;br /&gt;
                var galleryHtml = &#039;&#039;;&lt;br /&gt;
                //console.log(data);&lt;br /&gt;
                if(data.continue) loadCategory(category, data.continue.cmcontinue);&lt;br /&gt;
                pages.forEach(function (page) {&lt;br /&gt;
                    var pageUrl = mw.util.getUrl(page.title);&lt;br /&gt;
                    var imgUrl = &#039;&#039;;&lt;br /&gt;
                    $(&#039;.gallery-container&#039;).append(generateGalleryItem(pageUrl, page.title, imgUrl, category));&lt;br /&gt;
                    //pageTitles.push(page.title);&lt;br /&gt;
                    hideSpinner();&lt;br /&gt;
                    let card = µ(&#039;.gallery-container .gallery-item:last-child img&#039;)[0];&lt;br /&gt;
                    new mw.Api().get({&lt;br /&gt;
                        action: &#039;parse&#039;,&lt;br /&gt;
                        page: page.title&lt;br /&gt;
                    }).done(function (pageData) {&lt;br /&gt;
                        //const parser = new DOMParser();&lt;br /&gt;
                        //const htmlDoc = parser.parseFromString(pageData.parse.text[&#039;*&#039;], &#039;text/xml&#039;);&lt;br /&gt;
                        let src = /(?:img|figure).*?src=&amp;quot;([^&amp;quot;&#039;]*?)&amp;quot;/.exec(pageData.parse.text[&#039;*&#039;])&lt;br /&gt;
                        console.log(src);&lt;br /&gt;
                        if(src != null){ &lt;br /&gt;
                                if(src[1] != &#039;null&#039; &amp;amp;&amp;amp; card.src.includes(&amp;quot;No-Image&amp;quot;)) return card.src = src[1];&lt;br /&gt;
                        }&lt;br /&gt;
                        //card.src = µ(&#039;figure img&#039;,htmlDoc)[0].getAttribute(&#039;src&#039;);&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // load gallery based on category&lt;br /&gt;
        function loadGallery(category) {&lt;br /&gt;
            &lt;br /&gt;
            let pageTitles = [];&lt;br /&gt;
&lt;br /&gt;
            galleryContainer.html(&amp;quot;&amp;lt;div class=&#039;loadDial&#039;&amp;gt;&amp;lt;p&amp;gt;Retrieving Data...&amp;lt;/p&amp;gt;&amp;lt;div class=&#039;loadSpinner&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;);&lt;br /&gt;
            // insert projects corresponding to each skill under broader category filter selected&lt;br /&gt;
            var filterCats = sortCats.filter(el=&amp;gt;el.super == category);&lt;br /&gt;
            if(category == &amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;) filterCats = [{name:&amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;}];&lt;br /&gt;
            filterCats.forEach(function(cat) {&lt;br /&gt;
                loadCategory(cat,0);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // generate a gallery&lt;br /&gt;
        function generateGalleryItem(pageUrl, title, imgUrl, category) {&lt;br /&gt;
            return `&lt;br /&gt;
                &amp;lt;div class=&amp;quot;gallery-item ${category}&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;a href=&amp;quot;${pageUrl}&amp;quot;&amp;gt;&lt;br /&gt;
                        ${imgUrl ? `&amp;lt;img class=&amp;quot;thumbs&amp;quot; src=&amp;quot;${imgUrl}&amp;quot; alt=&amp;quot;${title}&amp;quot;&amp;gt;` : `&amp;lt;img src=&amp;quot;https://upload.wikimedia.org/wikipedia/commons/6/65/No-Image-Placeholder.svg&amp;quot; alt=&amp;quot;No Image Available&amp;quot;&amp;gt;`}&lt;br /&gt;
&lt;br /&gt;
                    &amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;gallery-caption&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a href=&amp;quot;${pageUrl}&amp;quot;&amp;gt;${title}&amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            `;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        loadGallery(Category);&lt;br /&gt;
&lt;br /&gt;
        // find filter button corresponding to selected category and add css class &#039;selected-filter&#039;&lt;br /&gt;
        $(&amp;quot;.filter-btn&amp;quot;).each(function () { $(this).data(&amp;quot;filter&amp;quot;) === Category ? $(this).addClass(&#039;selected-filter&#039;) : null});&lt;br /&gt;
&lt;br /&gt;
        // when filter button is clicked, load projects for that category, deselect current filtered button, and select newly clicked filter button&lt;br /&gt;
        $(&amp;quot;.filter-btn&amp;quot;).click(function () {&lt;br /&gt;
            var selectedCategory = $(this).data(&amp;quot;filter&amp;quot;);&lt;br /&gt;
            loadGallery(selectedCategory);&lt;br /&gt;
            &lt;br /&gt;
            $(&#039;.filter-btn.selected-filter&#039;).each((i, elem) =&amp;gt; $(elem).removeClass(&#039;selected-filter&#039;));&lt;br /&gt;
            $(this).addClass(&#039;selected-filter&#039;);&lt;br /&gt;
        });&lt;br /&gt;
    });&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
if(!window.widgets) window.widgets = [];&lt;br /&gt;
window.widgets.push(cardWidgetStart);&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
  .filter-btn img{&lt;br /&gt;
    height:1.5em;&lt;br /&gt;
    padding-left:.4em;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
.gallery-item {&lt;br /&gt;
    width: 20%;&lt;br /&gt;
    min-width:200px;&lt;br /&gt;
    max-width: 30vw;&lt;br /&gt;
    margin: 10px;&lt;br /&gt;
    flex-grow: 2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.loadDial {&lt;br /&gt;
  width: 100%;&lt;br /&gt;
  text-align: center;&lt;br /&gt;
  p {&lt;br /&gt;
    font-weight: bolder;&lt;br /&gt;
    font-size: x-large;&lt;br /&gt;
    color: #666;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;card-gallery&amp;quot; class=&amp;quot;gallery-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Widget:CardGallery&amp;diff=9569</id>
		<title>Widget:CardGallery</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Widget:CardGallery&amp;diff=9569"/>
		<updated>2025-06-21T15:57:47Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;script&amp;gt;&lt;br /&gt;
var cardWidget = {};&lt;br /&gt;
&lt;br /&gt;
cardWidgetStart = function () {&lt;br /&gt;
    $(document).ready(function () {&lt;br /&gt;
        var sortCats = window[&amp;quot;&amp;lt;!--{$category|escape:&#039;url&#039;}--&amp;gt;&amp;quot;];&lt;br /&gt;
        var superCats = Array.from(new Set(sortCats.map(x=&amp;gt;x.super)));&lt;br /&gt;
        var Category = pageParams[&#039;filter&#039;] ? pageParams[&#039;filter&#039;] : &amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;; // If no filter query in url, use default category type&lt;br /&gt;
        var galleryContainer = $(&#039;#card-gallery&#039;);&lt;br /&gt;
        galleryContainer.before(&#039;&amp;lt;div id=&amp;quot;category-filter&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
        var addFilterButton = (cat) =&amp;gt; {&lt;br /&gt;
          var nextBut = µ(&#039;+button&#039;,µ(&#039;#category-filter&#039;));&lt;br /&gt;
          nextBut.id = cat+&#039;-filter-btn&#039;;&lt;br /&gt;
          nextBut.textContent = cat;&lt;br /&gt;
          nextBut.className = &#039;filter-btn&#039;;&lt;br /&gt;
          nextBut.setAttribute(&#039;data-filter&#039;,cat);&lt;br /&gt;
          sortCats.forEach((el,ind)=&amp;gt;{&lt;br /&gt;
            if(el.super == cat &amp;amp;&amp;amp; el.image) µ(&#039;+img&#039;, nextBut).src = el.image;&lt;br /&gt;
          });&lt;br /&gt;
          return nextBut;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var allBut = addFilterButton(&amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;);&lt;br /&gt;
        allBut.textContent = &#039;Show All&#039;;&lt;br /&gt;
&lt;br /&gt;
        superCats.forEach(el=&amp;gt;{&lt;br /&gt;
          addFilterButton(el);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        function hideSpinner(){ $(&#039;#card-gallery .loadDial&#039;).hide()};&lt;br /&gt;
&lt;br /&gt;
        function loadCategory(category,offset){&lt;br /&gt;
            new mw.Api().get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                list: &#039;categorymembers&#039;,&lt;br /&gt;
                cmtitle: &#039;Category:&#039; + category.name,&lt;br /&gt;
                cmlimit: 5,&lt;br /&gt;
                cmcontinue: offset,&lt;br /&gt;
                format: &#039;json&#039;&lt;br /&gt;
            }).done(function (data) {&lt;br /&gt;
                var pages = data.query.categorymembers;&lt;br /&gt;
                var galleryHtml = &#039;&#039;;&lt;br /&gt;
                //console.log(data);&lt;br /&gt;
                if(data.continue) loadCategory(category, data.continue.cmcontinue);&lt;br /&gt;
                pages.forEach(function (page) {&lt;br /&gt;
                    var pageUrl = mw.util.getUrl(page.title);&lt;br /&gt;
                    var imgUrl = &#039;&#039;;&lt;br /&gt;
                    $(&#039;.gallery-container&#039;).append(generateGalleryItem(pageUrl, page.title, imgUrl, category));&lt;br /&gt;
                    //pageTitles.push(page.title);&lt;br /&gt;
                    hideSpinner();&lt;br /&gt;
                    let card = µ(&#039;.gallery-container .gallery-item:last-child img&#039;)[0];&lt;br /&gt;
                    new mw.Api().get({&lt;br /&gt;
                        action: &#039;parse&#039;,&lt;br /&gt;
                        page: page.title&lt;br /&gt;
                    }).done(function (pageData) {&lt;br /&gt;
                        const parser = new DOMParser();&lt;br /&gt;
                        const htmlDoc = parser.parseFromString(pageData.parse.text[&#039;*&#039;], &#039;text/xml&#039;);&lt;br /&gt;
                        let src = /(?:img|figure).*?src=&amp;quot;([^&amp;quot;&#039;]*?)&amp;quot;/.exec(pageData.parse.text[&#039;*&#039;])&lt;br /&gt;
                        console.log(src);&lt;br /&gt;
                        if(src != null){ &lt;br /&gt;
                                if(src[1] != &#039;null&#039; &amp;amp;&amp;amp; card.src.includes(&amp;quot;No-Image&amp;quot;)) return card.src = src[1];&lt;br /&gt;
                        }&lt;br /&gt;
                        //card.src = µ(&#039;figure img&#039;,htmlDoc)[0].getAttribute(&#039;src&#039;);&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // load gallery based on category&lt;br /&gt;
        function loadGallery(category) {&lt;br /&gt;
            &lt;br /&gt;
            let pageTitles = [];&lt;br /&gt;
&lt;br /&gt;
            galleryContainer.html(&amp;quot;&amp;lt;div class=&#039;loadDial&#039;&amp;gt;&amp;lt;p&amp;gt;Retrieving Data...&amp;lt;/p&amp;gt;&amp;lt;div class=&#039;loadSpinner&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;);&lt;br /&gt;
            // insert projects corresponding to each skill under broader category filter selected&lt;br /&gt;
            var filterCats = sortCats.filter(el=&amp;gt;el.super == category);&lt;br /&gt;
            if(category == &amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;) filterCats = [{name:&amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;}];&lt;br /&gt;
            filterCats.forEach(function(cat) {&lt;br /&gt;
                loadCategory(cat,0);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // generate a gallery&lt;br /&gt;
        function generateGalleryItem(pageUrl, title, imgUrl, category) {&lt;br /&gt;
            return `&lt;br /&gt;
                &amp;lt;div class=&amp;quot;gallery-item ${category}&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;a href=&amp;quot;${pageUrl}&amp;quot;&amp;gt;&lt;br /&gt;
                        ${imgUrl ? `&amp;lt;img class=&amp;quot;thumbs&amp;quot; src=&amp;quot;${imgUrl}&amp;quot; alt=&amp;quot;${title}&amp;quot;&amp;gt;` : `&amp;lt;img src=&amp;quot;https://upload.wikimedia.org/wikipedia/commons/6/65/No-Image-Placeholder.svg&amp;quot; alt=&amp;quot;No Image Available&amp;quot;&amp;gt;`}&lt;br /&gt;
&lt;br /&gt;
                    &amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;gallery-caption&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a href=&amp;quot;${pageUrl}&amp;quot;&amp;gt;${title}&amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            `;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        loadGallery(Category);&lt;br /&gt;
&lt;br /&gt;
        // find filter button corresponding to selected category and add css class &#039;selected-filter&#039;&lt;br /&gt;
        $(&amp;quot;.filter-btn&amp;quot;).each(function () { $(this).data(&amp;quot;filter&amp;quot;) === Category ? $(this).addClass(&#039;selected-filter&#039;) : null});&lt;br /&gt;
&lt;br /&gt;
        // when filter button is clicked, load projects for that category, deselect current filtered button, and select newly clicked filter button&lt;br /&gt;
        $(&amp;quot;.filter-btn&amp;quot;).click(function () {&lt;br /&gt;
            var selectedCategory = $(this).data(&amp;quot;filter&amp;quot;);&lt;br /&gt;
            loadGallery(selectedCategory);&lt;br /&gt;
            &lt;br /&gt;
            $(&#039;.filter-btn.selected-filter&#039;).each((i, elem) =&amp;gt; $(elem).removeClass(&#039;selected-filter&#039;));&lt;br /&gt;
            $(this).addClass(&#039;selected-filter&#039;);&lt;br /&gt;
        });&lt;br /&gt;
    });&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
if(!window.widgets) window.widgets = [];&lt;br /&gt;
window.widgets.push(cardWidgetStart);&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
  .filter-btn img{&lt;br /&gt;
    height:1.5em;&lt;br /&gt;
    padding-left:.4em;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
.gallery-item {&lt;br /&gt;
    width: 20%;&lt;br /&gt;
    min-width:200px;&lt;br /&gt;
    max-width: 30vw;&lt;br /&gt;
    margin: 10px;&lt;br /&gt;
    flex-grow: 2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.loadDial {&lt;br /&gt;
  width: 100%;&lt;br /&gt;
  text-align: center;&lt;br /&gt;
  p {&lt;br /&gt;
    font-weight: bolder;&lt;br /&gt;
    font-size: x-large;&lt;br /&gt;
    color: #666;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;card-gallery&amp;quot; class=&amp;quot;gallery-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Widget:CardGallery&amp;diff=9568</id>
		<title>Widget:CardGallery</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Widget:CardGallery&amp;diff=9568"/>
		<updated>2025-06-21T15:56:41Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;script&amp;gt;&lt;br /&gt;
var cardWidget = {};&lt;br /&gt;
&lt;br /&gt;
cardWidgetStart = function () {&lt;br /&gt;
    $(document).ready(function () {&lt;br /&gt;
        var sortCats = window[&amp;quot;&amp;lt;!--{$category|escape:&#039;url&#039;}--&amp;gt;&amp;quot;];&lt;br /&gt;
        var superCats = Array.from(new Set(sortCats.map(x=&amp;gt;x.super)));&lt;br /&gt;
        var Category = pageParams[&#039;filter&#039;] ? pageParams[&#039;filter&#039;] : &amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;; // If no filter query in url, use default category type&lt;br /&gt;
        var galleryContainer = $(&#039;#card-gallery&#039;);&lt;br /&gt;
        galleryContainer.before(&#039;&amp;lt;div id=&amp;quot;category-filter&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
        var addFilterButton = (cat) =&amp;gt; {&lt;br /&gt;
          var nextBut = µ(&#039;+button&#039;,µ(&#039;#category-filter&#039;));&lt;br /&gt;
          nextBut.id = cat+&#039;-filter-btn&#039;;&lt;br /&gt;
          nextBut.textContent = cat;&lt;br /&gt;
          nextBut.className = &#039;filter-btn&#039;;&lt;br /&gt;
          nextBut.setAttribute(&#039;data-filter&#039;,cat);&lt;br /&gt;
          sortCats.forEach((el,ind)=&amp;gt;{&lt;br /&gt;
            if(el.super == cat &amp;amp;&amp;amp; el.image) µ(&#039;+img&#039;, nextBut).src = el.image;&lt;br /&gt;
          });&lt;br /&gt;
          return nextBut;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var allBut = addFilterButton(&amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;);&lt;br /&gt;
        allBut.textContent = &#039;Show All&#039;;&lt;br /&gt;
&lt;br /&gt;
        superCats.forEach(el=&amp;gt;{&lt;br /&gt;
          addFilterButton(el);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        function hideSpinner(){ $(&#039;#card-gallery .loadDial&#039;).hide()};&lt;br /&gt;
&lt;br /&gt;
        function loadCategory(category,offset){&lt;br /&gt;
            new mw.Api().get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                list: &#039;categorymembers&#039;,&lt;br /&gt;
                cmtitle: &#039;Category:&#039; + category.name,&lt;br /&gt;
                cmlimit: 5,&lt;br /&gt;
                cmcontinue: offset,&lt;br /&gt;
                format: &#039;json&#039;&lt;br /&gt;
            }).done(function (data) {&lt;br /&gt;
                var pages = data.query.categorymembers;&lt;br /&gt;
                var galleryHtml = &#039;&#039;;&lt;br /&gt;
                //console.log(data);&lt;br /&gt;
                if(data.continue) loadCategory(category, data.continue.cmcontinue);&lt;br /&gt;
                pages.forEach(function (page) {&lt;br /&gt;
                    var pageUrl = mw.util.getUrl(page.title);&lt;br /&gt;
                    var imgUrl = &#039;&#039;;&lt;br /&gt;
                    $(&#039;.gallery-container&#039;).append(generateGalleryItem(pageUrl, page.title, imgUrl, category));&lt;br /&gt;
                    //pageTitles.push(page.title);&lt;br /&gt;
                    hideSpinner();&lt;br /&gt;
                    let card = µ(&#039;.gallery-container .gallery-item:last-child img&#039;)[0];&lt;br /&gt;
                    new mw.Api().get({&lt;br /&gt;
                        action: &#039;parse&#039;,&lt;br /&gt;
                        page: page.title&lt;br /&gt;
                    }).done(function (pageData) {&lt;br /&gt;
                        const parser = new DOMParser();&lt;br /&gt;
                        const htmlDoc = parser.parseFromString(pageData.parse.text[&#039;*&#039;], &#039;text/xml&#039;);&lt;br /&gt;
                        let src = /(?:img|figure).*?src=&amp;quot;([^&amp;quot;&#039;]*?)&amp;quot;/.exec(pageData.parse.text[&#039;*&#039;])&lt;br /&gt;
                        console.log(src);&lt;br /&gt;
                        if(src == null) next;&lt;br /&gt;
                        if(src[1] != &#039;null&#039; &amp;amp;&amp;amp; card.src.includes(&amp;quot;No-Image&amp;quot;)) return card.src = src[1];&lt;br /&gt;
&lt;br /&gt;
                        &lt;br /&gt;
                        //card.src = µ(&#039;figure img&#039;,htmlDoc)[0].getAttribute(&#039;src&#039;);&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // load gallery based on category&lt;br /&gt;
        function loadGallery(category) {&lt;br /&gt;
            &lt;br /&gt;
            let pageTitles = [];&lt;br /&gt;
&lt;br /&gt;
            galleryContainer.html(&amp;quot;&amp;lt;div class=&#039;loadDial&#039;&amp;gt;&amp;lt;p&amp;gt;Retrieving Data...&amp;lt;/p&amp;gt;&amp;lt;div class=&#039;loadSpinner&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;);&lt;br /&gt;
            // insert projects corresponding to each skill under broader category filter selected&lt;br /&gt;
            var filterCats = sortCats.filter(el=&amp;gt;el.super == category);&lt;br /&gt;
            if(category == &amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;) filterCats = [{name:&amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;}];&lt;br /&gt;
            filterCats.forEach(function(cat) {&lt;br /&gt;
                loadCategory(cat,0);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // generate a gallery&lt;br /&gt;
        function generateGalleryItem(pageUrl, title, imgUrl, category) {&lt;br /&gt;
            return `&lt;br /&gt;
                &amp;lt;div class=&amp;quot;gallery-item ${category}&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;a href=&amp;quot;${pageUrl}&amp;quot;&amp;gt;&lt;br /&gt;
                        ${imgUrl ? `&amp;lt;img class=&amp;quot;thumbs&amp;quot; src=&amp;quot;${imgUrl}&amp;quot; alt=&amp;quot;${title}&amp;quot;&amp;gt;` : `&amp;lt;img src=&amp;quot;https://upload.wikimedia.org/wikipedia/commons/6/65/No-Image-Placeholder.svg&amp;quot; alt=&amp;quot;No Image Available&amp;quot;&amp;gt;`}&lt;br /&gt;
&lt;br /&gt;
                    &amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;gallery-caption&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a href=&amp;quot;${pageUrl}&amp;quot;&amp;gt;${title}&amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            `;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        loadGallery(Category);&lt;br /&gt;
&lt;br /&gt;
        // find filter button corresponding to selected category and add css class &#039;selected-filter&#039;&lt;br /&gt;
        $(&amp;quot;.filter-btn&amp;quot;).each(function () { $(this).data(&amp;quot;filter&amp;quot;) === Category ? $(this).addClass(&#039;selected-filter&#039;) : null});&lt;br /&gt;
&lt;br /&gt;
        // when filter button is clicked, load projects for that category, deselect current filtered button, and select newly clicked filter button&lt;br /&gt;
        $(&amp;quot;.filter-btn&amp;quot;).click(function () {&lt;br /&gt;
            var selectedCategory = $(this).data(&amp;quot;filter&amp;quot;);&lt;br /&gt;
            loadGallery(selectedCategory);&lt;br /&gt;
            &lt;br /&gt;
            $(&#039;.filter-btn.selected-filter&#039;).each((i, elem) =&amp;gt; $(elem).removeClass(&#039;selected-filter&#039;));&lt;br /&gt;
            $(this).addClass(&#039;selected-filter&#039;);&lt;br /&gt;
        });&lt;br /&gt;
    });&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
if(!window.widgets) window.widgets = [];&lt;br /&gt;
window.widgets.push(cardWidgetStart);&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
  .filter-btn img{&lt;br /&gt;
    height:1.5em;&lt;br /&gt;
    padding-left:.4em;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
.gallery-item {&lt;br /&gt;
    width: 20%;&lt;br /&gt;
    min-width:200px;&lt;br /&gt;
    max-width: 30vw;&lt;br /&gt;
    margin: 10px;&lt;br /&gt;
    flex-grow: 2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.loadDial {&lt;br /&gt;
  width: 100%;&lt;br /&gt;
  text-align: center;&lt;br /&gt;
  p {&lt;br /&gt;
    font-weight: bolder;&lt;br /&gt;
    font-size: x-large;&lt;br /&gt;
    color: #666;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;card-gallery&amp;quot; class=&amp;quot;gallery-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Widget:CardGallery&amp;diff=9567</id>
		<title>Widget:CardGallery</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Widget:CardGallery&amp;diff=9567"/>
		<updated>2025-06-21T15:55:15Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;script&amp;gt;&lt;br /&gt;
var cardWidget = {};&lt;br /&gt;
&lt;br /&gt;
cardWidgetStart = function () {&lt;br /&gt;
    $(document).ready(function () {&lt;br /&gt;
        var sortCats = window[&amp;quot;&amp;lt;!--{$category|escape:&#039;url&#039;}--&amp;gt;&amp;quot;];&lt;br /&gt;
        var superCats = Array.from(new Set(sortCats.map(x=&amp;gt;x.super)));&lt;br /&gt;
        var Category = pageParams[&#039;filter&#039;] ? pageParams[&#039;filter&#039;] : &amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;; // If no filter query in url, use default category type&lt;br /&gt;
        var galleryContainer = $(&#039;#card-gallery&#039;);&lt;br /&gt;
        galleryContainer.before(&#039;&amp;lt;div id=&amp;quot;category-filter&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
        var addFilterButton = (cat) =&amp;gt; {&lt;br /&gt;
          var nextBut = µ(&#039;+button&#039;,µ(&#039;#category-filter&#039;));&lt;br /&gt;
          nextBut.id = cat+&#039;-filter-btn&#039;;&lt;br /&gt;
          nextBut.textContent = cat;&lt;br /&gt;
          nextBut.className = &#039;filter-btn&#039;;&lt;br /&gt;
          nextBut.setAttribute(&#039;data-filter&#039;,cat);&lt;br /&gt;
          sortCats.forEach((el,ind)=&amp;gt;{&lt;br /&gt;
            if(el.super == cat &amp;amp;&amp;amp; el.image) µ(&#039;+img&#039;, nextBut).src = el.image;&lt;br /&gt;
          });&lt;br /&gt;
          return nextBut;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var allBut = addFilterButton(&amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;);&lt;br /&gt;
        allBut.textContent = &#039;Show All&#039;;&lt;br /&gt;
&lt;br /&gt;
        superCats.forEach(el=&amp;gt;{&lt;br /&gt;
          addFilterButton(el);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        function hideSpinner(){ $(&#039;#card-gallery .loadDial&#039;).hide()};&lt;br /&gt;
&lt;br /&gt;
        function loadCategory(category,offset){&lt;br /&gt;
            new mw.Api().get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                list: &#039;categorymembers&#039;,&lt;br /&gt;
                cmtitle: &#039;Category:&#039; + category.name,&lt;br /&gt;
                cmlimit: 5,&lt;br /&gt;
                cmcontinue: offset,&lt;br /&gt;
                format: &#039;json&#039;&lt;br /&gt;
            }).done(function (data) {&lt;br /&gt;
                var pages = data.query.categorymembers;&lt;br /&gt;
                var galleryHtml = &#039;&#039;;&lt;br /&gt;
                //console.log(data);&lt;br /&gt;
                if(data.continue) loadCategory(category, data.continue.cmcontinue);&lt;br /&gt;
                pages.forEach(function (page) {&lt;br /&gt;
                    var pageUrl = mw.util.getUrl(page.title);&lt;br /&gt;
                    var imgUrl = &#039;&#039;;&lt;br /&gt;
                    $(&#039;.gallery-container&#039;).append(generateGalleryItem(pageUrl, page.title, imgUrl, category));&lt;br /&gt;
                    //pageTitles.push(page.title);&lt;br /&gt;
                    hideSpinner();&lt;br /&gt;
                    let card = µ(&#039;.gallery-container .gallery-item:last-child img&#039;)[0];&lt;br /&gt;
                    new mw.Api().get({&lt;br /&gt;
                        action: &#039;parse&#039;,&lt;br /&gt;
                        page: page.title&lt;br /&gt;
                    }).done(function (pageData) {&lt;br /&gt;
                        const parser = new DOMParser();&lt;br /&gt;
                        const htmlDoc = parser.parseFromString(pageData.parse.text[&#039;*&#039;], &#039;text/xml&#039;);&lt;br /&gt;
                        let src = /(?:img|figure).*?src=&amp;quot;([^&amp;quot;&#039;]*?)&amp;quot;/.exec(pageData.parse.text[&#039;*&#039;])&lt;br /&gt;
                        console.log(src);&lt;br /&gt;
                        if(src[1] != &#039;null&#039; &amp;amp;&amp;amp; card.src.includes(&amp;quot;No-Image&amp;quot;)) return card.src = src[1];&lt;br /&gt;
                        &lt;br /&gt;
                        //card.src = µ(&#039;figure img&#039;,htmlDoc)[0].getAttribute(&#039;src&#039;);&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // load gallery based on category&lt;br /&gt;
        function loadGallery(category) {&lt;br /&gt;
            &lt;br /&gt;
            let pageTitles = [];&lt;br /&gt;
&lt;br /&gt;
            galleryContainer.html(&amp;quot;&amp;lt;div class=&#039;loadDial&#039;&amp;gt;&amp;lt;p&amp;gt;Retrieving Data...&amp;lt;/p&amp;gt;&amp;lt;div class=&#039;loadSpinner&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;);&lt;br /&gt;
            // insert projects corresponding to each skill under broader category filter selected&lt;br /&gt;
            var filterCats = sortCats.filter(el=&amp;gt;el.super == category);&lt;br /&gt;
            if(category == &amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;) filterCats = [{name:&amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;}];&lt;br /&gt;
            filterCats.forEach(function(cat) {&lt;br /&gt;
                loadCategory(cat,0);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // generate a gallery&lt;br /&gt;
        function generateGalleryItem(pageUrl, title, imgUrl, category) {&lt;br /&gt;
            return `&lt;br /&gt;
                &amp;lt;div class=&amp;quot;gallery-item ${category}&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;a href=&amp;quot;${pageUrl}&amp;quot;&amp;gt;&lt;br /&gt;
                        ${imgUrl ? `&amp;lt;img class=&amp;quot;thumbs&amp;quot; src=&amp;quot;${imgUrl}&amp;quot; alt=&amp;quot;${title}&amp;quot;&amp;gt;` : `&amp;lt;img src=&amp;quot;https://upload.wikimedia.org/wikipedia/commons/6/65/No-Image-Placeholder.svg&amp;quot; alt=&amp;quot;No Image Available&amp;quot;&amp;gt;`}&lt;br /&gt;
&lt;br /&gt;
                    &amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;gallery-caption&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a href=&amp;quot;${pageUrl}&amp;quot;&amp;gt;${title}&amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            `;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        loadGallery(Category);&lt;br /&gt;
&lt;br /&gt;
        // find filter button corresponding to selected category and add css class &#039;selected-filter&#039;&lt;br /&gt;
        $(&amp;quot;.filter-btn&amp;quot;).each(function () { $(this).data(&amp;quot;filter&amp;quot;) === Category ? $(this).addClass(&#039;selected-filter&#039;) : null});&lt;br /&gt;
&lt;br /&gt;
        // when filter button is clicked, load projects for that category, deselect current filtered button, and select newly clicked filter button&lt;br /&gt;
        $(&amp;quot;.filter-btn&amp;quot;).click(function () {&lt;br /&gt;
            var selectedCategory = $(this).data(&amp;quot;filter&amp;quot;);&lt;br /&gt;
            loadGallery(selectedCategory);&lt;br /&gt;
            &lt;br /&gt;
            $(&#039;.filter-btn.selected-filter&#039;).each((i, elem) =&amp;gt; $(elem).removeClass(&#039;selected-filter&#039;));&lt;br /&gt;
            $(this).addClass(&#039;selected-filter&#039;);&lt;br /&gt;
        });&lt;br /&gt;
    });&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
if(!window.widgets) window.widgets = [];&lt;br /&gt;
window.widgets.push(cardWidgetStart);&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
  .filter-btn img{&lt;br /&gt;
    height:1.5em;&lt;br /&gt;
    padding-left:.4em;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
.gallery-item {&lt;br /&gt;
    width: 20%;&lt;br /&gt;
    min-width:200px;&lt;br /&gt;
    max-width: 30vw;&lt;br /&gt;
    margin: 10px;&lt;br /&gt;
    flex-grow: 2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.loadDial {&lt;br /&gt;
  width: 100%;&lt;br /&gt;
  text-align: center;&lt;br /&gt;
  p {&lt;br /&gt;
    font-weight: bolder;&lt;br /&gt;
    font-size: x-large;&lt;br /&gt;
    color: #666;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;card-gallery&amp;quot; class=&amp;quot;gallery-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Widget:CardGallery&amp;diff=9566</id>
		<title>Widget:CardGallery</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Widget:CardGallery&amp;diff=9566"/>
		<updated>2025-06-21T15:48:20Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;script&amp;gt;&lt;br /&gt;
var cardWidget = {};&lt;br /&gt;
&lt;br /&gt;
cardWidgetStart = function () {&lt;br /&gt;
    $(document).ready(function () {&lt;br /&gt;
        var sortCats = window[&amp;quot;&amp;lt;!--{$category|escape:&#039;url&#039;}--&amp;gt;&amp;quot;];&lt;br /&gt;
        var superCats = Array.from(new Set(sortCats.map(x=&amp;gt;x.super)));&lt;br /&gt;
        var Category = pageParams[&#039;filter&#039;] ? pageParams[&#039;filter&#039;] : &amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;; // If no filter query in url, use default category type&lt;br /&gt;
        var galleryContainer = $(&#039;#card-gallery&#039;);&lt;br /&gt;
        galleryContainer.before(&#039;&amp;lt;div id=&amp;quot;category-filter&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
        var addFilterButton = (cat) =&amp;gt; {&lt;br /&gt;
          var nextBut = µ(&#039;+button&#039;,µ(&#039;#category-filter&#039;));&lt;br /&gt;
          nextBut.id = cat+&#039;-filter-btn&#039;;&lt;br /&gt;
          nextBut.textContent = cat;&lt;br /&gt;
          nextBut.className = &#039;filter-btn&#039;;&lt;br /&gt;
          nextBut.setAttribute(&#039;data-filter&#039;,cat);&lt;br /&gt;
          sortCats.forEach((el,ind)=&amp;gt;{&lt;br /&gt;
            if(el.super == cat &amp;amp;&amp;amp; el.image) µ(&#039;+img&#039;, nextBut).src = el.image;&lt;br /&gt;
          });&lt;br /&gt;
          return nextBut;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var allBut = addFilterButton(&amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;);&lt;br /&gt;
        allBut.textContent = &#039;Show All&#039;;&lt;br /&gt;
&lt;br /&gt;
        superCats.forEach(el=&amp;gt;{&lt;br /&gt;
          addFilterButton(el);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        function hideSpinner(){ $(&#039;#card-gallery .loadDial&#039;).hide()};&lt;br /&gt;
&lt;br /&gt;
        function loadCategory(category,offset){&lt;br /&gt;
            new mw.Api().get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                list: &#039;categorymembers&#039;,&lt;br /&gt;
                cmtitle: &#039;Category:&#039; + category.name,&lt;br /&gt;
                cmlimit: 5,&lt;br /&gt;
                cmcontinue: offset,&lt;br /&gt;
                format: &#039;json&#039;&lt;br /&gt;
            }).done(function (data) {&lt;br /&gt;
                var pages = data.query.categorymembers;&lt;br /&gt;
                var galleryHtml = &#039;&#039;;&lt;br /&gt;
                //console.log(data);&lt;br /&gt;
                if(data.continue) loadCategory(category, data.continue.cmcontinue);&lt;br /&gt;
                pages.forEach(function (page) {&lt;br /&gt;
                    var pageUrl = mw.util.getUrl(page.title);&lt;br /&gt;
                    var imgUrl = &#039;&#039;;&lt;br /&gt;
                    $(&#039;.gallery-container&#039;).append(generateGalleryItem(pageUrl, page.title, imgUrl, category));&lt;br /&gt;
                    //pageTitles.push(page.title);&lt;br /&gt;
                    hideSpinner();&lt;br /&gt;
                    let card = µ(&#039;.gallery-container .gallery-item:last-child img&#039;)[0];&lt;br /&gt;
                    new mw.Api().get({&lt;br /&gt;
                        action: &#039;parse&#039;,&lt;br /&gt;
                        page: page.title&lt;br /&gt;
                    }).done(function (pageData) {&lt;br /&gt;
                        const parser = new DOMParser();&lt;br /&gt;
                        const htmlDoc = parser.parseFromString(pageData.parse.text[&#039;*&#039;], &#039;text/xml&#039;);&lt;br /&gt;
                        let src = /src=&amp;quot;([^&amp;quot;&#039;]*?(?:\.jpg|\.png|\.webp))&amp;quot;/.exec(pageData.parse.text[&#039;*&#039;])&lt;br /&gt;
                        console.log(src);&lt;br /&gt;
                        if(src[1] != &#039;null&#039; &amp;amp;&amp;amp; card.src.includes(&amp;quot;No-Image&amp;quot;)) return card.src = src[1];&lt;br /&gt;
                        &lt;br /&gt;
                        //card.src = µ(&#039;figure img&#039;,htmlDoc)[0].getAttribute(&#039;src&#039;);&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // load gallery based on category&lt;br /&gt;
        function loadGallery(category) {&lt;br /&gt;
            &lt;br /&gt;
            let pageTitles = [];&lt;br /&gt;
&lt;br /&gt;
            galleryContainer.html(&amp;quot;&amp;lt;div class=&#039;loadDial&#039;&amp;gt;&amp;lt;p&amp;gt;Retrieving Data...&amp;lt;/p&amp;gt;&amp;lt;div class=&#039;loadSpinner&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;);&lt;br /&gt;
            // insert projects corresponding to each skill under broader category filter selected&lt;br /&gt;
            var filterCats = sortCats.filter(el=&amp;gt;el.super == category);&lt;br /&gt;
            if(category == &amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;) filterCats = [{name:&amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;}];&lt;br /&gt;
            filterCats.forEach(function(cat) {&lt;br /&gt;
                loadCategory(cat,0);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // generate a gallery&lt;br /&gt;
        function generateGalleryItem(pageUrl, title, imgUrl, category) {&lt;br /&gt;
            return `&lt;br /&gt;
                &amp;lt;div class=&amp;quot;gallery-item ${category}&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;a href=&amp;quot;${pageUrl}&amp;quot;&amp;gt;&lt;br /&gt;
                        ${imgUrl ? `&amp;lt;img class=&amp;quot;thumbs&amp;quot; src=&amp;quot;${imgUrl}&amp;quot; alt=&amp;quot;${title}&amp;quot;&amp;gt;` : `&amp;lt;img src=&amp;quot;https://upload.wikimedia.org/wikipedia/commons/6/65/No-Image-Placeholder.svg&amp;quot; alt=&amp;quot;No Image Available&amp;quot;&amp;gt;`}&lt;br /&gt;
&lt;br /&gt;
                    &amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;gallery-caption&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a href=&amp;quot;${pageUrl}&amp;quot;&amp;gt;${title}&amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            `;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        loadGallery(Category);&lt;br /&gt;
&lt;br /&gt;
        // find filter button corresponding to selected category and add css class &#039;selected-filter&#039;&lt;br /&gt;
        $(&amp;quot;.filter-btn&amp;quot;).each(function () { $(this).data(&amp;quot;filter&amp;quot;) === Category ? $(this).addClass(&#039;selected-filter&#039;) : null});&lt;br /&gt;
&lt;br /&gt;
        // when filter button is clicked, load projects for that category, deselect current filtered button, and select newly clicked filter button&lt;br /&gt;
        $(&amp;quot;.filter-btn&amp;quot;).click(function () {&lt;br /&gt;
            var selectedCategory = $(this).data(&amp;quot;filter&amp;quot;);&lt;br /&gt;
            loadGallery(selectedCategory);&lt;br /&gt;
            &lt;br /&gt;
            $(&#039;.filter-btn.selected-filter&#039;).each((i, elem) =&amp;gt; $(elem).removeClass(&#039;selected-filter&#039;));&lt;br /&gt;
            $(this).addClass(&#039;selected-filter&#039;);&lt;br /&gt;
        });&lt;br /&gt;
    });&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
if(!window.widgets) window.widgets = [];&lt;br /&gt;
window.widgets.push(cardWidgetStart);&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
  .filter-btn img{&lt;br /&gt;
    height:1.5em;&lt;br /&gt;
    padding-left:.4em;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
.gallery-item {&lt;br /&gt;
    width: 20%;&lt;br /&gt;
    min-width:200px;&lt;br /&gt;
    max-width: 30vw;&lt;br /&gt;
    margin: 10px;&lt;br /&gt;
    flex-grow: 2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.loadDial {&lt;br /&gt;
  width: 100%;&lt;br /&gt;
  text-align: center;&lt;br /&gt;
  p {&lt;br /&gt;
    font-weight: bolder;&lt;br /&gt;
    font-size: x-large;&lt;br /&gt;
    color: #666;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;card-gallery&amp;quot; class=&amp;quot;gallery-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Widget:CardGallery&amp;diff=9565</id>
		<title>Widget:CardGallery</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Widget:CardGallery&amp;diff=9565"/>
		<updated>2025-06-21T15:45:47Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;script&amp;gt;&lt;br /&gt;
var cardWidget = {};&lt;br /&gt;
&lt;br /&gt;
cardWidgetStart = function () {&lt;br /&gt;
    $(document).ready(function () {&lt;br /&gt;
        var sortCats = window[&amp;quot;&amp;lt;!--{$category|escape:&#039;url&#039;}--&amp;gt;&amp;quot;];&lt;br /&gt;
        var superCats = Array.from(new Set(sortCats.map(x=&amp;gt;x.super)));&lt;br /&gt;
        var Category = pageParams[&#039;filter&#039;] ? pageParams[&#039;filter&#039;] : &amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;; // If no filter query in url, use default category type&lt;br /&gt;
        var galleryContainer = $(&#039;#card-gallery&#039;);&lt;br /&gt;
        galleryContainer.before(&#039;&amp;lt;div id=&amp;quot;category-filter&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
        var addFilterButton = (cat) =&amp;gt; {&lt;br /&gt;
          var nextBut = µ(&#039;+button&#039;,µ(&#039;#category-filter&#039;));&lt;br /&gt;
          nextBut.id = cat+&#039;-filter-btn&#039;;&lt;br /&gt;
          nextBut.textContent = cat;&lt;br /&gt;
          nextBut.className = &#039;filter-btn&#039;;&lt;br /&gt;
          nextBut.setAttribute(&#039;data-filter&#039;,cat);&lt;br /&gt;
          sortCats.forEach((el,ind)=&amp;gt;{&lt;br /&gt;
            if(el.super == cat &amp;amp;&amp;amp; el.image) µ(&#039;+img&#039;, nextBut).src = el.image;&lt;br /&gt;
          });&lt;br /&gt;
          return nextBut;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var allBut = addFilterButton(&amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;);&lt;br /&gt;
        allBut.textContent = &#039;Show All&#039;;&lt;br /&gt;
&lt;br /&gt;
        superCats.forEach(el=&amp;gt;{&lt;br /&gt;
          addFilterButton(el);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        function hideSpinner(){ $(&#039;#card-gallery .loadDial&#039;).hide()};&lt;br /&gt;
&lt;br /&gt;
        function loadCategory(category,offset){&lt;br /&gt;
            new mw.Api().get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                list: &#039;categorymembers&#039;,&lt;br /&gt;
                cmtitle: &#039;Category:&#039; + category.name,&lt;br /&gt;
                cmlimit: 5,&lt;br /&gt;
                cmcontinue: offset,&lt;br /&gt;
                format: &#039;json&#039;&lt;br /&gt;
            }).done(function (data) {&lt;br /&gt;
                var pages = data.query.categorymembers;&lt;br /&gt;
                var galleryHtml = &#039;&#039;;&lt;br /&gt;
                //console.log(data);&lt;br /&gt;
                if(data.continue) loadCategory(category, data.continue.cmcontinue);&lt;br /&gt;
                pages.forEach(function (page) {&lt;br /&gt;
                    var pageUrl = mw.util.getUrl(page.title);&lt;br /&gt;
                    var imgUrl = &#039;&#039;;&lt;br /&gt;
                    $(&#039;.gallery-container&#039;).append(generateGalleryItem(pageUrl, page.title, imgUrl, category));&lt;br /&gt;
                    //pageTitles.push(page.title);&lt;br /&gt;
                    hideSpinner();&lt;br /&gt;
                    let card = µ(&#039;.gallery-container .gallery-item:last-child img&#039;)[0];&lt;br /&gt;
                    new mw.Api().get({&lt;br /&gt;
                        action: &#039;parse&#039;,&lt;br /&gt;
                        page: page.title&lt;br /&gt;
                    }).done(function (pageData) {&lt;br /&gt;
                        const parser = new DOMParser();&lt;br /&gt;
                        const htmlDoc = parser.parseFromString(pageData.parse.text[&#039;*&#039;], &#039;text/xml&#039;);&lt;br /&gt;
                        let src = /src=&amp;quot;(.*?)&amp;quot;/.exec(pageData.parse.text[&#039;*&#039;])&lt;br /&gt;
                        console.log(src);&lt;br /&gt;
                        if(src[1] != &#039;null&#039; &amp;amp;&amp;amp; card.src.includes(&amp;quot;No-Image&amp;quot;)) return card.src = src[1];&lt;br /&gt;
                        &lt;br /&gt;
                        //card.src = µ(&#039;figure img&#039;,htmlDoc)[0].getAttribute(&#039;src&#039;);&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // load gallery based on category&lt;br /&gt;
        function loadGallery(category) {&lt;br /&gt;
            &lt;br /&gt;
            let pageTitles = [];&lt;br /&gt;
&lt;br /&gt;
            galleryContainer.html(&amp;quot;&amp;lt;div class=&#039;loadDial&#039;&amp;gt;&amp;lt;p&amp;gt;Retrieving Data...&amp;lt;/p&amp;gt;&amp;lt;div class=&#039;loadSpinner&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;);&lt;br /&gt;
            // insert projects corresponding to each skill under broader category filter selected&lt;br /&gt;
            var filterCats = sortCats.filter(el=&amp;gt;el.super == category);&lt;br /&gt;
            if(category == &amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;) filterCats = [{name:&amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;}];&lt;br /&gt;
            filterCats.forEach(function(cat) {&lt;br /&gt;
                loadCategory(cat,0);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // generate a gallery&lt;br /&gt;
        function generateGalleryItem(pageUrl, title, imgUrl, category) {&lt;br /&gt;
            return `&lt;br /&gt;
                &amp;lt;div class=&amp;quot;gallery-item ${category}&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;a href=&amp;quot;${pageUrl}&amp;quot;&amp;gt;&lt;br /&gt;
                        ${imgUrl ? `&amp;lt;img class=&amp;quot;thumbs&amp;quot; src=&amp;quot;${imgUrl}&amp;quot; alt=&amp;quot;${title}&amp;quot;&amp;gt;` : `&amp;lt;img src=&amp;quot;https://upload.wikimedia.org/wikipedia/commons/6/65/No-Image-Placeholder.svg&amp;quot; alt=&amp;quot;No Image Available&amp;quot;&amp;gt;`}&lt;br /&gt;
&lt;br /&gt;
                    &amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;gallery-caption&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a href=&amp;quot;${pageUrl}&amp;quot;&amp;gt;${title}&amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            `;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        loadGallery(Category);&lt;br /&gt;
&lt;br /&gt;
        // find filter button corresponding to selected category and add css class &#039;selected-filter&#039;&lt;br /&gt;
        $(&amp;quot;.filter-btn&amp;quot;).each(function () { $(this).data(&amp;quot;filter&amp;quot;) === Category ? $(this).addClass(&#039;selected-filter&#039;) : null});&lt;br /&gt;
&lt;br /&gt;
        // when filter button is clicked, load projects for that category, deselect current filtered button, and select newly clicked filter button&lt;br /&gt;
        $(&amp;quot;.filter-btn&amp;quot;).click(function () {&lt;br /&gt;
            var selectedCategory = $(this).data(&amp;quot;filter&amp;quot;);&lt;br /&gt;
            loadGallery(selectedCategory);&lt;br /&gt;
            &lt;br /&gt;
            $(&#039;.filter-btn.selected-filter&#039;).each((i, elem) =&amp;gt; $(elem).removeClass(&#039;selected-filter&#039;));&lt;br /&gt;
            $(this).addClass(&#039;selected-filter&#039;);&lt;br /&gt;
        });&lt;br /&gt;
    });&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
if(!window.widgets) window.widgets = [];&lt;br /&gt;
window.widgets.push(cardWidgetStart);&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
  .filter-btn img{&lt;br /&gt;
    height:1.5em;&lt;br /&gt;
    padding-left:.4em;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
.gallery-item {&lt;br /&gt;
    width: 20%;&lt;br /&gt;
    min-width:200px;&lt;br /&gt;
    max-width: 30vw;&lt;br /&gt;
    margin: 10px;&lt;br /&gt;
    flex-grow: 2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.loadDial {&lt;br /&gt;
  width: 100%;&lt;br /&gt;
  text-align: center;&lt;br /&gt;
  p {&lt;br /&gt;
    font-weight: bolder;&lt;br /&gt;
    font-size: x-large;&lt;br /&gt;
    color: #666;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;card-gallery&amp;quot; class=&amp;quot;gallery-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Widget:CardGallery&amp;diff=9564</id>
		<title>Widget:CardGallery</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Widget:CardGallery&amp;diff=9564"/>
		<updated>2025-06-21T15:43:53Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;script&amp;gt;&lt;br /&gt;
var cardWidget = {};&lt;br /&gt;
&lt;br /&gt;
cardWidgetStart = function () {&lt;br /&gt;
    $(document).ready(function () {&lt;br /&gt;
        var sortCats = window[&amp;quot;&amp;lt;!--{$category|escape:&#039;url&#039;}--&amp;gt;&amp;quot;];&lt;br /&gt;
        var superCats = Array.from(new Set(sortCats.map(x=&amp;gt;x.super)));&lt;br /&gt;
        var Category = pageParams[&#039;filter&#039;] ? pageParams[&#039;filter&#039;] : &amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;; // If no filter query in url, use default category type&lt;br /&gt;
        var galleryContainer = $(&#039;#card-gallery&#039;);&lt;br /&gt;
        galleryContainer.before(&#039;&amp;lt;div id=&amp;quot;category-filter&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
        var addFilterButton = (cat) =&amp;gt; {&lt;br /&gt;
          var nextBut = µ(&#039;+button&#039;,µ(&#039;#category-filter&#039;));&lt;br /&gt;
          nextBut.id = cat+&#039;-filter-btn&#039;;&lt;br /&gt;
          nextBut.textContent = cat;&lt;br /&gt;
          nextBut.className = &#039;filter-btn&#039;;&lt;br /&gt;
          nextBut.setAttribute(&#039;data-filter&#039;,cat);&lt;br /&gt;
          sortCats.forEach((el,ind)=&amp;gt;{&lt;br /&gt;
            if(el.super == cat &amp;amp;&amp;amp; el.image) µ(&#039;+img&#039;, nextBut).src = el.image;&lt;br /&gt;
          });&lt;br /&gt;
          return nextBut;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var allBut = addFilterButton(&amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;);&lt;br /&gt;
        allBut.textContent = &#039;Show All&#039;;&lt;br /&gt;
&lt;br /&gt;
        superCats.forEach(el=&amp;gt;{&lt;br /&gt;
          addFilterButton(el);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        function hideSpinner(){ $(&#039;#card-gallery .loadDial&#039;).hide()};&lt;br /&gt;
&lt;br /&gt;
        function loadCategory(category,offset){&lt;br /&gt;
            new mw.Api().get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                list: &#039;categorymembers&#039;,&lt;br /&gt;
                cmtitle: &#039;Category:&#039; + category.name,&lt;br /&gt;
                cmlimit: 5,&lt;br /&gt;
                cmcontinue: offset,&lt;br /&gt;
                format: &#039;json&#039;&lt;br /&gt;
            }).done(function (data) {&lt;br /&gt;
                var pages = data.query.categorymembers;&lt;br /&gt;
                var galleryHtml = &#039;&#039;;&lt;br /&gt;
                //console.log(data);&lt;br /&gt;
                if(data.continue) loadCategory(category, data.continue.cmcontinue);&lt;br /&gt;
                pages.forEach(function (page) {&lt;br /&gt;
                    var pageUrl = mw.util.getUrl(page.title);&lt;br /&gt;
                    var imgUrl = &#039;&#039;;&lt;br /&gt;
                    $(&#039;.gallery-container&#039;).append(generateGalleryItem(pageUrl, page.title, imgUrl, category));&lt;br /&gt;
                    //pageTitles.push(page.title);&lt;br /&gt;
                    hideSpinner();&lt;br /&gt;
                    let card = µ(&#039;.gallery-container .gallery-item:last-child img&#039;)[0];&lt;br /&gt;
                    new mw.Api().get({&lt;br /&gt;
                        action: &#039;parse&#039;,&lt;br /&gt;
                        page: page.title&lt;br /&gt;
                    }).done(function (pageData) {&lt;br /&gt;
                        const parser = new DOMParser();&lt;br /&gt;
                        const htmlDoc = parser.parseFromString(pageData.parse.text[&#039;*&#039;], &#039;text/xml&#039;);&lt;br /&gt;
                        let src = /src=&amp;quot;(.*?)&amp;quot;/.exec(pageData.parse.text[&#039;*&#039;])&lt;br /&gt;
                        console.log(src);&lt;br /&gt;
                        if(src[1] != &#039;null&#039; &amp;amp;&amp;amp; card.src.includes(&amp;quot;No-Image&amp;quot;)) return card.src = src;&lt;br /&gt;
                        &lt;br /&gt;
                        //card.src = µ(&#039;figure img&#039;,htmlDoc)[0].getAttribute(&#039;src&#039;);&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // load gallery based on category&lt;br /&gt;
        function loadGallery(category) {&lt;br /&gt;
            &lt;br /&gt;
            let pageTitles = [];&lt;br /&gt;
&lt;br /&gt;
            galleryContainer.html(&amp;quot;&amp;lt;div class=&#039;loadDial&#039;&amp;gt;&amp;lt;p&amp;gt;Retrieving Data...&amp;lt;/p&amp;gt;&amp;lt;div class=&#039;loadSpinner&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;);&lt;br /&gt;
            // insert projects corresponding to each skill under broader category filter selected&lt;br /&gt;
            var filterCats = sortCats.filter(el=&amp;gt;el.super == category);&lt;br /&gt;
            if(category == &amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;) filterCats = [{name:&amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;}];&lt;br /&gt;
            filterCats.forEach(function(cat) {&lt;br /&gt;
                loadCategory(cat,0);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // generate a gallery&lt;br /&gt;
        function generateGalleryItem(pageUrl, title, imgUrl, category) {&lt;br /&gt;
            return `&lt;br /&gt;
                &amp;lt;div class=&amp;quot;gallery-item ${category}&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;a href=&amp;quot;${pageUrl}&amp;quot;&amp;gt;&lt;br /&gt;
                        ${imgUrl ? `&amp;lt;img class=&amp;quot;thumbs&amp;quot; src=&amp;quot;${imgUrl}&amp;quot; alt=&amp;quot;${title}&amp;quot;&amp;gt;` : `&amp;lt;img src=&amp;quot;https://upload.wikimedia.org/wikipedia/commons/6/65/No-Image-Placeholder.svg&amp;quot; alt=&amp;quot;No Image Available&amp;quot;&amp;gt;`}&lt;br /&gt;
&lt;br /&gt;
                    &amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;gallery-caption&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a href=&amp;quot;${pageUrl}&amp;quot;&amp;gt;${title}&amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            `;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        loadGallery(Category);&lt;br /&gt;
&lt;br /&gt;
        // find filter button corresponding to selected category and add css class &#039;selected-filter&#039;&lt;br /&gt;
        $(&amp;quot;.filter-btn&amp;quot;).each(function () { $(this).data(&amp;quot;filter&amp;quot;) === Category ? $(this).addClass(&#039;selected-filter&#039;) : null});&lt;br /&gt;
&lt;br /&gt;
        // when filter button is clicked, load projects for that category, deselect current filtered button, and select newly clicked filter button&lt;br /&gt;
        $(&amp;quot;.filter-btn&amp;quot;).click(function () {&lt;br /&gt;
            var selectedCategory = $(this).data(&amp;quot;filter&amp;quot;);&lt;br /&gt;
            loadGallery(selectedCategory);&lt;br /&gt;
            &lt;br /&gt;
            $(&#039;.filter-btn.selected-filter&#039;).each((i, elem) =&amp;gt; $(elem).removeClass(&#039;selected-filter&#039;));&lt;br /&gt;
            $(this).addClass(&#039;selected-filter&#039;);&lt;br /&gt;
        });&lt;br /&gt;
    });&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
if(!window.widgets) window.widgets = [];&lt;br /&gt;
window.widgets.push(cardWidgetStart);&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
  .filter-btn img{&lt;br /&gt;
    height:1.5em;&lt;br /&gt;
    padding-left:.4em;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
.gallery-item {&lt;br /&gt;
    width: 20%;&lt;br /&gt;
    min-width:200px;&lt;br /&gt;
    max-width: 30vw;&lt;br /&gt;
    margin: 10px;&lt;br /&gt;
    flex-grow: 2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.loadDial {&lt;br /&gt;
  width: 100%;&lt;br /&gt;
  text-align: center;&lt;br /&gt;
  p {&lt;br /&gt;
    font-weight: bolder;&lt;br /&gt;
    font-size: x-large;&lt;br /&gt;
    color: #666;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;card-gallery&amp;quot; class=&amp;quot;gallery-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Widget:CardGallery&amp;diff=9563</id>
		<title>Widget:CardGallery</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Widget:CardGallery&amp;diff=9563"/>
		<updated>2025-06-21T15:42:30Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;script&amp;gt;&lt;br /&gt;
var cardWidget = {};&lt;br /&gt;
&lt;br /&gt;
cardWidgetStart = function () {&lt;br /&gt;
    $(document).ready(function () {&lt;br /&gt;
        var sortCats = window[&amp;quot;&amp;lt;!--{$category|escape:&#039;url&#039;}--&amp;gt;&amp;quot;];&lt;br /&gt;
        var superCats = Array.from(new Set(sortCats.map(x=&amp;gt;x.super)));&lt;br /&gt;
        var Category = pageParams[&#039;filter&#039;] ? pageParams[&#039;filter&#039;] : &amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;; // If no filter query in url, use default category type&lt;br /&gt;
        var galleryContainer = $(&#039;#card-gallery&#039;);&lt;br /&gt;
        galleryContainer.before(&#039;&amp;lt;div id=&amp;quot;category-filter&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
        var addFilterButton = (cat) =&amp;gt; {&lt;br /&gt;
          var nextBut = µ(&#039;+button&#039;,µ(&#039;#category-filter&#039;));&lt;br /&gt;
          nextBut.id = cat+&#039;-filter-btn&#039;;&lt;br /&gt;
          nextBut.textContent = cat;&lt;br /&gt;
          nextBut.className = &#039;filter-btn&#039;;&lt;br /&gt;
          nextBut.setAttribute(&#039;data-filter&#039;,cat);&lt;br /&gt;
          sortCats.forEach((el,ind)=&amp;gt;{&lt;br /&gt;
            if(el.super == cat &amp;amp;&amp;amp; el.image) µ(&#039;+img&#039;, nextBut).src = el.image;&lt;br /&gt;
          });&lt;br /&gt;
          return nextBut;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var allBut = addFilterButton(&amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;);&lt;br /&gt;
        allBut.textContent = &#039;Show All&#039;;&lt;br /&gt;
&lt;br /&gt;
        superCats.forEach(el=&amp;gt;{&lt;br /&gt;
          addFilterButton(el);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        function hideSpinner(){ $(&#039;#card-gallery .loadDial&#039;).hide()};&lt;br /&gt;
&lt;br /&gt;
        function loadCategory(category,offset){&lt;br /&gt;
            new mw.Api().get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                list: &#039;categorymembers&#039;,&lt;br /&gt;
                cmtitle: &#039;Category:&#039; + category.name,&lt;br /&gt;
                cmlimit: 5,&lt;br /&gt;
                cmcontinue: offset,&lt;br /&gt;
                format: &#039;json&#039;&lt;br /&gt;
            }).done(function (data) {&lt;br /&gt;
                var pages = data.query.categorymembers;&lt;br /&gt;
                var galleryHtml = &#039;&#039;;&lt;br /&gt;
                //console.log(data);&lt;br /&gt;
                if(data.continue) loadCategory(category, data.continue.cmcontinue);&lt;br /&gt;
                pages.forEach(function (page) {&lt;br /&gt;
                    var pageUrl = mw.util.getUrl(page.title);&lt;br /&gt;
                    var imgUrl = &#039;&#039;;&lt;br /&gt;
                    $(&#039;.gallery-container&#039;).append(generateGalleryItem(pageUrl, page.title, imgUrl, category));&lt;br /&gt;
                    //pageTitles.push(page.title);&lt;br /&gt;
                    hideSpinner();&lt;br /&gt;
                    let card = µ(&#039;.gallery-container .gallery-item:last-child img&#039;)[0];&lt;br /&gt;
                    new mw.Api().get({&lt;br /&gt;
                        action: &#039;parse&#039;,&lt;br /&gt;
                        page: page.title&lt;br /&gt;
                    }).done(function (pageData) {&lt;br /&gt;
                        const parser = new DOMParser();&lt;br /&gt;
                        const htmlDoc = parser.parseFromString(pageData.parse.text[&#039;*&#039;], &#039;text/xml&#039;);&lt;br /&gt;
                        let src = /&amp;quot;(.*?)&amp;quot;/.exec(pageData.parse.text[&#039;*&#039;])[1];&lt;br /&gt;
                        console.log(src);&lt;br /&gt;
                        if(src !== &#039;null&#039; &amp;amp;&amp;amp; card.src.includes(&amp;quot;No-Image&amp;quot;)) return card.src = src;&lt;br /&gt;
                        //card.src = µ(&#039;figure img&#039;,htmlDoc)[0].getAttribute(&#039;src&#039;);&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // load gallery based on category&lt;br /&gt;
        function loadGallery(category) {&lt;br /&gt;
            &lt;br /&gt;
            let pageTitles = [];&lt;br /&gt;
&lt;br /&gt;
            galleryContainer.html(&amp;quot;&amp;lt;div class=&#039;loadDial&#039;&amp;gt;&amp;lt;p&amp;gt;Retrieving Data...&amp;lt;/p&amp;gt;&amp;lt;div class=&#039;loadSpinner&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;);&lt;br /&gt;
            // insert projects corresponding to each skill under broader category filter selected&lt;br /&gt;
            var filterCats = sortCats.filter(el=&amp;gt;el.super == category);&lt;br /&gt;
            if(category == &amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;) filterCats = [{name:&amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;}];&lt;br /&gt;
            filterCats.forEach(function(cat) {&lt;br /&gt;
                loadCategory(cat,0);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // generate a gallery&lt;br /&gt;
        function generateGalleryItem(pageUrl, title, imgUrl, category) {&lt;br /&gt;
            return `&lt;br /&gt;
                &amp;lt;div class=&amp;quot;gallery-item ${category}&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;a href=&amp;quot;${pageUrl}&amp;quot;&amp;gt;&lt;br /&gt;
                        ${imgUrl ? `&amp;lt;img class=&amp;quot;thumbs&amp;quot; src=&amp;quot;${imgUrl}&amp;quot; alt=&amp;quot;${title}&amp;quot;&amp;gt;` : `&amp;lt;img src=&amp;quot;https://upload.wikimedia.org/wikipedia/commons/6/65/No-Image-Placeholder.svg&amp;quot; alt=&amp;quot;No Image Available&amp;quot;&amp;gt;`}&lt;br /&gt;
&lt;br /&gt;
                    &amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;gallery-caption&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a href=&amp;quot;${pageUrl}&amp;quot;&amp;gt;${title}&amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            `;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        loadGallery(Category);&lt;br /&gt;
&lt;br /&gt;
        // find filter button corresponding to selected category and add css class &#039;selected-filter&#039;&lt;br /&gt;
        $(&amp;quot;.filter-btn&amp;quot;).each(function () { $(this).data(&amp;quot;filter&amp;quot;) === Category ? $(this).addClass(&#039;selected-filter&#039;) : null});&lt;br /&gt;
&lt;br /&gt;
        // when filter button is clicked, load projects for that category, deselect current filtered button, and select newly clicked filter button&lt;br /&gt;
        $(&amp;quot;.filter-btn&amp;quot;).click(function () {&lt;br /&gt;
            var selectedCategory = $(this).data(&amp;quot;filter&amp;quot;);&lt;br /&gt;
            loadGallery(selectedCategory);&lt;br /&gt;
            &lt;br /&gt;
            $(&#039;.filter-btn.selected-filter&#039;).each((i, elem) =&amp;gt; $(elem).removeClass(&#039;selected-filter&#039;));&lt;br /&gt;
            $(this).addClass(&#039;selected-filter&#039;);&lt;br /&gt;
        });&lt;br /&gt;
    });&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
if(!window.widgets) window.widgets = [];&lt;br /&gt;
window.widgets.push(cardWidgetStart);&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
  .filter-btn img{&lt;br /&gt;
    height:1.5em;&lt;br /&gt;
    padding-left:.4em;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
.gallery-item {&lt;br /&gt;
    width: 20%;&lt;br /&gt;
    min-width:200px;&lt;br /&gt;
    max-width: 30vw;&lt;br /&gt;
    margin: 10px;&lt;br /&gt;
    flex-grow: 2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.loadDial {&lt;br /&gt;
  width: 100%;&lt;br /&gt;
  text-align: center;&lt;br /&gt;
  p {&lt;br /&gt;
    font-weight: bolder;&lt;br /&gt;
    font-size: x-large;&lt;br /&gt;
    color: #666;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;card-gallery&amp;quot; class=&amp;quot;gallery-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Widget:CardGallery&amp;diff=9562</id>
		<title>Widget:CardGallery</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Widget:CardGallery&amp;diff=9562"/>
		<updated>2025-06-21T15:40:44Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;script&amp;gt;&lt;br /&gt;
var cardWidget = {};&lt;br /&gt;
&lt;br /&gt;
cardWidgetStart = function () {&lt;br /&gt;
    $(document).ready(function () {&lt;br /&gt;
        var sortCats = window[&amp;quot;&amp;lt;!--{$category|escape:&#039;url&#039;}--&amp;gt;&amp;quot;];&lt;br /&gt;
        var superCats = Array.from(new Set(sortCats.map(x=&amp;gt;x.super)));&lt;br /&gt;
        var Category = pageParams[&#039;filter&#039;] ? pageParams[&#039;filter&#039;] : &amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;; // If no filter query in url, use default category type&lt;br /&gt;
        var galleryContainer = $(&#039;#card-gallery&#039;);&lt;br /&gt;
        galleryContainer.before(&#039;&amp;lt;div id=&amp;quot;category-filter&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
        var addFilterButton = (cat) =&amp;gt; {&lt;br /&gt;
          var nextBut = µ(&#039;+button&#039;,µ(&#039;#category-filter&#039;));&lt;br /&gt;
          nextBut.id = cat+&#039;-filter-btn&#039;;&lt;br /&gt;
          nextBut.textContent = cat;&lt;br /&gt;
          nextBut.className = &#039;filter-btn&#039;;&lt;br /&gt;
          nextBut.setAttribute(&#039;data-filter&#039;,cat);&lt;br /&gt;
          sortCats.forEach((el,ind)=&amp;gt;{&lt;br /&gt;
            if(el.super == cat &amp;amp;&amp;amp; el.image) µ(&#039;+img&#039;, nextBut).src = el.image;&lt;br /&gt;
          });&lt;br /&gt;
          return nextBut;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var allBut = addFilterButton(&amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;);&lt;br /&gt;
        allBut.textContent = &#039;Show All&#039;;&lt;br /&gt;
&lt;br /&gt;
        superCats.forEach(el=&amp;gt;{&lt;br /&gt;
          addFilterButton(el);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        function hideSpinner(){ $(&#039;#card-gallery .loadDial&#039;).hide()};&lt;br /&gt;
&lt;br /&gt;
        function loadCategory(category,offset){&lt;br /&gt;
            new mw.Api().get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                list: &#039;categorymembers&#039;,&lt;br /&gt;
                cmtitle: &#039;Category:&#039; + category.name,&lt;br /&gt;
                cmlimit: 5,&lt;br /&gt;
                cmcontinue: offset,&lt;br /&gt;
                format: &#039;json&#039;&lt;br /&gt;
            }).done(function (data) {&lt;br /&gt;
                var pages = data.query.categorymembers;&lt;br /&gt;
                var galleryHtml = &#039;&#039;;&lt;br /&gt;
                //console.log(data);&lt;br /&gt;
                if(data.continue) loadCategory(category, data.continue.cmcontinue);&lt;br /&gt;
                const regexPattern = /src=&amp;quot;(.*?)&amp;quot;/;&lt;br /&gt;
                pages.forEach(function (page) {&lt;br /&gt;
                    var pageUrl = mw.util.getUrl(page.title);&lt;br /&gt;
                    var imgUrl = &#039;&#039;;&lt;br /&gt;
                    $(&#039;.gallery-container&#039;).append(generateGalleryItem(pageUrl, page.title, imgUrl, category));&lt;br /&gt;
                    //pageTitles.push(page.title);&lt;br /&gt;
                    hideSpinner();&lt;br /&gt;
                    let card = µ(&#039;.gallery-container .gallery-item:last-child img&#039;)[0];&lt;br /&gt;
                    new mw.Api().get({&lt;br /&gt;
                        action: &#039;parse&#039;,&lt;br /&gt;
                        page: page.title&lt;br /&gt;
                    }).done(function (pageData) {&lt;br /&gt;
                        const parser = new DOMParser();&lt;br /&gt;
                        const htmlDoc = parser.parseFromString(pageData.parse.text[&#039;*&#039;], &#039;text/xml&#039;);&lt;br /&gt;
                        let src = regexPattern.exec(pageData.parse.text[&#039;*&#039;])[1];&lt;br /&gt;
                        console.log(src);&lt;br /&gt;
                        if(src !== &#039;null&#039; &amp;amp;&amp;amp; card.src.includes(&amp;quot;No-Image&amp;quot;)) return card.src = src;&lt;br /&gt;
                        //card.src = µ(&#039;figure img&#039;,htmlDoc)[0].getAttribute(&#039;src&#039;);&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // load gallery based on category&lt;br /&gt;
        function loadGallery(category) {&lt;br /&gt;
            &lt;br /&gt;
            let pageTitles = [];&lt;br /&gt;
&lt;br /&gt;
            galleryContainer.html(&amp;quot;&amp;lt;div class=&#039;loadDial&#039;&amp;gt;&amp;lt;p&amp;gt;Retrieving Data...&amp;lt;/p&amp;gt;&amp;lt;div class=&#039;loadSpinner&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;);&lt;br /&gt;
            // insert projects corresponding to each skill under broader category filter selected&lt;br /&gt;
            var filterCats = sortCats.filter(el=&amp;gt;el.super == category);&lt;br /&gt;
            if(category == &amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;) filterCats = [{name:&amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;}];&lt;br /&gt;
            filterCats.forEach(function(cat) {&lt;br /&gt;
                loadCategory(cat,0);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // generate a gallery&lt;br /&gt;
        function generateGalleryItem(pageUrl, title, imgUrl, category) {&lt;br /&gt;
            return `&lt;br /&gt;
                &amp;lt;div class=&amp;quot;gallery-item ${category}&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;a href=&amp;quot;${pageUrl}&amp;quot;&amp;gt;&lt;br /&gt;
                        ${imgUrl ? `&amp;lt;img class=&amp;quot;thumbs&amp;quot; src=&amp;quot;${imgUrl}&amp;quot; alt=&amp;quot;${title}&amp;quot;&amp;gt;` : `&amp;lt;img src=&amp;quot;https://upload.wikimedia.org/wikipedia/commons/6/65/No-Image-Placeholder.svg&amp;quot; alt=&amp;quot;No Image Available&amp;quot;&amp;gt;`}&lt;br /&gt;
&lt;br /&gt;
                    &amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;gallery-caption&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a href=&amp;quot;${pageUrl}&amp;quot;&amp;gt;${title}&amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            `;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        loadGallery(Category);&lt;br /&gt;
&lt;br /&gt;
        // find filter button corresponding to selected category and add css class &#039;selected-filter&#039;&lt;br /&gt;
        $(&amp;quot;.filter-btn&amp;quot;).each(function () { $(this).data(&amp;quot;filter&amp;quot;) === Category ? $(this).addClass(&#039;selected-filter&#039;) : null});&lt;br /&gt;
&lt;br /&gt;
        // when filter button is clicked, load projects for that category, deselect current filtered button, and select newly clicked filter button&lt;br /&gt;
        $(&amp;quot;.filter-btn&amp;quot;).click(function () {&lt;br /&gt;
            var selectedCategory = $(this).data(&amp;quot;filter&amp;quot;);&lt;br /&gt;
            loadGallery(selectedCategory);&lt;br /&gt;
            &lt;br /&gt;
            $(&#039;.filter-btn.selected-filter&#039;).each((i, elem) =&amp;gt; $(elem).removeClass(&#039;selected-filter&#039;));&lt;br /&gt;
            $(this).addClass(&#039;selected-filter&#039;);&lt;br /&gt;
        });&lt;br /&gt;
    });&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
if(!window.widgets) window.widgets = [];&lt;br /&gt;
window.widgets.push(cardWidgetStart);&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
  .filter-btn img{&lt;br /&gt;
    height:1.5em;&lt;br /&gt;
    padding-left:.4em;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
.gallery-item {&lt;br /&gt;
    width: 20%;&lt;br /&gt;
    min-width:200px;&lt;br /&gt;
    max-width: 30vw;&lt;br /&gt;
    margin: 10px;&lt;br /&gt;
    flex-grow: 2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.loadDial {&lt;br /&gt;
  width: 100%;&lt;br /&gt;
  text-align: center;&lt;br /&gt;
  p {&lt;br /&gt;
    font-weight: bolder;&lt;br /&gt;
    font-size: x-large;&lt;br /&gt;
    color: #666;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;card-gallery&amp;quot; class=&amp;quot;gallery-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Widget:CardGallery&amp;diff=9561</id>
		<title>Widget:CardGallery</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Widget:CardGallery&amp;diff=9561"/>
		<updated>2025-06-21T15:36:43Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;script&amp;gt;&lt;br /&gt;
var cardWidget = {};&lt;br /&gt;
&lt;br /&gt;
cardWidgetStart = function () {&lt;br /&gt;
    $(document).ready(function () {&lt;br /&gt;
        var sortCats = window[&amp;quot;&amp;lt;!--{$category|escape:&#039;url&#039;}--&amp;gt;&amp;quot;];&lt;br /&gt;
        var superCats = Array.from(new Set(sortCats.map(x=&amp;gt;x.super)));&lt;br /&gt;
        var Category = pageParams[&#039;filter&#039;] ? pageParams[&#039;filter&#039;] : &amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;; // If no filter query in url, use default category type&lt;br /&gt;
        var galleryContainer = $(&#039;#card-gallery&#039;);&lt;br /&gt;
        galleryContainer.before(&#039;&amp;lt;div id=&amp;quot;category-filter&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
        var addFilterButton = (cat) =&amp;gt; {&lt;br /&gt;
          var nextBut = µ(&#039;+button&#039;,µ(&#039;#category-filter&#039;));&lt;br /&gt;
          nextBut.id = cat+&#039;-filter-btn&#039;;&lt;br /&gt;
          nextBut.textContent = cat;&lt;br /&gt;
          nextBut.className = &#039;filter-btn&#039;;&lt;br /&gt;
          nextBut.setAttribute(&#039;data-filter&#039;,cat);&lt;br /&gt;
          sortCats.forEach((el,ind)=&amp;gt;{&lt;br /&gt;
            if(el.super == cat &amp;amp;&amp;amp; el.image) µ(&#039;+img&#039;, nextBut).src = el.image;&lt;br /&gt;
          });&lt;br /&gt;
          return nextBut;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var allBut = addFilterButton(&amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;);&lt;br /&gt;
        allBut.textContent = &#039;Show All&#039;;&lt;br /&gt;
&lt;br /&gt;
        superCats.forEach(el=&amp;gt;{&lt;br /&gt;
          addFilterButton(el);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        function hideSpinner(){ $(&#039;#card-gallery .loadDial&#039;).hide()};&lt;br /&gt;
&lt;br /&gt;
        function loadCategory(category,offset){&lt;br /&gt;
            new mw.Api().get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                list: &#039;categorymembers&#039;,&lt;br /&gt;
                cmtitle: &#039;Category:&#039; + category.name,&lt;br /&gt;
                cmlimit: 5,&lt;br /&gt;
                cmcontinue: offset,&lt;br /&gt;
                format: &#039;json&#039;&lt;br /&gt;
            }).done(function (data) {&lt;br /&gt;
                var pages = data.query.categorymembers;&lt;br /&gt;
                var galleryHtml = &#039;&#039;;&lt;br /&gt;
                //console.log(data);&lt;br /&gt;
                if(data.continue) loadCategory(category, data.continue.cmcontinue);&lt;br /&gt;
                const regexPattern = /src=&amp;quot;(.*?)&amp;quot;/;&lt;br /&gt;
                pages.forEach(function (page) {&lt;br /&gt;
                    var pageUrl = mw.util.getUrl(page.title);&lt;br /&gt;
                    var imgUrl = &#039;&#039;;&lt;br /&gt;
                    $(&#039;.gallery-container&#039;).append(generateGalleryItem(pageUrl, page.title, imgUrl, category));&lt;br /&gt;
                    //pageTitles.push(page.title);&lt;br /&gt;
                    hideSpinner();&lt;br /&gt;
                    let card = µ(&#039;.gallery-container .gallery-item:last-child img&#039;)[0];&lt;br /&gt;
                    new mw.Api().get({&lt;br /&gt;
                        action: &#039;parse&#039;,&lt;br /&gt;
                        page: page.title&lt;br /&gt;
                    }).done(function (pageData) {&lt;br /&gt;
                        const parser = new DOMParser();&lt;br /&gt;
                        const htmlDoc = parser.parseFromString(pageData.parse.text[&#039;*&#039;], &#039;text/xml&#039;);&lt;br /&gt;
&lt;br /&gt;
                        console.log(regexPattern.exec(pageData.parse.text[&#039;*&#039;]));&lt;br /&gt;
                        let imgs = µ(&#039;img&#039;,htmlDoc);&lt;br /&gt;
                        imgs.forEach(img=&amp;gt;{&lt;br /&gt;
                          let src = img.getAttribute(&#039;src&#039;);&lt;br /&gt;
                          console.log(src);&lt;br /&gt;
                          if(src !== &#039;null&#039; &amp;amp;&amp;amp; card.src.includes(&amp;quot;No-Image&amp;quot;)) return card.src = src;&lt;br /&gt;
                        });&lt;br /&gt;
                        //card.src = µ(&#039;figure img&#039;,htmlDoc)[0].getAttribute(&#039;src&#039;);&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // load gallery based on category&lt;br /&gt;
        function loadGallery(category) {&lt;br /&gt;
            &lt;br /&gt;
            let pageTitles = [];&lt;br /&gt;
&lt;br /&gt;
            galleryContainer.html(&amp;quot;&amp;lt;div class=&#039;loadDial&#039;&amp;gt;&amp;lt;p&amp;gt;Retrieving Data...&amp;lt;/p&amp;gt;&amp;lt;div class=&#039;loadSpinner&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;);&lt;br /&gt;
            // insert projects corresponding to each skill under broader category filter selected&lt;br /&gt;
            var filterCats = sortCats.filter(el=&amp;gt;el.super == category);&lt;br /&gt;
            if(category == &amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;) filterCats = [{name:&amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;}];&lt;br /&gt;
            filterCats.forEach(function(cat) {&lt;br /&gt;
                loadCategory(cat,0);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // generate a gallery&lt;br /&gt;
        function generateGalleryItem(pageUrl, title, imgUrl, category) {&lt;br /&gt;
            return `&lt;br /&gt;
                &amp;lt;div class=&amp;quot;gallery-item ${category}&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;a href=&amp;quot;${pageUrl}&amp;quot;&amp;gt;&lt;br /&gt;
                        ${imgUrl ? `&amp;lt;img class=&amp;quot;thumbs&amp;quot; src=&amp;quot;${imgUrl}&amp;quot; alt=&amp;quot;${title}&amp;quot;&amp;gt;` : `&amp;lt;img src=&amp;quot;https://upload.wikimedia.org/wikipedia/commons/6/65/No-Image-Placeholder.svg&amp;quot; alt=&amp;quot;No Image Available&amp;quot;&amp;gt;`}&lt;br /&gt;
&lt;br /&gt;
                    &amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;gallery-caption&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a href=&amp;quot;${pageUrl}&amp;quot;&amp;gt;${title}&amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            `;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        loadGallery(Category);&lt;br /&gt;
&lt;br /&gt;
        // find filter button corresponding to selected category and add css class &#039;selected-filter&#039;&lt;br /&gt;
        $(&amp;quot;.filter-btn&amp;quot;).each(function () { $(this).data(&amp;quot;filter&amp;quot;) === Category ? $(this).addClass(&#039;selected-filter&#039;) : null});&lt;br /&gt;
&lt;br /&gt;
        // when filter button is clicked, load projects for that category, deselect current filtered button, and select newly clicked filter button&lt;br /&gt;
        $(&amp;quot;.filter-btn&amp;quot;).click(function () {&lt;br /&gt;
            var selectedCategory = $(this).data(&amp;quot;filter&amp;quot;);&lt;br /&gt;
            loadGallery(selectedCategory);&lt;br /&gt;
            &lt;br /&gt;
            $(&#039;.filter-btn.selected-filter&#039;).each((i, elem) =&amp;gt; $(elem).removeClass(&#039;selected-filter&#039;));&lt;br /&gt;
            $(this).addClass(&#039;selected-filter&#039;);&lt;br /&gt;
        });&lt;br /&gt;
    });&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
if(!window.widgets) window.widgets = [];&lt;br /&gt;
window.widgets.push(cardWidgetStart);&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
  .filter-btn img{&lt;br /&gt;
    height:1.5em;&lt;br /&gt;
    padding-left:.4em;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
.gallery-item {&lt;br /&gt;
    width: 20%;&lt;br /&gt;
    min-width:200px;&lt;br /&gt;
    max-width: 30vw;&lt;br /&gt;
    margin: 10px;&lt;br /&gt;
    flex-grow: 2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.loadDial {&lt;br /&gt;
  width: 100%;&lt;br /&gt;
  text-align: center;&lt;br /&gt;
  p {&lt;br /&gt;
    font-weight: bolder;&lt;br /&gt;
    font-size: x-large;&lt;br /&gt;
    color: #666;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;card-gallery&amp;quot; class=&amp;quot;gallery-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Widget:CardGallery&amp;diff=9559</id>
		<title>Widget:CardGallery</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Widget:CardGallery&amp;diff=9559"/>
		<updated>2025-06-20T20:49:10Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;script&amp;gt;&lt;br /&gt;
var cardWidget = {};&lt;br /&gt;
&lt;br /&gt;
cardWidgetStart = function () {&lt;br /&gt;
    $(document).ready(function () {&lt;br /&gt;
        var sortCats = window[&amp;quot;&amp;lt;!--{$category|escape:&#039;url&#039;}--&amp;gt;&amp;quot;];&lt;br /&gt;
        var superCats = Array.from(new Set(sortCats.map(x=&amp;gt;x.super)));&lt;br /&gt;
        var Category = pageParams[&#039;filter&#039;] ? pageParams[&#039;filter&#039;] : &amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;; // If no filter query in url, use default category type&lt;br /&gt;
        var galleryContainer = $(&#039;#card-gallery&#039;);&lt;br /&gt;
        galleryContainer.before(&#039;&amp;lt;div id=&amp;quot;category-filter&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
        var addFilterButton = (cat) =&amp;gt; {&lt;br /&gt;
          var nextBut = µ(&#039;+button&#039;,µ(&#039;#category-filter&#039;));&lt;br /&gt;
          nextBut.id = cat+&#039;-filter-btn&#039;;&lt;br /&gt;
          nextBut.textContent = cat;&lt;br /&gt;
          nextBut.className = &#039;filter-btn&#039;;&lt;br /&gt;
          nextBut.setAttribute(&#039;data-filter&#039;,cat);&lt;br /&gt;
          sortCats.forEach((el,ind)=&amp;gt;{&lt;br /&gt;
            if(el.super == cat &amp;amp;&amp;amp; el.image) µ(&#039;+img&#039;, nextBut).src = el.image;&lt;br /&gt;
          });&lt;br /&gt;
          return nextBut;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var allBut = addFilterButton(&amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;);&lt;br /&gt;
        allBut.textContent = &#039;Show All&#039;;&lt;br /&gt;
&lt;br /&gt;
        superCats.forEach(el=&amp;gt;{&lt;br /&gt;
          addFilterButton(el);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        function hideSpinner(){ $(&#039;#card-gallery .loadDial&#039;).hide()};&lt;br /&gt;
&lt;br /&gt;
        function loadCategory(category,offset){&lt;br /&gt;
            new mw.Api().get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                list: &#039;categorymembers&#039;,&lt;br /&gt;
                cmtitle: &#039;Category:&#039; + category.name,&lt;br /&gt;
                cmlimit: 5,&lt;br /&gt;
                cmcontinue: offset,&lt;br /&gt;
                format: &#039;json&#039;&lt;br /&gt;
            }).done(function (data) {&lt;br /&gt;
                var pages = data.query.categorymembers;&lt;br /&gt;
                var galleryHtml = &#039;&#039;;&lt;br /&gt;
                //console.log(data);&lt;br /&gt;
                if(data.continue) loadCategory(category, data.continue.cmcontinue);&lt;br /&gt;
                pages.forEach(function (page) {&lt;br /&gt;
                    var pageUrl = mw.util.getUrl(page.title);&lt;br /&gt;
                    var imgUrl = &#039;&#039;;&lt;br /&gt;
                    $(&#039;.gallery-container&#039;).append(generateGalleryItem(pageUrl, page.title, imgUrl, category));&lt;br /&gt;
                    //pageTitles.push(page.title);&lt;br /&gt;
                    hideSpinner();&lt;br /&gt;
                    let card = µ(&#039;.gallery-container .gallery-item:last-child img&#039;)[0];&lt;br /&gt;
                    new mw.Api().get({&lt;br /&gt;
                        action: &#039;parse&#039;,&lt;br /&gt;
                        page: page.title&lt;br /&gt;
                    }).done(function (pageData) {&lt;br /&gt;
                        const parser = new DOMParser();&lt;br /&gt;
                        const htmlDoc = parser.parseFromString(pageData.parse.text[&#039;*&#039;], &#039;text/xml&#039;);&lt;br /&gt;
&lt;br /&gt;
                        console.log(pageData.parse.text[&#039;*&#039;]);&lt;br /&gt;
                        let imgs = µ(&#039;img&#039;,htmlDoc);&lt;br /&gt;
                        imgs.forEach(img=&amp;gt;{&lt;br /&gt;
                          let src = img.getAttribute(&#039;src&#039;);&lt;br /&gt;
                          console.log(src);&lt;br /&gt;
                          if(src !== &#039;null&#039; &amp;amp;&amp;amp; card.src.includes(&amp;quot;No-Image&amp;quot;)) return card.src = src;&lt;br /&gt;
                        });&lt;br /&gt;
                        //card.src = µ(&#039;figure img&#039;,htmlDoc)[0].getAttribute(&#039;src&#039;);&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // load gallery based on category&lt;br /&gt;
        function loadGallery(category) {&lt;br /&gt;
            &lt;br /&gt;
            let pageTitles = [];&lt;br /&gt;
&lt;br /&gt;
            galleryContainer.html(&amp;quot;&amp;lt;div class=&#039;loadDial&#039;&amp;gt;&amp;lt;p&amp;gt;Retrieving Data...&amp;lt;/p&amp;gt;&amp;lt;div class=&#039;loadSpinner&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;);&lt;br /&gt;
            // insert projects corresponding to each skill under broader category filter selected&lt;br /&gt;
            var filterCats = sortCats.filter(el=&amp;gt;el.super == category);&lt;br /&gt;
            if(category == &amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;) filterCats = [{name:&amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;}];&lt;br /&gt;
            filterCats.forEach(function(cat) {&lt;br /&gt;
                loadCategory(cat,0);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // generate a gallery&lt;br /&gt;
        function generateGalleryItem(pageUrl, title, imgUrl, category) {&lt;br /&gt;
            return `&lt;br /&gt;
                &amp;lt;div class=&amp;quot;gallery-item ${category}&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;a href=&amp;quot;${pageUrl}&amp;quot;&amp;gt;&lt;br /&gt;
                        ${imgUrl ? `&amp;lt;img class=&amp;quot;thumbs&amp;quot; src=&amp;quot;${imgUrl}&amp;quot; alt=&amp;quot;${title}&amp;quot;&amp;gt;` : `&amp;lt;img src=&amp;quot;https://upload.wikimedia.org/wikipedia/commons/6/65/No-Image-Placeholder.svg&amp;quot; alt=&amp;quot;No Image Available&amp;quot;&amp;gt;`}&lt;br /&gt;
&lt;br /&gt;
                    &amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;gallery-caption&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a href=&amp;quot;${pageUrl}&amp;quot;&amp;gt;${title}&amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            `;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        loadGallery(Category);&lt;br /&gt;
&lt;br /&gt;
        // find filter button corresponding to selected category and add css class &#039;selected-filter&#039;&lt;br /&gt;
        $(&amp;quot;.filter-btn&amp;quot;).each(function () { $(this).data(&amp;quot;filter&amp;quot;) === Category ? $(this).addClass(&#039;selected-filter&#039;) : null});&lt;br /&gt;
&lt;br /&gt;
        // when filter button is clicked, load projects for that category, deselect current filtered button, and select newly clicked filter button&lt;br /&gt;
        $(&amp;quot;.filter-btn&amp;quot;).click(function () {&lt;br /&gt;
            var selectedCategory = $(this).data(&amp;quot;filter&amp;quot;);&lt;br /&gt;
            loadGallery(selectedCategory);&lt;br /&gt;
            &lt;br /&gt;
            $(&#039;.filter-btn.selected-filter&#039;).each((i, elem) =&amp;gt; $(elem).removeClass(&#039;selected-filter&#039;));&lt;br /&gt;
            $(this).addClass(&#039;selected-filter&#039;);&lt;br /&gt;
        });&lt;br /&gt;
    });&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
if(!window.widgets) window.widgets = [];&lt;br /&gt;
window.widgets.push(cardWidgetStart);&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
  .filter-btn img{&lt;br /&gt;
    height:1.5em;&lt;br /&gt;
    padding-left:.4em;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
.gallery-item {&lt;br /&gt;
    width: 20%;&lt;br /&gt;
    min-width:200px;&lt;br /&gt;
    max-width: 30vw;&lt;br /&gt;
    margin: 10px;&lt;br /&gt;
    flex-grow: 2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.loadDial {&lt;br /&gt;
  width: 100%;&lt;br /&gt;
  text-align: center;&lt;br /&gt;
  p {&lt;br /&gt;
    font-weight: bolder;&lt;br /&gt;
    font-size: x-large;&lt;br /&gt;
    color: #666;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;card-gallery&amp;quot; class=&amp;quot;gallery-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Widget:CardGallery&amp;diff=9558</id>
		<title>Widget:CardGallery</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Widget:CardGallery&amp;diff=9558"/>
		<updated>2025-06-20T20:46:07Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;script&amp;gt;&lt;br /&gt;
var cardWidget = {};&lt;br /&gt;
&lt;br /&gt;
cardWidgetStart = function () {&lt;br /&gt;
    $(document).ready(function () {&lt;br /&gt;
        var sortCats = window[&amp;quot;&amp;lt;!--{$category|escape:&#039;url&#039;}--&amp;gt;&amp;quot;];&lt;br /&gt;
        var superCats = Array.from(new Set(sortCats.map(x=&amp;gt;x.super)));&lt;br /&gt;
        var Category = pageParams[&#039;filter&#039;] ? pageParams[&#039;filter&#039;] : &amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;; // If no filter query in url, use default category type&lt;br /&gt;
        var galleryContainer = $(&#039;#card-gallery&#039;);&lt;br /&gt;
        galleryContainer.before(&#039;&amp;lt;div id=&amp;quot;category-filter&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
        var addFilterButton = (cat) =&amp;gt; {&lt;br /&gt;
          var nextBut = µ(&#039;+button&#039;,µ(&#039;#category-filter&#039;));&lt;br /&gt;
          nextBut.id = cat+&#039;-filter-btn&#039;;&lt;br /&gt;
          nextBut.textContent = cat;&lt;br /&gt;
          nextBut.className = &#039;filter-btn&#039;;&lt;br /&gt;
          nextBut.setAttribute(&#039;data-filter&#039;,cat);&lt;br /&gt;
          sortCats.forEach((el,ind)=&amp;gt;{&lt;br /&gt;
            if(el.super == cat &amp;amp;&amp;amp; el.image) µ(&#039;+img&#039;, nextBut).src = el.image;&lt;br /&gt;
          });&lt;br /&gt;
          return nextBut;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var allBut = addFilterButton(&amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;);&lt;br /&gt;
        allBut.textContent = &#039;Show All&#039;;&lt;br /&gt;
&lt;br /&gt;
        superCats.forEach(el=&amp;gt;{&lt;br /&gt;
          addFilterButton(el);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        function hideSpinner(){ $(&#039;#card-gallery .loadDial&#039;).hide()};&lt;br /&gt;
&lt;br /&gt;
        function loadCategory(category,offset){&lt;br /&gt;
            new mw.Api().get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                list: &#039;categorymembers&#039;,&lt;br /&gt;
                cmtitle: &#039;Category:&#039; + category.name,&lt;br /&gt;
                cmlimit: 5,&lt;br /&gt;
                cmcontinue: offset,&lt;br /&gt;
                format: &#039;json&#039;&lt;br /&gt;
            }).done(function (data) {&lt;br /&gt;
                var pages = data.query.categorymembers;&lt;br /&gt;
                var galleryHtml = &#039;&#039;;&lt;br /&gt;
                //console.log(data);&lt;br /&gt;
                if(data.continue) loadCategory(category, data.continue.cmcontinue);&lt;br /&gt;
                pages.forEach(function (page) {&lt;br /&gt;
                    var pageUrl = mw.util.getUrl(page.title);&lt;br /&gt;
                    var imgUrl = &#039;&#039;;&lt;br /&gt;
                    $(&#039;.gallery-container&#039;).append(generateGalleryItem(pageUrl, page.title, imgUrl, category));&lt;br /&gt;
                    //pageTitles.push(page.title);&lt;br /&gt;
                    hideSpinner();&lt;br /&gt;
                    let card = µ(&#039;.gallery-container .gallery-item:last-child img&#039;)[0];&lt;br /&gt;
                    new mw.Api().get({&lt;br /&gt;
                        action: &#039;parse&#039;,&lt;br /&gt;
                        page: page.title&lt;br /&gt;
                    }).done(function (pageData) {&lt;br /&gt;
                        const parser = new DOMParser();&lt;br /&gt;
                        const htmlDoc = parser.parseFromString(pageData.parse.text[&#039;*&#039;], &#039;text/xml&#039;);&lt;br /&gt;
                        let imgs = µ(&#039;img&#039;,htmlDoc);&lt;br /&gt;
                        imgs.forEach(img=&amp;gt;{&lt;br /&gt;
                          let src = img.getAttribute(&#039;src&#039;);&lt;br /&gt;
                          console.log(src);&lt;br /&gt;
                          if(src !== &#039;null&#039; &amp;amp;&amp;amp; card.src.includes(&amp;quot;No-Image&amp;quot;)) return card.src = src;&lt;br /&gt;
                        });&lt;br /&gt;
                        //card.src = µ(&#039;figure img&#039;,htmlDoc)[0].getAttribute(&#039;src&#039;);&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // load gallery based on category&lt;br /&gt;
        function loadGallery(category) {&lt;br /&gt;
            &lt;br /&gt;
            let pageTitles = [];&lt;br /&gt;
&lt;br /&gt;
            galleryContainer.html(&amp;quot;&amp;lt;div class=&#039;loadDial&#039;&amp;gt;&amp;lt;p&amp;gt;Retrieving Data...&amp;lt;/p&amp;gt;&amp;lt;div class=&#039;loadSpinner&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;);&lt;br /&gt;
            // insert projects corresponding to each skill under broader category filter selected&lt;br /&gt;
            var filterCats = sortCats.filter(el=&amp;gt;el.super == category);&lt;br /&gt;
            if(category == &amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;) filterCats = [{name:&amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;}];&lt;br /&gt;
            filterCats.forEach(function(cat) {&lt;br /&gt;
                loadCategory(cat,0);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // generate a gallery&lt;br /&gt;
        function generateGalleryItem(pageUrl, title, imgUrl, category) {&lt;br /&gt;
            return `&lt;br /&gt;
                &amp;lt;div class=&amp;quot;gallery-item ${category}&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;a href=&amp;quot;${pageUrl}&amp;quot;&amp;gt;&lt;br /&gt;
                        ${imgUrl ? `&amp;lt;img class=&amp;quot;thumbs&amp;quot; src=&amp;quot;${imgUrl}&amp;quot; alt=&amp;quot;${title}&amp;quot;&amp;gt;` : `&amp;lt;img src=&amp;quot;https://upload.wikimedia.org/wikipedia/commons/6/65/No-Image-Placeholder.svg&amp;quot; alt=&amp;quot;No Image Available&amp;quot;&amp;gt;`}&lt;br /&gt;
&lt;br /&gt;
                    &amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;gallery-caption&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a href=&amp;quot;${pageUrl}&amp;quot;&amp;gt;${title}&amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            `;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        loadGallery(Category);&lt;br /&gt;
&lt;br /&gt;
        // find filter button corresponding to selected category and add css class &#039;selected-filter&#039;&lt;br /&gt;
        $(&amp;quot;.filter-btn&amp;quot;).each(function () { $(this).data(&amp;quot;filter&amp;quot;) === Category ? $(this).addClass(&#039;selected-filter&#039;) : null});&lt;br /&gt;
&lt;br /&gt;
        // when filter button is clicked, load projects for that category, deselect current filtered button, and select newly clicked filter button&lt;br /&gt;
        $(&amp;quot;.filter-btn&amp;quot;).click(function () {&lt;br /&gt;
            var selectedCategory = $(this).data(&amp;quot;filter&amp;quot;);&lt;br /&gt;
            loadGallery(selectedCategory);&lt;br /&gt;
            &lt;br /&gt;
            $(&#039;.filter-btn.selected-filter&#039;).each((i, elem) =&amp;gt; $(elem).removeClass(&#039;selected-filter&#039;));&lt;br /&gt;
            $(this).addClass(&#039;selected-filter&#039;);&lt;br /&gt;
        });&lt;br /&gt;
    });&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
if(!window.widgets) window.widgets = [];&lt;br /&gt;
window.widgets.push(cardWidgetStart);&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
  .filter-btn img{&lt;br /&gt;
    height:1.5em;&lt;br /&gt;
    padding-left:.4em;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
.gallery-item {&lt;br /&gt;
    width: 20%;&lt;br /&gt;
    min-width:200px;&lt;br /&gt;
    max-width: 30vw;&lt;br /&gt;
    margin: 10px;&lt;br /&gt;
    flex-grow: 2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.loadDial {&lt;br /&gt;
  width: 100%;&lt;br /&gt;
  text-align: center;&lt;br /&gt;
  p {&lt;br /&gt;
    font-weight: bolder;&lt;br /&gt;
    font-size: x-large;&lt;br /&gt;
    color: #666;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;card-gallery&amp;quot; class=&amp;quot;gallery-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
	<entry>
		<id>https://makerspace.cc/wiki/index.php?title=Widget:CardGallery&amp;diff=9557</id>
		<title>Widget:CardGallery</title>
		<link rel="alternate" type="text/html" href="https://makerspace.cc/wiki/index.php?title=Widget:CardGallery&amp;diff=9557"/>
		<updated>2025-06-20T20:45:24Z</updated>

		<summary type="html">&lt;p&gt;JaneParson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;script&amp;gt;&lt;br /&gt;
var cardWidget = {};&lt;br /&gt;
&lt;br /&gt;
cardWidgetStart = function () {&lt;br /&gt;
    $(document).ready(function () {&lt;br /&gt;
        var sortCats = window[&amp;quot;&amp;lt;!--{$category|escape:&#039;url&#039;}--&amp;gt;&amp;quot;];&lt;br /&gt;
        var superCats = Array.from(new Set(sortCats.map(x=&amp;gt;x.super)));&lt;br /&gt;
        var Category = pageParams[&#039;filter&#039;] ? pageParams[&#039;filter&#039;] : &amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;; // If no filter query in url, use default category type&lt;br /&gt;
        var galleryContainer = $(&#039;#card-gallery&#039;);&lt;br /&gt;
        galleryContainer.before(&#039;&amp;lt;div id=&amp;quot;category-filter&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
        var addFilterButton = (cat) =&amp;gt; {&lt;br /&gt;
          var nextBut = µ(&#039;+button&#039;,µ(&#039;#category-filter&#039;));&lt;br /&gt;
          nextBut.id = cat+&#039;-filter-btn&#039;;&lt;br /&gt;
          nextBut.textContent = cat;&lt;br /&gt;
          nextBut.className = &#039;filter-btn&#039;;&lt;br /&gt;
          nextBut.setAttribute(&#039;data-filter&#039;,cat);&lt;br /&gt;
          sortCats.forEach((el,ind)=&amp;gt;{&lt;br /&gt;
            if(el.super == cat &amp;amp;&amp;amp; el.image) µ(&#039;+img&#039;, nextBut).src = el.image;&lt;br /&gt;
          });&lt;br /&gt;
          return nextBut;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var allBut = addFilterButton(&amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;);&lt;br /&gt;
        allBut.textContent = &#039;Show All&#039;;&lt;br /&gt;
&lt;br /&gt;
        superCats.forEach(el=&amp;gt;{&lt;br /&gt;
          addFilterButton(el);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        function hideSpinner(){ $(&#039;#card-gallery .loadDial&#039;).hide()};&lt;br /&gt;
&lt;br /&gt;
        function loadCategory(category,offset){&lt;br /&gt;
            new mw.Api().get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                list: &#039;categorymembers&#039;,&lt;br /&gt;
                cmtitle: &#039;Category:&#039; + category.name,&lt;br /&gt;
                cmlimit: 5,&lt;br /&gt;
                cmcontinue: offset,&lt;br /&gt;
                format: &#039;json&#039;&lt;br /&gt;
            }).done(function (data) {&lt;br /&gt;
                var pages = data.query.categorymembers;&lt;br /&gt;
                var galleryHtml = &#039;&#039;;&lt;br /&gt;
                //console.log(data);&lt;br /&gt;
                if(data.continue) loadCategory(category, data.continue.cmcontinue);&lt;br /&gt;
                pages.forEach(function (page) {&lt;br /&gt;
                    var pageUrl = mw.util.getUrl(page.title);&lt;br /&gt;
                    var imgUrl = &#039;&#039;;&lt;br /&gt;
                    $(&#039;.gallery-container&#039;).append(generateGalleryItem(pageUrl, page.title, imgUrl, category));&lt;br /&gt;
                    //pageTitles.push(page.title);&lt;br /&gt;
                    hideSpinner();&lt;br /&gt;
                    let card = µ(&#039;.gallery-container .gallery-item:last-child img&#039;)[0];&lt;br /&gt;
                    new mw.Api().get({&lt;br /&gt;
                        action: &#039;parse&#039;,&lt;br /&gt;
                        page: page.title&lt;br /&gt;
                    }).done(function (pageData) {&lt;br /&gt;
                        const parser = new DOMParser();&lt;br /&gt;
                        const htmlDoc = parser.parseFromString(pageData.parse.text[&#039;*&#039;].split(&amp;quot;&amp;lt;!--&amp;quot;)[0], &#039;text/xml&#039;);&lt;br /&gt;
                        let imgs = µ(&#039;img&#039;,htmlDoc);&lt;br /&gt;
                        imgs.forEach(img=&amp;gt;{&lt;br /&gt;
                          let src = img.getAttribute(&#039;src&#039;);&lt;br /&gt;
                          console.log(src);&lt;br /&gt;
                          if(src !== &#039;null&#039; &amp;amp;&amp;amp; card.src.includes(&amp;quot;No-Image&amp;quot;)) return card.src = src;&lt;br /&gt;
                        });&lt;br /&gt;
                        //card.src = µ(&#039;figure img&#039;,htmlDoc)[0].getAttribute(&#039;src&#039;);&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // load gallery based on category&lt;br /&gt;
        function loadGallery(category) {&lt;br /&gt;
            &lt;br /&gt;
            let pageTitles = [];&lt;br /&gt;
&lt;br /&gt;
            galleryContainer.html(&amp;quot;&amp;lt;div class=&#039;loadDial&#039;&amp;gt;&amp;lt;p&amp;gt;Retrieving Data...&amp;lt;/p&amp;gt;&amp;lt;div class=&#039;loadSpinner&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;);&lt;br /&gt;
            // insert projects corresponding to each skill under broader category filter selected&lt;br /&gt;
            var filterCats = sortCats.filter(el=&amp;gt;el.super == category);&lt;br /&gt;
            if(category == &amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;) filterCats = [{name:&amp;quot;&amp;lt;!--{$type|escape:&#039;url&#039;}--&amp;gt;&amp;quot;}];&lt;br /&gt;
            filterCats.forEach(function(cat) {&lt;br /&gt;
                loadCategory(cat,0);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // generate a gallery&lt;br /&gt;
        function generateGalleryItem(pageUrl, title, imgUrl, category) {&lt;br /&gt;
            return `&lt;br /&gt;
                &amp;lt;div class=&amp;quot;gallery-item ${category}&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;a href=&amp;quot;${pageUrl}&amp;quot;&amp;gt;&lt;br /&gt;
                        ${imgUrl ? `&amp;lt;img class=&amp;quot;thumbs&amp;quot; src=&amp;quot;${imgUrl}&amp;quot; alt=&amp;quot;${title}&amp;quot;&amp;gt;` : `&amp;lt;img src=&amp;quot;https://upload.wikimedia.org/wikipedia/commons/6/65/No-Image-Placeholder.svg&amp;quot; alt=&amp;quot;No Image Available&amp;quot;&amp;gt;`}&lt;br /&gt;
&lt;br /&gt;
                    &amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;gallery-caption&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a href=&amp;quot;${pageUrl}&amp;quot;&amp;gt;${title}&amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            `;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        loadGallery(Category);&lt;br /&gt;
&lt;br /&gt;
        // find filter button corresponding to selected category and add css class &#039;selected-filter&#039;&lt;br /&gt;
        $(&amp;quot;.filter-btn&amp;quot;).each(function () { $(this).data(&amp;quot;filter&amp;quot;) === Category ? $(this).addClass(&#039;selected-filter&#039;) : null});&lt;br /&gt;
&lt;br /&gt;
        // when filter button is clicked, load projects for that category, deselect current filtered button, and select newly clicked filter button&lt;br /&gt;
        $(&amp;quot;.filter-btn&amp;quot;).click(function () {&lt;br /&gt;
            var selectedCategory = $(this).data(&amp;quot;filter&amp;quot;);&lt;br /&gt;
            loadGallery(selectedCategory);&lt;br /&gt;
            &lt;br /&gt;
            $(&#039;.filter-btn.selected-filter&#039;).each((i, elem) =&amp;gt; $(elem).removeClass(&#039;selected-filter&#039;));&lt;br /&gt;
            $(this).addClass(&#039;selected-filter&#039;);&lt;br /&gt;
        });&lt;br /&gt;
    });&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
if(!window.widgets) window.widgets = [];&lt;br /&gt;
window.widgets.push(cardWidgetStart);&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
  .filter-btn img{&lt;br /&gt;
    height:1.5em;&lt;br /&gt;
    padding-left:.4em;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
.gallery-item {&lt;br /&gt;
    width: 20%;&lt;br /&gt;
    min-width:200px;&lt;br /&gt;
    max-width: 30vw;&lt;br /&gt;
    margin: 10px;&lt;br /&gt;
    flex-grow: 2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.loadDial {&lt;br /&gt;
  width: 100%;&lt;br /&gt;
  text-align: center;&lt;br /&gt;
  p {&lt;br /&gt;
    font-weight: bolder;&lt;br /&gt;
    font-size: x-large;&lt;br /&gt;
    color: #666;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;card-gallery&amp;quot; class=&amp;quot;gallery-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>JaneParson</name></author>
	</entry>
</feed>