Compare commits
116 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
ec435e6df2 |
|||
|
5137f84e92 |
|||
|
7d9645efe8 |
|||
| 4e864f5985 | |||
| 342b425a65 | |||
| 64e98cf339 | |||
|
3f01e59753 |
|||
|
00f4085617 |
|||
| 054eedc60a | |||
|
b6b3f8ef41 |
|||
|
fd3ecac5b5 |
|||
|
ad191421fe |
|||
|
3093a536c4 |
|||
|
690ea1a860 |
|||
|
62f3cbdc31 |
|||
| 3b98f7bfec | |||
| 6d23b83db0 | |||
| 391f723732 | |||
| f4cecbf3bf | |||
| 0ec42def01 | |||
| 7c97825b5d | |||
| a0b849dc1e | |||
| ebb3f0d599 | |||
| c21754a914 | |||
|
fef6728efb |
|||
| 650dfe4a07 | |||
| af2cbea31f | |||
| 457844e4c2 | |||
| 905b62631e | |||
|
609233af73 |
|||
|
7febb7eaf5 |
|||
| ea0e461854 | |||
|
e8edc52532 |
|||
|
2c6f65abfb |
|||
| c8be03dd5c | |||
| 8462bde2bf | |||
| 785291f478 | |||
| 6d4c71f8b9 | |||
| 60d65a35c9 | |||
| 6a8e9fc3cc | |||
| 175382618a | |||
| cdcf1ad1ed | |||
| 74f4f3d5e0 | |||
|
74dd0ae527 |
|||
| 8bcb1e9810 | |||
|
de1b179a10 |
|||
|
ceb1e82d60 |
|||
|
cadd36a3a9 |
|||
| 61921b5f8a | |||
| d43a11ac3f | |||
| 4545dcce6f | |||
| 73e970ce68 | |||
| cffcc85fd5 | |||
| d03d8cb955 | |||
| f24a41ae00 | |||
| 2fae74e74d | |||
| 21cd6babaf | |||
| dbe7efb2b5 | |||
| 86080df835 | |||
| ed54e13aad | |||
| f40bff9e00 | |||
| 8918fbdae7 | |||
| ed18f36775 | |||
|
6df6df2b61 |
|||
|
9536c677d9 |
|||
| ee436c76c2 | |||
| 98cdf33660 | |||
| 0feb8da4cd | |||
| 590588f93b | |||
| 983a5ddd3a | |||
| 4bd20d04e7 | |||
| abfcdf0761 | |||
| e6ef6315ac | |||
| bf22505073 | |||
| 3f8a64f417 | |||
| ac5ef5505c | |||
| bbb9c8f04c | |||
| afdf5dc10a | |||
|
06cda81e76 |
|||
|
4c7dcdac6e |
|||
|
|
17c4131d3f | ||
|
|
93d71dbac6 | ||
|
|
8be1c76911 | ||
|
|
11f0f13bd4 | ||
|
|
88643108e7 | ||
|
|
ddaf8e075a | ||
|
|
1d62650352 | ||
|
|
8ef028bc2d | ||
|
|
3f55efebf8 | ||
|
|
dc70f1ac38 | ||
|
|
50ad61244e | ||
|
|
40e35a4738 | ||
|
|
e8feab9eca | ||
|
8c462507b6 |
|||
|
|
9cf9114c64 | ||
|
|
18fead91f0 | ||
|
f4958f2ac6 |
|||
|
|
fe49edba00 | ||
|
|
be1874bcce | ||
|
|
1d9a6a2a93 | ||
|
|
7950f3a1a0 | ||
|
|
6e539a8ce1 | ||
|
|
edb4b8f481 | ||
|
|
6ed05ba06d | ||
|
|
498e7be1dc | ||
|
|
a4c7261448 | ||
|
|
9e1bc58748 | ||
|
|
a0bf838b00 | ||
|
|
41878d7fbb | ||
| 0779ea0f2c | |||
|
|
2e8736e4ee | ||
| 65cc7052a7 | |||
|
|
0520c3dd87 | ||
|
|
6fd3d42b8c | ||
|
|
3d9590fdc0 | ||
|
|
97c9617957 |
2
.gitattributes
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
*.woff filter=lfs diff=lfs merge=lfs -text
|
||||
*.woff2 filter=lfs diff=lfs merge=lfs -text
|
||||
5
.gitignore
vendored
|
|
@ -1,3 +1,6 @@
|
|||
# Calendar file used for local development. On a production server, the calendar
|
||||
# file is made available at the same path by reverse proxy.
|
||||
calendar.ics
|
||||
calendar.ics
|
||||
spaceapi.json
|
||||
news.json
|
||||
.DS_Store
|
||||
53
README.md
|
|
@ -1,34 +1,35 @@
|
|||
https://fahrplan.events.ccc.de/congress/2007/Fahrplan/attachments/1003_Building%20a%20Hacker%20Space.pdf
|
||||
# devhack.net
|
||||
|
||||
hackerbot labs seemed to be the closest thing to a seattle hackerspace
|
||||
> It's called devhack dot net because the devhack is on the net.
|
||||
|
||||
pdx hackerspace is *very* cool and I want to visit sometime.
|
||||
This is the official website for /dev/hack, a hackerspace in Seattle.
|
||||
|
||||
Contributions are welcome. The canonical repository for this project is at
|
||||
https://git.devhack.net/devhack/devhack.net.
|
||||
|
||||
|
||||
https://www.loopnet.com/search/office-space/seattle-wa/for-lease/?sk=50d7d36bf2f66fbcbac3baa5bf968fbf&bb=o4mp25jrtQh1x3H
|
||||
## Development
|
||||
|
||||
To get started with developing the website:
|
||||
|
||||
office spaces aren't actually too expensive.
|
||||
1. Clone this repository.
|
||||
2. Open `index.html` in your web browser to view the site, or better yet, use
|
||||
one of the ad-hoc live reload tools like Visual Studio Code's Live Server
|
||||
extension.
|
||||
3. Make the desired changes to:
|
||||
* `index.html`, `more.html`: Body copy for the main pages.
|
||||
* `index-cal.js`: Handles the calendar functionality.
|
||||
* `index-newsfeed.js`: Manages the news feed.
|
||||
* `index-spaceapi.js`: Deals with the SpaceAPI integration.
|
||||
* `index-common.js`: Contains shared utility functions.
|
||||
|
||||
seattle hacker spaces are a thing?
|
||||
For local development, you may want to download local copies of the data files
|
||||
that the site uses. In production, they are reverse proxied from their
|
||||
respective origins, and so they do not exist in git:
|
||||
|
||||
|
||||
|
||||
step 1: garner/gauge interest
|
||||
step 2: obligate some people into being in charge with me / starting it together & splitting the costs
|
||||
step 3: find a space
|
||||
step 4: move in
|
||||
step 5: make it cool
|
||||
|
||||
|
||||
|
||||
things the hackerspace has:
|
||||
seedbox
|
||||
server shit
|
||||
router
|
||||
VR headset
|
||||
old computers
|
||||
projector setup
|
||||
big ol UPS
|
||||
|
||||
/dev/hack
|
||||
```sh
|
||||
# in the root of the repository, run:
|
||||
curl -Lo calendar.ics https://devhack.net/calendar.ics
|
||||
curl -Lo spaceapi.json https://devhack.net/spaceapi.json
|
||||
curl -Lo news.json https://devhack.net/news.json
|
||||
```
|
||||
|
|
|
|||
34
RELICS.md
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
https://fahrplan.events.ccc.de/congress/2007/Fahrplan/attachments/1003_Building%20a%20Hacker%20Space.pdf
|
||||
|
||||
hackerbot labs seemed to be the closest thing to a seattle hackerspace
|
||||
|
||||
pdx hackerspace is *very* cool and I want to visit sometime.
|
||||
|
||||
|
||||
https://www.loopnet.com/search/office-space/seattle-wa/for-lease/?sk=50d7d36bf2f66fbcbac3baa5bf968fbf&bb=o4mp25jrtQh1x3H
|
||||
|
||||
|
||||
office spaces aren't actually too expensive.
|
||||
|
||||
seattle hacker spaces are a thing?
|
||||
|
||||
|
||||
|
||||
step 1: garner/gauge interest
|
||||
step 2: obligate some people into being in charge with me / starting it together & splitting the costs
|
||||
step 3: find a space
|
||||
step 4: move in
|
||||
step 5: make it cool
|
||||
|
||||
|
||||
|
||||
things the hackerspace has:
|
||||
seedbox
|
||||
server shit
|
||||
router
|
||||
VR headset
|
||||
old computers
|
||||
projector setup
|
||||
big ol UPS
|
||||
|
||||
/dev/hack
|
||||
3
assets/arrow_forward_ios.svg
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" id="img" fill="currentColor">
|
||||
<path d="M579-480 285-774q-15-15-14.5-35.5T286-845q15-15 35.5-15t35.5 15l307 308q12 12 18 27t6 30q0 15-6 30t-18 27L356-115q-15 15-35 14.5T286-116q-15-15-15-35.5t15-35.5l293-293Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 314 B |
42
index-cal.js
|
|
@ -16,10 +16,28 @@ function escape(str) {
|
|||
});
|
||||
}
|
||||
|
||||
function linkAndEscape(str) {
|
||||
if (!str) return '';
|
||||
|
||||
const escaped = str
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''');
|
||||
|
||||
const urlRegex = /(https?:\/\/[^\s]+)/g;
|
||||
|
||||
return escaped.replace(urlRegex, (url) => {
|
||||
const safeUrl = encodeURI(url);
|
||||
return `<a href="${safeUrl}" target="_blank">${safeUrl}</a>`;
|
||||
});
|
||||
}
|
||||
|
||||
async function fetchCalendar(url) {
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch calendar: ${response.status} ${response.statusText}`);
|
||||
throw new Error(`http: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
const icsData = await response.text();
|
||||
const jcalData = ICAL.parse(icsData);
|
||||
|
|
@ -43,7 +61,7 @@ function drawEventList(events) {
|
|||
const li = document.createElement('li');
|
||||
const dateStr = `${event.start.toLocaleDateString('en-US', dateOptions)}`.toLocaleLowerCase();
|
||||
const timeStr = `${event.start.toLocaleTimeString('en-US', timeOptions)} - ${event.end.toLocaleTimeString('en-US', timeOptions)}`.toLocaleLowerCase();
|
||||
const descriptionStr = event.description ? `<br>${escape(event.description)}` : '';
|
||||
const descriptionStr = event.description ? `<br>${linkAndEscape(event.description)}` : '';
|
||||
const recurrence = event.recurrence ? `${event.recurrence}<br>`.toLocaleLowerCase() : '';
|
||||
li.innerHTML = `${escape(event.summary)}<span class="secondary">${descriptionStr}<br>${recurrence}${dateStr}<br>${timeStr}</span>`;
|
||||
ul.appendChild(li);
|
||||
|
|
@ -70,10 +88,19 @@ function getUpcomingEvents(vcalendar, numEvents = 10) {
|
|||
|
||||
const upcomingEvents = [];
|
||||
|
||||
let titlesSeen = new Set();
|
||||
|
||||
events.forEach(event => {
|
||||
const icalEvent = new ICAL.Event(event);
|
||||
|
||||
if (icalEvent.isRecurring()) {
|
||||
// an attempt at preventing duplicate events when the same event was
|
||||
// preempted by an one-off instance created by editing the single
|
||||
// occurrence in NextCloud.
|
||||
if (titlesSeen.has(icalEvent.summary)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const expand = icalEvent.iterator();
|
||||
let next;
|
||||
|
||||
|
|
@ -85,6 +112,7 @@ function getUpcomingEvents(vcalendar, numEvents = 10) {
|
|||
const end = next.clone();
|
||||
end.addDuration(duration);
|
||||
if (end.compare(hoursAfterEnd) >= 0) {
|
||||
titlesSeen.add(icalEvent.summary);
|
||||
upcomingEvents.push({
|
||||
summary: icalEvent.summary,
|
||||
description: icalEvent.description,
|
||||
|
|
@ -98,6 +126,7 @@ function getUpcomingEvents(vcalendar, numEvents = 10) {
|
|||
} else {
|
||||
const eventStart = icalEvent.startDate;
|
||||
if (eventStart.compare(hoursAfterEnd) >= 0) {
|
||||
titlesSeen.add(icalEvent.summary);
|
||||
upcomingEvents.push({
|
||||
summary: icalEvent.summary,
|
||||
description: icalEvent.description,
|
||||
|
|
@ -108,6 +137,8 @@ function getUpcomingEvents(vcalendar, numEvents = 10) {
|
|||
}
|
||||
});
|
||||
|
||||
console.log("events added: " + Array.from(titlesSeen));
|
||||
|
||||
return upcomingEvents.sort((a, b) => a.start - b.start).slice(0, numEvents);
|
||||
}
|
||||
|
||||
|
|
@ -124,7 +155,12 @@ async function doCalendar(calendarUrl, targetElementId) {
|
|||
targetElement.appendChild(eventList);
|
||||
}
|
||||
catch (error) {
|
||||
targetElement.innerHTML = '<p>Sorry - couldn\'t load the calendar :(</p> <small>' + error + '</small>';
|
||||
console.error("Error fetching calendar:", error);
|
||||
targetElement.innerHTML = '';
|
||||
targetElement.appendChild(createError({
|
||||
thing: "calendar",
|
||||
message: error.toString()
|
||||
}));
|
||||
}
|
||||
}
|
||||
doCalendar(icsUrl, 'cal-parsed');
|
||||
|
|
|
|||
60
index-common.js
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
function escape(str) {
|
||||
return str.replace(/[&<>"'/]/g, function (char) {
|
||||
const escapeMap = {
|
||||
'&': '&',
|
||||
'<': '<',
|
||||
'>': '>',
|
||||
'"': '"',
|
||||
"'": ''',
|
||||
'/': '/'
|
||||
};
|
||||
return escapeMap[char] || char;
|
||||
});
|
||||
}
|
||||
|
||||
function elem(parent, query, value = undefined, unsafeHtml = false) {
|
||||
/** @type {HTMLElement} */
|
||||
const element = parent.querySelector(query);
|
||||
if (!element) {
|
||||
throw new Error(`Element not found for query: ${query}`);
|
||||
}
|
||||
|
||||
if (value !== undefined) {
|
||||
if (unsafeHtml) {
|
||||
element.innerHTML = value;
|
||||
} else {
|
||||
element.textContent = value;
|
||||
}
|
||||
} else {
|
||||
return element;
|
||||
}
|
||||
}
|
||||
|
||||
function createError({ thing, message }) {
|
||||
/** @type {HTMLTemplateElement} */
|
||||
const errorTemplate = document.getElementById("error-template");
|
||||
|
||||
const errorElement = errorTemplate.content.firstElementChild.cloneNode(true);
|
||||
elem(errorElement, `[data-slot="thing"]`, thing);
|
||||
elem(errorElement, `[data-slot="message"]`, message);
|
||||
|
||||
return errorElement;
|
||||
}
|
||||
|
||||
function linkAndEscape(str) {
|
||||
if (!str) return '';
|
||||
|
||||
const escaped = str
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''');
|
||||
|
||||
const urlRegex = /(https?:\/\/[^\s]+)/g;
|
||||
|
||||
return escaped.replace(urlRegex, (url) => {
|
||||
const safeUrl = encodeURI(url);
|
||||
return `<a href="${safeUrl}" target="_blank">${safeUrl}</a>`;
|
||||
});
|
||||
}
|
||||
30
index-health.js
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
(async () => {
|
||||
const el = document.getElementById('service-warning');
|
||||
if (!el) return;
|
||||
|
||||
// checks healthchecks.io to see if any of our important services are down
|
||||
// in the future maybe we do something self-hosted?
|
||||
async function areWeLosing() {
|
||||
const r = await fetch('https://healthchecks.io/b/2/f564cd28-6a7b-474c-bd33-aea7b641d359.json', { cache: 'no-store' });
|
||||
if (!r.ok) throw new Error(`http: ${r.status} ${r.statusText}`);
|
||||
const status = await r.json();
|
||||
if (!status || typeof status.down != 'number') {
|
||||
throw new Error('unexpected healthcheck response: ' + JSON.stringify(status));
|
||||
}
|
||||
return status.down > 0;
|
||||
}
|
||||
|
||||
try {
|
||||
const isDown = await areWeLosing();
|
||||
if (isDown) {
|
||||
el.innerHTML = '<strong>oh naur!</strong> some space services are currently down, so not all web interactions might work. to report this incident, <a href="#contact">contact us</a>.';
|
||||
el.hidden = false;
|
||||
} else {
|
||||
el.hidden = true;
|
||||
}
|
||||
} catch (e) {
|
||||
// if something goes wrong, no need to alert the visitor since this is just extra credit.
|
||||
console.error('Error checking service health:', e);
|
||||
el.hidden = true;
|
||||
}
|
||||
})();
|
||||
192
index-newsfeed.js
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
const newsFeed = document.getElementById("news-feed");
|
||||
const newsList = document.getElementById("news-list");
|
||||
|
||||
/** @type {HTMLButtonElement} */
|
||||
const newsFeedRight = document.getElementById("news-feed-right");
|
||||
|
||||
/** @type {HTMLTemplateElement} */
|
||||
const newsItemTemplate = document.getElementById("news-item-template");
|
||||
|
||||
const timeAgoFormatter = new Intl.RelativeTimeFormat(undefined, {
|
||||
style: "short",
|
||||
numeric: "auto",
|
||||
});
|
||||
|
||||
async function main() {
|
||||
newsFeedRight.addEventListener("click", () => {
|
||||
if (newsFeedRight.dataset.last == "true") {
|
||||
newsFeedRight.dataset.last = false;
|
||||
|
||||
newsList.scrollTo({ left: 0 });
|
||||
return;
|
||||
}
|
||||
|
||||
const currentItem = currentItemInNewsList();
|
||||
const nextItem = currentItem?.nextElementSibling;
|
||||
newsList.scrollTo({ left: nextItem.offsetLeft });
|
||||
|
||||
updateNewsFeedRightButton();
|
||||
});
|
||||
|
||||
newsList.addEventListener("scroll", () => {
|
||||
updateNewsFeedRightButton();
|
||||
});
|
||||
|
||||
await fetchNewsFeed();
|
||||
}
|
||||
|
||||
// updateNewsFeedRightButton updates the news feed right button's
|
||||
// dataset properties.
|
||||
function updateNewsFeedRightButton() {
|
||||
const isScrollEnd =
|
||||
newsList.scrollLeft + newsList.clientWidth >= newsList.scrollWidth;
|
||||
|
||||
const currentItem = currentItemInNewsList();
|
||||
const nextItem = currentItem?.nextElementSibling;
|
||||
|
||||
newsFeedRight.dataset.last = !nextItem || isScrollEnd;
|
||||
}
|
||||
|
||||
// currentItemInNewsList returns the currently shown item in the news feed,
|
||||
// defined by the scroll position of the newsList. If the scroll position
|
||||
// is at the end of the list, it returns null.
|
||||
function currentItemInNewsList() {
|
||||
const scrollLeft = newsList.scrollLeft;
|
||||
const children = [...newsList.children];
|
||||
return children.find((item) => item.offsetLeft >= scrollLeft);
|
||||
}
|
||||
|
||||
// fetchNewsFeed fetches the news feed from the server and appends them to
|
||||
// newsList.
|
||||
async function fetchNewsFeed(afterID = null) {
|
||||
newsFeed.querySelector(".error")?.remove();
|
||||
newsList.replaceChildren();
|
||||
|
||||
try {
|
||||
const query = afterID ? `?after=${afterID}` : "";
|
||||
const response = await fetch(`/news.json?${query}`, {
|
||||
headers: { "Accept": "application/json" },
|
||||
credentials: "omit",
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`http: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
|
||||
const feed = await response.json();
|
||||
const newsItems = feed.map((item) =>
|
||||
createNewsItem({
|
||||
id: item.id,
|
||||
createdAt: item.created_at,
|
||||
editedAt: item.edited_at,
|
||||
username: item.author.username,
|
||||
content: item.content,
|
||||
thumbnailURL: item.thumbnail_url,
|
||||
thumbnailURLSmall: item.thumbnail_url_small,
|
||||
tracTicketID: item.trac_ticket_id,
|
||||
})
|
||||
);
|
||||
|
||||
newsList.append(...newsItems);
|
||||
|
||||
newsFeed.dataset.initial = false;
|
||||
newsFeed.dataset.error = false;
|
||||
} catch (err) {
|
||||
console.error("Error fetching news feed:", err);
|
||||
|
||||
newsFeed.append(createError({
|
||||
thing: "news feed",
|
||||
message: `${err}`
|
||||
}));
|
||||
newsFeed.dataset.error = true;
|
||||
}
|
||||
}
|
||||
|
||||
function createNewsItem({
|
||||
id,
|
||||
createdAt,
|
||||
editedAt,
|
||||
username,
|
||||
content,
|
||||
thumbnailURL,
|
||||
thumbnailURLSmall,
|
||||
tracTicketID,
|
||||
}) {
|
||||
const newsItem = newsItemTemplate.content.firstElementChild.cloneNode(true);
|
||||
|
||||
newsItem.id = `news-${id}`;
|
||||
|
||||
elem(newsItem, ".news-username", username);
|
||||
elem(newsItem, ".news-avatar").alt = `${username}'s avatar`;
|
||||
elem(newsItem, ".news-avatar").src =
|
||||
`https://members.devhack.net/user/avatar/${username}`;
|
||||
elem(newsItem, ".news-created-time", createdAgoString(createdAt));
|
||||
elem(newsItem, ".news-created-time").dateTime = createdAt;
|
||||
elem(newsItem, ".news-created-time").title = createdAtTimestamp(createdAt);
|
||||
elem(newsItem, ".news-content", linkAndEscape(content), true);
|
||||
|
||||
if (editedAt) {
|
||||
elem(newsItem, ".news-edited").title = createdAtTimestamp(editedAt);
|
||||
} else {
|
||||
elem(newsItem, ".news-edited").setAttribute("hidden", "");
|
||||
elem(newsItem, ".news-edited").setAttribute("aria-hidden", "true");
|
||||
}
|
||||
|
||||
if (thumbnailURL) {
|
||||
elem(newsItem, ".news-thumbnail-link").href = thumbnailURL;
|
||||
elem(newsItem, ".news-thumbnail-link").target = "_blank";
|
||||
|
||||
elem(newsItem, ".news-thumbnail-image").src = thumbnailURLSmall ??
|
||||
thumbnailURL;
|
||||
elem(newsItem, ".news-thumbnail-image").alt = `thumbnail image for post`;
|
||||
}
|
||||
|
||||
if (tracTicketID) {
|
||||
elem(newsItem, ".news-trac-ticket-id", `#${tracTicketID}`);
|
||||
elem(newsItem, ".news-trac-ticket-id").target = "_blank";
|
||||
elem(newsItem, ".news-trac-ticket-id").href =
|
||||
`https://bugs.devhack.net/ticket/${tracTicketID}`;
|
||||
}
|
||||
|
||||
return newsItem;
|
||||
}
|
||||
|
||||
function createdAgoString(createdAt) {
|
||||
const now = new Date();
|
||||
const createdAtDate = new Date(Date.parse(createdAt));
|
||||
const diffMs = createdAtDate - now; // Negative for past dates
|
||||
|
||||
// Convert to various time units. The following calculates are just heuristics
|
||||
// and are not accurate for all months/years. This is fine because it is just
|
||||
// a human-readable approximation.
|
||||
const diffHours = diffMs / (1000 * 60 * 60);
|
||||
const diffDays = diffHours / 24;
|
||||
const diffMonths = diffDays / 30;
|
||||
const diffYears = diffDays / 365;
|
||||
|
||||
if (Math.abs(diffYears) >= 1) {
|
||||
return timeAgoFormatter.format(Math.round(diffYears), "year");
|
||||
}
|
||||
if (Math.abs(diffMonths) >= 1) {
|
||||
return timeAgoFormatter.format(Math.round(diffMonths), "month");
|
||||
}
|
||||
if (Math.abs(diffDays) >= 1) {
|
||||
return timeAgoFormatter.format(Math.round(diffDays), "day");
|
||||
}
|
||||
return timeAgoFormatter.format(Math.round(diffHours), "hour");
|
||||
}
|
||||
|
||||
function createdAtTimestamp(createdAt) {
|
||||
const createdAtDate = new Date(Date.parse(createdAt));
|
||||
return createdAtDate.toLocaleString(undefined, {
|
||||
weekday: "long",
|
||||
month: "numeric",
|
||||
day: "numeric",
|
||||
year: "numeric",
|
||||
hour: "numeric",
|
||||
minute: "numeric",
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
main();
|
||||
77
index-spaceapi.js
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
const spaceapiUrl = '/spaceapi.json';
|
||||
|
||||
|
||||
function escape(str) {
|
||||
return str.replace(/[&<>"'/]/g, function (char) {
|
||||
const escapeMap = {
|
||||
'&': '&',
|
||||
'<': '<',
|
||||
'>': '>',
|
||||
'"': '"',
|
||||
"'": ''',
|
||||
'/': '/'
|
||||
};
|
||||
return escapeMap[char] || char;
|
||||
});
|
||||
}
|
||||
|
||||
/* figures out what unit a time value should be displayed in, then returns the value in that unit and the name of that unit */
|
||||
function secondsToValueInUnit(seconds) {
|
||||
const absSeconds = Math.abs(seconds);
|
||||
if (absSeconds < 3600) {
|
||||
return [Math.round(seconds / 60), 'minutes'];
|
||||
}
|
||||
if (absSeconds < 86400) {
|
||||
return [Math.round(seconds / 3600), 'hours'];
|
||||
}
|
||||
return [Math.round(seconds / 86400), 'days'];
|
||||
}
|
||||
|
||||
// Main function :)
|
||||
async function doSpaceapi(url, targetElementId) {
|
||||
const targetElement = document.getElementById(targetElementId);
|
||||
|
||||
try {
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) {
|
||||
throw new Error(`http: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
|
||||
let spaceapi;
|
||||
try {
|
||||
spaceapi = await response.json();
|
||||
} catch (jsonError) {
|
||||
throw new Error('bad json? ' + jsonError.message);
|
||||
}
|
||||
|
||||
console.log(spaceapi);
|
||||
const state = spaceapi["state"];
|
||||
const sensors = spaceapi["sensors"];
|
||||
|
||||
var openHtml = '';
|
||||
if (state && state.lastchange && typeof state.open !== 'undefined') {
|
||||
const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' })
|
||||
const elapsed = secondsToValueInUnit(state.lastchange - (Date.now() / 1000.0));
|
||||
const status = state.open ? '<a href="https://wiki.devhack.net/Entering_The_Space#Kinds_of_%22Open%22" target="_blank">doors open</a>!' : 'closed,';
|
||||
openHtml = `space: ${status} as of ${rtf.format(elapsed[0], elapsed[1])} `;
|
||||
}
|
||||
|
||||
var tempHtml = openHtml ? '<br>' : '';
|
||||
if (sensors && sensors.temperature && sensors.temperature[0] && sensors.temperature[0].value) {
|
||||
const temp = Math.round(sensors.temperature[0].value);
|
||||
const unit = sensors.temperature[0].unit;
|
||||
tempHtml = tempHtml + 'temp: ' + temp + unit + ' inside'
|
||||
}
|
||||
|
||||
targetElement.innerHTML = '<p>' + openHtml + tempHtml + '</p>';
|
||||
}
|
||||
catch (error) {
|
||||
console.error("Error fetching spaceapi:", error);
|
||||
targetElement.innerHTML = '';
|
||||
targetElement.appendChild(createError({
|
||||
thing: "spaceapi",
|
||||
message: error.toString()
|
||||
}));
|
||||
}
|
||||
}
|
||||
doSpaceapi(spaceapiUrl, 'spaceapi-body');
|
||||
134
index.html
|
|
@ -1,43 +1,145 @@
|
|||
<!DOCTYPE html>
|
||||
<!-- Look at you, hacker: a pathetic creature of meat and bone, panting and sweating as you run through my corridors. How can you challenge a perfect, immortal machine? -->
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>/dev/hack</title>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<meta name="description" content="seattle hackerspace focused on community and building cool things">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<link rel="canonical" href="https://www.devhack.net/">
|
||||
<script src="vendor/ical.min.js"></script>
|
||||
<script src="vendor/rrule.2.8.1.min.js"></script>
|
||||
<script src="vendor/rrule.js"></script>
|
||||
<script src="vendor/polyfill.min.js"></script>
|
||||
<script src="index-common.js"></script>
|
||||
<script defer src="index-cal.js"></script>
|
||||
<script defer src="index-spaceapi.js"></script>
|
||||
<script defer src="index-newsfeed.js" type="module"></script>
|
||||
<script defer src="index-health.js"></script>
|
||||
<link rel="canonical" href="http://devhack.net" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<h1>/dev/hack
|
||||
<span style="display: inline-block; white-space: nowrap">$
|
||||
<span class="holder" style="display: inline-block; white-space: nowrap">$
|
||||
<!-- decorative, for the cool prompt effect -->
|
||||
<input aria-hidden="true" type="text" autofocus size="2" name="_"></span>
|
||||
</h1>
|
||||
<p class="block">seattle hackerspace</p>
|
||||
<p class="meow"><strong>queer</strong>, <strong>anarchist</strong>, <strong>leftist</strong>, seattle hackerspace<br>focused on community and building cool things</p>
|
||||
<a href="more.html">click here to learn more </a>
|
||||
<p class="block">
|
||||
<span class="address">4534½ university way n.e.
|
||||
<span class="address">4534 1/2 university way ne
|
||||
<br>press [#] on keypad for doorbell
|
||||
<br>
|
||||
see info on: <a href="https://wiki.devhack.net/Directions">getting here</a> and
|
||||
visiting info: <a href="https://wiki.devhack.net/Entering_The_Space">space access</a>,
|
||||
<a href="https://wiki.devhack.net/Directions">directions</a>, and
|
||||
<a href="https://wiki.devhack.net/Accessibility">accessibility</a>
|
||||
</span>
|
||||
</p>
|
||||
<h2>calendar <span class="small">(<a href="/calendar.ics">ics</a>)</span></h2>
|
||||
<div id="cal-parsed">
|
||||
|
||||
<h2 id="status">status <span class="small">(<a href="https://mapall.space/heatmap/show.php?id=/dev/hack">stats</a>,
|
||||
<a href="/spaceapi.json">spaceapi.json</a>)</span></h2>
|
||||
<div id="service-warning" class="error" hidden role="alert"></div>
|
||||
|
||||
<div id="spaceapi-body">
|
||||
<ul>
|
||||
<li>loading...</li>
|
||||
<li>loading... (do you have javascript?)</li>
|
||||
</ul>
|
||||
</div>
|
||||
<h2>contact</h2>
|
||||
<ul>
|
||||
<!-- use HTML entities to obfuscate email address -->
|
||||
<li>e-mail: <a
|
||||
href="mailto:hello-25@devhack.net">hello@devhack.net</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2>
|
||||
what's new
|
||||
<span class="small">(
|
||||
<a href="https://members.devhack.net/news">add</a>,
|
||||
<a href="https://members.devhack.net/news/feed.json">json</a>,
|
||||
<a href="https://members.devhack.net/news/feed.atom">atom</a>
|
||||
)</span>
|
||||
</h2>
|
||||
<div id="news-feed">
|
||||
<div id="news-feed-gradient" class="overlay"></div>
|
||||
<div id="news-feed-controls" class="overlay">
|
||||
<button id="news-feed-right" aria-label="next news item">
|
||||
<svg width="24px" height="24px">
|
||||
<use href="/assets/arrow_forward_ios.svg#img"></use>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<ul id="news-list">
|
||||
<li>loading... (do you have JavaScript?)</li>
|
||||
</ul>
|
||||
</div>
|
||||
<template id="news-item-template">
|
||||
<li class="news-item">
|
||||
<header class="news-author">
|
||||
<img class="news-avatar" />
|
||||
<p>
|
||||
<span class="news-username"></span>
|
||||
<br />
|
||||
<time class="news-created-time"></time>
|
||||
<span class="news-edited"><!--(edited)--></span>
|
||||
</p>
|
||||
</header>
|
||||
<p class="news-body">
|
||||
<span class="news-content"></span>
|
||||
<a class="news-trac-ticket-id"></a>
|
||||
</p>
|
||||
<a class="news-thumbnail-link" role="button">
|
||||
<img class="news-thumbnail-image" />
|
||||
</a>
|
||||
</li>
|
||||
</template>
|
||||
|
||||
<h2 id="calendar">calendar <span class="small">(<a href="/calendar.ics">ics</a>)</span></h2>
|
||||
<div id="cal-parsed">
|
||||
<ul>
|
||||
<li>loading... (do you have JavaScript?)</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h2 id="contact">contact</h2>
|
||||
<dl>
|
||||
<!-- use HTML entities to obfuscate email address -->
|
||||
<dt>chats</dt>
|
||||
<dd>
|
||||
<a href="https://matrix.to/#/#lobby:devhack.net"
|
||||
target="_blank">#lobby:devhack.net</a>
|
||||
on matrix
|
||||
(<a href="https://wiki.devhack.net/Chatspace" target="_blank">wiki</a>)
|
||||
</dd>
|
||||
<dt>e-mail</dt>
|
||||
<dd><a
|
||||
href="mailto:hello-25@devhack.net">hello@devhack.net</a>
|
||||
</dd>
|
||||
<dt>telephony</dt>
|
||||
<dd>
|
||||
- voice: <a href="tel:+18333384225">+1 (833) DEV-HACK</a><br>
|
||||
- fax: <a href="tel:+18443384225">+1 (844) DEV-HACK</a><br>
|
||||
- payphone: <a href="tel:+15648887373">+1 (564) 888-7373</a>
|
||||
</dd>
|
||||
<dt>mail (send us cards!)</dt>
|
||||
<dd>/dev/hack<br>
|
||||
4534 1/2 University Way NE<br>
|
||||
Seattle, WA 98105-4528<br>
|
||||
US (<a href="https://wiki.devhack.net/Mail" target="_blank">wiki</a>)
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<template id="error-template">
|
||||
<div class="error">
|
||||
<strong>issue loading <span data-slot="thing"></span></strong>
|
||||
<small>
|
||||
<span data-slot="message"></span>
|
||||
<br />
|
||||
</small>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<footer>
|
||||
<a href="more.html#acknowledgements">
|
||||
underwriting / acknowledgements
|
||||
</a>
|
||||
</footer>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
|||
41
lore/error.html
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en"><head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8"><meta charset="UTF-8">
|
||||
<title>/dev/hack</title>
|
||||
|
||||
<!-- random bullshit V -->
|
||||
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1"> <meta name="description" content="seattle hackerspace focused on community and building cool things"> <link rel="stylesheet" href="/lore/errorstyle.css"> <link rel="canonical" href="https://www.devhack.net/">
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<p class="header header1">xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</p>
|
||||
|
||||
<p class="grouphug grouphugL">xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</p>
|
||||
<p class="grouphug grouphugR">xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/p>
|
||||
|
||||
<p class="baby">⠀<span class="violet">⣈⣛⠀⠀⣐⠋</span><span class="gray">⠀⠀⠀⠀⠀⠀</span><span class="redpink">⠀⠀⠰</span><span class="gray">⣏</span><span class="redpink">⡼⠷⢄⠅⠀</span><span class="gray">⠀⠀⠀⠀</span><span class="limegreen">⠙⠦⠥⠯⢉⠵⠋⠀</span><span class="gray">⠀⠀⠀⠀</span><span class="pink">⠛⢻⡷⠃</span><span class="violet">⣀⡴⠀</span><span class="gray">⠀⠀⠀</span><span class="redpink">⠀⠈⠑⠛
|
||||
</span><span class="gray">⠀</span><span class="violet">⠱⣡</span><span class="gray">⡆</span><span class="violet">⢰⡬⠛</span><span class="redpink">⢰⡞⢳⡀</span><span class="gray">⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀</span><span class="lightblue2">⠀⡠⠤⡄</span><span class="gray">⠀⠀⠀⠀⠀⠀⠀</span><span class="pink">⠀⣠⠟</span><span class="gray">⠀</span><span class="violet">⢺⣝⡧⠀</span><span class="gray">⠀</span><span class="pink">⠀⡀⢀⡠⠠⡀
|
||||
</span><span class="gray">⠀⠀</span><span class="violet">⠉⠈⠀</span><span class="gray">⠁⠀</span><span class="redpink">⠘⠾⠻⠉</span><span class="white">⣀⣠⣤⣴⣶⣶⣶⣶⣦⣤⣄</span><span class="lightblue2">⡀</span><span class="gray">⠀⠀</span><span class="lightblue2">⣠⠊⠀⢰⠃</span><span class="gray">⠀</span><span class="yellowgreen">⡼⡉⢳⠀</span><span class="gray">⠀⠀⠀⠀⠀</span><span class="violet">⠰⠋⠁</span><span class="gray">⠀⠀</span><span class="pink">⢀⡸⣀⣠⠅⡰⠃
|
||||
</span><span class="gray">⠀⠀</span><span class="pink">⠀⢀⡀⢲⢒⠂</span><span class="gray">⠀⠀</span><span class="white">⣞⠱⣯⣉⣀⣀⣀⣀⣀⣠⡭⠇⣹</span><span class="gray">⠆</span><span class="lightblue2">⢰⠃⠀⠀</span><span class="gray">⡘⠀</span><span class="yellowgreen">⠀⠉</span><span class="gray">⢓</span><span class="yellowgreen">⠋</span><span class="limegreen">⢠⣲⢦</span><span class="gray">⠀⠀⠀</span><span class="lightblue">⠀⢀⡴⠋⡜</span><span class="pink">⠈⠛⠉⠢⡴⠁⠀
|
||||
</span><span class="gray">⠀</span><span class="pink">⠀⠴⢍⣹⣄⠾⠀</span><span class="gray">⠀⠀</span><span class="white">⠈⠑⠒⠒⠒⠒⠒⠒⠒⠒⠚⠉⠁</span><span class="lightblue2">⡠⠃</span><span class="gray">⠀⠀</span><span class="lightblue2">⠠⡇</span><span class="gray">⠀</span><span class="yellowgreen">⠀⠰⣣⣱</span><span class="gray">⠀</span><span class="limegreen">⠉⠉</span><span class="gray">⠀⠀</span><span class="lightblue">⠀⢠⠊⠀⡰</span><span class="gray">⠁⠀⠀⠀⠀⠀⠀⠀
|
||||
</span><span class="pink">⠀⢸⠒⢒⣂⠬⠀</span><span class="gray">⠀⠀⠀⠀</span><span class="lightblue">⠀⠀</span><span class="gray">⠀⠀⠀⠀⠀⠀⠀⠀</span><span class="lightblue2">⠈⠉⠈⠉⠒⠤⠤⠳</span><span class="gray">⣄⠀⠀⠈⠀</span><span class="lightblue">⣠⢲⠀⠀⣀⠴⠃⠀⢰⠁</span><span class="gray">⠀⠀⠀⠀⠀⠀⠀⠀
|
||||
</span><span class="lightgold">⣄⣀⣉⠁</span><span class="gray">⠀⠀⠀⢀</span><span class="lightblue">⡤⠂⠁</span><span class="gray">⠀</span><span class="lightblue">⠀</span><span class="gray">⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀</span><span class="lightblue">⠈⠋⢿⣓⠫⡉⠉⠉⠉⠇⠇⢇⠀⠸⡀</span><span class="gray">⠀⠀</span><span class="lightgold">⢠⠏⣆⡞⡆</span><span class="gray">⠀
|
||||
</span><span class="lightgold">⠀⢰⠁⠀</span><span class="gray">⠀⠀⠀</span><span class="lightblue">⣎⠀</span><span class="gray">⠀⠀⠀</span><span class="lightblue">⠀⠀</span><span class="gray">⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀</span><span class="lightblue">⠀⠀⠻⠆⠲⣰⠀⠀⣸⠜⠛⢤⣀⠐⡄</span><span class="gray">⠀</span><span class="lightgold">⣼⢰⣹⣹⠁⠀
|
||||
⠋⠑⠓</span><span class="gray">⡀⠀⠀⠀</span><span class="lightblue">⠸⣄⣀</span><span class="gray">⠀⠀⠀</span><span class="lightblue">⢀⣀⡀⠀</span><span class="gray">⠀</span><span class="lightblue">⠀⠆⣄⠀</span><span class="gray">⠀⠀⠀⠀⠀⠀⠀⠀</span><span class="lightblue">⠀⠀⠁⠘⢀⣸⣔⣊⠁</span><span class="gray">⠀⠀</span><span class="lightgold">⣄</span><span class="gray">⠀</span><span class="lightblue">⠉⠁</span><span class="gray">⠀</span><span class="lightgold">⣇⠇⣿⠃⠀⠀
|
||||
⠀⠰⣴⢿⣤⠄</span><span class="gray">⠀⠀⠈</span><span class="lightblue">⠢⡉⠉⠁⠘⠫⢥⢆⡞⣼⣼⣏⣌⢎⠄</span><span class="gray">⠀⠀</span><span class="lightblue">⠀⢀⡀⠀⠀⠀⠒⠊⠙⠳⣴⠉⠀</span><span class="gray">⠀</span><span class="lightgold">⣼⡁⢹⠖⠀⢀⣟⣘⡃⠀</span><span class="gray">⠀⠀
|
||||
</span><span class="lightgold">⠀⠀⠟⠛⠇⠀</span><span class="gray">⠀⠀⠀</span><span class="lightblue">⠀⠈⠒⠠⢔⣀</span><span class="gray">⠀⠀⠀⠁⠈⠀⠈</span><span class="lightblue">⢹⣂</span><span class="gray">⠀⠀</span><span class="lightblue">⠀⠫⡀⠀</span><span class="gray">⠀⠀⠀⠀⠀⠀⠀</span><span class="lightgold">⠀⡀</span><span class="gray">⠀</span><span class="lightgold">⠀⢹⡏⠀</span><span class="gray">⠀</span><span class="lightgold">⠘⠛⠻⠃⠀</span><span class="gray">⠀⠀
|
||||
⠀⠀</span><span class="indigo">⠀⠀⢀⡤⠖⠚⢷⠀</span><span class="lightblue">⠀⠀⠀⠀⠀⢉⡶⣒⢤⠀</span><span class="gray">⠀⠀</span><span class="lightblue">⠐⠓⠤⣀⠀</span><span class="gray">⠀⠈</span><span class="lightblue">⠑⠢⠤⢀</span><span class="gray">⠀⠀⠀</span><span class="lightgold">⢀⣴⣛⡶</span><span class="gray">⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||
</span><span class="indigo">⠀⠀⡠⢞⣡⠴⠒⠋⠉⡆⠀</span><span class="gray">⠀⠀⠀</span><span class="lightblue">⠀⢸⡁⣣⠞⠀</span><span class="gray">⠀⠀⠀⠀</span><span class="lightgold">⢠</span><span class="gray">⠀</span><span class="lightblue">⠉⠁⠒⠛⠒⠒⠋</span><span class="gray">⠀⠀</span><span class="limegreen">⢀</span><span class="gray">⡀⠀</span><span class="lightgold">⠹⠁</span><span class="gray">⠀⠀⠀⠀⠀⠀⠀</span><span class="redpink">⠀⣤⣸⣵⡀
|
||||
</span><span class="indigo">⣠⣮⣖⣫⠔⠒⠉⠉⠉⢻⠀</span><span class="gray">⠀⠀⠀</span><span class="lightblue">⠀⠀⠟⠁</span><span class="gray">⠀⠀⠀⠀</span><span class="lightgold">⠀⢹⡯⣷</span><span class="gray">⠂⠀⠀</span><span class="limegreen">⢸⣍⠉⠓⣲⠋⠉⠉⠙⢦⡀</span><span class="gray">⠀⠀⠀⠀⠀⠀</span><span class="limegreen">⡀</span><span class="gray">⠀</span><span class="redpink">⢿⣿⡽⠃
|
||||
</span></p>
|
||||
|
||||
<h2 id="contact">404 page not found.</h2>
|
||||
<a class="header3" href="https://www.devhack.net/">click here to return home</a>
|
||||
|
||||
<p class="header header2">xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</p>
|
||||
|
||||
</body></html>
|
||||
449
lore/errorstyle.css
Normal file
|
|
@ -0,0 +1,449 @@
|
|||
@import url('vendor/berkeley_mono_transfonter/stylesheet.css');
|
||||
|
||||
body {
|
||||
background: black;
|
||||
color: lime;
|
||||
font-family: 'Berkeley Mono', Menlo, 'Cascadia Code', Consolas, Courier, monospace;
|
||||
line-height: 1.15;
|
||||
margin: 0px 20% 5% 20%;
|
||||
border: 10px red;
|
||||
font-size: 16px;
|
||||
max-width: 800px;
|
||||
overflow-y: hidden;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.baby{
|
||||
color:#b4ff9994;
|
||||
position: absodlute;
|
||||
font-size: 3.5vmin;
|
||||
left:;
|
||||
bottom: ;
|
||||
z-index: -1;
|
||||
padding-top: 1.7em;
|
||||
}
|
||||
|
||||
.header{
|
||||
position: absolute;
|
||||
left:0;
|
||||
z-index: 5;
|
||||
background-color: black;
|
||||
border:0.4em solid black;
|
||||
|
||||
}
|
||||
|
||||
h2{
|
||||
margin-bottom: 20px!important;
|
||||
}
|
||||
|
||||
.grouphug{
|
||||
position: absolute;
|
||||
max-width:2em;
|
||||
writing-mode: vertical-rl;
|
||||
padding: 0px 10px;
|
||||
color:grey!important;
|
||||
}
|
||||
|
||||
.grouphugL{
|
||||
left:0;
|
||||
}
|
||||
.grouphugR{
|
||||
right:0;
|
||||
}
|
||||
|
||||
.grouphug3{
|
||||
left:100;
|
||||
}
|
||||
|
||||
.header1{
|
||||
top:0;
|
||||
margin:2px;
|
||||
}
|
||||
|
||||
.header2{
|
||||
bottom:0;
|
||||
margin:0;
|
||||
}
|
||||
|
||||
.header1, .header2, .header3{
|
||||
font-size: 2.5vmin!important;
|
||||
color:grey!important;
|
||||
}
|
||||
|
||||
h2{
|
||||
font-size: 6.2vmin;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-type: '- ';
|
||||
}
|
||||
|
||||
li {
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
|
||||
dl {
|
||||
margin: 0;
|
||||
margin-block: 1em;
|
||||
padding-inline-start: 40px;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
dt {
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
|
||||
.holder {
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
|
||||
.secondary {
|
||||
color: #00b300;
|
||||
}
|
||||
|
||||
input[type="text"] {
|
||||
background-color: inherit;
|
||||
color: inherit;
|
||||
border: none;
|
||||
outline: none;
|
||||
font: inherit;
|
||||
caret-shape: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
h1,
|
||||
.block {
|
||||
margin: 40px 0px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
animation: headerGlow 4s infinite ease-in-out;
|
||||
text-shadow: 0 0 5px lime, 0 0 10px lime;
|
||||
}
|
||||
|
||||
@keyframes headerGlow {
|
||||
0% {
|
||||
opacity: 0.9;
|
||||
text-shadow: 0 0 3px lime, 0 0 7px lime;
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 1;
|
||||
text-shadow: 0 0 8px lime, 0 0 10px lime;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0.9;
|
||||
text-shadow: 0 0 3px lime, 0 0 7px lime;
|
||||
}
|
||||
}
|
||||
|
||||
h2 .small {
|
||||
display: inline-flex;
|
||||
|
||||
a:not(:first-child) {
|
||||
margin-left: 0.25em;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0.5em 0;
|
||||
}
|
||||
|
||||
a,
|
||||
a:visited {
|
||||
color: #84d7ba;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #d784a1;
|
||||
}
|
||||
|
||||
dt::before {
|
||||
content: ">";
|
||||
padding-right: 0.5em;
|
||||
}
|
||||
|
||||
.small {
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-size: 50%;
|
||||
}
|
||||
|
||||
.meow {
|
||||
margin: 0px 0px !important;
|
||||
}
|
||||
|
||||
.banners {
|
||||
margin: 40px 0px;
|
||||
}
|
||||
|
||||
img {
|
||||
image-rendering: pixelated;
|
||||
width: 85%;
|
||||
align-content: center;
|
||||
margin: auto;
|
||||
display: inline-block;
|
||||
filter: grayscale(30%);
|
||||
}
|
||||
|
||||
img:hover {
|
||||
filter: grayscale(0%);
|
||||
}
|
||||
|
||||
.grid-container {
|
||||
margin: 1em auto;
|
||||
}
|
||||
|
||||
.grid-container {
|
||||
padding: 10px;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.grid-container {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
.imgholder {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.imgholder img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.guysholder p {
|
||||
margin-top: 2em;
|
||||
}
|
||||
|
||||
#news-feed {
|
||||
position: relative;
|
||||
max-width: clamp(300px, 100%, 800px);
|
||||
|
||||
.overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
z-index: 10;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#news-feed-gradient {
|
||||
background: linear-gradient(to left,
|
||||
rgba(0, 0, 0, 1) 0,
|
||||
rgba(0, 0, 0, 0.8) 42px,
|
||||
transparent 100px,
|
||||
transparent 100%);
|
||||
}
|
||||
|
||||
#news-feed-controls {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#news-feed-right {
|
||||
cursor: pointer;
|
||||
pointer-events: all;
|
||||
|
||||
margin-left: auto;
|
||||
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
|
||||
border: 1px solid lime;
|
||||
border-radius: 99px;
|
||||
|
||||
color: lime;
|
||||
background-color: oklch(from lime 0.3 c h / 0.7);
|
||||
|
||||
transition:
|
||||
background-color 0.1s ease-in-out,
|
||||
transform 0.25s ease-in-out;
|
||||
|
||||
opacity: 0.7;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&[data-last="true"] {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
svg {
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#news-list {
|
||||
overflow: hidden;
|
||||
overflow-x: auto;
|
||||
|
||||
scrollbar-width: thin;
|
||||
scroll-behavior: smooth;
|
||||
scroll-snap-type: x mandatory;
|
||||
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 1rem;
|
||||
|
||||
list-style: none;
|
||||
|
||||
padding: 0;
|
||||
padding-right: 100px;
|
||||
/* space for gradient */
|
||||
margin: 0;
|
||||
|
||||
font-size: 0.85em;
|
||||
|
||||
.news-item {
|
||||
scroll-snap-align: start;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
overflow: auto;
|
||||
margin: 0;
|
||||
padding: 1em;
|
||||
|
||||
flex: 1 0 200px;
|
||||
min-height: 125px;
|
||||
max-height: 175px;
|
||||
|
||||
border: 1px solid oklch(from lime 0.3 c h);
|
||||
border-radius: 12px;
|
||||
|
||||
.news-author {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.news-avatar {
|
||||
border-radius: 6px;
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
margin: 0;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.news-username {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.news-edited {
|
||||
font-size: 0.75em;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.news-body {
|
||||
flex: 1;
|
||||
|
||||
margin-top: 1em;
|
||||
|
||||
margin-bottom: 0;
|
||||
padding-bottom: 1em;
|
||||
}
|
||||
|
||||
.news-thumbnail-link {
|
||||
display: block;
|
||||
|
||||
&:not([href]) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.news-thumbnail-image {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
object-fit: cover;
|
||||
border-radius: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
footer {
|
||||
margin-top: 5em;
|
||||
font-size: 0.8rem;
|
||||
text-align: right;
|
||||
max-width: 60%;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.footer-logo {
|
||||
height: 1em;
|
||||
width: auto;
|
||||
vertical-align: middle;
|
||||
margin-left: 0.25em;
|
||||
/* Override rendering for logos */
|
||||
image-rendering: auto;
|
||||
}
|
||||
|
||||
.error {
|
||||
border: 1px solid;
|
||||
padding: .75em 1em;
|
||||
margin: 1em 0;
|
||||
border-radius: 10px;
|
||||
font-size: 0.9em;
|
||||
max-width: 50%;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
padding-left: 10px;
|
||||
border-left: 2px solid;
|
||||
}
|
||||
|
||||
/* Mobile devices get slightly smaller margins, so that we actually have room
|
||||
* for text.
|
||||
*/
|
||||
@media only screen and (max-width: 749px) {
|
||||
body {
|
||||
margin: 50px 5% 5% 5%;
|
||||
}
|
||||
|
||||
.holder {
|
||||
width: 35%;
|
||||
}
|
||||
|
||||
.error {
|
||||
max-width: 80%;
|
||||
}
|
||||
}
|
||||
|
||||
.violet { color: #E5F }
|
||||
.gray { color: #999 }
|
||||
.redpink { color: #F86 }
|
||||
.limegreen { color: #0F0 }
|
||||
.pink { color: lightpink }
|
||||
.lightblue2 { color: #8CF }
|
||||
.white { color: #FFF }
|
||||
.yellowgreen { color: #CF7 }
|
||||
.lightblue { color: lightblue }
|
||||
.lightgold { color: #FF8 }
|
||||
.indigo { color: #97F }
|
||||
158
lore/schism.html
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="generator" content="pandoc" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||||
<title>schism</title>
|
||||
<style>
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
||||
div.column{flex: auto; overflow-x: auto;}
|
||||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||||
/* The extra [class] is a hack that increases specificity enough to
|
||||
override a similar rule in reveal.js */
|
||||
ul.task-list[class]{list-style: none;}
|
||||
ul.task-list li input[type="checkbox"] {
|
||||
font-size: inherit;
|
||||
width: 0.8em;
|
||||
margin: 0 0.8em 0.2em -1.6em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
|
||||
</style>
|
||||
<link rel="stylesheet" href="style.css" />
|
||||
<!--[if lt IE 9]>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="the-devhack-schism">The devhack schism</h1>
|
||||
<p><small>This is a complicated document to write -m</small></p>
|
||||
<hr />
|
||||
<h2 id="summary">Summary</h2>
|
||||
<p>One specific member joined devhack with misaligned expectations of
|
||||
what it was, conflicting with both the original founding intentions and
|
||||
the understanding of a large portion of the devhack active membership.
|
||||
In the 6 months of this member’s tenure, they contributed a great deal
|
||||
to the space but in the process alienated most of the former membership
|
||||
contributing to various aspects of the devhack project, including the
|
||||
original founding members and most of the infrastructure team.</p>
|
||||
<p>This concluded in both a <strong>ban</strong> and a subsequent
|
||||
standoff, shouting match, walk-out, and temporary closure by devhack
|
||||
membership on the space itself.</p>
|
||||
<p>The resulting ban cascaded from increased disengagement of long-time
|
||||
membership, reaching a tipping point that caused the leadership of
|
||||
devhack decided to make a unilateral decision to remove this member.
|
||||
Even though they were not communicated any warnings about this happening
|
||||
from leadership, this should not have come as a suprise, as they had
|
||||
been subject to substantial moderation – from both devhack leadership
|
||||
and peers at the space.</p>
|
||||
<h2 id="the-night-of-the-28th-of-august">The night of the 28th of
|
||||
august</h2>
|
||||
<p>Two days after an amicable exit interview, approximately 30 minutes
|
||||
before the townhall convened to discuss punitive board action, this
|
||||
person attempted to enter the space with the help of a few supporters.
|
||||
Many members blockaded the stairwell in response for some amount of
|
||||
time, before we decided to vacate the premises and hold an informal
|
||||
discussion at a park a few blocks away.</p>
|
||||
<p>During the blockade, this person was repeatedly asked to leave by
|
||||
devhack membership while both they and their supporters recited
|
||||
washington state law, questioned the space’s insurance status,
|
||||
unintentionally injured themselves and claimed they needed entry to the
|
||||
space for first aid, furled insults at devhack leadership and their
|
||||
supporters, and generally were just very loud and did quite a lot of
|
||||
emotional damage to those blockading the entrance and observers to these
|
||||
events. They also threatened to get in contact with devhack business
|
||||
partners to complain about our conduct throughout these events in an
|
||||
attempt to tarnish devhack’s business relationships.</p>
|
||||
<h2 id="consequences">Consequences</h2>
|
||||
<p>Consequently, these four additional members were banned from devhack
|
||||
and barred access for aiding in this person’s attempted entry. One ban
|
||||
has been rescinded due to overreach, and one is provisional due to their
|
||||
continued work with our business partners.</p>
|
||||
<p>Two of the banned members have threatened to enter the space with a
|
||||
police escort, one of the banned members has claimed to have filed a
|
||||
police report. One auxillary member has deferred all communications with
|
||||
us through legal counsel.</p>
|
||||
<p>These banned members have been invited to rightfully reclaim their
|
||||
personal equipment hosted at the space in a supervised fashion,
|
||||
alongside other members who have chosen to bow out. This has resulted in
|
||||
the loss of most of our networking equipment, most of our radio
|
||||
equipment, some retro equipment we actually liked, lots of auxillary
|
||||
tools, and other inconveniences.</p>
|
||||
<h2 id="background-flashpoints">Background / flashpoints</h2>
|
||||
<p>A concrete list of flashpoints contributing to this person’s
|
||||
removal:</p>
|
||||
<ul>
|
||||
<li>their introduction to the chatspace, and specifically
|
||||
infrastructure-related rooms, and subsequent disrespectful behaviour
|
||||
towards members resulted in a very explicit boundaries set by most of
|
||||
the infra team “we don’t want to work with you and we’re leaving the
|
||||
chats you look for help from us in”.</li>
|
||||
<li>entitlement to an audience by people who have communicated they do
|
||||
not want to engage, further alienating core devhack contributors and
|
||||
causing them to disengage further.</li>
|
||||
<li>upon communication of boundaries and the results of their actions,
|
||||
they had a rather angry rant about the state of things with lots of
|
||||
words directed at both the infra team and the leadership of devhack,
|
||||
resulting in an <a href="https://wiki.devhack.net/AskToLeave">ask to
|
||||
leave</a> from unrelated parties witnessing this. no further action was
|
||||
taken from this ATL.</li>
|
||||
<li>continuations of poor communication and collaboration skills during
|
||||
their attempted improvements of the space – including being
|
||||
disrespectful and dismissive towards prior work done at the space and
|
||||
verbally attacking professional partners of devhack while degrading the
|
||||
physical security of the space and the reliability of our services. The
|
||||
worst of this resulting in moderation action and subsequently met with
|
||||
an ATL invoked on the moderator by this person.</li>
|
||||
</ul>
|
||||
<p>Now, I do want to stress, this person contributed substantial hours
|
||||
to the space, just in a largely independent and uncommunicative manner;
|
||||
helping in some areas and hurting in others. Ultimately, /dev/hack is a
|
||||
cooperative enterprise, and undermining that cooperation harms the space
|
||||
more than volunteering helps it.</p>
|
||||
<!-- Now, I do want to stress, this person was being very helpful at the space and
|
||||
doing a lot to try to improve it. They were just doing so without taking into
|
||||
account any sort of reason for why things were done the way they were, doing so
|
||||
without polling the devhack membership at large for support/consensus, and
|
||||
generally just steamrolling progress without any sort of cooperation skills
|
||||
with those who have previously put in work to make the space what it is. This
|
||||
happened in part due to the fact that everyone who has previously put in work
|
||||
at the space did not like how they were treated by this person and did not want
|
||||
to speak to them or work with them in any respects beyond giving them
|
||||
credentials and links to existing documentation surrounding the work they were
|
||||
doing. -->
|
||||
<p>The ban was precipitated on our 13th member signalling their
|
||||
intention to leave due to the behaviour from this person.</p>
|
||||
<h2 id="learned-lessons">learned lessons</h2>
|
||||
<p>Times remain fraught. Volunteers are burnt, disengaged, and trying
|
||||
their best to get anything done to help the space.</p>
|
||||
<p>That said, here are some direct actions we are taking to prevent
|
||||
these kinds of events from <em>ever</em> happening again:</p>
|
||||
<ul>
|
||||
<li>Communicate the shared vision of devhack very clearly to guests and
|
||||
prospective members</li>
|
||||
<li>Communicate the existing structure of leadership within devhack –
|
||||
specifically that it is currently a benevolent dictatorship</li>
|
||||
<li>Be much less lenient towards toxic and antisocial behaviour –
|
||||
communicating the bad behaviour to those doing it and giving them
|
||||
chances to improve, but also setting boundaries to remove them from
|
||||
spaces if they continue to do so.</li>
|
||||
<li>Moderating the chats much more strictly in-line with our code of
|
||||
conduct, implementing a moderation team that is disconnected from the
|
||||
board to do so.</li>
|
||||
</ul>
|
||||
<hr />
|
||||
<blockquote>
|
||||
<p>For privacy reasons I will not be publishing any names regarding the
|
||||
actors throughout these events, but I do urge other leftist, anarchist,
|
||||
trans or other minority-focused organizations within the seattle area to
|
||||
reach out to me at <a href="mailto:m@devhack.net"
|
||||
class="email">m@devhack.net</a></p>
|
||||
</blockquote>
|
||||
<p>We will be collating an amount of statements, potentially anonymized
|
||||
at the discretion of the writers, to place alongside this document.</p>
|
||||
</body>
|
||||
</html>
|
||||
136
lore/schism.md
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
# The devhack schism
|
||||
|
||||
<small>This is a complicated document to write -m</small>
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
One specific member joined devhack with misaligned expectations of what it was,
|
||||
conflicting with both the original founding intentions and the understanding of
|
||||
a large portion of the devhack active membership. In the 6 months of this
|
||||
member's tenure, they contributed a great deal to the space but in the process
|
||||
alienated most of the former membership contributing to various aspects of the
|
||||
devhack project, including the original founding members and most
|
||||
of the infrastructure team.
|
||||
|
||||
This concluded in both a **ban** and a subsequent standoff, shouting match,
|
||||
walk-out, and temporary closure by devhack membership on the space itself.
|
||||
|
||||
The resulting ban cascaded from increased disengagement of long-time
|
||||
membership, reaching a tipping point that caused the leadership of devhack
|
||||
decided to make a unilateral decision to remove this member. Even though they
|
||||
were not communicated any warnings about this happening from leadership, this
|
||||
should not have come as a suprise, as they had been subject to substantial moderation
|
||||
-- from both devhack leadership and peers at the space.
|
||||
|
||||
## The night of the 28th of august
|
||||
|
||||
Two days after an amicable exit interview, approximately 30 minutes before the
|
||||
townhall convened to discuss punitive board action, this person attempted to
|
||||
enter the space with the help of a few supporters. Many members blockaded the
|
||||
stairwell in response for some amount of time, before we decided to vacate the
|
||||
premises and hold an informal discussion at a park a few blocks away.
|
||||
|
||||
During the blockade, this person was repeatedly asked to leave by devhack
|
||||
membership while both they and their supporters recited washington state law,
|
||||
questioned the space's insurance status, unintentionally injured themselves and
|
||||
claimed they needed entry to the space for first aid, furled insults at devhack
|
||||
leadership and their supporters, and generally were just very loud and did
|
||||
quite a lot of emotional damage to those blockading the entrance and observers
|
||||
to these events. They also threatened to get in contact with devhack business
|
||||
partners to complain about our conduct throughout these events in an attempt to
|
||||
tarnish devhack's business relationships.
|
||||
|
||||
## Consequences
|
||||
|
||||
Consequently, these four additional members were banned from devhack and barred access
|
||||
for aiding in this person's attempted entry. One ban has been rescinded due to
|
||||
overreach, and one is provisional due to their continued work with our
|
||||
business partners.
|
||||
|
||||
Two of the banned members have threatened to enter the space with a police
|
||||
escort, one of the banned members has claimed to have filed a police report.
|
||||
One auxillary member has deferred all communications with us through legal
|
||||
counsel.
|
||||
|
||||
These banned members have been invited to rightfully reclaim their personal
|
||||
equipment hosted at the space in a supervised fashion, alongside other
|
||||
members who have chosen to bow out.
|
||||
This has resulted in the loss of most of our networking equipment, most of our
|
||||
radio equipment, some retro equipment we actually liked, lots of auxillary
|
||||
tools, and other inconveniences.
|
||||
|
||||
|
||||
## Background / flashpoints
|
||||
|
||||
A concrete list of flashpoints contributing to this person's removal:
|
||||
|
||||
- their introduction to the chatspace, and specifically infrastructure-related
|
||||
rooms, and subsequent disrespectful behaviour towards members resulted in a
|
||||
very explicit boundaries set by most of the infra team "we don't want to work
|
||||
with you and we're leaving the chats you look for help from us in".
|
||||
- entitlement to an audience by people who have communicated they
|
||||
do not want to engage, further alienating core devhack contributors and
|
||||
causing them to disengage further.
|
||||
- upon communication of boundaries and the results of their actions, they had a
|
||||
rather angry rant about the state of things with lots of words directed at
|
||||
both the infra team and the leadership of devhack, resulting in an [ask to
|
||||
leave](https://wiki.devhack.net/AskToLeave) from unrelated parties witnessing
|
||||
this. no further action was taken from this ATL.
|
||||
- continuations of poor communication and collaboration skills during their
|
||||
attempted improvements of the space -- including being disrespectful and
|
||||
dismissive towards prior work done at the space and verbally attacking
|
||||
professional partners of devhack while degrading the physical security of the
|
||||
space and the reliability of our services.
|
||||
The worst of this resulting in moderation action and subsequently met with an
|
||||
ATL invoked on the moderator by this person.
|
||||
|
||||
|
||||
Now, I do want to stress, this person contributed substantial hours to the space,
|
||||
just in a largely independent and uncommunicative manner; helping in some areas
|
||||
and hurting in others. Ultimately, /dev/hack is a cooperative enterprise, and
|
||||
undermining that cooperation harms the space more than volunteering helps it.
|
||||
|
||||
<!-- Now, I do want to stress, this person was being very helpful at the space and
|
||||
doing a lot to try to improve it. They were just doing so without taking into
|
||||
account any sort of reason for why things were done the way they were, doing so
|
||||
without polling the devhack membership at large for support/consensus, and
|
||||
generally just steamrolling progress without any sort of cooperation skills
|
||||
with those who have previously put in work to make the space what it is. This
|
||||
happened in part due to the fact that everyone who has previously put in work
|
||||
at the space did not like how they were treated by this person and did not want
|
||||
to speak to them or work with them in any respects beyond giving them
|
||||
credentials and links to existing documentation surrounding the work they were
|
||||
doing. -->
|
||||
|
||||
The ban was precipitated on our 13th member signalling their intention to leave
|
||||
due to the behaviour from this person.
|
||||
|
||||
|
||||
## learned lessons
|
||||
|
||||
Times remain fraught. Volunteers are burnt, disengaged, and trying their best to get
|
||||
anything done to help the space.
|
||||
|
||||
That said, here are some direct actions we are taking to prevent these kinds of
|
||||
events from *ever* happening again:
|
||||
|
||||
- Communicate the shared vision of devhack very clearly to guests and prospective members
|
||||
- Communicate the existing structure of leadership within devhack --
|
||||
specifically that it is currently a benevolent dictatorship
|
||||
- Be much less lenient towards toxic and antisocial behaviour -- communicating
|
||||
the bad behaviour to those doing it and giving them chances to improve, but
|
||||
also setting boundaries to remove them from spaces if they continue to do so.
|
||||
- Moderating the chats much more strictly in-line with our code of conduct,
|
||||
implementing a moderation team that is disconnected from the board to do so.
|
||||
|
||||
---
|
||||
|
||||
> For privacy reasons I will not be publishing any names regarding the actors
|
||||
> throughout these events, but I do urge other leftist, anarchist, trans or other
|
||||
> minority-focused organizations within the seattle area to reach out to me at
|
||||
> <m@devhack.net>
|
||||
|
||||
We will be collating an amount of statements, potentially anonymized at the
|
||||
discretion of the writers, to place alongside this document.
|
||||
27
lore/style.css
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
@import "../style.css";
|
||||
p {
|
||||
margin: 1.5em 0.5em;
|
||||
}
|
||||
|
||||
small{
|
||||
margin-top:1em;
|
||||
margin-left:1.5em;
|
||||
}
|
||||
|
||||
h1{
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
hr{
|
||||
margin-top: 3em;
|
||||
margin-bottom: 3em;
|
||||
display:none;
|
||||
}
|
||||
|
||||
p:nth-child(4){
|
||||
margin-top:2.5em;
|
||||
}
|
||||
|
||||
body{
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
|
@ -1,48 +1,49 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<meta charset="UTF-8">
|
||||
<title>/dev/hack</title>
|
||||
<title>membership - /dev/hack</title>
|
||||
<link rel="canonical" href="https://www.devhack.net/membership.html">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
|
||||
<body>
|
||||
|
||||
<h1>/dev/hack membership</h1>
|
||||
|
||||
<p>/dev/hack is actively seeking members who can support the existence of a
|
||||
space in our region devoted to our goals in education, creative
|
||||
projects, and community service. Becoming a member, while not required
|
||||
to take advantage of /dev/hack services, provides:</p>
|
||||
<ul>
|
||||
<li>Around-the-clock key access to the /dev/hack space</li>
|
||||
<li>The ability to reserve the /dev/hack space and for mission-related events and classes</li>
|
||||
<li>Voting rights at official organizational meetings</li>
|
||||
<li>Access to the /dev/hack members-only mailing list</li>
|
||||
<li>Access to /dev/hack servers for projects</li>
|
||||
<li>An email adress @devhack.net</li>
|
||||
<li>An account on /dev/hack shell and VPS server</li>
|
||||
</ul>
|
||||
<p>Most importantly, however, supporting /dev/hack as a member enables one
|
||||
to help build an innovative community technology space and to contribute
|
||||
to the growing international movement of hackerspaces.</p>
|
||||
<h3><b>How to become a member</b></h3>
|
||||
<p>Check us out first. Visit /dev/hack events and classes, and swing by the
|
||||
space to meet other members and get a feel for the group. All of our
|
||||
activities are free and open to the public.* Once you have decided you
|
||||
would like to join:</p>
|
||||
<ol>
|
||||
<li><a href="https://buy.stripe.com/14kg0S2aJ9ibbSM6oo">Subscribe for dues ($50/month) via stripe.</a></li>
|
||||
<li>Attend a monthly member meeting on the second Tuesday of the month
|
||||
at approximately 7:15PM, so your membership can be formalized.</li>
|
||||
</ol>
|
||||
<!-- <p>* Although events are free, sometimes materials costs for workshops
|
||||
are the responsibility of workshop participants. Further, because of
|
||||
space limitations, some events are capped at a maximum number of
|
||||
participants. Events are published <a title="HacDC's events calendar at meetup.com" href="https://www.meetup.com/hac-dc/events/">on our calendar</a>.</p> -->
|
||||
|
||||
<script async src="https://js.stripe.com/v3/pricing-table.js"></script>
|
||||
<stripe-pricing-table pricing-table-id="prctbl_1OqI5NDnrGrK8UDJkbkPIg4E"
|
||||
publishable-key="pk_live_51N6dipDnrGrK8UDJnT10MmYp6SG6ONE3mmlprqxt1OIYXkVyYRPfSSmn0ShzHxOlvoGZEZfdPt3DKZEL9ZmjJpmW00DkF0Fien">
|
||||
</stripe-pricing-table>
|
||||
<h1>/dev/hack membership</h1>
|
||||
|
||||
<p>/dev/hack thanks you for your interest in becoming a member.</p>
|
||||
<p>We are actively seeking members who can support the existence of a
|
||||
space in our region devoted to our goals in education, creative
|
||||
projects, and community service. Becoming a member, while not required
|
||||
to take advantage of /dev/hack services, provides:</p>
|
||||
<ul>
|
||||
<li>Around-the-clock key access to the /dev/hack space</li>
|
||||
<li>The ability to reserve the /dev/hack space and for mission-related events and classes</li>
|
||||
<li>Voting rights at official organizational meetings</li>
|
||||
<li>Access to /dev/hack servers for projects</li>
|
||||
<li>An account on /dev/hack shell and VPS server</li>
|
||||
<li>And other volunteer-provided <a href="https://wiki.devhack.net/Services">services</a> provided on a <i>best
|
||||
effort basis</i></li>
|
||||
<!--
|
||||
<li>An email adress @devhack.net</li>
|
||||
<li>Access to the /dev/hack members-only mailing list</li>
|
||||
-->
|
||||
</ul>
|
||||
<p>Most importantly, however, supporting /dev/hack as a member enables one
|
||||
to help build an innovative community technology space and to contribute
|
||||
to the growing international movement of hackerspaces.</p>
|
||||
<h3><b>How to become a member</b></h3>
|
||||
<p>Check us out first. Visit /dev/hack events and classes, and swing by the
|
||||
space to meet other members and get a feel for the group. All of our
|
||||
activities are free and open to the public.</p>
|
||||
<p>Once you feel that membership is right for you, the
|
||||
<a href="https://wiki.devhack.net/Becoming_a_Member">Becoming a Member</a> wiki page
|
||||
describes the process.
|
||||
</p>
|
||||
<h3>Managing your membership</h3>
|
||||
<p>You can update your payment information via <a href="https://members.devhack.net/membership/">the member
|
||||
portal</a>.
|
||||
If you would like to cancel your membership, you should also talk to someone to ensure that your accounts are
|
||||
winded down.
|
||||
</body>
|
||||
</html>
|
||||
|
||||
</html>
|
||||
74
more.html
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<meta charset="UTF-8">
|
||||
<title>what is /dev/hack?</title>
|
||||
<meta name="description"
|
||||
content="/dev/hack is a hackerspace in seattle's university district, where folks come together to tinker, learn, share ideas, and find community.">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<link rel="canonical" href="https://www.devhack.net/more.html">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
|
||||
<body>
|
||||
<h1>what is /dev/hack?</h1>
|
||||
<div class="guysholder">
|
||||
<p>/dev/hack is a hackerspace in seattle's <a href="https://wiki.devhack.net/University_Way_NE">university
|
||||
district</a>, where folks come together to tinker, learn, share ideas,
|
||||
and find community.</p>
|
||||
<p>/dev/hack also:</p>
|
||||
<ul>
|
||||
<li>operates as a
|
||||
volunteer-run nonprofit and is <a href="membership.html">supported by its membership</a> </li>
|
||||
<li>shares membership and physical space with <a href="https://seattlecommunitynetwork.org/">local
|
||||
organizations</a></li>
|
||||
<li>hosts <a href="https://wiki.devhack.net/Services">space infrastructure</a> and <a
|
||||
href="https://wiki.devhack.net/Category:Projects">member projects</a> that you can read more
|
||||
about
|
||||
</li>
|
||||
<li>empowers you to contribute towards anything you see -- it's a <span style="white-space: nowrap;">do-ocracy</span></li>
|
||||
</ul>
|
||||
<p>so far, this has been /dev/hack:</p>
|
||||
<div class="grid-container">
|
||||
<!-- please write alt text for each image! -->
|
||||
<div class="imgholder">
|
||||
<img src="pictures/hallway.jpg"
|
||||
alt="An indoor hallway with a railing, featuring a big /dev/hack sign on the wall.">
|
||||
</div>
|
||||
<div class="imgholder">
|
||||
<img src="pictures/focus_foundry.jpg"
|
||||
alt="A dimly lit room with coworking desks and pretty fairy lights.">
|
||||
</div>
|
||||
<div class="imgholder">
|
||||
<img src="pictures/dvd_hell.jpg" alt="A tower computer that has 8 DVD drives on the front panel.">
|
||||
</div>
|
||||
|
||||
<div class="imgholder">
|
||||
<img src="pictures/shibari.jpg"
|
||||
alt="The shibari PC, tied up with rope and hanging from the ceiling, with a noticeable blue/purple glow.">
|
||||
</div>
|
||||
<div class="imgholder">
|
||||
<img src="pictures/debianwoman.jpg" alt="A diagnostics sign saying 'Woman Problem? Is there text on
|
||||
the screen?' next to a monitor with the Debian installer. ">
|
||||
</div>
|
||||
<div class="imgholder">
|
||||
<img src="pictures/servers.jpg" alt="A server rack with green lights and a bunch of cables.">
|
||||
</div>
|
||||
<div class="imgholder">
|
||||
<img src="pictures/payphone.jpg" alt="A Nortel Millennium payphone.">
|
||||
</div>
|
||||
<div class="imgholder">
|
||||
<img src="pictures/stoplight.jpg"
|
||||
alt="A traffic light, but with all the lights on and it's also on our floor.">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h2 id="acknowledgements">acknowledgements</h2>
|
||||
<p>
|
||||
/dev/hack is grateful for the support of <a href="https://seattlecommunitynetwork.org/">Seattle Community Network⁠<img
|
||||
src="vendor/scnBadgeWhite.svg" alt="Seattle Community Network logo" class="footer-logo"></a>,
|
||||
<a href="https://www.fastly.com" target="_blank" rel="noopener">Fastly⁠<img
|
||||
src="vendor/fastlyLogo-white-SVG.svg" alt="Fastly logo" class="footer-logo"></a>,
|
||||
|
||||
and our members for making this place possible.
|
||||
</p>
|
||||
|
||||
</html>
|
||||
BIN
pictures/debianwoman.jpg
Normal file
|
After Width: | Height: | Size: 50 KiB |
BIN
pictures/dvd_hell.jpg
Normal file
|
After Width: | Height: | Size: 54 KiB |
BIN
pictures/focus_foundry.jpg
Normal file
|
After Width: | Height: | Size: 49 KiB |
BIN
pictures/hallway.jpg
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
pictures/payphone.jpg
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
pictures/servers.jpg
Normal file
|
After Width: | Height: | Size: 45 KiB |
BIN
pictures/shibari.jpg
Normal file
|
After Width: | Height: | Size: 41 KiB |
BIN
pictures/stoplight.jpg
Normal file
|
After Width: | Height: | Size: 51 KiB |
76
reboot.html
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="generator" content="pandoc" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||||
<meta name="description" content="devhack needs your help" />
|
||||
<title>/dev/hack: reboot</title>
|
||||
<style>
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
||||
div.column{flex: auto; overflow-x: auto;}
|
||||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||||
/* The extra [class] is a hack that increases specificity enough to
|
||||
override a similar rule in reveal.js */
|
||||
ul.task-list[class]{list-style: none;}
|
||||
ul.task-list li input[type="checkbox"] {
|
||||
font-size: inherit;
|
||||
width: 0.8em;
|
||||
margin: 0 0.8em 0.2em -1.6em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
|
||||
</style>
|
||||
<link rel="stylesheet" href="style.css" />
|
||||
<!--[if lt IE 9]>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="devhack-needs-your-help">/dev/hack needs your help!</h1>
|
||||
<p>Due to <a href="./lore/schism.html">recent events</a> the /dev/hack
|
||||
hackerspace has run into, we need help re-setting up the space!</p>
|
||||
<p>Specifically, we need, in order of importance:</p>
|
||||
<ul>
|
||||
<li><a href="https://wiki.devhack.net/Giveafuck">giveafuck</a></li>
|
||||
<li>labor
|
||||
<ul>
|
||||
<li>technical labor, with focus on network infrastructure, electrical
|
||||
wiring</li>
|
||||
<li>manual labor. Carrying things around, lifting things, constructing
|
||||
things</li>
|
||||
</ul></li>
|
||||
<li><a
|
||||
href="https://donate.stripe.com/6oE4iaeXv8e7e0UaEG">money</a></li>
|
||||
<li><strong>specifically approved</strong> hardware, with preference to
|
||||
lower-power, usability, reliability
|
||||
<ul>
|
||||
<li><a href="https://bugs.devhack.net/ticket/955">#955</a></li>
|
||||
<li><a
|
||||
href="https://bugs.devhack.net/query?keywords=~shopping&status=!closed&order=changetime&desc=1">shopping
|
||||
tickets</a></li>
|
||||
</ul></li>
|
||||
<li>cars & trucks to help bring things to the space</li>
|
||||
<li>drafting up & proposing policy
|
||||
<ul>
|
||||
<li>especially if you are leftist, anarchist, trans. we want your help
|
||||
and feedback</li>
|
||||
<li><a
|
||||
href="https://bugs.devhack.net/query?component=Policy&status=!closed&order=changetime&desc=1">policy
|
||||
tickets</a></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
<hr />
|
||||
<p><a
|
||||
href="https://signal.group/#CjQKIHzMq7fKYgL_s_-hmssso3r2EkIfeImJ1kfZJQNmFREvEhBLy6y7HktLGVK76nJgNDc2">signal
|
||||
group here!</a></p>
|
||||
<hr />
|
||||
<p>Stripe donation link is here, feel very free to attach a message
|
||||
outlining your preference to where your money goes or any sort of
|
||||
message:</p>
|
||||
<p><a href="https://donate.stripe.com/6oE4iaeXv8e7e0UaEG"
|
||||
class="uri">https://donate.stripe.com/6oE4iaeXv8e7e0UaEG</a></p>
|
||||
</body>
|
||||
</html>
|
||||
34
reboot.md
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
---
|
||||
pagetitle: '/dev/hack: reboot'
|
||||
description-meta: 'devhack needs your help'
|
||||
---
|
||||
|
||||
# /dev/hack needs your help!
|
||||
|
||||
Due to [recent events](./lore/schism.html) the /dev/hack hackerspace has run into, we need help re-setting up the space!
|
||||
|
||||
Specifically, we need, in order of importance:
|
||||
|
||||
- [giveafuck](https://wiki.devhack.net/Giveafuck)
|
||||
- labor
|
||||
- technical labor, with focus on network infrastructure, electrical wiring
|
||||
- manual labor. Carrying things around, lifting things, constructing things
|
||||
- [money](https://donate.stripe.com/6oE4iaeXv8e7e0UaEG)
|
||||
- **specifically approved** hardware, with preference to lower-power, usability, reliability
|
||||
- [#955](https://bugs.devhack.net/ticket/955)
|
||||
- [shopping tickets](https://bugs.devhack.net/query?keywords=~shopping&status=!closed&order=changetime&desc=1)
|
||||
- cars & trucks to help bring things to the space
|
||||
- drafting up & proposing policy
|
||||
- especially if you are leftist, anarchist, trans. we want your help and feedback
|
||||
- [policy tickets](https://bugs.devhack.net/query?component=Policy&status=!closed&order=changetime&desc=1)
|
||||
|
||||
---
|
||||
|
||||
[signal group here!](https://signal.group/#CjQKIHzMq7fKYgL_s_-hmssso3r2EkIfeImJ1kfZJQNmFREvEhBLy6y7HktLGVK76nJgNDc2)
|
||||
|
||||
---
|
||||
|
||||
Stripe donation link is here, feel very free to attach a message outlining your
|
||||
preference to where your money goes or any sort of message:
|
||||
|
||||
<https://donate.stripe.com/6oE4iaeXv8e7e0UaEG>
|
||||
55
robots.txt
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
# Block all known AI crawlers and assistants
|
||||
# from using content for training AI models.
|
||||
# Source: https://robotstxt.com/ai
|
||||
User-Agent: GPTBot
|
||||
User-Agent: ClaudeBot
|
||||
User-Agent: Claude-Web
|
||||
User-Agent: CCBot
|
||||
User-Agent: Applebot-Extended
|
||||
User-Agent: Facebookbot
|
||||
User-Agent: Meta-ExternalAgent
|
||||
User-Agent: Meta-ExternalFetcher
|
||||
User-Agent: diffbot
|
||||
User-Agent: PerplexityBot
|
||||
User-Agent: Omgili
|
||||
User-Agent: Omgilibot
|
||||
User-Agent: webzio-extended
|
||||
User-Agent: ImagesiftBot
|
||||
User-Agent: Bytespider
|
||||
User-Agent: Amazonbot
|
||||
User-Agent: Youbot
|
||||
User-Agent: SemrushBot-OCOB
|
||||
User-Agent: Petalbot
|
||||
User-Agent: VelenPublicWebCrawler
|
||||
User-Agent: TurnitinBot
|
||||
User-Agent: Timpibot
|
||||
User-Agent: OAI-SearchBot
|
||||
User-Agent: ICC-Crawler
|
||||
User-Agent: AI2Bot
|
||||
User-Agent: AI2Bot-Dolma
|
||||
User-Agent: DataForSeoBot
|
||||
User-Agent: AwarioBot
|
||||
User-Agent: AwarioSmartBot
|
||||
User-Agent: AwarioRssBot
|
||||
User-Agent: Google-Extended
|
||||
User-Agent: Google-CloudVertexBot
|
||||
User-Agent: PanguBot
|
||||
User-Agent: Kangaroo Bot
|
||||
User-Agent: Sentibot
|
||||
User-Agent: img2dataset
|
||||
User-Agent: Meltwater
|
||||
User-Agent: Seekr
|
||||
User-Agent: peer39_crawler
|
||||
User-Agent: cohere-ai
|
||||
User-Agent: cohere-training-data-crawler
|
||||
User-Agent: DuckAssistBot
|
||||
User-Agent: Scrapy
|
||||
Disallow: /
|
||||
DisallowAITraining: /
|
||||
|
||||
# Block any non-specified AI crawlers (e.g., new
|
||||
# or unknown bots) from using content for training
|
||||
# AI models. This directive is still experimental
|
||||
# and may not be supported by all AI crawlers.
|
||||
User-Agent: *
|
||||
DisallowAITraining: /
|
||||
45
seattle.html
|
|
@ -1,45 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<meta charset="UTF-8">
|
||||
<title>/dev/hack > seattle</title>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<body>
|
||||
|
||||
<h1>seattle hackery</h1>
|
||||
<ul>
|
||||
<li><a href="https://www.blacklodgeresearch.org/">Black Lodge Research</a></li>
|
||||
<li><a href="https://web.archive.org/web/20201205014142/http://www.hackerbotlabs.com/">Hackerbot Labs</a></li>
|
||||
<li><a href="https://www.seattleretrocomputing.com/">Seattle Retro-Computing Society</a></li>
|
||||
<li><a href="https://wsealug.net/">West Seattle Linux Users Group</a></li>
|
||||
<li><a href="https://www.bsidesseattle.com/">Bsides Seattle</a></li>
|
||||
<li><a href="https://gslug.org/">Greater Seattle Linux Users Groups</a></li>
|
||||
<li><a href="http://belug.herber.us/">Bellevue Linux Users Group</a></li>
|
||||
<li><a href="http://seabug.org/">Seattle BSD Users Group</a></li>
|
||||
<li><a href="https://www.telcomhistory.org/connections-museum-seattle/">Connections Museum</a></li>
|
||||
<li><a href="https://livingcomputers.org">Living Computers: Museum</a></li>
|
||||
<li><a href="https://handmade-seattle.com/">Handmade Seattle</a></li>
|
||||
<li><a href="https://seattlecommunitynetwork.org/">Seattle Community Network</a></li>
|
||||
<li><a href="http://dorkbotsea.org/">dorkbot-sea</a></li>
|
||||
<li><a href="https://www.pspython.com/">Puget Sound Programming Python</a></li>
|
||||
<!-- <li><a href="https://www.newtechnorthwest.com/">New Tech Northwest</a></li> -->
|
||||
<li><a href="http://amasci.com/wsci/">Weird Science Salon</a></li>
|
||||
<li><a href="https://seattle.makerfaire.com/makers-exhibits/">Seattle Mini Maker Faire</a></li>
|
||||
<li><a href="https://web.archive.org/web/20110208131653/http://www.seattlewireless.net/">Seattle Wireless</a></li>
|
||||
<!-- <li><a href="http://seattle.beerandcode.org/">Beer && Code</a></li> -->
|
||||
<li><a href="https://www.meetup.com/Beer-Code-Seattle/">Beer && Code</a></li>
|
||||
<li><a href="http://refreshseattle.org/">Refresh Seattle</a></li>
|
||||
<li><a href="https://www.wa2600.org/">Seattle 2600</a></li>
|
||||
<li><a href="http://passable.art/">Passable</a></li>
|
||||
<li><a href="http://seattlexcoders.org/">Seattle Xcoders</a></li>
|
||||
<li><a href="https://toorcamp.toorcon.net/">ToorCamp</a></li>
|
||||
<li><a href="https://southsoundhacker.space/">Port 22: South Sound Hackers</a></li>
|
||||
<li><a href="https://dc253.org/">DC253</a></li>
|
||||
<li><a href="https://seattlematrix.org/">Seattle Matrix</a></li>
|
||||
<li><a href="https://seagl.org/">SeaGL</a></li>
|
||||
<li><a href="https://linuxfestnorthwest.org/">LinuxFest Northwest</a></li>
|
||||
<li><a href="https://hushcon.com/">Hushcon</a></li>
|
||||
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
335
style.css
|
|
@ -1,11 +1,14 @@
|
|||
@import url('vendor/berkeley_mono_transfonter/stylesheet.css');
|
||||
|
||||
body {
|
||||
background: black;
|
||||
color: lime;
|
||||
font-family: Menlo, 'Cascadia Code', Consolas, Courier, monospace;
|
||||
font-family: 'Berkeley Mono', Menlo, 'Cascadia Code', Consolas, Courier, monospace;
|
||||
line-height: 1.15;
|
||||
margin: 100px 20% 5% 20%;
|
||||
border: 10px red;
|
||||
font-size: 15px;
|
||||
font-size: 16px;
|
||||
max-width: 800px;
|
||||
}
|
||||
|
||||
ul {
|
||||
|
|
@ -16,15 +19,29 @@ li {
|
|||
margin-top: 0.5em;
|
||||
}
|
||||
|
||||
/* Mobile devices get slightly smaller margins, so that we actually have room
|
||||
* for text.
|
||||
*/
|
||||
@media only screen and (max-width: 600px) {
|
||||
body {
|
||||
margin: 50px 5% 5% 5%;
|
||||
}
|
||||
dl {
|
||||
margin: 0;
|
||||
margin-block: 1em;
|
||||
padding-inline-start: 40px;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
dt {
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
|
||||
.holder {
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
|
||||
.secondary {
|
||||
color: #00b300;
|
||||
}
|
||||
|
|
@ -36,24 +53,58 @@ input[type="text"] {
|
|||
outline: none;
|
||||
font: inherit;
|
||||
caret-shape: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
h1, .block {
|
||||
|
||||
h1,
|
||||
.block {
|
||||
margin: 40px 0px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0.5em 0;
|
||||
h1 {
|
||||
animation: headerGlow 4s infinite ease-in-out;
|
||||
text-shadow: 0 0 5px lime, 0 0 10px lime;
|
||||
}
|
||||
|
||||
a, a:visited {
|
||||
@keyframes headerGlow {
|
||||
0% {
|
||||
opacity: 0.9;
|
||||
text-shadow: 0 0 3px lime, 0 0 7px lime;
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 1;
|
||||
text-shadow: 0 0 8px lime, 0 0 10px lime;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0.9;
|
||||
text-shadow: 0 0 3px lime, 0 0 7px lime;
|
||||
}
|
||||
}
|
||||
|
||||
h2 .small {
|
||||
display: inline-flex;
|
||||
|
||||
a:not(:first-child) {
|
||||
margin-left: 0.25em;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0.5em 0;
|
||||
}
|
||||
|
||||
a,
|
||||
a:visited {
|
||||
color: #84d7ba;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #d784a1;
|
||||
}
|
||||
}
|
||||
|
||||
dt::before {
|
||||
content: ">";
|
||||
|
|
@ -64,4 +115,260 @@ dt::before {
|
|||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-size: 50%;
|
||||
}
|
||||
|
||||
.meow {
|
||||
margin: 0px 0px !important;
|
||||
}
|
||||
|
||||
.banners {
|
||||
margin: 40px 0px;
|
||||
}
|
||||
|
||||
img {
|
||||
image-rendering: pixelated;
|
||||
width: 85%;
|
||||
align-content: center;
|
||||
margin: auto;
|
||||
display: inline-block;
|
||||
filter: grayscale(30%);
|
||||
}
|
||||
|
||||
img:hover {
|
||||
filter: grayscale(0%);
|
||||
}
|
||||
|
||||
.grid-container {
|
||||
margin: 1em auto;
|
||||
}
|
||||
|
||||
.grid-container {
|
||||
padding: 10px;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.grid-container {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
.imgholder {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.imgholder img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.guysholder p {
|
||||
margin-top: 2em;
|
||||
}
|
||||
|
||||
#news-feed {
|
||||
position: relative;
|
||||
max-width: clamp(300px, 100%, 800px);
|
||||
|
||||
.overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
z-index: 10;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#news-feed-gradient {
|
||||
background: linear-gradient(to left,
|
||||
rgba(0, 0, 0, 1) 0,
|
||||
rgba(0, 0, 0, 0.8) 42px,
|
||||
transparent 100px,
|
||||
transparent 100%);
|
||||
}
|
||||
|
||||
#news-feed-controls {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#news-feed-right {
|
||||
cursor: pointer;
|
||||
pointer-events: all;
|
||||
|
||||
margin-left: auto;
|
||||
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
|
||||
border: 1px solid lime;
|
||||
border-radius: 99px;
|
||||
|
||||
color: lime;
|
||||
background-color: oklch(from lime 0.3 c h / 0.7);
|
||||
|
||||
transition:
|
||||
background-color 0.1s ease-in-out,
|
||||
transform 0.25s ease-in-out;
|
||||
|
||||
opacity: 0.7;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&[data-last="true"] {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
svg {
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#news-list {
|
||||
overflow: hidden;
|
||||
overflow-x: auto;
|
||||
|
||||
scrollbar-width: thin;
|
||||
scroll-behavior: smooth;
|
||||
scroll-snap-type: x mandatory;
|
||||
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 1rem;
|
||||
|
||||
list-style: none;
|
||||
|
||||
padding: 0;
|
||||
padding-right: 100px;
|
||||
/* space for gradient */
|
||||
margin: 0;
|
||||
|
||||
font-size: 0.85em;
|
||||
|
||||
.news-item {
|
||||
scroll-snap-align: start;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
overflow: auto;
|
||||
margin: 0;
|
||||
padding: 1em;
|
||||
|
||||
flex: 1 0 200px;
|
||||
min-height: 250px;
|
||||
max-height: 300px;
|
||||
|
||||
border: 1px solid oklch(from lime 0.3 c h);
|
||||
border-radius: 12px;
|
||||
|
||||
.news-author {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.news-avatar {
|
||||
border-radius: 6px;
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
margin: 0;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.news-username {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.news-edited {
|
||||
font-size: 0.75em;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.news-body {
|
||||
flex: 1;
|
||||
|
||||
margin-top: 1em;
|
||||
|
||||
margin-bottom: 0;
|
||||
padding-bottom: 1em;
|
||||
}
|
||||
|
||||
.news-thumbnail-link {
|
||||
display: block;
|
||||
|
||||
&:not([href]) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.news-thumbnail-image {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
object-fit: cover;
|
||||
border-radius: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
footer {
|
||||
margin-top: 5em;
|
||||
font-size: 0.8rem;
|
||||
text-align: right;
|
||||
max-width: 60%;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.footer-logo {
|
||||
height: 1em;
|
||||
width: auto;
|
||||
vertical-align: middle;
|
||||
margin-left: 0.25em;
|
||||
/* Override rendering for logos */
|
||||
image-rendering: auto;
|
||||
}
|
||||
|
||||
.error {
|
||||
border: 1px solid;
|
||||
padding: .75em 1em;
|
||||
margin: 1em 0;
|
||||
border-radius: 10px;
|
||||
font-size: 0.9em;
|
||||
max-width: 50%;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
padding-left: 10px;
|
||||
border-left: 2px solid;
|
||||
}
|
||||
|
||||
/* Mobile devices get slightly smaller margins, so that we actually have room
|
||||
* for text.
|
||||
*/
|
||||
@media only screen and (max-width: 749px) {
|
||||
body {
|
||||
margin: 50px 5% 5% 5%;
|
||||
}
|
||||
|
||||
.holder {
|
||||
width: 35%;
|
||||
}
|
||||
|
||||
.error {
|
||||
max-width: 80%;
|
||||
}
|
||||
}
|
||||
BIN
vendor/berkeley_mono_transfonter/BerkeleyMono-Bold.woff
(Stored with Git LFS)
vendored
Normal file
BIN
vendor/berkeley_mono_transfonter/BerkeleyMono-Bold.woff2
(Stored with Git LFS)
vendored
Normal file
BIN
vendor/berkeley_mono_transfonter/BerkeleyMono-BoldItalic.woff
(Stored with Git LFS)
vendored
Normal file
BIN
vendor/berkeley_mono_transfonter/BerkeleyMono-BoldItalic.woff2
(Stored with Git LFS)
vendored
Normal file
BIN
vendor/berkeley_mono_transfonter/BerkeleyMono-Italic.woff
(Stored with Git LFS)
vendored
Normal file
BIN
vendor/berkeley_mono_transfonter/BerkeleyMono-Italic.woff2
(Stored with Git LFS)
vendored
Normal file
BIN
vendor/berkeley_mono_transfonter/BerkeleyMono-Regular.woff
(Stored with Git LFS)
vendored
Normal file
BIN
vendor/berkeley_mono_transfonter/BerkeleyMono-Regular.woff2
(Stored with Git LFS)
vendored
Normal file
279
vendor/berkeley_mono_transfonter/demo.html
vendored
Normal file
|
|
@ -0,0 +1,279 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="robots" content="noindex, noarchive">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<title>Transfonter demo</title>
|
||||
<link href="stylesheet.css" rel="stylesheet">
|
||||
<style>
|
||||
/*
|
||||
http://meyerweb.com/eric/tools/css/reset/
|
||||
v2.0 | 20110126
|
||||
License: none (public domain)
|
||||
*/
|
||||
html, body, div, span, applet, object, iframe,
|
||||
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||
a, abbr, acronym, address, big, cite, code,
|
||||
del, dfn, em, img, ins, kbd, q, s, samp,
|
||||
small, strike, strong, sub, sup, tt, var,
|
||||
b, u, i, center,
|
||||
dl, dt, dd, ol, ul, li,
|
||||
fieldset, form, label, legend,
|
||||
table, caption, tbody, tfoot, thead, tr, th, td,
|
||||
article, aside, canvas, details, embed,
|
||||
figure, figcaption, footer, header, hgroup,
|
||||
menu, nav, output, ruby, section, summary,
|
||||
time, mark, audio, video {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font-size: 100%;
|
||||
font: inherit;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
/* HTML5 display-role reset for older browsers */
|
||||
article, aside, details, figcaption, figure,
|
||||
footer, header, hgroup, menu, nav, section {
|
||||
display: block;
|
||||
}
|
||||
body {
|
||||
line-height: 1;
|
||||
}
|
||||
ol, ul {
|
||||
list-style: none;
|
||||
}
|
||||
blockquote, q {
|
||||
quotes: none;
|
||||
}
|
||||
blockquote:before, blockquote:after,
|
||||
q:before, q:after {
|
||||
content: '';
|
||||
content: none;
|
||||
}
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
/* demo styles */
|
||||
body {
|
||||
background: #f0f0f0;
|
||||
color: #000;
|
||||
}
|
||||
.page {
|
||||
background: #fff;
|
||||
width: 920px;
|
||||
margin: 0 auto;
|
||||
padding: 20px 20px 0 20px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.font-container {
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
margin-bottom: 40px;
|
||||
line-height: 1.3;
|
||||
white-space: nowrap;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
h1 {
|
||||
position: relative;
|
||||
background: #444;
|
||||
font-size: 32px;
|
||||
color: #fff;
|
||||
padding: 10px 20px;
|
||||
margin: 0 -20px 12px -20px;
|
||||
}
|
||||
.letters {
|
||||
font-size: 25px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.s10:before {
|
||||
content: '10px';
|
||||
}
|
||||
.s11:before {
|
||||
content: '11px';
|
||||
}
|
||||
.s12:before {
|
||||
content: '12px';
|
||||
}
|
||||
.s14:before {
|
||||
content: '14px';
|
||||
}
|
||||
.s18:before {
|
||||
content: '18px';
|
||||
}
|
||||
.s24:before {
|
||||
content: '24px';
|
||||
}
|
||||
.s30:before {
|
||||
content: '30px';
|
||||
}
|
||||
.s36:before {
|
||||
content: '36px';
|
||||
}
|
||||
.s48:before {
|
||||
content: '48px';
|
||||
}
|
||||
.s60:before {
|
||||
content: '60px';
|
||||
}
|
||||
.s72:before {
|
||||
content: '72px';
|
||||
}
|
||||
.s10:before, .s11:before, .s12:before, .s14:before,
|
||||
.s18:before, .s24:before, .s30:before, .s36:before,
|
||||
.s48:before, .s60:before, .s72:before {
|
||||
font-family: Arial, sans-serif;
|
||||
font-size: 10px;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
color: #999;
|
||||
padding-right: 6px;
|
||||
}
|
||||
pre {
|
||||
display: block;
|
||||
padding: 9px;
|
||||
margin: 0 0 12px;
|
||||
font-family: Monaco, Menlo, Consolas, "Courier New", monospace;
|
||||
font-size: 13px;
|
||||
line-height: 1.428571429;
|
||||
color: #333;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
background-color: #f5f5f5;
|
||||
border: 1px solid #ccc;
|
||||
overflow-x: auto;
|
||||
border-radius: 4px;
|
||||
}
|
||||
/* responsive */
|
||||
@media (max-width: 959px) {
|
||||
.page {
|
||||
width: auto;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="page">
|
||||
<div class="demo">
|
||||
<h1 style="font-family: 'Berkeley Mono'; font-weight: bold; font-style: normal;">Berkeley Mono Bold</h1>
|
||||
<pre title="Usage">.your-style {
|
||||
font-family: 'Berkeley Mono';
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}</pre>
|
||||
<pre title="Preload (optional)">
|
||||
<link rel="preload" href="BerkeleyMono-Bold.woff2" as="font" type="font/woff2" crossorigin></pre>
|
||||
<div class="font-container" style="font-family: 'Berkeley Mono'; font-weight: bold; font-style: normal;">
|
||||
<p class="letters">
|
||||
abcdefghijklmnopqrstuvwxyz<br>
|
||||
ABCDEFGHIJKLMNOPQRSTUVWXYZ<br>
|
||||
0123456789.:,;()*!?'@#<>$%&^+-=~
|
||||
</p>
|
||||
<p class="s10" style="font-size: 10px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s11" style="font-size: 11px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s12" style="font-size: 12px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s14" style="font-size: 14px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s18" style="font-size: 18px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s24" style="font-size: 24px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s30" style="font-size: 30px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s36" style="font-size: 36px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s48" style="font-size: 48px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s60" style="font-size: 60px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s72" style="font-size: 72px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="demo">
|
||||
<h1 style="font-family: 'Berkeley Mono'; font-weight: normal; font-style: normal;">Berkeley Mono Regular</h1>
|
||||
<pre title="Usage">.your-style {
|
||||
font-family: 'Berkeley Mono';
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}</pre>
|
||||
<pre title="Preload (optional)">
|
||||
<link rel="preload" href="BerkeleyMono-Regular.woff2" as="font" type="font/woff2" crossorigin></pre>
|
||||
<div class="font-container" style="font-family: 'Berkeley Mono'; font-weight: normal; font-style: normal;">
|
||||
<p class="letters">
|
||||
abcdefghijklmnopqrstuvwxyz<br>
|
||||
ABCDEFGHIJKLMNOPQRSTUVWXYZ<br>
|
||||
0123456789.:,;()*!?'@#<>$%&^+-=~
|
||||
</p>
|
||||
<p class="s10" style="font-size: 10px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s11" style="font-size: 11px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s12" style="font-size: 12px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s14" style="font-size: 14px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s18" style="font-size: 18px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s24" style="font-size: 24px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s30" style="font-size: 30px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s36" style="font-size: 36px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s48" style="font-size: 48px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s60" style="font-size: 60px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s72" style="font-size: 72px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="demo">
|
||||
<h1 style="font-family: 'Berkeley Mono'; font-weight: normal; font-style: italic;">Berkeley Mono Italic</h1>
|
||||
<pre title="Usage">.your-style {
|
||||
font-family: 'Berkeley Mono';
|
||||
font-weight: normal;
|
||||
font-style: italic;
|
||||
}</pre>
|
||||
<pre title="Preload (optional)">
|
||||
<link rel="preload" href="BerkeleyMono-Italic.woff2" as="font" type="font/woff2" crossorigin></pre>
|
||||
<div class="font-container" style="font-family: 'Berkeley Mono'; font-weight: normal; font-style: italic;">
|
||||
<p class="letters">
|
||||
abcdefghijklmnopqrstuvwxyz<br>
|
||||
ABCDEFGHIJKLMNOPQRSTUVWXYZ<br>
|
||||
0123456789.:,;()*!?'@#<>$%&^+-=~
|
||||
</p>
|
||||
<p class="s10" style="font-size: 10px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s11" style="font-size: 11px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s12" style="font-size: 12px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s14" style="font-size: 14px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s18" style="font-size: 18px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s24" style="font-size: 24px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s30" style="font-size: 30px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s36" style="font-size: 36px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s48" style="font-size: 48px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s60" style="font-size: 60px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s72" style="font-size: 72px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="demo">
|
||||
<h1 style="font-family: 'Berkeley Mono'; font-weight: bold; font-style: italic;">Berkeley Mono Bold Italic</h1>
|
||||
<pre title="Usage">.your-style {
|
||||
font-family: 'Berkeley Mono';
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
}</pre>
|
||||
<pre title="Preload (optional)">
|
||||
<link rel="preload" href="BerkeleyMono-BoldItalic.woff2" as="font" type="font/woff2" crossorigin></pre>
|
||||
<div class="font-container" style="font-family: 'Berkeley Mono'; font-weight: bold; font-style: italic;">
|
||||
<p class="letters">
|
||||
abcdefghijklmnopqrstuvwxyz<br>
|
||||
ABCDEFGHIJKLMNOPQRSTUVWXYZ<br>
|
||||
0123456789.:,;()*!?'@#<>$%&^+-=~
|
||||
</p>
|
||||
<p class="s10" style="font-size: 10px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s11" style="font-size: 11px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s12" style="font-size: 12px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s14" style="font-size: 14px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s18" style="font-size: 18px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s24" style="font-size: 24px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s30" style="font-size: 30px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s36" style="font-size: 36px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s48" style="font-size: 48px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s60" style="font-size: 60px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
<p class="s72" style="font-size: 72px;">The quick brown fox jumps over the lazy dog.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
40
vendor/berkeley_mono_transfonter/stylesheet.css
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
@font-face {
|
||||
font-family: 'Berkeley Mono';
|
||||
src: local('Berkeley Mono Bold'), local('BerkeleyMono-Bold'),
|
||||
url('BerkeleyMono-Bold.woff2') format('woff2'),
|
||||
url('BerkeleyMono-Bold.woff') format('woff');
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Berkeley Mono';
|
||||
src: local('Berkeley Mono Regular'), local('BerkeleyMono-Regular'),
|
||||
url('BerkeleyMono-Regular.woff2') format('woff2'),
|
||||
url('BerkeleyMono-Regular.woff') format('woff');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Berkeley Mono';
|
||||
src: local('Berkeley Mono Italic'), local('BerkeleyMono-Italic'),
|
||||
url('BerkeleyMono-Italic.woff2') format('woff2'),
|
||||
url('BerkeleyMono-Italic.woff') format('woff');
|
||||
font-weight: normal;
|
||||
font-style: italic;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Berkeley Mono';
|
||||
src: local('Berkeley Mono Bold Italic'), local('BerkeleyMono-BoldItalic'),
|
||||
url('BerkeleyMono-BoldItalic.woff2') format('woff2'),
|
||||
url('BerkeleyMono-BoldItalic.woff') format('woff');
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
1
vendor/fastlyLogo-white-SVG.svg
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg viewBox="0 0 512 198.27" xmlns="http://www.w3.org/2000/svg"><g fill="#fff"><path d="m348.44 20.35v133.59h40.13v-20.41h-13.26v-133.53h-26.87z"/><path d="m0 133.53h13.64v-64.45h-13.64v-17.73l13.64-2.24v-17.94c0-21.74 4.73-31.17 32.45-31.17a115.17 115.17 0 0 1 19.29 2l-3.68 21.85a49.78 49.78 0 0 0 -9-.78c-9.76 0-12.23 1-12.23 10.51v15.53h20.32v20h-20.28v64.45h13.49v20.4h-54z"/><path d="m334.78 127.08a53.11 53.11 0 0 1 -10.54.84c-11.06.27-10.1-3.36-10.1-13.78v-45.06h21v-20h-21v-49.08h-26.87v119.71c0 23.5 5.8 34.23 31.08 34.23 6 0 14.21-1.54 20.42-2.87z"/><path d="m501.7 133.63a10.14 10.14 0 1 1 -10.19 10.14 10.14 10.14 0 0 1 10.19-10.14m0 18.68a8.55 8.55 0 0 0 8.51-8.54 8.5 8.5 0 1 0 -8.51 8.54m1.88-3.56-2.05-3h-1.42v3h-2.29v-10h4.18c2.46 0 4 1.24 4 3.45a3 3 0 0 1 -2.08 3.09l2.49 3.42zm-3.47-5h1.82c1 0 1.74-.4 1.74-1.5s-.7-1.45-1.68-1.45h-1.88z"/><path d="m253.72 69v-3.54a115.8 115.8 0 0 0 -20.58-1.46c-12.5 0-14 6.63-14 10.23 0 5.08 1.74 7.83 15.29 10.79 19.8 4.45 39.69 9.09 39.69 33.64 0 23.29-12 35.32-37.21 35.32-16.88 0-33.26-3.63-45.76-6.8v-20.1h20.35v3.56c8.75 1.69 17.93 1.52 22.73 1.52 13.34 0 15.49-7.17 15.49-11 0-5.29-3.82-7.83-16.32-10.37-23.56-4-42.25-12.07-42.25-36 0-22.65 15.14-31.54 40.37-31.54 17.09 0 30.08 2.65 42.59 5.83v19.92z"/><path d="m127.84 85.09-9.84 8.6a5.25 5.25 0 1 0 3.19 3.2l8.72-9.75z"/><path d="m171.25 127.07v-83.61h-26.88v7.54a55 55 0 0 0 -18.11-6.77v-9.1h3.28v-6.85h-27.06v6.83h3.28v9.17a55.32 55.32 0 1 0 38.76 101.87l4.77 7.78h28.38v-26.86zm-26.64-26.83a28.42 28.42 0 0 1 -26.88 26.76v-3.18h-3.22v3.18a28.43 28.43 0 0 1 -26.68-26.89h3.17v-3.2h-3.15a28.42 28.42 0 0 1 26.66-26.65v3.16h3.22v-3.17a28.42 28.42 0 0 1 26.88 26.75h-3.2v3.22z"/><path d="m456.58 49.11h55.42v20h-13.25l-34 83.62c-9.74 23.48-25.74 45.59-50.1 45.59a93.67 93.67 0 0 1 -19.5-2l2.43-24.39a68.7 68.7 0 0 0 10.63 1.1c11.3 0 24-7 28-19.19l-34.39-84.78h-13.25v-20h55.43v20h-13.22l19.51 48 19.51-48h-13.22z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
49
vendor/polyfill.min.js
vendored
Normal file
2
vendor/rrule.2.8.1.min.js
vendored
3813
vendor/rrule.js
vendored
Normal file
1
vendor/scnBadgeWhite.svg
vendored
Normal file
|
After Width: | Height: | Size: 51 KiB |