►
From YouTube: YUI In the Wild #9 with Steven Olmsted of IBI Group
Description
YUI Open Roundtables cover topic related to YUI and other cutting edge javascript developments.
A
All
right
welcome
to
our
next.
Why
why,
in
the
wild
series,
this
is
number
nine
we're
featuring
stephen
olmstead
from,
I
guess
the
ibi
group
is
that
correct.
That's
correct!
He's
gonna
talk
to
us
about
two
really
dynamically
dynamic
applications
that
you've
written
and
yui.
One,
I
think,
is
the
the
transit.
B
A
A
Real
time
it
transit
real
time
and
then
the
other
one
is
a
telephony
app.
Is
that
correct,
yes,
cool?
Well,
you
guys
can
go
ahead
and
kick
things
off
so.
C
I
kind
of
just
introduced
myself,
I'm
stephen
olmstead,
I'm
s
olmsted
on
irc
and
github.
If
you,
I
usually
hang
out
on
irc
a
lot.
I've
been
a
software
engineer
for
coming
up
on
six
years.
I
guess
I
kind
of
have
an
interesting
story.
I
have,
I
actually
have
a
fine
arts
degree
and
I
got
a
job
as
a
web
developer
at
a
startup,
so
I
hadn't
actually
looked
at
any
javascript
before
that
moment,
so
things
have
changed
but
yeah
the
startup.
C
C
A
C
Yeah,
I'm
doing
a
lot
of
stuff
right
now,
so
at
ibi
group
we're
a
consultancy,
we
do
all
sorts
of
stuff
from
like
urban
design,
architecture
landscaping,
but
I'm
mostly
working
with
like
transit
systems
right
now,
so
we
kind
of
whatever
project
we
get.
Sometimes
the
contract
stipulates
you
have
to
use
certain
technology
or
sometimes
it
doesn't,
we
can
kind
of
choose
or
we
can
try
to
persuade
them
to
use
something
or
the
other.
So
I
end
up
jumping
around
with
lots
of
different
things.
So
you'll
see
some
of
that
today.
C
So
I
guess
I'll
kind
of
get
started
with
the
transit
real
time
project
is
what
I'm
working
on
at
the
moment.
So
this
is
in
progress.
C
Let's
share
my
screen,
so
you
want
us
to
switch
to
your
other
desktop
it'll.
Be
this
one:
okay,
that
zooms
off
into
infinity,
okay,
so
transit!
Real
time
is
a.
Can
you
see
that
okay
yeah,
but
can
you
bump
the
font
up?
C
Maybe
if
that
breaks
my
layout
transit
real
time
is
a
web
application
for
transit
systems
of
transit
agencies
to
manage
the
state
of
their
transit
systems
so
like
if
a
bus
breaks
down
and
is
going
to
be
delayed,
they
can
create
an
alert
and
manage
that
in
the
system
and
that
information
can
be
disseminated
out
through
lots
of
different
channels.
C
C
We
can
we've
integrated
with
facebook
and
twitter,
so
it's
just
a
tool
really
for
these
transit
agencies
to
communicate
to
people
to
the
public
about
what's
going
on,
we
also
have
like
developer
apis,
so
third-party
app
developers
can
use
this
data
in
their
own
apps.
C
So
this
is
kind
of
the
main
page.
We
call
it
manage
alerts
so
on
the
current
alerts,
tab
is
a
list
of
all
the
currently
active
alerts
in
the
system.
This
is
a
development
database.
This
is
just
test
data,
but
we
have
boston's
gtfs
data
loaded
into
the
system,
so
this
is
just
kind
of
test
data
from
boston.
So,
if
you
see
fenway
station
is
closed,
it's
not
actually
closed.
Let's
just
test
data.
C
C
Yeah
we've
got
there's
this
page.
These
pages
look
very
simple,
but
there's
just
a
ton
of
code
going
on.
In
the
background,
I
guess
I'll
just
kind
of
give
you
an
overview
of
the
user
interface
real
quick
before
I
go
into
the
technical
details,
so
we
can
they're
sorted
by
id
by
default.
You
can
click
on
these
are
like
an
accordion,
so
you
can
get
all
the
information
about
this
alert.
C
C
We
have
some
with
that
end
at
a
specific
date
and
some
that
are
just
until
further
notice.
So
it's
does
some
smart
sorting
on
these
time
columns.
C
C
I
know
the
icons
are
rendering
funky
at
the
moment.
This
is
again
a
work
in
progress
alerts
can
be
starred
and
tagged
as
just
a
organization
mechanism.
So
some
tag
is
my
fancy
tag,
name
on
that
one.
So,
what's
going
on
behind.
C
So
so,
when
the
first
page
first
loads,
it
makes
an
ajax
request
to
get
the
list
of
current
alerts
and
that's
about
it
at
first.
The
data
table
knows
how
to
render
it
there's
lots
of
column,
formatters
and
a
couple
node
column
formatters
in
here
that
are
able
to
display
all
the
data
and
there
are
lots
of
events
on
them
for
like
the
accordions
there's
buttons
here.
So
I
can
like
close
an
alert.
C
So
if
I'm
done
with
it,
I
can
close
it
and
it
goes
away
or
edit
an
alert,
and
we
made
this
little
pop
out
for
more
options
like
I
can
see
the
history
of
the
alert.
C
C
D
C
So
this
here
is
just
getting
saved
in
our
own
database,
so
I
can
we
can,
when
we
initially
prime
the
system
with
gtfs
data
from
a
transit
agency
or
a
location,
you
can
get
gtfs
data
from
google,
or
sometimes
the
different
agencies
will
provide
you.
Their
data.
C
C
What
else
is
going
on
here?
So
we
can
also
sort
by
things.
So
if
I
only
want
to
look
at
boat
alerts
that
filters
the
table
same
thing
with
certain
effects,
I
only
want
to
see
cancellations
and
that
I
don't
have
that
many
demo
alerts
in
the
system.
Here
you
can
sort
by
the
different
tags.
You
can
search
on
things
and
you
can
even
dig
into
more
for
if
there's
a
repeating
alerts
like
you'll
see.
This
alert
here
is
repeating
it.
C
C
I
can
hit
this
little
refresh
button
to
refresh
because
this
app
is
intended
for
people
working
at
the
transit
agency
and
there
could
be
multiple
people
entering
and
updating
information
all
the
time.
So
if
I
check
this
little
button,
it'll
automatically
refresh
every
minute,
so
you
always
have
a
current
view
of
alerts.
C
Future
alerts
is
the
same
thing,
but
it's
things
that
are
scheduled
in
the
future,
so
you
don't
always
have
to
see
what's
happening
now,
but
you
can
see
what's
upcoming
and
past
alerts
is
all
of
the
alerts
in
the
past
and
there's
tons
of
them.
This
might
be
easier
to
show.
C
Show
the
filtering,
because
there's
a
couple
thousand
alerts
in
here
and
a
little
fun
thing
like
this-
is
the
blue
line
alert.
So
there's
a
little
blue
line
at
the
side
and
pass
alerts
are
cool
because
you
can,
you
can
reactivate
them,
so
it'll
keep
all
the
data
from
the
alert,
but
you
can
assign
like
a
new
time
period
to
it.
A
And
why
why
are
you
guys
using
right
now.
B
C
So
far
we
haven't
had
a
lot
of
memory
issues.
I
can
imagine
it
getting
out
of
control
eventually
and
what
will
will
probably
it'll
probably
be
something
I'll
come
back
to
once
we
kind
of
have
all
the
features
we
want
implemented,
so
I
guess
I'll,
I
kind
of
skipped
over.
So
this
isn't
a
completely
fresh
new
design
of
this.
When
I
joined
the
project,
this
was
an
asp.net
web
forms
application.
C
So
clarence
gave
a
good
talk
at
yui
conf,
where
he
described
the
difference
between
different
web
applications,
server
side,
rendering
only
client-side
rendering
only
and
a
hybrid
approach.
So
this
used
to
be
a
server-side
rendering
only
app
in
asp,
and
I
am
definitely
not
an
asp
developer.
C
So
when
I
kind
of
took
over
as
the
lead
developer
on
this,
my
first,
my
first
thing
was:
we
should
get
rid
of
all
the
asp
and
use
yui,
and
luckily
that
worked
out-
so
I
am
I'm
getting
pretty
far
along,
but
I'm
I'm
re-implementing
the
project
as
a
client-side
only
app.
So
it's
it's
switched
from
the
the
first
kind
of
app
to
the
second,
using
the.
D
White
line:
are
you
using
asp
as
the
api
behind
it,
though
still.
C
C
Yeah,
definitely,
you
said
you
mentioned
it
on
pure.
Is
it
a
responsive,
or
is
it
mostly
just
for
distance?
It's
it's
not
responsive
yet
because
our
main
target
is
only
desktop
and
actually
only
chrome
and
firefox.
C
So
that's
pretty
nice,
but
it
is
nice
for
like
some
of
the
like
the
supervisors
or
people
who
are
more
like
responsible
for
things
going
on
the
system,
it's
nice
for
them
to
like
pull
out
their
phone
and
check
it
like
when
they're
on
their
break
or
when
they're
at
home,
like
some
of
our
users
like
to
do
that.
So
it
does
work
on
mobile
devices,
but
they
get
this
same
layout
which
isn't
that
fun.
C
So
that
might
be
a
feature
we
add
in
the
future.
Definitely
switching
over
to
pure
lets.
Us
opens
up
that
option
for
the
future.
A
You
mentioned
when
the
when
the
page
first
loads,
that
it
renders
something
and
then
does
an
ajax
calling
and
gets
the
data.
Is
that
right,
correct.
C
It's
it
does
a
dispatch
in
y
dot
app
and
the
route
handler
figures
out.
What
view
needs
to
load
for
the
current
url?
C
It
does
why
that
use
to
get
the
view
and
all
of
its
dependencies
and
then
the
view
itself
might
want
to
fetch
more
data
and
there's
also
a
we're
using
why
that
cache
offline
for
some
of
this
data,
so
that
it
like
the
gtfs
data,
doesn't
get
refreshed
but
like
once
every
three
to
six
months,
so
we
can
cache
and
hold
on
to
a
lot
of
it.
D
One
of
the
tricks
that
we
have-
which
I
don't
know
it,
might
help
you
guys,
which
is
we
send
like
the
json
data
inside,
like
a
script
tag
too,
on
the
initial
like
server
render.
So
that
way,
you
don't
need
to
make
like
a
second
like
ajax,
an
ajax
request
as
soon
as
you
get
on
the
page,
so
that
your
templates
can
just
like
immediately
render
the
data
without
having
to
like
like
get
the
html
like
a
skeleton,
then
make
an
ajax
call
and
then
re-render
it
with
yui.
C
C
So
it's
it
takes
a
couple
seconds
to
load
which
could
be
improved,
but
the
way
it
is
now
the
server
is
completely
dumb.
Like
I'll
show
you
the
the
routes
in
a
minute
on
the
server,
basically
any
url
that
loads
a
page,
it
loads,
the
same
html
document
and
all
the
html
does.
Is
it
loads
yui
and
it
calls
render
on
our
y
dot
app?
That's
that's
so.
The
server
is
very
dumb
at
the
moment.
C
There's
no
smarts
there
and
we
we
sacrificed
some
initial
load
time,
but
that
isn't
really
that
isn't
really
a
driving
force
of
our
design
right
now,
because
most
of
the
time
someone
who's
using
this
is
coming
into
work.
They'll
load
it
in
the
morning
and
they'll
sit
on
this
page
all
day,
so
we're
not
worried
about
if
it
takes
five
seconds
to
load.
C
That's
not
too
big
of
an
issue
and
even
like
to
me
like,
philosophically,
in
general,
I
kind
of
find
it
odd
that,
like
web
apps,
have
this
huge
desire
to
have
initial
load
times
be
shrunk
down,
because
I
look
at
any
other
platform
like
on
my
phone.
Most
apps
have
a
little
loading
splash
screen.
If
I
open
up
microsoft,
word
or
photoshop,
I'm
sitting
there
for
a
while
with
a
loading
splash
screen.
I
was
like.
Why
can't
why
can't
websites
load
things
for
a
moment
too?
A
Desktop
machine
on
a
desktop,
your
your
expectation
is
that
it's
going
to
come
really
fast,
because
you
have
a
fast
connection
and
that's
one
thing.
Another
thing
is,
I
think,
for
mobile
devices:
mobile
apps,
there's
such
a
competition
for
speed
that
you
know
if
you
have
two
apps
and
one
is
a
slightly
slower
than
the
other
one
you'll
just
delete
it
and
go
the
other
one.
C
Sorry,
that's
the
joys
of
a
home
office.
D
C
So
well,
actually
let
me
let
me
jump
I'll
show
you
the
one
other
page.
We
have
right
now,
it's
actually
creating
alerts
and
I'll
come
back
to
that.
So
when
you
want
to
create
alert,
you
pick
what
mode
you're
on
and
then
what
effect
happens.
So
if
it's,
if
it's
a
bus
alert
say
a
bus
is
delayed.
C
So
now
this
brings
down
affected
services
so
what's
affected
by
this
bus
delay,
and
here
we
have
a
route
direction.
Stop
we
call
that
the
paradigm
rds
so
different
mode
effect
combinations
will
have
different
paradigms.
C
C
A
C
It
is
we're
probably
going
to
reskin
that
a
bit,
but
right
now,
that's
just
the
raw
calendar
widget,
I
can
say
it's
to
say
it's
delayed
because
of
a
disabled
bus
and
that
it's
moderately
severe,
and
so,
as
I'm
filling
this
out,
it's
automatically
creating
this
message
so
saying
route
14
is
experiencing
moderate
inbound
delays
until
saturday
march
29th
at
10
pm
due
to
disabled
bus.
C
So
we
have
a
big
templating
engine
in
the
background
that
is,
there
are
different
templates
based
on
the
mode
and
the
effect
and
what
you
fill
out
here,
and
so
it's
kind
of
like
there's
one
template,
but
then
the
the
values
that
you
insert
into
them
are
other
templates
that
have
values
that
insert
into
them.
So
it's
like
this
nested
templating
system,
which
is
kind
of
crazy,
but
it
turned
out
to
work
out
pretty
well.
That's.
C
Interactive
form
yeah,
and
so
you
saw
that
it
filled
this
out
and
also
includes
the
additional
information
like
if
I,
if
I
pick
a
bunch
of
stops
here,
they're
all
listed
here
and
I
can
give
it
an
optional
like
url,
if
there's
more
information
about
this
alert
online
somewhere-
and
that's
that's
as
far
as
I've
gotten
on
my
redesign
here,
there's
a
couple
other
fields
that
I'm
going
to
add
for
outputs.
C
So
if
we
want
to
send
it
to
twitter,
we
might
want
to
tweak
the
message
that
goes
out
to
twitter
or
we
might
want
to
specify
when
it
goes
out
and
so
on
and
so
forth.
So
what
happens
when
you
hit
preview
there
right
now,
nothing,
but
what
what
it's
supposed
to
do
is
it
brings
up
a
kind
of
an
overview
of
the
whole
alert.
C
So
if
you
go
back
to
what
one
of
these
looks
like,
the
preview
will
show,
you
it'll
be
the
same
view
of
all
the
information
and
it
will
let
you
either
confirm
or
go
back
and
edit
something.
So
it's
just
a
review
to
to
make
sure
you
picked
what
you
thought
you
picked,
because
as
soon
as
you
submit
it,
if
you
set
it
up
to
go
out
now,
it's
gonna
alert
people.
So
you
wanna,
you
want
an
extra
confirmation
before
you
do
that.
C
Yeah
yeah
we
tried
to
try
to
make
this
form
to
go
top
to
bottom
left
to
right,
so
that
you
can.
You
can
go
back
and
like
change,
something
like
if
I
pick
that
route
I
can.
I
can
change
it,
but
you've
you've
updated
all
your
stops
and
stuff
in
the
background
as
well
nice,
so
yeah
I
can.
I
can
show
you
some
of
the
code
behind
here
is
the.
C
C
Yes,
it
is
so
I'll
show
you
a
different
paradigm.
So
if
I
go
like
a
commuter
rail
cancellation,
this
one
has
trips
instead
of
stops,
so
it
knows
on
this
than
the
lowell
line.
It
knows
all
the
trips
that
are
going
out
and
what
their
schedule
is
so
right
now
it's
5
26
on
my
time,
so
it
backs
up
a
little
bit
so
at
it
only
showing
me
trips
from
about
an
hour
ago
forward.
C
So
I
can
pick
which
trips
are
gonna,
be
canceled
tonight
and
if
I
or
if
I
wanted
to
pick
tomorrow's
alerts,
I
can
look
at
those
as
well
and
there.
It
shows
me
the
whole
day's
worth.
C
That's
great,
and
I
don't
some
of
them-
are
that's
route
direction,
trips
and
stops
this
one
is
called
stop
routes,
so
we
can
pick
pick
stops
that
are
affected
and
then
we'll
see
which
routes
it
affects,
and
sometimes
this
can
I
don't
know
the
data
that
well
sometimes
this
will
affect
multiple
modes,
because
you
might
either
might
be
like
a
train
station
that
has
a
bus
stop
at
it
and
a
subway
stop.
So
it
might
be
a
multi-modal
location.
C
C
And
like
even
on
a
regular
rds,
normally,
if
you
can
only
pick
one
route
and
you
what
you're
really
picking
is
stops,
but
I've
hit
this
little
check
box
those
go
away
and
I
can
pick
multiple
routes.
So
then
it's
it's
affecting
the
entire
route
for
all
of
those
routes.
Right,
so
you
don't
need
the
granularity.
If
there
you
just
pick
the
whole
route
right,
yeah,
exactly.
C
A
A
C
I'll
go
to
the
the
bottom
where
the
routes
are
so
here,
I'm
just
defining
all
the
routes,
it's
a
pretty
simple
when
I'm
at
create
alert,
there's
a
mode
or
an
effect
that
gets
added
to
it
and
I
define
a
callback
function.
So
it's
pretty
there's
not
a
whole
lot
going
on
here.
It's
just
a
simple
mapping
to
a
url
to
a
callback
function,
and
so
all
those
functions
are
on
the
app
instance.
C
C
So
I
called
that
main
view
which
extends
view
and
then
like
manage
alerts,
view
extends
main
view.
So
there's
some.
C
C
C
This
is
a
filters
view
this
top
bar
and
you
click
on
more
filters.
This
is
the
advanced
filters
view,
so
that's
split
into
two
views.
C
The
data
table
is
inside
of
an
alerts
view
and
this
extra
bar
here
I
didn't
really
show
that
off
it's
for
bulk
operations.
So
if
I
select
all
the
alerts,
I
can
close
them
all
at
once.
If
I
wanted
to-
or
I
can
star
them,
unstar
them
so
on
and
so
forth.
C
C
Yeah
yeah,
so
so
there's
subclasses
and
there's
nesting.
So
we
have
like
the
main
view
and
the
manager
alerts
extends
main
view.
But
then
the
manage
alerts,
view
instantiates
like
the
main
menu
the
filters
and
the
alerts
view.
D
So,
with
the
bulk
operations
view
like,
what's
handling
all,
what's
handling
like
the
events
to
make
like
the
alerts
view
select,
all
of
them
is
that
all
are
you
having
events
that
bubble
all
the
way
back
up
to
the
top
level
app.
C
C
C
I've
so
so
this
source
folder,
is
all
my
yui
modules
and
templates
and
css
very
cool
alerts.
View.
C
Where's
my
render
function
it
calls
underscore
render.
So
this
is
my
data
table.
Configuration
is
very
large
and
once
it
renders
the
data
table,
it
stuffs
the
bulk
operations
view
inside
of
the
header
table
header,
so
the
alerts
view
is
creating
and
rendering
the
bulk
operations
view
and
it's
adding
itself
as
a
bubble
target.
C
E
C
So
so,
some
of
the
places
where
I've
kind
of
brushed
into
the
limits
of
yui
so
to
say
I've.
I
had
a
couple
so
so
one
thing
I
can
show
you
well
to
say:
I'm
not
using
models
anywhere
except
like
within
data
table,
uses
models,
but
I'm
not
passing
it
models.
C
I
started
with
this
manage
alerts
stuff
and
it
was
just
doing
y.I.o
and
returning
an
array
of
objects,
and
that
was
fine
for
me
for
pretty
much.
Everything
was
like.
I've
got
this
hierarchy
of
views
and
I
was
fine
with
like
instantiating
the
view
and
passing
it
objects
as
attributes
and
then,
if
something
changed,
I
was
fine
bubbling
it
back
up,
but
there
was
one
thing:
one
thing
that
was
weird,
and
so
that's
this
modes
filter
so
like
any
of
these
others.
C
If
I
filter
by
it-
and
I
leave
the
page-
it
just
resets,
but
this
modes,
one
is
special.
If
I
switch
to
a
specific
mode
and
go
to
another
page,
it
key,
it
stays
there
because,
like
sometimes
we'll
have
users,
so
it's
their
job
specifically
to
monitor
boat
events,
so
they're
only
interested
in
boat
ever
so
we
didn't
want
them
to
have
to
keep
resetting
this
every
time
they
switch
from
page
to
page.
C
But
it's
also,
if
you
do
a
full
refresh
on
the
page
that
will
reset
so
before
that
was
like
a
session
variable
in
asp,
stored.
C
Is
you
just
set
this
global
setting
and
whenever
a
new
view
comes
in,
it
checks
that
yeah?
So
so,
when
I
I
showed
you
on
here,
mode
name
gets
passed
into
the
manage
alerts
view
and
then,
when
the
manager
alerts
view
creates
the
filters
view
it
passes
it
along
as
well
so
from
the
from
the
top
level.
C
It's
it's
whatever
its
value
is
keeps
passed
in
and
in
and
in
until
it
gets
here
and
then
when
it
changes
the
change
event,
bubbles
all
the
way
back
up
and
that
that
was
working
out
pretty
well
for
this.
But
when
I
got
to
create
alerts,
there's
just
so
much
data
going
on
here
with
like
picking
a
route
updates.
These
picking
these
updates
this
and
everything
is
by
just
basically
doing
it
with
attribute
change.
Events
bubbling
was
too
much
work.
He
was
just
an
exponential
combination
of
things
going
up
and
down
the
tree.
C
So,
like
I
thought
in
my
head,
the
solution
to
this
is
use
a
model
because
then,
all
of
these
view
objects
can
all
reference
the
same
model
and
then,
when
one
of
them
changes
it
they
all
change,
they
don't
have
to
bubble
right
but
model.
I
liked
this
way
I
was
using
wider.
I
o
and
had
just
plain
objects.
C
C
So
I'm
using
these
simple
data
objects
as
a
way
for
multiple
views,
just
to
share
a
simple
value
and
have
change
events.
So
now
we're
using
these
data
objects.
I
really
only
when
I
create
an
instance
of
something
I
have
to
pass.
The
data
object
to
the
new
instance,
but
I
don't
have
to
worry
about
bubbling
change,
events
up
and
down
the
stack,
so
they
just
they
just
get
set
once
and
they
you
can
see.
C
I've
extended
this
to
do
specific
things
for
specific
types
of
data
so
like
when
I
that
route
selector
I've
got
a
route
data,
and
so
this
has
the
fetch
function
in
it
that
it's
just
a
wrapper,
basically
around
wide
io
that
handles
the
json
objects
and
I've
got
this
abort
and
fetch.
So
if
someone
like
hits
the
button
like
the
50
times,
really
fast,
it'll
abort
all
of
the
old
requests,
so
you
don't
have
like
50
responses
coming
back.
D
C
Yeah,
because,
like
so
so
in
the
case
of
in
the
case
of
that
mode
name
is
an
easy
one
to
describe
so.
I've
got
transit,
real
time,
app
filters
view
r.
Yet
sorry,
I've
got
transit,
real-time,
app,
manage
alerts,
view
and
filters
view.
There's
this
view
in
the
middle
that
doesn't
really
care
about
mode
name,
but
it
has
to
listen
on
all
the
change
events
to
pass
the
data
back
and
forth
between
the
the
upper
view
and
the
lower
view.
C
So
it
has
to
listen
like
on
filters
view
mode,
name,
change,
fire
mode,
name
change,
so
it
bubbles
back
up
and
that
would
that
just
became
a
a
pain
when
the
this
nested
view
is
several
layers
deep
and
something
at
the
bottom
wants
to
talk
to
something
at
the
top
and
everything
in
the
middle
has
to
relay
the
data.
C
Just
writing
all
that
code
to
just
copy
values
from
here
to
there
was
a
pain
yeah
but
yeah.
If
they
all
just
share
a
common
data
object,
they
just
keep
that
reference
and
they
can
all
just
list
if
they
care
about
it.
They
just
have
to
listen.
Listen
to
the
change
event
on
the
data
object.
They
don't
have
to
worry
about
moving
the
data
around
and
yeah
it's.
What
I
have
is
similar
to
why
that
model,
because
I've
got
my,
I
o
layer
baked
into
it
type
thing
right.
C
Yeah
yeah,
it's
basically
kind
of
it's
just
simpler
than
model,
because
I
didn't
need
all
of
the
sync
stuff
I
just
needed
kind
of
like
a
fetch
to
get
stuff,
and
I
needed
to
change.
Events
like
I
don't
have
anything
comparable
to
model
list.
My
data
object
will
happily
store
an
array
of
stuff.
D
C
So
I
just
don't
have
that
use
case
like
if
I
hit
a
refresher
on
this
table,
it
just
pulls
everything
again
and
it
resets
it
on
the
data
table.
If
I
like
close
an
alert
that
will
it
disappears,
it
edits
it
on
the
data
table,
because
the
data
table
creates
a
model
list
under
the
covers,
and
so
I
edit
that
model
list
oh
yeah
and
then
the
next
time
it
refresh
if
it
if
auto
refresh,
is
on
by
default
in
the
next
minute.
This
will
get
blown
away
by
new
data
anyway.
C
D
C
So
so,
like
here,
there's
even
more
nested
views
because
I've
got
the
affected
services
selector,
and
it
knows
like
what
paradigm
and,
depending
on
the
paradigm
it'll
load
the
route
selector
view
the
direction
selector
view
the
stop
selector
view
and
each
one
of
those
has
its
own
specific
data.
That
knows
how
to
fetch
that
type
of
data.
C
So
this
is
actually
I've
been
working
on.
I
I
just
invented
that
data
object
last
friday,
so
how
many?
How
many
things
in
here
end
with
data?
I've
got
a
lot
of
objects
in
here
now,
but
the
I'm
gonna,
I'm
gonna,
move
on
there's
one
more
thing.
I
wanted
to
talk
about
this
because
I've
got
another
project.
I
want
to
talk
about
too,
but
one
more
thing
in
here,
along
with
the
attribute
data
system,
is
this
alert
text
generator?
C
So
that's
these
nested
nested
templating
system,
and
so
I
had
to
keep
some
of
the
old
design.
So
I'll
show
you
on
the
admin
page.
These
can
be
updated.
C
Here's
a
copy
of
a
config
file
that
can
be
uploaded
at
any
time
and
it's
got
these
templates
in
it
that
have
these
question
mark
things,
so
it's
like
the
mustaches
and
handlebars
or
whatever
we
just
have
a
question
mark
and
then
a
value
that
gets
replaced
is
what
we
came
up
with.
So
I
had
to
keep
that
design.
I
couldn't
like
switch
to
micro
templates
and
then
some
of
these
things,
like
alert
duration,
is
another
template,
and
so
then
that
has
the
values
in
that
have
other
rules
for
generating
them.
C
C
C
C
C
C
If
the
value
is
null
basically
it
generates
it
and
then
sets
it
and
when
it
generates
I've
got
this
thing
called
track
dependencies
before
it
calls
the
generator
function.
What
this
does
is
it
adds
a
y
dot
do
before
around
y
dot
get
so
when
the
generator
tries
to
get
another
attribute
to
fill
in
the
template.
C
This
tracks,
all
of
the
calls
to
y
dot
get,
and
it
subscribes
to
a
change
event.
So
if,
if
something
that
this
depend
that
this
generator
depends
on
changes,
it
will
know
this
value
so
the
next
time
you
get
it
it'll
regenerate
itself.
C
So
this
is
a
lot
of
hacking
in
the
event
system.
So
at
first
until
this
morning,
this
line
here
was
me:
dot,
set
name
value.
I
just
used
regular
set
that
caused
all
sorts
of
crazy
issues,
because
the
within
y
dot
set
it
try.
It
called
makes
more
calls
to
y.get
to
try
and
figure
out
if
the
value
changed,
and
it
goes
into
this
crazy
loop
of
checking.
If
this
value
was
known,
this
would
end
up
running
like
30
times
before
it
finished.
C
So
eventually,
I
found
I
could
shortcut
the
system
and
directly
set
state
val
to
to
set
the
cache
value
in
there
and
then
the
generators
are
it.
It
gets
some
logic
about
how
to
create
the
value
and
it
returns
a
string.
Basically,
but
yeah.
This
get
cached
or
generate
was
a
pretty
pretty
big
hack
on
the
change
event
attribute
change.
Events
like
you're.
A
C
Yeah
yeah,
it's
interesting,
and
it's
it's
interesting
that
this
is
just
so
little
code.
What
the
track
dependencies
function
is
a
little
bit
more.
It's
not
that
much
more
though.
So
it's
basically
just
wrapping
white
or
this
dot
get
and
keeping
track
of
what
value
was
gotten
and
adds
it
to
a
change
event
array
and
when
it's
done
it
subscribes
to
after
change.
C
It
resets
this
value
to
null
and
then
detaches
the
change
events,
so
that
way,
the
either
either
every
attribute
value
is
valid
or
it's
null
and
if
it's
null
it'll
regenerate
itself.
So
all
you
have
to
do
is
get
one
of
the
attributes
and
you
have
what
you
want.
C
Definitely
it
feels
like
you
might
try
promises
with
this
right.
It
sounds
like
something
yeah
I've.
I
really
like
the
idea
of
promises
and
I
haven't
done
much
with
them
just
because
all
the
other,
all
the
other
apis
use
like
callback
functions,
and
I
don't
like
mixing
the
two.
So
it's
like.
A
C
So
the
fun
answer
is
no.
There
are
no
unit
tests.
I
want
there
to
be
it's
something
that
just
hasn't
we
haven't
been
able
to
do
yet
it's
something
I
would
really
like
to
do.
C
Well:
okay,.
A
Thank
you,
yeah,
thanks
to
you
no
problem
and
the
last
one
was
it
just
one
of
the
things
I
thought,
while
you're
looking
with
the
app
framework,
if
you
thought
about
like
constructing
like
pass
that
would
like
you
know,
say
you
want
to
auto,
create
an
alert.
You
might
have
a
url
path.
That
sort
of
has
all
that
filled
in,
so
that
when
it'll
read
the
url
and
auto
populate
the
form.
C
Yeah,
that
could
definitely
be
something
we
could
do.
We
don't
have
like.
We
don't
have
a
use
case
for
that
right
now,
mostly,
we
just
have
just
operators
filling
this
stuff
out.
We
don't
have
a
lot
of
shares.
We
don't
have
a
lot
of
things
like
automatically
like
compute
come
like
what
is
the
word,
I'm
looking
for
you.
Do
you
have
anything
automatically
generating
alerts?
It's
all
like
by
hand.
C
Let's
see
one
other
thing
I
can.
I
guess
I
can
show
real
quick.
Is
I
I'm
using
visual
studio
here,
but
I
wanted
to
still
be
able
to
have
a
build
process.
So,
like
you
see
here,
I'm
I'm
actually
using
yui
dot.
Add
around
all
these
modules.
C
All
these
templates
are
micro
templates
like
if
I
show
you
the
main
view
template
it's
a
micro
template.
Also
visual
studio
does
not
like
micro
templates.
C
It
thinks
it's
xml
and
thinks
every
one
of
these
is
an
error,
so
that's
fun,
but
so
I
wrote
my
own
build
system
because
I
can't
use
like
yogi
or
shifter,
because
I
can't,
if
other
developers
use
this
they're
not
going
to
have
node.js
installed
and
they're
not
going
to
they're
not
going
to
want
to
deal
with
it.
So
what
I
ended
up
doing
is
I
I
stuffed
node.js
into
this
solution.
C
So
there's
the
binary
right
there
and
I
created
this
build
script.
My
own
build
script
is
pretty
simple:
it
calls
uglify
on
the
javascript
and
it's
the
one
smart
thing
it
does.
Is
it
actually
parses
this
yui
ad
call?
So
it
reads
the
module
name
and
it
reads
all
of
the
requires
and
it
automatically
builds
my
yui
config
object
for
me.
So
I
don't
have
to
worry
about
managing
that
separate.
C
So
all
I
have
to
do
is
create
full
modules
and
then
it
automatically
knows
how
to
load
all
the
stuff
and
all
the
dependencies
and
everything
cool
and
it
yeah
it
compiles
the
micro
templates
and
turns
them
into
a
full
module.
So
again,
I
just
have
to
why
not
use
the
module
name,
and
I
have
the
micro
template.
C
Okay,
so
moving
on
my
other
project,
that
is
pretty
cool,
is
a
telephony
system
like
phone
ivr.
How
do
I
turn
that
off?
Okay,
that's
not
as
easy
to
demo
a
phone
system,
so
this
is
mostly
going
to
be
me
talking
about
it
and
I
can
switch
to
sharing
my
screen
on
my
other
computer.
C
C
But
yeah
I'll
just
talk
for
a
little
bit,
so
I'm
sorry
to
make
you
do
that
so
phone
systems
using
yui,
that's
crazy.
So
this
kind
of
came
back
from
my
time
I
said
I
worked
for
a
small
startup
company
and
a
lot
of
our
technology
was
involved
in
messaging.
C
C
So
if
you're
out
stuck
in
traffic,
you
can
call
511
and
try
and
figure
out
how
long
this
traffic
is
backed
up
for
so
a
lot
of
different
states
or
local
governments
have
a
511
system.
C
So
we
had
our
original
system
and
when
I
took
over,
I
didn't
really
like
how
a
lot
of
it
was
implemented
like
it
works
great.
It
has
some
cool
features,
but
it's
like
I
I
want
node.js.
I
want.
I
want
node.js
like
I'm.
I
came
from
being
a
front-end
developer,
so
that's
that's
where
I'm
at
and
like
yui
has
been
with
me.
The
whole
way
so,
once
like
once,
I
got
node.js
like
I'm
doing,
yui
too,
because
it's
got
I've
got
modules.
I've
got
change.
C
Events
attributes
actually
plug-ins
based
plugins
are
huge
for
me
on
node.js.
So
I
designed
when
we
went
to
design
a
new
system.
That's
that
was
my
first
thought
is.
This
is
what
I'm
doing,
but
there's
some
interesting
challenges
there.
So
I
guess
the
the
first
thing.
So
how
do
you
actually
answer
a
phone
call
with
code,
so
we
have
an
open
source
project
called.
C
Really
awesome:
it's
a
software
pbx
pbx
stands
for
private
branch
exchange,
but
I
don't
know
if
that
term
actually
means
anything
anymore.
To
me,
pbx
just
means
something
that
deals
with
phone
calls
so
and
asterisk
has
not
a
lot
of
great
documentation
and
a
very
weird
api.
C
So
by
default
it
has
something
called
a
dial
plan,
and
it's
this
weird
config
file,
where
you
can
kind
of
script.
What
happens
during
a
phone
call
and
you
can
create
like
different
blocks
and
navigate
between
them
and
have
a
few
commands
to
do
certain
things
on
the
phone
call,
but
it's
very
coming
from
like
a
programming
like
a
real
programming
language,
it's
very
weird
and
difficult
to
use.
C
If
there's
any
asterisk
developers
watching
they're
not
happy
with
me,
but
that's
kind
of
my
view,
but
they
they
came
up
with
an
interface
called
the
asterisk
gateway
interface
agi.
So,
in
your
dial
plan
you
can
just
say,
call
agi
and
point
it
at
an
executable
file
and
it
will
execute
that
as
a
background
process,
and
it
will
start
talking
to
it
over
standard
and
standard
out
and
you
can.
C
It
has
a
different
api
than
the
regular
asterisk
api,
which
is
fun,
but
you
can
use
that
to
build
your
your
telephony
interfaces
and
you
then
you're
in
your
own
language,
doing
whatever
you
want
to
that
works
pretty
well,
but
it
turns
out
that
creating
like,
if
you're
you
have
one
server
handling
hundreds
of
phone
calls
for
each
one
of
those
starting
up
a
background
process.
B
C
Not
being
efficient,
like
you'll
you'll
start
noticing,
like
call
quality
issues
or
other
problems
on
your
server
just
because
your
resources
are
taxed,
so
they
came
up
with
a
new
solution
called
fast
agi,
which
is
similar
in
your
in
your
dial
plan.
You
call
fast
agi
and
give
it
a
url.
A
C
A
C
C
So
I
can
show
you
some
of
that
so
you'll
see
all
of
this
code
has
a
senza.
Namespace
senza
was
the
name
of
my
old
company
and
we
just
haven't
refactored
the
name
out
of
it.
C
Yeah,
I
will,
when
I
open
a
file,
this
project
doesn't
really
have
a
name.
It's
got
two
parts:
the
ivr
for
interactive
voice
response.
The
ivr
is
where
you
actually
implement
the
phone
stuff
and
we
have
the
data
aggregator.
So
when
you're
dealing
with
something
with
511
you're
pulling
in
real-time
data
from
some
source-
and
you
don't
necessarily
for
different
projects,
you'll
have
different
data
sources
completely.
Like
you
might
be
pulling
a
rest
web
service,
you
might
be
pulling
a
json
feed.
C
You
might
be
listening
on
another
tcp
socket
and
getting
data,
so
the
data
aggregator
is
kind
of
this.
C
The
service
agnostic
way
of
pulling
data,
but
anyway,
one
of
these
is
a
little
over
low
on
the
fast
hdi
server,
so
yeah.
So
what
do
I
object?
So
you
see
I'm
I'm
mixing
yoy's
module
system
with
node's
module
system.
C
C
Yeah,
so
this
is
a
regular
base
object
when
it
starts
it
creates
a
new
tcp
server
and
when
it
gets
a
new
socket
it
wraps
it
in
this
socket
object.
So
it's
taking
the
raw
node.js
tcp
socket
object
and
wrapping
it
in
a
yui,
my
own
socket
object
and
then,
if
you're,
using
your
socket
object,
it
is
oh
wow,
cool
I'll,
show
you
that
in
a
minute.
C
C
I
get
things
like
being
able
to
prevent
defaults
and
all
that
all
that
fun
stuff
after
subscriptions
so
yeah,
here's,
here's,
just
events
that
are
re-firing
the
socket
events
and
that's
that's
basically
it
for
the
server
it
just
listens
for
connections
and
it
wraps
the
native
stock
gate
in
a
stock
object.
C
C
Okay,
so
when,
when
asterisk
first
enters
a
call
and
creates
this
fast
agi
connection,
it
sends
a
bunch
of
information.
C
So
this,
what
this
is
doing
is
the
initial
setup
is
it's
listening
for
to
the
data
event
and
trying
to
parse
out
this
data,
and
it
will
finish
once
it
gets
a
couple
of
new
lines
in
a
row
and
it
also
asterisk
at
any
time
could
send
this
hang
up
string.
So
I
have
to
listen
for
it
here.
Just
in
case
someone
hangs
up
like
immediately-
and
I
didn't
even
finish-
parsing
the
header
data
before
they
hung
up,
but
basically,
once
once,
I've
got
all
the
header
data.
C
C
Then
here
yeah
I'm.
Basically,
then
this
is
afterwards
once
once
that
header
is
done,
it
becomes
a
request
response
api,
the
opposite
way,
so
my
server
can
make
requests
to
asterisk
and
asterisk
will
do
something
and
respond.
C
C
A
C
Yeah,
well,
it's
the
same
api.
It's
just
going
over
tcp,
rather
than
standard
and
standard
out
trying
to
find
stream
file.
Is
that
one
looking
for
so.
D
C
This
stream
file
method
is
you
want
to.
You
want
to
play
an
audio
file
to
the
caller,
so
you
just
call
stream
file,
you
give
it
the
file
path
to
a
audio
file
and
you
can
pass
it
some
extra
options
like
escape
digits.
So
if
you
can
pass
in
like
a
one,
someone
can
press
one
to
stop
playing
or
you
can
put
in
a
seek
number.
So
if
you
want
to
offset
you
want
to
play
the
whole
audio
file,
you
want
to
play
part
of
it
and
then
you
get
a
callback
function.
C
So
it's
it's
going
to
listen
for
asterisk
response
and
give
you
a
call
back
when
it's
done
playing
the
file.
It's
an
error.
First
callback
and
it'll
give
you
some
information
like
if
it
was
interrupted
by
the
caller
by
pressing
a
button.
It'll
tell
you,
and
it
will
also
tell
you
how
far
along
the
audio
played.
C
C
C
The
the
results
the
asterisk
gives
back
aren't
always
consistent,
sometimes
it'll,
like
return
negative
one
for
an
error,
sometimes
it'll
return,
0
for
an
error
and
so
on
and
so
forth.
So
each
one
of
these
has
its
own
separate
logic
for
figuring
out
what
happened
with
the
result
result
from
asterisk,
but
eventually
it'll
return
back
the
callback
function
when
it's
done.
D
C
Yes,
yeah,
I
just
return
whatever
makes
sense
to
return
like
if
sometimes
it'll
just
return,
a
string,
sometimes
it'll
return,
an
hash
of
parameters,
cool
yeah,
so
so
yeah,
because
it's
just
a
text
format.
Sometimes
it's
comma
separated.
Sometimes
it's
space
separated.
It's
the
the
responses
from
asterisks
are
really
inconsistent.
So
so
a
lot
of
this
was
implemented
with
like
trial
and
error,
but
yeah
there's
just
a
bunch
of
stream
files.
If
you
want
to
stream
more
than
one
file
together,
so
we
thought
about.
C
A
Thought
about
open
sourcing,
this
fast
agi,
no
js.
C
Bridge
that
you've
created-
I
have-
I
really
wanted
to
I'm.
I
was
going
to
before
we
joined
ibi
group.
Ibi
group
doesn't
really
have
a
policy
for
open
sourcing
stuff.
I've
been
asking
to
because
there's
nothing
propriet,
there's
no
proprietary
information.
Here,
it's
an
implementation
of
asterisks
api,
so,
hopefully
someday.
I
can
make
this
npm
module.
I
just
need
to
get
permission,
but
getting
there's.
No
there's
no
procedure
for
that
at
the
company
right
now.
So
I'm
kind
of
stuck.
C
C
Yeah,
definitely
it's
there's
lots
of
lots
of
ways
we
can
go
with
this,
but
yeah
these
the
rest
of
these
functions
like
they
do
some
cool
stuff.
But
if,
if
you
look
up
fast,
agi
you'll
you'll
know
everything
that's
in
here.
This
is
just
a
wrapper
around
it
all.
A
C
C
So
I
have
master
processes
and
work
processes,
so
the
this
is
the
main
function
that
runs
it.
The
first
thing
it
does:
is
it
loads
yui
with
a
big
fancy,
config
object,
and
then
it
does
some
boilerplate
to
figure
out
its
own
network
interface
address.
C
But
this
kind
of
block
here
I
can
some
of
this
is
some
pretty
ugly
code,
because
I
was
in
a
big
rush
when
I
implemented
this
the
first
time
we
didn't
have
a
lot
of
time
before
the
deadline,
so
sometimes
I've
got
comments
on
things
and
documentation
and
a
lot
of
places.
It's
just
a
bunch
of
code,
but
I
guess
that's
one
of
the
strengths
of
this
system.
If
you
think
about
it,
I
hacked
this
all
together,
pretty
quick
and
it
works
and
it's
stable
and
we
profited
from
it.
C
So
javascript
and
node.js
are
awesome,
but
anyway,
when
this
starts
up,
I've
got
my
lazy
load
as
a
wrapper
around.
Why
not
use
it's
a
gallery
module?
I
made
a
while
back,
but
this
is
this
cluster
function.
I
made
it
just
you
pass
it
two
things
and
it
will
return
either
the
first
one,
if
you're
in
the
master
process
or
the
second
one,
if
you're
in
the
worker
process.
C
So
what
this
is
doing
is,
if
I'm
and
if
you're,
on
the
master
or
worker
process,
there's
a
different
list
of
plugins.
So
by
default
it
does
nothing,
but
a
config
file
tells
it
to
load
plugins.
C
So,
let's
figure
out
what
plugins
to
load
it
calls
wide-out
use
to
get
all
of
them
and
it
basically
loops
through
the
plugins
and
calls
plug
on
them
pretty
boring.
But
it
gives
us
a
lot
of
flexibility
there
when
it
starts
up.
And
if
you
look
at
the
master.
C
Let
me
I
don't
remember
if
there's
anything
interesting
in
here,
oh
so
this
is
basically
just
forking
off
the
worker
processes
and
it
manages
if
one
of
them
crashes
for
any
reason
it
restarts
it.
Mdns
mdns
is
an
awesome
feature
of
this,
so
multicast
dns
we're
using.
That
is
a
a
way.
So
we
have
multiple
ivr
servers,
multiple
aggregator
servers
we
want
to.
C
We
want
them
for
fault
tolerance,
and
we
also
want
to
load
balance
across
them.
So
we
have
redundancy,
but
we
don't
want
to
basically
be
tied
down
to
a
configuration
like
this
server
is
running
at
this
address,
so
we
use
mdns
and
basically
it's
it-
tells
the
network-
hey
I'm
running
here.
C
B
C
Okay,
so
what's
the
what's,
the
worst
thing
about
node.js
is:
if
there's
an
error
anywhere
an
unhandled
exception,
your
process
crashes
immediately
for
for
most
people,
they're
running
like
web
servers.
That's
not
a
huge
issue
because
you
usually
have
you'll
have
something
like
forever
or
something
in
the
background
to
restart
it.
If
it
crashes.
B
C
So,
depending
on
your
server
load,
you
might
have,
you
might
have
dropped
some
http
requests.
People
hit
refresh
or,
depending
on
your
client
people
might
not
even
notice
that
the
request
failed.
So
it's
it's
annoying
if
your
web
server
crashes,
but
it's
not
a
huge
deal
when
you're
dealing
with
phone
calls.
C
If
your
process
crashes,
you
just
hung
up
on
someone
right
and
if
you're,
if
your
server
has
a
couple
dozen
calls,
you
just
hung
up
on
a
couple
dozen
people,
so
I
try
to
actually
do
as
little
as
possible
in
the
master
process,
because
if
the
master
goes
down,
it
takes
all
the
workers
with
it
and
that's
an
entire
servers.
Full
of
phone
calls
just
went
offline,
so
we
we
try
to
mitigate
that
as
much
as
possible.
C
C
No
because
once
once
fast
agi
once
that
tcp
connection
terminates
asterisk
will
kill
the
call.
A
C
C
A
C
So
a
lot
of
times
we
have
as
much
as
possible.
We
have
all
of
the
prompts
pre-recorded,
so
we
usually
get
a
professional
voice
artist
to
record
all
of
our
prompts,
so
we
have
audio
files
and
when
we
have
like
dynamic
data
like
some,
some
traffic
event
happened
on
this
highway.
C
Yeah
so
on
the
data
aggregator
half
of
it
when
we
get
new
data,
it
does
a
lot
of
work
to
create
audio
files
by
concatenating
stuff
together.
But
coming
back
to
your
your
question,
this
is
where
we're
answering
the
phone
call.
So
the
server
is
this:
isn't
the
worker
process?
We
get
a
socket
event
with
the
new
socket
and
it
fires
the
dnid
dnid.
C
I
forget
what
that
stands
for
it's
a
voice
over
ip
term,
but
basically
it's
it's.
What
phone
number
did
the
caller
dial?
So
if
my
phone
number
is
five
five,
five
one
two
one
two
and
someone
calls
me:
the
dnid
will
be
five
five,
five
one,
two
one
two,
so
I'm
firing
an
event.
This
is
a
dynamic
event
that
has
that
value
in
it.
So
my
server
can
respond
to
phone
calls
on
different
phone
numbers.
C
So
again,
I've
got
a
configuration
file
that
maps
these
phone
numbers
to
a
callback
function.
So
when
I
receive
a
phone
call
on
a
number
I'm
expecting,
I
can
handle
it
so
that
right
there
is
all
the
the
main
ivr
worker
does,
and
so
the
rest
is
handled
by
plugins,
explaining
australia.
Our
main
implementation
was
for
alaska
511.
I've
got
the
alaska
511
ivr
it's
worker
process,
so
this
is
a
plug-in
to
that
worker
process.
C
So
it's
worker
plug-in.
This
is
what's
actually
listening
to
that
event.
So
here
it's
it's
looking
through
my
config
file
and
for
each
one
of
those
events.
I
subscribe
to
it's
listening
on
the
host
event
and
picking
up
the
socket
and
then
it's
I
have
an
ivr
object,
which
is
the
actual
implementation
of
all
the
call
flow.
C
That's
about
it,
so
this
is
where
things
get
fuzzy,
so
I
guess
that
I
was.
I
was
in
a
pretty
big
rush
to
implement
alaska
and
it
got
done,
but
everything
ended
up
in
this
side
object.
This
file
is
like.
D
C
Man
that
was
just
a
so
this
is
top
up,
so
I
even
I
have
things
like
date
helpers
in
here,
because
javascript
is
so
good
at
daytime
math
I,
on
top
of
that
fast
agi
layer.
I
have
kind
of
a
second
level
api
that
I'm
it's
built
baked
into
this
ivr
right
now.
My
goal
is
to
extract
it
into
its
own
api
layer,
so
you
can
build
these
call
flows
more
easily,
so
it
has
things
like
a
prompt
function.
C
I've
got
props.
Let
me
show
it
to
you.
C
Prompt
and
they
I
don't
have
any-
this-
is
the
most
api
documentation
I
have
in
this
whole
file.
So
when
I
prompt,
I
give
it
a
bunch
of
options
and
I
have
a
list
of
called
functions.
C
So
options
will
include
things
like
what
audio
file
to
play,
because
because
the
kind
of
general
voice
interface
is
you,
you
play
some
audio,
that
might
say
press
5
for
information
about
this
press
4
for
information
about
this
and
so
on
and
so
forth.
And
then
you
listen
to
those
dtmf
inputs
and
you
have
a
callback
function
for
each
one.
C
C
Basically,
all
that
whole
configuration
for
the
prompt
is
in
the
options
object.
We
also
have
things
like
context,
sensitive
help,
so
at
any
point
in
the
call
flow
someone
can
say
help
and
they'll
get
info.
They'll
get
a
different
prompt
with
information
specific
to
where
they're
at
in
the
call
flow.
C
All
that
this
options
object
is
overloaded
to
do
a
ton
of
stuff
and
actions.
Again,
it's
a
hash
of
callback
functions
depending
on
what
was
picked.
C
The
implementation
is
funky
because
it
kind
of
has
to
be
there's
a
lot
of
things
like
if
someone
at
any
time
there's
a
lot
of
like
global
options
as
well.
At
any
time,
people
can
switch
from
speech
recognition
mode
to
touch
tone
only
mode,
so
we
have
to
handle
that
we
have
to
if
speech.
Recognition
is
a
technology
that
actually
doesn't
work
so
great,
like
you'll,
see
a
lot
of
people
do
the
talk
to
type
text
on
their
phone
and
that
even
that
doesn't
work
so
well.
C
But
when
you
combine
that
with
your,
your
voice
is
getting
compressed
and
sent
through
a
cell
phone
tower
signal
through
the
publicly
switched
telephone
network
encoded
in
voip,
and
we
have
this
heavily
compressed
low
quality
audio
file.
To
listen
to
that.
Just
makes
the
problem
that
much
worse
and
if
you're,
in
a
car
with
background
noise
and
other
things
going
on
speech,
recognition
is
prone
to
failure.
D
It's
not
asterisk.
That's
doing
the
speech.
C
C
Well,
we
tell
asterisk
to
do
the
speech,
recognition
and
it
passes
the
data
to
the
speech,
recognition
engine
and
passes
its
results
back
through
asterisk
and
then
back
to
us
here
like
a
car
and
there's
there
yeah
and
there's
different
speech
recognition
engines,
we
we
have
one
specific
one
implemented
here,
but
the
way
this
is
set
up,
it
can
be
agnostic
to
any
speech
recognition
platform
as
long
as
we
know
what
data
to
expect
back
from
it,
but
we
have
to
be
able
to
handle.
C
If
say,
we
just
can't
understand
what
they
said.
Maybe
it's
just
garbage
noise.
If
that
happens
like
we
give
them
an
error
message,
if
that
keeps
happening,
we
might
give
them
a
different
error
message
and
if
it
still
keeps
happening
we'll
send
them
to
touch
tone
only
mode.
C
So
we
have
these
these
different
prompt
modes
and
they
can
fall
through
from
one
to
the
other,
depending
on
what's
going
on
and
the
yeah,
if
they're
in
like
touch
tone
only
mode,
you
want
to
say
like
press
six,
you
don't
want
to
say
say
highway
reports
and
vice
versa.
E
C
There's
it's
switching
out
audio
files,
switching
out
speech,
recognition,
options
and
all
sorts
of
stuff
in
this
prompt
object
and
finally,
it'll
come
to
a
caller
input
event
that
processes,
what
the
caller
said
or
pressed,
and
it
will
eventually
call
one
of
the
action
callbacks.
C
So
if
I
look
at
one
of
the
call
states
so
so,
when
we
build
a
call
flow,
we
we
usually
break
it
into
call
states.
They'll
have
I'll
have
this
huge,
like
visio
diagram
of
how
the
caller
gets
from
one
place
to
another,
with
all
the
branching
options,
and
so
I
kind
of
turn
each
one
of
those
little
boxes
in
the
diagram
to
a
something
called
a
called
state
and
that's
just
an
organizational
term.
C
In
this
case,
a
call
state
is
just
a
method
on
this
class.
This
huge,
huge,
huge
class,
I'm
sure
I'm
looking
for
the
top
of
this
method.
C
So
amh
amhs
is
the
alaska
marine
highway
system.
So
that's
one
of
the
features
of
our
phone
system
and
this
is
fetching
schedules.
So
this
is
one
call
state
and
call
in
in
this
ivr
call
states
also
have
global
options
like
go
back,
so
someone
can
navigate
forward
and
backward
just
like
you
could
on
a
web
browser
with
your
forward
back
buttons.
You
can
say:
go
back
to
go
back
through
your
history
of
call
states,
but
for
this
call
state
oh,
go
ahead.
How.
A
C
Ran
this
through
a
debugger,
it's
all,
so
it's
actually
a
pain
because
the
especially
the
speech
recognition
engine.
I
can't
run
that
locally
on
my
laptop
because
there's
licensing
restraints
and
the
speech
recognition
systems
are
expensive
even
for
a
development
copy,
they're,
usually
expensive.
So
I
can't
I
can't
get
my
own
copy
to
play
with,
so
we
set
up
a
development
environment
so
anytime
I
make
a
change.
I
have
to
deploy
all
the
codes
to
the
development
environment
and
call
it
with
my
phone.
C
Oh
wow
wow,
so
I
use
a
lot
of
console.log
statements.
That's
one
thing
that
I
would
really
like
to
do
is
improve
like
debugging
and
diagnostic
tools.
I
know
there
are
a
lot
of
useful
tools
for
node.js
and
again,
just
in
my
initial
rush
to
implement
this.
C
I
didn't
have
time
to
do
a
lot
of
experimentation,
so
this
has
a
a
lot
like
there's
the
grand
plan
to
expand
this
and
make
this
a
really
nice
system
for
developers
to
work
on
to
to
make
all
of
this
garbage
code
really
pretty
and
easy
to
maintain.
C
So
basically,
this
get
audio
list
is
a
function
that
the
prompt
method
uses
to
figure
out
what
audio
to
play.
So
in
this
case,
if
I'm
asking
for
touch
tone
help
here's
the
list
of
audio
files
that
play
on
this
call
state
for
touch
tone
help,
and
you
see
I
have
things
in
here
like
pick
it'll,
just
randomly
pick
one.
So
that
way,
if,
if
they're
repeating
this
call
flow
again
and
again
like
and
they're
asking
for
help,
they
don't
get
the
same
response
because
that
gets
tedious
and
annoying
to
callers.
C
So
sometimes
it
might
say
all
right
I'll
help
or
they
might
say
sure
here's
some
help,
so
it
just
kind
of
adds
a
little
bit
of
flavor
to
the
ivr.
And
then
I
have
these
conditions.
So
this
is
kind
of
my
and
a
different
type
of
templating
system
for
adding
logic
into
concatenating.
A
bunch
of
audio
files
together,
but
yeah
for
each
if
it's
just
a
touch
tone
menu,
is
different
than
if
it's
a
speech
recognition
menu.
C
If
it's
there's
error
levels,
if
it's
help
or
if
it's
just
the
default,
here's
what
happens
so
I've
got
this
big
function
for
figuring
out
which
audio
to
play
and
there's
lots
of
things
like
pauses
like
silence.
300
is
a
300
millisecond
pause
so
when
it
plays
like
it's
not
just
running
a
bunch
of
words
together,
there's
actually
a
moment
to
understand
what
it's
saying-
and
I
have
things
like
here
in
like
time.
C
C
C
Yeah
so
for
like
for
this
one,
all
the
numbers
from
1
to
100,
we
have
every
individual
number
recorded
as
a
separate
file,
but
then
we
want
like
so
if
45
is
an
audio
file
we
have,
but
if
we
want
145,
we
have
the
prefix
100
and
then
we
can
say
45
after
it.
So
we
can
say
145
by
saying
three
different
audio
files.
C
So
when
I
actually
get
to
the
prompt
function,
I
can
list
dtmf
values.
So
these
are
all
the
what
people
can
type
in
at
this
call
state
that
get
audio
list
function
and
grammars
grammars
are
speech,
recognition,
grammars,
it's
another
little
script
that
tells
the
speech
recognition
engine.
How
to
understand
what
people
say:
that's
a
whole!
Another
topic.
C
I
actually
ended
up
writing
my
own
language
for
speech,
recognition
grammar
because
the
there's
two
different
official
languages,
one
is
xml
based
and
one
of
them
is
called
a
bnf
grammars
and
the
speech
recognition
engine
we
were
using
here
did
not
implement
all
of
the
features
of
abnf
grammars.
C
C
Yes,
definitely,
then
yeah
all
night,
there
was
a
time
when
my
wife
was
home
when
I
was
working
and
I'm
debugging
speech
recognition
and
so
like
we're
trying
to
get
all
of
the
highway
names
to
recognize.
So
it's
in
alaska.
So
I'm
I'm
calling
in
and
I'm
saying,
seward
highway
no
seward
highway,
no
seward
highway
he's
probably
spent
about
a
day
just
trying
to
get
seward
highway
to
recognize,
and
my
wife
always
laughs
at
me
because
of
that,
okay,
but
yeah.
C
So
it
knows
which
callback
function
to
call,
and
so
a
callback
function
might
like
in
this
case,
if
they
said
repeat,
it
clears
some
of
the
information
on
the
prompt
and
it
recalls
prompt
with
the
same
options.
C
In
other
cases,
we
deactivate
the
grammars
and
we
move
on
to
another
call
state
and
so
the
way
I've
implemented
it
here
last
state
is
just
an
attribute
on
this
base
class
and
so
there's
a
attribute
change
event.
That
knows
how
to
switch
from
one
call
state
to
another,
and
the
change
event
also
keeps
the
record
of
all
the
call
states.
So
when
you
say
go
back,
it
knows
to
how
to
go
back
in
the
history
from
one
call
state
to
the
previous
and
there's
just
a
bunch
of
these
methods.
C
C
There's
a
couple
so
with
with
this
there's
a
couple
places
where
I
specifically
commented
on
things
that
are
bugs
like
here
so
yeah
and
well
they're
listed
as
tickets
or
they
were
in
the
old
ticketing
system.
I've
got
the
links
right
there
if
you
want
to
look
them
up
and
fix
them.
C
So
this
is
where
I
have
a
base
class
and
I'm
pulling
in
a
class
extensions
that
also
extend
base.
So
I
have
a
class,
so
I've
got
like
two
base
objects
mixed
together
and
that
works,
but
the
initialization
functions
run
in
the
wrong
order.
So,
if
I'm,
if
I'm
instantiating
this
class
and
it's
extending
this
other
class,
I
expect
that
one's
initializer
to
run
first.
C
So
when
this
initializer
runs
all
the
other
stuff
it
depends
on
is
already
there,
but
it
doesn't.
This
initializer
runs
first
and
I
have
to
subscribe
to
the
initialize
change
event
in
order
to
find
a
moment.
After
all,
the
other
initializers
are
done.
So
I
have
to
kind
of
delay
initialization
in
a
weird
way.
C
That's
that's
kind
of
a
nuisance.
I
found
workarounds
for
a
lot
of
these
problems,
though.
D
C
This
one
here
is
older.
Let
me
see
if
I've
got
it.
C
This
is
yui
312.,
this
one,
okay
yeah.
I
remember
there
was
something
there
was
a.
There
was
a
change
log
about
initializer
order,
and
I
think
I
tested
this
exact
thing
after
that
and
it
didn't
it
didn't
affect
this
particular
issue,
but
yes,
stuff,
that
I've
run
into
are
more
like
just
kind
of
little
annoyances,
but
I
found
ways
to
work
around
it.
Last
week
I
had
an
issue
that
I
don't
even
remember
what
the
issue
was.
It
turned
out.
C
C
So
if,
if
there's
something
called
prevent
default
on
the
change
event
or
if
a
validator
fails
or
there's
a,
I
think
there's
another
way
a
set
can
just
not
work.
There's
no
way
to
find
out
if
your
set
actually
succeeded
or
failed
from
the
outside.
C
C
So
and
things
like
events,
it
would
be
nice
if
sometimes
an
event
handler
could
be
asynchronous
or
a
default
function
could
be
this
because
sometimes
I
just
have
to
do
something
asynchronous,
and
I
don't
want
my
after
subscribers
firing
before
the
thing
happened,
but
there's
there's
always
workarounds
to
all
these
issues.
I
found.
A
C
Yeah
definitely
I
I,
when
I
hit
these
things
like
I'll,
take
the
time
to
debug
through,
like
the
attribute
set,
which
is
a
good
amount
of
code.
If
you
go
through
the
exchange
event
code
too,
so
I'll,
like
debug
through
and
find
out
exactly
what's
going
on,
like
that's
what
I
had
to
do
with
my
text,
generator
on
transit,
real
time
to
find
out
that
when
you
set
something,
it
also
gets
itself
internally,
and
that
was
messing
up
my
caching
and
just
to
just
to
throw
this
out
there.
C
C
C
People
someone
just
a
while
ago
was
complaining
about.
Datatable.Hide
doesn't
do
anything,
but
if
you
had
that
widget
skinning,
if
that
that
cascaded,
you
could
create
the
like
yoy
widget,
hidden
css
class,
and
you
could
do
that
once
and
then
all
widgets
could
benefit
from
that
one
rule
rather
than
creating
a
hidden
class
for
every
single
widget.
C
So
I
also
I
made
a
gallery
module
called
gallery
widget
inherit
css
that
it
makes
a
hack
into
widget.
So
when
you
get
class
name,
it
returns
multiple
class
names
in
a
space
separated
string,
so
it-
and
it
goes
all
the
way
up
the
prototype
chain
to
put
multiple
class
names
on
your
widget,
but
that
fails
in
some
places
because
sometimes
when
you
try
to
get
a
class
name,
you're
not
expecting
to
get
multiple
class
names,
you're
expecting
to
get
one.
So
I
I've
looked
into
that
problem.
C
I
don't
see
a
simple
solution,
but
that's
my
three
cents
on
it.
I.
A
C
Yeah
somewhat
so
well,
I
tried
to
do
that
a
while
back.
So
one
thing
I'll
ask
is
when
I
try
to
go
to
the
old
site,
if
I
have
the
full
url
to
the
issue,
it'll
show
it
to
me,
but
if
I
try
to
just
search
for
an
issue
or
get
a
list
of
issues
it
automatically
redirects
me
to
github.
C
Yeah
there's
some
sometimes
like
details
or
code
reproductions
that
I
don't
have
anymore.
A
C
Yeah
sure
I
can
so
some
of
the
things
like
I
have
commented
in
my
code
as
a
workaround
I
can.
I
can
pull
those
out
and
I
can
throw
them
on
github
yeah.
C
C
Just
a
quick
summary,
the
other
half
of
this
is
the
data
aggregator
portion,
I
told
you
like
it
has
to
be
kind
of
agnostic
to
different
data
services
like
sometimes
it's
just
a
fetching
from
a
rest.
Endpoint,
sometimes
we're
implementing
a
completely
custom.
Tcp
socket
server
thing
to
get
data,
so
it
starts
up
the
same
way.
The
ivr
starts
up.
C
It
just
does
basically
nothing
by
default,
but
it
loads
plugins,
and
so
these
plugins
is
where
you
can
implement
custom
code
for
all
the
data,
but
we
also
want
it
to
be
efficient
so
like
for
our
old
511
system,
the
original
one
I
told
you
about,
we
had
some
like
five
different
servers
for
handling
calls
and
each
one
manage
their
own
data,
so
our
data
provider.
Wasn't
that
happy
that,
like
every
couple
minutes,
it
was
getting
five
requests
hit
to
its
server.
C
So
for
our
new
architecture,
we
decided
we
wanted
to
make
it
smart,
like
we
only
want
one
server
to
make
the
request
and
it
can
share
the
results
with
all
the
others,
and
we
also
want
to
make
it
fault
tolerant.
We
want
to
make
it.
C
We
want
a
load
balance,
so
it's
it's
doing
distributed
computing
a
bit
in
in
that
all
of
the
servers,
all
the
aggregator
servers
that
come
up
will
all
talk
to
each
other
they'll
all
connect
to
each
other
automatically,
and
one
of
them
will
become
the
leader
node
and
the
leader
can
send
tasks
to
other
nodes.
C
C
So
that's
pretty
cool.
I
learned.
D
In
that,
like
master
node
from
from
what
you're
saying
I
missed
the
beginning
of
that,
so
like
the
master
node
like
just
like
matches
up
all
of
your
requests
and
then
like
it,
dedupes
them
so
like
it
only
like
sends
it
once.
C
Yeah,
so
for
something
like
the
way
alaska
511
works,
we
get
most
of
our
data
from
they're,
using
a
an
open
source,
xml
server
thing,
so
we
make
a
tcp
connection
to
them
and
anytime
there's
a
data
update.
They
push
it
to
us,
so
we
don't
have
to
be
like
keep
fetching
data
we'll
get
on
like
instant
updates.
C
But
so
we
get
this
raw
data
object
xml.
So
we
we,
who,
whichever
server
gets
it,
will
randomly
send
it
to
another
server
to
process
or
it
will
round
robin.
Whichever
way
we
want
to
do
it
and
it
will
process
that
and
figure
out.
Okay,
do
we?
C
We
need
to
fetch
any
data
from
any
any
other
data
that
this
depends
on.
Do
we
need
to
do
any
tts
so
sometimes
like
we,
even
though
we
do
have
a
big
library
of
audio
files,
sometimes
we'll
get
like
a
road
name
or
something
that
we
don't
have,
so
we
will
use
tts
to
fill
in
the
gaps
like
do.
C
So
we
have.
We
have
a
simple
nosql
database
running
on
all
the
aggregators,
so
just
in
case
something
fails
and
we
have
to
restart
a
server
it
can
get.
It
can
pull
a
complete
copy
of
all
of
the
data
all
at
once,
so
it,
although
otherwise
we
just
have
like
real-time
data
in
memory
all
the
time
we're
not
doing
a
lot
of
storing
of
it
anywhere
so
yeah,
the
the
master
node
is
there
to
kind
of
handle.
C
C
And
that
that's
that's,
basically,
all
it
is,
and
if,
if
the
leader
goes
down,
all
the
other
nodes
will
see
it
and
they
all
have
a
they
all
have
a
randomly
generated
id,
so
they'll
just
sort
on
the
id
and
if
they're,
at
the
top
of
the
list,
they'll
say
I'm
the
new
leader.
C
So
that
way,
we
basically
as
long
as
any
one
of
those
servers
is
alive.
We
we're
still
running.
We
have
real-time
data.
C
Up
with
so
so,
the
big
message
I
want
to
get
is:
if
anyone
out
there
thinks
that
either
of
these
projects
is
cool
or
interesting,
we
are
hiring
new
developers.
C
We
have
a
couple
new
big
projects
in
the
pipeline
and
I'm
really
kind
of
been
a
development
team
of
one
on
these
projects
for
a
while-
and
I
don't
have
enough
manpower
to
accomplish
everything,
so
we
are
definitely
definitely
hiring
new
developers
and
if
you
know
javascript,
yy,
node.js
or
even
dotnet
stuff,
we
we
want
you,
so
you.
C
So
the
easiest
way
right
now
is
probably
through
email,
stephen.olmstead,
ibi
group.com.
Is
there
a
way?
We
can
add
that
in
a
comment
on
the
video
or
something.
C
Sure
sure
I'm
the
yui
weekly
definitely
and
yeah.
You
can
grab
me
an
irc,
I'm
s
olmstead
on
the
yui
channel
on
freenode,
I'm
usually
hanging
out
there.
Most
of
the
day
are
you
on
twitter
and
I
I
have
a
twitter
but
I've
never
tweeted
anything.
C
Okay,
so
that's
probably
not
the
best
way
to
get
me
or
even
leave
a
comment
on
this
video
on
youtube,
and
I
can
I
can
find
it
the
emails
if
you
email
my
ipi
group,
email
that'll,
be
the
quickest
easiest
way
to
to
grab
me
cool
as.
A
Yeah,
I
think
yeah,
that's
I'm
just
overwhelmed.
I
mean
you've
packed
like
three
three
or
four
you
just
sort
of
casually
said.
Oh
I
implemented
you
know
the
voice
recognition.
I
integrated
asterisks.
Yes,
you
know
just
kind.
C
A
A
C
Yeah,
definitely,
I
think
I
don't
I
don't
imagine
there'd
be
objections
to
it.
I
just
need
to
to
find
the
right
channels
to
get
permission
and
put
a
license
on
it
right
and
it
might
not.
It
might
not
make
it
into
something
like
the
gallery
or
npm,
but
hopefully
it
can
go
up
on
github
or
something
like
that.
Yeah.
As
I
said.
B
C
If
I
had
some
other
developers,
even
just
using
it
and
submitting
bug
reports,
that
would
that
would
help
us
out
yeah
and.
A
C
A
Pretty
cool!
Well,
thanks
again
for
coming.
I
really
appreciate
you
spending
the
time
with
us
and
sharing
all
this
great
stuff
and.
E
A
I
mean
you
know
it
seems
kind
of
understated,
but,
like
you
know,
these
things
are
amazing.
I
mean
I
can
imagine
you
know
this
and,
like
maybe
moodle
are
like
really
the
sort
of
you
know
in
the
trenches
code.
That's
like
really
hardcore.
Really,
it's
just
got
to
work
right.
Your
code
just
has
to
work.
You
know
you
can't
let
phone
calls
be
dropped
and
it's
just
really
testimony
to
like
why.
Why
and
note
how
it's
just.
D
A
You
should
talk
to
dave
dave
glass
because
he's
been
working
with
like
what
you
know:
yui
node,
in
on
like
arduino
and
stuff
like
that
and
there's
this
new
arduino
api
coming
out
and
that's
another
way
of
like
talking
to
hardware,
and
you
know
you
might
have
some
affinity
yeah.
Definitely
you
can
talk
over
the
phone
and
tell
the
the
drone
to
turn
left
to
turn
right.
A
C
Yeah
so
yeah
there's.
I
could
keep
talking
about
this
forever,
like
so,
even
with
ivr
stuff.
We
can
push
that
back
down
to
client
with
some
of
the
new
html5
apis
for
speech,
recognition
or
sometimes
we
can
have
multimodal
interfaces
where
you
might
have.
You
might
call
into
a
phone
system
and
use
speech
recognition
with
that
to
update
your
web
app
interface
like
so
you.
C
D
C
A
Sure
yeah,
let
us
know
if
you
want
to
come
back
on
sometime,
we'll,
definitely
like
to
do
a
follow-up
cool.
A
Here
we
go
cool
well
all
right!
Well,
we're
going
to
close
up
for
now
and
thanks
again
in
terms
of
yy
news,
we're
getting
rounding,
we're
about
to
close
out
this
latest
sprint.
A
We're
gonna
have
basically
code
freeze
this
friday,
then
we'll
do
the
release
branch
and
then
we'll
get
a
release
out
early
april.
So
looking
good
so
far,
all
right.