Git Product home page Git Product logo

google-home-notifier's Introduction

google-home-notifier

Send notifications to Google Home

Installation

$ npm install google-home-notifier

Usage

var googlehome = require('google-home-notifier');
var language = 'pl'; // if not set 'us' language will be used

googlehome.device('Google Home', language); // Change to your Google Home name
// or if you know your Google Home IP
// googlehome.ip('192.168.1.20', language);

googlehome.notify('Hey Foo', function(res) {
  console.log(res);
});

Listener

If you want to run a listener, take a look at the example.js file. You can run this from a Raspberry Pi, pc or mac. The example uses ngrok so the server can be reached from outside your network. I tested with ifttt.com Maker channel and it worked like a charm.

$ git clone https://github.com/noelportugal/google-home-notifier
$ cd google-home-notifier
$ npm install
$ node example.js
Endpoints:
    http://192.168.1.20:8091/google-home-notifier
    https://xxxxx.ngrok.io/google-home-notifier
GET example:
curl -X GET https://xxxxx.ngrok.io/google-home-notifier?text=Hello+Google+Home  - to play given text
curl -X GET https://xxxxx.ngrok.io/google-home-notifier?text=http%3A%2F%2Fdomain%2Ffile.mp3 - to play from given url
POST example:
curl -X POST -d "text=Hello Google Home" https://xxxxx.ngrok.io/google-home-notifier - to play given text
curl -X POST -d "http://domain/file.mp3" https://xxxxx.ngrok.io/google-home-notifier - to play from given url

Raspberry Pi

If you are running from Raspberry Pi make sure you have the following before nunning "npm install": Use the latest nodejs dist.

curl -sL https://deb.nodesource.com/setup_7.x | sudo -E bash -
sudo apt-get install nodejs

Also install these packages:

sudo apt-get install git-core libnss-mdns libavahi-compat-libdnssd-dev

After "npm install"

Modify the following file "node_modules/mdns/lib/browser.js"

vi node_modules/mdns/lib/browser.js

Find this line:

Browser.defaultResolverSequence = [
  rst.DNSServiceResolve(), 'DNSServiceGetAddrInfo' in dns_sd ? rst.DNSServiceGetAddrInfo() : rst.getaddrinfo()
, rst.makeAddressesUnique()
];

And change to:

Browser.defaultResolverSequence = [
  rst.DNSServiceResolve(), 'DNSServiceGetAddrInfo' in dns_sd ? rst.DNSServiceGetAddrInfo() : rst.getaddrinfo({families:[4]})
, rst.makeAddressesUnique()
];

google-home-notifier's People

Contributors

andyjenkinson avatar bhacaz avatar btrial avatar darrencruse avatar ghostrick avatar harperreed avatar noelportugal avatar robertmain avatar toshi0607 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

google-home-notifier's Issues

Can not start up on aws lambda.

The following error appears and can not be started.

{
  "errorMessage": "libdns_sd.so.1: cannot open shared object file: No such file or directory",
  "errorType": "Error",
  "stackTrace": [
    "Object.Module._extensions..node (module.js:597:18)",
    "Module.load (module.js:487:32)",
    "tryModuleLoad (module.js:446:12)",
    "Function.Module._load (module.js:438:3)",
    "Module.require (module.js:497:17)",
    "require (internal/module.js:20:19)",
    "Object.<anonymous> (/var/task/node_modules/mdns/lib/dns_sd.js:24:20)",
    "Module._compile (module.js:570:32)",
    "Object.Module._extensions..js (module.js:579:10)"
  ]
}

Can not aws run with lambda?

Confused by how to use notifier

I installed google-home-notifier successfully. I am confused as to how this works. I want to try sending notifications to my Google home. How do I go about doing this? How can I send text inputs? Could someone show me step by step how to try this out? I am using an Ubuntu VirtualBox on my pc.

Cannot read property ‘fd’ of null

I’m not able to run the example.js.
When I made the first request, it prints out this without any notifications in Google Home.

{ text: 'Hello Google Home' }
Device "Google-Home-3e482a7482fb715cf1cc578a08278d10" at 192.168.1.88:8009

Then, subsequent requests will get this error. I made sure I have the latest version of nodejs.

{ text: 'Hello Google Home' }
TypeError: Cannot read property 'fd' of null
at Browser.start (/home/pi/google-home-notifier/node_modules/mdns/lib/mdns_service.js:32:35)
at Object.notify (/home/pi/google-home-notifier/google-home-notifier.js:23:13)
at /home/pi/google-home-notifier/example.js:20:16
at Layer.handle [as handle_request] (/home/pi/google-home-notifier/node_modules/express/lib/router/layer.js:95:5)
at next (/home/pi/google-home-notifier/node_modules/express/lib/router/route.js:137:13)
at /home/pi/google-home-notifier/node_modules/body-parser/lib/read.js:130:5
at invokeCallback (/home/pi/google-home-notifier/node_modules/raw-body/index.js:262:16)
at done (/home/pi/google-home-notifier/node_modules/raw-body/index.js:251:7)
at IncomingMessage.onEnd (/home/pi/google-home-notifier/node_modules/raw-body/index.js:307:7)
at emitNone (events.js:105:13)

get key failed from google

I've been happily using google-home-notifier for quite some time, but have recently started encountering this error:

Error: get key failed from google
at /home/pi/MyHouse/node_modules/google-tts-api/lib/key.js:27:13
at
at process._tickCallback (internal/process/next_tick.js:188:7)

The error message originates in the key.js module as indicated:
try {
eval(html.match(/TKK=eval('(.*)');/g)[0]); // TKK = '405291.1334555331'
if (TKK === null) throw null;
} catch (e) {
throw new Error('get key failed from google');
}

I've tried removing and reinstalling node.js and google-home-notifier, I've tried rebooting the Google Home, and I've tried calling googlehome.device and googlehome.ip to no avail ; does anyone have any idea where I go from here? Is it some sort of authorization error from google?

Managed to install without MDNS / found a bug in main-script

Hello Noel, this is a great node I was looking for a long time! Thank You for sharing!
It took me a while to install it on a synology-nas without mdns. If in docker or natively installed, mdns is not possible to run on a synology.
You should generate a branch without mdns, since it it used only to get the ip-adress of the google-home-device (I could provide the changes of package.json and the main script to do so, You should know, how to do it - just ask me...).

Bug in google-home-notifier.js
Since I am german, I would like to talk google home in german, but it is ignoring the language.
Cause:
When You initialize with
var language = 'de';
googlehome.ip('192.168.1.59', language);
the language argument is not recognized by the main script.

I had to change in google-home-notifier.js
var ip = function(ip) {
deviceAddress = ip;
return this;
}
into
var ip = function(ip, lang = 'de') {
deviceAddress = ip;
language = lang;
return this;
}
Now it talks in the given language or default 'de' in my case.

100% CPU on RPI3

Hello,
I am so glad I came across this, it is exactly what I need, thank you.
Unfortunately, when using example.js I get 100% CPU usage on the node process right after POSTing to it. The only way to stop it is to kill the process. Apart from that it is working ok and it does what it's supposed to do. I don't really have an idea how to troubleshoot this, so any help would be greatly appreciated.
Using Node 7.10.1 (npm 4.2.0) on Debian Jessie running on a Raspberry 3.
Thanks for reading.

Accent Support

It looks like the npm package is somehow out of sync with what's on GitHub. I was trying to get accent support working by hacking at the code in my node_modules folder. I figured it out and was going to put a PR together, but it looks like there are huge differences between what's on npm and what's on GitHub...

I'm going to put a PR in anyway, so you can see what I mean - but I expect it will need a little modification before merge :)

Error when running command

Hello,

This setup is running on a Raspberry PI 3.
In the example.js, I've set the following:

const serverPort = 8081;
var deviceName = 'Master Bedroom Home';

I then ran $ sudo node example.js.
But when I run the following command, there is no respond from my Google Home:
$ curl -X POST -d "text=test" http://localhost:8081/google-home-notifier

If I run the command again, I receive the following error as indicated in the screenshot attached

google-home-notification_error

Any help is appreciated, thanks.

URL undefined on ubuntu

hi
I tested the program on my mac and its works fantastically.
but when i run it on my ubuntu PC, it can't get the url and shows
undefined/google-home-notifier on my console log.
how can i fix this?
or it maybe optimized for only mac?
Thank you

Error with curl

I have this installed but i get and google doesnt say anything

{ text: 'Hello Google Home' }
Error: connect EHOSTUNREACH 192.168.*.*:8009
error
Living room Home will say: Hello Google Home

How too windows

Hi this looks really cool

Could I please ask how do I set this up on a Windows pc?
I'm a complete noob and don't quite understand your github page.

Many thanks

How too ESP8266 (as Arduino)

I'm using an ESP8266 to control my home, and would like to be able to send notification to Google home, like this instead to have "bip" when the door is closed, I will have Google home says "Door Closed".
but I don't really understand how to build the same thing on an ESP8266

Should i send a Get request http://192.168.0.XXX:8091/google-home-notifier?text=Hello+Google+Home ?
I don't really understand what Google-home-notifier really does / send to Google Home ?

thanks for your help

CANNOT excute "node example.js"

Hi there.
I tried installing and running "node example.js" following this README but failed.
I got a error below.

/home/bun/Downloads/google-home-notifier/node_modules/mdns/lib/browser.js:86
dns_sd.DNSServiceBrowse(self.serviceRef, flags, ifaceIdx, '' + requested_type,
^

Error: dns service error: unknown
at new Browser (/home/bun/Downloads/google-home-notifier/node_modules/mdns/lib/browser.js:86:10)
at Object.create [as createBrowser] (/home/bun/Downloads/google-home-notifier/node_modules/mdns/lib/browser.js:114:10)
at Object. (/home/bun/Downloads/google-home-notifier/google-home-notifier.js:4:20)
at Module._compile (module.js:641:30)
at Object.Module._extensions..js (module.js:652:10)
at Module.load (module.js:560:32)
at tryModuleLoad (module.js:503:12)
at Function.Module._load (module.js:495:3)
at Module.require (module.js:585:17)
at require (internal/module.js:11:18)

Can anyone help me out?

My environment is,
Xubuntu(on Chromebook)
node -v : v9.2.1
npm -v : 5.5.1

Thank you in advance.

Getting error: TypeError: undefined is not a function (RBPI)

pi@raspberrypi:~/google-home/google-home-notifier $ node -v
v0.12.6

pi@raspberrypi:~/google-home/google-home-notifier $ nodejs -v
v7.5.0

...
TypeError: undefined is not a function
at Browser. (/home/pi/google-home/google-home-notifier/google-home-notifier.js:17:24)
at Browser.emit (events.js:110:17)
at on_resolver_done (/home/pi/google-home/google-home-notifier/node_modules/mdns/lib/browser.js:31:14)
at next (/home/pi/google-home/google-home-notifier/node_modules/mdns/lib/browser.js:104:7)
at Array.makeAddressesUnique (/home/pi/google-home/google-home-notifier/node_modules/mdns/lib/resolver_sequence_tasks.js:177:5)
at next (/home/pi/google-home/google-home-notifier/node_modules/mdns/lib/browser.js:107:21)
at /home/pi/google-home/google-home-notifier/node_modules/mdns/lib/resolver_sequence_tasks.js:160:11
at getaddrinfo_complete (/home/pi/google-home/google-home-notifier/node_modules/mdns/lib/resolver_sequence_tasks.js:108:7)
at GetAddrInfoReqWrap.oncomplete (/home/pi/google-home/google-home-notifier/node_modules/mdns/lib/resolver_sequence_tasks.js:120:9)

use same ngrok url every time

First of all, thanks for this -- it's working great on my Pi. Second, is there a way to use a fixed ngrok url, rather than a new one being generated every time?

Can't install from npm

Can't install from npm install command. I can install other npm module.

$ node --version                                     
v10.6.0
$ npm --version
2.15.1
$ npm install google-home-notifier
> [email protected] install /Users/kidapu/00-DocRoot/02-projects/node_modules/google-home-notifier/node_modules/mdns
> node-gyp rebuild

gyp ERR! configure error
gyp ERR! stack Error: Python executable "/Users/kidapu/.pyenv/shims/python" is v3.4.3, which is not supported by gyp.
gyp ERR! stack You can pass the --python switch to point to Python >= v2.5.0 & < 3.0.0.
gyp ERR! stack     at failPythonVersion (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/configure.js:406:14)
gyp ERR! stack     at /usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/configure.js:395:9
gyp ERR! stack     at ChildProcess.exithandler (child_process.js:282:7)
gyp ERR! stack     at ChildProcess.emit (events.js:182:13)
gyp ERR! stack     at maybeClose (internal/child_process.js:961:16)
gyp ERR! stack     at Socket.stream.socket.on (internal/child_process.js:380:11)
gyp ERR! stack     at Socket.emit (events.js:182:13)
gyp ERR! stack     at Pipe._handle.close (net.js:598:12)
gyp ERR! System Darwin 17.6.0
gyp ERR! command "/usr/local/bin/node" "/usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /Users/kidapu/00-DocRoot/02-projects/node_modules/google-home-notifier/node_modules/mdns
gyp ERR! node -v v10.6.0
gyp ERR! node-gyp -v v3.3.1
gyp ERR! not ok

> [email protected] postinstall /Users/kidapu/00-DocRoot/02-projects/node_modules/google-home-notifier/node_modules/ngrok
> node ./postinstall.js

ngrok - unpacking binary
ngrok - binary unpacked to /Users/kidapu/00-DocRoot/02-projects/node_modules/google-home-notifier/node_modules/ngrok/bin/ngrok
npm ERR! Darwin 17.6.0
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "install" "google-home-notifier"
npm ERR! node v10.6.0
npm ERR! npm  v2.15.1
npm ERR! code ELIFECYCLE

npm ERR! [email protected] install: `node-gyp rebuild`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] install script 'node-gyp rebuild'.
npm ERR! This is most likely a problem with the mdns package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     node-gyp rebuild
npm ERR! You can get information on how to open an issue for this project with:
npm ERR!     npm bugs mdns
npm ERR! Or if that isn't available, you can get their info via:
npm ERR!
npm ERR!     npm owner ls mdns
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /Users/kidapu/00-DocRoot/02-projects/npm-debug.log

My OS is OSX 10.13.5.

Default parameter in function doesn't work.

On Ubuntu 17.04 , node ver.4..7.2 when I run example.js I am getting:
/home/artur/google-home-notifier/google-home-notifier.js:8
var device = function(name, lang = 'en') {

                             ^

How to bypass the bip before each message

Hi,
I was wondering if there is a way to use a parameter to avoid my google home to play a short sound before talking. In some cases, it's useful but sometime it's not. I am using this library with ifttt to let my device to answer questions and this sound is not necessary for this scenario.
I have checked the source code and also the one for node-castv2-client and I didn't see anything. Perhaps it's something hardcoded in google home?
Any idea?

Thanks

Error: connect ETIMEDOUT

Hi.
how to notify google home device using IP address remotely when I'm outside of local wifi network?

Unable to start srcript

Error: get key failed from google
at /Users/lc/Documents/work/GoogleHomeNotifications/node_modules/google-home-notifier/node_modules/google-tts-api/lib/key.js:27:13
at
at process._tickCallback (internal/process/next_tick.js:188:7)

This problem started recently.

Error: getaddrinfo -3008 with mdns

I get the following when trying to run this:

*** WARNING *** The program 'node' uses the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see http://0pointer.de/avahi-compat?s=libdns_sd&e=node
*** WARNING *** The program 'node' called 'DNSServiceRegister()' which is not supported (or only supported partially) in the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see http://0pointer.de/avahi-compat?s=libdns_sd&e=node&f=DNSServiceRegister
events.js:160
throw er; // Unhandled 'error' event
^

Error: getaddrinfo -3008
at errnoException (/home/kelly/node_modules/mdns/lib/resolver_sequence_tasks.js:199:11)
at getaddrinfo_complete (/home/kelly/node_modules/mdns/lib/resolver_sequence_tasks.js:112:10)
at GetAddrInfoReqWrap.oncomplete (/home/kelly/node_modules/mdns/lib/resolver_sequence_tasks.js:120:9)

In researching this, I see lots of people having issues using mdns and end up using something else.

Anyone else get this?

No includes

@noelportugal

Not sure why I am getting this. I can run the example and it waits for commands. Once I use curl, this is the output. Another thing I noticed is it is only sometimes picking my ghome. Other times it picks another cast device on my network. Any ideas?

/tmp/google-home-notifier/google-home-notifier.js:17
if (service.name.includes(device.replace(' ', '-'))){
^
TypeError: Object Google-Home-5e7040daf543262437d19be8062f43d5 has no method 'includes'
at Browser. (/tmp/google-home-notifier/google-home-notifier.js:17:24)
at Browser.emit (events.js:98:17)
at on_resolver_done (/tmp/google-home-notifier/node_modules/mdns/lib/browser.js:31:14)
at next (/tmp/google-home-notifier/node_modules/mdns/lib/browser.js:104:7)
at Array.makeAddressesUnique [as 2] (/tmp/google-home-notifier/node_modules/mdns/lib/resolver_sequence_tasks.js:177:5)
at next (/tmp/google-home-notifier/node_modules/mdns/lib/browser.js:107:21)
at /tmp/google-home-notifier/node_modules/mdns/lib/resolver_sequence_tasks.js:160:11
at getaddrinfo_complete (/tmp/google-home-notifier/node_modules/mdns/lib/resolver_sequence_tasks.js:108:7)
at Object.wrap.oncomplete (/tmp/google-home-notifier/node_modules/mdns/lib/resolver_sequence_tasks.js:130:7)

French support

Hi,
Is there a way to send a notification in French? I tried to reference FR instead of UK or US in the source code but without success.
I can see a reference to the google TTS engine ("google-tts-api": "https://github.com/darrencruse/google-tts/tarball/british-voice",) into package.json so I guess I have to replace this reference to something pointing to france, but neither french-voice or france-voice work. Any idea?
Thanks

Do we really need mdns lib?

It really makes the install kind of problematic... and if you npm install again you would need to do the change in the browser.js file again.

Instead of trying to resolve the DNS like that the user should be able to just use the IP adress of the Google Home. Makes things a lot easier in my opinion.

dependent module mdns won't build with recent versions of node (on arm ubuntu)

IDK if there's an easy resolution or maybe just something to highlight in your README, but on my raspberry pi (and odroid c1) running Ubuntu MATE...

When doing "npm install google-home-notifier" I kept getting an error at the point it was installing and trying to build mdns - errors like: "Module version mismatch. Expected 48, got 47."

I ended up (with the help of nvm) trying a whole bunch of different versions of node kind of doing a binary search until I finally figured out that node v5.5.0 would give it the expected version.

Just fwiw (this is a neat module btw thanks for writing it!).

Darren

How to choose the accent

Hi, I'm trying to send a notification in French with a Canadian accent but every time it's with a French accent ... I installed the google-its-api

this is my google-home-notifier.js


var Client = require('castv2-client').Client;
var DefaultMediaReceiver = require('castv2-client').DefaultMediaReceiver;
var mdns = require('mdns');
var browser = mdns.createBrowser(mdns.tcp('googlecast'));
var deviceAddress;
var language = 'fr-CA';

var device = function(name, lang = 'fr-CA') {
    device = name;
    language = lang;
    return this;
};

var ip = function(ip) {
  deviceAddress = ip;
  return this;
}

var googletts = require('google-tts-api');
var googlettsaccent = 'fr-CA';
var accent = function(accent) {
  googlettsaccent = accent;
  return this;
}

Failed at the [email protected] install script 'node-gyp rebuild'.

This fails when trying to install

npm ERR! [email protected] install: `node-gyp rebuild`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] install script 'node-gyp rebuild'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the mdns package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     node-gyp rebuild
npm ERR! You can get information on how to open an issue for this project with:
npm ERR!     npm bugs mdns
npm ERR! Or if that isn't available, you can get their info via:
npm ERR!     npm owner ls mdns
npm ERR! There is likely additional logging output above.

Using Node 7.8.0 on Windows 10

Are warnings expected?

Hi,

I tried to run the sample from the readme markdown. I uncommented googlehome.ip command and changed the ip address to match the ip address of my google home as found in the google home app. I saved the sample in app.js, and ran:

node app.js

I see this output:

*** WARNING *** The program 'nodejs' uses the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see http://0pointer.de/avahi-compat?s=libdns_sd&e=nodejs
*** WARNING *** The program 'nodejs' called 'DNSServiceRegister()' which is not supported (or only supported partially) in the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see http://0pointer.de/avahi-compat?s=libdns_sd&e=nodejs&f=DNSServiceRegister
Device notified

I don't hear anything from my google home mini. Are the warning expected?

Thank you!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.