├── .npmignore ├── server ├── public │ ├── robots.txt │ ├── favicon.ico │ ├── sharingimage.png │ ├── images │ │ ├── sharing.png │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── mstile-70x70.png │ │ ├── mstile-144x144.png │ │ ├── mstile-150x150.png │ │ ├── mstile-310x150.png │ │ ├── mstile-310x310.png │ │ ├── apple-touch-icon.png │ │ ├── android-chrome-192x192.png │ │ ├── android-chrome-512x512.png │ │ ├── icon.svg │ │ └── safari-pinned-tab.svg │ ├── fonts │ │ ├── Roboto-Medium.ttf │ │ └── Roboto-Regular.ttf │ ├── assets │ │ └── images │ │ │ ├── icon_dsearch.jpg │ │ │ ├── logo_dsearch.png │ │ │ ├── alert-triangle.svg │ │ │ ├── icon_presearch.svg │ │ │ ├── icon_dsearch.svg │ │ │ ├── logo_p_new.svg │ │ │ ├── logo_presearch.svg │ │ │ └── logo_presearch_new.svg │ ├── service-worker.js │ ├── browserconfig.xml │ ├── site.webmanifest │ └── results.json ├── views │ ├── _partials │ │ ├── sidebar.pug │ │ ├── icons │ │ │ ├── results │ │ │ │ ├── next.pug │ │ │ │ ├── prev.pug │ │ │ │ ├── videos.pug │ │ │ │ └── news.pug │ │ │ ├── header │ │ │ │ ├── chevron-down.pug │ │ │ │ ├── keyword_staking.pug │ │ │ │ ├── menu.pug │ │ │ │ ├── arrow-left.pug │ │ │ │ ├── all.pug │ │ │ │ ├── account.pug │ │ │ │ ├── share.pug │ │ │ │ ├── videos.pug │ │ │ │ ├── nodes.pug │ │ │ │ ├── marketplace.pug │ │ │ │ ├── images.pug │ │ │ │ ├── logo-p_.pug │ │ │ │ ├── news.pug │ │ │ │ ├── sun.pug │ │ │ │ ├── features.pug │ │ │ │ ├── logo-presearch.pug │ │ │ │ └── moon.pug │ │ │ ├── providers │ │ │ │ └── p_.pug │ │ │ ├── social │ │ │ │ ├── facebook.pug │ │ │ │ ├── instagram.pug │ │ │ │ ├── twitter.pug │ │ │ │ └── youtube.pug │ │ │ └── home │ │ │ │ ├── logo-p_.pug │ │ │ │ └── logo-presearch.pug │ │ ├── user-info-mobile.pug │ │ ├── user-info-homepage.pug │ │ ├── user-info.pug │ │ ├── footer.pug │ │ ├── presearch-package.pug │ │ ├── providers-mobile.pug │ │ ├── error.pug │ │ ├── ad.pug │ │ ├── providers-desktop.pug │ │ ├── search-form.pug │ │ ├── standard-results.pug │ │ ├── settings.pug │ │ ├── header.pug │ │ └── special-sections │ │ │ └── info.pug │ ├── search.pug │ ├── wrapper.pug │ ├── nonPug │ │ ├── opensearch.xml.js │ │ └── error.js │ ├── _layout.pug │ └── index.pug ├── .env-example ├── package.json └── index.js ├── .github └── ISSUE_TEMPLATE │ ├── custom.md │ ├── feature_request.md │ └── bug_report.md ├── .editorconfig ├── packages ├── map │ ├── jwt.js │ ├── package.json │ └── generateKey.js ├── flight │ └── package.json ├── math │ └── package.json ├── userAgents │ ├── package.json │ └── index.js ├── stopWatch │ ├── package.json │ └── index.js ├── daysOfTheYear │ ├── package.json │ └── index.js ├── presearchNews │ └── package.json ├── periodicElements │ ├── package.json │ ├── yarn.lock │ ├── package-lock.json │ └── index.js ├── colorGenerator │ └── package.json ├── starWarsQuote │ ├── package.json │ └── index.js ├── weather │ └── package.json ├── colorPicker │ └── package.json ├── openSea │ └── package.json ├── emoji │ ├── package.json │ └── index.js ├── passwordGenerator │ ├── package.json │ ├── services.test.js │ ├── services.js │ └── index.js ├── loremIpsumGenerator │ ├── package.json │ ├── services.test.js │ ├── services.js │ └── index.js ├── cryptoInfo │ ├── package.json │ └── package-lock.json └── currencyConverter │ ├── package.json │ ├── services.test.js │ ├── fiatCurrencies.json │ └── index.js ├── index.js ├── bin ├── merge-dependencies.js └── create-package.sh ├── .gitignore ├── package.json ├── CHANGELOG.md ├── common.css ├── create-package.js └── README.md /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | server/node_modules 3 | -------------------------------------------------------------------------------- /server/public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | Crawl-delay: 10 4 | -------------------------------------------------------------------------------- /server/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PresearchOfficial/presearch-packages/HEAD/server/public/favicon.ico -------------------------------------------------------------------------------- /server/public/sharingimage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PresearchOfficial/presearch-packages/HEAD/server/public/sharingimage.png -------------------------------------------------------------------------------- /server/public/images/sharing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PresearchOfficial/presearch-packages/HEAD/server/public/images/sharing.png -------------------------------------------------------------------------------- /server/views/_partials/sidebar.pug: -------------------------------------------------------------------------------- 1 | div(class="w-40 lg:w-56 md:w-44 flex-none hidden md:block") 2 | include ./providers-desktop 3 | -------------------------------------------------------------------------------- /server/public/fonts/Roboto-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PresearchOfficial/presearch-packages/HEAD/server/public/fonts/Roboto-Medium.ttf -------------------------------------------------------------------------------- /server/public/fonts/Roboto-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PresearchOfficial/presearch-packages/HEAD/server/public/fonts/Roboto-Regular.ttf -------------------------------------------------------------------------------- /server/public/images/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PresearchOfficial/presearch-packages/HEAD/server/public/images/favicon-16x16.png -------------------------------------------------------------------------------- /server/public/images/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PresearchOfficial/presearch-packages/HEAD/server/public/images/favicon-32x32.png -------------------------------------------------------------------------------- /server/public/images/mstile-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PresearchOfficial/presearch-packages/HEAD/server/public/images/mstile-70x70.png -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/custom.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Custom issue template 3 | about: Describe this issue template's purpose here. 4 | 5 | --- 6 | 7 | 8 | -------------------------------------------------------------------------------- /server/public/images/mstile-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PresearchOfficial/presearch-packages/HEAD/server/public/images/mstile-144x144.png -------------------------------------------------------------------------------- /server/public/images/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PresearchOfficial/presearch-packages/HEAD/server/public/images/mstile-150x150.png -------------------------------------------------------------------------------- /server/public/images/mstile-310x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PresearchOfficial/presearch-packages/HEAD/server/public/images/mstile-310x150.png -------------------------------------------------------------------------------- /server/public/images/mstile-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PresearchOfficial/presearch-packages/HEAD/server/public/images/mstile-310x310.png -------------------------------------------------------------------------------- /server/public/images/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PresearchOfficial/presearch-packages/HEAD/server/public/images/apple-touch-icon.png -------------------------------------------------------------------------------- /server/public/assets/images/icon_dsearch.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PresearchOfficial/presearch-packages/HEAD/server/public/assets/images/icon_dsearch.jpg -------------------------------------------------------------------------------- /server/public/assets/images/logo_dsearch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PresearchOfficial/presearch-packages/HEAD/server/public/assets/images/logo_dsearch.png -------------------------------------------------------------------------------- /server/public/images/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PresearchOfficial/presearch-packages/HEAD/server/public/images/android-chrome-192x192.png -------------------------------------------------------------------------------- /server/public/images/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PresearchOfficial/presearch-packages/HEAD/server/public/images/android-chrome-512x512.png -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true -------------------------------------------------------------------------------- /packages/map/jwt.js: -------------------------------------------------------------------------------- 1 | const generateJwt = require("./generateKey"); 2 | 3 | const args = process.argv.slice(2); 4 | const [seconds] = args; 5 | 6 | console.log("JWT:", generateJwt(seconds ? parseInt(seconds, 10) : undefined)); -------------------------------------------------------------------------------- /server/public/service-worker.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | self.addEventListener("install", function(e) { 3 | return self.skipWaiting(); 4 | }), 5 | self.addEventListener("activate", function(e) { 6 | return self.clients.claim(); 7 | }); -------------------------------------------------------------------------------- /server/views/_partials/icons/results/next.pug: -------------------------------------------------------------------------------- 1 | svg(class="h-4 w-4" fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 407.436 407.436") 2 | path(d="M112.814 0L91.566 21.178l181.946 182.54-181.946 182.54 21.248 21.178 203.055-203.718z") -------------------------------------------------------------------------------- /server/views/_partials/icons/results/prev.pug: -------------------------------------------------------------------------------- 1 | svg(class="h-4 w-4 transform rotate-180" fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 407.436 407.436") 2 | path(d="M112.814 0L91.566 21.178l181.946 182.54-181.946 182.54 21.248 21.178 203.055-203.718z") -------------------------------------------------------------------------------- /packages/flight/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name":"flight", 3 | "version":"1.0.0", 4 | "description":"", 5 | "main":"index.js", 6 | "scripts":{ 7 | "test":"echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords":[], 10 | "author":"Marijuš Mackevič", 11 | "license":"MIT" 12 | } -------------------------------------------------------------------------------- /packages/math/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "math", 3 | "description": "Calculator", 4 | "version": "1.0.9", 5 | "main": "index.js", 6 | "license": "MIT", 7 | "author": "Ishan-Ravindu, Joshua Paul Barnard", 8 | "dependencies": { 9 | "mathjs": "^9.5.1" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/userAgents/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name":"useragents", 3 | "version":"1.0.0", 4 | "description":"", 5 | "main":"index.js", 6 | "scripts":{ 7 | "test":"echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords":[], 10 | "author":"Phil Parr", 11 | "license":"MIT" 12 | } -------------------------------------------------------------------------------- /packages/stopWatch/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name":"stopWatch", 3 | "version":"1.0.0", 4 | "description":"", 5 | "main":"index.js", 6 | "scripts":{ 7 | "test":"echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords":[], 10 | "author":"Ishan-Ravindu", 11 | "license":"MIT" 12 | } -------------------------------------------------------------------------------- /server/views/_partials/icons/header/chevron-down.pug: -------------------------------------------------------------------------------- 1 | svg(class="w-3 h-3" fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 407.437 407.437") 2 | path(d="M386.258 91.567l-182.54 181.945L21.179 91.567 0 112.815 203.718 315.87l203.719-203.055z" stroke="currentColor" stroke-width="8") -------------------------------------------------------------------------------- /server/.env-example: -------------------------------------------------------------------------------- 1 | # Here's the place for your API keys 2 | # You need to create env variable by following pattern API.{YOUR_PACKAGE_NAME - this should be uppercase, just line on the example below} 3 | 4 | NODE_ENV=development 5 | API.YOURPACKAGENAME=123123 6 | 7 | # Remember to rename the file to .env -------------------------------------------------------------------------------- /packages/daysOfTheYear/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name":"daysoftheyear", 3 | "version":"1.0.0", 4 | "description":"", 5 | "main":"index.js", 6 | "scripts":{ 7 | "test":"echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords":[], 10 | "author":"Marijuš Mackevič", 11 | "license":"MIT" 12 | } -------------------------------------------------------------------------------- /packages/presearchNews/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name":"presearchnews", 3 | "version":"1.1.0", 4 | "description":"", 5 | "main":"index.js", 6 | "scripts":{ 7 | "test":"echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords":[], 10 | "author":"Marijuš Mackevič", 11 | "license":"MIT" 12 | } -------------------------------------------------------------------------------- /packages/periodicElements/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "periodicElements", 3 | "description": "Periodic Elements", 4 | "version": "1.0.0", 5 | "main": "index.js", 6 | "license": "MIT", 7 | "author": "PresearchOffical", 8 | "dependencies": { 9 | "periodic-table": "^0.0.8" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/periodicElements/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | periodic-table@^0.0.8: 6 | version "0.0.8" 7 | resolved "https://registry.yarnpkg.com/periodic-table/-/periodic-table-0.0.8.tgz#aa497dbbf5a97c23f7791aea6aabb30df196e858" 8 | -------------------------------------------------------------------------------- /packages/colorGenerator/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "colorgenerator", 3 | "version": "1.0.0", 4 | "description": "Generate random colors", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "jejopl", 10 | "license": "MIT" 11 | } 12 | -------------------------------------------------------------------------------- /packages/starWarsQuote/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "starWarsQuote", 3 | "version": "1.0.0", 4 | "description": "Star Wars Quote", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "PresearchOfficial", 10 | "license": "MIT" 11 | } 12 | -------------------------------------------------------------------------------- /packages/map/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "map", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "scripts": { 6 | "test": "echo \"Error: no test specified\" && exit 1" 7 | }, 8 | "keywords": [], 9 | "author": "Joshua Paul Barnard", 10 | "license": "MIT", 11 | "description": "", 12 | "order": "1" 13 | } 14 | -------------------------------------------------------------------------------- /packages/weather/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "weather", 3 | "version": "1.0.1", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "Marijuš Mackevič", 11 | "license": "MIT", 12 | "order": "1" 13 | } 14 | -------------------------------------------------------------------------------- /server/views/_partials/icons/header/keyword_staking.pug: -------------------------------------------------------------------------------- 1 | svg(class="w-6 h-6" fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 482 482") 2 | path(d="M189.9 441.4H147V52c0-7.7 4.1-14.7 10.7-18.6s14.8-3.8 21.5 0l215.6 124.4c7.3 4.2 11.5 12.4 10.6 20.8-.9 8.4-6.7 15.5-14.7 18.2l-200.8 64.9v179.7zm0-352.2v127.5l141.6-45.8-141.6-81.7z") -------------------------------------------------------------------------------- /packages/colorPicker/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "colorPicker", 3 | "version": "2.0.0", 4 | "description": "Javascript color picker and converter", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "jejopl", 10 | "license": "MIT", 11 | "dependencies": {} 12 | } 13 | -------------------------------------------------------------------------------- /packages/openSea/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "opensea", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "Awa Dieudonne", 10 | "license": "MIT", 11 | "dependencies": { 12 | "ethereum-address": "^0.0.4" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /packages/emoji/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "emoji", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "ishan27596", 11 | "license": "MIT", 12 | "dependencies": { 13 | "emoji-api": "^2.0.1", 14 | "emoji-regex": "^10.0.0" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/passwordGenerator/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "passwordGenerator", 3 | "version": "1.0.0", 4 | "description": "Generate random password", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "jest --watch" 8 | }, 9 | "keywords": [], 10 | "author": "Alexander Gerk, Essel Adjei-Mensah", 11 | "license": "MIT", 12 | "devDependencies": { 13 | "jest": "^27.4.5" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('fs'); 4 | 5 | const moduleExports = {}; 6 | 7 | fs.readdir(`${__dirname}/packages`, (err, dirs) => { 8 | if (!err) { 9 | dirs = dirs.filter(dir => dir[0] !== '.'); 10 | dirs.map(dir => moduleExports[dir] = require(`${__dirname}/packages/${dir}`)) 11 | } 12 | else { 13 | throw err; 14 | } 15 | }); 16 | 17 | module.exports = moduleExports; 18 | -------------------------------------------------------------------------------- /packages/loremIpsumGenerator/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "loremIpsumGenerator", 3 | "version": "1.0.0", 4 | "description": "Generate a random lorem ipsum", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "jest --watch" 8 | }, 9 | "keywords": [], 10 | "author": "Alexander Gerk, Essel Adjei-Mensah", 11 | "license": "MIT", 12 | "devDependencies": { 13 | "jest": "^27.4.5" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/periodicElements/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "periodicElements", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "periodic-table": { 8 | "version": "0.0.8", 9 | "resolved": "https://registry.npmjs.org/periodic-table/-/periodic-table-0.0.8.tgz", 10 | "integrity": "sha1-qkl9u/WpfCP3eRrqaquzDfGW6Fg=" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/cryptoInfo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cryptoInfo", 3 | "version": "1.1.0", 4 | "description": "Cryptocurrency Information Package", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "PresearchOfficial", 11 | "license": "MIT", 12 | "dependencies": { 13 | "dotenv": "^10.0.0", 14 | "node-fetch": "^2.6.7" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /server/public/assets/images/alert-triangle.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /server/views/_partials/user-info-mobile.pug: -------------------------------------------------------------------------------- 1 | div(class="font-light flex mr-3 md:pb-0 md:mr-0" x-cloak) 2 | div(class="flex items-center") 3 | span(class="w-px h-5 bg-gray-400 dark:bg-gray-200 ml-3 mr-1 md:ml-4 md:mr-2") 4 | a(x-on:mouseover="showSettings(true, true)" x-on:mouseleave="blockShowSettings(true)" @click="showSettingsOnClick()" class="transition hover:opacity-60 p-2 cursor-pointer text-gray-700 dark:text-white") 5 | include ./icons/header/menu -------------------------------------------------------------------------------- /packages/currencyConverter/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "currencyConverter", 3 | "version": "1.1.0", 4 | "description": "Convert currencies", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "jest --watch" 8 | }, 9 | "keywords": [], 10 | "author": "Niklas Ekman, Joshua Tomajko, Alex Vernacchia", 11 | "license": "MIT", 12 | "dependencies": { 13 | "axios": "^0.24.0" 14 | }, 15 | "devDependencies": { 16 | "jest": "^27.4.5" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "presearch-packages-test-server", 3 | "version": "0.1.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "nodemon --watch ../ index.js", 8 | "map:jwt": "node ../packages/map/jwt.js" 9 | }, 10 | "dependencies": { 11 | "dotenv": "^10.0.0", 12 | "express": "^4.18.2", 13 | "nodemon": "^2.0.20", 14 | "pug": "^3.0.2" 15 | }, 16 | "author": "", 17 | "license": "MIT" 18 | } 19 | -------------------------------------------------------------------------------- /server/public/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | #2d8eff 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /server/views/_partials/user-info-homepage.pug: -------------------------------------------------------------------------------- 1 | div(class="font-light flex mr-3 md:pb-0 md:mr-0" x-cloak) 2 | div(class="flex items-center") 3 | div(x-on:mouseover="blockShowSettings(true)" class="px-3 flex items-center") 4 | span(class="h-5 bg-gray-400 dark:bg-gray-200") 5 | a(x-on:mouseover="showSettings(false, false, true)" x-on:mouseleave="blockShowSettings(true)" @click="showSettingsOnClick()" class="transition cursor-pointer text-white dark:text-white p-1 hover:opacity-60") 6 | include ./icons/header/menu -------------------------------------------------------------------------------- /server/views/_partials/user-info.pug: -------------------------------------------------------------------------------- 1 | div(class="font-light flex mr-3 md:pb-0 md:mr-0" x-cloak) 2 | div(class="flex items-center") 3 | div(x-on:mouseover="blockShowSettings(true)" class="px-3 flex items-center") 4 | span(class="w-px h-5 bg-gray-400 dark:bg-gray-200") 5 | a(x-on:mouseover="showSettings(false, false, true)" x-on:mouseleave="blockShowSettings(true)" @click="showSettingsOnClick()" class="transition hover:opacity-60 cursor-pointer text-gray-700 p-1 dark:text-white") 6 | include ./icons/header/menu -------------------------------------------------------------------------------- /server/views/_partials/icons/header/menu.pug: -------------------------------------------------------------------------------- 1 | svg(class="w-4 h-4" fill="currentColor" viewBox="0 -53 384 384" xmlns="http://www.w3.org/2000/svg") 2 | path(d="m368 154.667969h-352c-8.832031 0-16-7.167969-16-16s7.167969-16 16-16h352c8.832031 0 16 7.167969 16 16s-7.167969 16-16 16zm0 0") 3 | path(d="m368 32h-352c-8.832031 0-16-7.167969-16-16s7.167969-16 16-16h352c8.832031 0 16 7.167969 16 16s-7.167969 16-16 16zm0 0") 4 | path(d="m368 277.332031h-352c-8.832031 0-16-7.167969-16-16s7.167969-16 16-16h352c8.832031 0 16 7.167969 16 16s-7.167969 16-16 16zm0 0") -------------------------------------------------------------------------------- /server/views/_partials/icons/providers/p_.pug: -------------------------------------------------------------------------------- 1 | svg(class="text-white" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 1000 1000") 2 | path(d="M538.7 627.7c30-14.5 56.6-35.1 78.1-60.4 21.8-25.8 38.7-55.2 50.2-86.9 11.9-32.2 18-66.4 18-100.7-.1-33.8-6.6-67.1-19.1-98.6-12.2-31.6-29.8-60.9-52-86.5-22.4-25.5-49.4-46.4-79.7-61.7-31.4-15.9-66.2-24-101.3-23.7H109.8V891h205.6V650.2h122.4c35 .4 69.5-7.4 100.9-22.5zM315.4 463.6V296.2h103.5c14.4.8 28 7.2 37.9 17.7 12.7 11.8 19.1 33.9 19.1 66.1s-5.4 54.1-16.2 65.5a47.66 47.66 0 01-35.4 18.1H315.4z") 3 | path(d="M407.5 742.3h482.7v148.6H407.5z") -------------------------------------------------------------------------------- /server/public/site.webmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Presearch", 3 | "short_name": "Presearch", 4 | "icons": [ 5 | { 6 | "src": "/images/android-chrome-192x192.png", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | }, 10 | { 11 | "src": "/images/android-chrome-512x512.png", 12 | "sizes": "512x512", 13 | "type": "image/png" 14 | } 15 | ], 16 | "theme_color": "#ffffff", 17 | "background_color": "#ffffff", 18 | "start_url": "/", 19 | "display": "standalone" 20 | } 21 | -------------------------------------------------------------------------------- /server/views/_partials/icons/header/arrow-left.pug: -------------------------------------------------------------------------------- 1 | svg(class="w-3.5 h-5 mr-1" fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 407.436 407.436") 2 | path(d="M131.047 222.409l138.75-138.756c7.05-7.043 10.567-15.657 10.567-25.841 0-10.183-3.518-18.793-10.567-25.835l-21.409-21.416C241.349 3.521 232.734 0 222.554 0s-18.791 3.521-25.841 10.561L10.566 196.425C3.522 203.468 0 212.081 0 222.266s3.521 18.791 10.566 25.837l186.146 185.864c7.05 7.043 15.66 10.564 25.841 10.564 10.181 0 18.795-3.521 25.834-10.564l21.409-21.412c7.05-7.039 10.567-15.604 10.567-25.697 0-10.085-3.518-18.746-10.567-25.978z") -------------------------------------------------------------------------------- /server/views/search.pug: -------------------------------------------------------------------------------- 1 | extends _layout 2 | 3 | include ./wrapper 4 | 5 | block content 6 | +wrapper 7 | div(x-data="searchResults({html:window.packageData.split('END_OF_SCRIPT_TAG').join(''), info: window.packageInfo})" :class="state.results.error ? 'mt-20 flex-1 justify-center' : ''") 8 | include ./_partials/error 9 | include ./_partials/presearch-package 10 | div(class="w-full 2lg:flex 2lg:flex-row-reverse 2lg:justify-end") 11 | include ./_partials/special-sections/info 12 | include ./_partials/standard-results 13 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | 5 | --- 6 | 7 | **Is your feature request related to a problem? Please describe.** 8 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 9 | 10 | **Describe the solution you'd like** 11 | A clear and concise description of what you want to happen. 12 | 13 | **Describe alternatives you've considered** 14 | A clear and concise description of any alternative solutions or features you've considered. 15 | 16 | **Additional context** 17 | Add any other context or screenshots about the feature request here. 18 | -------------------------------------------------------------------------------- /packages/passwordGenerator/services.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const expect = require('expect'); 4 | const { generate } = require("./services"); 5 | 6 | describe("services", function () { 7 | it("generate password of specific length", function () { 8 | // test case with 10 chars 9 | expect(generate(10).length).toBe(10); 10 | // test case with 72 chars should use default length 11 | expect(generate(72).length).toBe(8); 12 | // test case with 0 chars should use default length 13 | expect(generate(0).length).toBe(8); 14 | // test case with invalid parameter 15 | expect(generate("zero").length).toBe(8); 16 | 17 | }); 18 | 19 | }); 20 | -------------------------------------------------------------------------------- /server/views/_partials/footer.pug: -------------------------------------------------------------------------------- 1 | div(class="text-sm p-4 fixed bottom-0 dark:text-white bg-white dark:bg-background-dark200 rounded") 2 | div name: #{title} 3 | div query: !{query} 4 | div(style=`background: ${triggered ? '#00ff0040' : '#FF000040'}`) triggered: 5 | span #{triggered ? 'yes' : 'no'} 6 | div(x-show=`${totalTime && totalTime} > 0` style=`background: ${totalTime && totalTime > 1500 ? '#FF000040' : (totalTime && totalTime > 1000 ? '#ffff0040' : '#00ff0040')}`) time: 7 | span #{totalTime && totalTime}ms 8 | div(style=`background: red`) 9 | if (overlappingPackages) 10 | span Overlapping packages: !{overlappingPackages.join(", ")} -------------------------------------------------------------------------------- /server/views/_partials/icons/header/all.pug: -------------------------------------------------------------------------------- 1 | svg(class="hidden md:block w-3.5 h-3.5 mr-2" fill="currentColor" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve") 2 | path(d="M505.749,475.587l-145.6-145.6c28.203-34.837,45.184-79.104,45.184-127.317c0-111.744-90.923-202.667-202.667-202.667 S0,90.925,0,202.669s90.923,202.667,202.667,202.667c48.213,0,92.48-16.981,127.317-45.184l145.6,145.6 c4.16,4.16,9.621,6.251,15.083,6.251s10.923-2.091,15.083-6.251C514.091,497.411,514.091,483.928,505.749,475.587z M202.667,362.669c-88.235,0-160-71.765-160-160s71.765-160,160-160s160,71.765,160,160S290.901,362.669,202.667,362.669z") -------------------------------------------------------------------------------- /packages/starWarsQuote/index.js: -------------------------------------------------------------------------------- 1 | const quotes = require('./quotes') 2 | 3 | function starWarsQuote(query) { 4 | const quote = quotes[Math.floor(Math.random() * quotes.length)]; 5 | 6 | return ` 7 |
8 |

"${quote ? quote : ``}"

9 |
10 | 20 | `; 21 | } 22 | 23 | function trigger(query) { 24 | return query === 'starwars quote' || query === 'star wars quote'; 25 | } 26 | 27 | module.exports = { starWarsQuote, trigger }; 28 | -------------------------------------------------------------------------------- /server/views/_partials/icons/header/account.pug: -------------------------------------------------------------------------------- 1 | svg(class="w-5 h-5 mt-0.5 ml-0.5" fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 -5 520 520") 2 | path(d="M256 288.389c-153.837 0-238.56 72.776-238.56 204.925 0 10.321 8.365 18.686 18.686 18.686h439.747c10.321 0 18.686-8.365 18.686-18.686.001-132.142-84.722-204.925-238.559-204.925zM55.492 474.628c7.35-98.806 74.713-148.866 200.508-148.866s193.159 50.06 200.515 148.866H55.492zM256 0c-70.665 0-123.951 54.358-123.951 126.437 0 74.19 55.604 134.54 123.951 134.54s123.951-60.35 123.951-134.534C379.951 54.358 326.665 0 256 0zm0 223.611c-47.743 0-86.579-43.589-86.579-97.168 0-51.611 36.413-89.071 86.579-89.071 49.363 0 86.579 38.288 86.579 89.071 0 53.579-38.836 97.168-86.579 97.168z" stroke-width="10" stroke="currentColor") -------------------------------------------------------------------------------- /server/views/wrapper.pug: -------------------------------------------------------------------------------- 1 | mixin wrapper 2 | div(class="relative flex bg-background-light200 dark:bg-background-dark500 h-full md:min-h-screen") 3 | div(x-show="$store.showSettings && $store.showSettings.show" x-on:mouseover="hideSettings(true, false, true)" class="fixed w-screen h-screen z-20 top-0 left-0") 4 | div(class="flex flex-col flex-auto w-full h-full md:min-h-screen") 5 | div 6 | include _partials/header 7 | include _partials/settings 8 | div(class="flex results-div") 9 | include _partials/sidebar 10 | div(class="w-full flex-auto flex flex-col bg-background-light200 border-gray-200 dark:bg-background-dark500 dark:border-gray-900") 11 | block 12 | include _partials/footer -------------------------------------------------------------------------------- /server/views/nonPug/opensearch.xml.js: -------------------------------------------------------------------------------- 1 | const opensearchXml = (PRESEARCH_DOMAIN) => { 2 | 3 | const domain = `${PRESEARCH_DOMAIN.replace(".org", ".com")}`; 4 | 5 | return ` 6 | 7 | Presearch 8 | Presearch is a decentralized search engine, powered by the community. 9 | UTF-8 10 | ${domain}/images/icon.svg 11 | 12 | 13 | `; 14 | } 15 | 16 | module.exports = opensearchXml; 17 | -------------------------------------------------------------------------------- /server/views/_partials/icons/header/share.pug: -------------------------------------------------------------------------------- 1 | svg(class="w-3.5 h-3.5 mr-2" fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512") 2 | path(d="M406 332c-29.636 0-55.969 14.402-72.378 36.571l-141.27-72.195A89.738 89.738 0 00196 271a89.51 89.51 0 00-6.574-33.753l148.06-88.958C354.006 167.679 378.59 180 406 180c49.626 0 90-40.374 90-90S455.626 0 406 0s-90 40.374-90 90a89.54 89.54 0 006.09 32.54l-148.43 89.18C157.152 192.902 132.941 181 106 181c-49.626 0-90 40.374-90 90s40.374 90 90 90c30.122 0 56.832-14.876 73.177-37.666l140.86 71.985A89.702 89.702 0 00316 422c0 49.626 40.374 90 90 90s90-40.374 90-90-40.374-90-90-90zm0-302c33.084 0 60 26.916 60 60s-26.916 60-60 60-60-26.916-60-60 26.916-60 60-60zM106 331c-33.084 0-60-26.916-60-60s26.916-60 60-60 60 26.916 60 60-26.916 60-60 60zm300 151c-33.084 0-60-26.916-60-60s26.916-60 60-60 60 26.916 60 60-26.916 60-60 60z") -------------------------------------------------------------------------------- /packages/loremIpsumGenerator/services.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const expect = require('expect'); 4 | const { generate } = require("./services"); 5 | const DEFAULT_LENGTH = 12; 6 | 7 | describe("services", function () { 8 | it("generate lorem ipsum phrase of specific word length ", function () { 9 | // test case with 10 words, should use default length 10 | expect(generate(10).split(" ").length).toBe(DEFAULT_LENGTH); 11 | // test case with 72 words 12 | expect(generate(72).split(" ").length).toBe(72); 13 | // test case with 0 words, should use default length 14 | expect(generate(0).split(" ").length).toBe(DEFAULT_LENGTH); 15 | // test case with 1000 words 16 | expect(generate(1000).split(" ").length).toBe(1000); 17 | // test case with invalid parameter 18 | expect(generate("zero").split(" ").length).toBe(DEFAULT_LENGTH); 19 | }); 20 | 21 | }); 22 | -------------------------------------------------------------------------------- /server/views/_partials/icons/results/videos.pug: -------------------------------------------------------------------------------- 1 | svg(class="w-4 h-4 mr-2" fill="currentColor" viewBox="0 -87 472 472" xmlns="http://www.w3.org/2000/svg") 2 | path(d="m467.101562 26.527344c-3.039062-1.800782-6.796874-1.871094-9.898437-.179688l-108.296875 59.132813v-35.480469c-.03125-27.601562-22.398438-49.96875-50-50h-248.90625c-27.601562.03125-49.96875 22.398438-50 50v197.421875c.03125 27.601563 22.398438 49.96875 50 50h248.90625c27.601562-.03125 49.96875-22.398437 50-50v-34.835937l108.300781 59.132812c3.097657 1.691406 6.859375 1.625 9.894531-.175781 3.039063-1.804688 4.898438-5.074219 4.898438-8.601563v-227.816406c0-3.53125-1.863281-6.796875-4.898438-8.597656zm-138.203124 220.898437c-.015626 16.5625-13.4375 29.980469-30 30h-248.898438c-16.5625-.019531-29.980469-13.4375-30-30v-197.425781c.019531-16.558594 13.4375-29.980469 30-30h248.90625c16.558594.019531 29.980469 13.441406 30 30zm123.101562-1.335937-103.09375-56.289063v-81.535156l103.09375-56.285156zm0 0") -------------------------------------------------------------------------------- /bin/merge-dependencies.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict'; 3 | 4 | const fs = require('fs'); 5 | const path = require('path'); 6 | 7 | const SOURCE = './packages'; 8 | const MAIN_PACKAGE = './package.json'; 9 | 10 | const directories = source => fs.readdirSync(source).filter(child => fs.statSync(path.join(source, child)).isDirectory()); 11 | const packages = directories(SOURCE).map(dir => fs.readFileSync(`${SOURCE}/${dir}/package.json`, 'utf-8')); 12 | 13 | let dependencies = {}; 14 | 15 | for (let pack of packages) { 16 | const packageObj = JSON.parse(pack); 17 | dependencies = Object.assign({}, packageObj.dependencies, dependencies); 18 | } 19 | 20 | const mainPackage = JSON.parse(fs.readFileSync(MAIN_PACKAGE, 'utf-8')); 21 | mainPackage.dependencies = Object.assign({}, mainPackage.dependencies, dependencies); 22 | const newPackageJson = JSON.stringify(mainPackage, null, 4); 23 | fs.writeFileSync(MAIN_PACKAGE, newPackageJson, 'utf-8'); 24 | -------------------------------------------------------------------------------- /server/views/_partials/icons/header/videos.pug: -------------------------------------------------------------------------------- 1 | svg(class="hidden md:block w-4 h-4 mr-2" fill="currentColor" viewBox="0 -87 472 472" xmlns="http://www.w3.org/2000/svg") 2 | path(d="m467.101562 26.527344c-3.039062-1.800782-6.796874-1.871094-9.898437-.179688l-108.296875 59.132813v-35.480469c-.03125-27.601562-22.398438-49.96875-50-50h-248.90625c-27.601562.03125-49.96875 22.398438-50 50v197.421875c.03125 27.601563 22.398438 49.96875 50 50h248.90625c27.601562-.03125 49.96875-22.398437 50-50v-34.835937l108.300781 59.132812c3.097657 1.691406 6.859375 1.625 9.894531-.175781 3.039063-1.804688 4.898438-5.074219 4.898438-8.601563v-227.816406c0-3.53125-1.863281-6.796875-4.898438-8.597656zm-138.203124 220.898437c-.015626 16.5625-13.4375 29.980469-30 30h-248.898438c-16.5625-.019531-29.980469-13.4375-30-30v-197.425781c.019531-16.558594 13.4375-29.980469 30-30h248.90625c16.558594.019531 29.980469 13.441406 30 30zm123.101562-1.335937-103.09375-56.289063v-81.535156l103.09375-56.285156zm0 0") -------------------------------------------------------------------------------- /server/public/images/icon.svg: -------------------------------------------------------------------------------- 1 | presearch-logo-border-blue-transparent 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | 5 | --- 6 | 7 | **Describe the bug** 8 | A clear and concise description of what the bug is. 9 | 10 | **To Reproduce** 11 | Steps to reproduce the behavior: 12 | 1. Go to '...' 13 | 2. Click on '....' 14 | 3. Scroll down to '....' 15 | 4. See error 16 | 17 | **Expected behavior** 18 | A clear and concise description of what you expected to happen. 19 | 20 | **Screenshots** 21 | If applicable, add screenshots to help explain your problem. 22 | 23 | **Desktop (please complete the following information):** 24 | - OS: [e.g. iOS] 25 | - Browser [e.g. chrome, safari] 26 | - Version [e.g. 22] 27 | 28 | **Smartphone (please complete the following information):** 29 | - Device: [e.g. iPhone6] 30 | - OS: [e.g. iOS8.1] 31 | - Browser [e.g. stock browser, safari] 32 | - Version [e.g. 22] 33 | 34 | **Additional context** 35 | Add any other context about the problem here. 36 | -------------------------------------------------------------------------------- /server/views/_partials/presearch-package.pug: -------------------------------------------------------------------------------- 1 | template(x-if="state.presearchPackage && state.presearchPackage.html" x-effect="injectJs($el)") 2 | div(class="bg-white shadow dark:bg-dark-700 p-5 mt-4 mx-2 md:mt-9 md:mx-0 max-w-package rounded") 3 | div(x-html="state.presearchPackage.html") 4 | div(class="flex mt-2 space-x-1 text-xs text-gray-600 dark:text-white") 5 | p Created by 6 | span(x-html="state.presearchPackage.info.author" class="font-bold") 7 | p Version 8 | span(x-html="state.presearchPackage.info.version" class="font-bold") 9 | a(href="https://github.com/PresearchOfficial/presearch-packages/issues/new/choose") Feedback 10 | template(x-if="state.presearchPackage && state.presearchPackage.html") 11 | div(class="mt-6 md:mt-4 packageError") 12 | template(x-if="!state.presearchPackage || !state.presearchPackage.html") 13 | div(class="mt-0 md:mt-9 packageError text-md" style="color:#ee0000") -------------------------------------------------------------------------------- /server/public/assets/images/icon_presearch.svg: -------------------------------------------------------------------------------- 1 | presearch-logo-border-blue-transparent 2 | -------------------------------------------------------------------------------- /server/views/_partials/icons/header/nodes.pug: -------------------------------------------------------------------------------- 1 | svg(class="w-6 h-6" fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 482 482") 2 | path(d="M410.1 311.5c-14.7 0-28.3 5.3-38.8 14l-73.1-40.9c.8-4 1.3-8.1 1.3-12.4 0-26.4-16.8-48.9-40.3-57.4v-61c23.5-8.5 40.3-31 40.3-57.4 0-33.6-27.4-61-61-61s-61 27.4-61 61c0 26.4 16.8 48.9 40.3 57.4v61c-23.5 8.5-40.3 31-40.3 57.4 0 5.9.9 11.6 2.4 17L111 328.8c-10.6-8.9-24.2-14.2-39.1-14.2-33.7 0-61 27.4-61 61s27.4 61 61 61 61-27.4 61-61c0-3.8-.4-7.5-1-11.1l72.5-41.7c9.7 6.6 21.5 10.4 34.1 10.4 14.4 0 27.6-5 38.1-13.4l73.7 41.3c-.7 3.7-1.1 7.5-1.1 11.4 0 33.6 27.4 61 61 61 33.7 0 61-27.4 61-61s-27.4-61-61.1-61zM238.4 76.7c10.8 0 19.7 8.8 19.7 19.7s-8.8 19.7-19.7 19.7c-10.8 0-19.7-8.8-19.7-19.7s8.9-19.7 19.7-19.7zM71.9 395.3c-10.8 0-19.7-8.8-19.7-19.7S61.1 356 71.9 356c10.8 0 19.6 8.8 19.6 19.7s-8.8 19.6-19.6 19.6zm166.5-103.5c-10.8 0-19.7-8.8-19.7-19.7 0-10.8 8.8-19.7 19.7-19.7 10.8 0 19.7 8.8 19.7 19.7 0 10.9-8.8 19.7-19.7 19.7zm171.7 100.4c-10.8 0-19.6-8.8-19.6-19.7 0-10.8 8.8-19.7 19.6-19.7s19.7 8.8 19.7 19.7c0 10.9-8.9 19.7-19.7 19.7z") -------------------------------------------------------------------------------- /packages/userAgents/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | async function userAgents() { 4 | return ` 5 |
6 | Your User Agent 7 |
8 | Welp this is embarrassing, failed to get user agent 9 |
10 | 11 | 25 | 29 | `; 30 | } 31 | async function trigger(query) { 32 | if (query) { 33 | query = query ? query.toLowerCase() : ""; 34 | if (query.includes("user agent") || query.includes("useragent")) return true; 35 | } 36 | return false; 37 | } 38 | 39 | module.exports = { userAgents, trigger }; -------------------------------------------------------------------------------- /server/views/_partials/providers-mobile.pug: -------------------------------------------------------------------------------- 1 | div(x-show="$store.showProviders && $store.showProviders.show" class="absolute left-0 mt-16 h-10 max-w-full min-w-full px-4 md:hidden dark:border-dark-700 border-b" x-cloak) 2 | div(class="flex items-center justify-start h-full overflow-x-auto") 3 | template(x-for="(provider, index) in user.providersColored") 4 | a(class="svgIcon relative flex mr-5 items-center justify-center text-center text-gray-600 transition duration-150 group max-w-6 hover:text-primary-500" rel="noopener noreferrer" :href=`'${settings.PRESEARCH_DOMAIN}/presearch?provider_id=' + provider.id + '&term=${requestQuery && requestQuery.includes("'") ? requestQuery.split("'").join("%27") : requestQuery}'` :key="provider.id") 5 | template(x-if="provider.icon.type === 'svg'") 6 | div(class="inline-block w-5 h-5 svgIcon flex" x-html="decodeSVG(provider.icon.svg_content)") 7 | template(x-if="provider.icon.type === 'class'") 8 | div(class="text-2xl fa" x-bind:class="`${provider.icon.class} ${provider.icon.color}`") 9 | -------------------------------------------------------------------------------- /packages/map/generateKey.js: -------------------------------------------------------------------------------- 1 | const jwt = require("jsonwebtoken"); 2 | const dotenv = require("dotenv"); 3 | dotenv.config() 4 | 5 | const TEAM_ID = process.env["API.MAP_TEAM_ID"]; 6 | const KEY_ID = process.env["API.MAP_KEY_ID"]; 7 | const MAPS_ID = process.env["API.MAP_MAPS_ID"]; 8 | const privateKey = process.env["API.MAP_PRIVATE_KEY"]; 9 | 10 | // Function to generate the JWT token 11 | function generateJwt(seconds = 30) { 12 | if (!TEAM_ID || !KEY_ID || !MAPS_ID || !privateKey) { 13 | console.error("Missing environment variables"); 14 | return; 15 | } 16 | const privateKeyFormatted = privateKey.replace(/\\n/g, '\n'); 17 | 18 | const now = Math.floor(Date.now() / 1000); 19 | // Token expires in 30 seconds by default 20 | const expires = now + seconds; 21 | 22 | const payload = { 23 | iss: TEAM_ID, 24 | iat: now, 25 | exp: expires, 26 | sub: MAPS_ID 27 | }; 28 | 29 | const header = { 30 | alg: 'ES256', 31 | kid: KEY_ID, 32 | }; 33 | 34 | const token = jwt.sign(payload, privateKeyFormatted, { header }); 35 | return token; 36 | } 37 | 38 | module.exports = generateJwt; -------------------------------------------------------------------------------- /server/views/_partials/icons/header/marketplace.pug: -------------------------------------------------------------------------------- 1 | svg(class="w-6 h-6" fill="currentColor" version="1.1" xmlns="http://www.w3.org/2000/svg" x="0" y="0" viewBox="0 0 482 482" xml:space="preserve") 2 | path(d="M254.9 238.2h16.5c4.6 0 9.5-.9 13.8-3.1 4-2.1 7.7-4.6 10.7-8.3 2.8-3.4 5.2-7.7 6.7-11.9s2.4-8.9 2.4-13.8c0-4.6-.9-8.9-2.8-13.5-1.5-4-4-8.3-7-11.6-3.1-3.4-6.7-6.4-10.7-8.3-4.3-2.1-8.9-3.4-13.8-3.4h-43.8v105.9h27.9v-32zm0-48H269c2.1.3 4 .9 5.2 2.4 1.5 1.5 2.8 4.6 2.8 8.9 0 4.6-.9 7-2.4 8.6-1.2 1.5-2.8 2.4-4.6 2.4h-14.7v-22.3h-.4z") 3 | path(d="M267.5 250.8H333V271h-65.5z") 4 | path(d="M388.3 325.2h-228c-6.9 0-13-4.4-15.2-10.9L65.7 79.8H22.1c-8.8 0-16-7.2-16-16s7.2-16 16-16h55.1c6.9 0 13 4.4 15.2 10.9l18.5 54.6H441c5 0 9.8 2.4 12.8 6.4s4 9.3 2.5 14.1l-52.7 179.9c-1.9 6.8-8.2 11.5-15.3 11.5zm-216.6-32h204.6l43.3-147.9h-298l50.1 147.9zM183.4 445c-29 0-52.6-23.6-52.6-52.6s23.6-52.6 52.6-52.6 52.6 23.6 52.6 52.6-23.6 52.6-52.6 52.6zm0-77.7c-13.8 0-25.1 11.3-25.1 25.1s11.3 25.1 25.1 25.1 25.1-11.3 25.1-25.1-11.2-25.1-25.1-25.1zM355.2 445c-29 0-52.6-23.6-52.6-52.6s23.6-52.6 52.6-52.6 52.6 23.6 52.6 52.6-23.6 52.6-52.6 52.6zm0-77.7c-13.8 0-25.1 11.3-25.1 25.1s11.3 25.1 25.1 25.1 25.1-11.3 25.1-25.1-11.3-25.1-25.1-25.1z") -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # next.js build output 61 | .next 62 | 63 | # MapKitJS specific files 64 | .p8 65 | 66 | .DS_Store 67 | -------------------------------------------------------------------------------- /server/views/_partials/icons/header/images.pug: -------------------------------------------------------------------------------- 1 | svg(class="hidden md:block w-3.5 h-3.5 mr-2" fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 420.8 420.8") 2 | path(d="M406.8 96.4c-8.4-8.8-20-14-33.2-14h-66.4v-.8c0-10-4-19.6-10.8-26-6.8-6.8-16-10.8-26-10.8h-120c-10.4 0-19.6 4-26.4 10.8-6.8 6.8-10.8 16-10.8 26v.8h-66c-13.2 0-24.8 5.2-33.2 14-8.4 8.4-14 20.4-14 33.2v199.2C0 342 5.2 353.6 14 362c8.4 8.4 20.4 14 33.2 14h326.4c13.2 0 24.8-5.2 33.2-14 8.4-8.4 14-20.4 14-33.2V129.6c0-13.2-5.2-24.8-14-33.2zM400 328.8h-.4c0 7.2-2.8 13.6-7.6 18.4s-11.2 7.6-18.4 7.6H47.2c-7.2 0-13.6-2.8-18.4-7.6-4.8-4.8-7.6-11.2-7.6-18.4V129.6c0-7.2 2.8-13.6 7.6-18.4s11.2-7.6 18.4-7.6h77.2c6 0 10.8-4.8 10.8-10.8V81.2c0-4.4 1.6-8.4 4.4-11.2s6.8-4.4 11.2-4.4h119.6c4.4 0 8.4 1.6 11.2 4.4 2.8 2.8 4.4 6.8 4.4 11.2v11.6c0 6 4.8 10.8 10.8 10.8H374c7.2 0 13.6 2.8 18.4 7.6s7.6 11.2 7.6 18.4v199.2z") 3 | path(d="M210.4 130.8c-27.2 0-52 11.2-69.6 28.8-18 18-28.8 42.4-28.8 69.6s11.2 52 28.8 69.6c18 18 42.4 28.8 69.6 28.8s52-11.2 69.6-28.8c18-18 28.8-42.4 28.8-69.6s-11.2-52-28.8-69.6c-17.6-17.6-42.4-28.8-69.6-28.8zM264.8 284c-14 13.6-33.2 22.4-54.4 22.4S170 297.6 156 284c-14-14-22.4-33.2-22.4-54.4 0-21.2 8.8-40.4 22.4-54.4 14-14 33.2-22.4 54.4-22.4s40.4 8.8 54.4 22.4c14 14 22.4 33.2 22.4 54.4.4 21.2-8.4 40.4-22.4 54.4z") 4 | circle(cx="352.8" cy="150" r="19.6") -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "presearch-packages", 3 | "version": "0.2.5", 4 | "description": "Instant information packages for the Presearch engine", 5 | "main": "index.js", 6 | "scripts": { 7 | "merge-dependencies": "node ./bin/merge-dependencies.js", 8 | "add-package-json": "git add package.json", 9 | "create-package": "node create-package.js", 10 | "create-package-linux": "./bin/create-package.sh", 11 | "create-package-windows": ".\\bin\\create-package.sh", 12 | "postinstall": "cd server && npm install && cd .." 13 | }, 14 | "pre-commit": [ 15 | "merge-dependencies", 16 | "add-package-json" 17 | ], 18 | "author": "", 19 | "license": "MIT", 20 | "dependencies": { 21 | "async-wait-until": "^2.0.8", 22 | "axios": "^0.24.0", 23 | "binary-search": "^1.3.6", 24 | "colors": "^1.4.0", 25 | "cors": "^2.8.5", 26 | "dayjs": "^1.11.3", 27 | "dotenv": "^10.0.0", 28 | "emoji-api": "^2.0.1", 29 | "emoji-regex": "^10.0.0", 30 | "ethereum-address": "^0.0.4", 31 | "jsonwebtoken": "^9.0.2", 32 | "mathjs": "^9.5.1", 33 | "node-fetch": "^2.6.7", 34 | "periodic-table": "^0.0.8", 35 | "wikijs": "^6.3.2" 36 | }, 37 | "devDependencies": { 38 | "pre-commit": "^1.2.2" 39 | } 40 | } -------------------------------------------------------------------------------- /server/views/nonPug/error.js: -------------------------------------------------------------------------------- 1 | const nonPugError = (error) => { 2 | return ` 3 | 4 | 5 | 6 | 7 | Presearch 8 | 9 | 15 | 16 | 22 | 23 |
24 |

Oops, something went wrong...

25 |

Please try again later

26 |
27 |

Message: ${error.message}

28 |

Code: ${error.code}

29 |
30 |
31 | 32 | ` 33 | } 34 | 35 | module.exports = nonPugError; 36 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | ## 0.2.5 3 | - Filter out low mcap coins from cryptoInfo package 4 | - Updated coin_list and coin_metadata for cryptoInfo package 5 | ## 0.2.4 6 | - Use part of the trigger function from cryptoConverter package in currencyConverter package 7 | - Improved dev environment - show warning message when there's more than one package triggered buy the query 8 | 9 | ## 0.2.3 10 | - Added offline list for fiat and cryptocurrencies for 'currencyConverter' package 11 | - Improved regex for math package to exclude phone numbers 12 | 13 | ## 0.2.2 14 | - New package 'currencyConverter' 15 | - Removed 'exchangeRates' package 16 | - Temporarly disabled 'cryptoConversion' package, because 'currencyConverter' has similar functionality 17 | 18 | ## 0.2.1 19 | - New package 'cryptoConversion' 20 | - Updated 'math' package 21 | - Updated coin list for 'cryptoInfo' package 22 | 23 | ## 0.2.0 24 | - New test enviorment 25 | 26 | ## 0.1.34 27 | - Updated cryptoInfo package 28 | 29 | ## 0.1.33 30 | - Updated cryptoInfo coin list 31 | 32 | ## 0.1.32 33 | - Added Polkamarkets to cryptoInfo package 34 | 35 | ## 0.1.31 36 | - Added dark mode support 37 | - Removed dictionary and mathSteps packages 38 | 39 | ## 0.1.30 40 | - Fixed math package 41 | - Updated offline coin list for cryptoInfo package 42 | - Removed console.log from cryptoInfo package 43 | - Added changelog 44 | -------------------------------------------------------------------------------- /packages/passwordGenerator/services.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const DEFAULT_LENGTH = 8; 4 | 5 | /** 6 | * Execute the password generation using the provided character length 7 | * @param {int} len 8 | * @returns {String} 9 | */ 10 | function generate(len) { 11 | let chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_+~|}{[]:;?><,./-="; 12 | let res = ""; 13 | let length = 8; 14 | 15 | if (len && Number.isInteger(len) && (len > 8 && len <= 64)) { 16 | length = len; 17 | } 18 | 19 | for (let i = 0, n = chars.length; i < length; ++i) { 20 | res += chars.charAt(Math.floor(Math.random() * n)); 21 | } 22 | return res; 23 | } 24 | 25 | /** 26 | * Parses the query and normalizes it 27 | * @param {String} query 28 | * @returns {int} 29 | */ 30 | function parseAndNormalize(query) { 31 | const terms = ["randompassword", "randompw","pass","password","random password","random pw","generate password","pwd"]; 32 | 33 | for (let term of terms) { 34 | if (query.startsWith(term.toLowerCase())) { 35 | const queryArray = query.trim().split(" "); 36 | const lastQueryString = queryArray[queryArray.length - 1]; 37 | const num = parseInt(lastQueryString) || undefined; 38 | if (num !== undefined) { 39 | return num; 40 | } 41 | return DEFAULT_LENGTH; 42 | } 43 | } 44 | return undefined; 45 | } 46 | 47 | module.exports = { DEFAULT_LENGTH, parseAndNormalize, generate }; 48 | -------------------------------------------------------------------------------- /common.css: -------------------------------------------------------------------------------- 1 | .answerContain { 2 | flex: 1; 3 | padding: 10px 0; 4 | background-color: #f2f2f2; 5 | border-bottom: 1px solid #ddd; 6 | } 7 | .answerInner { 8 | flex: 1; 9 | display: flex; 10 | } 11 | .answerRow { 12 | display: flex; 13 | } 14 | .answerCol { 15 | display: flex; 16 | flex-direction: column; 17 | } 18 | a { 19 | text-decoration: none; 20 | color: inherit; 21 | } 22 | 23 | @media screen and (min-width: 1200px) { 24 | .answerInner { 25 | width: calc(95% - 70px); 26 | max-width: 1200px; 27 | margin: 15px auto 15px 70px; 28 | flex-flow: row nowrap; 29 | } 30 | } 31 | 32 | @media screen and (min-width: 840px) and (max-width: 1199px) { 33 | .answerInner { 34 | width: 95%; 35 | max-width: 1200px; 36 | margin: 15px auto; 37 | flex-flow: row nowrap; 38 | } 39 | } 40 | 41 | @media screen and (min-width: 840px) { 42 | .answerContain { 43 | flex-flow: row nowrap; 44 | } 45 | .answerRow { 46 | flex-flow: row nowrap; 47 | } 48 | .mainCol { 49 | width: 55%; 50 | } 51 | .sideCol { 52 | width: 45%; 53 | } 54 | } 55 | 56 | @media screen and (max-width: 839px) { 57 | .answerInner { 58 | width: 95%; 59 | margin: 15px auto; 60 | flex-flow: column-reverse nowrap; 61 | } 62 | .answerContain { 63 | flex-flow: column nowrap; 64 | } 65 | .answerRow { 66 | flex-flow: column nowrap; 67 | } 68 | .mainCol { 69 | width: 100%; 70 | } 71 | .sideCol { 72 | width: 100%; 73 | } 74 | } 75 | 76 | -------------------------------------------------------------------------------- /packages/cryptoInfo/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cryptoInfo", 3 | "version": "1.1.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "dotenv": { 8 | "version": "10.0.0", 9 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", 10 | "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" 11 | }, 12 | "node-fetch": { 13 | "version": "2.6.7", 14 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", 15 | "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", 16 | "requires": { 17 | "whatwg-url": "^5.0.0" 18 | } 19 | }, 20 | "tr46": { 21 | "version": "0.0.3", 22 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", 23 | "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" 24 | }, 25 | "webidl-conversions": { 26 | "version": "3.0.1", 27 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", 28 | "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" 29 | }, 30 | "whatwg-url": { 31 | "version": "5.0.0", 32 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", 33 | "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", 34 | "requires": { 35 | "tr46": "~0.0.3", 36 | "webidl-conversions": "^3.0.0" 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /server/views/_partials/error.pug: -------------------------------------------------------------------------------- 1 | div(x-show="state.results.error" class="flex flex-1 flex-col md:justify-center items-center pt-4 my-auto" x-cloak) 2 | svg(class="w-16 h-16 mb-2 stroke-current text-primary-500 opacity-85 dark:opacity-100 dark:text-blue-300" mlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round") 3 | path(d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z") 4 | line(x1="12" y1="9" x2="12" y2="13") 5 | line(x1="12" y1="17" x2="12.01" y2="17") 6 | 7 | div(class="font-light flex text-center justify-center flex-col dark:text-white") 8 | p Oops, something went wrong with your search... 9 | p(class="mt-1 text-base") While we're working on a fix, you can try your search again on our #[span backup engine]: 10 | a(class="mt-2 text-lg text-primary-600 transition duration-150 hover:text-primary-700 hover:underline dark:text-blue-300 dark:hover:text-blue-200" href=`https://dsearch.com${path}?q=${requestQuery}`) #{ `https://dsearch.com${path}?q=${requestQuery}` } 11 | 12 | div(class="text-xs mt-4 text-center border p-2 dark:border-gray-300 dark:text-white") 13 | p Code: #[span(class="text-gray-600 dark:text-gray-400" x-html="state.results.error ? state.results.error.code : ''")] 14 | p Message: #[span(class="text-gray-600 dark:text-gray-400" x-html="state.results.error ? state.results.error.message : ''")] -------------------------------------------------------------------------------- /server/views/_partials/icons/social/facebook.pug: -------------------------------------------------------------------------------- 1 | svg(viewBox="-110 1 511 511.99996" fill="currentColor" xmlns="http://www.w3.org/2000/svg") 2 | path(d="m180 512h-81.992188c-13.695312 0-24.835937-11.140625-24.835937-24.835938v-184.9375h-47.835937c-13.695313 0-24.835938-11.144531-24.835938-24.835937v-79.246094c0-13.695312 11.140625-24.835937 24.835938-24.835937h47.835937v-39.683594c0-39.347656 12.355469-72.824219 35.726563-96.804688 23.476562-24.089843 56.285156-36.820312 94.878906-36.820312l62.53125.101562c13.671875.023438 24.792968 11.164063 24.792968 24.835938v73.578125c0 13.695313-11.136718 24.835937-24.828124 24.835937l-42.101563.015626c-12.839844 0-16.109375 2.574218-16.808594 3.363281-1.152343 1.308593-2.523437 5.007812-2.523437 15.222656v31.351563h58.269531c4.386719 0 8.636719 1.082031 12.289063 3.121093 7.878906 4.402344 12.777343 12.726563 12.777343 21.722657l-.03125 79.246093c0 13.6875-11.140625 24.828125-24.835937 24.828125h-58.46875v184.941406c0 13.695313-11.144532 24.835938-24.839844 24.835938zm-76.8125-30.015625h71.632812v-193.195313c0-9.144531 7.441407-16.582031 16.582032-16.582031h66.726562l.027344-68.882812h-66.757812c-9.140626 0-16.578126-7.4375-16.578126-16.582031v-44.789063c0-11.726563 1.191407-25.0625 10.042969-35.085937 10.695313-12.117188 27.550781-13.515626 39.300781-13.515626l36.921876-.015624v-63.226563l-57.332032-.09375c-62.023437 0-100.566406 39.703125-100.566406 103.609375v53.117188c0 9.140624-7.4375 16.582031-16.578125 16.582031h-56.09375v68.882812h56.09375c9.140625 0 16.578125 7.4375 16.578125 16.582031zm163.0625-451.867187h.003906zm0 0") -------------------------------------------------------------------------------- /server/views/_partials/icons/social/instagram.pug: -------------------------------------------------------------------------------- 1 | svg(viewBox="0 0 512.00096 512.00096" fill="currentColor" xmlns="http://www.w3.org/2000/svg") 2 | path(d="m373.40625 0h-234.8125c-76.421875 0-138.59375 62.171875-138.59375 138.59375v234.816406c0 76.417969 62.171875 138.589844 138.59375 138.589844h234.816406c76.417969 0 138.589844-62.171875 138.589844-138.589844v-234.816406c0-76.421875-62.171875-138.59375-138.59375-138.59375zm108.578125 373.410156c0 59.867188-48.707031 108.574219-108.578125 108.574219h-234.8125c-59.871094 0-108.578125-48.707031-108.578125-108.574219v-234.816406c0-59.871094 48.707031-108.578125 108.578125-108.578125h234.816406c59.867188 0 108.574219 48.707031 108.574219 108.578125zm0 0") 3 | path(d="m256 116.003906c-77.195312 0-139.996094 62.800782-139.996094 139.996094s62.800782 139.996094 139.996094 139.996094 139.996094-62.800782 139.996094-139.996094-62.800782-139.996094-139.996094-139.996094zm0 249.976563c-60.640625 0-109.980469-49.335938-109.980469-109.980469 0-60.640625 49.339844-109.980469 109.980469-109.980469 60.644531 0 109.980469 49.339844 109.980469 109.980469 0 60.644531-49.335938 109.980469-109.980469 109.980469zm0 0") 4 | path(d="m399.34375 66.285156c-22.8125 0-41.367188 18.558594-41.367188 41.367188 0 22.8125 18.554688 41.371094 41.367188 41.371094s41.371094-18.558594 41.371094-41.371094-18.558594-41.367188-41.371094-41.367188zm0 52.71875c-6.257812 0-11.351562-5.09375-11.351562-11.351562 0-6.261719 5.09375-11.351563 11.351562-11.351563 6.261719 0 11.355469 5.089844 11.355469 11.351563 0 6.257812-5.09375 11.351562-11.355469 11.351562zm0 0") -------------------------------------------------------------------------------- /server/views/_partials/icons/home/logo-p_.pug: -------------------------------------------------------------------------------- 1 | xml(version="1.0" encoding="UTF-8" standalone="no") 2 | svg(class="w-12 h-12 ml-4" viewBox="0 0 80 80" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/") 3 | g(transform="translate(-21.55574,-0.85780717)") 4 | rect(class="text-transparent" fill="currentColor" width="76.895065" height="66.493217" x="21.55574" y="5.4498072") 5 | g(transform="translate(40.352312,-0.16746033)") 6 | path(d="m 9.475428,50.625267 h 7.784 a 15.048,15.048 0 0 0 6.448,-1.439999 16.448,16.448 0 0 0 5,-3.848 17.856,17.856 0 0 0 3.2,-5.6 18.256,18.256 0 0 0 1.152,-6.448001 15.816,15.816 0 0 0 -1.248,-6.248 19.024,19.024 0 0 0 -3.408,-5.44 16.96,16.96 0 0 0 -5.096,-3.944 13.808,13.808 0 0 0 -6.4,-1.536 h -20.504 v 49.704 h 13.072 z m 0,-22.503999 h 6.632 a 3.584,3.584 0 0 1 2.4,1.16 c 0.8,0.8 1.256,2.112 1.256,4.224 0,2.112 -0.48,3.368 -1.16,4.04 a 2.984,2.984 0 0 1 -2.2,1.175999 h -6.928 z" style="fill:#ffffff;stroke-width:0.8") 7 | path(d="M -18.796572,5.6172675 V 76.433267 a 4.592,4.592 0 0 0 4.592,4.592 h 70.816 a 4.592,4.592 0 0 0 4.592,-4.592 V 5.6172675 a 4.592,4.592 0 0 0 -4.592,-4.592 h -70.816 a 4.592,4.592 0 0 0 -4.592,4.592 z m 65.984,65.9840005 h -52.064 a 4.592,4.592 0 0 1 -4.592,-4.592 v -52.064 a 4.592,4.592 0 0 1 4.592,-4.592001 h 52.064 a 4.592,4.592 0 0 1 4.592,4.592001 v 52.063999 a 4.592,4.592 0 0 1 -4.592,4.592001 z" style="stroke-width:0.8;" fill="currentColor" class="text-transparent") 8 | rect(x="15.343428" y="56.42527" width="30.67" height="9.3999996" style="fill:#ffffff;") -------------------------------------------------------------------------------- /server/public/images/safari-pinned-tab.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by potrace 1.14, written by Peter Selinger 2001-2017 9 | 10 | 12 | 20 | 26 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /server/views/_partials/ad.pug: -------------------------------------------------------------------------------- 1 | template(x-if="state.ads") 2 | template(x-for="ad in state.ads") 3 | div(class="mx-2 md:mx-0 md:mr-0 md:mb-6 md:mt-0 my-4 md:max-w-xl lg:max-w-2xl p-4 bg-white dark:bg-background-dark200 dark:text-presearch-dark rounded shadow") 4 | div 5 | div(class="flex justify-between") 6 | a(class="cursor-pointer font-normal" target="_blank" rel="noopener noreferrer" class="text-presearch-alternative transition duration-150 hover:opacity-60 dark:text-presearch-dark inline-block") 7 | span(x-html="ad.headline" :class="$store.largeText && $store.largeText.status ? 'text-lg align-middle' : 'align-middle'") 8 | div(class="flex items-center text-results-link text-xs dark:text-gray-300" :class="$store.largeText && $store.largeText.status ? 'text-sm' : ''") 9 | span(class="rounded border px-0.5 mr-1 no-underline leading-none") Ad 10 | a(class="cursor-pointer underline" target="_blank" rel="noopener noreferrer") 11 | div #[span(x-html="generateLink(ad.link)")] 12 | a(href=`${settings.PRESEARCH_DOMAIN}/report/` :href="`${$el.href}${ad.code}`" title="Report Ad" target="_blank" rel="noopener noreferrer") 13 | div(class="ml-1.5 group cursor-pointer") 14 | div(class="hidden group-hover:block") 15 | i(class="fa fa-flag") 16 | div(class="block group-hover:hidden") 17 | i(class="fa fa-flag-o") 18 | div(x-html="ad.description" class="text-gray-800 dark:text-white mt-2 text-sm" :class="$store.largeText && $store.largeText.status ? 'text-base' : ''") 19 | -------------------------------------------------------------------------------- /server/views/_partials/icons/header/logo-p_.pug: -------------------------------------------------------------------------------- 1 | xml(version="1.0" encoding="UTF-8" standalone="no") 2 | svg(class="w-12 h-12 md:w-10 md:h-10" viewBox="0 0 80 80" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/") 3 | g(transform="translate(-21.55574,-0.85780717)") 4 | rect(class="text-presearch-default" fill="currentColor" width="76.895065" height="66.493217" x="21.55574" y="5.4498072") 5 | g(transform="translate(40.352312,-0.16746033)") 6 | path(d="m 9.475428,50.625267 h 7.784 a 15.048,15.048 0 0 0 6.448,-1.439999 16.448,16.448 0 0 0 5,-3.848 17.856,17.856 0 0 0 3.2,-5.6 18.256,18.256 0 0 0 1.152,-6.448001 15.816,15.816 0 0 0 -1.248,-6.248 19.024,19.024 0 0 0 -3.408,-5.44 16.96,16.96 0 0 0 -5.096,-3.944 13.808,13.808 0 0 0 -6.4,-1.536 h -20.504 v 49.704 h 13.072 z m 0,-22.503999 h 6.632 a 3.584,3.584 0 0 1 2.4,1.16 c 0.8,0.8 1.256,2.112 1.256,4.224 0,2.112 -0.48,3.368 -1.16,4.04 a 2.984,2.984 0 0 1 -2.2,1.175999 h -6.928 z" style="fill:#ffffff;stroke-width:0.8") 7 | path(d="M -18.796572,5.6172675 V 76.433267 a 4.592,4.592 0 0 0 4.592,4.592 h 70.816 a 4.592,4.592 0 0 0 4.592,-4.592 V 5.6172675 a 4.592,4.592 0 0 0 -4.592,-4.592 h -70.816 a 4.592,4.592 0 0 0 -4.592,4.592 z m 65.984,65.9840005 h -52.064 a 4.592,4.592 0 0 1 -4.592,-4.592 v -52.064 a 4.592,4.592 0 0 1 4.592,-4.592001 h 52.064 a 4.592,4.592 0 0 1 4.592,4.592001 v 52.063999 a 4.592,4.592 0 0 1 -4.592,4.592001 z" style="stroke-width:0.8;" fill="currentColor" class="text-presearch-default") 8 | rect(x="15.343428" y="56.42527" width="30.67" height="9.3999996" style="fill:#ffffff;") -------------------------------------------------------------------------------- /packages/periodicElements/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const pt = require('periodic-table'); 3 | 4 | function capitalize(string) { 5 | return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase(); 6 | } 7 | 8 | function unCamelCase(string) { 9 | return string 10 | .replace(/([A-Z])/g, ' $1') 11 | .replace(/^./, function(string){ return string.toUpperCase(); }) 12 | } 13 | 14 | const fieldNames = ['atomicNumber','symbol','atomicMass','electronicConfiguration','standardState','groupBlock','yearDiscovered'] 15 | 16 | async function periodicElements(query) { 17 | let data = false; 18 | let filteredData; 19 | const possibleElement = capitalize(query); 20 | if (possibleElement in pt.symbols) data = pt.symbols[possibleElement]; 21 | if (data) { 22 | filteredData = Object.keys(data).filter((item) => fieldNames.includes(item)); 23 | return ` 24 |
25 |

${data.name ? data.name : ``}

26 | ${filteredData.map((key, index) => ( 27 | `

${unCamelCase(key)}: ${data[key]}

` 28 | )).join('')} 29 |
30 | 42 | `; 43 | } 44 | else { 45 | return { error: "Failed to generate the data." }; 46 | } 47 | } 48 | 49 | // This line is for testing package with browserify bundle 50 | // window.periodic = periodicElements("H"); 51 | 52 | async function trigger(query) { 53 | return query.match(/^\w{1,2}$/); 54 | } 55 | 56 | module.exports = { periodicElements, trigger }; 57 | -------------------------------------------------------------------------------- /bin/create-package.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ ! -d "./packages/$1" ]; then 4 | echo "Creating package: $1" 5 | mkdir "./packages/$1" 6 | cd "./packages/$1" 7 | touch index.js 8 | printf "'use strict';\n\nasync function $1(query, API_KEY) {\n\t// returns a random integer between 0 and 9\n\tconst randomNumber = Math.floor(Math.random() * 10);\n\t// here you need to return HTML code for your package. You can use \n\t\n\t\n\t\`;\n}\n\n// here you should check, if the query should trigger your package\n// ie. if you are building 'randomNumber' package, 'random number' query will be a good choice\nasync function trigger(query) {\n\tif (query) {\n\t\t// convert query to lower case, to trigger the package with queries like 'Random number', 'RANDOM NUMBER' etc.\n\t\tquery = query ? query.toLowerCase() : \"\";\n\t\tif (query === \"random number\") return true;\n\t}\n\t// you need to return false when the query should not trigger your package\n\treturn false;\n}\n\nmodule.exports = { $1, trigger };" > index.js 9 | fi 10 | 11 | if [ -d "./packages/$1" ]; then 12 | echo "Package with the same name already exisits, please choose another name" 13 | fi 14 | -------------------------------------------------------------------------------- /server/public/assets/images/icon_dsearch.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 11 | 12 | 16 | 19 | -------------------------------------------------------------------------------- /server/views/_partials/icons/results/news.pug: -------------------------------------------------------------------------------- 1 | svg(class="w-4 h-4 mr-2" fill="currentColor" enable-background="new 0 0 512 512" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg") 2 | path(d="m502 0h-404c-5.522 0-10 4.477-10 10v44h-34c-5.522 0-10 4.478-10 10v54h-34c-5.523 0-10 4.478-10 10v330c0 29.775 24.225 54 54 54h404c29.775 0 54-24.225 54-54v-448c0-5.523-4.478-10-10-10zm-10 458c0 18.748-15.252 34-34 34h-362.088c7.55-9.29 12.088-21.123 12.088-34v-134.997c0-5.522-4.478-10-10-10s-10 4.478-10 10v134.997c0 18.748-15.252 34-34 34s-34-15.252-34-34v-320h24v310c0 5.522 4.478 10 10 10s10-4.478 10-10v-374h24v159.003c0 5.523 4.478 10 10 10s10-4.477 10-10v-213.003h384z") 3 | path(d="m146 158h308c5.522 0 10-4.477 10-10v-72c0-5.522-4.478-10-10-10h-308c-5.523 0-10 4.478-10 10v72c0 5.523 4.477 10 10 10zm10-72h288v52h-288z") 4 | path(d="m146 398h154c5.522 0 10-4.478 10-10v-192c0-5.523-4.478-10-10-10h-154c-5.523 0-10 4.477-10 10v192c0 5.522 4.477 10 10 10zm10-192h134v172h-134z") 5 | path(d="m454 186h-106c-5.522 0-10 4.477-10 10s4.478 10 10 10h106c5.522 0 10-4.477 10-10s-4.478-10-10-10z") 6 | path(d="m454 234h-106c-5.522 0-10 4.477-10 10s4.478 10 10 10h106c5.522 0 10-4.477 10-10s-4.478-10-10-10z") 7 | path(d="m454 282h-106c-5.522 0-10 4.478-10 10s4.478 10 10 10h106c5.522 0 10-4.478 10-10s-4.478-10-10-10z") 8 | path(d="m454 330h-106c-5.522 0-10 4.478-10 10s4.478 10 10 10h106c5.522 0 10-4.478 10-10s-4.478-10-10-10z") 9 | path(d="m454 378h-106c-5.522 0-10 4.478-10 10s4.478 10 10 10h106c5.522 0 10-4.478 10-10s-4.478-10-10-10z") 10 | path(d="m146 446h308c5.522 0 10-4.478 10-10s-4.478-10-10-10h-308c-5.523 0-10 4.478-10 10s4.477 10 10 10z") 11 | path(d="m98.5 268c-2.63 0-5.21 1.069-7.07 2.93-1.86 1.86-2.93 4.44-2.93 7.07 0 2.64 1.069 5.21 2.93 7.069 1.86 1.87 4.44 2.931 7.07 2.931s5.21-1.06 7.069-2.931c1.86-1.859 2.931-4.439 2.931-7.069s-1.07-5.21-2.931-7.07c-1.859-1.861-4.439-2.93-7.069-2.93z") -------------------------------------------------------------------------------- /server/views/_partials/icons/header/news.pug: -------------------------------------------------------------------------------- 1 | svg(class="hidden md:block w-3.5 h-3.5 mr-2" fill="currentColor" enable-background="new 0 0 512 512" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg") 2 | path(d="m502 0h-404c-5.522 0-10 4.477-10 10v44h-34c-5.522 0-10 4.478-10 10v54h-34c-5.523 0-10 4.478-10 10v330c0 29.775 24.225 54 54 54h404c29.775 0 54-24.225 54-54v-448c0-5.523-4.478-10-10-10zm-10 458c0 18.748-15.252 34-34 34h-362.088c7.55-9.29 12.088-21.123 12.088-34v-134.997c0-5.522-4.478-10-10-10s-10 4.478-10 10v134.997c0 18.748-15.252 34-34 34s-34-15.252-34-34v-320h24v310c0 5.522 4.478 10 10 10s10-4.478 10-10v-374h24v159.003c0 5.523 4.478 10 10 10s10-4.477 10-10v-213.003h384z") 3 | path(d="m146 158h308c5.522 0 10-4.477 10-10v-72c0-5.522-4.478-10-10-10h-308c-5.523 0-10 4.478-10 10v72c0 5.523 4.477 10 10 10zm10-72h288v52h-288z") 4 | path(d="m146 398h154c5.522 0 10-4.478 10-10v-192c0-5.523-4.478-10-10-10h-154c-5.523 0-10 4.477-10 10v192c0 5.522 4.477 10 10 10zm10-192h134v172h-134z") 5 | path(d="m454 186h-106c-5.522 0-10 4.477-10 10s4.478 10 10 10h106c5.522 0 10-4.477 10-10s-4.478-10-10-10z") 6 | path(d="m454 234h-106c-5.522 0-10 4.477-10 10s4.478 10 10 10h106c5.522 0 10-4.477 10-10s-4.478-10-10-10z") 7 | path(d="m454 282h-106c-5.522 0-10 4.478-10 10s4.478 10 10 10h106c5.522 0 10-4.478 10-10s-4.478-10-10-10z") 8 | path(d="m454 330h-106c-5.522 0-10 4.478-10 10s4.478 10 10 10h106c5.522 0 10-4.478 10-10s-4.478-10-10-10z") 9 | path(d="m454 378h-106c-5.522 0-10 4.478-10 10s4.478 10 10 10h106c5.522 0 10-4.478 10-10s-4.478-10-10-10z") 10 | path(d="m146 446h308c5.522 0 10-4.478 10-10s-4.478-10-10-10h-308c-5.523 0-10 4.478-10 10s4.477 10 10 10z") 11 | path(d="m98.5 268c-2.63 0-5.21 1.069-7.07 2.93-1.86 1.86-2.93 4.44-2.93 7.07 0 2.64 1.069 5.21 2.93 7.069 1.86 1.87 4.44 2.931 7.07 2.931s5.21-1.06 7.069-2.931c1.86-1.859 2.931-4.439 2.931-7.069s-1.07-5.21-2.931-7.07c-1.859-1.861-4.439-2.93-7.069-2.93z") -------------------------------------------------------------------------------- /packages/loremIpsumGenerator/services.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const DEFAULT_LENGTH = 12; 4 | const terms = ["lorem", "lorem ipsum", "ipsum"]; 5 | 6 | /** 7 | * Execute the lorem ipsum generation using the provided word length 8 | * @param {int} len 9 | * @returns {String} 10 | */ 11 | function generate(len) { 12 | const words = ["ad", "adipisicing", "aliqua", "aliquip", "amet", "anim", "aute", "cillum", "commodo", "consectetur", "consequat", "culpa", "cupidatat", "deserunt", "do", "dolor", "dolore", "duis", "ea", "eiusmod", "elit", "enim", "esse", "est", "et", "eu", "ex", "excepteur", "exercitation", "fugiat", "id", "in", "incididunt", "ipsum", "irure", "labore", "laboris", "laborum", "Lorem", "magna", "minim", "mollit", "nisi", "non", "nostrud", "nulla", "occaecat", "officia", "pariatur", "proident", "qui", "quis", "reprehenderit", "sint", "sit", "sunt", "tempor", "ullamco", "ut", "velit", "veniam", "voluptate"]; 13 | let res = ""; 14 | let length = DEFAULT_LENGTH; 15 | 16 | if (len && Number.isInteger(len) && (len > DEFAULT_LENGTH && len <= 1000)) { 17 | length = len; 18 | } 19 | 20 | for (let i = 0; i < length; i++) { 21 | const pos = Math.floor(Math.random() * (words.length - 1)); 22 | res += words[pos] + " "; 23 | } 24 | 25 | return res.charAt(0).toUpperCase() + res.slice(1).trim() + "."; 26 | } 27 | 28 | /** 29 | * Parses the query and normalizes it 30 | * @param {String} query 31 | * @returns {int} 32 | */ 33 | function parseAndNormalize(query) { 34 | for (let term of terms) { 35 | if (query.startsWith(term.toLowerCase())) { 36 | const queryArray = query.trim().split(" "); 37 | const lastQueryString = queryArray[queryArray.length - 1]; 38 | const num = parseInt(lastQueryString) || undefined; 39 | if (num !== undefined) { 40 | return num; 41 | } 42 | return DEFAULT_LENGTH; 43 | } 44 | } 45 | return undefined; 46 | } 47 | 48 | module.exports = { DEFAULT_LENGTH, parseAndNormalize, generate }; 49 | -------------------------------------------------------------------------------- /server/views/_partials/icons/header/sun.pug: -------------------------------------------------------------------------------- 1 | svg(class="w-4 h-4" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve") 2 | path(style="fill:#FFA600;" d="M507.834,301.608l-54.769-48.312l52.832-50.399c1.941-1.852,2.74-4.591,2.099-7.189 c-0.642-2.597-2.629-4.655-5.211-5.401l-70.316-20.292l25.988-68.056c0.955-2.5,0.495-5.316-1.204-7.389 c-1.7-2.072-4.383-3.085-7.038-2.657l-72.274,11.652l-5.878-72.561c-0.216-2.666-1.846-5.015-4.275-6.161 c-2.429-1.146-5.291-0.917-7.504,0.601l-60.266,41.342L263.409,3.742C262.064,1.426,259.579,0,256.889,0 c-2.69,0-5.174,1.426-6.519,3.742L208.347,76.11l-72.69-41.953c-2.327-1.343-5.197-1.349-7.528-0.018 c-2.333,1.331-3.773,3.799-3.78,6.473l-0.176,72.795l-72.965-6.014c-2.675-0.22-5.275,0.997-6.807,3.194 c-1.533,2.197-1.771,5.041-0.622,7.459l31.242,65.835L6.508,209.562c-2.516,0.943-4.335,3.15-4.773,5.789 c-0.438,2.638,0.575,5.308,2.656,7.003l56.619,46.152l-50.813,52.41c-1.866,1.925-2.559,4.694-1.816,7.264 c0.744,2.57,2.81,4.55,5.419,5.194l71.055,17.551L61.56,419.936c-0.856,2.535-0.286,5.331,1.494,7.336 c1.781,2.005,4.502,2.913,7.137,2.382l71.76-14.443l8.721,72.278c0.319,2.655,2.041,4.938,4.513,5.99 c2.474,1.052,5.323,0.712,7.475-0.891l58.596-43.647l39.055,59.566c1.382,2.179,3.789,3.492,6.367,3.492 c0.098,0,0.196-0.002,0.295-0.006c2.687-0.104,5.115-1.626,6.368-3.992l34.107-62.405l61.839,38.974 c2.273,1.432,5.137,1.55,7.522,0.31c2.382-1.24,3.919-3.65,4.03-6.322l3.031-72.734l72.674,8.84c2.664,0.324,5.31-0.791,6.928-2.927 c1.618-2.137,1.966-4.969,0.914-7.43l-28.636-66.997l69.465-23.003c2.552-0.845,4.456-2.979,4.997-5.599 C510.752,306.09,509.845,303.383,507.834,301.608z") 3 | ellipse(style="fill:#FFDB2D;" cx="254.35" cy="254.691" rx="155.069" ry="154.949") 4 | path(style="fill:#FFCA00;" d="M254.354,99.743c-3.884,0-7.732,0.147-11.543,0.428c80.25,5.901,143.525,72.825,143.525,154.521 c0,81.695-63.275,148.619-143.525,154.521c3.811,0.28,7.66,0.428,11.543,0.428c85.641,0,155.068-69.373,155.068-154.948 C409.422,169.116,339.995,99.743,254.354,99.743z") -------------------------------------------------------------------------------- /server/views/_partials/providers-desktop.pug: -------------------------------------------------------------------------------- 1 | div(x-show="$store.showProviders && $store.showProviders.show" x-transition:enter="transition ease-out" x-transition:enter-start="opacity-0 transform scale-95" x-transition:enter-end="opacity-100 transform scale-100" x-transition:leave="transition ease-in" x-transition:leave-start="opacity-100 transform scale-100" x-transition:leave-end="opacity-0 transform scale-95" class="w-10/12 lg:pl-6 md:pl-4 pt-5 space-y-4 flex flex-wrap") 2 | template(x-if="user && user.providersColored") 3 | template(x-for="(provider, index) in user.providersColored") 4 | div(x-bind:class="index % 2 !== 0 ? 'ml-4' : ''" x-data="{ show: false }" ) 5 | a(x-on:mouseover="show = true" x-on:mouseleave="show=false" :class="`svgIcon flex cursor-pointer w-14 h-14 bg-white dark:bg-background-dark200 rounded shadow items-center ${provider.icon.type === 'class' ? 'text-4xl' : ''}`" rel="noopener noreferrer" :key="provider.id") 6 | template(x-if="provider.icon.type === 'svg'") 7 | div(class="p-2 w-14 h-14 flex justify-center items-center transform transition hover:scale-110" x-html="decodeSVG(provider.icon.svg_content)") 8 | template(x-if="provider.icon.type === 'class'") 9 | div(class=`p-2 fa w-full items-center justify-center transform transition hover:scale-110` style="display:flex" x-bind:class="`${provider.icon.class} ${provider.icon.color}`") 10 | div(x-show="show" x-transition:enter="transition ease-out" x-transition:enter-start="opacity-0 transform scale-95" x-transition:enter-end="opacity-100 transform scale-100" x-transition:leave="transition ease-in" x-transition:leave-start="opacity-100 transform scale-100" x-transition:leave-end="opacity-0 transform scale-95" x-transition:leave.duration.50ms class="flex flex-col justify-center absolute z-50") 11 | div(class="arrow-up ml-6 relative z-10") 12 | div(class="whitespace-nowrap text-xs p-1 bg-black text-white dark:bg-white dark:text-black rounded relative shadow select-none" x-html="`${provider.name=='More Options' ? '' : 'Search on '}${provider.name}`") 13 | -------------------------------------------------------------------------------- /server/views/_layout.pug: -------------------------------------------------------------------------------- 1 | doctype html 2 | html(lang="en" class="dark h-full") 3 | head 4 | meta(charset="utf-8") 5 | meta(name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, shrink-to-fit=no") 6 | meta(http-equiv="x-ua-compatible" content="ie=edge") 7 | 8 | title #{title} 9 | script. 10 | if (document.cookie.includes("screenMode=dark")|| (!document.cookie.includes("screenMode") && window.matchMedia('(prefers-color-scheme: dark)').matches)) { 11 | document.documentElement.classList.add('dark'); 12 | } else { 13 | document.documentElement.classList.remove('dark'); 14 | } 15 | script. 16 | try { 17 | window.packageData = `!{packageData && !packageError ? packageData.split("").join("END_OF_SCRIPT_TAG") : ""}`; 18 | window.packageError = `!{packageError}`; 19 | setTimeout(() => { 20 | if (window.packageError) { 21 | if (typeof window.packageError !== "string") { 22 | window.packageError = JSON.stringify(window.packageError); 23 | } 24 | document.querySelector(".packageError").innerHTML = `Package error: ${window.packageError}`; 25 | } 26 | }, 100) 27 | } catch(err) { 28 | window.packageData = ""; 29 | } 30 | script. 31 | try { 32 | window.packageInfo = JSON.parse('!{packageInfo}'); 33 | } catch(err) { 34 | console.log(err) 35 | window.packageInfo = {}; 36 | } 37 | 38 | link(rel="stylesheet" href="/assets/app.css") 39 | link(rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous") 40 | script(src="assets/app.js", defer) 41 | body(class="bg-background-light200 dark:bg-background-dark500 h-full") 42 | div(x-data=`userInfo("${settings.PRESEARCH_DOMAIN}")` :class="'h-full'") 43 | block content 44 | -------------------------------------------------------------------------------- /server/views/_partials/icons/social/twitter.pug: -------------------------------------------------------------------------------- 1 | svg(viewBox="0 -47 512.00004 512" fill="currentColor" xmlns="http://www.w3.org/2000/svg") 2 | path(d="m512 55.964844c-32.207031 1.484375-31.503906 1.363281-35.144531 1.667968l19.074219-54.472656s-59.539063 21.902344-74.632813 25.820313c-39.640625-35.628907-98.5625-37.203125-140.6875-11.3125-34.496094 21.207031-53.011719 57.625-46.835937 100.191406-67.136719-9.316406-123.703126-41.140625-168.363282-94.789063l-14.125-16.964843-10.554687 19.382812c-13.339844 24.492188-17.769531 52.496094-12.476563 78.851563 2.171875 10.8125 5.863282 21.125 10.976563 30.78125l-12.117188-4.695313-1.4375 20.246094c-1.457031 20.566406 5.390625 44.574219 18.320313 64.214844 3.640625 5.53125 8.328125 11.605469 14.269531 17.597656l-6.261719-.960937 7.640625 23.199218c10.042969 30.480469 30.902344 54.0625 57.972657 67.171875-27.035157 11.472657-48.875 18.792969-84.773438 30.601563l-32.84375 10.796875 30.335938 16.585937c11.566406 6.324219 52.4375 27.445313 92.820312 33.78125 89.765625 14.078125 190.832031 2.613282 258.871094-58.664062 57.308594-51.613282 76.113281-125.03125 72.207031-201.433594-.589844-11.566406 2.578125-22.605469 8.921875-31.078125 12.707031-16.964844 48.765625-66.40625 48.84375-66.519531zm-72.832031 48.550781c-10.535157 14.066406-15.8125 32.03125-14.867188 50.578125 3.941407 77.066406-17.027343 136.832031-62.328125 177.628906-52.917968 47.660156-138.273437 66.367188-234.171875 51.324219-17.367187-2.722656-35.316406-8.820313-50.171875-14.910156 30.097656-10.355469 53.339844-19.585938 90.875-37.351563l52.398438-24.800781-57.851563-3.703125c-27.710937-1.773438-50.785156-15.203125-64.96875-37.007812 7.53125-.4375 14.792969-1.65625 22.023438-3.671876l55.175781-15.367187-55.636719-13.625c-27.035156-6.621094-42.445312-22.796875-50.613281-35.203125-5.363281-8.152344-8.867188-16.503906-10.96875-24.203125 5.578125 1.496094 12.082031 2.5625 22.570312 3.601563l51.496094 5.09375-40.800781-31.828126c-29.398437-22.929687-41.179687-57.378906-32.542969-90.496093 91.75 95.164062 199.476563 88.011719 210.320313 90.527343-2.386719-23.183593-2.449219-23.238281-3.074219-25.445312-13.886719-49.089844 16.546875-74.015625 30.273438-82.453125 28.671874-17.621094 74.183593-20.277344 105.707031 8.753906 6.808593 6.265625 16.015625 8.730469 24.632812 6.589844 7.734375-1.921875 14.082031-3.957031 20.296875-6.171875l-12.9375 36.945312 16.515625.011719c-3.117187 4.179688-6.855469 9.183594-11.351562 15.183594zm0 0") -------------------------------------------------------------------------------- /server/views/_partials/icons/header/features.pug: -------------------------------------------------------------------------------- 1 | svg(class="w-3.5 h-3.5 mr-2" fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 368 368") 2 | path(d="M344 144h-29.952c-2.512-8.2-5.8-16.12-9.792-23.664l21.16-21.16c4.528-4.528 7.024-10.56 7.024-16.984 0-6.416-2.496-12.448-7.024-16.976l-22.64-22.64c-9.048-9.048-24.888-9.072-33.952 0l-21.16 21.16A135.753 135.753 0 00224 53.944V24c0-13.232-10.768-24-24-24h-32c-13.232 0-24 10.768-24 24v29.952c-8.2 2.52-16.12 5.8-23.664 9.792l-21.168-21.16c-9.36-9.36-24.592-9.36-33.952 0l-22.648 22.64c-9.352 9.36-9.352 24.592 0 33.952l21.16 21.168a135.753 135.753 0 00-9.792 23.664H24c-13.232 0-24 10.768-24 24v32C0 213.232 10.768 224 24 224h29.952c2.52 8.2 5.8 16.12 9.792 23.664l-21.16 21.168c-9.36 9.36-9.36 24.592 0 33.952l22.64 22.648c9.36 9.352 24.592 9.352 33.952 0l21.168-21.16a135.753 135.753 0 0023.664 9.792V344c0 13.232 10.768 24 24 24h32c13.232 0 24-10.768 24-24v-29.952c8.2-2.52 16.128-5.8 23.664-9.792l21.16 21.168c9.072 9.064 24.912 9.048 33.952 0l22.64-22.64c4.528-4.528 7.024-10.56 7.024-16.976 0-6.424-2.496-12.448-7.024-16.976l-21.16-21.168A135.753 135.753 0 00314.056 224H344c13.232 0 24-10.768 24-24v-32c0-13.232-10.768-24-24-24zm8 56c0 4.408-3.584 8-8 8h-36a8.002 8.002 0 00-7.744 6c-2.832 10.92-7.144 21.344-12.832 30.976a8.01 8.01 0 001.232 9.72l25.44 25.448a7.948 7.948 0 012.336 5.664c0 2.152-.832 4.16-2.336 5.664l-22.64 22.64c-3.008 3.008-8.312 3.008-11.328 0l-25.44-25.44c-2.576-2.584-6.576-3.08-9.728-1.232-9.616 5.68-20.04 10-30.968 12.824A7.988 7.988 0 00208 308v36c0 4.408-3.584 8-8 8h-32c-4.408 0-8-3.592-8-8v-36a8.002 8.002 0 00-6-7.744 119.948 119.948 0 01-30.976-12.824 7.915 7.915 0 00-4.064-1.112c-2.072 0-4.12.8-5.664 2.344l-25.44 25.44a8.025 8.025 0 01-11.328 0l-22.64-22.64c-3.128-3.128-3.128-8.208 0-11.328l25.44-25.44a7.99 7.99 0 001.232-9.72c-5.68-9.632-10-20.048-12.824-30.976A7.986 7.986 0 0060 208H24c-4.408 0-8-3.592-8-8v-32c0-4.408 3.592-8 8-8h36a8.002 8.002 0 007.744-6 119.948 119.948 0 0112.824-30.976 7.988 7.988 0 00-1.232-9.72l-25.44-25.44c-3.12-3.12-3.12-8.2 0-11.328l22.64-22.64c3.128-3.128 8.2-3.12 11.328 0l25.44 25.44a7.978 7.978 0 009.72 1.232c9.632-5.68 20.048-10 30.976-12.824A8.002 8.002 0 00160 60V24c0-4.408 3.592-8 8-8h32c4.416 0 8 3.592 8 8v36a8.002 8.002 0 006 7.744 119.827 119.827 0 0130.968 12.824c3.152 1.856 7.152 1.36 9.728-1.232l25.44-25.44c3.016-3.024 8.32-3.016 11.328 0l22.64 22.64c1.504 1.504 2.336 3.52 2.336 5.664s-.832 4.16-2.336 5.664l-25.44 25.44a8.002 8.002 0 00-1.232 9.72c5.688 9.632 10 20.048 12.832 30.976a7.986 7.986 0 007.736 6h36c4.416 0 8 3.592 8 8v32z") 3 | path(d="M184 112c-39.696 0-72 32.304-72 72s32.304 72 72 72c39.704 0 72-32.304 72-72s-32.296-72-72-72zm0 128c-30.88 0-56-25.12-56-56s25.12-56 56-56c30.872 0 56 25.12 56 56s-25.128 56-56 56z") -------------------------------------------------------------------------------- /server/views/_partials/search-form.pug: -------------------------------------------------------------------------------- 1 | div(class="flex-1 flex items-center relative w-52") 2 | form(action=`${path}` name="q" method="GET" class="w-full" x-on:submit="resultsFormSubmit($event, $refs.searchInput.value)") 3 | div(class="relative overflow-hidden shadow rounded flex items-center mt-3 md:mt-5") 4 | input(x-ref="searchInput" placeholder="Test your package ᕙ(⇀‸↼‶)ᕗ" type="text" autocomplete="off" name="q" value=`${requestQuery ? decodeURIComponent(requestQuery) : ""}` class="w-full h-12 pr-20 focus:outline-none pl-4 font-light dark:bg-background-dark300 dark:text-gray-50 text-sm sm:text-base" autofocus=requestQuery ? false : true) 5 | div(x-data="searchForm()" class="absolute top-0 right-0 flex items-center h-full ml-2 mr-2") 6 | svg(x-show="state.clearButton" @click="clearButtonPress()" fill="currentColor" class="w-6 h-6 mr-1 cursor-pointer hover:opacity-40 transition p-2 dark:text-white" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 492 492" style="enable-background:new 0 0 492 492;" xml:space="preserve" x-cloak) 7 | path(d="M300.188,246L484.14,62.04c5.06-5.064,7.852-11.82,7.86-19.024c0-7.208-2.792-13.972-7.86-19.028L468.02,7.872 c-5.068-5.076-11.824-7.856-19.036-7.856c-7.2,0-13.956,2.78-19.024,7.856L246.008,191.82L62.048,7.872 c-5.06-5.076-11.82-7.856-19.028-7.856c-7.2,0-13.96,2.78-19.02,7.856L7.872,23.988c-10.496,10.496-10.496,27.568,0,38.052 L191.828,246L7.872,429.952c-5.064,5.072-7.852,11.828-7.852,19.032c0,7.204,2.788,13.96,7.852,19.028l16.124,16.116 c5.06,5.072,11.824,7.856,19.02,7.856c7.208,0,13.968-2.784,19.028-7.856l183.96-183.952l183.952,183.952 c5.068,5.072,11.824,7.856,19.024,7.856h0.008c7.204,0,13.96-2.784,19.028-7.856l16.12-16.116 c5.06-5.064,7.852-11.824,7.852-19.028c0-7.204-2.792-13.96-7.852-19.028L300.188,246z") 8 | span(class="w-px h-5 mx-1 bg-gray-200 dark:bg-gray-200") 9 | button(type="submit" class="text-primary-500 hover:opacity-70 p-2 dark:hover:opacity-60 dark:text-white transition") 10 | svg(class="w-5 h-5 color-presearch-default" fill="currentColor" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve") 11 | path(d="M505.749,475.587l-145.6-145.6c28.203-34.837,45.184-79.104,45.184-127.317c0-111.744-90.923-202.667-202.667-202.667 S0,90.925,0,202.669s90.923,202.667,202.667,202.667c48.213,0,92.48-16.981,127.317-45.184l145.6,145.6 c4.16,4.16,9.621,6.251,15.083,6.251s10.923-2.091,15.083-6.251C514.091,497.411,514.091,483.928,505.749,475.587z M202.667,362.669c-88.235,0-160-71.765-160-160s71.765-160,160-160s160,71.765,160,160S290.901,362.669,202.667,362.669z") -------------------------------------------------------------------------------- /server/views/index.pug: -------------------------------------------------------------------------------- 1 | extends _layout 2 | 3 | include ./wrapper 4 | 5 | block content 6 | style. 7 | .mainContainer { 8 | width: 60%; 9 | } 10 | @media screen and (max-width: 1920px) { 11 | .mainContainer { 12 | width: 70%; 13 | } 14 | } 15 | @media screen and (max-width: 1600px) { 16 | .mainContainer { 17 | width: 80%; 18 | } 19 | } 20 | @media screen and (max-width: 1400px) { 21 | .mainContainer { 22 | width: 90%; 23 | } 24 | } 25 | div(x-show="$store.showSettings && $store.showSettings.show" x-on:mouseover="hideSettings(true, false, true)" class="fixed w-screen h-screen z-20 top-0 left-0") 26 | div(class="h-full dark:bg-background-dark300 dark:text-white") 27 | div(class="bg-presearch-default dark:bg-background-dark500" style="height: 90px") 28 | div(class="absolute mt-3 md:mt-5 top-0 ml-2") 29 | include _partials/icons/home/logo-p_ 30 | div(class="absolute top-0 right-0 mr-2 mt-6 md:mt-8 md:mr-8") 31 | include _partials/user-info-homepage.pug 32 | include _partials/settings 33 | div(class="mt-8 text-center dark:text-white mb-2") 34 | h2 Welcome to #[span(class="text-presearch-default") Presearch Packages] dev center (◉‿◉)つ 35 | div(class="flex mx-auto mt-6 mainContainer") 36 | div(class="flex-1" style="margin-left: 2rem; margin-right:4rem") 37 | h2(class="mb-2") How to start? 38 | div(class="mt-1") 1. Open your terminal and navigate to #[span(class="text-presearch-default text-sm") presearch-packages] directory 39 | div(class="mt-1") 2. Run #[span(class="bg-gray-300 dark:bg-background-dark400 text-sm rounded p-1 mb-1") npm install] command 40 | div(class="mt-1") 3. Run #[span(class="bg-gray-300 dark:bg-background-dark400 text-sm rounded p-1 mb-1") npm run create-package {packageName}] command 41 | div(class="mt-1") 4. Open #[span(class="text-presearch-default text-sm") presearch-packages/packages/{packageName}] directory in your favorite code editor 42 | h2(class="mb-2 mt-8") How to test? 43 | div(class="mt-1") If you already created your package, it should appear on the list of packages. 44 | div(class="mt-1") You can click on it or navigate to #[span(class="text-presearch-default text-sm") http://localhost:4000/{packageName}]. 45 | div(class="mt-1") Then just preform a search - that's all! 46 | h2(class="mb-2 mt-8") Have fun! ;-) 47 | div(class="p-4 self-end mr-8 rounded bg-gray-200 dark:bg-background-dark400") 48 | h2(class="mx-2") List of packages: 49 | div(class="ml-2") 50 | each packageName, index in Object.keys(packageObject) 51 | div(class="mt-2") 52 | a(href=`/${packageName}`) !{packageName} 53 | -------------------------------------------------------------------------------- /server/views/_partials/standard-results.pug: -------------------------------------------------------------------------------- 1 | template(x-if="state.results && state.results.standardResults && state.results.standardResults.length") 2 | div(class="text-gray-300") 3 | include ./ad 4 | template(x-for="(result, index) in state.results.standardResults") 5 | div 6 | div(class="mx-2 md:mx-0 md:mr-0 md:max-w-xl lg:max-w-2xl pr-4 p-4 bg-white dark:bg-background-dark200 shadow rounded mb-3") 7 | div 8 | div 9 | div(class="inline-block md:items-center") 10 | a(x-bind:target="$store.linksInNewTab && $store.linksInNewTab.status ? '_blank' : '_self'" class="cursor-pointer font-normal text-base text-primary-600 transition duration-150 hover:underline hover:opacity-70 dark:hover:opacity-60 dark:text-presearch-dark inline-block" :class="$store.largeText && $store.largeText.status ? 'text-lg' : ''") 11 | template(x-if="result.favicon") 12 | img(class="w-4 h-4 mr-1 mb-1 inline-block hidden" alt="" x-cloak) 13 | span(x-html="result.title") 14 | div 15 | a(x-bind:target="$store.linksInNewTab && $store.linksInNewTab.status ? '_blank' : '_self'" class="cursor-pointer text-results-link mt-1 font-normal underline text-xs dark:text-gray-300" :class="$store.largeText && $store.largeText.status ? 'text-sm' : ''") 16 | div(x-html="generateLink(result.link)" class="break-all") 17 | div(class="text-gray-800 dark:text-white mt-2 text-sm" :class="`${$store.largeText && $store.largeText.status ? 'text-base' : ''}`" x-html="result.description ? adjustLongWordDescription(result.description) : ''") 18 | template(x-if="result.extraDescription") 19 | div(class="mt-2 md:flex md:mt-0 flex-row flex-wrap text-sm link-tilt text-gray-800 dark:text-white") 20 | template(x-for="extra in result.extraDescription") 21 | div(x-html="extra" class="mt-1 md:flex-2 text-xs mt-2" :class="$store.largeText && $store.largeText.status ? 'text-xs' : ''") 22 | template(x-if="result.similarSearches") 23 | div 24 | hr(class="min-w-full mt-3.5 dark:border-gray-600") 25 | div(class="md:flex mt-1.5 flex-row flex-wrap text-sm" :class="$store.largeText && $store.largeText.status ? 'text-base' : ''") 26 | template(x-for="similar in result.similarSearches") 27 | div(x-html="similar" class="mr-4 mt-1 font-semibold text-xs text-gray-800 transition duration-150 hover:opacity-70 dark:hover:opacity-60 dark:text-white") -------------------------------------------------------------------------------- /create-package.js: -------------------------------------------------------------------------------- 1 | const { exec, spawn } = require("child_process"); 2 | const fs = require("fs"); 3 | const colors = require("colors"); 4 | const readline = require("readline"); 5 | const rl = readline.createInterface({ 6 | input: process.stdin, 7 | output: process.stdout, 8 | }); 9 | 10 | const isWindows = process.platform === "win32"; 11 | 12 | const packageName = process.argv[2]; 13 | if (!packageName) { 14 | console.log("Error: Please enter package name".red, "\nnpm run create-package {package-name}\n".yellow); 15 | return process.exit(0); 16 | } 17 | try { 18 | let packageDir = fs.readdirSync(`./packages/${packageName}`); 19 | if (packageDir) { 20 | console.log(`Error: Package ${packageName} already exist.\n`.red); 21 | return process.exit(0); 22 | } 23 | } catch (err) {} 24 | 25 | function execCallback(error) { 26 | if (error) { 27 | console.log(`\nError: package has not been created... ${error}`.red); 28 | return process.exit(0); 29 | } 30 | const cmd = isWindows ? "cmd" : "npm"; 31 | const args = isWindows ? ["/c", "npm init -y --quiet > NUL"] : ["init -y &>/dev/null"]; 32 | 33 | const npmInitComman = spawn(cmd, args, { 34 | shell: true, 35 | stdio: "inherit", 36 | cwd: `${__dirname}/packages/${packageName}`, 37 | }); 38 | npmInitComman.on("close", () => { 39 | let userName; 40 | rl.question("Enter your name: ".cyan, (name) => { 41 | userName = name; 42 | rl.close(); 43 | }); 44 | 45 | rl.on("close", function () { 46 | let packageInfo = fs.readFileSync(`./packages/${packageName}/package.json`); 47 | packageInfo = JSON.parse(packageInfo); 48 | packageInfo.author = userName; 49 | packageInfo.license = "MIT"; 50 | packageInfo = JSON.stringify(packageInfo); 51 | packageInfo = packageInfo.split(",").join(",\n ").split("{").join("{\n ").split("}").join("\n}"); 52 | fs.writeFileSync(`./packages/${packageName}/package.json`, packageInfo); 53 | console.log(`\nSuccess! ${packageName} package has been created!\n`.green); 54 | console.log(`You can now open`.cyan + ` packages/${packageName} `.yellow + `directory in your fav code editor.\n`.cyan); 55 | console.log( 56 | `If you want to test your package, run a test server`.cyan + 57 | ` cd server && npm run start `.yellow + 58 | `and open`.cyan + 59 | ` http://localhost:4000/${packageName} `.yellow + 60 | `in your web browser.\n`.cyan 61 | ); 62 | process.exit(0); 63 | }); 64 | }); 65 | } 66 | 67 | if (isWindows) exec(`npm run create-package-windows ${packageName}`, execCallback); 68 | else exec(`npm run create-package-linux ${packageName}`, execCallback); 69 | -------------------------------------------------------------------------------- /server/views/_partials/icons/social/youtube.pug: -------------------------------------------------------------------------------- 1 | svg(viewBox="0 -62 512.00199 512" fill="currentColor" xmlns="http://www.w3.org/2000/svg") 2 | path(d="m334.808594 170.992188-113.113282-61.890626c-6.503906-3.558593-14.191406-3.425781-20.566406.351563-6.378906 3.78125-10.183594 10.460937-10.183594 17.875v122.71875c0 7.378906 3.78125 14.046875 10.117188 17.832031 3.308594 1.976563 6.976562 2.96875 10.652344 2.96875 3.367187 0 6.742187-.832031 9.847656-2.503906l113.117188-60.824219c6.714843-3.613281 10.90625-10.59375 10.9375-18.222656.027343-7.628906-4.113282-14.640625-10.808594-18.304687zm-113.859375 63.617187v-91.71875l84.539062 46.257813zm0 0") 3 | path(d="m508.234375 91.527344-.023437-.234375c-.433594-4.121094-4.75-40.777344-22.570313-59.421875-20.597656-21.929688-43.949219-24.59375-55.179687-25.871094-.929688-.105469-1.78125-.203125-2.542969-.304688l-.894531-.09375c-67.6875-4.921874-169.910157-5.5937495-170.933594-5.59765575l-.089844-.00390625-.089844.00390625c-1.023437.00390625-103.246094.67578175-171.542968 5.59765575l-.902344.09375c-.726563.097657-1.527344.1875-2.398438.289063-11.101562 1.28125-34.203125 3.949219-54.859375 26.671875-16.972656 18.445312-21.878906 54.316406-22.382812 58.347656l-.058594.523438c-.152344 1.714844-3.765625 42.539062-3.765625 83.523437v38.3125c0 40.984375 3.613281 81.808594 3.765625 83.527344l.027344.257813c.433593 4.054687 4.746093 40.039062 22.484375 58.691406 19.367187 21.195312 43.855468 24 57.027344 25.507812 2.082031.238282 3.875.441406 5.097656.65625l1.183594.164063c39.082031 3.71875 161.617187 5.550781 166.8125 5.625l.15625.003906.15625-.003906c1.023437-.003907 103.242187-.675781 170.929687-5.597657l.894531-.09375c.855469-.113281 1.816406-.214843 2.871094-.324218 11.039062-1.171875 34.015625-3.605469 54.386719-26.019532 16.972656-18.449218 21.882812-54.320312 22.382812-58.347656l.058594-.523437c.152344-1.71875 3.769531-42.539063 3.769531-83.523438v-38.3125c-.003906-40.984375-3.617187-81.804687-3.769531-83.523437zm-26.238281 121.835937c0 37.933594-3.3125 77-3.625 80.585938-1.273438 9.878906-6.449219 32.574219-14.71875 41.5625-12.75 14.027343-25.847656 15.417969-35.410156 16.429687-1.15625.121094-2.226563.238282-3.195313.359375-65.46875 4.734375-163.832031 5.460938-168.363281 5.488281-5.082032-.074218-125.824219-1.921874-163.714844-5.441406-1.941406-.316406-4.039062-.558594-6.25-.808594-11.214844-1.285156-26.566406-3.042968-38.371094-16.027343l-.277344-.296875c-8.125-8.464844-13.152343-29.6875-14.429687-41.148438-.238281-2.710937-3.636719-42.238281-3.636719-80.703125v-38.3125c0-37.890625 3.304688-76.914062 3.625-80.574219 1.519532-11.636718 6.792969-32.957031 14.71875-41.574218 13.140625-14.453125 26.996094-16.054688 36.160156-17.113282.875-.101562 1.691407-.195312 2.445313-.292968 66.421875-4.757813 165.492187-5.464844 169.046875-5.492188 3.554688.023438 102.589844.734375 168.421875 5.492188.808594.101562 1.691406.203125 2.640625.3125 9.425781 1.074218 23.671875 2.699218 36.746094 16.644531l.121094.128906c8.125 8.464844 13.152343 30.058594 14.429687 41.75.226563 2.558594 3.636719 42.171875 3.636719 80.71875zm0 0") -------------------------------------------------------------------------------- /server/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | require("dotenv").config(); 3 | 4 | const fs = require("fs"); 5 | const express = require("express"); 6 | const packageObject = require(`${__dirname}/../index`); 7 | const app = express(); 8 | const PORT = 4000; 9 | 10 | // Allow all origins (for development) 11 | const cors = require('cors'); 12 | app.use(cors()); 13 | 14 | app.set("view engine", "pug"); 15 | app.set("title", "Presearch"); 16 | app.set("PRESEARCH_DOMAIN", "/"); 17 | app.use(express.static("public")); 18 | 19 | // Share current path and query with views 20 | app.use((req, res, next) => { 21 | res.locals.path = req.path; 22 | next(); 23 | }); 24 | 25 | 26 | const checkOverlappingTrigger = async (query) => { 27 | return new Promise(async (resolve, reject) => { 28 | const packages = Object.keys(packageObject); 29 | const triggeredPackages = []; 30 | for (const packageName of packages) { 31 | const trigger = await packageObject[packageName].trigger(query); 32 | if (trigger) { 33 | triggeredPackages.push(packageName); 34 | } 35 | } 36 | if (triggeredPackages.length > 1) { 37 | return resolve(triggeredPackages); 38 | } 39 | resolve(false); 40 | }); 41 | }; 42 | 43 | const addRoutesTimeout = setTimeout(() => { 44 | if (packageObject && Object.keys(packageObject).length) { 45 | clearTimeout(addRoutesTimeout); 46 | Object.keys(packageObject).forEach((packageName) => { 47 | let packageInfo = fs.readFileSync(`../packages/${packageName}/package.json`); 48 | const { version, author } = JSON.parse(packageInfo); 49 | app.get(`/${packageName}`, async (req, res) => { 50 | const startTime = Date.now(); 51 | const query = req.query.q ? req.query.q : ""; 52 | const geolocation = req.query.geolocation && req.query.geolocation === "1" ? { city: 'London', coords: { lat: 51.5095, lon: -0.0955 } } : null; 53 | const trigger = await packageObject[packageName].trigger(query); 54 | if (trigger) { 55 | const overlappingPackages = await checkOverlappingTrigger(query); 56 | const packageData = await packageObject[packageName][packageName](query, process.env[`API.${packageName.toUpperCase()}`], geolocation); 57 | const packageError = (packageData && packageData.error) && packageData.error; 58 | const totalTime = Date.now() - startTime; 59 | return res.render("search", { title: packageName, packageData, packageError, triggered: true, overlappingPackages, query, packageInfo: JSON.stringify({ version, author }), totalTime }); 60 | } 61 | res.render("search", { title: packageName, triggered: false, query, packageInfo}); 62 | }); 63 | }); 64 | } 65 | }, 200); 66 | 67 | app.get("/", async (req, res) => { 68 | res.render("index", { packageObject }); 69 | }); 70 | 71 | app.listen(PORT, () => console.log(`Server listening on: ${PORT}`)); 72 | -------------------------------------------------------------------------------- /packages/currencyConverter/services.test.js: -------------------------------------------------------------------------------- 1 | const axios = require("axios"); 2 | const { parseAndNormalize, convert, fetchRates } = require("./services"); 3 | 4 | jest.mock("axios"); 5 | 6 | describe("services", function () { 7 | it("should be able to parse and normalize a query", function () { 8 | expect(parseAndNormalize("5 btc to cad")).toEqual({ value: 5, from: "BTC", to: "CAD", fromName: "Bitcoin" }); 9 | // test case sensitivity 10 | expect(parseAndNormalize("1337 ETh to UsD")).toEqual({ value: 1337, from: "ETH", to: "USD", fromName: "Ethereum" }); 11 | // test no value 12 | expect(parseAndNormalize("ETh to UsD")).toEqual({ value: 1, from: "ETH", to: "USD", fromName: "Ethereum" }); 13 | // test fractions 14 | expect(parseAndNormalize("5,6 btc to cad")).toEqual({ value: 5.6, from: "BTC", to: "CAD", fromName: "Bitcoin" }); 15 | expect(parseAndNormalize("5.2 btc to cad")).toEqual({ value: 5.2, from: "BTC", to: "CAD", fromName: "Bitcoin" }); 16 | // test trim 17 | expect(parseAndNormalize(" 5 btc to cad ")).toEqual({ value: 5, from: "BTC", to: "CAD", fromName: "Bitcoin" }); 18 | // test fiat 19 | expect(parseAndNormalize("1337 eur to UsD")).toEqual({ value: 1337, from: "EUR", to: "USD", fromName: "" }); 20 | }); 21 | 22 | it("should be able to fetch rates", async function () { 23 | axios.get.mockImplementation(url => 24 | Promise.resolve({ 25 | data: url.includes("ec.europa.eu") 26 | ? [ 27 | { 28 | isoA3Code: "EUR", 29 | value: 1 30 | }, 31 | { 32 | isoA3Code: "USD", 33 | value: 10, 34 | } 35 | ] 36 | : { 37 | data: { 38 | 1: { 39 | symbol: "BTC", 40 | quote: { 41 | USD: { 42 | price: 60000, 43 | } 44 | } 45 | } 46 | } 47 | } 48 | }) 49 | ); 50 | 51 | const conversion = { 52 | from: "EUR", 53 | to: "BTC", 54 | value: 5, 55 | }; 56 | 57 | const expected = [ 58 | { 59 | code: "EUR", 60 | rate: 1, 61 | round: 2, 62 | }, 63 | { 64 | code: "USD", 65 | rate: 10, 66 | round: 2, 67 | }, 68 | { 69 | code: "BTC", 70 | rate: 0.00016666666666666666, 71 | round: undefined, 72 | } 73 | ]; 74 | 75 | const rates = await fetchRates(conversion, "123"); 76 | 77 | expect(rates).toEqual(expected); 78 | }); 79 | 80 | it("should be able to convert from one currency to another", function () { 81 | const conversion = { 82 | from: "EUR", 83 | to: "SEK", 84 | value: 100, 85 | }; 86 | 87 | const rates = [ 88 | { 89 | code: "EUR", 90 | rate: 1, 91 | }, 92 | { 93 | code: "SEK", 94 | rate: 10.7, 95 | } 96 | ]; 97 | 98 | const expected = { 99 | code: "SEK", 100 | round: undefined, 101 | value: 1070, 102 | }; 103 | 104 | expect(convert(conversion, rates)).toEqual(expected); 105 | }); 106 | 107 | }); 108 | -------------------------------------------------------------------------------- /server/views/_partials/settings.pug: -------------------------------------------------------------------------------- 1 | div(x-show="$store.showSettings && $store.showSettings.show" x-transition:enter="transition ease-out" x-transition:enter-start="opacity-0 transform scale-95" x-transition:enter-end="opacity-100 transform scale-100" x-transition:leave="transition ease-in" x-transition:leave-start="opacity-100 transform scale-100" x-transition:leave-end="opacity-0 transform scale-95" class="fixed z-20 p-6 sm:w-96 w-full max-w-full h-auto min-h-full bg-background-light100 dark:bg-background-dark200 shadow top-0 right-0" :class="Alpine.store('lowWidthScreen') && Alpine.store('lowWidthScreen').status ? 'absolute' : ''" @click.outside="hideSettings(user.shareVisible)" x-cloak) 2 | div(x-data=`settings('${settings.PRESEARCH_DOMAIN}')` class="flex flex-col dark:text-white") 3 | div(class="flex" style="justify-content:flex-end") 4 | div(class="self-end mt-2 flex items-center cursor-pointer text-black dark:text-white hover:opacity-60 transition font-light" @click="hideSettings(true, true)") 5 | include ./icons/header/arrow-left 6 | div(class="select-none") Back 7 | div(class="p-4 bg-white dark:bg-background-dark400 rounded mt-6") 8 | div(class="uppercase text-xs text-presearch-alternative") 9 | div 10 | span(class="mr-1") Interface 11 | div 12 | hr(class="my-3") 13 | div(class="mb-3") 14 | div(class="flex items-center justify-between") 15 | div 16 | div(class="text-sm") Theme 17 | div(class="text-xs font-light") Update the look and feel. 18 | div(class="flex items-center") 19 | div(@click="enableDarkMode()" class="flex items-center p-2 cursor-pointer hover:opacity-60 transition rounded" :class="`${state.darkModeEnabled ? 'bg-background-dark200' : ''}`") 20 | div(class="mr-2") 21 | include ./icons/header/moon 22 | div(class="text-sm font-light") Dark 23 | div(@click="disableDarkMode()" class="flex items-center p-2 cursor-pointer hover:opacity-60 transition rounded" :class="`${!state.darkModeEnabled ? 'bg-gray-100' : ''}`") 24 | div(class="mr-2") 25 | include ./icons/header/sun 26 | div(class="text-sm font-light") Light 27 | div 28 | div(class="flex items-center justify-between") 29 | div 30 | div(class="text-sm") Text Size 31 | div(class="text-xs font-light") Change results text size. 32 | div(class="flex items-center") 33 | div(@click="useLargeText(false)" class="flex items-center p-2 mr-3 cursor-pointer hover:opacity-60 transition rounded" :class="`${$store.largeText && !$store.largeText.status ? 'bg-gray-100 dark:bg-background-dark200' : ''}`") 34 | div(class="text-sm select-none") aA 35 | div(@click="useLargeText(true)" class="flex items-center p-1 px-2 cursor-pointer hover:opacity-60 transition rounded" :class="`${$store.largeText && $store.largeText.status ? 'bg-gray-100 dark:bg-background-dark200' : ''}`") 36 | div(class="text-lg select-none") aA -------------------------------------------------------------------------------- /server/public/assets/images/logo_p_new.svg: -------------------------------------------------------------------------------- 1 | 2 | 15 | 17 | 19 | 27 | 31 | 35 | 36 | 43 | 52 | 61 | 62 | presearch_logo 64 | 66 | 73 | 75 | 81 | 87 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /server/views/_partials/header.pug: -------------------------------------------------------------------------------- 1 | dic(class="md:h-30 flex z-10 relative shadow dark:border-b dark:border-background-dark300" :class="$store.showProviders && $store.showProviders.show ? 'h-36' : 'h-28'") 2 | div(class="pt-3 md:pt-6 bg-gray-100 dark:bg-background-dark500 dark:border-gray-900 hidden md:block" ) 3 | div(class="pl-2 pr-1 md:pl-6 md:w-48 lg:w-56") 4 | a(class="flex items-center" x-bind:href="window.homepageLink().state.link") 5 | include ./icons/header/logo-p_ 6 | include ./icons/header/logo-presearch 7 | div(class="flex flex-col w-full pr-2 bg-background-light100 dark:bg-background-dark500 sm:pr-0") 8 | div(class="flex items-center md:max-w-xl lg:max-w-2xl ml-1 relative") 9 | a(class="flex items-center mt-3 mr-2 md:hidden" x-bind:href="window.homepageLink().state.link") 10 | include ./icons/header/logo-p_ 11 | include ./search-form 12 | include ./providers-mobile 13 | template(x-if="translated.all") 14 | div(class="flex h-full md:w-screen md:ml-0 md:pl-0 md:w-auto md:max-w-xl lg:max-w-2xl left-0 md:static") 15 | div(class="flex h-full items-end overflow-auto flex-1 ml-2") 16 | - 17 | const classes = { 18 | common: "block flex mx-1 px-1.5 md:px-2 pb-2.5 md:pb-3.5 text-gray-700 border-transparent text-sm border-b-2", 19 | active: "text-primary-500 border-blue-500 dark:text-presearch-dark dark:border-presearch-dark", 20 | inactive: "text-gray-700 dark:text-white border-transparent", 21 | link:"flex hover:opacity-60 transition cursor-pointer items-center" 22 | } 23 | div(class=`${classes["common"]} ${classes["active"]}`) 24 | a(class=classes["link"]) 25 | include ./icons/header/all 26 | span(x-html="translated.all") 27 | div(class=`${classes["common"]} ${path === "/images" ? classes["active"] : classes["inactive"]}`) 28 | a(class=classes["link"]) 29 | include ./icons/header/images 30 | span(x-html="translated.images") 31 | div(class=`${classes["common"]} ${path === "/videos" ? classes["active"] : classes["inactive"]}`) 32 | a(class=classes["link"]) 33 | include ./icons/header/videos 34 | span(x-html="translated.videos") 35 | div(class=`${classes["common"]} ${path === "/news" ? classes["active"] : classes["inactive"]}`) 36 | a(class=classes["link"]) 37 | include ./icons/header/news 38 | span(x-html="translated.news") 39 | div(class="flex items-center justify-end flex-1 md:ml-2 text-xs text-center whitespace-no-wrap border-transparent sm:text-sm border-b-2 sm:pr-4 mb-1 md:mb-2 2lg:hidden") 40 | include ./user-info-mobile 41 | div(class="md:flex h-full hidden items-end justify-end overflow-auto mr-2 text-gray-700") 42 | div 43 | div(class="cursor-pointer dark:text-white flex items-center px-2 mx-1 pb-3.5 text-sm border-b-2 border-transparent hover:opacity-60 transition") 44 | include ./icons/header/share 45 | div(x-html="translated.share") 46 | div(class="absolute top-0 right-0 hidden mt-8 mr-8 2lg:block") 47 | include ./user-info 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Presearch Packages 2 | 3 | *Open source instant information packages for the Presearch engine* 4 | 5 | 6 | ## Install 7 | 8 | In order to install and use presearch-packages you need to have Node.js and NPM installed locally. [Node.js install](https://nodejs.org/en/download/) 9 | 10 | ``` 11 | $ git clone https://github.com/PresearchOfficial/presearch-packages 12 | $ cd presearch-packages && npm install 13 | ``` 14 | 15 | ## Development 16 | 17 | ``` 18 | $ cd server && npm start 19 | ``` 20 | 21 | Development server will be available at: `http://localhost:4000/` 22 | 23 | ### API keys 24 | 25 | Use `.env` file, inside `presearch-packages/server` directory to store your API keys. 26 | When you will set up your API key correctly, it will be accessible inside your package main function as `API_KEY`. 27 | 28 | You can copy example file `.env-example` and change the file name to `.env` 29 | 30 | *Do not push your API keys to the presearch-packages repository* 31 | 32 | ## Contributing 33 | 34 | Developing a new package for the Presearch engine: 35 | 36 | - Fork `presearch-packages` and clone locally if you have not already done so 37 | - Create an upstream remote and sync your local copy before you branch 38 | - Create a new branch `/` 39 | - Always create a new branch for separate packages 40 | - Switch to your new branch 41 | - Run `npm run create-package ` 42 | - Develop and test package using local development server 43 | - Write good commit messages 44 | - Create a pull request with the packageKey in the title 45 | - To create a pull request you need to push your branch to the origin remote and then click on the create pull request button on Github 46 | - If API key(s) are required email them to dev@presearch.io with the pull request number in the subject and the key in the body 47 | - Your pull request will be merged in if the package is correct and relevant 48 | - Email dev@presearch.io with any questions other questions 49 | 50 | [Useful Github Contributing Guide](https://akrabat.com/the-beginners-guide-to-contributing-to-a-github-project/) 51 | 52 | ## Package Evaluation Guide 53 | 54 | Review Step: 55 | 56 | Open up the pull request for the package and take a look at the file changes under the `Files changed` tab 57 | 58 | You're going to need to look over these files for any malicious code 59 | 60 | - Look for proper indentation 61 | - Check for readability 62 | - Are variable names expressive? 63 | - Is it indented properly? 64 | - Did the author use proper syntax? 65 | - Check all http requests to outer api's and make sure only the data used is being returned and nothing else 66 | - Check any scripts being inserted for suspicious activity 67 | - Check the code for quality 68 | - Is it concise? 69 | - Is it effective code? 70 | - Are there any unnecessary steps being taken? 71 | - Is there repetition that could be minimized? 72 | - Is it built to allow easy future maintenance? 73 | - Check that there are no api keys or other sensitive data exposed 74 | - Lastly, just make sure you understand each line and what it does 75 | 76 | Testing Step: 77 | 78 | - Switch to the appropriate branch and update your local repo (git pull) 79 | - Navigate to `http://localhost:4000/{PACKAGE_NAME}` and insert the appropriate query 80 | - Make sure everything loads and works as expected 81 | - If something behaves differently than described by the creator then take note of that 82 | - Check the console in your browsers developers menu for errors or warnings 83 | 84 | Feedback Step: 85 | 86 | If at any stage in this process you found an error or something was off or you have a question for the author, leave explicit, detailed comments on the pull request for the author to go through and fix. 87 | 88 | 89 | -------------------------------------------------------------------------------- /packages/stopWatch/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | async function stopWatch(query, API_KEY) { 4 | 5 | return ` 6 |
7 |
8 |
9 | 00:00:00 10 |
11 |
12 | 18 | 24 | 30 |
31 |
32 |
33 | 34 | 78 | 79 | 126 | `; 127 | } 128 | 129 | async function trigger(query) { 130 | if (query) { 131 | query = query ? query.toLowerCase() : ""; 132 | if (query === "stop watch" || query === "stopwatch") return true; 133 | } 134 | return false; 135 | } 136 | 137 | module.exports = { stopWatch, trigger }; -------------------------------------------------------------------------------- /server/views/_partials/special-sections/info.pug: -------------------------------------------------------------------------------- 1 | template(x-if="state.results.infoSection") 2 | div(class="px-2 2lg:ml-6 2lg:mt-0 mt-4 md:mb-4 md:px-0 infoSection") 3 | div(class="md:max-w-xl lg:max-w-2xl 2lg:max-w-sm bg-white dark:bg-background-dark200 shadow rounded dark:border-gray-600") 4 | div(class="relative p-5 text-gray-800 dark:text-white") 5 | div(class="flex justify-between items-center mb-3") 6 | div(class="w-full flex flex-col justify-center relative info-text") 7 | p(x-html="state.results.infoSection.data.title" class="font-normal text-left") 8 | div(x-html="state.results.infoSection.data.subtitle ? state.results.infoSection.data.subtitle : ''" class="text-sm w-11/12" style="height:42px;") 9 | hr(class="w-11/12 dark:border-gray-600 absolute bottom-0 left-0" :class="state.results.infoSection.data.image ? 'mb-1' : ''") 10 | div(:class="`flex items-center bg-current text-white dark:text-gray-200 tw-transition ${state.results.infoSection.data.image ? 'p-1 rounded' : ''}`") 11 | template(x-if="state.results.infoSection.data.image") 12 | div 13 | img(x-bind:src="state.results.infoSection.data.image" class="imagesource max-h-40") 14 | div(class="bg-current bg-contain bg-no-repeat bg-center text-white dark:text-gray-200 imagedestination" x-bind:style="`background-image:url('${state.results.infoSection.data.image}'); background-blend-mode:multiply;`") 15 | div(x-html="state.results.infoSection.data.description" class="mt-2 text-sm link-tilt" :class="$store.largeText && $store.largeText.status ? 'text-base' : ''") 16 | template(x-if="state.results.infoSection.data.about") 17 | div 18 | hr(class="min-w-full mt-4 dark:border-gray-600 mb-4") 19 | div(class="link-tilt") 20 | template(x-for="about in state.results.infoSection.data.about") 21 | div(x-html="about" class="text-sm mt-1") 22 | template(x-if="state.results.infoSection.data.sidewaysData") 23 | div 24 | hr(class="min-w-full mt-4 mb-2 dark:border-gray-600") 25 | div(x-html="state.results.infoSection.data.sidewaysTitle ? state.results.infoSection.data.sidewaysTitle : ''" class="mb-4 mt-3") 26 | div(class="mt-2 flex items-center justify-around") 27 | template(x-if="state.results.infoSection.data.sidewaysData") 28 | template(x-for="(sideway, index) in state.results.infoSection.data.sidewaysData") 29 | template(x-if="index < 5") 30 | div(class="text-xs flex flex-col items-center mx-1 text-center w-12 h-12 md:w-14 md:h-14") 31 | a(x-bind:href="sideway.link" class="group relative") 32 | div(class="rounded w-12 h-12 md:w-14 md:h-14 bg-current bg-contain bg-no-repeat bg-center text-white dark:text-gray-200 transition hover:opacity-60" x-bind:style="`background-image:url('${sideway.image}'); background-blend-mode:multiply;`") 33 | div(class="mt-2 flex items-start justify-around") 34 | template(x-for="(sideway, index) in state.results.infoSection.data.sidewaysData") 35 | template(x-if="index < 5") 36 | div(class="text-xs flex flex-col items-center mx-1 text-center w-12 md:w-14 break-words") 37 | a(x-bind:href="sideway.link" class="group relative transition hover:opacity-60") 38 | div(x-html="sideway.text ? sideway.text : ''" style="word-break: break-word;") 39 | template(x-if="sideway.extra") 40 | div(x-html="`(${sideway.extra})`") -------------------------------------------------------------------------------- /packages/loremIpsumGenerator/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const { parseAndNormalize, generate } = require('./services'); 3 | async function loremIpsumGenerator(query) { 4 | const length = parseAndNormalize(query); 5 | if (!length) { 6 | return { error: "Failed to parse query." }; 7 | } 8 | const generatedStr = generate(length); 9 | if (!generatedStr) { 10 | return { error: "Failed to generate lorem ipsum string." }; 11 | } 12 | 13 | return ` 14 |
15 |
16 |
Lorem ipsum placeholder text has been created
17 |
18 | 19 | 20 | 21 |
22 |
23 |
Examples
24 |
Lorem Ipsum 10 generates 10 words
25 |
Lorem Ipsum 64 generates 64 words
26 |
Lorem Ipsum 100 generates 100 words
27 |
28 |
29 | 30 | 54 | 118 | `; 119 | } 120 | 121 | function trigger(query) { 122 | return parseAndNormalize(query.toLowerCase()) !== undefined; 123 | } 124 | 125 | module.exports = { loremIpsumGenerator, trigger }; 126 | -------------------------------------------------------------------------------- /packages/emoji/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | const { EmojiAPI } = require("emoji-api"); 3 | const emoji_data = new EmojiAPI(); 4 | const emojiRegex = require('emoji-regex'); 5 | 6 | async function emoji(query, API_KEY) { 7 | const regex = emojiRegex(); 8 | // get only emoji from the query 9 | const emoji = query.match(regex)[0]; 10 | 11 | /* sample query = 🥺 */ 12 | const emoji_details = await emoji_data.get(emoji).catch(error => ({error})); 13 | 14 | if (!emoji_details || emoji_details.error) { 15 | return { error: `Failed to get emoji data from the API. ${emoji_details ? emoji_details.error : ''}` }; 16 | } 17 | 18 | if ( 19 | !( 20 | emoji_details.emoji && 21 | emoji_details.name && 22 | emoji_details.unicode && 23 | emoji_details.description && 24 | emoji_details.images 25 | ) 26 | ) { 27 | return { error: "Incomplete emoji data" }; 28 | } 29 | 30 | const vendorList = ["Apple", "Microsoft", "Google", "Twitter", "Facebook", "Messenger"]; 31 | 32 | let images_list = emoji_details.images.filter((data) => { 33 | if (data.url && data.vendor) return data; 34 | }); 35 | 36 | return ` 37 |
38 |
39 | 40 |
41 | ${ 42 | emoji_details.emoji && emoji_details.name 43 | ? `
44 |

${emoji_details.emoji} ${emoji_details.name}

45 |
` 46 | : `` 47 | } 48 |
49 |

${ 50 | emoji_details.unicode ? `Unicode: ${emoji_details.unicode}` : `` 51 | }

52 |
53 | ${ 54 | images_list && 55 | `
${images_list 56 | .map((image, index) => 57 | image.url && image.vendor && vendorList.includes(image.vendor) 58 | ? `
59 | ${image.vendor} 60 |
${image.vendor}
61 |
` 62 | : `` 63 | ) 64 | .join("")} 65 |
` 66 | } 67 |
68 | 69 |
70 | ${ 71 | emoji_details.description && 72 | `
73 |

Description

74 |
75 |
76 |

${emoji_details.description}

77 |
` 78 | } 79 |
80 | 81 |
82 |
83 | 84 | 148 | `; 149 | } 150 | 151 | async function trigger(query) { 152 | /* sample query = 🥺 */ 153 | const regex = emojiRegex(); 154 | if (query.match(regex)) { 155 | return true; 156 | } 157 | return false; 158 | } 159 | 160 | module.exports = { emoji, trigger }; 161 | -------------------------------------------------------------------------------- /packages/passwordGenerator/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const { parseAndNormalize, generate } = require('./services'); 3 | async function passwordGenerator(query) { 4 | const length = parseAndNormalize(query); 5 | if (!length) { 6 | return { error: "Failed to parse query." }; 7 | } 8 | const generatedStr = generate(length); 9 | if (!generatedStr) { 10 | return { error: "Failed to generate password." }; 11 | } 12 | 13 | return ` 14 |
15 |
16 |
Random password has been created
17 |
18 |
19 | 20 | 21 | 22 |
23 | 24 |
25 |
26 |
Examples
27 |
Pass 8 generates 8 chars password
28 |
Password 12 generates 12 chars password
29 |
Random pw 32 generates 32 chars password
30 |
31 |
32 | 33 | 57 | 138 | `; 139 | } 140 | 141 | function trigger(query) { 142 | return parseAndNormalize(query.toLowerCase()) !== undefined; 143 | } 144 | 145 | module.exports = { passwordGenerator, trigger }; 146 | -------------------------------------------------------------------------------- /packages/currencyConverter/fiatCurrencies.json: -------------------------------------------------------------------------------- 1 | { 2 | "AED": "United Arab Emirates Dirham", 3 | "AFN": "Afghan Afghani", 4 | "ALL": "Albanian Lek", 5 | "AMD": "Armenian Dram", 6 | "ANG": "Netherlands Antillean Guilder", 7 | "AOA": "Angolan Kwanza", 8 | "ARS": "Argentine Peso", 9 | "AUD": "Australian Dollar", 10 | "AWG": "Aruban Florin", 11 | "AZN": "Azerbaijani Manat", 12 | "BAM": "Bosnia-Herzegovina Convertible Mark", 13 | "BBD": "Barbadian Dollar", 14 | "BDT": "Bangladeshi Taka", 15 | "BGN": "Bulgarian Lev", 16 | "BHD": "Bahraini Dinar", 17 | "BIF": "Burundian Franc", 18 | "BMD": "Bermudan Dollar", 19 | "BND": "Brunei Dollar", 20 | "BOB": "Bolivian Boliviano", 21 | "BRL": "Brazilian Real", 22 | "BSD": "Bahamian Dollar", 23 | "BTN": "Bhutanese Ngultrum", 24 | "BWP": "Botswanan Pula", 25 | "BYN": "Belarusian Ruble", 26 | "BZD": "Belize Dollar", 27 | "CAD": "Canadian Dollar", 28 | "CDF": "Congolese Franc", 29 | "CHF": "Swiss Franc", 30 | "CLF": "Chilean Unit of Account (UF)", 31 | "CLP": "Chilean Peso", 32 | "CNH": "Chinese Yuan (Offshore)", 33 | "CNY": "Chinese Yuan", 34 | "COP": "Colombian Peso", 35 | "CRC": "Costa Rican Colón", 36 | "CUC": "Cuban Convertible Peso", 37 | "CUP": "Cuban Peso", 38 | "CVE": "Cape Verdean Escudo", 39 | "CZK": "Czech Republic Koruna", 40 | "DJF": "Djiboutian Franc", 41 | "DKK": "Danish Krone", 42 | "DOP": "Dominican Peso", 43 | "DZD": "Algerian Dinar", 44 | "EGP": "Egyptian Pound", 45 | "ERN": "Eritrean Nakfa", 46 | "ETB": "Ethiopian Birr", 47 | "EUR": "Euro", 48 | "FJD": "Fijian Dollar", 49 | "FKP": "Falkland Islands Pound", 50 | "GBP": "British Pound Sterling", 51 | "GEL": "Georgian Lari", 52 | "GGP": "Guernsey Pound", 53 | "GHS": "Ghanaian Cedi", 54 | "GIP": "Gibraltar Pound", 55 | "GMD": "Gambian Dalasi", 56 | "GNF": "Guinean Franc", 57 | "GTQ": "Guatemalan Quetzal", 58 | "GYD": "Guyanaese Dollar", 59 | "HKD": "Hong Kong Dollar", 60 | "HNL": "Honduran Lempira", 61 | "HRK": "Croatian Kuna", 62 | "HTG": "Haitian Gourde", 63 | "HUF": "Hungarian Forint", 64 | "IDR": "Indonesian Rupiah", 65 | "ILS": "Israeli New Sheqel", 66 | "IMP": "Manx pound", 67 | "INR": "Indian Rupee", 68 | "IQD": "Iraqi Dinar", 69 | "IRR": "Iranian Rial", 70 | "ISK": "Icelandic Króna", 71 | "JEP": "Jersey Pound", 72 | "JMD": "Jamaican Dollar", 73 | "JOD": "Jordanian Dinar", 74 | "JPY": "Japanese Yen", 75 | "KES": "Kenyan Shilling", 76 | "KGS": "Kyrgystani Som", 77 | "KHR": "Cambodian Riel", 78 | "KMF": "Comorian Franc", 79 | "KPW": "North Korean Won", 80 | "KRW": "South Korean Won", 81 | "KWD": "Kuwaiti Dinar", 82 | "KYD": "Cayman Islands Dollar", 83 | "KZT": "Kazakhstani Tenge", 84 | "LAK": "Laotian Kip", 85 | "LBP": "Lebanese Pound", 86 | "LKR": "Sri Lankan Rupee", 87 | "LRD": "Liberian Dollar", 88 | "LSL": "Lesotho Loti", 89 | "LYD": "Libyan Dinar", 90 | "MAD": "Moroccan Dirham", 91 | "MDL": "Moldovan Leu", 92 | "MGA": "Malagasy Ariary", 93 | "MKD": "Macedonian Denar", 94 | "MMK": "Myanma Kyat", 95 | "MNT": "Mongolian Tugrik", 96 | "MOP": "Macanese Pataca", 97 | "MRO": "Mauritanian Ouguiya (pre-2018)", 98 | "MRU": "Mauritanian Ouguiya", 99 | "MUR": "Mauritian Rupee", 100 | "MVR": "Maldivian Rufiyaa", 101 | "MWK": "Malawian Kwacha", 102 | "MXN": "Mexican Peso", 103 | "MYR": "Malaysian Ringgit", 104 | "MZN": "Mozambican Metical", 105 | "NAD": "Namibian Dollar", 106 | "NGN": "Nigerian Naira", 107 | "NIO": "Nicaraguan Córdoba", 108 | "NOK": "Norwegian Krone", 109 | "NPR": "Nepalese Rupee", 110 | "NZD": "New Zealand Dollar", 111 | "OMR": "Omani Rial", 112 | "PAB": "Panamanian Balboa", 113 | "PEN": "Peruvian Nuevo Sol", 114 | "PGK": "Papua New Guinean Kina", 115 | "PHP": "Philippine Peso", 116 | "PKR": "Pakistani Rupee", 117 | "PLN": "Polish Zloty", 118 | "PYG": "Paraguayan Guarani", 119 | "QAR": "Qatari Rial", 120 | "RON": "Romanian Leu", 121 | "RSD": "Serbian Dinar", 122 | "RUB": "Russian Ruble", 123 | "RWF": "Rwandan Franc", 124 | "SAR": "Saudi Riyal", 125 | "SBD": "Solomon Islands Dollar", 126 | "SCR": "Seychellois Rupee", 127 | "SDG": "Sudanese Pound", 128 | "SEK": "Swedish Krona", 129 | "SGD": "Singapore Dollar", 130 | "SHP": "Saint Helena Pound", 131 | "SLL": "Sierra Leonean Leone", 132 | "SOS": "Somali Shilling", 133 | "SRD": "Surinamese Dollar", 134 | "SSP": "South Sudanese Pound", 135 | "STD": "São Tomé and Príncipe Dobra (pre-2018)", 136 | "STN": "São Tomé and Príncipe Dobra", 137 | "SVC": "Salvadoran Colón", 138 | "SYP": "Syrian Pound", 139 | "SZL": "Swazi Lilangeni", 140 | "THB": "Thai Baht", 141 | "TJS": "Tajikistani Somoni", 142 | "TMT": "Turkmenistani Manat", 143 | "TND": "Tunisian Dinar", 144 | "TOP": "Tongan Pa'anga", 145 | "TRY": "Turkish Lira", 146 | "TTD": "Trinidad and Tobago Dollar", 147 | "TWD": "New Taiwan Dollar", 148 | "TZS": "Tanzanian Shilling", 149 | "UAH": "Ukrainian Hryvnia", 150 | "UGX": "Ugandan Shilling", 151 | "USD": "United States Dollar", 152 | "UYU": "Uruguayan Peso", 153 | "UZS": "Uzbekistan Som", 154 | "VEF": "Venezuelan Bolívar Fuerte", 155 | "VND": "Vietnamese Dong", 156 | "VUV": "Vanuatu Vatu", 157 | "WST": "Samoan Tala", 158 | "XAF": "CFA Franc BEAC", 159 | "XAG": "Silver Ounce", 160 | "XAU": "Gold Ounce", 161 | "XCD": "East Caribbean Dollar", 162 | "XDR": "Special Drawing Rights", 163 | "XOF": "CFA Franc BCEAO", 164 | "XPD": "Palladium Ounce", 165 | "XPF": "CFP Franc", 166 | "XPT": "Platinum Ounce", 167 | "YER": "Yemeni Rial", 168 | "ZAR": "South African Rand", 169 | "ZMW": "Zambian Kwacha", 170 | "ZWL": "Zimbabwean Dollar" 171 | } -------------------------------------------------------------------------------- /server/views/_partials/icons/home/logo-presearch.pug: -------------------------------------------------------------------------------- 1 | svg(class="h-10 md:h-12 mx-auto text-white" viewBox="0 0 295.03001 48.021238" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" fill="currentColor") 2 | g(transform="translate(-113.73,-17.58)") 3 | path(class="cls-4" d="m 431.25,319.69 a 7.53,7.53 0 0 0 -0.81,-3.63 7.39,7.39 0 0 0 -2.46,-2.6 17,17 0 0 0 -4.15,-1.91 q -2.5,-0.81 -5.87,-1.59 -2.14,-0.52 -3.67,-1 a 11,11 0 0 1 -2.5,-1 3.67,3.67 0 0 1 -1.39,-1.36 4,4 0 0 1 -0.42,-1.95 4.61,4.61 0 0 1 2.17,-4.25 9.94,9.94 0 0 1 5.29,-1.33 16.23,16.23 0 0 1 5.45,0.94 14.59,14.59 0 0 1 4.8,2.82 l 2.6,-3.44 a 17.58,17.58 0 0 0 -5.58,-3.24 20.3,20.3 0 0 0 -7.14,-1.23 18.35,18.35 0 0 0 -5.09,0.68 12.4,12.4 0 0 0 -4.12,2 9.53,9.53 0 0 0 -2.76,3.31 9.81,9.81 0 0 0 -1,4.51 7.81,7.81 0 0 0 0.65,3.37 5.9,5.9 0 0 0 2.08,2.34 14.17,14.17 0 0 0 3.63,1.69 q 2.2,0.72 5.26,1.49 2.4,0.59 4.22,1.1 a 14.44,14.44 0 0 1 3,1.17 4.91,4.91 0 0 1 1.75,1.52 3.71,3.71 0 0 1 0.58,2.11 4.68,4.68 0 0 1 -2.17,4.12 10.4,10.4 0 0 1 -5.87,1.46 17.55,17.55 0 0 1 -6.29,-1.14 24,24 0 0 1 -6,-3.4 l -2.44,3.83 a 19.8,19.8 0 0 0 6.81,3.67 26.27,26.27 0 0 0 8,1.26 q 6.16,0 9.8,-2.79 a 9,9 0 0 0 3.63,-7.53 m 33.35,-9.54 h -23 a 12.77,12.77 0 0 1 1.14,-4.41 11.51,11.51 0 0 1 2.47,-3.47 11,11 0 0 1 3.54,-2.27 11.51,11.51 0 0 1 12.1,2.24 11.9,11.9 0 0 1 2.53,3.47 12.22,12.22 0 0 1 1.2,4.44 m 5.35,3.31 v -1.3 a 18.15,18.15 0 0 0 -1.2,-6.52 16.81,16.81 0 0 0 -3.4,-5.51 16.62,16.62 0 0 0 -12.32,-5.22 17.26,17.26 0 0 0 -7,1.39 16.94,16.94 0 0 0 -5.48,3.8 17.13,17.13 0 0 0 -3.57,5.58 18.1,18.1 0 0 0 -1.27,6.75 18.33,18.33 0 0 0 1.32,6.77 17.28,17.28 0 0 0 3.54,5.61 16.58,16.58 0 0 0 5.45,3.8 17.27,17.27 0 0 0 7,1.39 18.11,18.11 0 0 0 4.86,-0.65 17.4,17.4 0 0 0 4.25,-1.78 15.25,15.25 0 0 0 3.37,-2.69 12.47,12.47 0 0 0 2.3,-3.44 l -4.93,-1.36 a 7.15,7.15 0 0 1 -1.53,2.34 9.67,9.67 0 0 1 -2.3,1.75 13.15,13.15 0 0 1 -2.79,1.14 11.12,11.12 0 0 1 -3,0.42 10.54,10.54 0 0 1 -4.18,-0.84 11.68,11.68 0 0 1 -3.54,-2.34 11.87,11.87 0 0 1 -2.53,-3.57 13.12,13.12 0 0 1 -1.17,-4.61 h 28.09 a 7.52,7.52 0 0 0 0.1,-0.91 m 27.43,5.54 a 3.61,3.61 0 0 1 -1.23,2.53 9.35,9.35 0 0 1 -4,3 14.14,14.14 0 0 1 -5.68,1.14 8.11,8.11 0 0 1 -2.92,-0.52 7.42,7.42 0 0 1 -2.37,-1.43 6.32,6.32 0 0 1 -1.56,-2.14 6.41,6.41 0 0 1 -0.55,-2.66 5.5,5.5 0 0 1 2.69,-4.73 12.23,12.23 0 0 1 7,-1.82 23.53,23.53 0 0 1 8.63,1.62 v 5 z m 6,10.51 1.49,-0.2 v -4.93 q -1.82,-0.06 -1.82,-2.08 v -13.77 q 0,-6.49 -3.73,-10.06 -3.73,-3.57 -10.36,-3.56 a 23.43,23.43 0 0 0 -13.17,4.41 l 1.88,3.7 q 5.64,-4 10.77,-4 a 8.16,8.16 0 0 1 9,8.89 v 2.72 a 23.06,23.06 0 0 0 -4.48,-1.23 28.3,28.3 0 0 0 -5,-0.45 20.11,20.11 0 0 0 -5.74,0.78 15.2,15.2 0 0 0 -4.54,2.14 9.66,9.66 0 0 0 -3,3.28 8.76,8.76 0 0 0 -1,4.25 9.94,9.94 0 0 0 0.88,4.18 10.5,10.5 0 0 0 2.4,3.34 11.12,11.12 0 0 0 3.6,2.24 12.21,12.21 0 0 0 4.4,0.84 17.64,17.64 0 0 0 7.43,-1.59 14.65,14.65 0 0 0 5.74,-4.64 l 0.13,2.4 a 4.13,4.13 0 0 0 1.2,2.43 3.64,3.64 0 0 0 2.69,1 11.71,11.71 0 0 0 1.23,-0.07 m 19.17,-26.86 a 14.69,14.69 0 0 1 7.56,-2.2 v -5.17 a 4.16,4.16 0 0 0 -0.78,-0.07 h -1.1 a 11.44,11.44 0 0 0 -6.1,2.43 16,16 0 0 0 -4.61,5.68 v -7.85 h -5.32 v 33.86 H 518 v -20.88 a 11.26,11.26 0 0 1 4.64,-5.78 m 16.9,14.66 a 13.63,13.63 0 0 1 -0.91,-5 13.78,13.78 0 0 1 0.88,-5 12.89,12.89 0 0 1 2.37,-4 10.44,10.44 0 0 1 3.57,-2.63 10.57,10.57 0 0 1 4.41,-0.94 10.3,10.3 0 0 1 5.19,1.33 9.28,9.28 0 0 1 3.63,3.73 l 5.58,-1.75 a 14.55,14.55 0 0 0 -5.55,-6 16.42,16.42 0 0 0 -8.73,-2.24 17.2,17.2 0 0 0 -7,1.39 16.92,16.92 0 0 0 -5.42,3.76 16.58,16.58 0 0 0 -3.5,5.55 18.94,18.94 0 0 0 0,13.53 17.27,17.27 0 0 0 3.54,5.61 16.9,16.9 0 0 0 12.4,5.31 17.93,17.93 0 0 0 9,-2.4 13.63,13.63 0 0 0 3.28,-2.66 12,12 0 0 0 2.17,-3.44 l -5.58,-1.69 a 5.62,5.62 0 0 1 -1.3,2 10.1,10.1 0 0 1 -2.11,1.65 11.38,11.38 0 0 1 -2.66,1.13 10.55,10.55 0 0 1 -3,0.42 10.07,10.07 0 0 1 -4.38,-1 11.15,11.15 0 0 1 -3.57,-2.69 13.33,13.33 0 0 1 -2.43,-4.06 m 60.85,12 v -20.15 a 27.33,27.33 0 0 0 -0.55,-5.61 13,13 0 0 0 -1.72,-4.5 8.82,8.82 0 0 0 -3.31,-3 10.67,10.67 0 0 0 -5.06,-1.1 14.3,14.3 0 0 0 -7.53,2.08 14.91,14.91 0 0 0 -5.45,5.77 V 282 H 571 v 47.36 h 5.71 v -20.44 a 12.3,12.3 0 0 1 1.72,-3.57 13.29,13.29 0 0 1 2.59,-2.79 12.5,12.5 0 0 1 3.15,-1.85 9,9 0 0 1 3.37,-0.68 6.1,6.1 0 0 1 5.32,2.56 q 1.82,2.56 1.82,7.82 v 18.94 h 5.71 z" transform="translate(-191.63,-264.42)") 4 | path(class="cls-3" d="m 332.58,298 a 11.6,11.6 0 0 1 -0.58,3.7 10.19,10.19 0 0 1 -1.62,3.08 7.43,7.43 0 0 1 -2.5,2.08 7.09,7.09 0 0 1 -3.28,0.74 h -13.43 v -19.12 h 13 a 7.48,7.48 0 0 1 3.21,0.71 8,8 0 0 1 2.66,2 10.36,10.36 0 0 1 2.5,6.81 m 4.93,5.51 a 15.94,15.94 0 0 0 1,-5.51 14.45,14.45 0 0 0 -1,-5.35 16.13,16.13 0 0 0 -2.89,-4.74 14.17,14.17 0 0 0 -4.41,-3.37 12.51,12.51 0 0 0 -5.61,-1.26 h -19.2 v 46.06 h 5.84 v -16.53 h 13.75 a 12.36,12.36 0 0 0 5.55,-1.23 13.42,13.42 0 0 0 4.28,-3.31 15.23,15.23 0 0 0 2.76,-4.74 m 17.68,-0.84 a 14.67,14.67 0 0 1 7.56,-2.21 v -5.19 A 4.15,4.15 0 0 0 362,295.23 h -1.1 a 11.44,11.44 0 0 0 -6.1,2.43 16,16 0 0 0 -4.61,5.68 v -7.85 h -5.32 v 33.86 h 5.71 v -20.88 a 11.25,11.25 0 0 1 4.64,-5.77 m 39,7.46 h -23 a 12.7,12.7 0 0 1 1.14,-4.41 11.45,11.45 0 0 1 2.46,-3.47 11.05,11.05 0 0 1 3.54,-2.27 11.5,11.5 0 0 1 12.1,2.24 11.89,11.89 0 0 1 2.53,3.47 12.25,12.25 0 0 1 1.2,4.44 m 5.35,3.31 v -1.3 a 18.15,18.15 0 0 0 -1.2,-6.52 16.8,16.8 0 0 0 -3.41,-5.51 16.6,16.6 0 0 0 -12.32,-5.22 17.27,17.27 0 0 0 -7,1.39 16.89,16.89 0 0 0 -9.05,9.38 18.09,18.09 0 0 0 -1.27,6.75 18.34,18.34 0 0 0 1.27,6.78 17.3,17.3 0 0 0 3.54,5.61 16.57,16.57 0 0 0 5.45,3.8 17.28,17.28 0 0 0 7,1.39 18.08,18.08 0 0 0 4.87,-0.65 17.42,17.42 0 0 0 4.25,-1.78 15.27,15.27 0 0 0 3.37,-2.69 12.47,12.47 0 0 0 2.3,-3.44 l -4.93,-1.36 a 7.11,7.11 0 0 1 -1.52,2.34 9.69,9.69 0 0 1 -2.3,1.75 13.17,13.17 0 0 1 -2.79,1.14 11.13,11.13 0 0 1 -3,0.42 10.55,10.55 0 0 1 -4.18,-0.84 11.67,11.67 0 0 1 -3.54,-2.34 11.84,11.84 0 0 1 -2.53,-3.57 13.1,13.1 0 0 1 -1.17,-4.61 h 28.09 a 7,7 0 0 0 0.1,-0.91" transform="translate(-191.63,-264.42)") 5 | -------------------------------------------------------------------------------- /server/views/_partials/icons/header/logo-presearch.pug: -------------------------------------------------------------------------------- 1 | svg(class="md:h-4 lg:h-5 mx-auto hidden md:block" viewBox="0 0 295.03001 48.021238" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/") 2 | g(transform="translate(-113.73,-17.58)") 3 | path(class="cls-4" d="m 431.25,319.69 a 7.53,7.53 0 0 0 -0.81,-3.63 7.39,7.39 0 0 0 -2.46,-2.6 17,17 0 0 0 -4.15,-1.91 q -2.5,-0.81 -5.87,-1.59 -2.14,-0.52 -3.67,-1 a 11,11 0 0 1 -2.5,-1 3.67,3.67 0 0 1 -1.39,-1.36 4,4 0 0 1 -0.42,-1.95 4.61,4.61 0 0 1 2.17,-4.25 9.94,9.94 0 0 1 5.29,-1.33 16.23,16.23 0 0 1 5.45,0.94 14.59,14.59 0 0 1 4.8,2.82 l 2.6,-3.44 a 17.58,17.58 0 0 0 -5.58,-3.24 20.3,20.3 0 0 0 -7.14,-1.23 18.35,18.35 0 0 0 -5.09,0.68 12.4,12.4 0 0 0 -4.12,2 9.53,9.53 0 0 0 -2.76,3.31 9.81,9.81 0 0 0 -1,4.51 7.81,7.81 0 0 0 0.65,3.37 5.9,5.9 0 0 0 2.08,2.34 14.17,14.17 0 0 0 3.63,1.69 q 2.2,0.72 5.26,1.49 2.4,0.59 4.22,1.1 a 14.44,14.44 0 0 1 3,1.17 4.91,4.91 0 0 1 1.75,1.52 3.71,3.71 0 0 1 0.58,2.11 4.68,4.68 0 0 1 -2.17,4.12 10.4,10.4 0 0 1 -5.87,1.46 17.55,17.55 0 0 1 -6.29,-1.14 24,24 0 0 1 -6,-3.4 l -2.44,3.83 a 19.8,19.8 0 0 0 6.81,3.67 26.27,26.27 0 0 0 8,1.26 q 6.16,0 9.8,-2.79 a 9,9 0 0 0 3.63,-7.53 m 33.35,-9.54 h -23 a 12.77,12.77 0 0 1 1.14,-4.41 11.51,11.51 0 0 1 2.47,-3.47 11,11 0 0 1 3.54,-2.27 11.51,11.51 0 0 1 12.1,2.24 11.9,11.9 0 0 1 2.53,3.47 12.22,12.22 0 0 1 1.2,4.44 m 5.35,3.31 v -1.3 a 18.15,18.15 0 0 0 -1.2,-6.52 16.81,16.81 0 0 0 -3.4,-5.51 16.62,16.62 0 0 0 -12.32,-5.22 17.26,17.26 0 0 0 -7,1.39 16.94,16.94 0 0 0 -5.48,3.8 17.13,17.13 0 0 0 -3.57,5.58 18.1,18.1 0 0 0 -1.27,6.75 18.33,18.33 0 0 0 1.32,6.77 17.28,17.28 0 0 0 3.54,5.61 16.58,16.58 0 0 0 5.45,3.8 17.27,17.27 0 0 0 7,1.39 18.11,18.11 0 0 0 4.86,-0.65 17.4,17.4 0 0 0 4.25,-1.78 15.25,15.25 0 0 0 3.37,-2.69 12.47,12.47 0 0 0 2.3,-3.44 l -4.93,-1.36 a 7.15,7.15 0 0 1 -1.53,2.34 9.67,9.67 0 0 1 -2.3,1.75 13.15,13.15 0 0 1 -2.79,1.14 11.12,11.12 0 0 1 -3,0.42 10.54,10.54 0 0 1 -4.18,-0.84 11.68,11.68 0 0 1 -3.54,-2.34 11.87,11.87 0 0 1 -2.53,-3.57 13.12,13.12 0 0 1 -1.17,-4.61 h 28.09 a 7.52,7.52 0 0 0 0.1,-0.91 m 27.43,5.54 a 3.61,3.61 0 0 1 -1.23,2.53 9.35,9.35 0 0 1 -4,3 14.14,14.14 0 0 1 -5.68,1.14 8.11,8.11 0 0 1 -2.92,-0.52 7.42,7.42 0 0 1 -2.37,-1.43 6.32,6.32 0 0 1 -1.56,-2.14 6.41,6.41 0 0 1 -0.55,-2.66 5.5,5.5 0 0 1 2.69,-4.73 12.23,12.23 0 0 1 7,-1.82 23.53,23.53 0 0 1 8.63,1.62 v 5 z m 6,10.51 1.49,-0.2 v -4.93 q -1.82,-0.06 -1.82,-2.08 v -13.77 q 0,-6.49 -3.73,-10.06 -3.73,-3.57 -10.36,-3.56 a 23.43,23.43 0 0 0 -13.17,4.41 l 1.88,3.7 q 5.64,-4 10.77,-4 a 8.16,8.16 0 0 1 9,8.89 v 2.72 a 23.06,23.06 0 0 0 -4.48,-1.23 28.3,28.3 0 0 0 -5,-0.45 20.11,20.11 0 0 0 -5.74,0.78 15.2,15.2 0 0 0 -4.54,2.14 9.66,9.66 0 0 0 -3,3.28 8.76,8.76 0 0 0 -1,4.25 9.94,9.94 0 0 0 0.88,4.18 10.5,10.5 0 0 0 2.4,3.34 11.12,11.12 0 0 0 3.6,2.24 12.21,12.21 0 0 0 4.4,0.84 17.64,17.64 0 0 0 7.43,-1.59 14.65,14.65 0 0 0 5.74,-4.64 l 0.13,2.4 a 4.13,4.13 0 0 0 1.2,2.43 3.64,3.64 0 0 0 2.69,1 11.71,11.71 0 0 0 1.23,-0.07 m 19.17,-26.86 a 14.69,14.69 0 0 1 7.56,-2.2 v -5.17 a 4.16,4.16 0 0 0 -0.78,-0.07 h -1.1 a 11.44,11.44 0 0 0 -6.1,2.43 16,16 0 0 0 -4.61,5.68 v -7.85 h -5.32 v 33.86 H 518 v -20.88 a 11.26,11.26 0 0 1 4.64,-5.78 m 16.9,14.66 a 13.63,13.63 0 0 1 -0.91,-5 13.78,13.78 0 0 1 0.88,-5 12.89,12.89 0 0 1 2.37,-4 10.44,10.44 0 0 1 3.57,-2.63 10.57,10.57 0 0 1 4.41,-0.94 10.3,10.3 0 0 1 5.19,1.33 9.28,9.28 0 0 1 3.63,3.73 l 5.58,-1.75 a 14.55,14.55 0 0 0 -5.55,-6 16.42,16.42 0 0 0 -8.73,-2.24 17.2,17.2 0 0 0 -7,1.39 16.92,16.92 0 0 0 -5.42,3.76 16.58,16.58 0 0 0 -3.5,5.55 18.94,18.94 0 0 0 0,13.53 17.27,17.27 0 0 0 3.54,5.61 16.9,16.9 0 0 0 12.4,5.31 17.93,17.93 0 0 0 9,-2.4 13.63,13.63 0 0 0 3.28,-2.66 12,12 0 0 0 2.17,-3.44 l -5.58,-1.69 a 5.62,5.62 0 0 1 -1.3,2 10.1,10.1 0 0 1 -2.11,1.65 11.38,11.38 0 0 1 -2.66,1.13 10.55,10.55 0 0 1 -3,0.42 10.07,10.07 0 0 1 -4.38,-1 11.15,11.15 0 0 1 -3.57,-2.69 13.33,13.33 0 0 1 -2.43,-4.06 m 60.85,12 v -20.15 a 27.33,27.33 0 0 0 -0.55,-5.61 13,13 0 0 0 -1.72,-4.5 8.82,8.82 0 0 0 -3.31,-3 10.67,10.67 0 0 0 -5.06,-1.1 14.3,14.3 0 0 0 -7.53,2.08 14.91,14.91 0 0 0 -5.45,5.77 V 282 H 571 v 47.36 h 5.71 v -20.44 a 12.3,12.3 0 0 1 1.72,-3.57 13.29,13.29 0 0 1 2.59,-2.79 12.5,12.5 0 0 1 3.15,-1.85 9,9 0 0 1 3.37,-0.68 6.1,6.1 0 0 1 5.32,2.56 q 1.82,2.56 1.82,7.82 v 18.94 h 5.71 z" transform="translate(-191.63,-264.42)" fill="currentColor" class="text-presearch-default dark:text-white") 4 | path(class="cls-3" d="m 332.58,298 a 11.6,11.6 0 0 1 -0.58,3.7 10.19,10.19 0 0 1 -1.62,3.08 7.43,7.43 0 0 1 -2.5,2.08 7.09,7.09 0 0 1 -3.28,0.74 h -13.43 v -19.12 h 13 a 7.48,7.48 0 0 1 3.21,0.71 8,8 0 0 1 2.66,2 10.36,10.36 0 0 1 2.5,6.81 m 4.93,5.51 a 15.94,15.94 0 0 0 1,-5.51 14.45,14.45 0 0 0 -1,-5.35 16.13,16.13 0 0 0 -2.89,-4.74 14.17,14.17 0 0 0 -4.41,-3.37 12.51,12.51 0 0 0 -5.61,-1.26 h -19.2 v 46.06 h 5.84 v -16.53 h 13.75 a 12.36,12.36 0 0 0 5.55,-1.23 13.42,13.42 0 0 0 4.28,-3.31 15.23,15.23 0 0 0 2.76,-4.74 m 17.68,-0.84 a 14.67,14.67 0 0 1 7.56,-2.21 v -5.19 A 4.15,4.15 0 0 0 362,295.23 h -1.1 a 11.44,11.44 0 0 0 -6.1,2.43 16,16 0 0 0 -4.61,5.68 v -7.85 h -5.32 v 33.86 h 5.71 v -20.88 a 11.25,11.25 0 0 1 4.64,-5.77 m 39,7.46 h -23 a 12.7,12.7 0 0 1 1.14,-4.41 11.45,11.45 0 0 1 2.46,-3.47 11.05,11.05 0 0 1 3.54,-2.27 11.5,11.5 0 0 1 12.1,2.24 11.89,11.89 0 0 1 2.53,3.47 12.25,12.25 0 0 1 1.2,4.44 m 5.35,3.31 v -1.3 a 18.15,18.15 0 0 0 -1.2,-6.52 16.8,16.8 0 0 0 -3.41,-5.51 16.6,16.6 0 0 0 -12.32,-5.22 17.27,17.27 0 0 0 -7,1.39 16.89,16.89 0 0 0 -9.05,9.38 18.09,18.09 0 0 0 -1.27,6.75 18.34,18.34 0 0 0 1.27,6.78 17.3,17.3 0 0 0 3.54,5.61 16.57,16.57 0 0 0 5.45,3.8 17.28,17.28 0 0 0 7,1.39 18.08,18.08 0 0 0 4.87,-0.65 17.42,17.42 0 0 0 4.25,-1.78 15.27,15.27 0 0 0 3.37,-2.69 12.47,12.47 0 0 0 2.3,-3.44 l -4.93,-1.36 a 7.11,7.11 0 0 1 -1.52,2.34 9.69,9.69 0 0 1 -2.3,1.75 13.17,13.17 0 0 1 -2.79,1.14 11.13,11.13 0 0 1 -3,0.42 10.55,10.55 0 0 1 -4.18,-0.84 11.67,11.67 0 0 1 -3.54,-2.34 11.84,11.84 0 0 1 -2.53,-3.57 13.1,13.1 0 0 1 -1.17,-4.61 h 28.09 a 7,7 0 0 0 0.1,-0.91" transform="translate(-191.63,-264.42)" fill="currentColor" class="text-presearch-default dark:text-white") 5 | -------------------------------------------------------------------------------- /server/public/assets/images/logo_presearch.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | presearch_logo 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /server/public/assets/images/logo_presearch_new.svg: -------------------------------------------------------------------------------- 1 | 2 | 15 | 17 | 19 | 27 | 31 | 35 | 36 | 43 | 44 | presearch_logo 46 | 49 | 55 | 61 | 62 | 64 | 65 | 67 | presearch_logo 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /server/views/_partials/icons/header/moon.pug: -------------------------------------------------------------------------------- 1 | svg(class="w-4 h-4" enable-background="new 0 0 512 512" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg") 2 | path(d="m469.5 256c0 48.07-15.886 92.43-42.696 128.115-38.952 51.848-95.996 76.502-165.838 76.502-117.913 0-208.534-86.704-208.534-204.617 0-68.407 22.24-129.3 72.28-168.374 36.212-28.277 81.782-45.126 131.288-45.126 117.913 0 213.5 95.587 213.5 213.5z" fill="#e3e0e4") 3 | path(d="m433.97 373.97c-38.24 57.58-103.67 95.53-177.97 95.53-117.91 0-213.5-95.59-213.5-213.5 0-74.3 37.95-139.73 95.53-177.97-22.45 33.79-35.53 74.35-35.53 117.97 0 117.91 95.59 213.5 213.5 213.5 43.62 0 84.18-13.08 117.97-35.53z" fill="#d4cfd5") 4 | path(d="m430.674 11.078 7.746 15.493c.194.387.507.701.894.894l15.493 7.746c1.474.737 1.474 2.841 0 3.578l-15.493 7.746c-.387.194-.701.507-.894.894l-7.746 15.493c-.737 1.474-2.841 1.474-3.578 0l-7.746-15.492c-.194-.387-.507-.701-.894-.894l-15.493-7.746c-1.474-.737-1.474-2.841 0-3.578l15.493-7.746c.387-.194.701-.507.894-.894l7.746-15.493c.737-1.475 2.841-1.475 3.578-.001z" fill="#5d91b9") 5 | path(d="m68.211 500.922-7.746-15.493c-.194-.387-.507-.701-.894-.894l-15.493-7.746c-1.474-.737-1.474-2.841 0-3.578l15.493-7.746c.387-.194.701-.507.894-.894l7.746-15.493c.737-1.474 2.841-1.474 3.578 0l7.746 15.493c.194.387.507.701.894.894l15.493 7.746c1.474.737 1.474 2.841 0 3.578l-15.493 7.746c-.387.194-.701.507-.894.894l-7.746 15.493c-.737 1.474-2.841 1.474-3.578 0z" fill="#5d91b9") 6 | path(d="m194 224c0 5.247-1.063 10.245-2.986 14.791-5.769 13.639-19.104 17.709-34.844 17.709-20.987 0-30.745-10.013-30.745-31 0-15.68 2.071-30.641 15.626-36.447 4.589-1.965 9.642-3.053 14.949-3.053 20.987 0 38 17.013 38 38z" fill="#d4cfd5") 7 | path(d="m288.5 383.5c0 8.686-2.914 16.691-7.818 23.091-6.945 9.064-17.881 8.238-30.182 8.238-20.987 0-38-10.343-38-31.33s17.013-38 38-38 38 17.014 38 38.001z" fill="#d4cfd5") 8 | path(d="m280.68 406.59c-6.94 9.07-17.88 14.91-30.18 14.91-20.99 0-38-17.01-38-38 0-.24 0-.48.01-.72 20.83 11.57 43.8 19.76 68.17 23.81z" fill="#c5bec6") 9 | path(d="m378.5 172.5c0 4.425-1.25 8.558-3.415 12.066-4.051 6.562-10.658 9.328-18.936 9.328-12.703 0-21.362-8.481-21.362-21.184 0-9.192 3.105-17.335 10.899-21.017 2.977-1.406 6.303-2.193 9.814-2.193 12.703 0 23 10.297 23 23z" fill="#d4cfd5") 10 | path(d="m395.5 348.5c0 3.035-.588 5.933-1.656 8.586-3.402 8.45-11.677 10.085-21.344 10.085-12.703 0-16.351-5.758-16.351-18.46 0-11.115 1.235-20.598 11.716-22.743 1.497-.306 3.047-.467 4.635-.467 12.703-.001 23 10.296 23 22.999z" fill="#d4cfd5") 11 | path(d="m190.95 238.95c-5.8 13.55-19.27 23.05-34.95 23.05-20.99 0-38-17.01-38-38 0-15.68 9.5-29.15 23.05-34.95-1.96 4.59-3.05 9.64-3.05 14.95 0 20.99 17.01 38 38 38 5.31 0 10.36-1.09 14.95-3.05z" fill="#c5bec6") 12 | path(d="m376.83 181.08c-3.39 8.45-11.66 14.42-21.33 14.42-12.7 0-23-10.3-23-23 0-11.22 8.04-20.57 18.67-22.58-1.08 2.65-1.67 5.55-1.67 8.58 0 12.7 10.3 23 23 23 1.48 0 2.93-.14 4.33-.42z" fill="#c5bec6") 13 | path(d="m393.83 357.08c-3.39 8.45-11.66 14.42-21.33 14.42-12.7 0-23-10.3-23-23 0-11.22 8.04-20.57 18.67-22.58-1.08 2.65-1.67 5.55-1.67 8.58 0 12.7 10.3 23 23 23 1.48 0 2.93-.14 4.33-.42z" fill="#c5bec6") 14 | circle(cx="264.5" cy="110" fill="#d4cfd5" r="15.5") 15 | circle(cx="254" cy="243" fill="#d4cfd5" r="17.5") 16 | circle(cx="94" cy="298" fill="#c5bec6" r="14.5") 17 | circle(cx="400" cy="271" fill="#d4cfd5" r="14.5") 18 | circle(cx="163.5" cy="149.5" fill="#d4cfd5" r="7.33") 19 | circle(cx="152.5" cy="351.5" fill="#c5bec6" r="7.33") 20 | g(fill="#d4cfd5") 21 | circle(cx="345.5" cy="399.5" r="7.33") 22 | circle(cx="429.5" cy="218.5" r="7.33") 23 | circle(cx="325.5" cy="107.5" r="7.33") 24 | path(d="m441.706 136.144c-22.484-34.769-54.117-62.469-91.477-80.104-3.745-1.768-8.216-.166-9.983 3.581-1.769 3.746-.165 8.216 3.581 9.984 71.787 33.887 118.173 107.051 118.173 186.395 0 19.146-2.624 38.103-7.798 56.344-1.131 3.985 1.184 8.132 5.168 9.262.685.194 1.373.287 2.051.287 3.27 0 6.275-2.154 7.211-5.455 5.553-19.573 8.368-39.907 8.368-60.438 0-42.707-12.204-84.152-35.294-119.856z") 25 | path(d="m452.248 340.549c-3.738-1.773-8.215-.178-9.989 3.565-33.94 71.613-107.051 117.886-186.259 117.886-113.589 0-206-92.411-206-206s92.411-206 206-206c18.854 0 37.529 2.544 55.509 7.563 3.994 1.116 8.127-1.218 9.24-5.207 1.114-3.99-1.218-8.127-5.207-9.24-19.293-5.386-39.326-8.116-59.542-8.116-59.031 0-114.529 22.988-156.271 64.729s-64.729 97.24-64.729 156.271 22.988 114.529 64.729 156.271 97.24 64.729 156.271 64.729c42.646 0 84.043-12.172 119.714-35.202 34.734-22.425 62.433-53.982 80.1-91.26 1.774-3.743.177-8.215-3.566-9.989z") 26 | path(d="m396.03 43.708 17.432 8.716 8.715 17.43c1.271 2.541 3.867 4.146 6.708 4.146s5.438-1.605 6.708-4.146l8.715-17.43 17.432-8.716c2.54-1.27 4.146-3.867 4.146-6.708s-1.605-5.438-4.146-6.708l-17.432-8.716-8.715-17.43c-1.271-2.541-3.867-4.146-6.708-4.146s-5.438 1.605-6.708 4.146l-8.715 17.43-17.432 8.716c-2.54 1.27-4.146 3.867-4.146 6.708s1.606 5.438 4.146 6.708zm26.376-9.833c1.451-.726 2.628-1.902 3.354-3.354l3.125-6.25 3.125 6.25c.726 1.452 1.902 2.628 3.354 3.354l6.25 3.125-6.251 3.125c-1.451.726-2.628 1.902-3.354 3.354l-3.125 6.25-3.125-6.25c-.726-1.452-1.902-2.628-3.354-3.354l-6.25-3.125z") 27 | path(d="m504.5 376.5h-5v-5c0-4.142-3.357-7.5-7.5-7.5s-7.5 3.358-7.5 7.5v5h-5c-4.143 0-7.5 3.358-7.5 7.5s3.357 7.5 7.5 7.5h5v5c0 4.142 3.357 7.5 7.5 7.5s7.5-3.358 7.5-7.5v-5h5c4.143 0 7.5-3.358 7.5-7.5s-3.357-7.5-7.5-7.5z") 28 | path(d="m102.854 468.292-17.432-8.716-8.715-17.43c-1.269-2.541-3.866-4.146-6.707-4.146s-5.438 1.605-6.708 4.146l-8.715 17.43-17.432 8.716c-2.54 1.27-4.145 3.867-4.145 6.708s1.605 5.438 4.146 6.708l17.432 8.716 8.715 17.43c1.27 2.541 3.866 4.146 6.707 4.146s5.438-1.605 6.708-4.146l8.715-17.43 17.432-8.716c2.54-1.27 4.146-3.867 4.146-6.708s-1.606-5.438-4.147-6.708zm-26.375 9.833c-1.451.726-2.628 1.902-3.354 3.354l-3.125 6.25-3.125-6.25c-.726-1.452-1.902-2.628-3.354-3.354l-6.25-3.125 6.251-3.125c1.451-.726 2.628-1.902 3.354-3.354l3.125-6.25 3.125 6.25c.726 1.452 1.902 2.628 3.354 3.354l6.249 3.125z") 29 | path(d="m40 118c0-4.142-3.357-7.5-7.5-7.5h-5v-5c0-4.142-3.357-7.5-7.5-7.5s-7.5 3.358-7.5 7.5v5h-5c-4.143 0-7.5 3.358-7.5 7.5s3.357 7.5 7.5 7.5h5v5c0 4.142 3.357 7.5 7.5 7.5s7.5-3.358 7.5-7.5v-5h5c4.143 0 7.5-3.358 7.5-7.5z") 30 | path(d="m201.5 224c0-25.089-20.411-45.5-45.5-45.5-10.938 0-21.51 3.938-29.77 11.09-3.132 2.711-3.472 7.448-.761 10.579 2.712 3.133 7.448 3.47 10.579.761 5.534-4.791 12.619-7.43 19.951-7.43 16.817 0 30.5 13.682 30.5 30.5s-13.683 30.5-30.5 30.5c-15.699 0-28.742-11.755-30.339-27.344-.422-4.12-4.092-7.127-8.226-6.697-4.12.422-7.118 4.104-6.696 8.225 2.384 23.269 21.842 40.816 45.262 40.816 25.089 0 45.5-20.411 45.5-45.5z") 31 | path(d="m250.5 414c-1.62 0-3.244-.127-4.828-.379-4.092-.653-7.935 2.141-8.583 6.231-.649 4.091 2.141 7.934 6.231 8.583 2.359.375 4.774.564 7.18.564 25.089 0 45.5-20.411 45.5-45.5s-20.411-45.499-45.5-45.499-45.5 20.411-45.5 45.5c0 7.008 1.553 13.733 4.615 19.988 1.822 3.719 6.313 5.258 10.034 3.438 3.721-1.821 5.26-6.314 3.438-10.034-2.049-4.184-3.088-8.689-3.088-13.392 0-16.818 13.683-30.5 30.5-30.5s30.5 13.682 30.5 30.5-13.682 30.5-30.499 30.5z") 32 | path(d="m355.5 142c-16.817 0-30.5 13.682-30.5 30.5s13.683 30.5 30.5 30.5 30.5-13.682 30.5-30.5-13.683-30.5-30.5-30.5zm0 46c-8.547 0-15.5-6.953-15.5-15.5s6.953-15.5 15.5-15.5 15.5 6.953 15.5 15.5-6.953 15.5-15.5 15.5z") 33 | path(d="m403 348.5c0-16.818-13.683-30.5-30.5-30.5s-30.5 13.682-30.5 30.5 13.683 30.5 30.5 30.5 30.5-13.682 30.5-30.5zm-46 0c0-8.547 6.953-15.5 15.5-15.5s15.5 6.953 15.5 15.5-6.953 15.5-15.5 15.5-15.5-6.953-15.5-15.5z") 34 | path(d="m287.5 110c0-12.682-10.317-23-23-23s-23 10.318-23 23 10.317 23 23 23 23-10.318 23-23zm-31 0c0-4.411 3.589-8 8-8s8 3.589 8 8-3.589 8-8 8-8-3.589-8-8z") 35 | path(d="m229 243c0 13.785 11.215 25 25 25s25-11.215 25-25-11.215-25-25-25-25 11.215-25 25zm25-10c5.514 0 10 4.486 10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10z") 36 | path(d="m94 276c-12.131 0-22 9.869-22 22s9.869 22 22 22 22-9.869 22-22-9.869-22-22-22zm0 29c-3.859 0-7-3.14-7-7s3.141-7 7-7 7 3.14 7 7-3.141 7-7 7z") 37 | path(d="m422 271c0-12.131-9.869-22-22-22s-22 9.869-22 22 9.869 22 22 22 22-9.869 22-22zm-22 7c-3.859 0-7-3.14-7-7s3.141-7 7-7 7 3.14 7 7-3.141 7-7 7z") 38 | circle(cx="163.5" cy="149.504" r="7.496") 39 | circle(cx="325.5" cy="107.5" r="7.496") 40 | circle(cx="429.5" cy="218.503" r="7.496") 41 | circle(cx="345.5" cy="399.5" r="7.496") 42 | circle(cx="152.5" cy="351.5" r="7.496") -------------------------------------------------------------------------------- /packages/currencyConverter/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const {parseAndNormalize, fetchRates, convert: serverConvert} = require('./services'); 3 | 4 | // global variable to store return value from parseAndNormalize function 5 | let rateConversion = ''; 6 | 7 | async function currencyConverter(query, API_KEY) { 8 | if (!rateConversion) { 9 | return undefined; 10 | } 11 | 12 | const rates = await fetchRates(rateConversion, API_KEY); 13 | if (!rates) { 14 | return { error: "Failed to get rates from the API" }; 15 | } 16 | 17 | const converted = serverConvert(rateConversion, rates); 18 | if (!converted) { 19 | return { error: "Conversion has failed" } 20 | } 21 | const convertedFixed = (Math.round(converted.value * (10 ** converted.round)) / (10 ** converted.round)); 22 | 23 | return ` 24 |
25 |
26 |
27 |
28 |
29 |
30 | 31 |
32 |
33 | 34 |
35 |
36 |

Exchange rates are downloaded from the European Commission and CoinMarketCap. Presearch does not guarantee the accuracy.

37 |
38 |
39 | 91 | 220 | `; 221 | } 222 | 223 | // here you should check, if the query should trigger your package 224 | // i.e. if you are building 'randomNumber' package, 'random number' query will be a good choice 225 | function trigger(query) { 226 | // store result into global variable for further use if package triggers 227 | rateConversion = parseAndNormalize(query) 228 | return rateConversion !== undefined; 229 | } 230 | 231 | module.exports = { currencyConverter, trigger }; 232 | -------------------------------------------------------------------------------- /packages/daysOfTheYear/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const axios = require("axios"); 4 | const dayjs = require("dayjs"); 5 | 6 | const DAYS_API_URL = "https://www.daysoftheyear.com/api/v1/"; 7 | 8 | async function daysOfTheYear(query, API_KEY) { 9 | 10 | const data = await getMemorableDays(API_KEY); 11 | if (!data || data.error) { 12 | return; 13 | } 14 | 15 | return ` 16 |
17 |
18 |
19 |
20 |
21 | ${data.map((day, index) => { return ''; }).join('')} 22 |
23 |
24 |
25 |
26 | 27 |
28 |
29 |
30 |
31 |
32 | Powered by Days Of The Year. 33 |
34 |
35 |
36 | 37 | 110 | 111 | 206 | `; 207 | } 208 | 209 | async function getMemorableDays(API_KEY) { 210 | 211 | const escapeHtml = (unsafe) => { 212 | return unsafe.replaceAll('&', '&') 213 | .replaceAll('<', '<') 214 | .replaceAll('>', '>') 215 | .replaceAll('"', '"') 216 | .replaceAll("'", ''') 217 | .replaceAll("\n", '
') 218 | .replaceAll("–", '-') 219 | .replaceAll("’", '\''); 220 | } 221 | 222 | const toContract = async (day, data) => { 223 | const dayName = day.isSame(dayjs(), 'day') 224 | ? "Today" : day.isSame(dayjs().add(1, 'day'), 'day') 225 | ? "Tomorrow" : day.format('MMM D'); 226 | 227 | return { 228 | date: day.format('dddd, MMMM D'), 229 | name: dayName, 230 | data: data.data.map(d => ({ 231 | name: escapeHtml(d.name), 232 | description: escapeHtml(d.excerpt), 233 | url: d.url 234 | })) 235 | }; 236 | }; 237 | 238 | try { 239 | const daysToFetch = Array.from(Array(3).keys()).map((index)=> dayjs().add(index, 'day')); 240 | 241 | const promises = daysToFetch.map(async day => { 242 | const url = `${DAYS_API_URL}date/${day.format('YYYY/MM/DD/')}`; 243 | const { data } = await axios.get(url, 244 | { 245 | headers: { 246 | 'X-Api-Key': API_KEY 247 | } 248 | } 249 | ); 250 | return toContract(day, data); 251 | }); 252 | 253 | return await Promise.all(promises); 254 | } 255 | catch (error) { 256 | return { error }; 257 | } 258 | } 259 | 260 | async function trigger(query) { 261 | query = (query || "").toLowerCase(); 262 | const triggers = [/day(s?) of the year/, /what to celebrate/, /today/]; 263 | return triggers.some(t => t.test(query)); 264 | } 265 | 266 | module.exports = { daysOfTheYear, trigger }; -------------------------------------------------------------------------------- /server/public/results.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "standardResults": [ 4 | { 5 | "title": "Bitcoin - Open source P2P money", 6 | "link": "https://bitcoin.org/", 7 | "description": "Bitcoin is an innovative payment network and a new kind of money. Find all you need to know and get started with Bitcoin on bitcoin.org.", 8 | "favicon": "f59a1f4600697666272338400b7281b4" 9 | }, 10 | { 11 | "title": "CoinDesk: Bitcoin, Ethereum, Crypto News and Price Data", 12 | "link": "https://www.coindesk.com/price/bitcoin/", 13 | "description": "11 hours ago — Bitcoin is the world's first decentralized cryptocurrency – a type of digital asset that uses public-key cryptography to record, sign and send transactions ...", 14 | "favicon": "24b8d3642d7cd2afd8279d43bb8a3a4d281a0d2bbe20561caf059b825f87b906" 15 | } 16 | ], 17 | "infoSection": { 18 | "data": { 19 | "title": "Bitcoin", 20 | "subtitle": "Currency", 21 | "description": "Bitcoin is a decentralized digital currency, without a central bank or single administrator, that can be sent from user to user on the peer-to-peer bitcoin network without the need for intermediaries. Wikipedia", 22 | "image": "data:image/jpeg;base64,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" 23 | } 24 | }, 25 | "specialSections": { 26 | }, 27 | "pages": 1 28 | }, 29 | "presearchPackage" : {}, 30 | "ads": [ 31 | { 32 | "code": "e47cf514-9109-4788-9f4e-ad1116dc6803", 33 | "headline": "Just an ad ", 34 | "description": "Blah, blah, blah...", 35 | "link": "https://keywords.presearch-preview.org/", 36 | "keyword": "test", 37 | "jwt": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpYXQiOiIxNjMzOTUxMTA1Iiwia2V5d29yZF9pZCI6IjE1MDg5IiwidXVpZCI6ImNhM2Y2ZGQ2LWNkYzgtNGEzYi05OGZiLTYyNjk2ZTI0NTZhMCIsImxpbmsiOiJodHRwczpcL1wva2V5d29yZHMucHJlc2VhcmNoLXByZXZpZXcub3JnXC8ifQ.S4Z0q9xgp4DhNOC6YEqTC-PzmpcWaDwXhf7dJ_Nsq4f-YZ9OmTsQyjCNVXnbRzy6IUxwj8C5TTqFHqXo0IBdCkLm3_Jl1Nycn9eDW53_mIHsmHjnu0-iElvCDasBUiep8mt-1PQ0DG9TohSD8ue1xPUW1oirfFqIPtQr6inuRqagY1SnXFyfpJG3NCGv1ohcj4ynHOAwB8b6SEjWQ3ZWekCUhZhuXttj8Ot8MU-ElTIjY07XOCDXQdDVyRIRLYN868odJZvvhiBvXj92zNOL-FAyhJ25vS4KBoRxGbkOsx-8eTGLSQgtiz5z9Gu3LVxsRlBmcSVeJj4zxBFiZr4Awg" 38 | } 39 | ] 40 | } 41 | --------------------------------------------------------------------------------