@scalable.software/pin 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,365 +1,365 @@
1
- # Pin Component Documentation
2
-
3
- Below is a **comprehensive** document detailing the **Pin** component’s architecture, usage, and developer workflow. It prioritizes a **Quick Start** so you can see the pin in action right away, then dives into **State**, **Operations**, **Events**, and more advanced topics.
4
-
5
- ---
6
-
7
- ## 1. Introduction
8
-
9
- The **Pin** component provides a toggleable element that can be pinned/unpinned and hidden/shown via both **imperative** and **declarative** APIs. It leverages custom Web Component features, including Shadow DOM, custom events, and attribute reflection for a clean, modular design.
10
-
11
- ### 1.1 Installation & Setup
12
-
13
- 1. **Clone the Repository**
14
-
15
- ```bash
16
- git clone <repository-url>
17
- cd pin-component
18
- ```
19
-
20
- 2. **Install Dependencies**
21
-
22
- ```bash
23
- npm install
24
- ```
25
-
26
- 3. **Run Tests (Optional)**
27
-
28
- ```bash
29
- npm test
30
- ```
31
-
32
- - Ensures everything is working as expected before you start.
33
-
34
- 4. **Start Local Server**
35
- ```bash
36
- npm run serve
37
- ```
38
- - This runs a local development server, making `<pin-button>` available in your browser.
39
-
40
- ---
41
-
42
- ## 2. Quick Start Usage Walkthrough
43
-
44
- This walkthrough demonstrates how to interact with `<pin-button>` right after installation, letting you see how the pin behaves before exploring its internal design.
45
-
46
- 1. **Open** the served page in your browser.
47
-
48
- - You should see a `<pin-button>` component displayed.
49
-
50
- 2. **Open the Developer Tools**, select the **Console**.
51
-
52
- 3. **Get a reference** to the component:
53
-
54
- ```js
55
- const pin = document.querySelector("pin-button");
56
- ```
57
-
58
- 4. **Create a handler** for when the pin is pinned:
59
-
60
- ```js
61
- const onpin = (event) => {
62
- console.log("Pin was pinned:", event.detail.status);
63
- };
64
- ```
65
-
66
- 5. **Assign** that handler to the `onpin` property:
67
-
68
- ```js
69
- pin.onpin = onpin;
70
- ```
71
-
72
- 6. **Pin** the component imperatively:
73
-
74
- ```js
75
- pin.pin();
76
- ```
77
-
78
- - This changes `status` from `unpinned` to `pinned`.
79
- - Observe the console output: `"Pin was pinned: pinned"`.
80
-
81
- 7. **Inspect** the `<pin-button>` in the **Elements** tab:
82
-
83
- ```html
84
- <pin-button status="pinned"></pin-button>
85
- ```
86
-
87
- 8. **Manually change** the `status` attribute to `"unpinned"`
88
-
89
- - Notice the pin’s icon and internal state update.
90
-
91
- 9. **Check** the current status in the console:
92
-
93
- ```js
94
- pin.status; // Should return "unpinned"
95
- ```
96
-
97
- 10. **Click** the `<pin-button>` in the UI
98
-
99
- - By default, clicking toggles it between `pinned` and `unpinned`.
100
- - If pinned, the `onpin` event is fired (if you have a listener).
101
-
102
- 11. **Check** the status again:
103
-
104
- ```js
105
- pin.status; // "pinned" or "unpinned"
106
- ```
107
-
108
- > **Visibility**
109
- >
110
- > - You can similarly call `pin.hide()` or `pin.show()` to toggle the `visible` state.
111
- > - Watch for `onhide` or `onshow` events in the console.
112
-
113
- For more details on **States**, **Operations**, and **Events**, consult the sections below or check the generated **API documentation** (see `npm run document` instructions).
114
-
115
- ---
116
-
117
- ## 3. Architectural Overview
118
-
119
- ### 3.1 Composition
120
-
121
- - **Template** (e.g., `Pin.template.html`):
122
- Defines DOM structure (a `.icon` container, pinned/unpinned SVGs, etc.).
123
-
124
- - **Style** (e.g., `Pin.style.css`):
125
- Encapsulates appearance, including hover effects, pinned/unpinned icon transitions.
126
-
127
- - **Class** (`Pin.ts`):
128
- Extends a base component class to handle lifecycle hooks, Shadow DOM creation, attribute reflection, etc.
129
-
130
- > **Separation of Concerns**
131
- >
132
- > - **HTML** for structure
133
- > - **CSS** for presentation
134
- > - **TypeScript** for behavior
135
-
136
- ### 3.2 Class Lifecycle
137
-
138
- Lifecycle methods are implemented in the base class and extended by the **Pin** component:
139
-
140
- - **`connectedCallback()`**
141
-
142
- 1. Creates a Shadow DOM.
143
- 2. Clones the HTML template into the Shadow Root.
144
- 3. Inserts a `<link>` for scoped CSS.
145
- 4. Initializes default states (`visible`, `status`).
146
- 5. Sets up event listeners (e.g., on click).
147
-
148
- - **`disconnectedCallback()`**
149
- - Removes event listeners and cleans up references.
150
-
151
- ---
152
-
153
- ## 4. Core Concepts: State, Operations, and Events
154
-
155
- After seeing the pin in action, the following sections explain **how** it works internally.
156
-
157
- ### 4.1 State
158
-
159
- The **Pin** component uses both **internal properties** and **DOM attributes** to manage its state. This ensures consistency whether you modify the pin via script or HTML attributes.
160
-
161
- #### 4.1.1 Definition
162
-
163
- - **`visible`** (`yes` | `no`)
164
-
165
- - Whether the pin is displayed.
166
- - **Not-initialized** by default, meaning the component reverts to an internal default (`yes`) if `visible` is absent.
167
-
168
- - **`status`** (`pinned` | `unpinned`)
169
- - Whether the pin is pinned or unpinned.
170
- - **Initialized** by default, so if `<pin-button status="pinned">` is found at startup, it remains pinned initially.
171
-
172
- #### 4.1.2 Internal vs. Attribute-Driven State
173
-
174
- 1. **Internal State**
175
-
176
- ```typescript
177
- private _visible: Visibility = Visible.YES;
178
- private _status: Statuses = Status.UNPINNED;
179
- ```
180
-
181
- - Predictable defaults decoupled from external attributes.
182
-
183
- 2. **Attribute-Driven State**
184
- ```typescript
185
- public get visible(): Visibility {
186
- return this.hasAttribute(Attribute.VISIBLE)
187
- ? (this.getAttribute(Attribute.VISIBLE) as Visibility)
188
- : this._visible;
189
- }
190
- public set visible(visible: Visibility) {
191
- visible = visible || Visible.YES; // fallback
192
- if (this._visible !== visible) {
193
- this._visible = visible;
194
- visible === Visible.YES && this.removeAttribute(Attribute.VISIBLE);
195
- visible === Visible.NO && this.setAttribute(Attribute.VISIBLE, visible);
196
- }
197
- }
198
- ```
199
- - Keeps `_visible` in sync with `[visible="no"]` if you set it in HTML or JS.
200
-
201
- #### 4.1.3 Lifecycle & Attribute Handlers
202
-
203
- - `_initialize()` sets internal defaults on connect.
204
- - `attributeChangedCallback()` invokes `_attributeHandlers`, updating state when external attributes change.
205
-
206
- #### 4.1.4 Usage Tips
207
-
208
- - **Fallback**: Removing `[visible="no"]` reverts to `YES`.
209
- - **Clean DOM**: If `visible` is `YES`, no attribute is present.
210
-
211
- ---
212
-
213
- ### 4.2 Operations
214
-
215
- The **Pin** component’s imperative API manipulates state, which in turn updates the DOM and triggers events.
216
-
217
- #### 4.2.1 Definition
218
-
219
- 1. `hide()` → `visible="no"`
220
- 2. `show()` → `visible="yes"`
221
- 3. `pin()` → `status="pinned"`
222
- 4. `unpin()` → `status="unpinned"`
223
- 5. `toggle()` → flips between pinned/unpinned
224
-
225
- #### 4.2.2 Example
226
-
227
- ```typescript
228
- public toggle = () => (
229
- this.status = this.status === Status.PINNED ? Status.UNPINNED : Status.PINNED
230
- );
231
- ```
232
-
233
- ---
234
-
235
- ### 4.3 Events
236
-
237
- The **Pin** component broadcasts custom events when its internal state changes.
238
-
239
- #### 4.3.1 Definition
240
-
241
- - **`onhide`**: Fired when going from visible to hidden.
242
- - **`onshow`**: Fired when going from hidden to visible.
243
- - **`onpin`**: Fired when going from unpinned to pinned.
244
- - **`onunpin`**: Fired when going from pinned to unpinned.
245
- - **`on`**: A catch-all for any of the above changes.
246
-
247
- #### 4.3.2 Usage Tips
248
-
249
- - Assign a handler:
250
-
251
- ```js
252
- pin.onpin = (event) => console.log(event.detail.status);
253
- ```
254
-
255
- - Or use standard DOM events:
256
-
257
- ```js
258
- pin.addEventListener("onpin", (e) => {
259
- // ...
260
- });
261
- ```
262
-
263
- ---
264
-
265
- ## 5. Development Workflow
266
-
267
- Below is a recommended workflow for building, testing, documenting, and publishing the Pin component:
268
-
269
- ### 5.1 From Specifications to Implementation
270
-
271
- 1. **Define Specs** (states, operations, events).
272
- 2. **Implement** in TypeScript (reflect states as attributes, dispatch events on changes).
273
- 3. **Link** the final compiled JS or leverage import maps.
274
-
275
- ### 5.2 Testing
276
-
277
- - **Unit Tests** using Karma + Jasmine or real-time Wallaby.
278
- - Ensure coverage for states, operations, events.
279
- - Generate coverage:
280
-
281
- ```bash
282
- npm test
283
- ```
284
-
285
- ### 5.3 Import Maps
286
-
287
- ```html
288
- <script type="importmap">
289
- {
290
- "imports": {
291
- "pin-component": "./dist/Pin.js"
292
- }
293
- }
294
- </script>
295
- <script type="module">
296
- import "pin-component";
297
- </script>
298
- ```
299
-
300
- ### 5.4 Documentation (Typedoc)
301
-
302
- ```bash
303
- npm run document
304
- ```
305
-
306
- - Auto-generates API docs from TypeScript annotations.
307
-
308
- ### 5.5 Publishing & Versioning
309
-
310
- 1. **Build**:
311
-
312
- ```bash
313
- npm run build
314
- ```
315
-
316
- → outputs `dist/`.
317
-
318
- 2. **Bump Version**:
319
-
320
- ```bash
321
- npm version [major|minor|patch]
322
- ```
323
-
324
- 3. **Publish**:
325
- ```bash
326
- npm publish
327
- ```
328
- to npm or private registry.
329
-
330
- ---
331
-
332
- ## 6. Best Practices & Extensibility
333
-
334
- 1. **Descriptive Naming**
335
-
336
- - `pinned/unpinned` is domain-friendly for toggles.
337
-
338
- 2. **Accessibility**
339
-
340
- - Consider ARIA attributes and keyboard interactions if you want `<pin-button>` fully accessible as a toggle/button.
341
-
342
- 3. **Testing**
343
-
344
- - Simulate user clicks/touches to confirm correct state changes and event dispatch.
345
-
346
- 4. **Documentation**
347
-
348
- - Provide real usage snippets (like in the Quick Start) for developer onboarding.
349
-
350
- 5. **Publishing**
351
- - Use semantic versioning to manage features/breaking changes.
352
- - Employ CI/CD for automated build/test/publish.
353
-
354
- ---
355
-
356
- ## 7. Conclusion
357
-
358
- By showing you how to **pin** or **unpin** the component immediately (in the Usage Walkthrough), we’ve demonstrated its core features. Internally, the **Pin** component’s **State**, **Operations**, and **Events** ensure predictable, event-driven functionality. Follow the **development workflow** for specs, build, test, docs, and publishing to confidently integrate `<pin-button>` into your projects.
359
-
360
- ---
361
-
362
- ### License
363
-
364
- > This document is released under the **Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International** (CC BY-NC-SA 4.0) license.
365
- > For more details, please visit the [license agreement](https://creativecommons.org/licenses/by-nc-sa/4.0/).
1
+ # Pin Component Documentation
2
+
3
+ Below is a **comprehensive** document detailing the **Pin** component’s architecture, usage, and developer workflow. It prioritizes a **Quick Start** so you can see the pin in action right away, then dives into **State**, **Operations**, **Events**, and more advanced topics.
4
+
5
+ ---
6
+
7
+ ## 1. Introduction
8
+
9
+ The **Pin** component provides a toggleable element that can be pinned/unpinned and hidden/shown via both **imperative** and **declarative** APIs. It leverages custom Web Component features, including Shadow DOM, custom events, and attribute reflection for a clean, modular design.
10
+
11
+ ### 1.1 Installation & Setup
12
+
13
+ 1. **Clone the Repository**
14
+
15
+ ```bash
16
+ git clone <repository-url>
17
+ cd pin-component
18
+ ```
19
+
20
+ 2. **Install Dependencies**
21
+
22
+ ```bash
23
+ npm install
24
+ ```
25
+
26
+ 3. **Run Tests (Optional)**
27
+
28
+ ```bash
29
+ npm test
30
+ ```
31
+
32
+ - Ensures everything is working as expected before you start.
33
+
34
+ 4. **Start Local Server**
35
+ ```bash
36
+ npm run serve
37
+ ```
38
+ - This runs a local development server, making `<pin-button>` available in your browser.
39
+
40
+ ---
41
+
42
+ ## 2. Quick Start Usage Walkthrough
43
+
44
+ This walkthrough demonstrates how to interact with `<pin-button>` right after installation, letting you see how the pin behaves before exploring its internal design.
45
+
46
+ 1. **Open** the served page in your browser.
47
+
48
+ - You should see a `<pin-button>` component displayed.
49
+
50
+ 2. **Open the Developer Tools**, select the **Console**.
51
+
52
+ 3. **Get a reference** to the component:
53
+
54
+ ```js
55
+ const pin = document.querySelector("pin-button");
56
+ ```
57
+
58
+ 4. **Create a handler** for when the pin is pinned:
59
+
60
+ ```js
61
+ const onpin = (event) => {
62
+ console.log("Pin was pinned:", event.detail.status);
63
+ };
64
+ ```
65
+
66
+ 5. **Assign** that handler to the `onpin` property:
67
+
68
+ ```js
69
+ pin.onpin = onpin;
70
+ ```
71
+
72
+ 6. **Pin** the component imperatively:
73
+
74
+ ```js
75
+ pin.pin();
76
+ ```
77
+
78
+ - This changes `status` from `unpinned` to `pinned`.
79
+ - Observe the console output: `"Pin was pinned: pinned"`.
80
+
81
+ 7. **Inspect** the `<pin-button>` in the **Elements** tab:
82
+
83
+ ```html
84
+ <pin-button status="pinned"></pin-button>
85
+ ```
86
+
87
+ 8. **Manually change** the `status` attribute to `"unpinned"`
88
+
89
+ - Notice the pin’s icon and internal state update.
90
+
91
+ 9. **Check** the current status in the console:
92
+
93
+ ```js
94
+ pin.status; // Should return "unpinned"
95
+ ```
96
+
97
+ 10. **Click** the `<pin-button>` in the UI
98
+
99
+ - By default, clicking toggles it between `pinned` and `unpinned`.
100
+ - If pinned, the `onpin` event is fired (if you have a listener).
101
+
102
+ 11. **Check** the status again:
103
+
104
+ ```js
105
+ pin.status; // "pinned" or "unpinned"
106
+ ```
107
+
108
+ > **Visibility**
109
+ >
110
+ > - You can similarly call `pin.hide()` or `pin.show()` to toggle the `visible` state.
111
+ > - Watch for `onhide` or `onshow` events in the console.
112
+
113
+ For more details on **States**, **Operations**, and **Events**, consult the sections below or check the generated **API documentation** (see `npm run document` instructions).
114
+
115
+ ---
116
+
117
+ ## 3. Architectural Overview
118
+
119
+ ### 3.1 Composition
120
+
121
+ - **Template** (e.g., `Pin.template.html`):
122
+ Defines DOM structure (a `.icon` container, pinned/unpinned SVGs, etc.).
123
+
124
+ - **Style** (e.g., `Pin.style.css`):
125
+ Encapsulates appearance, including hover effects, pinned/unpinned icon transitions.
126
+
127
+ - **Class** (`Pin.ts`):
128
+ Extends a base component class to handle lifecycle hooks, Shadow DOM creation, attribute reflection, etc.
129
+
130
+ > **Separation of Concerns**
131
+ >
132
+ > - **HTML** for structure
133
+ > - **CSS** for presentation
134
+ > - **TypeScript** for behavior
135
+
136
+ ### 3.2 Class Lifecycle
137
+
138
+ Lifecycle methods are implemented in the base class and extended by the **Pin** component:
139
+
140
+ - **`connectedCallback()`**
141
+
142
+ 1. Creates a Shadow DOM.
143
+ 2. Clones the HTML template into the Shadow Root.
144
+ 3. Inserts a `<link>` for scoped CSS.
145
+ 4. Initializes default states (`visible`, `status`).
146
+ 5. Sets up event listeners (e.g., on click).
147
+
148
+ - **`disconnectedCallback()`**
149
+ - Removes event listeners and cleans up references.
150
+
151
+ ---
152
+
153
+ ## 4. Core Concepts: State, Operations, and Events
154
+
155
+ After seeing the pin in action, the following sections explain **how** it works internally.
156
+
157
+ ### 4.1 State
158
+
159
+ The **Pin** component uses both **internal properties** and **DOM attributes** to manage its state. This ensures consistency whether you modify the pin via script or HTML attributes.
160
+
161
+ #### 4.1.1 Definition
162
+
163
+ - **`visible`** (`yes` | `no`)
164
+
165
+ - Whether the pin is displayed.
166
+ - **Not-initialized** by default, meaning the component reverts to an internal default (`yes`) if `visible` is absent.
167
+
168
+ - **`status`** (`pinned` | `unpinned`)
169
+ - Whether the pin is pinned or unpinned.
170
+ - **Initialized** by default, so if `<pin-button status="pinned">` is found at startup, it remains pinned initially.
171
+
172
+ #### 4.1.2 Internal vs. Attribute-Driven State
173
+
174
+ 1. **Internal State**
175
+
176
+ ```typescript
177
+ private _visible: Visibility = Visible.YES;
178
+ private _status: Statuses = Status.UNPINNED;
179
+ ```
180
+
181
+ - Predictable defaults decoupled from external attributes.
182
+
183
+ 2. **Attribute-Driven State**
184
+ ```typescript
185
+ public get visible(): Visibility {
186
+ return this.hasAttribute(Attribute.VISIBLE)
187
+ ? (this.getAttribute(Attribute.VISIBLE) as Visibility)
188
+ : this._visible;
189
+ }
190
+ public set visible(visible: Visibility) {
191
+ visible = visible || Visible.YES; // fallback
192
+ if (this._visible !== visible) {
193
+ this._visible = visible;
194
+ visible === Visible.YES && this.removeAttribute(Attribute.VISIBLE);
195
+ visible === Visible.NO && this.setAttribute(Attribute.VISIBLE, visible);
196
+ }
197
+ }
198
+ ```
199
+ - Keeps `_visible` in sync with `[visible="no"]` if you set it in HTML or JS.
200
+
201
+ #### 4.1.3 Lifecycle & Attribute Handlers
202
+
203
+ - `_initialize()` sets internal defaults on connect.
204
+ - `attributeChangedCallback()` invokes `_attributeHandlers`, updating state when external attributes change.
205
+
206
+ #### 4.1.4 Usage Tips
207
+
208
+ - **Fallback**: Removing `[visible="no"]` reverts to `YES`.
209
+ - **Clean DOM**: If `visible` is `YES`, no attribute is present.
210
+
211
+ ---
212
+
213
+ ### 4.2 Operations
214
+
215
+ The **Pin** component’s imperative API manipulates state, which in turn updates the DOM and triggers events.
216
+
217
+ #### 4.2.1 Definition
218
+
219
+ 1. `hide()` → `visible="no"`
220
+ 2. `show()` → `visible="yes"`
221
+ 3. `pin()` → `status="pinned"`
222
+ 4. `unpin()` → `status="unpinned"`
223
+ 5. `toggle()` → flips between pinned/unpinned
224
+
225
+ #### 4.2.2 Example
226
+
227
+ ```typescript
228
+ public toggle = () => (
229
+ this.status = this.status === Status.PINNED ? Status.UNPINNED : Status.PINNED
230
+ );
231
+ ```
232
+
233
+ ---
234
+
235
+ ### 4.3 Events
236
+
237
+ The **Pin** component broadcasts custom events when its internal state changes.
238
+
239
+ #### 4.3.1 Definition
240
+
241
+ - **`onhide`**: Fired when going from visible to hidden.
242
+ - **`onshow`**: Fired when going from hidden to visible.
243
+ - **`onpin`**: Fired when going from unpinned to pinned.
244
+ - **`onunpin`**: Fired when going from pinned to unpinned.
245
+ - **`on`**: A catch-all for any of the above changes.
246
+
247
+ #### 4.3.2 Usage Tips
248
+
249
+ - Assign a handler:
250
+
251
+ ```js
252
+ pin.onpin = (event) => console.log(event.detail.status);
253
+ ```
254
+
255
+ - Or use standard DOM events:
256
+
257
+ ```js
258
+ pin.addEventListener("onpin", (e) => {
259
+ // ...
260
+ });
261
+ ```
262
+
263
+ ---
264
+
265
+ ## 5. Development Workflow
266
+
267
+ Below is a recommended workflow for building, testing, documenting, and publishing the Pin component:
268
+
269
+ ### 5.1 From Specifications to Implementation
270
+
271
+ 1. **Define Specs** (states, operations, events).
272
+ 2. **Implement** in TypeScript (reflect states as attributes, dispatch events on changes).
273
+ 3. **Link** the final compiled JS or leverage import maps.
274
+
275
+ ### 5.2 Testing
276
+
277
+ - **Unit Tests** using Karma + Jasmine or real-time Wallaby.
278
+ - Ensure coverage for states, operations, events.
279
+ - Generate coverage:
280
+
281
+ ```bash
282
+ npm test
283
+ ```
284
+
285
+ ### 5.3 Import Maps
286
+
287
+ ```html
288
+ <script type="importmap">
289
+ {
290
+ "imports": {
291
+ "pin-component": "./dist/Pin.js"
292
+ }
293
+ }
294
+ </script>
295
+ <script type="module">
296
+ import "pin-component";
297
+ </script>
298
+ ```
299
+
300
+ ### 5.4 Documentation (Typedoc)
301
+
302
+ ```bash
303
+ npm run document
304
+ ```
305
+
306
+ - Auto-generates API docs from TypeScript annotations.
307
+
308
+ ### 5.5 Publishing & Versioning
309
+
310
+ 1. **Build**:
311
+
312
+ ```bash
313
+ npm run build
314
+ ```
315
+
316
+ → outputs `dist/`.
317
+
318
+ 2. **Bump Version**:
319
+
320
+ ```bash
321
+ npm version [major|minor|patch]
322
+ ```
323
+
324
+ 3. **Publish**:
325
+ ```bash
326
+ npm publish
327
+ ```
328
+ to npm or private registry.
329
+
330
+ ---
331
+
332
+ ## 6. Best Practices & Extensibility
333
+
334
+ 1. **Descriptive Naming**
335
+
336
+ - `pinned/unpinned` is domain-friendly for toggles.
337
+
338
+ 2. **Accessibility**
339
+
340
+ - Consider ARIA attributes and keyboard interactions if you want `<pin-button>` fully accessible as a toggle/button.
341
+
342
+ 3. **Testing**
343
+
344
+ - Simulate user clicks/touches to confirm correct state changes and event dispatch.
345
+
346
+ 4. **Documentation**
347
+
348
+ - Provide real usage snippets (like in the Quick Start) for developer onboarding.
349
+
350
+ 5. **Publishing**
351
+ - Use semantic versioning to manage features/breaking changes.
352
+ - Employ CI/CD for automated build/test/publish.
353
+
354
+ ---
355
+
356
+ ## 7. Conclusion
357
+
358
+ By showing you how to **pin** or **unpin** the component immediately (in the Usage Walkthrough), we’ve demonstrated its core features. Internally, the **Pin** component’s **State**, **Operations**, and **Events** ensure predictable, event-driven functionality. Follow the **development workflow** for specs, build, test, docs, and publishing to confidently integrate `<pin-button>` into your projects.
359
+
360
+ ---
361
+
362
+ ### License
363
+
364
+ > This document is released under the **Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International** (CC BY-NC-SA 4.0) license.
365
+ > For more details, please visit the [license agreement](https://creativecommons.org/licenses/by-nc-sa/4.0/).