diff --git a/.github/workflows/eleventy-build.yml b/.github/workflows/eleventy-build.yml index 2f5428c9..078ed23a 100644 --- a/.github/workflows/eleventy-build.yml +++ b/.github/workflows/eleventy-build.yml @@ -20,8 +20,7 @@ jobs: - run: npm run build - # New step to copy files from _site to root - - name: Copy files to root + - name: copy files to root run: | cp -R _site/* . rm -rf _site diff --git a/.gitignore b/.gitignore index b70525b5..b512c09d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1 @@ -_site node_modules \ No newline at end of file diff --git a/_site/LICENSE/index.html b/_site/LICENSE/index.html new file mode 100644 index 00000000..cea83d39 --- /dev/null +++ b/_site/LICENSE/index.html @@ -0,0 +1,17 @@ +

MIT License

+

Copyright (c) 2023 Spinal Developers

+

Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions:

+

The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software.

+

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE.

diff --git a/_site/README/index.html b/_site/README/index.html new file mode 100644 index 00000000..73e697d4 --- /dev/null +++ b/_site/README/index.html @@ -0,0 +1,46 @@ +

Eleventy documentation template using Tailwind CSS #

+

An 11ty documentation site theme, built with Tailwind CSS.

+preview of the Eleventy documentation theme, built with Tailwind CSS + + + Spinal CMS logo + +

Getting started #

+
    +
  1. Clone this repository
  2. +
+
git clone https://github.com/spinalcms/11ty-docs-template.git documentation
+
+
    +
  1. Go into this new folder
  2. +
+
cd documentation
+
+
    +
  1. Install dependencies
  2. +
+
npm install
+
+

Development #

+
npm run dev
+
+

Production #

+
npm run build
+
+

Configuring #

+

To change title, description, etc. Update files in src/_data.

+ + +

Contributing #

+
    +
  1. Fork it (https://github.com/spinalcms/11ty-docs-template/fork)
  2. +
  3. Clone the fork using git clone to your local development machine.
  4. +
  5. Create your feature branch (git checkout -b my-new-feature)
  6. +
  7. Commit your changes (git commit -am 'Add some feature')
  8. +
  9. Push to the branch (git push origin my-new-feature)
  10. +
  11. Create a new Pull Request
  12. +
diff --git a/_site/assets/css/index.css b/_site/assets/css/index.css new file mode 100644 index 00000000..807fea12 --- /dev/null +++ b/_site/assets/css/index.css @@ -0,0 +1,53 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +/* Dropdown Styling */ + +/* Table of Contents Styling */ + +/* Wrapper Styling */ +.my-custom-toc { + @apply bg-gray-100 p-4 rounded-md shadow-md; +} + +/* List Styling */ +.my-custom-toc ol { + @apply pl-5; +} + +.my-custom-toc ul { + @apply pl-0; +} + +.my-custom-toc ol > li { + @apply my-1; +} + +.my-custom-toc ol > li > ol, +.my-custom-toc ol > li > ul { + @apply pl-5 mt-1; +} + +.my-custom-toc ol > li > ol > li, +.my-custom-toc ol > li > ul > li { + @apply my-1; +} + +.my-custom-toc ol > li > ol > li > ol, +.my-custom-toc ol > li > ul > li > ul { + @apply pl-5 mt-1; +} + +/* Link Styling */ +.my-custom-toc a { + @apply text-blue-600 hover:text-blue-800 transition-colors duration-200; +} + +.sticky { + position: -webkit-sticky; + position: sticky; + top: 1rem; +} + + diff --git a/_site/assets/images/HR3NaGg.png b/_site/assets/images/HR3NaGg.png new file mode 100644 index 00000000..d28ca173 Binary files /dev/null and b/_site/assets/images/HR3NaGg.png differ diff --git a/_site/assets/images/logo.png b/_site/assets/images/logo.png new file mode 100644 index 00000000..d28ca173 Binary files /dev/null and b/_site/assets/images/logo.png differ diff --git a/_site/assets/images/sprucebotimage.jpeg b/_site/assets/images/sprucebotimage.jpeg new file mode 100644 index 00000000..33102677 Binary files /dev/null and b/_site/assets/images/sprucebotimage.jpeg differ diff --git a/_site/docs/Katas/index.html b/_site/docs/Katas/index.html new file mode 100644 index 00000000..a8c92028 --- /dev/null +++ b/_site/docs/Katas/index.html @@ -0,0 +1,229 @@ + + + + Katas + + + + + + +
+
+ + Lumena Labs + +
+ +
+ + + + + + +
+ + +
+ + +
+ + + + + + + + +
+
+
+

+ Learn +

+ +

+ Katas +

+
+ + + + + + + + + + +
+

katas

+ +
+ +

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + + +
+ +
+
+ Previous +
+ +
+ + How does Spinal work? + +
+
+ + + +
+
+ Next +
+ +
+ + Previewing content + +
+
+ +
+ + + +
+
+ + diff --git a/_site/docs/Learn/index.html b/_site/docs/Learn/index.html new file mode 100644 index 00000000..d8bbf55d --- /dev/null +++ b/_site/docs/Learn/index.html @@ -0,0 +1,211 @@ + + + + LumenaLabs + + + + + + +
+
+ + Lumena Labs + +
+ +
+ + + + + + +
+ + +
+ + +
+ + + + + + +
+
+
+

+ +

+ +

+ +

+
+ + + + + + + +
+ +
+ +

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + + +
+ + + + + +
+ + + +
+
+ + diff --git a/_site/docs/_eleventy_redirect/index.html b/_site/docs/_eleventy_redirect/index.html new file mode 100644 index 00000000..de34a983 --- /dev/null +++ b/_site/docs/_eleventy_redirect/index.html @@ -0,0 +1,61 @@ + + + + Lumena Labs + + + + + + + + + +
+ + + + + +
+ +
+ + + + +
+ + diff --git a/_site/docs/concepts copy/concept-1/index.html b/_site/docs/concepts copy/concept-1/index.html new file mode 100644 index 00000000..2796443a --- /dev/null +++ b/_site/docs/concepts copy/concept-1/index.html @@ -0,0 +1,204 @@ + + + + Concept 1 + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Concepts + + + Ideology + + + Developer Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + +
+
+
+

+ Concepts +

+

+ Concept 1 +

+
+ + + + + +
+

Content here

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Ideology + +
+
+ + + +
+
+ Next +
+ +
+ + Concept 2 + +
+
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/concepts copy/concept-2/index.html b/_site/docs/concepts copy/concept-2/index.html new file mode 100644 index 00000000..635118fe --- /dev/null +++ b/_site/docs/concepts copy/concept-2/index.html @@ -0,0 +1,204 @@ + + + + Concept 2 + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Concepts + + + Ideology + + + Developer Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + +
+
+
+

+ Concepts +

+

+ Concept 2 +

+
+ + + + + +
+

Content here. You can use markdown.

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Concept 1 + +
+
+ + + +
+
+ Next +
+ +
+ + Concept 3 + +
+
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/concepts copy/concept-3/index.html b/_site/docs/concepts copy/concept-3/index.html new file mode 100644 index 00000000..34a339c2 --- /dev/null +++ b/_site/docs/concepts copy/concept-3/index.html @@ -0,0 +1,204 @@ + + + + Concept 3 + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Concepts + + + Ideology + + + Developer Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + +
+
+
+

+ Concepts +

+

+ Concept 3 +

+
+ + + + + +
+

katas

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Concept 2 + +
+
+ + + +
+
+ Next +
+ +
+ + Concepts + +
+
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/concepts copy/concepts/index.html b/_site/docs/concepts copy/concepts/index.html new file mode 100644 index 00000000..510e4485 --- /dev/null +++ b/_site/docs/concepts copy/concepts/index.html @@ -0,0 +1,268 @@ + + + + Concepts + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Concepts + + + Ideology + + + Developer Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + +
+
+
+

+ Main +

+

+ Concepts +

+
+ +

+ This is the Concepts Homepage +

+ + + + +
+ [Screenshot Image] +
+ +
+

+ Video walkthrough +

+ +

+ Watch this 5 minutes video-walkthrough of Concepts. You quickly learn how to set up your dashboard, invite team members, set permissions and how to schedule and publish content. +

+
+
+ + + + +

+ Navigate through the Concepts +

+ + + + +
+

Enter Content Here

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Concept 3 + +
+
+ + + +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/concepts/concept-1/index.html b/_site/docs/concepts/concept-1/index.html new file mode 100644 index 00000000..d60ee9b1 --- /dev/null +++ b/_site/docs/concepts/concept-1/index.html @@ -0,0 +1,148 @@ + + + + Concept 1 + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ + + +
+ + + + + + + + + + +
+
+
+

+ Concept 1 +

+
+ + + + + + + + + + + +
+

Content here

+ +
+
+ + diff --git a/_site/docs/concepts/concept-2/index.html b/_site/docs/concepts/concept-2/index.html new file mode 100644 index 00000000..48e1ba47 --- /dev/null +++ b/_site/docs/concepts/concept-2/index.html @@ -0,0 +1,160 @@ + + + + Concept 2 + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ + + +
+ + + + + + + + + + +
+
+
+

+ Concept 2 +

+
+ + + + + + + + + + + +
+

Content here. You can use markdown.

+ +
+
+ + diff --git a/_site/docs/concepts/concept-3/index.html b/_site/docs/concepts/concept-3/index.html new file mode 100644 index 00000000..601a81d6 --- /dev/null +++ b/_site/docs/concepts/concept-3/index.html @@ -0,0 +1,160 @@ + + + + Concept 3 + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ + + +
+ + + + + + + + + + +
+
+
+

+ Concept 3 +

+
+ + + + + + + + + + + +
+

katas

+ +
+
+ + diff --git a/_site/docs/concepts/create-edit-content-types/index.html b/_site/docs/concepts/create-edit-content-types/index.html new file mode 100644 index 00000000..484c540a --- /dev/null +++ b/_site/docs/concepts/create-edit-content-types/index.html @@ -0,0 +1,71 @@ + + + + Create and edit content types? + + + + + + + +
+ + +
+
+
+

+ Getting Started +

+

+ Create and edit content types? +

+
+ + + + +
+

Content here

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ + + +
+
+ Next +
+ +
+ + How does Spinal work? + +
+
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/concepts/errors/index.html b/_site/docs/concepts/errors/index.html new file mode 100644 index 00000000..6f5d06c7 --- /dev/null +++ b/_site/docs/concepts/errors/index.html @@ -0,0 +1,212 @@ + + + + Errors + + + + + + + +
+
+ + Site Logo + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ + + +
+ + + + + +
+
+
+

+ Errors +

+
+ +

+ Handling Errors in Sprucebot +

+ + + + + + + + + + + + +
+

Overview #

+

In the context of Sprucebot, effective error handling is not just desirable but essential. It ensures that your application maintains high reliability, excellent user experience, and ease of debugging. This section of the guide will delve deep into strategies for robust error handling in your Sprucebot platform.

+

Use Case #

+ +
+
+
+ + + + +
+ + diff --git a/_site/docs/concepts/events/index.html b/_site/docs/concepts/events/index.html new file mode 100644 index 00000000..eb5cbe88 --- /dev/null +++ b/_site/docs/concepts/events/index.html @@ -0,0 +1,349 @@ + + + + Events + + + + + + + +
+
+ + Site Logo + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ + + +
+ + + + + +
+
+
+

+ Events +

+
+ +

+ Guide to Spruce Events and Mercury Event Engine +

+ + + + + + + + + + + + +
+

Overview #

+

In Spruce, events are the communicative threads that connect different parts of the system, allowing for a reactive and synchronized ecosystem. This guide is your comprehensive resource for mastering events within Spruce.

+

Understanding Events in Spruce #

+

Events in Spruce are triggered by user interactions, system updates, or scheduled occurrences. These events are managed by Mercury, the central nervous system of Spruce, which facilitates communication between skills.

+

Mercury - The Event Engine #

+

Mercury processes events through commands like spruce create.event, spruce listen.event, and spruce sync.events, ensuring the smooth operation of your system’s event-driven architecture.

+

Anatomy of an Event #

+

An event is characterized by its fully qualified event name (FQEN), payload, and source. Events are named following a pattern like action-subject::version to facilitate clear communication and handling.

+

Types of Events #

+

Core Events #

+

Core events are foundational and understood by all Spruce components. Examples include:

+
    +
  • create-organization::v2020_01_01
  • +
  • update-role::v2020_01_01
  • +
+

Skill Events #

+

Skill events are custom to specific skills, such as:

+
    +
  • appointments.create-category::v2020_01_10
  • +
  • shifts.create-shift-type::v2020_01_10
  • +
+

Global Events #

+

Global events are broadcasted across the system and do not target specific recipients.

+

Crafting and Emitting Events #

+

Targets #

+

Targets are defined using builders, and unless the event is global, a target may look like:

+
const acceptEmitTargetBuilder = buildSchema({
+    id: 'acceptEmitTarget',
+    fields: {
+        organizationId: {
+            type: 'id',
+            isRequired: true,
+        },
+    },
+})
+
+export default acceptEmitTargetBuilder
+
+

Payloads #

+

The payload of an event carries the data and is defined based on your requirements. Here’s an example of how to construct a payload:

+
import inviteBuilder from '../../../schemas/v2021_12_16/invite.builder'
+
+const sendEmitPayloadBuilder = buildSchema({
+    id: 'sendEmitPayload',
+    fields: {
+        ...dropPrivateFields(
+            dropFields(inviteBuilder.fields, [
+                'id',
+                'dateCreated',
+                'status',
+                'target',
+            ])
+        ),
+    },
+})
+
+export default sendEmitPayloadBuilder
+
+

Emitting Events #

+

Emitting events involves invoking specific commands and handling the responses:

+
// Emitting an event and handling the response
+const [{ auth }] = await client.emitAndFlattenResponses('whoami::v2020_12_25')
+
+// Listening to events and pushing payloads
+const payloads = []
+const results = await client.emit('test-skill::register-dashboard-cards', {}, ({ payload }) => {
+    payloads.push(payload)
+})
+
+// Handling all payloads and errors
+const { payloads: allPayloads, errors } = eventResponseUtil.getAllPayloadsAndErrors(results, SpruceError)
+assert.isFalsy(errors)
+assert.isEqualDeep(allPayloads, payloads)
+
+

Event Emitters #

+

Your event emitters are the mechanisms through which your system sends and receives events.

+

Local: Event Emitter #

+

A local event emitter is a strictly typed, payload-validating event emitter. Here are the steps to create one:

+
    +
  1. Dependencies:
  2. +
+
yarn add @sprucelabs/mercury-event-emitter
+
+
    +
  1. Create Your Emitter Class:
  2. +
+
import { AbstractEventEmitter } from '@sprucelabs/mercury-event-emitter'
+import { buildEventContract } from '@sprucelabs/mercury-types'
+
+// Defining the contract
+const contract = buildEventContract({
+    eventSignatures: {
+        // Your event signatures here
+    },
+})
+
+// SkillViewEmitter class
+export default class SkillViewEmitter extends AbstractEventEmitter<SkillViewEventContract> {
+    // Your implementation here
+}
+
+// Usage
+const emitter = SkillViewEmitter.getInstance()
+
+
    +
  1. Build Your Contract:
  2. +
+
const contract = buildEventContract({
+    eventSignatures: {
+        'did-scroll': {
+            emitPayloadSchema: buildSchema({
+                id: 'didScrollEmitPayload',
+                fields: {
+                    scrollTop: {
+                        type: 'number',
+                        isRequired: true,
+                    },
+                },
+            }),
+        },
+        // More event signatures can be added here
+    },
+})
+
+
    +
  1. Use Your Emitter:
  2. +
+
// Attaching a listener
+await instance.on('did-scroll', (payload) => {
+    console.log(payload
+
+.scrollTop)
+})
+
+// Emitting an event
+await emitter.emit('did-scroll', {
+    scrollTop: 0
+})
+
+

Use Case #

+ +
+
+
+ + + + +
+ + diff --git a/_site/docs/concepts/how-does-spinal-work/index.html b/_site/docs/concepts/how-does-spinal-work/index.html new file mode 100644 index 00000000..2c59e4be --- /dev/null +++ b/_site/docs/concepts/how-does-spinal-work/index.html @@ -0,0 +1,151 @@ + + + + How does Spinal work? + + + + + + + +
+ + + + + + + + +
+
+
+

+ Getting Started +

+

+ How does Spinal work? +

+
+ +

+ This is some intro for this doc. It's styled slightly different. +

+ + + + +
+

Content here. You can use markdown.

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + concept-1 + +
+
+ + + +
+
+ Next +
+ +
+ + Katas + +
+
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/concepts/index.html b/_site/docs/concepts/index.html new file mode 100644 index 00000000..69022d14 --- /dev/null +++ b/_site/docs/concepts/index.html @@ -0,0 +1,276 @@ + + + + Introduction to Sprucebot Concepts + + + + + + + +
+
+ + Site Logo + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ + + +
+ + + + + +
+
+
+

+ Introduction to Sprucebot Concepts +

+
+ +

+ This is the Concepts Homepage +

+ + + + +
+ [Screenshot Image] +
+ +
+

+ Video walkthrough +

+ +

+ Watch this video-walkthrough of Concepts. +

+
+
+ + + + + + +

+ Navigate through the Concepts +

+ + + + + + + + + +
+ +
+
+
+ + + + +
+ + diff --git a/_site/docs/concepts/katas/index.html b/_site/docs/concepts/katas/index.html new file mode 100644 index 00000000..c1ae493d --- /dev/null +++ b/_site/docs/concepts/katas/index.html @@ -0,0 +1,147 @@ + + + + Concept 3 + + + + + + + +
+ + + + + + + + +
+
+
+

+ Getting Started +

+

+ Concept 3 +

+
+ + + + +
+

katas

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Concept 2 + +
+
+ + + +
+
+ Next +
+ +
+ + Previewing content + +
+
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/concepts/listeners/index.html b/_site/docs/concepts/listeners/index.html new file mode 100644 index 00000000..13080aec --- /dev/null +++ b/_site/docs/concepts/listeners/index.html @@ -0,0 +1,212 @@ + + + + Listeners + + + + + + + +
+
+ + Site Logo + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ + + +
+ + + + + +
+
+
+

+ Listeners +

+
+ +

+ Implementing Listeners in Spruce +

+ + + + + + + + + + + + +
+

Overview #

+

Listeners are important in creating interactive, responsive Skills. They act as the conduits for your application to respond to events happening around it, whether within the system, from user interactions, or external services. This document provides an in-depth guide on implementing listeners effectively in your Skills.

+

Use Case #

+ +
+
+
+ + + + +
+ + diff --git a/_site/docs/concepts/schemas/index.html b/_site/docs/concepts/schemas/index.html new file mode 100644 index 00000000..447169bb --- /dev/null +++ b/_site/docs/concepts/schemas/index.html @@ -0,0 +1,212 @@ + + + + Schemas + + + + + + + +
+
+ + Site Logo + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ + + +
+ + + + + +
+
+
+

+ Schemas +

+
+ +

+ This is the Concepts Homepage +

+ + + + + + + + + + + + +
+

Introduction #

+

Schemas act as a contractual blueprint between data and the way it is handled throughout an application. It’s a critical construct that not only outlines the structure of data entities but also enforces rules and relationships essential for ensuring data integrity, consistency, and reliability.

+

Use Case #

+ +
+
+
+ + + + +
+ + diff --git a/_site/docs/concepts/skills/index.html b/_site/docs/concepts/skills/index.html new file mode 100644 index 00000000..b1b73940 --- /dev/null +++ b/_site/docs/concepts/skills/index.html @@ -0,0 +1,43 @@ + + + + Lumena Labs + + + + + + + + + +
+ + + + +
+
+
+

+ +

+
+ + + + + + + + + + + +
+ +
+
+ + diff --git a/_site/docs/concepts/stores/index.html b/_site/docs/concepts/stores/index.html new file mode 100644 index 00000000..1839b3a8 --- /dev/null +++ b/_site/docs/concepts/stores/index.html @@ -0,0 +1,307 @@ + + + + Stores + + + + + + + +
+
+ + Site Logo + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ + + +
+ + + + + +
+
+
+

+ Stores +

+
+ +

+ Data Stores - The Technical Backbone of Spruce +

+ + + + + + + + + + + + +
+

Overview #

+

Data Stores serve as the pivotal repositories within Spruce’s digital ecosystem. They are fundamentally database-agnostic, providing a uniform interface for data manipulation across various database systems. This technical manual delves into the intricacies of creating, synchronizing, and utilizing Stores to their full potential.

+

Command Line Interface (CLI) Operations #

+

Initialization of Stores #

+

To start with a Store, use the spruce create.store command. This initializes a new Store, setting the stage for data management operations.

+

Store Synchronization #

+

Post-renaming of classes or files, it’s imperative to align the Store with the changes. This is achieved through the spruce sync.stores command, ensuring that the Store’s structure and its references remain consistent.

+

Schema Definition within Stores #

+

Schemas act as the blueprint for data validation and structure within the Stores. They come in various forms, tailoring to specific actions:

+
    +
  • fullSchema: Defines the data structure returned by .find(...) or .findOne(...).
  • +
  • createSchema: Ensures data integrity for .create(...) or .createOne(...).
  • +
  • updateSchema: Governs data adjustments made through .update(...), .updateOne(...), or .upsert(...).
  • +
  • databaseSchema: Represents the actual data structure stored in the database.
  • +
+

A recommended best practice is to generate a fully typed schema using spruce create.schema, aligning it with fullSchema to enforce data consistency.

+

Data Lifecycle Hooks #

+

Hooks are critical in managing the data lifecycle within Stores, allowing for pre- and post-operation data manipulation:

+
    +
  • willCreate: Invoked before data creation.
  • +
  • didCreate: Triggered after data creation.
  • +
  • willUpdate: Engaged before data updates.
  • +
  • didUpdate: Activated after data updates.
  • +
  • willScramble: Employed to obfuscate data before saving or retrieval for security reasons.
  • +
+

These hooks provide a mechanism to fine-tune data before it’s committed to the Store or before it’s fetched from it.

+

Implementing Stores in Listeners and Tests #

+

Listeners Integration #

+

When integrating Stores within listeners, it’s crucial to manage data fields efficiently. Utilizing includeFields ensures the Store only retrieves necessary data fields, thus optimizing performance and adherence to response payload constraints.

+
export default async (
+    event: SpruceEvent<SkillEventContract, EmitPayload>
+): SpruceEventResponse<ResponsePayload> => {
+
+    const { stores, source } = event
+
+    const store = await stores.getStore('profiles')
+    const profile = await store.findOne({
+        target: {
+            personId: source.personId
+        }
+    }, {
+        includeFields: getFields(getProfileSchema),
+    })
+
+    return {
+        profile
+    }
+
+}
+
+

Testing with Stores #

+

Stores also prove their mettle in testing environments. Through seeding and various assertive checks, one can ensure the Store’s performance and reliability. Testing operations like youCanSeedDataIntoYourStore and helpersLikeGetNewestAndListAreSoNice provide evidence of a well-functioning Store.

+
export default class AcceptingAnInviteTest extends AbstractSpruceFixtureTest {
+    private static vc: AcceptSkillViewController
+    private static invites: InvitesStore
+
+    protected static async beforeEach() {
+        await super.beforeEach()
+        this.invites = await this.stores.getStore('invites')
+    }
+
+    @test()
+    @seed('invites', 1)
+    protected static async youCanSeedDataIntoYourStore() {
+        const invite = await this.getNewestInvite()
+        assert.isTruthy(invite)
+    }
+
+   @test()
+   @seed('invites', 20)
+    proctected static async helpersLikeGetNewestAndListAreSoNice() {
+        const invites = this.listInvites()
+        assert.isLength(invites, 20)
+    }
+
+    private static async getNewestInvite() {
+        const invite = await this.invites.findOne({})
+        assert.isTruthy(invite, `Don't forget to @seed('invites', 1) to get started!`)
+        return invite
+    }
+    
+    private static async listInvites() {
+        const invites = await this.invites.find({})
+        assert.isAbove(invite.length, 0, `Don't forget to @seed('invites', 1) to get started!`)
+        return invites
+    }
+
+    
+}
+
+

Database Integration: Embracing Postgres #

+

While Stores are indifferent to the underlying database technology, they can be augmented with adapters like @sprucelabs/postgres-data-store. This extends the Store’s capabilities to leverage the robustness of SQL-based systems, configured via environment variables like DATABASE_CONNECTION_STRING. If you want to add Postgres support, you must import the dependency.

+
yarn add @sprucelabs/postgres-data-store
+
+

Then you can configure your databes in your env.

+
DATABASE_CONNECTION_STRING="postgres://postgres:password@localhost:5432/database_name"
+
+

Use Case #

+ +
+
+
+ + + + +
+ + diff --git a/_site/docs/concepts/tests/index.html b/_site/docs/concepts/tests/index.html new file mode 100644 index 00000000..6277ad16 --- /dev/null +++ b/_site/docs/concepts/tests/index.html @@ -0,0 +1,424 @@ + + + + Tests + + + + + + + +
+
+ + Site Logo + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ + + +
+ + + + + +
+
+
+

+ Tests +

+
+ +

+ Testing in Spruce +

+ + + + + + + + + + + + +
+

Overview #

+

In Sprucebot, Tests maintain quality, ensuring that every aspect of the system performs flawlessly. This guide provides insights into the testing methodologies within Sprucebot.

+

Creating and Running Tests #

+

spruce create.test - Commits to quality by initializing a new test.
+spruce test - Validates code readiness for deployment by running the test suite.

+

Fixtures #

+

Fixtures are utility classes that emulate real-world scenarios, setting up the environment for tests. They are essential for creating realistic test conditions.

+
    +
  • View Fixture
  • +
  • Store Fixture
  • +
  • Mercury Fixture
  • +
  • Person Fixture
  • +
  • Location Fixture
  • +
  • Organization Fixture
  • +
  • Role Fixture
  • +
  • Seed Fixture
  • +
+

Built-in Fixtures #

+

When extending AbstractSpruceFixtureTest, built-in fixtures are available:

+
    +
  • this.views => ViewFixture
  • +
  • this.roles => RoleFixture
  • +
  • this.locations => LocationFixture
  • +
  • this.organizations => OrganizationFixture
  • +
  • this.people => PersonFixture
  • +
  • this.seeder => SeedFixture
  • +
  • this.skills => SkillFixture
  • +
  • this.mercury => MercuryFixture
  • +
+

Example Fixture Use #

+
export default class RenderingRootViewControllerTest extends AbstractSpruceFixtureTest {
+
+    @test()
+    protected static gettingFixtures() {
+
+        const organizationFixture = this.organizations
+
+        assert.isTruthy(organizationFixture)
+
+        //Save time by accessing the fixture via protected pro
+        assert.isTruthy(this.organizations)
+        assert.isTruthy(this.locations)
+    }
+}
+
+

Authentication in Testing #

+

Authentication mechanisms are tested using the @login decorator, ensuring security is as robust as other system components.

+
@login()
+export default class MySkillViewControllerTest extends AbstractSpruceFixtureTest {
+
+    @test()
+    protected static async beforeEach() {
+        await super.beforeEach()
+
+        /**
+        * Is the exact same as @login decorator, don't bother doing this manually
+        * const { client } = await this.Fixture('view').loginAsDemoPerson(DEMO_NUMBER_ROOT_SVC)
+        * MercuryFixture.setDefaultClient(client)
+        **/
+
+        const client = login.getClient()
+        const { client: client2 } = await this.Fixture('view').loginAsDemoPerson()
+
+        assert.isEqual(client, client2) //once default client is set, unless you pass a new number, the client is reused
+
+        const { client: client3 } = await this.Fixture('view').loginAsDemoPerson(DEMO_NUMBER_ROOT_2)
+        assert.isNotEqual(client,client3)
+
+    }
+}
+
+

Seeding Data #

+

Seeding prepares the testing landscape with necessary data, from roles to profiles, using decorators like @seed.

+

Seeding Example #

+
//@login sets the default client for all fixtures and seeders going forward
+@login()
+export default class RenderingRootViewControllerTest extends AbstractSpruceFixtureTest {
+
+    @seed('organizations', 2)
+    protected static async beforeEach() {
+        await super.beforeEach()
+
+        const totalOrgs = await this.organizations.listOrganizations()
+        assert.isLength(totalOrgs, 2)
+
+        //since this is in the beforeEach(), every test will come with 2 organizations
+    }
+
+    @test()
+    @seed('locations',10)
+    protected static async locationsShouldSeed() {
+        const currentOrg = await this.organizations.getNewestOrganization()
+        const locations = await this.locations.listLocations({ organizationId: currentOrg?.id })
+
+        assert.isLength(locations, 10)
+    }
+
+    @test()
+    protected static async seedingEntireAccount() {
+
+        // will seed data under newest organization
+        const {
+            locations, 
+            guests, 
+            managers, 
+            owners, 
+            teammates 
+        } = await this.seeder.seedAccount({
+            totalLocations: 1,
+            totalGuests: 3,
+            totalManagers: 5,
+            totalOwners: 2,
+            totalTeammetes: 3,
+            startingPhone: DEMO_NUMBER_SEED_STARTING_PHONE
+        })
+
+
+    }
+
+}
+
+

Installing your Skill #

+
@login()
+export default class RenderingRootViewControllerTest extends AbstractSpruceFixtureTest {
+
+    @test()
+    @seed('organization',1)
+    @install.skills('skill-namespace-1', 'skill-namespace-2')
+    protected static async skillsArInstalled() {
+        //the skill is only installed at the newest organizatios
+        //now your skill can emit events to skills that are installed at the newest org
+    }
+}
+
+

Skill Views #

+

Everything you need to know is under the Views section!

+

Best Practices and Advanced Strategies #

+

Creating reusable fixtures, employing meaningful assertions, and anticipating user behavior are among the golden rules of Spruce testing.

+

AbstractProfileTest Setup Guide

+

To optimize your testing process, start by creating an abstract test class named AbstractProfileTest. This class will serve as the foundation for all your subsequent tests.

+
    +
  • +

    Inheritance: Ensure that every new test class extends the AbstractProfileTest.

    +
  • +
  • +

    Helper Methods: Implement utility functions such as getNewestInvite() and listOrgs() to streamline common actions.

    +
  • +
  • +

    Fixture Initialization:

    +
      +
    • In the beforeEach() setup method, assign commonly used fixtures to class properties with plural names for easy reference. For example:
      this.views = this.Fixture('views');
      +this.orgs = this.Fixture('organizations');
      +
      +
    • +
    +
  • +
  • +

    Store Access:

    +
      +
    • Similarly, initialize stores as class properties within beforeEach(), using the store’s singular name. For instance:
      this.invites = await this.Store('invites');
      +this.profiles = await this.Store('profiles');
      +
      +
    • +
    +
  • +
  • +

    Reusability:

    +
      +
    • Avoid repetitive fixture creation by saving them as protected properties within your abstract test.
    • +
    +
  • +
  • +

    Convenience Getters: For frequently accessed data, create getter methods like getNewestOrganization() to retrieve information quickly.

    +
  • +
  • +

    Assertions:

    +
      +
    • Use assertive checks with clear error messages to ensure the test environment is correctly set up, aiding in troubleshooting.
    • +
    +
  • +
+

Follow these guidelines to establish a robust and efficient testing structure that will benefit your current and future development needs.

+

Abstract Skill Test Example #

+
export default class AbstractProfileTest extends AbstractViewControllerTest {
+    protected static profiles: ProfilesStore
+    protected static router: Router
+
+    protected static async beforeEach() {
+        await super.beforeEach()
+
+        this.profiles = await this.stores.Store('profiles')
+        this.router = this.views.getRouter()
+    }
+
+    protected static async getNewestProfile() {
+        const profile = await this.profiles.findOne({})
+
+        assert.isTruthy(profile, `You gotta @seed('profiles',1) to continue.`)
+        return profile
+    }
+
+    protected static async getNewestOrg() {
+        const org = await this.organizations.getNewestOrganization()
+        assert.isTruthy(org, `You gotta @seed('organizations',1) to continue.`)
+        return org
+    }
+
+    protected static async listProfiles () {
+        const profiles = await this.profiles.findOne({})
+        assert.isAbove(profiles.length, 0, `You gotta @seed('profiles',1) to continue.`)
+        return profiles
+    }
+}
+
+

Use Cases #

+ +
+
+
+ + + + +
+ + diff --git a/_site/docs/concepts/views/index.html b/_site/docs/concepts/views/index.html new file mode 100644 index 00000000..32ec085f --- /dev/null +++ b/_site/docs/concepts/views/index.html @@ -0,0 +1,763 @@ + + + + Views + + + + + + + +
+
+ + Site Logo + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ + + +
+ + + + + +
+
+
+

+ Views +

+
+ +

+ Introduction to Views in Sprucebot +

+ + + + + + + + + + + + +
+

Overview #

+

Skill Views are the elements users interact with when they visit spruce.bot. They are top-level Views that include various components such as CardViews, ListViews, FormViews, etc. These are controlled by SkillViewControllers. Every skill has a RootSkillViewController that is loaded by the skill’s namespace, and there is no limit to the number of Skill Views (and Views) a skill can have.

+

Creating and Previewing Skill Views #

+

Creating a New Skill View #

+

To create a new Skill View or View, use the command:

+
spruce create.view
+
+

Previewing Skill Views #

+

For live reloading and previewing of your Views, use:

+
spruce watch.views
+
+

Note: Your skill must be registered before you can publish your Skill Views.

+

Root View Controller #

+

This is the primary view for your skill, which is accessible by your Skill’s namespace. The creation of the RootViewController should be the first step for each skill.

+

Incremental Building #

+

As you make changes to the source, your Views will be incrementally built when you use:

+
spruce watch.views
+
+

Make sure you have logged in and registered your skill first!

+

Testing View Controllers #

+

Testing involves several steps to ensure your Views perform as expected.

+
    +
  1. +

    Create Your Test File
    +Begin by creating your test file using the command:

    +
    spruce create.test
    +
    +

    Choose AbstractSpruceFixtureTest or your Skill’s primary AbstractTest if it has been created.

    +
  2. +
  3. +

    Writing Your First Failing Test
    +Start by clearing out any existing tests and add your first failing test. Make sure your namespace is correct.

    +
    @test()
    +protected static async canRenderRootSkillView() {
    +    const vc = this.views.Controller('adventure.root', {})
    +}
    +
    +
  4. +
  5. +

    Creating Your Root View Controller
    +Use the command spruce create.view to create your RootViewController.

    +
  6. +
  7. +

    Finishing Your First Test
    +Your test should now ensure that the RootViewController always renders successfully.

    +
    @test()
    +protected static async canRenderRootSkillView() {
    +    const vc = this.views.Controller('adventure.root', {})
    +    this.render(vc)
    +}
    +
    +

    If this test ever fails, it indicates a problem with the RootViewController.

    +
  8. +
+

Assertion Libraries #

+

Several libraries are available to make writing tests easier:

+
    +
  • vcAssert: A general catch-all library for assertions.
  • +
  • formAssert
  • +
  • listAssert
  • +
  • buttonAssert
  • +
+

These are used for constructing failing tests which are an essential part of test-driven development.

+

Tests #

+

Testing lists #

+
export default class RootSkillViewControllerTest extends AbstractSpruceFixtureTest {
+
+  protected static vc: SpyRootSkillView
+
+  protected static async beforeEach() {
+    await super.beforeEach()
+
+    this.views.setController('adventure.root', SpyRootSkillView)
+    this.vc = this.views.Controller('adventure.root', {}) as SpyRootSkillView
+  }
+
+    @test()
+    protected static async rendersList() {
+        const listVc = listAssert.cardRendersList(this.equipCardVc)
+
+        listAssert.listRendersRow(vc, 'no-entries')
+
+        listVc.addRow({...})
+        listVc.addRow({...})
+        listVc.addRow({ id: location.id, ...})
+
+        await interactor.clickInRow(vc, 2, 'edit')
+        await interactor.clickInRow(vc, location.id, 'edit')
+    }
+
+  protected static get equipCardVc() {
+    return this.vc.equipCardVc
+  }
+
+}
+
+//for accessing the list vc
+class SpyRootSkillView extends RootSkilLViewController {
+  public equipCardVc: CardViewController
+  public equipmentListVc: ListViewController
+}
+
+//production
+class RootSkillviewController extends AbstractSkillViewController {
+  protected equipCardVc: CardViewController
+  protected equipmentListVc: ListViewController
+    public constructor(options: ViewControllerOptions) {
+        super(options)
+        this.equipmentListVc = this.Controller('list', {...})
+    this.equipCardVc = this.Controller('card', ...)
+    }
+}
+Testing confirmation dialogs
+//test
+export default class RootSkillViewControllerTest extends AbstractSpruceFixtureTest {
+  @test()
+  protected static async confirmsBeforeSaving() {
+    const formVc = this.vc.getFormVc();
+
+    formVc.setValue("name", "Haircut");
+
+    const confirmVc = await vcAssert.assertRendersConfirm(this.vc, () =>
+      interactor.submitForm(formVc)
+    );
+
+    await confirmVc.accept();
+
+    const match = await this.Store("services").findOne({});
+
+    assert.isEqual(match.name, "Haircut");
+  }
+
+  @test()
+  protected static async rejectingConfirmDoesNotSave() {
+    const formVc = this.vc.getFormVc();
+
+    await formVc.setValue("name", "Haircut");
+
+    const confirmVc = await vcAssert.assertRendersConfirm(this.vc, () =>
+      interactor.submitForm(formVc)
+    );
+
+    await confirmVc.reject();
+
+    const match = await this.Store("services").findOne({});
+
+    assert.isNotEqual(match.name, "Haircut");
+  }
+}
+
+//production
+class RootSkillviewController extends AbstractSkillViewController {
+  public constructor(options: ViewControllerOptions) {
+    super(options);
+    this.formCardVc = this.FormCardVc();
+  }
+
+  private FormVc() {
+    return this.views.Controller(
+      "form",
+      buildForm({
+        id: "service",
+        schema: serviceSchema,
+        onSubmit: this.handleSubmit.bind(this),
+        sections: [
+          {
+            fields: [
+              {
+                name: "name",
+                hint: "Give it something good!",
+              },
+              "duration",
+            ],
+          },
+        ],
+      })
+    );
+  }
+
+  private FormCardVc() {
+    return this.views.Controller("card", {
+      id: "service",
+      header: {
+        title: "Create your service!",
+      },
+      body: {
+        sections: [
+          {
+            form: this.formVc.render(),
+          },
+        ],
+      },
+    });
+  }
+
+  private async handleSubmit({ values }: SubmitHandler<ServiceSchema>) {
+    const confirm = await this.confirm({ message: "You ready to do this?" });
+    if (confirm) {
+      await this.createService(values);
+    }
+  }
+
+  public getFormVc() {
+    return this.formVc;
+  }
+}
+
+

Testing active record cards #

+

A card with a list that is wicked easy to use and cuts out a ton of reduntant work!

+

Make sure you load your Active Record Card for it to show any results!

+
export default class RootSkillViewControllerTest extends AbstractSpruceFixtureTest {
+  @test()
+  protected static async rendersActiveRecordCard() {
+    const vc = this.views.Controller("my-skill.root", {});
+    const activeVc = vcAssert.assertSkillViewRendersActiveRecordCard(vc);
+    assert.isEqual(vc.getActiveRecordCard(), activeVc);
+
+    await this.views.load(vc);
+
+    assert.isTrue(activeVc.getIsLoaded());
+  }
+}
+
+// Production
+export default class RootSkillViewController extends AbstractViewController<Card> {
+  public constructor(options: ViewControllerOptions) {
+    super(options);
+    this.activeRecrodCardVc = this.ActiveRecordVc();
+  }
+
+  private ActiveRecordVc() {
+    return this.views.Controller(
+      "activeRecordCard",
+      buildActiveRecordCard({
+        header: {
+          title: "Your locations",
+        },
+        eventName: "list-locations::v2020_12_25",
+        payload: {
+          includePrivateLocations: true,
+        },
+        responseKey: "locations",
+        rowTransformer: (location) => ({ id: location.id, cells: [] }),
+      })
+    );
+  }
+
+  public load(options: SkillViewControllerLoadOptions) {
+    const organization = await options.scope.getCurrentOrganization();
+    this.activeRecordCardVc.setTarget({ organizationId: organization.id });
+  }
+
+  public getActiveRecordCardVc() {
+    return this.activeRecordCardVc;
+  }
+}
+
+

Testing scope #

+

Scoping experience to a specific organization or location.

+

By default, you will be scoped to your latest organization and location.

+

Learn more here.

+
@login()
+export default class RootSkillViewControllerTest extends AbstractSpruceFixtureTest {
+  protected static async beforeEach() {
+    await super.beforeEach();
+  }
+
+  @test()
+  protected static async redirectsWhenNoCurrentOrg() {
+    let wasHit = false;
+
+    await vcAssert.assertActionRedirects({
+      router: this.views.getRouter(),
+      action: () => this.views.load(this.vc),
+      destination: {
+        id: "organization.add",
+      },
+    });
+  }
+
+  @test()
+  @seed("organization", 1)
+  protected static async doesNotRedirectWhenCurrentOrg() {
+    const organization = await this.fakedOrganizations[0]
+
+    //this is optional, the current org defaults to the newest added
+    //this.views.getScope().setCurrentOrganization(organization.id)
+
+    await vcAssert.assertActionDidNotRedirect({
+      router: this.views.getRouter(),
+      action: () => this.views.load(this.vc),
+    });
+
+    assert.isEqualDeep(this.vc.currentOrg, organization);
+  }
+
+  @test()
+  @seed("organizations", 3)
+  protected static async usesOrgFromScope() {
+    // since scope loads the newest org by default, we can set
+    // it back to the first org to test our productions code
+    const [organizations] = await this.fakedOrganizations
+
+    this.views.getScope().setCurrentOrganization(organization.id);
+
+    let wasHit = false;
+
+    await this.views.load(this.vc);
+
+    assert.isEqualDeep(this.vc.currentOrg, organization);
+  }
+}
+
+//production
+class RootSkillviewController extends AbstractSkillViewController {
+  public async load(options: SkillViewControllerLoadOptions) {
+    const organization = await options.scope.getCurrentOrganization();
+
+    if (!organization) {
+      await options.router.redirect("organization.add" as any);
+      return;
+    }
+
+    this.currentOrganization = organization;
+    this.profileCardVc.setRouter(options.router);
+    this.profileCardVc.setIsBusy(false);
+  }
+}
+
+

Testing Stats #

+
//test
+@login()
+export default class RootSkillViewControllerTest extends AbstractSpruceFixtureTest {
+  @test()
+  protected static rendersStats() {
+    vcAssert.assertRendersStats(this.vc.getCardVc());
+  }
+
+  @test()
+  @seed("organization", 1)
+  protected static async rendersExpectedStatsAfterLoad() {
+    await this.bootAndLoad();
+  }
+
+  private static async bootAndLoad() {
+    await this.bootSkill();
+    await this.views.load(this.vc);
+  }
+}
+
+//production
+class RootSkillViewController extends AbstractSkillViewController {
+  public constructor(options: ViewControllerOptions) {
+    super(options);
+
+    this.cardVc = this.CardVc();
+  }
+
+  public async load(options: SkillViewControllerLoadOptions) {}
+}
+
+

Testing forms #

+

It is important that you test the graceful handling of failed requests on save. Use the eventMocker to make events throw so you can gracefully handle them!

+
//test
+@login()
+export default class RootSkillViewControllerTest extends AbstractSpruceFixtureTest {
+
+    @test()
+    protected static async showsErrorWhenSavingFails() {
+
+        await eventMocker.makeEventThrow('create-organization::v2020_01_01')
+
+        const formVc = this.vc.getFormVc()
+        formVc.setValues({...})
+
+        await vcAssert.assertRenderAlert(this.vc, () => interactor.submitForm(formVc))
+    }
+
+
+    @test()
+    protected static async savesOrgWhenSubmittingForm() {
+        const formVc = this.vc.getFormVc()
+        await formVc.setValues({...})
+        await vcAssert.assertRendersSuccessAlert(this.vc, () => interactor.subimForm(formVc))
+
+        ...
+    }
+}
+
+//production
+class RootSkillviewController extends AbstractSkillViewController {
+    public constructor(options: SkillViewControllerOptions) {
+        super(options)
+        this.formVc = this.FormVc()
+    }
+
+    private FormVc() {
+        return this.views.Controller('form', buildForm({
+            ...,
+            onSubmit: this.handleSubmit.bind(this)
+        }))
+    }
+
+    private async handleSubmit() {
+        const values = this.formVc.getValues()
+
+        try {
+            const client = await this.connectToApi()
+            await client.emitAndFlattenResponses('create-organization::v2020_01_01', {
+                payload: values
+            })
+
+            await this.alert({ message: 'You did it!!', style: 'success' })
+
+        } catch (err: any) {
+            await this.alert({ message: err.message })
+        }
+    }
+}
+
+

Testing toolbelt #

+
//test
+export default class RootSkillViewControllerTest extends AbstractSpruceFixtureTest {
+    @test()
+    protected static rendersToolBelt() {
+        tt.assertDoesNotRenderToolBelt(this.vc)
+
+        await this.views.load(this.vc)
+
+        const toolBeltVc = vcAssert.assertRendersToolBelt(this.vc)
+        const toolVc = vcAssert.assertToolBeltRendersTool(this.vc, 'edit')
+
+        assert.isTruthy(toolVc, 'Your ToolBelt does not render a tool with a properly rendered CardVc.')
+   
+    }
+
+  @test()
+    protected static async addsTitleSubTitleCard() {
+    // check if a tool is an instance of a specific Class
+        const toolVc = vcAssert.assertToolInstanceOf(
+            this.toolBeltVc,
+            'title',
+            EventTitleCardViewController
+        )
+
+    // check if tool is accessible off the parent view controller
+        assert.isEqual(toolVc, this.vc.getTitleCardVc())
+    }
+  
+}
+
+//production
+class RootSkillviewController extends AbstractSkillViewController {
+    public constructor(options: SkillViewControllerOptions) {
+        super(options)
+
+        this.toolBeltVc = this.ToolBelt()
+    }
+
+    private ToolBelt() {
+        return this.views.Controller('toolBelt', {
+            ...,
+        })
+    }
+
+    public async load(options: SkillViewControllerLoadOptions) {
+        this.toolBeltVc.addTool({
+            id: 'edit',
+            lineIcon: 'globe',
+            card: this.views.Controller('card', { ... })
+        })
+    }
+
+    public renderToolBelt() {
+        return this.toolBeltVc.render()
+    }
+}
+
+

Testing redirects #

+
//test
+export default class RootSkillViewControllerTest extends AbstractSpruceFixtureTest {
+    @test()
+    protected static redirectsOnSelectLocation() {
+        const locationsCardVc = this.vc.getLocationsCardVc()
+        const location = await this.views.getScope().getCurrentLocation()
+
+        await vcAssert.assertActionRedirects({
+            router: this.views.getRouter(),
+            action: () =>
+                interactor.clickButtonInRow(
+                    locationsCardVc.getListVc(),
+                    location.id,
+                    'edit'
+                ),
+            destination: {
+                id: 'locations.root',
+                args: {
+                    locationId: location.id,
+                },
+            },
+        })
+    }
+}
+
+//production
+class RootSkillviewController extends AbstractSkillViewController {
+    public constructor(options: SkillViewControllerOptions) {
+        super(options)
+        this.locationsCardVc = this.ActiveRecordCardVc()
+    }
+
+    public async load(options: SkillViewControllerLoadOptions) {
+        this.router = options.router
+        await this.locationsCardVc.load()
+    }
+
+    private activeRecordCardVc() {
+        return this.views.Controller('activeRecordCard', buildActiveRecordCard({
+            ...,
+            rowTransformer: (location) => ({
+                id: location.id
+                cells: [
+                    {
+                        text: {
+                            content: location.name
+                        },
+                    },
+                    {
+                        button: {
+                            id: 'edit',
+                            onClick: async () => {
+                                await this.router?.redirect('locations.root', {
+                                    locationId: location.id
+                                })
+                            }
+                        }
+                    }
+                ]
+            })
+        }))
+    }
+
+    public getLocationsCardVc() {
+        return this.locationsCardVc
+    }
+}
+
+

Authentication #

+

Using @fake.login(), you can simulate a client for API requests, which is useful for testing authentication-related scenarios.

+

Optimizing Source #

+

To inspect your bundled view controller source, set the VIEW_PROFILER_STATS_DESTINATION_DIR in your skill’s environment. This will output a file that can be analyzed to see what is included in your bundle.

+

Test Hints #

+

The document ends with practical hints for testing, such as looking at existing skills, using spruce watch.views for a real-time feedback loop, and checking out vcAssert.test.ts in heartwood-view-controllers for examples.

+

Use Case #

+ +
+
+
+ + + + +
+ + diff --git a/_site/docs/create-edit-content-types/index.html b/_site/docs/create-edit-content-types/index.html new file mode 100644 index 00000000..87844300 --- /dev/null +++ b/_site/docs/create-edit-content-types/index.html @@ -0,0 +1,107 @@ + + + + Create and edit content types? + + + + + +
+
+ + Lumena Labs + +
+ + + + +
+ +
+ +
+
+
+

+ Content Types +

+

+ Create and edit content types? +

+
+ + + + + +
+

Content here

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Katas + +
+
+ + + +
+
+ Next +
+ +
+ + How does Spinal work? + +
+
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/default/index.html b/_site/docs/default/index.html new file mode 100644 index 00000000..6bb19ecd --- /dev/null +++ b/_site/docs/default/index.html @@ -0,0 +1,211 @@ + + + + LumenaLabs + + + + + + +
+
+ + Lumena Labs + +
+ +
+ + + + + + +
+ + +
+ + +
+ + + + + + +
+
+
+

+ +

+ +

+ +

+
+ + + + + + + +
+ +
+ +

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + + +
+ + + + + +
+ + + +
+
+ + diff --git a/_site/docs/dev/Kata/kata-1/index.html b/_site/docs/dev/Kata/kata-1/index.html new file mode 100644 index 00000000..790eb1da --- /dev/null +++ b/_site/docs/dev/Kata/kata-1/index.html @@ -0,0 +1,271 @@ + + + + Kata 1 + + + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + + + +
+
+
+

+ Learn +

+

+ Kata 1 +

+
+ + + + + + + + + +
+

Content here

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Ideology + +
+
+ + + +
+
+ Next +
+ +
+ + Kata 2 + +
+
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/dev/Kata/kata-2/index.html b/_site/docs/dev/Kata/kata-2/index.html new file mode 100644 index 00000000..493a5b33 --- /dev/null +++ b/_site/docs/dev/Kata/kata-2/index.html @@ -0,0 +1,271 @@ + + + + Kata 2 + + + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + + + +
+
+
+

+ Learn +

+

+ Kata 2 +

+
+ + + + + + + + + +
+

Content here. You can use markdown.

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Kata 1 + +
+
+ + + +
+
+ Next +
+ +
+ + Kata 3 + +
+
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/dev/Kata/kata-3/index.html b/_site/docs/dev/Kata/kata-3/index.html new file mode 100644 index 00000000..0f510564 --- /dev/null +++ b/_site/docs/dev/Kata/kata-3/index.html @@ -0,0 +1,271 @@ + + + + Kata 3 + + + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + + + +
+
+
+

+ Learn +

+

+ Kata 3 +

+
+ + + + + + + + + +
+

katas

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Kata 2 + +
+
+ + + +
+
+ Next +
+ +
+ + beebooo + +
+
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/dev/Kata/kata-4/index.html b/_site/docs/dev/Kata/kata-4/index.html new file mode 100644 index 00000000..1c317533 --- /dev/null +++ b/_site/docs/dev/Kata/kata-4/index.html @@ -0,0 +1,259 @@ + + + + Kata 4 + + + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + + + +
+
+
+

+ Learn +

+

+ Kata 4 +

+
+ + + + + + + + + +
+

katas

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + beebooo + +
+
+ + + +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/dev/Overview/index.html b/_site/docs/dev/Overview/index.html new file mode 100644 index 00000000..709f2483 --- /dev/null +++ b/_site/docs/dev/Overview/index.html @@ -0,0 +1,215 @@ + + + + Lumena Labs + + + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + + + +
+
+
+

+ +

+
+ +

+ This is the Concepts Homepage +

+ + + + + + +
+ [Screenshot Image] +
+ +
+

+ Video walkthrough +

+ +

+ Watch this 5 minutes video-walkthrough of Katas. You quickly learn how to set up your dashboard, invite team members, set permissions and how to schedule and publish content. +

+
+
+ + + + + + +

+ Navigate through the Katas +

+ + + + + + +
+ +
+
+ + diff --git a/_site/docs/dev/Overview/overview/index.html b/_site/docs/dev/Overview/overview/index.html new file mode 100644 index 00000000..b1b73940 --- /dev/null +++ b/_site/docs/dev/Overview/overview/index.html @@ -0,0 +1,43 @@ + + + + Lumena Labs + + + + + + + + + +
+ + + + +
+
+
+

+ +

+
+ + + + + + + + + + + +
+ +
+
+ + diff --git a/_site/docs/dev/build/index.html b/_site/docs/dev/build/index.html new file mode 100644 index 00000000..f8f7fe2d --- /dev/null +++ b/_site/docs/dev/build/index.html @@ -0,0 +1,312 @@ + + + + Building Root Skill View + + + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + +
+
+
+

+ Building Root Skill View +

+
+ +

+ In this section of the guide, you will learn how to build skill views and implement dynamic routing. +

+ + + + + + +
+ +
+ +
+

+ Video walkthrough +

+ +

+ Watch this 5 minutes video-walkthrough of Katas. You quickly learn how to set up your dashboard, invite team members, set permissions and how to schedule and publish content. +

+
+
+ + + + + + + + + +
+

Guide: Building a RootSkillView #

+

Setup Tests and IDE #

+

Introduction: #

+
    +
  • Utilize dual screens for efficiency, coding on one and testing on the other.
  • +
  • Tests are integrated into the VS Code environment.
  • +
+

Start a New Skill #

+
    +
  • Create a skill space with spruce .create The example skill is “Eight-bit stories”.
  • +
+
# Replace with the actual command to start a new skill
+
+

Installing Dependencies: #

+
    +
  • Install all necessary dependencies for the project.
  • +
+
# Replace with the actual command to install dependencies
+
+

Write Your First Failing Test in RootSkillView.tests.ts #

+

Setting up the IDE: #

+
    +
  • Run spruce in the terminal and install prompted extensions.
  • +
  • Configure VS Code to run tasks automatically.
  • +
+
# Replace with the actual commands to set up the IDE
+
+

Creating the First Test: #

+
    +
  • Create a new behavioral test named “RootSkillView”.
  • +
  • Extend the test using the “abstract spruce fixture test”.
  • +
+
 # Replace with the actual code snippet for creating a new test
+
+

Create a RootSkillView to Make the Test Pass #

+

Setup Remote: #

+
    +
  • Configure the remote environment for testing with spruce set.remotes
  • +
  • Install required concepts like schema, permission, and events.
  • +
+
# Replace with the actual commands to setup remote and install features
+
+

Create the Root View Controller: #

+
    +
  • Create the view controller using the provided Spruce command.
  • +
+
# Replace with the actual command to create the view controller
+
+
    +
  • After creating the root view controller, update the test and package.json with the new view controller name.
  • +
+

Enhancing the Skill and Adding Functionality #

+

Implementing the Card and Buttons #

+

Create a Card #

+
    +
  • Begin by creating a card component with an image and buttons.
  • +
+
# Replace with the actual code snippet for creating a card component
+
+

Efficient Test Setup #

+
    +
  • Use beforeEach hooks for setting up tests.
  • +
  • Write an assertion to check the card’s rendering.
  • +
+
# Replace with the actual code snippet for beforeEach hook and assertion
+
+
+

Dynamic Rendering of the Card #

+
    +
  • Assign an ID to the card and update tests accordingly.
  • +
+
# Replace with the actual code snippet for dynamic card rendering
+
+

Testing Button Rendering #

+

Verify Button Existence #

+
    +
  • Test for the existence of “Meta,” “Members,” and “Generate” buttons.
  • +
+
# Replace with the actual code snippet for button existence test
+
+

Button Implementation #

+
    +
  • Implement the buttons within the card’s body.
  • +
+
# Replace with the actual code snippet for button implementation
+
+

Refactoring for Encapsulation and Maintainability #

+

Restrict Direct Access #

+
    +
  • Change the visibility of cardVC to protected.
  • +
+
# Replace with the actual code snippet for changing visibility
+
+

Safe Access Through Getters #

+
    +
  • Introduce a getter method for cardVC.
  • +
+
# Replace with the actual code snippet for getter method
+
+

Type Safety and Casting #

+
    +
  • Ensure type safety through casting and typing adjustments.
  • +
+
# Replace with the actual code snippet for type safety and casting
+
+
+

Section Protect Tests from Implementation Changes #

+
    +
  • Design tests to remain valid despite changes in implementation.
  • +
+

Elaborate

+

Set up RootSkillView and Test it on One Device, Create MetaPage #

+

Set up RootSkillView and Test it on One Device #

+
    +
  • Start watch.views to sync code with tests.
  • +
  • Preview and test the RootSkillView on a device.
  • +
+

Create MetaPage #

+
    +
  • Register the skill with a unique namespace using Spruce Command.
  • +
  • Boot the skill and handle login requirements.
  • +
  • Create tests for MetaSkillView redirections.
  • +
  • Develop MetaSkillView with buttons and actions.
  • +
  • Write tests for button interactions and expected redirects.
  • +
  • Refactor code for readability and efficiency.
  • +
+ +
+
+
+ + + + +
+ + diff --git a/_site/docs/dev/f/index.html b/_site/docs/dev/f/index.html new file mode 100644 index 00000000..8647b9a4 --- /dev/null +++ b/_site/docs/dev/f/index.html @@ -0,0 +1,236 @@ + + + + Lumena Labs + + + + + + + + + +
+ + + + + +
+
+
+

+ +

+
+ + + + + + + + + + + + +
+

Create a RootSkillView to Make the Test Pass #

+

Setup Remote: #

+
    +
  • Configure the remote environment for testing with spruce set.remotes
  • +
  • Install required concepts like schema, permission, and events.
  • +
+
# Replace with the actual commands to setup remote and install features
+
+

Create the Root View Controller: #

+
    +
  • Create the view controller using the provided Spruce command.
  • +
+
# Replace with the actual command to create the view controller
+
+
    +
  • After creating the root view controller, update the test and package.json with the new view controller name.
  • +
+

Enhancing the Skill and Adding Functionality #

+

Implementing the Card and Buttons #

+

Create a Card #

+
    +
  • Begin by creating a card component with an image and buttons.
  • +
+
# Replace with the actual code snippet for creating a card component
+
+

Efficient Test Setup #

+
    +
  • Use beforeEach hooks for setting up tests.
  • +
  • Write an assertion to check the card’s rendering.
  • +
+
# Replace with the actual code snippet for beforeEach hook and assertion
+
+
+

Dynamic Rendering of the Card #

+
    +
  • Assign an ID to the card and update tests accordingly.
  • +
+
# Replace with the actual code snippet for dynamic card rendering
+
+

Testing Button Rendering #

+

Verify Button Existence #

+
    +
  • Test for the existence of “Meta,” “Members,” and “Generate” buttons.
  • +
+
# Replace with the actual code snippet for button existence test
+
+

Button Implementation #

+
    +
  • Implement the buttons within the card’s body.
  • +
+
# Replace with the actual code snippet for button implementation
+
+

Refactoring for Encapsulation and Maintainability #

+

Restrict Direct Access #

+
    +
  • Change the visibility of cardVC to protected.
  • +
+
# Replace with the actual code snippet for changing visibility
+
+

Safe Access Through Getters #

+
    +
  • Introduce a getter method for cardVC.
  • +
+
# Replace with the actual code snippet for getter method
+
+

Type Safety and Casting #

+
    +
  • Ensure type safety through casting and typing adjustments.
  • +
+
# Replace with the actual code snippet for type safety and casting
+
+
+

Section Protect Tests from Implementation Changes #

+
    +
  • Design tests to remain valid despite changes in implementation.
  • +
+

Elaborate

+

Set up RootSkillView and Test it on One Device, Create MetaPage #

+

Set up RootSkillView and Test it on One Device #

+
    +
  • Start watch.views to sync code with tests.
  • +
  • Preview and test the RootSkillView on a device.
  • +
+

Create MetaPage #

+
    +
  • Register the skill with a unique namespace using Spruce Command.
  • +
  • Boot the skill and handle login requirements.
  • +
  • Create tests for MetaSkillView redirections.
  • +
  • Develop MetaSkillView with buttons and actions.
  • +
  • Write tests for button interactions and expected redirects.
  • +
  • Refactor code for readability and efficiency.
  • +
+

Certainly! Based on the format and content you’ve provided, here is a continuation of the guide:

+
+

Understood. Let’s create an exhaustive guide that mirrors the step-by-step process detailed in the 47-minute video transcript. This guide will include each action, decision point, and explanation provided in the video, offering a user a comprehensive set of instructions that leave no detail out. Code snippet and command placeholders will be clearly marked for you to complete with the specific technical content.

+
+

Title: Building a Root Skill View - Comprehensive Instructional Guide

+

Introduction:
+This guide is a thorough instruction manual for building a root skill view. It follows a detailed transcript, ensuring users can execute each step without additional resources.

+
+

Initial Setup #

+

Docker Configuration for NPM Caching:

+
    +
  • Run the command to start Docker NPM caching.
    spruce start.cache
    +
    +
  • +
+

Creating the Skill Space:

+
    +
  • Use the following command to create a new skill, replacing (skillname) with your desired name (not starting with a number).
    spruce create.skill (skillname)
    +
    +
  • +
  • Follow the CLI prompts to name and describe your skill, allowing dependencies to install.
  • +
+

Preparing the Development Environment:

+
    +
  • Navigate to your skill directory in Visual Studio Code:
    cd (skillname) && code .
    +
    +
  • +
  • Set up your IDE for development:
    spruce setup.vscode
    +
    +
  • +
  • Enable automatic tasks and reload the IDE to initiate the test environment setup.
  • +
+

Test-Driven Development Initialization #

+

Start Test Monitoring (WatchMode):

+
    +
  • In your terminal, start WatchMode to monitor your test suite:
    spruce test --watchMode smart
    +
    +
  • +
+

Create the First Behavioral Test:

+
    +
  • In Visual Studio Code, open the command palette and run:
    create.test
    +
    +
  • +
  • Choose ‘Behavioural’ tests and specify what you are testing in camel case.
  • +
  • Add the code snippet to create a new behavioral test named “RootSkillView” here: [Behavioral test code snippet]
  • +
+

Skill View Development Steps #

+

Building the Root Skill View:

+
    +
  • Begin constructing your root skill view with the following command:
    spruce create.view
    +
    +
  • +
  • Select ‘Skill View Controller’ and name it ‘root’.
  • +
+

Implementing the Root Skill View Logic:

+
    +
  • Add the implementation for UI elements in the RootSkillViewController here: [UI elements implementation code snippet]
  • +
  • Define UI component behaviors and error handling strategies here: [UI behavior and error handling code snippet]
  • +
+

Continuous Testing and Refinement #

+

Testing the UI Components:

+
    +
  • Create test cases for UI rendering:
    // Example test case for rendering a card
    +it('renders a card', () => {
    +  const card = rootSkillViewController.renderCard();
    +  assert(card).toBeVisible();
    +});
    +
    +
  • +
  • Continually run tests for immediate feedback on changes.
  • +
+

Advanced Features and Dynamic Routing #

+

Implementing Dynamic Routing:

+
    +
  • Define and test navigation routes within your skill view here: [Navigation routes definition and testing code snippet]
  • +
  • Implement routing logic functions like redirectToMetaView and ensure they work as intended.
  • +
+

Final Steps: Device Testing and Preview #

+

Previewing on a Device:

+
    +
  • Preview your skill view on a device to test its UX and UI.
  • +
  • Adjust and refine the UI based on device feedback and ensure cross-device compatibility.
  • +
+
+

By following this guide, you will execute a complete setup, develop a root skill view using TDD, and ensure your skill works seamlessly across devices. Each placeholder marks where detailed technical input is required, making the guide a comprehensive walkthrough from start to finish.

+ +
+
+
+ + + + +
+ + diff --git a/_site/docs/dev/getting_started/dev/index.html b/_site/docs/dev/getting_started/dev/index.html new file mode 100644 index 00000000..978cf7c3 --- /dev/null +++ b/_site/docs/dev/getting_started/dev/index.html @@ -0,0 +1,204 @@ + + + + Home + + + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + + + +
+
+
+

+ Home +

+
+ +

+ This is the Katas Homepage +

+ + + + + + +
+ [Screenshot Image] +
+ +
+

+ Video walkthrough +

+ +

+ Watch this 5 minutes video-walkthrough of Katas. You quickly learn how to set up your dashboard, invite team members, set permissions and how to schedule and publish content. +

+
+
+ + + + + + +

+ Navigate through the Katas +

+ + + + + + +
+

Enter Content Here

+ +
+
+ + diff --git a/_site/docs/dev/getting_started/index.html b/_site/docs/dev/getting_started/index.html new file mode 100644 index 00000000..b1b73940 --- /dev/null +++ b/_site/docs/dev/getting_started/index.html @@ -0,0 +1,43 @@ + + + + Lumena Labs + + + + + + + + + +
+ + + + +
+
+
+

+ +

+
+ + + + + + + + + + + +
+ +
+
+ + diff --git a/_site/docs/dev/getting_started/overview/index.html b/_site/docs/dev/getting_started/overview/index.html new file mode 100644 index 00000000..12671547 --- /dev/null +++ b/_site/docs/dev/getting_started/overview/index.html @@ -0,0 +1,44 @@ + + + + Overview + + + + + + + + + +
+ + + + +
+
+
+

+ Overview +

+
+ + + + + + + + + + + +
+

Content specific to this subsection.

+ +
+
+ + diff --git a/_site/docs/dev/index.html b/_site/docs/dev/index.html new file mode 100644 index 00000000..51fa5f0b --- /dev/null +++ b/_site/docs/dev/index.html @@ -0,0 +1,263 @@ + + + + Getting Started + + + + + + + + + +
+
+ + Site Logo + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + +
+ +
+ + + + +
+ + diff --git a/_site/docs/dev/kata-1/index.html b/_site/docs/dev/kata-1/index.html new file mode 100644 index 00000000..b70a0370 --- /dev/null +++ b/_site/docs/dev/kata-1/index.html @@ -0,0 +1,215 @@ + + + + Kata 1 + + + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + + + +
+
+
+

+ Kata 1 +

+
+ +

+ This is the Kata Homepage +

+ + + + + + +
+ [Screenshot Image] +
+ +
+

+ Video walkthrough +

+ +

+ Watch this 5 minutes video-walkthrough of Katas. You quickly learn how to set up your dashboard, invite team members, set permissions and how to schedule and publish content. +

+
+
+ + + + + + +

+ Navigate through the Katas +

+ + + + + + +
+ +
+
+ + diff --git a/_site/docs/dev/kata-2/index.html b/_site/docs/dev/kata-2/index.html new file mode 100644 index 00000000..cf4c96d9 --- /dev/null +++ b/_site/docs/dev/kata-2/index.html @@ -0,0 +1,271 @@ + + + + Kata 2 + + + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + + + +
+
+
+

+ Learn +

+

+ Kata 2 +

+
+ + + + + + + + + +
+

Content here. You can use markdown.

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Kata 1 + +
+
+ + + +
+
+ Next +
+ +
+ + Kata 3 + +
+
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/dev/kata-3 copy/index.html b/_site/docs/dev/kata-3 copy/index.html new file mode 100644 index 00000000..a20626b2 --- /dev/null +++ b/_site/docs/dev/kata-3 copy/index.html @@ -0,0 +1,200 @@ + + + + Kata 3 + + + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Concepts + + + Ideology + + + Developer Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + + + +
+
+
+

+ Katas +

+

+ Kata 3 +

+
+ + + + + + + + + +
+

katas

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Katas + +
+
+ + + +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/dev/kata-3/index.html b/_site/docs/dev/kata-3/index.html new file mode 100644 index 00000000..f8c3b0d8 --- /dev/null +++ b/_site/docs/dev/kata-3/index.html @@ -0,0 +1,271 @@ + + + + Kata 3 + + + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + + + +
+
+
+

+ Learn +

+

+ Kata 3 +

+
+ + + + + + + + + +
+

katas

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Kata 2 + +
+
+ + + +
+
+ Next +
+ +
+ + beebooo + +
+
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/dev/kata-4/index.html b/_site/docs/dev/kata-4/index.html new file mode 100644 index 00000000..7a87f80f --- /dev/null +++ b/_site/docs/dev/kata-4/index.html @@ -0,0 +1,259 @@ + + + + Kata 4 + + + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + + + +
+
+
+

+ Learn +

+

+ Kata 4 +

+
+ + + + + + + + + +
+

katas

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + beebooo + +
+
+ + + +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/dev/learn/index.html b/_site/docs/dev/learn/index.html new file mode 100644 index 00000000..3f56170b --- /dev/null +++ b/_site/docs/dev/learn/index.html @@ -0,0 +1,215 @@ + + + + Building Root Skill View + + + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + + + +
+
+
+

+ Building Root Skill View +

+
+ +

+ This is the Concepts Homepage +

+ + + + + + +
+ [Screenshot Image] +
+ +
+

+ Video walkthrough +

+ +

+ Watch this 5 minutes video-walkthrough of Katas. You quickly learn how to set up your dashboard, invite team members, set permissions and how to schedule and publish content. +

+
+
+ + + + + + +

+ Navigate through the Katas +

+ + + + + + +
+ +
+
+ + diff --git a/_site/docs/dev/learn/kata/kata-1/index.html b/_site/docs/dev/learn/kata/kata-1/index.html new file mode 100644 index 00000000..a5b5658e --- /dev/null +++ b/_site/docs/dev/learn/kata/kata-1/index.html @@ -0,0 +1,160 @@ + + + + Kata 1 + + + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + + + +
+
+
+

+ Kata 1 +

+
+ + + + + + + + + + + +
+

Content here

+ +
+
+ + diff --git a/_site/docs/dev/learn/kata/kata-2/index.html b/_site/docs/dev/learn/kata/kata-2/index.html new file mode 100644 index 00000000..98ef668b --- /dev/null +++ b/_site/docs/dev/learn/kata/kata-2/index.html @@ -0,0 +1,160 @@ + + + + Kata 2 + + + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + + + +
+
+
+

+ Kata 2 +

+
+ + + + + + + + + + + +
+

Content here. You can use markdown.

+ +
+
+ + diff --git a/_site/docs/dev/learn/kata/kata-3/index.html b/_site/docs/dev/learn/kata/kata-3/index.html new file mode 100644 index 00000000..42d2c74e --- /dev/null +++ b/_site/docs/dev/learn/kata/kata-3/index.html @@ -0,0 +1,160 @@ + + + + Kata 3 + + + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + + + +
+
+
+

+ Kata 3 +

+
+ + + + + + + + + + + +
+

katas

+ +
+
+ + diff --git a/_site/docs/dev/learn/kata/kata-4/index.html b/_site/docs/dev/learn/kata/kata-4/index.html new file mode 100644 index 00000000..9ae93cf2 --- /dev/null +++ b/_site/docs/dev/learn/kata/kata-4/index.html @@ -0,0 +1,160 @@ + + + + Kata 4 + + + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + + + +
+
+
+

+ Kata 4 +

+
+ + + + + + + + + + + +
+

katas

+ +
+
+ + diff --git a/_site/docs/dev/learn/katas/kata-1/index.html b/_site/docs/dev/learn/katas/kata-1/index.html new file mode 100644 index 00000000..c0ed6da4 --- /dev/null +++ b/_site/docs/dev/learn/katas/kata-1/index.html @@ -0,0 +1,158 @@ + + + + Kata 1 + + + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + + + +
+
+
+

+ Kata 1 +

+
+ + + + + + + + + + + +
+

Content here

+ +
+
+ + diff --git a/_site/docs/dev/learn/katas/kata-2/index.html b/_site/docs/dev/learn/katas/kata-2/index.html new file mode 100644 index 00000000..b5ab24fb --- /dev/null +++ b/_site/docs/dev/learn/katas/kata-2/index.html @@ -0,0 +1,108 @@ + + + + Kata 2 + + + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + + + +
+
+
+

+ Kata 2 +

+
+ + + + + + + + + + + +
+

Content here. You can use markdown.

+ +
+
+ + diff --git a/_site/docs/dev/learn/katas/kata-3/index.html b/_site/docs/dev/learn/katas/kata-3/index.html new file mode 100644 index 00000000..d5d5ba9f --- /dev/null +++ b/_site/docs/dev/learn/katas/kata-3/index.html @@ -0,0 +1,108 @@ + + + + Kata 3 + + + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + + + +
+
+
+

+ Kata 3 +

+
+ + + + + + + + + + + +
+

katas

+ +
+
+ + diff --git a/_site/docs/dev/learn/katas/kata-4/index.html b/_site/docs/dev/learn/katas/kata-4/index.html new file mode 100644 index 00000000..afc085a5 --- /dev/null +++ b/_site/docs/dev/learn/katas/kata-4/index.html @@ -0,0 +1,108 @@ + + + + Kata 4 + + + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + + + +
+
+
+

+ Kata 4 +

+
+ + + + + + + + + + + +
+

katas

+ +
+
+ + diff --git a/_site/docs/dev/metadata/index.html b/_site/docs/dev/metadata/index.html new file mode 100644 index 00000000..2daa05fb --- /dev/null +++ b/_site/docs/dev/metadata/index.html @@ -0,0 +1,359 @@ + + + + Managing your Family's Metadata + + + + + + + + + +
+
+ + Site Logo + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + +
+
+
+

+ Managing your Family's Metadata +

+
+ +

+ In this section of the guide, you will learn how to manage your metadata. +

+ + + + + + +
+ +
+ +
+

+ Video walkthrough +

+ +

+ Watch this video-walkthrough of Katas. +

+
+
+ + + + + + + + + +
+

Overview #

+

Welcome to our step-by-step guide on managing metadata! Today, we’re going on an exciting journey to build a dynamic system for handling metadata. This guide will walk you through every step with clear explanations and practical examples. Let’s dive in!

+

Setting the Stage: Render Basic Form #

+

First things first, let’s create a form to collect metadata. Imagine this form as the gateway through which users will input their data.

+
    +
  1. +

    Layout Design:

    +
      +
    • Sketch a simple yet intuitive form layout.
    • +
    • Think about the user experience. What information are we collecting? How can we make it easy and logical for the user to input data?
    • +
    • Placeholder for layout design code.
    • +
    +
    (add layout design code here)
    +
    +
  2. +
  3. +

    Implementing Validation:

    +
      +
    • Now, let’s ensure our form makes sense. We don’t want users entering their names in date fields, right?
    • +
    • Write some front-end validation rules.
    • +
    • Placeholder for validation rules.
    • +
    +
  4. +
+
(add validation code here)
+
+
    +
  1. +

    Data Binding:

    +
      +
    • Time to make our form functional. Let’s bind our form fields to a data model so that when a user types in something, it gets stored correctly.
    • +
    • Placeholder for data binding implementation.
    • +
    +
    (add data binding code here)
    +
    +
  2. +
+

Structuring Our Data: Use Schemas to Define Forms #

+

With our form ready, let’s define how our data should look and behave using schemas.

+
    +
  1. +

    Define a Schema:

    +
      +
    • Think of a schema as a rule book for your data.
    • +
    • Let’s define what fields we need and the type of data each field should hold.
    • +
    • Placeholder for schema definition.
    • +
    +
    (add schema definition code here)
    +
    +
  2. +
  3. +

    Linking Schema to Form:

    +
      +
    • Now, integrate this schema with our form. This ensures that the data entered matches our expectations.
    • +
    • Placeholder for schema-form integration.
    • +
    +
    (add integration code here)
    +
    +
  4. +
  5. +

    Evolving the Schema:

    +
      +
    • Our needs might change, and so might our data. Let’s write code to update our schema as required.
    • +
    • Placeholder for schema update.
    • +
    +
       (add schema update code here)
    +
    +
  6. +
+

Communication is Key: Emit and Listen to Events #

+

Our form and schema are set. Let’s now focus on making them communicate with the backend.

+
    +
  1. +

    Setting Up Event Emitters:

    +
      +
    • When a user submits the form, an event will be emitted. This is our way of sending data from the frontend to the backend.
    • +
    • Placeholder for setting up event emitters.
    • +
    +
    (add event emitter code here)
    +
    +
  2. +
  3. +

    Processing Events with Listeners:

    +
      +
    • The backend needs to listen to these events and know what to do with them.
    • +
    • Placeholder for setting up event listeners.
    • +
    +
    (add event listener code here)
    +
    +
  4. +
+

Access Control: Building Permissions Contracts #

+

We must ensure only the right people have access to the right data.

+
    +
  1. +

    Defining User Roles:

    +
      +
    • Let’s define different user roles and what each role can or cannot do.
    • +
    • Placeholder for defining user roles.
    • +
    +
    (add roles definition code here)
    +
    +
  2. +
  3. +

    Implementing Permission Checks:

    +
      +
    • With roles defined, we now write code to check if a user has the necessary permissions to perform an action.
    • +
    • Placeholder for permission checks.
    • +
    +
    (add permission check code here)
    +
    +
  4. +
+

Data Persistence: Using Data Stores #

+

Finally, we need to store our data so that it’s not lost when the app closes.

+
    +
  1. +

    Choosing a Data Store:

    +
      +
    • Based on our needs, let’s choose a suitable place to store our data. This could be a database or any other form of persistent storage.
    • +
    • Placeholder for rationale behind data store selection.
    • +
    +
    (add rationale here)
    +
    +
  2. +
  3. +

    Saving Data:

    +
      +
    • Now, write the code to save data into our chosen data store.
    • +
    • Placeholder for data saving mechanism.
    • +
    +
    (add data saving code here)
    +
    +
  4. +
  5. +

    Retrieving Data:

    +
      +
    • Equally important is how we get this data back when we need it.
    • +
    • Placeholder for data retrieval method.
    • +
    +
    (add data retrieval code here)
    +
    +
  6. +
+

Wrapping Up #

+

Congratulations! You’ve just walked through the process of creating a system to manage metadata. Remember, the journey doesn’t end here. Keep experimenting, keep learning, and most importantly, have fun coding!

+ +
+
+
+ + + + +
+ + diff --git a/_site/docs/dev/rootskillview/index.html b/_site/docs/dev/rootskillview/index.html new file mode 100644 index 00000000..42818841 --- /dev/null +++ b/_site/docs/dev/rootskillview/index.html @@ -0,0 +1,300 @@ + + + + Building a Root Skill View + + + + + + + + + +
+
+ + Site Logo + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + +
+
+
+

+ Building a Root Skill View +

+
+ +

+ In this section of the guide, you will learn how to build skill views and implement dynamic routing. +

+ + + + + + +
+ +
+ +
+

+ Video walkthrough +

+ +

+ Watch this video-walkthrough of Katas. +

+
+
+ + + + + + + + + +
+

Set Up Testing Environment and IDE #

+

Start Docker for NPM Caching #

+

Run the command spruce start.cache

+

This initializes Docker to use aggressive caching for NPM packages, which improves the speed of dependency retrieval.

+

Begin a New Skill Project #

+

Create a new skill environment by typing spruce create.skill (yourSkillName). For example, our test skill is called

+

“kata-1”:

+
spruce create.skill kata-1
+
+

You’ll need to provide a name and description for your skill.

+

Note: Skill names can’t start with a number.

+

Next, the system will install various dependencies.

+

Access Your New Skill #

+

To open your skill in Visual Studio Code, type cd (yourSkillName) && code .. For instance:

+
cd kata-1 && code .
+
+

Inside Visual Studio Code, go to the terminal and run:

+
spruce setup.vscode
+
+

The terminal will guide you through finalizing the setup for debugging, building, testing, linting, and configuring watchers for starting Visual Studio Code.

+

When done, use the command palette to find Manage Automatic Tasks and select Allow Automatic Tasks.

+

Reopen the command palette and choose Reload Window.

+

This will start tasks that enable testing. The tests will run, spot any missing dependencies, and install them as needed.

+

Turn on WatchMode #

+

In your external terminal, type:

+
spruce test --watchMode smart
+
+

This command continuously runs tests you’re developing, and upon success, it starts the remaining tests. It’s recommended to keep this on during development.

+

Write Your First Failing Test #

+

Create a Test #

+

With WatchMode on, go back to Visual Studio Code and the command palette, and run create.test.
+You’ll choose between two types of testing:

+
    +
  1. Behavioural: To check the changes you make in the environment.
  2. +
  3. Implementation: To check the inner workings.
  4. +
+

We’ll focus on Behavioural tests due to the significant changes we’re implementing, especially when integrating with other services.

+

Select Behavioural tests, and you’ll be asked to specify what you’re testing, using camel case.

+
# Enter the actual commands for the IDE setup here
+
+

Drafting the First Test: #

+

Write a new behavioral test called “RootSkillView”.
+Base the test on the “abstract spruce fixture test”.

+
 # Enter the actual code snippet for creating a new test here
+
+

Develop Your Root Skill Interface #

+

After setting up the IDE and starting testing, the next step is to build the skill interfaces, starting with the root skill interface.

+

Create the Root Skill Interface #

+

Use the command spruce create.view to begin making your root skill interface.

+
spruce create.view
+
+

When asked, choose Skill View Controller for your controller type.

+

For the controller name, type root.

+

The command-line will handle file generation and setup for your root skill interface.

+

display the code structure here

+

Add Logic to Your Root Skill Interface #

+

In your RootSkillViewController, add basic UI elements like cards, buttons, and images.

+

enter code snippet for UI elements here

+

Describe the elements and how they interact, such as what happens when buttons are clicked.

+

enter code snippet for UI interactions and error handling here

+
// Example of button implementation
+handleButtonClick() {
+  // Response logic for button click
+}
+
+

Include error management and plan for when users deviate from the expected interaction path.

+

Test the Root Skill Interface #

+

Write a test to make sure the root skill interface is rendered correctly.

+

Use the assert library to check for the existence and proper display of all UI components.

+
// Testing card display example
+it('should show a card', () => {
+  const card = rootSkillViewController.renderCard();
+  assert(card).toBeVisible();
+});
+
+

Run your tests using spruce test in watch mode to continuously monitor for changes and mistakes.

+

Set Up Dynamic Routing #

+

Define routes in your skill interface to allow for smooth transitions between different views.

+

enter snippet for route definition and testing here

+

Create functions to manage the routes, like redirectToMetaView or returnToRootView.

+
// Example of a redirect function
+
+

Design tests to ensure your routing works correctly, particularly in handling user actions.

+

Preview on a Device #

+

Test the skill interface on an actual device to ensure the UI and navigation feel natural and responsive.

+

If possible, use emulation tools in your development environment to simulate different devices.

+

Adjust the UI based on device preview feedback.

+ +
+
+
+ + + + +
+ + diff --git a/_site/docs/dev/test/index.html b/_site/docs/dev/test/index.html new file mode 100644 index 00000000..aa13ece7 --- /dev/null +++ b/_site/docs/dev/test/index.html @@ -0,0 +1,211 @@ + + + + Managing your Faamily's Metadata + + + + + + + + + +
+
+ + Site Logo + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + +
+ +
+ + + + +
+ + diff --git a/_site/docs/developer-onboarding/index.html b/_site/docs/developer-onboarding/index.html new file mode 100644 index 00000000..8de26dcf --- /dev/null +++ b/_site/docs/developer-onboarding/index.html @@ -0,0 +1,236 @@ + + + + Katas + + + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Concepts + + + Ideology + + + Developer Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + + + +
+
+
+

+ Developer Onboarding +

+

+ Katas +

+
+ +

+ This is the Katas Homepage +

+ + + + + + +
+ [Screenshot Image] +
+ +
+

+ Video walkthrough +

+ +

+ Watch this 5 minutes video-walkthrough of Katas. You quickly learn how to set up your dashboard, invite team members, set permissions and how to schedule and publish content. +

+
+
+ + + + + + +

+ Navigate through the Katas +

+ + + + +
+

Enter Content Here

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Kata 3 + +
+
+ + + +
+
+ Next +
+ +
+ + Kata 3 + +
+
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/developer-onboarding/kata-1/index.html b/_site/docs/developer-onboarding/kata-1/index.html new file mode 100644 index 00000000..0bd146c5 --- /dev/null +++ b/_site/docs/developer-onboarding/kata-1/index.html @@ -0,0 +1,160 @@ + + + + Kata 1 + + + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Concepts + + + Ideology + + + Developer Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + + + +
+
+
+

+ Katas +

+

+ Kata 1 +

+
+ + + + + + + + + +
+

Content here

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Ideology + +
+
+ + + +
+
+ Next +
+ +
+ + Kata 2 + +
+
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/developer-onboarding/kata-2/index.html b/_site/docs/developer-onboarding/kata-2/index.html new file mode 100644 index 00000000..68168b7e --- /dev/null +++ b/_site/docs/developer-onboarding/kata-2/index.html @@ -0,0 +1,160 @@ + + + + Kata 2 + + + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Concepts + + + Ideology + + + Developer Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + + + +
+
+
+

+ Katas +

+

+ Kata 2 +

+
+ + + + + + + + + +
+

Content here. You can use markdown.

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Kata 1 + +
+
+ + + +
+
+ Next +
+ +
+ + Kata 3 + +
+
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/developer-onboarding/kata-3 copy/index.html b/_site/docs/developer-onboarding/kata-3 copy/index.html new file mode 100644 index 00000000..e8e4f8d6 --- /dev/null +++ b/_site/docs/developer-onboarding/kata-3 copy/index.html @@ -0,0 +1,148 @@ + + + + Kata 3 + + + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Concepts + + + Ideology + + + Developer Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + + + +
+
+
+

+ Katas +

+

+ Kata 3 +

+
+ + + + + + + + + +
+

katas

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Katas + +
+
+ + + +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/developer-onboarding/kata-3/index.html b/_site/docs/developer-onboarding/kata-3/index.html new file mode 100644 index 00000000..d72fdbb4 --- /dev/null +++ b/_site/docs/developer-onboarding/kata-3/index.html @@ -0,0 +1,160 @@ + + + + Kata 3 + + + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Concepts + + + Ideology + + + Developer Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + + + +
+
+
+

+ Katas +

+

+ Kata 3 +

+
+ + + + + + + + + +
+

katas

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Kata 2 + +
+
+ + + +
+
+ Next +
+ +
+ + Katas + +
+
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/developer-onboarding/kata-4/index.html b/_site/docs/developer-onboarding/kata-4/index.html new file mode 100644 index 00000000..e8e4f8d6 --- /dev/null +++ b/_site/docs/developer-onboarding/kata-4/index.html @@ -0,0 +1,148 @@ + + + + Kata 3 + + + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Concepts + + + Ideology + + + Developer Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + + + +
+
+
+

+ Katas +

+

+ Kata 3 +

+
+ + + + + + + + + +
+

katas

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Katas + +
+
+ + + +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/developer-onboarding/katas/index.html b/_site/docs/developer-onboarding/katas/index.html new file mode 100644 index 00000000..800d3099 --- /dev/null +++ b/_site/docs/developer-onboarding/katas/index.html @@ -0,0 +1,270 @@ + + + + Katas + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Concepts + + + Ideology + + + Developer Onboarding + +
+
+ + + + + + +
+
+ + + +
+ + + + + + + + + + +
+
+
+

+ Intro +

+

+ Katas +

+
+ +

+ This is the Katas Homepage +

+ + + + +
+ [Screenshot Image] +
+ +
+

+ Video walkthrough +

+ +

+ Watch this 5 minutes video-walkthrough of Concepts. You quickly learn how to set up your dashboard, invite team members, set permissions and how to schedule and publish content. +

+
+
+ + + + + + +

+ Navigate through the Concepts +

+ + + + + + +
+

Enter Content Here

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Kata 3 + +
+
+ + + +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/developerOnboarding/index.html b/_site/docs/developerOnboarding/index.html new file mode 100644 index 00000000..24ee2ff5 --- /dev/null +++ b/_site/docs/developerOnboarding/index.html @@ -0,0 +1,96 @@ + + + + Katas + + + + + + + + + +
+ + + + +
+
+
+

+ Developer Onboarding +

+

+ Katas +

+
+ +

+ This is the Katas Homepage +

+ + + + + + + + + +
+

Enter Content Here

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Kata 3 + +
+
+ + + +
+
+ Next +
+ +
+ + Kata 3 + +
+
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/developerOnboarding/kata-1/index.html b/_site/docs/developerOnboarding/kata-1/index.html new file mode 100644 index 00000000..0280119e --- /dev/null +++ b/_site/docs/developerOnboarding/kata-1/index.html @@ -0,0 +1,92 @@ + + + + Kata 1 + + + + + + + + + +
+ + + + +
+
+
+

+ Katas +

+

+ Kata 1 +

+
+ + + + + + + + + +
+

Content here

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Ideology + +
+
+ + + +
+
+ Next +
+ +
+ + Kata 2 + +
+
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/developerOnboarding/kata-2/index.html b/_site/docs/developerOnboarding/kata-2/index.html new file mode 100644 index 00000000..b87ddf3e --- /dev/null +++ b/_site/docs/developerOnboarding/kata-2/index.html @@ -0,0 +1,92 @@ + + + + Kata 2 + + + + + + + + + +
+ + + + +
+
+
+

+ Katas +

+

+ Kata 2 +

+
+ + + + + + + + + +
+

Content here. You can use markdown.

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Kata 1 + +
+
+ + + +
+
+ Next +
+ +
+ + Kata 3 + +
+
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/developerOnboarding/kata-3/index.html b/_site/docs/developerOnboarding/kata-3/index.html new file mode 100644 index 00000000..2e3ca50d --- /dev/null +++ b/_site/docs/developerOnboarding/kata-3/index.html @@ -0,0 +1,92 @@ + + + + Kata 3 + + + + + + + + + +
+ + + + +
+
+
+

+ Katas +

+

+ Kata 3 +

+
+ + + + + + + + + +
+

katas

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Kata 2 + +
+
+ + + +
+
+ Next +
+ +
+ + Katas + +
+
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/developerOnboarding/kata-4/index.html b/_site/docs/developerOnboarding/kata-4/index.html new file mode 100644 index 00000000..e7a7e0e8 --- /dev/null +++ b/_site/docs/developerOnboarding/kata-4/index.html @@ -0,0 +1,80 @@ + + + + Kata 3 + + + + + + + + + +
+ + + + +
+
+
+

+ Katas +

+

+ Kata 3 +

+
+ + + + + + + + + +
+

katas

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Katas + +
+
+ + + +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/developerOnboarding/katas/index.html b/_site/docs/developerOnboarding/katas/index.html new file mode 100644 index 00000000..0def7b72 --- /dev/null +++ b/_site/docs/developerOnboarding/katas/index.html @@ -0,0 +1,224 @@ + + + + Katas + + + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Concepts + + + Ideology + + + Developer Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + + + +
+
+
+

+ Intro +

+

+ Katas +

+
+ +

+ This is the Katas Homepage +

+ + + + + + +
+ [Screenshot Image] +
+ +
+

+ Video walkthrough +

+ +

+ Watch this 5 minutes video-walkthrough of Katas. You quickly learn how to set up your dashboard, invite team members, set permissions and how to schedule and publish content. +

+
+
+ + + + + + +

+ Navigate through the Katas +

+ + + + +
+

Enter Content Here

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Kata 3 + +
+
+ + + +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/developer_onboarding/Kata 1/index.html b/_site/docs/developer_onboarding/Kata 1/index.html new file mode 100644 index 00000000..4cf43eea --- /dev/null +++ b/_site/docs/developer_onboarding/Kata 1/index.html @@ -0,0 +1,198 @@ + + + + Kata 1 + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Concepts + + + Ideology + + + Developer Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + +
+
+
+

+ Katas +

+

+ Kata 1 +

+
+ + + + + +
+

Content here

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Ideology + +
+
+ + + +
+
+ Next +
+ +
+ + Kata 2 + +
+
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/developer_onboarding/Kata 2/index.html b/_site/docs/developer_onboarding/Kata 2/index.html new file mode 100644 index 00000000..f5f2c137 --- /dev/null +++ b/_site/docs/developer_onboarding/Kata 2/index.html @@ -0,0 +1,198 @@ + + + + Kata 2 + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Concepts + + + Ideology + + + Developer Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + +
+
+
+

+ Katas +

+

+ Kata 2 +

+
+ + + + + +
+

Content here. You can use markdown.

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Kata 1 + +
+
+ + + +
+
+ Next +
+ +
+ + Kata 3 + +
+
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/developer_onboarding/Kata 3/index.html b/_site/docs/developer_onboarding/Kata 3/index.html new file mode 100644 index 00000000..e7a2fbd3 --- /dev/null +++ b/_site/docs/developer_onboarding/Kata 3/index.html @@ -0,0 +1,198 @@ + + + + Kata 3 + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Concepts + + + Ideology + + + Developer Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + +
+
+
+

+ Katas +

+

+ Kata 3 +

+
+ + + + + +
+

katas

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Kata 2 + +
+
+ + + +
+
+ Next +
+ +
+ + Concepts + +
+
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/developer_onboarding/concept-1/index.html b/_site/docs/developer_onboarding/concept-1/index.html new file mode 100644 index 00000000..5bbf804e --- /dev/null +++ b/_site/docs/developer_onboarding/concept-1/index.html @@ -0,0 +1,204 @@ + + + + Concept 1 + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Concepts + + + Ideology + + + Developer Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + +
+
+
+

+ Concepts +

+

+ Concept 1 +

+
+ + + + + +
+

Content here

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Ideology + +
+
+ + + +
+
+ Next +
+ +
+ + Concept 2 + +
+
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/developer_onboarding/concept-2/index.html b/_site/docs/developer_onboarding/concept-2/index.html new file mode 100644 index 00000000..1952f43d --- /dev/null +++ b/_site/docs/developer_onboarding/concept-2/index.html @@ -0,0 +1,204 @@ + + + + Concept 2 + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Concepts + + + Ideology + + + Developer Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + +
+
+
+

+ Concepts +

+

+ Concept 2 +

+
+ + + + + +
+

Content here. You can use markdown.

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Concept 1 + +
+
+ + + +
+
+ Next +
+ +
+ + Concept 3 + +
+
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/developer_onboarding/concept-3/index.html b/_site/docs/developer_onboarding/concept-3/index.html new file mode 100644 index 00000000..17e7f061 --- /dev/null +++ b/_site/docs/developer_onboarding/concept-3/index.html @@ -0,0 +1,204 @@ + + + + Concept 3 + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Concepts + + + Ideology + + + Developer Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + +
+
+
+

+ Concepts +

+

+ Concept 3 +

+
+ + + + + +
+

katas

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Concept 2 + +
+
+ + + +
+
+ Next +
+ +
+ + Concepts + +
+
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/developer_onboarding/concepts/index.html b/_site/docs/developer_onboarding/concepts/index.html new file mode 100644 index 00000000..802345c0 --- /dev/null +++ b/_site/docs/developer_onboarding/concepts/index.html @@ -0,0 +1,268 @@ + + + + Concepts + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Concepts + + + Ideology + + + Developer Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + +
+
+
+

+ Main +

+

+ Concepts +

+
+ +

+ This is the Concepts Homepage +

+ + + + +
+ [Screenshot Image] +
+ +
+

+ Video walkthrough +

+ +

+ Watch this 5 minutes video-walkthrough of Concepts. You quickly learn how to set up your dashboard, invite team members, set permissions and how to schedule and publish content. +

+
+
+ + + + +

+ Navigate through the Concepts +

+ + + + +
+

Enter Content Here

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Kata 3 + +
+
+ + + +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/developer_onboarding/kata-1/index.html b/_site/docs/developer_onboarding/kata-1/index.html new file mode 100644 index 00000000..d77c9597 --- /dev/null +++ b/_site/docs/developer_onboarding/kata-1/index.html @@ -0,0 +1,198 @@ + + + + Kata 1 + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Concepts + + + Ideology + + + Developer Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + +
+
+
+

+ Katas +

+

+ Kata 1 +

+
+ + + + + +
+

Content here

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Ideology + +
+
+ + + +
+
+ Next +
+ +
+ + Kata 2 + +
+
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/developer_onboarding/kata-2/index.html b/_site/docs/developer_onboarding/kata-2/index.html new file mode 100644 index 00000000..f5cb3e99 --- /dev/null +++ b/_site/docs/developer_onboarding/kata-2/index.html @@ -0,0 +1,198 @@ + + + + Kata 2 + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Concepts + + + Ideology + + + Developer Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + +
+
+
+

+ Katas +

+

+ Kata 2 +

+
+ + + + + +
+

Content here. You can use markdown.

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Kata 1 + +
+
+ + + +
+
+ Next +
+ +
+ + Kata 3 + +
+
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/developer_onboarding/kata-3/index.html b/_site/docs/developer_onboarding/kata-3/index.html new file mode 100644 index 00000000..366d9fe0 --- /dev/null +++ b/_site/docs/developer_onboarding/kata-3/index.html @@ -0,0 +1,198 @@ + + + + Kata 3 + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Concepts + + + Ideology + + + Developer Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + +
+
+
+

+ Katas +

+

+ Kata 3 +

+
+ + + + + +
+

katas

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Kata 2 + +
+
+ + + +
+
+ Next +
+ +
+ + Katas + +
+
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/developer_onboarding/katas/index.html b/_site/docs/developer_onboarding/katas/index.html new file mode 100644 index 00000000..8e555a6e --- /dev/null +++ b/_site/docs/developer_onboarding/katas/index.html @@ -0,0 +1,262 @@ + + + + Katas + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Concepts + + + Ideology + + + Developer Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + +
+
+
+

+ Intro +

+

+ Katas +

+
+ +

+ This is the Katas Homepage +

+ + + + +
+ [Screenshot Image] +
+ +
+

+ Video walkthrough +

+ +

+ Watch this 5 minutes video-walkthrough of Concepts. You quickly learn how to set up your dashboard, invite team members, set permissions and how to schedule and publish content. +

+
+
+ + + + +

+ Navigate through the Concepts +

+ + + + +
+

Enter Content Here

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Kata 3 + +
+
+ + + +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/developer_onboarding/previewing-content/index.html b/_site/docs/developer_onboarding/previewing-content/index.html new file mode 100644 index 00000000..49ac21f3 --- /dev/null +++ b/_site/docs/developer_onboarding/previewing-content/index.html @@ -0,0 +1,119 @@ + + + + Previewing content + + + + + + + +
+ + + + + + + + +
+
+
+

+ dev +

+

+ Previewing content +

+
+ + + + + +
+

Content here

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Concept 3 + +
+
+ + + +
+
+ Next +
+ +
+ + What are content types? + +
+
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/developer_onboarding/what-are-content-types/index.html b/_site/docs/developer_onboarding/what-are-content-types/index.html new file mode 100644 index 00000000..d9eef88c --- /dev/null +++ b/_site/docs/developer_onboarding/what-are-content-types/index.html @@ -0,0 +1,119 @@ + + + + What are content types? + + + + + + + +
+ + + + + + + + +
+
+
+

+ dev +

+

+ What are content types? +

+
+ + + + + +
+

Content here

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Previewing content + +
+
+ + + + + +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/how-does-spinal-work/index.html b/_site/docs/how-does-spinal-work/index.html new file mode 100644 index 00000000..533f5e0f --- /dev/null +++ b/_site/docs/how-does-spinal-work/index.html @@ -0,0 +1,232 @@ + + + + How does Spinal work? + + + + + +
+
+ + Lumena Labs + +
+ + + + +
+ +
+ + + + + + + +
+
+
+

+ Getting Started +

+

+ How does Spinal work? +

+
+ +

+ This is some intro for this doc. It's styled slightly different. +

+ + + + + +
+

Content here. You can use markdown.

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Katas + +
+
+ + + +
+
+ Next +
+ +
+ + Previewing content + +
+
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/ideology/concept-1/index.html b/_site/docs/ideology/concept-1/index.html new file mode 100644 index 00000000..5230b4a7 --- /dev/null +++ b/_site/docs/ideology/concept-1/index.html @@ -0,0 +1,198 @@ + + + + Concept 1 + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Concepts + + + Ideology + + + Developer Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + +
+
+
+

+ Concepts +

+

+ Concept 1 +

+
+ + + + + +
+

Content here

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Concepts + +
+
+ + + +
+
+ Next +
+ +
+ + Concept 2 + +
+
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/ideology/concept-2/index.html b/_site/docs/ideology/concept-2/index.html new file mode 100644 index 00000000..2c741be1 --- /dev/null +++ b/_site/docs/ideology/concept-2/index.html @@ -0,0 +1,202 @@ + + + + Concept 2 + + + + + + +
+
+ + Lumena Labs + +
+
+ + Concepts + + + Ideology + + + Developer Onboarding + +
+
+ + + + + + +
+
+ + +
+ + + + + + + + +
+
+
+

+ Concepts +

+

+ Concept 2 +

+
+ +

+ This is some intro for this doc. It's styled slightly different. +

+ + + + + +
+

Content here. You can use markdown.

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Concept 1 + +
+
+ + + +
+
+ Next +
+ +
+ + Concept 3 + +
+
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/ideology/concept-3/index.html b/_site/docs/ideology/concept-3/index.html new file mode 100644 index 00000000..5c06d7bb --- /dev/null +++ b/_site/docs/ideology/concept-3/index.html @@ -0,0 +1,198 @@ + + + + Concept 3 + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Concepts + + + Ideology + + + Developer Onboarding + +
+
+ + + + + + +
+
+ +
+ + + + + + + + +
+
+
+

+ Concepts +

+

+ Concept 3 +

+
+ + + + + +
+

katas

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Concept 1 + +
+
+ + + +
+
+ Next +
+ +
+ + Concept 2 + +
+
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/ideology/ideology-1/index.html b/_site/docs/ideology/ideology-1/index.html new file mode 100644 index 00000000..15fdd75f --- /dev/null +++ b/_site/docs/ideology/ideology-1/index.html @@ -0,0 +1,160 @@ + + + + Ideology 1 + + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ + +
+ + + + + + + + + + +
+
+
+

+ Ideology 1 +

+
+ + + + + + + + + + + +
+

Content here

+ +
+
+ + diff --git a/_site/docs/ideology/ideology-2/index.html b/_site/docs/ideology/ideology-2/index.html new file mode 100644 index 00000000..19475b16 --- /dev/null +++ b/_site/docs/ideology/ideology-2/index.html @@ -0,0 +1,160 @@ + + + + Ideology 2 + + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ + +
+ + + + + + + + + + +
+
+
+

+ Ideology 2 +

+
+ + + + + + + + + + + +
+

Content here. You can use markdown.

+ +
+
+ + diff --git a/_site/docs/ideology/ideology-3/index.html b/_site/docs/ideology/ideology-3/index.html new file mode 100644 index 00000000..391c0435 --- /dev/null +++ b/_site/docs/ideology/ideology-3/index.html @@ -0,0 +1,160 @@ + + + + Ideology 3 + + + + + + + + +
+
+ + Lumena Labs + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ + +
+ + + + + + + + + + +
+
+
+

+ Ideology 3 +

+
+ + + + + + + + + + + +
+

katas

+ +
+
+ + diff --git a/_site/docs/ideology/index.html b/_site/docs/ideology/index.html new file mode 100644 index 00000000..6049ae1a --- /dev/null +++ b/_site/docs/ideology/index.html @@ -0,0 +1,222 @@ + + + + Introduction to Sprucebot Ideology + + + + + + + + +
+
+ + Site Logo + +
+
+ + Ideology + + + Concepts + + + DX Onboarding + +
+
+ + + + + + +
+
+ + +
+ + + + + +
+
+
+

+ Introduction to Sprucebot Ideology +

+
+ +

+ This is the Ideology Homepage +

+ + + + + +
+ [Screenshot Image] +
+ +
+

+ Video walkthrough +

+ +

+ Watch this video-walkthrough of Ideology. +

+
+
+ + + + + + +

+ Navigate through the Ideology +

+ + + + + + + + +
+

Enter Content Here

+ +
+
+
+ + + + +
+ + diff --git a/_site/docs/ideology/what-kind-can-i-edit/index.html b/_site/docs/ideology/what-kind-can-i-edit/index.html new file mode 100644 index 00000000..0cceb2fd --- /dev/null +++ b/_site/docs/ideology/what-kind-can-i-edit/index.html @@ -0,0 +1,119 @@ + + + + What kind of content can I create and edit? + + + + + + + +
+ + + + + + + + +
+
+
+

+ ideology +

+

+ What kind of content can I create and edit? +

+
+ + + + + +
+

Content here

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + What are content types? + +
+
+ + + +
+
+ Next +
+ +
+ + Home + +
+
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/index.html b/_site/docs/index.html new file mode 100644 index 00000000..de34a983 --- /dev/null +++ b/_site/docs/index.html @@ -0,0 +1,61 @@ + + + + Lumena Labs + + + + + + + + + +
+ + + + + +
+ +
+ + + + +
+ + diff --git a/_site/docs/previewing-content/index.html b/_site/docs/previewing-content/index.html new file mode 100644 index 00000000..4b650861 --- /dev/null +++ b/_site/docs/previewing-content/index.html @@ -0,0 +1,228 @@ + + + + Previewing content + + + + + +
+
+ + Lumena Labs + +
+ + + + +
+ +
+ + + + + + + +
+
+
+

+ Content +

+

+ Previewing content +

+
+ + + + + +
+

Content here

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Katas + +
+
+ + + +
+
+ Next +
+ +
+ + What are content types? + +
+
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/what-are-content-types/index.html b/_site/docs/what-are-content-types/index.html new file mode 100644 index 00000000..45047bf1 --- /dev/null +++ b/_site/docs/what-are-content-types/index.html @@ -0,0 +1,228 @@ + + + + What are content types? + + + + + +
+
+ + Lumena Labs + +
+ + + + +
+ +
+ + + + + + + +
+
+
+

+ Content Types +

+

+ What are content types? +

+
+ + + + + +
+

Content here

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + Previewing content + +
+
+ + + + + +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/docs/what-kind-can-i-edit/index.html b/_site/docs/what-kind-can-i-edit/index.html new file mode 100644 index 00000000..ab51b131 --- /dev/null +++ b/_site/docs/what-kind-can-i-edit/index.html @@ -0,0 +1,228 @@ + + + + What kind of content can I create and edit? + + + + + +
+
+ + Lumena Labs + +
+ + + + +
+ +
+ + + + + + + +
+
+
+

+ Content +

+

+ What kind of content can I create and edit? +

+
+ + + + + +
+

Content here

+ +
+

+ Have questions? +

+ +

+ Still have questions? Talk to support. +

+ +
+ + + + + +
+ +
+
+ Previous +
+ +
+ + What are content types? + +
+
+ + + +
+
+ Next +
+ +
+ + Home + +
+
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/_site/index.css b/_site/index.css new file mode 100644 index 00000000..72dc21eb --- /dev/null +++ b/_site/index.css @@ -0,0 +1,2145 @@ +/* +! tailwindcss v3.1.8 | MIT License | https://tailwindcss.com +*/ + +/* +1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4) +2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116) +*/ + +*, +::before, +::after { + box-sizing: border-box; + /* 1 */ + border-width: 0; + /* 2 */ + border-style: solid; + /* 2 */ + border-color: #e5e7eb; + /* 2 */ +} + +::before, +::after { + --tw-content: ''; +} + +/* +1. Use a consistent sensible line-height in all browsers. +2. Prevent adjustments of font size after orientation changes in iOS. +3. Use a more readable tab size. +4. Use the user's configured `sans` font-family by default. +*/ + +html { + line-height: 1.5; + /* 1 */ + -webkit-text-size-adjust: 100%; + /* 2 */ + -moz-tab-size: 4; + /* 3 */ + -o-tab-size: 4; + tab-size: 4; + /* 3 */ + font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + /* 4 */ +} + +/* +1. Remove the margin in all browsers. +2. Inherit line-height from `html` so users can set them as a class directly on the `html` element. +*/ + +body { + margin: 0; + /* 1 */ + line-height: inherit; + /* 2 */ +} + +/* +1. Add the correct height in Firefox. +2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) +3. Ensure horizontal rules are visible by default. +*/ + +hr { + height: 0; + /* 1 */ + color: inherit; + /* 2 */ + border-top-width: 1px; + /* 3 */ +} + +/* +Add the correct text decoration in Chrome, Edge, and Safari. +*/ + +abbr:where([title]) { + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; +} + +/* +Remove the default font size and weight for headings. +*/ + +h1, +h2, +h3, +h4, +h5, +h6 { + font-size: inherit; + font-weight: inherit; +} + +/* +Reset links to optimize for opt-in styling instead of opt-out. +*/ + +a { + color: inherit; + text-decoration: inherit; +} + +/* +Add the correct font weight in Edge and Safari. +*/ + +b, +strong { + font-weight: bolder; +} + +/* +1. Use the user's configured `mono` font family by default. +2. Correct the odd `em` font sizing in all browsers. +*/ + +code, +kbd, +samp, +pre { + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + /* 1 */ + font-size: 1em; + /* 2 */ +} + +/* +Add the correct font size in all browsers. +*/ + +small { + font-size: 80%; +} + +/* +Prevent `sub` and `sup` elements from affecting the line height in all browsers. +*/ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +/* +1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) +2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) +3. Remove gaps between table borders by default. +*/ + +table { + text-indent: 0; + /* 1 */ + border-color: inherit; + /* 2 */ + border-collapse: collapse; + /* 3 */ +} + +/* +1. Change the font styles in all browsers. +2. Remove the margin in Firefox and Safari. +3. Remove default padding in all browsers. +*/ + +button, +input, +optgroup, +select, +textarea { + font-family: inherit; + /* 1 */ + font-size: 100%; + /* 1 */ + font-weight: inherit; + /* 1 */ + line-height: inherit; + /* 1 */ + color: inherit; + /* 1 */ + margin: 0; + /* 2 */ + padding: 0; + /* 3 */ +} + +/* +Remove the inheritance of text transform in Edge and Firefox. +*/ + +button, +select { + text-transform: none; +} + +/* +1. Correct the inability to style clickable types in iOS and Safari. +2. Remove default button styles. +*/ + +button, +[type='button'], +[type='reset'], +[type='submit'] { + -webkit-appearance: button; + /* 1 */ + background-color: transparent; + /* 2 */ + background-image: none; + /* 2 */ +} + +/* +Use the modern Firefox focus style for all focusable elements. +*/ + +:-moz-focusring { + outline: auto; +} + +/* +Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737) +*/ + +:-moz-ui-invalid { + box-shadow: none; +} + +/* +Add the correct vertical alignment in Chrome and Firefox. +*/ + +progress { + vertical-align: baseline; +} + +/* +Correct the cursor style of increment and decrement buttons in Safari. +*/ + +::-webkit-inner-spin-button, +::-webkit-outer-spin-button { + height: auto; +} + +/* +1. Correct the odd appearance in Chrome and Safari. +2. Correct the outline style in Safari. +*/ + +[type='search'] { + -webkit-appearance: textfield; + /* 1 */ + outline-offset: -2px; + /* 2 */ +} + +/* +Remove the inner padding in Chrome and Safari on macOS. +*/ + +::-webkit-search-decoration { + -webkit-appearance: none; +} + +/* +1. Correct the inability to style clickable types in iOS and Safari. +2. Change font properties to `inherit` in Safari. +*/ + +::-webkit-file-upload-button { + -webkit-appearance: button; + /* 1 */ + font: inherit; + /* 2 */ +} + +/* +Add the correct display in Chrome and Safari. +*/ + +summary { + display: list-item; +} + +/* +Removes the default spacing and border for appropriate elements. +*/ + +blockquote, +dl, +dd, +h1, +h2, +h3, +h4, +h5, +h6, +hr, +figure, +p, +pre { + margin: 0; +} + +fieldset { + margin: 0; + padding: 0; +} + +legend { + padding: 0; +} + +ol, +ul, +menu { + list-style: none; + margin: 0; + padding: 0; +} + +/* +Prevent resizing textareas horizontally by default. +*/ + +textarea { + resize: vertical; +} + +/* +1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300) +2. Set the default placeholder color to the user's configured gray 400 color. +*/ + +input::-moz-placeholder, textarea::-moz-placeholder { + opacity: 1; + /* 1 */ + color: #9ca3af; + /* 2 */ +} + +input::placeholder, +textarea::placeholder { + opacity: 1; + /* 1 */ + color: #9ca3af; + /* 2 */ +} + +/* +Set the default cursor for buttons. +*/ + +button, +[role="button"] { + cursor: pointer; +} + +/* +Make sure disabled buttons don't get the pointer cursor. +*/ + +:disabled { + cursor: default; +} + +/* +1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) +2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) + This can trigger a poorly considered lint error in some tools but is included by design. +*/ + +img, +svg, +video, +canvas, +audio, +iframe, +embed, +object { + display: block; + /* 1 */ + vertical-align: middle; + /* 2 */ +} + +/* +Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) +*/ + +img, +video { + max-width: 100%; + height: auto; +} + +*, ::before, ::after { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; +} + +::-webkit-backdrop { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; +} + +::backdrop { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; +} + +.prose { + color: var(--tw-prose-body); + max-width: 65ch; +} + +.prose :where([class~="lead"]):not(:where([class~="not-prose"] *)) { + color: var(--tw-prose-lead); + font-size: 1.25em; + line-height: 1.6; + margin-top: 1.2em; + margin-bottom: 1.2em; +} + +.prose :where(a):not(:where([class~="not-prose"] *)) { + color: var(--tw-prose-links); + text-decoration: underline; + font-weight: 500; +} + +.prose :where(strong):not(:where([class~="not-prose"] *)) { + color: var(--tw-prose-bold); + font-weight: 600; +} + +.prose :where(a strong):not(:where([class~="not-prose"] *)) { + color: inherit; +} + +.prose :where(blockquote strong):not(:where([class~="not-prose"] *)) { + color: inherit; +} + +.prose :where(thead th strong):not(:where([class~="not-prose"] *)) { + color: inherit; +} + +.prose :where(ol):not(:where([class~="not-prose"] *)) { + list-style-type: decimal; + margin-top: 1.25em; + margin-bottom: 1.25em; + padding-left: 1.625em; +} + +.prose :where(ol[type="A"]):not(:where([class~="not-prose"] *)) { + list-style-type: upper-alpha; +} + +.prose :where(ol[type="a"]):not(:where([class~="not-prose"] *)) { + list-style-type: lower-alpha; +} + +.prose :where(ol[type="A" s]):not(:where([class~="not-prose"] *)) { + list-style-type: upper-alpha; +} + +.prose :where(ol[type="a" s]):not(:where([class~="not-prose"] *)) { + list-style-type: lower-alpha; +} + +.prose :where(ol[type="I"]):not(:where([class~="not-prose"] *)) { + list-style-type: upper-roman; +} + +.prose :where(ol[type="i"]):not(:where([class~="not-prose"] *)) { + list-style-type: lower-roman; +} + +.prose :where(ol[type="I" s]):not(:where([class~="not-prose"] *)) { + list-style-type: upper-roman; +} + +.prose :where(ol[type="i" s]):not(:where([class~="not-prose"] *)) { + list-style-type: lower-roman; +} + +.prose :where(ol[type="1"]):not(:where([class~="not-prose"] *)) { + list-style-type: decimal; +} + +.prose :where(ul):not(:where([class~="not-prose"] *)) { + list-style-type: disc; + margin-top: 1.25em; + margin-bottom: 1.25em; + padding-left: 1.625em; +} + +.prose :where(ol > li):not(:where([class~="not-prose"] *))::marker { + font-weight: 400; + color: var(--tw-prose-counters); +} + +.prose :where(ul > li):not(:where([class~="not-prose"] *))::marker { + color: var(--tw-prose-bullets); +} + +.prose :where(hr):not(:where([class~="not-prose"] *)) { + border-color: var(--tw-prose-hr); + border-top-width: 1px; + margin-top: 3em; + margin-bottom: 3em; +} + +.prose :where(blockquote):not(:where([class~="not-prose"] *)) { + font-weight: 500; + font-style: italic; + color: var(--tw-prose-quotes); + border-left-width: 0.25rem; + border-left-color: var(--tw-prose-quote-borders); + quotes: "\201C""\201D""\2018""\2019"; + margin-top: 1.6em; + margin-bottom: 1.6em; + padding-left: 1em; +} + +.prose :where(blockquote p:first-of-type):not(:where([class~="not-prose"] *))::before { + content: open-quote; +} + +.prose :where(blockquote p:last-of-type):not(:where([class~="not-prose"] *))::after { + content: close-quote; +} + +.prose :where(h1):not(:where([class~="not-prose"] *)) { + color: var(--tw-prose-headings); + font-weight: 800; + font-size: 2.25em; + margin-top: 0; + margin-bottom: 0.8888889em; + line-height: 1.1111111; +} + +.prose :where(h1 strong):not(:where([class~="not-prose"] *)) { + font-weight: 900; + color: inherit; +} + +.prose :where(h2):not(:where([class~="not-prose"] *)) { + color: var(--tw-prose-headings); + font-weight: 700; + font-size: 1.5em; + margin-top: 2em; + margin-bottom: 1em; + line-height: 1.3333333; +} + +.prose :where(h2 strong):not(:where([class~="not-prose"] *)) { + font-weight: 800; + color: inherit; +} + +.prose :where(h3):not(:where([class~="not-prose"] *)) { + color: var(--tw-prose-headings); + font-weight: 600; + font-size: 1.25em; + margin-top: 1.6em; + margin-bottom: 0.6em; + line-height: 1.6; +} + +.prose :where(h3 strong):not(:where([class~="not-prose"] *)) { + font-weight: 700; + color: inherit; +} + +.prose :where(h4):not(:where([class~="not-prose"] *)) { + color: var(--tw-prose-headings); + font-weight: 600; + margin-top: 1.5em; + margin-bottom: 0.5em; + line-height: 1.5; +} + +.prose :where(h4 strong):not(:where([class~="not-prose"] *)) { + font-weight: 700; + color: inherit; +} + +.prose :where(img):not(:where([class~="not-prose"] *)) { + margin-top: 2em; + margin-bottom: 2em; +} + +.prose :where(figure > *):not(:where([class~="not-prose"] *)) { + margin-top: 0; + margin-bottom: 0; +} + +.prose :where(figcaption):not(:where([class~="not-prose"] *)) { + color: var(--tw-prose-captions); + font-size: 0.875em; + line-height: 1.4285714; + margin-top: 0.8571429em; +} + +.prose :where(code):not(:where([class~="not-prose"] *)) { + color: var(--tw-prose-code); + font-weight: 600; + font-size: 0.875em; +} + +.prose :where(code):not(:where([class~="not-prose"] *))::before { + content: "`"; +} + +.prose :where(code):not(:where([class~="not-prose"] *))::after { + content: "`"; +} + +.prose :where(a code):not(:where([class~="not-prose"] *)) { + color: inherit; +} + +.prose :where(h1 code):not(:where([class~="not-prose"] *)) { + color: inherit; +} + +.prose :where(h2 code):not(:where([class~="not-prose"] *)) { + color: inherit; + font-size: 0.875em; +} + +.prose :where(h3 code):not(:where([class~="not-prose"] *)) { + color: inherit; + font-size: 0.9em; +} + +.prose :where(h4 code):not(:where([class~="not-prose"] *)) { + color: inherit; +} + +.prose :where(blockquote code):not(:where([class~="not-prose"] *)) { + color: inherit; +} + +.prose :where(thead th code):not(:where([class~="not-prose"] *)) { + color: inherit; +} + +.prose :where(pre):not(:where([class~="not-prose"] *)) { + color: var(--tw-prose-pre-code); + background-color: var(--tw-prose-pre-bg); + overflow-x: auto; + font-weight: 400; + font-size: 0.875em; + line-height: 1.7142857; + margin-top: 1.7142857em; + margin-bottom: 1.7142857em; + border-radius: 0.375rem; + padding-top: 0.8571429em; + padding-right: 1.1428571em; + padding-bottom: 0.8571429em; + padding-left: 1.1428571em; +} + +.prose :where(pre code):not(:where([class~="not-prose"] *)) { + background-color: transparent; + border-width: 0; + border-radius: 0; + padding: 0; + font-weight: inherit; + color: inherit; + font-size: inherit; + font-family: inherit; + line-height: inherit; +} + +.prose :where(pre code):not(:where([class~="not-prose"] *))::before { + content: none; +} + +.prose :where(pre code):not(:where([class~="not-prose"] *))::after { + content: none; +} + +.prose :where(table):not(:where([class~="not-prose"] *)) { + width: 100%; + table-layout: auto; + text-align: left; + margin-top: 2em; + margin-bottom: 2em; + font-size: 0.875em; + line-height: 1.7142857; +} + +.prose :where(thead):not(:where([class~="not-prose"] *)) { + border-bottom-width: 1px; + border-bottom-color: var(--tw-prose-th-borders); +} + +.prose :where(thead th):not(:where([class~="not-prose"] *)) { + color: var(--tw-prose-headings); + font-weight: 600; + vertical-align: bottom; + padding-right: 0.5714286em; + padding-bottom: 0.5714286em; + padding-left: 0.5714286em; +} + +.prose :where(tbody tr):not(:where([class~="not-prose"] *)) { + border-bottom-width: 1px; + border-bottom-color: var(--tw-prose-td-borders); +} + +.prose :where(tbody tr:last-child):not(:where([class~="not-prose"] *)) { + border-bottom-width: 0; +} + +.prose :where(tbody td):not(:where([class~="not-prose"] *)) { + vertical-align: baseline; +} + +.prose :where(tfoot):not(:where([class~="not-prose"] *)) { + border-top-width: 1px; + border-top-color: var(--tw-prose-th-borders); +} + +.prose :where(tfoot td):not(:where([class~="not-prose"] *)) { + vertical-align: top; +} + +.prose { + --tw-prose-body: #374151; + --tw-prose-headings: #111827; + --tw-prose-lead: #4b5563; + --tw-prose-links: #111827; + --tw-prose-bold: #111827; + --tw-prose-counters: #6b7280; + --tw-prose-bullets: #d1d5db; + --tw-prose-hr: #e5e7eb; + --tw-prose-quotes: #111827; + --tw-prose-quote-borders: #e5e7eb; + --tw-prose-captions: #6b7280; + --tw-prose-code: #111827; + --tw-prose-pre-code: #e5e7eb; + --tw-prose-pre-bg: #1f2937; + --tw-prose-th-borders: #d1d5db; + --tw-prose-td-borders: #e5e7eb; + --tw-prose-invert-body: #d1d5db; + --tw-prose-invert-headings: #fff; + --tw-prose-invert-lead: #9ca3af; + --tw-prose-invert-links: #fff; + --tw-prose-invert-bold: #fff; + --tw-prose-invert-counters: #9ca3af; + --tw-prose-invert-bullets: #4b5563; + --tw-prose-invert-hr: #374151; + --tw-prose-invert-quotes: #f3f4f6; + --tw-prose-invert-quote-borders: #374151; + --tw-prose-invert-captions: #9ca3af; + --tw-prose-invert-code: #fff; + --tw-prose-invert-pre-code: #d1d5db; + --tw-prose-invert-pre-bg: rgb(0 0 0 / 50%); + --tw-prose-invert-th-borders: #4b5563; + --tw-prose-invert-td-borders: #374151; + font-size: 1rem; + line-height: 1.75; +} + +.prose :where(p):not(:where([class~="not-prose"] *)) { + margin-top: 1.25em; + margin-bottom: 1.25em; +} + +.prose :where(video):not(:where([class~="not-prose"] *)) { + margin-top: 2em; + margin-bottom: 2em; +} + +.prose :where(figure):not(:where([class~="not-prose"] *)) { + margin-top: 2em; + margin-bottom: 2em; +} + +.prose :where(li):not(:where([class~="not-prose"] *)) { + margin-top: 0.5em; + margin-bottom: 0.5em; +} + +.prose :where(ol > li):not(:where([class~="not-prose"] *)) { + padding-left: 0.375em; +} + +.prose :where(ul > li):not(:where([class~="not-prose"] *)) { + padding-left: 0.375em; +} + +.prose :where(.prose > ul > li p):not(:where([class~="not-prose"] *)) { + margin-top: 0.75em; + margin-bottom: 0.75em; +} + +.prose :where(.prose > ul > li > *:first-child):not(:where([class~="not-prose"] *)) { + margin-top: 1.25em; +} + +.prose :where(.prose > ul > li > *:last-child):not(:where([class~="not-prose"] *)) { + margin-bottom: 1.25em; +} + +.prose :where(.prose > ol > li > *:first-child):not(:where([class~="not-prose"] *)) { + margin-top: 1.25em; +} + +.prose :where(.prose > ol > li > *:last-child):not(:where([class~="not-prose"] *)) { + margin-bottom: 1.25em; +} + +.prose :where(ul ul, ul ol, ol ul, ol ol):not(:where([class~="not-prose"] *)) { + margin-top: 0.75em; + margin-bottom: 0.75em; +} + +.prose :where(hr + *):not(:where([class~="not-prose"] *)) { + margin-top: 0; +} + +.prose :where(h2 + *):not(:where([class~="not-prose"] *)) { + margin-top: 0; +} + +.prose :where(h3 + *):not(:where([class~="not-prose"] *)) { + margin-top: 0; +} + +.prose :where(h4 + *):not(:where([class~="not-prose"] *)) { + margin-top: 0; +} + +.prose :where(thead th:first-child):not(:where([class~="not-prose"] *)) { + padding-left: 0; +} + +.prose :where(thead th:last-child):not(:where([class~="not-prose"] *)) { + padding-right: 0; +} + +.prose :where(tbody td, tfoot td):not(:where([class~="not-prose"] *)) { + padding-top: 0.5714286em; + padding-right: 0.5714286em; + padding-bottom: 0.5714286em; + padding-left: 0.5714286em; +} + +.prose :where(tbody td:first-child, tfoot td:first-child):not(:where([class~="not-prose"] *)) { + padding-left: 0; +} + +.prose :where(tbody td:last-child, tfoot td:last-child):not(:where([class~="not-prose"] *)) { + padding-right: 0; +} + +.prose :where(.prose > :first-child):not(:where([class~="not-prose"] *)) { + margin-top: 0; +} + +.prose :where(.prose > :last-child):not(:where([class~="not-prose"] *)) { + margin-bottom: 0; +} + +.prose-sm :where(.prose > ul > li p):not(:where([class~="not-prose"] *)) { + margin-top: 0.5714286em; + margin-bottom: 0.5714286em; +} + +.prose-sm :where(.prose > ul > li > *:first-child):not(:where([class~="not-prose"] *)) { + margin-top: 1.1428571em; +} + +.prose-sm :where(.prose > ul > li > *:last-child):not(:where([class~="not-prose"] *)) { + margin-bottom: 1.1428571em; +} + +.prose-sm :where(.prose > ol > li > *:first-child):not(:where([class~="not-prose"] *)) { + margin-top: 1.1428571em; +} + +.prose-sm :where(.prose > ol > li > *:last-child):not(:where([class~="not-prose"] *)) { + margin-bottom: 1.1428571em; +} + +.prose-sm :where(.prose > :first-child):not(:where([class~="not-prose"] *)) { + margin-top: 0; +} + +.prose-sm :where(.prose > :last-child):not(:where([class~="not-prose"] *)) { + margin-bottom: 0; +} + +.prose-base :where(.prose > ul > li p):not(:where([class~="not-prose"] *)) { + margin-top: 0.75em; + margin-bottom: 0.75em; +} + +.prose-base :where(.prose > ul > li > *:first-child):not(:where([class~="not-prose"] *)) { + margin-top: 1.25em; +} + +.prose-base :where(.prose > ul > li > *:last-child):not(:where([class~="not-prose"] *)) { + margin-bottom: 1.25em; +} + +.prose-base :where(.prose > ol > li > *:first-child):not(:where([class~="not-prose"] *)) { + margin-top: 1.25em; +} + +.prose-base :where(.prose > ol > li > *:last-child):not(:where([class~="not-prose"] *)) { + margin-bottom: 1.25em; +} + +.prose-base :where(.prose > :first-child):not(:where([class~="not-prose"] *)) { + margin-top: 0; +} + +.prose-base :where(.prose > :last-child):not(:where([class~="not-prose"] *)) { + margin-bottom: 0; +} + +.prose-lg :where(.prose > ul > li p):not(:where([class~="not-prose"] *)) { + margin-top: 0.8888889em; + margin-bottom: 0.8888889em; +} + +.prose-lg :where(.prose > ul > li > *:first-child):not(:where([class~="not-prose"] *)) { + margin-top: 1.3333333em; +} + +.prose-lg :where(.prose > ul > li > *:last-child):not(:where([class~="not-prose"] *)) { + margin-bottom: 1.3333333em; +} + +.prose-lg :where(.prose > ol > li > *:first-child):not(:where([class~="not-prose"] *)) { + margin-top: 1.3333333em; +} + +.prose-lg :where(.prose > ol > li > *:last-child):not(:where([class~="not-prose"] *)) { + margin-bottom: 1.3333333em; +} + +.prose-lg :where(.prose > :first-child):not(:where([class~="not-prose"] *)) { + margin-top: 0; +} + +.prose-lg :where(.prose > :last-child):not(:where([class~="not-prose"] *)) { + margin-bottom: 0; +} + +.prose-xl :where(.prose > ul > li p):not(:where([class~="not-prose"] *)) { + margin-top: 0.8em; + margin-bottom: 0.8em; +} + +.prose-xl :where(.prose > ul > li > *:first-child):not(:where([class~="not-prose"] *)) { + margin-top: 1.2em; +} + +.prose-xl :where(.prose > ul > li > *:last-child):not(:where([class~="not-prose"] *)) { + margin-bottom: 1.2em; +} + +.prose-xl :where(.prose > ol > li > *:first-child):not(:where([class~="not-prose"] *)) { + margin-top: 1.2em; +} + +.prose-xl :where(.prose > ol > li > *:last-child):not(:where([class~="not-prose"] *)) { + margin-bottom: 1.2em; +} + +.prose-xl :where(.prose > :first-child):not(:where([class~="not-prose"] *)) { + margin-top: 0; +} + +.prose-xl :where(.prose > :last-child):not(:where([class~="not-prose"] *)) { + margin-bottom: 0; +} + +.prose-2xl :where(.prose > ul > li p):not(:where([class~="not-prose"] *)) { + margin-top: 0.8333333em; + margin-bottom: 0.8333333em; +} + +.prose-2xl :where(.prose > ul > li > *:first-child):not(:where([class~="not-prose"] *)) { + margin-top: 1.3333333em; +} + +.prose-2xl :where(.prose > ul > li > *:last-child):not(:where([class~="not-prose"] *)) { + margin-bottom: 1.3333333em; +} + +.prose-2xl :where(.prose > ol > li > *:first-child):not(:where([class~="not-prose"] *)) { + margin-top: 1.3333333em; +} + +.prose-2xl :where(.prose > ol > li > *:last-child):not(:where([class~="not-prose"] *)) { + margin-bottom: 1.3333333em; +} + +.prose-2xl :where(.prose > :first-child):not(:where([class~="not-prose"] *)) { + margin-top: 0; +} + +.prose-2xl :where(.prose > :last-child):not(:where([class~="not-prose"] *)) { + margin-bottom: 0; +} + +.prose-slate { + --tw-prose-body: #334155; + --tw-prose-headings: #0f172a; + --tw-prose-lead: #475569; + --tw-prose-links: #0f172a; + --tw-prose-bold: #0f172a; + --tw-prose-counters: #64748b; + --tw-prose-bullets: #cbd5e1; + --tw-prose-hr: #e2e8f0; + --tw-prose-quotes: #0f172a; + --tw-prose-quote-borders: #e2e8f0; + --tw-prose-captions: #64748b; + --tw-prose-code: #0f172a; + --tw-prose-pre-code: #e2e8f0; + --tw-prose-pre-bg: #1e293b; + --tw-prose-th-borders: #cbd5e1; + --tw-prose-td-borders: #e2e8f0; + --tw-prose-invert-body: #cbd5e1; + --tw-prose-invert-headings: #fff; + --tw-prose-invert-lead: #94a3b8; + --tw-prose-invert-links: #fff; + --tw-prose-invert-bold: #fff; + --tw-prose-invert-counters: #94a3b8; + --tw-prose-invert-bullets: #475569; + --tw-prose-invert-hr: #334155; + --tw-prose-invert-quotes: #f1f5f9; + --tw-prose-invert-quote-borders: #334155; + --tw-prose-invert-captions: #94a3b8; + --tw-prose-invert-code: #fff; + --tw-prose-invert-pre-code: #cbd5e1; + --tw-prose-invert-pre-bg: rgb(0 0 0 / 50%); + --tw-prose-invert-th-borders: #475569; + --tw-prose-invert-td-borders: #334155; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border-width: 0; +} + +.static { + position: static; +} + +.fixed { + position: fixed; +} + +.absolute { + position: absolute; +} + +.relative { + position: relative; +} + +.sticky { + position: -webkit-sticky; + position: sticky; +} + +.inset-y-0 { + top: 0px; + bottom: 0px; +} + +.top-0 { + top: 0px; +} + +.bottom-0 { + bottom: 0px; +} + +.left-0 { + left: 0px; +} + +.top-\[3\.5rem\] { + top: 3.5rem; +} + +.right-0 { + right: 0px; +} + +.top-\[4\.5rem\] { + top: 4.5rem; +} + +.left-1\/2 { + left: 50%; +} + +.z-50 { + z-index: 50; +} + +.mx-auto { + margin-left: auto; + margin-right: auto; +} + +.mr-20 { + margin-right: 5rem; +} + +.ml-20 { + margin-left: 5rem; +} + +.ml-0 { + margin-left: 0px; +} + +.ml-3 { + margin-left: 0.75rem; +} + +.mt-16 { + margin-top: 4rem; +} + +.mt-4 { + margin-top: 1rem; +} + +.mb-4 { + margin-bottom: 1rem; +} + +.ml-4 { + margin-left: 1rem; +} + +.-ml-0\.5 { + margin-left: -0.125rem; +} + +.-ml-0 { + margin-left: -0px; +} + +.mt-3 { + margin-top: 0.75rem; +} + +.mt-1 { + margin-top: 0.25rem; +} + +.mt-24 { + margin-top: 6rem; +} + +.mt-6 { + margin-top: 1.5rem; +} + +.mr-auto { + margin-right: auto; +} + +.ml-auto { + margin-left: auto; +} + +.mt-2 { + margin-top: 0.5rem; +} + +.mt-8 { + margin-top: 2rem; +} + +.block { + display: block; +} + +.inline-block { + display: inline-block; +} + +.flex { + display: flex; +} + +.grid { + display: grid; +} + +.hidden { + display: none; +} + +.h-8 { + height: 2rem; +} + +.h-4 { + height: 1rem; +} + +.h-12 { + height: 3rem; +} + +.h-6 { + height: 1.5rem; +} + +.h-screen { + height: 100vh; +} + +.h-\[calc\(100vh-4\.5rem\)\] { + height: calc(100vh - 4.5rem); +} + +.w-4 { + width: 1rem; +} + +.w-full { + width: 100%; +} + +.w-12 { + width: 3rem; +} + +.w-6 { + width: 1.5rem; +} + +.w-64 { + width: 16rem; +} + +.w-1\/5 { + width: 20%; +} + +.min-w-0 { + min-width: 0px; +} + +.max-w-none { + max-width: none; +} + +.max-w-2xl { + max-width: 42rem; +} + +.flex-auto { + flex: 1 1 auto; +} + +.flex-shrink-0 { + flex-shrink: 0; +} + +.flex-grow { + flex-grow: 1; +} + +.basis-0 { + flex-basis: 0px; +} + +.origin-top { + transform-origin: top; +} + +.-translate-x-1\/2 { + --tw-translate-x: -50%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.scale-y-0 { + --tw-scale-y: 0; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.transform { + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.cursor-pointer { + cursor: pointer; +} + +.grid-cols-1 { + grid-template-columns: repeat(1, minmax(0, 1fr)); +} + +.flex-col { + flex-direction: column; +} + +.items-center { + align-items: center; +} + +.justify-end { + justify-content: flex-end; +} + +.justify-center { + justify-content: center; +} + +.justify-between { + justify-content: space-between; +} + +.gap-6 { + gap: 1.5rem; +} + +.space-y-8 > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(2rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(2rem * var(--tw-space-y-reverse)); +} + +.space-y-2 > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(0.5rem * var(--tw-space-y-reverse)); +} + +.overflow-hidden { + overflow: hidden; +} + +.overflow-y-auto { + overflow-y: auto; +} + +.rounded { + border-radius: 0.25rem; +} + +.rounded-full { + border-radius: 9999px; +} + +.rounded-lg { + border-radius: 0.5rem; +} + +.border { + border-width: 1px; +} + +.border-b { + border-bottom-width: 1px; +} + +.border-t { + border-top-width: 1px; +} + +.border-r { + border-right-width: 1px; +} + +.border-l { + border-left-width: 1px; +} + +.border-slate-400\/40 { + border-color: rgb(148 163 184 / 0.4); +} + +.border-slate-100 { + --tw-border-opacity: 1; + border-color: rgb(241 245 249 / var(--tw-border-opacity)); +} + +.border-slate-300 { + --tw-border-opacity: 1; + border-color: rgb(203 213 225 / var(--tw-border-opacity)); +} + +.border-slate-200 { + --tw-border-opacity: 1; + border-color: rgb(226 232 240 / var(--tw-border-opacity)); +} + +.bg-white\/90 { + background-color: rgb(255 255 255 / 0.9); +} + +.bg-slate-900 { + --tw-bg-opacity: 1; + background-color: rgb(15 23 42 / var(--tw-bg-opacity)); +} + +.bg-slate-100 { + --tw-bg-opacity: 1; + background-color: rgb(241 245 249 / var(--tw-bg-opacity)); +} + +.bg-slate-50 { + --tw-bg-opacity: 1; + background-color: rgb(248 250 252 / var(--tw-bg-opacity)); +} + +.bg-white { + --tw-bg-opacity: 1; + background-color: rgb(255 255 255 / var(--tw-bg-opacity)); +} + +.bg-gradient-to-br { + background-image: linear-gradient(to bottom right, var(--tw-gradient-stops)); +} + +.from-indigo-200 { + --tw-gradient-from: #c7d2fe; + --tw-gradient-to: rgb(199 210 254 / 0); + --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); +} + +.via-sky-100 { + --tw-gradient-to: rgb(224 242 254 / 0); + --tw-gradient-stops: var(--tw-gradient-from), #e0f2fe, var(--tw-gradient-to); +} + +.to-indigo-100 { + --tw-gradient-to: #e0e7ff; +} + +.fill-slate-400 { + fill: #94a3b8; +} + +.p-4 { + padding: 1rem; +} + +.px-3 { + padding-left: 0.75rem; + padding-right: 0.75rem; +} + +.py-2 { + padding-top: 0.5rem; + padding-bottom: 0.5rem; +} + +.px-4 { + padding-left: 1rem; + padding-right: 1rem; +} + +.px-6 { + padding-left: 1.5rem; + padding-right: 1.5rem; +} + +.py-4 { + padding-top: 1rem; + padding-bottom: 1rem; +} + +.py-7 { + padding-top: 1.75rem; + padding-bottom: 1.75rem; +} + +.py-16 { + padding-top: 4rem; + padding-bottom: 4rem; +} + +.py-10 { + padding-top: 2.5rem; + padding-bottom: 2.5rem; +} + +.pl-10 { + padding-left: 2.5rem; +} + +.pr-2 { + padding-right: 0.5rem; +} + +.pr-8 { + padding-right: 2rem; +} + +.pl-0\.5 { + padding-left: 0.125rem; +} + +.pl-0 { + padding-left: 0px; +} + +.pl-3 { + padding-left: 0.75rem; +} + +.pt-6 { + padding-top: 1.5rem; +} + +.text-left { + text-align: left; +} + +.text-right { + text-align: right; +} + +.text-sm { + font-size: 0.875rem; + line-height: 1.25rem; +} + +.text-base { + font-size: 1rem; + line-height: 1.5rem; +} + +.text-xl { + font-size: 1.25rem; + line-height: 1.75rem; +} + +.text-lg { + font-size: 1.125rem; + line-height: 1.75rem; +} + +.text-3xl { + font-size: 1.875rem; + line-height: 2.25rem; +} + +.text-2xl { + font-size: 1.5rem; + line-height: 2rem; +} + +.font-semibold { + font-weight: 600; +} + +.font-bold { + font-weight: 700; +} + +.font-normal { + font-weight: 400; +} + +.font-medium { + font-weight: 500; +} + +.tracking-tight { + letter-spacing: -0.025em; +} + +.text-slate-50 { + --tw-text-opacity: 1; + color: rgb(248 250 252 / var(--tw-text-opacity)); +} + +.text-slate-800 { + --tw-text-opacity: 1; + color: rgb(30 41 59 / var(--tw-text-opacity)); +} + +.text-slate-900 { + --tw-text-opacity: 1; + color: rgb(15 23 42 / var(--tw-text-opacity)); +} + +.text-slate-600 { + --tw-text-opacity: 1; + color: rgb(71 85 105 / var(--tw-text-opacity)); +} + +.text-slate-900\/20 { + color: rgb(15 23 42 / 0.2); +} + +.text-slate-500 { + --tw-text-opacity: 1; + color: rgb(100 116 139 / var(--tw-text-opacity)); +} + +.underline { + -webkit-text-decoration-line: underline; + text-decoration-line: underline; +} + +.placeholder-slate-400::-moz-placeholder { + --tw-placeholder-opacity: 1; + color: rgb(148 163 184 / var(--tw-placeholder-opacity)); +} + +.placeholder-slate-400::placeholder { + --tw-placeholder-opacity: 1; + color: rgb(148 163 184 / var(--tw-placeholder-opacity)); +} + +.opacity-0 { + opacity: 0; +} + +.shadow-lg { + --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.shadow-xl { + --tw-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.outline { + outline-style: solid; +} + +.outline-2 { + outline-width: 2px; +} + +.outline-offset-2 { + outline-offset: 2px; +} + +.outline-transparent { + outline-color: transparent; +} + +.backdrop-blur-sm { + --tw-backdrop-blur: blur(4px); + -webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); + backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); +} + +.transition { + transition-property: color, background-color, border-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-text-decoration-color, -webkit-backdrop-filter; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-text-decoration-color, -webkit-backdrop-filter; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} + +.transition-transform { + transition-property: transform; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} + +.delay-75 { + transition-delay: 75ms; +} + +.duration-200 { + transition-duration: 200ms; +} + +.ease-in-out { + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} + +/* Dropdown Styling */ + +/* Table of Contents Styling */ + +/* Wrapper Styling */ + +.my-custom-toc { + border-radius: 0.375rem; + --tw-bg-opacity: 1; + background-color: rgb(243 244 246 / var(--tw-bg-opacity)); + padding: 1rem; + --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +/* List Styling */ + +.my-custom-toc ol { + padding-left: 1.25rem; +} + +.my-custom-toc ul { + padding-left: 0px; +} + +.my-custom-toc ol > li { + margin-top: 0.25rem; + margin-bottom: 0.25rem; +} + +.my-custom-toc ol > li > ol, +.my-custom-toc ol > li > ul { + margin-top: 0.25rem; + padding-left: 1.25rem; +} + +.my-custom-toc ol > li > ol > li, +.my-custom-toc ol > li > ul > li { + margin-top: 0.25rem; + margin-bottom: 0.25rem; +} + +.my-custom-toc ol > li > ol > li > ol, +.my-custom-toc ol > li > ul > li > ul { + margin-top: 0.25rem; + padding-left: 1.25rem; +} + +/* Link Styling */ + +.my-custom-toc a { + --tw-text-opacity: 1; + color: rgb(37 99 235 / var(--tw-text-opacity)); + transition-property: color, background-color, border-color, fill, stroke, -webkit-text-decoration-color; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, -webkit-text-decoration-color; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 200ms; +} + +.my-custom-toc a:hover { + --tw-text-opacity: 1; + color: rgb(30 64 175 / var(--tw-text-opacity)); +} + +.sticky { + position: -webkit-sticky; + position: sticky; + top: 1rem; +} + +.hover\:scale-105:hover { + --tw-scale-x: 1.05; + --tw-scale-y: 1.05; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.hover\:border-slate-200:hover { + --tw-border-opacity: 1; + border-color: rgb(226 232 240 / var(--tw-border-opacity)); +} + +.hover\:bg-white:hover { + --tw-bg-opacity: 1; + background-color: rgb(255 255 255 / var(--tw-bg-opacity)); +} + +.hover\:text-slate-800:hover { + --tw-text-opacity: 1; + color: rgb(30 41 59 / var(--tw-text-opacity)); +} + +.hover\:underline:hover { + -webkit-text-decoration-line: underline; + text-decoration-line: underline; +} + +.hover\:no-underline:hover { + -webkit-text-decoration-line: none; + text-decoration-line: none; +} + +.focus\:border-slate-200:focus { + --tw-border-opacity: 1; + border-color: rgb(226 232 240 / var(--tw-border-opacity)); +} + +.focus\:outline-slate-600:focus { + outline-color: #475569; +} + +.active\:scale-95:active { + --tw-scale-x: .95; + --tw-scale-y: .95; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.group:hover .group-hover\:scale-y-100 { + --tw-scale-y: 1; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.group:hover .group-hover\:fill-slate-500 { + fill: #64748b; +} + +.group:hover .group-hover\:opacity-100 { + opacity: 1; +} + +.group:focus .group-focus\:fill-slate-500 { + fill: #64748b; +} + +.group:active .group-active\:scale-y-100 { + --tw-scale-y: 1; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.group:active .group-active\:opacity-100 { + opacity: 1; +} + +.peer:checked ~ .peer-checked\:block { + display: block; +} + +.prose-headings\:font-semibold :is(:where(h1, h2, h3, h4, h5, h6, th):not(:where([class~="not-prose"] *))) { + font-weight: 600; +} + +.prose-headings\:tracking-tight :is(:where(h1, h2, h3, h4, h5, h6, th):not(:where([class~="not-prose"] *))) { + letter-spacing: -0.025em; +} + +.prose-a\:font-semibold :is(:where(a):not(:where([class~="not-prose"] *))) { + font-weight: 600; +} + +.prose-a\:underline :is(:where(a):not(:where([class~="not-prose"] *))) { + -webkit-text-decoration-line: underline; + text-decoration-line: underline; +} + +.prose-pre\:bg-slate-900 :is(:where(pre):not(:where([class~="not-prose"] *))) { + --tw-bg-opacity: 1; + background-color: rgb(15 23 42 / var(--tw-bg-opacity)); +} + +.prose-lead\:text-slate-500 :is(:where([class~="lead"]):not(:where([class~="not-prose"] *))) { + --tw-text-opacity: 1; + color: rgb(100 116 139 / var(--tw-text-opacity)); +} + +@media (min-width: 640px) { + .sm\:grid-cols-2 { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + + .sm\:px-2 { + padding-left: 0.5rem; + padding-right: 0.5rem; + } +} + +@media (min-width: 768px) { + .md\:flex { + display: flex; + } + + .md\:w-80 { + width: 20rem; + } + + .md\:w-4\/5 { + width: 80%; + } + + .md\:w-1\/3 { + width: 33.333333%; + } + + .md\:w-2\/3 { + width: 66.666667%; + } + + .md\:flex-row { + flex-direction: row; + } +} + +@media (min-width: 1024px) { + .lg\:relative { + position: relative; + } + + .lg\:top-0 { + top: 0px; + } + + .lg\:block { + display: block; + } + + .lg\:hidden { + display: none; + } + + .lg\:h-auto { + height: auto; + } + + .lg\:w-96 { + width: 24rem; + } + + .lg\:w-\[50vw\] { + width: 50vw; + } + + .lg\:max-w-none { + max-width: none; + } + + .lg\:flex-none { + flex: none; + } + + .lg\:bg-slate-50 { + --tw-bg-opacity: 1; + background-color: rgb(248 250 252 / var(--tw-bg-opacity)); + } + + .lg\:px-0 { + padding-left: 0px; + padding-right: 0px; + } + + .lg\:px-8 { + padding-left: 2rem; + padding-right: 2rem; + } + + .lg\:pr-0 { + padding-right: 0px; + } + + .lg\:pl-8 { + padding-left: 2rem; + } + + .lg\:text-sm { + font-size: 0.875rem; + line-height: 1.25rem; + } + + .lg\:shadow-none { + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + } +} + +@media (min-width: 1280px) { + .xl\:w-72 { + width: 18rem; + } + + .xl\:px-12 { + padding-left: 3rem; + padding-right: 3rem; + } + + .xl\:px-16 { + padding-left: 4rem; + padding-right: 4rem; + } + + .xl\:pr-16 { + padding-right: 4rem; + } +} + + diff --git a/_site/index.html b/_site/index.html new file mode 100644 index 00000000..6d0573ce --- /dev/null +++ b/_site/index.html @@ -0,0 +1,159 @@ + + + + Developer Portal + + + + + + +
+
+ + Site Logo + +
+
+ + + + + + + +
+
+ + + + +
+ + + + + +
+
+
+

+ Developer Portal +

+
+ +

+ Welcome to the developer portal of the Lumena Platform, anchored by Sprucebot. This guide is designed to be a self-serve tool that will enable both individuals and teams to use, develop, and expand on the Lumena Platform. +

+ + + + + + +

+ Get Started +

+ + + + + + + + +

+ Have questions? +

+ +

+ Talk to Support. +

+ + + + +
+ +
+
+
+ + + + +
+ +