New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

phoenix_live_view

Package Overview
Dependencies
Maintainers
1
Versions
116
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

phoenix_live_view - npm Package Compare versions

Comparing version 0.1.0-dev to 0.1.0

CHANGELOG.md

982

assets/js/phoenix_live_view.js
/*
================================================================================
Phoenix LiveView Javascript Client
Phoenix LiveView JavaScript Client
================================================================================
## Usage
See the hexdocs at `https://hexdocs.pm/phoenix_live_view` for documentation.
Instantiate a single LiveSocket instances to enable LiveView
client/server interaction, for example:
import LiveSocket from "live_view"
let liveSocket = new LiveSocket("/live")
liveSocket.connect()
A LiveSocket can also be created from an existing socket:
import { Socket } from "phoenix"
import LiveSocket from "live_view"
let socket = new Socket("/live")
let liveSocket = new LiveSocket(socket)
liveSocket.connect()
All options are passed directly to the `Phoenix.Socket` constructor,
except for the following LiveView specific options:
* `bindingPrefix` - the prefix to use for phoenix bindings. Defaults `"phx-"`
## Events
### Click Events
When pushed, the value sent to the server will be chosen with the
following priority:
- An optional `"phx-value"` binding on the clicked element
- The clicked element's `value` property
- An empty string
### Key Events
The onkeypress, onkeydown, and onkeyup events are supported via
the `phx-keypress`, `phx-keydown`, and `phx-keyup` bindings. By
default, the bound element will be the event listener, but an
optional `phx-target` may be provided which may be `"document"`,
`"window"`, or the DOM id of a target element.
When pushed, the value sent to the server will be the event's keyCode.
## Loading state and Errors
By default, the following classes are applied to the Live View's parent
container:
- `"phx-connected"` - applied when the view has connected to the server
- `"phx-disconnected"` - applied when the view is not connected to the server
- `"phx-error"` - applied when an error occurs on the server. Note, this
class will be applied in conjunction with `"phx-disconnected"` connection
to the server is lost.
In addition to applied classes, an empty `"phx-loader"` exists adjacent
to every LiveView, and its display status is toggled automatically based on
connection and error class changes. This behavior may be disabled by overriding
`.phx-loader` in your css to `display: none!important`.
*/
import morphdom from "morphdom"
import {Socket} from "phoenix"
import morphdom from "morphdom"
const PHX_VIEW = "data-phx-view"
const PHX_LIVE_LINK = "data-phx-live-link"
const PHX_CONNECTED_CLASS = "phx-connected"
const PHX_LOADING_CLASS = "phx-loading"
const PHX_DISCONNECTED_CLASS = "phx-disconnected"

@@ -78,12 +22,18 @@ const PHX_ERROR_CLASS = "phx-error"

const PHX_ERROR_FOR = "data-phx-error-for"
const PHX_HAS_FOCUSED = "data-phx-has-focused"
const PHX_HAS_FOCUSED = "phx-has-focused"
const PHX_BOUND = "data-phx-bound"
const FOCUSABLE_INPUTS = ["text", "textarea", "password"]
const PHX_HAS_SUBMITTED = "data-phx-has-submitted"
const FOCUSABLE_INPUTS = ["text", "textarea", "number", "email", "password", "search", "tel", "url"]
const PHX_HAS_SUBMITTED = "phx-has-submitted"
const PHX_SESSION = "data-phx-session"
const PHX_STATIC = "data-phx-static"
const PHX_READONLY = "data-phx-readonly"
const LOADER_TIMEOUT = 100
const LOADER_ZOOM = 2
const PHX_DISABLED = "data-phx-disabled"
const PHX_DISABLE_WITH = "disable-with"
const PHX_HOOK = "hook"
const PHX_UPDATE = "update"
const LOADER_TIMEOUT = 1
const BEFORE_UNLOAD_LOADER_TIMEOUT = 200
const BINDING_PREFIX = "phx-"
const PUSH_TIMEOUT = 20000
const PUSH_TIMEOUT = 30000
const LINK_HEADER = "x-requested-with"

@@ -94,8 +44,23 @@ export let debug = (view, kind, msg, obj) => {

// wraps value in closure or returns closure
let closure = (val) => typeof val === "function" ? val : function(){ return val }
let clone = (obj) => { return JSON.parse(JSON.stringify(obj)) }
let closestPhxBinding = (el, binding) => {
do {
if(el.matches(`[${binding}]`)){ return el }
el = el.parentElement || el.parentNode
} while(el !== null && el.nodeType === 1 && !el.matches(PHX_VIEW_SELECTOR))
return null
}
let isObject = (obj) => {
return typeof(obj) === "object" && !(obj instanceof Array)
return obj !== null && typeof obj === "object" && !(obj instanceof Array)
}
let isEmpty = (obj) => {
return Object.keys(obj).length === 0
for (let x in obj){ return false }
return true
}

@@ -111,7 +76,18 @@

let serializeForm = (form, meta = {}) => {
let formData = new FormData(form)
let params = new URLSearchParams()
for(let [key, val] of formData.entries()){ params.append(key, val) }
for(let metaKey in meta){ params.append(metaKey, meta[metaKey]) }
return params.toString()
}
let recursiveMerge = (target, source) => {
for(let key in source){
let val = source[key]
if(isObject(val) && target[key]){
recursiveMerge(target[key], val)
let targetVal = target[key]
if(isObject(val) && isObject(targetVal)){
if(targetVal.dynamics && !val.dynamics){ delete targetVal.dynamics}
recursiveMerge(targetVal, val)
} else {

@@ -123,4 +99,10 @@ target[key] = val

let Rendered = {
let Session = {
get(el){ return el.getAttribute(PHX_SESSION) },
isEqual(el1, el2){ return this.get(el1) === this.get(el2) }
}
export let Rendered = {
mergeDiff(source, diff){

@@ -135,3 +117,3 @@ if(this.isNewFingerprint(diff)){

isNewFingerprint(diff){ return diff.static },
isNewFingerprint(diff = {}){ return !!diff.static },

@@ -147,3 +129,3 @@ toString(rendered){

let {static: statics} = rendered
output.buffer += statics[0]

@@ -180,32 +162,37 @@ for(let i = 1; i < statics.length; i++){

export class LiveSocket {
constructor(urlOrSocket, opts = {}){
constructor(url, opts = {}){
this.unloaded = false
window.addEventListener("beforeunload", e => {
this.unloaded = true
})
this.socket = this.buildSocket(urlOrSocket, opts)
this.socket.onOpen(() => this.unloaded = false)
this.socket = new Socket(url, opts)
this.bindingPrefix = opts.bindingPrefix || BINDING_PREFIX
this.opts = opts
this.views = {}
this.params = closure(opts.params || {})
this.viewLogger = opts.viewLogger
this.activeElement = null
this.prevActive = null
}
this.prevInput = null
this.prevValue = null
this.silenced = false
this.root = null
this.linkRef = 0
this.href = window.location.href
this.pendingLink = null
this.currentLocation = clone(window.location)
this.hooks = opts.hooks || {}
buildSocket(urlOrSocket, opts){
if(typeof urlOrSocket !== "string"){ return urlOrSocket }
if(!opts.reconnectAfterMs){
opts.reconnectAfterMs = (tries) => {
if(this.unloaded){
return [50, 100, 250][tries - 1] || 500
} else {
return [1000, 2000, 5000, 10000][tries - 1] || 10000
}
this.socket.onOpen(() => {
if(this.isUnloaded()){
this.destroyAllViews()
this.joinRootViews()
}
}
return new Socket(urlOrSocket, opts)
this.unloaded = false
})
window.addEventListener("beforeunload", e => {
this.unloaded = true
})
this.bindTopLevelEvents()
}
getSocket(){ return this.socket }
log(view, kind, msgCallback){

@@ -229,18 +216,62 @@ if(this.viewLogger){

disconnect(){ return this.socket.disconnect()}
disconnect(){ this.socket.disconnect() }
channel(topic, params){ return this.socket.channel(topic, params || {}) }
// private
getHookCallbacks(hookName){ return this.hooks[hookName] }
isUnloaded(){ return this.unloaded }
getBindingPrefix(){ return this.bindingPrefix }
binding(kind){ return `${this.getBindingPrefix()}${kind}` }
channel(topic, params){ return this.socket.channel(topic, params) }
joinRootViews(){
document.querySelectorAll(`${PHX_VIEW_SELECTOR}:not([${PHX_PARENT_ID}])`).forEach(rootEl => {
this.joinView(rootEl)
Browser.all(document, `${PHX_VIEW_SELECTOR}:not([${PHX_PARENT_ID}])`, rootEl => {
let view = this.joinView(rootEl, null, this.getHref())
this.root = this.root || view
})
}
joinView(el, parentView){
let view = new View(el, this, parentView)
replaceRoot(href, callback = null, linkRef = this.setPendingLink(href)){
this.root.showLoader(LOADER_TIMEOUT)
let rootEl = this.root.el
let rootID = this.root.id
let wasLoading = this.root.isLoading()
Browser.fetchPage(href, (status, html) => {
if(status !== 200){ return Browser.redirect(href) }
let div = document.createElement("div")
div.innerHTML = html
this.joinView(div.firstChild, null, href, newRoot => {
if(!this.commitPendingLink(linkRef)){
newRoot.destroy()
return
}
callback && callback()
this.destroyViewById(rootID)
rootEl.replaceWith(newRoot.el)
this.root = newRoot
if(wasLoading){ this.root.showLoader() }
})
})
}
joinView(el, parentView, href, callback){
if(this.getViewById(el.id)){ return }
let view = new View(el, this, parentView, href)
this.views[view.id] = view
view.join()
view.join(callback)
return view
}
owner(childEl, callback){
let view = this.getViewById(maybe(childEl.closest(PHX_VIEW_SELECTOR), "id"))
if(view){ callback(view) }
}
getViewById(id){ return this.views[id] }

@@ -252,2 +283,6 @@

destroyAllViews(){
for(let id in this.views){ this.destroyViewById(id) }
}
destroyViewById(id){

@@ -257,2 +292,3 @@ let view = this.views[id]

delete this.views[view.id]
if(this.root && view.id === this.root.id){ this.root = null }
view.destroy()

@@ -262,4 +298,2 @@ }

getBindingPrefix(){ return this.bindingPrefix }
setActiveElement(target){

@@ -290,3 +324,3 @@ if(this.activeElement === target){ return }

}
restorePreviouslyActiveFocus(){

@@ -302,5 +336,229 @@ if(this.prevActive && this.prevActive !== document.body){

}
bindTopLevelEvents(){
this.bindClicks()
this.bindNav()
this.bindForms()
this.bindTargetable({keyup: "keyup", keydown: "keydown"}, (e, type, view, target, phxEvent, phxTarget) => {
view.pushKey(target, type, phxEvent, {
altGraphKey: e.altGraphKey,
altKey: e.altKey,
charCode: e.charCode,
code: e.code,
ctrlKey: e.ctrlKey,
key: e.key,
keyCode: e.keyCode,
keyIdentifier: e.keyIdentifier,
keyLocation: e.keyLocation,
location: e.location,
metaKey: e.metaKey,
repeat: e.repeat,
shiftKey: e.shiftKey,
which: e.which
})
})
this.bindTargetable({blur: "focusout", focus: "focusin"}, (e, type, view, targetEl, phxEvent, phxTarget) => {
if(!phxTarget){
view.pushEvent(type, targetEl, phxEvent, {type: "focus"})
}
})
this.bindTargetable({blur: "blur", focus: "focus"}, (e, type, view, targetEl, phxEvent, phxTarget) => {
// blur and focus are triggered on document and window. Discard one to avoid dups
if(phxTarget && !phxTarget !== "window"){
view.pushEvent(type, targetEl, phxEvent, {type: e.type})
}
})
}
setPendingLink(href){
this.linkRef++
let ref = this.linkRef
this.pendingLink = href
return this.linkRef
}
commitPendingLink(linkRef){
if(this.linkRef !== linkRef){
return false
} else {
this.href = this.pendingLink
this.pendingLink = null
return true
}
}
getHref(){ return this.href }
hasPendingLink(){ return !!this.pendingLink }
bindTargetable(events, callback){
for(let event in events){
let browserEventName = events[event]
this.on(browserEventName, e => {
let binding = this.binding(event)
let bindTarget = this.binding("target")
let targetPhxEvent = e.target.getAttribute && e.target.getAttribute(binding)
if(targetPhxEvent && !e.target.getAttribute(bindTarget)){
this.owner(e.target, view => callback(e, event, view, e.target, targetPhxEvent, null))
} else {
Browser.all(document, `[${binding}][${bindTarget}=window]`, el => {
let phxEvent = el.getAttribute(binding)
this.owner(el, view => callback(e, event, view, el, phxEvent, "window"))
})
}
})
}
}
bindClicks(){
window.addEventListener("click", e => {
let click = this.binding("click")
let target = closestPhxBinding(e.target, click)
let phxEvent = target && target.getAttribute(click)
if(!phxEvent){ return }
e.preventDefault()
let meta = {
altKey: e.altKey,
shiftKey: e.shiftKey,
ctrlKey: e.ctrlKey,
metaKey: e.metaKey,
x: e.x || e.clientX,
y: e.y || e.clientY,
pageX: e.pageX,
pageY: e.pageY,
screenX: e.screenX,
screenY: e.screenY,
}
this.owner(target, view => view.pushEvent("click", target, phxEvent, meta))
}, false)
}
bindNav(){
if(!Browser.canPushState()){ return }
window.onpopstate = (event) => {
if(!this.registerNewLocation(window.location)){ return }
let href = window.location.href
if(this.root.isConnected()) {
this.root.pushInternalLink(href)
} else {
this.replaceRoot(href)
}
}
window.addEventListener("click", e => {
let target = closestPhxBinding(e.target, PHX_LIVE_LINK)
let phxEvent = target && target.getAttribute(PHX_LIVE_LINK)
if(!phxEvent){ return }
let href = target.href
e.preventDefault()
this.root.pushInternalLink(href, () => {
Browser.pushState(phxEvent, {}, href)
this.registerNewLocation(window.location)
})
}, false)
}
registerNewLocation(newLocation){
let {pathname, search} = this.currentLocation
if(pathname + search === newLocation.pathname + newLocation.search){
return false
} else {
this.currentLocation = clone(newLocation)
return true
}
}
bindForms(){
this.on("submit", e => {
let phxEvent = e.target.getAttribute(this.binding("submit"))
if(!phxEvent){ return }
e.preventDefault()
e.target.disabled = true
this.owner(e.target, view => view.submitForm(e.target, phxEvent))
}, false)
for(let type of ["change", "input"]){
this.on(type, e => {
let input = e.target
let key = input.type === "checkbox" ? "checked" : "value"
if(this.prevInput === input && this.prevValue === input[key]){ return }
this.prevInput = input
this.prevValue = input[key]
let phxEvent = input.form && input.form.getAttribute(this.binding("change"))
if(!phxEvent){ return }
this.owner(input, view => {
if(DOM.isTextualInput(input)){
input[PHX_HAS_FOCUSED] = true
} else {
this.setActiveElement(input)
}
view.pushInput(input, phxEvent, e)
})
}, false)
}
}
silenceEvents(callback){
this.silenced = true
callback()
this.silenced = false
}
on(event, callback){
window.addEventListener(event, e => {
if(!this.silenced){ callback(e) }
})
}
}
let Browser = {
export let Browser = {
all(node, query, callback){
node.querySelectorAll(query).forEach(callback)
},
canPushState(){ return (typeof(history.pushState) !== "undefined") },
fetchPage(href, callback){
let req = new XMLHttpRequest()
req.open("GET", href, true)
req.timeout = PUSH_TIMEOUT
req.setRequestHeader("content-type", "text/html")
req.setRequestHeader("cache-control", "max-age=0, no-cache, no-store, must-revalidate, post-check=0, pre-check=0")
req.setRequestHeader(LINK_HEADER, "live-link")
req.onerror = () => callback(400)
req.ontimeout = () => callback(504)
req.onreadystatechange = () => {
if(req.readyState !== 4){ return }
if(req.getResponseHeader(LINK_HEADER) !== "live-link"){ return callback(400) }
if(req.status !== 200){ return callback(req.status) }
callback(200, req.responseText)
}
req.send()
},
pushState(kind, meta, to){
if(this.canPushState()){
if(to !== window.location.href){ history[kind + "State"](meta, "", to) }
} else {
this.redirect(to)
}
},
dispatchEvent(target, eventString){
let event = null
if(typeof(Event) === "function"){
event = new Event(eventString)
} else {
event = document.createEvent("Event")
event.initEvent(eventString, true, true)
}
target.dispatchEvent(event)
},
setCookie(name, value){

@@ -322,4 +580,15 @@ document.cookie = `${name}=${value}`

setInputsReadOnly(form){
form.querySelectorAll("input").forEach(input => {
disableForm(form, prefix){
let disableWith = `${prefix}${PHX_DISABLE_WITH}`
form.classList.add(PHX_LOADING_CLASS)
Browser.all(form, `[${disableWith}]`, el => {
let value = el.getAttribute(disableWith)
el.setAttribute(`${disableWith}-restore`, el.innerText)
el.innerText = value
})
Browser.all(form, "button", button => {
button.setAttribute(PHX_DISABLED, button.disabled)
button.disabled = true
})
Browser.all(form, "input", input => {
input.setAttribute(PHX_READONLY, input.readOnly)

@@ -330,7 +599,28 @@ input.readOnly = true

restoreReadOnlyInputs(form){
form.querySelectorAll("input").forEach(input => {
restoreDisabledForm(form, prefix){
let disableWith = `${prefix}${PHX_DISABLE_WITH}`
form.classList.remove(PHX_LOADING_CLASS)
Browser.all(form, `[${disableWith}]`, el => {
let value = el.getAttribute(`${disableWith}-restore`)
if(value){
if(el.nodeName === "INPUT") {
el.value = value
} else {
el.innerText = value
}
el.removeAttribute(`${disableWith}-restore`)
}
})
Browser.all(form, "button", button => {
let prev = button.getAttribute(PHX_DISABLED)
if(prev){
button.disabled = prev === "true"
button.removeAttribute(PHX_DISABLED)
}
})
Browser.all(form, "input", input => {
let prev = input.getAttribute(PHX_READONLY)
if(prev){
input.readOnly = prev == "true"
input.readOnly = prev === "true"
input.removeAttribute(PHX_READONLY)

@@ -346,3 +636,3 @@ }

if(field && !(input.getAttribute(PHX_HAS_FOCUSED) || input.form.getAttribute(PHX_HAS_SUBMITTED))){
if(field && !(input[PHX_HAS_FOCUSED] || input.form[PHX_HAS_SUBMITTED])){
el.style.display = "none"

@@ -356,6 +646,31 @@ }

applyPhxUpdate(fromEl, toEl, phxUpdate){
let type = toEl.getAttribute && toEl.getAttribute(phxUpdate)
if(!type || type === "replace"){
return false
} else {
DOM.mergeAttrs(fromEl, toEl)
}
switch(type){
case "ignore": break
case "append":
fromEl.innerHTML += toEl.innerHTML
break
case "prepend":
fromEl.innerHTML = toEl.innerHTML + fromEl.innerHTML
break
default: throw new Error(`unsupported phx-update "${type}"`)
}
return true
},
patch(view, container, id, html){
let changes = {added: [], updated: [], discarded: []}
let focused = view.liveSocket.getActiveElement()
let selectionStart = null
let selectionEnd = null
let phxUpdate = view.liveSocket.binding(PHX_UPDATE)
let containerTagName = container.tagName.toLowerCase()
if(DOM.isTextualInput(focused)){

@@ -366,3 +681,3 @@ selectionStart = focused.selectionStart

morphdom(container, `<div>${html}</div>`, {
morphdom(container, `<${containerTagName}>${html}</${containerTagName}>`, {
childrenOnly: true,

@@ -377,6 +692,7 @@ onBeforeNodeAdded: function(el){

if(DOM.isPhxChild(el) && view.ownsElement(el)){
view.onNewChildAdded(el)
view.onNewChildAdded()
return true
} else {
changes.added.push(el)
}
view.maybeBindAddedNode(el)
},

@@ -389,7 +705,22 @@ onBeforeNodeDiscarded: function(el){

}
changes.discarded.push(el)
},
onBeforeElUpdated: function(fromEl, toEl) {
if(fromEl.isEqualNode(toEl)){ return false } // Skip subtree if both elems and children are equal
if(DOM.applyPhxUpdate(fromEl, toEl, phxUpdate)){
changes.updated.push({fromEl, toEl: fromEl})
return false
}
// nested view handling
if(DOM.isPhxChild(toEl)){
let prevStatic = fromEl.getAttribute(PHX_STATIC)
if(!Session.isEqual(toEl, fromEl)){
view.liveSocket.destroyViewById(fromEl.id)
view.onNewChildAdded()
}
DOM.mergeAttrs(fromEl, toEl)
fromEl.setAttribute(PHX_STATIC, prevStatic)
return false

@@ -399,7 +730,7 @@ }

// input handling
if(fromEl.getAttribute && fromEl.getAttribute(PHX_HAS_SUBMITTED)){
toEl.setAttribute(PHX_HAS_SUBMITTED, true)
if(fromEl.getAttribute && fromEl[PHX_HAS_SUBMITTED]){
toEl[PHX_HAS_SUBMITTED] = true
}
if(fromEl.getAttribute && fromEl.getAttribute(PHX_HAS_FOCUSED)){
toEl.setAttribute(PHX_HAS_FOCUSED, true)
if(fromEl[PHX_HAS_FOCUSED]){
toEl[PHX_HAS_FOCUSED] = true
}

@@ -410,4 +741,6 @@ DOM.discardError(toEl)

DOM.mergeInputs(fromEl, toEl)
changes.updated.push({fromEl, toEl: fromEl})
return false
} else {
changes.updated.push({fromEl, toEl})
return true

@@ -418,11 +751,16 @@ }

DOM.restoreFocus(focused, selectionStart, selectionEnd)
document.dispatchEvent(new Event("phx:update"))
view.liveSocket.silenceEvents(() => {
DOM.restoreFocus(focused, selectionStart, selectionEnd)
})
Browser.dispatchEvent(document, "phx:update")
return changes
},
mergeAttrs(target, source){
source.getAttributeNames().forEach(name => {
var attrs = source.attributes
for (let i = 0, length = attrs.length; i < length; i++){
let name = attrs[i].name
let value = source.getAttribute(name)
target.setAttribute(name, value)
})
}
},

@@ -449,4 +787,4 @@

class View {
constructor(el, liveSocket, parentView){
export class View {
constructor(el, liveSocket, parentView, href){
this.liveSocket = liveSocket

@@ -457,43 +795,73 @@ this.parent = parentView

this.el = el
this.prevKey = null
this.bindingPrefix = liveSocket.getBindingPrefix()
this.loader = this.el.nextElementSibling
this.id = this.el.id
this.view = this.el.getAttribute(PHX_VIEW)
this.hasBoundUI = false
this.loaderTimer = null
this.pendingDiffs = []
this.href = href
this.joinedOnce = false
this.viewHooks = {}
this.channel = this.liveSocket.channel(`lv:${this.id}`, () => {
return {session: this.getSession()}
return {
url: this.href || this.liveSocket.root.href,
params: this.liveSocket.params(this.view),
session: this.getSession(),
static: this.getStatic()
}
})
this.loaderTimer = setTimeout(() => this.showLoader(), LOADER_TIMEOUT)
this.showLoader(LOADER_TIMEOUT)
this.bindChannel()
}
getSession(){
return this.el.getAttribute(PHX_SESSION)|| this.parent.getSession()
isConnected(){ return this.channel.canPush() }
getSession(){ return Session.get(this.el) }
getStatic(){
let val = this.el.getAttribute(PHX_STATIC)
return val === "" ? null : val
}
destroy(callback = function(){}){
clearTimeout(this.loaderTimer)
let onFinished = () => {
callback()
for(let id in this.viewHooks){ this.destroyHook(this.viewHooks[id]) }
}
if(this.hasGracefullyClosed()){
this.log("destroyed", () => ["the server view has gracefully closed"])
callback()
onFinished()
} else {
this.log("destroyed", () => ["the child has been removed from the parent"])
this.channel.leave()
.receive("ok", callback)
.receive("error", callback)
.receive("timeout", callback)
.receive("ok", onFinished)
.receive("error", onFinished)
.receive("timeout", onFinished)
}
}
hideLoader(){
setContainerClasses(...classes){
this.el.classList.remove(
PHX_CONNECTED_CLASS,
PHX_DISCONNECTED_CLASS,
PHX_ERROR_CLASS
)
this.el.classList.add(...classes)
}
isLoading(){ return this.el.classList.contains(PHX_DISCONNECTED_CLASS)}
showLoader(timeout){
clearTimeout(this.loaderTimer)
this.loader.style.display = "none"
if(timeout){
this.loaderTimer = setTimeout(() => this.showLoader(), timeout)
} else {
for(let id in this.viewHooks){ this.viewHooks[id].__trigger__("disconnected") }
this.setContainerClasses(PHX_DISCONNECTED_CLASS)
}
}
showLoader(){
hideLoader(){
clearTimeout(this.loaderTimer)
this.el.classList = PHX_DISCONNECTED_CLASS
this.loader.style.display = "block"
let middle = Math.floor(this.el.clientHeight / LOADER_ZOOM)
this.loader.style.top = `-${middle}px`
for(let id in this.viewHooks){ this.viewHooks[id].__trigger__("reconnected") }
this.setContainerClasses(PHX_CONNECTED_CLASS)
}

@@ -504,20 +872,23 @@

}
onJoin({rendered}){
onJoin({rendered, live_redirect}){
this.log("join", () => ["", JSON.stringify(rendered)])
this.rendered = rendered
this.hideLoader()
this.el.classList = PHX_CONNECTED_CLASS
DOM.patch(this, this.el, this.id, Rendered.toString(this.rendered))
if(!this.hasBoundUI){ this.bindUI() }
this.hasBoundUI = true
let changes = DOM.patch(this, this.el, this.id, Rendered.toString(this.rendered))
changes.added.push(this.el)
Browser.all(this.el, `[${this.binding(PHX_HOOK)}]`, hookEl => changes.added.push(hookEl))
this.triggerHooks(changes)
this.joinNewChildren()
if(live_redirect){
let {kind, to} = live_redirect
Browser.pushState(kind, {}, to)
}
}
joinNewChildren(){
let selector = `${PHX_VIEW_SELECTOR}[${PHX_PARENT_ID}="${this.id}"]`
document.querySelectorAll(selector).forEach(childEl => {
let child = this.liveSocket.getViewById(childEl.id)
Browser.all(document, `${PHX_VIEW_SELECTOR}[${PHX_PARENT_ID}="${this.id}"]`, el => {
let child = this.liveSocket.getViewById(el.id)
if(!child){
this.liveSocket.joinView(childEl, this)
this.liveSocket.joinView(el, this)
}

@@ -529,2 +900,4 @@ })

if(isEmpty(diff)){ return }
if(this.liveSocket.hasPendingLink()){ return this.pendingDiffs.push(diff) }
this.log("update", () => ["", JSON.stringify(diff)])

@@ -534,7 +907,47 @@ this.rendered = Rendered.mergeDiff(this.rendered, diff)

this.newChildrenAdded = false
DOM.patch(this, this.el, this.id, html)
this.triggerHooks(DOM.patch(this, this.el, this.id, html))
if(this.newChildrenAdded){ this.joinNewChildren() }
}
onNewChildAdded(el){
getHook(el){ return this.viewHooks[ViewHook.elementID(el)] }
addHook(el){ if(ViewHook.elementID(el) || !el.getAttribute){ return }
let callbacks = this.liveSocket.getHookCallbacks(el.getAttribute(this.binding(PHX_HOOK)))
if(callbacks && this.ownsElement(el)){
let hook = new ViewHook(this, el, callbacks)
this.viewHooks[ViewHook.elementID(hook.el)] = hook
hook.__trigger__("mounted")
}
}
destroyHook(hook){
hook.__trigger__("destroyed")
delete this.viewHooks[ViewHook.elementID(hook.el)]
}
triggerHooks(changes){
changes.updated.push({fromEl: this.el, toEl: this.el})
changes.added.forEach(el => this.addHook(el))
changes.updated.forEach(({fromEl, toEl}) => {
let hook = this.getHook(fromEl)
let phxAttr = this.binding(PHX_HOOK)
if(hook && toEl.getAttribute && fromEl.getAttribute(phxAttr) === toEl.getAttribute(phxAttr)){
hook.__trigger__("updated")
} else if(hook){
this.destroyHook(hook)
this.addHook(fromEl)
}
})
changes.discarded.forEach(el => {
let hook = this.getHook(el)
hook && this.destroyHook(hook)
})
}
applyPendingUpdates(){
this.pendingDiffs.forEach(diff => this.update(diff))
this.pendingDiffs = []
}
onNewChildAdded(){
this.newChildrenAdded = true

@@ -544,4 +957,6 @@ }

bindChannel(){
this.channel.on("render", (diff) => this.update(diff))
this.channel.on("redirect", ({to, flash}) => Browser.redirect(to, flash) )
this.channel.on("diff", (diff) => this.update(diff))
this.channel.on("redirect", ({to, flash}) => this.onRedirect({to, flash}))
this.channel.on("live_redirect", ({to, kind}) => this.onLiveRedirect({to, kind}))
this.channel.on("external_live_redirect", ({to, kind}) => this.onExternalLiveRedirect({to, kind}))
this.channel.on("session", ({token}) => this.el.setAttribute(PHX_SESSION, token))

@@ -557,12 +972,32 @@ this.channel.onError(reason => this.onError(reason))

onExternalLiveRedirect({to, kind}){
this.liveSocket.replaceRoot(to, () => Browser.pushState(kind, {}, to))
}
onLiveRedirect({to, kind}){
Browser.pushState(kind, {}, to)
}
onRedirect({to, flash}){ Browser.redirect(to, flash) }
hasGracefullyClosed(){ return this.gracefullyClosed }
join(){
if(this.parent){ this.parent.channel.onError(() => this.channel.leave())}
join(callback){
if(this.parent){
this.parent.channel.onClose(() => this.onGracefulClose())
this.parent.channel.onError(() => this.liveSocket.destroyViewById(this.id))
}
this.channel.join()
.receive("ok", data => this.onJoin(data))
.receive("ok", data => {
if(!this.joinedOnce){ callback && callback(this) }
this.joinedOnce = true
this.onJoin(data)
})
.receive("error", resp => this.onJoinError(resp))
.receive("timeout", () => this.onJoinError("timeout"))
}
onJoinError(resp){
if(resp.redirect){ return this.onRedirect(resp.redirect) }
if(resp.external_live_redirect){ return this.onExternalLiveRedirect(resp.external_live_redirect) }
this.displayError()

@@ -576,3 +1011,7 @@ this.log("error", () => ["unable to join", resp])

document.activeElement.blur()
this.displayError()
if(this.liveSocket.isUnloaded()){
this.showLoader(BEFORE_UNLOAD_LOADER_TIMEOUT)
} else {
this.displayError()
}
}

@@ -582,58 +1021,77 @@

this.showLoader()
this.el.classList = `${PHX_DISCONNECTED_CLASS} ${PHX_ERROR_CLASS}`
this.setContainerClasses(PHX_DISCONNECTED_CLASS, PHX_ERROR_CLASS)
}
pushWithReply(event, payload, onReply = function(){ }){
this.channel.push(event, payload, PUSH_TIMEOUT)
.receive("ok", diff => {
this.update(diff)
onReply()
return(
this.channel.push(event, payload, PUSH_TIMEOUT).receive("ok", resp => {
if(resp.diff){ this.update(resp.diff) }
if(resp.redirect){ this.onRedirect(resp.redirect) }
if(resp.live_redirect){ this.onLiveRedirect(resp.live_redirect) }
if(resp.external_live_redirect){ this.onExternalLiveRedirect(resp.external_live_redirect) }
onReply(resp)
})
)
}
pushClick(clickedEl, event, phxEvent){
event.preventDefault()
let val = clickedEl.getAttribute(this.binding("value")) || clickedEl.value || ""
pushEvent(type, el, phxEvent, meta){
let value = el.getAttribute(this.binding("value"))
if(value === null){
value = meta
let prefix = this.binding("value-")
for(let key of el.getAttributeNames()){ if(!key.startsWith(prefix)){ continue }
value[key.replace(prefix, "")] = el.getAttribute(key)
}
if(el.value !== undefined){ value.value = el.value }
}
this.pushWithReply("event", {
type: "click",
type: type,
event: phxEvent,
id: clickedEl.id,
value: val
value: value
})
}
pushKey(keyElement, kind, event, phxEvent){
if(this.prevKey === event.key){ return }
this.prevKey = event.key
pushKey(keyElement, kind, phxEvent, meta){
let value = keyElement.getAttribute(this.binding("value"))
if(value === null){
value = meta
if(keyElement.value !== undefined){ value.value = keyElement.value }
}
this.pushWithReply("event", {
type: `key${kind}`,
type: kind,
event: phxEvent,
id: event.target.id,
value: keyElement.value || event.key
value: value
})
}
pushInput(inputEl, event, phxEvent){
pushInput(inputEl, phxEvent, e){
this.pushWithReply("event", {
type: "form",
event: phxEvent,
id: event.target.id,
value: this.serializeForm(inputEl.form)
value: serializeForm(inputEl.form, {_target: e.target.name})
})
}
pushFormSubmit(formEl, event, phxEvent, onReply){
if(event){ event.target.disabled = true }
pushFormSubmit(formEl, phxEvent, onReply){
this.pushWithReply("event", {
type: "form",
event: phxEvent,
id: event && event.target.id || null,
value: this.serializeForm(formEl)
value: serializeForm(formEl)
}, onReply)
}
eachChild(selector, each){
return this.el.querySelectorAll(selector).forEach(child => {
if(this.ownsElement(child)){ each(child) }
})
pushInternalLink(href, callback){
if(!this.isLoading()){ this.showLoader(LOADER_TIMEOUT) }
let linkRef = this.liveSocket.setPendingLink(href)
this.pushWithReply("link", {url: href}, resp => {
if(resp.link_redirect){
this.liveSocket.replaceRoot(href, callback, linkRef)
} else if(this.liveSocket.commitPendingLink(linkRef)){
this.href = href
this.applyPendingUpdates()
this.hideLoader()
callback && callback()
}
}).receive("timeout", () => Browser.redirect(window.location.href))
}

@@ -646,71 +1104,9 @@

bindUI(){
this.bindForms()
this.eachChild(`[${this.binding("click")}]`, el => this.bindClick(el))
this.eachChild(`[${this.binding("keyup")}]`, el => this.bindKey(el, "up"))
this.eachChild(`[${this.binding("keydown")}]`, el => this.bindKey(el, "down"))
this.eachChild(`[${this.binding("keypress")}]`, el => this.bindKey(el, "press"))
}
bindClick(el){
this.bindOwnAddedNode(el, el, this.binding("click"), phxEvent => {
el.addEventListener("click", e => this.pushClick(el, e, phxEvent))
})
}
bindKey(el, kind){
let event = `key${kind}`
this.bindOwnAddedNode(el, el, this.binding(event), (phxEvent) => {
let phxTarget = this.target(el)
phxTarget.addEventListener(event, e => {
this.pushKey(el, kind, e, phxEvent)
})
})
}
bindForms(){
let change = this.binding("change")
this.eachChild(`form[${change}] input`, input => {
this.bindChange(input)
})
this.eachChild(`form[${change}] select`, input => {
this.bindChange(input)
})
this.eachChild(`form[${change}] textarea`, textarea => {
this.bindChange(textarea)
})
let submit = this.binding("submit")
this.eachChild(`form[${submit}]`, form => {
this.bindSubmit(form)
})
}
bindChange(input){
this.onInput(input, (phxEvent, e) => {
if(DOM.isTextualInput(input)){
input.setAttribute(PHX_HAS_FOCUSED, true)
} else {
this.liveSocket.setActiveElement(e.target)
}
this.pushInput(input, e, phxEvent)
})
}
bindSubmit(form){
this.bindOwnAddedNode(form, form, this.binding("submit"), phxEvent => {
form.addEventListener("submit", e => {
e.preventDefault()
this.submitForm(form, phxEvent, e)
})
this.scheduleSubmit(form, phxEvent)
})
}
submitForm(form, phxEvent, e){
form.setAttribute(PHX_HAS_SUBMITTED, "true")
DOM.setInputsReadOnly(form)
submitForm(form, phxEvent){
let prefix = this.liveSocket.getBindingPrefix()
form[PHX_HAS_SUBMITTED] = "true"
DOM.disableForm(form, prefix)
this.liveSocket.blurActiveElement(this)
this.pushFormSubmit(form, e, phxEvent, () => {
DOM.restoreReadOnlyInputs(form)
this.pushFormSubmit(form, phxEvent, () => {
DOM.restoreDisabledForm(form, prefix)
this.liveSocket.restorePreviouslyActiveFocus()

@@ -720,64 +1116,28 @@ })

scheduleSubmit(form, phxEvent){
let everyMs = parseInt(form.getAttribute(this.binding("submit-every")))
if(everyMs && this.el.contains(form)){
setTimeout(() => {
this.submitForm(form, phxEvent)
this.scheduleSubmit(form, phxEvent)
}, everyMs)
}
}
binding(kind){ return this.liveSocket.binding(kind)}
}
maybeBindAddedNode(el){
if(!el.getAttribute || !this.ownsElement(el)) { return }
let viewHookID = 1
class ViewHook {
static makeID(){ return viewHookID++ }
static elementID(el){ return el.phxHookId }
this.bindClick(el)
this.bindSubmit(el)
this.bindChange(el)
this.bindKey(el, "up")
this.bindKey(el, "down")
this.bindKey(el, "press")
constructor(view, el, callbacks){
this.__view = view
this.__callbacks = callbacks
this.el = el
this.viewName = view.view
this.el.phxHookId = this.constructor.makeID()
for(let key in this.__callbacks){ this[key] = this.__callbacks[key] }
}
binding(kind){ return `${this.bindingPrefix}${kind}` }
// private
serializeForm(form){
return((new URLSearchParams(new FormData(form))).toString())
pushEvent(event, payload){
this.__view.pushWithReply("event", {type: "hook", event: event, value: payload})
}
bindOwnAddedNode(el, targetEl, event, callback){
if(targetEl && !targetEl.getAttribute){ return }
let phxEvent = targetEl.getAttribute(event)
if(phxEvent && !el.getAttribute(PHX_BOUND) && this.ownsElement(el)){
el.setAttribute(PHX_BOUND, true)
callback(phxEvent)
}
__trigger__(kind){
let callback = this.__callbacks[kind]
callback && callback.call(this)
}
onInput(input, callback){
if(!input.form){ return }
this.bindOwnAddedNode(input, input.form, this.binding("change"), phxEvent => {
let event = input.type === "radio" ? "change" : "input"
input.addEventListener(event, e => callback(phxEvent, e))
})
}
target(el){
let target = el.getAttribute(this.binding("target"))
if(target === "window"){
return window
}else if(target === "document"){
return document
} else if(target){
return document.getElementById(target)
} else {
return el
}
}
}
export default LiveSocket

@@ -10,13 +10,16 @@ {

"build": "webpack --mode production",
"watch": "webpack --mode development --watch"
"watch": "webpack --mode development --watch",
"test": "jest",
"test.coverage": "jest --coverage",
"test.watch": "jest --watch"
},
"dependencies": {
"morphdom": "^2.3.3",
"phoenix": "file:~/oss/phoenix",
"morphdom": "2.5.5",
"phoenix": "file:../deps/phoenix",
"phoenix_html": "file:../deps/phoenix_html"
},
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.3",
"babel-preset-env": "^1.6.1",
"@babel/core": "^7.3.4",
"@babel/preset-env": "^7.4.1",
"babel-loader": "^8.0.5",
"copy-webpack-plugin": "^4.5.0",

@@ -26,7 +29,11 @@ "css-loader": "^0.28.10",

"extract-text-webpack-plugin": "^4.0.0-beta.0",
"jasmine": "^3.3.1",
"jest": "^24.5.0",
"style-loader": "^0.20.2",
"wait-for-expect": "^1.1.0",
"webpack": "4.0.0",
"webpack-cli": "^2.0.10"
},
"jest": {
"testRegex": "/test/.*_test\\.js$"
}
}
{
"name": "phoenix_live_view",
"version": "0.1.0-dev",
"description": "The JavaScript client for the Phoenix LiveView",
"version": "0.1.0",
"description": "The Phoenix LiveView JavaScript client.",
"license": "MIT",

@@ -6,0 +6,0 @@ "main": "./priv/static/phoenix_live_view.js",

@@ -1,1 +0,1 @@

!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.phoenix_live_view=t():e.phoenix_live_view=t()}(this,function(){return function(e){var t={};function n(i){if(t[i])return t[i].exports;var o=t[i]={i:i,l:!1,exports:{}};return e[i].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:i})},n.r=function(e){Object.defineProperty(e,"__esModule",{value:!0})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=4)}([function(e,t,n){"use strict";var i,o="http://www.w3.org/1999/xhtml",r="undefined"==typeof document?void 0:document,s=r?r.body||r.createElement("div"):{},u=s.hasAttributeNS?function(e,t,n){return e.hasAttributeNS(t,n)}:s.hasAttribute?function(e,t,n){return e.hasAttribute(n)}:function(e,t,n){return null!=e.getAttributeNode(t,n)};function a(e,t){var n=e.nodeName,i=t.nodeName;return n===i||!!(t.actualize&&n.charCodeAt(0)<91&&i.charCodeAt(0)>90)&&n===i.toUpperCase()}function c(e,t,n){e[n]!==t[n]&&(e[n]=t[n],e[n]?e.setAttribute(n,""):e.removeAttribute(n,""))}var l={OPTION:function(e,t){c(e,t,"selected")},INPUT:function(e,t){c(e,t,"checked"),c(e,t,"disabled"),e.value!==t.value&&(e.value=t.value),u(t,null,"value")||e.removeAttribute("value")},TEXTAREA:function(e,t){var n=t.value;e.value!==n&&(e.value=n);var i=e.firstChild;if(i){var o=i.nodeValue;if(o==n||!n&&o==e.placeholder)return;i.nodeValue=n}},SELECT:function(e,t){if(!u(t,null,"multiple")){for(var n=0,i=t.firstChild;i;){var o=i.nodeName;if(o&&"OPTION"===o.toUpperCase()){if(u(i,null,"selected")){n;break}n++}i=i.nextSibling}e.selectedIndex=n}}},h=1,f=3,d=8;function v(){}function p(e){return e.id}var y=function(e){return function(t,n,s){if(s||(s={}),"string"==typeof n)if("#document"===t.nodeName||"HTML"===t.nodeName){var u=n;(n=r.createElement("html")).innerHTML=u}else c=n,!i&&r.createRange&&(i=r.createRange()).selectNode(r.body),i&&i.createContextualFragment?y=i.createContextualFragment(c):(y=r.createElement("body")).innerHTML=c,n=y.childNodes[0];var c,y,m,g=s.getNodeKey||p,b=s.onBeforeNodeAdded||v,k=s.onNodeAdded||v,w=s.onBeforeElUpdated||v,E=s.onElUpdated||v,x=s.onBeforeNodeDiscarded||v,A=s.onNodeDiscarded||v,C=s.onBeforeElChildrenUpdated||v,S=!0===s.childrenOnly,j={};function R(e){m?m.push(e):m=[e]}function T(e,t,n){!1!==x(e)&&(t&&t.removeChild(e),A(e),function e(t,n){if(t.nodeType===h)for(var i=t.firstChild;i;){var o=void 0;n&&(o=g(i))?R(o):(A(i),i.firstChild&&e(i,n)),i=i.nextSibling}}(e,n))}function O(e){k(e);for(var t=e.firstChild;t;){var n=t.nextSibling,i=g(t);if(i){var o=j[i];o&&a(t,o)&&(t.parentNode.replaceChild(o,t),N(o,t))}O(t),t=n}}function N(i,o,s){var u,c=g(o);if(c&&delete j[c],!n.isSameNode||!n.isSameNode(t)){if(!s){if(!1===w(i,o))return;if(e(i,o),E(i),!1===C(i,o))return}if("TEXTAREA"!==i.nodeName){var v,p,y,m,k=o.firstChild,x=i.firstChild;e:for(;k;){for(y=k.nextSibling,v=g(k);x;){if(p=x.nextSibling,k.isSameNode&&k.isSameNode(x)){k=y,x=p;continue e}u=g(x);var A=x.nodeType,S=void 0;if(A===k.nodeType&&(A===h?(v?v!==u&&((m=j[v])?x.nextSibling===m?S=!1:(i.insertBefore(m,x),p=x.nextSibling,u?R(u):T(x,i,!0),x=m):S=!1):u&&(S=!1),(S=!1!==S&&a(x,k))&&N(x,k)):A!==f&&A!=d||(S=!0,x.nodeValue!==k.nodeValue&&(x.nodeValue=k.nodeValue))),S){k=y,x=p;continue e}u?R(u):T(x,i,!0),x=p}if(v&&(m=j[v])&&a(m,k))i.appendChild(m),N(m,k);else{var L=b(k);!1!==L&&(L&&(k=L),k.actualize&&(k=k.actualize(i.ownerDocument||r)),i.appendChild(k),O(k))}k=y,x=p}for(;x;)p=x.nextSibling,(u=g(x))?R(u):T(x,i,!0),x=p}var P=l[i.nodeName];P&&P(i,o)}}!function e(t){if(t.nodeType===h)for(var n=t.firstChild;n;){var i=g(n);i&&(j[i]=n),e(n),n=n.nextSibling}}(t);var L,P,I=t,_=I.nodeType,B=n.nodeType;if(!S)if(_===h)B===h?a(t,n)||(A(t),I=function(e,t){for(var n=e.firstChild;n;){var i=n.nextSibling;t.appendChild(n),n=i}return t}(t,(L=n.nodeName,(P=n.namespaceURI)&&P!==o?r.createElementNS(P,L):r.createElement(L)))):I=n;else if(_===f||_===d){if(B===_)return I.nodeValue!==n.nodeValue&&(I.nodeValue=n.nodeValue),I;I=n}if(I===n)A(t);else if(N(I,n,S),m)for(var M=0,U=m.length;M<U;M++){var J=j[m[M]];J&&T(J,J.parentNode,!1)}return!S&&I!==t&&t.parentNode&&(I.actualize&&(I=I.actualize(t.ownerDocument||r)),t.parentNode.replaceChild(I,t)),I}}(function(e,t){var n,i,o,r,s,a=t.attributes;for(n=a.length-1;n>=0;--n)o=(i=a[n]).name,r=i.namespaceURI,s=i.value,r?(o=i.localName||o,e.getAttributeNS(r,o)!==s&&e.setAttributeNS(r,o,s)):e.getAttribute(o)!==s&&e.setAttribute(o,s);for(n=(a=e.attributes).length-1;n>=0;--n)!1!==(i=a[n]).specified&&(o=i.name,(r=i.namespaceURI)?(o=i.localName||o,u(t,r,o)||e.removeAttributeNS(r,o)):u(t,null,o)||e.removeAttribute(o))});e.exports=y},function(e,t,n){e.exports=function(e){var t={};function n(i){if(t[i])return t[i].exports;var o=t[i]={i:i,l:!1,exports:{}};return e[i].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(i,o,function(t){return e[t]}.bind(null,o));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){(function(t){e.exports=t.Phoenix=n(2)}).call(this,n(1))},function(e,t){var n;n=function(){return this}();try{n=n||Function("return this")()||(0,eval)("this")}catch(e){"object"==typeof window&&(n=window)}e.exports=n},function(e,t,n){"use strict";function i(e){return(i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function r(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}function s(e,t,n){return t&&r(e.prototype,t),n&&r(e,n),e}n.r(t),n.d(t,"Channel",function(){return g}),n.d(t,"Socket",function(){return k}),n.d(t,"LongPoll",function(){return w}),n.d(t,"Ajax",function(){return E}),n.d(t,"Presence",function(){return x});var u="undefined"!=typeof self?self:null,a="undefined"!=typeof window?window:null,c=u||a||void 0,l={connecting:0,open:1,closing:2,closed:3},h=1e4,f={closed:"closed",errored:"errored",joined:"joined",joining:"joining",leaving:"leaving"},d={close:"phx_close",error:"phx_error",join:"phx_join",reply:"phx_reply",leave:"phx_leave"},v=[d.close,d.error,d.join,d.reply,d.leave],p={longpoll:"longpoll",websocket:"websocket"},y=function(e){return"function"==typeof e?e:function(){return e}},m=function(){function e(t,n,i,r){o(this,e),this.channel=t,this.event=n,this.payload=i||function(){return{}},this.receivedResp=null,this.timeout=r,this.timeoutTimer=null,this.recHooks=[],this.sent=!1}return s(e,[{key:"resend",value:function(e){this.timeout=e,this.reset(),this.send()}},{key:"send",value:function(){this.hasReceived("timeout")||(this.startTimeout(),this.sent=!0,this.channel.socket.push({topic:this.channel.topic,event:this.event,payload:this.payload(),ref:this.ref,join_ref:this.channel.joinRef()}))}},{key:"receive",value:function(e,t){return this.hasReceived(e)&&t(this.receivedResp.response),this.recHooks.push({status:e,callback:t}),this}},{key:"reset",value:function(){this.cancelRefEvent(),this.ref=null,this.refEvent=null,this.receivedResp=null,this.sent=!1}},{key:"matchReceive",value:function(e){var t=e.status,n=e.response;e.ref,this.recHooks.filter(function(e){return e.status===t}).forEach(function(e){return e.callback(n)})}},{key:"cancelRefEvent",value:function(){this.refEvent&&this.channel.off(this.refEvent)}},{key:"cancelTimeout",value:function(){clearTimeout(this.timeoutTimer),this.timeoutTimer=null}},{key:"startTimeout",value:function(){var e=this;this.timeoutTimer&&this.cancelTimeout(),this.ref=this.channel.socket.makeRef(),this.refEvent=this.channel.replyEventName(this.ref),this.channel.on(this.refEvent,function(t){e.cancelRefEvent(),e.cancelTimeout(),e.receivedResp=t,e.matchReceive(t)}),this.timeoutTimer=setTimeout(function(){e.trigger("timeout",{})},this.timeout)}},{key:"hasReceived",value:function(e){return this.receivedResp&&this.receivedResp.status===e}},{key:"trigger",value:function(e,t){this.channel.trigger(this.refEvent,{status:e,response:t})}}]),e}(),g=function(){function e(t,n,i){var r=this;o(this,e),this.state=f.closed,this.topic=t,this.params=y(n||{}),this.socket=i,this.bindings=[],this.bindingRef=0,this.timeout=this.socket.timeout,this.joinedOnce=!1,this.joinPush=new m(this,d.join,this.params,this.timeout),this.pushBuffer=[],this.rejoinTimer=new A(function(){return r.rejoinUntilConnected()},this.socket.reconnectAfterMs),this.joinPush.receive("ok",function(){r.state=f.joined,r.rejoinTimer.reset(),r.pushBuffer.forEach(function(e){return e.send()}),r.pushBuffer=[]}),this.onClose(function(){r.rejoinTimer.reset(),r.socket.hasLogger()&&r.socket.log("channel","close ".concat(r.topic," ").concat(r.joinRef())),r.state=f.closed,r.socket.remove(r)}),this.onError(function(e){r.isLeaving()||r.isClosed()||(r.socket.hasLogger()&&r.socket.log("channel","error ".concat(r.topic),e),r.state=f.errored,r.rejoinTimer.scheduleTimeout())}),this.joinPush.receive("timeout",function(){r.isJoining()&&(r.socket.hasLogger()&&r.socket.log("channel","timeout ".concat(r.topic," (").concat(r.joinRef(),")"),r.joinPush.timeout),new m(r,d.leave,y({}),r.timeout).send(),r.state=f.errored,r.joinPush.reset(),r.rejoinTimer.scheduleTimeout())}),this.on(d.reply,function(e,t){r.trigger(r.replyEventName(t),e)})}return s(e,[{key:"rejoinUntilConnected",value:function(){this.rejoinTimer.scheduleTimeout(),this.socket.isConnected()&&this.rejoin()}},{key:"join",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.timeout;if(this.joinedOnce)throw new Error("tried to join multiple times. 'join' can only be called a single time per channel instance");return this.joinedOnce=!0,this.rejoin(e),this.joinPush}},{key:"onClose",value:function(e){this.on(d.close,e)}},{key:"onError",value:function(e){return this.on(d.error,function(t){return e(t)})}},{key:"on",value:function(e,t){var n=this.bindingRef++;return this.bindings.push({event:e,ref:n,callback:t}),n}},{key:"off",value:function(e,t){this.bindings=this.bindings.filter(function(n){return!(n.event===e&&(void 0===t||t===n.ref))})}},{key:"canPush",value:function(){return this.socket.isConnected()&&this.isJoined()}},{key:"push",value:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:this.timeout;if(!this.joinedOnce)throw new Error("tried to push '".concat(e,"' to '").concat(this.topic,"' before joining. Use channel.join() before pushing events"));var i=new m(this,e,function(){return t},n);return this.canPush()?i.send():(i.startTimeout(),this.pushBuffer.push(i)),i}},{key:"leave",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.timeout;this.state=f.leaving;var n=function(){e.socket.hasLogger()&&e.socket.log("channel","leave ".concat(e.topic)),e.trigger(d.close,"leave")},i=new m(this,d.leave,y({}),t);return i.receive("ok",function(){return n()}).receive("timeout",function(){return n()}),i.send(),this.canPush()||i.trigger("ok",{}),i}},{key:"onMessage",value:function(e,t,n){return t}},{key:"isLifecycleEvent",value:function(e){return v.indexOf(e)>=0}},{key:"isMember",value:function(e,t,n,i){return!(this.topic!==e||i&&i!==this.joinRef()&&this.isLifecycleEvent(t)&&(this.socket.hasLogger()&&this.socket.log("channel","dropping outdated message",{topic:e,event:t,payload:n,joinRef:i}),1))}},{key:"joinRef",value:function(){return this.joinPush.ref}},{key:"sendJoin",value:function(e){this.state=f.joining,this.joinPush.resend(e)}},{key:"rejoin",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.timeout;this.isLeaving()||this.sendJoin(e)}},{key:"trigger",value:function(e,t,n,i){var o=this.onMessage(e,t,n,i);if(t&&!o)throw new Error("channel onMessage callbacks must return the payload, modified or unmodified");for(var r=0;r<this.bindings.length;r++){var s=this.bindings[r];s.event===e&&s.callback(o,n,i||this.joinRef())}}},{key:"replyEventName",value:function(e){return"chan_reply_".concat(e)}},{key:"isClosed",value:function(){return this.state===f.closed}},{key:"isErrored",value:function(){return this.state===f.errored}},{key:"isJoined",value:function(){return this.state===f.joined}},{key:"isJoining",value:function(){return this.state===f.joining}},{key:"isLeaving",value:function(){return this.state===f.leaving}}]),e}(),b={encode:function(e,t){var n=[e.join_ref,e.ref,e.topic,e.event,e.payload];return t(JSON.stringify(n))},decode:function(e,t){var n=function(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=[],i=!0,o=!1,r=void 0;try{for(var s,u=e[Symbol.iterator]();!(i=(s=u.next()).done)&&(n.push(s.value),!t||n.length!==t);i=!0);}catch(e){o=!0,r=e}finally{try{i||null==u.return||u.return()}finally{if(o)throw r}}return n}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}(JSON.parse(e),5);return t({join_ref:n[0],ref:n[1],topic:n[2],event:n[3],payload:n[4]})}},k=function(){function e(t){var n=this,i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};o(this,e),this.stateChangeCallbacks={open:[],close:[],error:[],message:[]},this.channels=[],this.sendBuffer=[],this.ref=0,this.timeout=i.timeout||h,this.transport=i.transport||c.WebSocket||w,this.defaultEncoder=b.encode,this.defaultDecoder=b.decode,this.transport!==w?(this.encode=i.encode||this.defaultEncoder,this.decode=i.decode||this.defaultDecoder):(this.encode=this.defaultEncoder,this.decode=this.defaultDecoder),this.heartbeatIntervalMs=i.heartbeatIntervalMs||3e4,this.reconnectAfterMs=i.reconnectAfterMs||function(e){return[1e3,2e3,5e3,1e4][e-1]||1e4},this.logger=i.logger||null,this.longpollerTimeout=i.longpollerTimeout||2e4,this.params=y(i.params||{}),this.endPoint="".concat(t,"/").concat(p.websocket),this.heartbeatTimer=null,this.pendingHeartbeatRef=null,this.reconnectTimer=new A(function(){n.teardown(function(){return n.connect()})},this.reconnectAfterMs)}return s(e,[{key:"protocol",value:function(){return location.protocol.match(/^https/)?"wss":"ws"}},{key:"endPointURL",value:function(){var e=E.appendParams(E.appendParams(this.endPoint,this.params()),{vsn:"2.0.0"});return"/"!==e.charAt(0)?e:"/"===e.charAt(1)?"".concat(this.protocol(),":").concat(e):"".concat(this.protocol(),"://").concat(location.host).concat(e)}},{key:"disconnect",value:function(e,t,n){this.reconnectTimer.reset(),this.teardown(e,t,n)}},{key:"connect",value:function(e){var t=this;e&&(console&&console.log("passing params to connect is deprecated. Instead pass :params to the Socket constructor"),this.params=y(e)),this.conn||(this.conn=new this.transport(this.endPointURL()),this.conn.timeout=this.longpollerTimeout,this.conn.onopen=function(){return t.onConnOpen()},this.conn.onerror=function(e){return t.onConnError(e)},this.conn.onmessage=function(e){return t.onConnMessage(e)},this.conn.onclose=function(e){return t.onConnClose(e)})}},{key:"log",value:function(e,t,n){this.logger(e,t,n)}},{key:"hasLogger",value:function(){return null!==this.logger}},{key:"onOpen",value:function(e){this.stateChangeCallbacks.open.push(e)}},{key:"onClose",value:function(e){this.stateChangeCallbacks.close.push(e)}},{key:"onError",value:function(e){this.stateChangeCallbacks.error.push(e)}},{key:"onMessage",value:function(e){this.stateChangeCallbacks.message.push(e)}},{key:"onConnOpen",value:function(){this.hasLogger()&&this.log("transport","connected to ".concat(this.endPointURL())),this.flushSendBuffer(),this.reconnectTimer.reset(),this.resetHeartbeat(),this.stateChangeCallbacks.open.forEach(function(e){return e()})}},{key:"resetHeartbeat",value:function(){var e=this;this.conn.skipHeartbeat||(this.pendingHeartbeatRef=null,clearInterval(this.heartbeatTimer),this.heartbeatTimer=setInterval(function(){return e.sendHeartbeat()},this.heartbeatIntervalMs))}},{key:"teardown",value:function(e,t,n){this.conn&&(this.conn.onclose=function(){},t?this.conn.close(t,n||""):this.conn.close(),this.conn=null),e&&e()}},{key:"onConnClose",value:function(e){this.hasLogger()&&this.log("transport","close",e),this.triggerChanError(),clearInterval(this.heartbeatTimer),e&&1e3!==e.code&&this.reconnectTimer.scheduleTimeout(),this.stateChangeCallbacks.close.forEach(function(t){return t(e)})}},{key:"onConnError",value:function(e){this.hasLogger()&&this.log("transport",e),this.triggerChanError(),this.stateChangeCallbacks.error.forEach(function(t){return t(e)})}},{key:"triggerChanError",value:function(){this.channels.forEach(function(e){return e.trigger(d.error)})}},{key:"connectionState",value:function(){switch(this.conn&&this.conn.readyState){case l.connecting:return"connecting";case l.open:return"open";case l.closing:return"closing";default:return"closed"}}},{key:"isConnected",value:function(){return"open"===this.connectionState()}},{key:"remove",value:function(e){this.channels=this.channels.filter(function(t){return t.joinRef()!==e.joinRef()})}},{key:"channel",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=new g(e,t,this);return this.channels.push(n),n}},{key:"push",value:function(e){var t=this;if(this.hasLogger()){var n=e.topic,i=e.event,o=e.payload,r=e.ref,s=e.join_ref;this.log("push","".concat(n," ").concat(i," (").concat(s,", ").concat(r,")"),o)}this.isConnected()?this.encode(e,function(e){return t.conn.send(e)}):this.sendBuffer.push(function(){return t.encode(e,function(e){return t.conn.send(e)})})}},{key:"makeRef",value:function(){var e=this.ref+1;return e===this.ref?this.ref=0:this.ref=e,this.ref.toString()}},{key:"sendHeartbeat",value:function(){if(this.isConnected()){if(this.pendingHeartbeatRef)return this.pendingHeartbeatRef=null,this.hasLogger()&&this.log("transport","heartbeat timeout. Attempting to re-establish connection"),void this.conn.close(1e3,"hearbeat timeout");this.pendingHeartbeatRef=this.makeRef(),this.push({topic:"phoenix",event:"heartbeat",payload:{},ref:this.pendingHeartbeatRef})}}},{key:"flushSendBuffer",value:function(){this.isConnected()&&this.sendBuffer.length>0&&(this.sendBuffer.forEach(function(e){return e()}),this.sendBuffer=[])}},{key:"onConnMessage",value:function(e){var t=this;this.decode(e.data,function(e){var n=e.topic,i=e.event,o=e.payload,r=e.ref,s=e.join_ref;r&&r===t.pendingHeartbeatRef&&(t.pendingHeartbeatRef=null),t.hasLogger()&&t.log("receive","".concat(o.status||""," ").concat(n," ").concat(i," ").concat(r&&"("+r+")"||""),o);for(var u=0;u<t.channels.length;u++){var a=t.channels[u];a.isMember(n,i,o,s)&&a.trigger(i,o,r,s)}for(var c=0;c<t.stateChangeCallbacks.message.length;c++)t.stateChangeCallbacks.message[c](e)})}}]),e}(),w=function(){function e(t){o(this,e),this.endPoint=null,this.token=null,this.skipHeartbeat=!0,this.onopen=function(){},this.onerror=function(){},this.onmessage=function(){},this.onclose=function(){},this.pollEndpoint=this.normalizeEndpoint(t),this.readyState=l.connecting,this.poll()}return s(e,[{key:"normalizeEndpoint",value:function(e){return e.replace("ws://","http://").replace("wss://","https://").replace(new RegExp("(.*)/"+p.websocket),"$1/"+p.longpoll)}},{key:"endpointURL",value:function(){return E.appendParams(this.pollEndpoint,{token:this.token})}},{key:"closeAndRetry",value:function(){this.close(),this.readyState=l.connecting}},{key:"ontimeout",value:function(){this.onerror("timeout"),this.closeAndRetry()}},{key:"poll",value:function(){var e=this;this.readyState!==l.open&&this.readyState!==l.connecting||E.request("GET",this.endpointURL(),"application/json",null,this.timeout,this.ontimeout.bind(this),function(t){if(t){var n=t.status,i=t.token,o=t.messages;e.token=i}else n=0;switch(n){case 200:o.forEach(function(t){return e.onmessage({data:t})}),e.poll();break;case 204:e.poll();break;case 410:e.readyState=l.open,e.onopen(),e.poll();break;case 0:case 500:e.onerror(),e.closeAndRetry();break;default:throw new Error("unhandled poll status ".concat(n))}})}},{key:"send",value:function(e){var t=this;E.request("POST",this.endpointURL(),"application/json",e,this.timeout,this.onerror.bind(this,"timeout"),function(e){e&&200===e.status||(t.onerror(e&&e.status),t.closeAndRetry())})}},{key:"close",value:function(e,t){this.readyState=l.closed,this.onclose()}}]),e}(),E=function(){function e(){o(this,e)}return s(e,null,[{key:"request",value:function(e,t,n,i,o,r,s){if(c.XDomainRequest){var u=new XDomainRequest;this.xdomainRequest(u,e,t,i,o,r,s)}else{var a=c.XMLHttpRequest?new c.XMLHttpRequest:new ActiveXObject("Microsoft.XMLHTTP");this.xhrRequest(a,e,t,n,i,o,r,s)}}},{key:"xdomainRequest",value:function(e,t,n,i,o,r,s){var u=this;e.timeout=o,e.open(t,n),e.onload=function(){var t=u.parseJSON(e.responseText);s&&s(t)},r&&(e.ontimeout=r),e.onprogress=function(){},e.send(i)}},{key:"xhrRequest",value:function(e,t,n,i,o,r,s,u){var a=this;e.open(t,n,!0),e.timeout=r,e.setRequestHeader("Content-Type",i),e.onerror=function(){u&&u(null)},e.onreadystatechange=function(){if(e.readyState===a.states.complete&&u){var t=a.parseJSON(e.responseText);u(t)}},s&&(e.ontimeout=s),e.send(o)}},{key:"parseJSON",value:function(e){if(!e||""===e)return null;try{return JSON.parse(e)}catch(t){return console&&console.log("failed to parse JSON response",e),null}}},{key:"serialize",value:function(e,t){var n=[];for(var o in e)if(e.hasOwnProperty(o)){var r=t?"".concat(t,"[").concat(o,"]"):o,s=e[o];"object"===i(s)?n.push(this.serialize(s,r)):n.push(encodeURIComponent(r)+"="+encodeURIComponent(s))}return n.join("&")}},{key:"appendParams",value:function(e,t){if(0===Object.keys(t).length)return e;var n=e.match(/\?/)?"&":"?";return"".concat(e).concat(n).concat(this.serialize(t))}}]),e}();E.states={complete:4};var x=function(){function e(t){var n=this,i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};o(this,e);var r=i.events||{state:"presence_state",diff:"presence_diff"};this.state={},this.pendingDiffs=[],this.channel=t,this.joinRef=null,this.caller={onJoin:function(){},onLeave:function(){},onSync:function(){}},this.channel.on(r.state,function(t){var i=n.caller,o=i.onJoin,r=i.onLeave,s=i.onSync;n.joinRef=n.channel.joinRef(),n.state=e.syncState(n.state,t,o,r),n.pendingDiffs.forEach(function(t){n.state=e.syncDiff(n.state,t,o,r)}),n.pendingDiffs=[],s()}),this.channel.on(r.diff,function(t){var i=n.caller,o=i.onJoin,r=i.onLeave,s=i.onSync;n.inPendingSyncState()?n.pendingDiffs.push(t):(n.state=e.syncDiff(n.state,t,o,r),s())})}return s(e,[{key:"onJoin",value:function(e){this.caller.onJoin=e}},{key:"onLeave",value:function(e){this.caller.onLeave=e}},{key:"onSync",value:function(e){this.caller.onSync=e}},{key:"list",value:function(t){return e.list(this.state,t)}},{key:"inPendingSyncState",value:function(){return!this.joinRef||this.joinRef!==this.channel.joinRef()}}],[{key:"syncState",value:function(e,t,n,i){var o=this,r=this.clone(e),s={},u={};return this.map(r,function(e,n){t[e]||(u[e]=n)}),this.map(t,function(e,t){var n=r[e];if(n){var i=t.metas.map(function(e){return e.phx_ref}),a=n.metas.map(function(e){return e.phx_ref}),c=t.metas.filter(function(e){return a.indexOf(e.phx_ref)<0}),l=n.metas.filter(function(e){return i.indexOf(e.phx_ref)<0});c.length>0&&(s[e]=t,s[e].metas=c),l.length>0&&(u[e]=o.clone(n),u[e].metas=l)}else s[e]=t}),this.syncDiff(r,{joins:s,leaves:u},n,i)}},{key:"syncDiff",value:function(e,t,n,i){var o=t.joins,r=t.leaves,s=this.clone(e);return n||(n=function(){}),i||(i=function(){}),this.map(o,function(e,t){var i=s[e];if(s[e]=t,i){var o,r=s[e].metas.map(function(e){return e.phx_ref}),u=i.metas.filter(function(e){return r.indexOf(e.phx_ref)<0});(o=s[e].metas).unshift.apply(o,function(e){return function(e){if(Array.isArray(e)){for(var t=0,n=new Array(e.length);t<e.length;t++)n[t]=e[t];return n}}(e)||function(e){if(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e))return Array.from(e)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance")}()}(u))}n(e,i,t)}),this.map(r,function(e,t){var n=s[e];if(n){var o=t.metas.map(function(e){return e.phx_ref});n.metas=n.metas.filter(function(e){return o.indexOf(e.phx_ref)<0}),i(e,n,t),0===n.metas.length&&delete s[e]}}),s}},{key:"list",value:function(e,t){return t||(t=function(e,t){return t}),this.map(e,function(e,n){return t(e,n)})}},{key:"map",value:function(e,t){return Object.getOwnPropertyNames(e).map(function(n){return t(n,e[n])})}},{key:"clone",value:function(e){return JSON.parse(JSON.stringify(e))}}]),e}(),A=function(){function e(t,n){o(this,e),this.callback=t,this.timerCalc=n,this.timer=null,this.tries=0}return s(e,[{key:"reset",value:function(){this.tries=0,clearTimeout(this.timer)}},{key:"scheduleTimeout",value:function(){var e=this;clearTimeout(this.timer),this.timer=setTimeout(function(){e.tries=e.tries+1,e.callback()},this.timerCalc(this.tries+1))}}]),e}()}])},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.LiveSocket=t.debug=void 0;var i,o=function(){return function(e,t){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return function(e,t){var n=[],i=!0,o=!1,r=void 0;try{for(var s,u=e[Symbol.iterator]();!(i=(s=u.next()).done)&&(n.push(s.value),!t||n.length!==t);i=!0);}catch(e){o=!0,r=e}finally{try{!i&&u.return&&u.return()}finally{if(o)throw r}}return n}(e,t);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),r=function(){function e(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}return function(t,n,i){return n&&e(t.prototype,n),i&&e(t,i),t}}(),s="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},u=n(1),a=n(0),c=(i=a)&&i.__esModule?i:{default:i};function l(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var h="data-phx-view",f="["+h+"]",d=["text","textarea","password"],v=100,p="phx-",y=(t.debug=function(e,t,n,i){console.log(e.id+" "+t+": "+n+" - ",i)},function(e){return"object"===(void 0===e?"undefined":s(e))&&!(e instanceof Array)}),m={mergeDiff:function(e,t){return this.isNewFingerprint(t)?t:(function e(t,n){for(var i in n){var o=n[i];y(o)&&t[i]?e(t[i],o):t[i]=o}}(e,t),e)},isNewFingerprint:function(e){return e.static},toString:function(e){var t={buffer:""};return this.toOutputBuffer(e,t),t.buffer},toOutputBuffer:function(e,t){if(e.dynamics)return this.comprehensionToBuffer(e,t);var n=e.static;t.buffer+=n[0];for(var i=1;i<n.length;i++)this.dynamicToBuffer(e[i-1],t),t.buffer+=n[i]},comprehensionToBuffer:function(e,t){for(var n=e.dynamics,i=e.static,o=0;o<n.length;o++){var r=n[o];t.buffer+=i[0];for(var s=1;s<i.length;s++)this.dynamicToBuffer(r[s-1],t),t.buffer+=i[s]}},dynamicToBuffer:function(e,t){y(e)?this.toOutputBuffer(e,t):t.buffer+=e}},g=t.LiveSocket=function(){function e(t){var n=this,i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};l(this,e),this.unloaded=!1,window.addEventListener("beforeunload",function(e){n.unloaded=!0}),this.socket=this.buildSocket(t,i),this.socket.onOpen(function(){return n.unloaded=!1}),this.bindingPrefix=i.bindingPrefix||p,this.opts=i,this.views={},this.viewLogger=i.viewLogger,this.activeElement=null,this.prevActive=null}return r(e,[{key:"buildSocket",value:function(e,t){var n=this;return"string"!=typeof e?e:(t.reconnectAfterMs||(t.reconnectAfterMs=function(e){return n.unloaded?[50,100,250][e-1]||500:[1e3,2e3,5e3,1e4][e-1]||1e4}),new u.Socket(e,t))}},{key:"log",value:function(e,t,n){if(this.viewLogger){var i=n(),r=o(i,2),s=r[0],u=r[1];this.viewLogger(e,t,s,u)}}},{key:"connect",value:function(){var e=this;return["complete","loaded","interactive"].indexOf(document.readyState)>=0?this.joinRootViews():document.addEventListener("DOMContentLoaded",function(){e.joinRootViews()}),this.socket.connect()}},{key:"disconnect",value:function(){return this.socket.disconnect()}},{key:"channel",value:function(e,t){return this.socket.channel(e,t||{})}},{key:"joinRootViews",value:function(){var e=this;document.querySelectorAll(f+":not([data-phx-parent-id])").forEach(function(t){e.joinView(t)})}},{key:"joinView",value:function(e,t){var n=new w(e,this,t);this.views[n.id]=n,n.join()}},{key:"getViewById",value:function(e){return this.views[e]}},{key:"onViewError",value:function(e){this.dropActiveElement(e)}},{key:"destroyViewById",value:function(e){var t=this.views[e];t&&(delete this.views[t.id],t.destroy())}},{key:"getBindingPrefix",value:function(){return this.bindingPrefix}},{key:"setActiveElement",value:function(e){var t=this;if(this.activeElement!==e){this.activeElement=e;var n=function(){e===t.activeElement&&(t.activeElement=null),e.removeEventListener("mouseup",t),e.removeEventListener("touchend",t)};e.addEventListener("mouseup",n),e.addEventListener("touchend",n)}}},{key:"getActiveElement",value:function(){return document.activeElement===document.body&&this.activeElement||document.activeElement}},{key:"dropActiveElement",value:function(e){this.prevActive&&e.ownsElement(this.prevActive)&&(this.prevActive=null)}},{key:"restorePreviouslyActiveFocus",value:function(){this.prevActive&&this.prevActive!==document.body&&this.prevActive.focus()}},{key:"blurActiveElement",value:function(){this.prevActive=this.getActiveElement(),this.prevActive!==document.body&&this.prevActive.blur()}}]),e}(),b={setCookie:function(e,t){document.cookie=e+"="+t},getCookie:function(e){return document.cookie.replace(new RegExp("(?:(?:^|.*;s*)"+e+"s*=s*([^;]*).*$)|^.*$"),"$1")},redirect:function(e,t){t&&b.setCookie("__phoenix_flash__",t+"; max-age=60000; path=/"),window.location=e}},k={setInputsReadOnly:function(e){e.querySelectorAll("input").forEach(function(e){e.setAttribute("data-phx-readonly",e.readOnly),e.readOnly=!0})},restoreReadOnlyInputs:function(e){e.querySelectorAll("input").forEach(function(e){var t=e.getAttribute("data-phx-readonly");t&&(e.readOnly="true"==t,e.removeAttribute("data-phx-readonly"))})},discardError:function(e){var t=e.getAttribute&&e.getAttribute("data-phx-error-for");if(t){var n=document.getElementById(t);!t||n.getAttribute("data-phx-has-focused")||n.form.getAttribute("data-phx-has-submitted")||(e.style.display="none")}},isPhxChild:function(e){return e.getAttribute&&e.getAttribute("data-phx-parent-id")},patch:function(e,t,n,i){var o=e.liveSocket.getActiveElement(),r=null,s=null;k.isTextualInput(o)&&(r=o.selectionStart,s=o.selectionEnd),(0,c.default)(t,"<div>"+i+"</div>",{childrenOnly:!0,onBeforeNodeAdded:function(e){return k.discardError(e),e},onNodeAdded:function(t){if(k.isPhxChild(t)&&e.ownsElement(t))return e.onNewChildAdded(t),!0;e.maybeBindAddedNode(t)},onBeforeNodeDiscarded:function(t){if(k.isPhxChild(t))return e.liveSocket.destroyViewById(t.id),!0},onBeforeElUpdated:function(e,t){return k.isPhxChild(t)?(k.mergeAttrs(e,t),!1):(e.getAttribute&&e.getAttribute("data-phx-has-submitted")&&t.setAttribute("data-phx-has-submitted",!0),e.getAttribute&&e.getAttribute("data-phx-has-focused")&&t.setAttribute("data-phx-has-focused",!0),k.discardError(t),!k.isTextualInput(e)||e!==o||(k.mergeInputs(e,t),!1))}}),k.restoreFocus(o,r,s),document.dispatchEvent(new Event("phx:update"))},mergeAttrs:function(e,t){t.getAttributeNames().forEach(function(n){var i=t.getAttribute(n);e.setAttribute(n,i)})},mergeInputs:function(e,t){k.mergeAttrs(e,t),e.readOnly=t.readOnly},restoreFocus:function(e,t,n){k.isTextualInput(e)&&((""===e.value||e.readOnly)&&e.blur(),e.focus(),(e.setSelectionRange&&"text"===e.type||"textarea"===e.type)&&e.setSelectionRange(t,n))},isTextualInput:function(e){return d.indexOf(e.type)>=0}},w=function(){function e(t,n,i){var o=this;l(this,e),this.liveSocket=n,this.parent=i,this.newChildrenAdded=!1,this.gracefullyClosed=!1,this.el=t,this.prevKey=null,this.bindingPrefix=n.getBindingPrefix(),this.loader=this.el.nextElementSibling,this.id=this.el.id,this.view=this.el.getAttribute(h),this.hasBoundUI=!1,this.channel=this.liveSocket.channel("lv:"+this.id,function(){return{session:o.getSession()}}),this.loaderTimer=setTimeout(function(){return o.showLoader()},v),this.bindChannel()}return r(e,[{key:"getSession",value:function(){return this.el.getAttribute("data-phx-session")||this.parent.getSession()}},{key:"destroy",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:function(){};this.hasGracefullyClosed()?(this.log("destroyed",function(){return["the server view has gracefully closed"]}),e()):(this.log("destroyed",function(){return["the child has been removed from the parent"]}),this.channel.leave().receive("ok",e).receive("error",e).receive("timeout",e))}},{key:"hideLoader",value:function(){clearTimeout(this.loaderTimer),this.loader.style.display="none"}},{key:"showLoader",value:function(){clearTimeout(this.loaderTimer),this.el.classList="phx-disconnected",this.loader.style.display="block";var e=Math.floor(this.el.clientHeight/2);this.loader.style.top="-"+e+"px"}},{key:"log",value:function(e,t){this.liveSocket.log(this,e,t)}},{key:"onJoin",value:function(e){var t=e.rendered;this.log("join",function(){return["",JSON.stringify(t)]}),this.rendered=t,this.hideLoader(),this.el.classList="phx-connected",k.patch(this,this.el,this.id,m.toString(this.rendered)),this.hasBoundUI||this.bindUI(),this.hasBoundUI=!0,this.joinNewChildren()}},{key:"joinNewChildren",value:function(){var e=this,t=f+'[data-phx-parent-id="'+this.id+'"]';document.querySelectorAll(t).forEach(function(t){e.liveSocket.getViewById(t.id)||e.liveSocket.joinView(t,e)})}},{key:"update",value:function(e){if(t=e,0!==Object.keys(t).length){var t;this.log("update",function(){return["",JSON.stringify(e)]}),this.rendered=m.mergeDiff(this.rendered,e);var n=m.toString(this.rendered);this.newChildrenAdded=!1,k.patch(this,this.el,this.id,n),this.newChildrenAdded&&this.joinNewChildren()}}},{key:"onNewChildAdded",value:function(e){this.newChildrenAdded=!0}},{key:"bindChannel",value:function(){var e=this;this.channel.on("render",function(t){return e.update(t)}),this.channel.on("redirect",function(e){var t=e.to,n=e.flash;return b.redirect(t,n)}),this.channel.on("session",function(t){var n=t.token;return e.el.setAttribute("data-phx-session",n)}),this.channel.onError(function(t){return e.onError(t)}),this.channel.onClose(function(){return e.onGracefulClose()})}},{key:"onGracefulClose",value:function(){this.gracefullyClosed=!0,this.liveSocket.destroyViewById(this.id)}},{key:"hasGracefullyClosed",value:function(){return this.gracefullyClosed}},{key:"join",value:function(){var e=this;this.parent&&this.parent.channel.onError(function(){return e.channel.leave()}),this.channel.join().receive("ok",function(t){return e.onJoin(t)}).receive("error",function(t){return e.onJoinError(t)})}},{key:"onJoinError",value:function(e){this.displayError(),this.log("error",function(){return["unable to join",e]})}},{key:"onError",value:function(e){this.log("error",function(){return["view crashed",e]}),this.liveSocket.onViewError(this),document.activeElement.blur(),this.displayError()}},{key:"displayError",value:function(){this.showLoader(),this.el.classList="phx-disconnected phx-error"}},{key:"pushWithReply",value:function(e,t){var n=this,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:function(){};this.channel.push(e,t,2e4).receive("ok",function(e){n.update(e),i()})}},{key:"pushClick",value:function(e,t,n){t.preventDefault();var i=e.getAttribute(this.binding("value"))||e.value||"";this.pushWithReply("event",{type:"click",event:n,id:e.id,value:i})}},{key:"pushKey",value:function(e,t,n,i){this.prevKey!==n.key&&(this.prevKey=n.key,this.pushWithReply("event",{type:"key"+t,event:i,id:n.target.id,value:e.value||n.key}))}},{key:"pushInput",value:function(e,t,n){this.pushWithReply("event",{type:"form",event:n,id:t.target.id,value:this.serializeForm(e.form)})}},{key:"pushFormSubmit",value:function(e,t,n,i){t&&(t.target.disabled=!0),this.pushWithReply("event",{type:"form",event:n,id:t&&t.target.id||null,value:this.serializeForm(e)},i)}},{key:"eachChild",value:function(e,t){var n=this;return this.el.querySelectorAll(e).forEach(function(e){n.ownsElement(e)&&t(e)})}},{key:"ownsElement",value:function(e){return e.getAttribute("data-phx-parent-id")===this.id||((t=e.closest(f))?t["id"]:null)===this.id;var t}},{key:"bindUI",value:function(){var e=this;this.bindForms(),this.eachChild("["+this.binding("click")+"]",function(t){return e.bindClick(t)}),this.eachChild("["+this.binding("keyup")+"]",function(t){return e.bindKey(t,"up")}),this.eachChild("["+this.binding("keydown")+"]",function(t){return e.bindKey(t,"down")}),this.eachChild("["+this.binding("keypress")+"]",function(t){return e.bindKey(t,"press")})}},{key:"bindClick",value:function(e){var t=this;this.bindOwnAddedNode(e,e,this.binding("click"),function(n){e.addEventListener("click",function(i){return t.pushClick(e,i,n)})})}},{key:"bindKey",value:function(e,t){var n=this,i="key"+t;this.bindOwnAddedNode(e,e,this.binding(i),function(o){n.target(e).addEventListener(i,function(i){n.pushKey(e,t,i,o)})})}},{key:"bindForms",value:function(){var e=this,t=this.binding("change");this.eachChild("form["+t+"] input",function(t){e.bindChange(t)}),this.eachChild("form["+t+"] select",function(t){e.bindChange(t)}),this.eachChild("form["+t+"] textarea",function(t){e.bindChange(t)});var n=this.binding("submit");this.eachChild("form["+n+"]",function(t){e.bindSubmit(t)})}},{key:"bindChange",value:function(e){var t=this;this.onInput(e,function(n,i){k.isTextualInput(e)?e.setAttribute("data-phx-has-focused",!0):t.liveSocket.setActiveElement(i.target),t.pushInput(e,i,n)})}},{key:"bindSubmit",value:function(e){var t=this;this.bindOwnAddedNode(e,e,this.binding("submit"),function(n){e.addEventListener("submit",function(i){i.preventDefault(),t.submitForm(e,n,i)}),t.scheduleSubmit(e,n)})}},{key:"submitForm",value:function(e,t,n){var i=this;e.setAttribute("data-phx-has-submitted","true"),k.setInputsReadOnly(e),this.liveSocket.blurActiveElement(this),this.pushFormSubmit(e,n,t,function(){k.restoreReadOnlyInputs(e),i.liveSocket.restorePreviouslyActiveFocus()})}},{key:"scheduleSubmit",value:function(e,t){var n=this,i=parseInt(e.getAttribute(this.binding("submit-every")));i&&this.el.contains(e)&&setTimeout(function(){n.submitForm(e,t),n.scheduleSubmit(e,t)},i)}},{key:"maybeBindAddedNode",value:function(e){e.getAttribute&&this.ownsElement(e)&&(this.bindClick(e),this.bindSubmit(e),this.bindChange(e),this.bindKey(e,"up"),this.bindKey(e,"down"),this.bindKey(e,"press"))}},{key:"binding",value:function(e){return""+this.bindingPrefix+e}},{key:"serializeForm",value:function(e){return new URLSearchParams(new FormData(e)).toString()}},{key:"bindOwnAddedNode",value:function(e,t,n,i){if(!t||t.getAttribute){var o=t.getAttribute(n);o&&!e.getAttribute("data-phx-bound")&&this.ownsElement(e)&&(e.setAttribute("data-phx-bound",!0),i(o))}}},{key:"onInput",value:function(e,t){e.form&&this.bindOwnAddedNode(e,e.form,this.binding("change"),function(n){var i="radio"===e.type?"change":"input";e.addEventListener(i,function(e){return t(n,e)})})}},{key:"target",value:function(e){var t=e.getAttribute(this.binding("target"));return"window"===t?window:"document"===t?document:t?document.getElementById(t):e}}]),e}();t.default=g},function(e,t){var n;n=function(){return this}();try{n=n||Function("return this")()||(0,eval)("this")}catch(e){"object"==typeof window&&(n=window)}e.exports=n},function(e,t,n){(function(t){t.Phoenix||(t.Phoenix={}),e.exports=t.Phoenix.LiveView=n(2)}).call(this,n(3))}])});
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.phoenix_live_view=t():e.phoenix_live_view=t()}(this,function(){return function(e){var t={};function n(i){if(t[i])return t[i].exports;var o=t[i]={i:i,l:!1,exports:{}};return e[i].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:i})},n.r=function(e){Object.defineProperty(e,"__esModule",{value:!0})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=4)}([function(e,t,n){(function(e){var n,i,o;function r(e){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}!function(s,a){"object"==r(t)&&"object"==r(e)?e.exports=a():(i=[],void 0===(o="function"==typeof(n=a)?n.apply(t,i):n)||(e.exports=o))}(0,function(){return function(e){var t={};function n(i){if(t[i])return t[i].exports;var o=t[i]={i:i,l:!1,exports:{}};return e[i].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==r(e)&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(i,o,function(t){return e[t]}.bind(null,o));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){(function(t){e.exports=t.Phoenix=n(2)}).call(this,n(1))},function(e,t){var n;n=function(){return this}();try{n=n||Function("return this")()||(0,eval)("this")}catch(e){"object"==("undefined"==typeof window?"undefined":r(window))&&(n=window)}e.exports=n},function(e,t,n){"use strict";function i(e){return(i="function"==typeof Symbol&&"symbol"==r(Symbol.iterator)?function(e){return r(e)}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":r(e)})(e)}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function s(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}function a(e,t,n){return t&&s(e.prototype,t),n&&s(e,n),e}n.r(t),n.d(t,"Channel",function(){return k}),n.d(t,"Serializer",function(){return b}),n.d(t,"Socket",function(){return w}),n.d(t,"LongPoll",function(){return E}),n.d(t,"Ajax",function(){return x}),n.d(t,"Presence",function(){return S});var u="undefined"!=typeof self?self:null,c="undefined"!=typeof window?window:null,l=u||c||void 0,h={connecting:0,open:1,closing:2,closed:3},f=1e4,d={closed:"closed",errored:"errored",joined:"joined",joining:"joining",leaving:"leaving"},v={close:"phx_close",error:"phx_error",join:"phx_join",reply:"phx_reply",leave:"phx_leave"},p=[v.close,v.error,v.join,v.reply,v.leave],y={longpoll:"longpoll",websocket:"websocket"},g=function(e){return"function"==typeof e?e:function(){return e}},m=function(){function e(t,n,i,r){o(this,e),this.channel=t,this.event=n,this.payload=i||function(){return{}},this.receivedResp=null,this.timeout=r,this.timeoutTimer=null,this.recHooks=[],this.sent=!1}return a(e,[{key:"resend",value:function(e){this.timeout=e,this.reset(),this.send()}},{key:"send",value:function(){this.hasReceived("timeout")||(this.startTimeout(),this.sent=!0,this.channel.socket.push({topic:this.channel.topic,event:this.event,payload:this.payload(),ref:this.ref,join_ref:this.channel.joinRef()}))}},{key:"receive",value:function(e,t){return this.hasReceived(e)&&t(this.receivedResp.response),this.recHooks.push({status:e,callback:t}),this}},{key:"reset",value:function(){this.cancelRefEvent(),this.ref=null,this.refEvent=null,this.receivedResp=null,this.sent=!1}},{key:"matchReceive",value:function(e){var t=e.status,n=e.response;e.ref,this.recHooks.filter(function(e){return e.status===t}).forEach(function(e){return e.callback(n)})}},{key:"cancelRefEvent",value:function(){this.refEvent&&this.channel.off(this.refEvent)}},{key:"cancelTimeout",value:function(){clearTimeout(this.timeoutTimer),this.timeoutTimer=null}},{key:"startTimeout",value:function(){var e=this;this.timeoutTimer&&this.cancelTimeout(),this.ref=this.channel.socket.makeRef(),this.refEvent=this.channel.replyEventName(this.ref),this.channel.on(this.refEvent,function(t){e.cancelRefEvent(),e.cancelTimeout(),e.receivedResp=t,e.matchReceive(t)}),this.timeoutTimer=setTimeout(function(){e.trigger("timeout",{})},this.timeout)}},{key:"hasReceived",value:function(e){return this.receivedResp&&this.receivedResp.status===e}},{key:"trigger",value:function(e,t){this.channel.trigger(this.refEvent,{status:e,response:t})}}]),e}(),k=function(){function e(t,n,i){var r=this;o(this,e),this.state=d.closed,this.topic=t,this.params=g(n||{}),this.socket=i,this.bindings=[],this.bindingRef=0,this.timeout=this.socket.timeout,this.joinedOnce=!1,this.joinPush=new m(this,v.join,this.params,this.timeout),this.pushBuffer=[],this.rejoinTimer=new C(function(){r.socket.isConnected()&&r.rejoin()},this.socket.rejoinAfterMs),this.socket.onError(function(){return r.rejoinTimer.reset()}),this.socket.onOpen(function(){r.rejoinTimer.reset(),r.isErrored()&&r.rejoin()}),this.joinPush.receive("ok",function(){r.state=d.joined,r.rejoinTimer.reset(),r.pushBuffer.forEach(function(e){return e.send()}),r.pushBuffer=[]}),this.joinPush.receive("error",function(){r.state=d.errored,r.socket.isConnected()&&r.rejoinTimer.scheduleTimeout()}),this.onClose(function(){r.rejoinTimer.reset(),r.socket.hasLogger()&&r.socket.log("channel","close ".concat(r.topic," ").concat(r.joinRef())),r.state=d.closed,r.socket.remove(r)}),this.onError(function(e){r.socket.hasLogger()&&r.socket.log("channel","error ".concat(r.topic),e),r.isJoining()&&r.joinPush.reset(),r.state=d.errored,r.socket.isConnected()&&r.rejoinTimer.scheduleTimeout()}),this.joinPush.receive("timeout",function(){r.socket.hasLogger()&&r.socket.log("channel","timeout ".concat(r.topic," (").concat(r.joinRef(),")"),r.joinPush.timeout),new m(r,v.leave,g({}),r.timeout).send(),r.state=d.errored,r.joinPush.reset(),r.socket.isConnected()&&r.rejoinTimer.scheduleTimeout()}),this.on(v.reply,function(e,t){r.trigger(r.replyEventName(t),e)})}return a(e,[{key:"join",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.timeout;if(this.joinedOnce)throw new Error("tried to join multiple times. 'join' can only be called a single time per channel instance");return this.timeout=e,this.joinedOnce=!0,this.rejoin(),this.joinPush}},{key:"onClose",value:function(e){this.on(v.close,e)}},{key:"onError",value:function(e){return this.on(v.error,function(t){return e(t)})}},{key:"on",value:function(e,t){var n=this.bindingRef++;return this.bindings.push({event:e,ref:n,callback:t}),n}},{key:"off",value:function(e,t){this.bindings=this.bindings.filter(function(n){return!(n.event===e&&(void 0===t||t===n.ref))})}},{key:"canPush",value:function(){return this.socket.isConnected()&&this.isJoined()}},{key:"push",value:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:this.timeout;if(!this.joinedOnce)throw new Error("tried to push '".concat(e,"' to '").concat(this.topic,"' before joining. Use channel.join() before pushing events"));var i=new m(this,e,function(){return t},n);return this.canPush()?i.send():(i.startTimeout(),this.pushBuffer.push(i)),i}},{key:"leave",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.timeout;this.rejoinTimer.reset(),this.joinPush.cancelTimeout(),this.state=d.leaving;var n=function(){e.socket.hasLogger()&&e.socket.log("channel","leave ".concat(e.topic)),e.trigger(v.close,"leave")},i=new m(this,v.leave,g({}),t);return i.receive("ok",function(){return n()}).receive("timeout",function(){return n()}),i.send(),this.canPush()||i.trigger("ok",{}),i}},{key:"onMessage",value:function(e,t,n){return t}},{key:"isLifecycleEvent",value:function(e){return p.indexOf(e)>=0}},{key:"isMember",value:function(e,t,n,i){return!(this.topic!==e||i&&i!==this.joinRef()&&this.isLifecycleEvent(t)&&(this.socket.hasLogger()&&this.socket.log("channel","dropping outdated message",{topic:e,event:t,payload:n,joinRef:i}),1))}},{key:"joinRef",value:function(){return this.joinPush.ref}},{key:"sendJoin",value:function(e){this.state=d.joining,this.joinPush.resend(e)}},{key:"rejoin",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.timeout;this.isLeaving()||this.sendJoin(e)}},{key:"trigger",value:function(e,t,n,i){var o=this.onMessage(e,t,n,i);if(t&&!o)throw new Error("channel onMessage callbacks must return the payload, modified or unmodified");for(var r=0;r<this.bindings.length;r++){var s=this.bindings[r];s.event===e&&s.callback(o,n,i||this.joinRef())}}},{key:"replyEventName",value:function(e){return"chan_reply_".concat(e)}},{key:"isClosed",value:function(){return this.state===d.closed}},{key:"isErrored",value:function(){return this.state===d.errored}},{key:"isJoined",value:function(){return this.state===d.joined}},{key:"isJoining",value:function(){return this.state===d.joining}},{key:"isLeaving",value:function(){return this.state===d.leaving}}]),e}(),b={encode:function(e,t){var n=[e.join_ref,e.ref,e.topic,e.event,e.payload];return t(JSON.stringify(n))},decode:function(e,t){var n=function(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=[],i=!0,o=!1,r=void 0;try{for(var s,a=e[Symbol.iterator]();!(i=(s=a.next()).done)&&(n.push(s.value),!t||n.length!==t);i=!0);}catch(e){o=!0,r=e}finally{try{i||null==a.return||a.return()}finally{if(o)throw r}}return n}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}(JSON.parse(e),5);return t({join_ref:n[0],ref:n[1],topic:n[2],event:n[3],payload:n[4]})}},w=function(){function e(t){var n=this,i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};o(this,e),this.stateChangeCallbacks={open:[],close:[],error:[],message:[]},this.channels=[],this.sendBuffer=[],this.ref=0,this.timeout=i.timeout||f,this.transport=i.transport||l.WebSocket||E,this.defaultEncoder=b.encode,this.defaultDecoder=b.decode,this.closeWasClean=!1,this.unloaded=!1,this.binaryType=i.binaryType||"arraybuffer",this.transport!==E?(this.encode=i.encode||this.defaultEncoder,this.decode=i.decode||this.defaultDecoder):(this.encode=this.defaultEncoder,this.decode=this.defaultDecoder),c&&c.addEventListener&&c.addEventListener("beforeunload",function(e){n.conn&&(n.unloaded=!0,n.abnormalClose("unloaded"))}),this.heartbeatIntervalMs=i.heartbeatIntervalMs||3e4,this.rejoinAfterMs=function(e){return i.rejoinAfterMs?i.rejoinAfterMs(e):[1e3,2e3,5e3][e-1]||1e4},this.reconnectAfterMs=function(e){return n.unloaded?100:i.reconnectAfterMs?i.reconnectAfterMs(e):[10,50,100,150,200,250,500,1e3,2e3][e-1]||5e3},this.logger=i.logger||null,this.longpollerTimeout=i.longpollerTimeout||2e4,this.params=g(i.params||{}),this.endPoint="".concat(t,"/").concat(y.websocket),this.heartbeatTimer=null,this.pendingHeartbeatRef=null,this.reconnectTimer=new C(function(){n.teardown(function(){return n.connect()})},this.reconnectAfterMs)}return a(e,[{key:"protocol",value:function(){return location.protocol.match(/^https/)?"wss":"ws"}},{key:"endPointURL",value:function(){var e=x.appendParams(x.appendParams(this.endPoint,this.params()),{vsn:"2.0.0"});return"/"!==e.charAt(0)?e:"/"===e.charAt(1)?"".concat(this.protocol(),":").concat(e):"".concat(this.protocol(),"://").concat(location.host).concat(e)}},{key:"disconnect",value:function(e,t,n){this.closeWasClean=!0,this.reconnectTimer.reset(),this.teardown(e,t,n)}},{key:"connect",value:function(e){var t=this;e&&(console&&console.log("passing params to connect is deprecated. Instead pass :params to the Socket constructor"),this.params=g(e)),this.conn||(this.closeWasClean=!1,this.conn=new this.transport(this.endPointURL()),this.conn.binaryType=this.binaryType,this.conn.timeout=this.longpollerTimeout,this.conn.onopen=function(){return t.onConnOpen()},this.conn.onerror=function(e){return t.onConnError(e)},this.conn.onmessage=function(e){return t.onConnMessage(e)},this.conn.onclose=function(e){return t.onConnClose(e)})}},{key:"log",value:function(e,t,n){this.logger(e,t,n)}},{key:"hasLogger",value:function(){return null!==this.logger}},{key:"onOpen",value:function(e){this.stateChangeCallbacks.open.push(e)}},{key:"onClose",value:function(e){this.stateChangeCallbacks.close.push(e)}},{key:"onError",value:function(e){this.stateChangeCallbacks.error.push(e)}},{key:"onMessage",value:function(e){this.stateChangeCallbacks.message.push(e)}},{key:"onConnOpen",value:function(){this.hasLogger()&&this.log("transport","connected to ".concat(this.endPointURL())),this.unloaded=!1,this.closeWasClean=!1,this.flushSendBuffer(),this.reconnectTimer.reset(),this.resetHeartbeat(),this.stateChangeCallbacks.open.forEach(function(e){return e()})}},{key:"resetHeartbeat",value:function(){var e=this;this.conn&&this.conn.skipHeartbeat||(this.pendingHeartbeatRef=null,clearInterval(this.heartbeatTimer),this.heartbeatTimer=setInterval(function(){return e.sendHeartbeat()},this.heartbeatIntervalMs))}},{key:"teardown",value:function(e,t,n){this.conn&&(this.conn.onclose=function(){},t?this.conn.close(t,n||""):this.conn.close(),this.conn=null),e&&e()}},{key:"onConnClose",value:function(e){this.hasLogger()&&this.log("transport","close",e),this.triggerChanError(),clearInterval(this.heartbeatTimer),this.closeWasClean||this.reconnectTimer.scheduleTimeout(),this.stateChangeCallbacks.close.forEach(function(t){return t(e)})}},{key:"onConnError",value:function(e){this.hasLogger()&&this.log("transport",e),this.triggerChanError(),this.stateChangeCallbacks.error.forEach(function(t){return t(e)})}},{key:"triggerChanError",value:function(){this.channels.forEach(function(e){e.isErrored()||e.isLeaving()||e.isClosed()||e.trigger(v.error)})}},{key:"connectionState",value:function(){switch(this.conn&&this.conn.readyState){case h.connecting:return"connecting";case h.open:return"open";case h.closing:return"closing";default:return"closed"}}},{key:"isConnected",value:function(){return"open"===this.connectionState()}},{key:"remove",value:function(e){this.channels=this.channels.filter(function(t){return t.joinRef()!==e.joinRef()})}},{key:"channel",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=new k(e,t,this);return this.channels.push(n),n}},{key:"push",value:function(e){var t=this;if(this.hasLogger()){var n=e.topic,i=e.event,o=e.payload,r=e.ref,s=e.join_ref;this.log("push","".concat(n," ").concat(i," (").concat(s,", ").concat(r,")"),o)}this.isConnected()?this.encode(e,function(e){return t.conn.send(e)}):this.sendBuffer.push(function(){return t.encode(e,function(e){return t.conn.send(e)})})}},{key:"makeRef",value:function(){var e=this.ref+1;return e===this.ref?this.ref=0:this.ref=e,this.ref.toString()}},{key:"sendHeartbeat",value:function(){if(this.isConnected()){if(this.pendingHeartbeatRef)return this.pendingHeartbeatRef=null,this.hasLogger()&&this.log("transport","heartbeat timeout. Attempting to re-establish connection"),void this.abnormalClose("heartbeat timeout");this.pendingHeartbeatRef=this.makeRef(),this.push({topic:"phoenix",event:"heartbeat",payload:{},ref:this.pendingHeartbeatRef})}}},{key:"abnormalClose",value:function(e){this.closeWasClean=!1,this.conn.close(1e3,e)}},{key:"flushSendBuffer",value:function(){this.isConnected()&&this.sendBuffer.length>0&&(this.sendBuffer.forEach(function(e){return e()}),this.sendBuffer=[])}},{key:"onConnMessage",value:function(e){var t=this;this.decode(e.data,function(e){var n=e.topic,i=e.event,o=e.payload,r=e.ref,s=e.join_ref;r&&r===t.pendingHeartbeatRef&&(t.pendingHeartbeatRef=null),t.hasLogger()&&t.log("receive","".concat(o.status||""," ").concat(n," ").concat(i," ").concat(r&&"("+r+")"||""),o);for(var a=0;a<t.channels.length;a++){var u=t.channels[a];u.isMember(n,i,o,s)&&u.trigger(i,o,r,s)}for(var c=0;c<t.stateChangeCallbacks.message.length;c++)t.stateChangeCallbacks.message[c](e)})}}]),e}(),E=function(){function e(t){o(this,e),this.endPoint=null,this.token=null,this.skipHeartbeat=!0,this.onopen=function(){},this.onerror=function(){},this.onmessage=function(){},this.onclose=function(){},this.pollEndpoint=this.normalizeEndpoint(t),this.readyState=h.connecting,this.poll()}return a(e,[{key:"normalizeEndpoint",value:function(e){return e.replace("ws://","http://").replace("wss://","https://").replace(new RegExp("(.*)/"+y.websocket),"$1/"+y.longpoll)}},{key:"endpointURL",value:function(){return x.appendParams(this.pollEndpoint,{token:this.token})}},{key:"closeAndRetry",value:function(){this.close(),this.readyState=h.connecting}},{key:"ontimeout",value:function(){this.onerror("timeout"),this.closeAndRetry()}},{key:"poll",value:function(){var e=this;this.readyState!==h.open&&this.readyState!==h.connecting||x.request("GET",this.endpointURL(),"application/json",null,this.timeout,this.ontimeout.bind(this),function(t){if(t){var n=t.status,i=t.token,o=t.messages;e.token=i}else n=0;switch(n){case 200:o.forEach(function(t){return e.onmessage({data:t})}),e.poll();break;case 204:e.poll();break;case 410:e.readyState=h.open,e.onopen(),e.poll();break;case 0:case 500:e.onerror(),e.closeAndRetry();break;default:throw new Error("unhandled poll status ".concat(n))}})}},{key:"send",value:function(e){var t=this;x.request("POST",this.endpointURL(),"application/json",e,this.timeout,this.onerror.bind(this,"timeout"),function(e){e&&200===e.status||(t.onerror(e&&e.status),t.closeAndRetry())})}},{key:"close",value:function(e,t){this.readyState=h.closed,this.onclose()}}]),e}(),x=function(){function e(){o(this,e)}return a(e,null,[{key:"request",value:function(e,t,n,i,o,r,s){if(l.XDomainRequest){var a=new XDomainRequest;this.xdomainRequest(a,e,t,i,o,r,s)}else{var u=l.XMLHttpRequest?new l.XMLHttpRequest:new ActiveXObject("Microsoft.XMLHTTP");this.xhrRequest(u,e,t,n,i,o,r,s)}}},{key:"xdomainRequest",value:function(e,t,n,i,o,r,s){var a=this;e.timeout=o,e.open(t,n),e.onload=function(){var t=a.parseJSON(e.responseText);s&&s(t)},r&&(e.ontimeout=r),e.onprogress=function(){},e.send(i)}},{key:"xhrRequest",value:function(e,t,n,i,o,r,s,a){var u=this;e.open(t,n,!0),e.timeout=r,e.setRequestHeader("Content-Type",i),e.onerror=function(){a&&a(null)},e.onreadystatechange=function(){if(e.readyState===u.states.complete&&a){var t=u.parseJSON(e.responseText);a(t)}},s&&(e.ontimeout=s),e.send(o)}},{key:"parseJSON",value:function(e){if(!e||""===e)return null;try{return JSON.parse(e)}catch(t){return console&&console.log("failed to parse JSON response",e),null}}},{key:"serialize",value:function(e,t){var n=[];for(var o in e)if(e.hasOwnProperty(o)){var r=t?"".concat(t,"[").concat(o,"]"):o,s=e[o];"object"===i(s)?n.push(this.serialize(s,r)):n.push(encodeURIComponent(r)+"="+encodeURIComponent(s))}return n.join("&")}},{key:"appendParams",value:function(e,t){if(0===Object.keys(t).length)return e;var n=e.match(/\?/)?"&":"?";return"".concat(e).concat(n).concat(this.serialize(t))}}]),e}();x.states={complete:4};var S=function(){function e(t){var n=this,i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};o(this,e);var r=i.events||{state:"presence_state",diff:"presence_diff"};this.state={},this.pendingDiffs=[],this.channel=t,this.joinRef=null,this.caller={onJoin:function(){},onLeave:function(){},onSync:function(){}},this.channel.on(r.state,function(t){var i=n.caller,o=i.onJoin,r=i.onLeave,s=i.onSync;n.joinRef=n.channel.joinRef(),n.state=e.syncState(n.state,t,o,r),n.pendingDiffs.forEach(function(t){n.state=e.syncDiff(n.state,t,o,r)}),n.pendingDiffs=[],s()}),this.channel.on(r.diff,function(t){var i=n.caller,o=i.onJoin,r=i.onLeave,s=i.onSync;n.inPendingSyncState()?n.pendingDiffs.push(t):(n.state=e.syncDiff(n.state,t,o,r),s())})}return a(e,[{key:"onJoin",value:function(e){this.caller.onJoin=e}},{key:"onLeave",value:function(e){this.caller.onLeave=e}},{key:"onSync",value:function(e){this.caller.onSync=e}},{key:"list",value:function(t){return e.list(this.state,t)}},{key:"inPendingSyncState",value:function(){return!this.joinRef||this.joinRef!==this.channel.joinRef()}}],[{key:"syncState",value:function(e,t,n,i){var o=this,r=this.clone(e),s={},a={};return this.map(r,function(e,n){t[e]||(a[e]=n)}),this.map(t,function(e,t){var n=r[e];if(n){var i=t.metas.map(function(e){return e.phx_ref}),u=n.metas.map(function(e){return e.phx_ref}),c=t.metas.filter(function(e){return u.indexOf(e.phx_ref)<0}),l=n.metas.filter(function(e){return i.indexOf(e.phx_ref)<0});c.length>0&&(s[e]=t,s[e].metas=c),l.length>0&&(a[e]=o.clone(n),a[e].metas=l)}else s[e]=t}),this.syncDiff(r,{joins:s,leaves:a},n,i)}},{key:"syncDiff",value:function(e,t,n,i){var o=t.joins,r=t.leaves,s=this.clone(e);return n||(n=function(){}),i||(i=function(){}),this.map(o,function(e,t){var i=s[e];if(s[e]=t,i){var o,r=s[e].metas.map(function(e){return e.phx_ref}),a=i.metas.filter(function(e){return r.indexOf(e.phx_ref)<0});(o=s[e].metas).unshift.apply(o,function(e){return function(e){if(Array.isArray(e)){for(var t=0,n=new Array(e.length);t<e.length;t++)n[t]=e[t];return n}}(e)||function(e){if(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e))return Array.from(e)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance")}()}(a))}n(e,i,t)}),this.map(r,function(e,t){var n=s[e];if(n){var o=t.metas.map(function(e){return e.phx_ref});n.metas=n.metas.filter(function(e){return o.indexOf(e.phx_ref)<0}),i(e,n,t),0===n.metas.length&&delete s[e]}}),s}},{key:"list",value:function(e,t){return t||(t=function(e,t){return t}),this.map(e,function(e,n){return t(e,n)})}},{key:"map",value:function(e,t){return Object.getOwnPropertyNames(e).map(function(n){return t(n,e[n])})}},{key:"clone",value:function(e){return JSON.parse(JSON.stringify(e))}}]),e}(),C=function(){function e(t,n){o(this,e),this.callback=t,this.timerCalc=n,this.timer=null,this.tries=0}return a(e,[{key:"reset",value:function(){this.tries=0,clearTimeout(this.timer)}},{key:"scheduleTimeout",value:function(){var e=this;clearTimeout(this.timer),this.timer=setTimeout(function(){e.tries=e.tries+1,e.callback()},this.timerCalc(this.tries+1))}}]),e}()}])})}).call(this,n(2)(e))},function(e,t,n){"use strict";var i;n.r(t);var o="http://www.w3.org/1999/xhtml",r="undefined"==typeof document?void 0:document,s=!!r&&"content"in r.createElement("template"),a=!!r&&r.createRange&&"createContextualFragment"in r.createRange();function u(e){return s?function(e){var t=r.createElement("template");return t.innerHTML=e,t.content.childNodes[0]}(e):a?function(e){return i||(i=r.createRange()).selectNode(r.body),i.createContextualFragment(e).childNodes[0]}(e):function(e){var t=r.createElement("body");return t.innerHTML=e,t.childNodes[0]}(e)}function c(e,t){var n=e.nodeName,i=t.nodeName;return n===i||!!(t.actualize&&n.charCodeAt(0)<91&&i.charCodeAt(0)>90)&&n===i.toUpperCase()}function l(e,t,n){e[n]!==t[n]&&(e[n]=t[n],e[n]?e.setAttribute(n,""):e.removeAttribute(n))}var h={OPTION:function(e,t){var n=e.parentNode;if(n){var i=n.nodeName.toUpperCase();"OPTGROUP"===i&&(i=(n=n.parentNode)&&n.nodeName.toUpperCase()),"SELECT"!==i||n.hasAttribute("multiple")||(e.hasAttribute("selected")&&!t.selected&&(e.setAttribute("selected","selected"),e.removeAttribute("selected")),n.selectedIndex=-1)}l(e,t,"selected")},INPUT:function(e,t){l(e,t,"checked"),l(e,t,"disabled"),e.value!==t.value&&(e.value=t.value),t.hasAttribute("value")||e.removeAttribute("value")},TEXTAREA:function(e,t){var n=t.value;e.value!==n&&(e.value=n);var i=e.firstChild;if(i){var o=i.nodeValue;if(o==n||!n&&o==e.placeholder)return;i.nodeValue=n}},SELECT:function(e,t){if(!t.hasAttribute("multiple")){for(var n,i,o=-1,r=0,s=e.firstChild;s;)if("OPTGROUP"===(i=s.nodeName&&s.nodeName.toUpperCase()))s=(n=s).firstChild;else{if("OPTION"===i){if(s.hasAttribute("selected")){o=r;break}r++}!(s=s.nextSibling)&&n&&(s=n.nextSibling,n=null)}e.selectedIndex=o}}},f=1,d=11,v=3,p=8;function y(){}function g(e){return e.id}var m=function(e){return function(t,n,i){if(i||(i={}),"string"==typeof n)if("#document"===t.nodeName||"HTML"===t.nodeName){var s=n;(n=r.createElement("html")).innerHTML=s}else n=u(n);var a,l=i.getNodeKey||g,m=i.onBeforeNodeAdded||y,k=i.onNodeAdded||y,b=i.onBeforeElUpdated||y,w=i.onElUpdated||y,E=i.onBeforeNodeDiscarded||y,x=i.onNodeDiscarded||y,S=i.onBeforeElChildrenUpdated||y,C=!0===i.childrenOnly,A={};function j(e){a?a.push(e):a=[e]}function T(e,t,n){!1!==E(e)&&(t&&t.removeChild(e),x(e),function e(t,n){if(t.nodeType===f)for(var i=t.firstChild;i;){var o=void 0;n&&(o=l(i))?j(o):(x(i),i.firstChild&&e(i,n)),i=i.nextSibling}}(e,n))}function L(e){k(e);for(var t=e.firstChild;t;){var n=t.nextSibling,i=l(t);if(i){var o=A[i];o&&c(t,o)&&(t.parentNode.replaceChild(o,t),R(o,t))}L(t),t=n}}function R(i,o,s){var a=l(o);if(a&&delete A[a],!n.isSameNode||!n.isSameNode(t)){if(!s){if(!1===b(i,o))return;if(e(i,o),w(i),!1===S(i,o))return}"TEXTAREA"!==i.nodeName?function(e,t){var n,i,o,s,a,u=t.firstChild,d=e.firstChild;e:for(;u;){for(s=u.nextSibling,n=l(u);d;){if(o=d.nextSibling,u.isSameNode&&u.isSameNode(d)){u=s,d=o;continue e}i=l(d);var y=d.nodeType,g=void 0;if(y===u.nodeType&&(y===f?(n?n!==i&&((a=A[n])?o===a?g=!1:(e.insertBefore(a,d),i?j(i):T(d,e,!0),d=a):g=!1):i&&(g=!1),(g=!1!==g&&c(d,u))&&R(d,u)):y!==v&&y!=p||(g=!0,d.nodeValue!==u.nodeValue&&(d.nodeValue=u.nodeValue))),g){u=s,d=o;continue e}i?j(i):T(d,e,!0),d=o}if(n&&(a=A[n])&&c(a,u))e.appendChild(a),R(a,u);else{var k=m(u);!1!==k&&(k&&(u=k),u.actualize&&(u=u.actualize(e.ownerDocument||r)),e.appendChild(u),L(u))}u=s,d=o}!function(e,t,n){for(;t;){var i=t.nextSibling;(n=l(t))?j(n):T(t,e,!0),t=i}}(e,d,i);var b=h[e.nodeName];b&&b(e,t)}(i,o):h.TEXTAREA(i,o)}}!function e(t){if(t.nodeType===f||t.nodeType===d)for(var n=t.firstChild;n;){var i=l(n);i&&(A[i]=n),e(n),n=n.nextSibling}}(t);var _=t,P=_.nodeType,N=n.nodeType;if(!C)if(P===f)N===f?c(t,n)||(x(t),_=function(e,t){for(var n=e.firstChild;n;){var i=n.nextSibling;t.appendChild(n),n=i}return t}(t,function(e,t){return t&&t!==o?r.createElementNS(t,e):r.createElement(e)}(n.nodeName,n.namespaceURI))):_=n;else if(P===v||P===p){if(N===P)return _.nodeValue!==n.nodeValue&&(_.nodeValue=n.nodeValue),_;_=n}if(_===n)x(t);else if(R(_,n,C),a)for(var O=0,H=a.length;O<H;O++){var I=A[a[O]];I&&T(I,I.parentNode,!1)}return!C&&_!==t&&t.parentNode&&(_.actualize&&(_=_.actualize(t.ownerDocument||r)),t.parentNode.replaceChild(_,t)),_}}(function(e,t){var n,i,o,r,s,a=t.attributes;for(n=a.length-1;n>=0;--n)o=(i=a[n]).name,r=i.namespaceURI,s=i.value,r?(o=i.localName||o,e.getAttributeNS(r,o)!==s&&e.setAttributeNS(r,o,s)):e.getAttribute(o)!==s&&e.setAttribute(o,s);for(n=(a=e.attributes).length-1;n>=0;--n)!1!==(i=a[n]).specified&&(o=i.name,(r=i.namespaceURI)?(o=i.localName||o,t.hasAttributeNS(r,o)||e.removeAttributeNS(r,o)):t.hasAttribute(o)||e.removeAttribute(o))}),k=n(0);function b(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function w(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}function E(e,t,n){return t&&w(e.prototype,t),n&&w(e,n),e}function x(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=[],i=!0,o=!1,r=void 0;try{for(var s,a=e[Symbol.iterator]();!(i=(s=a.next()).done)&&(n.push(s.value),!t||n.length!==t);i=!0);}catch(e){o=!0,r=e}finally{try{i||null==a.return||a.return()}finally{if(o)throw r}}return n}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}function S(e){return(S="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}n.d(t,"debug",function(){return R}),n.d(t,"Rendered",function(){return M}),n.d(t,"LiveSocket",function(){return D}),n.d(t,"Browser",function(){return V}),n.d(t,"View",function(){return J});var C="data-phx-view",A="[".concat(C,"]"),j=["text","textarea","number","email","password","search","tel","url"],T=1,L="phx-",R=function(e,t,n,i){console.log("".concat(e.id," ").concat(t,": ").concat(n," - "),i)},_=function(e){return"function"==typeof e?e:function(){return e}},P=function(e){return JSON.parse(JSON.stringify(e))},N=function(e,t){do{if(e.matches("[".concat(t,"]")))return e;e=e.parentElement||e.parentNode}while(null!==e&&1===e.nodeType&&!e.matches(A));return null},O=function(e){return null!==e&&"object"===S(e)&&!(e instanceof Array)},H=function(e,t){return e?e[t]:null},I=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=new FormData(e),i=new URLSearchParams,o=!0,r=!1,s=void 0;try{for(var a,u=n.entries()[Symbol.iterator]();!(o=(a=u.next()).done);o=!0){var c=x(a.value,2),l=c[0],h=c[1];i.append(l,h)}}catch(e){r=!0,s=e}finally{try{o||null==u.return||u.return()}finally{if(r)throw s}}for(var f in t)i.append(f,t[f]);return i.toString()},B={get:function(e){return e.getAttribute("data-phx-session")},isEqual:function(e,t){return this.get(e)===this.get(t)}},M={mergeDiff:function(e,t){return this.isNewFingerprint(t)?t:(function e(t,n){for(var i in n){var o=n[i],r=t[i];O(o)&&O(r)?(r.dynamics&&!o.dynamics&&delete r.dynamics,e(r,o)):t[i]=o}}(e,t),e)},isNewFingerprint:function(){return!!(arguments.length>0&&void 0!==arguments[0]?arguments[0]:{}).static},toString:function(e){var t={buffer:""};return this.toOutputBuffer(e,t),t.buffer},toOutputBuffer:function(e,t){if(e.dynamics)return this.comprehensionToBuffer(e,t);var n=e.static;t.buffer+=n[0];for(var i=1;i<n.length;i++)this.dynamicToBuffer(e[i-1],t),t.buffer+=n[i]},comprehensionToBuffer:function(e,t){for(var n=e.dynamics,i=e.static,o=0;o<n.length;o++){var r=n[o];t.buffer+=i[0];for(var s=1;s<i.length;s++)this.dynamicToBuffer(r[s-1],t),t.buffer+=i[s]}},dynamicToBuffer:function(e,t){O(e)?this.toOutputBuffer(e,t):t.buffer+=e}},D=function(){function e(t){var n=this,i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};b(this,e),this.unloaded=!1,this.socket=new k.Socket(t,i),this.bindingPrefix=i.bindingPrefix||L,this.opts=i,this.views={},this.params=_(i.params||{}),this.viewLogger=i.viewLogger,this.activeElement=null,this.prevActive=null,this.prevInput=null,this.prevValue=null,this.silenced=!1,this.root=null,this.linkRef=0,this.href=window.location.href,this.pendingLink=null,this.currentLocation=P(window.location),this.hooks=i.hooks||{},this.socket.onOpen(function(){n.isUnloaded()&&(n.destroyAllViews(),n.joinRootViews()),n.unloaded=!1}),window.addEventListener("beforeunload",function(e){n.unloaded=!0}),this.bindTopLevelEvents()}return E(e,[{key:"getSocket",value:function(){return this.socket}},{key:"log",value:function(e,t,n){if(this.viewLogger){var i=x(n(),2),o=i[0],r=i[1];this.viewLogger(e,t,o,r)}}},{key:"connect",value:function(){var e=this;return["complete","loaded","interactive"].indexOf(document.readyState)>=0?this.joinRootViews():document.addEventListener("DOMContentLoaded",function(){e.joinRootViews()}),this.socket.connect()}},{key:"disconnect",value:function(){this.socket.disconnect()}},{key:"getHookCallbacks",value:function(e){return this.hooks[e]}},{key:"isUnloaded",value:function(){return this.unloaded}},{key:"getBindingPrefix",value:function(){return this.bindingPrefix}},{key:"binding",value:function(e){return"".concat(this.getBindingPrefix()).concat(e)}},{key:"channel",value:function(e,t){return this.socket.channel(e,t)}},{key:"joinRootViews",value:function(){var e=this;V.all(document,"".concat(A,":not([").concat("data-phx-parent-id","])"),function(t){var n=e.joinView(t,null,e.getHref());e.root=e.root||n})}},{key:"replaceRoot",value:function(e){var t=this,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:this.setPendingLink(e);this.root.showLoader(T);var o=this.root.el,r=this.root.id,s=this.root.isLoading();V.fetchPage(e,function(a,u){if(200!==a)return V.redirect(e);var c=document.createElement("div");c.innerHTML=u,t.joinView(c.firstChild,null,e,function(e){t.commitPendingLink(i)?(n&&n(),t.destroyViewById(r),o.replaceWith(e.el),t.root=e,s&&t.root.showLoader()):e.destroy()})})}},{key:"joinView",value:function(e,t,n,i){if(!this.getViewById(e.id)){var o=new J(e,this,t,n);return this.views[o.id]=o,o.join(i),o}}},{key:"owner",value:function(e,t){var n=this.getViewById(H(e.closest(A),"id"));n&&t(n)}},{key:"getViewById",value:function(e){return this.views[e]}},{key:"onViewError",value:function(e){this.dropActiveElement(e)}},{key:"destroyAllViews",value:function(){for(var e in this.views)this.destroyViewById(e)}},{key:"destroyViewById",value:function(e){var t=this.views[e];t&&(delete this.views[t.id],this.root&&t.id===this.root.id&&(this.root=null),t.destroy())}},{key:"setActiveElement",value:function(e){var t=this;if(this.activeElement!==e){this.activeElement=e;var n=function(){e===t.activeElement&&(t.activeElement=null),e.removeEventListener("mouseup",t),e.removeEventListener("touchend",t)};e.addEventListener("mouseup",n),e.addEventListener("touchend",n)}}},{key:"getActiveElement",value:function(){return document.activeElement===document.body&&this.activeElement||document.activeElement}},{key:"dropActiveElement",value:function(e){this.prevActive&&e.ownsElement(this.prevActive)&&(this.prevActive=null)}},{key:"restorePreviouslyActiveFocus",value:function(){this.prevActive&&this.prevActive!==document.body&&this.prevActive.focus()}},{key:"blurActiveElement",value:function(){this.prevActive=this.getActiveElement(),this.prevActive!==document.body&&this.prevActive.blur()}},{key:"bindTopLevelEvents",value:function(){this.bindClicks(),this.bindNav(),this.bindForms(),this.bindTargetable({keyup:"keyup",keydown:"keydown"},function(e,t,n,i,o,r){n.pushKey(i,t,o,{altGraphKey:e.altGraphKey,altKey:e.altKey,charCode:e.charCode,code:e.code,ctrlKey:e.ctrlKey,key:e.key,keyCode:e.keyCode,keyIdentifier:e.keyIdentifier,keyLocation:e.keyLocation,location:e.location,metaKey:e.metaKey,repeat:e.repeat,shiftKey:e.shiftKey,which:e.which})}),this.bindTargetable({blur:"focusout",focus:"focusin"},function(e,t,n,i,o,r){r||n.pushEvent(t,i,o,{type:"focus"})}),this.bindTargetable({blur:"blur",focus:"focus"},function(e,t,n,i,o,r){r&&"window"!==!r&&n.pushEvent(t,i,o,{type:e.type})})}},{key:"setPendingLink",value:function(e){this.linkRef++;this.linkRef;return this.pendingLink=e,this.linkRef}},{key:"commitPendingLink",value:function(e){return this.linkRef===e&&(this.href=this.pendingLink,this.pendingLink=null,!0)}},{key:"getHref",value:function(){return this.href}},{key:"hasPendingLink",value:function(){return!!this.pendingLink}},{key:"bindTargetable",value:function(e,t){var n=this,i=function(i){var o=e[i];n.on(o,function(e){var o=n.binding(i),r=n.binding("target"),s=e.target.getAttribute&&e.target.getAttribute(o);s&&!e.target.getAttribute(r)?n.owner(e.target,function(n){return t(e,i,n,e.target,s,null)}):V.all(document,"[".concat(o,"][").concat(r,"=window]"),function(r){var s=r.getAttribute(o);n.owner(r,function(n){return t(e,i,n,r,s,"window")})})})};for(var o in e)i(o)}},{key:"bindClicks",value:function(){var e=this;window.addEventListener("click",function(t){var n=e.binding("click"),i=N(t.target,n),o=i&&i.getAttribute(n);if(o){t.preventDefault();var r={altKey:t.altKey,shiftKey:t.shiftKey,ctrlKey:t.ctrlKey,metaKey:t.metaKey,x:t.x||t.clientX,y:t.y||t.clientY,pageX:t.pageX,pageY:t.pageY,screenX:t.screenX,screenY:t.screenY};e.owner(i,function(e){return e.pushEvent("click",i,o,r)})}},!1)}},{key:"bindNav",value:function(){var e=this;V.canPushState()&&(window.onpopstate=function(t){if(e.registerNewLocation(window.location)){var n=window.location.href;e.root.isConnected()?e.root.pushInternalLink(n):e.replaceRoot(n)}},window.addEventListener("click",function(t){var n=N(t.target,"data-phx-live-link"),i=n&&n.getAttribute("data-phx-live-link");if(i){var o=n.href;t.preventDefault(),e.root.pushInternalLink(o,function(){V.pushState(i,{},o),e.registerNewLocation(window.location)})}},!1))}},{key:"registerNewLocation",value:function(e){var t=this.currentLocation;return t.pathname+t.search!==e.pathname+e.search&&(this.currentLocation=P(e),!0)}},{key:"bindForms",value:function(){var e=this;this.on("submit",function(t){var n=t.target.getAttribute(e.binding("submit"));n&&(t.preventDefault(),t.target.disabled=!0,e.owner(t.target,function(e){return e.submitForm(t.target,n)}))},!1);for(var t=["change","input"],n=0;n<t.length;n++){var i=t[n];this.on(i,function(t){var n=t.target,i="checkbox"===n.type?"checked":"value";if(e.prevInput!==n||e.prevValue!==n[i]){e.prevInput=n,e.prevValue=n[i];var o=n.form&&n.form.getAttribute(e.binding("change"));o&&e.owner(n,function(i){U.isTextualInput(n)?n["phx-has-focused"]=!0:e.setActiveElement(n),i.pushInput(n,o,t)})}},!1)}}},{key:"silenceEvents",value:function(e){this.silenced=!0,e(),this.silenced=!1}},{key:"on",value:function(e,t){var n=this;window.addEventListener(e,function(e){n.silenced||t(e)})}}]),e}(),V={all:function(e,t,n){e.querySelectorAll(t).forEach(n)},canPushState:function(){return void 0!==history.pushState},fetchPage:function(e,t){var n=new XMLHttpRequest;n.open("GET",e,!0),n.timeout=3e4,n.setRequestHeader("content-type","text/html"),n.setRequestHeader("cache-control","max-age=0, no-cache, no-store, must-revalidate, post-check=0, pre-check=0"),n.setRequestHeader("x-requested-with","live-link"),n.onerror=function(){return t(400)},n.ontimeout=function(){return t(504)},n.onreadystatechange=function(){if(4===n.readyState)return"live-link"!==n.getResponseHeader("x-requested-with")?t(400):200!==n.status?t(n.status):void t(200,n.responseText)},n.send()},pushState:function(e,t,n){this.canPushState()?n!==window.location.href&&history[e+"State"](t,"",n):this.redirect(n)},dispatchEvent:function(e,t){var n=null;"function"==typeof Event?n=new Event(t):(n=document.createEvent("Event")).initEvent(t,!0,!0),e.dispatchEvent(n)},setCookie:function(e,t){document.cookie="".concat(e,"=").concat(t)},getCookie:function(e){return document.cookie.replace(new RegExp("(?:(?:^|.*;s*)".concat(e,"s*=s*([^;]*).*$)|^.*$")),"$1")},redirect:function(e,t){t&&V.setCookie("__phoenix_flash__",t+"; max-age=60000; path=/"),window.location=e}},U={disableForm:function(e,t){var n="".concat(t).concat("disable-with");e.classList.add("phx-loading"),V.all(e,"[".concat(n,"]"),function(e){var t=e.getAttribute(n);e.setAttribute("".concat(n,"-restore"),e.innerText),e.innerText=t}),V.all(e,"button",function(e){e.setAttribute("data-phx-disabled",e.disabled),e.disabled=!0}),V.all(e,"input",function(e){e.setAttribute("data-phx-readonly",e.readOnly),e.readOnly=!0})},restoreDisabledForm:function(e,t){var n="".concat(t).concat("disable-with");e.classList.remove("phx-loading"),V.all(e,"[".concat(n,"]"),function(e){var t=e.getAttribute("".concat(n,"-restore"));t&&("INPUT"===e.nodeName?e.value=t:e.innerText=t,e.removeAttribute("".concat(n,"-restore")))}),V.all(e,"button",function(e){var t=e.getAttribute("data-phx-disabled");t&&(e.disabled="true"===t,e.removeAttribute("data-phx-disabled"))}),V.all(e,"input",function(e){var t=e.getAttribute("data-phx-readonly");t&&(e.readOnly="true"===t,e.removeAttribute("data-phx-readonly"))})},discardError:function(e){var t=e.getAttribute&&e.getAttribute("data-phx-error-for");if(t){var n=document.getElementById(t);!t||n["phx-has-focused"]||n.form["phx-has-submitted"]||(e.style.display="none")}},isPhxChild:function(e){return e.getAttribute&&e.getAttribute("data-phx-parent-id")},applyPhxUpdate:function(e,t,n){var i=t.getAttribute&&t.getAttribute(n);if(!i||"replace"===i)return!1;switch(U.mergeAttrs(e,t),i){case"ignore":break;case"append":e.innerHTML+=t.innerHTML;break;case"prepend":e.innerHTML=t.innerHTML+e.innerHTML;break;default:throw new Error('unsupported phx-update "'.concat(i,'"'))}return!0},patch:function(e,t,n,i){var o={added:[],updated:[],discarded:[]},r=e.liveSocket.getActiveElement(),s=null,a=null,u=e.liveSocket.binding("update"),c=t.tagName.toLowerCase();return U.isTextualInput(r)&&(s=r.selectionStart,a=r.selectionEnd),m(t,"<".concat(c,">").concat(i,"</").concat(c,">"),{childrenOnly:!0,onBeforeNodeAdded:function(e){return U.discardError(e),e},onNodeAdded:function(t){if(U.isPhxChild(t)&&e.ownsElement(t))return e.onNewChildAdded(),!0;o.added.push(t)},onBeforeNodeDiscarded:function(t){if(U.isPhxChild(t))return e.liveSocket.destroyViewById(t.id),!0;o.discarded.push(t)},onBeforeElUpdated:function(t,n){if(t.isEqualNode(n))return!1;if(U.applyPhxUpdate(t,n,u))return o.updated.push({fromEl:t,toEl:t}),!1;if(U.isPhxChild(n)){var i=t.getAttribute("data-phx-static");return B.isEqual(n,t)||(e.liveSocket.destroyViewById(t.id),e.onNewChildAdded()),U.mergeAttrs(t,n),t.setAttribute("data-phx-static",i),!1}return t.getAttribute&&t["phx-has-submitted"]&&(n["phx-has-submitted"]=!0),t["phx-has-focused"]&&(n["phx-has-focused"]=!0),U.discardError(n),U.isTextualInput(t)&&t===r?(U.mergeInputs(t,n),o.updated.push({fromEl:t,toEl:t}),!1):(o.updated.push({fromEl:t,toEl:n}),!0)}}),e.liveSocket.silenceEvents(function(){U.restoreFocus(r,s,a)}),V.dispatchEvent(document,"phx:update"),o},mergeAttrs:function(e,t){for(var n=t.attributes,i=0,o=n.length;i<o;i++){var r=n[i].name,s=t.getAttribute(r);e.setAttribute(r,s)}},mergeInputs:function(e,t){U.mergeAttrs(e,t),e.readOnly=t.readOnly},restoreFocus:function(e,t,n){U.isTextualInput(e)&&((""===e.value||e.readOnly)&&e.blur(),e.focus(),(e.setSelectionRange&&"text"===e.type||"textarea"===e.type)&&e.setSelectionRange(t,n))},isTextualInput:function(e){return j.indexOf(e.type)>=0}},J=function(){function e(t,n,i,o){var r=this;b(this,e),this.liveSocket=n,this.parent=i,this.newChildrenAdded=!1,this.gracefullyClosed=!1,this.el=t,this.id=this.el.id,this.view=this.el.getAttribute(C),this.loaderTimer=null,this.pendingDiffs=[],this.href=o,this.joinedOnce=!1,this.viewHooks={},this.channel=this.liveSocket.channel("lv:".concat(this.id),function(){return{url:r.href||r.liveSocket.root.href,params:r.liveSocket.params(r.view),session:r.getSession(),static:r.getStatic()}}),this.showLoader(T),this.bindChannel()}return E(e,[{key:"isConnected",value:function(){return this.channel.canPush()}},{key:"getSession",value:function(){return B.get(this.el)}},{key:"getStatic",value:function(){var e=this.el.getAttribute("data-phx-static");return""===e?null:e}},{key:"destroy",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:function(){};clearTimeout(this.loaderTimer);var n=function(){for(var n in t(),e.viewHooks)e.destroyHook(e.viewHooks[n])};this.hasGracefullyClosed()?(this.log("destroyed",function(){return["the server view has gracefully closed"]}),n()):(this.log("destroyed",function(){return["the child has been removed from the parent"]}),this.channel.leave().receive("ok",n).receive("error",n).receive("timeout",n))}},{key:"setContainerClasses",value:function(){var e;this.el.classList.remove("phx-connected","phx-disconnected","phx-error"),(e=this.el.classList).add.apply(e,arguments)}},{key:"isLoading",value:function(){return this.el.classList.contains("phx-disconnected")}},{key:"showLoader",value:function(e){var t=this;if(clearTimeout(this.loaderTimer),e)this.loaderTimer=setTimeout(function(){return t.showLoader()},e);else{for(var n in this.viewHooks)this.viewHooks[n].__trigger__("disconnected");this.setContainerClasses("phx-disconnected")}}},{key:"hideLoader",value:function(){for(var e in clearTimeout(this.loaderTimer),this.viewHooks)this.viewHooks[e].__trigger__("reconnected");this.setContainerClasses("phx-connected")}},{key:"log",value:function(e,t){this.liveSocket.log(this,e,t)}},{key:"onJoin",value:function(e){var t=e.rendered,n=e.live_redirect;this.log("join",function(){return["",JSON.stringify(t)]}),this.rendered=t,this.hideLoader();var i=U.patch(this,this.el,this.id,M.toString(this.rendered));if(i.added.push(this.el),V.all(this.el,"[".concat(this.binding("hook"),"]"),function(e){return i.added.push(e)}),this.triggerHooks(i),this.joinNewChildren(),n){var o=n.kind,r=n.to;V.pushState(o,{},r)}}},{key:"joinNewChildren",value:function(){var e=this;V.all(document,"".concat(A,"[").concat("data-phx-parent-id",'="').concat(this.id,'"]'),function(t){e.liveSocket.getViewById(t.id)||e.liveSocket.joinView(t,e)})}},{key:"update",value:function(e){if(!function(e){for(var t in e)return!1;return!0}(e)){if(this.liveSocket.hasPendingLink())return this.pendingDiffs.push(e);this.log("update",function(){return["",JSON.stringify(e)]}),this.rendered=M.mergeDiff(this.rendered,e);var t=M.toString(this.rendered);this.newChildrenAdded=!1,this.triggerHooks(U.patch(this,this.el,this.id,t)),this.newChildrenAdded&&this.joinNewChildren()}}},{key:"getHook",value:function(e){return this.viewHooks[F.elementID(e)]}},{key:"addHook",value:function(e){if(!F.elementID(e)&&e.getAttribute){var t=this.liveSocket.getHookCallbacks(e.getAttribute(this.binding("hook")));if(t&&this.ownsElement(e)){var n=new F(this,e,t);this.viewHooks[F.elementID(n.el)]=n,n.__trigger__("mounted")}}}},{key:"destroyHook",value:function(e){e.__trigger__("destroyed"),delete this.viewHooks[F.elementID(e.el)]}},{key:"triggerHooks",value:function(e){var t=this;e.updated.push({fromEl:this.el,toEl:this.el}),e.added.forEach(function(e){return t.addHook(e)}),e.updated.forEach(function(e){var n=e.fromEl,i=e.toEl,o=t.getHook(n),r=t.binding("hook");o&&i.getAttribute&&n.getAttribute(r)===i.getAttribute(r)?o.__trigger__("updated"):o&&(t.destroyHook(o),t.addHook(n))}),e.discarded.forEach(function(e){var n=t.getHook(e);n&&t.destroyHook(n)})}},{key:"applyPendingUpdates",value:function(){var e=this;this.pendingDiffs.forEach(function(t){return e.update(t)}),this.pendingDiffs=[]}},{key:"onNewChildAdded",value:function(){this.newChildrenAdded=!0}},{key:"bindChannel",value:function(){var e=this;this.channel.on("diff",function(t){return e.update(t)}),this.channel.on("redirect",function(t){var n=t.to,i=t.flash;return e.onRedirect({to:n,flash:i})}),this.channel.on("live_redirect",function(t){var n=t.to,i=t.kind;return e.onLiveRedirect({to:n,kind:i})}),this.channel.on("external_live_redirect",function(t){var n=t.to,i=t.kind;return e.onExternalLiveRedirect({to:n,kind:i})}),this.channel.on("session",function(t){var n=t.token;return e.el.setAttribute("data-phx-session",n)}),this.channel.onError(function(t){return e.onError(t)}),this.channel.onClose(function(){return e.onGracefulClose()})}},{key:"onGracefulClose",value:function(){this.gracefullyClosed=!0,this.liveSocket.destroyViewById(this.id)}},{key:"onExternalLiveRedirect",value:function(e){var t=e.to,n=e.kind;this.liveSocket.replaceRoot(t,function(){return V.pushState(n,{},t)})}},{key:"onLiveRedirect",value:function(e){var t=e.to,n=e.kind;V.pushState(n,{},t)}},{key:"onRedirect",value:function(e){var t=e.to,n=e.flash;V.redirect(t,n)}},{key:"hasGracefullyClosed",value:function(){return this.gracefullyClosed}},{key:"join",value:function(e){var t=this;this.parent&&(this.parent.channel.onClose(function(){return t.onGracefulClose()}),this.parent.channel.onError(function(){return t.liveSocket.destroyViewById(t.id)})),this.channel.join().receive("ok",function(n){t.joinedOnce||e&&e(t),t.joinedOnce=!0,t.onJoin(n)}).receive("error",function(e){return t.onJoinError(e)}).receive("timeout",function(){return t.onJoinError("timeout")})}},{key:"onJoinError",value:function(e){return e.redirect?this.onRedirect(e.redirect):e.external_live_redirect?this.onExternalLiveRedirect(e.external_live_redirect):(this.displayError(),void this.log("error",function(){return["unable to join",e]}))}},{key:"onError",value:function(e){this.log("error",function(){return["view crashed",e]}),this.liveSocket.onViewError(this),document.activeElement.blur(),this.liveSocket.isUnloaded()?this.showLoader(200):this.displayError()}},{key:"displayError",value:function(){this.showLoader(),this.setContainerClasses("phx-disconnected","phx-error")}},{key:"pushWithReply",value:function(e,t){var n=this,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:function(){};return this.channel.push(e,t,3e4).receive("ok",function(e){e.diff&&n.update(e.diff),e.redirect&&n.onRedirect(e.redirect),e.live_redirect&&n.onLiveRedirect(e.live_redirect),e.external_live_redirect&&n.onExternalLiveRedirect(e.external_live_redirect),i(e)})}},{key:"pushEvent",value:function(e,t,n,i){var o=t.getAttribute(this.binding("value"));if(null===o){o=i;var r=this.binding("value-"),s=!0,a=!1,u=void 0;try{for(var c,l=t.getAttributeNames()[Symbol.iterator]();!(s=(c=l.next()).done);s=!0){var h=c.value;h.startsWith(r)&&(o[h.replace(r,"")]=t.getAttribute(h))}}catch(e){a=!0,u=e}finally{try{s||null==l.return||l.return()}finally{if(a)throw u}}void 0!==t.value&&(o.value=t.value)}this.pushWithReply("event",{type:e,event:n,value:o})}},{key:"pushKey",value:function(e,t,n,i){var o=e.getAttribute(this.binding("value"));null===o&&(o=i,void 0!==e.value&&(o.value=e.value)),this.pushWithReply("event",{type:t,event:n,value:o})}},{key:"pushInput",value:function(e,t,n){this.pushWithReply("event",{type:"form",event:t,value:I(e.form,{_target:n.target.name})})}},{key:"pushFormSubmit",value:function(e,t,n){this.pushWithReply("event",{type:"form",event:t,value:I(e)},n)}},{key:"pushInternalLink",value:function(e,t){var n=this;this.isLoading()||this.showLoader(T);var i=this.liveSocket.setPendingLink(e);this.pushWithReply("link",{url:e},function(o){o.link_redirect?n.liveSocket.replaceRoot(e,t,i):n.liveSocket.commitPendingLink(i)&&(n.href=e,n.applyPendingUpdates(),n.hideLoader(),t&&t())}).receive("timeout",function(){return V.redirect(window.location.href)})}},{key:"ownsElement",value:function(e){return e.getAttribute("data-phx-parent-id")===this.id||H(e.closest(A),"id")===this.id}},{key:"submitForm",value:function(e,t){var n=this,i=this.liveSocket.getBindingPrefix();e["phx-has-submitted"]="true",U.disableForm(e,i),this.liveSocket.blurActiveElement(this),this.pushFormSubmit(e,t,function(){U.restoreDisabledForm(e,i),n.liveSocket.restorePreviouslyActiveFocus()})}},{key:"binding",value:function(e){return this.liveSocket.binding(e)}}]),e}(),q=1,F=function(){function e(t,n,i){for(var o in b(this,e),this.__view=t,this.__callbacks=i,this.el=n,this.viewName=t.view,this.el.phxHookId=this.constructor.makeID(),this.__callbacks)this[o]=this.__callbacks[o]}return E(e,null,[{key:"makeID",value:function(){return q++}},{key:"elementID",value:function(e){return e.phxHookId}}]),E(e,[{key:"pushEvent",value:function(e,t){this.__view.pushWithReply("event",{type:"hook",event:e,value:t})}},{key:"__trigger__",value:function(e){var t=this.__callbacks[e];t&&t.call(this)}}]),e}();t.default=D},function(e,t){e.exports=function(e){return e.webpackPolyfill||(e.deprecate=function(){},e.paths=[],e.children||(e.children=[]),Object.defineProperty(e,"loaded",{enumerable:!0,get:function(){return e.l}}),Object.defineProperty(e,"id",{enumerable:!0,get:function(){return e.i}}),e.webpackPolyfill=1),e}},function(e,t){var n;n=function(){return this}();try{n=n||Function("return this")()||(0,eval)("this")}catch(e){"object"==typeof window&&(n=window)}e.exports=n},function(e,t,n){(function(t){t.Phoenix||(t.Phoenix={}),e.exports=t.Phoenix.LiveView=n(1)}).call(this,n(3))}])});

@@ -1,12 +0,21 @@

# Phoenix Live View
# Phoenix LiveView
[![Build Status](https://travis-ci.com/phoenixframework/phoenix_live_view.svg?token=Dc4VoVYF33Y2H4Gy8pGi&branch=master)](https://travis-ci.com/phoenixframework/phoenix_live_view)
[![Build Status](https://travis-ci.org/phoenixframework/phoenix_live_view.svg?branch=master)](https://travis-ci.org/phoenixframework/phoenix_live_view)
Phoenix LiveView enables rich, real-time user experiences with server-rendered HTML. For more information, [see the initial announcement](https://dockyard.com/blog/2018/12/12/phoenix-liveview-interactive-real-time-apps-no-need-to-write-javascript).
**Note**: Currently Live View is under active development and we are focused on getting a stable and solid initial version out. For this reason, we will be accepting only bug reports in the issues tracker for now. We will open the issues tracker for features after the current milestone is ironed out.
**Note**: Currently LiveView is under active development and we are focused on getting a stable and solid initial version out. For this reason, we will be accepting only bug reports in the issues tracker for now. We will open the issues tracker for features after the current milestone is ironed out.
## Learning
As official guides are being developed, see our existing
comprehensive docs and examples to get up to speed:
* [Phoenix.LiveView docs for Elixir and JavaScript usage](https://hexdocs.pm/phoenix_live_view)
* [Phoenix.LiveViewTest for testing docs](https://github.com/phoenixframework/phoenix_live_view/blob/master/lib/phoenix_live_view/test/live_view_test.ex)
* [LiveView example repo](https://github.com/chrismccord/phoenix_live_view_example) with a handful of examples from Weather widgets, autocomplete search, and games like Snake or Pacman
## Installation
Currently Live View is only avaialble from GitHub. To use it, add to your `mix.exs`:
To use LiveView, add to your `mix.exs` and run `mix deps.get`:

@@ -16,3 +25,3 @@ ```elixir

[
{:phoenix_live_view, github: "phoenixframework/phoenix_live_view"}
{:phoenix_live_view, "~> 0.1.0"}
]

@@ -25,2 +34,4 @@ end

```elixir
# config/config.exs
config :my_app, MyAppWeb.Endpoint,

@@ -32,12 +43,7 @@ live_view: [

Update your configuration to enable writing LiveView templates with the `.leex` extension.
Next, add the LiveView flash plug to your browser pipeline, after `:fetch_flash`:
```elixir
config :phoenix,
template_engines: [leex: Phoenix.LiveView.Engine]
```
# lib/my_app_web/router.ex
Next, add the Live View flash plug to your browser pipeline, after `:fetch_flash`:
```elixir
pipeline :browser do

@@ -50,9 +56,18 @@ ...

Then add the following imports to your web file in `lib/app_web.ex`:
Then add the following imports to your web file in `lib/my_app_web.ex`:
```elixir
# lib/my_app_web.ex
def controller do
quote do
...
import Phoenix.LiveView.Controller, only: [live_render: 3]
end
end
def view do
quote do
...
import Phoenix.LiveView, only: [live_render: 2, live_render: 3]
import Phoenix.LiveView, only: [live_render: 2, live_render: 3, live_link: 1, live_link: 2]
end

@@ -72,2 +87,4 @@ end

```elixir
# lib/my_app_web/endpoint.ex
defmodule MyAppWeb.Endpoint do

@@ -82,3 +99,3 @@ use Phoenix.Endpoint

Add LiveView NPM dependencies in your package.json.
Add LiveView NPM dependencies in your `assets/package.json`.

@@ -88,3 +105,3 @@ ```json

"dependencies": {
"phoenix": "../deps/phoenix",
"phoenix": "file:../deps/phoenix",
"phoenix_html": "file:../deps/phoenix_html",

@@ -96,9 +113,68 @@ "phoenix_live_view": "file:../deps/phoenix_live_view"

Enable connecting to a LiveView socket in your app.js file.
Then install the new npm dependency.
```bash
npm install --prefix assets
```
If you had previously installed phoenix_live_view and want to get the
latest javascript, then force an install.
```bash
(cd assets && npm install --force phoenix_live_view)
```
Enable connecting to a LiveView socket in your `app.js` file.
```javascript
import LiveSocket from "phoenix_live_view";
// assets/js/app.js
import LiveSocket from "phoenix_live_view"
let liveSocket = new LiveSocket("/live");
liveSocket.connect();
let liveSocket = new LiveSocket("/live")
liveSocket.connect()
```
Finally, by convention live views are saved in a `lib/my_app_web/live/`
directory. For live page reload support, add the following pattern to
your `config/dev.exs`:
```elixir
# config/dev.exs
config :demo, MyAppWeb.Endpoint,
live_reload: [
patterns: [
...,
~r{lib/my_app_web/live/.*(ex)$}
]
]
```
You can also optionally import the style for the default CSS classes in your `app.css` file.
```css
/* assets/css/app.css */
@import "../../deps/phoenix_live_view/assets/css/live_view.css";
```
## Browser Support
All current Chrome, Safari, Firefox, and MS Edge are supported.
IE11 support is available with the following polyfills:
```console
$ npm install --save --prefix assets mdn-polyfills url-search-params-polyfill formdata-polyfill child-replace-with-polyfill classlist-polyfill
```
```javascript
// assets/js/app.js
import "mdn-polyfills/NodeList.prototype.forEach"
import "mdn-polyfills/Element.prototype.closest"
import "mdn-polyfills/Element.prototype.matches"
import "child-replace-with-polyfill"
import "url-search-params-polyfill"
import "formdata-polyfill"
import "classlist-polyfill"
import LiveSocket from "phoenix_live_view"
...
```
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc