mirror of
https://github.com/believethehype/nostrdvm.git
synced 2025-11-18 09:16:49 +01:00
local user database
This commit is contained in:
@@ -16,9 +16,7 @@ import {
|
||||
import store from '../store';
|
||||
import miniToastr from "mini-toastr";
|
||||
import VueNotifications from "vue-notifications";
|
||||
import searchdvms from './data/searchdvms.json'
|
||||
import {computed, watch} from "vue";
|
||||
import countries from "@/components/data/countries.json";
|
||||
import deadnip89s from "@/components/data/deadnip89s.json";
|
||||
import {data} from "autoprefixer";
|
||||
import {requestProvider} from "webln";
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
<h3 className="card-title">Nip07 Login</h3>
|
||||
<p>Use a Browser Nip07 Extension like getalby or nos2x to login or use Amber on Android</p>
|
||||
<button className="btn" @click="sign_in_nip07()">Browser Extension</button>
|
||||
<!-- <button className="btn" @click="sign_in_nip46()">NsecBunker</button> Not working on server end rn.-->
|
||||
<template v-if="supports_android_signer">
|
||||
<button className="btn" @click="sign_in_amber()">Amber Sign in</button>
|
||||
</template>
|
||||
@@ -54,7 +55,17 @@ import {
|
||||
Filter,
|
||||
initLogger,
|
||||
LogLevel,
|
||||
Timestamp, Keys, NostrDatabase, ClientBuilder, ClientZapper, Alphabet, SingleLetterTag, Options, Duration, PublicKey
|
||||
Timestamp,
|
||||
Keys,
|
||||
NostrDatabase,
|
||||
ClientBuilder,
|
||||
ClientZapper,
|
||||
Alphabet,
|
||||
SingleLetterTag,
|
||||
Options,
|
||||
Duration,
|
||||
PublicKey,
|
||||
Nip46Signer, NegentropyDirection, NegentropyOptions
|
||||
} from "@rust-nostr/nostr-sdk";
|
||||
import VueNotifications from "vue-notifications";
|
||||
import store from '../store';
|
||||
@@ -69,7 +80,8 @@ const isDark = useDark();
|
||||
|
||||
|
||||
let nip89dvms = []
|
||||
let logger = true
|
||||
|
||||
let logger = false
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
@@ -223,12 +235,85 @@ export default {
|
||||
localStorage.setItem('nostr-key', "")
|
||||
console.log("Client connected")
|
||||
await this.get_user_info(pubkey)
|
||||
//await this.reconcile_all_profiles()
|
||||
//miniToastr.showMessage("Login successful!", "Logged in as " + this.current_user, VueNotifications.types.success)
|
||||
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
|
||||
async sign_in_nip46() {
|
||||
|
||||
try {
|
||||
|
||||
await loadWasmAsync();
|
||||
|
||||
|
||||
|
||||
let connectionstring = ""
|
||||
if (localStorage.getItem('nostr-key') !== "" && localStorage.getItem('nostr-key').startsWith("nsecbunker://") ){
|
||||
connectionstring = localStorage.getItem('nostr-key')
|
||||
}
|
||||
|
||||
if (connectionstring === ""){
|
||||
//ADD DEFAULT TEST STRING FOR NOW, USE USER INPUT LATER
|
||||
connectionstring = "nsecbunker://npub1ffske30n349f7z3sccn6n90f9dxxqhcy5n4cgpq32355ka2ye6ls7sa6t4#7a53c7292aa6a8f731cd6fcc15b396213c6a7b0448f9e8994b2479f8832c029f?relay=wss://relay.nsecbunker.com"
|
||||
}
|
||||
|
||||
if (connectionstring.startsWith("nsecbunker://")){
|
||||
connectionstring = connectionstring.replace("nsecbunker://", "")
|
||||
let split = connectionstring.split("?relay=")
|
||||
let relay_url = split[1]
|
||||
let split2 = split[0].split("#")
|
||||
let publickey = Keys.fromPkStr(split2[0]).publicKey
|
||||
let app_keys = Keys.fromSkStr(split2[1])
|
||||
|
||||
|
||||
let nip46_signer = new Nip46Signer(relay_url, app_keys, publickey) ;
|
||||
try{
|
||||
this.signer = ClientSigner.nip46(nip46_signer);
|
||||
console.log("SIGNER: " + this.signer)
|
||||
|
||||
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
this.signer = ClientSigner.keys(Keys.generate())
|
||||
}
|
||||
|
||||
//let zapper = ClientZapper.webln()
|
||||
let opts = new Options().waitForSend(false).connectionTimeout(Duration.fromSecs(5));
|
||||
let client = new ClientBuilder().signer(this.signer).opts(opts).build()
|
||||
|
||||
await client.addRelay(relay_url)
|
||||
for (const relay of store.state.relays){
|
||||
await client.addRelay(relay);
|
||||
}
|
||||
|
||||
const pubkey = await nip46_signer.signerPublicKey()
|
||||
console.log("PUBKEY : " + pubkey.toBech32())
|
||||
await client.connect();
|
||||
|
||||
store.commit('set_client', client)
|
||||
store.commit('set_pubkey', pubkey)
|
||||
store.commit('set_hasEventListener', false)
|
||||
localStorage.setItem('nostr-key-method', "nip46")
|
||||
localStorage.setItem('nostr-key', connectionstring)
|
||||
console.log("Client connected")
|
||||
await this.get_user_info(pubkey)
|
||||
//miniToastr.showMessage("Login successful!", "Logged in as " + this.current_user, VueNotifications.types.success)
|
||||
|
||||
|
||||
}
|
||||
else {
|
||||
miniToastr.showMessage("Invalid Nsecbunker url")
|
||||
}
|
||||
|
||||
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
async sign_in_amber(key="") {
|
||||
try {
|
||||
|
||||
@@ -334,7 +419,41 @@ export default {
|
||||
|
||||
|
||||
},
|
||||
async reconcile_all_profiles() {
|
||||
|
||||
let keys = Keys.fromSkStr("ece3c0aa759c3e895ecb3c13ab3813c0f98430c6d4bd22160b9c2219efc9cf0e")
|
||||
let db = NostrDatabase.indexeddb("profiles");
|
||||
let signer = ClientSigner.keys(keys) //TODO store keys
|
||||
dbclient = new ClientBuilder().signer(signer).database(await db).build()
|
||||
|
||||
await dbclient.addRelay("wss://relay.damus.io");
|
||||
await dbclient.connect();
|
||||
let direction = NegentropyDirection.Down;
|
||||
let opts = new NegentropyOptions().direction(direction);
|
||||
|
||||
|
||||
let followings = []
|
||||
let followers_filter = new Filter().author(store.state.pubkey).kind(3).limit(1)
|
||||
let followers = await dbclient.getEventsOf([followers_filter], 10)
|
||||
|
||||
console.log(followers)
|
||||
if (followers.length > 0){
|
||||
console.log(followers.length)
|
||||
for (let tag of followers[0].tags) {
|
||||
console.log(tag.asVec())
|
||||
if (tag.asVec()[0] === "p") {
|
||||
let following = tag.asVec()[1]
|
||||
followings.push(PublicKey.fromHex(following))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
console.log("Followings: " + (followings.length).toString())
|
||||
|
||||
|
||||
let filter = new Filter().kind(0).authors(followings)
|
||||
await dbclient.reconcile(filter, opts);
|
||||
},
|
||||
|
||||
|
||||
async get_user_info(pubkey){
|
||||
@@ -364,7 +483,7 @@ export default {
|
||||
this.current_user = ""
|
||||
localStorage.setItem('nostr-key-method', "anon")
|
||||
localStorage.setItem('nostr-key', "")
|
||||
await this.state.client.shutdown();
|
||||
//await this.state.client.shutdown();
|
||||
await this.sign_in_anon()
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<script setup>
|
||||
|
||||
|
||||
import {
|
||||
Client,
|
||||
Filter,
|
||||
@@ -9,14 +11,12 @@ import {
|
||||
EventBuilder,
|
||||
Tag,
|
||||
EventId,
|
||||
Nip19Event, Alphabet
|
||||
Nip19Event, Alphabet, ClientBuilder, ClientSigner, Keys, NostrDatabase, NegentropyOptions, NegentropyDirection
|
||||
} from "@rust-nostr/nostr-sdk";
|
||||
import store from '../store';
|
||||
import miniToastr from "mini-toastr";
|
||||
import VueNotifications from "vue-notifications";
|
||||
import searchdvms from './data/searchdvms.json'
|
||||
import {computed, onMounted, ref} from "vue";
|
||||
import countries from "@/components/data/countries.json";
|
||||
import deadnip89s from "@/components/data/deadnip89s.json";
|
||||
import amberSignerService from "./android-signer/AndroidSigner";
|
||||
import VueDatePicker from '@vuepic/vue-datepicker';
|
||||
@@ -28,13 +28,16 @@ let listener = false
|
||||
let searching = false
|
||||
|
||||
const message = ref("");
|
||||
const fromuser = ref("");
|
||||
|
||||
|
||||
let dbclient = Client
|
||||
let usernames = []
|
||||
|
||||
|
||||
const datefrom = ref(new Date().setFullYear(new Date().getFullYear() - 1));
|
||||
const dateto = ref(Date.now());
|
||||
|
||||
|
||||
onMounted(async () => {
|
||||
let urlParams = new URLSearchParams(window.location.search);
|
||||
if (urlParams.has('q')) {
|
||||
@@ -42,6 +45,10 @@ onMounted(async () => {
|
||||
await sleep(1000)
|
||||
await send_search_request(message.value)
|
||||
}
|
||||
|
||||
await sleep(1000)
|
||||
await reconcile_all_profiles()
|
||||
|
||||
})
|
||||
|
||||
|
||||
@@ -51,10 +58,48 @@ onMounted(async () => {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const sleep = (ms) => {
|
||||
return new Promise(resolve => setTimeout(resolve, ms))
|
||||
}
|
||||
|
||||
async function reconcile_all_profiles() {
|
||||
if (store.state.pubkey !== undefined){
|
||||
|
||||
let keys = Keys.fromSkStr("ece3c0aa759c3e895ecb3c13ab3813c0f98430c6d4bd22160b9c2219efc9cf0e")
|
||||
let db = NostrDatabase.indexeddb("profiles");
|
||||
let signer = ClientSigner.keys(keys) //TODO store keys
|
||||
dbclient = new ClientBuilder().signer(signer).database(await db).build()
|
||||
|
||||
await dbclient.addRelay("wss://relay.damus.io");
|
||||
await dbclient.connect();
|
||||
let direction = NegentropyDirection.Down;
|
||||
let opts = new NegentropyOptions().direction(direction);
|
||||
|
||||
|
||||
let followings = []
|
||||
let followers_filter = new Filter().author(store.state.pubkey).kind(3).limit(1)
|
||||
let followers = await dbclient.getEventsOf([followers_filter], 10)
|
||||
|
||||
if (followers.length > 0){
|
||||
for (let tag of followers[0].tags) {
|
||||
if (tag.asVec()[0] === "p") {
|
||||
let following = tag.asVec()[1]
|
||||
followings.push(PublicKey.fromHex(following))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
console.log("Followings: " + (followings.length).toString())
|
||||
|
||||
|
||||
let filter = new Filter().kind(0).authors(followings)
|
||||
await dbclient.reconcile(filter, opts);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function send_search_request(msg) {
|
||||
try {
|
||||
if (msg === undefined){
|
||||
@@ -89,6 +134,12 @@ async function send_search_request(msg) {
|
||||
users.push(pTag.asVec());
|
||||
}
|
||||
|
||||
if (fromuser.value !== ""){
|
||||
const userPubkey = PublicKey.fromBech32(fromuser.value.replace("@", "")).toHex()
|
||||
const pTag = Tag.parse(["p", userPubkey]);
|
||||
users.push(pTag.asVec());
|
||||
}
|
||||
|
||||
msg = search.replace(/from:|to:|@/g, '').trim();
|
||||
console.log(search);
|
||||
|
||||
@@ -166,15 +217,17 @@ async function getEvents(eventids) {
|
||||
return await client.getEventsOf([event_filter], 5)
|
||||
}
|
||||
|
||||
|
||||
async function get_user_infos(pubkeys){
|
||||
let profiles = []
|
||||
let client = store.state.client
|
||||
const profile_filter = new Filter().kind(0).authors(pubkeys)
|
||||
let evts = await client.getEventsOf([profile_filter], 10)
|
||||
console.log("PROFILES:" + evts.length)
|
||||
|
||||
for (const entry of evts){
|
||||
try{
|
||||
let contentjson = JSON.parse(entry.content)
|
||||
console.log(contentjson)
|
||||
profiles.push({profile: contentjson, author: entry.author.toHex(), createdAt: entry.createdAt});
|
||||
}
|
||||
catch(error){
|
||||
@@ -309,12 +362,12 @@ async function listen() {
|
||||
for (const evt of events) {
|
||||
let p = profiles.find(record => record.author === evt.author.toHex())
|
||||
let bech32id = evt.id.toBech32()
|
||||
let nip19 = new Nip19Event(event.id, event.author, store.state.relays)
|
||||
let nip19 = new Nip19Event(evt.id, evt.author, store.state.relays)
|
||||
let nip19bech32 = nip19.toBech32()
|
||||
let picture = p === undefined ? "../assets/nostr-purple.svg" : p["profile"]["picture"]
|
||||
let name = p === undefined ? bech32id : p["profile"]["name"]
|
||||
let highlighterurl = "https://highlighter.com/a/" + bech32id
|
||||
let njumpurl = "https://njump.me/" + bech32id
|
||||
let highlighterurl = "https://highlighter.com/e/" + nip19bech32
|
||||
let njumpurl = "https://njump.me/" + nip19bech32
|
||||
let nostrudelurl = "https://nostrudel.ninja/#/n/" + bech32id
|
||||
let uri = "nostr:" + bech32id // nip19.toNostrUri()
|
||||
|
||||
@@ -379,6 +432,46 @@ function nextInput(e) {
|
||||
}
|
||||
}
|
||||
|
||||
async function checkuser(msg){
|
||||
usernames = []
|
||||
let profiles = await get_user_from_search(msg)
|
||||
for (let profile of profiles){
|
||||
usernames.push(profile)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
async function get_user_from_search(name){
|
||||
name = "\"name\":" + name
|
||||
let profiles = []
|
||||
let filter1 = new Filter().kind(0).search(name)
|
||||
let evts = await dbclient.database.query([filter1])
|
||||
|
||||
|
||||
|
||||
//const profile_filter = new Filter().kind(0).search(name)
|
||||
//let evts = await client.getEventsOf([profile_filter], 3)
|
||||
|
||||
for (const entry of evts){
|
||||
try{
|
||||
let contentjson = JSON.parse(entry.content)
|
||||
//console.log(entry.content)
|
||||
profiles.push({profile: contentjson, author: entry.author.toBech32(), createdAt: entry.createdAt});
|
||||
}
|
||||
catch(error){
|
||||
console.log(error)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return profiles
|
||||
|
||||
}
|
||||
|
||||
defineProps({
|
||||
msg: {
|
||||
type: String,
|
||||
@@ -386,6 +479,9 @@ defineProps({
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
@@ -399,13 +495,37 @@ defineProps({
|
||||
Search the Nostr with Data Vending Machines</h2>
|
||||
<h3>
|
||||
<br>
|
||||
<input class="c-Input" type="search" name="s" autofocus placeholder="Search..." v-model="message" @keyup.enter="send_search_request(message)" @keydown.enter="nextInput">
|
||||
<button class="v-Button" @click="send_search_request(message)">Search the Nostr</button>
|
||||
|
||||
<input class="c-Input" type="search" name="s" autofocus placeholder="Search..." v-model="message" @keyup.enter="send_search_request(message)" @keydown.enter="nextInput">
|
||||
|
||||
|
||||
|
||||
<button class="v-Button" @click="send_search_request(message)">Search the Nostr</button>
|
||||
</h3>
|
||||
|
||||
<details class="collapse bg-base " className="advanced" >
|
||||
<summary class="collapse-title font-thin bg">Advanced Options</summary>
|
||||
<div class="collapse-content font-size-0" className="z-10" id="collapse-settings">
|
||||
|
||||
<div>
|
||||
<h4 className="inline-flex flex-none font-thin">by: </h4>
|
||||
<div className="inline-flex flex-none" style="width: 10px;"></div>
|
||||
<input list="users" id="user" class="u-Input" style="margin-left: 10px" type="search" name="user" autofocus placeholder="npub..." v-model="fromuser" @input="checkuser(fromuser)">
|
||||
|
||||
<datalist id="users">
|
||||
<option v-for="profile in usernames" :value="profile.author">
|
||||
|
||||
{{profile.profile.name + ' (' + profile.profile.nip05 + ')'}}
|
||||
|
||||
</option>
|
||||
</datalist>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div className="inline-flex flex-none" style="width: 20px;"></div>
|
||||
|
||||
<div>
|
||||
<h4 className="inline-flex flex-none font-thin">from:</h4>
|
||||
<div className="inline-flex flex-none" style="width: 10px;"></div>
|
||||
@@ -418,10 +538,7 @@ defineProps({
|
||||
<div className="inline-flex flex-none" style="width: 10px;"></div>
|
||||
<VueDatePicker :teleport="true" :dark="true" position="left" className="bg-base-200 inline-flex flex-none" style="width: 220px;" v-model="dateto"></VueDatePicker>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</details>
|
||||
|
||||
</div>
|
||||
<div class="max-w-5xl relative space-y-3">
|
||||
<div class="grid grid-cols-1 gap-6">
|
||||
@@ -465,6 +582,15 @@ defineProps({
|
||||
|
||||
}
|
||||
|
||||
.u-Input {
|
||||
@apply bg-base-200 text-accent dark:bg-base-200 dark:text-white focus:ring-white border border-transparent px-3 py-1.5 text-sm leading-4 text-accent-content transition-colors duration-300 focus:ring-offset-2 focus:ring-offset-white dark:focus:ring-offset-gray-900;
|
||||
|
||||
width: 220px;
|
||||
height: 35px;
|
||||
|
||||
|
||||
}
|
||||
|
||||
.logo {
|
||||
display: flex;
|
||||
width:100%;
|
||||
@@ -485,8 +611,11 @@ h4 {
|
||||
.greetings h3 {
|
||||
text-align: center;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@media (min-width: 1000px) {
|
||||
|
||||
.greetings h1,
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
<div style="padding: 2px; text-align: left;" >
|
||||
<a class="menusmall" :href="links.uri" target="_blank">Nostr Client</a>
|
||||
<a class="menusmall" :href="links.njump" target="_blank">NJump</a>
|
||||
<a class="menusmall" :href="links.highlighter" target="_blank">Highlighter</a>
|
||||
<!-- <a class="menusmall":href="links.nostrudel" target="_blank">Nostrudel</a> -->
|
||||
<!--<a class="menusmall" :href="links.highlighter" target="_blank">Highlighter</a> -->
|
||||
<a class="menusmall":href="links.nostrudel" target="_blank">Nostrudel</a>
|
||||
</div>
|
||||
<!-- <p>{{content}}</p> -->
|
||||
</template>
|
||||
|
||||
@@ -1,250 +0,0 @@
|
||||
[
|
||||
{"name": "Albania"},
|
||||
{"name": "Åland Islands"},
|
||||
{"name": "Algeria"},
|
||||
{"name": "American Samoa"},
|
||||
{"name": "Andorra"},
|
||||
{"name": "Angola"},
|
||||
{"name": "Anguilla"},
|
||||
{"name": "Antarctica"},
|
||||
{"name": "Antigua and Barbuda"},
|
||||
{"name": "Argentina"},
|
||||
{"name": "Armenia"},
|
||||
{"name": "Aruba"},
|
||||
{"name": "Australia"},
|
||||
{"name": "Austria"},
|
||||
{"name": "Azerbaijan"},
|
||||
{"name": "Bahamas (the)"},
|
||||
{"name": "Bahrain"},
|
||||
{"name": "Bangladesh"},
|
||||
{"name": "Barbados"},
|
||||
{"name": "Belarus"},
|
||||
{"name": "Belgium"},
|
||||
{"name": "Belize"},
|
||||
{"name": "Benin"},
|
||||
{"name": "Bermuda"},
|
||||
{"name": "Bhutan"},
|
||||
{"name": "Bolivia (Plurinational State of)"},
|
||||
{"name": "Bonaire, Sint Eustatius and Saba"},
|
||||
{"name": "Bosnia and Herzegovina"},
|
||||
{"name": "Botswana"},
|
||||
{"name": "Bouvet Island"},
|
||||
{"name": "Brazil"},
|
||||
{"name": "British Indian Ocean Territory (the)"},
|
||||
{"name": "Brunei Darussalam"},
|
||||
{"name": "Bulgaria"},
|
||||
{"name": "Burkina Faso"},
|
||||
{"name": "Burundi"},
|
||||
{"name": "Cabo Verde"},
|
||||
{"name": "Cambodia"},
|
||||
{"name": "Cameroon"},
|
||||
{"name": "Canada"},
|
||||
{"name": "Cayman Islands (the)"},
|
||||
{"name": "Central African Republic (the)"},
|
||||
{"name": "Chad"},
|
||||
{"name": "Chile"},
|
||||
{"name": "China"},
|
||||
{"name": "Christmas Island"},
|
||||
{"name": "Cocos (Keeling) Islands (the)"},
|
||||
{"name": "Colombia"},
|
||||
{"name": "Comoros (the)"},
|
||||
{"name": "Congo (the Democratic Republic of the)"},
|
||||
{"name": "Congo (the)"},
|
||||
{"name": "Cook Islands (the)"},
|
||||
{"name": "Costa Rica"},
|
||||
{"name": "Croatia"},
|
||||
{"name": "Cuba"},
|
||||
{"name": "Curaçao"},
|
||||
{"name": "Cyprus"},
|
||||
{"name": "Czechia"},
|
||||
{"name": "Côte d'Ivoire"},
|
||||
{"name": "Denmark"},
|
||||
{"name": "Djibouti"},
|
||||
{"name": "Dominica"},
|
||||
{"name": "Dominican Republic (the)"},
|
||||
{"name": "Ecuador"},
|
||||
{"name": "Egypt"},
|
||||
{"name": "El Salvador"},
|
||||
{"name": "Equatorial Guinea"},
|
||||
{"name": "Eritrea"},
|
||||
{"name": "Estonia"},
|
||||
{"name": "Eswatini"},
|
||||
{"name": "Ethiopia"},
|
||||
{"name": "Falkland Islands (the) [Malvinas]"},
|
||||
{"name": "Faroe Islands (the)"},
|
||||
{"name": "Fiji"},
|
||||
{"name": "Finland"},
|
||||
{"name": "France"},
|
||||
{"name": "French Guiana"},
|
||||
{"name": "French Polynesia"},
|
||||
{"name": "French Southern Territories (the)"},
|
||||
{"name": "Gabon"},
|
||||
{"name": "Gambia (the)"},
|
||||
{"name": "Georgia"},
|
||||
{"name": "Germany"},
|
||||
{"name": "Ghana"},
|
||||
{"name": "Gibraltar"},
|
||||
{"name": "Greece"},
|
||||
{"name": "Greenland"},
|
||||
{"name": "Grenada"},
|
||||
{"name": "Guadeloupe"},
|
||||
{"name": "Guam"},
|
||||
{"name": "Guatemala"},
|
||||
{"name": "Guernsey"},
|
||||
{"name": "Guinea"},
|
||||
{"name": "Guinea-Bissau"},
|
||||
{"name": "Guyana"},
|
||||
{"name": "Haiti"},
|
||||
{"name": "Heard Island and McDonald Islands"},
|
||||
{"name": "Holy See (the)"},
|
||||
{"name": "Honduras"},
|
||||
{"name": "Hong Kong"},
|
||||
{"name": "Hungary"},
|
||||
{"name": "Iceland"},
|
||||
{"name": "India"},
|
||||
{"name": "Indonesia"},
|
||||
{"name": "Iran (Islamic Republic of)"},
|
||||
{"name": "Iraq"},
|
||||
{"name": "Ireland"},
|
||||
{"name": "Isle of Man"},
|
||||
{"name": "Israel"},
|
||||
{"name": "Italy"},
|
||||
{"name": "Jamaica"},
|
||||
{"name": "Japan"},
|
||||
{"name": "Jersey"},
|
||||
{"name": "Jordan"},
|
||||
{"name": "Kazakhstan"},
|
||||
{"name": "Kenya"},
|
||||
{"name": "Kiribati"},
|
||||
{"name": "Korea (the Democratic People's Republic of)"},
|
||||
{"name": "Korea (the Republic of)"},
|
||||
{"name": "Kuwait"},
|
||||
{"name": "Kyrgyzstan"},
|
||||
{"name": "Lao People's Democratic Republic (the)"},
|
||||
{"name": "Latvia"},
|
||||
{"name": "Lebanon"},
|
||||
{"name": "Lesotho"},
|
||||
{"name": "Liberia"},
|
||||
{"name": "Libya"},
|
||||
{"name": "Liechtenstein"},
|
||||
{"name": "Lithuania"},
|
||||
{"name": "Luxembourg"},
|
||||
{"name": "Macao"},
|
||||
{"name": "Madagascar"},
|
||||
{"name": "Malawi"},
|
||||
{"name": "Malaysia"},
|
||||
{"name": "Maldives"},
|
||||
{"name": "Mali"},
|
||||
{"name": "Malta"},
|
||||
{"name": "Marshall Islands (the)"},
|
||||
{"name": "Martinique"},
|
||||
{"name": "Mauritania"},
|
||||
{"name": "Mauritius"},
|
||||
{"name": "Mayotte"},
|
||||
{"name": "Mexico"},
|
||||
{"name": "Micronesia (Federated States of)"},
|
||||
{"name": "Moldova (the Republic of)"},
|
||||
{"name": "Monaco"},
|
||||
{"name": "Mongolia"},
|
||||
{"name": "Montenegro"},
|
||||
{"name": "Montserrat"},
|
||||
{"name": "Morocco"},
|
||||
{"name": "Mozambique"},
|
||||
{"name": "Myanmar"},
|
||||
{"name": "Namibia"},
|
||||
{"name": "Nauru"},
|
||||
{"name": "Nepal"},
|
||||
{"name": "Netherlands (the)"},
|
||||
{"name": "New Caledonia"},
|
||||
{"name": "New Zealand"},
|
||||
{"name": "Nicaragua"},
|
||||
{"name": "Niger (the)"},
|
||||
{"name": "Nigeria"},
|
||||
{"name": "Niue"},
|
||||
{"name": "Norfolk Island"},
|
||||
{"name": "Northern Mariana Islands (the)"},
|
||||
{"name": "Norway"},
|
||||
{"name": "Oman"},
|
||||
{"name": "Pakistan"},
|
||||
{"name": "Palau"},
|
||||
{"name": "Palestine, State of"},
|
||||
{"name": "Panama"},
|
||||
{"name": "Papua New Guinea"},
|
||||
{"name": "Paraguay"},
|
||||
{"name": "Peru"},
|
||||
{"name": "Philippines (the)"},
|
||||
{"name": "Pitcairn"},
|
||||
{"name": "Poland"},
|
||||
{"name": "Portugal"},
|
||||
{"name": "Puerto Rico"},
|
||||
{"name": "Qatar"},
|
||||
{"name": "Republic of North Macedonia"},
|
||||
{"name": "Romania"},
|
||||
{"name": "Russian Federation (the)"},
|
||||
{"name": "Rwanda"},
|
||||
{"name": "Réunion"},
|
||||
{"name": "Saint Barthélemy"},
|
||||
{"name": "Saint Helena, Ascension and Tristan da Cunha"},
|
||||
{"name": "Saint Kitts and Nevis"},
|
||||
{"name": "Saint Lucia"},
|
||||
{"name": "Saint Martin (French part)"},
|
||||
{"name": "Saint Pierre and Miquelon"},
|
||||
{"name": "Saint Vincent and the Grenadines"},
|
||||
{"name": "Samoa"},
|
||||
{"name": "San Marino"},
|
||||
{"name": "Sao Tome and Principe"},
|
||||
{"name": "Saudi Arabia"},
|
||||
{"name": "Senegal"},
|
||||
{"name": "Serbia"},
|
||||
{"name": "Seychelles"},
|
||||
{"name": "Sierra Leone"},
|
||||
{"name": "Singapore"},
|
||||
{"name": "Sint Maarten (Dutch part)"},
|
||||
{"name": "Slovakia"},
|
||||
{"name": "Slovenia"},
|
||||
{"name": "Solomon Islands"},
|
||||
{"name": "Somalia"},
|
||||
{"name": "South Africa"},
|
||||
{"name": "South Georgia and the South Sandwich Islands"},
|
||||
{"name": "South Sudan"},
|
||||
{"name": "Spain"},
|
||||
{"name": "Sri Lanka"},
|
||||
{"name": "Sudan (the)"},
|
||||
{"name": "Suriname"},
|
||||
{"name": "Svalbard and Jan Mayen"},
|
||||
{"name": "Sweden"},
|
||||
{"name": "Switzerland"},
|
||||
{"name": "Syrian Arab Republic"},
|
||||
{"name": "Taiwan (Province of China)"},
|
||||
{"name": "Tajikistan"},
|
||||
{"name": "Tanzania, United Republic of"},
|
||||
{"name": "Thailand"},
|
||||
{"name": "Timor-Leste"},
|
||||
{"name": "Togo"},
|
||||
{"name": "Tokelau"},
|
||||
{"name": "Tonga"},
|
||||
{"name": "Trinidad and Tobago"},
|
||||
{"name": "Tunisia"},
|
||||
{"name": "Turkey"},
|
||||
{"name": "Turkmenistan"},
|
||||
{"name": "Turks and Caicos Islands (the)"},
|
||||
{"name": "Tuvalu"},
|
||||
{"name": "Uganda"},
|
||||
{"name": "Ukraine"},
|
||||
{"name": "United Arab Emirates (the)"},
|
||||
{"name": "United Kingdom of Great Britain and Northern Ireland (the)"},
|
||||
{"name": "United States Minor Outlying Islands (the)"},
|
||||
{"name": "United States of America (the)"},
|
||||
{"name": "Uruguay"},
|
||||
{"name": "Uzbekistan"},
|
||||
{"name": "Vanuatu"},
|
||||
{"name": "Venezuela (Bolivarian Republic of)"},
|
||||
{"name": "Viet Nam"},
|
||||
{"name": "Virgin Islands (British)"},
|
||||
{"name": "Virgin Islands (U.S.)"},
|
||||
{"name": "Wallis and Futuna"},
|
||||
{"name": "Western Sahara"},
|
||||
{"name": "Yemen"},
|
||||
{"name": "Zambia"},
|
||||
{"name": "Zimbabwe", "code": "ZW"}
|
||||
]
|
||||
@@ -1,4 +0,0 @@
|
||||
[
|
||||
{"id": "1c986b929f61d7a696719c9f92d41e2163e82c0fcdf30779a09f9b70886ad59c", "name": "Noogle: Latest" },
|
||||
{"id": "d70aea7efa004887514b0c6b53d0448029303989c6fc33ba37f2315ca77a4170", "name": "Noogle: One year ago"}
|
||||
]
|
||||
Reference in New Issue
Block a user