<commit_before>define([
    'base/object',
    'base/rectBox'
], function(object, rectBox) {
    var extend = object.extend;

    var register = function(parentInstance, childInstance) {
        parentInstance.instances.push(childInstance);
        return parentInstance.instances;
    };

    var calculateStage = function(context) {
        var currentWidth = context.properties.currentMeasures.width;
        var currentHeight = context.properties.currentMeasures.height;

        var defaultWidth = context.properties.defaultMeasures.width;
        var defaultHeight = context.properties.defaultMeasures.height;

        var stage = {
            width: defaultWidth,
            height: defaultHeight
        };

        var newAspectRatio = currentWidth / currentHeight;
        var defaultAspectRatio = defaultWidth / defaultHeight;

        if (newAspectRatio < defaultAspectRatio) {
            stage.height = stage.width / newAspectRatio;
        } else if (newAspectRatio > defaultAspectRatio) {
            stage.width = stage.height * newAspectRatio;
        }

        context.setProperties({ stage: stage });

        return stage;
    };

    var setCurrentMeasures = function(context) {
        var div = context.properties.div;   // d3 object

        var boundingRect = div.node().getBoundingClientRect();

        var currentMeasures = {
            width: boundingRect.width,
            height: boundingRect.height
        };

        context.setProperties({ currentMeasures: currentMeasures });

        return currentMeasures;
    };

    var setSvgViewBox = function(context) {
        var svg = context.properties.svg;
        var stage = context.properties.stage;

        svg.attr('viewBox', '0 0 ' + stage.width + ' ' + stage.height);
        svg.attr('preserveAspectRatio', 'xMinYMin meet');

        return svg;
    };

    var setSvgMeasures = function(context) {
        var currentMeasures = context.properties.currentMeasures;
        var svg = context.properties.svg;

        svg.attr('width', currentMeasures.width);
        svg.attr('height', currentMeasures.height);
    };

    var processItem = function(item, context) {
        var layout = item.layout;
        var schema = item.schema;
        var item = item.item;
        var anchors = Object.keys(layout[schema][item]);

        for (var i = 0; i < anchors.length; i++) {
            // Skip reserved properties
            switch(anchors[i]) {
                case 'element':
                case 'render':
                    continue;
            }

            var point = layout[schema][item][anchors[i]];

            if (typeof point === 'object') {
                var linkedAnchor;
                if (point.parent !== 'stage') {
                    linkedAnchor = layout[schema][point.parent][point.anchor];
                } else {
                    linkedAnchor = context.properties.stage[point.anchor];
                }

                if (point.padding) linkedAnchor += point.padding;
                if (point.percentage) linkedAnchor *= (point.percentage / 100);

                // replace object with calculated value
                layout[schema][item][anchors[i]] = linkedAnchor;
            } else if (typeof point !== 'number') {
                layout[schema][item][anchors[i]] = Number(point);
            }
        }

        return layout[schema][item];
    };

    var fillHeightWidth = function(item) {
        // 'rectbox' a function/object instead of a plain d3 object!
        var rectBox = new RectBox(item.element);
        item.height = rectBox.getHeight();
        item.width = rectBox.getWidth();
    };

    var arrange = function(item) {
        if (item.xcenter) {
            item.left = item.xcenter - (item.width / 2);
            item.right = item.left + item.width;
        } else {
            if (item.left) {
                if (!item.right) {
                    item.right = item.left + item.width;
                }
            } else {
                if (item.right) {
                    item.left = item.right - item.width;
                } else {
                    item.left = 0;
                    item.right = item.width;
                }
            }

            item.xcenter = item.left + (item.width / 2);
        }

        if (item.ycenter) {
            item.top = item.ycenter - (item.height / 2);
            item.bottom = item.top + item.height;
        } else {
            if (item.top) {
                if (!item.bottom) {
                    item.bottom = item.top + item.height;
                }
            } else {
                if (item.bottom) {
                    item.top = item.bottom - item.height;
                } else {
                    item.top = 0;
                    item.bottom = item.height;
                }
            }

            item.ycenter = item.top + (item.height / 2);
        }
    };

    var place = function(item) {
        var rectBox = new RectBox(item.element);
        rectBox.move(item.left, item.top);
    };

    var triggerRender = function(item) {
        var horizontal = item.right - item.left;
        var vertical = item.bottom - item.top;

        // If horizontal/vertical === NaN, its is still ok to go through:
        // it means that the item does not rely on horizontal/vertical to draw
        // itself on the stage.
        if (item.render) item.render(horizontal, vertical);
    };

    var position = function(context) {
        var layout = context.get();
        var schema = context.getProperties().schema;
        var item = Object.keys(layout[schema]);
        var newAnchor = {};

        for (var i = 0; i < item.length; i++) {

            newAnchor[item[i]] = processItem({
                layout: layout,
                schema: schema,
                item: item[i]
            }, context);

            triggerRender(layout[schema][item[i]]);
            fillHeightWidth(layout[schema][item[i]]);
            arrange(newAnchor[item[i]]);
            place(layout[schema][item[i]]);
        }
    };

    var update = function(context) {
        setCurrentMeasures(context);
        calculateStage(context);
        setSvgMeasures(context);
        setSvgViewBox(context);
        position(context);
    };

    var layoutManagerSingleton = {
        instances: [],

        updateAll: function() {
            for (var i = 0; i < this.instances.length; i++) {
                this.instances[i].update();
            }
        },

        instance: function() {
            var instance = {
                layout: {},

                properties: {
                    // for now, a d3 object
                    svg: undefined,
                    // for now, a d3 object
                    div: undefined,
                    // array with default width/height
                    defaultMeasures: { width: 900, height: 500 },
                    // array with current width/height
                    currentMeasures: { width: 900, height: 500 },
                    // the stage and its measures
                    stage: undefined,
                    // currently selected schema for updating
                    schema: undefined,
                },

                set: function(layout) {
                    this.layout = layout;
                },

                get: function() {
                    return extend({}, this.layout);
                },

                clear: function() {
                    this.layout = {};
                },

                add: function(layout) {
                    extend(this.layout, layout);
                },

                setProperties: function(properties) {
                    extend(this.properties, properties);
                },

                getProperties: function() {
                    return extend({}, this.properties);
                },

                update: function() {
                    update(this);
                }
            };

            register(this, instance);

            return instance;
        }
    };

    return layoutManagerSingleton;
});
<commit_msg>name fx<commit_after>define([
    'base/object',
    'base/rectBox'
], function(object, RectBox) {
    var extend = object.extend;

    var register = function(parentInstance, childInstance) {
        parentInstance.instances.push(childInstance);
        return parentInstance.instances;
    };

    var calculateStage = function(context) {
        var currentWidth = context.properties.currentMeasures.width;
        var currentHeight = context.properties.currentMeasures.height;

        var defaultWidth = context.properties.defaultMeasures.width;
        var defaultHeight = context.properties.defaultMeasures.height;

        var stage = {
            width: defaultWidth,
            height: defaultHeight
        };

        var newAspectRatio = currentWidth / currentHeight;
        var defaultAspectRatio = defaultWidth / defaultHeight;

        if (newAspectRatio < defaultAspectRatio) {
            stage.height = stage.width / newAspectRatio;
        } else if (newAspectRatio > defaultAspectRatio) {
            stage.width = stage.height * newAspectRatio;
        }

        context.setProperties({ stage: stage });

        return stage;
    };

    var setCurrentMeasures = function(context) {
        var div = context.properties.div;   // d3 object

        var boundingRect = div.node().getBoundingClientRect();

        var currentMeasures = {
            width: boundingRect.width,
            height: boundingRect.height
        };

        context.setProperties({ currentMeasures: currentMeasures });

        return currentMeasures;
    };

    var setSvgViewBox = function(context) {
        var svg = context.properties.svg;
        var stage = context.properties.stage;

        svg.attr('viewBox', '0 0 ' + stage.width + ' ' + stage.height);
        svg.attr('preserveAspectRatio', 'xMinYMin meet');

        return svg;
    };

    var setSvgMeasures = function(context) {
        var currentMeasures = context.properties.currentMeasures;
        var svg = context.properties.svg;

        svg.attr('width', currentMeasures.width);
        svg.attr('height', currentMeasures.height);
    };

    var processItem = function(item, context) {
        var layout = item.layout;
        var schema = item.schema;
        var item = item.item;
        var anchors = Object.keys(layout[schema][item]);

        for (var i = 0; i < anchors.length; i++) {
            // Skip reserved properties
            switch(anchors[i]) {
                case 'element':
                case 'render':
                    continue;
            }

            var point = layout[schema][item][anchors[i]];

            if (typeof point === 'object') {
                var linkedAnchor;
                if (point.parent !== 'stage') {
                    linkedAnchor = layout[schema][point.parent][point.anchor];
                } else {
                    linkedAnchor = context.properties.stage[point.anchor];
                }

                if (point.padding) linkedAnchor += point.padding;
                if (point.percentage) linkedAnchor *= (point.percentage / 100);

                // replace object with calculated value
                layout[schema][item][anchors[i]] = linkedAnchor;
            } else if (typeof point !== 'number') {
                layout[schema][item][anchors[i]] = Number(point);
            }
        }

        return layout[schema][item];
    };

    var fillHeightWidth = function(item) {
        // 'rectbox' a function/object instead of a plain d3 object!
        var rectBox = new RectBox(item.element);
        item.height = rectBox.getHeight();
        item.width = rectBox.getWidth();
    };

    var arrange = function(item) {
        if (item.xcenter) {
            item.left = item.xcenter - (item.width / 2);
            item.right = item.left + item.width;
        } else {
            if (item.left) {
                if (!item.right) {
                    item.right = item.left + item.width;
                }
            } else {
                if (item.right) {
                    item.left = item.right - item.width;
                } else {
                    item.left = 0;
                    item.right = item.width;
                }
            }

            item.xcenter = item.left + (item.width / 2);
        }

        if (item.ycenter) {
            item.top = item.ycenter - (item.height / 2);
            item.bottom = item.top + item.height;
        } else {
            if (item.top) {
                if (!item.bottom) {
                    item.bottom = item.top + item.height;
                }
            } else {
                if (item.bottom) {
                    item.top = item.bottom - item.height;
                } else {
                    item.top = 0;
                    item.bottom = item.height;
                }
            }

            item.ycenter = item.top + (item.height / 2);
        }
    };

    var place = function(item) {
        var rectBox = new RectBox(item.element);
        rectBox.move(item.left, item.top);
    };

    var triggerRender = function(item) {
        var horizontal = item.right - item.left;
        var vertical = item.bottom - item.top;

        // If horizontal/vertical === NaN, its is still ok to go through:
        // it means that the item does not rely on horizontal/vertical to draw
        // itself on the stage.
        if (item.render) item.render(horizontal, vertical);
    };

    var position = function(context) {
        var layout = context.get();
        var schema = context.getProperties().schema;
        var item = Object.keys(layout[schema]);
        var newAnchor = {};

        for (var i = 0; i < item.length; i++) {

            newAnchor[item[i]] = processItem({
                layout: layout,
                schema: schema,
                item: item[i]
            }, context);

            triggerRender(layout[schema][item[i]]);
            fillHeightWidth(layout[schema][item[i]]);
            arrange(newAnchor[item[i]]);
            place(layout[schema][item[i]]);
        }
    };

    var update = function(context) {
        setCurrentMeasures(context);
        calculateStage(context);
        setSvgMeasures(context);
        setSvgViewBox(context);
        position(context);
    };

    var layoutManagerSingleton = {
        instances: [],

        updateAll: function() {
            for (var i = 0; i < this.instances.length; i++) {
                this.instances[i].update();
            }
        },

        instance: function() {
            var instance = {
                layout: {},

                properties: {
                    // for now, a d3 object
                    svg: undefined,
                    // for now, a d3 object
                    div: undefined,
                    // array with default width/height
                    defaultMeasures: { width: 900, height: 500 },
                    // array with current width/height
                    currentMeasures: { width: 900, height: 500 },
                    // the stage and its measures
                    stage: undefined,
                    // currently selected schema for updating
                    schema: undefined,
                },

                set: function(layout) {
                    this.layout = layout;
                },

                get: function() {
                    return extend({}, this.layout);
                },

                clear: function() {
                    this.layout = {};
                },

                add: function(layout) {
                    extend(this.layout, layout);
                },

                setProperties: function(properties) {
                    extend(this.properties, properties);
                },

                getProperties: function() {
                    return extend({}, this.properties);
                },

                update: function() {
                    update(this);
                }
            };

            register(this, instance);

            return instance;
        }
    };

    return layoutManagerSingleton;
});
<|endoftext|>


<commit_before>/*! Sweetroll by https://unrelenting.technology | thanks to https://serviceworke.rs */
/* global localforage */

importScripts('/dist/localforage/dist/localforage.js')

const PRECACHED_ASSETS = []
const SLOW_NET_TIMEOUT = 4000

/* Simple push handling (why isn't there built-in functionality for URL focus-or-open?!) */

self.addEventListener('push', e => {
	const data = e.data.json()
	e.waitUntil(
		self.registration.showNotification('Sweetroll', { body: data.body, data: data })
	)
})

self.addEventListener('notificationclick', e => {
	e.notification.close()
	const data = e.notification.data
	if (!data) {
		return
	}
	e.waitUntil(
		self.clients.matchAll({ type: 'window' }).then(clientList => {
			for (const client of clientList) {
				if (client.url === data.url) {
					return client.focus()
				}
			}
			return self.clients.openWindow(new URL(data.url))
		})
	)
})

/* Smart site caching */

self.addEventListener('install', e => {
	e.waitUntil((async () => {
		try {
			await caches.delete('assets')
			const cache = await caches.open('assets')
			await cache.addAll(PRECACHED_ASSETS)
		} catch (err) {
			console.error(err)
		}
	})())
	e.waitUntil((async () => {
		try {
			await caches.delete('fallback')
			const cache = await caches.open('fallback')
			await cache.addAll(['/offline.html'])
		} catch (err) {
			console.error(err)
		}
	})())
	e.waitUntil((async () => {
		try {
			const cache = caches.open('pages')
			await cache.addAll(['/'])
		} catch (err) {
			console.error(err)
		}
	})())
})

self.addEventListener('fetch', e => {
	if (e.request.method === 'GET') {
		if ((e.request.url.includes('/dist/') || e.request.url.includes('/color.css')) &&
			(e.request.url.includes('?') || e.request.url.endsWith('.woff2'))) {
			// Assets: return cached if exists, they're all cachebusted with query strings
			// Not all assets should be precached, every visitor does not need micro-panel :D
			e.respondWith(
				fromCache('assets', e.request).catch(() =>
					fromNetwork(e.request)
						.then(resp => {
							if (resp.status < 200 || resp.status >= 300) {
								return resp
							}
							const resp2 = resp.clone()
							caches.open('assets')
								.then(cache => cache.put(e.request, resp2))
							return resp
						})
				)
			)
		} else if (e.request.headers.get('accept').includes('text/html')) {
			// Pages: load from network, show cached (but keep loading) on timeout for slow connections
			e.respondWith((async () => {
				const jr = await localforage.getItem('just-refreshed')
				if ((jr || []).includes(e.request.url)) {
					console.log('SW | Returning %cjust-refreshed%c page %s', 'color: green', 'color: inherit', e.request.url)
					try {
						await localforage.setItem('just-refreshed', setRemove(jr, e.request.url))
						return fromCache('pages', e.request)
					} catch (err) {
						console.error(err)
						return fromNetwork(e.request)
					}
				}
				try {
					const resp = await fromNetwork(e.request, SLOW_NET_TIMEOUT)
					await addPageToCache(e.request)(resp)
					return resp
				} catch (err) {
					console.log('SW | %cTimeout%c for page %s / $O', 'color: red', 'color: inherit', e.request.url, err)
					// timeout failed so we refetch without timeout *asynchronously*
					fromNetwork(e.request).then(async resp => {
						await addPageToCache(e.request)(resp)
						if (isFailed(resp)) {
							console.log('SW | Fetched %cserver error%c page %s', 'color: orange', 'color: inherit', e.request.url)
							alertClients(e.request.url, await self.clients.matchAll(), { event: 'failed', err: 'error ' + resp.status })
						} else {
							const jr = localforage.getItem('just-refreshed')
							await localforage.setItem('just-refreshed', setAdd(jr, e.request.url))
							console.log('SW | Added %cjust-refreshed%c page %s', 'color: green', 'color: inherit', e.request.url)
							alertClients(e.request.url, await self.clients.matchAll(), { event: 'refreshed-in-cache' })
						}
					}, async err => {
						console.log('SW | Failed to fetch page %s', e.request.url)
						alertClients(e.request.url, await self.clients.matchAll(), { event: 'failed', err: err.message })
					})
					try {
						const resp = await fromCache('pages', e.request)
						console.log('SW | Returning %ccached%c page %s', 'color: orange', 'color: inherit', e.request.url)
						const meta = {
							status: resp.status,
							statusText: resp.statusText,
							headers: {}
						}
						const hkeys = resp.headers.keys()
						for (const k of hkeys) {
							meta.headers[k] = resp.headers.get(k)
						}
						const body = await resp.text()
						return new Response(body + '<meta name="sw-offline" content="true">', meta)
					} catch (err) {
						console.log('SW | Returning %cfallback%c page for %s (%O)', 'color: red', 'color: inherit', e.request.url, err)
						return fromCache('fallback', 'offline.html')
					}
				}
			})())
		}
	}
})

function alertClients (url, clientList, data) {
	for (const client of clientList) {
		if (client.url === url) {
			client.postMessage(JSON.stringify(data))
		}
	}
}

function isFailed (resp) {
	return resp.status < 200 || resp.status >= 300 || !(resp.headers.get('content-type') || '').includes('html')
}

function addPageToCache (req) {
	return async function (resp) {
		if (isFailed(resp)) {
			return resp
		}
		const pages = await localforage.getItem('cached-pages')
		await localforage.setItem('cached-pages', setAdd(pages, req.url))
		const cache = await caches.open('pages')
		await cache.put(req, resp.clone())
		return resp
	}
}

async function fromCache (cname, req) {
	const cache = await caches.open(cname)
	const matching = await cache.match(req)
	if (!matching) {
		throw new Error('no-match')
	}
	return matching
}

function fromNetwork (req, timeout) {
	return new Promise((resolve, reject) => {
		const timeoutId = timeout && setTimeout(reject, timeout)
		fetch(req).then(resp => {
			timeoutId && clearTimeout(timeoutId)
			resolve(resp)
		}, reject)
	})
}

function setAdd (a, v) {
	return Array.from(new Set(a || []).add(v))
}

function setRemove (a, v) {
	return Array.from(new Set(a || []).delete(v))
}
<commit_msg>fe: sw: increase slow net timeout<commit_after>/*! Sweetroll by https://unrelenting.technology | thanks to https://serviceworke.rs */
/* global localforage */

importScripts('/dist/localforage/dist/localforage.js')

const PRECACHED_ASSETS = []
const SLOW_NET_TIMEOUT = 9000

/* Simple push handling (why isn't there built-in functionality for URL focus-or-open?!) */

self.addEventListener('push', e => {
	const data = e.data.json()
	e.waitUntil(
		self.registration.showNotification('Sweetroll', { body: data.body, data: data })
	)
})

self.addEventListener('notificationclick', e => {
	e.notification.close()
	const data = e.notification.data
	if (!data) {
		return
	}
	e.waitUntil(
		self.clients.matchAll({ type: 'window' }).then(clientList => {
			for (const client of clientList) {
				if (client.url === data.url) {
					return client.focus()
				}
			}
			return self.clients.openWindow(new URL(data.url))
		})
	)
})

/* Smart site caching */

self.addEventListener('install', e => {
	e.waitUntil((async () => {
		try {
			await caches.delete('assets')
			const cache = await caches.open('assets')
			await cache.addAll(PRECACHED_ASSETS)
		} catch (err) {
			console.error(err)
		}
	})())
	e.waitUntil((async () => {
		try {
			await caches.delete('fallback')
			const cache = await caches.open('fallback')
			await cache.addAll(['/offline.html'])
		} catch (err) {
			console.error(err)
		}
	})())
	e.waitUntil((async () => {
		try {
			const cache = caches.open('pages')
			await cache.addAll(['/'])
		} catch (err) {
			console.error(err)
		}
	})())
})

self.addEventListener('fetch', e => {
	if (e.request.method === 'GET') {
		if ((e.request.url.includes('/dist/') || e.request.url.includes('/color.css')) &&
			(e.request.url.includes('?') || e.request.url.endsWith('.woff2'))) {
			// Assets: return cached if exists, they're all cachebusted with query strings
			// Not all assets should be precached, every visitor does not need micro-panel :D
			e.respondWith(
				fromCache('assets', e.request).catch(() =>
					fromNetwork(e.request)
						.then(resp => {
							if (resp.status < 200 || resp.status >= 300) {
								return resp
							}
							const resp2 = resp.clone()
							caches.open('assets')
								.then(cache => cache.put(e.request, resp2))
							return resp
						})
				)
			)
		} else if (e.request.headers.get('accept').includes('text/html')) {
			// Pages: load from network, show cached (but keep loading) on timeout for slow connections
			e.respondWith((async () => {
				const jr = await localforage.getItem('just-refreshed')
				if ((jr || []).includes(e.request.url)) {
					console.log('SW | Returning %cjust-refreshed%c page %s', 'color: green', 'color: inherit', e.request.url)
					try {
						await localforage.setItem('just-refreshed', setRemove(jr, e.request.url))
						return fromCache('pages', e.request)
					} catch (err) {
						console.error(err)
						return fromNetwork(e.request)
					}
				}
				try {
					const resp = await fromNetwork(e.request, SLOW_NET_TIMEOUT)
					await addPageToCache(e.request)(resp)
					return resp
				} catch (err) {
					console.log('SW | %cTimeout%c for page %s / $O', 'color: red', 'color: inherit', e.request.url, err)
					// timeout failed so we refetch without timeout *asynchronously*
					fromNetwork(e.request).then(async resp => {
						await addPageToCache(e.request)(resp)
						if (isFailed(resp)) {
							console.log('SW | Fetched %cserver error%c page %s', 'color: orange', 'color: inherit', e.request.url)
							alertClients(e.request.url, await self.clients.matchAll(), { event: 'failed', err: 'error ' + resp.status })
						} else {
							const jr = localforage.getItem('just-refreshed')
							await localforage.setItem('just-refreshed', setAdd(jr, e.request.url))
							console.log('SW | Added %cjust-refreshed%c page %s', 'color: green', 'color: inherit', e.request.url)
							alertClients(e.request.url, await self.clients.matchAll(), { event: 'refreshed-in-cache' })
						}
					}, async err => {
						console.log('SW | Failed to fetch page %s', e.request.url)
						alertClients(e.request.url, await self.clients.matchAll(), { event: 'failed', err: err.message })
					})
					try {
						const resp = await fromCache('pages', e.request)
						console.log('SW | Returning %ccached%c page %s', 'color: orange', 'color: inherit', e.request.url)
						const meta = {
							status: resp.status,
							statusText: resp.statusText,
							headers: {}
						}
						const hkeys = resp.headers.keys()
						for (const k of hkeys) {
							meta.headers[k] = resp.headers.get(k)
						}
						const body = await resp.text()
						return new Response(body + '<meta name="sw-offline" content="true">', meta)
					} catch (err) {
						console.log('SW | Returning %cfallback%c page for %s (%O)', 'color: red', 'color: inherit', e.request.url, err)
						return fromCache('fallback', 'offline.html')
					}
				}
			})())
		}
	}
})

function alertClients (url, clientList, data) {
	for (const client of clientList) {
		if (client.url === url) {
			client.postMessage(JSON.stringify(data))
		}
	}
}

function isFailed (resp) {
	return resp.status < 200 || resp.status >= 300 || !(resp.headers.get('content-type') || '').includes('html')
}

function addPageToCache (req) {
	return async function (resp) {
		if (isFailed(resp)) {
			return resp
		}
		const pages = await localforage.getItem('cached-pages')
		await localforage.setItem('cached-pages', setAdd(pages, req.url))
		const cache = await caches.open('pages')
		await cache.put(req, resp.clone())
		return resp
	}
}

async function fromCache (cname, req) {
	const cache = await caches.open(cname)
	const matching = await cache.match(req)
	if (!matching) {
		throw new Error('no-match')
	}
	return matching
}

function fromNetwork (req, timeout) {
	return new Promise((resolve, reject) => {
		const timeoutId = timeout && setTimeout(reject, timeout)
		fetch(req).then(resp => {
			timeoutId && clearTimeout(timeoutId)
			resolve(resp)
		}, reject)
	})
}

function setAdd (a, v) {
	return Array.from(new Set(a || []).add(v))
}

function setRemove (a, v) {
	return Array.from(new Set(a || []).delete(v))
}
<|endoftext|>


<commit_before>angular.module('Shazam2Spotify')
	.config(function() {
		// Load SVG icons (dirty, should not use jQuery...)
		$.ajax({
			url: 'img/icons.svg',
			method: 'GET',
			dataType: 'html',
			success: function(data) {
				$("body").prepend(data);
			}
		});
	});<commit_msg>Load SVG icons with $http instead of jQuery<commit_after>angular.module('Shazam2Spotify')
	.run(function($http) {
		// Load SVG icons (dirty, should not use jQuery...)
		$http.get('img/icons.svg', {responseType: 'html'}).
			success(function(data) {
				angular.element('body').prepend(data);
			});
	});<|endoftext|>


<commit_before>'use strict';

var flatterData = function(arr) {
	var res = [];
	var i;
	for (i=0; i < arr.length; i++) {
		res.push([arr[i].name, '', '', '']);
	}
	console.log('res = ');
	console.log(res);
	return res;
}

angular.module('brewApp.directives')
    .directive('brewTable', function() {
        return {
            restrict: 'AE',
            link: function(scope, element) {
            	scope.$watch('ctrl.isLoading', function() {
            		if (!scope.ctrl.isLoading) {
            			scope.dataTableOptions.data = flatterData(scope.ctrl.recipes);
                		$(element).DataTable(scope.dataTableOptions);
                	}
            	});
            }
        };
    });
<commit_msg>removes console debug messages<commit_after>'use strict';

var flatterData = function(arr) {
	var res = [];
	var i;
	for (i=0; i < arr.length; i++) {
		res.push([arr[i].name, '', '', '']);
	}
	return res;
}

angular.module('brewApp.directives')
    .directive('brewTable', function() {
        return {
            restrict: 'AE',
            link: function(scope, element) {
            	scope.$watch('ctrl.isLoading', function() {
            		if (!scope.ctrl.isLoading) {
            			scope.dataTableOptions.data = flatterData(scope.ctrl.recipes);
                		$(element).DataTable(scope.dataTableOptions);
                	}
            	});
            }
        };
    });
<|endoftext|>


<commit_before>import { findHelper } from 'discourse-common/lib/helpers';

/* global requirejs, require */
var classify = Ember.String.classify;
var get = Ember.get;

var LOADING_WHITELIST = ['badges', 'userActivity', 'userPrivateMessages', 'admin', 'adminFlags',
                         'user', 'preferences', 'adminEmail', 'adminUsersList'];
var _dummyRoute;
var _loadingView;

function loadingResolver(cb) {
  return function(parsedName) {
    var fullNameWithoutType = parsedName.fullNameWithoutType;

    if (fullNameWithoutType.indexOf('Loading') >= 0) {
      fullNameWithoutType = fullNameWithoutType.replace('Loading', '');
      if (LOADING_WHITELIST.indexOf(fullNameWithoutType) !== -1) {
        return cb(fullNameWithoutType);
      }
    }
  };
}

function parseName(fullName) {
  const nameParts = fullName.split(":"),
        type = nameParts[0], fullNameWithoutType = nameParts[1],
        name = fullNameWithoutType,
        namespace = get(this, 'namespace'),
        root = namespace;

  return {
    fullName: fullName,
    type: type,
    fullNameWithoutType: fullNameWithoutType,
    name: name,
    root: root,
    resolveMethodName: "resolve" + classify(type)
  };
}

export function buildResolver(baseName) {
  return Ember.DefaultResolver.extend({
    parseName,

    resolveRouter(parsedName) {
      const routerPath = `${baseName}/router`;
      if (requirejs.entries[routerPath]) {
        const module = require(routerPath, null, null, true);
        return module.default;
      }
      return this._super(parsedName);
    },

    normalize(fullName) {
      const split = fullName.split(':');
      if (split.length > 1) {
        const appBase = `${baseName}/${split[0]}s/`;
        const adminBase = 'admin/' + split[0] + 's/';

        // Allow render 'admin/templates/xyz' too
        split[1] = split[1].replace('.templates', '').replace('/templates', '');

        // Try slashes
        let dashed = Ember.String.dasherize(split[1].replace(/\./g, '/'));
        if (requirejs.entries[appBase + dashed] || requirejs.entries[adminBase + dashed]) {
          return split[0] + ":" + dashed;
        }

        // Try with dashes instead of slashes
        dashed = Ember.String.dasherize(split[1].replace(/\./g, '-'));
        if (requirejs.entries[appBase + dashed] || requirejs.entries[adminBase + dashed]) {
          return split[0] + ":" + dashed;
        }
      }
      return this._super(fullName);
    },

    customResolve(parsedName) {
      // If we end with the name we want, use it. This allows us to define components within plugins.
      const suffix = parsedName.type + 's/' + parsedName.fullNameWithoutType,
            dashed = Ember.String.dasherize(suffix),
            moduleName = Object.keys(requirejs.entries).find(function(e) {
              return (e.indexOf(suffix, e.length - suffix.length) !== -1) ||
                     (e.indexOf(dashed, e.length - dashed.length) !== -1);
            });

      var module;
      if (moduleName) {
        module = require(moduleName, null, null, true /* force sync */);
        if (module && module['default']) { module = module['default']; }
      }
      return module;
    },

    resolveWidget(parsedName) {
      return this.customResolve(parsedName) || this._super(parsedName);
    },

    resolveAdapter(parsedName) {
      return this.customResolve(parsedName) || this._super(parsedName);
    },

    resolveModel(parsedName) {
      return this.customResolve(parsedName) || this._super(parsedName);
    },

    resolveView(parsedName) {
      return this.findLoadingView(parsedName) || this.customResolve(parsedName) || this._super(parsedName);
    },

    resolveHelper(parsedName) {
      return findHelper(parsedName.fullNameWithoutType) ||
             this.customResolve(parsedName) ||
             this._super(parsedName);
    },

    resolveController(parsedName) {
      return this.customResolve(parsedName) || this._super(parsedName);
    },

    resolveComponent(parsedName) {
      return this.customResolve(parsedName) || this._super(parsedName);
    },

    resolveService(parsedName) {
      return this.customResolve(parsedName) || this._super(parsedName);
    },

    resolveRoute(parsedName) {
      return this.findLoadingRoute(parsedName) || this.customResolve(parsedName) || this._super(parsedName);
    },

    resolveTemplate(parsedName) {
      let fullName = parsedName.fullNameWithoutType;
      if (fullName.indexOf('.raw') !== -1) {
        return Ember.TEMPLATES[fullName] ||
               Ember.TEMPLATES[fullName.replace(/\.raw$/, '')];
      }

      return this.findPluginMobileTemplate(parsedName) ||
             this.findPluginTemplate(parsedName) ||
             this.findMobileTemplate(parsedName) ||
             this.findTemplate(parsedName) ||
             Ember.TEMPLATES.not_found;
    },

    findLoadingRoute: loadingResolver(function() {
      _dummyRoute = _dummyRoute || Ember.Route.extend();
      return _dummyRoute;
    }),

    findLoadingView: loadingResolver(function() {
      if (!_loadingView) {
        _loadingView = require('discourse/views/loading', null, null, true /* force sync */);
        if (_loadingView && _loadingView['default']) { _loadingView = _loadingView['default']; }
      }
      return _loadingView;
    }),

    findPluginTemplate(parsedName) {
      var pluginParsedName = this.parseName(parsedName.fullName.replace("template:", "template:javascripts/"));
      return this.findTemplate(pluginParsedName);
    },

    findPluginMobileTemplate(parsedName) {
      if (this.mobileView) {
        var pluginParsedName = this.parseName(parsedName.fullName.replace("template:", "template:javascripts/mobile/"));
        return this.findTemplate(pluginParsedName);
      }
    },

    findMobileTemplate(parsedName) {
      if (this.mobileView) {
        var mobileParsedName = this.parseName(parsedName.fullName.replace("template:", "template:mobile/"));
        return this.findTemplate(mobileParsedName);
      }
    },

    findTemplate(parsedName) {
      const withoutType = parsedName.fullNameWithoutType,
            slashedType = withoutType.replace(/\./g, '/'),
            decamelized = withoutType.decamelize(),
            dashed = decamelized.replace(/\./g, '-').replace(/\_/g, '-'),
            templates = Ember.TEMPLATES;

      return this._super(parsedName) ||
             templates[slashedType] ||
             templates[withoutType] ||
             templates[dashed] ||
             templates[decamelized.replace(/\./, '/')] ||
             templates[decamelized.replace(/\_/, '/')] ||
             templates[`${baseName}/templates/${withoutType}`] ||
             this.findAdminTemplate(parsedName) ||
             this.findUnderscoredTemplate(parsedName);
    },

    findUnderscoredTemplate(parsedName) {
      var decamelized = parsedName.fullNameWithoutType.decamelize();
      var underscored = decamelized.replace(/\-/g, "_");
      return Ember.TEMPLATES[underscored];
    },

    // Try to find a template within a special admin namespace, e.g. adminEmail => admin/templates/email
    // (similar to how discourse lays out templates)
    findAdminTemplate(parsedName) {
      var decamelized = parsedName.fullNameWithoutType.decamelize();

      if (decamelized.indexOf('components') === 0) {
        const compTemplate = Ember.TEMPLATES['admin/templates/' + decamelized];
        if (compTemplate) { return compTemplate; }
      }

      if (decamelized === "javascripts/admin") {
        return Ember.TEMPLATES['admin/templates/admin'];
      }

      if (decamelized.indexOf('admin') === 0 || decamelized.indexOf('javascripts/admin') === 0) {
        decamelized = decamelized.replace(/^admin\_/, 'admin/templates/');
        decamelized = decamelized.replace(/^admin\./, 'admin/templates/');
        decamelized = decamelized.replace(/\./g, '_');

        const dashed = decamelized.replace(/_/g, '-');
        return Ember.TEMPLATES[decamelized] ||
               Ember.TEMPLATES[dashed] ||
               Ember.TEMPLATES[dashed.replace('admin-', 'admin/')];
      }
    }

  });
}
<commit_msg>FIX: Mobile raw templates weren't being resolved<commit_after>import { findHelper } from 'discourse-common/lib/helpers';

/* global requirejs, require */
var classify = Ember.String.classify;
var get = Ember.get;

var LOADING_WHITELIST = ['badges', 'userActivity', 'userPrivateMessages', 'admin', 'adminFlags',
                         'user', 'preferences', 'adminEmail', 'adminUsersList'];
var _dummyRoute;
var _loadingView;

function loadingResolver(cb) {
  return function(parsedName) {
    var fullNameWithoutType = parsedName.fullNameWithoutType;

    if (fullNameWithoutType.indexOf('Loading') >= 0) {
      fullNameWithoutType = fullNameWithoutType.replace('Loading', '');
      if (LOADING_WHITELIST.indexOf(fullNameWithoutType) !== -1) {
        return cb(fullNameWithoutType);
      }
    }
  };
}

function parseName(fullName) {
  const nameParts = fullName.split(":"),
        type = nameParts[0], fullNameWithoutType = nameParts[1],
        name = fullNameWithoutType,
        namespace = get(this, 'namespace'),
        root = namespace;

  return {
    fullName: fullName,
    type: type,
    fullNameWithoutType: fullNameWithoutType,
    name: name,
    root: root,
    resolveMethodName: "resolve" + classify(type)
  };
}

export function buildResolver(baseName) {
  return Ember.DefaultResolver.extend({
    parseName,

    resolveRouter(parsedName) {
      const routerPath = `${baseName}/router`;
      if (requirejs.entries[routerPath]) {
        const module = require(routerPath, null, null, true);
        return module.default;
      }
      return this._super(parsedName);
    },

    normalize(fullName) {
      const split = fullName.split(':');
      if (split.length > 1) {
        const appBase = `${baseName}/${split[0]}s/`;
        const adminBase = 'admin/' + split[0] + 's/';

        // Allow render 'admin/templates/xyz' too
        split[1] = split[1].replace('.templates', '').replace('/templates', '');

        // Try slashes
        let dashed = Ember.String.dasherize(split[1].replace(/\./g, '/'));
        if (requirejs.entries[appBase + dashed] || requirejs.entries[adminBase + dashed]) {
          return split[0] + ":" + dashed;
        }

        // Try with dashes instead of slashes
        dashed = Ember.String.dasherize(split[1].replace(/\./g, '-'));
        if (requirejs.entries[appBase + dashed] || requirejs.entries[adminBase + dashed]) {
          return split[0] + ":" + dashed;
        }
      }
      return this._super(fullName);
    },

    customResolve(parsedName) {
      // If we end with the name we want, use it. This allows us to define components within plugins.
      const suffix = parsedName.type + 's/' + parsedName.fullNameWithoutType,
            dashed = Ember.String.dasherize(suffix),
            moduleName = Object.keys(requirejs.entries).find(function(e) {
              return (e.indexOf(suffix, e.length - suffix.length) !== -1) ||
                     (e.indexOf(dashed, e.length - dashed.length) !== -1);
            });

      var module;
      if (moduleName) {
        module = require(moduleName, null, null, true /* force sync */);
        if (module && module['default']) { module = module['default']; }
      }
      return module;
    },

    resolveWidget(parsedName) {
      return this.customResolve(parsedName) || this._super(parsedName);
    },

    resolveAdapter(parsedName) {
      return this.customResolve(parsedName) || this._super(parsedName);
    },

    resolveModel(parsedName) {
      return this.customResolve(parsedName) || this._super(parsedName);
    },

    resolveView(parsedName) {
      return this.findLoadingView(parsedName) || this.customResolve(parsedName) || this._super(parsedName);
    },

    resolveHelper(parsedName) {
      return findHelper(parsedName.fullNameWithoutType) ||
             this.customResolve(parsedName) ||
             this._super(parsedName);
    },

    resolveController(parsedName) {
      return this.customResolve(parsedName) || this._super(parsedName);
    },

    resolveComponent(parsedName) {
      return this.customResolve(parsedName) || this._super(parsedName);
    },

    resolveService(parsedName) {
      return this.customResolve(parsedName) || this._super(parsedName);
    },

    resolveRoute(parsedName) {
      return this.findLoadingRoute(parsedName) || this.customResolve(parsedName) || this._super(parsedName);
    },

    resolveTemplate(parsedName) {
      return this.findPluginMobileTemplate(parsedName) ||
             this.findPluginTemplate(parsedName) ||
             this.findMobileTemplate(parsedName) ||
             this.findTemplate(parsedName) ||
             Ember.TEMPLATES.not_found;
    },

    findLoadingRoute: loadingResolver(function() {
      _dummyRoute = _dummyRoute || Ember.Route.extend();
      return _dummyRoute;
    }),

    findLoadingView: loadingResolver(function() {
      if (!_loadingView) {
        _loadingView = require('discourse/views/loading', null, null, true /* force sync */);
        if (_loadingView && _loadingView['default']) { _loadingView = _loadingView['default']; }
      }
      return _loadingView;
    }),

    findPluginTemplate(parsedName) {
      var pluginParsedName = this.parseName(parsedName.fullName.replace("template:", "template:javascripts/"));
      return this.findTemplate(pluginParsedName);
    },

    findPluginMobileTemplate(parsedName) {
      if (this.mobileView) {
        var pluginParsedName = this.parseName(parsedName.fullName.replace("template:", "template:javascripts/mobile/"));
        return this.findTemplate(pluginParsedName);
      }
    },

    findMobileTemplate(parsedName) {
      if (this.mobileView) {
        var mobileParsedName = this.parseName(parsedName.fullName.replace("template:", "template:mobile/"));
        return this.findTemplate(mobileParsedName);
      }
    },

    findTemplate(parsedName) {
      const withoutType = parsedName.fullNameWithoutType,
            slashedType = withoutType.replace(/\./g, '/'),
            decamelized = withoutType.decamelize(),
            dashed = decamelized.replace(/\./g, '-').replace(/\_/g, '-'),
            templates = Ember.TEMPLATES;

      return this._super(parsedName) ||
             templates[slashedType] ||
             templates[withoutType] ||
             templates[withoutType.replace(/\.raw$/, '')] ||
             templates[dashed] ||
             templates[decamelized.replace(/\./, '/')] ||
             templates[decamelized.replace(/\_/, '/')] ||
             templates[`${baseName}/templates/${withoutType}`] ||
             this.findAdminTemplate(parsedName) ||
             this.findUnderscoredTemplate(parsedName);
    },

    findUnderscoredTemplate(parsedName) {
      var decamelized = parsedName.fullNameWithoutType.decamelize();
      var underscored = decamelized.replace(/\-/g, "_");
      return Ember.TEMPLATES[underscored];
    },

    // Try to find a template within a special admin namespace, e.g. adminEmail => admin/templates/email
    // (similar to how discourse lays out templates)
    findAdminTemplate(parsedName) {
      var decamelized = parsedName.fullNameWithoutType.decamelize();

      if (decamelized.indexOf('components') === 0) {
        const compTemplate = Ember.TEMPLATES['admin/templates/' + decamelized];
        if (compTemplate) { return compTemplate; }
      }

      if (decamelized === "javascripts/admin") {
        return Ember.TEMPLATES['admin/templates/admin'];
      }

      if (decamelized.indexOf('admin') === 0 || decamelized.indexOf('javascripts/admin') === 0) {
        decamelized = decamelized.replace(/^admin\_/, 'admin/templates/');
        decamelized = decamelized.replace(/^admin\./, 'admin/templates/');
        decamelized = decamelized.replace(/\./g, '_');

        const dashed = decamelized.replace(/_/g, '-');
        return Ember.TEMPLATES[decamelized] ||
               Ember.TEMPLATES[dashed] ||
               Ember.TEMPLATES[dashed.replace('admin-', 'admin/')];
      }
    }

  });
}
<|endoftext|>


<commit_before>$.fn.activeFeedback  = function() {
   form = this.closest('form');
   active = this.find('.step.active');
   if(form.valid()) {
      active.removeClass('wrong');
      active.find('.step-content').prepend('

');
   } else {
      active.addClass('wrong');
   }
};

$.fn.nextStep = function() {
   form = this.closest('form');
   active = this.find('.step.active');
   if(form.valid()) {
      active.find('.step-content').find('.wait-feedback').remove();
      active.removeClass('active wrong').addClass('done').find('.step-content').stop().slideUp('normal');
      active.next().addClass('active').find('.step-content').slideDown('normal');
   } else {
      active.removeClass('done').addClass('wrong');
   }
};

$.fn.prevStep = function() {
   active = this.find('.step.active');
   active.removeClass('active').find('.step-content').stop().slideUp('normal');
   active.prev().removeClass('done').addClass('active').find('.step-content').slideDown('normal');
};

$.fn.openStep = function(step) {
   step = this.find('.step:eq('+step+')');
   if(step.hasClass('active')) return;
   active = this.find('.step.active');
   active.removeClass('active').find('.step-content').stop().slideUp('normal');
   step.addClass('active').find('.step-content').slideDown('normal');
};

$.fn.activateStepper = function() {
   $(this).each(function(){
      var $stepper = $(this);
      method = $stepper.attr('method');
      action = $stepper.attr('action');
      method = (method ? method : "GET");
      action = (action ? action : "?");
      $stepper.wrap( '<form action="'+action+'" method="'+method+'">
' );
      $stepper.find('li.step.active .step-content').slideDown('normal');
      $stepper.find('li.step .step-title').each(function(index) {
         var myIndex = index + 1;
         $(this).prepend('
'+myIndex+'
');
      });

      $stepper.on("click", '.step:not(.active)', function () {
         if(!$stepper.hasClass('linear')) {
            object = $('.step').index($(this));
            $stepper.openStep(object);
         }
      }).on("click", '.next-step', function (e) {
         e.preventDefault();
         if($stepper.data("feedback")) {
            $stepper.activeFeedback();
            return window[$stepper.data("feedback")].call();
         }
         $stepper.nextStep();
      }).on("click", '.previous-step', function (e) {
         e.preventDefault();
         $stepper.prevStep();
      });
   });
};
<commit_msg>Delete materialize-stepper.js<commit_after><|endoftext|>


<commit_before>angular
  .module('mapcache')
  .controller('MapcacheCreateController', MapcacheCreateController);

MapcacheCreateController.$inject = [
  '$scope',
  '$location',
  '$http',
  '$routeParams',
  '$modal',
  'CacheService',
  'SourceService'
];

function MapcacheCreateController($scope, $location, $http, $routeParams, $modal, CacheService, SourceService) {

  $scope.currentAdminPanel = $routeParams.adminPanel || "user";

  var seenCorners;
  var boundsSet = false;

  var defaultStyle = {
    'fill': "#000000",
    'fill-opacity': 0.5,
    'stroke': "#0000FF",
    'stroke-opacity': 1.0,
    'stroke-width': 1
  };
  $scope.featureProperties = [];
  $scope.newRule = {
    style: angular.copy(defaultStyle)
  };

  $http.get('/api/server')
  .success(function(data, status) {
    $scope.storage = data;
  }).error(function(data, status) {
    console.log("error pulling server data", status);
  });

  $scope.bb = {};

  $scope.cache = {
    format: "xyz",
    create: {}
  };

  $scope.sizes = [{
    label: 'MB',
    multiplier: 1024*1024
  },{
    label: 'GB',
    multiplier: 1024*1024*1024
  }];

  $scope.cache.selectedSizeMultiplier = $scope.sizes[0];
  $scope.loadingSources = true;
  SourceService.getAllSources(true).success(function(sources) {
    $scope.loadingSources = false;
    $scope.sources = sources;
    if ($routeParams.sourceId) {
      for (var i = 0; i < $scope.sources.length && $scope.cache.source == null; i++) {
        if ($routeParams.sourceId == $scope.sources[i].id) {
          $scope.cache.source = $scope.sources[i];
        }
      }
    }
  }).error(function(error) {
    $scope.loadingSources = false;
  });

  $scope.useCurrentView = function() {
    $scope.cache.useCurrentView = Date.now();
  }

  $scope.dmsChange = function(direction, dms) {
    $scope.bb[direction] = (!isNaN(dms.degrees) ? Number(dms.degrees) : 0) + (!isNaN(dms.minutes) ? dms.minutes/60 : 0) + (!isNaN(dms.seconds) ? dms.seconds/(60*60) : 0);
    $scope.manualEntry();
  }

  $scope.manualEntry = function() {
    console.log('manual entry', $scope.bb);
    if (isNaN($scope.bb.north) || !$scope.bb.north || $scope.bb.north.toString().endsWith('.')
    || isNaN($scope.bb.south) || !$scope.bb.south || $scope.bb.south.toString().endsWith('.')
    || isNaN($scope.bb.west) || !$scope.bb.west || $scope.bb.west.toString().endsWith('.')
    || isNaN($scope.bb.east) || !$scope.bb.east || $scope.bb.east.toString().endsWith('.')) {
      boundsSet = false;
      $scope.$broadcast('extentChanged', null);
      return true;
    }
    boundsSet = true;
    console.log("all directions are set");
    var envelope = {
      north: Number($scope.bb.north),
      south: Number($scope.bb.south),
      west: Number($scope.bb.west),
      east: Number($scope.bb.east)
    };

    $scope.$broadcast('extentChanged', envelope);
  }

  function setDirectionDMS (deg, direction) {
     var d = Math.floor (deg);
     var minfloat = (deg-d)*60;
     var m = Math.floor(minfloat);
     var secfloat = (minfloat-m)*60;
     var s = Math.round(secfloat);
     direction.degrees = d;
     direction.minutes = m;
     direction.seconds = s;
}

  $scope.$watch('cache.geometry', function(geometry) {
    if (!geometry) {
      $scope.bb.north = null;
      $scope.bb.south = null;
      $scope.bb.west = null;
      $scope.bb.east = null;
      $scope.north = {};
      $scope.south = {};
      $scope.west = {};
      $scope.east = {};
      boundsSet = false;
      return;
    }
    boundsSet = true;
    var extent = turf.extent(geometry);
    $scope.bb.north = extent[3];
    setDirectionDMS($scope.bb.north, $scope.north);
    $scope.bb.south = extent[1];
    setDirectionDMS($scope.bb.south, $scope.south);
    $scope.bb.west = extent[0];
    setDirectionDMS($scope.bb.west, $scope.west);
    $scope.bb.east = extent[2];
    setDirectionDMS($scope.bb.east, $scope.east);

    calculateCacheSize();
  });

  $scope.$watch('cache.source', function(source) {
    $scope.cache.create = {};
    if ($scope.cache.source) {
      $scope.cache.style = $scope.cache.source.style;
      for (var i = 0; i < $scope.cache.source.cacheTypes.length; i++) {
        var type = $scope.cache.source.cacheTypes[i];
        $scope.cache.create[type.type] = type.required;
      }
      $scope.requiredFieldsSet();
    }

    if (!source || !source.geometry) {
      $scope.bb.north = null;
      $scope.bb.south = null;
      $scope.bb.west = null;
      $scope.bb.east = null;
      $scope.cache.geometry = null;
      return;
    }
    if (source && source.format == 'geotiff') {
      var geometry = source.geometry;
      while(geometry.type != "Polygon" && geometry != null){
        geometry = geometry.geometry;
      }
      $scope.cache.geometry = geometry;
    }
  });

  $scope.$watch('cache.source.previewLayer', function(layer, oldLayer) {
    if (layer) {
      if (layer.EX_GeographicBoundingBox) {
        $scope.cache.extent = layer.EX_GeographicBoundingBox;
      }
    }
  });

  $scope.$watch('cache.minZoom+cache.maxZoom', calculateCacheSize);

  $scope.requiredFieldsSet = function() {
    $scope.unsetFields = [];

    if (!$scope.cache.source) {
      $scope.unsetFields.push('cache source');
      return false;
    }

    if (!$scope.cache.name) {
      $scope.unsetFields.push('cache name');
    }

    var zoomValidated = false;
    if (isNaN($scope.cache.minZoom) || isNaN($scope.cache.maxZoom) || $scope.cache.maxZoom === null || $scope.cache.minZoom === null) {
      zoomValidated = false;
    } else if ($scope.cache.minZoom === 0 && $scope.cache.maxZoom === 0) {
      zoomValidated = true;
    } else if ($scope.cache.minZoom === 0 && $scope.cache.maxZoom > 0) {
      zoomValidated = true;
    } else if ($scope.cache.maxZoom >= $scope.cache.minZoom) {
      zoomValidated = true;
    }

    var cacheTypeSet = false;
    console.log('scope.cache.create', $scope.cache.create);
    for (var type in $scope.cache.create) {
      if ($scope.cache.create[type] == true) {
        cacheTypeSet = true;
      }
    }

    if (!cacheTypeSet) {
      $scope.unsetFields.push('type of cache to create');
    }

    if (!zoomValidated) {
      $scope.unsetFields.push('zoom levels')
    }
    if (!boundsSet) {
      $scope.unsetFields.push('cache boundaries');
    }

    if ($scope.cache.source.format == 'wms' && !$scope.cache.source.previewLayer) {
      $scope.unsetFields.push('WMS layer');
      return false;
    }

    return $scope.cache.geometry && boundsSet && $scope.cache.name && $scope.cache.source && (zoomValidated || $scope.cache.source.vector);
  }

  $scope.createCache = function() {
    if ($scope.cache.rawTileSizeLimit) {
      $scope.cache.tileSizeLimit = $scope.cache.rawTileSizeLimit * $scope.cache.selectedSizeMultiplier.multiplier;
    }
    console.log($scope.cache);
    $scope.creatingCache = true;
    $scope.cacheCreationError = null;
    $scope.cache.cacheCreationParams = {};
    if ($scope.cache.source.previewLayer) {
      $scope.cache.cacheCreationParams.layer = $scope.cache.source.previewLayer.Name;
    };
    var create = [];
    for (var type in $scope.cache.create) {
      if ($scope.cache.create[type]) {
        create.push(type);
      }
    }
    $scope.cache.create = create;
    CacheService.createCache($scope.cache, function(cache) {
      $scope.creatingCache = false;
      $location.path('/cache/'+cache.id);
    }, function(error, status) {
      $scope.creatingCache = false;
      $scope.cacheCreationError = {error: error, status: status};
    });
  }

  $scope.createSource = function() {
    $location.path('/source');
  }

  function calculateCacheSize() {
    if (!$scope.cache.source || ((isNaN($scope.cache.minZoom) || isNaN($scope.cache.maxZoom)) && !$scope.cache.source.vector) || !$scope.cache.geometry) return;
    $scope.totalCacheSize = 0;
    $scope.totalCacheTiles = 0;
    var extent = turf.extent($scope.cache.geometry);
    for (var i = $scope.cache.minZoom; i <= $scope.cache.maxZoom; i++) {
      var xtiles = xCalculator(extent, i);
      var ytiles = yCalculator(extent, i);
      $scope.totalCacheTiles += (1 + (ytiles.max - ytiles.min)) * (1 + (xtiles.max - xtiles.min));
    }
    $scope.totalCacheSize = $scope.totalCacheTiles * ($scope.cache.source.tileSize/$scope.cache.source.tileSizeCount);
    $scope.cacheFeatures = 0;
    $scope.cache.source.totalFeatures = $scope.cache.source.data ? $scope.cache.source.data.features.length : 0;
    if ($scope.cache.source.vector) {
      var poly = turf.bboxPolygon(extent);
      for (var i = 0; i < $scope.cache.source.data.features.length; i++) {
        var feature = $scope.cache.source.data.features[i];
        var intersection = turf.intersect(poly, feature);
        if (intersection) {
          $scope.cacheFeatures++;
        }
      }
    }
  }

  Math.radians = function(degrees) {
    return degrees * Math.PI / 180;
  };

  // Converts from radians to degrees.
  Math.degrees = function(radians) {
    return radians * 180 / Math.PI;
  };

  function tile2lon(x,z) {
    return (x/Math.pow(2,z)*360-180);
  }

  function tile2lat(y,z) {
    var n=Math.PI-2*Math.PI*y/Math.pow(2,z);
    return (180/Math.PI*Math.atan(0.5*(Math.exp(n)-Math.exp(-n))));
  }

  function tileBboxCalculator(x, y, z) {
    console.log('tile box calculator for ' + x + ' ' + y + ' ' + z);
    x = Number(x);
    y = Number(y);
    var tileBounds = {
      north: tile2lat(y, z),
      east: tile2lon(x+1, z),
      south: tile2lat(y+1, z),
      west: tile2lon(x, z)
    };

    return tileBounds;
  }

   function xCalculator(bbox,z) {
  	var x = [];
  	var x1 = getX(Number(bbox[0]), z);
  	var x2 = getX(Number(bbox[2]), z);
  	x.max = Math.max(x1, x2);
  	x.min = Math.min(x1, x2);
  	if (z == 0){
  		x.current = Math.min(x1, x2);
  	}
  	return x;
  }

  function yCalculator(bbox,z) {
  	var y = [];
  	var y1 = getY(Number(bbox[1]), z);
  	var y2 = getY(Number(bbox[3]), z);
  	y.max = Math.max(y1, y2);
  	y.min = Math.min(y1, y2);
  	y.current = Math.min(y1, y2);
  	return y;
  }

  function getX(lon, zoom) {
  	var xtile = Math.floor((lon + 180) / 360 * (1 << zoom));
  	return xtile;
  }

  function getY(lat, zoom) {
  	var ytile = Math.floor((1 - Math.log(Math.tan(Math.radians(parseFloat(lat))) + 1 / Math.cos(Math.radians(parseFloat(lat)))) / Math.PI) /2 * (1 << zoom));
  	return ytile;
  }

};
<commit_msg>corrected some logic<commit_after>angular
  .module('mapcache')
  .controller('MapcacheCreateController', MapcacheCreateController);

MapcacheCreateController.$inject = [
  '$scope',
  '$location',
  '$http',
  '$routeParams',
  '$modal',
  'CacheService',
  'SourceService'
];

function MapcacheCreateController($scope, $location, $http, $routeParams, $modal, CacheService, SourceService) {

  $scope.currentAdminPanel = $routeParams.adminPanel || "user";

  var seenCorners;
  var boundsSet = false;

  var defaultStyle = {
    'fill': "#000000",
    'fill-opacity': 0.5,
    'stroke': "#0000FF",
    'stroke-opacity': 1.0,
    'stroke-width': 1
  };
  $scope.featureProperties = [];
  $scope.newRule = {
    style: angular.copy(defaultStyle)
  };

  $http.get('/api/server')
  .success(function(data, status) {
    $scope.storage = data;
  }).error(function(data, status) {
    console.log("error pulling server data", status);
  });

  $scope.bb = {};

  $scope.cache = {
    format: "xyz",
    create: {}
  };

  $scope.sizes = [{
    label: 'MB',
    multiplier: 1024*1024
  },{
    label: 'GB',
    multiplier: 1024*1024*1024
  }];

  $scope.cache.selectedSizeMultiplier = $scope.sizes[0];
  $scope.loadingSources = true;
  SourceService.getAllSources(true).success(function(sources) {
    $scope.loadingSources = false;
    $scope.sources = sources;
    if ($routeParams.sourceId) {
      for (var i = 0; i < $scope.sources.length && $scope.cache.source == null; i++) {
        if ($routeParams.sourceId == $scope.sources[i].id) {
          $scope.cache.source = $scope.sources[i];
        }
      }
    }
  }).error(function(error) {
    $scope.loadingSources = false;
  });

  $scope.useCurrentView = function() {
    $scope.cache.useCurrentView = Date.now();
  }

  $scope.dmsChange = function(direction, dms) {
    $scope.bb[direction] = (!isNaN(dms.degrees) ? Number(dms.degrees) : 0) + (!isNaN(dms.minutes) ? dms.minutes/60 : 0) + (!isNaN(dms.seconds) ? dms.seconds/(60*60) : 0);
    $scope.manualEntry();
  }

  $scope.manualEntry = function() {
    console.log('manual entry', $scope.bb);
    setDirectionDMS($scope.bb.north, $scope.north);
    setDirectionDMS($scope.bb.south, $scope.south);
    setDirectionDMS($scope.bb.east, $scope.east);
    setDirectionDMS($scope.bb.west, $scope.west);
    if (isNaN($scope.bb.north) || !$scope.bb.north || $scope.bb.north.toString().endsWith('.')
    || isNaN($scope.bb.south) || !$scope.bb.south || $scope.bb.south.toString().endsWith('.')
    || isNaN($scope.bb.west) || !$scope.bb.west || $scope.bb.west.toString().endsWith('.')
    || isNaN($scope.bb.east) || !$scope.bb.east || $scope.bb.east.toString().endsWith('.')) {
      boundsSet = false;
      $scope.$broadcast('extentChanged', null);
      return true;
    }
    boundsSet = true;
    console.log("all directions are set");
    var envelope = {
      north: Number($scope.bb.north),
      south: Number($scope.bb.south),
      west: Number($scope.bb.west),
      east: Number($scope.bb.east)
    };

    $scope.$broadcast('extentChanged', envelope);
  }

  function setDirectionDMS (deg, direction) {
    if (!deg) return;
     var d = Math.floor (deg);
     var minfloat = (deg-d)*60;
     var m = Math.floor(minfloat);
     var secfloat = (minfloat-m)*60;
     var s = Math.round(secfloat);
     direction.degrees = d;
     direction.minutes = m;
     direction.seconds = s;
}

  $scope.$watch('cache.geometry', function(geometry) {
    if (!geometry) {
      $scope.bb.north = null;
      $scope.bb.south = null;
      $scope.bb.west = null;
      $scope.bb.east = null;
      $scope.north = {};
      $scope.south = {};
      $scope.west = {};
      $scope.east = {};
      boundsSet = false;
      return;
    }
    boundsSet = true;
    var extent = turf.extent(geometry);
    $scope.bb.north = extent[3];
    setDirectionDMS($scope.bb.north, $scope.north);
    $scope.bb.south = extent[1];
    setDirectionDMS($scope.bb.south, $scope.south);
    $scope.bb.west = extent[0];
    setDirectionDMS($scope.bb.west, $scope.west);
    $scope.bb.east = extent[2];
    setDirectionDMS($scope.bb.east, $scope.east);

    calculateCacheSize();
  });

  $scope.$watch('cache.source', function(source) {
    $scope.cache.create = {};
    if ($scope.cache.source) {
      $scope.cache.style = $scope.cache.source.style;
      for (var i = 0; i < $scope.cache.source.cacheTypes.length; i++) {
        var type = $scope.cache.source.cacheTypes[i];
        $scope.cache.create[type.type] = type.required;
      }
      $scope.requiredFieldsSet();
    }

    if (!source || !source.geometry) {
      $scope.bb.north = null;
      $scope.bb.south = null;
      $scope.bb.west = null;
      $scope.bb.east = null;
      $scope.cache.geometry = null;
      return;
    }
    if (source && source.format == 'geotiff') {
      var geometry = source.geometry;
      while(geometry.type != "Polygon" && geometry != null){
        geometry = geometry.geometry;
      }
      $scope.cache.geometry = geometry;
    }
  });

  $scope.$watch('cache.source.previewLayer', function(layer, oldLayer) {
    if (layer) {
      if (layer.EX_GeographicBoundingBox) {
        $scope.cache.extent = layer.EX_GeographicBoundingBox;
      }
    }
  });

  $scope.$watch('cache.minZoom+cache.maxZoom', calculateCacheSize);

  $scope.requiredFieldsSet = function() {
    $scope.unsetFields = [];

    if (!$scope.cache.source) {
      $scope.unsetFields.push('cache source');
      return false;
    }

    if (!$scope.cache.name) {
      $scope.unsetFields.push('cache name');
    }

    var zoomValidated = false;
    if (isNaN($scope.cache.minZoom) || isNaN($scope.cache.maxZoom) || $scope.cache.maxZoom === null || $scope.cache.minZoom === null) {
      zoomValidated = false;
    } else if ($scope.cache.minZoom === 0 && $scope.cache.maxZoom === 0) {
      zoomValidated = true;
    } else if ($scope.cache.minZoom === 0 && $scope.cache.maxZoom > 0) {
      zoomValidated = true;
    } else if ($scope.cache.maxZoom >= $scope.cache.minZoom) {
      zoomValidated = true;
    }

    var cacheTypeSet = false;
    console.log('scope.cache.create', $scope.cache.create);
    for (var type in $scope.cache.create) {
      if ($scope.cache.create[type] == true) {
        cacheTypeSet = true;
      }
    }

    if (!cacheTypeSet) {
      $scope.unsetFields.push('type of cache to create');
    }

    if (!zoomValidated) {
      $scope.unsetFields.push('zoom levels')
    }
    if (!boundsSet) {
      $scope.unsetFields.push('cache boundaries');
    }

    if ($scope.cache.source.format == 'wms' && !$scope.cache.source.previewLayer) {
      $scope.unsetFields.push('WMS layer');
      return false;
    }

    return $scope.cache.geometry && boundsSet && $scope.cache.name && $scope.cache.source && (zoomValidated || $scope.cache.source.vector);
  }

  $scope.createCache = function() {
    if ($scope.cache.rawTileSizeLimit) {
      $scope.cache.tileSizeLimit = $scope.cache.rawTileSizeLimit * $scope.cache.selectedSizeMultiplier.multiplier;
    }
    console.log($scope.cache);
    $scope.creatingCache = true;
    $scope.cacheCreationError = null;
    $scope.cache.cacheCreationParams = {};
    if ($scope.cache.source.previewLayer) {
      $scope.cache.cacheCreationParams.layer = $scope.cache.source.previewLayer.Name;
    };
    var create = [];
    for (var type in $scope.cache.create) {
      if ($scope.cache.create[type]) {
        create.push(type);
      }
    }
    $scope.cache.create = create;
    CacheService.createCache($scope.cache, function(cache) {
      $scope.creatingCache = false;
      $location.path('/cache/'+cache.id);
    }, function(error, status) {
      $scope.creatingCache = false;
      $scope.cacheCreationError = {error: error, status: status};
    });
  }

  $scope.createSource = function() {
    $location.path('/source');
  }

  function calculateCacheSize() {
    if (!$scope.cache.source || ((isNaN($scope.cache.minZoom) || isNaN($scope.cache.maxZoom)) && !$scope.cache.source.vector) || !$scope.cache.geometry) return;
    $scope.totalCacheSize = 0;
    $scope.totalCacheTiles = 0;
    var extent = turf.extent($scope.cache.geometry);
    for (var i = $scope.cache.minZoom; i <= $scope.cache.maxZoom; i++) {
      var xtiles = xCalculator(extent, i);
      var ytiles = yCalculator(extent, i);
      $scope.totalCacheTiles += (1 + (ytiles.max - ytiles.min)) * (1 + (xtiles.max - xtiles.min));
    }
    $scope.totalCacheSize = $scope.totalCacheTiles * ($scope.cache.source.tileSize/$scope.cache.source.tileSizeCount);
    $scope.cacheFeatures = 0;
    $scope.cache.source.totalFeatures = $scope.cache.source.data ? $scope.cache.source.data.features.length : 0;
    if ($scope.cache.source.vector) {
      var poly = turf.bboxPolygon(extent);
      for (var i = 0; i < $scope.cache.source.data.features.length; i++) {
        var feature = $scope.cache.source.data.features[i];
        var intersection = turf.intersect(poly, feature);
        if (intersection) {
          $scope.cacheFeatures++;
        }
      }
    }
  }

  Math.radians = function(degrees) {
    return degrees * Math.PI / 180;
  };

  // Converts from radians to degrees.
  Math.degrees = function(radians) {
    return radians * 180 / Math.PI;
  };

  function tile2lon(x,z) {
    return (x/Math.pow(2,z)*360-180);
  }

  function tile2lat(y,z) {
    var n=Math.PI-2*Math.PI*y/Math.pow(2,z);
    return (180/Math.PI*Math.atan(0.5*(Math.exp(n)-Math.exp(-n))));
  }

  function tileBboxCalculator(x, y, z) {
    console.log('tile box calculator for ' + x + ' ' + y + ' ' + z);
    x = Number(x);
    y = Number(y);
    var tileBounds = {
      north: tile2lat(y, z),
      east: tile2lon(x+1, z),
      south: tile2lat(y+1, z),
      west: tile2lon(x, z)
    };

    return tileBounds;
  }

   function xCalculator(bbox,z) {
  	var x = [];
  	var x1 = getX(Number(bbox[0]), z);
  	var x2 = getX(Number(bbox[2]), z);
  	x.max = Math.max(x1, x2);
  	x.min = Math.min(x1, x2);
  	if (z == 0){
  		x.current = Math.min(x1, x2);
  	}
  	return x;
  }

  function yCalculator(bbox,z) {
  	var y = [];
  	var y1 = getY(Number(bbox[1]), z);
  	var y2 = getY(Number(bbox[3]), z);
  	y.max = Math.max(y1, y2);
  	y.min = Math.min(y1, y2);
  	y.current = Math.min(y1, y2);
  	return y;
  }

  function getX(lon, zoom) {
  	var xtile = Math.floor((lon + 180) / 360 * (1 << zoom));
  	return xtile;
  }

  function getY(lat, zoom) {
  	var ytile = Math.floor((1 - Math.log(Math.tan(Math.radians(parseFloat(lat))) + 1 / Math.cos(Math.radians(parseFloat(lat)))) / Math.PI) /2 * (1 << zoom));
  	return ytile;
  }

};
<|endoftext|>


<commit_before>// Copyright 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview Rule to flag references to undeclared variables.
 */

goog.module('eslintClosure.rules.noUndef');

const ast = goog.require('eslintClosure.ast');
const utils = goog.require('eslintClosure.utils');

/**
 * Checks if the given node is the argument of a typeof operator.
 * @param {!AST.Node} node The AST node being checked.
 * @return {boolean} Whether or not the node is the argument of a typeof
 *     operator.
 */
function hasTypeOfOperator(node) {
  const parent = node.parent;

  return parent.type === 'UnaryExpression' &&
      /** @type {!AST.UnaryExpression} */ (parent).operator === 'typeof';
}

/**
 * Valid options for the no-undef rule.
 * @typedef {{
 *   typeof: boolean,
 * }}
 */
let NoUndefRuleOptions;

/** @const {!ESLint.RuleDefinition} */
const NO_UNDEF_RULE = {
  meta: {
    docs: {
      description: 'disallow the use of undeclared variables unless ' +
          'mentioned in `/*global */` comments',
      category: 'Variables',
      recommended: true,
    },

    schema: [
      {
        type: 'object',
        properties: {
          typeof: {type: 'boolean'},
        },
        additionalProperties: false,
      },
    ],
  },

  /**
   * @param {!ESLint.RuleContext} context
   * @return {!Object<!AST.NodeType, function(!AST.Node)>}
   */
  create(context) {
    const options = /** @type {!NoUndefRuleOptions} */ (context.options[0]);
    const considerTypeOf = options && options.typeof === true || false;

    /** @type {!Array<string>} */
    let googRequiredStrings = [];

    /** @type {!Array<string>} */
    let googProvidedStrings = [];

    return {
      /** @param {!AST.Program} programNode */
      Program(programNode) {
        googRequiredStrings = programNode.body
            .map(ast.matchExtractBareGoogRequire)
             // No eta reduction because Closure complains about types.
            .filter((b) => Boolean(b))
            .map((dependency) => dependency.source);

        googProvidedStrings = programNode.body
            .map(ast.matchExtractGoogProvide)
            .filter((b) => Boolean(b))
            .map((dependency) => dependency.source);
      },

      'Program:exit': () => {
        const globalScope = context.getScope();
        const undeclaredVariables = globalScope.through;

        /**
         * @param {string} fullName
         * @return {boolean}
         */
        function isGoogProvided(fullName) {
          return googProvidedStrings.some(
            (provided) => utils.isValidPrefix(fullName, provided));
        }

        /**
         * @param {string} fullName
         * @return {boolean}
         */
        function isGoogRequired(fullName) {
          return googRequiredStrings.some(
            (required) => utils.isValidPrefix(fullName, required));
        }

        undeclaredVariables.forEach((ref) => {
          /** @type {!AST.Identifier} */
          const identifier = ref.identifier;
          const fullName = ast.getFullyQualifedName(identifier);

          if (!considerTypeOf && hasTypeOfOperator(identifier)) {
            return;
          } else if (isGoogProvided(fullName) || isGoogRequired(fullName)) {
            return;
          }

          context.report({
            node: identifier,
            message: `'${identifier.name}' is not defined.`,
          });
        });
      },
    };
  },
};

exports = NO_UNDEF_RULE;
<commit_msg>Update no-undef.js<commit_after>// Copyright 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview Rule to flag references to undeclared variables.
 */

goog.module('eslintClosure.rules.noUndef');

const ast = goog.require('eslintClosure.ast');
const utils = goog.require('eslintClosure.utils');

/**
 * Checks if the given node is the argument of a typeof operator.
 * @param {!AST.Node} node The AST node being checked.
 * @return {boolean} Whether or not the node is the argument of a typeof
 *     operator.
 */
function hasTypeOfOperator(node) {
  const parent = node.parent;

  return parent.type === 'UnaryExpression' &&
      /** @type {!AST.UnaryExpression} */ (parent).operator === 'typeof';
}

/**
 * Valid options for the no-undef rule.
 * @typedef {{
 *   typeof: boolean,
 * }}
 */
let NoUndefRuleOptions;

/** @const {!ESLint.RuleDefinition} */
const NO_UNDEF_RULE = {
  meta: {
    docs: {
      description: 'disallow the use of undeclared variables unless ' +
          'mentioned in `/*global */` comments',
      category: 'Variables',
      recommended: true,
    },

    schema: [
      {
        type: 'object',
        properties: {
          typeof: {type: 'boolean'},
        },
        additionalProperties: false,
      },
    ],
  },

  /**
   * @param {!ESLint.RuleContext} context
   * @return {!Object<!AST.NodeType, function(!AST.Node)>}
   */
  create(context) {
    const options = /** @type {!NoUndefRuleOptions} */ (context.options[0]);
    const considerTypeOf = options && options.typeof === true || false;

    /** @type {!Array<string>} */
    let googRequiredStrings = [];

    /** @type {!Array<string>} */
    let googProvidedStrings = [];

    return {
      /** @param {!AST.Program} programNode */
      Program(programNode) {
        googRequiredStrings = programNode.body
            .map(ast.matchExtractBareGoogRequire)
             // No eta reduction because Closure complains about types.
            .filter((b) => Boolean(b))
            .map((dependency) => dependency.source);

        googProvidedStrings = programNode.body
            .map(ast.matchExtractGoogProvide)
            .filter((b) => Boolean(b))
            .map((dependency) => dependency.source);
      },

      'Program:exit': () => {
        const globalScope = context.getScope();
        const undeclaredVariables = globalScope.through;

        /**
         * @param {string} fullName
         * @return {boolean}
         */
        function isGoogProvided(fullName) {
          return googProvidedStrings.some(
            (provided) => utils.isValidPrefix(fullName, provided));
        }

        /**
         * @param {string} fullName
         * @return {boolean}
         */
        function isGoogRequired(fullName) {
          return googRequiredStrings.some(
            (required) => utils.isValidPrefix(fullName, required));
        }

        undeclaredVariables.forEach((ref) => {
          /** @type {!AST.Identifier} */
          const identifier = ref.identifier;
          const fullName = ast.getFullyQualifedName(identifier);

          if (!considerTypeOf && hasTypeOfOperator(identifier)) {
            return;
          } else if (isGoogProvided(fullName) || isGoogRequired(fullName)) {
            return;
          }

          context.report({
            node: identifier,
            message: `'${identifier.name}' is not defined (can't evaluate ${fullName}).`,
          });
        });
      },
    };
  },
};

exports = NO_UNDEF_RULE;
<|endoftext|>


<commit_before>/*
 *  FCKPlugin.js
 *  ------------
 *  This is a generic file which is needed for plugins that are developed
 *  for FCKEditor. With the below statements that toolbar is created and
 *  several options are being activated.
 *
 *  See the online documentation for more information:
 *  http://wiki.fckeditor.net/
 */

// Register the related commands.
FCKCommands.RegisterCommand(
	'tikiimage',
	new FCKDialogCommand(
		'tikiimage',
		FCKConfig.tikiimageDlgTitle,
		FCKConfig.BasePath + 'dialog/fck_image.html',
		400,
		400
	)
);

var otikiimageItem = new FCKToolbarButton( 'tikiimage', FCKConfig.tikiimageBtn, null, null, false, true );
otikiimageItem.IconPath = _TikiRoot + 'pics/icons/page_white_picture.png';

FCKToolbarItems.RegisterItem( 'tikiimage', otikiimageItem );

var FCKTikiImages = new Object() ;

FCKTikiImages.add = function( sSrc, sHeight, sWidth, sLink, sAlign, sDesc, sAlt, sUsemap, sClass ) {
	var oImg = FCK.CreateElement( 'IMG' ) ;
	this.SetupImage( oImg, sSrc, sHeight, sWidth, sLink, sAlign, sDesc, sAlt, sUsemap, sClass ) ;
}

FCKTikiImages.SetupImage  = function( img, sSrc, sHeight, sWidth, sLink, sAlign, sDesc, sAlt, sUsemap, sClass ) {
	img.contentEditable = 'false' ;
	if ( sClass ) img.className = sClass ;
	if ( sHeight ) img.height = sHeight ;
	if ( sWidth ) img.width = sWidth ;
	if ( sAlign ) img.align = sAlign ;
	if ( sAlt ) img.alt = sAlt ;
	var reg = new RegExp ("(img/wiki_up/)("+_TikiDomain+"/)?(.*)","gi");
	if (sSrc.match('https?://'))
		img.src = sSrc;
	else
		img.src = sSrc.replace(reg,'$1'+_TikiDomain+'/$3') ;
	img._tikiimage = true ;
	img.onresizestart = function() {
		FCK.EditorWindow.event.returnValue = false ;
		return false ;
	}
}

FCKTikiImages._SetupClickListener = function() {
	FCKTikiImages._ClickListener = function( e ) {
		if ( e.target.tagName == 'IMG' && e.target.src ) {
			FCKSelection.SelectNode( e.target ) ;
		}
	}
	FCK.EditorDocument.addEventListener( 'click', FCKTikiImages._ClickListener, true ) ;
}

FCKTikiImages.OnDoubleClick = function( img ) {
	if ( img.tagName == 'IMG' && img.src ) {
		FCKCommands.GetCommand( 'tikiimage' ).Execute() ;
	}
}

FCK.RegisterDoubleClickHandler( FCKTikiImages.OnDoubleClick, 'IMG' ) ;

FCKTikiImages.Exist = function( name ) {
	var aImg = FCK.EditorDocument.getElementsByTagName( 'IMG' ) ;
	for ( var i = 0 ; i < aImg.length ; i++ ) {
		if ( aImg[i]._tikiimage ) {
			return true ;
		}
	}
}

if ( FCKBrowserInfo.IsIE ) {
	FCKTikiImages.Redraw = function() {
		var aImgs = FCK.EditorDocument.body.innerText.match( /(\{img\s*[^\}]*\})/g ) ;
		if ( !aImgs ) {
			return ;
		}
		var oRange = FCK.EditorDocument.body.createTextRange() ;
		for ( var i = 0 ; i < aImgs.length ; i++ ) {
			if ( oRange.findText( aImgs[i] ) ) {
				var sImg = aImgs[i].match( /{img\s*([^\}]*)\}/ )[1].split(' ') ;
				var sSrc = '' ;
				var sClass  = '' ;
				var sHeight  = '' ;
				var sWidth  = '' ;
				var sAlign  = '' ;
				var sImalign  = '' ;
				for ( var j = 0 ; j < sImg.length ; j++ ) {
					var equalindex=sImg[j].indexOf( '=' );
					if ( equalindex != -1 ) {
						var lParam = sImg[j].substring(0, equalindex);
						var lValue = sImg[j].substring(equalindex+1);
						if ( lParam == 'src') {
							sSrc = lValue ;
						} else if ( lParam == 'height' ) {
							sHeight = lValue ;
						} else if ( lParam == 'width' ) {
							sWidth = lValue ;
						} else if ( lParam == 'align' || lParam == 'imalign' ) {
							sAlign = lValue ;
						} else if ( lParam == 'class' ) {
							sClass = lValue ;
						}
					}
				}
				if ( sSrc ) {
					var extra = '' ;
					var reg = new RegExp ("(img/wiki_up/)("+_TikiDomain+"/)?(.*)","gi");
					if ( sHeight ) extra = extra + ' height="' + sHeight + '"' ;
					if ( sWidth ) extra = extra + ' width="' + sWidth + '"' ;
					if ( sClass ) extra = extra + ' class="' + sClass + '"' ;
					if ( sAlign ) extra = extra + ' align="' + sAlign + '"' ;
					oRange.pasteHTML( '' );
				}
			}
		}
	}
} else {
	FCKTikiImages.Redraw = function() {
		var oInteractor = FCK.EditorDocument.createTreeWalker( FCK.EditorDocument.body, NodeFilter.SHOW_TEXT, FCKTikiImages._AcceptNode, true ) ;
		var aNodes = new Array() ;
		while ( oNode = oInteractor.nextNode() ) {
			aNodes[ aNodes.length ] = oNode ;
		}
		for ( var n = 0 ; n < aNodes.length ; n++ ) {
			var aPieces = aNodes[n].nodeValue.split( /(\{img\s*[^\}]*\})/ );
			for ( var i = 0 ; i < aPieces.length ; i++ ) {
				if ( aPieces[i].length > 0 ) {
					if ( aPieces[i].indexOf( '{img ' ) == 0 ) {
						var sImg = aPieces[i].match( /\{img\s*([^\}]*)\}/ )[1].split(' ') ;
						var sSrc = '' ;
						var sHeight = '' ;
						var sWidth = '' ;
						var sLink = '' ;
						var sAlign = '' ;
						var sDesc = '' ;
						var sImalign = '' ;
						var sAlt = '' ;
						var sUsemap = '' ;
						var sClass = '' ;
						var reg = new RegExp ("(img/wiki_up/)("+_TikiDomain+"/)?(.*)","gi");
						for ( var j = 0 ; j < sImg.length ; j++ ) {
							var equalindex=sImg[j].indexOf( '=' );
							if ( equalindex != -1 ) {
								var lParam = sImg[j].substring(0, equalindex);
								var lValue = sImg[j].substring(equalindex+1);
								if ( lParam == 'src') {
									if (!lValue.match('https?://'))
										sSrc = lValue.replace(reg,'$1'+_TikiDomain+'/$3') ;
									else
										sSrc = lValue;
								} else if ( lParam == 'height' ) {
									sHeight = lValue ;
								} else if ( lParam == 'width' ) {
									sWidth = lValue ;
								} else if ( lParam == 'align' ) {
									sAlign = lValue ;
								} else if ( lParam == 'alt' ) {
									sAlt = lValue ;
								} else if ( lParam == 'link' ) {
								} else if ( lParam == 'desc' ) {
								} else if ( lParam == 'imalign' ) {
									sAlign = lValue ;
								} else if ( lParam == 'usemap' ) {
								} else if ( lParam == 'class' ) {
								}
							}
						}
						var oImg = FCK.EditorDocument.createElement( 'img' ) ;
						FCKTikiImages.SetupImage( oImg, sSrc, sHeight, sWidth, sLink, sAlign, sDesc, sAlt, sUsemap, sClass ) ;
						aNodes[n].parentNode.insertBefore( oImg, aNodes[n] ) ;
					} else {
						aNodes[n].parentNode.insertBefore( FCK.EditorDocument.createTextNode( aPieces[i] ) , aNodes[n] ) ;
					}
				}
			}
			aNodes[n].parentNode.removeChild( aNodes[n] ) ;
		}
		FCKTikiImages._SetupClickListener() ;
	}
	FCKTikiImages._AcceptNode = function( node ) {
		if ( /\{img\s/.test( node.nodeValue ) ) {
			return NodeFilter.FILTER_ACCEPT ;
		} else {
			return NodeFilter.FILTER_SKIP ;
		}
	}
}

FCK.Events.AttachEvent( 'OnAfterSetHTML', FCKTikiImages.Redraw ) ;

FCKXHtml.TagProcessors['img'] = function( node, htmlNode ) {
	if ( htmlNode.src ) {
		var extra = '' ;
		if ( htmlNode.height ) extra = extra + ' height=' + htmlNode.height ;
		if ( htmlNode.width ) extra = extra + ' width=' + htmlNode.width ;
		if ( htmlNode.align ) {
			if ( htmlNode.align == 'left' || htmlNode.align == 'right' ) {
				extra = extra + ' imalign=' + htmlNode.align ;
			} else {
				extra = extra + ' align=' + htmlNode.align ;
			}
		}
		if ( htmlNode.alt ) extra = extra + ' alt=' + htmlNode.alt ;
		// we clean the src of the image if the image is local to the
		// server
		if (htmlNode.src.indexOf(_TikiBaseHost) == -1) {
			sSrc = htmlNode.src;
		} else {
			var reg = new RegExp ("^(?:"+_TikiBaseHost+")?([\"'])?([^\"']*)([\"'])?.*","gi");
			var reg2 = new RegExp ("(img/wiki_up)/("+_TikiDomain+"/)?(.*)","gi");
			sSrc = htmlNode.src.replace(reg,'$2').replace(reg2,'$1/$3');
		}
		node = FCKXHtml.XML.createTextNode( '{img src=' + sSrc + ' ' + extra + '}' ) ;
		node = FCKXHtml.XML.createTextNode( '{img src=' + htmlNode.src.replace(reg,'$2').replace(reg2,'$1/$3') + ' ' + extra + '}' ) ;
	} else {
		FCKXHtml._AppendChildNodes( node, htmlNode, false ) ;
	}
	return node ;
}

<commit_msg>[FIX]fck: to be able to have {img src=show_image.php?id=1} and {img src="show_image.php?id=1"} as we have {img src=/show_image.php?id=1} or {img src=http://../show_image.php?id=1}<commit_after>/*
 *  FCKPlugin.js
 *  ------------
 *  This is a generic file which is needed for plugins that are developed
 *  for FCKEditor. With the below statements that toolbar is created and
 *  several options are being activated.
 *
 *  See the online documentation for more information:
 *  http://wiki.fckeditor.net/
 */

// Register the related commands.
FCKCommands.RegisterCommand(
	'tikiimage',
	new FCKDialogCommand(
		'tikiimage',
		FCKConfig.tikiimageDlgTitle,
		FCKConfig.BasePath + 'dialog/fck_image.html',
		400,
		400
	)
);

var otikiimageItem = new FCKToolbarButton( 'tikiimage', FCKConfig.tikiimageBtn, null, null, false, true );
otikiimageItem.IconPath = _TikiRoot + 'pics/icons/page_white_picture.png';

FCKToolbarItems.RegisterItem( 'tikiimage', otikiimageItem );

var FCKTikiImages = new Object() ;

FCKTikiImages.add = function( sSrc, sHeight, sWidth, sLink, sAlign, sDesc, sAlt, sUsemap, sClass ) {
	var oImg = FCK.CreateElement( 'IMG' ) ;
	this.SetupImage( oImg, sSrc, sHeight, sWidth, sLink, sAlign, sDesc, sAlt, sUsemap, sClass ) ;
}

FCKTikiImages.SetupImage  = function( img, sSrc, sHeight, sWidth, sLink, sAlign, sDesc, sAlt, sUsemap, sClass ) {
	img.contentEditable = 'false' ;
	if ( sClass ) img.className = sClass ;
	if ( sHeight ) img.height = sHeight ;
	if ( sWidth ) img.width = sWidth ;
	if ( sAlign ) img.align = sAlign ;
	if ( sAlt ) img.alt = sAlt ;
	img.src = FCKTikiImages._AdaptUrl(sSrc);
	img._tikiimage = true ;
	img.onresizestart = function() {
		FCK.EditorWindow.event.returnValue = false ;
		return false ;
	}
}
FCKTikiImages._AdaptUrl = function ( sSrc) {
	var reg =  new RegExp ("\"","gi");
	sSrc = sSrc.replace(reg, '');// {img src="show_image.php?id=1"}
	if (sSrc.match('https?:\/\/')) {
		src = sSrc;
	} else if (sSrc.indexOf(_TikiRoot) == -1 && sSrc.match('\.php\?')) {//case {img src=tiki-download_file.php?fileId=1}
		src = _TikiRoot+sSrc; // need the tikiroot as fck in working in an iframe
	} else {
		src = sSrc;
	}
	var reg = new RegExp ("(img/wiki_up/)("+_TikiDomain+"/)?(.*)","gi");
	src = src.replace(reg,'$1'+_TikiDomain+'/$3');
	return src;
}

FCKTikiImages._SetupClickListener = function() {
	FCKTikiImages._ClickListener = function( e ) {
		if ( e.target.tagName == 'IMG' && e.target.src ) {
			FCKSelection.SelectNode( e.target ) ;
		}
	}
	FCK.EditorDocument.addEventListener( 'click', FCKTikiImages._ClickListener, true ) ;
}

FCKTikiImages.OnDoubleClick = function( img ) {
	if ( img.tagName == 'IMG' && img.src ) {
		FCKCommands.GetCommand( 'tikiimage' ).Execute() ;
	}
}

FCK.RegisterDoubleClickHandler( FCKTikiImages.OnDoubleClick, 'IMG' ) ;

FCKTikiImages.Exist = function( name ) {
	var aImg = FCK.EditorDocument.getElementsByTagName( 'IMG' ) ;
	for ( var i = 0 ; i < aImg.length ; i++ ) {
		if ( aImg[i]._tikiimage ) {
			return true ;
		}
	}
}

if ( FCKBrowserInfo.IsIE ) {
	FCKTikiImages.Redraw = function() {
		var aImgs = FCK.EditorDocument.body.innerText.match( /(\{img\s*[^\}]*\})/g ) ;
		if ( !aImgs ) {
			return ;
		}
		var oRange = FCK.EditorDocument.body.createTextRange() ;
		for ( var i = 0 ; i < aImgs.length ; i++ ) {
			if ( oRange.findText( aImgs[i] ) ) {
				var sImg = aImgs[i].match( /{img\s*([^\}]*)\}/ )[1].split(' ') ;
				var sSrc = '' ;
				var sClass  = '' ;
				var sHeight  = '' ;
				var sWidth  = '' ;
				var sAlign  = '' ;
				var sImalign  = '' ;
				for ( var j = 0 ; j < sImg.length ; j++ ) {
					var equalindex=sImg[j].indexOf( '=' );
					if ( equalindex != -1 ) {
						var lParam = sImg[j].substring(0, equalindex);
						var lValue = sImg[j].substring(equalindex+1);
						if ( lParam == 'src') {
							sSrc = FCKTikiImages._AdaptUrl(lValue);
						} else if ( lParam == 'height' ) {
							sHeight = lValue ;
						} else if ( lParam == 'width' ) {
							sWidth = lValue ;
						} else if ( lParam == 'align' || lParam == 'imalign' ) {
							sAlign = lValue ;
						} else if ( lParam == 'class' ) {
							sClass = lValue ;
						}
					}
				}
				if ( sSrc ) {
					var extra = '' ;
					if ( sHeight ) extra = extra + ' height="' + sHeight + '"' ;
					if ( sWidth ) extra = extra + ' width="' + sWidth + '"' ;
					if ( sClass ) extra = extra + ' class="' + sClass + '"' ;
					if ( sAlign ) extra = extra + ' align="' + sAlign + '"' ;
					oRange.pasteHTML( '' );
				}
			}
		}
	}
} else {
	FCKTikiImages.Redraw = function() {
		var oInteractor = FCK.EditorDocument.createTreeWalker( FCK.EditorDocument.body, NodeFilter.SHOW_TEXT, FCKTikiImages._AcceptNode, true ) ;
		var aNodes = new Array() ;
		while ( oNode = oInteractor.nextNode() ) {
			aNodes[ aNodes.length ] = oNode ;
		}
		for ( var n = 0 ; n < aNodes.length ; n++ ) {
			var aPieces = aNodes[n].nodeValue.split( /(\{img\s*[^\}]*\})/ );
			for ( var i = 0 ; i < aPieces.length ; i++ ) {
				if ( aPieces[i].length > 0 ) {
					if ( aPieces[i].indexOf( '{img ' ) == 0 ) {
						var sImg = aPieces[i].match( /\{img\s*([^\}]*)\}/ )[1].split(' ') ;
						var sSrc = '' ;
						var sHeight = '' ;
						var sWidth = '' ;
						var sLink = '' ;
						var sAlign = '' ;
						var sDesc = '' ;
						var sImalign = '' ;
						var sAlt = '' ;
						var sUsemap = '' ;
						var sClass = '' ;
						for ( var j = 0 ; j < sImg.length ; j++ ) {
							var equalindex=sImg[j].indexOf( '=' );
							if ( equalindex != -1 ) {
								var lParam = sImg[j].substring(0, equalindex);
								var lValue = sImg[j].substring(equalindex+1);
								if ( lParam == 'src') {
									sSrc = FCKTikiImages._AdaptUrl(lValue);
								} else if ( lParam == 'height' ) {
									sHeight = lValue ;
								} else if ( lParam == 'width' ) {
									sWidth = lValue ;
								} else if ( lParam == 'align' ) {
									sAlign = lValue ;
								} else if ( lParam == 'alt' ) {
									sAlt = lValue ;
								} else if ( lParam == 'link' ) {
								} else if ( lParam == 'desc' ) {
								} else if ( lParam == 'imalign' ) {
									sAlign = lValue ;
								} else if ( lParam == 'usemap' ) {
								} else if ( lParam == 'class' ) {
								}
							}
						}
						var oImg = FCK.EditorDocument.createElement( 'img' ) ;
						FCKTikiImages.SetupImage( oImg, sSrc, sHeight, sWidth, sLink, sAlign, sDesc, sAlt, sUsemap, sClass ) ;
						aNodes[n].parentNode.insertBefore( oImg, aNodes[n] ) ;
					} else {
						aNodes[n].parentNode.insertBefore( FCK.EditorDocument.createTextNode( aPieces[i] ) , aNodes[n] ) ;
					}
				}
			}
			aNodes[n].parentNode.removeChild( aNodes[n] ) ;
		}
		FCKTikiImages._SetupClickListener() ;
	}
	FCKTikiImages._AcceptNode = function( node ) {
		if ( /\{img\s/.test( node.nodeValue ) ) {
			return NodeFilter.FILTER_ACCEPT ;
		} else {
			return NodeFilter.FILTER_SKIP ;
		}
	}
}

FCK.Events.AttachEvent( 'OnAfterSetHTML', FCKTikiImages.Redraw ) ;

FCKXHtml.TagProcessors['img'] = function( node, htmlNode ) {
	if ( htmlNode.src ) {
		var extra = '' ;
		if ( htmlNode.height ) extra = extra + ' height=' + htmlNode.height ;
		if ( htmlNode.width ) extra = extra + ' width=' + htmlNode.width ;
		if ( htmlNode.align ) {
			if ( htmlNode.align == 'left' || htmlNode.align == 'right' ) {
				extra = extra + ' imalign=' + htmlNode.align ;
			} else {
				extra = extra + ' align=' + htmlNode.align ;
			}
		}
		if ( htmlNode.alt ) extra = extra + ' alt=' + htmlNode.alt ;
		// we clean the src of the image if the image is local to the
		// server
		if (htmlNode.src.indexOf(_TikiBaseHost) == -1) {
			sSrc = htmlNode.src;
		} else {
			var reg = new RegExp ("^(?:"+_TikiBaseHost+")?([\"'])?([^\"']*)([\"'])?.*","gi");
			var reg2 = new RegExp ("(img/wiki_up)/("+_TikiDomain+"/)?(.*)","gi");
			sSrc = htmlNode.src.replace(reg,'$2').replace(reg2,'$1/$3');
		}
		node = FCKXHtml.XML.createTextNode( '{img src=' + sSrc + ' ' + extra + '}' ) ;
		node = FCKXHtml.XML.createTextNode( '{img src=' + htmlNode.src.replace(reg,'$2').replace(reg2,'$1/$3') + ' ' + extra + '}' ) ;
	} else {
		FCKXHtml._AppendChildNodes( node, htmlNode, false ) ;
	}
	return node ;
}

<|endoftext|>