diff --git a/manual/FAQ.md b/manual/FAQ.md new file mode 100644 index 0000000..111af8b --- /dev/null +++ b/manual/FAQ.md @@ -0,0 +1,22 @@ +# FAQ +## Is Autopilot open source? + +Yes. All Webrecorder tools are licensed under open source licenses. + +From the beginning, the goal of Webrecorder has been to build quality open source tools enable ‘web archiving for all’ to allow anyone with a browser to create their own web archives, and to accurately replay them at a later time. + +## What does Autopilot cost? + +Autopilot is free to use. + +## What platforms does Autopilot run on? + + + +## How can I contribute to Autopilot? + +Read the chapter on [Hacking Autopilot](./chapter3.md) for a guide on contributing to Autopilot. We suggest that beginner developers take a look at [Chapter 2](./chapter2.md) for a simpler overview of how Autopilot works. + +##Glossary of Terms + + diff --git a/manual/bug-report.md b/manual/bug-report.md new file mode 100644 index 0000000..44545b7 --- /dev/null +++ b/manual/bug-report.md @@ -0,0 +1,15 @@ +#Bug Report Template +Fill out this template when reporting bugs. + +##Description + +##Stepts to reproduce +1. +2. +3. + +##Current behavior (bug) + +##Expected behavior (correct) + +##Additional information \ No newline at end of file diff --git a/manual/chapter1.md b/manual/chapter1.md new file mode 100644 index 0000000..a0ad783 --- /dev/null +++ b/manual/chapter1.md @@ -0,0 +1,113 @@ +# Chapter 1 + + +## What is web archiving? + +Web archiving is the process of recording web resources. Various elements of the website such as HTML, scripts, images, videos, etc. can be recorded to preserve as much of the original resource as possible. By creating dynamic archives that provide a user with the same experience they would have if they accessed the original site, web archives can give much more information than a static screenshot. + +Web archives may be utilized by future researchers, historians and the general public. + +## Why Autopilot? + +Autopilot is a tool that navigates a website similarly to how a human would, doing things like scrolling, clicking buttons, and playing videos. These actions executed through functions called "behaviors." Because Autopilot can go through the technically complicated aspects of a website, it is useful for recording high-fidelity websites. Furthermore, Autopilot is designed to be accessible for anyone to use, and anyone with little javascript knowledge to contribute to. This makes webarchiving available to everyone. + +# Autopilot basics +Autopilot uses [behaviors](https://github.com/webrecorder/behaviors/blob/master/manual/behaviors.md) to collect metadata from websites. Behaviors are Javascript modules which perform a series of actions on a webpage in order to collect information. + +## Installing Autopilot + +To use this project you must first install its dependencies. You can do this via a package manager like [Yarn](https://classic.yarnpkg.com/en/docs/install/#mac-stable) or [npm](https://www.npmjs.com/). + +``` +$ yarn install +# or "npm install" +``` + +To install Autopilot, use Terminal to clone the Webrecorder repository: + +**You must be using node 12~** + +``` +1. `git clone https://github.com/webrecorder/behaviors.git` +2. `cd behaviors` +3. `yarn build-watch` +4. `open new terminal window` +5. `bash scripts/init.sh` +``` +If you wish to use this project via Docker, install [Docker](https://docs.docker.com/get-docker/) and [Docker Compose](https://docs.docker.com/compose/install/). + +``` +3. docker-compose build +4. docker-compose up -d +``` + +The Autopilot instance can be accessed in the browser at `http://localhost:8089`. + +# Running Behaviors +1. In order to run the behaviors you will first need to build them: +``` +npm run generate-runnable-behaviors + +``` + +2. Then, go into the dist directory. +``` +cd dist +``` + +3. In the dist directory you will see behavior files. Open the behavior file you want and copy the code. +``` +open [filename] +``` + +4. Copy all of the behavior code and paste it into the developer console of a webpage. The console can be accessed in Chrome using the shortcut: Option + ⌘ + J (on macOS), or Shift + CTRL + J (on Windows/Linux). + +You can also run behaviors using the CLI: + +## CLI and API + +The cli provides two commands `API` and `behaviors` and each command has its own options. + +## Behaviors command + +Execute `./bin/cli behaviors -b` to build the behaviors made available. This will build the behaviors using the behavior config file located in the root of this project. + +The built behaviors, along with a behavior metadata file (`behaviorMetadata.js`), can be found in the `dist` directory which will be created for you if it does not exist in the root of this project. + +## API command + +To run the behavior API server execute `./bin/cli api --build-behaviors`. + +This will start the API server after all behaviors provided by this project have been built. + +If you have already built the behaviors using the `behaviors` command provided by the cli then you may omit the `--build-behaviors` flag. + + +Some configuration of the API server can be done via the environment variables listed below + +* `BEHAVIOR_API_HOST`: the host the api server will use (e.g. 127.0.0.1) +* `BEHAVIOR_API_PORT`: the port the api server will listen on (e.g. 3030) +* `WR_BEHAVIOR_DIR`: path to the directory containing the built behaviors +* `WR_BEHAVIOR_METADATA_PATH`: path to the behavior metadata file +* `BUILD_BEHAVIORS`: should the api server build the behaviors before starting + + + +# Docker +If you would like, you can use Docker to run Autopilot. + +To build the wr-behaviors docker image (`webrecorder/behaviors:latest`) execute `docker-compose build`. + +The image created is suitable for building behaviors and running the behavior api server. + +The default configuration of the image is to run the api server, however you can substitute the default command with any of the cli commands listed previously. + +For more information please consult the provided `Dockerfile` and `docker-compose.yml` files. + + + + + diff --git a/manual/chapter2.md b/manual/chapter2.md new file mode 100644 index 0000000..8a98adf --- /dev/null +++ b/manual/chapter2.md @@ -0,0 +1,305 @@ +# Chapter 2: Creating your first behavior + +A behavior is a [Javascript Module](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) which executes a series of actions that collect some information (metadata) about a webpage. Before you create your first behavior, you should first take a look at the [Pre-Made Behaviors](https://github.com/webrecorder/behaviors/blob/master/manual/premade-behaviors.md). This will give you a basic idea of what kind of behaviors have already been created. + +## Setting up your file +Once you have an idea of what you want your behavior to do, clone the webrecorder repository so that you can work locally on your computer. + +1. `mkdir webrecorder` (or skip steps 1-2 and use an already existing directory) +2. `cd webrecorder` +3. `git clone https://github.com/webrecorder/behaviors.git` +4. `cd behaviors` + +You should also download a package manager like yarn or npm, and make sure that you are using the correct version. +``` +$ yarn install +# or "npm install" +``` + +To check your version of npm, type the command `npm --version`. You can check the [npm website](https://www.npmjs.com/package/npm?activeTab=versions) to see what the latest version is. + +You should also check to make sure that your version of node is 12 or above. + +### Getting started using the CLI + +You should now create a Javascript file for your new behavior. You can do this using the CLI. + +The `newBehavior` command provides a simple way to create a new behavior by generating a new file in the behavior directory containing the required boiler plate. + +Executing `./bin/cli newBehavior awesomeBehavior` will create a new behavior file `awesomeBehavior.js` located in the behavior directory. + + +### Format + +Every behavior has: + +1. a **default export** that is an [async generator function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of#Iterating_over_async_generators) or a function returning an [async iterator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of#Iterating_over_async_generators). This is the function that will retrieve the metadata we want from the webpage. + +```js +export detault async function* myBehavior(cliAPI){...} +``` + +More details on how the default export should be written can be found under the [Default Export](#default-export) section. + +2. an export named ***metadata*** that is an object + + Details: the ***metadata*** object gives information about the behavior, such as when it was last updated, whether it's functional, its display name, etc. + + Example of expected format: +```js + export const metadata = { ... }; +``` + +More details on how the metadata object should be written can be found under the [Metadata](#metadata) section. + +3. an export named **isBehavior**. + + Details: **isBehavior** is a constant that you will flag as **true** when the file is complete and ready to be used. Otherwise, while the file is still in progress, keep it as **false**. + + Example of expected format: +```js +export const isBehavior = true; +``` + + +It's important to note that the tools will not recognize that the behavior is ready for use and valid if any of these three main components (the default export, **isBehavior**, and **metadata**) are missing. + +### Metadata +A behavior's exported metadata object is used to: + +- describe how the behavior should be matched to the pages it is written for +- provide an overview of what the behavior does +- provide a more specific name associated with it when querying for it using the behavior api +- embed any additional information about the behavior + +With those usages in mind, every metadata object is expected to have the following properties: + +- **name** (string): the name for your behavior to be used when querying the behavior API for it by name +- **description** (string): a description of the behavior +- **match** (object): how the behavior will be matched to the page(s) it is written for + +The **match** object has two variations, but you will probably only need to know the first. + +```js +// variation 1 +export const metadata = { + name: 'the name of your behavior', + match: { + regex: /a regular expression dictating the URL the behavior will run on/, + }, + description: 'an description of what your behavior does', +}; +``` +The first variation of `match`, shown above, defines a single property `regex` that is an JavaScript [RegExp](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp). The behavior using variation one is considered matched to an URL when the regular expression, defined in the `regex` property of match, matches the URL. + +The second variation of `match` is a bit more advanced and lets you compare your URL to multiple sub URLs. You can get more information on that in [chapter 3](./chapter3). + +### Default Export + +#### Asyncronous Generator Functions + +The purpose of an [asyncronous generator function](https://thecodebarbarian.com/async-generator-functions-in-javascript.html#:~:text=Async%20generator%20functions%20behave%20similarly,()%20function%20returns%20a%20promise.) is to collect data from a source that has too much data to return all at once (or would take too long to return all at once). Instead, the generator is a function that returns an object with a next() method on it. The programmer can keep calling next() until all of the data is received. An asynchronous generator function uses promises for the same purpose (promises will be expanded upon in the following section). + +The primary reasons that a behavior's **default export** is required to be an async generator function or a function returning an [async iterator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator) are: + +- async generators are widely supported in Javascript +- they provide a simple way to run the behavior in the browser or through [browsertrix](https://github.com/webrecorder/browsertrix) +- they allow information about the behavior and its state to be easily retrieved by code executing the behavior + +Consider the following example: + +```js +import * as lib from '../lib'; + +export default async function* myBehavior(cliAPI) { + // behavior code will be developed here +} + +export const metadata = { + name: 'myBehavior', + match: { + regex: /^(?:https?:\/\/(?:www\.)?)?:myAwesomeWebSite.com.*$/, + }, + description: 'It does really cool stuff', +}; + +export const isBehavior = true; +``` + +In this example, `myBehavior` is an asynchronous generator function that's being exported for our behavior and this behavior would work for any website with myAwesomeWebSite.com in its name (notice the regex for the matching above). Much of this boiler plate code shown above has been generated automatically by the cli command +`./bin/cli newBehavior [behaviorName]`. + +#### Promises + +Next, you may have notticed looking over some of the behavior documentation that many of the functions return [Promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). + +Now, without turning into a JavaScript tutorial, the only thing you need to know about promises is that they can be awaited, that is to say you can await for their completion. + +This comes in handy when you want to wait for the the document's state to become ready since the pages of myAwesomeWebSite.com take a long time to load and can be done as easily as shown in `step 1`. This is the beginning of the code that will go in the default async function. + +```js +// step 1, wait for the page to complete loading +await lib.domCompletePromise(); +``` + +Now that we know the browser has fully loaded the page, we can safely start executing behaviors on the page. + +The next step is to initialize our state and report it, which is done by yielding a value as shown in `step 2`, where state contains the number of videos played. + +```js +// step 2, initialize state and return it +const state = { videosPlayed: 0 }; +yield lib.stateWithMsgNoWait('Document ready!', state); +``` + +The function `lib.stateWithMsgNoWait` indicates to the code executing the behavior that it has an update to report and that it does not have to wait. + +If the behavior was being run by [browsertrix](https://github.com/webrecorder/browsertrix) and the other function `lib.stateWithMsgWait` was used, browsertrix would have waited until the HTTP requests made by the page had significantly slowed down (no request made for set period of time) before executing further code in the function. However, since we use the *no wait* variant, the behavior will immediately return state. + +When you `yield` a value from the behavior you can consider the behavior paused until the runner initiates the `next()` action. + +Additionally, it should be noted that the second argument supplied to `lib.stateWithMsgNoWait` is optional but useful for reporting to yourself more detailed information about the state of your behavior. + +Continuing on with the creation of our behavior, let us assume that the page that the behavior is operating in has a list of videos we want to play. Our behavior will generate the next video to play each iteration. + +We can accomplish this as shown in `step 3`. + +```js +// step 3 +for (const videoListItem of lib.childElementIterator(lib.id('videos'))) { + // videoListItem is a child of the element with id == 'videos' + // that has a video as child element + const videoWasPlayed = await lib.selectAndPlay('video', videoListItem); + if (videoWasPlayed) { + // increment our states counter for number of videos played + state.videosPlayed += 1; + // let ourselves know we played a video + yield lib.stateWithMsgNoWait('Played a video!', state); + } else { + yield lib.stateWithMsgNoWait('Failed to play a video using the standard DOM methods', state); + } +} +return lib.stateWithMsgNoWait('Done!', state); +``` + +In `step 3` we use the function `childElementIterator` that returns an iterator over the child elements of the supplied parent element. Then for each child of the element with `id="videos"` we: + +- select the video element that is a descendant of the `videoListItems` and play the video +- increment the number of videos played in our behavior's state +- let ourselves know that we played a video + +Also seen in `step 3` is the usage keyword `yield*`. + +`yield*` means that we are yielding another generator, that is to say all actions of the generator are to be treated as if we yielded them ourselves. + +In short, `step 3` can be described as playing a video contained in every child of the element with `id == video`, and once we have played all the videos on the page return a message with our final state from the behavior. + +The full behavior is shown below: + +```js +import * as lib from '../lib'; + +export default async function* myBehavior(cliAPI) { + // behavior code + // step 1 + await lib.domCompletePromise(); + // step 2 + const state = { videosPlayed: 0 }; + yield lib.stateWithMsgNoWait('Document ready!', state); + // step 3 + for (const videoListItem of lib.childElementIterator(lib.id('videos'))) { + // videoListItem is a child of the element with id == 'videos' + // that has a video as child element + const videoWasPlayed = await lib.selectAndPlay('video', videoListItem); + if (videoWasPlayed) { + // increment our states counter for number of videos played + state.videosPlayed += 1; + // let ourselves know we played a video + yield lib.stateWithMsgNoWait('Played a video!', state); + } else { + yield lib.stateWithMsgNoWait('Failed to play a video using the standard DOM methods', state); + } + } + return lib.stateWithMsgNoWait('Done!', state); +} + +export const metadata = { + name: 'myBehavior', + match: { + regex: /^(?:https?:\/\/(?:www\.)?)?:myAwesomeWebSite.com.*$/, + }, + description: 'It does really cool stuff', +}; + +export const isBehavior = true; +``` + +## Running your behavior +The easiest way to run your behavior is to copy all of the behavior code and paste it into the developer console of a webpage. + +The console can be accessed in Chrome using the shortcut: Option + ⌘ + J (on macOS), or Shift + CTRL + J (on Windows/Linux). + +###Runner CLI +You can also use the runner CLI to run your behavior. The runner command allows you to automatically run a behavior on a specified URL using a Chrome/Chromium browser installed on your machine. + +`$ ./bin/cli help runner` + +Please note that in order to provide automatic running of behaviors, this command must be able to launch the Chrome/Chromium browser. In other words, an already running instance of Chrome/Chromium can not be used. + +First, you will need to create a config file (yaml format) to use the runner. A run config file is provided for you and can found in the root of this project (`behavior-run-config.yml`). + +The file will look like this: +```yaml +behaviors: ./behaviors +lib: ./lib +build: ./build +dist: ./dist +tsconfig: ./tsconfig.json +metadata: ./dist/behaviorMetadata.js +``` + +By using the provided configuration file [`behavior-run-config.yml`](./behavior-run-config.yml) all that you have to do is change two fields: + +1. `behaviors`: the path to your new behavior in the behavior directory of this project +2. `url`: the url of the page your behavior should be run in + +Now you can start the build and run process by executing the following from the root directory of this project: + +`./bin/cli runner -c behavior-run-config.yml` + +The command will launch a Chrome/Chromium browser installed on your computer, build the behavior, and then run it until completion. + +If any changes are made to the behavior or any of the files it includes while the behavior is being run, it will be rebuilt and re-run automatically. + +## Testing your first behavior + +Blocked by [PR 63](https://github.com/webrecorder/behaviors/pull/63) + + + +## Fixing a broken behavior + +A behavior is broken when it doesn't work as expected or like it used to. Behaviors have to be fixed sometimes as websites can change at anytime. For example, a website might change its css and html names and classes, or how the Javascript behaves when you scroll. If a behavior depends on something that has changed, it may stop working. + +Here are the steps to fixing a broken behavior: + +1. Find the file of the behavior +2. Run the behavior +3. Note the output and check for console errors +4. Update the offending lines +5. [Create a fork](https://docs.github.com/en/github/getting-started-with-github/fork-a-repo) for your contributions +6. Commit and push your changes to your local branch +7. Create a pull request against the master branch + +You will then receive feedback on your work, which you can respond to in the pull request. + + + + + diff --git a/manual/chapter3.md b/manual/chapter3.md new file mode 100644 index 0000000..bd0ccd0 --- /dev/null +++ b/manual/chapter3.md @@ -0,0 +1,163 @@ +# Hacking Autopilot + +## Contributing to Autopilot + +We welcome contributions from anyone with beginning to advanced programming knowledge. + +Please be advised that we have a [code of conduct](./code-of-conduct.md) that we expect all contributors to follow. + +### Reporting bugs +Bugs are tracked as [GitHub issues](https://guides.github.com/features/issues/). + +Use these steps to report a bug: +1. Determine which repository under which to report the problem +2. Perform a [search](https://github.com/search?q=is%3Aissue+user%3Awebrecorder) to check if the issue has already been reported +3. Use the [bug report template](./bug-report.md) to report the bug. + + + +### Advanced options + +#### postStep +The export `postStep` can be called after each action to convert the yielded results into the expected format. + +It is recommended that you use the library function `lib.buildCustomPostStepFn`if you want to perform some kind of action after each behavior step that is not directly tied to the running of the behavior. + +```js +export const postStep = lib.buildCustomPostStepFn(() => { ... }); +``` + +#### Metadata export: match +If you want to compare your URL to multiple sub URLs, you can use a different version of `match`. This version is shown below, and has the two properties `base` (RegExp) and `sub` (Array). + +The `base` regular expression is used as a generic test. If `base` matches a URL, the regular expressions in the `sub` array will be tested against the same URL. The behavior is considered matched to a URL when the `base` regular expression matches the URL and one of the `sub` regular expressions also matches the URL. + +```js +// variation 2 +export const metadata = { + name: 'the name of your behavior', + match: { + regex: { + base: /a regular expression dictating the base URL the behavior will run on/, + sub: [ + /an array of regular expressions dictating more specific parts of the base URL the behavior will run on/, + ], + }, + }, + description: 'a description of what your behavior does', +}; +``` +## Testing a behavior (Debugging) +Blocked by PR 63 (testing infrastructure) + +## Build System + +### Overview + +The behavior build process has three phases +- [Initialization](#initialization) +- [Collection](#collection) +- [Building](#building) + + +### Initialization + +Initialization has three steps +1. Ultimate build configuration +2. Building what resolution +3. Ensuring the necessary build directory structure exists + + +#### Ultimate build configuration + +The ultimate build configuration is created in combination with user supplied cli options using the following steps: + + 1. If a config was specified using `-c, --config`, the specified config will be used + 2. If the default config exists in the current working directory of the commands, the default config is used + 3. Otherwise the path to the behavior file or dir (`-b, --build [fileOrDir]`) is used and the six config values are set to the project defaults + +When a config file is used each of the six values from the config file are resolved as follows +- if the key exists and value is relative, make absolute by resolving it against the directory containing the config file +- if the key exists and is absolute, use key value +- if key does not exist use project default value + - build, dist: `/` + - lib, tsconfig: projects default value + - metadata: placed in current working directory + + +Once the ultimate build configuration has been created, the build process proceeds to the next step. + +#### Building what resolution + +The determination for what is being built is done using the value for the `-b, --build` cli option and that value can be one of two types: +- `boolean`: build all behaviors found in the value for the `behaviors` key from the supplied build config +- `string`: path to a directory containing behaviors or a single behavior to be built + +When the value for build is `boolean`: +- If the directory supplied via the `behaviors` config key exists, then what is being built is that directory and the initialization process contains to the next step +> [name=kyragaut] ^^ line 43 this doesn't make sense +- Otherwise, if the directory supplied via the `behaviors` config key does not exist the build process is ended + +When the value for build is a `string` and an absolute path: +- If the path exists, then what is being built is that directory or file and the initialization process contains to the next step +> [name=kyragaut] ^^ line 48 this doesn't make sense +- Otherwise, if the path does not exist the build process is ended + +When the value for build is a `string` and a relative path, it is resolved in the following order: +1. the value as is resolved using node's relative path resolution algorithm. Note this value is used by other steps if previous ones fail and is denoted as `resolvedPath` +2. the value as is joined with the supplied configs behavior dir or projects default behavior dir +3. the value as is joined with the the current working directory +4. `resolvedPath` is joined with the supplied configs behavior dir or projects default behavior dir +5. `resolvedPath` is joined with the current working directory + +If any of the absolute paths described above exist, then what is being built is the resolved path and the initialization process contains to the next step otherwise the build process is ended +> [name=kyragaut] ^^ line 59 this doesn't make sense + + +#### Ensuring the necessary build directory structure exists + +The final step in the initialization process is to ensure that the `build` and `dist` directories exist. + +These values may differ from the names used previously only when they are supplied by the user in a build config file. + +The `build` directory is used to hold intermediate files used by the build system in order to setup the behavior for final building and usage by other tools such as our own running system. + +Any setup in order to facilitate running the behavior is done here. + +The `dist` directory is where the built, bundled, behaviors are placed alongside their metadata if configured to do so. + + +### Collection + +The collection phase operates in one of two modes: +- `single behavior`: when the `what is being built` path resolves to file +- `multi-behavior`: when the `what is being built` path resolves to a directory + +The primary difference between modes is that `multi-behavior` mode considers every file contained in the directory and its descendant directories. + +Both modes use the same means in determining if a file is indeed a behavior which is as follows: +- the file is an es module +- has a `metadata` or `metaData` named export +- has an `isBehavior` named export + +Once the behavior(s) have been collected a report is printed stating how many behaviors were found and if any of the files considered partially met the requirements for collection. + +**Note**: Both the collection and building phases share modes with the mode operating under set by the collection phase. + +### Building + +The building phase can be described in the following steps: +1. Extract behaviors metadata +2. Create the behavior's intermediate file in the configured `build` directory +3. Use build behavior using rollup, built behavior placed in configured `dist` directory +4. Once all behaviors have been built generate behavior metadata. + + +The previous steps are applied to all behaviors returned by the collection phase +##CLI +write docs on npm or yarn scripts +revamp the cli as scripts package.json scripts + +## Provided CLI Commands +## Behavior Standard Library Reference + \ No newline at end of file diff --git a/manual/chapter4.md b/manual/chapter4.md new file mode 100644 index 0000000..cb59d56 --- /dev/null +++ b/manual/chapter4.md @@ -0,0 +1,33 @@ +# Behind Autopilot + + ## Maintainers + + Autopilot is maintained by: + + ## Contact Support + + Email [insert email] for support questions. + + ## Discussion Forum + + Use the [discussion forum](https://forum.webrecorder.net) to discuss ideas, questions, issues, etc. with the webrecorder community. + + ## Who Uses Autopilot? + We are happy to have a growing community of academic and memory institutions that are using Webrecorder tools and software. + + Some of our colleagues that are using various Webrecorder tools: + + ![DocNow](https://webrecorder.net/assets/logos/docnow-logo.png) + ![ArQuivo.PT](https://webrecorder.net/assets/logos/arquivo-logo.png) + ![UKWA](https://webrecorder.net/assets/logos/ukwa-logo.svg) + ![LOCKSS](https://webrecorder.net/assets/logos/lockss-logo.png) + ![Rhizome](https://webrecorder.net/assets/logos/rhizome-logo.png) + ![ONF NFB](https://webrecorder.net/assets/logos/nfb-logo.svg) + ![IIPC](https://webrecorder.net/assets/logos/iipc-logo.png) + ![Stanford University Press](https://webrecorder.net/assets/logos/sup-logo.png) + ![The National Archives](https://webrecorder.net/assets/logos/tna-logo.svg) + ![National Library of Australia](https://webrecorder.net/assets/logos/nla-logo.png) + ![Perma.cc](https://webrecorder.net/assets/logos/perma-logo.png) + ![CLOCKSS](https://webrecorder.net/assets/logos/clockss-logo.png) + + *If your institution is using Webrecorder software and would like to be listed, please let us know!* \ No newline at end of file diff --git a/manual/code-of-conduct.md b/manual/code-of-conduct.md new file mode 100644 index 0000000..f6100db --- /dev/null +++ b/manual/code-of-conduct.md @@ -0,0 +1,76 @@ +[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v2.0%20adopted-ff69b4.svg)](code_of_conduct.md) + +## Code of Conduct + +### Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, gender identity and expression, level of experience, +nationality, personal appearance, race, religion, or sexual identity and +orientation. + +### Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or +advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +### Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +### Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +### Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at [INSERT EMAIL ADDRESS]. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +### Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ \ No newline at end of file diff --git a/reference.md b/reference.md new file mode 100644 index 0000000..31bc70a --- /dev/null +++ b/reference.md @@ -0,0 +1,28 @@ +# API +## CBehaviorRunner +## CMutationStream +## FcreateState +## FstateWithMsgNoWait +## +## +## +## +## +## +## +## +## +## +## +## +## +## +## +## +## +## +## +## +## +## +## \ No newline at end of file