3306413d by Jabis Sevón

mirror config and gun added as there are customizations

1 parent 34c50db8
Showing 396 changed files with 4040 additions and 2 deletions
1 module.exports = { 1 module.exports = {
2 apps : [{ 2 apps : [{
3 name: 'multisocket', 3 name: 'multimirror',
4 script: 'server.js', 4 script: 'server.js',
5 watch: true, 5 watch: false,
6 env: { 6 env: {
7 DEBUG : true 7 DEBUG : true
8 } 8 }
......
1 node_modules
2 .git
3 .gitignore
4 *.md
1 # These are supported funding model platforms
2
3 github: amark
4 patreon: gunDB
5 open_collective: gun
6 ko_fi: # Replace with a single Ko-fi username
7 tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 liberapay: # Replace with a single Liberapay username
10 issuehunt: # Replace with a single IssueHunt username
11 otechie: # Replace with a single Otechie username
12 custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
1 *
...\ No newline at end of file ...\ No newline at end of file
1 language: node_js
2 branches:
3 except:
4 - debug
5 node_js:
6 - 10
7 cache:
8 directories:
9 - node_modules
1 # CHANGELOG
2
3 ## 0.9.x
4
5 No breaking changes, but the new Radix Storage Engine (RSE) has been finally integrated and works with S3 as a backup. Expect an order of magnitude or more in cost savings, we'll report our December bill compared to November when we get it.
6
7 We have successfully benchmarked it against **1,000,000 records** doing end-to-end triple verification using our Jepsen-inspired [PANIC](https://github.com/gundb/panic-server) distritubed testing framework, doing **~4K acked writes/second** on a Macbook Air dev machine. For more information on PANIC, check out this [5 minute presentation](https://youtu.be/nTbUCTgLmkY) we did in Sweden (and the prior talk, for those interested in [porting GUN](https://github.com/amark/gun/wiki/porting-gun) out of its reference implementation of JS).
8
9 > Warning: There is a known rare edge case in RSE currently, if data is split between two chunked files, a GET will only return from the first chunk. This will be fixed soon, but we still encourage developers to run and test against it, please report any problems.
10
11 To use RSE, initialize a gun server peer with the default storage disabled, like `Gun({localStorage: false})`. Want to use it with S3? All you need to do is make sure that your environment variables are configured and it will automatically use S3, here is a [template](https://github.com/amark/gun/wiki/Using-Amazon-S3-for-Storage). This works especially well for our 1-click-deploy Heroku [demo server](http://gunjs.herokuapp.com/) with the example apps.
12
13 Finally, with **end-to-end encryption** being enabled with our Security, Encryption, Authorization (SEA) framework (check out our [P2P/decentralized crypto-identity blockchain](https://github.com/amark/gun/wiki/auth)), gun is marching towards a stable v1.0 production-ready system (it is already being used in production by a Northern European government's Navy). So if you are able to [work around the remaining bugs](https://github.com/amark/gun/issues), we would appreciate everybody efforts in experimenting and testing out gun and reporting any last hiccups **in our lead up to the v1.0**!
14
15 We will be **overhauling documentation in this v0.9.x series**, please make complaints about what is missing, and how we can make it better, so it will be polished for the v1.0! The [chatroom is actively and friendly for help](https://gitter.im/amark/gun), [StackOverflow](https://stackoverflow.com/questions/tagged/gun) for questions. And we're looking for [sponsors](https://www.patreon.com/gunDB), we **regularly get 1,200+ uniques every 2 weeks** on this repo, we've had **53% monthly growth** on our installs, and GUN is ranked in the top quarter of the top 1% of the top 1% fastest growing projects across all GitHub! If you are an Enterprise, this would be a great time to chat with us about our IoT, AI/ML, edge computing, graph, and cybersecurity solutions.
16
17 Here is towards a v1.0! Cheers.
18
19 ## 0.8.x
20
21 Adapter interfaces have changed from `Gun.on('event', cb)` to `gun.on('event', cb)`, this will force adapters to be instance specific.
22
23 `.path()` and `.not()` have been officially removed from the core bundle, you can bundle them yourself at `lib/path.js` and `lib/not.js` if you still need them.
24
25 ## 0.7.x
26
27 Small breaking change to `.val(cb)`:
28
29 Previously `.val(cb)` would ONLY be called when data exists, like `.on(cb)`.
30
31 However, due to popular demand, people wanted `.val(cb)` to also get called for `.not(cb)` rather than (before) it would "wait" until data arrived.
32
33 NOTE: For dynamic paths, `.val(cb)` will still wait, like:
34
35 `gun.get('users').map().val(cb)` because the behavior of the `map()` is simply to not fire anything down the chain unless items are found.
36
37 ## 0.6.x
38
39 Introduced experimental features, chaining `.val()` (no callback) and `.map(cb)` behaving as a map/reduce function.
40
41 It also upgraded the socket adapters and did end-to-end load testing and correctness testing.
42
43 ## 0.5.9
44
45 GUN 0.3 -> 0.4 -> 0.5 Migration Guide:
46 `gun.back` -> `gun.back()`;
47 `gun.get(key, cb)` -> cb(err, data) -> cb(at) at.err, at.put;
48 `gun.map(cb)` -> `gun.map().on(cb)`;
49 `gun.init` -> deprecated;
50 `gun.put(data, cb)` -> cb(err, ok) -> cb(ack) ack.err, ack.ok;
51 `gun.get(key)` global/absolute -> `gun.back(-1).get(key)`;
52 `gun.key(key)` -> temporarily broken;
53
54 ## 0.3.7
55
56 - Catch localStorage errors.
57
58 ## 0.3.6
59
60 - Fixed S3 typo.
61
62 ## 0.3.5
63
64 - Fixed server push.
65
66 ## 0.3.4
67
68 - Breaking Change! `list.set(item)` returns the item's chain now, not the list chain.
69 - Client and Server GUN servers are now more up to spec, trimmed excess HTTP/REST header data.
70 - Gun.is.lex added.
71
72 ## 0.3.3
73
74 - You can now link nodes natively, `gun.get('mark').path('owner').put(gun.get('cat'))`!
75 - Sets (or tables, collections, lists) are now easily done with `gun.get('users').set(gun.get('person/mark'))`.
76
77 ## 0.3.2
78
79 Bug fixes.
80
81 ## 0.3.1
82
83 Bug fixes.
84
85 ## 0.3
86
87 Migration Guide! Migrate by changing `.attach(` to `.wsp(` on your server if you have one with gun. Remove `.set()` (delete it), and change `.set($DATA)` (where you call set with something) to `.path('I' + Date.now() + 'R' + Gun.text.random(5)).put($DATA)`. If you have NodeJS style callbacks in your `.get` (which documentation previously recommended that you shouldn't) they previous took `err, graph` and now they take `err, node` (which means now using callback style is fine to use). Inside of `.not()` no longer use `return` or `this`, instead (probably) use `gun` and no `return`. If you are a module developer, use `opt.wire` now instead of `opt.hooks` and message Mark since he needs to talk to you since the wire protocol has changed.
88
89 - Server side default `.wsp()` renamed from `.attach()`.
90 - `.set()` deprecated because it did a bunch of random inconsistent things. Its useful behavior has now become implicit (see below) or can be done explicitly.
91 - `.not()` it was previously common to `return` the chain inside of .not, beware that if you have code like `gun.get(key).not(function(){ return this.put({}).key(key) }).val()` cause `.val()` to be triggered twice (this is intentional, because it funnels two separate chains together) which previously didn't happen. To fix this, just don't return the chain.
92 - `.put()` and `.path()` do implicit `.init()` by default, turn on explicit behavior with `Gun({init: true})`.
93 - `.get(soul, cb)` cb is called back with `err, node` rather than `err, graph`.
94 - Options `opt.wire` renamed from `opt.hooks`.
95 - `.val()` when called empty automatically cleanly logs for convenience purposes.
96 - `.init()` added.
97 - `Gun.is.val` renamed from `Gun.is.value`.
98 - `Gun.is.rel` renamed from `Gun.is.soul`.
99 - `Gun.is.node.soul` renamed from `Gun.is.soul.on`.
100 - `Gun.union.ify` renamed from `Gun.union.pseudo`.
101 - `Gun.union.HAM` renamed from `Gun.HAM`.
102 - `Gun.HAM` is now the actual HAM function for conflict resolution.
103 - `Gun._.state` renamed from `Gun._.HAM`.
104 - Maximum Callstack Exceeded is less problematic now, unless you intentionally choke the thread. #95
105 - Putting a regex or Date or NaN is actually detected and causes an error now while before it was silent. #122 #123
106 - `.on()` gets called when a key is later newly made while before it did not. #116
107 - `.val()` should not ever get called with a relation alone (internals should resolve it), this is fixed. #132
1 FROM alpine:latest
2 # Build-time metadata as defined at http://label-schema.org
3 ARG BUILD_DATE
4 ARG VCS_REF
5 ARG VCS_URL
6 ARG VERSION
7 LABEL org.label-schema.build-date=$BUILD_DATE \
8 org.label-schema.name="Gun - Offline First, Javascript Graph Database" \
9 org.label-schema.url="http://gun.js.org" \
10 org.label-schema.vcs-ref=$VCS_REF \
11 org.label-schema.vcs-url=$VCS_URL \
12 org.label-schema.vendor="The Gun Database Team" \
13 org.label-schema.version=$VERSION \
14 org.label-schema.schema-version="1.0"
15 # org.label-schema.description="Let it be pulled from Readme.md..." \
16 WORKDIR /app
17 ADD . .
18 ENV NPM_CONFIG_LOGLEVEL warn
19 RUN apk update && apk upgrade \
20 && apk add --no-cache ca-certificates nodejs-npm \
21 && apk add --no-cache --virtual .build-dependencies python make g++ \
22 && npm install \
23 && apk del .build-dependencies && rm -rf /var/cache/* /tmp/npm*
24 EXPOSE 8080
25 EXPOSE 8765
26 CMD ["npm","start"]
1 Copyright (c) 2015 Mark Nadal
2
3 Permission is hereby granted, free of charge, to any person obtaining a copy
4 of this software and associated documentation files (the "Software"), to deal
5 in the Software without restriction, including without limitation the rights
6 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 copies of the Software, and to permit persons to whom the Software is
8 furnished to do so, subject to the following conditions:
9
10 The above copyright notice and this permission notice shall be included in
11 all copies or substantial portions of the Software.
12
13 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 THE SOFTWARE.
20
21 ---
22
23 Copyright (c) 2015 Mark Nadal
24
25 This software is provided 'as-is', without any express or implied
26 warranty. In no event will the authors be held liable for any damages
27 arising from the use of this software.
28
29 Permission is granted to anyone to use this software for any purpose,
30 including commercial applications, and to alter it and redistribute it
31 freely, subject to the following restrictions:
32
33 1. The origin of this software must not be misrepresented; you must not
34 claim that you wrote the original software. If you use this software
35 in a product, an acknowledgement in the product documentation would be
36 appreciated but is not required.
37 2. Altered source versions must be plainly marked as such, and must not be
38 misrepresented as being the original software.
39 3. This notice may not be removed or altered from any source distribution.
40
41 ---
42
43 Copyright 2015 Mark Nadal
44
45 Licensed under the Apache License, Version 2.0 (the "License");
46 you may not use this file except in compliance with the License.
47 You may obtain a copy of the License at
48
49 http://www.apache.org/licenses/LICENSE-2.0
50
51 Unless required by applicable law or agreed to in writing, software
52 distributed under the License is distributed on an "AS IS" BASIS,
53 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
54 See the License for the specific language governing permissions and
55 limitations under the License.
1 web: node examples/http.js
...\ No newline at end of file ...\ No newline at end of file
1 {
2 "name": "gun-server",
3 "stack": "heroku-18",
4 "website": "http://gun.eco/",
5 "repository": "https://github.com/amark/gun",
6 "logo": "https://avatars3.githubusercontent.com/u/8811914",
7 "keywords": ["node", "gun", "gunDB", "database","graph","offline-first"],
8 "description": "Javascript, Offline-First Javascript Graph Database Server Peer"
9 }
1 ;(function(){
2 function as(el, gun, cb, opt){
3 el = $(el);
4 if(gun === as.gui && as.el && as.el.is(el)){ return }
5
6 opt = opt || {};
7 opt.match = opt.match || '{{ ';
8 opt.end = opt.end || ' }}';
9 ;(function(){ // experimental
10 function nest(t, s,e, r, i,tmp,u){
11 if(r && !r.length){ return t||'' }
12 if(!t){ return [] }
13 e = e || s;
14 i = t.indexOf(s, i||0);
15 if(0 > i){ return [] }
16 tmp = t.indexOf(e, i+1);
17 if(!r){ return [t.slice(i+s.length, tmp)].concat(nest(t, s,e, r, tmp,tmp,u)) }
18 return t.slice(0,i)+r[0]+nest(t.slice(tmp+e.length), s,e, r.slice(1), 0,tmp,u);
19 }
20
21 /* experimental */
22 function template(tag, attr){
23 var html = (tag = $(tag))[0].outerHTML, sub, tmp;
24 if(html && (0 > html.indexOf(opt.match))){ return }
25 if(!attr){
26 $.each(tag[0].attributes, function(i,v){
27 if(!v){ return }
28 if(!nest(v.value, opt.match, opt.end).length){ return }
29 template(tag, v.name)
30 });
31 if((sub = tag.children()).length){
32 return sub.each(function(){ template(this) });
33 }
34 }
35 var data = [], plate = attr? tag.attr(attr) : tag.html();
36 tmp = nest(plate, opt.match, opt.end);
37 if(!tmp.length){ return }
38 $.each(tmp, function(pos, match){
39 var expr = match.split(' ');
40 var path = (expr[0]).split('.');
41 if(expr = expr.slice(1).join(' ')){
42 expr = new Function("_", "b", "return (_)" + expr);
43 }
44 var val = (expr && expr('')) || '';
45 data.push(val);
46 if(!attr){ tag.text(val) }
47
48 var ref = gun, sup = [], tmp;
49 if(tmp = tag.attr('name')){ sup.push(tmp) }
50 tag.parents("[name]").each(function(){
51 sup.push($(this).attr('name'));
52 });
53 $.each(path = sup.reverse().concat(path), function(i,v){
54 ref = ref.get(v);
55 });
56 ref.on(function(v){
57 v = data[pos] = expr? expr(v) : v;
58 var tmp = nest(plate, opt.match, opt.end, data);
59 if(attr){
60 tag.attr(attr, tmp);
61 } else {
62 tag.text(tmp);
63 }
64 });
65 });
66 }
67 template(el);
68
69 }());
70
71 as.gui = gun;
72 as.el = el;
73 if(el.data('as')){
74 el.html(el.data('as').fresh);
75 } else {
76 el.data('as', {
77 fresh: el.html()
78 })
79 }
80 el.find("[name]").each(function(){
81 if($(this).find("[name]").length){ return }
82 var name = $(this),
83 parents = name.parents("[name]"),
84 path = [],
85 ref = gun;
86
87 path.push(name.attr('name'));
88 parents.each(function(){
89 path.push($(this).attr('name'));
90 });
91 path = path.reverse();
92
93 path.forEach(function(key){
94 if('#' === key){
95 ref = ref.map()
96 } else {
97 ref = ref.get(key);
98 }
99 });
100
101 var many = path.slice().reverse().indexOf('#'), model;
102 many = (0 < ++many)? many : false;
103 if(many){
104 model = name.closest("[name='#']");
105 model = model.data('model') || model.data('model', {$: model.clone(), on: model.parent(), has: {}}).hide().data('model');
106 }
107
108 ref.get(function(at){
109 var data = at.put, key = at.get, gui = at.gun || at.$, ui = name, back;
110 if(model){
111 ui = model.has[(gui._).id];
112 if(!ui){
113 back = gui.back(many - 1);
114 ui = model.has[(back._).id];
115 if(!ui){
116 if(!(back._).get){ return }
117 ui = (model.has[(back._).id] = model.$.clone(true).prependTo(model.on));
118 }
119 ui = ui.find("[name='"+key+"']").first();
120 model.has[(gui._).id] = ui;
121 }
122 }
123 ui.data('gun', gui);
124 if(ui.data('was') === data){ return }
125 if(many && ui.is('.sort')){
126 var up = ui.closest("[name='#']");
127 var tmp = as.sort(data, up.parent().children().last());
128 tmp? up.insertAfter(tmp) : up.prependTo(up.parent());
129 }
130 if(as.lock === gui){ return }
131 if(!(data && data instanceof Object)){
132 (ui[0] && u === ui[0].value)? ui.text(data) : ui.val(data);
133 }
134 ui.data('was', data);
135 if(cb){
136 cb(data, key, ui);
137 }
138 });
139 });
140 }
141 as.wait = function(cb, wait, to){
142 return function(a,b,c){
143 var me = as.typing = this;
144 clearTimeout(to);
145 to = setTimeout(function(){
146 cb.call(me, a,b,c);
147 as.typing = me = false;
148 }, wait || 200);
149 }
150 }
151 as.sort = function sort(num, li){ return parseFloat(num) >= parseFloat($(li).find('.sort').text() || -Infinity)? li : sort(num, li.prev()) }
152 $(document).on('keyup', 'input, textarea, [contenteditable]', as.wait(function(){
153 var el = $(this);
154 var data = (el[0] && u === el[0].value)? el.text() : el.val();
155 var g = el.data('gun');
156 if(!g){ return }
157 as.lock = g;
158 g.put(data);
159 }, 99));
160 //$(document).on('submit', 'form', function(e){ e.preventDefault() });
161 var u;
162 window.as = as;
163 $.as = as;
164 }());
165
166 ;(function(){
167 $(document).on('click', 'a, button', function(e){
168 var tmp = $(this).attr('href') || '';
169 if(0 === tmp.indexOf('http')){ return }
170 e.preventDefault();
171 r(tmp);
172 });
173 function r(href){
174 if(!href){ return }
175 if(href[0] == '#'){ href = href.slice(1) }
176 var h = href.split('/')[0];
177 $('.page').hide();
178 $('#' + h).show();
179 if(r.on === h){ return }
180 location.hash = href;
181 (r.page[h] || {on:function(){}}).on();
182 r.on = h;
183 return r;
184 };
185 r.page = function(h, cb){
186 r.page[h] = r.page[h] || {on: cb};
187 return r;
188 }
189 r.render = function(id, model, onto, data){
190 var $data = $(
191 $('#' + id).get(0) ||
192 $('.model').find(model).clone(true).attr('id', id).appendTo(onto)
193 );
194 $.each(data, function(field, val){
195 if($.isPlainObject(val)){ return }
196 $data.find("[name='" + field + "']").val(val).text(val);
197 });
198 return $data;
199 }
200 window.onhashchange = function(){ r(location.hash.slice(1)) };
201 $.as && ($.as.route = r);
202 if(window.as){
203 as.route = r;
204 } else {
205 $.route = r;
206 }
207 }());
208
209 ;$(function(){
210 $('.page').not(':first').hide();
211 $.as.route(location.hash.slice(1));
212 $(JOY.start = JOY.start || function(){ $.as(document, gun, null, JOY.opt) });
213
214 if($('body').attr('peers')){ (console.warn || console.log)('Warning: Please upgrade <body peers=""> to https://github.com/eraeco/joydb#peers !') }
215
216 });
217 ;(function(){ // need to isolate into separate module!
218 var joy = window.JOY = function(){};
219 joy.auth = function(a,b,cb,o){
220 if(!o){ o = cb ; cb = 0 }
221 if(o === true){
222 gun.user().create(a, b);
223 return;
224 }
225 gun.user().auth(a,b, cb,o);
226 }
227
228 var opt = joy.opt = window.CONFIG || {}, peers;
229 $('link[type=peer]').each(function(){ (peers || (peers = [])).push($(this).attr('href')) });
230 !window.gun && (opt.peers = opt.peers || peers || (function(){
231 (console.warn || console.log)('Warning: No peer provided, defaulting to DEMO peer. Do not run in production, or your data will be regularly wiped, reset, or deleted. For more info, check https://github.com/eraeco/joydb#peers !');
232 return ['https://gunjs.herokuapp.com/gun'];
233 }()));
234 window.gun = window.gun || Gun(opt);
235
236 gun.on('auth', function(ack){
237 console.log("Your namespace is publicly available at", ack.soul);
238 });
239 }());
...\ No newline at end of file ...\ No newline at end of file
1 {
2 "name": "gun",
3 "main": "gun.js",
4 "version": "0.1.5",
5 "homepage": "http://gunDB.io",
6 "authors": [
7 { "name": "Mark Nadal", "email": "mark@accelsor.com" },
8 { "name": "Alex LaFroscia", "email": "alex@lafroscia.com" }
9 ],
10 "repository": {
11 "type": "git",
12 "url": "https://github.com/amark/gun"
13 },
14 "description": "A distributed, embedded, graph database engine.",
15 "moduleType": [
16 "globals"
17 ],
18 "keywords": [
19 "graph",
20 "database",
21 "gun",
22 "gundb",
23 "nodb"
24 ],
25 "license": "MIT",
26 "ignore": [
27 "**/.*",
28 "node_modules",
29 "bower_components",
30 "test",
31 "tests"
32 ]
33 }
1 module.exports.Gun = require('./gun.js')
2 module.exports.SEA = require('./sea.js')
...\ No newline at end of file ...\ No newline at end of file
1 module.exports.Gun = require('./gun.js')
2 module.exports.SEA = require('./sea.js')
...\ No newline at end of file ...\ No newline at end of file
1 module.exports = require('./gun.js')
...\ No newline at end of file ...\ No newline at end of file
1 {
2 "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3 "project": {
4 "name": "angular"
5 },
6 "apps": [
7 {
8 "root": "src",
9 "outDir": "dist",
10 "assets": [
11 "assets",
12 "favicon.ico"
13 ],
14 "index": "index.html",
15 "main": "main.ts",
16 "polyfills": "polyfills.ts",
17 "test": "test.ts",
18 "tsconfig": "tsconfig.app.json",
19 "testTsconfig": "tsconfig.spec.json",
20 "prefix": "app",
21 "styles": [
22 "styles.css"
23 ],
24 "scripts": [],
25 "environmentSource": "environments/environment.ts",
26 "environments": {
27 "dev": "environments/environment.ts",
28 "prod": "environments/environment.prod.ts"
29 }
30 }
31 ],
32 "e2e": {
33 "protractor": {
34 "config": "./protractor.conf.js"
35 }
36 },
37 "lint": [
38 {
39 "project": "src/tsconfig.app.json",
40 "exclude": "**/node_modules/**"
41 },
42 {
43 "project": "src/tsconfig.spec.json"
44 },
45 {
46 "project": "e2e/tsconfig.e2e.json"
47 }
48 ],
49 "test": {
50 "karma": {
51 "config": "./karma.conf.js"
52 }
53 },
54 "defaults": {
55 "styleExt": "css",
56 "component": {}
57 }
58 }
1 # Editor configuration, see http://editorconfig.org
2 root = true
3
4 [*]
5 charset = utf-8
6 indent_style = space
7 indent_size = 2
8 insert_final_newline = true
9 trim_trailing_whitespace = true
10
11 [*.md]
12 max_line_length = off
13 trim_trailing_whitespace = false
1 # Angular
2
3 This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 1.0.0.
4
5 ## Development server
6
7 Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
8
9 ## Code scaffolding
10
11 Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive/pipe/service/class/module`.
12
13 ## Build
14
15 Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `-prod` flag for a production build.
16
17 ## Running unit tests
18
19 Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
20
21 ## Running end-to-end tests
22
23 Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
24 Before running the tests make sure you are serving the app via `ng serve`.
25
26 ## Further help
27
28 To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
1 {
2 "extends": "../tsconfig.json",
3 "compilerOptions": {
4 "outDir": "../out-tsc/e2e",
5 "module": "commonjs",
6 "target": "es5",
7 "types":[
8 "jasmine",
9 "node"
10 ]
11 }
12 }
1 // Karma configuration file, see link for more information
2 // https://karma-runner.github.io/0.13/config/configuration-file.html
3
4 module.exports = function (config) {
5 config.set({
6 basePath: '',
7 frameworks: ['jasmine', '@angular/cli'],
8 plugins: [
9 require('karma-jasmine'),
10 require('karma-chrome-launcher'),
11 require('karma-jasmine-html-reporter'),
12 require('karma-coverage-istanbul-reporter'),
13 require('@angular/cli/plugins/karma')
14 ],
15 client:{
16 clearContext: false // leave Jasmine Spec Runner output visible in browser
17 },
18 files: [
19 { pattern: './src/test.ts', watched: false }
20 ],
21 preprocessors: {
22 './src/test.ts': ['@angular/cli']
23 },
24 mime: {
25 'text/x-typescript': ['ts','tsx']
26 },
27 coverageIstanbulReporter: {
28 reports: [ 'html', 'lcovonly' ],
29 fixWebpackSourcePaths: true
30 },
31 angularCli: {
32 environment: 'dev'
33 },
34 reporters: config.angularCli && config.angularCli.codeCoverage
35 ? ['progress', 'coverage-istanbul']
36 : ['progress', 'kjhtml'],
37 port: 9876,
38 colors: true,
39 logLevel: config.LOG_INFO,
40 autoWatch: true,
41 browsers: ['Chrome'],
42 singleRun: false
43 });
44 };
This diff could not be displayed because it is too large.
1 {
2 "name": "angular",
3 "version": "0.0.0",
4 "license": "MIT",
5 "scripts": {
6 "ng": "ng",
7 "start": "ng serve",
8 "build": "ng build",
9 "test": "ng test",
10 "lint": "ng lint",
11 "e2e": "ng e2e"
12 },
13 "private": true,
14 "dependencies": {
15 "@angular/common": "^4.1.0",
16 "@angular/compiler": "^4.1.0",
17 "@angular/core": "^4.1.0",
18 "@angular/forms": "^4.1.0",
19 "@angular/http": "^4.1.0",
20 "@angular/platform-browser": "^4.1.0",
21 "@angular/platform-browser-dynamic": "^4.1.0",
22 "@angular/router": "^4.1.0",
23 "core-js": "^2.4.1",
24 "express-http-proxy": "^1.0.1",
25 "gun": "^0.7.4",
26 "ngx-pipes": "^2.0.5",
27 "rxjs": "^5.3.0",
28 "underscore": "^1.8.3",
29 "zone.js": "^0.8.9"
30 },
31 "devDependencies": {
32 "@angular/cli": "1.0.0",
33 "@angular/compiler-cli": "^4.1.0",
34 "@types/jasmine": "2.5.38",
35 "@types/node": "~6.0.60",
36 "@types/underscore": "^1.8.0",
37 "codelyzer": "^2.1.1",
38 "jasmine-core": "^2.6.1",
39 "jasmine-spec-reporter": "^4.0.0",
40 "karma": "^1.6.0",
41 "karma-chrome-launcher": "~2.0.0",
42 "karma-cli": "~1.0.1",
43 "karma-coverage-istanbul-reporter": "^1.2.0",
44 "karma-jasmine": "~1.1.0",
45 "karma-jasmine-html-reporter": "^0.2.2",
46 "protractor": "~5.1.0",
47 "ts-node": "^3.0.2",
48 "tslint": "~4.5.0",
49 "typescript": "^2.3.2"
50 }
51 }
1 // Protractor configuration file, see link for more information
2 // https://github.com/angular/protractor/blob/master/lib/config.ts
3
4 const { SpecReporter } = require('jasmine-spec-reporter');
5
6 exports.config = {
7 allScriptsTimeout: 11000,
8 specs: [
9 './e2e/**/*.e2e-spec.ts'
10 ],
11 capabilities: {
12 'browserName': 'chrome'
13 },
14 directConnect: true,
15 baseUrl: 'http://localhost:4200/',
16 framework: 'jasmine',
17 jasmineNodeOpts: {
18 showColors: true,
19 defaultTimeoutInterval: 30000,
20 print: function() {}
21 },
22 beforeLaunch: function() {
23 require('ts-node').register({
24 project: 'e2e/tsconfig.e2e.json'
25 });
26 },
27 onPrepare() {
28 jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
29 }
30 };
1 var port = process.env.OPENSHIFT_NODEJS_PORT || process.env.VCAP_APP_PORT || process.env.PORT || process.argv[2] || 8765;
2 var host = process.env.OPENSHIFT_NODEJS_HOST || process.env.VCAP_APP_HOST || process.env.HOST || 'localhost';
3
4 var express = require('express');
5 var proxy = require('express-http-proxy');
6 var http = require('http');
7 var app = express();
8 var server = http.createServer(app);
9
10 var Gun = require('gun');
11 var gun = Gun({
12 file: 'data.json',
13 web: server
14 });
15
16 app.use(Gun.serve);
17 app.use(proxy(host + ':4200'));
18 server.listen(port);
19
20 console.log('Server started on port ' + port + ' with /gun');
1 html, body { font-size: 14pt; padding: 10px 2.5%;}
2 .hide { display: none; }
3 form .who { width: 10%; }
4 form .what { width: 80%; }
5 ul { list-style: none; padding: 0; }
6 ul .when {color: #555; font-size: 12pt; float: right; display: none; }
7 li:hover .when {display: inline;}
1 <div>
2
3 <form (ngSubmit)="add()">
4 <input type="text" [(ngModel)]="newTodo" name="newTodo" placeholder="New TODO">
5 <button type="submit" *ngIf="newTodo" [disabled]="newTodo?.trim().length === 0">Add</button>
6 </form>
7 <br />
8 <ul>
9 <li *ngFor="let todo of todos$ | async | pairs" (click)="delete(todo[0])">{{todo[1]}}</li>
10 </ul>
11 <button (click)="sub()" *ngIf="!todosSub">Log in console</button>
12 <button (click)="unsub()" *ngIf="!!todosSub">Stop logging</button>
13 </div>
1 <!doctype html>
2 <html>
3 <head>
4 <meta charset="utf-8">
5 <title>Angular</title>
6 <base href="/">
7
8 <meta name="viewport" content="width=device-width, initial-scale=1">
9 <link rel="icon" type="image/x-icon" href="favicon.ico">
10 </head>
11 <body>
12 <app-root>Loading...</app-root>
13 </body>
14 </html>
1 /* You can add global styles to this file, and also import other style files */
1 {
2 "extends": "../tsconfig.json",
3 "compilerOptions": {
4 "outDir": "../out-tsc/app",
5 "module": "es2015",
6 "baseUrl": "",
7 "types": []
8 },
9 "exclude": [
10 "test.ts",
11 "**/*.spec.ts"
12 ]
13 }
1 {
2 "extends": "../tsconfig.json",
3 "compilerOptions": {
4 "outDir": "../out-tsc/spec",
5 "module": "commonjs",
6 "target": "es5",
7 "baseUrl": "",
8 "types": [
9 "jasmine",
10 "node"
11 ]
12 },
13 "files": [
14 "test.ts"
15 ],
16 "include": [
17 "**/*.spec.ts",
18 "**/*.d.ts"
19 ]
20 }
1 /* SystemJS module definition */
2 declare var module: NodeModule;
3 interface NodeModule {
4 id: string;
5 }
1 {
2 "compileOnSave": false,
3 "compilerOptions": {
4 "outDir": "./dist/out-tsc",
5 "baseUrl": "src",
6 "sourceMap": true,
7 "declaration": false,
8 "moduleResolution": "node",
9 "emitDecoratorMetadata": true,
10 "experimentalDecorators": true,
11 "target": "es5",
12 "typeRoots": [
13 "node_modules/@types"
14 ],
15 "lib": [
16 "es2016",
17 "dom"
18 ]
19 }
20 }
1 {
2 "rulesDirectory": [
3 "node_modules/codelyzer"
4 ],
5 "rules": {
6 "callable-types": true,
7 "class-name": true,
8 "comment-format": [
9 true,
10 "check-space"
11 ],
12 "curly": true,
13 "eofline": true,
14 "forin": true,
15 "import-blacklist": [true, "rxjs"],
16 "import-spacing": true,
17 "indent": [
18 true,
19 "spaces"
20 ],
21 "interface-over-type-literal": true,
22 "label-position": true,
23 "max-line-length": [
24 true,
25 140
26 ],
27 "member-access": false,
28 "member-ordering": [
29 true,
30 "static-before-instance",
31 "variables-before-functions"
32 ],
33 "no-arg": true,
34 "no-bitwise": true,
35 "no-console": [
36 true,
37 "debug",
38 "info",
39 "time",
40 "timeEnd",
41 "trace"
42 ],
43 "no-construct": true,
44 "no-debugger": true,
45 "no-duplicate-variable": true,
46 "no-empty": false,
47 "no-empty-interface": true,
48 "no-eval": true,
49 "no-inferrable-types": [true, "ignore-params"],
50 "no-shadowed-variable": true,
51 "no-string-literal": false,
52 "no-string-throw": true,
53 "no-switch-case-fall-through": true,
54 "no-trailing-whitespace": true,
55 "no-unused-expression": true,
56 "no-use-before-declare": true,
57 "no-var-keyword": true,
58 "object-literal-sort-keys": false,
59 "one-line": [
60 true,
61 "check-open-brace",
62 "check-catch",
63 "check-else",
64 "check-whitespace"
65 ],
66 "prefer-const": true,
67 "quotemark": [
68 true,
69 "single"
70 ],
71 "radix": true,
72 "semicolon": [
73 "always"
74 ],
75 "triple-equals": [
76 true,
77 "allow-null-check"
78 ],
79 "typedef-whitespace": [
80 true,
81 {
82 "call-signature": "nospace",
83 "index-signature": "nospace",
84 "parameter": "nospace",
85 "property-declaration": "nospace",
86 "variable-declaration": "nospace"
87 }
88 ],
89 "typeof-compare": true,
90 "unified-signatures": true,
91 "variable-name": false,
92 "whitespace": [
93 true,
94 "check-branch",
95 "check-decl",
96 "check-operator",
97 "check-separator",
98 "check-type"
99 ],
100
101 "directive-selector": [true, "attribute", "app", "camelCase"],
102 "component-selector": [true, "element", "app", "kebab-case"],
103 "use-input-property-decorator": true,
104 "use-output-property-decorator": true,
105 "use-host-property-decorator": true,
106 "no-input-rename": true,
107 "no-output-rename": true,
108 "use-life-cycle-interface": true,
109 "use-pipe-transform-interface": true,
110 "component-class-suffix": true,
111 "directive-class-suffix": true,
112 "no-access-missing-member": true,
113 "templates-use-public": true,
114 "invoke-injectable": true
115 }
116 }
This diff could not be displayed because it is too large.
1 <!DOCTYPE HTML>
2 <html>
3
4 <head>
5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
6 <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0" />
7 <title>Testing AXE</title>
8 </head>
9
10 <body>
11 <h3 id="pid"></h3>
12 <script src="../gun.js"></script>
13 <script src="../gun/axe.js"></script>
14 <script src="../gun/lib/radix.js"></script>
15 <script src="../gun/lib/webrtc.js"></script>
16 <!-- <script src="../sea.js"></script> -->
17 <script>
18 var pid = location.hash.slice(1);
19
20 var opt = ({
21 peers: [`${location.origin}/gun`]
22 });
23
24 if (pid) { opt.pid = pid; }
25
26 Gun.on('opt', function(ctx) {
27 this.to.next(ctx);
28 ctx.on('hi', function(opt) {
29 // console.log('HI!! PEER', new Date(), opt.pid);
30 setTimeout(function() {
31 document.getElementById('pid').innerHTML = gun._.opt.pid;
32 });
33 });
34 // if (pid) {
35 // ctx.on('out', function(msg) {
36 // msg.pid = pid;
37 // this.to.next(msg);
38 // });
39 // }
40 });
41
42 var gun = Gun(opt);
43 //var user = gun.user();
44 </script>
45 </body>
46 </html>
1 <!DOCTYPE html>
2
3 <style>html, body, textarea { width: 100%; height: 100%; padding: 0; margin: 0; }</style>
4 <textarea placeholder="paste here!"></textarea>
5
6 <script src="../jquery.js"></script>
7 <script src="../../../gun/gun.js"></script>
8
9 <script>
10 var gun = Gun(location.origin + '/gun');
11
12 var to, paste = gun.get('test').get('paste').on(function(data){
13 $('textarea').val(data);
14 })
15
16 $('textarea').on('input change blur keyup mouseup touchend', function(){
17 clearTimeout(to); // debounce
18 to = setTimeout(function(){
19 paste.put($('textarea').val());
20 }, 100);
21 })
22 </script>
...\ No newline at end of file ...\ No newline at end of file
1 <!DOCTYPE html>
2 <style>
3 html, body {
4 background: rgb(245, 245, 245);
5 margin: 0;
6 padding: 0;
7 }
8 div {
9 position: relative;
10 overflow: hidden;
11 }
12 #top {
13 background: #283e4a;
14 height: 52px;
15 width: 100%;
16 }
17 .box {
18 border-radius: 3px;
19 box-shadow: 0px 0px 3px #777;
20 background: white;
21 max-width: 36em;
22 margin: 0 auto;
23 min-height: 10em;
24 margin-bottom: 0.5em;
25 }
26 .color {
27 background: #2977b5;
28 height: 7em;
29 width: 100%;
30 }
31 .pad {
32 margin: 1em;
33 }
34 .none { display: none; }
35 input {
36 font-size: 1em;
37 margin: 0.1em;
38 }
39 </style>
40 <div id="top">
41 <center>
42 <input id="search" placeholder="search by pub or DID">
43 </center>
44 </div>
45
46 <div class="box">
47 <div class="color"></div>
48 <div class="pad">
49 <form id="sign">
50 <h1>Login</h1>
51 <input id="alias" placeholder="username">
52 <input id="pass" type="password" placeholder="passphrase">
53 <input id="in" type="submit" value="sign in">
54 <input id="up" type="button" value="sign up">
55 </form>
56
57
58 <form id="profile" class="none">
59 <h1>Profile</h1>
60 <p>Data is privately encrypted by default. "+" to grant access, "x" to revoke access.</p>
61 <input id="name" placeholder="name"> <button>+</button><br/>
62 <input id="born" placeholder="born"> <button>+</button><br/>
63 <input id="edu" placeholder="education"> <button>+</button><br/>
64 <input id="skills" placeholder="skills"> <button>+</button><br/>
65 </form>
66 </div>
67 </div>
68
69 <div class="box"><div class="pad">
70 Public Key: <input id="pub">
71 </div></div>
72
73 <script src="../jquery.js"></script>
74 <script src="../../../gun/gun.js"></script>
75 <script src="../../../gun/sea.js"></script>
76
77 <script>
78
79 // extend SEA functions to base64 encode encrypted data
80 // workaround for https://github.com/amark/gun/issues/783
81
82 (() => {
83 const _encrypt = SEA.encrypt;
84 SEA.encrypt = function(...args) {
85 return _encrypt.apply(this, args).then(enc => btoa(JSON.stringify(enc)));
86 }
87
88 const _decrypt = SEA.decrypt;
89 SEA.decrypt = function(data, ...args) {
90 try { data = JSON.parse(atob(data)); }
91 finally { return _decrypt.apply(this, [data, ...args]); }
92 }
93 })();
94
95 // override User functions to fix several issues
96 // see https://github.com/amark/gun/issues/808
97
98 SEA.Gun.User.prototype.grant = function grant(to, cb) {
99 const gun = this; const user = gun.back(-1).user();
100 const pair = user._.sea; let path = '';
101
102 gun.back(at => { if (at.has) { path += at.get; } });
103
104 (async () => {
105 let enc, sec;
106
107 if (sec = await user.get('trust').get(pair.pub).get(path).then()) {
108 sec = await SEA.decrypt(sec, pair);
109
110 } else {
111 sec = SEA.random(24).toString();
112 enc = await SEA.encrypt(sec, pair);
113
114 user.get('trust').get(pair.pub).get(path).put(enc);
115 }
116
117 let pub = to.get('pub') .then();
118 let epub = to.get('epub').then();
119
120 pub = await pub; epub = await epub;
121
122 const dh = await SEA.secret (epub, pair);
123 enc = await SEA.encrypt(sec, dh);
124
125 // if pub is not already in trust, first put an empty node
126 // workaround for https://github.com/amark/gun/issues/844
127
128 if (!await user.get('trust').get(pub).then()) {
129 await user.get('trust').get(pub).get(path).put({}).then();
130 }
131
132 user.get('trust').get(pub).get(path).put(enc, cb);
133 })();
134
135 return gun;
136 }
137
138 SEA.Gun.User.prototype.secret = function(data, cb) {
139 const gun = this; const user = gun.back(-1).user();
140 const pair = user._.sea; let path = '';
141
142 gun.back(at => { if (at.has) { path += at.get; } });
143
144 (async () => {
145 let enc, sec;
146
147 if (sec = await user.get('trust').get(pair.pub).get(path).then()) {
148 sec = await SEA.decrypt(sec, pair);
149
150 } else {
151 sec = SEA.random(24).toString();
152 enc = await SEA.encrypt(sec, pair);
153
154 user.get('trust').get(pair.pub).get(path).put(enc);
155 }
156
157 enc = await SEA.encrypt(data, sec);
158 gun.put(enc, cb);
159 })();
160
161 return gun;
162 }
163
164 var gun = Gun('http://localhost:8765/gun');
165 var user = gun.user();
166 var LI = {};
167
168 user.recall({sessionStorage: true});
169
170 $('#up').on('click', function(e){
171 user.create($('#alias').val(), $('#pass').val());
172 });
173
174 $('#sign').on('submit', function(e){
175 e.preventDefault();
176 user.auth($('#alias').val(), $('#pass').val());
177 });
178
179 gun.on('auth', function(){
180 $('#sign').hide();
181 $('#profile').show();
182 var pub = user._.sea.pub;
183 $('#pub').val(pub);
184 return;
185 $("#search").val(pub).trigger('blur');
186 });
187
188 $('#profile input').on('keyup', function(e){
189 if(!user.is){ return }
190 var id = LI.busy = $(this).attr('id');
191 user.get('profile').get(id).secret($(this).val());
192 }).on('blur', function(){ LI.busy = false })
193
194 $('#profile button').on('click', async function(e){
195 e.preventDefault();
196 if(!user.is){ return }
197 var b = $(this);
198 var id = b.prev().attr('id');
199 var pub = prompt("What is the Public Key or DID you want to give read access to?");
200 var to = gun.user(pub);
201 var who = await to.get('alias').then();
202 if(!confirm("You want to give access to " + who + "?")){ return }
203 user.get('profile').get(id).grant(to);
204 });
205
206 $('#search').on('blur', function(e){
207 var s = LI.search = $(this).val();
208 var find = gun.user(s);
209 find.get('profile').on(function(data, key, at, ev){
210 if(s !== LI.search){
211 ev.off();
212 return;
213 }
214
215 Gun.node.is(data, async (enc, id) => {
216 if (id === LI.busy) { return; }
217
218 const pair = user._.sea;
219 let key, val;
220
221 if (key =
222 await find.get('trust').get(pair.pub).get(id + 'profile').then()) {
223 const mix = await Gun.SEA.secret(await find.get('epub').then(), pair);
224
225 key = await Gun.SEA.decrypt(key, mix);
226 val = await Gun.SEA.decrypt(enc, key);
227
228 // decode encrypted data to show 'SEA{...}'
229 } else { val = JSON.parse(atob(enc)); }
230
231 $('#' + id).val(val);
232 });
233 });
234 });
235 </script>
...\ No newline at end of file ...\ No newline at end of file
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=0">
5 <link href='https://fonts.googleapis.com/css?family=Poiret+One' rel='stylesheet' type='text/css'>
6 </head>
7 <body>
8
9 <h1><button id="left">&larr;</button> <span id="date"></span> Schedule <button id="right">&rarr;</button></h1>
10
11 <form id="add">
12 <style>input[type="number"]{ width: 4em; }</style>
13 <input id="what" placeholder="What?">
14 <input id="where" placeholder="Where?">
15 <input type="number" id="hour"><script>hour.value = new Date().getHours() % 12 || 12</script> :
16 <input type="number" id="min" value="0">
17 <select id="ampm">
18 <option value="">am</option>
19 <option value="1">pm</option>
20 <script>ampm.children[new Date().getHours() < 12? 0 : 1].selected='selected'</script>
21 </select>
22 <input id="id" type="hidden">
23 <input id="go" type="submit" value="add">
24 <div id="err"></div>
25 </form>
26
27 <style>
28 .none { display: none; }
29 p, ul, li { list-style-type: none; margin: 0; padding: 0; }
30 </style>
31
32 <ul></ul>
33
34 <div class="model none">
35 <li>
36 <b class="when"></b>
37 <span class="what"></span>
38 <u class="where"></u>
39 <span class="sort none">0</span>
40 <button class="edit"><</button>
41 </li>
42 </div>
43
44 <script src="../jquery.js"></script>
45 <script src="../../../gun/gun.js"></script>
46 <script src="../../../gun/nts.js"></script>
47 <script src="../../../gun/lib/webrtc.js"></script>
48
49 <script>
50 var name = 'schedule/' + location.hash.slice(1);
51 var gun = Gun(location.origin + '/gun');
52 //var gun = Gun('http://localhost:8765/gun');
53 //var gun = Gun();
54
55 $('#add').on('submit', function(event){
56 event.preventDefault();
57 event = {};
58 if(!schedule.on){ return err.innerText = "No date!" }
59 event.when = new Date(schedule.on.getFullYear(), schedule.on.getMonth(), schedule.on.getDate(), hour.value % 12 + (ampm.value? 12 : 0), min.value).getTime();
60 if(!(event.what = what.value)){ return err.innerText = "No description!" }
61 if(!(event.where = where.value)){ return err.innerText = "No location!" }
62 var day = gun.get(name+now(event.when));
63 day.get(id.value || Gun.text.random(9)).put(event);
64 what.value = where.value = id.value = err.innerText = '';
65 go.value = 'add';
66 schedule(event.when);
67 });
68
69 function schedule(ms){
70 var day = new Date(ms);
71 if(schedule.on && schedule.on.toLocaleDateString() === day.toLocaleDateString()){ return } schedule.on = day;
72 $('#date').text(day.getFullYear()+' '+ day.toString().split(' ')[1] +' '+day.getDate());
73 day = gun.get(name+now(ms));
74 $('ul').empty();
75 day.map().on(UI);
76 }
77 schedule(+new Date());
78
79 $('#left').on('click', function(){ schedule(+new Date(schedule.on.getFullYear(), schedule.on.getMonth(), schedule.on.getDate() - 1)) });
80 $('#right').on('click', function(){ schedule(+new Date(schedule.on.getFullYear(), schedule.on.getMonth(), schedule.on.getDate() + 1)) });
81
82 function UI(event, id){
83 if(!event){ return }
84 var when = new Date(event.when);
85 if(schedule.on && when.toLocaleDateString() !== schedule.on.toLocaleDateString()){ return }
86 var ul = $('ul')
87 var li = $("#cal-" + id)[0]; // grab if exists
88 if(!li){
89 li = $('.model li').clone(true) // else create it
90 .attr('id', 'cal-' + id);
91 }
92 li = (UI.last = sort(event.when, ul.children('li').last())[0])? $(li).insertAfter(UI.last) : $(li).prependTo(ul);
93 li.find('.what').text(event.what);
94 li.find('.where').text(event.where);
95 li.find('.sort').text(event.when);
96 li.find('.edit').val(id);
97
98 var time = when.toLocaleTimeString();
99 li.find('.when').text(time.split(':').slice(0,2).join(':') + time.slice(-2));
100 };
101
102 $(document).on('click', '.edit', function(){
103 go.value = 'update';
104 id.value = this.value;
105 what.value = $(this).parent().find('.what').text();
106 where.value = $(this).parent().find('.where').text();
107 var when = new Date(parseFloat($(this).parent().find('.sort').text()));
108 hour.value = when.getHours() % 12 || 12;
109 min.value = when.getMinutes();
110 ampm.value = when.getHours() < 12? '' : 1;
111 what.focus();
112 });
113
114 function now(t){
115 return new Date(t || Gun.state()).toLocaleDateString().split('/').reverse().join('/')
116 }
117
118 function sort(num, li){ return parseFloat(num) >= parseFloat($(li).find('.sort').text() || -Infinity)? li : sort(num, li.prev()) }
119 </script>
120 </body>
121 </html>
...\ No newline at end of file ...\ No newline at end of file
1 <!DOCTYPE html>
2
3 <video id="video" width="100%"></video>
4 <center>
5 <button id="record">Record</button>
6 <button id="play">Play</button>
7 </center>
8
9 <script src="../jquery.js"></script>
10 <script src="../../../gun/gun.js"></script>
11
12 <script>
13 var gun = Gun(location.origin + '/gun');
14 var record = {recorder: null, recording: false};
15
16 $('#record').on('click', ()=>{
17 if(!record.ing){ return record.stream() }
18 $('#record').text("Record");
19 if(record.ing.stop){ record.ing.stop() }
20 record.ing = false;
21 })
22
23 record.stream = function(){
24 navigator.mediaDevices.getDisplayMedia({ video: true }).then(stream => {
25 var chunks = []; // we have a stream, we can record it
26 record.ing = new MediaRecorder(stream);
27 record.ing.ondataavailable = eve => chunks.push(eve.data);
28 record.ing.onstop = eve => record.save(new Blob(chunks));
29 record.ing.start()
30 $('#record').text("End");
31 }, err => { console.log(err) });
32 }
33
34 record.save = function(data){
35 record.file = record.file || new FileReader();
36 record.file.readAsDataURL(data);
37 record.file.onloadend = function(){
38 var b64 = record.file.result;
39 b64 = "data:video/webm" + b64.slice(b64.indexOf(';'));
40 gun.get('test').get('screen').put(b64);
41 }
42 }
43
44 $('#play').on('click', ()=>{
45 if(record.playing){
46 $('#play').text("Play")
47 $('#video').get(0).stop();
48 record.playing = false;
49 return;
50 }
51 $('#play').text("Stop");
52 record.playing = true;
53 gun.get('test').get('screen').once((data)=>{
54 if(!data){ return }
55 $('#video').get(0).src = data;
56 $('#video').get(0).play()
57 })
58 })
59 </script>
...\ No newline at end of file ...\ No newline at end of file
1 <!DOCTYPE html>
2
3 <h1>Tables</h1>
4
5 <form id="sign">
6 <input id="alias" placeholder="username">
7 <input id="pass" type="password" placeholder="passphrase">
8 <input id="in" type="submit" value="sign in">
9 <input id="up" type="button" value="sign up">
10 </form>
11
12 <button id="tadd">+ table</button>
13 <ul></ul><br/>
14
15 <div id="table"></div>
16 <button id="radd">+ row</button>
17 <button id="cadd">+ col</button>
18
19 <style>
20 div {
21 position: relative;
22 overflow: hidden;
23 }
24 .cell {
25 width: 5em;
26 height: 5em;
27 border: 1px solid black;
28 float: left;
29 }
30 .item {
31 float: left;
32 min-width: 5em;
33 }
34 </style>
35 <div class="model" style="display: none;">
36 <div class="item"></div>
37 <div class="cell"></div>
38 <div class="row"></div>
39 </div>
40
41 <script src="https://cdn.jsdelivr.net/npm/gun/examples/jquery.js"></script>
42 <script src="https://cdn.jsdelivr.net/npm/gun/gun.js"></script>
43 <script src="https://cdn.jsdelivr.net/npm/gun/sea.js"></script>
44 <script src="https://cdn.jsdelivr.net/npm/gun/lib/open.js"></script>
45
46 <script>
47 //var gun = Gun(['http://localhost:8080/gun']);
48 var gun = Gun();
49 var user = gun.user();
50
51 $('#up').on('click', function(e){
52 user.create($('#alias').val(), $('#pass').val());
53 });
54
55 $('#sign').on('submit', function(e){
56 e.preventDefault();
57 user.auth($('#alias').val(), $('#pass').val());
58 });
59
60 user.recall({sessionStorage: true});
61
62 gun.on('auth', function(){
63 $('#sign').hide();
64 user.get('tables').map().once(list);
65 });
66
67 $('#tadd').on('click', function(e){
68 if(!user.is){ return alert("login first") }
69 var cell = user.get('cells').set({what: "Edit me!", sort: 1});
70 var row = user.get('rows').set({sort: 1});
71 row.get('cells').set(cell);
72 var name = prompt("What do you want to call this table?")
73 var table = user.get('tables').set({name: name});
74 table.get('rows').set(row);
75 choose(table);
76 });
77
78 $(document).on('click', '.item', function(){
79 choose($(this).data('$'));
80 });
81
82 function choose(table){
83 choose.table = table;
84 table.open(render);
85 }
86
87 function render(data){
88 console.log(data);
89 $('#table').empty(); // BAD! Write DOM-diffing!
90 Gun.obj.map(data.rows, function(row, id){
91 var $r = grab(id, '.model .row', '#table');
92 Gun.obj.map(row.cells, function(cell, id){
93 var $c = grab(id, '.model .cell', $r);
94 $c.text(cell.what);
95 });
96 });
97 }
98
99 $(document).on('click', '.cell', function(e){
100 var id = $(this).data('id'), ref = gun.get(id);
101 var what = prompt("What should be in this cell?");
102 ref.get('what').put(what);
103 });
104
105 $('#radd').on('click', function(){
106 if(!user.is){ return alert("login first") }
107 choose.table.get('rows').set();
108
109 var cell = user.get('cells').set({what: "Edit me!", sort: 1});
110 var row = user.get('rows').set({sort: 1});
111 row.get('cells').set(cell);
112 choose.table.get('rows').set(row);
113 });
114
115 $('#cadd').on('click', function(){
116 if(!user.is){ return alert("login first") }
117 choose.table.get('rows').map().once(function(){
118 var cell = user.get('cells').set({what: "Edit me!", sort: 1});
119 this.get('cells').set(cell);
120 });
121 });
122
123 function grab(id, $model, $to){
124 var did = btoa(id).replace(/[\+\-\=\.]/ig,'');
125 return $('#' + did).get(0) || $($model).clone(true, true).attr('id', did).appendTo($to).data('id', id);
126 };
127
128 function list(table, id, $model, $to){
129 var li = grab(id, '.model .item', 'ul');
130 $(li).text(table.name).data('$', this);
131 };
132 </script>
...\ No newline at end of file ...\ No newline at end of file
1 <!DOCTYPE html>
2
3 <h1>User</h1>
4
5 <form id="sign">
6 <input id="alias" placeholder="username">
7 <input id="pass" type="password" placeholder="passphrase">
8 <input id="in" type="submit" value="sign in">
9 <input id="up" type="button" value="sign up">
10 <input id="mask" type="button" value="Identifi Login">
11 </form>
12
13 <ul></ul>
14
15 <form id="said">
16 <input id="say">
17 <input id="speak" type="submit" value="speak">
18 </form>
19
20 <script src="../jquery.js"></script>
21 <script src="../../../gun/gun.js"></script>
22 <script src="../../../gun/sea.js"></script>
23
24 <script>
25 //var gun = Gun('http://localhost:8765/gun');
26 var gun = Gun(); //Gun(['http://localhost:8765/gun', 'https://guntest.herokuapp.com/gun']);
27 var user = gun.user().recall({sessionStorage: true});
28
29 $('#up').on('click', function(e){
30 user.create($('#alias').val(), $('#pass').val(), login);
31 });
32 function login(e){
33 user.auth($('#alias').val(), $('#pass').val());
34 return false; // e.preventDefault();
35 };
36 $('#sign').on('submit', login);
37 $('#mask').on('click', login);
38
39 gun.on('auth', function(){
40 $('#sign').hide();
41 user.get('said').map().on(UI);
42 });
43
44 $('#said').on('submit', function(e){
45 e.preventDefault();
46 //if(!user.is){ return }
47 user.get('said').set($('#say').val());
48 $('#say').val("");
49 });
50
51 function UI(say, id){
52 var li = $('#' + id).get(0) || $('<li>').attr('id', id).appendTo('ul');
53 $(li).text(say);
54 };
55 </script>
...\ No newline at end of file ...\ No newline at end of file
1 <!DOCTYPE html>
2 <html>
3
4 <head>
5 <title>Converse</title>
6 <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=0">
7 <link rel="stylesheet" type="text/css" href="/style.css">
8 <link href='https://fonts.googleapis.com/css?family=Poiret+One' rel='stylesheet' type='text/css'>
9 <style>
10 .chat__heading {
11 position: fixed;
12 text-align: center;
13 z-index: 1;
14 width: 100%;
15 margin-top: 0;
16 margin-bottom: 0;
17 }
18
19 .chat__form-container {
20 display: flex;
21 justify-content: center;
22 width: 100%;
23 padding: 10px 20px;
24 position: fixed;
25 z-index: 1;
26 bottom: 0;
27 }
28
29 .chat__form {
30 display: flex;
31 justify-content: center;
32 height: 50px;
33 background-color: white;
34 border: 2px solid white;
35 max-width: 900px;
36 width: 100%;
37 border-radius: 5px;
38 }
39
40 .chat__name-input {
41 flex: 1;
42 padding: 10px;
43 }
44
45 .chat__message-input {
46 flex: 5;
47 padding: 10px;
48 }
49
50 .chat__submit {
51 padding: 10px;
52 color: white;
53 border-radius: 5px;
54 }
55
56 .chat__submit:hover::after {
57 background-color: rgba(0,0,0,0.2);
58 }
59
60 .chat__submit:focus::after {
61 background-color: rgba(0,0,0,0.2);
62 }
63
64 .chat__submit::after {
65 content: '';
66 position: absolute;
67 width: 100%;
68 height: 100%;
69 left: 0;
70 top: 0;
71 border-radius: 5px;
72 transition: background-color 0.3s;
73 background-color: rgba(0,0,0,0);
74 }
75
76 .chat__message-list {
77 display: flex;
78 flex-direction: column;
79 align-items: center;
80 flex: 1;
81 overflow-y: auto;
82 padding: 60px 20px;
83 width: 100%;
84 background-color: rgba(0, 0, 0, 0.2);
85 min-height: 100vh;
86 }
87
88 .chat__message {
89 display: flex;
90 flex-wrap: wrap;
91 margin-bottom: 10px;
92 padding: 10px;
93 border-radius: 5px;
94 width: 100%;
95 position: relative;
96 max-width: 900px;
97 }
98
99 .chat__name {
100 margin-right: 20px;
101 }
102
103 .chat__when {
104 position: absolute;
105 top: 0;
106 right: 2em;
107 padding: 10px;
108 background: rgba(100%, 100%, 100%, 0.9);
109 opacity: 0;
110 border-radius: 5px;
111 }
112
113 .chat__message:hover .chat__when {
114 opacity: 1;
115 right: 0em;
116 }
117
118 @media (max-width: 567px) {
119 .chat__heading {
120 font-size: 30px;
121 }
122 }
123 </style>
124 </head>
125
126 <body>
127 <div class="chat hue2 page">
128 <h2 id='title' class="chat__heading hue2 whitet">Have a Conversation...</h2>
129 <ul class="chat__message-list">
130 <li class="none"></li>
131 </ul>
132
133 <div class="chat__form-container hue2">
134 <form class="chat__form">
135 <label for="name-input" class="visually-hidden">Name</label>
136 <input id="name-input" class="chat__name-input" placeholder="Name"></input>
137 <label for="message-input" class="visually-hidden">Message</label>
138 <input id="message-input" class="chat__message-input" placeholder="Write a message..."></input>
139 <button class="chat__submit say hue2">say</button>
140 </form>
141 </div>
142
143 <div class="model">
144 <li class="chat__message white huet2 box">
145 <b class="chat__name"></b>
146 <p class="chat__message-text"></p>
147 <span class="sort none">0</span>
148 <div class="chat__when"></div>
149 </li>
150 </div>
151 </div>
152
153 <script src="/jquery.js"></script>
154 <script src="/gun.js"></script>
155 <script src="/gun/nts.js"></script>
156 <script>
157 var gun = Gun(location.origin + '/gun');
158 var chat = gun.get('converse/' + location.hash.slice(1));
159
160 $(".chat__submit").on('click', submit);
161 $(".chat_form").on('keydown', enter);
162 function enter(e) {
163 if (e.which !== 13) { return }
164 submit(e);
165 }
166 function submit(e) {
167 e.preventDefault();
168
169 var msg = { when: Gun.time.is() };
170
171 msg.who = $('.chat__name-input').val();
172 if (!msg.who) {
173 msg.who = 'user' + Gun.text.random(3);
174 $('.chat__name-input').val(msg.who);
175 }
176
177 msg.what = $('.chat__message-input').val();
178 if (!msg.what) { return }
179
180 chat.set(msg);
181 $('.chat__message-input').val('').focus();
182 }
183
184 chat.map().val(function (msg, id) {
185 if (!msg) { return }
186 var messageList = $('.chat__message-list');
187 var last = sort(msg.when, messageList.children('li').last());
188
189 var li = $("#msg-" + id)[0]; // grab if exists
190 if (!li) {
191 li = $('.model li').clone(true) // else create it
192 .attr('id', 'msg-' + id)
193 .insertAfter(last);
194 }
195
196 // bind the message data into the UI
197 li = $(li);
198 li.find('.chat__name').text(msg.who);
199 li.find('.chat__message-text').text(msg.what);
200 li.find('.sort').text(msg.when);
201
202 var time = new Date(msg.when);
203 li.find('.chat__when').text(time.toDateString() + ', ' + time.toLocaleTimeString());
204
205 $('html, body').stop(true, true)
206 .animate({ scrollTop: messageList.height() });
207 });
208
209 function sort(num, li) { return parseFloat(num) >= parseFloat($(li).find('.sort').text() || -Infinity) ? li : sort(num, li.prev()) }
210 </script>
211 </body>
212
213 </html>
1 <script src="/gun.js"></script>
2 <!--
3 <script src="/gun/lib/cryptomodules.js" type="text/javascript"></script>
4 <script src="/gun/sea.js"></script>
5 -->
6 <script>
7 var gun = Gun(location.origin+'/gun');
8 var user = gun.user && gun.user();
9 if(user){
10 // 1st: call create. 2nd call auth. After that, call recall
11 // user.create('dude', 'my secret').then(function(ack) { console.log('created ack:', ack) });
12 // user.recall().then(function(ack){
13 // if (!ack || !ack.sea){
14 // console.log('user.recall not bootstrapping...');
15 // user.auth('dude', 'my secret', {pin: 'PIN'}).then(function(user) { console.log('authenticated user:', user) });
16 // // user.auth('dude', 'my secret', {pin: 'PIN', newpass: 'my new secret'}).then(function(user) { console.log('authenticated user:', user) });
17 // } else {
18 // console.log('user.recall authenticated user:', ack.alias);
19 // }
20 // });
21 }
22 </script>
...\ No newline at end of file ...\ No newline at end of file
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta name="viewport" content="width=device-width, initial-scale=1">
5 <link rel="stylesheet" type="text/css" href="../style.css">
6 </head>
7 <body>
8 <div id="sign" class="hue page">
9 <style>
10 input, button {
11 margin: 1em 0;
12 padding: 1em;
13 }
14 .or {
15 display: inline-block;
16 width: 15%;
17 }
18 </style>
19 <form id="inup" class="sign pad center">
20 <div class="loud">Welcome,</div>
21 <div class="mid row col">
22 <input name="alias" class="huet jot sap" placeholder="alias">
23 Enter your public username.
24 </div>
25 <div class="mid row col">
26 <input name="pass" class="huet jot sap" type="password" placeholder="passphrase">
27 And a long private passphrase.
28 </div>
29 <div class="mid row col go">
30 <button class="huet sap act symbol">sign in</button>
31 <div class="or">or</div>
32 <button class="huet sap act symbol">sign up</button>
33 </div>
34 <a href="info">more info</a>
35 </form>
36 </div id="sign">
37
38 <div id="people" class="hue2 page">
39 <ul name="users" class="pad">
40 <h3>Here is a list of people:</h3>
41 <li name="#">
42 <!-- <h3 name="."></h3> -->
43 <ul>
44 <a href="person" name="#" class="whitet act">
45 <li>
46 <span name="who">
47 <b name="name"></b>
48 </span>
49 <i>~</i><i name="alias" class="sort"></i>
50 <input name="pub">
51 </li>
52 </a>
53 </ul>
54 </li>
55 </ul>
56 </div id="people">
57
58 <div id="converse" class="page">
59 <ul>
60 </ul>
61 <div class="model">
62 <li class="msg">
63 <span name="fro">Alias</span>: <span name="what"></span>
64 </li>
65 </div>
66 <form>
67 <input placeholder="to" name="to">
68 <textarea name="what"></textarea>
69 <input type="submit" value="submit">
70 <div class="status"></div>
71 </form>
72 </div id="converse">
73
74 <div id="person" class="hue3 page">
75 <style>
76 #person .back {
77 position: absolute;
78 top: 0.3em;
79 left: 0.5em;
80 width: 2em;
81 height: 2em;
82 z-index: 99999;
83 }
84 </style>
85 <a href="people" class="whitet act back">&#8592</a>
86 <div class="pad">
87 <div name="who">
88 <!-- img src="" -->
89 <h2 name="name" contenteditable="true">Name</h2>
90 <i name="born"></i>
91 <span name="bio" contenteditable="true">bio</span>
92 <form id="say" class="center none">
93 <input class="jot" placeholder="Say something!" style="width: 80%;">
94 <input type="submit" id="speak" class="huet2 sap act symbol" style="min-width: 5em; width: 10%;" value="speak">
95 </form>
96 <div>
97 <ul name="said">
98 <li name="#" class="sit sort shade rim"><div name="what" class="rim"></div></li>
99 </ul>
100 </div>
101 </div>
102 <input name="pub">
103 </div>
104 </div id="person">
105
106 <div id="info" class="page">
107 <p>A mysterious new example app has appeared! It is not finished/ready yet.</p>
108 </div id="info">
109
110 <div id="tell" class="center">
111 <style>
112 #tell {
113 position: fixed;
114 top: 0;
115 left: 0;
116 right: 0;
117 height: 0;
118 overflow: visible;
119 }
120 #tell p {
121 top: -2em;
122 width: 50%;
123 border: solid #222 0.2em;
124 border-top: none;
125 padding: 1%;
126 opacity: 0;
127 visibility: hidden;
128 transition: visibility 2s, all 1s ease-in;
129 }
130 #tell .notify {
131 top: 0em;
132 opacity: 0.8;
133 visibility: visible;
134 transition: visibility 0s, all 0.25s ease-out;
135 }
136 </style>
137 <p class="mid black">Hello world!</p>
138 </div>
139
140 <!-- script src="/Users/mark/Dropbox/Public/gun/db/examples/jquery.js"></script>
141 <script src="/Users/mark/Dropbox/Public/gun/db/gun.js"></script>
142 <script src="/Users/mark/Dropbox/Public/gun/db/lib/cryptomodules.js"></script>
143 <script src="/Users/mark/Dropbox/Public/gun/db/sea.js"></script>
144 <script src="/Users/mark/Dropbox/Public/gun/db/as.js"></script -->
145
146 <script src="/jquery.js"></script>
147 <script src="/gun.js"></script>
148 <script src="/gun/sea.js"></script>
149 <script src="/gun/as.js"></script>
150 <script src="/gun/nts.js"></script>
151 <script>
152 // Check out the interactive tutorial
153 // for how to build a simplified version
154 // of this example: https://scrimba.com/c/c2gBgt4
155 var gun = Gun(location.origin+'/gun');
156 var app = gun.get('example/contacts/7');
157 var user = gun.user();
158 var c = window.c = {};
159 (function(){
160 c.hash = location.hash.slice(1);
161 gun.on('auth', function(at){
162 if('sign' === c.hash){ c.hash = '' }
163 as.route(c.hash || 'people');
164 });
165 gun.on('secure', function(at){
166 /* enforce some rules about shared app level data */
167 if(!at.put || !at.put.users){ return }
168 var no;
169 Gun.node.is(at.put.users, function(val, key){
170 Gun.SEA.verify(val, false, function(val){
171 //Gun.SEA.read(val, false, function(val){
172 if('~@'+key === Gun.val.link.is(val)){ return }
173 no = true;
174 })
175 if(no){ return no }
176 });
177 if(no){ return }
178 this.to.next(at);
179 });
180 $(document).on('keyup', "form.sign input:first", as.wait(function(){
181 /*
182 var form = $(this).closest('form'), data = {alias: $(this).val()};
183 if(!data.alias || data.alias.length < 5){
184 return;
185 }
186 var exist = gun.path('alias').path(data.alias);
187 exist.get(function(at){
188 form.find('.or').addClass('none');
189 form.find('button:first').toggleClass('none', at.put? false : true);
190 form.find('button:last').toggleClass('none', at.put? true : false);
191 });
192 */
193 })).on('click','form.sign button:last', function(){
194 var but = $(this), form = $(this).closest('form'), data = {alias: form.find('input:first').val(), pass: form.find('input:last').val()};
195 data.born = Gun.time.is();
196 if(!data.alias || data.alias.length < 5){
197 c.tell("Alias needs to be longer than 5 characters.");
198 return;
199 }
200 if(!data.pass || data.pass.length < 9){
201 c.tell("Passphrase needs to be longer than 9 characters.");
202 return;
203 }
204 but.addClass('pulse');
205 data.alias = data.alias.toLowerCase();
206 user.create(data.alias, data.pass, function(ack){
207 if(!ack.wait){ but.removeClass('pulse') }
208 if(ack.err){ c.tell(ack.err); return }
209 if(ack.pub){
210 gun.get('users').get(data.alias).put(gun.get('~@'+data.alias));
211 }
212 session(data);
213 user.auth(data.alias, data.pass);
214 });
215 }).on('click','form.sign button:first', become);
216 function become(){
217 var form = $('#sign').find('form'), data = {alias: form.find('input:first').val(), pass: form.find('input:last').val()};
218 data.alias = data.alias || sessionStorage.alias;
219 data.pass = data.pass || sessionStorage.tmp;
220 if(!data.alias || data.alias.length < 5){
221 c.tell("Alias needs to be longer than 5 characters.");
222 return;
223 }
224 if(!data.pass || data.pass.length < 9){
225 c.tell("Passphrase needs to be longer than 9 characters.");
226 return;
227 }
228 var but = form.find('button:first');
229 but.addClass('pulse');
230 data.alias = data.alias.toLowerCase();
231 user.auth(data.alias, data.pass, function(ack){
232 if(!ack.wait){ but.removeClass('pulse') }
233 if(ack.err){ c.tell(ack.err); return }
234 session(data);
235 });
236 }
237 if(!location.hash){
238 as.route('sign');
239 }
240 if(!window.sessionStorage){ window.sessionStorage = {clear:function(){}} }
241 if(sessionStorage.tmp){
242 become();
243 }
244 function session(data){
245 if(!sessionStorage){ return }
246 sessionStorage.alias = data.alias;
247 sessionStorage.tmp = data.pass;
248 }
249 c.tell = function(what, n){
250 var e = $('#tell').find('p');
251 e.addClass('notify').text(what);
252 clearTimeout(c.tell.to);
253 c.tell.to = setTimeout(function(){e.removeClass('notify')}, n || 2500);
254 }
255 }());
256 (function(){
257 $(document).on('submit', '#say', function(e){
258 e.preventDefault();
259 user.get('who').get('said').set({
260 what: $(this).find('.jot').val()
261 });
262 $(this).find('.jot').val('');
263 });
264 }());
265 as.route.page('sign', function(){
266 $(document.forms.inup.alias).focus();
267 });
268 as.route.page('people', function(){
269 if(!user.is){ return as.route('sign') }
270 as('#people', gun, function(data, key, el){
271 if('pub' !== key){ return }
272 el.closest('a').attr('href', '#person/' + data);
273 });
274 });
275 as.route.page('person', function(){
276 if(!user.is){ return as.route('sign') }
277 var pub = location.hash.split('/').slice(-1)[0];
278 (pub === user._.pub? $('#say').show() : $('#say').hide());
279 as('#person', window.PUB = gun.get('~'+pub));
280 });
281
282
283
284
285
286
287
288 (function(converse){
289 as.route.page('converse', function(){
290 if(!c.me){ return as.route('sign') }
291 converse.lock = false;
292 var alias = location.hash.split('/').slice(-1);
293 $('#converse form').find('input:first').val(alias);
294 function inbox(msg, id){
295 if(!sign.verify(msg.pub, msg.what, msg.sig)){ return }
296 msg.fro = (msg.to === c.me.alias? alias : c.me.alias);
297 as.route.render(id, '.msg', $('#converse ul'), msg);
298 }
299 sign.is(alias, function(acc){
300 sign.is(c.me.alias).path('msgs').path(acc.pub).map(inbox);
301 }).path('msgs').path(c.me.pub).map(inbox);
302 });
303 $(document).on('submit', '#converse form', function(e){
304 e.preventDefault();
305 if(converse.lock){ return console.log('message sending already') }
306 converse.lock = true; // prevent duplicate sends.
307 var form = $(this), msg = {};
308 msg.to = form.find('input:first').val();
309 msg.what = form.find('textarea').val();
310 sign.is(msg.to, function(to){
311 if(!priv){
312 form.find('.status').text("Failed to send. Please sign in again.");
313 converse.lock = false;
314 return;
315 }
316 msg.sig = sign.sig(msg.what, priv);
317 msg.pub = c.me.pub;
318 msg.when = Gun.time.is();
319 console.log("sending msg", msg);
320 sign.is(c.me.alias).path('msgs').path(to.pub).set(gun.put(msg));
321 converse.lock = false;
322 }, function(){
323 form.attr('disabled', false).find('.status').text(msg.to + " cannot be found! Alias is case sensitive.");
324 converse.lock = false;
325 });
326 });
327 }({}));
328 //}());</script>
329 </body>
330 </html>
...\ No newline at end of file ...\ No newline at end of file
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <!-- always start with these two lines to set a clean baseline for different devices -->
5 <meta name="viewport" content="width=device-width, initial-scale=1">
6 <link rel="stylesheet" type="text/css" href="style.css">
7 <script src="jquery.js"></script>
8
9 <title>Docs</title>
10 </head>
11 <body class="black whitet">
12 <style>
13 /*
14 Choose white text on a black background so you can add color in.
15 Pick your favorite font and choose a font size.
16 */
17 @import url('https://fonts.googleapis.com/css?family=Oxygen');
18 html, body {
19 font-family: "Oxygen", sans-serif;
20 }
21
22 [contenteditable]:focus {
23 outline: none;
24 }
25 </style>
26
27 <div class="hold full hue2">
28 <div id="page" class="max focus gap" style="padding-top: 9%;"></div>
29 </div>
30 <script src="../../gun/gun.js"></script>
31 <script src="../../gun/lib/monotype.js"></script>
32 <script src="../../gun/lib/meta.js"></script>
33 <script src="../../gun/lib/normalize.js"></script>
34 <script async src="../../gun/lib/fun.js"></script>
35
36 <script async src="../../gun/lib/wave.js"></script>
37 <!-- script async src="https://edide.io/music.lib"></script -->
38
39 <script>
40 var gun = Gun(['https://guntest.herokuapp.com/gun', 'http://localhost:8765/gun']);
41
42 ;(window.onhashchange = function(){
43 var file = (location.hash||'').slice(1);
44 var S = +new Date;
45 $('#page').empty().attr('contenteditable', 'false');
46 gun.get('test/gun/docs/'+file).get('what').map().on(function render(data, i){
47 if(window.LOCK){ return }
48 var p = $('#page').children().get(i);
49 if(!p){
50 $('#page').append('<p>');
51 setTimeout(function(){ render(data, i) },0);
52 return;
53 }
54 var r = monotype(p);
55 var safe = $.normalize(data);
56 p.outerHTML = safe;
57 r.restore();
58 });
59 })();
60
61 document.execCommand('defaultParagraphSeparator', false, 'p');
62 meta.edit({
63 name: "Edit",
64 combo: ['E'],
65 use: function(eve){
66 console.log('on');
67 }, on: function(eve){
68 if($(eve.target).closest('p').length){ return }
69 var edit = this;
70 setTimeout(function(){ meta.flip(false) },1);
71 edit.init();
72 $(document).on('keydown.tmp', '[contenteditable]', function(eve){
73 if(eve.which != 13){ return }
74 eve.preventDefault();
75 var r = window.getSelection().getRangeAt(0);
76 var c = r.commonAncestorContainer, p;
77 r.deleteContents();
78 var p = c.splitText? $(c.splitText(r.startOffset)).parent() : $(c);
79 var n = $("<"+p.get(0).tagName+">"), f;
80 p.contents().each(function(){
81 if(this === c){ return f = true }
82 if(!f){ return }
83 n.append(this);
84 });
85 p.after(n);
86 edit.select(n.get(0));
87 // make sure we re-save & sync each changed paragraph.
88 edit.save(p);
89 p.nextAll().each(function(){
90 edit.save(this);
91 });
92 }).on('keyup.tmp', '[contenteditable]', function(eve){
93 //$('#debug').val(doc.html());
94 var p = $(window.getSelection().anchorNode).closest('p');
95 var r = monotype(p);
96 var html = p.html() || '';
97 if(!html && !p.prev().length && !p.next().length && !$('#page').html()){
98 edit.init();
99 }
100 var safe = $.normalize(html);
101 p.html(safe);
102 r.restore();
103 edit.save(p);
104 });
105 },
106 up: function(){
107 console.log("UP");
108 $('[contenteditable=true]').off('.tmp');
109 },
110 init: function(){
111 var edit = this;
112 var doc = $('#page').attr('contenteditable', 'true');
113 if(!doc.text()){
114 doc.html('<p class="loud crack"></p>');
115 }
116 edit.select(doc.children().first().get(0));
117 },
118 save: function(p){
119 p = $(p);
120 var i = p.index();// = Array.prototype.indexOf.call(parent.children, child);
121 var file = (location.hash||'').slice(1);
122 var data = (p.get(0)||{}).outerHTML||'';
123 window.LOCK = true;
124 gun.get('test/gun/docs/'+file).get('what').get(i).put(data);
125 window.LOCK = false;
126 },
127 select: function(p){
128 var s = window.getSelection(),
129 r = document.createRange();
130 if(p.innerHTML){
131 r.setStart(p, 0);
132 r.collapse(true);
133 s.removeAllRanges();
134 s.addRange(r);
135 return;
136 }
137 p.innerHTML = '\u00a0';
138 r.selectNodeContents(p);
139 s.removeAllRanges();
140 s.addRange(r);
141 document.execCommand('delete', false, null);
142 }
143 });
144
145 ;(function(){
146
147 meta.edit({name: "Layout", combo: ['L']});
148
149 meta.edit({name: "Fill", combo: ['L','F'],
150 use: function(eve){},
151 on: function(eve){
152 var on = meta.tap();
153 meta.ask('Color name, code, or URL?', function(color){
154 on.css('background', color);
155 });
156 },
157 up: function(eve){}
158 });
159
160 meta.edit({name: "Add", combo: ['L','A']});
161 meta.edit({name: "Row", combo: ['L','A', 'R'],
162 on: function(eve){
163 meta.tap().append('<div style="min-height: 9em; padding: 2%;">');
164 }
165 });
166 meta.edit({name: "Columns", combo: ['L','A','C'],
167 on: function(eve){
168 var on = meta.tap().addClass('center'), tmp, c;
169 var html = '<div class="unit col" style="min-height: 9em; padding: 2%;"></div>';
170 if(!on.children('.col').length){ html += html }
171 c = (tmp = on.append(html).children('.col')).length;
172 tmp.each(function(){
173 $(this).css('width', (100/c)+'%');
174 })
175 }
176 });
177 meta.edit({name: "Text", combo: ['L','A','T'],
178 on: function(eve){
179 var tag = $('<p>text</p>');
180 meta.tap().append(tag);
181 tag.focus();
182 }
183 });
184
185 }());
186
187 ;(function(){
188 var song = {};
189 // TODO:
190 // 1. Manually OR automatically load music.js API, dependencies, and modules. - FINE for now
191 // 2. only export music API, not meta, not dom, not mouselock system, not UI/html, etc. better module isolation and export.
192 // 3. `var wave = Wave('a').play()` // also on `Music.now`
193 // defaults... instrument: pure tones, volume curve: |\_ , speed curve: 0.5
194 // 4. `wave.blur(0.5).itch(0.5);`
195 // 5. wave.long(2); // how long in seconds each note plays, optionally: wave.pace(60) is bpm
196 // 6. wave.loud(0.5); // 0% to 100% volume loudness of device output.
197 // 7. wave.vary(0.5); // slows down or speeds up wiggle per harmonic
198 // 8:
199 // wave structure, does ToneJS allow us to change the sine wave smoothness/type continuously or is it a pre-fixed type?
200 // wave structure: /\/\/, |_|, /|/, \|\| do some research with ToneJS whether these are dynamic or fixed
201 // wave.itch(); // changes the shape of the wiggle from smooth sine to square or triangle
202 // wave.blur(220hz); // blur may not apply/work on pure notes other than filtering them.
203
204 meta.edit({name: "Music", combo: ['M']});
205
206 meta.edit({name: "Play", combo: ['M','P'],
207 on: function(eve){
208 // TODO: We still need to add to meta API ability to change name.
209 if(song.play){
210 music.stop();
211 song.play = false;
212 return;
213 }
214 song.play = true;
215 music.stop();
216 setTimeout(function(){
217 song.now = wave($('#page').text()).play();
218 },250);
219 }
220 });
221
222 meta.edit({name: "Blur", combo: ['M','B'],
223 on: function(eve){
224 $(document).on('mousemove.tmp', function(eve){
225 var x = eve.pageX;
226 song.now.loud(x/$('body').innerWidth());
227 });
228 },
229 up: function(){
230 $(document).off('.tmp');
231 }
232 });
233
234 $(document).on('keydown', function(eve){
235 music.play(String.fromCharCode(eve.which));
236 });
237
238 }());
239 </script>
240 </body>
241 </html>
...\ No newline at end of file ...\ No newline at end of file
1 console.log("If module not found, install express globally `npm i express -g`!");
2 var port = process.env.OPENSHIFT_NODEJS_PORT || process.env.VCAP_APP_PORT || process.env.PORT || process.argv[2] || 8765;
3 var express = require('express');
4 var Gun = require('..');
5 require('../axe');
6
7 var app = express();
8 app.use(Gun.serve);
9 app.use(express.static(__dirname));
10
11 var server = app.listen(port);
12 var gun = Gun({ file: 'data', web: server });
13
14 global.Gun = Gun; /// make global to `node --inspect` - debug only
15 global.gun = gun; /// make global to `node --inspect` - debug only
16
17 console.log('Server started on port ' + port + ' with /gun');
1 <html>
2 <head>
3 <meta name="viewport" content="width=device-width, initial-scale=1.0">
4 </head>
5 <body style="text-align: center;">
6 <h1 id="when" style="font-size: 7vw; margin-top: 43vh; font-family: monospace;"></h1>
7 </body>
8 <script src="/gun.js"></script>
9 <script src="/gun/nts.js"></script>
10 <script>
11 window.gun = Gun(location.origin+'/gun');
12 requestAnimationFrame(function now(){
13 requestAnimationFrame(now);
14 var time = new Date(Gun.state());
15 var print = time.toLocaleString() +' '+ (time.getMilliseconds()/1000).toFixed(3).slice(1);
16 when.innerHTML = print;
17 });
18 </script>
19 </html>
1 <html>
2 <head>
3 <meta name="viewport" content="width=device-width, initial-scale=1.0">
4 </head>
5 <div id="area">
6 <div id="me" class="ship">
7 <div class="laser"></div>
8 </div>
9 </div>
10 <p id="debug" style="position: fixed; bottom: 0px; color: white; height: 1em;"></p>
11 <script src="../jquery.js"></script>
12 <script src="../../../gun/gun.js"></script>
13 <script src="../../../gun/nts.js"></script>
14 <script src="../../../gun/lib/webrtc.js"></script>
15 <script>
16 // Thanks to https://github.com/dmcinnes/HTML5-Asteroids
17 //var gun = Gun();
18 var gun = Gun(location.host? location.origin+'/gun' : 'http://localhost:8765/gun');
19 var game = {gun: gun.get('example/game/space'), area: {}, ships: {}};
20 game.keys = {38: 'up', 37: 'left', 39: 'right', 40: 'down', 32: 'space'};
21 $(document).on('keydown', function(e){
22 //e.preventDefault();
23 var key = e.keyCode, me;
24 game.keys[key = game.keys[key]] = true;
25 if(!(me = game.me)){ return }
26 me.last = game.now;
27 if('space' === key){ game.shoot(game.me) }
28 });
29 $(document).on('keyup', function(e){
30 //e.preventDefault();
31 game.sync();
32 game.keys[game.keys[e.keyCode]] = false;
33 });
34 game.shoot = function(ship, when){
35 if(!ship || ship.l){ return }
36 if(!when && ship.gun && ship.data){
37 ship.data.l = game.now;
38 game.sync(true);
39 return;
40 }
41 if(when + 250 < game.now){ return }
42 ship.l = true;
43 ship.$.children('.laser').show();
44 setTimeout(function(){
45 ship.$.children('.laser').hide();
46 setTimeout(function(){
47 ship.l = false;
48 }, 250);
49 }, 250 - (game.now - when));
50 }
51 game.ship = function(d, el){
52 if(!d){ // spawn our ship
53 var id = Gun.text.random(1, 'abcdefghijklmno');
54 game.me = game.ships[id] = {data: d = {id: id, t: game.now}};
55 game.me.gun = game.gun.get('players').get(d.id).put(d);
56 return;
57 }
58 if(!d.id){ return }
59 if(!game.ships[d.id]){
60 game.ships[d.id] = {};
61 }
62 var s = game.ships[d.id];
63 s.t = d.t || (d.t = 0);
64 s.x = d.x || (d.x = game.area.x * Math.random());
65 s.y = d.y || (d.y = game.area.y * Math.random());
66 s.r = d.r || (d.r = 0);
67 s.vx = d.vx || (d.vx = 0);
68 s.vy = d.vy || (d.vy = 0);
69 s.vr = d.vr || (d.vr = 0);
70 s.ax = s.ax || 0;
71 s.ay = s.ay || 0;
72 s.ar = s.ar || 0;
73 s.data = d;
74 s.$ = s.$ || (s.gun? ($('#me'))
75 : $('#me').clone(true).attr('id', d.id).appendTo('#area'));
76 if(!s.l){
77 game.shoot(s, d.l);
78 }
79 s.frame = s.frame || function(t, now){
80 if(s.gun){
81 s.fly(t, now);
82 }
83 if(s.calc(t, now)){ return }
84 s.draw();
85 }
86 var keys = game.keys;
87 var area = game.area;
88 s.fly = s.fly || function(t, now){
89 if(keys.left){
90 s.r += -6;
91 } else
92 if(keys.right) {
93 s.r += 6;
94 }
95 if(keys.up){
96 var rad = ((s.r - 90) * Math.PI)/180;
97 s.ax = 0.0001 * Math.cos(rad);
98 s.ay = 0.0001 * Math.sin(rad);
99 } else {
100 s.ax = 0;
101 s.ay = 0;
102 }
103
104 Gun.obj.map(game.ships, function(ship){
105 if(ship.gun){ return }
106 if(!ship.l){ return }
107 if(ship.x-50 <= s.x && s.x <= ship.x+50
108 && ship.y-50 <= s.y && s.y <= ship.y+50){
109 s.data.t = -1;
110 game.sync(true);
111 s.boom = true;
112 }
113 });
114
115 s.vx += s.ax * t;
116 s.x += s.vx * t;
117 s.vy += s.ay * t;
118 s.y += s.vy * t;
119 var data = s.data;
120 if(!data){ return }
121 data.r = s.r;
122 data.vx = s.vx;
123 data.x = s.x;
124 data.vy = s.vy;
125 data.y = s.y;
126 if(data.t < 0){ return }
127 data.t = now;
128 s.t = data.t;
129 }
130 s.calc = s.calc || function(t, now){
131 var d = s.data;
132 var dt = (now - d.t) || 0;
133 if(dt > 30 * 1000){
134 Gun.obj.del(game.ships, d.id);
135 s.$.remove();
136 return true;
137 }
138 if(!d){ return }
139 var speed = Math.sqrt(d.vx * d.vx + d.vy * d.vy);
140 if(speed > 0.15){
141 s.vy = d.vy = d.vy / speed * 0.15;
142 s.vx = d.vx = d.vx / speed * 0.15;
143 }
144 s.x = d.x + d.vx * dt;
145 s.y = d.y + d.vy * dt;
146
147 s.x = s.x % area.x;
148 if(s.x < 0){
149 s.x += area.x;
150 }
151 s.y = s.y % area.y;
152 if(s.y < 0){
153 s.y += area.y;
154 }
155 }
156 s.draw = s.draw || function(){
157 s.css = 'rotate('+s.r+'deg)';
158 s.$.css({left: s.x, top: s.y, transform: s.css});
159 }
160 return s;
161 }
162 localStorage.clear();
163 game.sync = function(shoot){
164 var me = game.me;
165 if(!me || me.boom){ return }
166 var keys = game.keys;
167 if(shoot || keys.up || keys.right || keys.left || keys.down){
168 var data = Gun.obj.to(me.data);
169 data.x = data.x / game.area.x;
170 data.y = data.y / game.area.y;
171 me.gun.put(data);
172 }
173 }
174 game.frame = window.requestAnimationFrame || setTimeout;
175 game.resize = function(){
176 game.area.x = $('#area').innerWidth();
177 game.area.y = $('#area').innerHeight();
178 }
179 $(window).on('resize', game.resize);
180 game.start = function(){
181 game.now = Gun.state();
182 game.resize();
183 game.ship();
184 game.gun.get('players').map().on(function(data, id){
185 data = Gun.obj.copy(data);
186 data.x = data.x * game.area.x;
187 data.y = data.y * game.area.y;
188 data.id = data.id || id;
189 game.ship(data);
190 });
191 var frame = game.frame, ships = game.ships;
192 var last = game.now, now, diff, delta;
193 setInterval(game.sync, 99);
194 frame(function next(t){
195 frame(next, 1000/60);
196 now = game.now = Gun.state();
197 diff = now - last;
198 last = now;
199 Gun.obj.map(ships, function(ship){
200 if(!ship.frame){ return }
201 ship.frame(diff, now);
202 });
203 }, 1000/60);
204 }
205 $(function(){
206 game.start();
207 });
208
209 // test WebRTC
210 gun.on('hi', function(peer){
211 console.log("hi!", peer);
212 if(peer.url){ return }
213 Gun.obj.map(gun.back('opt.peers'), function(peer){
214 if(!peer.url || !peer.wire){ return }
215 peer.wire._send = peer.wire.send;
216 peer.wire.send = send;
217 var tmp = 'GOBBLE GOBBLE: Not sending any non-WebRTC messages to ' + peer.url;
218 console.log(tmp);
219 $('#debug').text(tmp);
220 });
221 });
222 function send(raw){
223 if(!raw){ return }
224 if(raw.indexOf('rtc') >= 0){
225 if(!this._send){ return }
226 return this._send(raw);
227 }
228 }
229 </script>
230 <style>
231 html, body {
232 margin: 0;
233 padding: 0;
234 background: #111;
235 }
236 html, body, div {
237 position: relative;
238 }
239 #area {
240 width: 95%;
241 width: 1024px;
242 height: 768px;
243 margin: 0 auto;
244 background: black;
245 overflow: hidden;
246 }
247 .ship {
248 position: absolute;
249 width: 0px;
250 height: 0px;
251 border-left: 5px solid transparent;
252 border-right: 5px solid transparent;
253 border-bottom: 15px solid red;
254 transform-origin: 50% 50%;
255 color: white;
256 }
257 #me {
258 border-bottom: 15px solid limegreen;
259 }
260 .boom {
261 border: 1vmax dotted yellow;
262 border-bottom: 1vmax dotted yellow;
263 height: 5vmax;
264 width: 1vmax;
265 }
266 .laser {
267 display: none;
268 position: relative;
269 background: transparent;
270 border: 2px dotted yellow;
271 height: 100px;
272 width: 100px;
273 top: -50px;
274 left: -50px;
275 }
276 </style>
277 </html>
...\ No newline at end of file ...\ No newline at end of file
1 console.log("If module not found, install hapi globally `npm i hapi inert -g`!")
2
3 const Hapi = require('hapi')
4 const Inert = require('inert')
5 const Gun = require('..')
6
7 const server = new Hapi.Server({
8 port: 8765,
9 host: 'localhost',
10 routes: {
11 files: {
12 relativeTo: require('path').join(__dirname, '..')
13 }
14 }
15 })
16
17 async function runtime() {
18
19 const db = new Gun({
20 web: server.listener,
21 file: 'data.json'
22 })
23
24 await server.register(Inert)
25
26 server.route({
27 method: 'GET',
28 path: '/gun.js',
29 handler: {
30 file: 'gun.min.js'
31 }
32 })
33
34 server.route({
35 method: 'GET',
36 path: '/gun/nts.js',
37 handler: {
38 file: 'nts.js'
39 }
40 })
41
42 server.route({
43 method: 'GET',
44 path: '/{param*}',
45 handler: {
46 directory: {
47 path: __dirname,
48 redirectToSlash: true,
49 index: true
50 }
51 }
52 })
53
54 await server.start()
55 console.log('Server running at:', server.info.uri)
56 }
57
58 runtime()
1 ;(function(){
2 var cluster = require('cluster');
3 if(cluster.isMaster){
4 return cluster.fork() && cluster.on('exit', function(){ cluster.fork(); require('../lib/crashed'); });
5 }
6
7 var fs = require('fs');
8 var config = { port: process.env.OPENSHIFT_NODEJS_PORT || process.env.VCAP_APP_PORT || process.env.PORT || process.argv[2] || 8765 };
9 var Gun = require('../'); // require('gun')
10
11 if(process.env.HTTPS_KEY){
12 config.key = fs.readFileSync(process.env.HTTPS_KEY);
13 config.cert = fs.readFileSync(process.env.HTTPS_CERT);
14 config.server = require('https').createServer(config, Gun.serve(__dirname));
15 } else {
16 config.server = require('http').createServer(Gun.serve(__dirname));
17 }
18
19 var gun = Gun({web: config.server.listen(config.port)});
20 console.log('Relay peer started on port ' + config.port + ' with /gun');
21
22 module.exports = gun;
23 }());
...\ No newline at end of file ...\ No newline at end of file
1 <html>
2 <head>
3 <title>gun examples</title>
4 <meta charset="utf-8">
5 <meta name="viewport" content="width=device-width, initial-scale=1">
6 </head>
7
8 <body>
9 <!-- h1>Examples Directory <button style="float: right;" onclick="localStorage.clear()">Clear Local Storage</button></h1 -->
10 <style>
11 html, body {
12 margin: 0;
13 padding: 0;
14 }
15 iframe {
16 width: 100%;
17 height: 50%;
18 border: none;
19 b-order-top: ridge 2em skyblue;
20 border: none;
21 }
22 </style>
23 <a href="/todo/index.html"><iframe src="/todo/index.html" style="height: 100%;"></iframe></a>
24 <!-- a href="/json/index.html"><iframe src="/json/index.html"></iframe></a -->
25 <!-- a href="/chat/index.html"><iframe src="/chat/index.html"></iframe></a --> <!-- removing until DOM bug fixed -->
26 <!-- script src="../gun.js"></script -->
27 </body>
28 </html>
1 #!/bin/bash
2
3 # README
4 # This will install nodejs and npm on your system,
5 # should work on most places other than Windows.
6 # Copy paste and run each line into your terminal.
7 # If you are on Windows, http://nodejs.org/download/ has
8 # an installer that will automatically do it for you.
9 # curl -o- https://raw.githubusercontent.com/amark/gun/master/examples/install.sh | bash
10
11 #debian/ubuntu
12 su -
13 apt-get install sudo -y
14 sudo apt-get update -y
15 sudo apt-get install curl git git-core -y
16 #fedora/openSUSE
17 sudo yum check-update -y
18 sudo yum install curl git git-core -y
19
20 # install nodejs
21 git clone http://github.com/isaacs/nave.git
22 sudo ./nave/nave.sh usemain stable
23 # If you just want nodejs and npm but not gun, stop here.
24
25 npm install gun
26
27 # to run the gun examples:
28 cd ./node_modules/gun
29 npm install .
30 sudo /usr/local/bin/node ./examples/http.js 80 # change `80` to `8765` for development purposes.
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta name="viewport" content="width=device-width, initial-scale=1">
5 <script src="../../gun.js"></script>
6 </head>
7 <body>
8 <h3>Admin JSON Editor</h3>
9 This is a live view of your data, you can edit it in realtime or add new field/values.
10 <ul id="data">
11 </ul>
12 <li id="model">
13 <b>field</b>:
14 <span contenteditable="true">val</span>
15 </li>
16 <ul><li>
17 <form id="form">
18 <label>
19 <input id="field" placeholder="field">
20 <button type="submit">add</button>
21 </label>
22 </form>
23 </li></ul>
24 <script> // minimal jQuery polyfill
25 var $ = function(s, e){ return (e || document).querySelector(s) }
26 function clean(text){ return String(text).replace(/\</ig, '&lt;') }
27 </script>
28 <script>
29 var gun = Gun(location.origin + '/gun');
30 var ref = gun.get('example/json/data');
31 $('#form').onsubmit = function(e){
32 return ref.path( clean($('#field').value) ).put("value"), false; // add a new field, and cancel the form submit.
33 }
34 document.onkeyup = function(e){
35 if(!e || !e.target){ return } // ignore if no element!
36 if(!e.target.attributes.contenteditable){ return } // ignore if element content isn't editable!
37 console.log("save to", e.target.previousElementSibling.innerHTML, ":", e.target.innerHTML);
38 ref.path(clean(e.target.previousElementSibling.innerHTML)) // grab the label, which is in the previous element.
39 .put( clean(e.target.innerHTML) ); // insert the value of the text in the current element.
40 }
41 ref.on(function(json){
42 var data = Gun.obj.copy(json); // make a snapshot!
43 delete data._; // skip meta data!
44 for(var field in data){
45 var val = String(data[field]), id = field.replace(/[^A-z]/ig, ''), elem; // make data safe.
46 (elem = $('#' + id) || $('#data').appendChild($('#model').cloneNode(true))).id = id; // reuse or make element, set id.
47 $('b', elem).innerHTML = clean(field); // escape and display field
48 $('span', elem).innerHTML = clean(val); // escape and display value
49 }
50 });
51 </script>
52 <style>
53 html, body {
54 font-family: Verdana, Geneva, sans-serif;
55 }
56 a, button {
57 border: none;
58 color: skyblue;
59 background: transparent;
60 text-decoration: none;
61 cursor: poiner;
62 }
63 ul, li {
64 list-style-type: none;
65 }
66 ul:hover, li:hover {
67 list-style-type: inherit;
68 }
69 input {
70 border: none;
71 border-bottom: dashed 1px gainsboro;
72 }
73 .none, #model {
74 display: none;
75 }
76 </style>
77 </body>
78 </html>
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <!--
5 HELP WANTED!
6 Build decentralized Open Source Uber/Lyft!
7 Need people with experience on:
8 - Leaflet API, zoom and tile coordinates for subscribing to surrounding area.
9 - Creating cute little driving icons that animate with heading/direction.
10 -->
11 <title>Move by Neon ERA</title>
12 <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport" />
13 <meta charset="utf-8">
14 <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/leaflet@1.0.3/dist/leaflet.css"/>
15 <script src="https://cdn.jsdelivr.net/npm/leaflet@1.0.3/dist/leaflet.js"></script>
16 </head>
17 <body>
18 <div id="map"></div>
19 <a id="share" class="hide"><div class="stick button">Request Ride</div></a>
20 <div id="link" class="hide">
21 <p>Copy and Paste this URL to your friends to share your location:</p>
22 <center>
23 <p id="follow">Location sharing not available!</p>
24 </center>
25 <p><b>Note</b>: Location may not sync when your device's screen is off or the tab is out of focus. You'd need to install this as an app for that to work.</p>
26 <center>
27 <a id="close"><div class="button">Close</div></a>
28 </center>
29 </div>
30 <textarea style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 5em;" id="debug"></textarea>
31 <style>
32 html, body, #map {
33 margin: 0;
34 padding: 0;
35 width: 100%;
36 height: 100%;
37 font-family: Arial;
38 font-size: 16pt;
39 z-index: 1;
40 }
41 .stick {
42 position: absolute;
43 bottom: 1em;
44 right: 1em;
45 }
46 .button {
47 display: inline-block;
48 padding: 1em;
49 opacity: .5;
50 background: blue;
51 color: white;
52 z-index: 7;
53 transition: .25s all;
54 }
55 .button:hover {
56 opacity: 1;
57 }
58 .hide {
59 display: none;
60 }
61 #link {
62 position: absolute;
63 padding: 1em;
64 top: 2em;
65 left: 2em;
66 right: 2em;
67 bottom: 2em;
68 background: white;
69 overflow: scroll;
70 z-index: 9;
71 }
72 #follow {
73 background: #EEE;
74 padding: .5em;
75 word-wrap: break-word;
76 }
77 </style>
78 <script src="/jquery.js"></script>
79 <script src="/gun.js"></script>
80 <script>
81 function Where(opt, cb){
82 // a small wrapper around Leaflet for map tracking.
83 var where = {};
84 where.opt = opt || {};
85 where.opt.zoom = where.opt.zoom || {};
86 where.opt.err = where.opt.err || function(){};
87
88 where.map = L.map('map', { zoom: where.opt.zoom.level });
89
90 where.opt.tile = where.opt.tile || L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
91 maxZoom: where.opt.zoom.max,
92 minZoom: where.opt.zoom.min,
93 detectRetina: true,
94 attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
95 });
96 where.map.addLayer(where.opt.tile);
97
98 L.GridLayer.DebugCoords = L.GridLayer.extend({
99 createTile: function (coords) {
100 var tile = document.createElement('div');
101 tile.innerHTML = [coords.z, coords.x, coords.y].join(', ');
102 tile.style.outline = '1px solid black';
103 return tile;
104 }
105 });
106 L.gridLayer.debugCoords = function(opts) {
107 return new L.GridLayer.DebugCoords(opts);
108 };
109 where.map.addLayer( L.gridLayer.debugCoords() );
110
111 where.opt.zoom.ing = where.opt.zoom.ing || function(){
112 where.opt.zoom.level = where.map.getZoom();
113 }
114 where.map.on('zoomstart', where.opt.zoom.ing, where.opt.err);
115 where.map.on('zoomend', where.opt.zoom.ing, where.opt.err);
116 where.map.on('zoomlevelschange', where.opt.zoom.ing, where.opt.err);
117
118 where.update = function(latlng){
119 if((+new Date) - where.update.last < 400){
120 clearTimeout(where.update.to);
121 where.update.to = setTimeout(function(){
122 where.update(latlng);
123 });
124 return;
125 }
126 var z = 12;
127 var x = lng2tile(latlng.lng, z);
128 var y = lat2tile(latlng.lat, z);
129 console.log(x, y); //
130 where.map.setView(latlng, where.opt.zoom.level, {animate: true});
131 where.marker = where.marker || L.marker().setLatLng(latlng).addTo(where.map);
132 where.marker.setLatLng(latlng).update();
133 where.update.last = (+new Date);
134 }
135
136 if(where.opt.track){
137 where.map.on('locationfound', function(pos){
138 where.update(pos.latlng);
139 where.opt.track(pos);
140 });
141
142 where.map.locate({
143 setView: true,
144 zoom: where.opt.zoom.level,
145 watch: where.opt.continuous || true,
146 timeout: where.opt.timeout || 10000,
147 maximumAge: where.opt.maximumAge || 0,
148 enableHighAccuracy: where.opt.enableHighAccuracy || false
149 });
150 }
151
152 function lng2tile(lng,z) { return (Math.floor((lng+180)/360*Math.pow(2,z))) }
153 function lat2tile(lat,z) { return (Math.floor((1-Math.log(Math.tan(lat*Math.PI/180) + 1/Math.cos(lat*Math.PI/180))/Math.PI)/2 *Math.pow(2,z))) }
154
155 return where;
156 }
157 </script>
158 <script>
159 ;(function(){
160 // the actual GPS tracking app!
161 var gun = Gun(location.origin + '/gun');
162 var gps = {};
163 gps.opt = {
164 continuous: true, // get location just once uses `getCurrentPosition()` while continuously uses `watchPosition()`
165 enableHighAccuracy: true, // HighAccuracy uses more resources, https://developer.mozilla.org/en-US/docs/Web/API/PositionOptions
166 timeout: 5000, // have this long to get data before erring.
167 maximumAge: 0, // set to 0 to actually track.
168 zoom: {max: 18, level: 13, min: 12}
169 }
170 function start(){
171 gps.follow = (window.location.hash || '').slice(1);
172 if(gps.follow){
173 gps.where = gps.where || Where(gps.opt);
174 gps.ref = gun.get('gps/' + gps.follow);
175 gps.ref.on(function(latlng){
176 //$('#debug').value = 'track ' + JSON.stringify(latlng);
177 gps.where.update(latlng);
178 });
179 $('#share').addClass("hide");
180 } else {
181 document.cookie = 'gps=' + (gps.track = (document.cookie.match(/gps\=(.*?)(\&|$|\;)/i)||[])[1] || Gun.text.random(5)); // trick with cookies!
182 gps.ref = gun.get('gps/' + gps.track);
183 gps.opt.track = function(pos){
184 pos = pos.latlng;
185 if(gps.follow
186 || Gun.time.is() - gps.when < 1000
187 || gps.last && gps.last.lat == pos.lat && gps.last.lng == pos.lng){
188 return; // throttle!
189 }
190 gps.when = Gun.time.is();
191 gps.ref.put(gps.last = pos);
192 //$('#debug').value = JSON.stringify(gps.last);
193 }
194 gps.where = gps.where || Where(gps.opt);
195 $('#follow').text(("where.gunDB.io/" || (location.origin + location.pathname)) + '#' + gps.track);
196 $('#share').removeClass("hide");
197 $('#share').on('click', function(){
198 $('#link').toggleClass("hide");
199 });
200 $('#close').on('click', function(){
201 $('#link').toggleClass("hide");
202 });
203 }
204 }
205 start();
206 window.onhashchange = start;
207 }());
208 </script>
209 </body>
210 </html>
...\ No newline at end of file ...\ No newline at end of file
1 {
2 "presets": ["module:metro-react-native-babel-preset"]
3 }
1
2 [android]
3 target = Google Inc.:Google APIs:23
4
5 [maven_repositories]
6 central = https://repo1.maven.org/maven2
1 [ignore]
2 ; We fork some components by platform
3 .*/*[.]android.js
4
5 ; Ignore "BUCK" generated dirs
6 <PROJECT_ROOT>/\.buckd/
7
8 ; Ignore unexpected extra "@providesModule"
9 .*/node_modules/.*/node_modules/fbjs/.*
10
11 ; Ignore duplicate module providers
12 ; For RN Apps installed via npm, "Libraries" folder is inside
13 ; "node_modules/react-native" but in the source repo it is in the root
14 .*/Libraries/react-native/React.js
15
16 ; Ignore polyfills
17 .*/Libraries/polyfills/.*
18
19 ; Ignore metro
20 .*/node_modules/metro/.*
21
22 [include]
23
24 [libs]
25 node_modules/react-native/Libraries/react-native/react-native-interface.js
26 node_modules/react-native/flow/
27 node_modules/react-native/flow-github/
28
29 [options]
30 emoji=true
31
32 esproposal.optional_chaining=enable
33 esproposal.nullish_coalescing=enable
34
35 module.system=haste
36 module.system.haste.use_name_reducers=true
37 # get basename
38 module.system.haste.name_reducers='^.*/\([a-zA-Z0-9$_.-]+\.js\(\.flow\)?\)$' -> '\1'
39 # strip .js or .js.flow suffix
40 module.system.haste.name_reducers='^\(.*\)\.js\(\.flow\)?$' -> '\1'
41 # strip .ios suffix
42 module.system.haste.name_reducers='^\(.*\)\.ios$' -> '\1'
43 module.system.haste.name_reducers='^\(.*\)\.android$' -> '\1'
44 module.system.haste.name_reducers='^\(.*\)\.native$' -> '\1'
45 module.system.haste.paths.blacklist=.*/__tests__/.*
46 module.system.haste.paths.blacklist=.*/__mocks__/.*
47 module.system.haste.paths.blacklist=<PROJECT_ROOT>/node_modules/react-native/Libraries/Animated/src/polyfills/.*
48 module.system.haste.paths.whitelist=<PROJECT_ROOT>/node_modules/react-native/Libraries/.*
49
50 munge_underscores=true
51
52 module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub'
53
54 module.file_ext=.js
55 module.file_ext=.jsx
56 module.file_ext=.json
57 module.file_ext=.native.js
58
59 suppress_type=$FlowIssue
60 suppress_type=$FlowFixMe
61 suppress_type=$FlowFixMeProps
62 suppress_type=$FlowFixMeState
63
64 suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(<VERSION>\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
65 suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(<VERSION>\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
66 suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
67 suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
68
69 [version]
70 ^0.78.0
1 {}
...\ No newline at end of file ...\ No newline at end of file
1 # Gun on react-native!
2 ---
3 ### running the demo
4 1. do `yarn install` on the directory of the demo `examples/react-native`
5 2. run the demo with `react-native run-ios` or `react-native run-android`
6
7 ### debugging
8 i would recommend using [react-native-debugger](https://github.com/facebook/react-devtools/tree/master/packages/react-devtools) but you can use chrome's debugger as well
9
10 - ios: `cmd+D` then `Debug JS Remotely`
11 - android: `cmd+M` then `Debug JS Remotely`
12
13 now you have access to the gun globals on the console which are
14 `gun` -> the root gun
15 `user` -> the gun user
16 ---
17 # how it all of this is done
18 since react-native doesnt provide the crypto module that we desire the most and all of the packages are incompatible with react-native/sea, and so to get `sea.js` working we use a webview(react-native browser) and bridge the crypto module from that browser to the global `window` and thats exactly what `webview-crypto` does, thanks to [webview-crypto repo](https://github.com/saulshanabrook/webview-crypto), the webview-crypto provided in this repo is somewhat the same but modified to get it working and mostly compatible with sea/react-native (even though there is a polyfiller for that but it just doesnt work ;/).
...\ No newline at end of file ...\ No newline at end of file
1 # To learn about Buck see [Docs](https://buckbuild.com/).
2 # To run your application with Buck:
3 # - install Buck
4 # - `npm start` - to start the packager
5 # - `cd android`
6 # - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"`
7 # - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck
8 # - `buck install -r android/app` - compile, install and run application
9 #
10
11 lib_deps = []
12
13 for jarfile in glob(['libs/*.jar']):
14 name = 'jars__' + jarfile[jarfile.rindex('/') + 1: jarfile.rindex('.jar')]
15 lib_deps.append(':' + name)
16 prebuilt_jar(
17 name = name,
18 binary_jar = jarfile,
19 )
20
21 for aarfile in glob(['libs/*.aar']):
22 name = 'aars__' + aarfile[aarfile.rindex('/') + 1: aarfile.rindex('.aar')]
23 lib_deps.append(':' + name)
24 android_prebuilt_aar(
25 name = name,
26 aar = aarfile,
27 )
28
29 android_library(
30 name = "all-libs",
31 exported_deps = lib_deps,
32 )
33
34 android_library(
35 name = "app-code",
36 srcs = glob([
37 "src/main/java/**/*.java",
38 ]),
39 deps = [
40 ":all-libs",
41 ":build_config",
42 ":res",
43 ],
44 )
45
46 android_build_config(
47 name = "build_config",
48 package = "com.gundemo",
49 )
50
51 android_resource(
52 name = "res",
53 package = "com.gundemo",
54 res = "src/main/res",
55 )
56
57 android_binary(
58 name = "app",
59 keystore = "//android/keystores:debug",
60 manifest = "src/main/AndroidManifest.xml",
61 package_type = "debug",
62 deps = [
63 ":app-code",
64 ],
65 )
1 apply plugin: "com.android.application"
2
3 import com.android.build.OutputFile
4
5 /**
6 * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets
7 * and bundleReleaseJsAndAssets).
8 * These basically call `react-native bundle` with the correct arguments during the Android build
9 * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the
10 * bundle directly from the development server. Below you can see all the possible configurations
11 * and their defaults. If you decide to add a configuration block, make sure to add it before the
12 * `apply from: "../../node_modules/react-native/react.gradle"` line.
13 *
14 * project.ext.react = [
15 * // the name of the generated asset file containing your JS bundle
16 * bundleAssetName: "index.android.bundle",
17 *
18 * // the entry file for bundle generation
19 * entryFile: "index.android.js",
20 *
21 * // whether to bundle JS and assets in debug mode
22 * bundleInDebug: false,
23 *
24 * // whether to bundle JS and assets in release mode
25 * bundleInRelease: true,
26 *
27 * // whether to bundle JS and assets in another build variant (if configured).
28 * // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants
29 * // The configuration property can be in the following formats
30 * // 'bundleIn${productFlavor}${buildType}'
31 * // 'bundleIn${buildType}'
32 * // bundleInFreeDebug: true,
33 * // bundleInPaidRelease: true,
34 * // bundleInBeta: true,
35 *
36 * // whether to disable dev mode in custom build variants (by default only disabled in release)
37 * // for example: to disable dev mode in the staging build type (if configured)
38 * devDisabledInStaging: true,
39 * // The configuration property can be in the following formats
40 * // 'devDisabledIn${productFlavor}${buildType}'
41 * // 'devDisabledIn${buildType}'
42 *
43 * // the root of your project, i.e. where "package.json" lives
44 * root: "../../",
45 *
46 * // where to put the JS bundle asset in debug mode
47 * jsBundleDirDebug: "$buildDir/intermediates/assets/debug",
48 *
49 * // where to put the JS bundle asset in release mode
50 * jsBundleDirRelease: "$buildDir/intermediates/assets/release",
51 *
52 * // where to put drawable resources / React Native assets, e.g. the ones you use via
53 * // require('./image.png')), in debug mode
54 * resourcesDirDebug: "$buildDir/intermediates/res/merged/debug",
55 *
56 * // where to put drawable resources / React Native assets, e.g. the ones you use via
57 * // require('./image.png')), in release mode
58 * resourcesDirRelease: "$buildDir/intermediates/res/merged/release",
59 *
60 * // by default the gradle tasks are skipped if none of the JS files or assets change; this means
61 * // that we don't look at files in android/ or ios/ to determine whether the tasks are up to
62 * // date; if you have any other folders that you want to ignore for performance reasons (gradle
63 * // indexes the entire tree), add them here. Alternatively, if you have JS files in android/
64 * // for example, you might want to remove it from here.
65 * inputExcludes: ["android/**", "ios/**"],
66 *
67 * // override which node gets called and with what additional arguments
68 * nodeExecutableAndArgs: ["node"],
69 *
70 * // supply additional arguments to the packager
71 * extraPackagerArgs: []
72 * ]
73 */
74
75 project.ext.react = [
76 entryFile: "index.js"
77 ]
78
79 apply from: "../../node_modules/react-native/react.gradle"
80
81 /**
82 * Set this to true to create two separate APKs instead of one:
83 * - An APK that only works on ARM devices
84 * - An APK that only works on x86 devices
85 * The advantage is the size of the APK is reduced by about 4MB.
86 * Upload all the APKs to the Play Store and people will download
87 * the correct one based on the CPU architecture of their device.
88 */
89 def enableSeparateBuildPerCPUArchitecture = false
90
91 /**
92 * Run Proguard to shrink the Java bytecode in release builds.
93 */
94 def enableProguardInReleaseBuilds = false
95
96 android {
97 compileSdkVersion rootProject.ext.compileSdkVersion
98 buildToolsVersion rootProject.ext.buildToolsVersion
99
100 defaultConfig {
101 applicationId "com.gundemo"
102 minSdkVersion rootProject.ext.minSdkVersion
103 targetSdkVersion rootProject.ext.targetSdkVersion
104 versionCode 1
105 versionName "1.0"
106 ndk {
107 abiFilters "armeabi-v7a", "x86"
108 }
109 }
110 splits {
111 abi {
112 reset()
113 enable enableSeparateBuildPerCPUArchitecture
114 universalApk false // If true, also generate a universal APK
115 include "armeabi-v7a", "x86"
116 }
117 }
118 buildTypes {
119 release {
120 minifyEnabled enableProguardInReleaseBuilds
121 proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
122 }
123 }
124 // applicationVariants are e.g. debug, release
125 applicationVariants.all { variant ->
126 variant.outputs.each { output ->
127 // For each separate APK per architecture, set a unique version code as described here:
128 // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits
129 def versionCodes = ["armeabi-v7a":1, "x86":2]
130 def abi = output.getFilter(OutputFile.ABI)
131 if (abi != null) { // null for the universal-debug, universal-release variants
132 output.versionCodeOverride =
133 versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
134 }
135 }
136 }
137 }
138
139 dependencies {
140 compile project(':react-native-webview-bridge')
141 implementation fileTree(dir: "libs", include: ["*.jar"])
142 implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
143 implementation "com.facebook.react:react-native:+" // From node_modules
144 }
145
146 // Run this once to be able to run the application with BUCK
147 // puts all compile dependencies into folder libs for BUCK to use
148 task copyDownloadableDepsToLibs(type: Copy) {
149 from configurations.compile
150 into 'libs'
151 }
1 # Add project specific ProGuard rules here.
2 # By default, the flags in this file are appended to flags specified
3 # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
4 # You can edit the include path and order by changing the proguardFiles
5 # directive in build.gradle.
6 #
7 # For more details, see
8 # http://developer.android.com/guide/developing/tools/proguard.html
9
10 # Add any project specific keep options here:
11
12 # If your project uses WebView with JS, uncomment the following
13 # and specify the fully qualified class name to the JavaScript interface
14 # class:
15 #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 # public *;
17 #}
1 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
2 package="com.gundemo">
3
4 <uses-permission android:name="android.permission.INTERNET" />
5 <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
6
7 <application
8 android:name=".MainApplication"
9 android:label="@string/app_name"
10 android:icon="@mipmap/ic_launcher"
11 android:allowBackup="false"
12 android:theme="@style/AppTheme">
13 <activity
14 android:name=".MainActivity"
15 android:label="@string/app_name"
16 android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
17 android:windowSoftInputMode="adjustResize">
18 <intent-filter>
19 <action android:name="android.intent.action.MAIN" />
20 <category android:name="android.intent.category.LAUNCHER" />
21 </intent-filter>
22 </activity>
23 <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
24 </application>
25
26 </manifest>
1 package com.gundemo;
2
3 import com.facebook.react.ReactActivity;
4
5 public class MainActivity extends ReactActivity {
6
7 /**
8 * Returns the name of the main component registered from JavaScript.
9 * This is used to schedule rendering of the component.
10 */
11 @Override
12 protected String getMainComponentName() {
13 return "GunDemo";
14 }
15 }
1 package com.gundemo;
2
3 import android.app.Application;
4
5 import com.facebook.react.ReactApplication;
6 import com.github.alinz.reactnativewebviewbridge.WebViewBridgePackage;
7 import com.facebook.react.ReactNativeHost;
8 import com.facebook.react.ReactPackage;
9 import com.facebook.react.shell.MainReactPackage;
10 import com.facebook.soloader.SoLoader;
11
12 import java.util.Arrays;
13 import java.util.List;
14
15 public class MainApplication extends Application implements ReactApplication {
16
17 private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
18 @Override
19 public boolean getUseDeveloperSupport() {
20 return BuildConfig.DEBUG;
21 }
22
23 @Override
24 protected List<ReactPackage> getPackages() {
25 return Arrays.<ReactPackage>asList(
26 new MainReactPackage(),
27 new WebViewBridgePackage()
28 );
29 }
30
31 @Override
32 protected String getJSMainModuleName() {
33 return "index";
34 }
35 };
36
37 @Override
38 public ReactNativeHost getReactNativeHost() {
39 return mReactNativeHost;
40 }
41
42 @Override
43 public void onCreate() {
44 super.onCreate();
45 SoLoader.init(this, /* native exopackage */ false);
46 }
47 }
1 <resources>
2 <string name="app_name">GunDemo</string>
3 </resources>
1 <resources>
2
3 <!-- Base application theme. -->
4 <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
5 <!-- Customize your theme here. -->
6 </style>
7
8 </resources>
1 // Top-level build file where you can add configuration options common to all sub-projects/modules.
2
3 buildscript {
4 ext {
5 buildToolsVersion = "27.0.3"
6 minSdkVersion = 16
7 compileSdkVersion = 27
8 targetSdkVersion = 26
9 supportLibVersion = "27.1.1"
10 }
11 repositories {
12 google()
13 jcenter()
14 }
15 dependencies {
16 classpath 'com.android.tools.build:gradle:3.1.4'
17
18 // NOTE: Do not place your application dependencies here; they belong
19 // in the individual module build.gradle files
20 }
21 }
22
23 allprojects {
24 repositories {
25 mavenLocal()
26 google()
27 jcenter()
28 maven {
29 // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
30 url "$rootDir/../node_modules/react-native/android"
31 }
32 }
33 }
34
35
36 task wrapper(type: Wrapper) {
37 gradleVersion = '4.4'
38 distributionUrl = distributionUrl.replace("bin", "all")
39 }
1 # Project-wide Gradle settings.
2
3 # IDE (e.g. Android Studio) users:
4 # Gradle settings configured through the IDE *will override*
5 # any settings specified in this file.
6
7 # For more details on how to configure your build environment visit
8 # http://www.gradle.org/docs/current/userguide/build_environment.html
9
10 # Specifies the JVM arguments used for the daemon process.
11 # The setting is particularly useful for tweaking memory settings.
12 # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14
15 # When configured, Gradle will run in incubating parallel mode.
16 # This option should only be used with decoupled projects. More details, visit
17 # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 # org.gradle.parallel=true
1 distributionBase=GRADLE_USER_HOME
2 distributionPath=wrapper/dists
3 zipStoreBase=GRADLE_USER_HOME
4 zipStorePath=wrapper/dists
5 distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
1 #!/usr/bin/env sh
2
3 ##############################################################################
4 ##
5 ## Gradle start up script for UN*X
6 ##
7 ##############################################################################
8
9 # Attempt to set APP_HOME
10 # Resolve links: $0 may be a link
11 PRG="$0"
12 # Need this for relative symlinks.
13 while [ -h "$PRG" ] ; do
14 ls=`ls -ld "$PRG"`
15 link=`expr "$ls" : '.*-> \(.*\)$'`
16 if expr "$link" : '/.*' > /dev/null; then
17 PRG="$link"
18 else
19 PRG=`dirname "$PRG"`"/$link"
20 fi
21 done
22 SAVED="`pwd`"
23 cd "`dirname \"$PRG\"`/" >/dev/null
24 APP_HOME="`pwd -P`"
25 cd "$SAVED" >/dev/null
26
27 APP_NAME="Gradle"
28 APP_BASE_NAME=`basename "$0"`
29
30 # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 DEFAULT_JVM_OPTS=""
32
33 # Use the maximum available, or set MAX_FD != -1 to use that value.
34 MAX_FD="maximum"
35
36 warn () {
37 echo "$*"
38 }
39
40 die () {
41 echo
42 echo "$*"
43 echo
44 exit 1
45 }
46
47 # OS specific support (must be 'true' or 'false').
48 cygwin=false
49 msys=false
50 darwin=false
51 nonstop=false
52 case "`uname`" in
53 CYGWIN* )
54 cygwin=true
55 ;;
56 Darwin* )
57 darwin=true
58 ;;
59 MINGW* )
60 msys=true
61 ;;
62 NONSTOP* )
63 nonstop=true
64 ;;
65 esac
66
67 CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68
69 # Determine the Java command to use to start the JVM.
70 if [ -n "$JAVA_HOME" ] ; then
71 if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 # IBM's JDK on AIX uses strange locations for the executables
73 JAVACMD="$JAVA_HOME/jre/sh/java"
74 else
75 JAVACMD="$JAVA_HOME/bin/java"
76 fi
77 if [ ! -x "$JAVACMD" ] ; then
78 die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79
80 Please set the JAVA_HOME variable in your environment to match the
81 location of your Java installation."
82 fi
83 else
84 JAVACMD="java"
85 which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86
87 Please set the JAVA_HOME variable in your environment to match the
88 location of your Java installation."
89 fi
90
91 # Increase the maximum file descriptors if we can.
92 if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 MAX_FD_LIMIT=`ulimit -H -n`
94 if [ $? -eq 0 ] ; then
95 if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 MAX_FD="$MAX_FD_LIMIT"
97 fi
98 ulimit -n $MAX_FD
99 if [ $? -ne 0 ] ; then
100 warn "Could not set maximum file descriptor limit: $MAX_FD"
101 fi
102 else
103 warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 fi
105 fi
106
107 # For Darwin, add options to specify how the application appears in the dock
108 if $darwin; then
109 GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 fi
111
112 # For Cygwin, switch paths to Windows format before running java
113 if $cygwin ; then
114 APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 JAVACMD=`cygpath --unix "$JAVACMD"`
117
118 # We build the pattern for arguments to be converted via cygpath
119 ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 SEP=""
121 for dir in $ROOTDIRSRAW ; do
122 ROOTDIRS="$ROOTDIRS$SEP$dir"
123 SEP="|"
124 done
125 OURCYGPATTERN="(^($ROOTDIRS))"
126 # Add a user-defined pattern to the cygpath arguments
127 if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 fi
130 # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 i=0
132 for arg in "$@" ; do
133 CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135
136 if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 else
139 eval `echo args$i`="\"$arg\""
140 fi
141 i=$((i+1))
142 done
143 case $i in
144 (0) set -- ;;
145 (1) set -- "$args0" ;;
146 (2) set -- "$args0" "$args1" ;;
147 (3) set -- "$args0" "$args1" "$args2" ;;
148 (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 esac
155 fi
156
157 # Escape application args
158 save () {
159 for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 echo " "
161 }
162 APP_ARGS=$(save "$@")
163
164 # Collect all arguments for the java command, following the shell quoting and substitution rules
165 eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166
167 # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 cd "$(dirname "$0")"
170 fi
171
172 exec "$JAVACMD" "$@"
1 @if "%DEBUG%" == "" @echo off
2 @rem ##########################################################################
3 @rem
4 @rem Gradle startup script for Windows
5 @rem
6 @rem ##########################################################################
7
8 @rem Set local scope for the variables with windows NT shell
9 if "%OS%"=="Windows_NT" setlocal
10
11 set DIRNAME=%~dp0
12 if "%DIRNAME%" == "" set DIRNAME=.
13 set APP_BASE_NAME=%~n0
14 set APP_HOME=%DIRNAME%
15
16 @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 set DEFAULT_JVM_OPTS=
18
19 @rem Find java.exe
20 if defined JAVA_HOME goto findJavaFromJavaHome
21
22 set JAVA_EXE=java.exe
23 %JAVA_EXE% -version >NUL 2>&1
24 if "%ERRORLEVEL%" == "0" goto init
25
26 echo.
27 echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 echo.
29 echo Please set the JAVA_HOME variable in your environment to match the
30 echo location of your Java installation.
31
32 goto fail
33
34 :findJavaFromJavaHome
35 set JAVA_HOME=%JAVA_HOME:"=%
36 set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37
38 if exist "%JAVA_EXE%" goto init
39
40 echo.
41 echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 echo.
43 echo Please set the JAVA_HOME variable in your environment to match the
44 echo location of your Java installation.
45
46 goto fail
47
48 :init
49 @rem Get command-line arguments, handling Windows variants
50
51 if not "%OS%" == "Windows_NT" goto win9xME_args
52
53 :win9xME_args
54 @rem Slurp the command line arguments.
55 set CMD_LINE_ARGS=
56 set _SKIP=2
57
58 :win9xME_args_slurp
59 if "x%~1" == "x" goto execute
60
61 set CMD_LINE_ARGS=%*
62
63 :execute
64 @rem Setup the command line
65
66 set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67
68 @rem Execute Gradle
69 "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70
71 :end
72 @rem End local scope for the variables with windows NT shell
73 if "%ERRORLEVEL%"=="0" goto mainEnd
74
75 :fail
76 rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 rem the _cmd.exe /c_ return code!
78 if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 exit /b 1
80
81 :mainEnd
82 if "%OS%"=="Windows_NT" endlocal
83
84 :omega
1 keystore(
2 name = "debug",
3 properties = "debug.keystore.properties",
4 store = "debug.keystore",
5 visibility = [
6 "PUBLIC",
7 ],
8 )
1 key.store=debug.keystore
2 key.alias=androiddebugkey
3 key.store.password=android
4 key.alias.password=android
1 rootProject.name = 'GunDemo'
2 include ':react-native-webview-bridge'
3 project(':react-native-webview-bridge').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webview-bridge/android')
4
5 include ':app'
1 {
2 "name": "GunDemo",
3 "displayName": "GunDemo"
4 }
...\ No newline at end of file ...\ No newline at end of file
1 /** @format */
2 import './shim';
3 import {AppRegistry} from 'react-native';
4 import App from './src/App';
5 import {name as appName} from './app.json';
6
7 AppRegistry.registerComponent(appName, () => App);
8 console.disableYellowBox = true;
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3 <plist version="1.0">
4 <dict>
5 <key>CFBundleDevelopmentRegion</key>
6 <string>en</string>
7 <key>CFBundleExecutable</key>
8 <string>$(EXECUTABLE_NAME)</string>
9 <key>CFBundleIdentifier</key>
10 <string>org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)</string>
11 <key>CFBundleInfoDictionaryVersion</key>
12 <string>6.0</string>
13 <key>CFBundleName</key>
14 <string>$(PRODUCT_NAME)</string>
15 <key>CFBundlePackageType</key>
16 <string>APPL</string>
17 <key>CFBundleShortVersionString</key>
18 <string>1.0</string>
19 <key>CFBundleSignature</key>
20 <string>????</string>
21 <key>CFBundleVersion</key>
22 <string>1</string>
23 <key>LSRequiresIPhoneOS</key>
24 <true/>
25 <key>UILaunchStoryboardName</key>
26 <string>LaunchScreen</string>
27 <key>UIRequiredDeviceCapabilities</key>
28 <array>
29 <string>armv7</string>
30 </array>
31 <key>UISupportedInterfaceOrientations</key>
32 <array>
33 <string>UIInterfaceOrientationPortrait</string>
34 <string>UIInterfaceOrientationLandscapeLeft</string>
35 <string>UIInterfaceOrientationLandscapeRight</string>
36 </array>
37 <key>UIViewControllerBasedStatusBarAppearance</key>
38 <false/>
39 <key>NSLocationWhenInUseUsageDescription</key>
40 <string></string>
41 <key>NSAppTransportSecurity</key>
42 <!--See http://ste.vn/2015/06/10/configuring-app-transport-security-ios-9-osx-10-11/ -->
43 <dict>
44 <key>NSExceptionDomains</key>
45 <dict>
46 <key>localhost</key>
47 <dict>
48 <key>NSExceptionAllowsInsecureHTTPLoads</key>
49 <true/>
50 </dict>
51 </dict>
52 </dict>
53 </dict>
54 </plist>
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3 <plist version="1.0">
4 <dict>
5 <key>CFBundleDevelopmentRegion</key>
6 <string>en</string>
7 <key>CFBundleExecutable</key>
8 <string>$(EXECUTABLE_NAME)</string>
9 <key>CFBundleIdentifier</key>
10 <string>org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)</string>
11 <key>CFBundleInfoDictionaryVersion</key>
12 <string>6.0</string>
13 <key>CFBundleName</key>
14 <string>$(PRODUCT_NAME)</string>
15 <key>CFBundlePackageType</key>
16 <string>BNDL</string>
17 <key>CFBundleShortVersionString</key>
18 <string>1.0</string>
19 <key>CFBundleSignature</key>
20 <string>????</string>
21 <key>CFBundleVersion</key>
22 <string>1</string>
23 </dict>
24 </plist>
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
No preview for this file type
This diff could not be displayed because it is too large.
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!