├── .gitignore ├── share ├── site │ ├── duckduckgo │ │ ├── iframe.tx │ │ ├── app.tx │ │ ├── newbang.tx │ │ ├── spread.tx │ │ ├── app_info.tx │ │ ├── newsletter.tx │ │ ├── meta │ │ │ ├── chrome_newtab.tx │ │ │ ├── iframe.tx │ │ │ ├── title.tx │ │ │ ├── press.tx │ │ │ ├── duckduckbot.tx │ │ │ ├── search_box.tx │ │ │ ├── bang.tx │ │ │ ├── donations.tx │ │ │ ├── params.tx │ │ │ ├── newbang.tx │ │ │ ├── api.tx │ │ │ ├── styleguide.tx │ │ │ ├── privacy.tx │ │ │ ├── about.tx │ │ │ ├── settings.tx │ │ │ ├── feedback.tx │ │ │ ├── duckduckpreview.tx │ │ │ ├── index.tx │ │ │ ├── spread.tx │ │ │ ├── app.tx │ │ │ ├── app_info.tx │ │ │ ├── newsletter.tx │ │ │ └── base.tx │ │ ├── header_homepage.tx │ │ ├── install.tx │ │ ├── head.tx │ │ ├── 50x.tx │ │ ├── _logo_homepage.tx │ │ ├── chrome_newtab.tx │ │ ├── untranslated.tx │ │ ├── popout.tx │ │ ├── popover.tx │ │ ├── search_form_hero.tx │ │ ├── settings.tx │ │ ├── index.tx │ │ ├── search_form_homepage.tx │ │ ├── yahoo_static.tx │ │ ├── duckduckpreview.tx │ │ ├── footer_homepage.tx │ │ ├── duckduckbot.tx │ │ ├── head_js.tx │ │ ├── header_flex.tx │ │ ├── header.tx │ │ ├── donations.tx │ │ ├── bang.tx │ │ ├── feedback.tx │ │ ├── base.tx │ │ ├── press.tx │ │ ├── search_box.tx │ │ ├── about.tx │ │ ├── tour.tx │ │ ├── api.tx │ │ ├── privacy.tx │ │ └── params.tx │ ├── donttrackus │ │ ├── header.tx │ │ ├── share_links.tx │ │ ├── share_modal.tx │ │ ├── base.tx │ │ ├── head.tx │ │ └── index.tx │ ├── duckduckhack │ │ ├── index.tx │ │ ├── inc │ │ │ ├── head_doc.tx │ │ │ ├── side_nav.tx │ │ │ └── head.tx │ │ ├── base.tx │ │ ├── ddh-feature.tx │ │ ├── doc.tx │ │ └── index_content.tx │ └── dontbubbleus │ │ ├── header.tx │ │ ├── share_links.tx │ │ ├── head.tx │ │ ├── share_modal.tx │ │ ├── base.tx │ │ └── index.tx └── core │ ├── share_footer.tx │ ├── micro_foot.tx │ ├── footer_copyright.tx │ ├── lang_select.tx │ ├── head_js.tx │ ├── micro_bottom.tx │ ├── footer_nav.tx │ ├── header.tx │ ├── footer_about.tx │ └── footer.tx ├── Changes ├── .github ├── PULL_REQUEST_TEMPLATE.MD └── ISSUE_TEMPLATE.md ├── xbin └── site_scraper.sh ├── t └── load.t ├── lib └── DDG │ ├── Publisher │ ├── Site │ │ ├── Dontbubbleus │ │ │ └── Root.pm │ │ ├── Donttrackus │ │ │ └── Root.pm │ │ ├── Duckduckgo.pm │ │ ├── Duckduckhack.pm │ │ ├── Donttrackus.pm │ │ ├── Dontbubbleus.pm │ │ └── Duckduckhack │ │ │ └── Root.pm │ ├── DirRole.pm │ ├── SiteRole.pm │ └── File.pm │ ├── App │ └── Publisher.pm │ └── Publisher.pm ├── weaver.ini ├── bin └── ddg_publisher ├── .travis.yml ├── dist.ini ├── README.md └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | DDG-Publisher-* 2 | test_publish 3 | .build 4 | -------------------------------------------------------------------------------- /share/site/duckduckgo/iframe.tx: -------------------------------------------------------------------------------- 1 |
-------------------------------------------------------------------------------- /Changes: -------------------------------------------------------------------------------- 1 | Revision history for {{$dist->name}} 2 | 3 | {{$NEXT}} 4 | -------------------------------------------------------------------------------- /share/site/duckduckgo/app.tx: -------------------------------------------------------------------------------- 1 |
2 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.MD: -------------------------------------------------------------------------------- 1 | ## Description 2 | 3 | ## Testing 4 | -------------------------------------------------------------------------------- /share/core/share_footer.tx: -------------------------------------------------------------------------------- 1 | 2 |
3 | -------------------------------------------------------------------------------- /share/site/duckduckgo/newbang.tx: -------------------------------------------------------------------------------- 1 |
2 | -------------------------------------------------------------------------------- /share/site/duckduckgo/spread.tx: -------------------------------------------------------------------------------- 1 |
2 | -------------------------------------------------------------------------------- /share/site/duckduckgo/app_info.tx: -------------------------------------------------------------------------------- 1 |
2 | -------------------------------------------------------------------------------- /share/site/duckduckgo/newsletter.tx: -------------------------------------------------------------------------------- 1 |
2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Description 2 | 3 | -------------------------------------------------------------------------------- /share/site/duckduckgo/meta/chrome_newtab.tx: -------------------------------------------------------------------------------- 1 | <: include "meta/title.tx" { title => l('New Tab') } :> 2 | -------------------------------------------------------------------------------- /share/site/duckduckgo/meta/iframe.tx: -------------------------------------------------------------------------------- 1 | <: include "meta/title.tx" { title => l('DuckDuckGo') } :> 2 | -------------------------------------------------------------------------------- /share/site/duckduckgo/meta/title.tx: -------------------------------------------------------------------------------- 1 | <: $title :> 2 | 3 | -------------------------------------------------------------------------------- /xbin/site_scraper.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | locale_simple_scraper --only ^share/core/ \ 4 | --only ^share/site/$1/ 5 | 6 | -------------------------------------------------------------------------------- /share/site/duckduckgo/header_homepage.tx: -------------------------------------------------------------------------------- 1 |
2 |
3 |
-------------------------------------------------------------------------------- /share/site/duckduckgo/install.tx: -------------------------------------------------------------------------------- 1 |
2 | 5 | -------------------------------------------------------------------------------- /t/load.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | use strict; 3 | use warnings; 4 | use Test::LoadAllModules; 5 | 6 | BEGIN { 7 | all_uses_ok( search_path => 'DDG::Publisher' ); 8 | } 9 | -------------------------------------------------------------------------------- /share/site/duckduckgo/meta/press.tx: -------------------------------------------------------------------------------- 1 | <: include "meta/title.tx" { title => l('DuckDuckGo Press Page') } :> 2 | 3 | 4 | -------------------------------------------------------------------------------- /share/core/micro_foot.tx: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /share/site/duckduckgo/head.tx: -------------------------------------------------------------------------------- 1 | <: include "meta/base.tx" :> 2 | <: if find_template("meta/" ~ $f.filebase ~ ".tx") { :> 3 | <: include "meta/" ~ $f.filebase ~ ".tx" :> 4 | <: } else { :> 5 | DuckDuckGo 6 | <: } :> -------------------------------------------------------------------------------- /share/site/duckduckgo/50x.tx: -------------------------------------------------------------------------------- 1 |
2 | Oops, there was an error.  Please try again.

If it persists, please email ops@duckduckgo.com 3 |
4 |
-------------------------------------------------------------------------------- /share/site/duckduckgo/_logo_homepage.tx: -------------------------------------------------------------------------------- 1 |
2 | 3 | About DuckDuckGo 4 | Duck it! 5 | 6 |
7 | -------------------------------------------------------------------------------- /share/site/duckduckgo/chrome_newtab.tx: -------------------------------------------------------------------------------- 1 |
2 | <: include "_logo_homepage.tx" :> 3 | 4 |
5 | <: include "search_form_homepage.tx" :> 6 |
7 |
8 | -------------------------------------------------------------------------------- /share/site/duckduckgo/untranslated.tx: -------------------------------------------------------------------------------- 1 | <: if $f.locale != $s.default_locale { :> 2 |
<: l("Sorry, we can't offer any translation for this page. It is shown here in '%s'.",$locales[$s.default_locale].name_in_english) :>
3 | <: } :> -------------------------------------------------------------------------------- /lib/DDG/Publisher/Site/Dontbubbleus/Root.pm: -------------------------------------------------------------------------------- 1 | package DDG::Publisher::Site::Dontbubbleus::Root; 2 | 3 | use MooX; 4 | 5 | with qw( 6 | DDG::Publisher::DirRole 7 | ); 8 | 9 | sub path { '/' } 10 | 11 | sub pages {{ 12 | 13 | index => sub {}, 14 | 15 | }} 16 | 17 | 1; -------------------------------------------------------------------------------- /lib/DDG/Publisher/Site/Donttrackus/Root.pm: -------------------------------------------------------------------------------- 1 | package DDG::Publisher::Site::Donttrackus::Root; 2 | 3 | use MooX; 4 | 5 | with qw( 6 | DDG::Publisher::DirRole 7 | ); 8 | 9 | sub path { '/' } 10 | 11 | sub pages {{ 12 | 13 | index => sub {}, 14 | 15 | }} 16 | 17 | 1; -------------------------------------------------------------------------------- /share/site/duckduckgo/meta/duckduckbot.tx: -------------------------------------------------------------------------------- 1 | <: include "meta/title.tx" { title => 'DuckDuckGo Bot' } :> 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /share/site/duckduckgo/meta/search_box.tx: -------------------------------------------------------------------------------- 1 | <: include "meta/title.tx" { title => l('DuckDuckGo Search Box') } :> 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /share/site/duckduckgo/meta/bang.tx: -------------------------------------------------------------------------------- 1 | <: include "meta/title.tx" { title => 'DuckDuckGo !Bang' } :> 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /share/site/duckduckgo/meta/donations.tx: -------------------------------------------------------------------------------- 1 | <: include "meta/title.tx" { title => l('DuckDuckGo Donations') } :> 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /share/site/duckduckgo/meta/params.tx: -------------------------------------------------------------------------------- 1 | <: include "meta/title.tx" { title => l('DuckDuckGo URL Parameters') } :> 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /share/site/duckduckgo/meta/newbang.tx: -------------------------------------------------------------------------------- 1 | <: include "meta/title.tx" { title => l('DuckDuckGo New !Bang') } :> 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /share/site/donttrackus/header.tx: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | <: include "lang_select.tx" {s=>$s,f=>$f,locales=>$locales} :> 5 | 6 | -------------------------------------------------------------------------------- /share/site/duckduckgo/meta/api.tx: -------------------------------------------------------------------------------- 1 | <: include "meta/title.tx" { title => l('DuckDuckGo Instant Answer API') } :> 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /share/site/duckduckgo/meta/styleguide.tx: -------------------------------------------------------------------------------- 1 | <: include "meta/title.tx" { title => l('DuckDuckGo Style Guide') } :> 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /share/site/duckduckgo/popout.tx: -------------------------------------------------------------------------------- 1 | 2 | <: r($link) :> 3 | 6 | 7 | -------------------------------------------------------------------------------- /share/site/duckduckgo/meta/privacy.tx: -------------------------------------------------------------------------------- 1 | <: include "meta/title.tx" { title => l('DuckDuckGo Privacy') } :> 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /lib/DDG/Publisher/Site/Duckduckgo.pm: -------------------------------------------------------------------------------- 1 | package DDG::Publisher::Site::Duckduckgo; 2 | 3 | use strict; 4 | use MooX; 5 | 6 | with qw( 7 | DDG::Publisher::SiteRole 8 | ); 9 | 10 | sub default_hostname { 'duckduckgo.com' } 11 | 12 | sub dirs_classes {qw( 13 | Root 14 | )} 15 | 16 | sub locale_package { 'DDG::Locale' } 17 | sub locale_dist { '' } 18 | sub locale_domain { 'duckduckgo' } 19 | 20 | 1; -------------------------------------------------------------------------------- /share/site/duckduckgo/meta/about.tx: -------------------------------------------------------------------------------- 1 | <: include "meta/title.tx" { title => l('About DuckDuckGo') } :> 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /share/site/duckduckgo/popover.tx: -------------------------------------------------------------------------------- 1 | 11 | -------------------------------------------------------------------------------- /share/site/duckduckgo/meta/settings.tx: -------------------------------------------------------------------------------- 1 | <: include "meta/title.tx" { title => l('DuckDuckGo Settings') } :> 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /share/site/duckduckgo/meta/feedback.tx: -------------------------------------------------------------------------------- 1 | <: include "meta/title.tx" { title => l('DuckDuckGo Feedback') } :> 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /weaver.ini: -------------------------------------------------------------------------------- 1 | [@CorePrep] 2 | 3 | [Name] 4 | [Version] 5 | 6 | [Region / prelude] 7 | 8 | [Generic / SYNOPSIS] 9 | [Generic / DESCRIPTION] 10 | [Generic / OVERVIEW] 11 | 12 | [Collect / EXPORTS FUNCTIONS] 13 | command = keyword 14 | 15 | [Collect / ATTRIBUTES] 16 | command = attr 17 | 18 | [Collect / METHODS] 19 | command = method 20 | 21 | [Leftovers] 22 | 23 | [Region / postlude] 24 | 25 | [Authors] 26 | 27 | [Legal] 28 | 29 | -------------------------------------------------------------------------------- /lib/DDG/Publisher/Site/Duckduckhack.pm: -------------------------------------------------------------------------------- 1 | package DDG::Publisher::Site::Duckduckhack; 2 | 3 | use MooX; 4 | 5 | with qw( 6 | DDG::Publisher::SiteRole 7 | ); 8 | 9 | sub default_hostname { 'duckduckhack.com' } 10 | 11 | sub dirs_classes {qw( 12 | Root 13 | )} 14 | 15 | sub locale_package { 'DDGC::Locale::DuckduckgoDuckduckgo' } 16 | sub locale_dist { 'DDGC-Locale-DuckduckgoDuckduckgo' } 17 | sub locale_domain { 'duckduckgo-duckduckgo' } 18 | 19 | 1; -------------------------------------------------------------------------------- /share/site/duckduckgo/meta/duckduckpreview.tx: -------------------------------------------------------------------------------- 1 | <: include "meta/title.tx" { title => 'DuckDuckGo Preview Bot' } :> 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /share/site/duckduckgo/search_form_hero.tx: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /share/site/duckduckgo/meta/index.tx: -------------------------------------------------------------------------------- 1 | <: include "meta/title.tx" { title => 'DuckDuckGo — ' ~ l('Privacy, simplified.') } :> 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /share/site/duckduckhack/index.tx: -------------------------------------------------------------------------------- 1 | 2 | <: include "inc/head.tx" :> 3 | 4 | 5 | <: include "head_js.tx" :> 6 |
7 | <: include "header.tx" :> 8 |
9 | <: include "index_content.tx" :> 10 | <: include "footer_nav.tx" :> 11 | <: include "footer_copyright.tx" :> 12 |
13 |
14 | 15 | -------------------------------------------------------------------------------- /share/site/dontbubbleus/header.tx: -------------------------------------------------------------------------------- 1 | <: include "lang_select.tx" {s=>$s,f=>$f,locales=>$locales} :> 2 | 3 | 9 | -------------------------------------------------------------------------------- /share/site/duckduckhack/inc/head_doc.tx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /lib/DDG/Publisher/Site/Donttrackus.pm: -------------------------------------------------------------------------------- 1 | package DDG::Publisher::Site::Donttrackus; 2 | 3 | use MooX; 4 | use DDGC::Locale::DuckduckgoDonttrackus; 5 | 6 | with qw( 7 | DDG::Publisher::SiteRole 8 | ); 9 | 10 | sub default_hostname { 'donttrack.us' } 11 | 12 | sub dirs_classes {qw( 13 | Root 14 | )} 15 | 16 | sub locale_package { 'DDGC::Locale::DuckduckgoDonttrackus' } 17 | sub locale_dist { 'DDGC-Locale-DuckduckgoDonttrackus' } 18 | sub locale_domain { 'duckduckgo-donttrackus' } 19 | 20 | 1; -------------------------------------------------------------------------------- /lib/DDG/Publisher/Site/Dontbubbleus.pm: -------------------------------------------------------------------------------- 1 | package DDG::Publisher::Site::Dontbubbleus; 2 | 3 | use MooX; 4 | use DDGC::Locale::DuckduckgoDontbubbleus; 5 | 6 | with qw( 7 | DDG::Publisher::SiteRole 8 | ); 9 | 10 | sub default_hostname { 'dontbubble.us' } 11 | 12 | sub dirs_classes {qw( 13 | Root 14 | )} 15 | 16 | sub locale_package { 'DDGC::Locale::DuckduckgoDontbubbleus' } 17 | sub locale_dist { 'DDGC-Locale-DuckduckgoDontbubbleus' } 18 | sub locale_domain { 'duckduckgo-dontbubbleus' } 19 | 20 | 1; -------------------------------------------------------------------------------- /bin/ddg_publisher: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | # PODNAME: ddg_publisher 3 | # ABSTRACT: Generating static parts of DuckDuckGo 4 | 5 | =head1 SYNOPSIS 6 | 7 | perl -Ilib bin/ddg_publisher ~/test_publish 8 | 9 | # compressing html to one line without comments and unnecessary whitespaces 10 | perl -Ilib bin/ddg_publisher --no_compression ~/test_publish 11 | 12 | =cut 13 | 14 | use FindBin qw($Bin); 15 | use lib "$Bin/../lib"; 16 | use lib "lib"; 17 | 18 | use DDG::App::Publisher; 19 | 20 | DDG::App::Publisher->new_with_options->run; 21 | -------------------------------------------------------------------------------- /share/site/duckduckgo/settings.tx: -------------------------------------------------------------------------------- 1 |
2 | 8 |
9 | 10 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /share/core/footer_copyright.tx: -------------------------------------------------------------------------------- 1 | 16 | -------------------------------------------------------------------------------- /share/site/duckduckgo/index.tx: -------------------------------------------------------------------------------- 1 | 2 | 12 |
13 |
14 | -------------------------------------------------------------------------------- /share/site/duckduckgo/search_form_homepage.tx: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /share/site/donttrackus/share_links.tx: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | sudo: false 3 | before_install: 4 | - export HARNESS_OPTIONS=j10:c HARNESS_TIMER=1 5 | - git config --global user.name "Dist Zilla Plugin TravisCI" 6 | - git config --global user.email $HOSTNAME":not-for-mail@travis-ci.org" 7 | install: 8 | - cpanm --quiet --notest --skip-installed Dist::Zilla 9 | - dzil authordeps | grep -ve '^\W' | xargs -n 5 -P 10 cpanm --quiet --notest --mirror http://www.cpan.org/ --mirror http://duckpan.org 10 | - dzil listdeps | grep -ve '^\W' | cpanm --quiet --notest --mirror http://www.cpan.org/ --mirror http://duckpan.org 11 | language: perl 12 | perl: 13 | - '5.16' 14 | script: 15 | - dzil smoke --release --author 16 | -------------------------------------------------------------------------------- /share/site/dontbubbleus/share_links.tx: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /share/site/duckduckgo/yahoo_static.tx: -------------------------------------------------------------------------------- 1 |
2 | 3 |

This domain is owned by DuckDuckGo.

4 |

It is no longer in use.

5 |
6 | This DuckDuckGo owned server is operating on a subdomain (duckduckgo-owned-server.yahoo.net) that has been delegated to DuckDuckGo via DNS by Yahoo. In accordance with our privacy policy, we never share any personal information with any of our partners, including Yahoo. If you have any questions, please send an email to privacy@duckduckgo.com. 7 |
8 |
9 | -------------------------------------------------------------------------------- /share/site/duckduckhack/base.tx: -------------------------------------------------------------------------------- 1 | <: if $raw_output { include $maintemplate } else { :> 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | <: include $maintemplate :> 11 | 12 | 13 | <: } # closing the top line :> -------------------------------------------------------------------------------- /share/core/lang_select.tx: -------------------------------------------------------------------------------- 1 |
2 | <: $locales[$f.locale].name_in_local :> 3 | 13 |
-------------------------------------------------------------------------------- /share/site/duckduckgo/meta/spread.tx: -------------------------------------------------------------------------------- 1 | <: include "meta/title.tx" { title => l('Help Spread DuckDuckGo') } :> 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /share/site/duckduckhack/ddh-feature.tx: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
5 | 6 | <: $item.name :> 7 | 8 |
9 |

<: if !$item.desc { :>@<: $item.user :><: } else { :><:$item.desc :> by <: $item.user :><: } :>

10 |
11 |
-------------------------------------------------------------------------------- /share/site/duckduckgo/meta/app.tx: -------------------------------------------------------------------------------- 1 | <: include "meta/title.tx" { title => l('Privacy, simplified. — DuckDuckGo Browser Extension & Mobile App') } :> 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /share/site/duckduckgo/meta/app_info.tx: -------------------------------------------------------------------------------- 1 | <: include "meta/title.tx" { title => l('Privacy, simplified. — DuckDuckGo Browser Extension & Mobile App') } :> 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /share/site/duckduckgo/duckduckpreview.tx: -------------------------------------------------------------------------------- 1 |
DuckDuckGo Preview Bot
2 | 3 | <: include "untranslated.tx" :> 4 | 5 |
6 | Duck Duck Go is a new search engine. Duck Duck Preview is the server process behind our preview function, which allows users to preview pages before visiting them. 7 | 8 |

9 | We grab pages on behalf of our users and display to them parts of those pages most relevant to their queries. Duck Duck Preview is not a Web crawler or spider.

10 | 11 |

12 | If you have any questions, please email help@duckduckgo.com.

13 | 14 |

15 | Changelog 16 |

17 | 18 |

19 | DuckDuckPreview/1.0 - Initial version. 20 |

-------------------------------------------------------------------------------- /share/site/duckduckgo/meta/newsletter.tx: -------------------------------------------------------------------------------- 1 | <: include "meta/title.tx" { title => l('DuckDuckGo Privacy Crash Course') } :> 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /share/site/duckduckgo/footer_homepage.tx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 15 | -------------------------------------------------------------------------------- /dist.ini: -------------------------------------------------------------------------------- 1 | name = DDG-Publisher 2 | author = Torsten Raudssus 3 | license = Apache_2_0 4 | copyright_holder = DuckDuckGo, Inc. L 5 | copyright_year = 2012 6 | 7 | [PromptIfStale] 8 | index = http://duckpan.org 9 | module = Dist::Zilla::Plugin::UploadToDuckPAN 10 | 11 | [AutoPrereqs] 12 | skip = ^DDG:: 13 | 14 | [GatherDir] 15 | [PruneCruft] 16 | [ManifestSkip] 17 | [ExtraTests] 18 | [ExecDir] 19 | [ShareDir] 20 | [MakeMaker] 21 | [Manifest] 22 | [TestRelease] 23 | [ConfirmRelease] 24 | [UploadToDuckPAN] 25 | [MetaJSON] 26 | 27 | [MetaNoIndex] 28 | directory = t/ 29 | directory = xt/ 30 | directory = ex/ 31 | directory = inc/ 32 | 33 | [Git::NextVersion] 34 | version_regexp = ^(.+)$ 35 | [PkgVersion] 36 | [PodSyntaxTests] 37 | [GithubMeta] 38 | 39 | [@Git] 40 | tag_format = %v 41 | 42 | [Git::Push] 43 | push_to = origin master 44 | 45 | [PodWeaver] 46 | -------------------------------------------------------------------------------- /share/site/dontbubbleus/head.tx: -------------------------------------------------------------------------------- 1 | <: l('Escape your search engine Filter Bubble!') :> 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /share/site/duckduckhack/inc/side_nav.tx: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /share/site/duckduckhack/inc/head.tx: -------------------------------------------------------------------------------- 1 | <: lp("title","DuckDuckHack - an open source community for DuckDuckGo Instant Answers") :> 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /share/site/dontbubbleus/share_modal.tx: -------------------------------------------------------------------------------- 1 |
2 |

<: l('Email to friends') :>

3 |
4 | 5 |
6 |
7 |
8 |
9 |
10 | <: l('Remove friend') :> 11 | <: l('Add more friends') :> 12 |
13 | 14 | 15 |
16 |
17 |
-------------------------------------------------------------------------------- /share/site/donttrackus/share_modal.tx: -------------------------------------------------------------------------------- 1 |
2 |

<: l('Email to friends') :>

3 |
4 | 5 |
6 |
7 |
8 |
9 |
10 | <: l('Remove friend') :> 11 | <: l('Add more friends') :> 12 |
13 | 14 | 15 |
16 |
17 |
-------------------------------------------------------------------------------- /share/site/duckduckgo/duckduckbot.tx: -------------------------------------------------------------------------------- 1 |
<: l('DuckDuckGo Bot'):>
2 | 3 | <: include "untranslated.tx" :> 4 | 5 |
6 | <: lp('duckduckbot', 'DuckDuckBot is the Web crawler for %s. It respects %s and originates from these IP addresses:',r('DuckDuckGo'), r('WWW::RobotRules')) :> 7 | 8 |
9 |     107.20.237.51 10 |
    23.21.226.191 11 |
    107.21.1.8 12 |
    54.208.102.37 13 | 14 |
15 | <: lp('questions', 'If you have any questions or concerns, please %s.',r('') ~ lp('questions','let us know') ~ r('')) :>. 16 | 17 |
18 | Changelog 19 | 20 |
21 | DuckDuckBot/1.1 - Bug fix: was not respecting robots.txt in some cases. 22 | 23 |
24 | DuckDuckBot/1.0 - Initial version. 25 | -------------------------------------------------------------------------------- /share/core/head_js.tx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | <: if $js_include_g { :> 7 | 8 | <: } :> 9 | <: if $js_page_type && !$homepage { :> 10 | 11 | <: } :> 12 | <: if !$js_skip_init { :> 13 | 18 | <: } :> 19 | -------------------------------------------------------------------------------- /share/core/micro_bottom.tx: -------------------------------------------------------------------------------- 1 | 2 |

More you might like to know…

3 | -------------------------------------------------------------------------------- /share/core/footer_nav.tx: -------------------------------------------------------------------------------- 1 | 30 | -------------------------------------------------------------------------------- /share/site/donttrackus/base.tx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | <: include "head.tx" :> 11 | 12 | 13 | 14 |
15 | <: include "header.tx" :> 16 |
17 | <: include $maintemplate :> 18 |
19 |
20 |
21 | <: include "micro_bottom.tx" :> 22 |
23 |
24 | <: include "micro_foot.tx" :> 25 |
26 | 27 | <: include "share_modal.tx" :> 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /share/site/dontbubbleus/base.tx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | <: include "head.tx" :> 11 | 12 | 13 | 14 |
15 | <: include "header.tx" :> 16 |
17 | <: include $maintemplate :> 18 |
19 |
20 |
21 | <: include "micro_bottom.tx" :> 22 |
23 |
24 | <: include "micro_foot.tx" :> 25 |
26 | 27 | <: include "share_modal.tx" :> 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /share/site/duckduckgo/head_js.tx: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | <: if $js_include_g { :> 10 | 11 | <: } :> 12 | <: if !$homepage { :> 13 | 14 | <: } :> 15 | <: if !$js_skip_init { :> 16 | 19 | <: } :> 20 | <: if $js_bang_version { :> 21 | 24 | <: } :> 25 | -------------------------------------------------------------------------------- /share/site/donttrackus/head.tx: -------------------------------------------------------------------------------- 1 | <: l("Google tracks you. We don't.") :> <: l("An illustrated guide.") :> 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /share/site/duckduckgo/header_flex.tx: -------------------------------------------------------------------------------- 1 |
2 | 23 |
24 | 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DuckDuckGo Publisher [![Build Status](https://travis-ci.org/duckduckgo/duckduckgo-publisher.png?branch=master)](https://travis-ci.org/duckduckgo/duckduckgo-publisher) 2 | 3 | # Installation 4 | 5 | You require the following libraries of https://duck.co/ 6 | 7 | - DDG 8 | - DDGC::Locale::DuckduckgoDuckduckgo 9 | - DDGC::Locale::DuckduckgoDontbubbleus 10 | - DDGC::Locale::DuckduckgoDonttrackus 11 | 12 | You can install App::DuckPAN of CPAN for this and then do the following command: 13 | 14 | ``` 15 | duckpan \ 16 | DDG \ 17 | DDGC::Locale::DuckduckgoDuckduckgo \ 18 | DDGC::Locale::DuckduckgoDontbubbleus \ 19 | DDGC::Locale::DuckduckgoDonttrackus 20 | ``` 21 | 22 | # Proxying Requests to Dev Server 23 | 24 | My default, asset URLs are relative (e.g. /style.css). To proxy these request to a development server, you can specify the domain for individual sites: 25 | 26 | ```shell 27 | duckpan publisher --duckduckgo=http://moollaza.duckduckgo.com 28 | ``` 29 | 30 | Now all relative URLs will be directed to the specified server. In this case `/style.css` will be requested as `http://moollaza.duckduckgo.com/style.css`. 31 | 32 | This allows you to develop locally and load assets from another server. 33 | 34 | # Publishing 35 | 36 | Inside the repository you can do this to get a live simulation: 37 | 38 | ``` 39 | duckpan publisher 40 | ``` 41 | 42 | If you want to generate the static files you can do the following from the repository: 43 | 44 | ``` 45 | perl -Ilib bin/ddg_publisher test_publish 46 | ``` 47 | 48 | The directory test_publish will be generated and filled up with the results. 49 | 50 | 51 | -------------------------------------------------------------------------------- /share/site/duckduckgo/meta/base.tx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | <: if $homepage { :> 10 | 11 | <: } else {:> 12 | 13 | <: } :> 14 | <: if $css_serp { :> 15 | 16 | <: } :> 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /share/core/header.tx: -------------------------------------------------------------------------------- 1 | <: if !$no_search_header { :> 2 |
3 | 18 |
19 |
20 | <: } if $hero_header { :> 21 |
22 |
23 | <: if !$no_hero_header_icon { :><: } :> 24 | <: if $hero_header_text { :><: l('Try a search!') :><: } :> 25 | <: if $hero_header_link { :> 26 | <: l($hero_header_link_text) :> 27 | <: } :> 28 |
29 |
30 |
31 | <: } :> 32 | 33 | -------------------------------------------------------------------------------- /share/core/footer_about.tx: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |
6 |
7 |
DuckDuckGo
8 | 15 |
16 |
17 |
Follow Us
18 | 23 |
24 |
25 |
26 |
27 |
About Us
28 |

DuckDuckGo is an Internet privacy company that empowers you to seamlessly take control of your personal information online, without any tradeoffs. With our roots as the search engine that doesn’t track you, we’ve expanded what we do to protect you 29 | no matter where the Internet takes you.

30 | Learn more about our story 31 |
32 |
33 |
34 |
35 | 36 | -------------------------------------------------------------------------------- /share/site/duckduckgo/header.tx: -------------------------------------------------------------------------------- 1 | <: if !$no_search_header { :> 2 |
3 | 18 |
19 |
20 | <: } if $hero_header { :> 21 |
22 |
23 | <: if $hero_alt { :> 24 | 27 | <: } :> 28 | <: if !$no_hero_header_icon { :><: } :> 29 | <: if $hero_header_text { :><: l('Try a search!') :><: } :> 30 | <: if $hero_header_link { :> 31 | <: l($hero_header_link_text) :> 32 | <: } :> 33 |
34 |
35 |
36 | <: } :> 37 | 38 | -------------------------------------------------------------------------------- /share/site/duckduckgo/donations.tx: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |

Donating for Privacy

5 |

Every year since 2011, DuckDuckGo has been donating to organizations that contribute to our vision of raising the standard of trust online.

6 |
7 |
8 | 9 | 10 |
11 | 12 | 13 | 14 |

Over $1,300,000 in DuckDuckGo privacy donations

15 |
16 | 17 | 18 |
19 |
20 |
21 | <:- for $yearly_donations -> $event { -:> 22 |
23 |

<: $event.year :>

24 |

25 | <: $event.total :> 26 |
for
27 | <: $event.theme :> 28 |

29 |

<: $event.snippet | raw :>

30 | 31 | : macro donation_item -> $donation { 32 | : if $donation.amount { 33 | <: $donation.amount :> 34 | : } 35 | <: $donation.recipient :> 36 | : } 37 | 38 |
    39 | : for $event.donations.col1 -> $donation { 40 |
  • <:- donation_item($donation) -:>
  • 41 | : } 42 |
43 |
    44 | : for $event.donations.col2 -> $donation { 45 |
  • <:- donation_item($donation) -:>
  • 46 | : } 47 |
48 |
49 | <:- } -:> 50 |
51 |
52 |
53 | -------------------------------------------------------------------------------- /share/site/duckduckgo/bang.tx: -------------------------------------------------------------------------------- 1 |
2 |
3 | 6 | 7 |

Say hello to bangs.

8 |
9 |
10 |
11 |
12 |
13 |

What are bangs?

14 |

Bangs are shortcuts that quickly take you to search results on other sites. For example, when you know you want to search on another site like Wikipedia or Amazon, our bangs get you there fastest. A search for !w filter bubble will take you directly to Wikipedia.

15 |

Remember, though, because your search is actually taking place on that other site, you are subject to that site’s policies, including its data collection practices.

16 |

We’ve had bangs since 2008 as part of our geek roots. Now we have thousands of !bangs and you can even submit your own.

17 |
18 |
19 | 22 | 23 |
24 |
25 |
26 | 31 | 32 |
33 |
34 | -------------------------------------------------------------------------------- /lib/DDG/Publisher/Site/Duckduckhack/Root.pm: -------------------------------------------------------------------------------- 1 | package DDG::Publisher::Site::Duckduckhack::Root; 2 | 3 | use MooX; 4 | 5 | with qw( 6 | DDG::Publisher::DirRole 7 | ); 8 | 9 | sub path { '/' } 10 | 11 | sub pages { 12 | my $self = shift; 13 | 14 | my %pages = (); 15 | 16 | $pages{'index'} = sub { 17 | no_search_header => 1, 18 | hero_header => 1, 19 | no_hero_header_icon => 1, 20 | hero_header_link => '', 21 | hero_header_link_text => "Docs", 22 | hero_alt => 1, 23 | no_footer_arrow => 1, 24 | asset_path => 'ddg', 25 | js_page_type => 'DDH', 26 | hero_slides => [{ 27 | text => "Help us make %sDuckDuckGo%s the best search engine for programmers.", 28 | img => 'regex', 29 | tab => 'Regex', 30 | user => 'mintsoft', 31 | link => 'https://duckduckgo.com/?q=regex+cheat+sheet&ia=cheatsheet', 32 | }], 33 | foot_useful => [{ 34 | name => 'Fuel Economy', 35 | desc => 'Vehicle fuel economy data', 36 | user => 'zachthompson', 37 | link => 'https://duck.co/ia/view/fuel_economy', 38 | example_link => 'https://duckduckgo.com/?q=2013+tesla+mpg&ia=fueleconomy', 39 | },{ 40 | name => 'Resistor Colors', 41 | desc => 'Display resistor color bands', 42 | user => 'joewalnes', 43 | link => 'https://duck.co/ia/view/resistor_colors', 44 | example_link => 'https://duckduckgo.com/?q=10k+resistor&ia=answer', 45 | },{ 46 | name => 'Linux Cheat Sheet', 47 | desc => 'Common Linux shortcuts', 48 | user => 'crashrane', 49 | link => 'https://duck.co/ia/view/linux_cheat_sheet', 50 | example_link => 'https://duckduckgo.com/?q=linux+cheat+sheet&ia=cheatsheet', 51 | }], 52 | foot_fun => [{ 53 | name => 'People in Space', 54 | desc => "Find out who's orbiting Earth", 55 | user => 'NeoSilky', 56 | link => 'https://duck.co/ia/view/people_in_space', 57 | example_link => 'https://duckduckgo.com/?q=people+in+space&t=ffab&ia=answer', 58 | },{ 59 | name => 'Minecraft', 60 | desc => 'Minecraft crafting recipes', 61 | user => 'engvik', 62 | link => 'https://duck.co/ia/view/minecraft', 63 | example_link => 'https://duckduckgo.com/?q=cake+minecraft&ia=answer', 64 | },{ 65 | name => 'Riffsy Gif Search', 66 | desc => 'Search emoji-related gifs', 67 | user => 'bryanhart', 68 | link => 'https://duck.co/ia/view/riffsy', 69 | example_link => 'https://duckduckgo.com/?q=%F0%9F%91%8D&ia=gifs', 70 | }], 71 | foot_users => [{ 72 | name => 'Matthew Ramina', 73 | user => 'mattr555', 74 | },{ 75 | name => 'Rob Emery', 76 | user => 'mintsoft', 77 | },{ 78 | name => 'Chris Wilson', 79 | user => 'MrChrisW', 80 | }], 81 | }; 82 | 83 | return \%pages; 84 | } 85 | 86 | 1; 87 | -------------------------------------------------------------------------------- /share/site/duckduckgo/feedback.tx: -------------------------------------------------------------------------------- 1 | 42 | 43 |

<: l("Check the Help pages, then use this guide.:") :>

44 | 45 | 50 | 51 | 56 | 57 | 62 | -------------------------------------------------------------------------------- /share/site/duckduckgo/base.tx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | <: include "head.tx" :> 11 | 12 | 13 | <: if !$no_js { include "head_js.tx" } :> 14 |
15 | <: if !$no_wrapper { :> 16 | <: if !$no_header { :> 17 | <: if $flex_header { :> 18 | <: include "header_flex.tx" :> 19 | <: } else { :> 20 | <: include "header.tx" :> 21 | <: } :> 22 | <: } :> 23 |
24 | <: if !$no_content_internal { :> 25 |
26 |
27 | <: } :> 28 | <: } else { :> 29 | <: if $homepage { :> 30 | <: include "header_homepage.tx" :> 31 |
32 |
33 |
34 | <: include "_logo_homepage.tx" :> 35 |
36 | <: include "search_form_homepage.tx" :> 37 |
38 | <: } :> 39 | <: } :> 40 | 41 | <: include $maintemplate :> 42 | 43 | <: if $no_wrapper { :> 44 | <: if $homepage { :> 45 |
46 |
47 |
48 | <: include "footer_homepage.tx" :> 49 | <: } :> 50 | <: } else { :> 51 | <: if !$no_spacer { :>
<:}:> 52 | <: if !$no_content_internal { :> 53 |
54 |
55 | <: } :> 56 | <: if $nav_footer { :> 57 | <: include "footer_nav.tx" :> 58 | <: } else if $about_footer { :> 59 | <: include "footer_about.tx" :> 60 | <: } :> 61 | <: if $copyright_footer { :> 62 | <: include "footer_copyright.tx" :> 63 | <: } :> 64 |
65 | <: } :> 66 |
67 | 68 | 69 | -------------------------------------------------------------------------------- /share/core/footer.tx: -------------------------------------------------------------------------------- 1 |
2 |
3 | 19 |
20 | 32 |
33 |
34 | 47 |
48 |
49 |
50 | 60 | -------------------------------------------------------------------------------- /lib/DDG/App/Publisher.pm: -------------------------------------------------------------------------------- 1 | package DDG::App::Publisher; 2 | # ABSTRACT: The application class 3 | 4 | =head1 SYNOPSIS 5 | 6 | =cut 7 | 8 | use MooX; 9 | use MooX::Options protect_argv => 0; 10 | use Path::Class; 11 | use DDG::Publisher; 12 | 13 | =attr compression 14 | 15 | If this is activated then compression will be used. 16 | 17 | =cut 18 | 19 | option compression => ( 20 | is => 'ro', 21 | predicate => 1, 22 | ); 23 | 24 | # backward compatibility 25 | option no_compression => ( 26 | is => 'ro', 27 | ); 28 | 29 | =attr dryrun 30 | 31 | If this option is activated the publisher will not generate any files and 32 | will just execute the code so that tokens and generatly sanity of the code 33 | can be checked. This option requires a filename to be given, so this is used 34 | for the dryrun of L. 35 | 36 | =cut 37 | 38 | option dryrun => ( 39 | format => 's', 40 | is => 'ro', 41 | predicate => 1, 42 | ); 43 | 44 | =attr site_only 45 | 46 | Use this option to only execute one specific file. You can use it several 47 | times. Give the classname of the site you want to execute with the 48 | B part. This option can be given several times. 49 | 50 | =cut 51 | 52 | option site_only => ( 53 | format => 's', 54 | is => 'ro', 55 | predicate => 1, 56 | ); 57 | 58 | =attr tmpl_dir 59 | 60 | Use an extra template dir for the process (will be used for all sites). 61 | 62 | =cut 63 | 64 | option tmpl_dir => ( 65 | format => 's', 66 | is => 'ro', 67 | predicate => 1, 68 | ); 69 | 70 | =attr quiet 71 | 72 | Don't print Text::XSlate warnings 73 | 74 | =cut 75 | 76 | option quiet => ( 77 | is => 'ro', 78 | predicate => 1, 79 | ); 80 | 81 | =method run 82 | 83 | This method gets executed for the run of the publisher 84 | 85 | =cut 86 | 87 | sub run { 88 | my ( $self ) = @_; 89 | 90 | # 91 | # Getting the target directory from $ENV{DDG_PUBLISHER_TARGETDIR} 92 | # or from command line. 93 | # 94 | 95 | # warn qq(ENV DDG_MAX_CSS $ENV{DDG_MAX_CSS}); 96 | # warn qq(ENV DDG_MAX_JS $ENV{DDG_MAX_JS}); 97 | 98 | my $target = @ARGV 99 | ? shift @ARGV 100 | : defined $ENV{DDG_PUBLISHER_TARGETDIR} 101 | ? $ENV{DDG_PUBLISHER_TARGETDIR} 102 | : die "Require a target path or DDG_PUBLISHER_TARGETDIR set"; 103 | my $dir = dir($target)->absolute; 104 | my $publisher = DDG::Publisher->new( 105 | $self->has_quiet ? ( quiet => $self->quiet ) : (), 106 | $self->has_compression ? ( compression => $self->compression ) : (), 107 | $self->has_dryrun ? ( dryrun => $self->dryrun ) : (), 108 | $self->has_site_only ? ( site_classes => [$self->site_only] ) : (), 109 | $self->has_tmpl_dir ? ( extra_template_dirs => [$self->tmpl_dir] ) : (), 110 | ); 111 | print "Publishing to ".$dir."\n"; 112 | my $count; 113 | eval { 114 | $count = $publisher->publish_to($dir); 115 | }; 116 | if ($@) { 117 | print "\nFAILED: ".$@; 118 | exit 1; 119 | } else { 120 | print "\n".$count." files generated\n"; 121 | } 122 | } 123 | 124 | 1; 125 | -------------------------------------------------------------------------------- /share/site/duckduckhack/doc.tx: -------------------------------------------------------------------------------- 1 | <: if !$raw_output { :> 2 | 3 | <: include "inc/head_doc.tx" :> 4 | <: $title :><: if $category { :> / <: $category } :> / DuckDuckHack 5 | 6 | 7 |
8 |
9 |
10 | <: } :> 11 | <:# snip here :> 12 |
13 | 18 |
19 |
20 |
21 |
22 |

<: if $category { $category :> — <: } $title :> 23 | 24 | 25 | 26 |

27 | 28 | <: if $prev.0 || $next.0 { :> 29 | 30 | <: if $prev.0 { :> 31 | 32 | 33 | 34 | <: } if $next.0 { :> 35 | 36 | 37 | 38 | <: } :> 39 | 40 | <: } :> 41 |
42 |
43 |
44 | <: r($html) :> 45 |
46 |
47 | <: if $prev.0 || $next.0 { :> 48 | 49 | <: if $prev.0 { :> 50 | 51 | 52 | 53 | <: } if $next.0 { :> 54 | 55 | 56 | 57 | <: } :> 58 | 59 | <: } :> 60 |
61 | Not helpful? Help Edit or Ask the Community
62 |
63 |
64 |
65 |
66 |
67 | <: include "inc/side_nav.tx" {nav_ref=>$nav_ref, file=>$file, title=>$title, category=>$category} :> 68 |
69 |
70 |
71 | <:# snip here :> 72 | <: if !$raw_output { :> 73 |
74 |
75 |
76 | <:# for testing only - don't try this at home, kids! :> 77 | 78 | 94 | 95 | <: } :> 96 | -------------------------------------------------------------------------------- /lib/DDG/Publisher/DirRole.pm: -------------------------------------------------------------------------------- 1 | package DDG::Publisher::DirRole; 2 | # ABSTRACT: The role for a directory in the publisher system 3 | 4 | use MooX::Role; 5 | use DDG::Publisher::File; 6 | 7 | requires qw( 8 | path 9 | pages 10 | ); 11 | 12 | =attr key 13 | 14 | The key inside the site for this directory. Required for instantiation. 15 | 16 | =cut 17 | 18 | has key => ( 19 | is => 'ro', 20 | required => 1, 21 | ); 22 | 23 | =attr site 24 | 25 | Site object for this directory. Required for instantiation. 26 | 27 | =cut 28 | 29 | has site => ( 30 | is => 'ro', 31 | required => 1, 32 | ); 33 | 34 | =attr files 35 | 36 | Contains a hash of the files for this directory. 37 | 38 | =cut 39 | 40 | has files => ( 41 | is => 'ro', 42 | lazy => 1, 43 | builder => 1, 44 | ); 45 | 46 | sub _build_files { 47 | my ( $self ) = @_; 48 | my %pages = %{$self->pages_coderefs}; 49 | my @locales = $self->site->locales; 50 | my %files; 51 | for my $page (keys %pages) { 52 | my $code = $pages{$page}; 53 | for my $locale (@locales) { 54 | my $file = DDG::Publisher::File->new( 55 | code => $code, 56 | filebase => $page, 57 | locale => $locale, 58 | dir => $self, 59 | ); 60 | $files{$page}->{$locale} = $file; 61 | } 62 | } 63 | my $default_locale = $self->site->default_locale; 64 | my %statics = %{$self->statics_coderefs}; 65 | for my $static (keys %statics) { 66 | my $code = $statics{$static}; 67 | my $file = DDG::Publisher::File->new( 68 | code => $code, 69 | filebase => $static, 70 | locale => $default_locale, 71 | dir => $self, 72 | static => 1, 73 | ); 74 | $files{$static} = $file; 75 | } 76 | return \%files; 77 | } 78 | 79 | =attr fullpath 80 | 81 | This hash also contains all files, but with the full path on the filesystem 82 | as key, so that collides can be detected. 83 | 84 | =cut 85 | 86 | has fullpath_files => ( 87 | is => 'ro', 88 | lazy => 1, 89 | builder => 1, 90 | ); 91 | 92 | sub _build_fullpath_files { 93 | my ( $self ) = @_; 94 | my %fullpath_files; 95 | for (values %{$self->files}) { 96 | if (ref $_ eq 'HASH') { 97 | for (values %{$_}) { 98 | die "The file ".$_->fullpath." already exist!!!" if defined $fullpath_files{$_->fullpath}; 99 | $fullpath_files{$_->fullpath} = $_; 100 | } 101 | } else { 102 | die "The file ".$_->fullpath." already exist!!!" if defined $fullpath_files{$_->fullpath}; 103 | $fullpath_files{$_->fullpath} = $_; 104 | } 105 | } 106 | return \%fullpath_files; 107 | } 108 | 109 | =attr pages_coderefs 110 | 111 | This attribute contains all the coderefs for the pages that have to be 112 | generated for this specific directory. It uses L as builder. Normally 113 | you override L in your site class. 114 | 115 | =cut 116 | 117 | has pages_coderefs => ( 118 | is => 'ro', 119 | lazy => 1, 120 | builder => 'pages', 121 | ); 122 | 123 | sub pages {{}} 124 | 125 | =attr statics_coderefs 126 | 127 | This attribute contains all the coderefs for the static pages that have to be 128 | generated for this specific directory. It uses L as builder. Normally 129 | you override L in your site class. A static file is not generated for 130 | every language 131 | 132 | =cut 133 | 134 | has statics_coderefs => ( 135 | is => 'ro', 136 | lazy => 1, 137 | builder => 'statics', 138 | ); 139 | 140 | sub statics {{}} 141 | 142 | =attr web_path 143 | 144 | The path on the web for this directory. 145 | 146 | =cut 147 | 148 | has web_path => ( 149 | is => 'ro', 150 | lazy => 1, 151 | builder => 1, 152 | ); 153 | 154 | sub _build_web_path { my @path = shift->path; defined $path[1] ? $path[1] : $path[0] } 155 | 156 | =attr template_path 157 | 158 | This is the path inside the templates, used for the pages and statics of this 159 | directory. 160 | 161 | =cut 162 | 163 | has template_path => ( 164 | is => 'ro', 165 | lazy => 1, 166 | builder => 1, 167 | ); 168 | 169 | sub _build_template_path { my @path = shift->path; $path[0] } 170 | 171 | 1; -------------------------------------------------------------------------------- /lib/DDG/Publisher.pm: -------------------------------------------------------------------------------- 1 | package DDG::Publisher; 2 | # ABSTRACT: Generation of the static files of DuckDuckGo and its microsites. 3 | 4 | use MooX; 5 | use Path::Class; 6 | use Class::Load ':all'; 7 | use IO::All -utf8; 8 | use HTML::Packer; 9 | use JSON; 10 | use File::Path qw(make_path); 11 | 12 | =attr site_classes 13 | 14 | List of classes that should get executed on publishing. 15 | 16 | =cut 17 | 18 | has site_classes => ( 19 | is => 'ro', 20 | lazy => 1, 21 | builder => 1, 22 | ); 23 | 24 | sub _build_site_classes {[qw( 25 | Duckduckgo 26 | Donttrackus 27 | Dontbubbleus 28 | Duckduckhack 29 | )]} 30 | 31 | =attr extra_template_dirs 32 | 33 | List of extra directions that should be used for templates. 34 | 35 | =cut 36 | 37 | has extra_template_dirs => ( 38 | is => 'ro', 39 | lazy => 1, 40 | builder => 1, 41 | ); 42 | 43 | sub _build_extra_template_dirs {[qw( 44 | templates 45 | )]} 46 | 47 | 48 | has cache_dir => ( 49 | is => 'ro', 50 | lazy => 1, 51 | builder => 1, 52 | ); 53 | 54 | 55 | sub _build_cache_dir { 56 | my $dir = $ENV{DDG_PUBLISHER_CACHE_DIR} ? $ENV{DDG_PUBLISHER_CACHE_DIR} : $ENV{HOME}."/publisher"; 57 | make_path($dir) unless -d $dir; 58 | return $dir; 59 | } 60 | 61 | 62 | =attr sites 63 | 64 | This attribute holds the objects of the site classes that should get build. 65 | 66 | =cut 67 | 68 | has sites => ( 69 | is => 'ro', 70 | lazy => 1, 71 | builder => 1, 72 | ); 73 | 74 | sub _build_sites { 75 | my ( $self ) = @_; 76 | return {map { 77 | my $class = 'DDG::Publisher::Site::'.$_; 78 | load_class($class); 79 | s/([a-z])([A-Z])/$1_$2/g; 80 | $_ = lc($_); 81 | lc($_) => $class->new( key => lc($_), publisher => $self ); 82 | } @{$self->site_classes}}; 83 | } 84 | 85 | =attr compression 86 | 87 | See L. 88 | 89 | =cut 90 | 91 | has compression => ( 92 | is => 'ro', 93 | default => sub { 0 }, 94 | ); 95 | 96 | =attr dryrun 97 | 98 | See L. 99 | 100 | =cut 101 | 102 | has dryrun => ( 103 | is => 'ro', 104 | predicate => 1, 105 | ); 106 | 107 | =attr quiet 108 | 109 | Don't print Text::XSlate warnings 110 | 111 | =cut 112 | 113 | has quiet => ( 114 | is => 'ro', 115 | predicate => 1, 116 | ); 117 | 118 | sub BUILD { 119 | my ( $self ) = @_; 120 | $self->sites; 121 | } 122 | 123 | =method publish_to 124 | 125 | This method it called to publish the files to the given specific directory. 126 | 127 | =cut 128 | 129 | sub publish_to { 130 | my ( $self, $target ) = @_; 131 | my $target_dir = dir($target)->absolute; 132 | $target_dir->mkpath unless -d "$target_dir"; 133 | my $count = 0; 134 | my $packer; 135 | $packer = HTML::Packer->init() if ($self->compression); 136 | 137 | # 138 | # For every site... 139 | # 140 | 141 | for my $site (values %{$self->sites}) { 142 | 143 | # 144 | # For every dir in the site... 145 | # 146 | 147 | for my $dir (values %{$site->dirs}) { 148 | print " - " . (ref $site) . substr($dir->web_path, 0, -1) . "\n"; 149 | my @files = values %{$dir->fullpath_files}; 150 | for (sort { $a->fullpath cmp $b->fullpath } @files) { 151 | my $real_file = file($target_dir,$site->key,$_->fullpath)->absolute; 152 | $real_file->dir->mkpath unless -f $real_file->dir->absolute->stringify; 153 | my $content = $_->content; 154 | utf8::encode($content); 155 | 156 | # 157 | # If compression is requested, then the content of the files 158 | # get compressed via HTML::Packer here. 159 | # 160 | 161 | if ($packer) { 162 | $packer->minify(\$content,{ 163 | remove_comments => 0, 164 | remove_newlines => 1, 165 | do_javascript => 1, 166 | do_stylesheet => 1, 167 | no_compress_comments => 1, 168 | }) 169 | } 170 | utf8::decode($content); 171 | io($real_file->stringify)->print($content); 172 | $count++; 173 | } 174 | } 175 | 176 | # 177 | # Generate a datafile for the site, which can be used for deeper 178 | # processing of the static files. (It's used by the internal code 179 | # of DDG to generate, for example, the nginx config) 180 | # 181 | 182 | my $data_file = file($target_dir,$site->key.'.json')->absolute; 183 | io($data_file)->print(encode_json($site->save_data)); 184 | }; 185 | return $count; 186 | } 187 | 188 | 1; 189 | -------------------------------------------------------------------------------- /lib/DDG/Publisher/SiteRole.pm: -------------------------------------------------------------------------------- 1 | package DDG::Publisher::SiteRole; 2 | # ABSTRACT: The role for a site in the publisher 3 | 4 | use MooX::Role; 5 | use Class::Load ':all'; 6 | use Text::Xslate qw( mark_raw ); 7 | use File::ShareDir::ProjectDistDir; 8 | use Locale::Simple; 9 | use Config::INI::Reader; 10 | use Path::Class; 11 | use JavaScript::Value::Escape; 12 | 13 | requires qw( 14 | default_hostname 15 | dirs_classes 16 | locale_package 17 | locale_domain 18 | ); 19 | 20 | =attr publisher 21 | 22 | L object, must be given on construction. 23 | 24 | =cut 25 | 26 | has publisher => ( 27 | is => 'ro', 28 | required => 1, 29 | ); 30 | 31 | =attr key 32 | 33 | This is the key used for the directory and general identification of the site 34 | inside the publisher system. 35 | 36 | =cut 37 | 38 | has key => ( 39 | is => 'ro', 40 | required => 1, 41 | ); 42 | 43 | =attr hostname 44 | 45 | This is the hostname, which should get used for the final files, so far this 46 | option isn't used and has no effect. B 47 | 48 | =cut 49 | 50 | has hostname => ( 51 | is => 'ro', 52 | builder => 'default_hostname', 53 | lazy => 1, 54 | ); 55 | 56 | =attr dirs 57 | 58 | This attribute contains the objects of the L objects 59 | of this site. 60 | 61 | =cut 62 | 63 | has dirs => ( 64 | is => 'ro', 65 | builder => 1, 66 | lazy => 1, 67 | ); 68 | 69 | sub _build_dirs { 70 | my ( $self ) = @_; 71 | return {map { 72 | my $class = (ref $self || $self).'::'.$_; 73 | load_class($class); 74 | s/([a-z])([A-Z])/$1_$2/g; 75 | $_ = lc($_); 76 | $_ => $class->new( 77 | key => $_, 78 | site => $self, 79 | ); 80 | } $self->dirs_classes}; 81 | } 82 | 83 | =attr default_locale 84 | 85 | Default locale to use on this site. Defaults to en_US and should never be 86 | changed on a site of DuckDuckGo, as many other parts of the system are also 87 | thinking that en_US is the default. 88 | 89 | =cut 90 | 91 | has default_locale => ( 92 | is => 'ro', 93 | builder => 1, 94 | lazy => 1, 95 | ); 96 | 97 | sub _build_default_locale { 'en_US' } # DON'T CHANGE 98 | 99 | =attr fullpath 100 | 101 | Migrated fullpath file references for all dirs of the site 102 | 103 | =cut 104 | 105 | has fullpath_files => ( 106 | is => 'ro', 107 | lazy => 1, 108 | builder => 1, 109 | ); 110 | 111 | sub _build_fullpath_files { 112 | my ( $self ) = @_; 113 | my %fullpath_files; 114 | for my $dir (values %{$self->dirs}) { 115 | for my $key (keys %{$dir->fullpath_files}) { 116 | $fullpath_files{$key} = $dir->fullpath_files->{$key}; 117 | } 118 | } 119 | return \%fullpath_files; 120 | } 121 | 122 | =attr save_data 123 | 124 | This data is used in the end of the publishing process to generate the data 125 | file. It will be filled up on the process of executing all files of the site. 126 | 127 | =cut 128 | 129 | has save_data => ( 130 | is => 'rw', 131 | lazy => 1, 132 | default => sub {{}}, 133 | ); 134 | 135 | sub load_locale_package { 136 | my ( $self ) = @_; 137 | load_class($self->locale_package) unless (is_class_loaded($self->locale_package)); 138 | } 139 | 140 | has locale_metadata => ( is => 'lazy' ); 141 | sub _build_locale_metadata { 142 | my ( $self ) = @_; 143 | $self->load_locale_package; 144 | $self->locale_package->locales; 145 | } 146 | 147 | sub locales { 148 | my ( $self ) = @_; 149 | return (keys %{$self->locale_metadata}); 150 | } 151 | 152 | =attr template_engine 153 | 154 | This function holds the L engine for the specific site. 155 | 156 | =cut 157 | 158 | has template_engine => ( 159 | is => 'ro', 160 | lazy => 1, 161 | builder => 1, 162 | ); 163 | 164 | =attr quiet 165 | 166 | Don't print Text::XSlate warnings 167 | 168 | =cut 169 | 170 | has quiet => ( 171 | is => 'ro', 172 | default => sub { 0 }, 173 | ); 174 | 175 | sub _build_template_engine { 176 | my ( $self ) = @_; 177 | my $site_template_root = dir(dist_dir('DDG-Publisher'),'site',$self->key)->stringify; 178 | my $core_template_root = dir(dist_dir('DDG-Publisher'),'core')->stringify; 179 | # 180 | # This hash contains the translation functions, wrapped with the 181 | # functionality required to make it work proper with utf8 in the context 182 | # of Text::Xslate. 183 | # 184 | my %xslate_locale_functions; 185 | for my $key (keys %{ Locale::Simple->coderef_hash }) { 186 | $xslate_locale_functions{$key} = sub { 187 | my $translation = Locale::Simple->coderef_hash->{$key}->(@_); 188 | return mark_raw($translation); 189 | }; 190 | } 191 | my %args = ( 192 | # 193 | # Include share/site/$key and share/core as template directories 194 | # 195 | path => [@{$self->publisher->extra_template_dirs},$site_template_root,$core_template_root], 196 | function => { 197 | # 198 | # js() function to escape js 199 | # 200 | js => sub { return mark_raw(javascript_value_escape(join("",@_))) }, 201 | # 202 | # r() function to mark some output as "clean", which means that 203 | # it doesnt get HTML encoded by the Xslate generation system. 204 | # 205 | r => sub { return mark_raw(join("",@_)) }, 206 | %xslate_locale_functions, 207 | find_template => sub { 208 | my ($filename) = @_; 209 | return $filename if eval { $self->template_engine->find_file($filename); 1 }; 210 | $filename .= $self->template_engine->{suffix}; 211 | return $filename if eval { $self->template_engine->find_file($filename); 1 }; 212 | return 0; 213 | }, 214 | substr => sub { 215 | my($str, $offset, $length) = @_; 216 | return undef unless defined $str; 217 | $offset = 0 unless defined $offset; 218 | $length = length($str) unless defined $length; 219 | return CORE::substr($str, $offset, $length); 220 | }, 221 | lowercase => sub { 222 | return defined($_[0]) ? CORE::lc($_[0]) : undef; 223 | }, 224 | }, 225 | ); 226 | $args{warn_handler} = sub {} if $self->publisher->quiet; 227 | return Text::Xslate->new(%args); 228 | } 229 | 230 | 1; 231 | -------------------------------------------------------------------------------- /share/site/duckduckgo/press.tx: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | 5 |

DuckDuckGo Press Center

6 |

We are an Internet privacy company that empowers you to seamlessly take control of your personal information online, without any tradeoffs.

7 | jump to press materials 8 |
9 | 10 |
11 | 12 |
13 |
14 |

With our roots as the search engine that doesn’t track you, we’ve expanded what we do to protect you 15 | no matter where you go on the Internet.

16 |
17 | 18 |

Fast Facts

19 | 45 |
46 |
47 | 48 | 49 |
50 |
51 |

Our Mission

52 |

Too many people believe that you simply can't expect privacy on the Internet. We disagree and have made it our mission to set a new standard of trust online.

53 |
54 |
55 |

from our blog

56 | 57 | 58 |
59 |
60 |
61 |
62 | 63 | 64 | 69 | 70 | 71 | 72 |
73 |
74 |

Press Materials

75 |

Download brand materials, images, or contact us.

76 |
77 |
78 |
79 | 80 |

Brand & Logo

81 |

Download the latest logos, color palettes, and brand-related assets.

82 | download 83 |
84 |
85 | 86 |

Photos & More

87 |

Check out photos and other information about our global team.

88 | download 89 |
90 |
91 | 92 |

Contact Us

93 |

Reach out for press inquiries, including interview requests.

94 | press@duckduckgo.com 95 |
96 | For all non-press inquiries, please use open@duckduckgo.com 97 |
98 |
99 |
100 |
101 |
102 | 103 | 104 |
105 |
106 |
107 |
108 |

You deserve privacy.

109 |

The Internet shouldn't feel so creepy, and getting the privacy you want online should be as simple as closing the blinds.

110 |
111 | 112 |
113 |
114 |
115 | -------------------------------------------------------------------------------- /share/site/duckduckgo/search_box.tx: -------------------------------------------------------------------------------- 1 | 14 | 15 | 16 |
<: l('Search Box') :>
17 | 18 | <: include "untranslated.tx" :> 19 | 20 |
21 | <: l('Add a %s search box to your site!','DuckDuckGo') :> 22 | <: l('Feel free to adjust the settings below. Then, just copy and paste the code into your website.') :> 23 | 24 |
25 | Because of the way we generate our search results, we do not have the syndication rights to allow you to host our results on your site (e.g. in a frame). When your users click on the results they will be instead taken to our site. Please see our partnerships page for more info on guidelines and getting in touch with us. 26 | 27 |
28 | 29 |
 30 | <iframe src="https://duckduckgo.com/search.html" style="overflow:hidden;margin:0;padding:0;width:550px;height:60px;" frameborder="0"></iframe>
 31 | 
32 | 75 | 76 |
    77 |
  • Width: px (The example above uses 408 pixels) 78 |
    79 |
  • Duck logo: 80 | 81 | Off 82 |   On 83 | 84 | 85 |
    86 |
  • Background Color: # ex: #000000 (Color Cheat Sheet here) 87 | 88 | 92 | 93 |
    94 |
  • Site search: ex: yourwebsite.com (For multiple sites, separate with commas: yourwebsite.com,anotherwebsite.com) 95 |
    96 |
  • Prefill: ex: Search DuckDuckGo 97 |
    98 |
  • Autofocus: 99 | Off 100 |   On (If On, the cursor will automatically be in the search box when the page loads) 101 |
    102 |
103 | 104 | 105 |
106 | You can use our URL params and use DuckDuckGo settings to further customize the results pages. However, please see the guidelines at the top of that page before doing so. 107 | 108 |
109 | You can also make and style your own like the search box at the bottom of the Daring Fireball blog. There is also a great blog post (archived) on how to do this. 110 | 111 | 112 |
113 | -------------------------------------------------------------------------------- /lib/DDG/Publisher/File.pm: -------------------------------------------------------------------------------- 1 | package DDG::Publisher::File; 2 | # ABSTRACT: A file inside the publisher 3 | 4 | use MooX; 5 | use Locale::Simple; 6 | use File::ShareDir ':ALL'; 7 | 8 | sub fullpath { 9 | my ( $self ) = @_; 10 | my $fullpath = join('/',$self->dir->web_path,$self->file); 11 | $fullpath =~ s!/+!/!g; 12 | return $fullpath; 13 | } 14 | 15 | =attr dir 16 | 17 | L object of this file 18 | 19 | =cut 20 | 21 | has dir => ( 22 | is => 'ro', 23 | required => 1, 24 | ); 25 | 26 | =attr static 27 | 28 | This is a static file, so its not generated for every language, only one file. 29 | 30 | =cut 31 | 32 | has static => ( 33 | is => 'ro', 34 | lazy => 1, 35 | default => sub { 0 }, 36 | ); 37 | 38 | =attr file 39 | 40 | Filename inside the directory of the site. 41 | 42 | =cut 43 | 44 | has file => ( 45 | is => 'ro', 46 | required => 1, 47 | lazy => 1, 48 | builder => 1, 49 | ); 50 | 51 | sub _build_file { 52 | my ( $self ) = @_; 53 | return $self->static 54 | ? $self->filebase.'.html' 55 | : $self->filebase.'/'.$self->locale.'.html' 56 | } 57 | 58 | =attr file 59 | 60 | Base path inside the site directory, must be given on construction. 61 | 62 | =cut 63 | 64 | has filebase => ( 65 | is => 'ro', 66 | required => 1, 67 | ); 68 | 69 | =attr locale 70 | 71 | Locale used for this specific file. 72 | 73 | =cut 74 | 75 | has locale => ( 76 | is => 'ro', 77 | required => 1, 78 | ); 79 | 80 | =attr code 81 | 82 | Additional code that needs to be executed for getting the variables for the 83 | template of this file. 84 | 85 | =cut 86 | 87 | has code => ( 88 | is => 'ro', 89 | required => 1, 90 | ); 91 | 92 | sub url { 93 | my ( $self ) = @_; 94 | return $self->dir->path.$self->file if $self->static; 95 | return $self->dir->path if $self->filebase eq 'index'; 96 | return $self->dir->path.$self->filebase; 97 | } 98 | 99 | =attr file 100 | 101 | Template name used, normally by default this is not used, instead B 102 | template is loaded by default, and this one is using the template variable. If 103 | there is a variable B set inside the resulting variables for this 104 | file, then this template name is used instead of B 105 | 106 | =cut 107 | 108 | has template => ( 109 | is => 'ro', 110 | lazy => 1, 111 | builder => 1, 112 | ); 113 | 114 | sub _build_template { 115 | my ( $self ) = @_; 116 | my $template = $self->dir->template_path.'/'.$self->filebase; 117 | $template =~ s!/+!/!g; 118 | $template .= '.tx'; 119 | return $template; 120 | } 121 | 122 | =attr content 123 | 124 | The resulting (uncompressed) content of the file. Fetching this will 125 | automatically fire up the template engine to generate the content. 126 | 127 | =cut 128 | 129 | has content => ( 130 | is => 'ro', 131 | lazy => 1, 132 | builder => 1, 133 | ); 134 | sub uncached_content { shift->_build_content } 135 | 136 | has locale_js_version => ( is => 'lazy' ); 137 | sub _build_locale_js_version { 138 | my ( $self ) = @_; 139 | $self->dir->site->locale_metadata->{ $self->locale }->{js_version} || 999; 140 | } 141 | 142 | sub _build_content { 143 | my ( $self ) = @_; 144 | 145 | # 146 | # setting locale for the localilzation (see L) 147 | # 148 | my $dist_dir = $self->dir->site->locale_dist 149 | ? dist_dir($self->dir->site->locale_dist) 150 | : '/usr/local/ddg.cache/locale/'; 151 | l_dir($dist_dir); 152 | ltd($self->dir->site->locale_domain); 153 | l_lang($self->locale); 154 | 155 | # 156 | # Activating the dryrun if requested. 157 | # 158 | l_dry($self->dir->site->publisher->dryrun) if $self->dir->site->publisher->has_dryrun; 159 | 160 | # 161 | # Variables for the template 162 | # 163 | # f = reference to the file itself 164 | # d = reference to the directory of the file 165 | # s = reference to the site of directory of the file 166 | # 167 | # locale_package_version = Version number of the locale package 168 | # locales = the hash of the locales for this token domain 169 | # maintemplate = name of the template (so that base.tx can use it) 170 | # url = the final URL for this specific page 171 | # 172 | 173 | my %vars = ( 174 | f => $self, 175 | d => $self->dir, 176 | s => $self->dir->site, 177 | locale_package_version => $self->dir->site->locale_package->version, 178 | locales => $self->dir->site->locale_package->locales, 179 | maintemplate => $self->template, 180 | url => $self->url, 181 | ); 182 | 183 | my $site_code = $self->dir->site->can('code'); 184 | 185 | my $dir_code = $self->dir->can('code'); 186 | 187 | # 188 | # Attach ENV variables, doing at here, so that they can be overriden 189 | # 190 | %vars = ( %vars, 'ENV', \%ENV ); 191 | # 192 | # Execute code from L to get more variables 193 | # 194 | %vars = ( %vars, $site_code->($self,\%vars) ) if $site_code; 195 | # 196 | # Execute code from L to get more variables 197 | # 198 | %vars = ( %vars, $dir_code->($self,\%vars) ) if $dir_code; 199 | # 200 | # Execute code from L to get more variables 201 | # 202 | %vars = ( %vars, $self->code->($self,\%vars) ); 203 | 204 | # explicit getting out no_base for template decision later 205 | my $no_base = defined $vars{no_base} && $vars{no_base}; 206 | 207 | # 208 | # Gathering the save data for the data files generation 209 | # 210 | $self->dir->site->save_data->{locales} = $self->dir->site->locale_package->locales 211 | unless defined $self->dir->site->save_data->{locales}; 212 | $self->dir->site->save_data->{$self->dir->path} = {} 213 | unless defined $self->dir->site->save_data->{$self->dir->path}; 214 | $self->dir->site->save_data->{$self->dir->path}->{$self->filebase} = { static => $self->static } 215 | unless defined $self->dir->site->save_data->{$self->dir->path}->{$self->filebase}; 216 | $self->dir->site->save_data->{$self->dir->path}->{$self->filebase}->{$self->file} = { 217 | locale => $self->locale, 218 | url => $self->url, 219 | file => $self->file, 220 | dir => $self->dir->path, 221 | template => $self->template, 222 | no_base => $no_base, 223 | }; 224 | 225 | # execute template, return rendered content. 226 | return $self->dir->site->template_engine->render($no_base ? $self->template : 'base.tx',\%vars); 227 | } 228 | 229 | 1; 230 | -------------------------------------------------------------------------------- /share/site/donttrackus/index.tx: -------------------------------------------------------------------------------- 1 | 2 |

<: l("You know all those ads following you around the Internet?") :>

3 | 4 |
5 |
<: l('Fig. %d',1) :> 6 | <: lp('alt','hay there fish') :> 7 |
8 |
9 | 10 |

<: l("They're from online tracking.") :>

11 | 12 |
13 |
<: l('Fig. %d',2) :> 14 | <: lp('alt'," /> 15 |
16 |
17 | 18 |

<: l("You're also getting charged different prices%sbased on profiles corporations build about you.", r('

19 | 20 |
21 |
', l('Fig. %d',3), ' 22 | ', lp('alt','screenshot from a WSJ article'), ' 23 |
24 |
25 | 26 |

')) :>

27 | 28 |
29 |
<: l('Fig. %d',4) :> 30 | <: lp('alt','screenshot of a Google ads profile') :> 31 |
32 |
33 | 34 |

<: l("No one knows more about you than Google.") :> 35 |

36 | 37 |
38 |
<: l('Fig. %d',5) :> 39 | <: lp('alt'," /> 40 |
41 |
42 | 43 |

<: l("You share your problems with your search engine,%sand Google saves all of them with your profile,%swhich advertisers use to target ads at you everywhere,%ssince Google's ads are on millions of Web sites.", r('

44 | 45 |
46 |
', l('Fig. %d',6), ' 47 | ', lp('alt','I think this is what all of those lumps mean'), ' 48 |
49 |
50 | 51 |

'), r('

52 | 53 |
54 |
', l('Fig. %d',7), ' 55 | ', lp('alt','just doing research, I swear'), ' 56 |
57 |
58 | 59 |

'), r('

60 | 61 |
62 |
', l('Fig. %d',8), ' 63 | ', lp('alt','the pants that stalked me on the web'), ' 64 |
65 |
66 | 67 |

')) :>

68 | 69 |
70 |
<: l('Fig. %d',9) :> 71 | 72 |
73 |
74 | 75 |

<: l("But that's not all.") :>

76 | 77 |
78 |
<: l('Fig. %d',10) :> 79 | <: lp('alt'," /> 80 |
81 |
82 | 83 |

<: l("Your saved searches can be legally requested,%sand then come back to haunt you.", r('

84 | 85 |
86 |
', l('Fig. %d',11), ' 87 | ', lp('alt','number of legal requests made to Google for user history - a chart that just keeps growing'), ' 88 |
89 |
90 | 91 |

')) :>

92 | 93 |
94 |
<: l('Fig. %d',12) :> 95 | 96 |
97 |
98 | 99 |

<: l("Your browser's \"private\" mode %swon't help you.%s",'','') :>

100 | 101 |
102 |
<: l('Fig. %d',13) :> 103 | <: lp('alt','throwing a bucket of water on a towering inferno') :> 104 |
105 |
106 | 107 |

<: l("On the other hand...%sSearching on DuckDuckGo is completely anonymous.", '

108 |

') :>

109 | 110 |
111 |
<: l('Fig. %d',14) :> 112 | 113 |
114 |
115 | 116 |

<: l("We don't store any personal information at all. %s That's our privacy policy in a nutshell.",'
') :>

117 | 118 |
119 |
<: l('Fig. %d',15) :> 120 | <: lp('alt','our privacy policy in a nutshell... get it?') :> 121 |
122 |
123 | 124 |

<: l("So don't get tracked when searching. %sUse DuckDuckGo!%s",'','') :>

125 | 126 |

<: l("Privacy is just one of the %smany reasons%s why it's awesome!",'','') :>

127 | -------------------------------------------------------------------------------- /share/site/duckduckhack/index_content.tx: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | <: for $hero_slides -> $h { :>
5 |

6 | <: l($h.text, "","") :> 7 |

8 |
<: } :> 9 |
10 | <: l("Get Started") :> 11 |
12 |
13 |
14 | <: for $hero_slides -> $h { :> 15 |
16 | <: l("Featured IA:") :> <: $h.tab :><: l("Contributor:") :> <: $h.user:> 17 | <: $h.tab :> Instant Answer 18 |
19 | <: } :> 20 | 23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | 31 |

Get Started

32 |

33 | The DuckDuckHack community is focused on improving search 34 |
35 | results for the top 15 programming languages. 36 |
37 | Our goal is to have a high quality, relevant Instant Answer for every search. 38 |

39 | 42 | 43 |
44 |
45 | 46 |

Discuss Your Ideas

47 |

48 | Join the discussion on the DuckDuckHack forum 49 |

50 | 53 | 54 | 57 | 58 |
59 |
60 | 61 |

Become a Leader

62 |

63 | If you are an experienced DuckDuckHack contributor, 64 |
65 | or are an expert in one of the languages we're working on, see: 66 |

67 | 70 |
71 |
72 |
73 |
74 |
75 |
76 |

<: l("What others have said about DuckDuckHack...") :>

77 |

<: l("Whatever your reason for contributing, our community is here to make it a positive experience.") :>

78 |
79 |
80 |
It was my first time contributing to an open source project and I haven't been able to stop since. Keep being awesome, and thanks for inspiring me :) prezjordan on HackerNews
81 |
82 |
Contributing to an open-source project like DuckDuckGo is a fun and fulfilling experience. Youri Ackx
83 |
84 |
I had my first ever pull request merged by @duckduckhack. Yay! I helped make the internet a better place! @duckduckgo @duckco Eric Christensen @ecounysis
85 |
86 |
I think I just found an #opensource community that I want to become a part of http://duckduckhack.com/ Nick Kuchinski @NickUI
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |

<: l("Staff Pick Instant Answers") :>

96 |
97 |
<: l("Useful") :>
98 | <: for $foot_useful -> $item { :> 99 | <: include "ddh-feature.tx" {item=>$item} :> 100 | <: } :> 101 |
102 |
103 |
<: l("Just for Fun") :>
104 | <: for $foot_fun -> $item { :> 105 | <: include "ddh-feature.tx" {item=>$item} :> 106 | <: } :> 107 |
108 |
109 |
110 |

<: l("Top Active Contributors") :>

111 |
<: l("Thank you to") :>
112 | <: for $foot_users -> $item { :> 113 | <: include "ddh-feature.tx" {item=>$item} :> 114 | <: } :> 115 |
116 |
117 |
118 |
119 | -------------------------------------------------------------------------------- /share/site/duckduckgo/about.tx: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | 5 |

Welcome to DuckDuckGo

6 |

We’re setting the new standard of trust online, empowering people to take control of their information.

7 |
8 | 9 |
10 | 11 |
12 |
13 |

You deserve privacy. Companies are making money off of your private information online without your consent.

At DuckDuckGo, we don’t think the Internet should feel so creepy and getting the privacy you deserve online should be as simple as closing the blinds.

14 |
15 |

Fast Facts

16 | 43 |
44 |
45 | 46 | 47 |
48 |
49 | 50 |

Our Mission

51 |

Too many people believe that you simply can't expect privacy on the Internet. We disagree and have made it our mission to set a new standard of trust online.

52 |
53 |
54 |
55 | 56 | 57 | 91 | 92 | 93 | 94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 | 105 | 106 |

Our Story

107 |

With our roots as the search engine that doesn’t track you, we’ve expanded what we do to protect you no matter where you go on the Internet. Check out our story.

108 |
109 | <:- for $ddg_events -> $event { -:> 110 |
111 | 112 |

<: $event.title :>

113 |

<: $event.snippet :>

114 |

<: $event.date :>

115 |
116 | <:- } -:> 117 |
118 |
119 |
120 |
121 | 122 | <:- for $ddg_events -> $event { -:> 123 | <:- if $event.year { -:> 124 | 125 |
<: $event.year :>
126 |
127 | <:- } else {-:> 128 | 129 | <:- } -:> 130 | <:- } -:> 131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 | 139 | 146 | 147 | 148 | 153 | 154 | 155 | 156 |
157 |
158 | 159 |

Our Global Team

160 |

DuckDuckGo is an international community of extraordinary individuals, coming together on a mission to set a new standard of trust online.

161 | we're hiring 162 |
163 |
164 | DuckDuckGo Team Map 165 |
166 |
167 | 168 | 169 | 184 | -------------------------------------------------------------------------------- /share/site/dontbubbleus/index.tx: -------------------------------------------------------------------------------- 1 |

<: l('When you search the internet') :>…

2 |
3 |
<: l('Fig. %d',1) :> 4 |

<: l("What I've done since graduation:") :>

5 | 6 | pie chart showing 100% 7 | 8 |
9 |
10 | 11 |

<: l('Different results are shown to different people.') :>

12 |

<: l('Try searching for') :>…

13 |
14 |
<: l('Fig. %d',2) :> 15 | 16 | 17 |
18 |
19 |
<: l('News Sites') :>
20 | <: l('google result showing bp news sites') :> 21 |
22 |

vs.

23 |
24 |
<: l('Investment Sites') :>
25 | <: l('google result showing bp investment sites') :> 26 |
27 |
28 |
29 | 30 |

<: l('Results are tailored to who you are') :>…

31 |
32 |
<: l('Fig. %d',3) :> 33 | <: l('different personality types') :> 34 |
35 |
36 | 37 |

<: l('based on your search history') :>

38 |
39 |
<: l('Fig. %d',4) :> 40 | <: l('Google search for bankruptcy') :> 41 |

(<: l('%s your Google search history.',r('') ~ l('See') ~ r('')) :>)

42 |
43 |
44 | 45 |

<: l('and your click history.') :>

46 |
47 |
<: l('Fig. %d',5) :> 48 | <: l('facebook like button') :> 49 |
50 |
51 | 52 |

<: l('Since you often click on things you agree with') :>…

53 |
54 |
<: l('Fig. %d',6) :> 55 | <: l('article from the onion') :> 56 |
57 |
58 | 59 |

<: l('you keep getting more and more') :>

60 |
61 |
<: l('Fig. %d',7) :> 62 | 63 | <: l('what this song needs ... is more cowbell') :> 64 | 65 |
66 |
67 | 68 |

<: l('of what you already agree with,') :>

69 |

<: l('Try searching for') :>…

70 |
71 |
<: l('Fig. %d',8) :> 72 | 73 | 74 |
75 |
76 |
<: l('%s gets %s','Ann','MSNBC') :>
77 | <: l('google result showing an msnbc news article for barack obama') :> 78 |
79 | 80 |
81 |
<: l('%s gets %s','Elaine','Fox News') :>
82 | <: l('google result showing a fox news article for barack obama') :> 83 |
84 |

(<: l('%s a Google search for "%s"',r('') ~ l('Try') ~ r(''),'barack obama') :>)

85 |
86 |
87 | 88 |

<: l('which means other stuff gets demoted.') :>

89 |

(<: l('effectively filtered') :>)

90 |
91 |
<: l('Fig. %d',9) :> 92 | 93 | 94 | <: l('Diminishing returns in deeper pages from Google search results') :> 95 | 96 |

<: l('How often do you %s venture past page 1?',r('') ~ l('really') ~ r('')) :>

97 |
98 |
99 | 100 |

<: l('This raises the question:') :>

101 |

<: l('What are %s missing?',r('') ~ l('you') ~ r('')) :>

102 |
103 |
<: l('Fig. %d',10) :> 104 | 105 | 106 | <: l('amazon review pointing out search distortions') :> 107 | 108 |

(<: l('%s a Google search for "%s"',r('') ~ l('Try') ~ r(''),'guns') :>)

109 |
110 |
111 | 112 |

<: l('In other words,') :>

113 |

<: l('You are living in a Filter Bubble') :>

114 |
115 |
<: l('Fig. %d',11) :> 116 | 117 | <: l('The Filter Bubble - What the internet is hiding from you') :> 118 | 119 |
120 |
121 | 122 |

<: l("that promotes things it %s you'll like,",r('') ~ l('thinks') ~ r('')) :>

123 |

<: l('Try searching for') :>…

124 |
125 |
<: l('Fig. %d',12) :> 126 | 127 | 128 |
129 |
130 |
<: l('%s gets %s','Scott',l('Egyptian Protests')) :>
131 | <: l('google result showing egypt protest information') :> 132 |
133 | 134 |
135 |
<: l('%s gets %s','Daniel',l('Travel Information')) :>
136 | <: l('google result showing egypt travel information ') :> 137 |
138 |

(<: l('%s a Google search for "%s"',r('') ~ l('Try') ~ r(''),'egypt') :>)

139 |
140 |
141 | 142 |

<: l('and demotes the rest,') :>

143 |

(<: l('thereby filtering it out'):>)

144 |
145 |
<: l('Fig. %d',13) :> 146 | 147 | 148 | <: l('Quote from the New York Times on search filtering') :> 149 | 150 |

(<: l('%s a Google search for "%s"',r('') ~ l('Try') ~ r(''),'Is Osama really dead?') :>)

151 |
152 |
153 | 154 |

<: l('which may limit your exposure to opposing information.') :>

155 |
156 |
<: l('Fig. %d',14) :> 157 | 158 | <: l('xkcd comic - someone is wrong on the internet!') :> 159 | 160 |
161 |
162 | 163 |

<: l("Unfortunately, it's not easy to pop your filter bubble") :>,

164 |
165 |
<: l('Fig. %d',15) :> 166 | <: l('poping a bubble full of internet logos') :> 167 |
168 |
169 | 170 |

<: l('because the technology is used so much') :>

171 |
172 |
<: l('Fig. %d',16) :> 173 | <: l('the matrix') :> 174 |
175 |
176 | 177 |

<: l('across the Internet and even %s.',r('') ~ l('when signed out') ~ r('')) :>

178 |
179 |
<: l('Fig. %d',17) :> 180 | <: l('popular internet sites represented by bubbles') :> 181 |
182 |
183 | 184 |

<: l('We offer you an alternative: a %s.',r('') ~ l('search engine') ~ r('')) :>

185 |
186 |
<: l('Fig. %d',18) :> 187 | <: l('%s Homepage','DuckDuckGo') :> 188 |
189 |
190 | 191 |

<: l('that breaks you out of your Filter Bubble by default,') :>

192 |
193 |
<: l('Fig. %d',19) :> 194 | <: l('%s and a bubble','Dax') :> 195 |
196 |
197 | 198 |

<: l('plus %s like %s.',r('') ~ l('other differences') ~ r(''),r('') ~ l('real privacy') ~ r('')) :>

199 | 200 | 228 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This license does not apply to any DuckDuckGo logos or marks that may be contained 2 | in this repo. DuckDuckGo logos and marks are licensed separately under the CCBY-NC-ND 4.0 3 | license (https://creativecommons.org/licenses/by-nc-nd/4.0/), and official up-to-date 4 | versions can be downloaded from https://duckduckgo.com/press. 5 | 6 | Apache License 7 | Version 2.0, January 2004 8 | http://www.apache.org/licenses/ 9 | 10 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 11 | 12 | 1. Definitions. 13 | 14 | "License" shall mean the terms and conditions for use, reproduction, 15 | and distribution as defined by Sections 1 through 9 of this document. 16 | 17 | "Licensor" shall mean the copyright owner or entity authorized by 18 | the copyright owner that is granting the License. 19 | 20 | "Legal Entity" shall mean the union of the acting entity and all 21 | other entities that control, are controlled by, or are under common 22 | control with that entity. For the purposes of this definition, 23 | "control" means (i) the power, direct or indirect, to cause the 24 | direction or management of such entity, whether by contract or 25 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 26 | outstanding shares, or (iii) beneficial ownership of such entity. 27 | 28 | "You" (or "Your") shall mean an individual or Legal Entity 29 | exercising permissions granted by this License. 30 | 31 | "Source" form shall mean the preferred form for making modifications, 32 | including but not limited to software source code, documentation 33 | source, and configuration files. 34 | 35 | "Object" form shall mean any form resulting from mechanical 36 | transformation or translation of a Source form, including but 37 | not limited to compiled object code, generated documentation, 38 | and conversions to other media types. 39 | 40 | "Work" shall mean the work of authorship, whether in Source or 41 | Object form, made available under the License, as indicated by a 42 | copyright notice that is included in or attached to the work 43 | (an example is provided in the Appendix below). 44 | 45 | "Derivative Works" shall mean any work, whether in Source or Object 46 | form, that is based on (or derived from) the Work and for which the 47 | editorial revisions, annotations, elaborations, or other modifications 48 | represent, as a whole, an original work of authorship. For the purposes 49 | of this License, Derivative Works shall not include works that remain 50 | separable from, or merely link (or bind by name) to the interfaces of, 51 | the Work and Derivative Works thereof. 52 | 53 | "Contribution" shall mean any work of authorship, including 54 | the original version of the Work and any modifications or additions 55 | to that Work or Derivative Works thereof, that is intentionally 56 | submitted to Licensor for inclusion in the Work by the copyright owner 57 | or by an individual or Legal Entity authorized to submit on behalf of 58 | the copyright owner. For the purposes of this definition, "submitted" 59 | means any form of electronic, verbal, or written communication sent 60 | to the Licensor or its representatives, including but not limited to 61 | communication on electronic mailing lists, source code control systems, 62 | and issue tracking systems that are managed by, or on behalf of, the 63 | Licensor for the purpose of discussing and improving the Work, but 64 | excluding communication that is conspicuously marked or otherwise 65 | designated in writing by the copyright owner as "Not a Contribution." 66 | 67 | "Contributor" shall mean Licensor and any individual or Legal Entity 68 | on behalf of whom a Contribution has been received by Licensor and 69 | subsequently incorporated within the Work. 70 | 71 | 2. Grant of Copyright License. Subject to the terms and conditions of 72 | this License, each Contributor hereby grants to You a perpetual, 73 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 74 | copyright license to reproduce, prepare Derivative Works of, 75 | publicly display, publicly perform, sublicense, and distribute the 76 | Work and such Derivative Works in Source or Object form. 77 | 78 | 3. Grant of Patent License. Subject to the terms and conditions of 79 | this License, each Contributor hereby grants to You a perpetual, 80 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 81 | (except as stated in this section) patent license to make, have made, 82 | use, offer to sell, sell, import, and otherwise transfer the Work, 83 | where such license applies only to those patent claims licensable 84 | by such Contributor that are necessarily infringed by their 85 | Contribution(s) alone or by combination of their Contribution(s) 86 | with the Work to which such Contribution(s) was submitted. If You 87 | institute patent litigation against any entity (including a 88 | cross-claim or counterclaim in a lawsuit) alleging that the Work 89 | or a Contribution incorporated within the Work constitutes direct 90 | or contributory patent infringement, then any patent licenses 91 | granted to You under this License for that Work shall terminate 92 | as of the date such litigation is filed. 93 | 94 | 4. Redistribution. You may reproduce and distribute copies of the 95 | Work or Derivative Works thereof in any medium, with or without 96 | modifications, and in Source or Object form, provided that You 97 | meet the following conditions: 98 | 99 | (a) You must give any other recipients of the Work or 100 | Derivative Works a copy of this License; and 101 | 102 | (b) You must cause any modified files to carry prominent notices 103 | stating that You changed the files; and 104 | 105 | (c) You must retain, in the Source form of any Derivative Works 106 | that You distribute, all copyright, patent, trademark, and 107 | attribution notices from the Source form of the Work, 108 | excluding those notices that do not pertain to any part of 109 | the Derivative Works; and 110 | 111 | (d) If the Work includes a "NOTICE" text file as part of its 112 | distribution, then any Derivative Works that You distribute must 113 | include a readable copy of the attribution notices contained 114 | within such NOTICE file, excluding those notices that do not 115 | pertain to any part of the Derivative Works, in at least one 116 | of the following places: within a NOTICE text file distributed 117 | as part of the Derivative Works; within the Source form or 118 | documentation, if provided along with the Derivative Works; or, 119 | within a display generated by the Derivative Works, if and 120 | wherever such third-party notices normally appear. The contents 121 | of the NOTICE file are for informational purposes only and 122 | do not modify the License. You may add Your own attribution 123 | notices within Derivative Works that You distribute, alongside 124 | or as an addendum to the NOTICE text from the Work, provided 125 | that such additional attribution notices cannot be construed 126 | as modifying the License. 127 | 128 | You may add Your own copyright statement to Your modifications and 129 | may provide additional or different license terms and conditions 130 | for use, reproduction, or distribution of Your modifications, or 131 | for any such Derivative Works as a whole, provided Your use, 132 | reproduction, and distribution of the Work otherwise complies with 133 | the conditions stated in this License. 134 | 135 | 5. Submission of Contributions. Unless You explicitly state otherwise, 136 | any Contribution intentionally submitted for inclusion in the Work 137 | by You to the Licensor shall be under the terms and conditions of 138 | this License, without any additional terms or conditions. 139 | Notwithstanding the above, nothing herein shall supersede or modify 140 | the terms of any separate license agreement you may have executed 141 | with Licensor regarding such Contributions. 142 | 143 | 6. Trademarks. This License does not grant permission to use the trade 144 | names, trademarks, service marks, or product names of the Licensor, 145 | except as required for reasonable and customary use in describing the 146 | origin of the Work and reproducing the content of the NOTICE file. 147 | 148 | 7. Disclaimer of Warranty. Unless required by applicable law or 149 | agreed to in writing, Licensor provides the Work (and each 150 | Contributor provides its Contributions) on an "AS IS" BASIS, 151 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 152 | implied, including, without limitation, any warranties or conditions 153 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 154 | PARTICULAR PURPOSE. You are solely responsible for determining the 155 | appropriateness of using or redistributing the Work and assume any 156 | risks associated with Your exercise of permissions under this License. 157 | 158 | 8. Limitation of Liability. In no event and under no legal theory, 159 | whether in tort (including negligence), contract, or otherwise, 160 | unless required by applicable law (such as deliberate and grossly 161 | negligent acts) or agreed to in writing, shall any Contributor be 162 | liable to You for damages, including any direct, indirect, special, 163 | incidental, or consequential damages of any character arising as a 164 | result of this License or out of the use or inability to use the 165 | Work (including but not limited to damages for loss of goodwill, 166 | work stoppage, computer failure or malfunction, or any and all 167 | other commercial damages or losses), even if such Contributor 168 | has been advised of the possibility of such damages. 169 | 170 | 9. Accepting Warranty or Additional Liability. While redistributing 171 | the Work or Derivative Works thereof, You may choose to offer, 172 | and charge a fee for, acceptance of support, warranty, indemnity, 173 | or other liability obligations and/or rights consistent with this 174 | License. However, in accepting such obligations, You may act only 175 | on Your own behalf and on Your sole responsibility, not on behalf 176 | of any other Contributor, and only if You agree to indemnify, 177 | defend, and hold each Contributor harmless for any liability 178 | incurred by, or claims asserted against, such Contributor by reason 179 | of your accepting any such warranty or additional liability. 180 | 181 | END OF TERMS AND CONDITIONS 182 | 183 | APPENDIX: How to apply the Apache License to your work. 184 | 185 | To apply the Apache License to your work, attach the following 186 | boilerplate notice, with the fields enclosed by brackets "[]" 187 | replaced with your own identifying information. (Don't include 188 | the brackets!) The text should be enclosed in the appropriate 189 | comment syntax for the file format. We also recommend that a 190 | file or class name and description of purpose be included on the 191 | same "printed page" as the copyright notice for easier 192 | identification within third-party archives. 193 | 194 | Copyright [yyyy] [name of copyright owner] 195 | 196 | Licensed under the Apache License, Version 2.0 (the "License"); 197 | you may not use this file except in compliance with the License. 198 | You may obtain a copy of the License at 199 | 200 | http://www.apache.org/licenses/LICENSE-2.0 201 | 202 | Unless required by applicable law or agreed to in writing, software 203 | distributed under the License is distributed on an "AS IS" BASIS, 204 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 205 | See the License for the specific language governing permissions and 206 | limitations under the License. 207 | -------------------------------------------------------------------------------- /share/site/duckduckgo/tour.tx: -------------------------------------------------------------------------------- 1 |
2 |
3 |

<: l("Welcome to %sDuckDuckGo%s!","","") :>
<: l("Smarter Search, Less Clutter and Real Privacy.") :>

4 | Take a Tour 5 |
6 | search results and instant answer for 'Tycho' 7 |
8 |
9 |
10 |
11 |
12 |
13 |

<: l("Great Results") :>

14 |

<: l("Join the millions who are choosing a better search experience.") :>

15 |

DuckDuckGo has everything you expect a search engine to have, including images, news and places, all while respecting your privacy. Great results without tracking you. That's DuckDuckGo in a nutshell.

16 |
17 | 18 |
19 |
20 |
21 | 24 | image results for 'thailand beaches' 25 | places results for 'bars in new orleans' 26 | news results for 'lebron james cleveland' 27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |

<: l("Instant Answers") :>

37 |

Instant Answers for every situation. Music, weather and recipes to name a few.

38 |

Instant Answers help you find what you're looking for in fewer clicks. Everything from a stopwatch for your workout to finding movies with Chuck Norris can be found without leaving your search engine!

39 |
40 | 41 |
42 |
43 |
44 | 47 | music results on mobile for 'daft punk' 48 | weather results on mobile 49 | recipes results on mobile for 'sorbet' 50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |

<: l("Customization") :>

60 |

<: l("Fine tune your search experience just the way you like it.") :>

61 |

You can change nearly everything about DuckDuckGo, including the look and feel. For example, boost results for your region, try a different theme, or adjust the displayed language.

62 |
63 | 64 |
65 |
66 |
67 | 70 | region selector 71 | 'contrast' theme 72 | DuckDuckGo homepage in another language 73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |

<: l("!bangs") :>

83 |

<: l("A feature to help you search on thousands of other sites, directly.") :>

84 |

A search for !amazon shoes will take you right to a search for shoes on Amazon.com. Try !a shoes or !imdb rushmore. There are thousands of !bangs and you can even submit your own.

85 |
86 | 87 |
88 |
89 |
90 | 94 | bang autocomplete in our mobile app 95 | results from '!amazon shoes' on a mobile device 96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |

<: l("Time to Switch!") :>

106 |

<: l("It's never been easier to switch now that we're available in Safari & Firefox!") :>

107 |

No matter what your browser, just go to our homepage and click the button at the bottom to add DuckDuckGo. Get great results without being tracked.

108 |
109 | 110 |
111 |
112 |
113 | 116 | DuckDuckGo is available in Safari and Firefox! 117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |

<: l("...and did we mention we don't track you?"):>

125 |

<: l("If that's not convincing enough, have a look at what others are saying..."):>

126 | 127 |
128 |
129 |
I wonder how long it would take us to make duckduckgo.com our default search engine? Go duck, go! @stephenfry Stephen Fry @stephenfry
130 |
131 |
132 |
A search engine that doesn't collect personal data. How @duckduckgo keeps your information private while searching: https://cbsn.ws/1bv2pIG @CBSThisMorningCBS This Morning @CBSThisMorning
133 |
134 |
135 |
Person I'm working with: "How come your Google is better than my Google?" Because my Google is @duckduckgo.@ganeumannJerry Neumann @ganeumann
136 |
137 |
138 |
139 |
140 |
141 | 152 |
153 |
154 |
155 |

<: l("Or try one of these:") :>

156 |
157 |
158 |
<: l("Images") :>
159 | Tilt Shift images 160 | Thailand Beach images 161 |
<: l("Videos") :>
162 | GoPro videos 163 | Jimmy Fallon videos 164 |
165 |
166 |
<: l("Weather") :>
167 | Weather in Encinitas 168 | Weather in Paris 169 |
<: l("Recipes") :>
170 | Tilapia recipes 171 | Sorbet recipes 172 |
173 |
174 |
<: l("Places") :>
175 | Thai food in San Francisco 176 | Bars near me 177 | Katz's Deli New York 178 |
<: l("Meanings") :>
179 | Orange 180 |
181 |
182 |
<: l("SoundCloud") :>
183 | Daft Punk Soundcloud 184 |
<: l("Other Goodies") :>
185 | 8oz to grams 186 | Define superlative 187 | People in space 188 |
189 |
190 |
191 | 194 |
195 |
196 | -------------------------------------------------------------------------------- /share/site/duckduckgo/api.tx: -------------------------------------------------------------------------------- 1 | 15 | 16 |

<: l('Instant Answer API') :>

17 | 18 |
Summary: An API for some of our Instant Answers, not for full search results.
19 | 20 |
21 | 22 |
23 | Our Instant Answer API gives you free access to many of our instant answers like: 24 | topic summaries 25 | (API example), 26 | categories 27 | (API example), 28 | disambiguation 29 | (API example), 30 | and 31 | !bang redirects 32 | (API example). 33 | 34 |
35 | This API does not include all of our links, however. That is, it is not a full search results API or a way to get DuckDuckGo results into your applications beyond our instant answers. Because of the way we generate our search results, we unfortunately do not have the rights to fully syndicate our results, free or paid. For the same reason, we cannot allow framing our results without our branding. Please see our partnerships page for more info on guidelines and getting in touch with us. 36 | 37 |
38 | Our long-term goal is for all of our instant answers to be available through this open API. Many of these instant answers are open source via our DuckDuckHack platform. Using that platform, you can add your own APIs and data sources as well. 39 | 40 |

41 | Our instant answers come from a variety of sources, including Wikipedia, Wikia, CrunchBase, GitHub, WikiHow, The Free Dictionary – over 100 in total. 42 | 43 |

44 | This API serves over 10,000,000 queries a day for a variety of uses, e.g.: 45 | 46 |

    47 |
  • Defining people, places, things, words and concepts, e.g. for side-bars, onMouseover or onHighlight. 48 |
  • Providing direct links to other services (via !bang syntax). 49 |
  • Listing related topics. 50 |
  • Giving official sites when available. 51 |
52 | 53 |

54 | To consume it yourself, you can use one of the language libraries listed below or simply add '&format=json' (or xml if you prefer) onto any query URL in the api subdomain, e.g. 55 |
https://api.duckduckgo.com/?q=DuckDuckGo&format=json 56 | 57 |

58 | Here are the requirements for use: 59 |

    60 |
  • Attribution in each place you use our API for both us and any underlying source. For the source, you can link to the source's relevant detail page. For us, you can say Results from DuckDuckGo with our logo (and link to the specific result page). 61 |
  • Non-commercial use unless you get email approval from us (though we're generally fine with anything that isn't sketchy). 62 |
  • Use a descriptive t parameter, i.e. append &t=nameofapp to your requests. 63 |
64 | 65 | Our overall goal is to get more people using DuckDuckGo, so please keep that in mind as well. 66 | 67 |

68 | Here are the return fields: 69 |

70 |

 71 | Abstract: topic summary (can contain HTML, e.g. italics)
 72 | AbstractText: topic summary (with no HTML)
 73 | AbstractSource: name of Abstract source
 74 | AbstractURL: deep link to expanded topic page in AbstractSource
 75 | Image: link to image that goes with Abstract
 76 | Heading: name of topic that goes with Abstract
 77 | 
 78 | Answer: instant answer
 79 | AnswerType: type of Answer, e.g. calc, color, digest, info, ip, iploc, phone, pw, rand, regexp, unicode, upc, or zip (see the tour page for examples).
 80 | 
 81 | Definition: dictionary definition (may differ from Abstract)
 82 | DefinitionSource: name of Definition source
 83 | DefinitionURL: deep link to expanded definition page in DefinitionSource
 84 | 
 85 | RelatedTopics: array of internal links to related topics associated with Abstract
 86 |   Result: HTML link(s) to related topic(s)
 87 |   FirstURL: first URL in Result
 88 |   Icon: icon associated with related topic(s)
 89 |     URL: URL of icon
 90 |     Height: height of icon (px)
 91 |     Width: width of icon (px)
 92 |   Text: text from first URL
 93 | 
 94 | Results: array of external links associated with Abstract
 95 |   Result: HTML link(s) to external site(s)
 96 |   FirstURL: first URL in Result
 97 |   Icon: icon associated with FirstURL
 98 |     URL: URL of icon
 99 |     Height: height of icon (px)
100 |     Width: width of icon (px)
101 |   Text: text from FirstURL
102 | 
103 | Type: response category, i.e. A (article), D (disambiguation), C (category), N (name), E (exclusive), or nothing.
104 | 
105 | Redirect: !bang redirect URL
106 | 
107 | 108 |

109 | Here are all the parameters: 110 |

111 |

112 | q: query
113 | 
114 | 
115 | format: output format (json or xml)
116 | 
117 | If format=='json', you can also pass:
118 | 
119 | callback: function to callback (JSONP format)
120 | pretty: 1 to make JSON look pretty (like JSONView for Chrome/Firefox)
121 | 
122 | 
123 | no_redirect: 1 to skip HTTP redirects (for !bang commands).
124 | 
125 | 
126 | no_html: 1 to remove HTML from text, e.g. bold and italics.
127 | 
128 | 
129 | skip_disambig: 1 to skip disambiguation (D) Type.
130 | 
131 | 132 |

133 | Notes 134 |

    135 |
  • As this is an instant answer API, most deep queries (non topic names) will be blank. 136 |
    137 | {
    138 | Abstract: ""
    139 | AbstractText: ""
    140 | AbstractSource: ""
    141 | AbstractURL: ""
    142 | Image: ""
    143 | Heading: ""
    144 | Answer: ""
    145 | Redirect: ""
    146 | AnswerType: ""
    147 | Definition: ""
    148 | DefinitionSource: ""
    149 | DefinitionURL: ""
    150 | RelatedTopics: [ ]
    151 | Results: [ ]
    152 | Type: ""
    153 | }
    154 | 
    155 | 159 | 160 |

    161 |

  • Icons, i.e. the underlying images, may be greater than their specified Width/Height. You should explicitly set them to the specified measurements (if provided). 162 | 163 |

    164 |

  • For disambiguation pages (Type=='D'), RelatedTopics can be grouped into sections. In that case, RelatedTopics is an array of hashes. Each hash has a Name key and a Topics array matching the above RelatedTopics description. If you want to avoid this case altogether, use the disambiguation skip parameter (skip_disambig). 165 | 166 |

    167 |

  • For !bang commands, the redirect will happen at the HTTP level (since that is fastest), but it will also be returned in the content (for parsing). If you don't want the redirect to happen in the HTTP header, use the no_redirect flag. 168 | 169 |

    170 |

  • Queries can be case sensitive e.g. 171 | blackberry (API example) 172 | vs 173 | BlackBerry (API example). In the first case (lowercase blackberry) it returns a disambiguation page; in the latter case (MixedCase BlackBerry) it returns info primarily about the device (inferring what you meant from the case). 174 | 175 |

    176 |

  • This API can work over an encrypted (SSL/HTTPS) connection. 177 | 178 |
179 | 180 | 181 | 182 |

183 | FAQ 184 | 185 |

186 | Are there supporting library integrations? 187 |

188 | 189 |

208 | 209 | 210 |

211 | Why is x query blank? Where are all the Web links like on the main site? 212 | 213 |

214 | This is an Instant Answer API, and not a full results API. However, there are some Web links within it, e.g. official sites. Please see the second paragraph at the top for more info. 215 | 216 | 217 |

218 | Why is my query blank? I see an Instant Answer on the main site! 219 | 220 |

221 | 222 | Not all of our instant answers are available right now via this API for a variety of reasons, though it is our long term goal to make them so. However, if you would like to see something in particular please let us know, and perhaps we can prioritize making it happen. 223 | 224 | 225 | 226 |

227 | Can I use the DuckDuckGo name to help promote what I've developed with the API? 228 | 229 |

230 | 231 | Yes and no. We do not want to confuse users into thinking that your application was made by us. Please see our partnerships page for more info on guidelines and getting in touch with us. 232 | 233 | 234 | 235 |

236 | Is this API open source? 237 | 238 |

239 | 240 | No, though many of the instant answers it provides are open source via our DuckDuckHack platform, which is completely open source. For more information on DuckDuckGo open source, please see this help article. 241 | 242 | 243 | 244 |

245 | Are there technical limits on API use? 246 | 247 |

248 | 249 | We simply do not have the resources to support high queries per second (QPS) for a single machine. Generally, this isn't a problem because our API is designed to be used client-side by individual users after they take some specific action (like a search or right-click). We also get a lot of botnet attacks. As a result, there is automatic throttling for API requests that will probably not effect you if you use the API in a distributed fashion (i.e. on your application's front-end). For specific situations we also provide higher limits. If you feel you may be in such a situation, please reach out. For legal limits, please see above for attribution and other requirements. 250 | 251 | 252 | 253 |

254 | If you have more questions, please let us know. 255 | -------------------------------------------------------------------------------- /share/site/duckduckgo/privacy.tx: -------------------------------------------------------------------------------- 1 |

2 |
3 |
4 |
5 |

<: l("We don't collect or share personal information.") :>

6 |
<: l("That's our privacy policy in a nutshell.") :>
7 |
8 |
9 |
10 |
11 |
12 |
13 | 14 |

DuckDuckGo does not collect or share personal information. That is our privacy policy in a nutshell. The rest of this page tries to explain why you should care.

15 | 22 | 23 | 24 |
    25 |
  • Last updated on 04/11/12. Removed ", which gets sent to my personal email." in last paragraph as our feedback is now handled by multiple team members via desk.com.
  • 26 |
  • Before that, on 03/11/12. Removed dead link (Scroogle) and added a missing 'to'.
  • 27 |
  • Before that, on 11/16/10. This paragraph was added.
  • 28 |
  • Before that, on 9/25/10. This paragraph was added.
  • 29 |
  • Before that, on 9/16/10. This paragraph was added.
  • 30 |
31 | 32 | 33 | 34 |

Why You Should Care

35 |
36 |

Search Leakage   [top]

37 | 38 |

At other search engines, when you do a search and then click on a link, your search terms are sent to that site you clicked on (in the HTTP referrer header). We call this sharing of personal information "search leakage."

39 | 40 |

For example, when you search for something private, you are sharing that private search not only with your search engine, but also with all the sites that you clicked on (for that search).

41 | 42 |

In addition, when you visit any site, your computer automatically sends information about it to that site (including your User agent and IP address). This information can often be used to identify you directly.

43 | 44 |

So when you do that private search, not only can those other sites know your search terms, but they can also know that you searched it. It is this combination of available information about you that raises privacy concerns.

45 | 46 |

DuckDuckGo prevents search leakage by default. Instead, when you click on a link on our site, we route (redirect) that request in such a way so that it does not send your search terms to other sites. The other sites will still know that you visited them, but they will not know what search you entered beforehand.

47 | 48 |

At some other search engines (including us), you can also use an encrypted version (HTTPS), which as a byproduct doesn't usually send your search terms to sites. However, it is slower to connect to these versions and if you click on a site that also uses HTTPS then your search is sent. Nevertheless, the encrypted version does protect your search from being leaked onto the computers it travels on between you and us.

49 | 50 | 51 |

At DuckDuckGo, our encrypted version goes even further and automatically changes links from a number of major Web sites to point to the encrypted versions of those sites. It is modeled after (and uses code from) the HTTPS Everywhere FireFox add-on. These sites include Wikipedia, Facebook, Twitter, and Amazon to name a few.

52 | 53 |

Another way to prevent search leakage is by using something called a POST request, which has the effect of not showing your search in your browser, and, as a consequence, does not send it to other sites. You can turn on POST requests on our settings page, but it has its own issues. POST requests usually break browser back buttons, and they make it impossible for you to easily share your search by copying and pasting it out of your Web browser's address bar.

54 | 55 |

Finally, if you want to prevent sites from knowing you visited them at all, you can use a proxy like Tor. DuckDuckGo actually operates a Tor exit enclave, which means you can get end to end anonymous and encrypted searching using Tor & DDG together.

56 | 57 |

You can enter !proxy domain into DuckDuckGo as well, and we will route you through a proxy, e.g. !proxy breadpig.com. This feature is part of our !bang syntax. Unfortunately, proxies can also be slow, and free proxies (like the one we use) are funded by arguably excessive advertising.

58 | 59 |

Because of these drawbacks in HTTPS, POST and proxies we decided to take the redirect approach to combat search leakage. However, we leave the choice up to you. You can deviate from the default on our settings page by toggling the redirect or address bar settings. You can also use our encrypted version.

60 | 61 | 62 |

Search History   [top]

63 | 64 |

Other search engines save your search history. Usually your searches are saved along with the date and time of the search, some information about your computer (e.g. your IP address, User agent and often a unique identifier stored in a browser cookie), and if you are logged in, your account information (e.g. name and email address).

65 | 66 |

With only the timestamp and computer information, your searches can often be traced directly to you. With the additional account information, they are associated directly with you.

67 | 68 |

Also, note that with this information your searches can be tied together. This means someone can see everything you've been searching, not just one isolated search. You can usually find out a lot about a person from their search history.

69 | 70 |

It's sort of creepy that people at search engines can see all this info about you, but that is not the main concern. The main concern is when they either a) release it to the public or b) give it to law enforcement.

71 | 72 |

Why would they release it to the public? AOL famously released supposedly anonymous search terms for research purposes, except they didn't do a good job of making them completely anonymous, and they were ultimately sued over it. In fact, almost every attempt to anonymize data has similarly been later found out to be much less anonymous than initially thought.

73 | 74 |

The other way to release it to the public is by accident. Search engines could lose data, or get hacked, or accidentally expose data due to security holes or incompetence, all of which has happened with personal information on the Internet.

75 | 76 |

Why would search engines give your search history to law enforcement? Simply because law enforcement asked for it, usually as part of a legal investigation. If you read privacy policies and terms of service carefully you will notice that they say they can give your information on court order.

77 | 78 |

This makes sense because they may be legally obligated to do so. However, search engines are not legally obligated to collect personal information in the first place. They do it on their own volition.

79 | 80 |

The bottom line is if search engines have your information, it could get out, even if they have the best intentions. And this information (your search history) can be pretty personal.

81 | 82 |

For these reasons, DuckDuckGo takes the approach to not collect any personal information. The decisions of whether and how to comply with law enforcement requests, whether and how to anonymize data, and how to best protect your information from hackers are out of our hands. Your search history is safe with us because it cannot be tied to you in any way.

83 | 84 | 85 | 86 |

Information

87 |
88 |

Information Not Collected   [top]

89 | 90 |

When you search at DuckDuckGo, we don't know who you are and there is no way to tie your searches together.

91 | 92 |

When you access DuckDuckGo (or any Web site), your Web browser 93 | automatically sends information about your computer, e.g. 94 | your User agent and IP address.

95 | 96 |

Because this information could be used to link you to your 97 | searches, we do not log (store) it at all. This is a very unusual practice, but we feel it is an important step to protect your privacy.

98 | 99 |

It is unusual for a few reasons. First, most server software auto-stores this information, so you have to go out of your way not to store it. Second, most businesses want to keep as much information as possible because they don't know when it will be useful. Third, many search engines actively use this information, for example to show you more targeted advertising.

100 | 101 |

Another way that your searches are often tied together at other search engines are through browser cookies, which are pieces of information that sit on your computer and get sent to the search engine on each request. What search engines often do is store a unique identifier in your browser and then associate that identifier with your searches. At DuckDuckGo, no cookies are used by default.

102 | 103 |

In response to efforts by the EFF and others, the major search engines have begun "anonymizing" their search log data after periods of time. Sure, this is better than not doing so, but you should note that this does not make your search history anonymous in the same way that it is at DuckDuckGo.

104 | 105 |

What search engines generally do when they anonymize data is get rid of part of your IP address or turn it into something that doesn't look exactly like an IP address. And they do the same thing for uniquely identifying cookies.

106 | 107 |

However, in many cases, this so-called anonymous data can still tie your searches together, which can be used to reconstruct who you are and what you searched for. Additionally, search engines usually are silent on what they do with the User agent, which has been shown to also have enough information to often be personally identifiable, especially if isolated to a particular search session (day).

108 | 109 | 110 | 111 | 112 |

Information Collected   [top]

113 | 114 |

At DuckDuckGo, no cookies are used by default. If you have changed any settings, then cookies are used to store those changes. However, in that case, they are not stored in a personally identifiable way. For example, the large size setting is stored as 's=l'; no unique identifier is in there. Furthermore, if you prefer not to use cookies to store settings, you can use URL parameters instead.

115 | 116 | 117 |

Additionally, if you use our !bang syntax/dropdown, which bangs you use are stored in a cookie so that we can list your most frequently used ones on top of the !bang dropdown box. Just like the other settings, this information is not saved on our servers at all, but resides solely on your computer. There is also a setting to turn this off, which you can also set via a URL parameter. Particular searches are of course not stored. An example cookie might look like: php=2&yelp=19&java=4.

118 | 119 |

We also save searches, but again, not in a personally identifiable way, as we do not store IP addresses or unique User agent strings. We use aggregate, non-personal search data to improve things like misspellings.

120 | 121 | 122 |

Similarly, we may add an affiliate code to some eCommerce sites (e.g. Amazon & eBay) that results in small commissions being paid back to DuckDuckGo when you make purchases at those sites. We do not use any third parties to do the code insertion, and we do not work with any sites that share personally identifiable information (e.g. name, address, etc.) via their affiliate programs. This means that no information is shared from DuckDuckGo to the sites, and the only information that is collected from this process is product information, which is not tied to any particular user and which we do not save or store on our end. It is completely analogous to the search result case from the previous paragraph--we can see anonymous product info such that we cannot tie them to any particular person (or even tie multiple purchases together). This whole affiliate process is an attempt to keep advertising to a minimal level on DuckDuckGo.

123 | 124 |

Finally, if you give us feedback, it may be stored in our email. However, you can give anonymous feedback (by not entering your email or other personal info on the feedback form).

125 | 126 | 127 | 128 |

Information Shared   [top]

129 | 130 |

If you turn redirects off in the settings and you don't either turn POST on or use our encrypted site, then your search could leak to sites you click on. Yet as explained above, this does not happen by default.

131 | 132 |

Also, like anyone else, we will comply with court ordered legal requests. However, in our case, we don't expect any because there is nothing useful to give them since we don't collect any personal information.

133 | 134 | 135 | 136 | 137 |

Other

138 |
139 |

Other Search Engines   [top]

140 | 141 |

If you care about search privacy, you might also want to check out these other search engines that take it seriously by default.

142 | 145 | 146 |

Each does things a bit differently in terms of privacy and very differently in terms of results. And not all go as far as DuckDuckGo in some aspects. However, none store your personal information by default, which make them all pretty safe in our opinion.

147 | 148 | 149 |

Updates   [top]

150 | 151 |

If this policy is substantively updated, 152 | we will update the text of this page and provide notice to you 153 | at https://duckduckgo.com/about by 154 | writing '(Updated)' in red next to the link to this page (in the footer) for a period 155 | of at least 30 days. 156 | 157 | 158 |

Feedback   [top]

159 | 160 |

I 161 | (Gabriel 162 | Weinberg) am the founder of Duck Duck Go and personally wrote this 163 | privacy policy. If you have any questions or concerns, 164 | please submit 165 | feedback.

166 |
167 |
168 |
169 |
170 | -------------------------------------------------------------------------------- /share/site/duckduckgo/params.tx: -------------------------------------------------------------------------------- 1 | 15 | 16 | 17 |
<: l('URL Parameters') :>
18 | 19 |
20 | 21 | <: l('You can change %s via URL parameters by adding them after the search query, for example:',r('') ~ l('DuckDuckGo settings') ~ r('')) :> 22 | 23 |
24 |     https://duckduckgo.com/?q=search&kp=-1&kl=us-en 25 | 26 |
27 | These parameters are intended for individual use. They can also be used in conjunction with our site search to customize results pages more closely to your site. However, if using them for that purpose or any other beyond individual use (e.g. for apps/extensions), please do not remove our branding (ko, kr params etc.) or advertising (k1, k4 params etc.) as we have contracts in place that we would be violating if you did so. Please see our partnerships page for more info on guidelines and getting in touch with us. 28 | 29 |
30 | 31 | 32 | 33 | 34 | 35 | 38 | 111 | 112 | 113 | 114 | 117 | 122 | 123 | 124 | 125 | 128 | 132 | 133 | 134 | 135 | 138 | 142 | 143 | 144 | 145 | 148 | 152 | 153 | 154 | 155 | 158 | 162 | 163 | 164 | 167 | 175 | 176 | 177 | 178 | 179 | 182 | 186 | 187 | 188 | 189 | 192 | 196 | 197 | 198 | 199 | 200 | 201 | 204 | 208 | 209 | 210 | 211 | 214 | 221 | 222 | 223 | 224 | 227 | 231 | 232 | 233 | 234 | 237 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 254 | 271 | 272 | 273 | 274 | 277 | 290 | 291 | 292 | 293 | 296 | 312 | 313 | 314 | 315 | 318 | 325 | 326 | 327 | 328 | 331 | 339 | 340 | 341 | 342 | 345 | 353 | 354 | 355 | 356 | 357 | 358 | 361 | 372 | 373 | 374 | 375 | 376 | 379 | 389 | 390 | 391 | 392 | 395 | 403 | 404 | 405 | 406 | 409 | 416 | 417 | 418 | 419 | 422 | 439 | 440 | 441 | 442 | 443 | 446 | 452 | 453 | 454 | 455 | 458 | 475 | 476 | 477 | 478 | 479 | 480 | 483 | 492 | 493 | 494 | 495 | 498 | 504 | 505 | 506 | 509 | 516 | 517 | 518 | 521 | 528 | 529 | 530 | 533 | 539 | 540 | 541 | 542 | 545 | 555 | 556 | 557 | 558 |
<: l('Result Settings') :>
36 | <: l('Region:') :> 37 | 39 | kl = 40 |
    41 |
  • <: l('%s for %s','xa-ar','Arabia') :> 42 |
  • <: l('%s for %s','xa-en','Arabia (en)') :> 43 |
  • <: l('%s for %s','ar-es','Argentina') :> 44 |
  • <: l('%s for %s','au-en','Australia') :> 45 |
  • <: l('%s for %s','at-de','Austria') :> 46 |
  • <: l('%s for %s','be-fr','Belgium (fr)') :> 47 |
  • <: l('%s for %s','be-nl','Belgium (nl)') :> 48 |
  • <: l('%s for %s','br-pt','Brazil') :> 49 |
  • <: l('%s for %s','bg-bg','Bulgaria') :> 50 |
  • <: l('%s for %s','ca-en','Canada') :> 51 |
  • <: l('%s for %s','ca-fr','Canada (fr)') :> 52 |
  • <: l('%s for %s','ct-ca','Catalan') :> 53 |
  • <: l('%s for %s','cl-es','Chile') :> 54 |
  • <: l('%s for %s','cn-zh','China') :> 55 |
  • <: l('%s for %s','co-es','Colombia') :> 56 |
  • <: l('%s for %s','hr-hr','Croatia') :> 57 |
  • <: l('%s for %s','cz-cs','Czech Republic') :> 58 |
  • <: l('%s for %s','dk-da','Denmark') :> 59 |
  • <: l('%s for %s','ee-et','Estonia') :> 60 |
  • <: l('%s for %s','fi-fi','Finland') :> 61 |
  • <: l('%s for %s','fr-fr','France') :> 62 |
  • <: l('%s for %s','de-de','Germany') :> 63 |
  • <: l('%s for %s','gr-el','Greece') :> 64 |
  • <: l('%s for %s','hk-tzh','Hong Kong') :> 65 |
  • <: l('%s for %s','hu-hu','Hungary') :> 66 |
  • <: l('%s for %s','in-en','India') :> 67 |
  • <: l('%s for %s','id-id','Indonesia') :> 68 |
  • <: l('%s for %s','id-en','Indonesia (en)') :> 69 |
  • <: l('%s for %s','ie-en','Ireland') :> 70 |
  • <: l('%s for %s','il-he','Israel') :> 71 |
  • <: l('%s for %s','it-it','Italy') :> 72 |
  • <: l('%s for %s','jp-jp','Japan') :> 73 |
  • <: l('%s for %s','kr-kr','Korea') :> 74 |
  • <: l('%s for %s','lv-lv','Latvia') :> 75 |
  • <: l('%s for %s','lt-lt','Lithuania') :> 76 |
  • <: l('%s for %s','xl-es','Latin America') :> 77 |
  • <: l('%s for %s','my-ms','Malaysia') :> 78 |
  • <: l('%s for %s','my-en','Malaysia (en)') :> 79 |
  • <: l('%s for %s','mx-es','Mexico') :> 80 |
  • <: l('%s for %s','nl-nl','Netherlands') :> 81 |
  • <: l('%s for %s','nz-en','New Zealand') :> 82 |
  • <: l('%s for %s','no-no','Norway') :> 83 |
  • <: l('%s for %s','pe-es','Peru') :> 84 |
  • <: l('%s for %s','ph-en','Philippines') :> 85 |
  • <: l('%s for %s','ph-tl','Philippines (tl)') :> 86 |
  • <: l('%s for %s','pl-pl','Poland') :> 87 |
  • <: l('%s for %s','pt-pt','Portugal') :> 88 |
  • <: l('%s for %s','ro-ro','Romania') :> 89 |
  • <: l('%s for %s','ru-ru','Russia') :> 90 |
  • <: l('%s for %s','sg-en','Singapore') :> 91 |
  • <: l('%s for %s','sk-sk','Slovak Republic') :> 92 |
  • <: l('%s for %s','sl-sl','Slovenia') :> 93 |
  • <: l('%s for %s','za-en','South Africa') :> 94 |
  • <: l('%s for %s','es-es','Spain') :> 95 |
  • <: l('%s for %s','se-sv','Sweden') :> 96 |
  • <: l('%s for %s','ch-de','Switzerland (de)') :> 97 |
  • <: l('%s for %s','ch-fr','Switzerland (fr)') :> 98 |
  • <: l('%s for %s','ch-it','Switzerland (it)') :> 99 |
  • <: l('%s for %s','tw-tzh','Taiwan') :> 100 |
  • <: l('%s for %s','th-th','Thailand') :> 101 |
  • <: l('%s for %s','tr-tr','Turkey') :> 102 |
  • <: l('%s for %s','ua-uk','Ukraine') :> 103 |
  • <: l('%s for %s','uk-en','United Kingdom') :> 104 |
  • <: l('%s for %s','us-en','United States') :> 105 |
  • <: l('%s for %s','ue-es','United States (es)') :> 106 |
  • <: l('%s for %s','ve-es','Venezuela') :> 107 |
  • <: l('%s for %s','vn-vi','Vietnam') :> 108 |
  • <: l('%s for %s','wt-wt','No region') :> 109 |
110 |
115 | <: l('Safe Search:') :> 116 | 118 | <: l('%s for %s','kp = 1',lp('setting','On')) :>; 119 | <: l('%s for %s','kp = -1',lp('setting','Moderate')) :>; 120 | <: l('%s for %s','kp = -2',lp('setting','Off')) :>. 121 |
126 | <: l('Open Instant Answers:') :> 127 | 129 | <: l('%s for %s','kz = 1',lp('setting','On')) :>; 130 | <: l('%s for %s','-1',lp('setting','Off')) :>. 131 |
136 | <: l('Auto-load Images:') :> 137 | 139 | <: l('%s for %s','kc = 1',lp('setting','On')) :>; 140 | <: l('%s for %s','-1',lp('setting','Off')) :>. 141 |
146 | <: l('Auto-load Results:') :> 147 | 149 | <: l('%s for %s','kav = 1',lp('setting','On')) :>; 150 | <: l('%s for %s','-1',lp('setting','Off')) :>. 151 |
156 | <: l('New Window:') :> 157 | 159 | <: l('%s for %s','kn = 1',lp('setting','On')) :>; 160 | <: l('%s for %s','-1',lp('setting','Off')) :>. 161 |
165 | <: l('Favicons:') :> 166 | 168 | kf = 169 |
    170 |
  • <: l('%s for %s','1','Just favicons') :> 171 |
  • <: l('%s for %s','w','Just WOT (trust) ratings') :> 172 |
  • <: l('%s for %s','fw','All WOT + favicons (both)') :> 173 |
  • <: l('%s for %s','-1','Off') :> 174 |
180 | <: l('Full URLs:') :> 181 | 183 | <: l('%s for %s','kaf = 1',lp('setting','On')) :>; 184 | <: l('%s for %s','-1',lp('setting','Off')) :>. 185 |
190 | <: l('Auto-suggest:') :> 191 | 193 | <: l('%s for %s','kac = 1',lp('setting','On')) :>; 194 | <: l('%s for %s','-1',lp('setting','Off')) :>. 195 |
<: l('Privacy Settings') :>
202 | <: l('Redirect:') :> 203 | 205 | <: l('%s for %s','kd = 1',lp('setting','On')) :>; 206 | <: l('%s for %s','-1',lp('setting','Off')) :>. 207 |
212 | <: l('HTTPS:') :> 213 | 215 | kh = 216 |
    217 |
  • <: l('%s for %s','1',lp('setting','On')) :> 218 |
  • <: l('%s for %s','-1',lp('setting','Off')) :> 219 |
220 |
225 | <: l('Address bar:') :> 226 | 228 | <: l('%s for %s','kg = g','GET') :>; 229 | <: l('%s for %s','p','POST') :>. 230 |
235 | <: l('Video Playback:') :> 236 | 238 | k5 = 239 |
    240 |
  • <: l('%s for %s','1',lp('setting','Always play on DuckDuckGo')) :> 241 |
  • <: l('%s for %s','2',lp('setting','Open on third-party site')) :> 242 |
  • <: l('%s for %s','-1',lp('setting','Prompt me')) :> 243 |
244 |
<: l('Color Settings') :>
252 | <: l('Header:') :> 253 | 255 | kj = 256 |
    257 |
  • <: l('%s for %s','r3',l('Muted red')) :> (<: lp('setting','default') :>) 258 |
  • <: l('%s for %s','d',l('Light green')) :> 259 |
  • <: l('%s for %s','g',l('Intense green')) :> 260 |
  • <: l('%s for %s','g2',l('Green')) :> 261 |
  • <: l('%s for %s','b',l('Light blue')) :> 262 |
  • <: l('%s for %s','b2',l('Blue')) :> 263 |
  • <: l('%s for %s','r',l('Intense red')) :> 264 |
  • <: l('%s for %s','r2',l('Red')) :> 265 |
  • <: l('%s for %s','p',l('Purple')) :> 266 |
  • <: l('%s for %s','o',l('Orange')) :> 267 |
  • <: l('%s for %s','w',l('White')) :> 268 |
  • <: l('or write out the color code you want, e.g. %s (%s is an encoded %s char).','%23395323','%23','#') :> 269 |
270 |
275 | <: l('URLs:') :> 276 | 278 | kx = 279 |
    280 |
  • <: l('%s for %s','r',l('Red')) :> (<: lp('setting','default') :>) 281 |
  • <: l('%s for %s','g',l('Green')) :> 282 |
  • <: l('%s for %s','l',l('Black')) :> 283 |
  • <: l('%s for %s','b',l('Blue')) :> 284 |
  • <: l('%s for %s','p',l('Purple')) :> 285 |
  • <: l('%s for %s','o',l('Orange')) :> 286 |
  • <: l('%s for %s','e',l('Grey')) :> 287 |
  • <: l('or write out the color code you want, e.g. %s (%s is an encoded %s char).','%23395323','%23','#') :> 288 |
289 |
294 | <: l('Background:') :> 295 | 297 | k7 = 298 |
    299 |
  • <: l('%s for %s','w',l('White')) :> (<: lp('setting','default') :>) 300 |
  • <: l('%s for %s','d',l('Light green')) :> 301 |
  • <: l('%s for %s','g',l('Intense green')) :> 302 |
  • <: l('%s for %s','g2',l('Green')) :> 303 |
  • <: l('%s for %s','b',l('Light blue')) :> 304 |
  • <: l('%s for %s','b2',l('Blue')) :> 305 |
  • <: l('%s for %s','r',l('Intense red')) :> 306 |
  • <: l('%s for %s','r2',l('Red')) :> 307 |
  • <: l('%s for %s','p',l('Purple')) :> 308 |
  • <: l('%s for %s','o',l('Orange')) :> 309 |
  • <: l('or write out the color code you want, e.g. %s (%s is an encoded %s char).','%23395323','%23','#') :> 310 |
311 |
316 | <: l('Text:') :> 317 | 319 | k8 = 320 |
    321 |
  • <: l('%s for %s','g',l('Grey')) :> (<: lp('setting','default') :>) 322 |
  • <: l('or write out the color code you want, e.g. %s (%s is an encoded %s char).','%23395323','%23','#') :> 323 |
324 |
329 | <: l('Links:') :> 330 | 332 | k9 = 333 |
    334 |
  • <: l('%s for %s','g',l('Dark Grey')) :> (<: lp('setting','default') :>) 335 |
  • <: l('%s for %s','b',l('Blue')) :> 336 |
  • <: l('or write out the color code you want, e.g. %s (%s is an encoded %s char).','%23395323','%23','#') :> 337 |
338 |
343 | <: l('Visited links:') :> 344 | 346 | kaa = 347 |
    348 |
  • <: l('%s for %s','p',lp('setting','Grey with checkmark')) :> (<: lp('setting','default') :>) 349 |
  • <: l('%s for %s','p',l('Purple')) :> 350 |
  • <: l('or write out the color code you want, e.g. %s (%s is an encoded %s char).','%23395323','%23','#') :> 351 |
352 |
<: l('Look & Feel Settings') :>
359 | <: l('Theme:') :> 360 | 362 | kae = 363 |
    364 |
  • <: l('%s for %s','-1',lp('theme','Default')) :> (<: lp('setting','default') :>) 365 |
  • <: l('%s for %s','c',lp('theme','Contrast')) :> 366 |
  • <: l('%s for %s','r',lp('theme','Retro')) :> 367 |
  • <: l('%s for %s','d',lp('theme','Dark')) :> 368 |
  • <: l('%s for %s','t',lp('theme','Terminal')) :> 369 |
  • <: l('or write out the color code you want, e.g. %s (%s is an encoded %s char).','%23395323','%23','#') :> 370 |
371 |
377 | <: l('Size:') :> 378 | 380 | ks = 381 |
    382 |
  • <: l('%s for %s','n',lp('size','Large')) :> (<: lp('setting','default') :>) 383 |
  • <: l('%s for %s','l',lp('size','Larger')) :> 384 |
  • <: l('%s for %s','t',lp('size','Largest')) :> 385 |
  • <: l('%s for %s','m',lp('size','Medium')) :> 386 |
  • <: l('%s for %s','s',lp('size','Small')) :> 387 |
388 |
393 | <: l('Width:') :> 394 | 396 | kw = 397 |
    398 |
  • <: l('%s for %s','n',lp('width','Normal')) :> (<: lp('setting','default') :>) 399 |
  • <: l('%s for %s','w',lp('width','Wide')) :> 400 |
  • <: l('%s for %s','s',lp('width','Super wide')) :> 401 |
402 |
407 | <: l('Placement:') :> 408 | 410 | km = 411 |
    412 |
  • <: l('%s for %s','m',lp('placement','Middle')) :> (<: lp('setting','default') :>) 413 |
  • <: l('%s for %s','l',lp('placement','Left')) :> 414 |
415 |
420 | <: l('Link font:') :> 421 | 423 | ka = 424 |
    425 |
  • <: l('%s for %s','a','Arial') :> 426 |
  • <: l('%s for %s','c','Century Gothic') :> 427 |
  • <: l('%s for %s','g','Georgia') :> 428 |
  • <: l('%s for %s','h','Helvetica') :> 429 |
  • <: l('%s for %s','p','Proxima Nova') :> (<: lp('setting','default') :>) 430 |
  • <: l('%s for %s','n','Sans-serif') :> 431 |
  • <: l('%s for %s','e','Segoe UI') :> 432 |
  • <: l('%s for %s','s','Serif') :> 433 |
  • <: l('%s for %s','o','Tahoma') :> 434 |
  • <: l('%s for %s','t','Times') :> 435 |
  • <: l('%s for %s','b','Trebuchet MS') :> 436 |
  • <: l('%s for %s','v','Verdana') :> 437 |
  • <: l('or write out the font you want') :> 438 |
444 | <: l('Underline:') :> 445 | 447 | ku = 448 |
    449 |
  • <: l('%s for %s','1',lp('setting','On')) :> 450 |
  • <: l('%s for %s','-1',lp('setting','Off')) :> (<: lp('setting','default') :>) 451 |
456 | <: l('Text font:') :> 457 | 459 | kt = 460 |
    461 |
  • <: l('%s for %s','a','Arial') :> 462 |
  • <: l('%s for %s','c','Century Gothic') :> 463 |
  • <: l('%s for %s','g','Georgia') :> 464 |
  • <: l('%s for %s','h','Helvetica') :> 465 |
  • <: l('%s for %s','p','Proxima Nova') :> (<: lp('setting','default') :>) 466 |
  • <: l('%s for %s','n','Sans-serif') :> 467 |
  • <: l('%s for %s','e','Segoe UI') :> 468 |
  • <: l('%s for %s','s','Serif') :> 469 |
  • <: l('%s for %s','o','Tahoma') :> 470 |
  • <: l('%s for %s','t','Times') :> 471 |
  • <: l('%s for %s','b','Trebuchet MS') :> 472 |
  • <: l('%s for %s','v','Verdana') :> 473 |
  • <: l('or write out the font you want') :> 474 |
<: l('Interface Settings') :>
481 | <: l('Header:') :> 482 | 484 | ko = 485 |
    486 |
  • <: l('%s for %s','1',lp('setting','On & floating')) :> 487 |
  • <: l('%s for %s','s',lp('setting','On & scrolling')) :> (<: lp('setting','default') :>) 488 |
  • <: l('%s for %s','-1',lp('setting','Off except for Instant Answer Menu')) :> (Please do not remove our header for anything other than individual use. See paragraph at the top for more details.) 489 |
  • <: l('%s for %s','-2',lp('setting','Off')) :> (Please do not remove our header for anything other than individual use. See paragraph at the top for more details.) 490 |
491 |
496 | <: l('Advertisements:') :> 497 | 499 | k1 = 500 |
    501 |
  • <: l('%s for %s','1',lp('setting','On')) :> (<: lp('setting','default') :>) 502 |
  • <: l('%s for %s','-1',lp('setting','Off')) :> 503 |
507 | <: l('Page #s:') :> 508 | 510 | kv = 511 |
    512 |
  • <: l('%s for %s','1',lp('setting','On')) :> 513 |
  • <: l('%s for %s','n',lp('setting',"On but no numbers")) :> 514 |
  • <: l('%s for %s','-1',lp('setting','Off')) :> (<: lp('setting','default') :>) 515 |
519 | <: l('Units of Measure:') :> 520 | 522 | kaj = 523 |
    524 |
  • <: l('%s for %s','m',lp('setting','Metric (Kilograms, Meters, Celsius)')) :> 525 |
  • <: l('%s for %s','u',lp('setting','US based (Pounds, Feet, Fahrenheit)')) :> 526 |
  • <: l('%s for %s','-1',lp('setting','No Preference')) :> (<: lp('setting','default') :>) 527 |
531 | <: l('Source:') :> 532 | 534 | t = 535 |
543 | <: l('Directions Source:') :> 544 | 546 | kam = 547 |
    548 |
  • <: l('%s for %s','apple-maps',lp('setting','Apple Maps')) :> 549 |
  • <: l('%s for %s','bing-maps',lp('setting','Bing Maps')) :> 550 |
  • <: l('%s for %s','google-maps',lp('setting','Google Maps')) :> 551 |
  • <: l('%s for %s','here-maps',lp('setting','HERE Maps')) :> 552 |
  • <: l('%s for %s','osm',lp('setting','OpenStreetMap')) :> 553 |
554 |
559 | --------------------------------------------------------------------------------