0
0
mirror of https://github.com/naturalcrit/homebrewery.git synced 2026-01-24 20:43:03 +00:00

Compare commits

...

148 Commits

Author SHA1 Message Date
Trevor Buckner
790420b320 Merge pull request #2004 from naturalcrit/v3.0.7
Update to Version 3.0.7
2022-02-02 23:07:27 -05:00
Trevor Buckner
2f011ebb24 Merge pull request #2002 from naturalcrit/dependabot/npm_and_yarn/babel/core-7.17.0
Bump @babel/core from 7.16.12 to 7.17.0
2022-02-02 23:07:08 -05:00
Trevor Buckner
191adf0a7c Update to Version 3.0.7 2022-02-02 23:05:32 -05:00
dependabot[bot]
2ab95d908b Bump @babel/core from 7.16.12 to 7.17.0
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.16.12 to 7.17.0.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.17.0/packages/babel-core)

---
updated-dependencies:
- dependency-name: "@babel/core"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-03 03:06:17 +00:00
Trevor Buckner
62f505f982 Merge pull request #2003 from naturalcrit/dependabot/npm_and_yarn/babel/plugin-transform-runtime-7.17.0
Bump @babel/plugin-transform-runtime from 7.16.10 to 7.17.0
2022-02-02 22:05:37 -05:00
Trevor Buckner
eaafce0517 Merge pull request #2001 from naturalcrit/dependabot/npm_and_yarn/mongoose-6.2.0
Bump mongoose from 6.1.10 to 6.2.0
2022-02-02 22:05:22 -05:00
dependabot[bot]
10f529c6b6 Bump @babel/plugin-transform-runtime from 7.16.10 to 7.17.0
Bumps [@babel/plugin-transform-runtime](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-transform-runtime) from 7.16.10 to 7.17.0.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.17.0/packages/babel-plugin-transform-runtime)

---
updated-dependencies:
- dependency-name: "@babel/plugin-transform-runtime"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-03 03:01:47 +00:00
dependabot[bot]
8424e51592 Bump mongoose from 6.1.10 to 6.2.0
Bumps [mongoose](https://github.com/Automattic/mongoose) from 6.1.10 to 6.2.0.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Automattic/mongoose/compare/6.1.10...6.2.0)

---
updated-dependencies:
- dependency-name: mongoose
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-03 03:01:09 +00:00
Trevor Buckner
45e391b273 Merge pull request #2000 from naturalcrit/dependabot/npm_and_yarn/mongoose-6.1.10
Bump mongoose from 6.1.9 to 6.1.10
2022-02-02 09:21:59 -05:00
dependabot[bot]
0c41fdee6f Bump mongoose from 6.1.9 to 6.1.10
Bumps [mongoose](https://github.com/Automattic/mongoose) from 6.1.9 to 6.1.10.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Automattic/mongoose/compare/6.1.9...6.1.10)

---
updated-dependencies:
- dependency-name: mongoose
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-02 03:01:14 +00:00
Trevor Buckner
11bbf1b8fa Merge pull request #1999 from naturalcrit/dependabot/npm_and_yarn/googleapis-94.0.0
Bump googleapis from 92.0.0 to 94.0.0
2022-02-01 00:08:10 -05:00
Trevor Buckner
f89f686097 Merge pull request #1998 from naturalcrit/dependabot/npm_and_yarn/mongoose-6.1.9
Bump mongoose from 6.1.8 to 6.1.9
2022-02-01 00:07:58 -05:00
Trevor Buckner
d93e4c7458 Merge pull request #1897 from jeddai/migration-guide
Legacy -> v3 Migration guide
2022-02-01 00:05:01 -05:00
Trevor Buckner
6bf4fc6cf8 Help dropdown uses existing dropdown class. Small tweaks. 2022-02-01 00:02:46 -05:00
dependabot[bot]
35a8f7dd98 Bump googleapis from 92.0.0 to 94.0.0
Bumps [googleapis](https://github.com/googleapis/google-api-nodejs-client) from 92.0.0 to 94.0.0.
- [Release notes](https://github.com/googleapis/google-api-nodejs-client/releases)
- [Changelog](https://github.com/googleapis/google-api-nodejs-client/blob/main/CHANGELOG.md)
- [Commits](https://github.com/googleapis/google-api-nodejs-client/compare/googleapis-v92.0.0...googleapis-v94.0.0)

---
updated-dependencies:
- dependency-name: googleapis
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-01 03:01:35 +00:00
dependabot[bot]
d0ec8ba22f Bump mongoose from 6.1.8 to 6.1.9
Bumps [mongoose](https://github.com/Automattic/mongoose) from 6.1.8 to 6.1.9.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Automattic/mongoose/compare/6.1.8...6.1.9)

---
updated-dependencies:
- dependency-name: mongoose
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-01 03:01:08 +00:00
Charlie Humphreys
57d3db5322 Merge branch 'master' into migration-guide
# Conflicts:
#	server/app.js
2022-01-31 17:13:36 -06:00
Trevor Buckner
e43ee7ddba Merge pull request #1997 from naturalcrit/dependabot/npm_and_yarn/eslint-8.8.0
Bump eslint from 8.7.0 to 8.8.0
2022-01-31 11:20:14 -05:00
dependabot[bot]
7a7bffab24 Bump eslint from 8.7.0 to 8.8.0
Bumps [eslint](https://github.com/eslint/eslint) from 8.7.0 to 8.8.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v8.7.0...v8.8.0)

---
updated-dependencies:
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-31 03:00:57 +00:00
Trevor Buckner
1001e57249 Merge pull request #1981 from AlexeySachkov/private/asachkov/refactor-config-initialization
[NFC] Outline config creation into a separate module
2022-01-30 16:30:21 -05:00
Trevor Buckner
ccbeca2cad Move process.chdir up so it occurs before config.js is ever called.
app.js should be required before config to make sure process.cwd is updated first
2022-01-30 00:13:35 -05:00
Trevor Buckner
d7aa4afa60 process.chdir in app.js.
Everything works, no need for path.resolve. All tests pass.
2022-01-29 23:53:30 -05:00
Trevor Buckner
e4c2ce6a8c Merge branch 'private/asachkov/refactor-config-initialization' of https://github.com/AlexeySachkov/homebrewery into pr/1981 2022-01-29 21:36:10 -05:00
Trevor Buckner
de115c5113 Merge branch 'master' into pr/1981 2022-01-29 21:34:38 -05:00
Alexey Sachkov
4e0ab4b393 Adjust paths to config files 2022-01-28 21:40:40 +03:00
Trevor Buckner
050bc472d0 Merge pull request #1990 from naturalcrit/dependabot/npm_and_yarn/cached-path-relative-1.1.0
Bump cached-path-relative from 1.0.2 to 1.1.0
2022-01-28 11:52:19 -05:00
Trevor Buckner
48da1da5ee Merge pull request #1946 from naturalcrit/dependabot/npm_and_yarn/prop-types-15.8.1
Bump prop-types from 15.8.0 to 15.8.1
2022-01-28 11:51:52 -05:00
Trevor Buckner
1b5f408bef Merge pull request #1989 from naturalcrit/dependabot/npm_and_yarn/node-fetch-2.6.7
Bump node-fetch from 2.6.1 to 2.6.7
2022-01-28 11:51:37 -05:00
dependabot[bot]
b1869a33f9 Bump prop-types from 15.8.0 to 15.8.1
Bumps [prop-types](https://github.com/facebook/prop-types) from 15.8.0 to 15.8.1.
- [Release notes](https://github.com/facebook/prop-types/releases)
- [Changelog](https://github.com/facebook/prop-types/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/prop-types/compare/v15.8.0...v15.8.1)

---
updated-dependencies:
- dependency-name: prop-types
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-28 16:50:48 +00:00
Trevor Buckner
bb07cdaa9f Merge pull request #1992 from naturalcrit/RemovePropTypes
Remove prop-types dependency
2022-01-28 11:49:16 -05:00
Trevor Buckner
db0e4fcc0c Remove prop-types dependency 2022-01-28 11:47:24 -05:00
Trevor Buckner
ba8a2af87d Merge pull request #1929 from jeddai/links-in-home-document
Add discord, github, and reddit links to home page document
2022-01-28 10:29:26 -05:00
Trevor Buckner
85e7071d6c Merge pull request #1991 from naturalcrit/dependabot/npm_and_yarn/marked-4.0.12
Bump marked from 4.0.11 to 4.0.12
2022-01-28 10:27:28 -05:00
Trevor Buckner
ece6df023a Restore custom CSS styling on v3 preview 2022-01-28 09:59:29 -05:00
Trevor Buckner
4c08f4a6e1 Condense v3_preview to fit on two pages again. 2022-01-28 09:44:43 -05:00
Trevor Buckner
039e4dd4e5 Revert extraneous Config changes
Looks like these were part of something else? In any case it conflicts with #1981 so just undoing these changes.
2022-01-28 00:38:00 -05:00
dependabot[bot]
041abf1220 Bump marked from 4.0.11 to 4.0.12
Bumps [marked](https://github.com/markedjs/marked) from 4.0.11 to 4.0.12.
- [Release notes](https://github.com/markedjs/marked/releases)
- [Changelog](https://github.com/markedjs/marked/blob/master/.releaserc.json)
- [Commits](https://github.com/markedjs/marked/compare/v4.0.11...v4.0.12)

---
updated-dependencies:
- dependency-name: marked
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-28 03:00:41 +00:00
dependabot[bot]
56fc23f23a Bump cached-path-relative from 1.0.2 to 1.1.0
Bumps [cached-path-relative](https://github.com/ashaffer/cached-path-relative) from 1.0.2 to 1.1.0.
- [Release notes](https://github.com/ashaffer/cached-path-relative/releases)
- [Commits](https://github.com/ashaffer/cached-path-relative/commits)

---
updated-dependencies:
- dependency-name: cached-path-relative
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-27 14:36:29 +00:00
Trevor Buckner
87c28c76f3 Merge pull request #1979 from AlexeySachkov/private/asachkov/testing-with-supertest
Add very basic infrastructure for HTTP testing
2022-01-26 23:42:36 -05:00
dependabot[bot]
235f878dba Bump node-fetch from 2.6.1 to 2.6.7
Bumps [node-fetch](https://github.com/node-fetch/node-fetch) from 2.6.1 to 2.6.7.
- [Release notes](https://github.com/node-fetch/node-fetch/releases)
- [Commits](https://github.com/node-fetch/node-fetch/compare/v2.6.1...v2.6.7)

---
updated-dependencies:
- dependency-name: node-fetch
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-27 03:59:52 +00:00
Trevor Buckner
b2ec0d4a0c Merge pull request #1986 from naturalcrit/dependabot/npm_and_yarn/mongoose-6.1.8
Bump mongoose from 6.1.7 to 6.1.8
2022-01-26 22:59:29 -05:00
Trevor Buckner
02560d82ab Merge pull request #1988 from naturalcrit/dependabot/npm_and_yarn/marked-4.0.11
Bump marked from 4.0.10 to 4.0.11
2022-01-26 22:59:18 -05:00
Charlie Humphreys
22b80ffbb2 update app templates for welcome messages, add new images 2022-01-26 21:56:12 -06:00
dependabot[bot]
2db127d805 Bump marked from 4.0.10 to 4.0.11
Bumps [marked](https://github.com/markedjs/marked) from 4.0.10 to 4.0.11.
- [Release notes](https://github.com/markedjs/marked/releases)
- [Changelog](https://github.com/markedjs/marked/blob/master/.releaserc.json)
- [Commits](https://github.com/markedjs/marked/compare/v4.0.10...v4.0.11)

---
updated-dependencies:
- dependency-name: marked
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-27 03:01:08 +00:00
Charlie Humphreys
c2ca9f8f10 Merge branch 'master' into links-in-home-document
# Conflicts:
#	server.js
2022-01-26 13:59:47 -06:00
Charlie Humphreys
e614fbc5a1 Update app.js from master 2022-01-26 08:46:45 -06:00
Charlie Humphreys
7f001ee391 Merge branch 'master' into migration-guide
# Conflicts:
#	server.js
2022-01-26 08:44:28 -06:00
Charlie Humphreys
9432304be5 Merge branch 'master' into migration-guide
# Conflicts:
#	package-lock.json
2022-01-26 08:43:17 -06:00
Charlie Humphreys
38c0527d35 Add color mixins, help dropdown, and remove unused nav items 2022-01-26 08:40:33 -06:00
dependabot[bot]
6fc176e616 Bump mongoose from 6.1.7 to 6.1.8
Bumps [mongoose](https://github.com/Automattic/mongoose) from 6.1.7 to 6.1.8.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Automattic/mongoose/compare/6.1.7...6.1.8)

---
updated-dependencies:
- dependency-name: mongoose
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-25 03:01:18 +00:00
Alexey Sachkov
588bcebc87 [NFC] Outline config creation into a separate module
This is done in order to have config creation rules
unified in one place to avoid modifying them multiple times
if they change.

We already had 3 duplicated pieces of code initializing the
config and there will be more config uses in future tests.

This resolves #1960
2022-01-23 20:06:52 +03:00
Alexey Sachkov
4fd085b684 Update package-lock.json 2022-01-23 20:00:16 +03:00
Alexey Sachkov
d2250cdabb Merge remote-tracking branch 'origin/master' into private/asachkov/testing-with-supertest 2022-01-23 19:58:56 +03:00
Trevor Buckner
179d5e6312 Merge pull request #1980 from naturalcrit/dependabot/npm_and_yarn/babel/core-7.16.12
Bump @babel/core from 7.16.7 to 7.16.12
2022-01-22 22:04:36 -05:00
dependabot[bot]
12d0f69e9c Bump @babel/core from 7.16.7 to 7.16.12
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.16.7 to 7.16.12.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.16.12/packages/babel-core)

---
updated-dependencies:
- dependency-name: "@babel/core"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-22 18:23:01 +00:00
Trevor Buckner
788ff65283 Merge pull request #1973 from naturalcrit/dependabot/npm_and_yarn/babel/plugin-transform-runtime-7.16.10
Bump @babel/plugin-transform-runtime from 7.16.8 to 7.16.10
2022-01-22 13:22:02 -05:00
dependabot[bot]
d7d93c8975 Bump @babel/plugin-transform-runtime from 7.16.8 to 7.16.10
Bumps [@babel/plugin-transform-runtime](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-transform-runtime) from 7.16.8 to 7.16.10.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.16.10/packages/babel-plugin-transform-runtime)

---
updated-dependencies:
- dependency-name: "@babel/plugin-transform-runtime"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-22 16:36:20 +00:00
Trevor Buckner
eb07fd7c38 Merge pull request #1966 from naturalcrit/dependabot/npm_and_yarn/nanoid-3.2.0
Bump nanoid from 3.1.30 to 3.2.0
2022-01-22 11:35:49 -05:00
Trevor Buckner
c09b87482a Merge pull request #1977 from naturalcrit/dependabot/npm_and_yarn/babel/preset-env-7.16.11
Bump @babel/preset-env from 7.16.8 to 7.16.11
2022-01-22 11:35:17 -05:00
Trevor Buckner
19562a2445 Merge pull request #1978 from naturalcrit/dependabot/npm_and_yarn/codemirror-5.65.1
Bump codemirror from 5.65.0 to 5.65.1
2022-01-22 11:34:51 -05:00
Alexey Sachkov
543d65f43f Add very first HTTP tests
Added tests for "static" pages like Home, Changelog, FAQ, etc.
2022-01-22 00:36:54 +03:00
Alexey Sachkov
fc1af353f3 Install and configure required packages for HTTP testing
Two new dev dependencies were added:
- supertest package to perform HTTP testing
- @babel/plugin-transform-runtime

Configured jest to so it is able load files from server directory
2022-01-22 00:36:10 +03:00
Alexey Sachkov
9c57450330 [NFC] Explicitly define variables before using them
Fixed two errors which were discovered by trying to run the code in "strict" mode,
which is automatically done by Jest testing framework.
2022-01-22 00:18:13 +03:00
Trevor Buckner
0573084ffd Merge pull request #1959 from AlexeySachkov/private/asachkov/refactor-server-js
[NFC] Outline an express app into a separate module
2022-01-21 00:22:58 -05:00
dependabot[bot]
6cb39709c4 Bump codemirror from 5.65.0 to 5.65.1
Bumps [codemirror](https://github.com/codemirror/CodeMirror) from 5.65.0 to 5.65.1.
- [Release notes](https://github.com/codemirror/CodeMirror/releases)
- [Changelog](https://github.com/codemirror/CodeMirror/blob/master/CHANGELOG.md)
- [Commits](https://github.com/codemirror/CodeMirror/compare/5.65.0...5.65.1)

---
updated-dependencies:
- dependency-name: codemirror
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-21 03:01:49 +00:00
dependabot[bot]
4ea2fc34f0 Bump @babel/preset-env from 7.16.8 to 7.16.11
Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.16.8 to 7.16.11.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.16.11/packages/babel-preset-env)

---
updated-dependencies:
- dependency-name: "@babel/preset-env"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-21 03:01:12 +00:00
dependabot[bot]
a0e2bcb8e4 Bump nanoid from 3.1.30 to 3.2.0
Bumps [nanoid](https://github.com/ai/nanoid) from 3.1.30 to 3.2.0.
- [Release notes](https://github.com/ai/nanoid/releases)
- [Changelog](https://github.com/ai/nanoid/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ai/nanoid/compare/3.1.30...3.2.0)

---
updated-dependencies:
- dependency-name: nanoid
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-18 22:01:45 +00:00
Trevor Buckner
015644453b Merge pull request #1967 from naturalcrit/dependabot/npm_and_yarn/eslint-8.7.0
Bump eslint from 8.6.0 to 8.7.0
2022-01-18 17:00:45 -05:00
Trevor Buckner
199c7d4e02 Merge pull request #1969 from naturalcrit/dependabot/npm_and_yarn/mongoose-6.1.7
Bump mongoose from 6.1.6 to 6.1.7
2022-01-18 17:00:38 -05:00
Trevor Buckner
1d71e96421 Merge pull request #1964 from naturalcrit/dependabot/npm_and_yarn/marked-4.0.10
Bump marked from 4.0.9 to 4.0.10
2022-01-18 17:00:32 -05:00
dependabot[bot]
8d0dbac882 Bump mongoose from 6.1.6 to 6.1.7
Bumps [mongoose](https://github.com/Automattic/mongoose) from 6.1.6 to 6.1.7.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Automattic/mongoose/compare/6.1.6...6.1.7)

---
updated-dependencies:
- dependency-name: mongoose
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-18 03:01:19 +00:00
dependabot[bot]
6c1b4b1839 Bump eslint from 8.6.0 to 8.7.0
Bumps [eslint](https://github.com/eslint/eslint) from 8.6.0 to 8.7.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v8.6.0...v8.7.0)

---
updated-dependencies:
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-17 03:01:30 +00:00
dependabot[bot]
d4a4e7d139 Bump marked from 4.0.9 to 4.0.10
Bumps [marked](https://github.com/markedjs/marked) from 4.0.9 to 4.0.10.
- [Release notes](https://github.com/markedjs/marked/releases)
- [Changelog](https://github.com/markedjs/marked/blob/master/.releaserc.json)
- [Commits](https://github.com/markedjs/marked/compare/v4.0.9...v4.0.10)

---
updated-dependencies:
- dependency-name: marked
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-13 03:01:44 +00:00
Alexey Sachkov
0dfe18cd18 Fix liner errors 2022-01-11 23:24:50 +03:00
Alexey Sachkov
8895b44be9 [NFC] Outline an express app into a separate module
This is done in order to be able to re-use that app in API unit tests later
2022-01-11 22:24:23 +03:00
Trevor Buckner
279352377b Merge pull request #1957 from naturalcrit/dependabot/npm_and_yarn/babel/preset-env-7.16.8
Bump @babel/preset-env from 7.16.7 to 7.16.8
2022-01-11 11:32:59 -05:00
dependabot[bot]
51cf363c84 Bump @babel/preset-env from 7.16.7 to 7.16.8
Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.16.7 to 7.16.8.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.16.8/packages/babel-preset-env)

---
updated-dependencies:
- dependency-name: "@babel/preset-env"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-11 16:25:18 +00:00
Trevor Buckner
bdd554851d Merge pull request #1956 from naturalcrit/dependabot/npm_and_yarn/mongoose-6.1.6
Bump mongoose from 6.1.5 to 6.1.6
2022-01-11 11:24:06 -05:00
Trevor Buckner
f611a36089 Merge pull request #1955 from naturalcrit/dependabot/npm_and_yarn/babel/plugin-transform-runtime-7.16.8
Bump @babel/plugin-transform-runtime from 7.16.7 to 7.16.8
2022-01-11 11:23:59 -05:00
dependabot[bot]
0861e1ed29 Bump mongoose from 6.1.5 to 6.1.6
Bumps [mongoose](https://github.com/Automattic/mongoose) from 6.1.5 to 6.1.6.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Automattic/mongoose/compare/6.1.5...6.1.6)

---
updated-dependencies:
- dependency-name: mongoose
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-11 03:01:23 +00:00
dependabot[bot]
4070c53112 Bump @babel/plugin-transform-runtime from 7.16.7 to 7.16.8
Bumps [@babel/plugin-transform-runtime](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-transform-runtime) from 7.16.7 to 7.16.8.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.16.8/packages/babel-plugin-transform-runtime)

---
updated-dependencies:
- dependency-name: "@babel/plugin-transform-runtime"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-11 03:01:11 +00:00
Trevor Buckner
ac8ad98939 Merge pull request #1937 from AlexeySachkov/private/asachkov/v3-markdown-tests
Add tests for our markdown parser/renderer
2022-01-10 13:58:04 -05:00
Trevor Buckner
e315c29620 Merge pull request #1931 from AlexeySachkov/private/asachkov/outline-db-connection
[NFC] Outline database connection into a separate file
2022-01-10 13:55:55 -05:00
Alexey Sachkov
e84cd4fe8b Apply review comments
Switched from raw promises to async/await.
Outlined error handling function to reduce amount of nested code.
Added comment about the new file intent.
2022-01-10 19:25:36 +03:00
Alexey Sachkov
2d85638d7d Update package-lock.json after merge 2022-01-10 18:56:23 +03:00
Alexey Sachkov
1daa700a1a Merge remote-tracking branch 'origin/master' into private/asachkov/v3-markdown-tests 2022-01-10 18:54:53 +03:00
Trevor Buckner
c06176b3bf Merge pull request #1950 from naturalcrit/dependabot/npm_and_yarn/marked-4.0.9
Bump marked from 4.0.8 to 4.0.9
2022-01-06 23:18:59 -05:00
Trevor Buckner
85f93c7861 Merge pull request #1949 from naturalcrit/dependabot/npm_and_yarn/query-string-7.1.0
Bump query-string from 7.0.1 to 7.1.0
2022-01-06 23:18:35 -05:00
dependabot[bot]
e1457b5308 Bump marked from 4.0.8 to 4.0.9
Bumps [marked](https://github.com/markedjs/marked) from 4.0.8 to 4.0.9.
- [Release notes](https://github.com/markedjs/marked/releases)
- [Changelog](https://github.com/markedjs/marked/blob/master/.releaserc.json)
- [Commits](https://github.com/markedjs/marked/compare/v4.0.8...v4.0.9)

---
updated-dependencies:
- dependency-name: marked
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-07 03:01:25 +00:00
dependabot[bot]
fc6fd00fe9 Bump query-string from 7.0.1 to 7.1.0
Bumps [query-string](https://github.com/sindresorhus/query-string) from 7.0.1 to 7.1.0.
- [Release notes](https://github.com/sindresorhus/query-string/releases)
- [Commits](https://github.com/sindresorhus/query-string/compare/v7.0.1...v7.1.0)

---
updated-dependencies:
- dependency-name: query-string
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-07 03:00:55 +00:00
Trevor Buckner
3ccc36f87a Merge pull request #1945 from naturalcrit/dependabot/npm_and_yarn/mongoose-6.1.5
Bump mongoose from 6.1.4 to 6.1.5
2022-01-05 13:14:03 -05:00
Trevor Buckner
ceae540aa0 Merge pull request #1944 from G-Ambatte/increaseGooglePageSize-#1943
Increase Google pageSize to 1000
2022-01-05 13:13:53 -05:00
dependabot[bot]
a5cab7005e Bump mongoose from 6.1.4 to 6.1.5
Bumps [mongoose](https://github.com/Automattic/mongoose) from 6.1.4 to 6.1.5.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Automattic/mongoose/compare/6.1.4...6.1.5)

---
updated-dependencies:
- dependency-name: mongoose
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-05 03:00:44 +00:00
G.Ambatte
e48e8cd05b Increase pageSize to 1000 2022-01-05 13:17:56 +13:00
Trevor Buckner
e74800916e Merge pull request #1941 from naturalcrit/dependabot/npm_and_yarn/babel/preset-env-7.16.7
Bump @babel/preset-env from 7.16.5 to 7.16.7
2022-01-04 15:29:30 -05:00
Trevor Buckner
34f154d09d Merge pull request #1940 from naturalcrit/dependabot/npm_and_yarn/babel/core-7.16.7
Bump @babel/core from 7.16.5 to 7.16.7
2022-01-04 15:29:22 -05:00
dependabot[bot]
1bcdd6bc38 Bump @babel/core from 7.16.5 to 7.16.7
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.16.5 to 7.16.7.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.16.7/packages/babel-core)

---
updated-dependencies:
- dependency-name: "@babel/core"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-04 20:25:26 +00:00
dependabot[bot]
dd82ee68f0 Bump @babel/preset-env from 7.16.5 to 7.16.7
Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.16.5 to 7.16.7.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.16.7/packages/babel-preset-env)

---
updated-dependencies:
- dependency-name: "@babel/preset-env"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-04 20:24:50 +00:00
Trevor Buckner
564486f6d0 Merge pull request #1942 from naturalcrit/dependabot/npm_and_yarn/eslint-8.6.0
Bump eslint from 8.5.0 to 8.6.0
2022-01-04 15:23:35 -05:00
Trevor Buckner
bf632a8584 Merge pull request #1939 from naturalcrit/dependabot/npm_and_yarn/babel/plugin-transform-runtime-7.16.7
Bump @babel/plugin-transform-runtime from 7.16.5 to 7.16.7
2022-01-04 15:23:25 -05:00
Trevor Buckner
506cf78dac Merge pull request #1938 from naturalcrit/dependabot/npm_and_yarn/babel/preset-react-7.16.7
Bump @babel/preset-react from 7.16.5 to 7.16.7
2022-01-04 15:23:18 -05:00
dependabot[bot]
0dbb5f18ba Bump eslint from 8.5.0 to 8.6.0
Bumps [eslint](https://github.com/eslint/eslint) from 8.5.0 to 8.6.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v8.5.0...v8.6.0)

---
updated-dependencies:
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-03 03:01:02 +00:00
dependabot[bot]
85e9c57ee2 Bump @babel/plugin-transform-runtime from 7.16.5 to 7.16.7
Bumps [@babel/plugin-transform-runtime](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-transform-runtime) from 7.16.5 to 7.16.7.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.16.7/packages/babel-plugin-transform-runtime)

---
updated-dependencies:
- dependency-name: "@babel/plugin-transform-runtime"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-31 03:01:07 +00:00
dependabot[bot]
257c266a2e Bump @babel/preset-react from 7.16.5 to 7.16.7
Bumps [@babel/preset-react](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-react) from 7.16.5 to 7.16.7.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.16.7/packages/babel-preset-react)

---
updated-dependencies:
- dependency-name: "@babel/preset-react"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-31 03:00:54 +00:00
Alexey Sachkov
28793e06fc Fix linter errors 2021-12-30 23:40:58 +03:00
Alexey Sachkov
ba74b5aa13 Update package-lock.json 2021-12-30 23:24:38 +03:00
Alexey Sachkov
01bceca7df Add some tests for mustache span syntax
Also refactored test files a bit
2021-12-30 23:23:44 +03:00
Alexey Sachkov
ccca313a15 Initial commit with jest enabling
Removed dependency on pico-check and existing tests.
Added jest as dev dependency, introduced minimal configuration for it.
Added a very first couple of tests for our markdown parser/renderer.
2021-12-30 22:41:01 +03:00
Trevor Buckner
c463eedc50 Merge pull request #1933 from AlexeySachkov/private/asachkov/add-display-name-to-react-components
[NFC] Add display name for custom React components
2021-12-29 17:21:31 -05:00
Trevor Buckner
7f49d6f08b Merge pull request #1927 from naturalcrit/dependabot/npm_and_yarn/mongoose-6.1.4
Bump mongoose from 6.1.3 to 6.1.4
2021-12-29 16:33:08 -05:00
Alexey Sachkov
78d4487c58 Fix linter errors 2021-12-29 21:30:03 +03:00
Alexey Sachkov
8a3f52b704 [NFC] Add display name for custom React components
This improves readability of "Components" tab from React Development Tools extension for Chrome
2021-12-29 21:18:54 +03:00
Alexey Sachkov
6e04535eff [NFC] Outline database connection into a separate file 2021-12-29 19:04:17 +03:00
Charlie Humphreys
5bb580147a Add discord, github, and reddit links to home page document 2021-12-28 21:59:02 -06:00
dependabot[bot]
1adaa9f5c4 Bump mongoose from 6.1.3 to 6.1.4
Bumps [mongoose](https://github.com/Automattic/mongoose) from 6.1.3 to 6.1.4.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Automattic/mongoose/compare/6.1.3...6.1.4)

---
updated-dependencies:
- dependency-name: mongoose
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-28 03:01:01 +00:00
Trevor Buckner
7b19bbb1a7 Merge pull request #1922 from naturalcrit/dependabot/npm_and_yarn/prop-types-15.8.0
Bump prop-types from 15.7.2 to 15.8.0
2021-12-23 22:41:44 -05:00
Trevor Buckner
e3d4165fa4 Merge pull request #1921 from naturalcrit/dependabot/npm_and_yarn/eslint-plugin-react-7.28.0
Bump eslint-plugin-react from 7.27.1 to 7.28.0
2021-12-23 22:41:35 -05:00
dependabot[bot]
ec54434427 Bump prop-types from 15.7.2 to 15.8.0
Bumps [prop-types](https://github.com/facebook/prop-types) from 15.7.2 to 15.8.0.
- [Release notes](https://github.com/facebook/prop-types/releases)
- [Changelog](https://github.com/facebook/prop-types/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/prop-types/compare/v15.7.2...v15.8.0)

---
updated-dependencies:
- dependency-name: prop-types
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-23 03:01:28 +00:00
dependabot[bot]
67bf69fc21 Bump eslint-plugin-react from 7.27.1 to 7.28.0
Bumps [eslint-plugin-react](https://github.com/yannickcr/eslint-plugin-react) from 7.27.1 to 7.28.0.
- [Release notes](https://github.com/yannickcr/eslint-plugin-react/releases)
- [Changelog](https://github.com/yannickcr/eslint-plugin-react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/yannickcr/eslint-plugin-react/compare/v7.27.1...v7.28.0)

---
updated-dependencies:
- dependency-name: eslint-plugin-react
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-23 03:01:10 +00:00
Trevor Buckner
c60e287cbe Merge pull request #1901 from G-Ambatte/addInstallDocs-#1896
Add Install Instructions - Ubuntu
2021-12-21 23:50:01 -05:00
Trevor Buckner
de4b2861b6 Merge pull request #1911 from naturalcrit/dependabot/npm_and_yarn/express-4.17.2
Bump express from 4.17.1 to 4.17.2
2021-12-21 23:19:02 -05:00
Trevor Buckner
eb4234d814 Merge pull request #1912 from naturalcrit/dependabot/npm_and_yarn/marked-4.0.8
Bump marked from 4.0.7 to 4.0.8
2021-12-21 23:18:52 -05:00
Trevor Buckner
4da7b8bd17 Merge pull request #1919 from naturalcrit/dependabot/npm_and_yarn/mongoose-6.1.3
Bump mongoose from 6.1.2 to 6.1.3
2021-12-21 23:18:39 -05:00
Trevor Buckner
c0f5f224bf Merge pull request #1917 from naturalcrit/dependabot/npm_and_yarn/codemirror-5.65.0
Bump codemirror from 5.64.0 to 5.65.0
2021-12-21 23:18:29 -05:00
Trevor Buckner
9b89814056 Merge pull request #1910 from naturalcrit/dependabot/npm_and_yarn/eslint-8.5.0
Bump eslint from 8.4.1 to 8.5.0
2021-12-21 23:18:14 -05:00
Trevor Buckner
12d0baf5d3 Merge pull request #1913 from jeddai/codemirror-tweak-updates
Revert some codemirror tweaks, disable code folding in style tab
2021-12-21 22:48:37 -05:00
dependabot[bot]
8a695c14d7 Bump mongoose from 6.1.2 to 6.1.3
Bumps [mongoose](https://github.com/Automattic/mongoose) from 6.1.2 to 6.1.3.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Automattic/mongoose/compare/6.1.2...6.1.3)

---
updated-dependencies:
- dependency-name: mongoose
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-22 03:00:58 +00:00
dependabot[bot]
f253bdf954 Bump codemirror from 5.64.0 to 5.65.0
Bumps [codemirror](https://github.com/codemirror/CodeMirror) from 5.64.0 to 5.65.0.
- [Release notes](https://github.com/codemirror/CodeMirror/releases)
- [Changelog](https://github.com/codemirror/CodeMirror/blob/master/CHANGELOG.md)
- [Commits](https://github.com/codemirror/CodeMirror/compare/5.64.0...5.65.0)

---
updated-dependencies:
- dependency-name: codemirror
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-21 03:00:47 +00:00
Charlie Humphreys
38d8764f15 Disable code folding in style tab, disable active line highlight and whitespace visibility 2021-12-20 00:42:53 -06:00
dependabot[bot]
01f6d106a2 Bump marked from 4.0.7 to 4.0.8
Bumps [marked](https://github.com/markedjs/marked) from 4.0.7 to 4.0.8.
- [Release notes](https://github.com/markedjs/marked/releases)
- [Changelog](https://github.com/markedjs/marked/blob/master/.releaserc.json)
- [Commits](https://github.com/markedjs/marked/compare/v4.0.7...v4.0.8)

---
updated-dependencies:
- dependency-name: marked
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-20 03:01:12 +00:00
dependabot[bot]
9119860012 Bump express from 4.17.1 to 4.17.2
Bumps [express](https://github.com/expressjs/express) from 4.17.1 to 4.17.2.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.17.1...4.17.2)

---
updated-dependencies:
- dependency-name: express
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-20 03:01:01 +00:00
dependabot[bot]
eeaaa0e6c9 Bump eslint from 8.4.1 to 8.5.0
Bumps [eslint](https://github.com/eslint/eslint) from 8.4.1 to 8.5.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v8.4.1...v8.5.0)

---
updated-dependencies:
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-20 03:00:51 +00:00
G.Ambatte
db5987a466 Shift install instruction READMEs into install directory 2021-12-19 19:26:12 +13:00
G.Ambatte
b5d5cb085b Merge branch 'addInstallDocs-#1896' of https://github.com/G-Ambatte/homebrewery into addInstallDocs-#1896 2021-12-19 19:22:55 +13:00
G.Ambatte
dcf17e3b72 Add README.UBUNTU.md 2021-12-19 19:22:33 +13:00
G.Ambatte
5b746c0d9c Merge branch 'naturalcrit:master' into addInstallDocs-#1896 2021-12-19 18:51:59 +13:00
G.Ambatte
41bc6ca444 Add HB service file
Update install.sh to create service and set to start automatically
2021-12-19 18:50:35 +13:00
Trevor Buckner
aba2f58fc4 Merge pull request #1898 from naturalcrit/v3.0.6
3.0.6
2021-12-18 23:02:43 -05:00
Sean Robertson
aa4de67e90 Ensure curl is installed
Fix mongodb package name
Use apt satisfy instead of apt install
2021-12-17 16:06:34 +13:00
Sean Robertson
b1a9fbe3ca Update location of FreeBSD install instructions 2021-12-17 15:21:52 +13:00
Charlie Humphreys
603cf2c0ab Adjust migrate document text 2021-12-16 00:03:23 -06:00
Charlie Humphreys
0bc27e83ed Fix reference to old function 2021-12-16 00:01:16 -06:00
Charlie Humphreys
25c1d03cca Update package-lock.json 2021-12-15 23:59:36 -06:00
Charlie Humphreys
e2b4151ab4 Merge branch 'master' into migration-guide
# Conflicts:
#	shared/naturalcrit/markdown.js
2021-12-15 23:59:10 -06:00
Charlie Humphreys
889d307372 Lint change double quotes into single quotes 2021-12-15 23:58:49 -06:00
Charlie Humphreys
fd23396b95 Add migrate nav item to pages and update migrate document 2021-12-15 23:57:52 -06:00
Charlie Humphreys
f1c4910993 Add to migrate document and update colon-replacement for the markdown renderer 2021-12-10 20:25:31 -06:00
Charlie Humphreys
b817148d1c Initial page for migrating from GMB to HB 2021-12-07 22:09:01 -06:00
59 changed files with 8856 additions and 2267 deletions

View File

@@ -34,16 +34,37 @@ pre {
## changelog
For a full record of development, visit our [Github Page](https://github.com/naturalcrit/homebrewery).
### Wednesday 02/02/2022 - v3.0.7
{{taskList
* [x] Revert active line highlighting.
Fixes issues: [#1913](https://github.com/naturalcrit/homebrewery/issues/1913)
* [x] Added install steps for Ubuntu. [HERE](https://github.com/naturalcrit/homebrewery/blob/master/install/README.UBUNTU.md)
Fixes issues: [#1900](https://github.com/naturalcrit/homebrewery/issues/1900)
* [x] Added social media links to home page.
* [x] Increase brews visible on the user page to 1,000.
Fixes issues: [#1943](https://github.com/naturalcrit/homebrewery/issues/1943)
* [x] Added a Legacy to V3 migration guide under **NEED HELP? {{fa,fa-question-circle}} → MIGRATE {{fas,fa-file-import}}**
* [x] Background refactoring and unit tests.
}}
### Saturday 18/12/2021 - v3.0.6
{{taskList
* [x] Fixed text wrapping for long strings in code blocks.
Fixes issues: [#1736](https://github.com/naturalcrit/homebrewery/issues/1736)
* [x] Code search/replace `CTRL F / CTRL SHIFT F`
Fixes issues: [#1201](https://github.com/naturalcrit/homebrewery/issues/1201)
* [x] Auto-closing HTML tags and curly braces `{{ }}`
* [x] Highlight current active line
@@ -56,7 +77,7 @@ For a full record of development, visit our [Github Page](https://github.com/nat
* [x] Make columns even in V3 Table of Contents.
Fixes issues: [#1671](https://github.com/naturalcrit/homebrewery/issues/1671)
* [x] Fix `CTRL P` failing to print from `/new` pages.
Fixes issues: [#1815](https://github.com/naturalcrit/homebrewery/issues/1815)

View File

@@ -17,6 +17,7 @@ const PAGE_HEIGHT = 1056;
const PPR_THRESHOLD = 50;
const BrewRenderer = createClass({
displayName : 'BrewRenderer',
getDefaultProps : function() {
return {
text : '',

View File

@@ -5,6 +5,7 @@ const _ = require('lodash');
const cx = require('classnames');
const ErrorBar = createClass({
displayName : 'ErrorBar',
getDefaultProps : function() {
return {
errors : []

View File

@@ -7,6 +7,7 @@ const cx = require('classnames'); //Unused variable
const DISMISS_KEY = 'dismiss_notification09-9-21';
const NotificationPopup = createClass({
displayName : 'NotificationPopup',
getInitialState : function() {
return {
notifications : {}

View File

@@ -26,6 +26,7 @@ const splice = function(str, index, inject){
const Editor = createClass({
displayName : 'Editor',
getDefaultProps : function() {
return {
brew : {
@@ -208,6 +209,7 @@ const Editor = createClass({
view={this.state.view}
value={this.props.brew.style ?? DEFAULT_STYLE_TEXT}
onChange={this.props.onStyleChange}
enableFolding={false}
rerenderParent={this.rerenderParent} />
</>;
}

View File

@@ -8,6 +8,7 @@ const request = require('superagent');
const SYSTEMS = ['5e', '4e', '3.5e', 'Pathfinder'];
const MetadataEditor = createClass({
displayName : 'MetadataEditor',
getDefaultProps : function() {
return {
metadata : {

View File

@@ -14,6 +14,7 @@ const execute = function(val, brew){
};
const Snippetbar = createClass({
displayName : 'SnippetBar',
getDefaultProps : function() {
return {
brew : {},
@@ -103,6 +104,7 @@ module.exports = Snippetbar;
const SnippetGroup = createClass({
displayName : 'SnippetGroup',
getDefaultProps : function() {
return {
brew : {},

View File

@@ -13,6 +13,7 @@ const NewPage = require('./pages/newPage/newPage.jsx');
const PrintPage = require('./pages/printPage/printPage.jsx');
const Homebrew = createClass({
displayName : 'Homebrewery',
getDefaultProps : function() {
return {
url : '',

View File

@@ -3,7 +3,7 @@ const createClass = require('create-react-class');
const Nav = require('naturalcrit/nav/nav.jsx');
const Account = createClass({
displayName : 'AccountNavItem',
getInitialState : function() {
return {
url : ''

View File

@@ -7,6 +7,7 @@ const MAX_TITLE_LENGTH = 50;
const EditTitle = createClass({
displayName : 'EditTitleNavItem',
getDefaultProps : function() {
return {
title : '',

View File

@@ -0,0 +1,25 @@
const React = require('react');
const createClass = require('create-react-class');
const _ = require('lodash');
const Nav = require('naturalcrit/nav/nav.jsx');
module.exports = function(props){
return <Nav.dropdown>
<Nav.item color='grey' icon='fas fa-question-circle'>
need help?
</Nav.item>
<Nav.item color='red' icon='fas fa-fw fa-bug'
href={`https://www.reddit.com/r/homebrewery/submit?selftext=true&title=${encodeURIComponent('[Issue] Describe Your Issue Here')}`}
newTab={true}
rel='noopener noreferrer'>
report issue
</Nav.item>
<Nav.item color='blue' icon='fas fa-fw fa-file-import'
href='/migrate'
newTab={true}
rel='noopener noreferrer'>
migrate
</Nav.item>
</Nav.dropdown>;
};

View File

@@ -1,13 +0,0 @@
const React = require('react');
const createClass = require('create-react-class');
const Nav = require('naturalcrit/nav/nav.jsx');
module.exports = function(props){
return <Nav.item
newTab={true}
color='red'
icon='fas fa-bug'
href={`https://www.reddit.com/r/homebrewery/submit?selftext=true&title=${encodeURIComponent('[Issue] Describe Your Issue Here')}`} >
report issue
</Nav.item>;
};

View File

@@ -6,6 +6,7 @@ const Nav = require('naturalcrit/nav/nav.jsx');
const PatreonNavItem = require('./patreon.navitem.jsx');
const Navbar = createClass({
displayName : 'Navbar',
getInitialState : function() {
return {
//showNonChromeWarning : false,

View File

@@ -1,5 +1,6 @@
@import 'naturalcrit/styles/colors.less';
@navbarHeight : 28px;
@keyframes coloring {
@keyframes pinkColoring {
//from {color: white;}
//to {color: red;}
0% {color: pink;}
@@ -62,19 +63,21 @@
}
i{
.animate(color);
animation-name: coloring;
animation-name: pinkColoring;
animation-duration: 2s;
color: pink;
}
}
.recent.navItem{
.recent.navItem {
position : relative;
.dropdown{
position : absolute;
top : 28px;
left : 0px;
z-index : 10000;
width : 100%;
position : absolute;
top : 28px;
left : 0px;
z-index : 10000;
width : 100%;
overflow : hidden auto;
max-height : ~"calc(100vh - 28px)";
h4{
display : block;
box-sizing : border-box;
@@ -88,11 +91,12 @@
&:nth-of-type(2){ background-color: darken(@purple, 30%); }
}
.item{
#backgroundColors;
.animate(background-color);
position : relative;
display : block;
box-sizing : border-box;
padding : 13px 5px;
padding : 8px 5px 13px;
background-color : #333;
color : white;
text-decoration : none;

View File

@@ -10,7 +10,7 @@ const VIEW_KEY = 'homebrewery-recently-viewed';
const RecentItems = createClass({
DisplayName : 'RecentItems',
getDefaultProps : function() {
return {
storageKey : '',
@@ -123,8 +123,8 @@ const RecentItems = createClass({
if(!this.state.showDropdown) return null;
const makeItems = (brews)=>{
return _.map(brews, (brew)=>{
return <a href={brew.url} className='item' key={brew.id} target='_blank' rel='noopener noreferrer' title={brew.title || '[ no title ]'}>
return _.map(brews, (brew, i)=>{
return <a href={brew.url} className='item' key={`${brew.id}-${i}`} target='_blank' rel='noopener noreferrer' title={brew.title || '[ no title ]'}>
<span className='title'>{brew.title || '[ no title ]'}</span>
<span className='time'>{Moment(brew.ts).fromNow()}</span>
</a>;

View File

@@ -8,6 +8,7 @@ const MAIN_URL = 'https://www.reddit.com/r/UnearthedArcana/submit?selftext=true'
const RedditShare = createClass({
displayName : 'RedditShareNavItem',
getDefaultProps : function() {
return {
brew : {

View File

@@ -10,7 +10,7 @@ const Nav = require('naturalcrit/nav/nav.jsx');
const Navbar = require('../../navbar/navbar.jsx');
const NewBrew = require('../../navbar/newbrew.navitem.jsx');
const ReportIssue = require('../../navbar/issue.navitem.jsx');
const HelpNavItem = require('../../navbar/help.navitem.jsx');
const PrintLink = require('../../navbar/print.navitem.jsx');
const Account = require('../../navbar/account.navitem.jsx');
const RecentNavItem = require('../../navbar/recent.navitem.jsx').both;
@@ -27,6 +27,7 @@ const googleDriveInactive = require('../../googleDriveMono.png');
const SAVE_TIMEOUT = 3000;
const EditPage = createClass({
displayName : 'EditPage',
getDefaultProps : function() {
return {
brew : {
@@ -433,7 +434,7 @@ const EditPage = createClass({
{this.renderGoogleDriveIcon()}
{this.renderSaveButton()}
<NewBrew />
<ReportIssue />
<HelpNavItem/>
<Nav.dropdown>
<Nav.item color='teal' icon='fas fa-share-alt'>
share

View File

@@ -7,8 +7,8 @@ const cx = require('classnames');
const Nav = require('naturalcrit/nav/nav.jsx');
const Navbar = require('../../navbar/navbar.jsx');
const PatreonNavItem = require('../../navbar/patreon.navitem.jsx');
const IssueNavItem = require('../../navbar/issue.navitem.jsx');
const RecentNavItem = require('../../navbar/recent.navitem.jsx').both;
const HelpNavItem = require('../../navbar/help.navitem.jsx');
const BrewRenderer = require('../../brewRenderer/brewRenderer.jsx');
@@ -33,7 +33,7 @@ const ErrorPage = createClass({
<Nav.section>
<PatreonNavItem />
<IssueNavItem />
<HelpNavItem />
<RecentNavItem />
</Nav.section>
</Navbar>

View File

@@ -9,7 +9,7 @@ const { Meta } = require('vitreum/headtags');
const Nav = require('naturalcrit/nav/nav.jsx');
const Navbar = require('../../navbar/navbar.jsx');
const NewBrewItem = require('../../navbar/newbrew.navitem.jsx');
const IssueNavItem = require('../../navbar/issue.navitem.jsx');
const HelpNavItem = require('../../navbar/help.navitem.jsx');
const RecentNavItem = require('../../navbar/recent.navitem.jsx').both;
const AccountNavItem = require('../../navbar/account.navitem.jsx');
@@ -21,6 +21,7 @@ const BrewRenderer = require('../../brewRenderer/brewRenderer.jsx');
const HomePage = createClass({
displayName : 'HomePage',
getDefaultProps : function() {
return {
brew : {
@@ -58,7 +59,7 @@ const HomePage = createClass({
return <Navbar ver={this.props.ver}>
<Nav.section>
<NewBrewItem />
<IssueNavItem />
<HelpNavItem />
<RecentNavItem />
<AccountNavItem />
</Nav.section>

View File

@@ -0,0 +1,202 @@
# How to Convert a Legacy Document to v3
Here you will find a number of steps to guide you through converting a Legacy document into a Homebrewery v3 document.
**The first thing you'll want to do is switch the editor's rendering engine from `Legacy` to `v3`.** This will be the renderer we design features for moving forward.
There are some examples of Legacy code in the code pane if you need more context behind some of the changes.
**This document will evolve as users like yourself inform us of issues with it, or areas of conversion that it does not cover. _Please_ reach out if you have any suggestions for this document.**
## Simple Replacements
To make your life a little easier with this section, a text editor like [VSCode](https://code.visualstudio.com/) or Notepad will help a lot.
The following table describes Legacy and other document elements and their Homebrewery counterparts. A simple find/replace should get these in working order.
| Legacy / Other | Homebrewery |
|:----------------|:-----------------------------|
| `\pagebreak` | `\page` |
| `======` | `\page` |
| `\pagebreaknum` | `{{pageNumber,auto}}\n\page` |
| `@=====` | `{{pageNumber,auto}}\n\page` |
| `\columnbreak` | `\column` |
| `.phb` | `.page` |
## Classed or Styled Divs
Anything that relies on the following syntax can be changed to the new Homebrewery v3 curly brace syntax:
```
<div class="classTable wide">
...
</div>
```
:
The above example is equivalent to the following in v3 syntax.
```
{{classTable,wide
...
}}
```
:
Some examples of this include class tables (as shown above), descriptive blocks, notes, and spell lists.
\column
## Margins and Padding
Any manual margins and padding to push text down the page will likely need to be updated. Colons can be used on lines by themselves to push things down the page vertically if you'd rather not set pixel-perfect margins or padding.
## Notes
In Legacy, notes are denoted using markdown blockquote syntax. In Homebrewery v3, this is replaced by the curly brace syntax.
<!--
> ##### Catchy Title
> Useful Information
-->
{{note
##### Title
Information
}}
## Split Tables
Split tables also use the curly brace syntax, as the new renderer can handle style values separately from class names.
<!--
<div style='column-count:2'>
| d8 | Loot |
|:---:|:-----------:|
| 1 | 100gp |
| 2 | 200gp |
| 3 | 300gp |
| 4 | 400gp |
| d8 | Loot |
|:---:|:-----------:|
| 5 | 500gp |
| 6 | 600gp |
| 7 | 700gp |
| 8 | 1000gp |
</div>
-->
##### Typical Difficulty Classes
{{column-count:2
| Task Difficulty | DC |
|:----------------|:--:|
| Very easy | 5 |
| Easy | 10 |
| Medium | 15 |
| Task Difficulty | DC |
|:------------------|:--:|
| Hard | 20 |
| Very hard | 25 |
| Nearly impossible | 30 |
}}
## Blockquotes
Blockquotes are denoted by the `>` character at the beginning of the line. In Homebrewery's v3 renderer, they hold virtually no meaning and have no CSS styling. You are free to use blockquotes when styling your document or creating themes without needing to worry about your CSS affecting other parts of the document.
{{pageNumber,auto}}
\page
## Stat Blocks
There are pretty significant differences between stat blocks on the Legacy renderer and Homebrewery v3. This section contains a list of changes that will need to be made to update the stat block.
### Initial Changes
You will want to **remove all leading** `___` that started the stat block in Legacy, and replace that with `{{monster` before the stat block, and `}}` after it.
**If you want a frame** around the stat block, you can add `,frame` to the curly brace definition.
**If the stat block was wide**, make sure to add `,wide` to the curly brace definition.
### Blockquotes
The key difference is the lack of blockquotes. Legacy documents use the `>` symbol at the start of the line for each line in the stat block, and the v3 renderer does not. **You will want to remove all `>` characters at the beginning of all lines, and delete any leading spaces.**
### Lists
The basic characteristics and advanced characteristics sections are not list elements in Homebrewery. You will want to **remove all `-` or `*` characters from the beginning of lines.**
### Spacing
In order to have the correct spacing after removing the list elements, you will want to **add two colons between the name of each basic/advanced characteristic and its value.** _(see example in the code pane)_
Additionally, in the special traits and actions sections, you will want to add a colon at the beginning of each line that separates a trait/action from another, as seen below. **Any empty lines between special traits and actions should contain only a colon.** _(see example in the code pane)_
\column
{{margin-top:102px}}
<!--
### Legacy/Other Document Example:
___
> ## Centaur
> *Large Monstrosity, neutral good*
>___
> - **Armor Class** 12
> - **Hit Points** 45(6d10 + 12)
> - **Speed** 50ft.
>___
>|STR|DEX|CON|INT|WIS|CHA|
>|:---:|:---:|:---:|:---:|:---:|:---:|
>|18 (+4)|14 (+2)|14 (+2)|9 (-1)|13 (+1)|11 (+0)|
>___
> - **Skills** Athletics +6, Perception +3, Survival +3
> - **Senses** passive Perception 13
> - **Languages** Elvish, Sylvan
> - **Challenge** 2 (450 XP)
> ___
> ***Charge.*** If the centaur moves at least 30 feet straight toward a target and then hits it with a pike attack on the same turn, the target takes an extra 10 (3d6) piercing damage.
>
> ***Second Thing*** More details.
>
> ### Actions
> ***Multiattack.*** The centaur makes two attacks: one with its pike and one with its hooves or two with its longbow.
>
> ***Pike.*** *Melee Weapon Attack:* +6 to hit, reach 10 ft., one target. *Hit:* 9 (1d10 + 4) piercing damage.
>
> ***Hooves.*** *Melee Weapon Attack:* +6 to hit, reach 5 ft., one target. *Hit:* 11 (2d6 + 4) bludgeoning damage.
>
> ***Longbow.*** *Ranged Weapon Attack:* +4 to hit, range 150/600 ft., one target. *Hit:* 6 (1d8 + 2) piercing damage.
-->
### Homebrewery v3 Example:
{{monster
## Centaur
*Large monstrosity, neutral good*
___
**Armor Class** :: 12
**Hit Points** :: 45(6d10 + 12)
**Speed** :: 50ft.
___
| STR | DEX | CON | INT | WIS | CHA |
|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|
|18 (+4)|14 (+2)|14 (+2)|9 (-1) |13 (+1)|11 (+0)|
___
**Skills** :: Athletics +6, Perception +3, Survival +3
**Senses** :: passive Perception 13
**Languages** :: Elvish, Sylvan
**Challenge** :: 2 (450 XP)
___
***Charge.*** If the centaur moves at least 30 feet straight toward a target and then hits it with a pike attack on the same turn, the target takes an extra 10 (3d6) piercing damage.
:
***Second Thing*** More details.
### Actions
***Multiattack.*** The centaur makes two attacks: one with its pike and one with its hooves or two with its longbow.
:
***Pike.*** *Melee Weapon Attack:* +6 to hit, reach 10 ft., one target. *Hit:* 9 (1d10 + 4) piercing damage.
:
***Hooves.*** *Melee Weapon Attack:* +6 to hit, reach 5 ft., one target. *Hit:* 11 (2d6 + 4) bludgeoning damage.
:
***Longbow.*** *Ranged Weapon Attack:* +4 to hit, range 150/600 ft., one target. *Hit:* 6 (1d8 + 2) piercing damage.
}}
{{pageNumber,auto}}

View File

@@ -1,4 +1,5 @@
# The Homebrewery
Welcome traveler from an antique land. Please sit and tell us of what you have seen. The unheard of monsters, who slither and bite. Tell us of the wondrous items and and artifacts you have found, their mysteries yet to be unlocked. Of the vexing vocations and surprising skills you have seen.
### Homebrew D&D made easy
@@ -57,17 +58,20 @@ The Homebrewery is licensed using the [MIT License](https://github.com/naturalcr
If you wish to sell or in some way gain profit for what you make on this site, it's your responsibility to ensure you have the proper licenses/rights for any images or resources used.
### More Resources
If you are looking for more 5e Homebrew resources check out [r/UnearthedArcana](https://www.reddit.com/r/UnearthedArcana/) and their list of useful resources [here](https://www.reddit.com/r/UnearthedArcana/wiki/resources).
<a href='https://discord.gg/by3deKx' target='_blank'><img src='/assets/discordOfManyThings.svg' alt='Discord of Many Things Logo' title='Discord of Many Things Logo' style='width:50px; float: right; padding-left: 10px;'/></a>
If you are looking for more 5e Homebrew resources check out [r/UnearthedArcana](https://www.reddit.com/r/UnearthedArcana/) and their list of useful resources [here](https://www.reddit.com/r/UnearthedArcana/wiki/resources). The Discord of Many Things is another great resource to connect with fellow homebrewers for help and feedback.
<img src='https://i.imgur.com/hMna6G0.png' style='position:absolute;bottom:50px;right:30px;width:280px' />
<img src='https://i.imgur.com/hMna6G0.png' style='position:absolute;bottom:40px;right:30px;width:280px' />
<div class='pageNumber'>1</div>
<div class='footnote'>PART 1 | FANCINESS</div>
<div style='position: absolute; top: 40px; right: 60px;'>
<a href='https://discord.gg/by3deKx' target='_blank' title='Discord of Many Things'><img src='/assets/discord.png' height='36px'/></a><span style='position: absolute; left: -4px; top: 40px'>Discord</span>
<a href='https://github.com/naturalcrit/homebrewery' target='_blank' title='github' style='color: black; padding-left: 10px;'><img src='/assets/github.png' height='36px'/></a><span style='position: absolute; top: 40px; left: 48px'>Github</span>
<a href='https://patreon.com/NaturalCrit' target='_blank' title='patreon' style='color: black; padding-left: 10px;'><img src='/assets/patreon.png' height='36px'/></a><span style='position: absolute; top: 40px; right: 46px'>Patreon</span>
<a href='https://www.reddit.com/r/homebrewery/' target='_blank' title='reddit' style='color: black; padding-left: 10px;'><img src='/assets/reddit.png' height='36px'/></a><span style='position: absolute; top: 40px; right: 0px;'>Reddit</span>
</div>
\page

View File

@@ -2,7 +2,6 @@
.page #example + table td {
border:1px dashed #00000030;
}
.page {
padding-bottom : 1.1cm;
}
@@ -44,15 +43,22 @@ If you want to save ink or have a monochrome printer, add the **PRINT → {{fas,
[naturalcrit](https://homebrew.naturalcrit.com)
}}
{{position:absolute;top:40px;right:-580px
<a href='https://discord.gg/by3deKx' target='_blank' title='discord' style='color: black;'><img src='/assets/discord.png' height='36px'/></a><span style='position: absolute; left: -6px; top: 40px'>Discord</span>
<a href='https://github.com/naturalcrit/homebrewery' target='_blank' title='github' style='color: black; padding-left: 10px;'><img src='/assets/github.png' height='36px'/></a><span style='position: absolute; top: 40px; left: 47px'>Github</span>
<a href='https://patreon.com/NaturalCrit' target='_blank' title='patreon' style='color: black; padding-left: 10px;'><img src='/assets/patreon.png' height='36px'/></a><span style='position: absolute; top: 40px; left: 93px'>Patreon</span>
<a href='https://www.reddit.com/r/homebrewery/' target='_blank' title='reddit' style='color: black; padding-left: 10px;'><img src='/assets/reddit.png' height='36px'/></a><span style='position: absolute; top: 40px; left: 147px;'>Reddit</span>
}}
{{pageNumber 1}}
{{footnote PART 1 | FANCINESS}}
\column
## New in V3.0.0
With the latest major update to *The Homebrewery* we've implemented an extended Markdown-like syntax for block and span elements, plus a few other changes, eliminating the need for HTML tags like `div` and `span` in most cases. No raw HTML tags should be needed in a brew, and going forward, raw HTML will no longer receive debugging support (*but can still be used if you insist*).
We've implemented an extended Markdown-like syntax for block and span elements, plus a few other changes, eliminating the need for HTML tags like `div` and `span` in most cases. No raw HTML tags should be needed in a brew (*but can still be used if you insist*).
Much of the syntax and styling has changed in V3. Code in one version may be broken in the other, and updating an older brew to V3 will require more than just a copy and paste. *However*, all brews made prior to the release of v3.0.0 will still render normally, and you may switch between the "Legacy" brew renderer and the newer "V3" renderer via the {{fa,fa-info-circle}} **Properties** button on your brew at any time.
Much of the syntax and styling has changed in V3, so converting a Legacy brew to V3 (or vice-versa) will require tweaking your document. *However*, all brews made prior to the release of v3.0.0 will still render normally, and you may switch between the "Legacy" brew renderer and the newer "V3" renderer via the {{fa,fa-info-circle}} **Properties** button on your brew at any time.
Scroll down to the next page for a brief summary of the changes and new features available in V3!
@@ -80,8 +86,8 @@ If you wish to sell or in some way gain profit for what's created on this site,
If you'd like to credit me in your brew, I'd be flattered! Just reference that you made it with The Homebrewery.
### More Homebrew Resources
Check out [r/UnearthedArcana](https://www.reddit.com/r/UnearthedArcana/) and their list of useful resources [here](https://www.reddit.com/r/UnearthedArcana/wiki/resources).
<a href='https://discord.gg/by3deKx' target='_blank'><img src='/assets/discordOfManyThings.svg' alt='Discord of Many Things Logo' title='Discord of Many Things Logo' style='width:50px; float: right; padding-left: 10px;'/></a>
If you are looking for more 5e Homebrew resources check out [r/UnearthedArcana](https://www.reddit.com/r/UnearthedArcana/) and their list of useful resources [here](https://www.reddit.com/r/UnearthedArcana/wiki/resources). The <a href='https://discord.gg/by3deKx' target='_blank' title='Discord of Many Things'>Discord of Many Things</a> is another great resource to connect with fellow homebrewers for help and feedback.
\page
@@ -123,9 +129,7 @@ A blank line can be achieved with a run of one or more `:` alone on a line. More
Much nicer than `<br><br><br><br><br>`
### Definition Lists
V3 uses HTML *definition lists* to create "lists" with hanging indents.
**Senses** :: Here is some text that is long and overflows into a second line, creating a "hanging indent".
**Example** :: V3 uses HTML *definition lists* to create "lists" with hanging indents.
### Column Breaks
Column and page breaks with `\column` and `\page`.
@@ -153,9 +157,9 @@ These can be combined to span a cell across both columns and rows. Cells must ha
| 6A | 6B ^| 6C |
## Images
Images must be hosted online somewhere, like [Imgur](https://www.imgur.com). You use the address to that image to reference it in your brew\*. Images can be included using Markdown-style images.
Images must be hosted online somewhere, like [Imgur](https://www.imgur.com). You use the address to that image to reference it in your brew\*.
Using *Curly Injection* you can assign an id, classes, or specific inline CSS properties to the image.
Using *Curly Injection* you can assign an id, classes, or inline CSS properties to the Markdown image syntax.
![alt-text](https://s-media-cache-ak0.pinimg.com/736x/4a/81/79/4a8179462cfdf39054a418efd4cb743e.jpg) {width:100px,border:"2px solid",border-radius:10px}

View File

@@ -11,7 +11,7 @@ const Nav = require('naturalcrit/nav/nav.jsx');
const Navbar = require('../../navbar/navbar.jsx');
const AccountNavItem = require('../../navbar/account.navitem.jsx');
const RecentNavItem = require('../../navbar/recent.navitem.jsx').both;
const IssueNavItem = require('../../navbar/issue.navitem.jsx');
const HelpNavItem = require('../../navbar/help.navitem.jsx');
const SplitPane = require('naturalcrit/splitPane/splitPane.jsx');
const Editor = require('../../editor/editor.jsx');
@@ -23,6 +23,7 @@ const METAKEY = 'homebrewery-new-meta';
const NewPage = createClass({
displayName : 'NewPage',
getDefaultProps : function() {
return {
brew : {
@@ -290,7 +291,7 @@ const NewPage = createClass({
<Nav.section>
{this.renderSaveButton()}
{this.renderLocalPrintButton()}
<IssueNavItem />
<HelpNavItem />
<RecentNavItem />
<AccountNavItem />
</Nav.section>

View File

@@ -12,6 +12,7 @@ const STYLEKEY = 'homebrewery-new-style';
const METAKEY = 'homebrewery-new-meta';
const PrintPage = createClass({
displayName : 'PrintPage',
getDefaultProps : function() {
return {
query : {},

View File

@@ -14,6 +14,7 @@ const BrewRenderer = require('../../brewRenderer/brewRenderer.jsx');
const SharePage = createClass({
displayName : 'SharePage',
getDefaultProps : function() {
return {
brew : {

View File

@@ -10,6 +10,7 @@ const googleDriveIcon = require('../../../googleDrive.png');
const dedent = require('dedent-tabs').default;
const BrewItem = createClass({
displayName : 'BrewItem',
getDefaultProps : function() {
return {
brew : {

View File

@@ -13,7 +13,7 @@ const RecentNavItem = require('../../navbar/recent.navitem.jsx').both;
const Account = require('../../navbar/account.navitem.jsx');
const NewBrew = require('../../navbar/newbrew.navitem.jsx');
const BrewItem = require('./brewItem/brewItem.jsx');
const ReportIssue = require('../../navbar/issue.navitem.jsx');
const HelpNavItem = require('../../navbar/help.navitem.jsx');
// const brew = {
// title : 'SUPER Long title woah now',
@@ -24,6 +24,7 @@ const ReportIssue = require('../../navbar/issue.navitem.jsx');
const UserPage = createClass({
displayName : 'UserPage',
getDefaultProps : function() {
return {
username : '',
@@ -163,7 +164,7 @@ const UserPage = createClass({
<Navbar>
<Nav.section>
<NewBrew />
<ReportIssue />
<HelpNavItem />
<RecentNavItem />
<Account />
</Nav.section>

View File

@@ -10,7 +10,7 @@ These instructions assume that you are installing to a completely new, fresh Fre
2. Install wget (`pkg install -y wget`). On a fresh jail, you will be prompted to press 'Y' to set up `pkg`.
3. Download the installation script (`wget --no-check-certificate https://raw.githubusercontent.com/naturalcrit/homebrewery/master/freebsd/install.sh`). The parameter `--no-check-certificate` is required as we haven't set up any trusted certificates/authorities yet.
3. Download the installation script (`wget --no-check-certificate https://raw.githubusercontent.com/naturalcrit/homebrewery/master/install/freebsd/install.sh`). The parameter `--no-check-certificate` is required as we haven't set up any trusted certificates/authorities yet.
4. Make the downloaded file executable (`chmod +x install.sh`).

35
install/README.UBUNTU.md Normal file
View File

@@ -0,0 +1,35 @@
# Ubuntu Installation Instructions
## Before Installing
These instructions assume that you are installing to a completely new, fresh Ubuntu installation. As such, some steps will not be necessary if you are installing to an existing Ubuntu instance.
## Installation instructions
1. Install Ubuntu.
2. Install wget (`apt install -y wget`). This may already be installed, depending on your exact Ubuntu version.
3. Download the installation script (`wget https://raw.githubusercontent.com/naturalcrit/homebrewery/master/install/ubuntu/install.sh`).
4. Make the downloaded file executable (`chmod +x install.sh`).
5. Run the script (`sudo ./install.sh`). This will automatically download all of the required packages, install both them and HomeBrewery, configure the system and finally start HomeBrewery.
**NOTE:** At this time, the script **ONLY** installs HomeBrewery. It does **NOT** install the NaturalCrit login system, as that is currently a completely separate project.
---
### Testing
These installation instructions have been tested on the following Ubuntu releases:
- *ubuntu-20.04.3-desktop-amd64*
## Final Notes
While this installation process works successfully at the time of writing (December 19, 2021), it relies on all of the Node.JS packages used in the HomeBrewery project retaining their cross-platform capabilities to continue to function. This is one of the inherent advantages of Node.JS, but it is by no means guaranteed and as such, functionality or even installation may fail without warning at some point in the future.
Regards,
G
December 19, 2021

View File

@@ -0,0 +1,13 @@
[Unit]
Description=Homebrewery Web Server
[Service]
User=root
After=mongodb
Environment=NODE_ENV=local
WorkingDirectory=/usr/local/homebrewery
ExecStart=node server.js
Restart=always
[Install]
WantedBy=multi-user.target

34
install/ubuntu/install.sh Normal file
View File

@@ -0,0 +1,34 @@
#!/bin/sh
# Install CURL and add required NodeJS source to package repo
echo ::Install CURL
apt install -y curl
echo ::Add NodeJS source to package repo
curl -fsSL https://deb.nodesource.com/setup_16.x | sudo -E bash -
# Install required packages
echo ::Install Homebrewery requirements
apt satisfy -y git nodejs npm mongodb
# Clone Homebrewery repo
echo ::Get Homebrewery files
cd /usr/local/
git clone https://github.com/naturalcrit/homebrewery.git
# Install Homebrewery
echo ::Install Homebrewery
cd homebrewery
npm install
npm audit fix
npm run postinstall
# Create Homebrewery service
echo ::Create Homebrewery service
ln -s /usr/local/homebrewery/install/ubuntu/etc/systemd/system/homebrewery.service /etc/systemd/system/homebrewery.service
systemctl daemon-reload
echo ::Set Homebrewery to start automatically
systemctl enable homebrewery
# Start Homebrewery
echo ::Start Homebrewery
systemctl start homebrewery

9589
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
{
"name": "homebrewery",
"description": "Create authentic looking D&D homebrews using only markdown",
"version": "3.0.6",
"version": "3.0.7",
"engines": {
"node": "16.11.x"
},
@@ -18,8 +18,8 @@
"lint:dry": "eslint **/*.{js,jsx}",
"circleci": "npm test && eslint **/*.{js,jsx} --max-warnings=0",
"verify": "npm run lint && npm test",
"test": "pico-check",
"test:dev": "pico-check -v -w",
"test": "jest",
"test:dev": "jest --verbose --watch",
"phb": "node scripts/phb.js",
"prod": "set NODE_ENV=production && npm run build",
"postinstall": "npm run buildall",
@@ -30,44 +30,50 @@
"eslintIgnore": [
"build/*"
],
"pico-check": {
"require": "./tests/test.init.js"
"jest": {
"modulePaths": [
"mode_modules",
"shared",
"server"
]
},
"babel": {
"presets": [
"@babel/preset-env",
"@babel/preset-react"
],
"plugins": [
"@babel/plugin-transform-runtime"
]
},
"dependencies": {
"@babel/core": "^7.16.5",
"@babel/plugin-transform-runtime": "^7.16.5",
"@babel/preset-env": "^7.16.5",
"@babel/preset-react": "^7.16.5",
"@babel/core": "^7.17.0",
"@babel/plugin-transform-runtime": "^7.17.0",
"@babel/preset-env": "^7.16.11",
"@babel/preset-react": "^7.16.7",
"body-parser": "^1.19.1",
"classnames": "^2.3.1",
"codemirror": "^5.64.0",
"codemirror": "^5.65.1",
"cookie-parser": "^1.4.6",
"create-react-class": "^15.7.0",
"dedent-tabs": "^0.10.1",
"express": "^4.17.1",
"express": "^4.17.2",
"express-async-handler": "^1.2.0",
"express-static-gzip": "2.1.1",
"fs-extra": "10.0.0",
"googleapis": "92.0.0",
"googleapis": "94.0.0",
"js-yaml": "^4.1.0",
"jwt-simple": "^0.5.6",
"less": "^3.13.1",
"lodash": "^4.17.21",
"marked": "4.0.7",
"marked": "4.0.12",
"marked-extended-tables": "^1.0.3",
"markedLegacy": "npm:marked@^0.3.19",
"moment": "^2.29.1",
"mongoose": "^6.1.2",
"nanoid": "3.1.30",
"mongoose": "^6.2.0",
"nanoid": "3.2.0",
"nconf": "^0.11.3",
"prop-types": "15.7.2",
"query-string": "7.0.1",
"query-string": "7.1.0",
"react": "^16.14.0",
"react-dom": "^16.14.0",
"react-frame-component": "4.1.3",
@@ -77,8 +83,9 @@
"vitreum": "git+https://git@github.com/calculuschild/vitreum.git"
},
"devDependencies": {
"eslint": "^8.4.1",
"eslint-plugin-react": "^7.27.1",
"pico-check": "^2.2.0"
"eslint": "^8.8.0",
"eslint-plugin-react": "^7.28.0",
"jest": "^27.4.5",
"supertest": "^6.2.2"
}
}

View File

@@ -25,6 +25,7 @@ const build = async ({ bundle, render, ssr })=>{
await fs.outputFile('./build/homebrew/bundle.js', bundle);
await fs.outputFile('./build/homebrew/ssr.js', ssr);
await fs.copy('./themes/fonts', './build/fonts');
await fs.copy('./themes/assets', './build/assets');
let src = './themes/5ePhbLegacy.style.less';
//Parse brew theme files
less.render(fs.readFileSync(src).toString(), {
@@ -73,6 +74,6 @@ pack('./client/homebrew/homebrew.jsx', {
if(isDev){
livereload('./build');
watchFile('./server.js', {
watch : ['./client'] // Watch additional folders if you want
watch : ['./client', './server'] // Watch additional folders if you want
});
}

315
server.js
View File

@@ -1,309 +1,12 @@
/*eslint max-lines: ["warn", {"max": 300, "skipBlankLines": true, "skipComments": true}]*/
const _ = require('lodash');
const jwt = require('jwt-simple');
const express = require('express');
const yaml = require('js-yaml');
const app = express();
const DB = require('./server/db.js');
const server = require('./server/app.js');
const config = require('./server/config.js');
const homebrewApi = require('./server/homebrew.api.js');
const GoogleActions = require('./server/googleActions.js');
const serveCompressedStaticAssets = require('./server/static-assets.mv.js');
const sanitizeFilename = require('sanitize-filename');
const asyncHandler = require('express-async-handler');
const brewAccessTypes = ['edit', 'share', 'raw'];
//Get the brew object from the HB database or Google Drive
const getBrewFromId = asyncHandler(async (id, accessType)=>{
if(!brewAccessTypes.includes(accessType))
throw ('Invalid Access Type when getting brew');
let brew;
if(id.length > 12) {
const googleId = id.slice(0, -12);
id = id.slice(-12);
brew = await GoogleActions.readFileMetadata(config.get('google_api_key'), googleId, id, accessType);
} else {
brew = await HomebrewModel.get(accessType == 'edit' ? { editId: id } : { shareId: id });
brew = brew.toObject(); // Convert MongoDB object to standard Javascript Object
}
brew = sanitizeBrew(brew, accessType === 'edit' ? false : true);
//Split brew.text into text and style
//unless the Access Type is RAW, in which case return immediately
if(accessType == 'raw') {
return brew;
}
splitTextStyleAndMetadata(brew);
return brew;
});
const sanitizeBrew = (brew, full=false)=>{
delete brew._id;
delete brew.__v;
if(full){
delete brew.editId;
}
return brew;
};
const splitTextStyleAndMetadata = (brew)=>{
brew.text = brew.text.replaceAll('\r\n', '\n');
if(brew.text.startsWith('```metadata')) {
const index = brew.text.indexOf('```\n\n');
const metadataSection = brew.text.slice(12, index - 1);
const metadata = yaml.load(metadataSection);
Object.assign(brew, _.pick(metadata, ['title', 'description', 'tags', 'systems', 'renderer']));
brew.text = brew.text.slice(index + 5);
}
if(brew.text.startsWith('```css')) {
const index = brew.text.indexOf('```\n\n');
brew.style = brew.text.slice(7, index - 1);
brew.text = brew.text.slice(index + 5);
}
};
app.use('/', serveCompressedStaticAssets(`${__dirname}/build`));
process.chdir(__dirname);
//app.use(express.static(`${__dirname}/build`));
app.use(require('body-parser').json({ limit: '25mb' }));
app.use(require('cookie-parser')());
app.use(require('./server/forcessl.mw.js'));
const config = require('nconf')
.argv()
.env({ lowerCase: true })
.file('environment', { file: `config/${process.env.NODE_ENV}.json` })
.file('defaults', { file: 'config/default.json' });
//DB
const mongoose = require('mongoose');
mongoose.connect(config.get('mongodb_uri') || config.get('mongolab_uri') || 'mongodb://localhost/naturalcrit',
{ retryWrites: false });
mongoose.connection.on('error', (err)=>{
console.log('Error : Could not connect to a Mongo Database.');
console.log(' If you are running locally, make sure mongodb.exe is running.');
console.log(err);
throw 'Can not connect to Mongo';
});
//Account Middleware
app.use((req, res, next)=>{
if(req.cookies && req.cookies.nc_session){
try {
req.account = jwt.decode(req.cookies.nc_session, config.get('secret'));
//console.log("Just loaded up JWT from cookie:");
//console.log(req.account);
} catch (e){}
}
req.config = {
google_client_id : config.get('google_client_id'),
google_client_secret : config.get('google_client_secret')
};
return next();
});
app.use(homebrewApi);
app.use(require('./server/admin.api.js'));
const HomebrewModel = require('./server/homebrew.model.js').model;
const welcomeText = require('fs').readFileSync('./client/homebrew/pages/homePage/welcome_msg.md', 'utf8');
const welcomeTextV3 = require('fs').readFileSync('./client/homebrew/pages/homePage/welcome_msg_v3.md', 'utf8');
const changelogText = require('fs').readFileSync('./changelog.md', 'utf8');
const faqText = require('fs').readFileSync('./faq.md', 'utf8');
String.prototype.replaceAll = function(s, r){return this.split(s).join(r);};
//Robots.txt
app.get('/robots.txt', (req, res)=>{
return res.sendFile(`${__dirname}/robots.txt`);
});
//Home page
app.get('/', async (req, res, next)=>{
const brew = {
text : welcomeText
};
req.brew = brew;
return next();
});
//Home page v3
app.get('/v3_preview', async (req, res, next)=>{
const brew = {
text : welcomeTextV3,
renderer : 'V3'
};
splitTextStyleAndMetadata(brew);
req.brew = brew;
return next();
});
//Changelog page
app.get('/changelog', async (req, res, next)=>{
const brew = {
title : 'Changelog',
text : changelogText,
renderer : 'V3'
};
splitTextStyleAndMetadata(brew);
req.brew = brew;
return next();
});
//FAQ page
app.get('/faq', async (req, res, next)=>{
const brew = {
title : 'FAQ',
text : faqText,
renderer : 'V3'
};
splitTextStyleAndMetadata(brew);
req.brew = brew;
return next();
});
//Source page
app.get('/source/:id', asyncHandler(async (req, res)=>{
const brew = await getBrewFromId(req.params.id, 'raw');
const replaceStrings = { '&': '&amp;', '<': '&lt;', '>': '&gt;' };
let text = brew.text;
for (const replaceStr in replaceStrings) {
text = text.replaceAll(replaceStr, replaceStrings[replaceStr]);
}
text = `<code><pre style="white-space: pre-wrap;">${text}</pre></code>`;
res.status(200).send(text);
}));
//Download brew source page
app.get('/download/:id', asyncHandler(async (req, res)=>{
const brew = await getBrewFromId(req.params.id, 'raw');
const prefix = 'HB - ';
let fileName = sanitizeFilename(`${prefix}${brew.title}`).replaceAll(' ', '');
if(!fileName || !fileName.length) { fileName = `${prefix}-Untitled-Brew`; };
res.set({
'Cache-Control' : 'no-cache',
'Content-Type' : 'text/plain',
'Content-Disposition' : `attachment; filename="${fileName}.txt"`
DB.connect(config).then(()=>{
// Ensure that we have successfully connected to the database
// before launching server
const PORT = process.env.PORT || config.get('web_port') || 8000;
server.app.listen(PORT, ()=>{
console.log(`server on port: ${PORT}`);
});
res.status(200).send(brew.text);
}));
//User Page
app.get('/user/:username', async (req, res, next)=>{
const ownAccount = req.account && (req.account.username == req.params.username);
let brews = await HomebrewModel.getByUser(req.params.username, ownAccount)
.catch((err)=>{
console.log(err);
});
if(ownAccount && req?.account?.googleId){
const googleBrews = await GoogleActions.listGoogleBrews(req, res)
.catch((err)=>{
console.error(err);
});
if(googleBrews)
brews = _.concat(brews, googleBrews);
}
req.brews = _.map(brews, (brew)=>{
return sanitizeBrew(brew, !ownAccount);
});
return next();
});
//Edit Page
app.get('/edit/:id', asyncHandler(async (req, res, next)=>{
res.header('Cache-Control', 'no-cache, no-store'); //reload the latest saved brew when pressing back button, not the cached version before save.
const brew = await getBrewFromId(req.params.id, 'edit');
req.brew = brew;
return next();
}));
//New Page
app.get('/new/:id', asyncHandler(async (req, res, next)=>{
const brew = await getBrewFromId(req.params.id, 'share');
brew.title = `CLONE - ${brew.title}`;
req.brew = brew;
return next();
}));
//Share Page
app.get('/share/:id', asyncHandler(async (req, res, next)=>{
const brew = await getBrewFromId(req.params.id, 'share');
if(req.params.id.length > 12) {
const googleId = req.params.id.slice(0, -12);
const shareId = req.params.id.slice(-12);
await GoogleActions.increaseView(googleId, shareId, 'share', brew)
.catch((err)=>{next(err);});
} else {
await HomebrewModel.increaseView({ shareId: brew.shareId });
}
req.brew = brew;
return next();
}));
//Print Page
app.get('/print/:id', asyncHandler(async (req, res, next)=>{
const brew = await getBrewFromId(req.params.id, 'share');
req.brew = brew;
return next();
}));
//Render the page
const templateFn = require('./client/template.js');
app.use((req, res)=>{
const props = {
version : require('./package.json').version,
url : req.originalUrl,
brew : req.brew,
brews : req.brews,
googleBrews : req.googleBrews,
account : req.account,
enable_v3 : config.get('enable_v3')
};
templateFn('homebrew', title = req.brew ? req.brew.title : '', props)
.then((page)=>{ res.send(page); })
.catch((err)=>{
console.log(err);
return res.sendStatus(500);
});
});
//v=====----- Error-Handling Middleware -----=====v//
//Format Errors so all fields will be sent
const replaceErrors = (key, value)=>{
if(value instanceof Error) {
const error = {};
Object.getOwnPropertyNames(value).forEach(function (key) {
error[key] = value[key];
});
return error;
}
return value;
};
const getPureError = (error)=>{
return JSON.parse(JSON.stringify(error, replaceErrors));
};
app.use((err, req, res, next)=>{
const status = err.status || 500;
console.error(err);
res.status(status).send(getPureError(err));
});
//^=====--------------------------------------=====^//
const PORT = process.env.PORT || config.get('web_port') || 8000;
app.listen(PORT, ()=>{
console.log(`server on port:${PORT}`);
});

306
server/app.js Normal file
View File

@@ -0,0 +1,306 @@
/*eslint max-lines: ["warn", {"max": 300, "skipBlankLines": true, "skipComments": true}]*/
// Set working directory to project root
process.chdir(`${__dirname}/..`);
const _ = require('lodash');
const jwt = require('jwt-simple');
const express = require('express');
const yaml = require('js-yaml');
const app = express();
const config = require('./config.js');
const homebrewApi = require('./homebrew.api.js');
const GoogleActions = require('./googleActions.js');
const serveCompressedStaticAssets = require('./static-assets.mv.js');
const sanitizeFilename = require('sanitize-filename');
const asyncHandler = require('express-async-handler');
const brewAccessTypes = ['edit', 'share', 'raw'];
//Get the brew object from the HB database or Google Drive
const getBrewFromId = asyncHandler(async (id, accessType)=>{
if(!brewAccessTypes.includes(accessType))
throw ('Invalid Access Type when getting brew');
let brew;
if(id.length > 12) {
const googleId = id.slice(0, -12);
id = id.slice(-12);
brew = await GoogleActions.readFileMetadata(config.get('google_api_key'), googleId, id, accessType);
} else {
brew = await HomebrewModel.get(accessType == 'edit' ? { editId: id } : { shareId: id });
brew = brew.toObject(); // Convert MongoDB object to standard Javascript Object
}
brew = sanitizeBrew(brew, accessType === 'edit' ? false : true);
//Split brew.text into text and style
//unless the Access Type is RAW, in which case return immediately
if(accessType == 'raw') {
return brew;
}
splitTextStyleAndMetadata(brew);
return brew;
});
const sanitizeBrew = (brew, full=false)=>{
delete brew._id;
delete brew.__v;
if(full){
delete brew.editId;
}
return brew;
};
const splitTextStyleAndMetadata = (brew)=>{
brew.text = brew.text.replaceAll('\r\n', '\n');
if(brew.text.startsWith('```metadata')) {
const index = brew.text.indexOf('```\n\n');
const metadataSection = brew.text.slice(12, index - 1);
const metadata = yaml.load(metadataSection);
Object.assign(brew, _.pick(metadata, ['title', 'description', 'tags', 'systems', 'renderer']));
brew.text = brew.text.slice(index + 5);
}
if(brew.text.startsWith('```css')) {
const index = brew.text.indexOf('```\n\n');
brew.style = brew.text.slice(7, index - 1);
brew.text = brew.text.slice(index + 5);
}
};
app.use('/', serveCompressedStaticAssets(`build`));
//app.use(express.static(`${__dirname}/build`));
app.use(require('body-parser').json({ limit: '25mb' }));
app.use(require('cookie-parser')());
app.use(require('./forcessl.mw.js'));
//Account Middleware
app.use((req, res, next)=>{
if(req.cookies && req.cookies.nc_session){
try {
req.account = jwt.decode(req.cookies.nc_session, config.get('secret'));
//console.log("Just loaded up JWT from cookie:");
//console.log(req.account);
} catch (e){}
}
req.config = {
google_client_id : config.get('google_client_id'),
google_client_secret : config.get('google_client_secret')
};
return next();
});
app.use(homebrewApi);
app.use(require('./admin.api.js'));
const HomebrewModel = require('./homebrew.model.js').model;
const welcomeText = require('fs').readFileSync('client/homebrew/pages/homePage/welcome_msg.md', 'utf8');
const welcomeTextV3 = require('fs').readFileSync('client/homebrew/pages/homePage/welcome_msg_v3.md', 'utf8');
const migrateText = require('fs').readFileSync('client/homebrew/pages/homePage/migrate.md', 'utf8');
const changelogText = require('fs').readFileSync('changelog.md', 'utf8');
const faqText = require('fs').readFileSync('faq.md', 'utf8');
String.prototype.replaceAll = function(s, r){return this.split(s).join(r);};
//Robots.txt
app.get('/robots.txt', (req, res)=>{
return res.sendFile(`robots.txt`, { root: process.cwd() });
});
//Home page
app.get('/', async (req, res, next)=>{
const brew = {
text : welcomeText
};
req.brew = brew;
return next();
});
//Home page v3
app.get('/v3_preview', async (req, res, next)=>{
const brew = {
text : welcomeTextV3,
renderer : 'V3'
};
splitTextStyleAndMetadata(brew);
req.brew = brew;
return next();
});
//Legacy/Other Document -> v3 Migration Guide
app.get('/migrate', async (req, res, next)=>{
const brew = {
text : migrateText,
renderer : 'V3'
};
splitTextStyleAndMetadata(brew);
req.brew = brew;
return next();
});
//Changelog page
app.get('/changelog', async (req, res, next)=>{
const brew = {
title : 'Changelog',
text : changelogText,
renderer : 'V3'
};
splitTextStyleAndMetadata(brew);
req.brew = brew;
return next();
});
//FAQ page
app.get('/faq', async (req, res, next)=>{
const brew = {
title : 'FAQ',
text : faqText,
renderer : 'V3'
};
splitTextStyleAndMetadata(brew);
req.brew = brew;
return next();
});
//Source page
app.get('/source/:id', asyncHandler(async (req, res)=>{
const brew = await getBrewFromId(req.params.id, 'raw');
const replaceStrings = { '&': '&amp;', '<': '&lt;', '>': '&gt;' };
let text = brew.text;
for (const replaceStr in replaceStrings) {
text = text.replaceAll(replaceStr, replaceStrings[replaceStr]);
}
text = `<code><pre style="white-space: pre-wrap;">${text}</pre></code>`;
res.status(200).send(text);
}));
//Download brew source page
app.get('/download/:id', asyncHandler(async (req, res)=>{
const brew = await getBrewFromId(req.params.id, 'raw');
const prefix = 'HB - ';
let fileName = sanitizeFilename(`${prefix}${brew.title}`).replaceAll(' ', '');
if(!fileName || !fileName.length) { fileName = `${prefix}-Untitled-Brew`; };
res.set({
'Cache-Control' : 'no-cache',
'Content-Type' : 'text/plain',
'Content-Disposition' : `attachment; filename="${fileName}.txt"`
});
res.status(200).send(brew.text);
}));
//User Page
app.get('/user/:username', async (req, res, next)=>{
const ownAccount = req.account && (req.account.username == req.params.username);
let brews = await HomebrewModel.getByUser(req.params.username, ownAccount)
.catch((err)=>{
console.log(err);
});
if(ownAccount && req?.account?.googleId){
const googleBrews = await GoogleActions.listGoogleBrews(req, res)
.catch((err)=>{
console.error(err);
});
if(googleBrews)
brews = _.concat(brews, googleBrews);
}
req.brews = _.map(brews, (brew)=>{
return sanitizeBrew(brew, !ownAccount);
});
return next();
});
//Edit Page
app.get('/edit/:id', asyncHandler(async (req, res, next)=>{
res.header('Cache-Control', 'no-cache, no-store'); //reload the latest saved brew when pressing back button, not the cached version before save.
const brew = await getBrewFromId(req.params.id, 'edit');
req.brew = brew;
return next();
}));
//New Page
app.get('/new/:id', asyncHandler(async (req, res, next)=>{
const brew = await getBrewFromId(req.params.id, 'share');
brew.title = `CLONE - ${brew.title}`;
req.brew = brew;
return next();
}));
//Share Page
app.get('/share/:id', asyncHandler(async (req, res, next)=>{
const brew = await getBrewFromId(req.params.id, 'share');
if(req.params.id.length > 12) {
const googleId = req.params.id.slice(0, -12);
const shareId = req.params.id.slice(-12);
await GoogleActions.increaseView(googleId, shareId, 'share', brew)
.catch((err)=>{next(err);});
} else {
await HomebrewModel.increaseView({ shareId: brew.shareId });
}
req.brew = brew;
return next();
}));
//Print Page
app.get('/print/:id', asyncHandler(async (req, res, next)=>{
const brew = await getBrewFromId(req.params.id, 'share');
req.brew = brew;
return next();
}));
//Render the page
const templateFn = require('./../client/template.js');
app.use((req, res)=>{
const props = {
version : require('./../package.json').version,
url : req.originalUrl,
brew : req.brew,
brews : req.brews,
googleBrews : req.googleBrews,
account : req.account,
enable_v3 : config.get('enable_v3')
};
const title = req.brew ? req.brew.title : '';
templateFn('homebrew', title, props)
.then((page)=>{ res.send(page); })
.catch((err)=>{
console.log(err);
return res.sendStatus(500);
});
});
//v=====----- Error-Handling Middleware -----=====v//
//Format Errors so all fields will be sent
const replaceErrors = (key, value)=>{
if(value instanceof Error) {
const error = {};
Object.getOwnPropertyNames(value).forEach(function (key) {
error[key] = value[key];
});
return error;
}
return value;
};
const getPureError = (error)=>{
return JSON.parse(JSON.stringify(error, replaceErrors));
};
app.use((err, req, res, next)=>{
const status = err.status || 500;
console.error(err);
res.status(status).send(getPureError(err));
});
//^=====--------------------------------------=====^//
module.exports = {
app : app
};

5
server/config.js Normal file
View File

@@ -0,0 +1,5 @@
module.exports = require('nconf')
.argv()
.env({ lowerCase: true })
.file('environment', { file: `config/${process.env.NODE_ENV}.json` })
.file('defaults', { file: 'config/default.json' });

37
server/db.js Normal file
View File

@@ -0,0 +1,37 @@
// The main purpose of this file is to provide an interface for database
// connection. Even though the code is quite simple and basically a tiny
// wrapper around mongoose package, it works as single point where
// database setup/config is performed and the interface provided here can be
// reused by both the main application and all tests which require database
// connection.
const Mongoose = require('mongoose');
const getMongoDBURL = (config)=>{
return config.get('mongodb_uri') ||
config.get('mongolab_uri') ||
'mongodb://localhost/homebrewery';
};
const handleConnectionError = (error)=>{
if(error) {
console.error('Could not connect to a Mongo database: \n');
console.error(error);
console.error('\nIf you are running locally, make sure mongodb.exe is running and DB URL is configured properly');
process.exit(1); // non-zero exit code to indicate an error
}
};
const disconnect = async ()=>{
return await Mongoose.disconnect();
};
const connect = async (config)=>{
return await Mongoose.connect(getMongoDBURL(config),
{ retryWrites: false }, handleConnectionError);
};
module.exports = {
connect : connect,
disconnect : disconnect
};

View File

@@ -3,15 +3,11 @@ const _ = require('lodash');
const { google } = require('googleapis');
const { nanoid } = require('nanoid');
const token = require('./token.js');
const config = require('nconf')
.argv()
.env({ lowerCase: true }) // Load environment variables
.file('environment', { file: `config/${process.env.NODE_ENV}.json` })
.file('defaults', { file: 'config/default.json' });
const config = require('./config.js');
//let oAuth2Client;
GoogleActions = {
const GoogleActions = {
authCheck : (account, res)=>{
if(!account || !account.googleId){ // If not signed into Google
@@ -96,7 +92,7 @@ GoogleActions = {
const drive = google.drive({ version: 'v3', auth: oAuth2Client });
const obj = await drive.files.list({
pageSize : 100,
pageSize : 1000,
fields : 'nextPageToken, files(id, name, description, createdTime, modifiedTime, properties)',
q : 'mimeType != \'application/vnd.google-apps.folder\' and trashed = false'
})

View File

@@ -1,11 +1,7 @@
const jwt = require('jwt-simple');
// Load configuration values
const config = require('nconf')
.argv()
.env({ lowerCase: true }) // Load environment variables
.file('environment', { file: `config/${process.env.NODE_ENV}.json` })
.file('defaults', { file: 'config/default.json' });
const config = require('./config.js');
// Generate an Access Token for the given User ID
const generateAccessToken = (account)=>{

View File

@@ -7,6 +7,7 @@ const cx = require('classnames');
const DISMISS_KEY = 'dismiss_render_warning';
const RenderWarnings = createClass({
displayName : 'RenderWarnings',
getInitialState : function() {
return {
warnings : {}

View File

@@ -27,9 +27,9 @@ if(typeof navigator !== 'undefined'){
require('codemirror/addon/search/matchesonscrollbar.js');
require('codemirror/addon/dialog/dialog.js');
//Trailing space highlighting
require('codemirror/addon/edit/trailingspace.js');
// require('codemirror/addon/edit/trailingspace.js');
//Active line highlighting
require('codemirror/addon/selection/active-line.js');
// require('codemirror/addon/selection/active-line.js');
//Auto-closing
//XML code folding is a requirement of the auto-closing tag feature and is not enabled
require('codemirror/addon/fold/xml-fold.js');
@@ -40,12 +40,14 @@ if(typeof navigator !== 'undefined'){
}
const CodeEditor = createClass({
displayName : 'CodeEditor',
getDefaultProps : function() {
return {
language : '',
value : '',
wrap : true,
onChange : ()=>{}
language : '',
value : '',
wrap : true,
onChange : ()=>{},
enableFolding : true
};
},
@@ -81,6 +83,12 @@ const CodeEditor = createClass({
} else if(this.codeMirror?.getValue() != this.props.value) { //update editor contents if brew.text is changed from outside
this.codeMirror.setValue(this.props.value);
}
if(this.props.enableFolding) {
this.codeMirror.setOption('foldOptions', this.foldOptions(this.codeMirror));
} else {
this.codeMirror.setOption('foldOptions', false);
}
},
buildEditor : function() {
@@ -139,39 +147,19 @@ const CodeEditor = createClass({
'Ctrl-]' : this.unfoldAllCode,
'Cmd-]' : this.unfoldAllCode
},
foldGutter : true,
foldOptions : {
scanUp : true,
rangeFinder : CodeMirror.fold.homebrewery,
widget : (from, to)=>{
let text = '';
let currentLine = from.line;
const maxLength = 50;
while (currentLine <= to.line && text.length <= maxLength) {
text += this.codeMirror.getLine(currentLine);
if(currentLine < to.line)
text += ' ';
currentLine += 1;
}
text = text.trim();
if(text.length > maxLength)
text = `${text.substr(0, maxLength)}...`;
return `\u21A4 ${text} \u21A6`;
}
},
gutters : ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'],
autoCloseTags : true,
styleActiveLine : true,
showTrailingSpace : true,
specialChars : / /,
specialCharPlaceholder : function(char) {
const el = document.createElement('span');
el.className = 'cm-space';
el.innerHTML = ' ';
return el;
}
foldGutter : true,
foldOptions : this.foldOptions(this.codeMirror),
gutters : ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'],
autoCloseTags : true,
styleActiveLine : true,
showTrailingSpace : false,
// specialChars : / /,
// specialCharPlaceholder : function(char) {
// const el = document.createElement('span');
// el.className = 'cm-space';
// el.innerHTML = ' ';
// return el;
// }
});
closeTag.autoCloseCurlyBraces(CodeMirror, this.codeMirror);
@@ -355,6 +343,30 @@ const CodeEditor = createClass({
historySize : function(){
return this.codeMirror.doc.historySize();
},
foldOptions : function(cm){
return {
scanUp : true,
rangeFinder : CodeMirror.fold.homebrewery,
widget : (from, to)=>{
let text = '';
let currentLine = from.line;
const maxLength = 50;
while (currentLine <= to.line && text.length <= maxLength) {
text += this.codeMirror.getLine(currentLine);
if(currentLine < to.line)
text += ' ';
currentLine += 1;
}
text = text.trim();
if(text.length > maxLength)
text = `${text.substr(0, maxLength)}...`;
return `\u21A4 ${text} \u21A6`;
}
};
},
//----------------------//
render : function(){

View File

@@ -10,13 +10,13 @@
font-weight: 600;
}
.cm-tab {
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAQAAACOs/baAAAARUlEQVR4nGJgIAG8JkXxUAcCtDWemcGR1lY4MvgzCEKY7jSBjgxBDAG09UEQzAe0AMwMHrSOAwEGRtpaMIwAAAAA//8DAG4ID9EKs6YqAAAAAElFTkSuQmCC) no-repeat right;
}
//.cm-tab {
// background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAQAAACOs/baAAAARUlEQVR4nGJgIAG8JkXxUAcCtDWemcGR1lY4MvgzCEKY7jSBjgxBDAG09UEQzAe0AMwMHrSOAwEGRtpaMIwAAAAA//8DAG4ID9EKs6YqAAAAAElFTkSuQmCC) no-repeat right;
//}
.cm-trailingspace {
.cm-space {
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAQAgMAAABW5NbuAAAACVBMVEVHcEwAAAAAAAAWawmTAAAAA3RSTlMAPBJ6PMxpAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAFUlEQVQI12NgwACcCQysASAEZGAAACMuAX06aCQUAAAAAElFTkSuQmCC) no-repeat right;
}
}
//.cm-trailingspace {
// .cm-space {
// background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAQAgMAAABW5NbuAAAACVBMVEVHcEwAAAAAAAAWawmTAAAAA3RSTlMAPBJ6PMxpAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAFUlEQVQI12NgwACcCQysASAEZGAAACMuAX06aCQUAAAAAElFTkSuQmCC) no-repeat right;
// }
//}
}

View File

@@ -8,7 +8,8 @@ const NaturalCritIcon = require('naturalcrit/svg/naturalcrit.svg.jsx');
const Nav = {
base : createClass({
render : function(){
displayName : 'Nav.base',
render : function(){
return <nav>
<div className='navContent'>
{this.props.children}
@@ -26,7 +27,8 @@ const Nav = {
},
section : createClass({
render : function(){
displayName : 'Nav.section',
render : function(){
return <div className='navSection'>
{this.props.children}
</div>;
@@ -34,6 +36,7 @@ const Nav = {
}),
item : createClass({
displayName : 'Nav.item',
getDefaultProps : function() {
return {
icon : null,
@@ -69,6 +72,7 @@ const Nav = {
}),
dropdown : createClass({
displayName : 'Nav.dropdown',
getInitialState : function() {
return {
showDropdown : false

View File

@@ -1,3 +1,4 @@
@import '../styles/colors';
@keyframes glideDropDown {
0% {transform : translate(0px, -100%);
opacity : 0;
@@ -49,6 +50,7 @@ nav{
}
}
.navItem{
#backgroundColors;
.animate(background-color);
padding : 8px 12px;
cursor : pointer;
@@ -58,30 +60,12 @@ nav{
color : white;
text-decoration : none;
text-transform : uppercase;
line-height : 13px;
i{
margin-left : 5px;
font-size : 13px;
float : right;
}
&.tealLight:hover{ background-color : @tealLight };
&.teal:hover{ background-color : @teal };
&.greenLight:hover{ background-color : @greenLight };
&.green:hover{ background-color : @green };
&.blueLight:hover{ background-color : @blueLight };
&.blue:hover{ background-color : @blue };
&.purpleLight:hover{ background-color : @purpleLight };
&.purple:hover{ background-color : @purple };
&.steelLight:hover{ background-color : @steelLight };
&.steel:hover{ background-color : @steel };
&.yellowLight:hover{ background-color : @yellowLight };
&.yellow:hover{ background-color : @yellow };
&.orangeLight:hover{ background-color : @orangeLight };
&.orange:hover{ background-color : @orange };
&.redLight:hover{ background-color : @redLight };
&.red:hover{ background-color : @red };
&.silverLight:hover{ background-color : @silverLight };
&.silver:hover{ background-color : @silver };
&.greyLight:hover{ background-color : @greyLight };
&.grey:hover{ background-color : @grey };
}
.navSection:last-child .navItem{
border-left : 1px solid #666;

View File

@@ -5,6 +5,7 @@ const _ = require('lodash');
const cx = require('classnames');
const SplitPane = createClass({
displayName : 'SplitPane',
getDefaultProps : function() {
return {
storageKey : 'naturalcrit-pane-split',
@@ -77,6 +78,7 @@ const SplitPane = createClass({
});
const Pane = createClass({
displayName : 'Pane',
getDefaultProps : function() {
return {
width : null

View File

@@ -20,4 +20,27 @@
@silverLight : #ECF0F1;
@silver : #BDC3C7;
@greyLight : #95A5A6;
@grey : #7F8C8D;
@grey : #7F8C8D;
#backgroundColors {
&.tealLight:hover{ background-color : @tealLight };
&.teal:hover{ background-color : @teal };
&.greenLight:hover{ background-color : @greenLight };
&.green:hover{ background-color : @green };
&.blueLight:hover{ background-color : @blueLight };
&.blue:hover{ background-color : @blue };
&.purpleLight:hover{ background-color : @purpleLight };
&.purple:hover{ background-color : @purple };
&.steelLight:hover{ background-color : @steelLight };
&.steel:hover{ background-color : @steel };
&.yellowLight:hover{ background-color : @yellowLight };
&.yellow:hover{ background-color : @yellow };
&.orangeLight:hover{ background-color : @orangeLight };
&.orange:hover{ background-color : @orange };
&.redLight:hover{ background-color : @redLight };
&.red:hover{ background-color : @red };
&.silverLight:hover{ background-color : @silverLight };
&.silver:hover{ background-color : @silver };
&.greyLight:hover{ background-color : @greyLight };
&.grey:hover{ background-color : @grey };
}

View File

@@ -1,7 +0,0 @@
const test = require('pico-check');
test('Just setting up a spot for future tests', (t)=>{
t.pass();
});
module.exports = test;

View File

@@ -0,0 +1,15 @@
/* eslint-disable max-lines */
const Markdown = require('naturalcrit/markdown.js');
test('Escapes <script> tag', function() {
const source = '<script></script>';
const rendered = Markdown.render(source);
expect(rendered).toMatch('&lt;script&gt;&lt;/script&gt;');
});
test('Processes the markdown within an HTML block if its just a class wrapper', function() {
const source = '<div>*Bold text*</div>';
const rendered = Markdown.render(source);
expect(rendered).toBe('<div> <p><em>Bold text</em></p>\n </div>');
});

View File

@@ -0,0 +1,128 @@
/* eslint-disable max-lines */
const Markdown = require('naturalcrit/markdown.js');
test('Renders a mustache span with text only', function() {
const source = '{{ text}}';
const rendered = Markdown.render(source);
expect(rendered).toBe('<span class="inline-block ">text</span>');
});
test('Renders a mustache span with text only, but with spaces', function() {
const source = '{{ this is a text}}';
const rendered = Markdown.render(source);
expect(rendered).toBe('<span class="inline-block ">this is a text</span>');
});
test('Renders an empty mustache span', function() {
const source = '{{}}';
const rendered = Markdown.render(source);
expect(rendered).toBe('<span class="inline-block "></span>');
});
test('Renders a mustache span with just a space', function() {
const source = '{{ }}';
const rendered = Markdown.render(source);
expect(rendered).toBe('<span class="inline-block "></span>');
});
test('Renders a mustache span with a few spaces only', function() {
const source = '{{ }}';
const rendered = Markdown.render(source);
expect(rendered).toBe('<span class="inline-block "></span>');
});
test('Renders a mustache span with text and class', function() {
const source = '{{my-class text}}';
const rendered = Markdown.render(source);
// FIXME: why do we have those two extra spaces after closing "?
expect(rendered).toBe('<span class="inline-block my-class" >text</span>');
});
test('Renders a mustache span with text and two classes', function() {
const source = '{{my-class,my-class2 text}}';
const rendered = Markdown.render(source);
// FIXME: why do we have those two extra spaces after closing "?
expect(rendered).toBe('<span class="inline-block my-class my-class2" >text</span>');
});
test('Renders a mustache span with text with spaces and class', function() {
const source = '{{my-class this is a text}}';
const rendered = Markdown.render(source);
// FIXME: why do we have those two extra spaces after closing "?
expect(rendered).toBe('<span class="inline-block my-class" >this is a text</span>');
});
test('Renders a mustache span with text and id', function() {
const source = '{{#my-span text}}';
const rendered = Markdown.render(source);
// FIXME: why do we have that one extra space after closing "?
expect(rendered).toBe('<span class="inline-block " id="my-span" >text</span>');
});
test('Renders a mustache span with text and two ids', function() {
const source = '{{#my-span,#my-favorite-span text}}';
const rendered = Markdown.render(source);
// FIXME: do we need to report an error here somehow?
expect(rendered).toBe('<span class="inline-block " id="my-span" >text</span>');
});
test('Renders a mustache span with text and css property', function() {
const source = '{{color:red text}}';
const rendered = Markdown.render(source);
expect(rendered).toBe('<span class="inline-block " style="color:red;">text</span>');
});
test('Renders a mustache span with text and two css properties', function() {
const source = '{{color:red,padding:5px text}}';
const rendered = Markdown.render(source);
expect(rendered).toBe('<span class="inline-block " style="color:red; padding:5px;">text</span>');
});
test('Renders a mustache span with text and css property which contains quotes', function() {
const source = '{{font:"trebuchet ms" text}}';
const rendered = Markdown.render(source);
// FIXME: is it correct to remove quotes surrounding css property value?
expect(rendered).toBe('<span class="inline-block " style="font:trebuchet ms;">text</span>');
});
test('Renders a mustache span with text and two css properties which contains quotes', function() {
const source = '{{font:"trebuchet ms",padding:"5px 10px" text}}';
const rendered = Markdown.render(source);
expect(rendered).toBe('<span class="inline-block " style="font:trebuchet ms; padding:5px 10px;">text</span>');
});
test('Renders a mustache span with text with quotes and css property which contains quotes', function() {
const source = '{{font:"trebuchet ms" text "with quotes"}}';
const rendered = Markdown.render(source);
expect(rendered).toBe('<span class="inline-block " style="font:trebuchet ms;">text “with quotes”</span>');
});
test('Renders a mustache span with text, id, class and a couple of css properties', function() {
const source = '{{pen,#author,color:orange,font-family:"trebuchet ms" text}}';
const rendered = Markdown.render(source);
expect(rendered).toBe('<span class="inline-block pen" id="author" style="color:orange; font-family:trebuchet ms;">text</span>');
});
// TODO: add tests for ID with accordance to CSS spec:
//
// From https://drafts.csswg.org/selectors/#id-selectors:
//
// > An ID selector consists of a “number sign” (U+0023, #) immediately followed by the ID value, which must be a CSS identifier.
//
// From: https://www.w3.org/TR/CSS21/syndata.html#value-def-identifier:
//
// > In CSS, identifiers (including element names, classes, and IDs in selectors) can contain only the characters [a-zA-Z0-9]
// > and ISO 10646 characters U+00A0 and higher, plus the hyphen (-) and the underscore (_);
// > they cannot start with a digit, two hyphens, or a hyphen followed by a digit.
// > Identifiers can also contain escaped characters and any ISO 10646 character as a numeric code (see next item).
// > For instance, the identifier "B&W?" may be written as "B\&W\?" or "B\26 W\3F".
// > Note that Unicode is code-by-code equivalent to ISO 10646 (see [UNICODE] and [ISO10646]).
// TODO: add tests for class with accordance to CSS spec:
//
// From: https://drafts.csswg.org/selectors/#class-html:
//
// > The class selector is given as a full stop (. U+002E) immediately followed by an identifier.

View File

@@ -0,0 +1,27 @@
const supertest = require('supertest');
// Mimic https responses to avoid being redirected all the time
const app = supertest.agent(require('app.js').app)
.set('X-Forwarded-Proto', 'https');
describe('Tests for static pages', ()=>{
it('Home page works', ()=>{
return app.get('/').expect(200);
});
it('Home page v3 works', ()=>{
return app.get('/v3_preview').expect(200);
});
it('Changelog page works', ()=>{
return app.get('/changelog').expect(200);
});
it('FAQ page works', ()=>{
return app.get('/faq').expect(200);
});
it('robots.txt works', ()=>{
return app.get('/robots.txt').expect(200);
});
});

View File

@@ -1 +0,0 @@
//Set up configs and DB connectiosna nd what not in here

BIN
themes/assets/discord.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -0,0 +1 @@
<svg id="Layer_3" data-name="Layer 3" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 350.028 390.552"><defs><style>.cls-1{opacity:0.9;}.cls-2{fill:#001013;}.cls-3{fill:#fff;}.cls-4{fill:#aa2a29;}</style></defs><title>Discord of Many Things blank</title><g class="cls-1"><path d="M100.991,82.743c-1.649,3.324-3.395,5.768-4.1,8.482-1.49,5.753-3.44,11.644-3.455,17.482q-.332,125.259-.141,250.519c.007,20.122,12.708,36.368,31.407,40.239a38.328,38.328,0,0,0,7.722.761q103.611,0,207.222-.088h6.314c-3.256-11.462-9.664-34.015-9.664-34.015l2.431,2.023s41.561,37.755,62.33,56.6c2.489,2.26,3.694,4.462,3.593,7.885-.241,8.186-.078,16.383-.078,25.492-6.333-5.527-11.928-10.35-17.457-15.247-9.586-8.493-19.2-16.957-28.644-25.6a10.032,10.032,0,0,0-7.39-2.774q-117.228-.1-234.457-.334c-20.632-.031-33.959-9.189-41.021-28.578-.852-2.339-.783-5.091-.784-7.653q-.057-116.5-.031-233.007V119.145C74.791,102.517,84.2,89.068,100.991,82.743Z" transform="translate(-74.79 -67.573)"/></g><path class="cls-2" d="M338.234,371.589s5.556,19.924,8.513,30.53h-5.075c-69.335,0-138.67-.1-208,.074-16.925.043-35.116-9.515-40.505-33.247a26.538,26.538,0,0,1-.379-5.827q-.027-128.172.025-256.344c.021-19.276,15.226-36.749,34.427-38.688a82.669,82.669,0,0,1,8.279-.447q123.288-.034,246.578-.067c13.265-.016,24.7,3.79,33.278,14.235a39.273,39.273,0,0,1,9.447,25.5q-.015,167.477-.012,334.955c0,1.245-.1,2.49-.2,4.645-4.075-3.565-7.6-6.552-11.018-9.655q-35.236-31.992-70.44-64.017c-1.2-1.091-3.713-3.147-3.713-3.147l-2-1.775Z" transform="translate(-74.79 -67.573)"/><path class="cls-3" d="M419.838,435.934c-7.848-6.892-15.026-12.977-21.961-19.329q-28.235-25.86-56.253-51.954c-2.314-2.157-4.59-3.247-7.356-1.784-3.036,1.607-2.77,4.676-2.022,7.359,2.286,8.2,4.817,16.338,7.24,24.5a17.108,17.108,0,0,1,.294,1.851c-1.486.084-2.872.233-4.258.233-67.363.012-134.726-.155-202.088.123-18.267.075-32.955-13.095-34.769-29.353a92.257,92.257,0,0,1-.886-10.108Q97.7,233.488,97.793,109.5c.013-10.518,3.19-20.063,11.156-27.471a31.92,31.92,0,0,1,20.439-8.917c1.948-.109,3.9-.181,5.852-.181q123.5-.014,247-.063c9.957-.012,18.894,2.145,26.329,9.1,7.956,7.441,11.177,16.934,11.214,27.457.142,40.84.057,81.681.057,122.522V435.934Z" transform="translate(-74.79 -67.573)"/><path class="cls-4" d="M311.029,170.975c-11.8,45.005-23.315,88.959-35.123,134.016l-97.168-98.883Z" transform="translate(-74.79 -67.573)"/><path class="cls-4" d="M380.8,265.712l-95.97,40.316c11.438-43.808,22.639-86.709,33.839-129.609l1.08-.272Z" transform="translate(-74.79 -67.573)"/><path class="cls-4" d="M165.3,322.955c2.91-36.463,5.761-72.179,8.709-109.116l94.711,96.472Z" transform="translate(-74.79 -67.573)"/><path class="cls-4" d="M223.458,107.926l83.127,55.063L178.71,196.919Z" transform="translate(-74.79 -67.573)"/><path class="cls-4" d="M366.285,281.366l-72.5,73.414c-3.524-13.182-6.849-25.617-10.306-38.549Z" transform="translate(-74.79 -67.573)"/><path class="cls-4" d="M274.874,318.478c3.445,12.8,6.765,25.143,10.376,38.559l-98.635-26.556.032-1.153Z" transform="translate(-74.79 -67.573)"/><path class="cls-4" d="M374.888,241.261l-51.71-75.57,26.8-21.529,25.831,96.619Z" transform="translate(-74.79 -67.573)"/><path class="cls-4" d="M165.492,207.523c-2.39,30.748-4.736,60.942-7.083,91.135l-1.063.159c-8.5-31.936-17-63.872-25.705-96.581Z" transform="translate(-74.79 -67.573)"/><path class="cls-4" d="M317.039,159.316l-68.251-45.24.307-.794,93.794,25.212Z" transform="translate(-74.79 -67.573)"/><path class="cls-4" d="M136.517,193.952,203.5,125.03l1.086.832L167.794,198.9Z" transform="translate(-74.79 -67.573)"/></svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

BIN
themes/assets/github.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

BIN
themes/assets/patreon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
themes/assets/reddit.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB