querysub 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.dependency-cruiser.js +304 -0
- package/.eslintrc.js +51 -0
- package/.github/copilot-instructions.md +1 -0
- package/.vscode/settings.json +25 -0
- package/bin/deploy.js +4 -0
- package/bin/function.js +4 -0
- package/bin/server.js +4 -0
- package/costsBenefits.txt +112 -0
- package/deploy.ts +3 -0
- package/inject.ts +1 -0
- package/package.json +60 -0
- package/prompts.txt +54 -0
- package/spec.txt +820 -0
- package/src/-a-archives/archiveCache.ts +913 -0
- package/src/-a-archives/archives.ts +148 -0
- package/src/-a-archives/archivesBackBlaze.ts +792 -0
- package/src/-a-archives/archivesDisk.ts +418 -0
- package/src/-a-archives/copyLocalToBackblaze.ts +24 -0
- package/src/-a-auth/certs.ts +517 -0
- package/src/-a-auth/der.ts +122 -0
- package/src/-a-auth/ed25519.ts +1015 -0
- package/src/-a-auth/node-forge-ed25519.d.ts +17 -0
- package/src/-b-authorities/dnsAuthority.ts +203 -0
- package/src/-b-authorities/emailAuthority.ts +57 -0
- package/src/-c-identity/IdentityController.ts +200 -0
- package/src/-d-trust/NetworkTrust2.ts +150 -0
- package/src/-e-certs/EdgeCertController.ts +288 -0
- package/src/-e-certs/certAuthority.ts +192 -0
- package/src/-f-node-discovery/NodeDiscovery.ts +543 -0
- package/src/-g-core-values/NodeCapabilities.ts +134 -0
- package/src/-g-core-values/oneTimeForward.ts +91 -0
- package/src/-h-path-value-serialize/PathValueSerializer.ts +769 -0
- package/src/-h-path-value-serialize/stringSerializer.ts +176 -0
- package/src/0-path-value-core/LoggingClient.tsx +24 -0
- package/src/0-path-value-core/NodePathAuthorities.ts +978 -0
- package/src/0-path-value-core/PathController.ts +1 -0
- package/src/0-path-value-core/PathValueCommitter.ts +565 -0
- package/src/0-path-value-core/PathValueController.ts +231 -0
- package/src/0-path-value-core/archiveLocks/ArchiveLocks.ts +154 -0
- package/src/0-path-value-core/archiveLocks/ArchiveLocks2.ts +820 -0
- package/src/0-path-value-core/archiveLocks/archiveSnapshots.ts +180 -0
- package/src/0-path-value-core/debugLogs.ts +90 -0
- package/src/0-path-value-core/pathValueArchives.ts +483 -0
- package/src/0-path-value-core/pathValueCore.ts +2217 -0
- package/src/1-path-client/RemoteWatcher.ts +558 -0
- package/src/1-path-client/pathValueClientWatcher.ts +702 -0
- package/src/2-proxy/PathValueProxyWatcher.ts +1857 -0
- package/src/2-proxy/archiveMoveHarness.ts +376 -0
- package/src/2-proxy/garbageCollection.ts +753 -0
- package/src/2-proxy/pathDatabaseProxyBase.ts +37 -0
- package/src/2-proxy/pathValueProxy.ts +139 -0
- package/src/2-proxy/schema2.ts +518 -0
- package/src/3-path-functions/PathFunctionHelpers.ts +129 -0
- package/src/3-path-functions/PathFunctionRunner.ts +619 -0
- package/src/3-path-functions/PathFunctionRunnerMain.ts +67 -0
- package/src/3-path-functions/deployBlock.ts +10 -0
- package/src/3-path-functions/deployCheck.ts +7 -0
- package/src/3-path-functions/deployMain.ts +160 -0
- package/src/3-path-functions/pathFunctionLoader.ts +282 -0
- package/src/3-path-functions/syncSchema.ts +475 -0
- package/src/3-path-functions/tests/functionsTest.ts +135 -0
- package/src/3-path-functions/tests/rejectTest.ts +77 -0
- package/src/4-dom/css.tsx +29 -0
- package/src/4-dom/cssTypes.d.ts +212 -0
- package/src/4-dom/qreact.tsx +2322 -0
- package/src/4-dom/qreactTest.tsx +417 -0
- package/src/4-querysub/Querysub.ts +877 -0
- package/src/4-querysub/QuerysubController.ts +620 -0
- package/src/4-querysub/copyEvent.ts +0 -0
- package/src/4-querysub/permissions.ts +289 -0
- package/src/4-querysub/permissionsShared.ts +1 -0
- package/src/4-querysub/querysubPrediction.ts +525 -0
- package/src/5-diagnostics/FullscreenModal.tsx +67 -0
- package/src/5-diagnostics/GenericFormat.tsx +165 -0
- package/src/5-diagnostics/Modal.tsx +79 -0
- package/src/5-diagnostics/Table.tsx +183 -0
- package/src/5-diagnostics/TimeGrouper.tsx +114 -0
- package/src/5-diagnostics/diskValueAudit.ts +216 -0
- package/src/5-diagnostics/memoryValueAudit.ts +442 -0
- package/src/5-diagnostics/nodeMetadata.ts +135 -0
- package/src/5-diagnostics/qreactDebug.tsx +309 -0
- package/src/5-diagnostics/shared.ts +26 -0
- package/src/5-diagnostics/synchronousLagTracking.ts +47 -0
- package/src/TestController.ts +35 -0
- package/src/allowclient.flag +0 -0
- package/src/bits.ts +86 -0
- package/src/buffers.ts +69 -0
- package/src/config.ts +53 -0
- package/src/config2.ts +48 -0
- package/src/diagnostics/ActionsHistory.ts +56 -0
- package/src/diagnostics/NodeViewer.tsx +503 -0
- package/src/diagnostics/SizeLimiter.ts +62 -0
- package/src/diagnostics/TimeDebug.tsx +18 -0
- package/src/diagnostics/benchmark.ts +139 -0
- package/src/diagnostics/errorLogs/ErrorLogController.ts +515 -0
- package/src/diagnostics/errorLogs/ErrorLogCore.ts +274 -0
- package/src/diagnostics/errorLogs/LogClassifiers.tsx +302 -0
- package/src/diagnostics/errorLogs/LogFilterUI.tsx +84 -0
- package/src/diagnostics/errorLogs/LogNotify.tsx +101 -0
- package/src/diagnostics/errorLogs/LogTimeSelector.tsx +724 -0
- package/src/diagnostics/errorLogs/LogViewer.tsx +757 -0
- package/src/diagnostics/errorLogs/hookErrors.ts +60 -0
- package/src/diagnostics/errorLogs/logFiltering.tsx +149 -0
- package/src/diagnostics/heapTag.ts +13 -0
- package/src/diagnostics/listenOnDebugger.ts +77 -0
- package/src/diagnostics/logs/DiskLoggerPage.tsx +572 -0
- package/src/diagnostics/logs/ObjectDisplay.tsx +165 -0
- package/src/diagnostics/logs/ansiFormat.ts +108 -0
- package/src/diagnostics/logs/diskLogGlobalContext.ts +38 -0
- package/src/diagnostics/logs/diskLogger.ts +305 -0
- package/src/diagnostics/logs/diskShimConsoleLogs.ts +32 -0
- package/src/diagnostics/logs/injectFileLocationToConsole.ts +50 -0
- package/src/diagnostics/logs/logGitHashes.ts +30 -0
- package/src/diagnostics/managementPages.tsx +289 -0
- package/src/diagnostics/periodic.ts +89 -0
- package/src/diagnostics/runSaturationTest.ts +416 -0
- package/src/diagnostics/satSchema.ts +64 -0
- package/src/diagnostics/trackResources.ts +82 -0
- package/src/diagnostics/watchdog.ts +55 -0
- package/src/errors.ts +132 -0
- package/src/forceProduction.ts +3 -0
- package/src/fs.ts +72 -0
- package/src/heapDumps.ts +666 -0
- package/src/https.ts +2 -0
- package/src/inject.ts +1 -0
- package/src/library-components/ATag.tsx +84 -0
- package/src/library-components/Button.tsx +344 -0
- package/src/library-components/ButtonSelector.tsx +64 -0
- package/src/library-components/DropdownCustom.tsx +151 -0
- package/src/library-components/DropdownSelector.tsx +32 -0
- package/src/library-components/Input.tsx +334 -0
- package/src/library-components/InputLabel.tsx +198 -0
- package/src/library-components/InputPicker.tsx +125 -0
- package/src/library-components/LazyComponent.tsx +62 -0
- package/src/library-components/MeasureHeightCSS.tsx +48 -0
- package/src/library-components/MeasuredDiv.tsx +47 -0
- package/src/library-components/ShowMore.tsx +51 -0
- package/src/library-components/SyncedController.ts +171 -0
- package/src/library-components/TimeRangeSelector.tsx +407 -0
- package/src/library-components/URLParam.ts +263 -0
- package/src/library-components/colors.tsx +14 -0
- package/src/library-components/drag.ts +114 -0
- package/src/library-components/icons.tsx +692 -0
- package/src/library-components/niceStringify.ts +50 -0
- package/src/library-components/renderToString.ts +52 -0
- package/src/misc/PromiseRace.ts +101 -0
- package/src/misc/color.ts +30 -0
- package/src/misc/getParentProcessId.cs +53 -0
- package/src/misc/getParentProcessId.ts +53 -0
- package/src/misc/hash.ts +83 -0
- package/src/misc/ipPong.js +13 -0
- package/src/misc/networking.ts +2 -0
- package/src/misc/random.ts +45 -0
- package/src/misc.ts +19 -0
- package/src/noserverhotreload.flag +0 -0
- package/src/path.ts +226 -0
- package/src/persistentLocalStore.ts +37 -0
- package/src/promise.ts +15 -0
- package/src/server.ts +73 -0
- package/src/src.d.ts +1 -0
- package/src/test/heapProcess.ts +36 -0
- package/src/test/mongoSatTest.tsx +55 -0
- package/src/test/satTest.ts +193 -0
- package/src/test/test.tsx +552 -0
- package/src/zip.ts +92 -0
- package/src/zipThreaded.ts +106 -0
- package/src/zipThreadedWorker.js +19 -0
- package/tsconfig.json +27 -0
- package/yarnSpec.txt +56 -0
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
/** @type {import('dependency-cruiser').IConfiguration} */
|
|
2
|
+
module.exports = {
|
|
3
|
+
forbidden: [
|
|
4
|
+
/* rules from the 'recommended' preset: */
|
|
5
|
+
// {
|
|
6
|
+
// name: 'circular',
|
|
7
|
+
// severity: 'warn',
|
|
8
|
+
// comment:
|
|
9
|
+
// 'This dependency is part of a circular relationship. You might want to revise ' +
|
|
10
|
+
// 'your solution (i.e. use dependency inversion, make sure the modules have a single responsibility) ',
|
|
11
|
+
// from: {},
|
|
12
|
+
// to: {
|
|
13
|
+
// circular: true
|
|
14
|
+
// }
|
|
15
|
+
// },
|
|
16
|
+
{
|
|
17
|
+
name: 'no-orphans',
|
|
18
|
+
comment:
|
|
19
|
+
"This is an orphan module - it's likely not used (anymore?). Either use it or " +
|
|
20
|
+
"remove it. If it's logical this module is an orphan (i.e. it's a config file), " +
|
|
21
|
+
"add an exception for it in your dependency-cruiser configuration. By default " +
|
|
22
|
+
"this rule does not scrutinize dot-files (e.g. .eslintrc.js), TypeScript declaration " +
|
|
23
|
+
"files (.d.ts), tsconfig.json and some of the babel and webpack configs.",
|
|
24
|
+
severity: 'warn',
|
|
25
|
+
from: {
|
|
26
|
+
orphan: true,
|
|
27
|
+
pathNot: [
|
|
28
|
+
'(^|/)\\.[^/]+\\.(js|cjs|mjs|ts|json)$', // dot files
|
|
29
|
+
'\\.d\\.ts$', // TypeScript declaration files
|
|
30
|
+
'(^|/)tsconfig\\.json$', // TypeScript config
|
|
31
|
+
'(^|/)(babel|webpack)\\.config\\.(js|cjs|mjs|ts|json)$' // other configs
|
|
32
|
+
]
|
|
33
|
+
},
|
|
34
|
+
to: {},
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
options: {
|
|
38
|
+
|
|
39
|
+
/* conditions specifying which files not to follow further when encountered:
|
|
40
|
+
- path: a regular expression to match
|
|
41
|
+
- dependencyTypes: see https://github.com/sverweij/dependency-cruiser/blob/master/doc/rules-reference.md#dependencytypes-and-dependencytypesnot
|
|
42
|
+
for a complete list
|
|
43
|
+
*/
|
|
44
|
+
doNotFollow: {
|
|
45
|
+
path: 'node_modules'
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
/* conditions specifying which dependencies to exclude
|
|
49
|
+
- path: a regular expression to match
|
|
50
|
+
- dynamic: a boolean indicating whether to ignore dynamic (true) or static (false) dependencies.
|
|
51
|
+
leave out if you want to exclude neither (recommended!)
|
|
52
|
+
*/
|
|
53
|
+
exclude: {
|
|
54
|
+
path: ["src/[^/]+.ts", "benchmarkTests", "tests", "benchmarks", "diagnostics", "Main"],
|
|
55
|
+
dynamic: true
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
/* pattern specifying which files to include (regular expression)
|
|
59
|
+
dependency-cruiser will skip everything not matching this pattern
|
|
60
|
+
*/
|
|
61
|
+
// includeOnly : '',
|
|
62
|
+
|
|
63
|
+
/* dependency-cruiser will include modules matching against the focus
|
|
64
|
+
regular expression in its output, as well as their neighbours (direct
|
|
65
|
+
dependencies and dependents)
|
|
66
|
+
*/
|
|
67
|
+
// focus : '',
|
|
68
|
+
|
|
69
|
+
/* list of module systems to cruise */
|
|
70
|
+
// moduleSystems: ['amd', 'cjs', 'es6', 'tsd'],
|
|
71
|
+
|
|
72
|
+
/* prefix for links in html and svg output (e.g. 'https://github.com/you/yourrepo/blob/develop/'
|
|
73
|
+
to open it on your online repo or `vscode://file/${process.cwd()}/` to
|
|
74
|
+
open it in visual studio code),
|
|
75
|
+
*/
|
|
76
|
+
// prefix: '',
|
|
77
|
+
|
|
78
|
+
/* false (the default): ignore dependencies that only exist before typescript-to-javascript compilation
|
|
79
|
+
true: also detect dependencies that only exist before typescript-to-javascript compilation
|
|
80
|
+
"specify": for each dependency identify whether it only exists before compilation or also after
|
|
81
|
+
*/
|
|
82
|
+
tsPreCompilationDeps: true,
|
|
83
|
+
|
|
84
|
+
/*
|
|
85
|
+
list of extensions to scan that aren't javascript or compile-to-javascript.
|
|
86
|
+
Empty by default. Only put extensions in here that you want to take into
|
|
87
|
+
account that are _not_ parsable.
|
|
88
|
+
*/
|
|
89
|
+
// extraExtensionsToScan: [".json", ".jpg", ".png", ".svg", ".webp"],
|
|
90
|
+
|
|
91
|
+
/* if true combines the package.jsons found from the module up to the base
|
|
92
|
+
folder the cruise is initiated from. Useful for how (some) mono-repos
|
|
93
|
+
manage dependencies & dependency definitions.
|
|
94
|
+
*/
|
|
95
|
+
// combinedDependencies: false,
|
|
96
|
+
|
|
97
|
+
/* if true leave symlinks untouched, otherwise use the realpath */
|
|
98
|
+
// preserveSymlinks: false,
|
|
99
|
+
|
|
100
|
+
/* TypeScript project file ('tsconfig.json') to use for
|
|
101
|
+
(1) compilation and
|
|
102
|
+
(2) resolution (e.g. with the paths property)
|
|
103
|
+
|
|
104
|
+
The (optional) fileName attribute specifies which file to take (relative to
|
|
105
|
+
dependency-cruiser's current working directory). When not provided
|
|
106
|
+
defaults to './tsconfig.json'.
|
|
107
|
+
*/
|
|
108
|
+
tsConfig: {
|
|
109
|
+
fileName: 'tsconfig.json'
|
|
110
|
+
},
|
|
111
|
+
|
|
112
|
+
/* Webpack configuration to use to get resolve options from.
|
|
113
|
+
|
|
114
|
+
The (optional) fileName attribute specifies which file to take (relative
|
|
115
|
+
to dependency-cruiser's current working directory. When not provided defaults
|
|
116
|
+
to './webpack.conf.js'.
|
|
117
|
+
|
|
118
|
+
The (optional) `env` and `args` attributes contain the parameters to be passed if
|
|
119
|
+
your webpack config is a function and takes them (see webpack documentation
|
|
120
|
+
for details)
|
|
121
|
+
*/
|
|
122
|
+
// webpackConfig: {
|
|
123
|
+
// fileName: './webpack.config.js',
|
|
124
|
+
// env: {},
|
|
125
|
+
// args: {},
|
|
126
|
+
// },
|
|
127
|
+
|
|
128
|
+
/* Babel config ('.babelrc', '.babelrc.json', '.babelrc.json5', ...) to use
|
|
129
|
+
for compilation (and whatever other naughty things babel plugins do to
|
|
130
|
+
source code). This feature is well tested and usable, but might change
|
|
131
|
+
behavior a bit over time (e.g. more precise results for used module
|
|
132
|
+
systems) without dependency-cruiser getting a major version bump.
|
|
133
|
+
*/
|
|
134
|
+
// babelConfig: {
|
|
135
|
+
// fileName: './.babelrc'
|
|
136
|
+
// },
|
|
137
|
+
|
|
138
|
+
/* List of strings you have in use in addition to cjs/ es6 requires
|
|
139
|
+
& imports to declare module dependencies. Use this e.g. if you've
|
|
140
|
+
re-declared require, use a require-wrapper or use window.require as
|
|
141
|
+
a hack.
|
|
142
|
+
*/
|
|
143
|
+
// exoticRequireStrings: [],
|
|
144
|
+
/* options to pass on to enhanced-resolve, the package dependency-cruiser
|
|
145
|
+
uses to resolve module references to disk. You can set most of these
|
|
146
|
+
options in a webpack.conf.js - this section is here for those
|
|
147
|
+
projects that don't have a separate webpack config file.
|
|
148
|
+
|
|
149
|
+
Note: settings in webpack.conf.js override the ones specified here.
|
|
150
|
+
*/
|
|
151
|
+
enhancedResolveOptions: {
|
|
152
|
+
/* List of strings to consider as 'exports' fields in package.json. Use
|
|
153
|
+
['exports'] when you use packages that use such a field and your environment
|
|
154
|
+
supports it (e.g. node ^12.19 || >=14.7 or recent versions of webpack).
|
|
155
|
+
|
|
156
|
+
If you have an `exportsFields` attribute in your webpack config, that one
|
|
157
|
+
will have precedence over the one specified here.
|
|
158
|
+
*/
|
|
159
|
+
exportsFields: ["exports"],
|
|
160
|
+
/* List of conditions to check for in the exports field. e.g. use ['imports']
|
|
161
|
+
if you're only interested in exposed es6 modules, ['require'] for commonjs,
|
|
162
|
+
or all conditions at once `(['import', 'require', 'node', 'default']`)
|
|
163
|
+
if anything goes for you. Only works when the 'exportsFields' array is
|
|
164
|
+
non-empty.
|
|
165
|
+
|
|
166
|
+
If you have a 'conditionNames' attribute in your webpack config, that one will
|
|
167
|
+
have precedence over the one specified here.
|
|
168
|
+
*/
|
|
169
|
+
conditionNames: ["import", "require", "node", "default"],
|
|
170
|
+
/*
|
|
171
|
+
The extensions, by default are the same as the ones dependency-cruiser
|
|
172
|
+
can access (run `npx depcruise --info` to see which ones that are in
|
|
173
|
+
_your_ environment. If that list is larger than what you need (e.g.
|
|
174
|
+
it contains .js, .jsx, .ts, .tsx, .cts, .mts - but you don't use
|
|
175
|
+
TypeScript you can pass just the extensions you actually use (e.g.
|
|
176
|
+
[".js", ".jsx"]). This can speed up the most expensive step in
|
|
177
|
+
dependency cruising (module resolution) quite a bit.
|
|
178
|
+
*/
|
|
179
|
+
// extensions: [".js", ".jsx", ".ts", ".tsx", ".d.ts"],
|
|
180
|
+
/*
|
|
181
|
+
If your TypeScript project makes use of types specified in 'types'
|
|
182
|
+
fields in package.jsons of external dependencies, specify "types"
|
|
183
|
+
in addition to "main" in here, so enhanced-resolve (the resolver
|
|
184
|
+
dependency-cruiser uses) knows to also look there. You can also do
|
|
185
|
+
this if you're not sure, but still use TypeScript. In a future version
|
|
186
|
+
of dependency-cruiser this will likely become the default.
|
|
187
|
+
*/
|
|
188
|
+
mainFields: ["main", "types"],
|
|
189
|
+
},
|
|
190
|
+
reporterOptions: {
|
|
191
|
+
dot: {
|
|
192
|
+
/* pattern of modules that can be consolidated in the detailed
|
|
193
|
+
graphical dependency graph. The default pattern in this configuration
|
|
194
|
+
collapses everything in node_modules to one folder deep so you see
|
|
195
|
+
the external modules, but not the innards your app depends upon.
|
|
196
|
+
*/
|
|
197
|
+
collapsePattern: 'node_modules/(@[^/]+/[^/]+|[^/]+)',
|
|
198
|
+
|
|
199
|
+
/* Options to tweak the appearance of your graph.See
|
|
200
|
+
https://github.com/sverweij/dependency-cruiser/blob/master/doc/options-reference.md#reporteroptions
|
|
201
|
+
for details and some examples. If you don't specify a theme
|
|
202
|
+
don't worry - dependency-cruiser will fall back to the default one.
|
|
203
|
+
*/
|
|
204
|
+
theme: {
|
|
205
|
+
graph: {
|
|
206
|
+
/* use splines: "ortho" for straight lines. Be aware though
|
|
207
|
+
graphviz might take a long time calculating ortho(gonal)
|
|
208
|
+
routings.
|
|
209
|
+
*/
|
|
210
|
+
splines: "splines"
|
|
211
|
+
//splines: "ortho"
|
|
212
|
+
},
|
|
213
|
+
modules: [
|
|
214
|
+
{
|
|
215
|
+
criteria: { matchesFocus: true },
|
|
216
|
+
attributes: {
|
|
217
|
+
fillcolor: "lime",
|
|
218
|
+
penwidth: 2,
|
|
219
|
+
},
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
criteria: { matchesFocus: false },
|
|
223
|
+
attributes: {
|
|
224
|
+
fillcolor: "lightgrey",
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
criteria: { matchesReaches: true },
|
|
229
|
+
attributes: {
|
|
230
|
+
fillcolor: "lime",
|
|
231
|
+
penwidth: 2,
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
criteria: { matchesReaches: false },
|
|
236
|
+
attributes: {
|
|
237
|
+
fillcolor: "lightgrey",
|
|
238
|
+
},
|
|
239
|
+
},
|
|
240
|
+
],
|
|
241
|
+
dependencies: [
|
|
242
|
+
{
|
|
243
|
+
criteria: { "rules[0].severity": "error" },
|
|
244
|
+
attributes: { fontcolor: "red", color: "red" }
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
criteria: { "rules[0].severity": "warn" },
|
|
248
|
+
attributes: { fontcolor: "orange", color: "orange" }
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
criteria: { "rules[0].severity": "info" },
|
|
252
|
+
attributes: { fontcolor: "blue", color: "blue" }
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
criteria: { resolved: "4-querysub" },
|
|
256
|
+
attributes: { color: "#0000ff77" }
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
criteria: { resolved: "3-path-functions" },
|
|
260
|
+
attributes: { color: "#00770077" }
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
criteria: { resolved: "2-proxy" },
|
|
264
|
+
attributes: { color: "#77007777" }
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
criteria: { resolved: "1-path-client" },
|
|
268
|
+
attributes: { color: "#77000077" }
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
criteria: { resolved: "a-auth" },
|
|
272
|
+
attributes: { color: "#77770077" }
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
criteria: { resolved: "b-tree-core" },
|
|
276
|
+
attributes: { color: "#00777777" }
|
|
277
|
+
},
|
|
278
|
+
]
|
|
279
|
+
}
|
|
280
|
+
},
|
|
281
|
+
archi: {
|
|
282
|
+
/* pattern of modules that can be consolidated in the high level
|
|
283
|
+
graphical dependency graph. If you use the high level graphical
|
|
284
|
+
dependency graph reporter (`archi`) you probably want to tweak
|
|
285
|
+
this collapsePattern to your situation.
|
|
286
|
+
*/
|
|
287
|
+
collapsePattern: '^(packages|src|lib|app|bin|test(s?)|spec(s?))/[^/]+|node_modules/(@[^/]+/[^/]+|[^/]+)',
|
|
288
|
+
|
|
289
|
+
/* Options to tweak the appearance of your graph.See
|
|
290
|
+
https://github.com/sverweij/dependency-cruiser/blob/master/doc/options-reference.md#reporteroptions
|
|
291
|
+
for details and some examples. If you don't specify a theme
|
|
292
|
+
for 'archi' dependency-cruiser will use the one specified in the
|
|
293
|
+
dot section (see above), if any, and otherwise use the default one.
|
|
294
|
+
*/
|
|
295
|
+
// theme: {
|
|
296
|
+
// },
|
|
297
|
+
},
|
|
298
|
+
"text": {
|
|
299
|
+
"highlightFocused": true
|
|
300
|
+
},
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
// generated: dependency-cruiser@12.11.0 on 2023-03-20T01:54:07.550Z
|
package/.eslintrc.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
"root": true,
|
|
3
|
+
"env": {
|
|
4
|
+
"browser": true,
|
|
5
|
+
"es6": true,
|
|
6
|
+
"node": true
|
|
7
|
+
},
|
|
8
|
+
"extends": [],
|
|
9
|
+
"globals": {
|
|
10
|
+
"Atomics": "readonly",
|
|
11
|
+
"SharedArrayBuffer": "readonly"
|
|
12
|
+
},
|
|
13
|
+
"overrides": [
|
|
14
|
+
{
|
|
15
|
+
"files": [
|
|
16
|
+
"**/*.ts",
|
|
17
|
+
"**/*.tsx"
|
|
18
|
+
]
|
|
19
|
+
}
|
|
20
|
+
],
|
|
21
|
+
"parser": "@typescript-eslint/parser",
|
|
22
|
+
"parserOptions": {
|
|
23
|
+
"ecmaVersion": 2018,
|
|
24
|
+
"sourceType": "module",
|
|
25
|
+
"project": "./tsconfig.json",
|
|
26
|
+
"tsconfigRootDir": __dirname,
|
|
27
|
+
},
|
|
28
|
+
"plugins": [
|
|
29
|
+
"@typescript-eslint"
|
|
30
|
+
],
|
|
31
|
+
"rules": {
|
|
32
|
+
"@typescript-eslint/unbound-method": [
|
|
33
|
+
"error",
|
|
34
|
+
{
|
|
35
|
+
"ignoreStatic": true
|
|
36
|
+
}
|
|
37
|
+
],
|
|
38
|
+
"@typescript-eslint/no-floating-promises": [
|
|
39
|
+
"error"
|
|
40
|
+
],
|
|
41
|
+
"quotes": [
|
|
42
|
+
"error",
|
|
43
|
+
"double",
|
|
44
|
+
{
|
|
45
|
+
"allowTemplateLiterals": true
|
|
46
|
+
}
|
|
47
|
+
],
|
|
48
|
+
"eqeqeq": "error",
|
|
49
|
+
"semi": "error"
|
|
50
|
+
}
|
|
51
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
For error messages, always use templates strings and include variables which explain specifically what the error is.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
// "debug.node.autoAttach": "on",
|
|
3
|
+
"files.watcherExclude": {
|
|
4
|
+
"**/.git/objects/**": true,
|
|
5
|
+
"**/.git/subtree-cache/**": true,
|
|
6
|
+
"**/node_modules/*/**": true,
|
|
7
|
+
"**/.hg/store/**": true
|
|
8
|
+
},
|
|
9
|
+
"[typescript]": {
|
|
10
|
+
"editor.formatOnSave": true,
|
|
11
|
+
},
|
|
12
|
+
"[typescriptreact]": {
|
|
13
|
+
"editor.formatOnSave": true,
|
|
14
|
+
},
|
|
15
|
+
"[javascript]": {
|
|
16
|
+
"editor.formatOnSave": true,
|
|
17
|
+
},
|
|
18
|
+
"typescript.tsdk": "node_modules/typescript/lib",
|
|
19
|
+
"search.exclude": {
|
|
20
|
+
"**/node_modules": true,
|
|
21
|
+
"**/bower_components": true,
|
|
22
|
+
"**/*.code-search": true,
|
|
23
|
+
"**.cache": true
|
|
24
|
+
}
|
|
25
|
+
}
|
package/bin/deploy.js
ADDED
package/bin/function.js
ADDED
package/bin/server.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
Concepts
|
|
2
|
+
Naming
|
|
3
|
+
PathValue is the database
|
|
4
|
+
FunctionRunner is a tool which makes remote function calling easy
|
|
5
|
+
Querysub is the interface which untrusted parts of apps use to sync data and commit calls
|
|
6
|
+
- Quadratic sieve: `The quadratic sieve algorithm (QS) is an integer factorization algorithm and, in practice, the second fastest method known (after the general number field sieve). It is still the fastest for integers under 100 decimal digits or so, and is considerably simpler than the number field sieve`
|
|
7
|
+
- Quorum sensing: `In biology, quorum sensing or quorum signalling (QS)[1] is the ability to detect and respond to cell population density by gene regulation.`
|
|
8
|
+
- Query subscriptions (https://www.apollographql.com/docs/react/data/subscriptions/): In graphQL you have to choose between them, with Querysub you get both. `Like queries, subscriptions enable you to fetch data. Unlike queries, subscriptions are long-lasting operations that can change their result over time. They can maintain an active connection to your GraphQL server (most commonly via WebSocket), enabling the server to push updates to the subscription's result.` and the BS justification for why graphQL doesn't support automatic subscriptions: `In the majority of cases, your client should not use subscriptions to stay up to date with your backend. Instead, you should poll intermittently with queries, or re-execute queries on demand when a user performs a relevant action (such as clicking a button).`, which is true, but automatic subscriptions should still be easy to enable with 100% accuracy, instead of being hacked kludge to fill the massive missing piece of graphQL.
|
|
9
|
+
|
|
10
|
+
NOTE: The whole idea is "fix later" locks, where we invalidate writes later on, if we realized our lock wasn't ACID.
|
|
11
|
+
|
|
12
|
+
NOTE: We don't need to hang onto lock chains forever, because we require servers to keep their data fresh by constantly receiving the latest values. This means if a piece of data is old enough, we know it can be relied upon, because no one can go back in time far enough to remove it.
|
|
13
|
+
- We still need locks, because have changed relatively recently, but... we don't need to follow it's locks back, or even remember that it is supposed to be valid!
|
|
14
|
+
|
|
15
|
+
NOTE: Functions don't exist explicitly, but due to identical readLocks you can tell what happened from the same function. This also ensures writes are atomic, as if they have the same readLocks, either they are all accepted, or all rejected.
|
|
16
|
+
|
|
17
|
+
NOTE: We don't actually lock things such as Object.keys(). In practice we will get pretty close, but our handling of it is simply not fully ACID.
|
|
18
|
+
|
|
19
|
+
NOTE: In regards to FunctionRunners. FunctionRunner rerun any calls which seem to not be run. The first one to run will get the value, with the others having their ReadLock on the result (from epoch to their LATER writeTime) invalidated.
|
|
20
|
+
- Although, in practice, the writeTimes will be close, as they are based on requested writeTimes, made unique by creatorId. So... if two FunctionRunners run the same call, one will consistently create the accepted value. So... just don't have two FunctionRunners run the same call!
|
|
21
|
+
|
|
22
|
+
NOTE: "Bad" predictions are possibly by if you know the path some change will write to (ie, the call result path). You can create a prediction that depends on that path being undefined (in some range that includes the eventual remote change, but not the prediction), simply watch that path, and when the change eventually happens your prediction will automatically be invalidated.
|
|
23
|
+
- This is not suitable for trusted nodes, as it means all of our dependent values on that prediction will be only acceptable to us (as our prediction won't really be able to be propagated, as the change might never happen, in which case our prediction has to go away, which is impossible to do if we propagate it), but... it is very useful for clients to quickly predict writes (trusted nodes can just write actual values, not trying to get some remote to make a change).
|
|
24
|
+
- AND, if you only depend on that path there is no jitter as you reject old values, as there is no cascading! This DOES allow values to drift out of sync with the server (if they are CONSTANTLY written to), but... that is another problem, for games, and just one of many issues games have to overcome.
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
Summary of benefits/costs
|
|
28
|
+
|
|
29
|
+
Benefits
|
|
30
|
+
1) Decreased code size / decreased development time / decreased complexity
|
|
31
|
+
- Adding a new value doesn't require new endpoints
|
|
32
|
+
- Even for a non-syncing application the code size is about as small as it can get
|
|
33
|
+
2) Minimum possible clientside delay (so everything feels fast)
|
|
34
|
+
- If you just explicitly input predict values, and then clobber the predicted value when the call comes back, you run into a case where multiple predictions get clobber by an old callback. Which is bad.
|
|
35
|
+
- If you explicitly input predict values, and only clobber the latest, that works... until you have reasonably complex data.
|
|
36
|
+
- Explicit endpoints per data path is a non-starter, because when your user interfaces migrates it won't overlap, and then you will have to explicitly calling multiple endpoints after a mutate call, and it will become your entire job.
|
|
37
|
+
- The only way to do input prediction at a framework level is to track all accesses, and have a serverside which exposes path bases values, AND to have the same mutate functions clientside as you use serverside (otherwise you have to rewrite all mutate functions twice).
|
|
38
|
+
- AND THEN... if other users mutate data, you NEED the server to tell you when it changes. If you don't,
|
|
39
|
+
- In theory you can download data every time you need it... but this can't scale to reasonably large applications. AND, if you don't the user won't just see stale data, they will predict stale data, which will be really bad. So... the server needs to synchronize the paths as well
|
|
40
|
+
3) Excellent sharding / scaling via very lax sharding
|
|
41
|
+
- PathValue.locks are a simple locking mechanism, and very efficient (less efficient with high contention)
|
|
42
|
+
- Transactions can easily be done cross shard, and are still fully ACID, which most other databases have a hard time doing (unless they use virtually the same locking scheme)
|
|
43
|
+
|
|
44
|
+
Database flowchart
|
|
45
|
+
(NOTE: Large static assets should always be stored in some object storage database, like S3, even if you are using another system for other data.)
|
|
46
|
+
(NOTE: If you want an ultra responsive UI you can often use a write-then-reader wrapper for your database (which might require extra work to specify what should update, and what should be read). Or... just use query-sub)
|
|
47
|
+
|
|
48
|
+
- Do you want a very responsive user interface (via input prediction)
|
|
49
|
+
= Yes
|
|
50
|
+
- Is it easy to specify exactly what the writes are (with high accuracy) for most server write operations
|
|
51
|
+
(As in, are you using complex writes that involve functions with many lines of code, or is pretty much just KVP writes.)
|
|
52
|
+
= Yes
|
|
53
|
+
- Will the user often experience write contention
|
|
54
|
+
= YES
|
|
55
|
+
- query-sub
|
|
56
|
+
= NO
|
|
57
|
+
- query-sub
|
|
58
|
+
- OR Run again without a very responsive user interface, and then slap a write-then-reread wrapper onto your database, and then tell it what values it should predict.
|
|
59
|
+
= No
|
|
60
|
+
- query-sub
|
|
61
|
+
= NO
|
|
62
|
+
- Is % chance contention * impact of contention low (contention free)?
|
|
63
|
+
= Yes
|
|
64
|
+
Is the data static enough where stale data can be shown? (ex, search results, non-user part of youtube, twitter?)
|
|
65
|
+
= Yes
|
|
66
|
+
- Any NoSQL implementation (S3 for large data, MongoDB for complex data, otherwise BigTable, or even ElasticSearch?)
|
|
67
|
+
= No
|
|
68
|
+
- Do you want clientside data syncing
|
|
69
|
+
= Yes
|
|
70
|
+
- firebase
|
|
71
|
+
= No
|
|
72
|
+
- A fast writing NoSQL implementation (probably MongoDB)
|
|
73
|
+
= No
|
|
74
|
+
- Do you want clientside data syncing
|
|
75
|
+
= Yes
|
|
76
|
+
- firebase + firebase cloud functions
|
|
77
|
+
= No
|
|
78
|
+
- Are writes simple and only affect a single collection
|
|
79
|
+
= Yes
|
|
80
|
+
- MongoDB
|
|
81
|
+
= No
|
|
82
|
+
- MongoDB / SQL (likely with high transaction isolation levels)
|
|
83
|
+
|
|
84
|
+
Conclusion
|
|
85
|
+
- Realistically, you want a responsive user interface (who wouldn't?)
|
|
86
|
+
|
|
87
|
+
NOTE: For applications with very static data (so not just mostly reads, but the data actually changes so infrequently that users can be shown stale data and they won't even notice), using MongoDB is just as good (unless you need really complex transactions).
|
|
88
|
+
- You will still run into issues at huge scales with other databases though, as eventually the amount of transactions you want will exceed what one server can handle, and then you need to shard, and if you don't or can't shard well, everything will get slow.
|
|
89
|
+
|
|
90
|
+
Timestamped writes / clientside reproducible writes
|
|
91
|
+
BENEFIT: Allows clients to compare against incoming writes and know if they write is newer, or older, allowing predictions to never get out of sync.
|
|
92
|
+
ALTERNATIVE: Reading state after each write also allows this. HOWEVER, if the write is a function mutation, the impetus for the write might be small, but the data mutated could be large. For example, a paint application, where a write mutates the canvas, which is large, so we don't want to download the entire canvas after each write.
|
|
93
|
+
- AND, even if the values are small, this requires increased network usage
|
|
94
|
+
COST: Is slower. Is only useful with with KVP writes (if you can't map from clientside write to read paths this can't be used to predict values).
|
|
95
|
+
ADDITIONAL BENEFITS: Makes debugging easier, via keeping track of a history of operations
|
|
96
|
+
|
|
97
|
+
Watching/syncing
|
|
98
|
+
BENEFIT: Greatly reduces read count needed to keep data up to date
|
|
99
|
+
COST: Writes have more overhead, requiring everything to be notified
|
|
100
|
+
|
|
101
|
+
Lock tracking / valid tracking / contention invalidation / eventually consistent transactions
|
|
102
|
+
BENEFIT: ACID safety that is fast even with large collections.
|
|
103
|
+
- Also allows ACID safety even for servers that are off the main network, allowing anyone to add transactions without worrying about inserting an inconsistent write (worst case the write will be rejected).
|
|
104
|
+
- Also, ACID safety is a lot easier to implement with this technique
|
|
105
|
+
ALTERNATIVE: Use a single server, or a single server per collection and don't provide ACID cross collection.
|
|
106
|
+
ALTERNATIVE: Collection locking, which if you have enough servers using the same collection degenerates to single server performance.
|
|
107
|
+
ALTERNATIVE: Smart evenly sub-collection sharding. This can be very efficient, HOWEVER, it is extremely difficult to anticipate the access patterns. Accurately predicting all access patterns would be akin to a universal storage system that can run any search query in optimal time (either O(1), or O(logN)).
|
|
108
|
+
ALTERNATIVE: No ACID safety. This is pretty much only viable if the write interface is purely KVP based. Otherwise it is easy to create functions which depend on ACID safety, and give unpredictable results when it is not kept (ex, contention causes really bad breaking of things). This makes it impossible to implement things such as financial transactions, most games, etc.
|
|
109
|
+
- And, of course, we can have lock tracking support, but just commit writes with no readLocks, which will produce much faster writes, making the database based degenerate to a NoSQL database, with theoretically the same speed.
|
|
110
|
+
COST: Slower to compute writes, and writes become MUCH larger.
|
|
111
|
+
- Lock/eventually consistency transactions ONLY work if the client readers are syncing. If they aren't, they will get the wrong data and KEEP the wrong data, which would break pretty much any application.
|
|
112
|
+
ADDITIONAL BENEFITS: Makes debugging easier, via making it possible to trace the read source used to generate any write (so to track data through the system).
|
package/deploy.ts
ADDED
package/inject.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import "./src/inject";
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "querysub",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"main": "index.js",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"note1": "note on node-forge fork, see https://github.com/digitalbazaar/forge/issues/744 for details",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/sliftist/shard.git"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@sendgrid/mail": "^7.7.0",
|
|
13
|
+
"@types/fs-ext": "^2.0.3",
|
|
14
|
+
"@types/node-forge": "^1.3.1",
|
|
15
|
+
"@types/pako": "^2.0.3",
|
|
16
|
+
"@types/yargs": "^15.0.5",
|
|
17
|
+
"acme-client": "^5.0.0",
|
|
18
|
+
"cbor-x": "^1.5.6",
|
|
19
|
+
"chalk": "^5.2.0",
|
|
20
|
+
"diskusage": "^1.2.0",
|
|
21
|
+
"fs-ext": "^2.0.0",
|
|
22
|
+
"js-sha256": "https://github.com/sliftist/js-sha256",
|
|
23
|
+
"js-sha512": "^0.9.0",
|
|
24
|
+
"node-forge": "https://github.com/sliftist/forge#e618181b469b07bdc70b968b0391beb8ef5fecd6",
|
|
25
|
+
"pako": "^2.1.0",
|
|
26
|
+
"preact": "^10.11.3",
|
|
27
|
+
"socket-function": "^0.31.0",
|
|
28
|
+
"terser": "^5.31.0",
|
|
29
|
+
"typesafecss": "^0.6.3",
|
|
30
|
+
"yaml": "^2.5.0",
|
|
31
|
+
"yargs": "^15.3.1"
|
|
32
|
+
},
|
|
33
|
+
"optionalDependencies": {
|
|
34
|
+
"rdtsc-now": "^0.4.2"
|
|
35
|
+
},
|
|
36
|
+
"scripts": {
|
|
37
|
+
"server": "yarn typenode ./src/server.ts",
|
|
38
|
+
"serversharded": "yarn server --authority ./pathremain.json & yarn server --authority ./patha.json & yarn server --authority ./pathb.json & yarn server --authority ./pathc.json & yarn server --authority ./pathd.json",
|
|
39
|
+
"function": "yarn typenode ./src/3-path-functions/PathFunctionRunnerMain.ts --function --local D:/repos/shard/",
|
|
40
|
+
"deploy": "yarn typenode ./src/3-path-functions/deployMain.ts --domain querysub.com --local D:/repos/shard/",
|
|
41
|
+
"type": "yarn tsc --noEmit",
|
|
42
|
+
"depend": "yarn --silent depcruise src --include-only \"^src\" --config --output-type dot | dot -T svg > dependency-graph.svg",
|
|
43
|
+
"dbmerge": "yarn typenode ./src/dbmerge.ts",
|
|
44
|
+
"test": "yarn typenode ./src/test/test.tsx --local D:/repos/shard/",
|
|
45
|
+
"test2": "yarn typenode ./src/4-dom/qreactTest.tsx --local D:/repos/shard/"
|
|
46
|
+
},
|
|
47
|
+
"bin": {
|
|
48
|
+
"shard-deploy": "./bin/deploy.js",
|
|
49
|
+
"shard-server": "./bin/server.js",
|
|
50
|
+
"shard-function": "./bin/function.js"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"dependency-cruiser": "^12.11.0",
|
|
54
|
+
"open": "^8.4.0",
|
|
55
|
+
"typedev": "^0.3.0"
|
|
56
|
+
},
|
|
57
|
+
"resolutions": {
|
|
58
|
+
"node-forge": "https://github.com/sliftist/forge#e618181b469b07bdc70b968b0391beb8ef5fecd6"
|
|
59
|
+
}
|
|
60
|
+
}
|
package/prompts.txt
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Style
|
|
3
|
+
Steampunk City, night scene, street level, Dark Muted Colors, Shadows
|
|
4
|
+
Cinematic lighting
|
|
5
|
+
realistic
|
|
6
|
+
photo realism
|
|
7
|
+
ultra detailed
|
|
8
|
+
film grain
|
|
9
|
+
octane render
|
|
10
|
+
dark colored photo
|
|
11
|
+
photo by Justin James Muir, Peter Lindbergh
|
|
12
|
+
Peaker blinders
|
|
13
|
+
LA Noire
|
|
14
|
+
1920s
|
|
15
|
+
1930s
|
|
16
|
+
|
|
17
|
+
lights from blinds
|
|
18
|
+
painting
|
|
19
|
+
dim volumetric lighting
|
|
20
|
+
a detailed matte painting
|
|
21
|
+
new objectivity
|
|
22
|
+
|
|
23
|
+
<kitchen|bathroom|entertainment room|cellar>
|
|
24
|
+
|
|
25
|
+
<bedroom|living room|kitchen|bathroom|hallway|closet|basement|dining room|studio|hallway|balcony|elevator|study|utility room|basement|garage|cellar|apartment hallway>
|
|
26
|
+
<table|chairs|couch|bed|stool|cabinet|sofa|television|plants>
|
|
27
|
+
|
|
28
|
+
Angles
|
|
29
|
+
- https://youtu.be/ko3GKu4POXE?t=8
|
|
30
|
+
high angle shot, drone shot, birds eye view, low angle shot, close up shot, wide shot, medium shot, long shot, extreme close
|
|
31
|
+
fisheye lens, establishing shot, wide angle lens, wide field of view,
|
|
32
|
+
low angle shot, looking up
|
|
33
|
+
mid shot, fullbody shot, standing
|
|
34
|
+
macro photography, close up, extreme close up, shallow depth of field
|
|
35
|
+
|
|
36
|
+
Lighting
|
|
37
|
+
shadows
|
|
38
|
+
- Really sharpens everything, making it seem ultra modern (and often black and white)
|
|
39
|
+
soft shadows
|
|
40
|
+
- shadows, but softer
|
|
41
|
+
misty
|
|
42
|
+
- Pretty good way to add mood
|
|
43
|
+
foggy
|
|
44
|
+
- Seems to also add graffiti?
|
|
45
|
+
|
|
46
|
+
Negative prompts for people
|
|
47
|
+
- bad anatomy, bad proportions, blurry, cloned face, cropped, deformed, dehydrated, disfigured, duplicate, error, extra arms, extra fingers, extra legs, extra limbs, fused fingers, gross proportions, jpeg artifacts, long neck, low quality, lowres, malformed limbs, missing arms, missing legs, morbid, mutated hands, mutation, mutilated, out of frame, poorly drawn face, poorly drawn hands, signature, text, too many fingers, ugly, username, watermark, worst quality
|
|
48
|
+
- bad anatomy, bad proportions, blurry, cloned face, cropped, deformed, disfigured, duplicate, extra arms, extra fingers, extra legs, extra limbs, fused fingers, gross proportions, long neck, low quality, malformed limbs, missing arms, missing legs, mutated hands, poorly drawn face, poorly drawn hands, too many fingers, ugly
|
|
49
|
+
|
|
50
|
+
Emotions
|
|
51
|
+
{optimistic|pained|tired|worried|happy|disgust|confused|joyful|lonely|proud|nervous|embarrassed|amused|serious|laughing|sneering|smiling with teeth|}
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
*/
|