From be91a04022dc6ae76e640cab557288cd1aefabcf Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Tue, 18 Sep 2018 22:10:01 +0200 Subject: [PATCH 01/62] Add default login if no htpasswd provided --- main.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/main.go b/main.go index 1d32fce..1ca07d2 100644 --- a/main.go +++ b/main.go @@ -20,7 +20,9 @@ func main() { flag.StringVar(&ThumbsDir, "thumbsdir", "./images/thumbs/", "Directory where generate thumbs") flag.Parse() - htpasswd := &Htpasswd{} + htpasswd := &Htpasswd{ + entries: map[string]string{"admin": "2fClb0C8dIphk"}, + } if htpasswd_file != nil && *htpasswd_file != "" { log.Println("Reading htpasswd file...") @@ -28,6 +30,8 @@ func main() { if htpasswd, err = NewHtpasswd(*htpasswd_file); htpasswd == nil { log.Fatal("Unable to parse htpasswd:", err) } + } else { + log.Println("Using default credentials for administrative part: admin:admin") } log.Println("Checking paths...") From 4febf49b3eea4a5f3d887bbdb23a74221dc94796 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Tue, 18 Sep 2018 22:16:35 +0200 Subject: [PATCH 02/62] gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..71975ac --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +youp0m From bd76956b4627f9d212f1bfa3cb9cf3bbc7cbb08e Mon Sep 17 00:00:00 2001 From: nemunaire Date: Tue, 18 Sep 2018 22:16:58 +0200 Subject: [PATCH 03/62] format + bump --- api.go | 9 ++++++--- api_images.go | 10 ++++++++-- auth.go | 4 +--- images.go | 8 ++++---- main.go | 14 ++++++++------ picture.go | 34 ++++++++++++++++++---------------- version.go | 7 +++++-- 7 files changed, 50 insertions(+), 36 deletions(-) diff --git a/api.go b/api.go index 66cecd0..d955498 100644 --- a/api.go +++ b/api.go @@ -12,17 +12,20 @@ import ( type DispatchFunction func(*User, []string, io.ReadCloser) (interface{}, error) -var apiRoutes = map[string]*(map[string]struct{AuthFunction;DispatchFunction}){ +var apiRoutes = map[string]*(map[string]struct { + AuthFunction + DispatchFunction +}){ "images": &ApiImagesRouting, "next": &ApiNextImagesRouting, "version": &ApiVersionRouting, } type apiHandler struct { - Authenticate func(*http.Request) (*User) + Authenticate func(*http.Request) *User } -func ApiHandler(Authenticate func(*http.Request) (*User)) (apiHandler) { +func ApiHandler(Authenticate func(*http.Request) *User) apiHandler { return apiHandler{Authenticate} } diff --git a/api_images.go b/api_images.go index 422b767..a54d8f2 100644 --- a/api_images.go +++ b/api_images.go @@ -5,13 +5,19 @@ import ( "io" ) -var ApiImagesRouting = map[string]struct{AuthFunction; DispatchFunction}{ +var ApiImagesRouting = map[string]struct { + AuthFunction + DispatchFunction +}{ "GET": {PublicPage, listImages}, "POST": {PublicPage, addImage}, "DELETE": {PrivatePage, hideImage}, } -var ApiNextImagesRouting = map[string]struct{AuthFunction; DispatchFunction}{ +var ApiNextImagesRouting = map[string]struct { + AuthFunction + DispatchFunction +}{ "GET": {PrivatePage, listNextImages}, "POST": {PublicPage, addImage}, "DELETE": {PrivatePage, deleteImage}, diff --git a/auth.go b/auth.go index 96fe98d..4112116 100644 --- a/auth.go +++ b/auth.go @@ -52,10 +52,9 @@ func (h Htpasswd) Authenticate(username, password string) *User { } } - /// Request authentication -func Authenticate(htpasswd Htpasswd, r *http.Request) (*User) { +func Authenticate(htpasswd Htpasswd, r *http.Request) *User { // Authenticate the user if any if username, password, ok := r.BasicAuth(); ok { return htpasswd.Authenticate(username, password) @@ -64,7 +63,6 @@ func Authenticate(htpasswd Htpasswd, r *http.Request) (*User) { } } - /// Page rules type AuthFunction func(*User, []string) bool diff --git a/images.go b/images.go index a18baf6..56b38eb 100644 --- a/images.go +++ b/images.go @@ -6,14 +6,14 @@ import ( "strings" ) -type imagesHandler struct{ +type imagesHandler struct { name string - auth func(*http.Request) (bool) + auth func(*http.Request) bool hndlr http.Handler getter func(fname string) (Picture, error) } -func ImagesHandler(name string, auth func(*http.Request) (bool), hndlr http.Handler, getter func(fname string) (Picture, error)) (imagesHandler) { +func ImagesHandler(name string, auth func(*http.Request) bool, hndlr http.Handler, getter func(fname string) (Picture, error)) imagesHandler { return imagesHandler{name, auth, hndlr, getter} } @@ -39,7 +39,7 @@ func (i imagesHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } // Check rights - if ! i.auth(r) { + if !i.auth(r) { w.Header().Set("WWW-Authenticate", "Basic realm=\"YouP0m\"") http.Error(w, "You are not allowed to perform this request.", http.StatusUnauthorized) return diff --git a/main.go b/main.go index 1d32fce..9affd0f 100644 --- a/main.go +++ b/main.go @@ -48,7 +48,7 @@ func main() { } log.Println("Registering handlers...") - authFunc := func (r *http.Request) (*User){ return Authenticate(*htpasswd, r) } + authFunc := func(r *http.Request) *User { return Authenticate(*htpasswd, r) } staticDir, _ := filepath.Abs("static") if _, err := os.Stat(staticDir); os.IsNotExist(err) { @@ -59,7 +59,9 @@ func main() { } mux := http.NewServeMux() - mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, filepath.Join(staticDir, "index.html")) }) + mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + http.ServeFile(w, r, filepath.Join(staticDir, "index.html")) + }) mux.Handle("/css/", http.FileServer(http.Dir(staticDir))) mux.Handle("/js/", http.FileServer(http.Dir(staticDir))) @@ -67,26 +69,26 @@ func main() { mux.Handle("/images/", http.StripPrefix("/images", ImagesHandler( "images", - func (*http.Request) (bool){ return true; }, + func(*http.Request) bool { return true }, http.FileServer(http.Dir(PublishedImgDir)), GetPublishedImage, ))) mux.Handle("/images/next/", http.StripPrefix("/images/next", ImagesHandler( "next", - func (r *http.Request) (bool){ return authFunc(r) != nil; }, + func(r *http.Request) bool { return authFunc(r) != nil }, http.FileServer(http.Dir(NextImgDir)), GetNextImage, ))) mux.Handle("/images/thumbs/", http.StripPrefix("/images/thumbs", ImagesHandler( "thumbs", - func (*http.Request) (bool){ return true; }, + func(*http.Request) bool { return true }, http.FileServer(http.Dir(ThumbsDir)), GetPublishedImage, ))) mux.Handle("/images/next/thumbs/", http.StripPrefix("/images/next/thumbs", ImagesHandler( "nexthumbs", - func (r *http.Request) (bool){ return authFunc(r) != nil; }, + func(r *http.Request) bool { return authFunc(r) != nil }, http.FileServer(http.Dir(ThumbsDir)), GetNextImage, ))) diff --git a/picture.go b/picture.go index ac05793..b9e272e 100644 --- a/picture.go +++ b/picture.go @@ -2,12 +2,12 @@ package main import ( "errors" - "io" - "io/ioutil" "image" _ "image/gif" "image/jpeg" _ "image/png" + "io" + "io/ioutil" "os" "path/filepath" "sort" @@ -26,9 +26,11 @@ type Picture struct { type ByUploadTime []Picture -func (a ByUploadTime) Len() int { return len(a) } +func (a ByUploadTime) Len() int { return len(a) } func (a ByUploadTime) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -func (a ByUploadTime) Less(i, j int) bool { return a[i].UploadTime.Sub(a[j].UploadTime).Nanoseconds() < 0 } +func (a ByUploadTime) Less(i, j int) bool { + return a[i].UploadTime.Sub(a[j].UploadTime).Nanoseconds() < 0 +} func getImages(dir string) ([]Picture, error) { if files, err := ioutil.ReadDir(dir); err != nil { @@ -40,9 +42,9 @@ func getImages(dir string) ([]Picture, error) { filename := file.Name() pictures = append(pictures, Picture{ filepath.Join(dir, filename), // Path - filename, // Basename - filename[:len(filename) - len(filepath.Ext(filename))], // Sanitized filename - file.ModTime(), // UploadTime + filename, // Basename + filename[:len(filename)-len(filepath.Ext(filename))], // Sanitized filename + file.ModTime(), // UploadTime }) } } @@ -94,7 +96,7 @@ func GetNextImage(fname string) (Picture, error) { return getImage(GetNextImages, fname) } -func UniqueImage(filename string) (bool) { +func UniqueImage(filename string) bool { if pict, _ := GetPublishedImage(filename); pict.path != "" { return false } else { @@ -106,17 +108,17 @@ func UniqueImage(filename string) (bool) { } } -func AddImage(filename string, blob io.ReadCloser) (error) { +func AddImage(filename string, blob io.ReadCloser) error { // Check the name is not already used if ok := UniqueImage(filename); !ok { return errors.New("This filename is already used, please choose another one.") - // Convert to JPEG + // Convert to JPEG } else if img, _, err := image.Decode(blob); err != nil { return err - // Save file - } else if fw, err := os.Create(filepath.Join(NextImgDir, filename + ".jpg")); err != nil { + // Save file + } else if fw, err := os.Create(filepath.Join(NextImgDir, filename+".jpg")); err != nil { return err } else if err := jpeg.Encode(fw, img, nil); err != nil { return err @@ -126,7 +128,7 @@ func AddImage(filename string, blob io.ReadCloser) (error) { thumb := resize.Thumbnail(300, 185, img, resize.Lanczos3) // Save thumbnail - if fw, err := os.Create(filepath.Join(ThumbsDir, filename + ".jpg")); err != nil { + if fw, err := os.Create(filepath.Join(ThumbsDir, filename+".jpg")); err != nil { return err } else if err := jpeg.Encode(fw, thumb, nil); err != nil { return err @@ -138,7 +140,7 @@ func AddImage(filename string, blob io.ReadCloser) (error) { return nil } -func (p Picture) Publish() (error) { +func (p Picture) Publish() error { npath := filepath.Join(PublishedImgDir, p.basename) if err := os.Rename(p.path, npath); err != nil { return err @@ -149,7 +151,7 @@ func (p Picture) Publish() (error) { } } -func (p Picture) Unpublish() (error) { +func (p Picture) Unpublish() error { if err := os.Rename(p.path, filepath.Join(NextImgDir, p.basename)); err != nil { return err } else { @@ -157,7 +159,7 @@ func (p Picture) Unpublish() (error) { } } -func (p Picture) Remove() (error) { +func (p Picture) Remove() error { if err := os.Remove(p.path); err != nil { return err } else { diff --git a/version.go b/version.go index 85f9f6c..82911a9 100644 --- a/version.go +++ b/version.go @@ -4,12 +4,15 @@ import ( "io" ) -var ApiVersionRouting = map[string]struct{AuthFunction; DispatchFunction}{ +var ApiVersionRouting = map[string]struct { + AuthFunction + DispatchFunction +}{ "GET": {PublicPage, showVersion}, } func showVersion(u *User, args []string, body io.ReadCloser) (interface{}, error) { - m := map[string]interface{}{"version": 0.1} + m := map[string]interface{}{"version": 0.2} if u != nil { m["youare"] = *u From b3351cb3c9677fd1be03e477c1595c6c84698a71 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Tue, 18 Sep 2018 23:01:19 +0200 Subject: [PATCH 04/62] Use base64 to upload image So you can use: base64 mangemoi.jpg | curl --data @- http://localhost:8080/api/images/mangemoi --- picture.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/picture.go b/picture.go index b9e272e..3904cfc 100644 --- a/picture.go +++ b/picture.go @@ -1,6 +1,7 @@ package main import ( + "encoding/base64" "errors" "image" _ "image/gif" @@ -114,7 +115,7 @@ func AddImage(filename string, blob io.ReadCloser) error { return errors.New("This filename is already used, please choose another one.") // Convert to JPEG - } else if img, _, err := image.Decode(blob); err != nil { + } else if img, _, err := image.Decode(base64.NewDecoder(base64.StdEncoding, blob)); err != nil { return err // Save file From b08ad493a9499564620a714ee3641a2603ed27b8 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Tue, 18 Sep 2018 23:03:20 +0200 Subject: [PATCH 05/62] If no htpasswd provided, publish without futher moderation --- main.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/main.go b/main.go index 9affd0f..d727a97 100644 --- a/main.go +++ b/main.go @@ -28,6 +28,9 @@ func main() { if htpasswd, err = NewHtpasswd(*htpasswd_file); htpasswd == nil { log.Fatal("Unable to parse htpasswd:", err) } + } else if NextImgDir == "./images/next/" { + log.Println("Disable admin interface, images will be published without moderation") + NextImgDir = PublishedImgDir } log.Println("Checking paths...") From d5fd91902f4284c361ba17f34d485319fa3bb0bb Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sun, 1 Sep 2019 17:13:03 +0200 Subject: [PATCH 06/62] Use the Fetch API instead of PrototypeJS --- static/index.html | 3 +- static/js/prototype.js | 7588 ---------------------------------------- static/js/youp0m.js | 36 +- 3 files changed, 21 insertions(+), 7606 deletions(-) delete mode 100644 static/js/prototype.js diff --git a/static/index.html b/static/index.html index 8bf214b..8da01ec 100644 --- a/static/index.html +++ b/static/index.html @@ -4,8 +4,6 @@ YouP0m - -

Welcome on YouP0m!

@@ -18,5 +16,6 @@ + diff --git a/static/js/prototype.js b/static/js/prototype.js deleted file mode 100644 index cc89daf..0000000 --- a/static/js/prototype.js +++ /dev/null @@ -1,7588 +0,0 @@ -/* Prototype JavaScript framework, version 1.7.3 - * (c) 2005-2010 Sam Stephenson - * - * Prototype is freely distributable under the terms of an MIT-style license. - * For details, see the Prototype web site: http://www.prototypejs.org/ - * - *--------------------------------------------------------------------------*/ - -var Prototype = { - - Version: '1.7.3', - - Browser: (function(){ - var ua = navigator.userAgent; - var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]'; - return { - IE: !!window.attachEvent && !isOpera, - Opera: isOpera, - WebKit: ua.indexOf('AppleWebKit/') > -1, - Gecko: ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1, - MobileSafari: /Apple.*Mobile/.test(ua) - } - })(), - - BrowserFeatures: { - XPath: !!document.evaluate, - - SelectorsAPI: !!document.querySelector, - - ElementExtensions: (function() { - var constructor = window.Element || window.HTMLElement; - return !!(constructor && constructor.prototype); - })(), - SpecificElementExtensions: (function() { - if (typeof window.HTMLDivElement !== 'undefined') - return true; - - var div = document.createElement('div'), - form = document.createElement('form'), - isSupported = false; - - if (div['__proto__'] && (div['__proto__'] !== form['__proto__'])) { - isSupported = true; - } - - div = form = null; - - return isSupported; - })() - }, - - ScriptFragment: ']*>([\\S\\s]*?)<\/script\\s*>', - JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/, - - emptyFunction: function() { }, - - K: function(x) { return x } -}; - -if (Prototype.Browser.MobileSafari) - Prototype.BrowserFeatures.SpecificElementExtensions = false; -/* Based on Alex Arnell's inheritance implementation. */ - -var Class = (function() { - - var IS_DONTENUM_BUGGY = (function(){ - for (var p in { toString: 1 }) { - if (p === 'toString') return false; - } - return true; - })(); - - function subclass() {}; - function create() { - var parent = null, properties = $A(arguments); - if (Object.isFunction(properties[0])) - parent = properties.shift(); - - function klass() { - this.initialize.apply(this, arguments); - } - - Object.extend(klass, Class.Methods); - klass.superclass = parent; - klass.subclasses = []; - - if (parent) { - subclass.prototype = parent.prototype; - klass.prototype = new subclass; - parent.subclasses.push(klass); - } - - for (var i = 0, length = properties.length; i < length; i++) - klass.addMethods(properties[i]); - - if (!klass.prototype.initialize) - klass.prototype.initialize = Prototype.emptyFunction; - - klass.prototype.constructor = klass; - return klass; - } - - function addMethods(source) { - var ancestor = this.superclass && this.superclass.prototype, - properties = Object.keys(source); - - if (IS_DONTENUM_BUGGY) { - if (source.toString != Object.prototype.toString) - properties.push("toString"); - if (source.valueOf != Object.prototype.valueOf) - properties.push("valueOf"); - } - - for (var i = 0, length = properties.length; i < length; i++) { - var property = properties[i], value = source[property]; - if (ancestor && Object.isFunction(value) && - value.argumentNames()[0] == "$super") { - var method = value; - value = (function(m) { - return function() { return ancestor[m].apply(this, arguments); }; - })(property).wrap(method); - - value.valueOf = (function(method) { - return function() { return method.valueOf.call(method); }; - })(method); - - value.toString = (function(method) { - return function() { return method.toString.call(method); }; - })(method); - } - this.prototype[property] = value; - } - - return this; - } - - return { - create: create, - Methods: { - addMethods: addMethods - } - }; -})(); -(function() { - - var _toString = Object.prototype.toString, - _hasOwnProperty = Object.prototype.hasOwnProperty, - NULL_TYPE = 'Null', - UNDEFINED_TYPE = 'Undefined', - BOOLEAN_TYPE = 'Boolean', - NUMBER_TYPE = 'Number', - STRING_TYPE = 'String', - OBJECT_TYPE = 'Object', - FUNCTION_CLASS = '[object Function]', - BOOLEAN_CLASS = '[object Boolean]', - NUMBER_CLASS = '[object Number]', - STRING_CLASS = '[object String]', - ARRAY_CLASS = '[object Array]', - DATE_CLASS = '[object Date]', - NATIVE_JSON_STRINGIFY_SUPPORT = window.JSON && - typeof JSON.stringify === 'function' && - JSON.stringify(0) === '0' && - typeof JSON.stringify(Prototype.K) === 'undefined'; - - - - var DONT_ENUMS = ['toString', 'toLocaleString', 'valueOf', - 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'constructor']; - - var IS_DONTENUM_BUGGY = (function(){ - for (var p in { toString: 1 }) { - if (p === 'toString') return false; - } - return true; - })(); - - function Type(o) { - switch(o) { - case null: return NULL_TYPE; - case (void 0): return UNDEFINED_TYPE; - } - var type = typeof o; - switch(type) { - case 'boolean': return BOOLEAN_TYPE; - case 'number': return NUMBER_TYPE; - case 'string': return STRING_TYPE; - } - return OBJECT_TYPE; - } - - function extend(destination, source) { - for (var property in source) - destination[property] = source[property]; - return destination; - } - - function inspect(object) { - try { - if (isUndefined(object)) return 'undefined'; - if (object === null) return 'null'; - return object.inspect ? object.inspect() : String(object); - } catch (e) { - if (e instanceof RangeError) return '...'; - throw e; - } - } - - function toJSON(value) { - return Str('', { '': value }, []); - } - - function Str(key, holder, stack) { - var value = holder[key]; - if (Type(value) === OBJECT_TYPE && typeof value.toJSON === 'function') { - value = value.toJSON(key); - } - - var _class = _toString.call(value); - - switch (_class) { - case NUMBER_CLASS: - case BOOLEAN_CLASS: - case STRING_CLASS: - value = value.valueOf(); - } - - switch (value) { - case null: return 'null'; - case true: return 'true'; - case false: return 'false'; - } - - var type = typeof value; - switch (type) { - case 'string': - return value.inspect(true); - case 'number': - return isFinite(value) ? String(value) : 'null'; - case 'object': - - for (var i = 0, length = stack.length; i < length; i++) { - if (stack[i] === value) { - throw new TypeError("Cyclic reference to '" + value + "' in object"); - } - } - stack.push(value); - - var partial = []; - if (_class === ARRAY_CLASS) { - for (var i = 0, length = value.length; i < length; i++) { - var str = Str(i, value, stack); - partial.push(typeof str === 'undefined' ? 'null' : str); - } - partial = '[' + partial.join(',') + ']'; - } else { - var keys = Object.keys(value); - for (var i = 0, length = keys.length; i < length; i++) { - var key = keys[i], str = Str(key, value, stack); - if (typeof str !== "undefined") { - partial.push(key.inspect(true)+ ':' + str); - } - } - partial = '{' + partial.join(',') + '}'; - } - stack.pop(); - return partial; - } - } - - function stringify(object) { - return JSON.stringify(object); - } - - function toQueryString(object) { - return $H(object).toQueryString(); - } - - function toHTML(object) { - return object && object.toHTML ? object.toHTML() : String.interpret(object); - } - - function keys(object) { - if (Type(object) !== OBJECT_TYPE) { throw new TypeError(); } - var results = []; - for (var property in object) { - if (_hasOwnProperty.call(object, property)) - results.push(property); - } - - if (IS_DONTENUM_BUGGY) { - for (var i = 0; property = DONT_ENUMS[i]; i++) { - if (_hasOwnProperty.call(object, property)) - results.push(property); - } - } - - return results; - } - - function values(object) { - var results = []; - for (var property in object) - results.push(object[property]); - return results; - } - - function clone(object) { - return extend({ }, object); - } - - function isElement(object) { - return !!(object && object.nodeType == 1); - } - - function isArray(object) { - return _toString.call(object) === ARRAY_CLASS; - } - - var hasNativeIsArray = (typeof Array.isArray == 'function') - && Array.isArray([]) && !Array.isArray({}); - - if (hasNativeIsArray) { - isArray = Array.isArray; - } - - function isHash(object) { - return object instanceof Hash; - } - - function isFunction(object) { - return _toString.call(object) === FUNCTION_CLASS; - } - - function isString(object) { - return _toString.call(object) === STRING_CLASS; - } - - function isNumber(object) { - return _toString.call(object) === NUMBER_CLASS; - } - - function isDate(object) { - return _toString.call(object) === DATE_CLASS; - } - - function isUndefined(object) { - return typeof object === "undefined"; - } - - extend(Object, { - extend: extend, - inspect: inspect, - toJSON: NATIVE_JSON_STRINGIFY_SUPPORT ? stringify : toJSON, - toQueryString: toQueryString, - toHTML: toHTML, - keys: Object.keys || keys, - values: values, - clone: clone, - isElement: isElement, - isArray: isArray, - isHash: isHash, - isFunction: isFunction, - isString: isString, - isNumber: isNumber, - isDate: isDate, - isUndefined: isUndefined - }); -})(); -Object.extend(Function.prototype, (function() { - var slice = Array.prototype.slice; - - function update(array, args) { - var arrayLength = array.length, length = args.length; - while (length--) array[arrayLength + length] = args[length]; - return array; - } - - function merge(array, args) { - array = slice.call(array, 0); - return update(array, args); - } - - function argumentNames() { - var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1] - .replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '') - .replace(/\s+/g, '').split(','); - return names.length == 1 && !names[0] ? [] : names; - } - - - function bind(context) { - if (arguments.length < 2 && Object.isUndefined(arguments[0])) - return this; - - if (!Object.isFunction(this)) - throw new TypeError("The object is not callable."); - - var nop = function() {}; - var __method = this, args = slice.call(arguments, 1); - - var bound = function() { - var a = merge(args, arguments); - var c = this instanceof bound ? this : context; - return __method.apply(c, a); - }; - - nop.prototype = this.prototype; - bound.prototype = new nop(); - - return bound; - } - - function bindAsEventListener(context) { - var __method = this, args = slice.call(arguments, 1); - return function(event) { - var a = update([event || window.event], args); - return __method.apply(context, a); - } - } - - function curry() { - if (!arguments.length) return this; - var __method = this, args = slice.call(arguments, 0); - return function() { - var a = merge(args, arguments); - return __method.apply(this, a); - } - } - - function delay(timeout) { - var __method = this, args = slice.call(arguments, 1); - timeout = timeout * 1000; - return window.setTimeout(function() { - return __method.apply(__method, args); - }, timeout); - } - - function defer() { - var args = update([0.01], arguments); - return this.delay.apply(this, args); - } - - function wrap(wrapper) { - var __method = this; - return function() { - var a = update([__method.bind(this)], arguments); - return wrapper.apply(this, a); - } - } - - function methodize() { - if (this._methodized) return this._methodized; - var __method = this; - return this._methodized = function() { - var a = update([this], arguments); - return __method.apply(null, a); - }; - } - - var extensions = { - argumentNames: argumentNames, - bindAsEventListener: bindAsEventListener, - curry: curry, - delay: delay, - defer: defer, - wrap: wrap, - methodize: methodize - }; - - if (!Function.prototype.bind) - extensions.bind = bind; - - return extensions; -})()); - - - -(function(proto) { - - - function toISOString() { - return this.getUTCFullYear() + '-' + - (this.getUTCMonth() + 1).toPaddedString(2) + '-' + - this.getUTCDate().toPaddedString(2) + 'T' + - this.getUTCHours().toPaddedString(2) + ':' + - this.getUTCMinutes().toPaddedString(2) + ':' + - this.getUTCSeconds().toPaddedString(2) + 'Z'; - } - - - function toJSON() { - return this.toISOString(); - } - - if (!proto.toISOString) proto.toISOString = toISOString; - if (!proto.toJSON) proto.toJSON = toJSON; - -})(Date.prototype); - - -RegExp.prototype.match = RegExp.prototype.test; - -RegExp.escape = function(str) { - return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); -}; -var PeriodicalExecuter = Class.create({ - initialize: function(callback, frequency) { - this.callback = callback; - this.frequency = frequency; - this.currentlyExecuting = false; - - this.registerCallback(); - }, - - registerCallback: function() { - this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); - }, - - execute: function() { - this.callback(this); - }, - - stop: function() { - if (!this.timer) return; - clearInterval(this.timer); - this.timer = null; - }, - - onTimerEvent: function() { - if (!this.currentlyExecuting) { - try { - this.currentlyExecuting = true; - this.execute(); - this.currentlyExecuting = false; - } catch(e) { - this.currentlyExecuting = false; - throw e; - } - } - } -}); -Object.extend(String, { - interpret: function(value) { - return value == null ? '' : String(value); - }, - specialChar: { - '\b': '\\b', - '\t': '\\t', - '\n': '\\n', - '\f': '\\f', - '\r': '\\r', - '\\': '\\\\' - } -}); - -Object.extend(String.prototype, (function() { - var NATIVE_JSON_PARSE_SUPPORT = window.JSON && - typeof JSON.parse === 'function' && - JSON.parse('{"test": true}').test; - - function prepareReplacement(replacement) { - if (Object.isFunction(replacement)) return replacement; - var template = new Template(replacement); - return function(match) { return template.evaluate(match) }; - } - - function isNonEmptyRegExp(regexp) { - return regexp.source && regexp.source !== '(?:)'; - } - - - function gsub(pattern, replacement) { - var result = '', source = this, match; - replacement = prepareReplacement(replacement); - - if (Object.isString(pattern)) - pattern = RegExp.escape(pattern); - - if (!(pattern.length || isNonEmptyRegExp(pattern))) { - replacement = replacement(''); - return replacement + source.split('').join(replacement) + replacement; - } - - while (source.length > 0) { - match = source.match(pattern) - if (match && match[0].length > 0) { - result += source.slice(0, match.index); - result += String.interpret(replacement(match)); - source = source.slice(match.index + match[0].length); - } else { - result += source, source = ''; - } - } - return result; - } - - function sub(pattern, replacement, count) { - replacement = prepareReplacement(replacement); - count = Object.isUndefined(count) ? 1 : count; - - return this.gsub(pattern, function(match) { - if (--count < 0) return match[0]; - return replacement(match); - }); - } - - function scan(pattern, iterator) { - this.gsub(pattern, iterator); - return String(this); - } - - function truncate(length, truncation) { - length = length || 30; - truncation = Object.isUndefined(truncation) ? '...' : truncation; - return this.length > length ? - this.slice(0, length - truncation.length) + truncation : String(this); - } - - function strip() { - return this.replace(/^\s+/, '').replace(/\s+$/, ''); - } - - function stripTags() { - return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?(\/)?>|<\/\w+>/gi, ''); - } - - function stripScripts() { - return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), ''); - } - - function extractScripts() { - var matchAll = new RegExp(Prototype.ScriptFragment, 'img'), - matchOne = new RegExp(Prototype.ScriptFragment, 'im'); - return (this.match(matchAll) || []).map(function(scriptTag) { - return (scriptTag.match(matchOne) || ['', ''])[1]; - }); - } - - function evalScripts() { - return this.extractScripts().map(function(script) { return eval(script); }); - } - - function escapeHTML() { - return this.replace(/&/g,'&').replace(//g,'>'); - } - - function unescapeHTML() { - return this.stripTags().replace(/</g,'<').replace(/>/g,'>').replace(/&/g,'&'); - } - - - function toQueryParams(separator) { - var match = this.strip().match(/([^?#]*)(#.*)?$/); - if (!match) return { }; - - return match[1].split(separator || '&').inject({ }, function(hash, pair) { - if ((pair = pair.split('='))[0]) { - var key = decodeURIComponent(pair.shift()), - value = pair.length > 1 ? pair.join('=') : pair[0]; - - if (value != undefined) { - value = value.gsub('+', ' '); - value = decodeURIComponent(value); - } - - if (key in hash) { - if (!Object.isArray(hash[key])) hash[key] = [hash[key]]; - hash[key].push(value); - } - else hash[key] = value; - } - return hash; - }); - } - - function toArray() { - return this.split(''); - } - - function succ() { - return this.slice(0, this.length - 1) + - String.fromCharCode(this.charCodeAt(this.length - 1) + 1); - } - - function times(count) { - return count < 1 ? '' : new Array(count + 1).join(this); - } - - function camelize() { - return this.replace(/-+(.)?/g, function(match, chr) { - return chr ? chr.toUpperCase() : ''; - }); - } - - function capitalize() { - return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase(); - } - - function underscore() { - return this.replace(/::/g, '/') - .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2') - .replace(/([a-z\d])([A-Z])/g, '$1_$2') - .replace(/-/g, '_') - .toLowerCase(); - } - - function dasherize() { - return this.replace(/_/g, '-'); - } - - function inspect(useDoubleQuotes) { - var escapedString = this.replace(/[\x00-\x1f\\]/g, function(character) { - if (character in String.specialChar) { - return String.specialChar[character]; - } - return '\\u00' + character.charCodeAt().toPaddedString(2, 16); - }); - if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"'; - return "'" + escapedString.replace(/'/g, '\\\'') + "'"; - } - - function unfilterJSON(filter) { - return this.replace(filter || Prototype.JSONFilter, '$1'); - } - - function isJSON() { - var str = this; - if (str.blank()) return false; - str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@'); - str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']'); - str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, ''); - return (/^[\],:{}\s]*$/).test(str); - } - - function evalJSON(sanitize) { - var json = this.unfilterJSON(), - cx = /[\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff\u0000]/g; - if (cx.test(json)) { - json = json.replace(cx, function (a) { - return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); - }); - } - try { - if (!sanitize || json.isJSON()) return eval('(' + json + ')'); - } catch (e) { } - throw new SyntaxError('Badly formed JSON string: ' + this.inspect()); - } - - function parseJSON() { - var json = this.unfilterJSON(); - return JSON.parse(json); - } - - function include(pattern) { - return this.indexOf(pattern) > -1; - } - - function startsWith(pattern, position) { - position = Object.isNumber(position) ? position : 0; - return this.lastIndexOf(pattern, position) === position; - } - - function endsWith(pattern, position) { - pattern = String(pattern); - position = Object.isNumber(position) ? position : this.length; - if (position < 0) position = 0; - if (position > this.length) position = this.length; - var d = position - pattern.length; - return d >= 0 && this.indexOf(pattern, d) === d; - } - - function empty() { - return this == ''; - } - - function blank() { - return /^\s*$/.test(this); - } - - function interpolate(object, pattern) { - return new Template(this, pattern).evaluate(object); - } - - return { - gsub: gsub, - sub: sub, - scan: scan, - truncate: truncate, - strip: String.prototype.trim || strip, - stripTags: stripTags, - stripScripts: stripScripts, - extractScripts: extractScripts, - evalScripts: evalScripts, - escapeHTML: escapeHTML, - unescapeHTML: unescapeHTML, - toQueryParams: toQueryParams, - parseQuery: toQueryParams, - toArray: toArray, - succ: succ, - times: times, - camelize: camelize, - capitalize: capitalize, - underscore: underscore, - dasherize: dasherize, - inspect: inspect, - unfilterJSON: unfilterJSON, - isJSON: isJSON, - evalJSON: NATIVE_JSON_PARSE_SUPPORT ? parseJSON : evalJSON, - include: include, - startsWith: String.prototype.startsWith || startsWith, - endsWith: String.prototype.endsWith || endsWith, - empty: empty, - blank: blank, - interpolate: interpolate - }; -})()); - -var Template = Class.create({ - initialize: function(template, pattern) { - this.template = template.toString(); - this.pattern = pattern || Template.Pattern; - }, - - evaluate: function(object) { - if (object && Object.isFunction(object.toTemplateReplacements)) - object = object.toTemplateReplacements(); - - return this.template.gsub(this.pattern, function(match) { - if (object == null) return (match[1] + ''); - - var before = match[1] || ''; - if (before == '\\') return match[2]; - - var ctx = object, expr = match[3], - pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/; - - match = pattern.exec(expr); - if (match == null) return before; - - while (match != null) { - var comp = match[1].startsWith('[') ? match[2].replace(/\\\\]/g, ']') : match[1]; - ctx = ctx[comp]; - if (null == ctx || '' == match[3]) break; - expr = expr.substring('[' == match[3] ? match[1].length : match[0].length); - match = pattern.exec(expr); - } - - return before + String.interpret(ctx); - }); - } -}); -Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; - -var $break = { }; - -var Enumerable = (function() { - function each(iterator, context) { - try { - this._each(iterator, context); - } catch (e) { - if (e != $break) throw e; - } - return this; - } - - function eachSlice(number, iterator, context) { - var index = -number, slices = [], array = this.toArray(); - if (number < 1) return array; - while ((index += number) < array.length) - slices.push(array.slice(index, index+number)); - return slices.collect(iterator, context); - } - - function all(iterator, context) { - iterator = iterator || Prototype.K; - var result = true; - this.each(function(value, index) { - result = result && !!iterator.call(context, value, index, this); - if (!result) throw $break; - }, this); - return result; - } - - function any(iterator, context) { - iterator = iterator || Prototype.K; - var result = false; - this.each(function(value, index) { - if (result = !!iterator.call(context, value, index, this)) - throw $break; - }, this); - return result; - } - - function collect(iterator, context) { - iterator = iterator || Prototype.K; - var results = []; - this.each(function(value, index) { - results.push(iterator.call(context, value, index, this)); - }, this); - return results; - } - - function detect(iterator, context) { - var result; - this.each(function(value, index) { - if (iterator.call(context, value, index, this)) { - result = value; - throw $break; - } - }, this); - return result; - } - - function findAll(iterator, context) { - var results = []; - this.each(function(value, index) { - if (iterator.call(context, value, index, this)) - results.push(value); - }, this); - return results; - } - - function grep(filter, iterator, context) { - iterator = iterator || Prototype.K; - var results = []; - - if (Object.isString(filter)) - filter = new RegExp(RegExp.escape(filter)); - - this.each(function(value, index) { - if (filter.match(value)) - results.push(iterator.call(context, value, index, this)); - }, this); - return results; - } - - function include(object) { - if (Object.isFunction(this.indexOf) && this.indexOf(object) != -1) - return true; - - var found = false; - this.each(function(value) { - if (value == object) { - found = true; - throw $break; - } - }); - return found; - } - - function inGroupsOf(number, fillWith) { - fillWith = Object.isUndefined(fillWith) ? null : fillWith; - return this.eachSlice(number, function(slice) { - while(slice.length < number) slice.push(fillWith); - return slice; - }); - } - - function inject(memo, iterator, context) { - this.each(function(value, index) { - memo = iterator.call(context, memo, value, index, this); - }, this); - return memo; - } - - function invoke(method) { - var args = $A(arguments).slice(1); - return this.map(function(value) { - return value[method].apply(value, args); - }); - } - - function max(iterator, context) { - iterator = iterator || Prototype.K; - var result; - this.each(function(value, index) { - value = iterator.call(context, value, index, this); - if (result == null || value >= result) - result = value; - }, this); - return result; - } - - function min(iterator, context) { - iterator = iterator || Prototype.K; - var result; - this.each(function(value, index) { - value = iterator.call(context, value, index, this); - if (result == null || value < result) - result = value; - }, this); - return result; - } - - function partition(iterator, context) { - iterator = iterator || Prototype.K; - var trues = [], falses = []; - this.each(function(value, index) { - (iterator.call(context, value, index, this) ? - trues : falses).push(value); - }, this); - return [trues, falses]; - } - - function pluck(property) { - var results = []; - this.each(function(value) { - results.push(value[property]); - }); - return results; - } - - function reject(iterator, context) { - var results = []; - this.each(function(value, index) { - if (!iterator.call(context, value, index, this)) - results.push(value); - }, this); - return results; - } - - function sortBy(iterator, context) { - return this.map(function(value, index) { - return { - value: value, - criteria: iterator.call(context, value, index, this) - }; - }, this).sort(function(left, right) { - var a = left.criteria, b = right.criteria; - return a < b ? -1 : a > b ? 1 : 0; - }).pluck('value'); - } - - function toArray() { - return this.map(); - } - - function zip() { - var iterator = Prototype.K, args = $A(arguments); - if (Object.isFunction(args.last())) - iterator = args.pop(); - - var collections = [this].concat(args).map($A); - return this.map(function(value, index) { - return iterator(collections.pluck(index)); - }); - } - - function size() { - return this.toArray().length; - } - - function inspect() { - return '#'; - } - - - - - - - - - - return { - each: each, - eachSlice: eachSlice, - all: all, - every: all, - any: any, - some: any, - collect: collect, - map: collect, - detect: detect, - findAll: findAll, - select: findAll, - filter: findAll, - grep: grep, - include: include, - member: include, - inGroupsOf: inGroupsOf, - inject: inject, - invoke: invoke, - max: max, - min: min, - partition: partition, - pluck: pluck, - reject: reject, - sortBy: sortBy, - toArray: toArray, - entries: toArray, - zip: zip, - size: size, - inspect: inspect, - find: detect - }; -})(); - -function $A(iterable) { - if (!iterable) return []; - if ('toArray' in Object(iterable)) return iterable.toArray(); - var length = iterable.length || 0, results = new Array(length); - while (length--) results[length] = iterable[length]; - return results; -} - - -function $w(string) { - if (!Object.isString(string)) return []; - string = string.strip(); - return string ? string.split(/\s+/) : []; -} - -Array.from = $A; - - -(function() { - var arrayProto = Array.prototype, - slice = arrayProto.slice, - _each = arrayProto.forEach; // use native browser JS 1.6 implementation if available - - function each(iterator, context) { - for (var i = 0, length = this.length >>> 0; i < length; i++) { - if (i in this) iterator.call(context, this[i], i, this); - } - } - if (!_each) _each = each; - - function clear() { - this.length = 0; - return this; - } - - function first() { - return this[0]; - } - - function last() { - return this[this.length - 1]; - } - - function compact() { - return this.select(function(value) { - return value != null; - }); - } - - function flatten() { - return this.inject([], function(array, value) { - if (Object.isArray(value)) - return array.concat(value.flatten()); - array.push(value); - return array; - }); - } - - function without() { - var values = slice.call(arguments, 0); - return this.select(function(value) { - return !values.include(value); - }); - } - - function reverse(inline) { - return (inline === false ? this.toArray() : this)._reverse(); - } - - function uniq(sorted) { - return this.inject([], function(array, value, index) { - if (0 == index || (sorted ? array.last() != value : !array.include(value))) - array.push(value); - return array; - }); - } - - function intersect(array) { - return this.uniq().findAll(function(item) { - return array.indexOf(item) !== -1; - }); - } - - - function clone() { - return slice.call(this, 0); - } - - function size() { - return this.length; - } - - function inspect() { - return '[' + this.map(Object.inspect).join(', ') + ']'; - } - - function indexOf(item, i) { - if (this == null) throw new TypeError(); - - var array = Object(this), length = array.length >>> 0; - if (length === 0) return -1; - - i = Number(i); - if (isNaN(i)) { - i = 0; - } else if (i !== 0 && isFinite(i)) { - i = (i > 0 ? 1 : -1) * Math.floor(Math.abs(i)); - } - - if (i > length) return -1; - - var k = i >= 0 ? i : Math.max(length - Math.abs(i), 0); - for (; k < length; k++) - if (k in array && array[k] === item) return k; - return -1; - } - - - function lastIndexOf(item, i) { - if (this == null) throw new TypeError(); - - var array = Object(this), length = array.length >>> 0; - if (length === 0) return -1; - - if (!Object.isUndefined(i)) { - i = Number(i); - if (isNaN(i)) { - i = 0; - } else if (i !== 0 && isFinite(i)) { - i = (i > 0 ? 1 : -1) * Math.floor(Math.abs(i)); - } - } else { - i = length; - } - - var k = i >= 0 ? Math.min(i, length - 1) : - length - Math.abs(i); - - for (; k >= 0; k--) - if (k in array && array[k] === item) return k; - return -1; - } - - function concat(_) { - var array = [], items = slice.call(arguments, 0), item, n = 0; - items.unshift(this); - for (var i = 0, length = items.length; i < length; i++) { - item = items[i]; - if (Object.isArray(item) && !('callee' in item)) { - for (var j = 0, arrayLength = item.length; j < arrayLength; j++) { - if (j in item) array[n] = item[j]; - n++; - } - } else { - array[n++] = item; - } - } - array.length = n; - return array; - } - - - function wrapNative(method) { - return function() { - if (arguments.length === 0) { - return method.call(this, Prototype.K); - } else if (arguments[0] === undefined) { - var args = slice.call(arguments, 1); - args.unshift(Prototype.K); - return method.apply(this, args); - } else { - return method.apply(this, arguments); - } - }; - } - - - function map(iterator) { - if (this == null) throw new TypeError(); - iterator = iterator || Prototype.K; - - var object = Object(this); - var results = [], context = arguments[1], n = 0; - - for (var i = 0, length = object.length >>> 0; i < length; i++) { - if (i in object) { - results[n] = iterator.call(context, object[i], i, object); - } - n++; - } - results.length = n; - return results; - } - - if (arrayProto.map) { - map = wrapNative(Array.prototype.map); - } - - function filter(iterator) { - if (this == null || !Object.isFunction(iterator)) - throw new TypeError(); - - var object = Object(this); - var results = [], context = arguments[1], value; - - for (var i = 0, length = object.length >>> 0; i < length; i++) { - if (i in object) { - value = object[i]; - if (iterator.call(context, value, i, object)) { - results.push(value); - } - } - } - return results; - } - - if (arrayProto.filter) { - filter = Array.prototype.filter; - } - - function some(iterator) { - if (this == null) throw new TypeError(); - iterator = iterator || Prototype.K; - var context = arguments[1]; - - var object = Object(this); - for (var i = 0, length = object.length >>> 0; i < length; i++) { - if (i in object && iterator.call(context, object[i], i, object)) { - return true; - } - } - - return false; - } - - if (arrayProto.some) { - some = wrapNative(Array.prototype.some); - } - - function every(iterator) { - if (this == null) throw new TypeError(); - iterator = iterator || Prototype.K; - var context = arguments[1]; - - var object = Object(this); - for (var i = 0, length = object.length >>> 0; i < length; i++) { - if (i in object && !iterator.call(context, object[i], i, object)) { - return false; - } - } - - return true; - } - - if (arrayProto.every) { - every = wrapNative(Array.prototype.every); - } - - - Object.extend(arrayProto, Enumerable); - - if (arrayProto.entries === Enumerable.entries) { - delete arrayProto.entries; - } - - if (!arrayProto._reverse) - arrayProto._reverse = arrayProto.reverse; - - Object.extend(arrayProto, { - _each: _each, - - map: map, - collect: map, - select: filter, - filter: filter, - findAll: filter, - some: some, - any: some, - every: every, - all: every, - - clear: clear, - first: first, - last: last, - compact: compact, - flatten: flatten, - without: without, - reverse: reverse, - uniq: uniq, - intersect: intersect, - clone: clone, - toArray: clone, - size: size, - inspect: inspect - }); - - var CONCAT_ARGUMENTS_BUGGY = (function() { - return [].concat(arguments)[0][0] !== 1; - })(1,2); - - if (CONCAT_ARGUMENTS_BUGGY) arrayProto.concat = concat; - - if (!arrayProto.indexOf) arrayProto.indexOf = indexOf; - if (!arrayProto.lastIndexOf) arrayProto.lastIndexOf = lastIndexOf; -})(); -function $H(object) { - return new Hash(object); -}; - -var Hash = Class.create(Enumerable, (function() { - function initialize(object) { - this._object = Object.isHash(object) ? object.toObject() : Object.clone(object); - } - - - function _each(iterator, context) { - var i = 0; - for (var key in this._object) { - var value = this._object[key], pair = [key, value]; - pair.key = key; - pair.value = value; - iterator.call(context, pair, i); - i++; - } - } - - function set(key, value) { - return this._object[key] = value; - } - - function get(key) { - if (this._object[key] !== Object.prototype[key]) - return this._object[key]; - } - - function unset(key) { - var value = this._object[key]; - delete this._object[key]; - return value; - } - - function toObject() { - return Object.clone(this._object); - } - - - - function keys() { - return this.pluck('key'); - } - - function values() { - return this.pluck('value'); - } - - function index(value) { - var match = this.detect(function(pair) { - return pair.value === value; - }); - return match && match.key; - } - - function merge(object) { - return this.clone().update(object); - } - - function update(object) { - return new Hash(object).inject(this, function(result, pair) { - result.set(pair.key, pair.value); - return result; - }); - } - - function toQueryPair(key, value) { - if (Object.isUndefined(value)) return key; - - value = String.interpret(value); - - value = value.gsub(/(\r)?\n/, '\r\n'); - value = encodeURIComponent(value); - value = value.gsub(/%20/, '+'); - return key + '=' + value; - } - - function toQueryString() { - return this.inject([], function(results, pair) { - var key = encodeURIComponent(pair.key), values = pair.value; - - if (values && typeof values == 'object') { - if (Object.isArray(values)) { - var queryValues = []; - for (var i = 0, len = values.length, value; i < len; i++) { - value = values[i]; - queryValues.push(toQueryPair(key, value)); - } - return results.concat(queryValues); - } - } else results.push(toQueryPair(key, values)); - return results; - }).join('&'); - } - - function inspect() { - return '#'; - } - - function clone() { - return new Hash(this); - } - - return { - initialize: initialize, - _each: _each, - set: set, - get: get, - unset: unset, - toObject: toObject, - toTemplateReplacements: toObject, - keys: keys, - values: values, - index: index, - merge: merge, - update: update, - toQueryString: toQueryString, - inspect: inspect, - toJSON: toObject, - clone: clone - }; -})()); - -Hash.from = $H; -Object.extend(Number.prototype, (function() { - function toColorPart() { - return this.toPaddedString(2, 16); - } - - function succ() { - return this + 1; - } - - function times(iterator, context) { - $R(0, this, true).each(iterator, context); - return this; - } - - function toPaddedString(length, radix) { - var string = this.toString(radix || 10); - return '0'.times(length - string.length) + string; - } - - function abs() { - return Math.abs(this); - } - - function round() { - return Math.round(this); - } - - function ceil() { - return Math.ceil(this); - } - - function floor() { - return Math.floor(this); - } - - return { - toColorPart: toColorPart, - succ: succ, - times: times, - toPaddedString: toPaddedString, - abs: abs, - round: round, - ceil: ceil, - floor: floor - }; -})()); - -function $R(start, end, exclusive) { - return new ObjectRange(start, end, exclusive); -} - -var ObjectRange = Class.create(Enumerable, (function() { - function initialize(start, end, exclusive) { - this.start = start; - this.end = end; - this.exclusive = exclusive; - } - - function _each(iterator, context) { - var value = this.start, i; - for (i = 0; this.include(value); i++) { - iterator.call(context, value, i); - value = value.succ(); - } - } - - function include(value) { - if (value < this.start) - return false; - if (this.exclusive) - return value < this.end; - return value <= this.end; - } - - return { - initialize: initialize, - _each: _each, - include: include - }; -})()); - - - -var Abstract = { }; - - -var Try = { - these: function() { - var returnValue; - - for (var i = 0, length = arguments.length; i < length; i++) { - var lambda = arguments[i]; - try { - returnValue = lambda(); - break; - } catch (e) { } - } - - return returnValue; - } -}; - -var Ajax = { - getTransport: function() { - return Try.these( - function() {return new XMLHttpRequest()}, - function() {return new ActiveXObject('Msxml2.XMLHTTP')}, - function() {return new ActiveXObject('Microsoft.XMLHTTP')} - ) || false; - }, - - activeRequestCount: 0 -}; - -Ajax.Responders = { - responders: [], - - _each: function(iterator, context) { - this.responders._each(iterator, context); - }, - - register: function(responder) { - if (!this.include(responder)) - this.responders.push(responder); - }, - - unregister: function(responder) { - this.responders = this.responders.without(responder); - }, - - dispatch: function(callback, request, transport, json) { - this.each(function(responder) { - if (Object.isFunction(responder[callback])) { - try { - responder[callback].apply(responder, [request, transport, json]); - } catch (e) { } - } - }); - } -}; - -Object.extend(Ajax.Responders, Enumerable); - -Ajax.Responders.register({ - onCreate: function() { Ajax.activeRequestCount++ }, - onComplete: function() { Ajax.activeRequestCount-- } -}); -Ajax.Base = Class.create({ - initialize: function(options) { - this.options = { - method: 'post', - asynchronous: true, - contentType: 'application/x-www-form-urlencoded', - encoding: 'UTF-8', - parameters: '', - evalJSON: true, - evalJS: true - }; - Object.extend(this.options, options || { }); - - this.options.method = this.options.method.toLowerCase(); - - if (Object.isHash(this.options.parameters)) - this.options.parameters = this.options.parameters.toObject(); - } -}); -Ajax.Request = Class.create(Ajax.Base, { - _complete: false, - - initialize: function($super, url, options) { - $super(options); - this.transport = Ajax.getTransport(); - this.request(url); - }, - - request: function(url) { - this.url = url; - this.method = this.options.method; - var params = Object.isString(this.options.parameters) ? - this.options.parameters : - Object.toQueryString(this.options.parameters); - - if (!['get', 'post'].include(this.method)) { - params += (params ? '&' : '') + "_method=" + this.method; - this.method = 'post'; - } - - if (params && this.method === 'get') { - this.url += (this.url.include('?') ? '&' : '?') + params; - } - - this.parameters = params.toQueryParams(); - - try { - var response = new Ajax.Response(this); - if (this.options.onCreate) this.options.onCreate(response); - Ajax.Responders.dispatch('onCreate', this, response); - - this.transport.open(this.method.toUpperCase(), this.url, - this.options.asynchronous); - - if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1); - - this.transport.onreadystatechange = this.onStateChange.bind(this); - this.setRequestHeaders(); - - this.body = this.method == 'post' ? (this.options.postBody || params) : null; - this.transport.send(this.body); - - /* Force Firefox to handle ready state 4 for synchronous requests */ - if (!this.options.asynchronous && this.transport.overrideMimeType) - this.onStateChange(); - - } - catch (e) { - this.dispatchException(e); - } - }, - - onStateChange: function() { - var readyState = this.transport.readyState; - if (readyState > 1 && !((readyState == 4) && this._complete)) - this.respondToReadyState(this.transport.readyState); - }, - - setRequestHeaders: function() { - var headers = { - 'X-Requested-With': 'XMLHttpRequest', - 'X-Prototype-Version': Prototype.Version, - 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*' - }; - - if (this.method == 'post') { - headers['Content-type'] = this.options.contentType + - (this.options.encoding ? '; charset=' + this.options.encoding : ''); - - /* Force "Connection: close" for older Mozilla browsers to work - * around a bug where XMLHttpRequest sends an incorrect - * Content-length header. See Mozilla Bugzilla #246651. - */ - if (this.transport.overrideMimeType && - (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005) - headers['Connection'] = 'close'; - } - - if (typeof this.options.requestHeaders == 'object') { - var extras = this.options.requestHeaders; - - if (Object.isFunction(extras.push)) - for (var i = 0, length = extras.length; i < length; i += 2) - headers[extras[i]] = extras[i+1]; - else - $H(extras).each(function(pair) { headers[pair.key] = pair.value }); - } - - for (var name in headers) - if (headers[name] != null) - this.transport.setRequestHeader(name, headers[name]); - }, - - success: function() { - var status = this.getStatus(); - return !status || (status >= 200 && status < 300) || status == 304; - }, - - getStatus: function() { - try { - if (this.transport.status === 1223) return 204; - return this.transport.status || 0; - } catch (e) { return 0 } - }, - - respondToReadyState: function(readyState) { - var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this); - - if (state == 'Complete') { - try { - this._complete = true; - (this.options['on' + response.status] - || this.options['on' + (this.success() ? 'Success' : 'Failure')] - || Prototype.emptyFunction)(response, response.headerJSON); - } catch (e) { - this.dispatchException(e); - } - - var contentType = response.getHeader('Content-type'); - if (this.options.evalJS == 'force' - || (this.options.evalJS && this.isSameOrigin() && contentType - && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i))) - this.evalResponse(); - } - - try { - (this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON); - Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON); - } catch (e) { - this.dispatchException(e); - } - - if (state == 'Complete') { - this.transport.onreadystatechange = Prototype.emptyFunction; - } - }, - - isSameOrigin: function() { - var m = this.url.match(/^\s*https?:\/\/[^\/]*/); - return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({ - protocol: location.protocol, - domain: document.domain, - port: location.port ? ':' + location.port : '' - })); - }, - - getHeader: function(name) { - try { - return this.transport.getResponseHeader(name) || null; - } catch (e) { return null; } - }, - - evalResponse: function() { - try { - return eval((this.transport.responseText || '').unfilterJSON()); - } catch (e) { - this.dispatchException(e); - } - }, - - dispatchException: function(exception) { - (this.options.onException || Prototype.emptyFunction)(this, exception); - Ajax.Responders.dispatch('onException', this, exception); - } -}); - -Ajax.Request.Events = - ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; - - - - - - - - -Ajax.Response = Class.create({ - initialize: function(request){ - this.request = request; - var transport = this.transport = request.transport, - readyState = this.readyState = transport.readyState; - - if ((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) { - this.status = this.getStatus(); - this.statusText = this.getStatusText(); - this.responseText = String.interpret(transport.responseText); - this.headerJSON = this._getHeaderJSON(); - } - - if (readyState == 4) { - var xml = transport.responseXML; - this.responseXML = Object.isUndefined(xml) ? null : xml; - this.responseJSON = this._getResponseJSON(); - } - }, - - status: 0, - - statusText: '', - - getStatus: Ajax.Request.prototype.getStatus, - - getStatusText: function() { - try { - return this.transport.statusText || ''; - } catch (e) { return '' } - }, - - getHeader: Ajax.Request.prototype.getHeader, - - getAllHeaders: function() { - try { - return this.getAllResponseHeaders(); - } catch (e) { return null } - }, - - getResponseHeader: function(name) { - return this.transport.getResponseHeader(name); - }, - - getAllResponseHeaders: function() { - return this.transport.getAllResponseHeaders(); - }, - - _getHeaderJSON: function() { - var json = this.getHeader('X-JSON'); - if (!json) return null; - - try { - json = decodeURIComponent(escape(json)); - } catch(e) { - } - - try { - return json.evalJSON(this.request.options.sanitizeJSON || - !this.request.isSameOrigin()); - } catch (e) { - this.request.dispatchException(e); - } - }, - - _getResponseJSON: function() { - var options = this.request.options; - if (!options.evalJSON || (options.evalJSON != 'force' && - !(this.getHeader('Content-type') || '').include('application/json')) || - this.responseText.blank()) - return null; - try { - return this.responseText.evalJSON(options.sanitizeJSON || - !this.request.isSameOrigin()); - } catch (e) { - this.request.dispatchException(e); - } - } -}); - -Ajax.Updater = Class.create(Ajax.Request, { - initialize: function($super, container, url, options) { - this.container = { - success: (container.success || container), - failure: (container.failure || (container.success ? null : container)) - }; - - options = Object.clone(options); - var onComplete = options.onComplete; - options.onComplete = (function(response, json) { - this.updateContent(response.responseText); - if (Object.isFunction(onComplete)) onComplete(response, json); - }).bind(this); - - $super(url, options); - }, - - updateContent: function(responseText) { - var receiver = this.container[this.success() ? 'success' : 'failure'], - options = this.options; - - if (!options.evalScripts) responseText = responseText.stripScripts(); - - if (receiver = $(receiver)) { - if (options.insertion) { - if (Object.isString(options.insertion)) { - var insertion = { }; insertion[options.insertion] = responseText; - receiver.insert(insertion); - } - else options.insertion(receiver, responseText); - } - else receiver.update(responseText); - } - } -}); - -Ajax.PeriodicalUpdater = Class.create(Ajax.Base, { - initialize: function($super, container, url, options) { - $super(options); - this.onComplete = this.options.onComplete; - - this.frequency = (this.options.frequency || 2); - this.decay = (this.options.decay || 1); - - this.updater = { }; - this.container = container; - this.url = url; - - this.start(); - }, - - start: function() { - this.options.onComplete = this.updateComplete.bind(this); - this.onTimerEvent(); - }, - - stop: function() { - this.updater.options.onComplete = undefined; - clearTimeout(this.timer); - (this.onComplete || Prototype.emptyFunction).apply(this, arguments); - }, - - updateComplete: function(response) { - if (this.options.decay) { - this.decay = (response.responseText == this.lastText ? - this.decay * this.options.decay : 1); - - this.lastText = response.responseText; - } - this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency); - }, - - onTimerEvent: function() { - this.updater = new Ajax.Updater(this.container, this.url, this.options); - } -}); - -(function(GLOBAL) { - - var UNDEFINED; - var SLICE = Array.prototype.slice; - - var DIV = document.createElement('div'); - - - function $(element) { - if (arguments.length > 1) { - for (var i = 0, elements = [], length = arguments.length; i < length; i++) - elements.push($(arguments[i])); - return elements; - } - - if (Object.isString(element)) - element = document.getElementById(element); - return Element.extend(element); - } - - GLOBAL.$ = $; - - - if (!GLOBAL.Node) GLOBAL.Node = {}; - - if (!GLOBAL.Node.ELEMENT_NODE) { - Object.extend(GLOBAL.Node, { - ELEMENT_NODE: 1, - ATTRIBUTE_NODE: 2, - TEXT_NODE: 3, - CDATA_SECTION_NODE: 4, - ENTITY_REFERENCE_NODE: 5, - ENTITY_NODE: 6, - PROCESSING_INSTRUCTION_NODE: 7, - COMMENT_NODE: 8, - DOCUMENT_NODE: 9, - DOCUMENT_TYPE_NODE: 10, - DOCUMENT_FRAGMENT_NODE: 11, - NOTATION_NODE: 12 - }); - } - - var ELEMENT_CACHE = {}; - - function shouldUseCreationCache(tagName, attributes) { - if (tagName === 'select') return false; - if ('type' in attributes) return false; - return true; - } - - var HAS_EXTENDED_CREATE_ELEMENT_SYNTAX = (function(){ - try { - var el = document.createElement(''); - return el.tagName.toLowerCase() === 'input' && el.name === 'x'; - } - catch(err) { - return false; - } - })(); - - - var oldElement = GLOBAL.Element; - function Element(tagName, attributes) { - attributes = attributes || {}; - tagName = tagName.toLowerCase(); - - if (HAS_EXTENDED_CREATE_ELEMENT_SYNTAX && attributes.name) { - tagName = '<' + tagName + ' name="' + attributes.name + '">'; - delete attributes.name; - return Element.writeAttribute(document.createElement(tagName), attributes); - } - - if (!ELEMENT_CACHE[tagName]) - ELEMENT_CACHE[tagName] = Element.extend(document.createElement(tagName)); - - var node = shouldUseCreationCache(tagName, attributes) ? - ELEMENT_CACHE[tagName].cloneNode(false) : document.createElement(tagName); - - return Element.writeAttribute(node, attributes); - } - - GLOBAL.Element = Element; - - Object.extend(GLOBAL.Element, oldElement || {}); - if (oldElement) GLOBAL.Element.prototype = oldElement.prototype; - - Element.Methods = { ByTag: {}, Simulated: {} }; - - var methods = {}; - - var INSPECT_ATTRIBUTES = { id: 'id', className: 'class' }; - function inspect(element) { - element = $(element); - var result = '<' + element.tagName.toLowerCase(); - - var attribute, value; - for (var property in INSPECT_ATTRIBUTES) { - attribute = INSPECT_ATTRIBUTES[property]; - value = (element[property] || '').toString(); - if (value) result += ' ' + attribute + '=' + value.inspect(true); - } - - return result + '>'; - } - - methods.inspect = inspect; - - - function visible(element) { - return $(element).getStyle('display') !== 'none'; - } - - function toggle(element, bool) { - element = $(element); - if (typeof bool !== 'boolean') - bool = !Element.visible(element); - Element[bool ? 'show' : 'hide'](element); - - return element; - } - - function hide(element) { - element = $(element); - element.style.display = 'none'; - return element; - } - - function show(element) { - element = $(element); - element.style.display = ''; - return element; - } - - - Object.extend(methods, { - visible: visible, - toggle: toggle, - hide: hide, - show: show - }); - - - function remove(element) { - element = $(element); - element.parentNode.removeChild(element); - return element; - } - - var SELECT_ELEMENT_INNERHTML_BUGGY = (function(){ - var el = document.createElement("select"), - isBuggy = true; - el.innerHTML = ""; - if (el.options && el.options[0]) { - isBuggy = el.options[0].nodeName.toUpperCase() !== "OPTION"; - } - el = null; - return isBuggy; - })(); - - var TABLE_ELEMENT_INNERHTML_BUGGY = (function(){ - try { - var el = document.createElement("table"); - if (el && el.tBodies) { - el.innerHTML = "test"; - var isBuggy = typeof el.tBodies[0] == "undefined"; - el = null; - return isBuggy; - } - } catch (e) { - return true; - } - })(); - - var LINK_ELEMENT_INNERHTML_BUGGY = (function() { - try { - var el = document.createElement('div'); - el.innerHTML = ""; - var isBuggy = (el.childNodes.length === 0); - el = null; - return isBuggy; - } catch(e) { - return true; - } - })(); - - var ANY_INNERHTML_BUGGY = SELECT_ELEMENT_INNERHTML_BUGGY || - TABLE_ELEMENT_INNERHTML_BUGGY || LINK_ELEMENT_INNERHTML_BUGGY; - - var SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING = (function () { - var s = document.createElement("script"), - isBuggy = false; - try { - s.appendChild(document.createTextNode("")); - isBuggy = !s.firstChild || - s.firstChild && s.firstChild.nodeType !== 3; - } catch (e) { - isBuggy = true; - } - s = null; - return isBuggy; - })(); - - function update(element, content) { - element = $(element); - - var descendants = element.getElementsByTagName('*'), - i = descendants.length; - while (i--) purgeElement(descendants[i]); - - if (content && content.toElement) - content = content.toElement(); - - if (Object.isElement(content)) - return element.update().insert(content); - - - content = Object.toHTML(content); - var tagName = element.tagName.toUpperCase(); - - if (tagName === 'SCRIPT' && SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING) { - element.text = content; - return element; - } - - if (ANY_INNERHTML_BUGGY) { - if (tagName in INSERTION_TRANSLATIONS.tags) { - while (element.firstChild) - element.removeChild(element.firstChild); - - var nodes = getContentFromAnonymousElement(tagName, content.stripScripts()); - for (var i = 0, node; node = nodes[i]; i++) - element.appendChild(node); - - } else if (LINK_ELEMENT_INNERHTML_BUGGY && Object.isString(content) && content.indexOf(' -1) { - while (element.firstChild) - element.removeChild(element.firstChild); - - var nodes = getContentFromAnonymousElement(tagName, - content.stripScripts(), true); - - for (var i = 0, node; node = nodes[i]; i++) - element.appendChild(node); - } else { - element.innerHTML = content.stripScripts(); - } - } else { - element.innerHTML = content.stripScripts(); - } - - content.evalScripts.bind(content).defer(); - return element; - } - - function replace(element, content) { - element = $(element); - - if (content && content.toElement) { - content = content.toElement(); - } else if (!Object.isElement(content)) { - content = Object.toHTML(content); - var range = element.ownerDocument.createRange(); - range.selectNode(element); - content.evalScripts.bind(content).defer(); - content = range.createContextualFragment(content.stripScripts()); - } - - element.parentNode.replaceChild(content, element); - return element; - } - - var INSERTION_TRANSLATIONS = { - before: function(element, node) { - element.parentNode.insertBefore(node, element); - }, - top: function(element, node) { - element.insertBefore(node, element.firstChild); - }, - bottom: function(element, node) { - element.appendChild(node); - }, - after: function(element, node) { - element.parentNode.insertBefore(node, element.nextSibling); - }, - - tags: { - TABLE: ['', '
', 1], - TBODY: ['', '
', 2], - TR: ['', '
', 3], - TD: ['
', '
', 4], - SELECT: ['', 1] - } - }; - - var tags = INSERTION_TRANSLATIONS.tags; - - Object.extend(tags, { - THEAD: tags.TBODY, - TFOOT: tags.TBODY, - TH: tags.TD - }); - - function replace_IE(element, content) { - element = $(element); - if (content && content.toElement) - content = content.toElement(); - if (Object.isElement(content)) { - element.parentNode.replaceChild(content, element); - return element; - } - - content = Object.toHTML(content); - var parent = element.parentNode, tagName = parent.tagName.toUpperCase(); - - if (tagName in INSERTION_TRANSLATIONS.tags) { - var nextSibling = Element.next(element); - var fragments = getContentFromAnonymousElement( - tagName, content.stripScripts()); - - parent.removeChild(element); - - var iterator; - if (nextSibling) - iterator = function(node) { parent.insertBefore(node, nextSibling) }; - else - iterator = function(node) { parent.appendChild(node); } - - fragments.each(iterator); - } else { - element.outerHTML = content.stripScripts(); - } - - content.evalScripts.bind(content).defer(); - return element; - } - - if ('outerHTML' in document.documentElement) - replace = replace_IE; - - function isContent(content) { - if (Object.isUndefined(content) || content === null) return false; - - if (Object.isString(content) || Object.isNumber(content)) return true; - if (Object.isElement(content)) return true; - if (content.toElement || content.toHTML) return true; - - return false; - } - - function insertContentAt(element, content, position) { - position = position.toLowerCase(); - var method = INSERTION_TRANSLATIONS[position]; - - if (content && content.toElement) content = content.toElement(); - if (Object.isElement(content)) { - method(element, content); - return element; - } - - content = Object.toHTML(content); - var tagName = ((position === 'before' || position === 'after') ? - element.parentNode : element).tagName.toUpperCase(); - - var childNodes = getContentFromAnonymousElement(tagName, content.stripScripts()); - - if (position === 'top' || position === 'after') childNodes.reverse(); - - for (var i = 0, node; node = childNodes[i]; i++) - method(element, node); - - content.evalScripts.bind(content).defer(); - } - - function insert(element, insertions) { - element = $(element); - - if (isContent(insertions)) - insertions = { bottom: insertions }; - - for (var position in insertions) - insertContentAt(element, insertions[position], position); - - return element; - } - - function wrap(element, wrapper, attributes) { - element = $(element); - - if (Object.isElement(wrapper)) { - $(wrapper).writeAttribute(attributes || {}); - } else if (Object.isString(wrapper)) { - wrapper = new Element(wrapper, attributes); - } else { - wrapper = new Element('div', wrapper); - } - - if (element.parentNode) - element.parentNode.replaceChild(wrapper, element); - - wrapper.appendChild(element); - - return wrapper; - } - - function cleanWhitespace(element) { - element = $(element); - var node = element.firstChild; - - while (node) { - var nextNode = node.nextSibling; - if (node.nodeType === Node.TEXT_NODE && !/\S/.test(node.nodeValue)) - element.removeChild(node); - node = nextNode; - } - return element; - } - - function empty(element) { - return $(element).innerHTML.blank(); - } - - function getContentFromAnonymousElement(tagName, html, force) { - var t = INSERTION_TRANSLATIONS.tags[tagName], div = DIV; - - var workaround = !!t; - if (!workaround && force) { - workaround = true; - t = ['', '', 0]; - } - - if (workaround) { - div.innerHTML = ' ' + t[0] + html + t[1]; - div.removeChild(div.firstChild); - for (var i = t[2]; i--; ) - div = div.firstChild; - } else { - div.innerHTML = html; - } - - return $A(div.childNodes); - } - - function clone(element, deep) { - if (!(element = $(element))) return; - var clone = element.cloneNode(deep); - if (!HAS_UNIQUE_ID_PROPERTY) { - clone._prototypeUID = UNDEFINED; - if (deep) { - var descendants = Element.select(clone, '*'), - i = descendants.length; - while (i--) - descendants[i]._prototypeUID = UNDEFINED; - } - } - return Element.extend(clone); - } - - function purgeElement(element) { - var uid = getUniqueElementID(element); - if (uid) { - Element.stopObserving(element); - if (!HAS_UNIQUE_ID_PROPERTY) - element._prototypeUID = UNDEFINED; - delete Element.Storage[uid]; - } - } - - function purgeCollection(elements) { - var i = elements.length; - while (i--) - purgeElement(elements[i]); - } - - function purgeCollection_IE(elements) { - var i = elements.length, element, uid; - while (i--) { - element = elements[i]; - uid = getUniqueElementID(element); - delete Element.Storage[uid]; - delete Event.cache[uid]; - } - } - - if (HAS_UNIQUE_ID_PROPERTY) { - purgeCollection = purgeCollection_IE; - } - - - function purge(element) { - if (!(element = $(element))) return; - purgeElement(element); - - var descendants = element.getElementsByTagName('*'), - i = descendants.length; - - while (i--) purgeElement(descendants[i]); - - return null; - } - - Object.extend(methods, { - remove: remove, - update: update, - replace: replace, - insert: insert, - wrap: wrap, - cleanWhitespace: cleanWhitespace, - empty: empty, - clone: clone, - purge: purge - }); - - - - function recursivelyCollect(element, property, maximumLength) { - element = $(element); - maximumLength = maximumLength || -1; - var elements = []; - - while (element = element[property]) { - if (element.nodeType === Node.ELEMENT_NODE) - elements.push(Element.extend(element)); - - if (elements.length === maximumLength) break; - } - - return elements; - } - - - function ancestors(element) { - return recursivelyCollect(element, 'parentNode'); - } - - function descendants(element) { - return Element.select(element, '*'); - } - - function firstDescendant(element) { - element = $(element).firstChild; - while (element && element.nodeType !== Node.ELEMENT_NODE) - element = element.nextSibling; - - return $(element); - } - - function immediateDescendants(element) { - var results = [], child = $(element).firstChild; - - while (child) { - if (child.nodeType === Node.ELEMENT_NODE) - results.push(Element.extend(child)); - - child = child.nextSibling; - } - - return results; - } - - function previousSiblings(element) { - return recursivelyCollect(element, 'previousSibling'); - } - - function nextSiblings(element) { - return recursivelyCollect(element, 'nextSibling'); - } - - function siblings(element) { - element = $(element); - var previous = previousSiblings(element), - next = nextSiblings(element); - return previous.reverse().concat(next); - } - - function match(element, selector) { - element = $(element); - - if (Object.isString(selector)) - return Prototype.Selector.match(element, selector); - - return selector.match(element); - } - - - function _recursivelyFind(element, property, expression, index) { - element = $(element), expression = expression || 0, index = index || 0; - if (Object.isNumber(expression)) { - index = expression, expression = null; - } - - while (element = element[property]) { - if (element.nodeType !== 1) continue; - if (expression && !Prototype.Selector.match(element, expression)) - continue; - if (--index >= 0) continue; - - return Element.extend(element); - } - } - - - function up(element, expression, index) { - element = $(element); - - if (arguments.length === 1) return $(element.parentNode); - return _recursivelyFind(element, 'parentNode', expression, index); - } - - function down(element, expression, index) { - if (arguments.length === 1) return firstDescendant(element); - element = $(element), expression = expression || 0, index = index || 0; - - if (Object.isNumber(expression)) - index = expression, expression = '*'; - - var node = Prototype.Selector.select(expression, element)[index]; - return Element.extend(node); - } - - function previous(element, expression, index) { - return _recursivelyFind(element, 'previousSibling', expression, index); - } - - function next(element, expression, index) { - return _recursivelyFind(element, 'nextSibling', expression, index); - } - - function select(element) { - element = $(element); - var expressions = SLICE.call(arguments, 1).join(', '); - return Prototype.Selector.select(expressions, element); - } - - function adjacent(element) { - element = $(element); - var expressions = SLICE.call(arguments, 1).join(', '); - var siblings = Element.siblings(element), results = []; - for (var i = 0, sibling; sibling = siblings[i]; i++) { - if (Prototype.Selector.match(sibling, expressions)) - results.push(sibling); - } - - return results; - } - - function descendantOf_DOM(element, ancestor) { - element = $(element), ancestor = $(ancestor); - if (!element || !ancestor) return false; - while (element = element.parentNode) - if (element === ancestor) return true; - return false; - } - - function descendantOf_contains(element, ancestor) { - element = $(element), ancestor = $(ancestor); - if (!element || !ancestor) return false; - if (!ancestor.contains) return descendantOf_DOM(element, ancestor); - return ancestor.contains(element) && ancestor !== element; - } - - function descendantOf_compareDocumentPosition(element, ancestor) { - element = $(element), ancestor = $(ancestor); - if (!element || !ancestor) return false; - return (element.compareDocumentPosition(ancestor) & 8) === 8; - } - - var descendantOf; - if (DIV.compareDocumentPosition) { - descendantOf = descendantOf_compareDocumentPosition; - } else if (DIV.contains) { - descendantOf = descendantOf_contains; - } else { - descendantOf = descendantOf_DOM; - } - - - Object.extend(methods, { - recursivelyCollect: recursivelyCollect, - ancestors: ancestors, - descendants: descendants, - firstDescendant: firstDescendant, - immediateDescendants: immediateDescendants, - previousSiblings: previousSiblings, - nextSiblings: nextSiblings, - siblings: siblings, - match: match, - up: up, - down: down, - previous: previous, - next: next, - select: select, - adjacent: adjacent, - descendantOf: descendantOf, - - getElementsBySelector: select, - - childElements: immediateDescendants - }); - - - var idCounter = 1; - function identify(element) { - element = $(element); - var id = Element.readAttribute(element, 'id'); - if (id) return id; - - do { id = 'anonymous_element_' + idCounter++ } while ($(id)); - - Element.writeAttribute(element, 'id', id); - return id; - } - - - function readAttribute(element, name) { - return $(element).getAttribute(name); - } - - function readAttribute_IE(element, name) { - element = $(element); - - var table = ATTRIBUTE_TRANSLATIONS.read; - if (table.values[name]) - return table.values[name](element, name); - - if (table.names[name]) name = table.names[name]; - - if (name.include(':')) { - if (!element.attributes || !element.attributes[name]) return null; - return element.attributes[name].value; - } - - return element.getAttribute(name); - } - - function readAttribute_Opera(element, name) { - if (name === 'title') return element.title; - return element.getAttribute(name); - } - - var PROBLEMATIC_ATTRIBUTE_READING = (function() { - DIV.setAttribute('onclick', []); - var value = DIV.getAttribute('onclick'); - var isFunction = Object.isArray(value); - DIV.removeAttribute('onclick'); - return isFunction; - })(); - - if (PROBLEMATIC_ATTRIBUTE_READING) { - readAttribute = readAttribute_IE; - } else if (Prototype.Browser.Opera) { - readAttribute = readAttribute_Opera; - } - - - function writeAttribute(element, name, value) { - element = $(element); - var attributes = {}, table = ATTRIBUTE_TRANSLATIONS.write; - - if (typeof name === 'object') { - attributes = name; - } else { - attributes[name] = Object.isUndefined(value) ? true : value; - } - - for (var attr in attributes) { - name = table.names[attr] || attr; - value = attributes[attr]; - if (table.values[attr]) { - value = table.values[attr](element, value); - if (Object.isUndefined(value)) continue; - } - if (value === false || value === null) - element.removeAttribute(name); - else if (value === true) - element.setAttribute(name, name); - else element.setAttribute(name, value); - } - - return element; - } - - var PROBLEMATIC_HAS_ATTRIBUTE_WITH_CHECKBOXES = (function () { - if (!HAS_EXTENDED_CREATE_ELEMENT_SYNTAX) { - return false; - } - var checkbox = document.createElement(''); - checkbox.checked = true; - var node = checkbox.getAttributeNode('checked'); - return !node || !node.specified; - })(); - - function hasAttribute(element, attribute) { - attribute = ATTRIBUTE_TRANSLATIONS.has[attribute] || attribute; - var node = $(element).getAttributeNode(attribute); - return !!(node && node.specified); - } - - function hasAttribute_IE(element, attribute) { - if (attribute === 'checked') { - return element.checked; - } - return hasAttribute(element, attribute); - } - - GLOBAL.Element.Methods.Simulated.hasAttribute = - PROBLEMATIC_HAS_ATTRIBUTE_WITH_CHECKBOXES ? - hasAttribute_IE : hasAttribute; - - function classNames(element) { - return new Element.ClassNames(element); - } - - var regExpCache = {}; - function getRegExpForClassName(className) { - if (regExpCache[className]) return regExpCache[className]; - - var re = new RegExp("(^|\\s+)" + className + "(\\s+|$)"); - regExpCache[className] = re; - return re; - } - - function hasClassName(element, className) { - if (!(element = $(element))) return; - - var elementClassName = element.className; - - if (elementClassName.length === 0) return false; - if (elementClassName === className) return true; - - return getRegExpForClassName(className).test(elementClassName); - } - - function addClassName(element, className) { - if (!(element = $(element))) return; - - if (!hasClassName(element, className)) - element.className += (element.className ? ' ' : '') + className; - - return element; - } - - function removeClassName(element, className) { - if (!(element = $(element))) return; - - element.className = element.className.replace( - getRegExpForClassName(className), ' ').strip(); - - return element; - } - - function toggleClassName(element, className, bool) { - if (!(element = $(element))) return; - - if (Object.isUndefined(bool)) - bool = !hasClassName(element, className); - - var method = Element[bool ? 'addClassName' : 'removeClassName']; - return method(element, className); - } - - var ATTRIBUTE_TRANSLATIONS = {}; - - var classProp = 'className', forProp = 'for'; - - DIV.setAttribute(classProp, 'x'); - if (DIV.className !== 'x') { - DIV.setAttribute('class', 'x'); - if (DIV.className === 'x') - classProp = 'class'; - } - - var LABEL = document.createElement('label'); - LABEL.setAttribute(forProp, 'x'); - if (LABEL.htmlFor !== 'x') { - LABEL.setAttribute('htmlFor', 'x'); - if (LABEL.htmlFor === 'x') - forProp = 'htmlFor'; - } - LABEL = null; - - function _getAttr(element, attribute) { - return element.getAttribute(attribute); - } - - function _getAttr2(element, attribute) { - return element.getAttribute(attribute, 2); - } - - function _getAttrNode(element, attribute) { - var node = element.getAttributeNode(attribute); - return node ? node.value : ''; - } - - function _getFlag(element, attribute) { - return $(element).hasAttribute(attribute) ? attribute : null; - } - - DIV.onclick = Prototype.emptyFunction; - var onclickValue = DIV.getAttribute('onclick'); - - var _getEv; - - if (String(onclickValue).indexOf('{') > -1) { - _getEv = function(element, attribute) { - var value = element.getAttribute(attribute); - if (!value) return null; - value = value.toString(); - value = value.split('{')[1]; - value = value.split('}')[0]; - return value.strip(); - }; - } - else if (onclickValue === '') { - _getEv = function(element, attribute) { - var value = element.getAttribute(attribute); - if (!value) return null; - return value.strip(); - }; - } - - ATTRIBUTE_TRANSLATIONS.read = { - names: { - 'class': classProp, - 'className': classProp, - 'for': forProp, - 'htmlFor': forProp - }, - - values: { - style: function(element) { - return element.style.cssText.toLowerCase(); - }, - title: function(element) { - return element.title; - } - } - }; - - ATTRIBUTE_TRANSLATIONS.write = { - names: { - className: 'class', - htmlFor: 'for', - cellpadding: 'cellPadding', - cellspacing: 'cellSpacing' - }, - - values: { - checked: function(element, value) { - value = !!value; - element.checked = value; - return value ? 'checked' : null; - }, - - style: function(element, value) { - element.style.cssText = value ? value : ''; - } - } - }; - - ATTRIBUTE_TRANSLATIONS.has = { names: {} }; - - Object.extend(ATTRIBUTE_TRANSLATIONS.write.names, - ATTRIBUTE_TRANSLATIONS.read.names); - - var CAMEL_CASED_ATTRIBUTE_NAMES = $w('colSpan rowSpan vAlign dateTime ' + - 'accessKey tabIndex encType maxLength readOnly longDesc frameBorder'); - - for (var i = 0, attr; attr = CAMEL_CASED_ATTRIBUTE_NAMES[i]; i++) { - ATTRIBUTE_TRANSLATIONS.write.names[attr.toLowerCase()] = attr; - ATTRIBUTE_TRANSLATIONS.has.names[attr.toLowerCase()] = attr; - } - - Object.extend(ATTRIBUTE_TRANSLATIONS.read.values, { - href: _getAttr2, - src: _getAttr2, - type: _getAttr, - action: _getAttrNode, - disabled: _getFlag, - checked: _getFlag, - readonly: _getFlag, - multiple: _getFlag, - onload: _getEv, - onunload: _getEv, - onclick: _getEv, - ondblclick: _getEv, - onmousedown: _getEv, - onmouseup: _getEv, - onmouseover: _getEv, - onmousemove: _getEv, - onmouseout: _getEv, - onfocus: _getEv, - onblur: _getEv, - onkeypress: _getEv, - onkeydown: _getEv, - onkeyup: _getEv, - onsubmit: _getEv, - onreset: _getEv, - onselect: _getEv, - onchange: _getEv - }); - - - Object.extend(methods, { - identify: identify, - readAttribute: readAttribute, - writeAttribute: writeAttribute, - classNames: classNames, - hasClassName: hasClassName, - addClassName: addClassName, - removeClassName: removeClassName, - toggleClassName: toggleClassName - }); - - - function normalizeStyleName(style) { - if (style === 'float' || style === 'styleFloat') - return 'cssFloat'; - return style.camelize(); - } - - function normalizeStyleName_IE(style) { - if (style === 'float' || style === 'cssFloat') - return 'styleFloat'; - return style.camelize(); - } - - function setStyle(element, styles) { - element = $(element); - var elementStyle = element.style, match; - - if (Object.isString(styles)) { - elementStyle.cssText += ';' + styles; - if (styles.include('opacity')) { - var opacity = styles.match(/opacity:\s*(\d?\.?\d*)/)[1]; - Element.setOpacity(element, opacity); - } - return element; - } - - for (var property in styles) { - if (property === 'opacity') { - Element.setOpacity(element, styles[property]); - } else { - var value = styles[property]; - if (property === 'float' || property === 'cssFloat') { - property = Object.isUndefined(elementStyle.styleFloat) ? - 'cssFloat' : 'styleFloat'; - } - elementStyle[property] = value; - } - } - - return element; - } - - - function getStyle(element, style) { - element = $(element); - style = normalizeStyleName(style); - - var value = element.style[style]; - if (!value || value === 'auto') { - var css = document.defaultView.getComputedStyle(element, null); - value = css ? css[style] : null; - } - - if (style === 'opacity') return value ? parseFloat(value) : 1.0; - return value === 'auto' ? null : value; - } - - function getStyle_Opera(element, style) { - switch (style) { - case 'height': case 'width': - if (!Element.visible(element)) return null; - - var dim = parseInt(getStyle(element, style), 10); - - if (dim !== element['offset' + style.capitalize()]) - return dim + 'px'; - - return Element.measure(element, style); - - default: return getStyle(element, style); - } - } - - function getStyle_IE(element, style) { - element = $(element); - style = normalizeStyleName_IE(style); - - var value = element.style[style]; - if (!value && element.currentStyle) { - value = element.currentStyle[style]; - } - - if (style === 'opacity') { - if (!STANDARD_CSS_OPACITY_SUPPORTED) - return getOpacity_IE(element); - else return value ? parseFloat(value) : 1.0; - } - - if (value === 'auto') { - if ((style === 'width' || style === 'height') && Element.visible(element)) - return Element.measure(element, style) + 'px'; - return null; - } - - return value; - } - - function stripAlphaFromFilter_IE(filter) { - return (filter || '').replace(/alpha\([^\)]*\)/gi, ''); - } - - function hasLayout_IE(element) { - if (!element.currentStyle || !element.currentStyle.hasLayout) - element.style.zoom = 1; - return element; - } - - var STANDARD_CSS_OPACITY_SUPPORTED = (function() { - DIV.style.cssText = "opacity:.55"; - return /^0.55/.test(DIV.style.opacity); - })(); - - function setOpacity(element, value) { - element = $(element); - if (value == 1 || value === '') value = ''; - else if (value < 0.00001) value = 0; - element.style.opacity = value; - return element; - } - - function setOpacity_IE(element, value) { - if (STANDARD_CSS_OPACITY_SUPPORTED) - return setOpacity(element, value); - - element = hasLayout_IE($(element)); - var filter = Element.getStyle(element, 'filter'), - style = element.style; - - if (value == 1 || value === '') { - filter = stripAlphaFromFilter_IE(filter); - if (filter) style.filter = filter; - else style.removeAttribute('filter'); - return element; - } - - if (value < 0.00001) value = 0; - - style.filter = stripAlphaFromFilter_IE(filter) + - ' alpha(opacity=' + (value * 100) + ')'; - - return element; - } - - - function getOpacity(element) { - return Element.getStyle(element, 'opacity'); - } - - function getOpacity_IE(element) { - if (STANDARD_CSS_OPACITY_SUPPORTED) - return getOpacity(element); - - var filter = Element.getStyle(element, 'filter'); - if (filter.length === 0) return 1.0; - var match = (filter || '').match(/alpha\(opacity=(.*)\)/i); - if (match && match[1]) return parseFloat(match[1]) / 100; - return 1.0; - } - - - Object.extend(methods, { - setStyle: setStyle, - getStyle: getStyle, - setOpacity: setOpacity, - getOpacity: getOpacity - }); - - if ('styleFloat' in DIV.style) { - methods.getStyle = getStyle_IE; - methods.setOpacity = setOpacity_IE; - methods.getOpacity = getOpacity_IE; - } - - var UID = 0; - - GLOBAL.Element.Storage = { UID: 1 }; - - function getUniqueElementID(element) { - if (element === window) return 0; - - if (typeof element._prototypeUID === 'undefined') - element._prototypeUID = Element.Storage.UID++; - return element._prototypeUID; - } - - function getUniqueElementID_IE(element) { - if (element === window) return 0; - if (element == document) return 1; - return element.uniqueID; - } - - var HAS_UNIQUE_ID_PROPERTY = ('uniqueID' in DIV); - if (HAS_UNIQUE_ID_PROPERTY) - getUniqueElementID = getUniqueElementID_IE; - - function getStorage(element) { - if (!(element = $(element))) return; - - var uid = getUniqueElementID(element); - - if (!Element.Storage[uid]) - Element.Storage[uid] = $H(); - - return Element.Storage[uid]; - } - - function store(element, key, value) { - if (!(element = $(element))) return; - var storage = getStorage(element); - if (arguments.length === 2) { - storage.update(key); - } else { - storage.set(key, value); - } - return element; - } - - function retrieve(element, key, defaultValue) { - if (!(element = $(element))) return; - var storage = getStorage(element), value = storage.get(key); - - if (Object.isUndefined(value)) { - storage.set(key, defaultValue); - value = defaultValue; - } - - return value; - } - - - Object.extend(methods, { - getStorage: getStorage, - store: store, - retrieve: retrieve - }); - - - var Methods = {}, ByTag = Element.Methods.ByTag, - F = Prototype.BrowserFeatures; - - if (!F.ElementExtensions && ('__proto__' in DIV)) { - GLOBAL.HTMLElement = {}; - GLOBAL.HTMLElement.prototype = DIV['__proto__']; - F.ElementExtensions = true; - } - - function checkElementPrototypeDeficiency(tagName) { - if (typeof window.Element === 'undefined') return false; - if (!HAS_EXTENDED_CREATE_ELEMENT_SYNTAX) return false; - var proto = window.Element.prototype; - if (proto) { - var id = '_' + (Math.random() + '').slice(2), - el = document.createElement(tagName); - proto[id] = 'x'; - var isBuggy = (el[id] !== 'x'); - delete proto[id]; - el = null; - return isBuggy; - } - - return false; - } - - var HTMLOBJECTELEMENT_PROTOTYPE_BUGGY = - checkElementPrototypeDeficiency('object'); - - function extendElementWith(element, methods) { - for (var property in methods) { - var value = methods[property]; - if (Object.isFunction(value) && !(property in element)) - element[property] = value.methodize(); - } - } - - var EXTENDED = {}; - function elementIsExtended(element) { - var uid = getUniqueElementID(element); - return (uid in EXTENDED); - } - - function extend(element) { - if (!element || elementIsExtended(element)) return element; - if (element.nodeType !== Node.ELEMENT_NODE || element == window) - return element; - - var methods = Object.clone(Methods), - tagName = element.tagName.toUpperCase(); - - if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]); - - extendElementWith(element, methods); - EXTENDED[getUniqueElementID(element)] = true; - return element; - } - - function extend_IE8(element) { - if (!element || elementIsExtended(element)) return element; - - var t = element.tagName; - if (t && (/^(?:object|applet|embed)$/i.test(t))) { - extendElementWith(element, Element.Methods); - extendElementWith(element, Element.Methods.Simulated); - extendElementWith(element, Element.Methods.ByTag[t.toUpperCase()]); - } - - return element; - } - - if (F.SpecificElementExtensions) { - extend = HTMLOBJECTELEMENT_PROTOTYPE_BUGGY ? extend_IE8 : Prototype.K; - } - - function addMethodsToTagName(tagName, methods) { - tagName = tagName.toUpperCase(); - if (!ByTag[tagName]) ByTag[tagName] = {}; - Object.extend(ByTag[tagName], methods); - } - - function mergeMethods(destination, methods, onlyIfAbsent) { - if (Object.isUndefined(onlyIfAbsent)) onlyIfAbsent = false; - for (var property in methods) { - var value = methods[property]; - if (!Object.isFunction(value)) continue; - if (!onlyIfAbsent || !(property in destination)) - destination[property] = value.methodize(); - } - } - - function findDOMClass(tagName) { - var klass; - var trans = { - "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph", - "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList", - "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading", - "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote", - "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION": - "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD": - "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR": - "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET": - "FrameSet", "IFRAME": "IFrame" - }; - if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element'; - if (window[klass]) return window[klass]; - klass = 'HTML' + tagName + 'Element'; - if (window[klass]) return window[klass]; - klass = 'HTML' + tagName.capitalize() + 'Element'; - if (window[klass]) return window[klass]; - - var element = document.createElement(tagName), - proto = element['__proto__'] || element.constructor.prototype; - - element = null; - return proto; - } - - function addMethods(methods) { - if (arguments.length === 0) addFormMethods(); - - if (arguments.length === 2) { - var tagName = methods; - methods = arguments[1]; - } - - if (!tagName) { - Object.extend(Element.Methods, methods || {}); - } else { - if (Object.isArray(tagName)) { - for (var i = 0, tag; tag = tagName[i]; i++) - addMethodsToTagName(tag, methods); - } else { - addMethodsToTagName(tagName, methods); - } - } - - var ELEMENT_PROTOTYPE = window.HTMLElement ? HTMLElement.prototype : - Element.prototype; - - if (F.ElementExtensions) { - mergeMethods(ELEMENT_PROTOTYPE, Element.Methods); - mergeMethods(ELEMENT_PROTOTYPE, Element.Methods.Simulated, true); - } - - if (F.SpecificElementExtensions) { - for (var tag in Element.Methods.ByTag) { - var klass = findDOMClass(tag); - if (Object.isUndefined(klass)) continue; - mergeMethods(klass.prototype, ByTag[tag]); - } - } - - Object.extend(Element, Element.Methods); - Object.extend(Element, Element.Methods.Simulated); - delete Element.ByTag; - delete Element.Simulated; - - Element.extend.refresh(); - - ELEMENT_CACHE = {}; - } - - Object.extend(GLOBAL.Element, { - extend: extend, - addMethods: addMethods - }); - - if (extend === Prototype.K) { - GLOBAL.Element.extend.refresh = Prototype.emptyFunction; - } else { - GLOBAL.Element.extend.refresh = function() { - if (Prototype.BrowserFeatures.ElementExtensions) return; - Object.extend(Methods, Element.Methods); - Object.extend(Methods, Element.Methods.Simulated); - - EXTENDED = {}; - }; - } - - function addFormMethods() { - Object.extend(Form, Form.Methods); - Object.extend(Form.Element, Form.Element.Methods); - Object.extend(Element.Methods.ByTag, { - "FORM": Object.clone(Form.Methods), - "INPUT": Object.clone(Form.Element.Methods), - "SELECT": Object.clone(Form.Element.Methods), - "TEXTAREA": Object.clone(Form.Element.Methods), - "BUTTON": Object.clone(Form.Element.Methods) - }); - } - - Element.addMethods(methods); - - function destroyCache_IE() { - DIV = null; - ELEMENT_CACHE = null; - } - - if (window.attachEvent) - window.attachEvent('onunload', destroyCache_IE); - -})(this); -(function() { - - function toDecimal(pctString) { - var match = pctString.match(/^(\d+)%?$/i); - if (!match) return null; - return (Number(match[1]) / 100); - } - - function getRawStyle(element, style) { - element = $(element); - - var value = element.style[style]; - if (!value || value === 'auto') { - var css = document.defaultView.getComputedStyle(element, null); - value = css ? css[style] : null; - } - - if (style === 'opacity') return value ? parseFloat(value) : 1.0; - return value === 'auto' ? null : value; - } - - function getRawStyle_IE(element, style) { - var value = element.style[style]; - if (!value && element.currentStyle) { - value = element.currentStyle[style]; - } - return value; - } - - function getContentWidth(element, context) { - var boxWidth = element.offsetWidth; - - var bl = getPixelValue(element, 'borderLeftWidth', context) || 0; - var br = getPixelValue(element, 'borderRightWidth', context) || 0; - var pl = getPixelValue(element, 'paddingLeft', context) || 0; - var pr = getPixelValue(element, 'paddingRight', context) || 0; - - return boxWidth - bl - br - pl - pr; - } - - if (!Object.isUndefined(document.documentElement.currentStyle) && !Prototype.Browser.Opera) { - getRawStyle = getRawStyle_IE; - } - - - function getPixelValue(value, property, context) { - var element = null; - if (Object.isElement(value)) { - element = value; - value = getRawStyle(element, property); - } - - if (value === null || Object.isUndefined(value)) { - return null; - } - - if ((/^(?:-)?\d+(\.\d+)?(px)?$/i).test(value)) { - return window.parseFloat(value); - } - - var isPercentage = value.include('%'), isViewport = (context === document.viewport); - - if (/\d/.test(value) && element && element.runtimeStyle && !(isPercentage && isViewport)) { - var style = element.style.left, rStyle = element.runtimeStyle.left; - element.runtimeStyle.left = element.currentStyle.left; - element.style.left = value || 0; - value = element.style.pixelLeft; - element.style.left = style; - element.runtimeStyle.left = rStyle; - - return value; - } - - if (element && isPercentage) { - context = context || element.parentNode; - var decimal = toDecimal(value), whole = null; - - var isHorizontal = property.include('left') || property.include('right') || - property.include('width'); - - var isVertical = property.include('top') || property.include('bottom') || - property.include('height'); - - if (context === document.viewport) { - if (isHorizontal) { - whole = document.viewport.getWidth(); - } else if (isVertical) { - whole = document.viewport.getHeight(); - } - } else { - if (isHorizontal) { - whole = $(context).measure('width'); - } else if (isVertical) { - whole = $(context).measure('height'); - } - } - - return (whole === null) ? 0 : whole * decimal; - } - - return 0; - } - - function toCSSPixels(number) { - if (Object.isString(number) && number.endsWith('px')) - return number; - return number + 'px'; - } - - function isDisplayed(element) { - while (element && element.parentNode) { - var display = element.getStyle('display'); - if (display === 'none') { - return false; - } - element = $(element.parentNode); - } - return true; - } - - var hasLayout = Prototype.K; - if ('currentStyle' in document.documentElement) { - hasLayout = function(element) { - if (!element.currentStyle.hasLayout) { - element.style.zoom = 1; - } - return element; - }; - } - - function cssNameFor(key) { - if (key.include('border')) key = key + '-width'; - return key.camelize(); - } - - Element.Layout = Class.create(Hash, { - initialize: function($super, element, preCompute) { - $super(); - this.element = $(element); - - Element.Layout.PROPERTIES.each( function(property) { - this._set(property, null); - }, this); - - if (preCompute) { - this._preComputing = true; - this._begin(); - Element.Layout.PROPERTIES.each( this._compute, this ); - this._end(); - this._preComputing = false; - } - }, - - _set: function(property, value) { - return Hash.prototype.set.call(this, property, value); - }, - - set: function(property, value) { - throw "Properties of Element.Layout are read-only."; - }, - - get: function($super, property) { - var value = $super(property); - return value === null ? this._compute(property) : value; - }, - - _begin: function() { - if (this._isPrepared()) return; - - var element = this.element; - if (isDisplayed(element)) { - this._setPrepared(true); - return; - } - - - var originalStyles = { - position: element.style.position || '', - width: element.style.width || '', - visibility: element.style.visibility || '', - display: element.style.display || '' - }; - - element.store('prototype_original_styles', originalStyles); - - var position = getRawStyle(element, 'position'), width = element.offsetWidth; - - if (width === 0 || width === null) { - element.style.display = 'block'; - width = element.offsetWidth; - } - - var context = (position === 'fixed') ? document.viewport : - element.parentNode; - - var tempStyles = { - visibility: 'hidden', - display: 'block' - }; - - if (position !== 'fixed') tempStyles.position = 'absolute'; - - element.setStyle(tempStyles); - - var positionedWidth = element.offsetWidth, newWidth; - if (width && (positionedWidth === width)) { - newWidth = getContentWidth(element, context); - } else if (position === 'absolute' || position === 'fixed') { - newWidth = getContentWidth(element, context); - } else { - var parent = element.parentNode, pLayout = $(parent).getLayout(); - - newWidth = pLayout.get('width') - - this.get('margin-left') - - this.get('border-left') - - this.get('padding-left') - - this.get('padding-right') - - this.get('border-right') - - this.get('margin-right'); - } - - element.setStyle({ width: newWidth + 'px' }); - - this._setPrepared(true); - }, - - _end: function() { - var element = this.element; - var originalStyles = element.retrieve('prototype_original_styles'); - element.store('prototype_original_styles', null); - element.setStyle(originalStyles); - this._setPrepared(false); - }, - - _compute: function(property) { - var COMPUTATIONS = Element.Layout.COMPUTATIONS; - if (!(property in COMPUTATIONS)) { - throw "Property not found."; - } - - return this._set(property, COMPUTATIONS[property].call(this, this.element)); - }, - - _isPrepared: function() { - return this.element.retrieve('prototype_element_layout_prepared', false); - }, - - _setPrepared: function(bool) { - return this.element.store('prototype_element_layout_prepared', bool); - }, - - toObject: function() { - var args = $A(arguments); - var keys = (args.length === 0) ? Element.Layout.PROPERTIES : - args.join(' ').split(' '); - var obj = {}; - keys.each( function(key) { - if (!Element.Layout.PROPERTIES.include(key)) return; - var value = this.get(key); - if (value != null) obj[key] = value; - }, this); - return obj; - }, - - toHash: function() { - var obj = this.toObject.apply(this, arguments); - return new Hash(obj); - }, - - toCSS: function() { - var args = $A(arguments); - var keys = (args.length === 0) ? Element.Layout.PROPERTIES : - args.join(' ').split(' '); - var css = {}; - - keys.each( function(key) { - if (!Element.Layout.PROPERTIES.include(key)) return; - if (Element.Layout.COMPOSITE_PROPERTIES.include(key)) return; - - var value = this.get(key); - if (value != null) css[cssNameFor(key)] = value + 'px'; - }, this); - return css; - }, - - inspect: function() { - return "#"; - } - }); - - Object.extend(Element.Layout, { - PROPERTIES: $w('height width top left right bottom border-left border-right border-top border-bottom padding-left padding-right padding-top padding-bottom margin-top margin-bottom margin-left margin-right padding-box-width padding-box-height border-box-width border-box-height margin-box-width margin-box-height'), - - COMPOSITE_PROPERTIES: $w('padding-box-width padding-box-height margin-box-width margin-box-height border-box-width border-box-height'), - - COMPUTATIONS: { - 'height': function(element) { - if (!this._preComputing) this._begin(); - - var bHeight = this.get('border-box-height'); - if (bHeight <= 0) { - if (!this._preComputing) this._end(); - return 0; - } - - var bTop = this.get('border-top'), - bBottom = this.get('border-bottom'); - - var pTop = this.get('padding-top'), - pBottom = this.get('padding-bottom'); - - if (!this._preComputing) this._end(); - - return bHeight - bTop - bBottom - pTop - pBottom; - }, - - 'width': function(element) { - if (!this._preComputing) this._begin(); - - var bWidth = this.get('border-box-width'); - if (bWidth <= 0) { - if (!this._preComputing) this._end(); - return 0; - } - - var bLeft = this.get('border-left'), - bRight = this.get('border-right'); - - var pLeft = this.get('padding-left'), - pRight = this.get('padding-right'); - - if (!this._preComputing) this._end(); - return bWidth - bLeft - bRight - pLeft - pRight; - }, - - 'padding-box-height': function(element) { - var height = this.get('height'), - pTop = this.get('padding-top'), - pBottom = this.get('padding-bottom'); - - return height + pTop + pBottom; - }, - - 'padding-box-width': function(element) { - var width = this.get('width'), - pLeft = this.get('padding-left'), - pRight = this.get('padding-right'); - - return width + pLeft + pRight; - }, - - 'border-box-height': function(element) { - if (!this._preComputing) this._begin(); - var height = element.offsetHeight; - if (!this._preComputing) this._end(); - return height; - }, - - 'border-box-width': function(element) { - if (!this._preComputing) this._begin(); - var width = element.offsetWidth; - if (!this._preComputing) this._end(); - return width; - }, - - 'margin-box-height': function(element) { - var bHeight = this.get('border-box-height'), - mTop = this.get('margin-top'), - mBottom = this.get('margin-bottom'); - - if (bHeight <= 0) return 0; - - return bHeight + mTop + mBottom; - }, - - 'margin-box-width': function(element) { - var bWidth = this.get('border-box-width'), - mLeft = this.get('margin-left'), - mRight = this.get('margin-right'); - - if (bWidth <= 0) return 0; - - return bWidth + mLeft + mRight; - }, - - 'top': function(element) { - var offset = element.positionedOffset(); - return offset.top; - }, - - 'bottom': function(element) { - var offset = element.positionedOffset(), - parent = element.getOffsetParent(), - pHeight = parent.measure('height'); - - var mHeight = this.get('border-box-height'); - - return pHeight - mHeight - offset.top; - }, - - 'left': function(element) { - var offset = element.positionedOffset(); - return offset.left; - }, - - 'right': function(element) { - var offset = element.positionedOffset(), - parent = element.getOffsetParent(), - pWidth = parent.measure('width'); - - var mWidth = this.get('border-box-width'); - - return pWidth - mWidth - offset.left; - }, - - 'padding-top': function(element) { - return getPixelValue(element, 'paddingTop'); - }, - - 'padding-bottom': function(element) { - return getPixelValue(element, 'paddingBottom'); - }, - - 'padding-left': function(element) { - return getPixelValue(element, 'paddingLeft'); - }, - - 'padding-right': function(element) { - return getPixelValue(element, 'paddingRight'); - }, - - 'border-top': function(element) { - return getPixelValue(element, 'borderTopWidth'); - }, - - 'border-bottom': function(element) { - return getPixelValue(element, 'borderBottomWidth'); - }, - - 'border-left': function(element) { - return getPixelValue(element, 'borderLeftWidth'); - }, - - 'border-right': function(element) { - return getPixelValue(element, 'borderRightWidth'); - }, - - 'margin-top': function(element) { - return getPixelValue(element, 'marginTop'); - }, - - 'margin-bottom': function(element) { - return getPixelValue(element, 'marginBottom'); - }, - - 'margin-left': function(element) { - return getPixelValue(element, 'marginLeft'); - }, - - 'margin-right': function(element) { - return getPixelValue(element, 'marginRight'); - } - } - }); - - if ('getBoundingClientRect' in document.documentElement) { - Object.extend(Element.Layout.COMPUTATIONS, { - 'right': function(element) { - var parent = hasLayout(element.getOffsetParent()); - var rect = element.getBoundingClientRect(), - pRect = parent.getBoundingClientRect(); - - return (pRect.right - rect.right).round(); - }, - - 'bottom': function(element) { - var parent = hasLayout(element.getOffsetParent()); - var rect = element.getBoundingClientRect(), - pRect = parent.getBoundingClientRect(); - - return (pRect.bottom - rect.bottom).round(); - } - }); - } - - Element.Offset = Class.create({ - initialize: function(left, top) { - this.left = left.round(); - this.top = top.round(); - - this[0] = this.left; - this[1] = this.top; - }, - - relativeTo: function(offset) { - return new Element.Offset( - this.left - offset.left, - this.top - offset.top - ); - }, - - inspect: function() { - return "#".interpolate(this); - }, - - toString: function() { - return "[#{left}, #{top}]".interpolate(this); - }, - - toArray: function() { - return [this.left, this.top]; - } - }); - - function getLayout(element, preCompute) { - return new Element.Layout(element, preCompute); - } - - function measure(element, property) { - return $(element).getLayout().get(property); - } - - function getHeight(element) { - return Element.getDimensions(element).height; - } - - function getWidth(element) { - return Element.getDimensions(element).width; - } - - function getDimensions(element) { - element = $(element); - var display = Element.getStyle(element, 'display'); - - if (display && display !== 'none') { - return { width: element.offsetWidth, height: element.offsetHeight }; - } - - var style = element.style; - var originalStyles = { - visibility: style.visibility, - position: style.position, - display: style.display - }; - - var newStyles = { - visibility: 'hidden', - display: 'block' - }; - - if (originalStyles.position !== 'fixed') - newStyles.position = 'absolute'; - - Element.setStyle(element, newStyles); - - var dimensions = { - width: element.offsetWidth, - height: element.offsetHeight - }; - - Element.setStyle(element, originalStyles); - - return dimensions; - } - - function getOffsetParent(element) { - element = $(element); - - function selfOrBody(element) { - return isHtml(element) ? $(document.body) : $(element); - } - - if (isDocument(element) || isDetached(element) || isBody(element) || isHtml(element)) - return $(document.body); - - var isInline = (Element.getStyle(element, 'display') === 'inline'); - if (!isInline && element.offsetParent) return selfOrBody(element.offsetParent); - - while ((element = element.parentNode) && element !== document.body) { - if (Element.getStyle(element, 'position') !== 'static') { - return selfOrBody(element); - } - } - - return $(document.body); - } - - - function cumulativeOffset(element) { - element = $(element); - var valueT = 0, valueL = 0; - if (element.parentNode) { - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - element = element.offsetParent; - } while (element); - } - return new Element.Offset(valueL, valueT); - } - - function positionedOffset(element) { - element = $(element); - - var layout = element.getLayout(); - - var valueT = 0, valueL = 0; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - element = element.offsetParent; - if (element) { - if (isBody(element)) break; - var p = Element.getStyle(element, 'position'); - if (p !== 'static') break; - } - } while (element); - - valueL -= layout.get('margin-left'); - valueT -= layout.get('margin-top'); - - return new Element.Offset(valueL, valueT); - } - - function cumulativeScrollOffset(element) { - var valueT = 0, valueL = 0; - do { - if (element === document.body) { - var bodyScrollNode = document.documentElement || document.body.parentNode || document.body; - valueT += !Object.isUndefined(window.pageYOffset) ? window.pageYOffset : bodyScrollNode.scrollTop || 0; - valueL += !Object.isUndefined(window.pageXOffset) ? window.pageXOffset : bodyScrollNode.scrollLeft || 0; - break; - } else { - valueT += element.scrollTop || 0; - valueL += element.scrollLeft || 0; - element = element.parentNode; - } - } while (element); - return new Element.Offset(valueL, valueT); - } - - function viewportOffset(forElement) { - var valueT = 0, valueL = 0, docBody = document.body; - - forElement = $(forElement); - var element = forElement; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - if (element.offsetParent == docBody && - Element.getStyle(element, 'position') == 'absolute') break; - } while (element = element.offsetParent); - - element = forElement; - do { - if (element != docBody) { - valueT -= element.scrollTop || 0; - valueL -= element.scrollLeft || 0; - } - } while (element = element.parentNode); - return new Element.Offset(valueL, valueT); - } - - function absolutize(element) { - element = $(element); - - if (Element.getStyle(element, 'position') === 'absolute') { - return element; - } - - var offsetParent = getOffsetParent(element); - var eOffset = element.viewportOffset(), - pOffset = offsetParent.viewportOffset(); - - var offset = eOffset.relativeTo(pOffset); - var layout = element.getLayout(); - - element.store('prototype_absolutize_original_styles', { - position: element.getStyle('position'), - left: element.getStyle('left'), - top: element.getStyle('top'), - width: element.getStyle('width'), - height: element.getStyle('height') - }); - - element.setStyle({ - position: 'absolute', - top: offset.top + 'px', - left: offset.left + 'px', - width: layout.get('width') + 'px', - height: layout.get('height') + 'px' - }); - - return element; - } - - function relativize(element) { - element = $(element); - if (Element.getStyle(element, 'position') === 'relative') { - return element; - } - - var originalStyles = - element.retrieve('prototype_absolutize_original_styles'); - - if (originalStyles) element.setStyle(originalStyles); - return element; - } - - - function scrollTo(element) { - element = $(element); - var pos = Element.cumulativeOffset(element); - window.scrollTo(pos.left, pos.top); - return element; - } - - - function makePositioned(element) { - element = $(element); - var position = Element.getStyle(element, 'position'), styles = {}; - if (position === 'static' || !position) { - styles.position = 'relative'; - if (Prototype.Browser.Opera) { - styles.top = 0; - styles.left = 0; - } - Element.setStyle(element, styles); - Element.store(element, 'prototype_made_positioned', true); - } - return element; - } - - function undoPositioned(element) { - element = $(element); - var storage = Element.getStorage(element), - madePositioned = storage.get('prototype_made_positioned'); - - if (madePositioned) { - storage.unset('prototype_made_positioned'); - Element.setStyle(element, { - position: '', - top: '', - bottom: '', - left: '', - right: '' - }); - } - return element; - } - - function makeClipping(element) { - element = $(element); - - var storage = Element.getStorage(element), - madeClipping = storage.get('prototype_made_clipping'); - - if (Object.isUndefined(madeClipping)) { - var overflow = Element.getStyle(element, 'overflow'); - storage.set('prototype_made_clipping', overflow); - if (overflow !== 'hidden') - element.style.overflow = 'hidden'; - } - - return element; - } - - function undoClipping(element) { - element = $(element); - var storage = Element.getStorage(element), - overflow = storage.get('prototype_made_clipping'); - - if (!Object.isUndefined(overflow)) { - storage.unset('prototype_made_clipping'); - element.style.overflow = overflow || ''; - } - - return element; - } - - function clonePosition(element, source, options) { - options = Object.extend({ - setLeft: true, - setTop: true, - setWidth: true, - setHeight: true, - offsetTop: 0, - offsetLeft: 0 - }, options || {}); - - var docEl = document.documentElement; - - source = $(source); - element = $(element); - var p, delta, layout, styles = {}; - - if (options.setLeft || options.setTop) { - p = Element.viewportOffset(source); - delta = [0, 0]; - if (Element.getStyle(element, 'position') === 'absolute') { - var parent = Element.getOffsetParent(element); - if (parent !== document.body) delta = Element.viewportOffset(parent); - } - } - - function pageScrollXY() { - var x = 0, y = 0; - if (Object.isNumber(window.pageXOffset)) { - x = window.pageXOffset; - y = window.pageYOffset; - } else if (document.body && (document.body.scrollLeft || document.body.scrollTop)) { - x = document.body.scrollLeft; - y = document.body.scrollTop; - } else if (docEl && (docEl.scrollLeft || docEl.scrollTop)) { - x = docEl.scrollLeft; - y = docEl.scrollTop; - } - return { x: x, y: y }; - } - - var pageXY = pageScrollXY(); - - - if (options.setWidth || options.setHeight) { - layout = Element.getLayout(source); - } - - if (options.setLeft) - styles.left = (p[0] + pageXY.x - delta[0] + options.offsetLeft) + 'px'; - if (options.setTop) - styles.top = (p[1] + pageXY.y - delta[1] + options.offsetTop) + 'px'; - - var currentLayout = element.getLayout(); - - if (options.setWidth) { - styles.width = layout.get('width') + 'px'; - } - if (options.setHeight) { - styles.height = layout.get('height') + 'px'; - } - - return Element.setStyle(element, styles); - } - - - if (Prototype.Browser.IE) { - getOffsetParent = getOffsetParent.wrap( - function(proceed, element) { - element = $(element); - - if (isDocument(element) || isDetached(element) || isBody(element) || isHtml(element)) - return $(document.body); - - var position = element.getStyle('position'); - if (position !== 'static') return proceed(element); - - element.setStyle({ position: 'relative' }); - var value = proceed(element); - element.setStyle({ position: position }); - return value; - } - ); - - positionedOffset = positionedOffset.wrap(function(proceed, element) { - element = $(element); - if (!element.parentNode) return new Element.Offset(0, 0); - var position = element.getStyle('position'); - if (position !== 'static') return proceed(element); - - var offsetParent = element.getOffsetParent(); - if (offsetParent && offsetParent.getStyle('position') === 'fixed') - hasLayout(offsetParent); - - element.setStyle({ position: 'relative' }); - var value = proceed(element); - element.setStyle({ position: position }); - return value; - }); - } else if (Prototype.Browser.Webkit) { - cumulativeOffset = function(element) { - element = $(element); - var valueT = 0, valueL = 0; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - if (element.offsetParent == document.body) { - if (Element.getStyle(element, 'position') == 'absolute') break; - } - - element = element.offsetParent; - } while (element); - - return new Element.Offset(valueL, valueT); - }; - } - - - Element.addMethods({ - getLayout: getLayout, - measure: measure, - getWidth: getWidth, - getHeight: getHeight, - getDimensions: getDimensions, - getOffsetParent: getOffsetParent, - cumulativeOffset: cumulativeOffset, - positionedOffset: positionedOffset, - cumulativeScrollOffset: cumulativeScrollOffset, - viewportOffset: viewportOffset, - absolutize: absolutize, - relativize: relativize, - scrollTo: scrollTo, - makePositioned: makePositioned, - undoPositioned: undoPositioned, - makeClipping: makeClipping, - undoClipping: undoClipping, - clonePosition: clonePosition - }); - - function isBody(element) { - return element.nodeName.toUpperCase() === 'BODY'; - } - - function isHtml(element) { - return element.nodeName.toUpperCase() === 'HTML'; - } - - function isDocument(element) { - return element.nodeType === Node.DOCUMENT_NODE; - } - - function isDetached(element) { - return element !== document.body && - !Element.descendantOf(element, document.body); - } - - if ('getBoundingClientRect' in document.documentElement) { - Element.addMethods({ - viewportOffset: function(element) { - element = $(element); - if (isDetached(element)) return new Element.Offset(0, 0); - - var rect = element.getBoundingClientRect(), - docEl = document.documentElement; - return new Element.Offset(rect.left - docEl.clientLeft, - rect.top - docEl.clientTop); - } - }); - } - - -})(); - -(function() { - - var IS_OLD_OPERA = Prototype.Browser.Opera && - (window.parseFloat(window.opera.version()) < 9.5); - var ROOT = null; - function getRootElement() { - if (ROOT) return ROOT; - ROOT = IS_OLD_OPERA ? document.body : document.documentElement; - return ROOT; - } - - function getDimensions() { - return { width: this.getWidth(), height: this.getHeight() }; - } - - function getWidth() { - return getRootElement().clientWidth; - } - - function getHeight() { - return getRootElement().clientHeight; - } - - function getScrollOffsets() { - var x = window.pageXOffset || document.documentElement.scrollLeft || - document.body.scrollLeft; - var y = window.pageYOffset || document.documentElement.scrollTop || - document.body.scrollTop; - - return new Element.Offset(x, y); - } - - document.viewport = { - getDimensions: getDimensions, - getWidth: getWidth, - getHeight: getHeight, - getScrollOffsets: getScrollOffsets - }; - -})(); -window.$$ = function() { - var expression = $A(arguments).join(', '); - return Prototype.Selector.select(expression, document); -}; - -Prototype.Selector = (function() { - - function select() { - throw new Error('Method "Prototype.Selector.select" must be defined.'); - } - - function match() { - throw new Error('Method "Prototype.Selector.match" must be defined.'); - } - - function find(elements, expression, index) { - index = index || 0; - var match = Prototype.Selector.match, length = elements.length, matchIndex = 0, i; - - for (i = 0; i < length; i++) { - if (match(elements[i], expression) && index == matchIndex++) { - return Element.extend(elements[i]); - } - } - } - - function extendElements(elements) { - for (var i = 0, length = elements.length; i < length; i++) { - Element.extend(elements[i]); - } - return elements; - } - - - var K = Prototype.K; - - return { - select: select, - match: match, - find: find, - extendElements: (Element.extend === K) ? K : extendElements, - extendElement: Element.extend - }; -})(); -Prototype._original_property = window.Sizzle; - -;(function () { - function fakeDefine(fn) { - Prototype._actual_sizzle = fn(); - } - fakeDefine.amd = true; - - if (typeof define !== 'undefined' && define.amd) { - Prototype._original_define = define; - Prototype._actual_sizzle = null; - window.define = fakeDefine; - } -})(); - -/*! - * Sizzle CSS Selector Engine v1.10.18 - * http://sizzlejs.com/ - * - * Copyright 2013 jQuery Foundation, Inc. and other contributors - * Released under the MIT license - * http://jquery.org/license - * - * Date: 2014-02-05 - */ -(function( window ) { - -var i, - support, - Expr, - getText, - isXML, - compile, - select, - outermostContext, - sortInput, - hasDuplicate, - - setDocument, - document, - docElem, - documentIsHTML, - rbuggyQSA, - rbuggyMatches, - matches, - contains, - - expando = "sizzle" + -(new Date()), - preferredDoc = window.document, - dirruns = 0, - done = 0, - classCache = createCache(), - tokenCache = createCache(), - compilerCache = createCache(), - sortOrder = function( a, b ) { - if ( a === b ) { - hasDuplicate = true; - } - return 0; - }, - - strundefined = typeof undefined, - MAX_NEGATIVE = 1 << 31, - - hasOwn = ({}).hasOwnProperty, - arr = [], - pop = arr.pop, - push_native = arr.push, - push = arr.push, - slice = arr.slice, - indexOf = arr.indexOf || function( elem ) { - var i = 0, - len = this.length; - for ( ; i < len; i++ ) { - if ( this[i] === elem ) { - return i; - } - } - return -1; - }, - - booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", - - - whitespace = "[\\x20\\t\\r\\n\\f]", - characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", - - identifier = characterEncoding.replace( "w", "w#" ), - - attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace + - "*(?:([*^$|!~]?=)" + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]", - - pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)", - - rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), - - rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), - rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), - - rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), - - rpseudo = new RegExp( pseudos ), - ridentifier = new RegExp( "^" + identifier + "$" ), - - matchExpr = { - "ID": new RegExp( "^#(" + characterEncoding + ")" ), - "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), - "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), - "ATTR": new RegExp( "^" + attributes ), - "PSEUDO": new RegExp( "^" + pseudos ), - "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + - "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + - "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), - "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), - "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + - whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) - }, - - rinputs = /^(?:input|select|textarea|button)$/i, - rheader = /^h\d$/i, - - rnative = /^[^{]+\{\s*\[native \w/, - - rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, - - rsibling = /[+~]/, - rescape = /'|\\/g, - - runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), - funescape = function( _, escaped, escapedWhitespace ) { - var high = "0x" + escaped - 0x10000; - return high !== high || escapedWhitespace ? - escaped : - high < 0 ? - String.fromCharCode( high + 0x10000 ) : - String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); - }; - -try { - push.apply( - (arr = slice.call( preferredDoc.childNodes )), - preferredDoc.childNodes - ); - arr[ preferredDoc.childNodes.length ].nodeType; -} catch ( e ) { - push = { apply: arr.length ? - - function( target, els ) { - push_native.apply( target, slice.call(els) ); - } : - - function( target, els ) { - var j = target.length, - i = 0; - while ( (target[j++] = els[i++]) ) {} - target.length = j - 1; - } - }; -} - -function Sizzle( selector, context, results, seed ) { - var match, elem, m, nodeType, - i, groups, old, nid, newContext, newSelector; - - if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { - setDocument( context ); - } - - context = context || document; - results = results || []; - - if ( !selector || typeof selector !== "string" ) { - return results; - } - - if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) { - return []; - } - - if ( documentIsHTML && !seed ) { - - if ( (match = rquickExpr.exec( selector )) ) { - if ( (m = match[1]) ) { - if ( nodeType === 9 ) { - elem = context.getElementById( m ); - if ( elem && elem.parentNode ) { - if ( elem.id === m ) { - results.push( elem ); - return results; - } - } else { - return results; - } - } else { - if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && - contains( context, elem ) && elem.id === m ) { - results.push( elem ); - return results; - } - } - - } else if ( match[2] ) { - push.apply( results, context.getElementsByTagName( selector ) ); - return results; - - } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) { - push.apply( results, context.getElementsByClassName( m ) ); - return results; - } - } - - if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { - nid = old = expando; - newContext = context; - newSelector = nodeType === 9 && selector; - - if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { - groups = tokenize( selector ); - - if ( (old = context.getAttribute("id")) ) { - nid = old.replace( rescape, "\\$&" ); - } else { - context.setAttribute( "id", nid ); - } - nid = "[id='" + nid + "'] "; - - i = groups.length; - while ( i-- ) { - groups[i] = nid + toSelector( groups[i] ); - } - newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; - newSelector = groups.join(","); - } - - if ( newSelector ) { - try { - push.apply( results, - newContext.querySelectorAll( newSelector ) - ); - return results; - } catch(qsaError) { - } finally { - if ( !old ) { - context.removeAttribute("id"); - } - } - } - } - } - - return select( selector.replace( rtrim, "$1" ), context, results, seed ); -} - -/** - * Create key-value caches of limited size - * @returns {Function(string, Object)} Returns the Object data after storing it on itself with - * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) - * deleting the oldest entry - */ -function createCache() { - var keys = []; - - function cache( key, value ) { - if ( keys.push( key + " " ) > Expr.cacheLength ) { - delete cache[ keys.shift() ]; - } - return (cache[ key + " " ] = value); - } - return cache; -} - -/** - * Mark a function for special use by Sizzle - * @param {Function} fn The function to mark - */ -function markFunction( fn ) { - fn[ expando ] = true; - return fn; -} - -/** - * Support testing using an element - * @param {Function} fn Passed the created div and expects a boolean result - */ -function assert( fn ) { - var div = document.createElement("div"); - - try { - return !!fn( div ); - } catch (e) { - return false; - } finally { - if ( div.parentNode ) { - div.parentNode.removeChild( div ); - } - div = null; - } -} - -/** - * Adds the same handler for all of the specified attrs - * @param {String} attrs Pipe-separated list of attributes - * @param {Function} handler The method that will be applied - */ -function addHandle( attrs, handler ) { - var arr = attrs.split("|"), - i = attrs.length; - - while ( i-- ) { - Expr.attrHandle[ arr[i] ] = handler; - } -} - -/** - * Checks document order of two siblings - * @param {Element} a - * @param {Element} b - * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b - */ -function siblingCheck( a, b ) { - var cur = b && a, - diff = cur && a.nodeType === 1 && b.nodeType === 1 && - ( ~b.sourceIndex || MAX_NEGATIVE ) - - ( ~a.sourceIndex || MAX_NEGATIVE ); - - if ( diff ) { - return diff; - } - - if ( cur ) { - while ( (cur = cur.nextSibling) ) { - if ( cur === b ) { - return -1; - } - } - } - - return a ? 1 : -1; -} - -/** - * Returns a function to use in pseudos for input types - * @param {String} type - */ -function createInputPseudo( type ) { - return function( elem ) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && elem.type === type; - }; -} - -/** - * Returns a function to use in pseudos for buttons - * @param {String} type - */ -function createButtonPseudo( type ) { - return function( elem ) { - var name = elem.nodeName.toLowerCase(); - return (name === "input" || name === "button") && elem.type === type; - }; -} - -/** - * Returns a function to use in pseudos for positionals - * @param {Function} fn - */ -function createPositionalPseudo( fn ) { - return markFunction(function( argument ) { - argument = +argument; - return markFunction(function( seed, matches ) { - var j, - matchIndexes = fn( [], seed.length, argument ), - i = matchIndexes.length; - - while ( i-- ) { - if ( seed[ (j = matchIndexes[i]) ] ) { - seed[j] = !(matches[j] = seed[j]); - } - } - }); - }); -} - -/** - * Checks a node for validity as a Sizzle context - * @param {Element|Object=} context - * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value - */ -function testContext( context ) { - return context && typeof context.getElementsByTagName !== strundefined && context; -} - -support = Sizzle.support = {}; - -/** - * Detects XML nodes - * @param {Element|Object} elem An element or a document - * @returns {Boolean} True iff elem is a non-HTML XML node - */ -isXML = Sizzle.isXML = function( elem ) { - var documentElement = elem && (elem.ownerDocument || elem).documentElement; - return documentElement ? documentElement.nodeName !== "HTML" : false; -}; - -/** - * Sets document-related variables once based on the current document - * @param {Element|Object} [doc] An element or document object to use to set the document - * @returns {Object} Returns the current document - */ -setDocument = Sizzle.setDocument = function( node ) { - var hasCompare, - doc = node ? node.ownerDocument || node : preferredDoc, - parent = doc.defaultView; - - if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { - return document; - } - - document = doc; - docElem = doc.documentElement; - - documentIsHTML = !isXML( doc ); - - if ( parent && parent !== parent.top ) { - if ( parent.addEventListener ) { - parent.addEventListener( "unload", function() { - setDocument(); - }, false ); - } else if ( parent.attachEvent ) { - parent.attachEvent( "onunload", function() { - setDocument(); - }); - } - } - - /* Attributes - ---------------------------------------------------------------------- */ - - support.attributes = assert(function( div ) { - div.className = "i"; - return !div.getAttribute("className"); - }); - - /* getElement(s)By* - ---------------------------------------------------------------------- */ - - support.getElementsByTagName = assert(function( div ) { - div.appendChild( doc.createComment("") ); - return !div.getElementsByTagName("*").length; - }); - - support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) { - div.innerHTML = "
"; - - div.firstChild.className = "i"; - return div.getElementsByClassName("i").length === 2; - }); - - support.getById = assert(function( div ) { - docElem.appendChild( div ).id = expando; - return !doc.getElementsByName || !doc.getElementsByName( expando ).length; - }); - - if ( support.getById ) { - Expr.find["ID"] = function( id, context ) { - if ( typeof context.getElementById !== strundefined && documentIsHTML ) { - var m = context.getElementById( id ); - return m && m.parentNode ? [m] : []; - } - }; - Expr.filter["ID"] = function( id ) { - var attrId = id.replace( runescape, funescape ); - return function( elem ) { - return elem.getAttribute("id") === attrId; - }; - }; - } else { - delete Expr.find["ID"]; - - Expr.filter["ID"] = function( id ) { - var attrId = id.replace( runescape, funescape ); - return function( elem ) { - var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); - return node && node.value === attrId; - }; - }; - } - - Expr.find["TAG"] = support.getElementsByTagName ? - function( tag, context ) { - if ( typeof context.getElementsByTagName !== strundefined ) { - return context.getElementsByTagName( tag ); - } - } : - function( tag, context ) { - var elem, - tmp = [], - i = 0, - results = context.getElementsByTagName( tag ); - - if ( tag === "*" ) { - while ( (elem = results[i++]) ) { - if ( elem.nodeType === 1 ) { - tmp.push( elem ); - } - } - - return tmp; - } - return results; - }; - - Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { - if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) { - return context.getElementsByClassName( className ); - } - }; - - /* QSA/matchesSelector - ---------------------------------------------------------------------- */ - - - rbuggyMatches = []; - - rbuggyQSA = []; - - if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) { - assert(function( div ) { - div.innerHTML = ""; - - if ( div.querySelectorAll("[t^='']").length ) { - rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); - } - - if ( !div.querySelectorAll("[selected]").length ) { - rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); - } - - if ( !div.querySelectorAll(":checked").length ) { - rbuggyQSA.push(":checked"); - } - }); - - assert(function( div ) { - var input = doc.createElement("input"); - input.setAttribute( "type", "hidden" ); - div.appendChild( input ).setAttribute( "name", "D" ); - - if ( div.querySelectorAll("[name=d]").length ) { - rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); - } - - if ( !div.querySelectorAll(":enabled").length ) { - rbuggyQSA.push( ":enabled", ":disabled" ); - } - - div.querySelectorAll("*,:x"); - rbuggyQSA.push(",.*:"); - }); - } - - if ( (support.matchesSelector = rnative.test( (matches = docElem.webkitMatchesSelector || - docElem.mozMatchesSelector || - docElem.oMatchesSelector || - docElem.msMatchesSelector) )) ) { - - assert(function( div ) { - support.disconnectedMatch = matches.call( div, "div" ); - - matches.call( div, "[s!='']:x" ); - rbuggyMatches.push( "!=", pseudos ); - }); - } - - rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); - rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); - - /* Contains - ---------------------------------------------------------------------- */ - hasCompare = rnative.test( docElem.compareDocumentPosition ); - - contains = hasCompare || rnative.test( docElem.contains ) ? - function( a, b ) { - var adown = a.nodeType === 9 ? a.documentElement : a, - bup = b && b.parentNode; - return a === bup || !!( bup && bup.nodeType === 1 && ( - adown.contains ? - adown.contains( bup ) : - a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 - )); - } : - function( a, b ) { - if ( b ) { - while ( (b = b.parentNode) ) { - if ( b === a ) { - return true; - } - } - } - return false; - }; - - /* Sorting - ---------------------------------------------------------------------- */ - - sortOrder = hasCompare ? - function( a, b ) { - - if ( a === b ) { - hasDuplicate = true; - return 0; - } - - var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; - if ( compare ) { - return compare; - } - - compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? - a.compareDocumentPosition( b ) : - - 1; - - if ( compare & 1 || - (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { - - if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { - return -1; - } - if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { - return 1; - } - - return sortInput ? - ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : - 0; - } - - return compare & 4 ? -1 : 1; - } : - function( a, b ) { - if ( a === b ) { - hasDuplicate = true; - return 0; - } - - var cur, - i = 0, - aup = a.parentNode, - bup = b.parentNode, - ap = [ a ], - bp = [ b ]; - - if ( !aup || !bup ) { - return a === doc ? -1 : - b === doc ? 1 : - aup ? -1 : - bup ? 1 : - sortInput ? - ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : - 0; - - } else if ( aup === bup ) { - return siblingCheck( a, b ); - } - - cur = a; - while ( (cur = cur.parentNode) ) { - ap.unshift( cur ); - } - cur = b; - while ( (cur = cur.parentNode) ) { - bp.unshift( cur ); - } - - while ( ap[i] === bp[i] ) { - i++; - } - - return i ? - siblingCheck( ap[i], bp[i] ) : - - ap[i] === preferredDoc ? -1 : - bp[i] === preferredDoc ? 1 : - 0; - }; - - return doc; -}; - -Sizzle.matches = function( expr, elements ) { - return Sizzle( expr, null, null, elements ); -}; - -Sizzle.matchesSelector = function( elem, expr ) { - if ( ( elem.ownerDocument || elem ) !== document ) { - setDocument( elem ); - } - - expr = expr.replace( rattributeQuotes, "='$1']" ); - - if ( support.matchesSelector && documentIsHTML && - ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && - ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { - - try { - var ret = matches.call( elem, expr ); - - if ( ret || support.disconnectedMatch || - elem.document && elem.document.nodeType !== 11 ) { - return ret; - } - } catch(e) {} - } - - return Sizzle( expr, document, null, [elem] ).length > 0; -}; - -Sizzle.contains = function( context, elem ) { - if ( ( context.ownerDocument || context ) !== document ) { - setDocument( context ); - } - return contains( context, elem ); -}; - -Sizzle.attr = function( elem, name ) { - if ( ( elem.ownerDocument || elem ) !== document ) { - setDocument( elem ); - } - - var fn = Expr.attrHandle[ name.toLowerCase() ], - val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? - fn( elem, name, !documentIsHTML ) : - undefined; - - return val !== undefined ? - val : - support.attributes || !documentIsHTML ? - elem.getAttribute( name ) : - (val = elem.getAttributeNode(name)) && val.specified ? - val.value : - null; -}; - -Sizzle.error = function( msg ) { - throw new Error( "Syntax error, unrecognized expression: " + msg ); -}; - -/** - * Document sorting and removing duplicates - * @param {ArrayLike} results - */ -Sizzle.uniqueSort = function( results ) { - var elem, - duplicates = [], - j = 0, - i = 0; - - hasDuplicate = !support.detectDuplicates; - sortInput = !support.sortStable && results.slice( 0 ); - results.sort( sortOrder ); - - if ( hasDuplicate ) { - while ( (elem = results[i++]) ) { - if ( elem === results[ i ] ) { - j = duplicates.push( i ); - } - } - while ( j-- ) { - results.splice( duplicates[ j ], 1 ); - } - } - - sortInput = null; - - return results; -}; - -/** - * Utility function for retrieving the text value of an array of DOM nodes - * @param {Array|Element} elem - */ -getText = Sizzle.getText = function( elem ) { - var node, - ret = "", - i = 0, - nodeType = elem.nodeType; - - if ( !nodeType ) { - while ( (node = elem[i++]) ) { - ret += getText( node ); - } - } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { - if ( typeof elem.textContent === "string" ) { - return elem.textContent; - } else { - for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { - ret += getText( elem ); - } - } - } else if ( nodeType === 3 || nodeType === 4 ) { - return elem.nodeValue; - } - - return ret; -}; - -Expr = Sizzle.selectors = { - - cacheLength: 50, - - createPseudo: markFunction, - - match: matchExpr, - - attrHandle: {}, - - find: {}, - - relative: { - ">": { dir: "parentNode", first: true }, - " ": { dir: "parentNode" }, - "+": { dir: "previousSibling", first: true }, - "~": { dir: "previousSibling" } - }, - - preFilter: { - "ATTR": function( match ) { - match[1] = match[1].replace( runescape, funescape ); - - match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape ); - - if ( match[2] === "~=" ) { - match[3] = " " + match[3] + " "; - } - - return match.slice( 0, 4 ); - }, - - "CHILD": function( match ) { - /* matches from matchExpr["CHILD"] - 1 type (only|nth|...) - 2 what (child|of-type) - 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) - 4 xn-component of xn+y argument ([+-]?\d*n|) - 5 sign of xn-component - 6 x of xn-component - 7 sign of y-component - 8 y of y-component - */ - match[1] = match[1].toLowerCase(); - - if ( match[1].slice( 0, 3 ) === "nth" ) { - if ( !match[3] ) { - Sizzle.error( match[0] ); - } - - match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); - match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); - - } else if ( match[3] ) { - Sizzle.error( match[0] ); - } - - return match; - }, - - "PSEUDO": function( match ) { - var excess, - unquoted = !match[5] && match[2]; - - if ( matchExpr["CHILD"].test( match[0] ) ) { - return null; - } - - if ( match[3] && match[4] !== undefined ) { - match[2] = match[4]; - - } else if ( unquoted && rpseudo.test( unquoted ) && - (excess = tokenize( unquoted, true )) && - (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { - - match[0] = match[0].slice( 0, excess ); - match[2] = unquoted.slice( 0, excess ); - } - - return match.slice( 0, 3 ); - } - }, - - filter: { - - "TAG": function( nodeNameSelector ) { - var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); - return nodeNameSelector === "*" ? - function() { return true; } : - function( elem ) { - return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; - }; - }, - - "CLASS": function( className ) { - var pattern = classCache[ className + " " ]; - - return pattern || - (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && - classCache( className, function( elem ) { - return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" ); - }); - }, - - "ATTR": function( name, operator, check ) { - return function( elem ) { - var result = Sizzle.attr( elem, name ); - - if ( result == null ) { - return operator === "!="; - } - if ( !operator ) { - return true; - } - - result += ""; - - return operator === "=" ? result === check : - operator === "!=" ? result !== check : - operator === "^=" ? check && result.indexOf( check ) === 0 : - operator === "*=" ? check && result.indexOf( check ) > -1 : - operator === "$=" ? check && result.slice( -check.length ) === check : - operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : - operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : - false; - }; - }, - - "CHILD": function( type, what, argument, first, last ) { - var simple = type.slice( 0, 3 ) !== "nth", - forward = type.slice( -4 ) !== "last", - ofType = what === "of-type"; - - return first === 1 && last === 0 ? - - function( elem ) { - return !!elem.parentNode; - } : - - function( elem, context, xml ) { - var cache, outerCache, node, diff, nodeIndex, start, - dir = simple !== forward ? "nextSibling" : "previousSibling", - parent = elem.parentNode, - name = ofType && elem.nodeName.toLowerCase(), - useCache = !xml && !ofType; - - if ( parent ) { - - if ( simple ) { - while ( dir ) { - node = elem; - while ( (node = node[ dir ]) ) { - if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { - return false; - } - } - start = dir = type === "only" && !start && "nextSibling"; - } - return true; - } - - start = [ forward ? parent.firstChild : parent.lastChild ]; - - if ( forward && useCache ) { - outerCache = parent[ expando ] || (parent[ expando ] = {}); - cache = outerCache[ type ] || []; - nodeIndex = cache[0] === dirruns && cache[1]; - diff = cache[0] === dirruns && cache[2]; - node = nodeIndex && parent.childNodes[ nodeIndex ]; - - while ( (node = ++nodeIndex && node && node[ dir ] || - - (diff = nodeIndex = 0) || start.pop()) ) { - - if ( node.nodeType === 1 && ++diff && node === elem ) { - outerCache[ type ] = [ dirruns, nodeIndex, diff ]; - break; - } - } - - } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { - diff = cache[1]; - - } else { - while ( (node = ++nodeIndex && node && node[ dir ] || - (diff = nodeIndex = 0) || start.pop()) ) { - - if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { - if ( useCache ) { - (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; - } - - if ( node === elem ) { - break; - } - } - } - } - - diff -= last; - return diff === first || ( diff % first === 0 && diff / first >= 0 ); - } - }; - }, - - "PSEUDO": function( pseudo, argument ) { - var args, - fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || - Sizzle.error( "unsupported pseudo: " + pseudo ); - - if ( fn[ expando ] ) { - return fn( argument ); - } - - if ( fn.length > 1 ) { - args = [ pseudo, pseudo, "", argument ]; - return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? - markFunction(function( seed, matches ) { - var idx, - matched = fn( seed, argument ), - i = matched.length; - while ( i-- ) { - idx = indexOf.call( seed, matched[i] ); - seed[ idx ] = !( matches[ idx ] = matched[i] ); - } - }) : - function( elem ) { - return fn( elem, 0, args ); - }; - } - - return fn; - } - }, - - pseudos: { - "not": markFunction(function( selector ) { - var input = [], - results = [], - matcher = compile( selector.replace( rtrim, "$1" ) ); - - return matcher[ expando ] ? - markFunction(function( seed, matches, context, xml ) { - var elem, - unmatched = matcher( seed, null, xml, [] ), - i = seed.length; - - while ( i-- ) { - if ( (elem = unmatched[i]) ) { - seed[i] = !(matches[i] = elem); - } - } - }) : - function( elem, context, xml ) { - input[0] = elem; - matcher( input, null, xml, results ); - return !results.pop(); - }; - }), - - "has": markFunction(function( selector ) { - return function( elem ) { - return Sizzle( selector, elem ).length > 0; - }; - }), - - "contains": markFunction(function( text ) { - return function( elem ) { - return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; - }; - }), - - "lang": markFunction( function( lang ) { - if ( !ridentifier.test(lang || "") ) { - Sizzle.error( "unsupported lang: " + lang ); - } - lang = lang.replace( runescape, funescape ).toLowerCase(); - return function( elem ) { - var elemLang; - do { - if ( (elemLang = documentIsHTML ? - elem.lang : - elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { - - elemLang = elemLang.toLowerCase(); - return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; - } - } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); - return false; - }; - }), - - "target": function( elem ) { - var hash = window.location && window.location.hash; - return hash && hash.slice( 1 ) === elem.id; - }, - - "root": function( elem ) { - return elem === docElem; - }, - - "focus": function( elem ) { - return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); - }, - - "enabled": function( elem ) { - return elem.disabled === false; - }, - - "disabled": function( elem ) { - return elem.disabled === true; - }, - - "checked": function( elem ) { - var nodeName = elem.nodeName.toLowerCase(); - return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); - }, - - "selected": function( elem ) { - if ( elem.parentNode ) { - elem.parentNode.selectedIndex; - } - - return elem.selected === true; - }, - - "empty": function( elem ) { - for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { - if ( elem.nodeType < 6 ) { - return false; - } - } - return true; - }, - - "parent": function( elem ) { - return !Expr.pseudos["empty"]( elem ); - }, - - "header": function( elem ) { - return rheader.test( elem.nodeName ); - }, - - "input": function( elem ) { - return rinputs.test( elem.nodeName ); - }, - - "button": function( elem ) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && elem.type === "button" || name === "button"; - }, - - "text": function( elem ) { - var attr; - return elem.nodeName.toLowerCase() === "input" && - elem.type === "text" && - - ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); - }, - - "first": createPositionalPseudo(function() { - return [ 0 ]; - }), - - "last": createPositionalPseudo(function( matchIndexes, length ) { - return [ length - 1 ]; - }), - - "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { - return [ argument < 0 ? argument + length : argument ]; - }), - - "even": createPositionalPseudo(function( matchIndexes, length ) { - var i = 0; - for ( ; i < length; i += 2 ) { - matchIndexes.push( i ); - } - return matchIndexes; - }), - - "odd": createPositionalPseudo(function( matchIndexes, length ) { - var i = 1; - for ( ; i < length; i += 2 ) { - matchIndexes.push( i ); - } - return matchIndexes; - }), - - "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { - var i = argument < 0 ? argument + length : argument; - for ( ; --i >= 0; ) { - matchIndexes.push( i ); - } - return matchIndexes; - }), - - "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { - var i = argument < 0 ? argument + length : argument; - for ( ; ++i < length; ) { - matchIndexes.push( i ); - } - return matchIndexes; - }) - } -}; - -Expr.pseudos["nth"] = Expr.pseudos["eq"]; - -for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { - Expr.pseudos[ i ] = createInputPseudo( i ); -} -for ( i in { submit: true, reset: true } ) { - Expr.pseudos[ i ] = createButtonPseudo( i ); -} - -function setFilters() {} -setFilters.prototype = Expr.filters = Expr.pseudos; -Expr.setFilters = new setFilters(); - -function tokenize( selector, parseOnly ) { - var matched, match, tokens, type, - soFar, groups, preFilters, - cached = tokenCache[ selector + " " ]; - - if ( cached ) { - return parseOnly ? 0 : cached.slice( 0 ); - } - - soFar = selector; - groups = []; - preFilters = Expr.preFilter; - - while ( soFar ) { - - if ( !matched || (match = rcomma.exec( soFar )) ) { - if ( match ) { - soFar = soFar.slice( match[0].length ) || soFar; - } - groups.push( (tokens = []) ); - } - - matched = false; - - if ( (match = rcombinators.exec( soFar )) ) { - matched = match.shift(); - tokens.push({ - value: matched, - type: match[0].replace( rtrim, " " ) - }); - soFar = soFar.slice( matched.length ); - } - - for ( type in Expr.filter ) { - if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || - (match = preFilters[ type ]( match ))) ) { - matched = match.shift(); - tokens.push({ - value: matched, - type: type, - matches: match - }); - soFar = soFar.slice( matched.length ); - } - } - - if ( !matched ) { - break; - } - } - - return parseOnly ? - soFar.length : - soFar ? - Sizzle.error( selector ) : - tokenCache( selector, groups ).slice( 0 ); -} - -function toSelector( tokens ) { - var i = 0, - len = tokens.length, - selector = ""; - for ( ; i < len; i++ ) { - selector += tokens[i].value; - } - return selector; -} - -function addCombinator( matcher, combinator, base ) { - var dir = combinator.dir, - checkNonElements = base && dir === "parentNode", - doneName = done++; - - return combinator.first ? - function( elem, context, xml ) { - while ( (elem = elem[ dir ]) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - return matcher( elem, context, xml ); - } - } - } : - - function( elem, context, xml ) { - var oldCache, outerCache, - newCache = [ dirruns, doneName ]; - - if ( xml ) { - while ( (elem = elem[ dir ]) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - if ( matcher( elem, context, xml ) ) { - return true; - } - } - } - } else { - while ( (elem = elem[ dir ]) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - outerCache = elem[ expando ] || (elem[ expando ] = {}); - if ( (oldCache = outerCache[ dir ]) && - oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { - - return (newCache[ 2 ] = oldCache[ 2 ]); - } else { - outerCache[ dir ] = newCache; - - if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { - return true; - } - } - } - } - } - }; -} - -function elementMatcher( matchers ) { - return matchers.length > 1 ? - function( elem, context, xml ) { - var i = matchers.length; - while ( i-- ) { - if ( !matchers[i]( elem, context, xml ) ) { - return false; - } - } - return true; - } : - matchers[0]; -} - -function multipleContexts( selector, contexts, results ) { - var i = 0, - len = contexts.length; - for ( ; i < len; i++ ) { - Sizzle( selector, contexts[i], results ); - } - return results; -} - -function condense( unmatched, map, filter, context, xml ) { - var elem, - newUnmatched = [], - i = 0, - len = unmatched.length, - mapped = map != null; - - for ( ; i < len; i++ ) { - if ( (elem = unmatched[i]) ) { - if ( !filter || filter( elem, context, xml ) ) { - newUnmatched.push( elem ); - if ( mapped ) { - map.push( i ); - } - } - } - } - - return newUnmatched; -} - -function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { - if ( postFilter && !postFilter[ expando ] ) { - postFilter = setMatcher( postFilter ); - } - if ( postFinder && !postFinder[ expando ] ) { - postFinder = setMatcher( postFinder, postSelector ); - } - return markFunction(function( seed, results, context, xml ) { - var temp, i, elem, - preMap = [], - postMap = [], - preexisting = results.length, - - elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), - - matcherIn = preFilter && ( seed || !selector ) ? - condense( elems, preMap, preFilter, context, xml ) : - elems, - - matcherOut = matcher ? - postFinder || ( seed ? preFilter : preexisting || postFilter ) ? - - [] : - - results : - matcherIn; - - if ( matcher ) { - matcher( matcherIn, matcherOut, context, xml ); - } - - if ( postFilter ) { - temp = condense( matcherOut, postMap ); - postFilter( temp, [], context, xml ); - - i = temp.length; - while ( i-- ) { - if ( (elem = temp[i]) ) { - matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); - } - } - } - - if ( seed ) { - if ( postFinder || preFilter ) { - if ( postFinder ) { - temp = []; - i = matcherOut.length; - while ( i-- ) { - if ( (elem = matcherOut[i]) ) { - temp.push( (matcherIn[i] = elem) ); - } - } - postFinder( null, (matcherOut = []), temp, xml ); - } - - i = matcherOut.length; - while ( i-- ) { - if ( (elem = matcherOut[i]) && - (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { - - seed[temp] = !(results[temp] = elem); - } - } - } - - } else { - matcherOut = condense( - matcherOut === results ? - matcherOut.splice( preexisting, matcherOut.length ) : - matcherOut - ); - if ( postFinder ) { - postFinder( null, results, matcherOut, xml ); - } else { - push.apply( results, matcherOut ); - } - } - }); -} - -function matcherFromTokens( tokens ) { - var checkContext, matcher, j, - len = tokens.length, - leadingRelative = Expr.relative[ tokens[0].type ], - implicitRelative = leadingRelative || Expr.relative[" "], - i = leadingRelative ? 1 : 0, - - matchContext = addCombinator( function( elem ) { - return elem === checkContext; - }, implicitRelative, true ), - matchAnyContext = addCombinator( function( elem ) { - return indexOf.call( checkContext, elem ) > -1; - }, implicitRelative, true ), - matchers = [ function( elem, context, xml ) { - return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( - (checkContext = context).nodeType ? - matchContext( elem, context, xml ) : - matchAnyContext( elem, context, xml ) ); - } ]; - - for ( ; i < len; i++ ) { - if ( (matcher = Expr.relative[ tokens[i].type ]) ) { - matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; - } else { - matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); - - if ( matcher[ expando ] ) { - j = ++i; - for ( ; j < len; j++ ) { - if ( Expr.relative[ tokens[j].type ] ) { - break; - } - } - return setMatcher( - i > 1 && elementMatcher( matchers ), - i > 1 && toSelector( - tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) - ).replace( rtrim, "$1" ), - matcher, - i < j && matcherFromTokens( tokens.slice( i, j ) ), - j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), - j < len && toSelector( tokens ) - ); - } - matchers.push( matcher ); - } - } - - return elementMatcher( matchers ); -} - -function matcherFromGroupMatchers( elementMatchers, setMatchers ) { - var bySet = setMatchers.length > 0, - byElement = elementMatchers.length > 0, - superMatcher = function( seed, context, xml, results, outermost ) { - var elem, j, matcher, - matchedCount = 0, - i = "0", - unmatched = seed && [], - setMatched = [], - contextBackup = outermostContext, - elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), - dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), - len = elems.length; - - if ( outermost ) { - outermostContext = context !== document && context; - } - - for ( ; i !== len && (elem = elems[i]) != null; i++ ) { - if ( byElement && elem ) { - j = 0; - while ( (matcher = elementMatchers[j++]) ) { - if ( matcher( elem, context, xml ) ) { - results.push( elem ); - break; - } - } - if ( outermost ) { - dirruns = dirrunsUnique; - } - } - - if ( bySet ) { - if ( (elem = !matcher && elem) ) { - matchedCount--; - } - - if ( seed ) { - unmatched.push( elem ); - } - } - } - - matchedCount += i; - if ( bySet && i !== matchedCount ) { - j = 0; - while ( (matcher = setMatchers[j++]) ) { - matcher( unmatched, setMatched, context, xml ); - } - - if ( seed ) { - if ( matchedCount > 0 ) { - while ( i-- ) { - if ( !(unmatched[i] || setMatched[i]) ) { - setMatched[i] = pop.call( results ); - } - } - } - - setMatched = condense( setMatched ); - } - - push.apply( results, setMatched ); - - if ( outermost && !seed && setMatched.length > 0 && - ( matchedCount + setMatchers.length ) > 1 ) { - - Sizzle.uniqueSort( results ); - } - } - - if ( outermost ) { - dirruns = dirrunsUnique; - outermostContext = contextBackup; - } - - return unmatched; - }; - - return bySet ? - markFunction( superMatcher ) : - superMatcher; -} - -compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { - var i, - setMatchers = [], - elementMatchers = [], - cached = compilerCache[ selector + " " ]; - - if ( !cached ) { - if ( !match ) { - match = tokenize( selector ); - } - i = match.length; - while ( i-- ) { - cached = matcherFromTokens( match[i] ); - if ( cached[ expando ] ) { - setMatchers.push( cached ); - } else { - elementMatchers.push( cached ); - } - } - - cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); - - cached.selector = selector; - } - return cached; -}; - -/** - * A low-level selection function that works with Sizzle's compiled - * selector functions - * @param {String|Function} selector A selector or a pre-compiled - * selector function built with Sizzle.compile - * @param {Element} context - * @param {Array} [results] - * @param {Array} [seed] A set of elements to match against - */ -select = Sizzle.select = function( selector, context, results, seed ) { - var i, tokens, token, type, find, - compiled = typeof selector === "function" && selector, - match = !seed && tokenize( (selector = compiled.selector || selector) ); - - results = results || []; - - if ( match.length === 1 ) { - - tokens = match[0] = match[0].slice( 0 ); - if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && - support.getById && context.nodeType === 9 && documentIsHTML && - Expr.relative[ tokens[1].type ] ) { - - context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; - if ( !context ) { - return results; - - } else if ( compiled ) { - context = context.parentNode; - } - - selector = selector.slice( tokens.shift().value.length ); - } - - i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; - while ( i-- ) { - token = tokens[i]; - - if ( Expr.relative[ (type = token.type) ] ) { - break; - } - if ( (find = Expr.find[ type ]) ) { - if ( (seed = find( - token.matches[0].replace( runescape, funescape ), - rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context - )) ) { - - tokens.splice( i, 1 ); - selector = seed.length && toSelector( tokens ); - if ( !selector ) { - push.apply( results, seed ); - return results; - } - - break; - } - } - } - } - - ( compiled || compile( selector, match ) )( - seed, - context, - !documentIsHTML, - results, - rsibling.test( selector ) && testContext( context.parentNode ) || context - ); - return results; -}; - - -support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; - -support.detectDuplicates = !!hasDuplicate; - -setDocument(); - -support.sortDetached = assert(function( div1 ) { - return div1.compareDocumentPosition( document.createElement("div") ) & 1; -}); - -if ( !assert(function( div ) { - div.innerHTML = ""; - return div.firstChild.getAttribute("href") === "#" ; -}) ) { - addHandle( "type|href|height|width", function( elem, name, isXML ) { - if ( !isXML ) { - return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); - } - }); -} - -if ( !support.attributes || !assert(function( div ) { - div.innerHTML = ""; - div.firstChild.setAttribute( "value", "" ); - return div.firstChild.getAttribute( "value" ) === ""; -}) ) { - addHandle( "value", function( elem, name, isXML ) { - if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { - return elem.defaultValue; - } - }); -} - -if ( !assert(function( div ) { - return div.getAttribute("disabled") == null; -}) ) { - addHandle( booleans, function( elem, name, isXML ) { - var val; - if ( !isXML ) { - return elem[ name ] === true ? name.toLowerCase() : - (val = elem.getAttributeNode( name )) && val.specified ? - val.value : - null; - } - }); -} - -if ( typeof define === "function" && define.amd ) { - define(function() { return Sizzle; }); -} else if ( typeof module !== "undefined" && module.exports ) { - module.exports = Sizzle; -} else { - window.Sizzle = Sizzle; -} - -})( window ); - -;(function() { - if (typeof Sizzle !== 'undefined') { - return; - } - - if (typeof define !== 'undefined' && define.amd) { - window.Sizzle = Prototype._actual_sizzle; - window.define = Prototype._original_define; - delete Prototype._actual_sizzle; - delete Prototype._original_define; - } else if (typeof module !== 'undefined' && module.exports) { - window.Sizzle = module.exports; - module.exports = {}; - } -})(); - -;(function(engine) { - var extendElements = Prototype.Selector.extendElements; - - function select(selector, scope) { - return extendElements(engine(selector, scope || document)); - } - - function match(element, selector) { - return engine.matches(selector, [element]).length == 1; - } - - Prototype.Selector.engine = engine; - Prototype.Selector.select = select; - Prototype.Selector.match = match; -})(Sizzle); - -window.Sizzle = Prototype._original_property; -delete Prototype._original_property; - -var Form = { - reset: function(form) { - form = $(form); - form.reset(); - return form; - }, - - serializeElements: function(elements, options) { - if (typeof options != 'object') options = { hash: !!options }; - else if (Object.isUndefined(options.hash)) options.hash = true; - var key, value, submitted = false, submit = options.submit, accumulator, initial; - - if (options.hash) { - initial = {}; - accumulator = function(result, key, value) { - if (key in result) { - if (!Object.isArray(result[key])) result[key] = [result[key]]; - result[key] = result[key].concat(value); - } else result[key] = value; - return result; - }; - } else { - initial = ''; - accumulator = function(result, key, values) { - if (!Object.isArray(values)) {values = [values];} - if (!values.length) {return result;} - var encodedKey = encodeURIComponent(key).gsub(/%20/, '+'); - return result + (result ? "&" : "") + values.map(function (value) { - value = value.gsub(/(\r)?\n/, '\r\n'); - value = encodeURIComponent(value); - value = value.gsub(/%20/, '+'); - return encodedKey + "=" + value; - }).join("&"); - }; - } - - return elements.inject(initial, function(result, element) { - if (!element.disabled && element.name) { - key = element.name; value = $(element).getValue(); - if (value != null && element.type != 'file' && (element.type != 'submit' || (!submitted && - submit !== false && (!submit || key == submit) && (submitted = true)))) { - result = accumulator(result, key, value); - } - } - return result; - }); - } -}; - -Form.Methods = { - serialize: function(form, options) { - return Form.serializeElements(Form.getElements(form), options); - }, - - - getElements: function(form) { - var elements = $(form).getElementsByTagName('*'); - var element, results = [], serializers = Form.Element.Serializers; - - for (var i = 0; element = elements[i]; i++) { - if (serializers[element.tagName.toLowerCase()]) - results.push(Element.extend(element)); - } - return results; - }, - - getInputs: function(form, typeName, name) { - form = $(form); - var inputs = form.getElementsByTagName('input'); - - if (!typeName && !name) return $A(inputs).map(Element.extend); - - for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) { - var input = inputs[i]; - if ((typeName && input.type != typeName) || (name && input.name != name)) - continue; - matchingInputs.push(Element.extend(input)); - } - - return matchingInputs; - }, - - disable: function(form) { - form = $(form); - Form.getElements(form).invoke('disable'); - return form; - }, - - enable: function(form) { - form = $(form); - Form.getElements(form).invoke('enable'); - return form; - }, - - findFirstElement: function(form) { - var elements = $(form).getElements().findAll(function(element) { - return 'hidden' != element.type && !element.disabled; - }); - var firstByIndex = elements.findAll(function(element) { - return element.hasAttribute('tabIndex') && element.tabIndex >= 0; - }).sortBy(function(element) { return element.tabIndex }).first(); - - return firstByIndex ? firstByIndex : elements.find(function(element) { - return /^(?:input|select|textarea)$/i.test(element.tagName); - }); - }, - - focusFirstElement: function(form) { - form = $(form); - var element = form.findFirstElement(); - if (element) element.activate(); - return form; - }, - - request: function(form, options) { - form = $(form), options = Object.clone(options || { }); - - var params = options.parameters, action = form.readAttribute('action') || ''; - if (action.blank()) action = window.location.href; - options.parameters = form.serialize(true); - - if (params) { - if (Object.isString(params)) params = params.toQueryParams(); - Object.extend(options.parameters, params); - } - - if (form.hasAttribute('method') && !options.method) - options.method = form.method; - - return new Ajax.Request(action, options); - } -}; - -/*--------------------------------------------------------------------------*/ - - -Form.Element = { - focus: function(element) { - $(element).focus(); - return element; - }, - - select: function(element) { - $(element).select(); - return element; - } -}; - -Form.Element.Methods = { - - serialize: function(element) { - element = $(element); - if (!element.disabled && element.name) { - var value = element.getValue(); - if (value != undefined) { - var pair = { }; - pair[element.name] = value; - return Object.toQueryString(pair); - } - } - return ''; - }, - - getValue: function(element) { - element = $(element); - var method = element.tagName.toLowerCase(); - return Form.Element.Serializers[method](element); - }, - - setValue: function(element, value) { - element = $(element); - var method = element.tagName.toLowerCase(); - Form.Element.Serializers[method](element, value); - return element; - }, - - clear: function(element) { - $(element).value = ''; - return element; - }, - - present: function(element) { - return $(element).value != ''; - }, - - activate: function(element) { - element = $(element); - try { - element.focus(); - if (element.select && (element.tagName.toLowerCase() != 'input' || - !(/^(?:button|reset|submit)$/i.test(element.type)))) - element.select(); - } catch (e) { } - return element; - }, - - disable: function(element) { - element = $(element); - element.disabled = true; - return element; - }, - - enable: function(element) { - element = $(element); - element.disabled = false; - return element; - } -}; - -/*--------------------------------------------------------------------------*/ - -var Field = Form.Element; - -var $F = Form.Element.Methods.getValue; - -/*--------------------------------------------------------------------------*/ - -Form.Element.Serializers = (function() { - function input(element, value) { - switch (element.type.toLowerCase()) { - case 'checkbox': - case 'radio': - return inputSelector(element, value); - default: - return valueSelector(element, value); - } - } - - function inputSelector(element, value) { - if (Object.isUndefined(value)) - return element.checked ? element.value : null; - else element.checked = !!value; - } - - function valueSelector(element, value) { - if (Object.isUndefined(value)) return element.value; - else element.value = value; - } - - function select(element, value) { - if (Object.isUndefined(value)) - return (element.type === 'select-one' ? selectOne : selectMany)(element); - - var opt, currentValue, single = !Object.isArray(value); - for (var i = 0, length = element.length; i < length; i++) { - opt = element.options[i]; - currentValue = this.optionValue(opt); - if (single) { - if (currentValue == value) { - opt.selected = true; - return; - } - } - else opt.selected = value.include(currentValue); - } - } - - function selectOne(element) { - var index = element.selectedIndex; - return index >= 0 ? optionValue(element.options[index]) : null; - } - - function selectMany(element) { - var values, length = element.length; - if (!length) return null; - - for (var i = 0, values = []; i < length; i++) { - var opt = element.options[i]; - if (opt.selected) values.push(optionValue(opt)); - } - return values; - } - - function optionValue(opt) { - return Element.hasAttribute(opt, 'value') ? opt.value : opt.text; - } - - return { - input: input, - inputSelector: inputSelector, - textarea: valueSelector, - select: select, - selectOne: selectOne, - selectMany: selectMany, - optionValue: optionValue, - button: valueSelector - }; -})(); - -/*--------------------------------------------------------------------------*/ - - -Abstract.TimedObserver = Class.create(PeriodicalExecuter, { - initialize: function($super, element, frequency, callback) { - $super(callback, frequency); - this.element = $(element); - this.lastValue = this.getValue(); - }, - - execute: function() { - var value = this.getValue(); - if (Object.isString(this.lastValue) && Object.isString(value) ? - this.lastValue != value : String(this.lastValue) != String(value)) { - this.callback(this.element, value); - this.lastValue = value; - } - } -}); - -Form.Element.Observer = Class.create(Abstract.TimedObserver, { - getValue: function() { - return Form.Element.getValue(this.element); - } -}); - -Form.Observer = Class.create(Abstract.TimedObserver, { - getValue: function() { - return Form.serialize(this.element); - } -}); - -/*--------------------------------------------------------------------------*/ - -Abstract.EventObserver = Class.create({ - initialize: function(element, callback) { - this.element = $(element); - this.callback = callback; - - this.lastValue = this.getValue(); - if (this.element.tagName.toLowerCase() == 'form') - this.registerFormCallbacks(); - else - this.registerCallback(this.element); - }, - - onElementEvent: function() { - var value = this.getValue(); - if (this.lastValue != value) { - this.callback(this.element, value); - this.lastValue = value; - } - }, - - registerFormCallbacks: function() { - Form.getElements(this.element).each(this.registerCallback, this); - }, - - registerCallback: function(element) { - if (element.type) { - switch (element.type.toLowerCase()) { - case 'checkbox': - case 'radio': - Event.observe(element, 'click', this.onElementEvent.bind(this)); - break; - default: - Event.observe(element, 'change', this.onElementEvent.bind(this)); - break; - } - } - } -}); - -Form.Element.EventObserver = Class.create(Abstract.EventObserver, { - getValue: function() { - return Form.Element.getValue(this.element); - } -}); - -Form.EventObserver = Class.create(Abstract.EventObserver, { - getValue: function() { - return Form.serialize(this.element); - } -}); -(function(GLOBAL) { - var DIV = document.createElement('div'); - var docEl = document.documentElement; - var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl - && 'onmouseleave' in docEl; - - var Event = { - KEY_BACKSPACE: 8, - KEY_TAB: 9, - KEY_RETURN: 13, - KEY_ESC: 27, - KEY_LEFT: 37, - KEY_UP: 38, - KEY_RIGHT: 39, - KEY_DOWN: 40, - KEY_DELETE: 46, - KEY_HOME: 36, - KEY_END: 35, - KEY_PAGEUP: 33, - KEY_PAGEDOWN: 34, - KEY_INSERT: 45 - }; - - - var isIELegacyEvent = function(event) { return false; }; - - if (window.attachEvent) { - if (window.addEventListener) { - isIELegacyEvent = function(event) { - return !(event instanceof window.Event); - }; - } else { - isIELegacyEvent = function(event) { return true; }; - } - } - - var _isButton; - - function _isButtonForDOMEvents(event, code) { - return event.which ? (event.which === code + 1) : (event.button === code); - } - - var legacyButtonMap = { 0: 1, 1: 4, 2: 2 }; - function _isButtonForLegacyEvents(event, code) { - return event.button === legacyButtonMap[code]; - } - - function _isButtonForWebKit(event, code) { - switch (code) { - case 0: return event.which == 1 && !event.metaKey; - case 1: return event.which == 2 || (event.which == 1 && event.metaKey); - case 2: return event.which == 3; - default: return false; - } - } - - if (window.attachEvent) { - if (!window.addEventListener) { - _isButton = _isButtonForLegacyEvents; - } else { - _isButton = function(event, code) { - return isIELegacyEvent(event) ? _isButtonForLegacyEvents(event, code) : - _isButtonForDOMEvents(event, code); - } - } - } else if (Prototype.Browser.WebKit) { - _isButton = _isButtonForWebKit; - } else { - _isButton = _isButtonForDOMEvents; - } - - function isLeftClick(event) { return _isButton(event, 0) } - - function isMiddleClick(event) { return _isButton(event, 1) } - - function isRightClick(event) { return _isButton(event, 2) } - - function element(event) { - return Element.extend(_element(event)); - } - - function _element(event) { - event = Event.extend(event); - - var node = event.target, type = event.type, - currentTarget = event.currentTarget; - - if (currentTarget && currentTarget.tagName) { - if (type === 'load' || type === 'error' || - (type === 'click' && currentTarget.tagName.toLowerCase() === 'input' - && currentTarget.type === 'radio')) - node = currentTarget; - } - - return node.nodeType == Node.TEXT_NODE ? node.parentNode : node; - } - - function findElement(event, expression) { - var element = _element(event), selector = Prototype.Selector; - if (!expression) return Element.extend(element); - while (element) { - if (Object.isElement(element) && selector.match(element, expression)) - return Element.extend(element); - element = element.parentNode; - } - } - - function pointer(event) { - return { x: pointerX(event), y: pointerY(event) }; - } - - function pointerX(event) { - var docElement = document.documentElement, - body = document.body || { scrollLeft: 0 }; - - return event.pageX || (event.clientX + - (docElement.scrollLeft || body.scrollLeft) - - (docElement.clientLeft || 0)); - } - - function pointerY(event) { - var docElement = document.documentElement, - body = document.body || { scrollTop: 0 }; - - return event.pageY || (event.clientY + - (docElement.scrollTop || body.scrollTop) - - (docElement.clientTop || 0)); - } - - - function stop(event) { - Event.extend(event); - event.preventDefault(); - event.stopPropagation(); - - event.stopped = true; - } - - - Event.Methods = { - isLeftClick: isLeftClick, - isMiddleClick: isMiddleClick, - isRightClick: isRightClick, - - element: element, - findElement: findElement, - - pointer: pointer, - pointerX: pointerX, - pointerY: pointerY, - - stop: stop - }; - - var methods = Object.keys(Event.Methods).inject({ }, function(m, name) { - m[name] = Event.Methods[name].methodize(); - return m; - }); - - if (window.attachEvent) { - function _relatedTarget(event) { - var element; - switch (event.type) { - case 'mouseover': - case 'mouseenter': - element = event.fromElement; - break; - case 'mouseout': - case 'mouseleave': - element = event.toElement; - break; - default: - return null; - } - return Element.extend(element); - } - - var additionalMethods = { - stopPropagation: function() { this.cancelBubble = true }, - preventDefault: function() { this.returnValue = false }, - inspect: function() { return '[object Event]' } - }; - - Event.extend = function(event, element) { - if (!event) return false; - - if (!isIELegacyEvent(event)) return event; - - if (event._extendedByPrototype) return event; - event._extendedByPrototype = Prototype.emptyFunction; - - var pointer = Event.pointer(event); - - Object.extend(event, { - target: event.srcElement || element, - relatedTarget: _relatedTarget(event), - pageX: pointer.x, - pageY: pointer.y - }); - - Object.extend(event, methods); - Object.extend(event, additionalMethods); - - return event; - }; - } else { - Event.extend = Prototype.K; - } - - if (window.addEventListener) { - Event.prototype = window.Event.prototype || document.createEvent('HTMLEvents').__proto__; - Object.extend(Event.prototype, methods); - } - - var EVENT_TRANSLATIONS = { - mouseenter: 'mouseover', - mouseleave: 'mouseout' - }; - - function getDOMEventName(eventName) { - return EVENT_TRANSLATIONS[eventName] || eventName; - } - - if (MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED) - getDOMEventName = Prototype.K; - - function getUniqueElementID(element) { - if (element === window) return 0; - - if (typeof element._prototypeUID === 'undefined') - element._prototypeUID = Element.Storage.UID++; - return element._prototypeUID; - } - - function getUniqueElementID_IE(element) { - if (element === window) return 0; - if (element == document) return 1; - return element.uniqueID; - } - - if ('uniqueID' in DIV) - getUniqueElementID = getUniqueElementID_IE; - - function isCustomEvent(eventName) { - return eventName.include(':'); - } - - Event._isCustomEvent = isCustomEvent; - - function getOrCreateRegistryFor(element, uid) { - var CACHE = GLOBAL.Event.cache; - if (Object.isUndefined(uid)) - uid = getUniqueElementID(element); - if (!CACHE[uid]) CACHE[uid] = { element: element }; - return CACHE[uid]; - } - - function destroyRegistryForElement(element, uid) { - if (Object.isUndefined(uid)) - uid = getUniqueElementID(element); - delete GLOBAL.Event.cache[uid]; - } - - - function register(element, eventName, handler) { - var registry = getOrCreateRegistryFor(element); - if (!registry[eventName]) registry[eventName] = []; - var entries = registry[eventName]; - - var i = entries.length; - while (i--) - if (entries[i].handler === handler) return null; - - var uid = getUniqueElementID(element); - var responder = GLOBAL.Event._createResponder(uid, eventName, handler); - var entry = { - responder: responder, - handler: handler - }; - - entries.push(entry); - return entry; - } - - function unregister(element, eventName, handler) { - var registry = getOrCreateRegistryFor(element); - var entries = registry[eventName] || []; - - var i = entries.length, entry; - while (i--) { - if (entries[i].handler === handler) { - entry = entries[i]; - break; - } - } - - if (entry) { - var index = entries.indexOf(entry); - entries.splice(index, 1); - } - - if (entries.length === 0) { - delete registry[eventName]; - if (Object.keys(registry).length === 1 && ('element' in registry)) - destroyRegistryForElement(element); - } - - return entry; - } - - - function observe(element, eventName, handler) { - element = $(element); - var entry = register(element, eventName, handler); - - if (entry === null) return element; - - var responder = entry.responder; - if (isCustomEvent(eventName)) - observeCustomEvent(element, eventName, responder); - else - observeStandardEvent(element, eventName, responder); - - return element; - } - - function observeStandardEvent(element, eventName, responder) { - var actualEventName = getDOMEventName(eventName); - if (element.addEventListener) { - element.addEventListener(actualEventName, responder, false); - } else { - element.attachEvent('on' + actualEventName, responder); - } - } - - function observeCustomEvent(element, eventName, responder) { - if (element.addEventListener) { - element.addEventListener('dataavailable', responder, false); - } else { - element.attachEvent('ondataavailable', responder); - element.attachEvent('onlosecapture', responder); - } - } - - function stopObserving(element, eventName, handler) { - element = $(element); - var handlerGiven = !Object.isUndefined(handler), - eventNameGiven = !Object.isUndefined(eventName); - - if (!eventNameGiven && !handlerGiven) { - stopObservingElement(element); - return element; - } - - if (!handlerGiven) { - stopObservingEventName(element, eventName); - return element; - } - - var entry = unregister(element, eventName, handler); - - if (!entry) return element; - removeEvent(element, eventName, entry.responder); - return element; - } - - function stopObservingStandardEvent(element, eventName, responder) { - var actualEventName = getDOMEventName(eventName); - if (element.removeEventListener) { - element.removeEventListener(actualEventName, responder, false); - } else { - element.detachEvent('on' + actualEventName, responder); - } - } - - function stopObservingCustomEvent(element, eventName, responder) { - if (element.removeEventListener) { - element.removeEventListener('dataavailable', responder, false); - } else { - element.detachEvent('ondataavailable', responder); - element.detachEvent('onlosecapture', responder); - } - } - - - - function stopObservingElement(element) { - var uid = getUniqueElementID(element), registry = GLOBAL.Event.cache[uid]; - if (!registry) return; - - destroyRegistryForElement(element, uid); - - var entries, i; - for (var eventName in registry) { - if (eventName === 'element') continue; - - entries = registry[eventName]; - i = entries.length; - while (i--) - removeEvent(element, eventName, entries[i].responder); - } - } - - function stopObservingEventName(element, eventName) { - var registry = getOrCreateRegistryFor(element); - var entries = registry[eventName]; - if (entries) { - delete registry[eventName]; - } - - entries = entries || []; - - var i = entries.length; - while (i--) - removeEvent(element, eventName, entries[i].responder); - - for (var name in registry) { - if (name === 'element') continue; - return; // There is another registered event - } - - destroyRegistryForElement(element); - } - - - function removeEvent(element, eventName, handler) { - if (isCustomEvent(eventName)) - stopObservingCustomEvent(element, eventName, handler); - else - stopObservingStandardEvent(element, eventName, handler); - } - - - - function getFireTarget(element) { - if (element !== document) return element; - if (document.createEvent && !element.dispatchEvent) - return document.documentElement; - return element; - } - - function fire(element, eventName, memo, bubble) { - element = getFireTarget($(element)); - if (Object.isUndefined(bubble)) bubble = true; - memo = memo || {}; - - var event = fireEvent(element, eventName, memo, bubble); - return Event.extend(event); - } - - function fireEvent_DOM(element, eventName, memo, bubble) { - var event = document.createEvent('HTMLEvents'); - event.initEvent('dataavailable', bubble, true); - - event.eventName = eventName; - event.memo = memo; - - element.dispatchEvent(event); - return event; - } - - function fireEvent_IE(element, eventName, memo, bubble) { - var event = document.createEventObject(); - event.eventType = bubble ? 'ondataavailable' : 'onlosecapture'; - - event.eventName = eventName; - event.memo = memo; - - element.fireEvent(event.eventType, event); - return event; - } - - var fireEvent = document.createEvent ? fireEvent_DOM : fireEvent_IE; - - - - Event.Handler = Class.create({ - initialize: function(element, eventName, selector, callback) { - this.element = $(element); - this.eventName = eventName; - this.selector = selector; - this.callback = callback; - this.handler = this.handleEvent.bind(this); - }, - - - start: function() { - Event.observe(this.element, this.eventName, this.handler); - return this; - }, - - stop: function() { - Event.stopObserving(this.element, this.eventName, this.handler); - return this; - }, - - handleEvent: function(event) { - var element = Event.findElement(event, this.selector); - if (element) this.callback.call(this.element, event, element); - } - }); - - function on(element, eventName, selector, callback) { - element = $(element); - if (Object.isFunction(selector) && Object.isUndefined(callback)) { - callback = selector, selector = null; - } - - return new Event.Handler(element, eventName, selector, callback).start(); - } - - Object.extend(Event, Event.Methods); - - Object.extend(Event, { - fire: fire, - observe: observe, - stopObserving: stopObserving, - on: on - }); - - Element.addMethods({ - fire: fire, - - observe: observe, - - stopObserving: stopObserving, - - on: on - }); - - Object.extend(document, { - fire: fire.methodize(), - - observe: observe.methodize(), - - stopObserving: stopObserving.methodize(), - - on: on.methodize(), - - loaded: false - }); - - if (GLOBAL.Event) Object.extend(window.Event, Event); - else GLOBAL.Event = Event; - - GLOBAL.Event.cache = {}; - - function destroyCache_IE() { - GLOBAL.Event.cache = null; - } - - if (window.attachEvent) - window.attachEvent('onunload', destroyCache_IE); - - DIV = null; - docEl = null; -})(this); - -(function(GLOBAL) { - /* Code for creating leak-free event responders is based on work by - John-David Dalton. */ - - var docEl = document.documentElement; - var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl - && 'onmouseleave' in docEl; - - function isSimulatedMouseEnterLeaveEvent(eventName) { - return !MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED && - (eventName === 'mouseenter' || eventName === 'mouseleave'); - } - - function createResponder(uid, eventName, handler) { - if (Event._isCustomEvent(eventName)) - return createResponderForCustomEvent(uid, eventName, handler); - if (isSimulatedMouseEnterLeaveEvent(eventName)) - return createMouseEnterLeaveResponder(uid, eventName, handler); - - return function(event) { - if (!Event.cache) return; - - var element = Event.cache[uid].element; - Event.extend(event, element); - handler.call(element, event); - }; - } - - function createResponderForCustomEvent(uid, eventName, handler) { - return function(event) { - var cache = Event.cache[uid]; - var element = cache && cache.element; - - if (Object.isUndefined(event.eventName)) - return false; - - if (event.eventName !== eventName) - return false; - - Event.extend(event, element); - handler.call(element, event); - }; - } - - function createMouseEnterLeaveResponder(uid, eventName, handler) { - return function(event) { - var element = Event.cache[uid].element; - - Event.extend(event, element); - var parent = event.relatedTarget; - - while (parent && parent !== element) { - try { parent = parent.parentNode; } - catch(e) { parent = element; } - } - - if (parent === element) return; - handler.call(element, event); - } - } - - GLOBAL.Event._createResponder = createResponder; - docEl = null; -})(this); - -(function(GLOBAL) { - /* Support for the DOMContentLoaded event is based on work by Dan Webb, - Matthias Miller, Dean Edwards, John Resig, and Diego Perini. */ - - var TIMER; - - function fireContentLoadedEvent() { - if (document.loaded) return; - if (TIMER) window.clearTimeout(TIMER); - document.loaded = true; - document.fire('dom:loaded'); - } - - function checkReadyState() { - if (document.readyState === 'complete') { - document.detachEvent('onreadystatechange', checkReadyState); - fireContentLoadedEvent(); - } - } - - function pollDoScroll() { - try { - document.documentElement.doScroll('left'); - } catch (e) { - TIMER = pollDoScroll.defer(); - return; - } - - fireContentLoadedEvent(); - } - - - if (document.readyState === 'complete') { - fireContentLoadedEvent(); - return; - } - - if (document.addEventListener) { - document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false); - } else { - document.attachEvent('onreadystatechange', checkReadyState); - if (window == top) TIMER = pollDoScroll.defer(); - } - - Event.observe(window, 'load', fireContentLoadedEvent); -})(this); - - -Element.addMethods(); -/*------------------------------- DEPRECATED -------------------------------*/ - -Hash.toQueryString = Object.toQueryString; - -var Toggle = { display: Element.toggle }; - -Element.addMethods({ - childOf: Element.Methods.descendantOf -}); - -var Insertion = { - Before: function(element, content) { - return Element.insert(element, {before:content}); - }, - - Top: function(element, content) { - return Element.insert(element, {top:content}); - }, - - Bottom: function(element, content) { - return Element.insert(element, {bottom:content}); - }, - - After: function(element, content) { - return Element.insert(element, {after:content}); - } -}; - -var $continue = new Error('"throw $continue" is deprecated, use "return" instead'); - -var Position = { - includeScrollOffsets: false, - - prepare: function() { - this.deltaX = window.pageXOffset - || document.documentElement.scrollLeft - || document.body.scrollLeft - || 0; - this.deltaY = window.pageYOffset - || document.documentElement.scrollTop - || document.body.scrollTop - || 0; - }, - - within: function(element, x, y) { - if (this.includeScrollOffsets) - return this.withinIncludingScrolloffsets(element, x, y); - this.xcomp = x; - this.ycomp = y; - this.offset = Element.cumulativeOffset(element); - - return (y >= this.offset[1] && - y < this.offset[1] + element.offsetHeight && - x >= this.offset[0] && - x < this.offset[0] + element.offsetWidth); - }, - - withinIncludingScrolloffsets: function(element, x, y) { - var offsetcache = Element.cumulativeScrollOffset(element); - - this.xcomp = x + offsetcache[0] - this.deltaX; - this.ycomp = y + offsetcache[1] - this.deltaY; - this.offset = Element.cumulativeOffset(element); - - return (this.ycomp >= this.offset[1] && - this.ycomp < this.offset[1] + element.offsetHeight && - this.xcomp >= this.offset[0] && - this.xcomp < this.offset[0] + element.offsetWidth); - }, - - overlap: function(mode, element) { - if (!mode) return 0; - if (mode == 'vertical') - return ((this.offset[1] + element.offsetHeight) - this.ycomp) / - element.offsetHeight; - if (mode == 'horizontal') - return ((this.offset[0] + element.offsetWidth) - this.xcomp) / - element.offsetWidth; - }, - - - cumulativeOffset: Element.Methods.cumulativeOffset, - - positionedOffset: Element.Methods.positionedOffset, - - absolutize: function(element) { - Position.prepare(); - return Element.absolutize(element); - }, - - relativize: function(element) { - Position.prepare(); - return Element.relativize(element); - }, - - realOffset: Element.Methods.cumulativeScrollOffset, - - offsetParent: Element.Methods.getOffsetParent, - - page: Element.Methods.viewportOffset, - - clone: function(source, target, options) { - options = options || { }; - return Element.clonePosition(target, source, options); - } -}; - -/*--------------------------------------------------------------------------*/ - -if (!document.getElementsByClassName) document.getElementsByClassName = function(instanceMethods){ - function iter(name) { - return name.blank() ? null : "[contains(concat(' ', @class, ' '), ' " + name + " ')]"; - } - - instanceMethods.getElementsByClassName = Prototype.BrowserFeatures.XPath ? - function(element, className) { - className = className.toString().strip(); - var cond = /\s/.test(className) ? $w(className).map(iter).join('') : iter(className); - return cond ? document._getElementsByXPath('.//*' + cond, element) : []; - } : function(element, className) { - className = className.toString().strip(); - var elements = [], classNames = (/\s/.test(className) ? $w(className) : null); - if (!classNames && !className) return elements; - - var nodes = $(element).getElementsByTagName('*'); - className = ' ' + className + ' '; - - for (var i = 0, child, cn; child = nodes[i]; i++) { - if (child.className && (cn = ' ' + child.className + ' ') && (cn.include(className) || - (classNames && classNames.all(function(name) { - return !name.toString().blank() && cn.include(' ' + name + ' '); - })))) - elements.push(Element.extend(child)); - } - return elements; - }; - - return function(className, parentElement) { - return $(parentElement || document.body).getElementsByClassName(className); - }; -}(Element.Methods); - -/*--------------------------------------------------------------------------*/ - -Element.ClassNames = Class.create(); -Element.ClassNames.prototype = { - initialize: function(element) { - this.element = $(element); - }, - - _each: function(iterator, context) { - this.element.className.split(/\s+/).select(function(name) { - return name.length > 0; - })._each(iterator, context); - }, - - set: function(className) { - this.element.className = className; - }, - - add: function(classNameToAdd) { - if (this.include(classNameToAdd)) return; - this.set($A(this).concat(classNameToAdd).join(' ')); - }, - - remove: function(classNameToRemove) { - if (!this.include(classNameToRemove)) return; - this.set($A(this).without(classNameToRemove).join(' ')); - }, - - toString: function() { - return $A(this).join(' '); - } -}; - -Object.extend(Element.ClassNames.prototype, Enumerable); - -/*--------------------------------------------------------------------------*/ - -(function() { - window.Selector = Class.create({ - initialize: function(expression) { - this.expression = expression.strip(); - }, - - findElements: function(rootElement) { - return Prototype.Selector.select(this.expression, rootElement); - }, - - match: function(element) { - return Prototype.Selector.match(element, this.expression); - }, - - toString: function() { - return this.expression; - }, - - inspect: function() { - return "#"; - } - }); - - Object.extend(Selector, { - matchElements: function(elements, expression) { - var match = Prototype.Selector.match, - results = []; - - for (var i = 0, length = elements.length; i < length; i++) { - var element = elements[i]; - if (match(element, expression)) { - results.push(Element.extend(element)); - } - } - return results; - }, - - findElement: function(elements, expression, index) { - index = index || 0; - var matchIndex = 0, element; - for (var i = 0, length = elements.length; i < length; i++) { - element = elements[i]; - if (Prototype.Selector.match(element, expression) && index === matchIndex++) { - return Element.extend(element); - } - } - }, - - findChildElements: function(element, expressions) { - var selector = expressions.toArray().join(', '); - return Prototype.Selector.select(selector, element || document); - } - }); -})(); diff --git a/static/js/youp0m.js b/static/js/youp0m.js index 4b7c49d..2cb2ad4 100644 --- a/static/js/youp0m.js +++ b/static/js/youp0m.js @@ -3,12 +3,16 @@ var api_url = "/api/images"; var img_url = "/images/"; function get_picts(then, then_value) { - new Ajax.Request(api_url, { - method: 'get', - onSuccess: function(transport) { - picts = transport.responseText.evalJSON(); - if (then) then(then_value); - }, + fetch(api_url) + .then(function(response) { + return response.json(); + }) + .then(function(my_picts) { + picts = my_picts; + if (then) then(then_value); + }) + .catch(function(error) { + display_error(error); }); } @@ -69,16 +73,16 @@ function show_picture(id) { function get_picture(id) { if (id == null) id = "last"; - new Ajax.Request(api_url + "/" + id, { - method: 'get', - onSuccess: function(transport) { - var response = transport.responseText.evalJSON(); - display_picture(response); - }, - onFailure: function(transport) { - var response = transport.responseText.evalJSON(); - display_error(response["errmsg"]); - } + + fetch(api_url + "/" + id) + .then(function(response) { + return response.json(); + }) + .then(function(my_pict) { + display_picture(my_pict); + }) + .catch(function(error) { + display_error(error); }); } From 3dd22ecb09965f4d63991c264538e73ab7e6d0e4 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Mon, 2 Sep 2019 15:41:37 +0200 Subject: [PATCH 07/62] In production mode, embed static content --- .gitignore | 1 + main.go | 9 ++++----- static-dev.go | 39 +++++++++++++++++++++++++++++++++++++++ static.go | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 5 deletions(-) create mode 100644 static-dev.go create mode 100644 static.go diff --git a/.gitignore b/.gitignore index 71975ac..e943f04 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ +bindata.go youp0m diff --git a/main.go b/main.go index d727a97..2e7821e 100644 --- a/main.go +++ b/main.go @@ -8,6 +8,8 @@ import ( "path/filepath" ) +var mux = http.NewServeMux() + var PublishedImgDir string var NextImgDir string var ThumbsDir string @@ -61,12 +63,9 @@ func main() { } } - mux := http.NewServeMux() mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - http.ServeFile(w, r, filepath.Join(staticDir, "index.html")) + serveStaticAsset(w, r, "index.html") }) - mux.Handle("/css/", http.FileServer(http.Dir(staticDir))) - mux.Handle("/js/", http.FileServer(http.Dir(staticDir))) mux.Handle("/api/", http.StripPrefix("/api", ApiHandler(authFunc))) @@ -101,7 +100,7 @@ func main() { w.Header().Set("WWW-Authenticate", "Basic realm=\"YouP0m\"") http.Error(w, "You are not allowed to perform this request.", http.StatusUnauthorized) } else { - http.ServeFile(w, r, filepath.Join(staticDir, "admin.html")) + serveStaticAsset(w, r, "admin.html") } }) diff --git a/static-dev.go b/static-dev.go new file mode 100644 index 0000000..36215fa --- /dev/null +++ b/static-dev.go @@ -0,0 +1,39 @@ +// +build dev + +package main + +import ( + "flag" + "net/http" + "os" + "path/filepath" +) + +var StaticDir string = "static/" + +func init() { + mux.Handle("/css/", http.FileServer(http.Dir(StaticDir))) + mux.Handle("/js/", http.FileServer(http.Dir(StaticDir))) + + flag.StringVar(&StaticDir, "static", StaticDir, "Directory containing static files") +} + +func serveStaticAsset(w http.ResponseWriter, r *http.Request, url string) { + if url == "index.html" { + r.URL.Path = "/" + } else { + r.URL.Path = "/" + url + } + http.FileServer(http.Dir(StaticDir)).ServeHTTP(w, r) +} + +func sanitizeStaticOptions() error { + StaticDir, _ := filepath.Abs("static") + if _, err := os.Stat(StaticDir); os.IsNotExist(err) { + StaticDir, _ = filepath.Abs(filepath.Join(filepath.Dir(os.Args[0]), "static")) + if _, err := os.Stat(StaticDir); os.IsNotExist(err) { + return err + } + } + return nil +} diff --git a/static.go b/static.go new file mode 100644 index 0000000..b4340fe --- /dev/null +++ b/static.go @@ -0,0 +1,36 @@ +// +build !dev + +package main + +import ( + "net/http" + "path" +) + +//go:generate go-bindata -ignore "\\.go|\\.less" -pkg "main" -o "bindata.go" static/... +//go:generate go fmt bindata.go + +const StaticDir string = "./static/" + +func init() { + mux.HandleFunc("/css/", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "text/css") + serveStaticAsset(w, r, r.URL.Path) + }) + mux.HandleFunc("/js/", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "text/javascript") + serveStaticAsset(w, r, r.URL.Path) + }) +} + +func serveStaticAsset(w http.ResponseWriter, r *http.Request, url string) { + if data, err := Asset(path.Join(StaticDir, url)); err != nil { + http.NotFound(w, r) + } else { + w.Write(data) + } +} + +func sanitizeStaticOptions() error { + return nil +} From dd8305ec06661a355f6b68850c86bacaafcc2325 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Wed, 16 Oct 2019 03:01:32 +0200 Subject: [PATCH 08/62] Move go-crypt to gitlab --- auth.go | 2 +- vendor/{github.com => gitlab.com}/nyarla/go-crypt/.travis.yml | 0 vendor/{github.com => gitlab.com}/nyarla/go-crypt/LICENSE | 0 vendor/{github.com => gitlab.com}/nyarla/go-crypt/README.md | 0 vendor/{github.com => gitlab.com}/nyarla/go-crypt/crypt.go | 0 vendor/{github.com => gitlab.com}/nyarla/go-crypt/crypt_test.go | 0 vendor/{github.com => gitlab.com}/nyarla/go-crypt/doc.go | 0 7 files changed, 1 insertion(+), 1 deletion(-) rename vendor/{github.com => gitlab.com}/nyarla/go-crypt/.travis.yml (100%) rename vendor/{github.com => gitlab.com}/nyarla/go-crypt/LICENSE (100%) rename vendor/{github.com => gitlab.com}/nyarla/go-crypt/README.md (100%) rename vendor/{github.com => gitlab.com}/nyarla/go-crypt/crypt.go (100%) rename vendor/{github.com => gitlab.com}/nyarla/go-crypt/crypt_test.go (100%) rename vendor/{github.com => gitlab.com}/nyarla/go-crypt/doc.go (100%) diff --git a/auth.go b/auth.go index 4112116..0860bd9 100644 --- a/auth.go +++ b/auth.go @@ -6,7 +6,7 @@ import ( "os" "strings" - "github.com/nyarla/go-crypt" + "gitlab.com/nyarla/go-crypt" ) type User struct { diff --git a/vendor/github.com/nyarla/go-crypt/.travis.yml b/vendor/gitlab.com/nyarla/go-crypt/.travis.yml similarity index 100% rename from vendor/github.com/nyarla/go-crypt/.travis.yml rename to vendor/gitlab.com/nyarla/go-crypt/.travis.yml diff --git a/vendor/github.com/nyarla/go-crypt/LICENSE b/vendor/gitlab.com/nyarla/go-crypt/LICENSE similarity index 100% rename from vendor/github.com/nyarla/go-crypt/LICENSE rename to vendor/gitlab.com/nyarla/go-crypt/LICENSE diff --git a/vendor/github.com/nyarla/go-crypt/README.md b/vendor/gitlab.com/nyarla/go-crypt/README.md similarity index 100% rename from vendor/github.com/nyarla/go-crypt/README.md rename to vendor/gitlab.com/nyarla/go-crypt/README.md diff --git a/vendor/github.com/nyarla/go-crypt/crypt.go b/vendor/gitlab.com/nyarla/go-crypt/crypt.go similarity index 100% rename from vendor/github.com/nyarla/go-crypt/crypt.go rename to vendor/gitlab.com/nyarla/go-crypt/crypt.go diff --git a/vendor/github.com/nyarla/go-crypt/crypt_test.go b/vendor/gitlab.com/nyarla/go-crypt/crypt_test.go similarity index 100% rename from vendor/github.com/nyarla/go-crypt/crypt_test.go rename to vendor/gitlab.com/nyarla/go-crypt/crypt_test.go diff --git a/vendor/github.com/nyarla/go-crypt/doc.go b/vendor/gitlab.com/nyarla/go-crypt/doc.go similarity index 100% rename from vendor/github.com/nyarla/go-crypt/doc.go rename to vendor/gitlab.com/nyarla/go-crypt/doc.go From c622ada0df8ebd8f793e643293e32e49f58d0d9e Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Wed, 16 Oct 2019 03:01:46 +0200 Subject: [PATCH 09/62] Add go module --- go.mod | 8 ++++++++ go.sum | 4 ++++ 2 files changed, 12 insertions(+) create mode 100644 go.mod create mode 100644 go.sum diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..5fc81f9 --- /dev/null +++ b/go.mod @@ -0,0 +1,8 @@ +module git.nemunai.re/youp0m + +go 1.10 + +require ( + github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 + gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..2acb4d9 --- /dev/null +++ b/go.sum @@ -0,0 +1,4 @@ +github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= +github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= +gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b h1:7gd+rd8P3bqcn/96gOZa3F5dpJr/vEiDQYlNb/y2uNs= +gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2cqquPa0MKWeNkmOM5RQsRhkrwMWonFMN7fE= From 0876fc3c2edf2f3912ed9b1f841964cce096baf0 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sun, 1 Sep 2019 17:13:03 +0200 Subject: [PATCH 10/62] Use the Fetch API instead of PrototypeJS --- static/admin.html | 5 ++--- static/js/youp0m.js | 7 ++++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/static/admin.html b/static/admin.html index c1b1445..2fc8f91 100644 --- a/static/admin.html +++ b/static/admin.html @@ -4,9 +4,6 @@ YouP0m Administration - - -

Welcome on YouP0m!

@@ -19,5 +16,7 @@ + + diff --git a/static/js/youp0m.js b/static/js/youp0m.js index 2cb2ad4..73dac11 100644 --- a/static/js/youp0m.js +++ b/static/js/youp0m.js @@ -50,6 +50,11 @@ function show_picture(id) { return; } + if (picts.length == 0) { + document.body.innerHTML = '

Welcome on YouP0m!

There is no image currently, come back soon!

'; + return + } + if (id == null || id == "") id = picts[Math.floor(Math.random() * picts.length)].name; @@ -112,7 +117,7 @@ function display_picture(pict, next) { } function display_error(msg) { - $$("body")[0].innerHTML = '

An error occurs

' + msg + '

'; + document.body.innerHTML = '

An error occurs

' + msg + '

'; } function sync() { From deb4ff03caba8301e0a1d103fed6b5e8ab80d1fd Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Mon, 2 Sep 2019 15:41:37 +0200 Subject: [PATCH 11/62] In production mode, embed static content --- main.go | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/main.go b/main.go index 2e7821e..a77b44e 100644 --- a/main.go +++ b/main.go @@ -5,7 +5,6 @@ import ( "log" "net/http" "os" - "path/filepath" ) var mux = http.NewServeMux() @@ -55,12 +54,8 @@ func main() { log.Println("Registering handlers...") authFunc := func(r *http.Request) *User { return Authenticate(*htpasswd, r) } - staticDir, _ := filepath.Abs("static") - if _, err := os.Stat(staticDir); os.IsNotExist(err) { - staticDir, _ = filepath.Abs(filepath.Join(filepath.Dir(os.Args[0]), "static")) - if _, err := os.Stat(staticDir); os.IsNotExist(err) { - log.Fatal(err) - } + if err := sanitizeStaticOptions(); err != nil { + log.Fatal(err) } mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { From 80dca4434d1d4d504a8b4fd0e9c81e758e1c9135 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Wed, 16 Oct 2019 15:36:50 +0200 Subject: [PATCH 12/62] Fix use of path given| by -static when compiled in dev --- static-dev.go | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/static-dev.go b/static-dev.go index 36215fa..0dcb2dd 100644 --- a/static-dev.go +++ b/static-dev.go @@ -12,8 +12,14 @@ import ( var StaticDir string = "static/" func init() { - mux.Handle("/css/", http.FileServer(http.Dir(StaticDir))) - mux.Handle("/js/", http.FileServer(http.Dir(StaticDir))) + mux.HandleFunc("/css/", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "text/css") + serveStaticAsset(w, r, r.URL.Path) + }) + mux.HandleFunc("/js/", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "text/javascript") + serveStaticAsset(w, r, r.URL.Path) + }) flag.StringVar(&StaticDir, "static", StaticDir, "Directory containing static files") } @@ -28,7 +34,7 @@ func serveStaticAsset(w http.ResponseWriter, r *http.Request, url string) { } func sanitizeStaticOptions() error { - StaticDir, _ := filepath.Abs("static") + StaticDir, _ = filepath.Abs(StaticDir) if _, err := os.Stat(StaticDir); os.IsNotExist(err) { StaticDir, _ = filepath.Abs(filepath.Join(filepath.Dir(os.Args[0]), "static")) if _, err := os.Stat(StaticDir); os.IsNotExist(err) { From 5f62fdef66899fa851dfd6bdddec3b1eba273282 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sun, 18 Oct 2020 18:32:36 +0200 Subject: [PATCH 13/62] Add drone CI --- .drone.yml | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 .drone.yml diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..ebfea21 --- /dev/null +++ b/.drone.yml @@ -0,0 +1,29 @@ +--- +kind: pipeline +type: docker +name: default + +platform: + os: linux + arch: arm64 + +steps: + - name: build + image: golang:alpine + commands: + - apk --no-cache add git go-bindata + - go generate -v + - go get -v -d + - go build -v -o youp0m + - wget -O Dockerfile https://ouaset.masr.nemunai.re/local/Dockerfile-youp0m + + - name: docker + image: plugins/docker + settings: + repo: nemunaire/youp0m + auto_tag: true + auto_tag_suffix: ${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH} + username: + from_secret: docker_username + password: + from_secret: docker_password From 2cc038968f6845ca158b9bc3dc8c80c09c4a0333 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sun, 18 Oct 2020 18:34:14 +0200 Subject: [PATCH 14/62] Add drone CI --- .drone.yml | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/.drone.yml b/.drone.yml index ebfea21..906f1f8 100644 --- a/.drone.yml +++ b/.drone.yml @@ -1,7 +1,7 @@ --- kind: pipeline type: docker -name: default +name: linux-arm64 platform: os: linux @@ -15,9 +15,41 @@ steps: - go generate -v - go get -v -d - go build -v -o youp0m - - wget -O Dockerfile https://ouaset.masr.nemunai.re/local/Dockerfile-youp0m + - wget -O Dockerfile https://ankh.serekh.nemunai.re/local/Dockerfile-youp0m + - wget -O entrypoint.sh https://ankh.serekh.nemunai.re/local/entrypoint.sh-youp0m && chmod +x entrypoint.sh - - name: docker + - name: publish + image: plugins/docker + settings: + repo: nemunaire/youp0m + auto_tag: true + auto_tag_suffix: ${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH} + username: + from_secret: docker_username + password: + from_secret: docker_password + +--- +kind: pipeline +type: docker +name: linux-arm + +platform: + os: linux + arch: arm + +steps: + - name: build + image: golang:alpine + commands: + - apk --no-cache add git go-bindata + - go generate -v + - go get -v -d + - go build -v -o youp0m + - wget -O Dockerfile https://ankh.serekh.nemunai.re/local/Dockerfile-youp0m + - wget -O entrypoint.sh https://ankh.serekh.nemunai.re/local/entrypoint.sh-youp0m && chmod +x entrypoint.sh + + - name: publish image: plugins/docker settings: repo: nemunaire/youp0m From db8a42eebf73d89223e0eaefb6e0e43f10c3829c Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Tue, 3 Aug 2021 09:10:10 +0000 Subject: [PATCH 15/62] Add renovate.json --- renovate.json | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 renovate.json diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..7190a60 --- /dev/null +++ b/renovate.json @@ -0,0 +1,3 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json" +} From f707954bd07b8f7c53682843f1150fc231209ab7 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Wed, 15 Sep 2021 18:06:52 +0200 Subject: [PATCH 16/62] CD: Add docker image manifest --- .drone-manifest.yml | 22 ++++++++++++++++ .drone.yml | 62 +++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 .drone-manifest.yml diff --git a/.drone-manifest.yml b/.drone-manifest.yml new file mode 100644 index 0000000..ade2314 --- /dev/null +++ b/.drone-manifest.yml @@ -0,0 +1,22 @@ +image: nemunaire/youp0m:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}latest{{/if}} +{{#if build.tags}} +tags: +{{#each build.tags}} + - {{this}} +{{/each}} +{{/if}} +manifests: + - image: nemunaire/youp0m:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}linux-amd64 + platform: + architecture: amd64 + os: linux + - image: nemunaire/youp0m:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}linux-arm64 + platform: + architecture: arm64 + os: linux + variant: v8 + - image: nemunaire/youp0m:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}linux-arm + platform: + architecture: arm + os: linux + variant: v7 diff --git a/.drone.yml b/.drone.yml index 906f1f8..8b6498c 100644 --- a/.drone.yml +++ b/.drone.yml @@ -1,7 +1,7 @@ --- kind: pipeline type: docker -name: linux-arm64 +name: build-arm64 platform: os: linux @@ -32,7 +32,38 @@ steps: --- kind: pipeline type: docker -name: linux-arm +name: build-amd64 + +platform: + os: linux + arch: amd64 + +steps: + - name: build + image: golang:alpine + commands: + - apk --no-cache add git go-bindata + - go generate -v + - go get -v -d + - go build -v -o youp0m + - wget -O Dockerfile https://ankh.serekh.nemunai.re/local/Dockerfile-youp0m + - wget -O entrypoint.sh https://ankh.serekh.nemunai.re/local/entrypoint.sh-youp0m && chmod +x entrypoint.sh + + - name: publish + image: plugins/docker + settings: + repo: nemunaire/youp0m + auto_tag: true + auto_tag_suffix: ${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH} + username: + from_secret: docker_username + password: + from_secret: docker_password + +--- +kind: pipeline +type: docker +name: build-arm platform: os: linux @@ -59,3 +90,30 @@ steps: from_secret: docker_username password: from_secret: docker_password + +--- +kind: pipeline +name: docker-manifest + +steps: +- name: publish + image: plugins/manifest + settings: + auto_tag: true + ignore_missing: true + spec: .drone-manifest.yml + username: + from_secret: docker_username + password: + from_secret: docker_password + +trigger: + event: + - cron + - push + - tag + +depends_on: +- build-arm +- build-arm64 +- build-amd64 From 9d031ea9f9e5a0156e187bfc18337df8e503b1e2 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Wed, 15 Sep 2021 18:09:35 +0200 Subject: [PATCH 17/62] Refactor admin --- static/css/style.css | 18 +++++++++++++++ static/js/youp0m-admin.js | 46 +++++++++++++++++++++++++++++++++----- static/js/youp0m.js | 47 +++++++++++++++++++++++---------------- 3 files changed, 87 insertions(+), 24 deletions(-) diff --git a/static/css/style.css b/static/css/style.css index 8b7b6f2..cdf4039 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -28,6 +28,24 @@ figure.moz { vertical-align: middle; } +figure.moz .menu { + position: absolute; + margin: inherit; + display: none; +} +figure.moz:hover .menu { + display: block; +} +figure.moz:hover .menu a { + background: rgba(0,0,0,0.5); + color: #eee; + padding: 6px 10px 8px 10px; + text-decoration: none; +} +figure.moz .menu a:hover { + background: rgba(0,0,0,0.8); +} + .big img { max-height: calc(100vh - 5px); max-width: calc(100vw - 5px); diff --git a/static/js/youp0m-admin.js b/static/js/youp0m-admin.js index 43f3341..c4a504c 100644 --- a/static/js/youp0m-admin.js +++ b/static/js/youp0m-admin.js @@ -1,11 +1,47 @@ api_url = "/api/next/"; img_url = "/images/next/"; -function admin_ctrl(figure) { - var menu = document.createElement("ul"); - var item = document.createElement("li", "test"); - menu.appendChild(item); - figure.appendChild(menu) +function publish_pict(pict) { + fetch(api_url + "/" + pict.name + "/publish").then(response => { + picts = null; + sync() + }); +} + +function delete_pict(pict) { + fetch(api_url + "/" + pict.name, { method: "DELETE" }).then(response => { + picts = null; + sync() + }); +} + +function admin_ctrl(pict) { + var figure = document.createElement("figure"); + figure.className = "moz"; + var img = document.createElement("img"); + img.src = img_url + pict.name; + img.alt = pict.name; + var div = document.createElement("div"); + div.className = "menu" + var linkPub = document.createElement("a"); + linkPub.onclick = function(e) { + publish_pict(pict); + return false; + }; + linkPub.href = "#"; + linkPub.innerHTML = "Publier"; + var linkDel = document.createElement("a"); + linkDel.onclick = function(e) { + delete_pict(pict); + return false; + }; + linkDel.href = "#"; + linkDel.innerHTML = "Supprimer"; + div.appendChild(linkPub); + div.appendChild(linkDel); + figure.appendChild(div); + figure.appendChild(img); + document.body.appendChild(figure); } function sync() { diff --git a/static/js/youp0m.js b/static/js/youp0m.js index 73dac11..00fe883 100644 --- a/static/js/youp0m.js +++ b/static/js/youp0m.js @@ -16,32 +16,41 @@ function get_picts(then, then_value) { }); } -function show_mozaic() { +function show_mozaic(callpict) { if (!picts) { - get_picts(show_mozaic); + get_picts(show_mozaic, callpict); return; } + if (!picts.length) { + document.body.innerHTML = '

Welcome on YouP0m!

There is no image currently, come back soon!

'; + return; + } + + if (!callpict) { + callpict = function (pict) { + var figure = document.createElement("figure"); + figure.className = "moz"; + var img = document.createElement("img"); + img.src = img_url + pict.name; + img.alt = pict.name; + var link = document.createElement("a"); + link.onclick = function(e) { + window.history.pushState(null, "YouP0m", link.href); + sync(); + return false; + }; + link.href = "/" + pict.name; + link.appendChild(img); + figure.appendChild(link); + document.body.appendChild(figure); + } + } + while (document.body.hasChildNodes()) document.body.removeChild(document.body.lastChild); - picts.forEach(function (pict) { - var figure = document.createElement("figure"); - figure.className = "moz"; - var img = document.createElement("img"); - img.src = img_url + pict.name; - img.alt = pict.name; - var link = document.createElement("a"); - link.onclick = function(e) { - window.history.pushState(null, "YouP0m", link.href); - sync(); - return false; - }; - link.href = "/" + pict.name; - link.appendChild(img); - figure.appendChild(link); - document.body.appendChild(figure); - }); + picts.forEach(callpict); } function show_picture(id) { From 187d71cb5b99616d370b46614a305af6ff305e62 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Wed, 22 Sep 2021 09:59:21 +0200 Subject: [PATCH 18/62] Enable image squash --- .drone.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.drone.yml b/.drone.yml index 8b6498c..aff4b74 100644 --- a/.drone.yml +++ b/.drone.yml @@ -24,6 +24,8 @@ steps: repo: nemunaire/youp0m auto_tag: true auto_tag_suffix: ${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH} + experimental: true + squash: true username: from_secret: docker_username password: @@ -55,6 +57,8 @@ steps: repo: nemunaire/youp0m auto_tag: true auto_tag_suffix: ${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH} + experimental: true + squash: true username: from_secret: docker_username password: @@ -86,6 +90,8 @@ steps: repo: nemunaire/youp0m auto_tag: true auto_tag_suffix: ${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH} + experimental: true + squash: true username: from_secret: docker_username password: From 6564d9c4fa4a25fcd765459321c3322244bfa02f Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Fri, 2 Sep 2022 17:09:13 +0200 Subject: [PATCH 19/62] Upgrade to go 1.16 and use embed module --- .drone.yml | 6 +- .gitignore | 2 +- assets-dev.go | 32 + assets.go | 28 + go.mod | 2 +- main.go | 6 +- static-dev.go | 45 -- static.go | 26 +- vendor/github.com/nfnt/resize/.travis.yml | 7 - vendor/github.com/nfnt/resize/LICENSE | 13 - vendor/github.com/nfnt/resize/README.md | 149 ----- vendor/github.com/nfnt/resize/converter.go | 438 ------------- .../github.com/nfnt/resize/converter_test.go | 43 -- vendor/github.com/nfnt/resize/filters.go | 143 ---- vendor/github.com/nfnt/resize/nearest.go | 318 --------- vendor/github.com/nfnt/resize/nearest_test.go | 57 -- vendor/github.com/nfnt/resize/resize.go | 614 ------------------ vendor/github.com/nfnt/resize/resize_test.go | 330 ---------- vendor/github.com/nfnt/resize/thumbnail.go | 55 -- .../github.com/nfnt/resize/thumbnail_test.go | 47 -- vendor/github.com/nfnt/resize/ycc.go | 227 ------- vendor/github.com/nfnt/resize/ycc_test.go | 214 ------ vendor/gitlab.com/nyarla/go-crypt/.travis.yml | 7 - vendor/gitlab.com/nyarla/go-crypt/LICENSE | 14 - vendor/gitlab.com/nyarla/go-crypt/README.md | 42 -- vendor/gitlab.com/nyarla/go-crypt/crypt.go | 276 -------- .../gitlab.com/nyarla/go-crypt/crypt_test.go | 18 - vendor/gitlab.com/nyarla/go-crypt/doc.go | 11 - 28 files changed, 71 insertions(+), 3099 deletions(-) create mode 100644 assets-dev.go create mode 100644 assets.go delete mode 100644 static-dev.go delete mode 100644 vendor/github.com/nfnt/resize/.travis.yml delete mode 100644 vendor/github.com/nfnt/resize/LICENSE delete mode 100644 vendor/github.com/nfnt/resize/README.md delete mode 100644 vendor/github.com/nfnt/resize/converter.go delete mode 100644 vendor/github.com/nfnt/resize/converter_test.go delete mode 100644 vendor/github.com/nfnt/resize/filters.go delete mode 100644 vendor/github.com/nfnt/resize/nearest.go delete mode 100644 vendor/github.com/nfnt/resize/nearest_test.go delete mode 100644 vendor/github.com/nfnt/resize/resize.go delete mode 100644 vendor/github.com/nfnt/resize/resize_test.go delete mode 100644 vendor/github.com/nfnt/resize/thumbnail.go delete mode 100644 vendor/github.com/nfnt/resize/thumbnail_test.go delete mode 100644 vendor/github.com/nfnt/resize/ycc.go delete mode 100644 vendor/github.com/nfnt/resize/ycc_test.go delete mode 100644 vendor/gitlab.com/nyarla/go-crypt/.travis.yml delete mode 100644 vendor/gitlab.com/nyarla/go-crypt/LICENSE delete mode 100644 vendor/gitlab.com/nyarla/go-crypt/README.md delete mode 100644 vendor/gitlab.com/nyarla/go-crypt/crypt.go delete mode 100644 vendor/gitlab.com/nyarla/go-crypt/crypt_test.go delete mode 100644 vendor/gitlab.com/nyarla/go-crypt/doc.go diff --git a/.drone.yml b/.drone.yml index aff4b74..ca48e19 100644 --- a/.drone.yml +++ b/.drone.yml @@ -14,7 +14,7 @@ steps: - apk --no-cache add git go-bindata - go generate -v - go get -v -d - - go build -v -o youp0m + - go build -v -ldflags="-s -w" -o youp0m - wget -O Dockerfile https://ankh.serekh.nemunai.re/local/Dockerfile-youp0m - wget -O entrypoint.sh https://ankh.serekh.nemunai.re/local/entrypoint.sh-youp0m && chmod +x entrypoint.sh @@ -47,7 +47,7 @@ steps: - apk --no-cache add git go-bindata - go generate -v - go get -v -d - - go build -v -o youp0m + - go build -v -ldflags="-s -w" -o youp0m - wget -O Dockerfile https://ankh.serekh.nemunai.re/local/Dockerfile-youp0m - wget -O entrypoint.sh https://ankh.serekh.nemunai.re/local/entrypoint.sh-youp0m && chmod +x entrypoint.sh @@ -80,7 +80,7 @@ steps: - apk --no-cache add git go-bindata - go generate -v - go get -v -d - - go build -v -o youp0m + - go build -v -ldflags="-s -w" -o youp0m - wget -O Dockerfile https://ankh.serekh.nemunai.re/local/Dockerfile-youp0m - wget -O entrypoint.sh https://ankh.serekh.nemunai.re/local/entrypoint.sh-youp0m && chmod +x entrypoint.sh diff --git a/.gitignore b/.gitignore index e943f04..656e38e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ -bindata.go youp0m +vendor \ No newline at end of file diff --git a/assets-dev.go b/assets-dev.go new file mode 100644 index 0000000..549607f --- /dev/null +++ b/assets-dev.go @@ -0,0 +1,32 @@ +//go:build dev +// +build dev + +package main + +import ( + "flag" + "net/http" + "os" + "path/filepath" +) + +var ( + Assets http.FileSystem + StaticDir string = "static/" +) + +func init() { + flag.StringVar(&StaticDir, "static", StaticDir, "Directory containing static files") +} + +func sanitizeStaticOptions() error { + StaticDir, _ = filepath.Abs(StaticDir) + if _, err := os.Stat(StaticDir); os.IsNotExist(err) { + StaticDir, _ = filepath.Abs(filepath.Join(filepath.Dir(os.Args[0]), "static")) + if _, err := os.Stat(StaticDir); os.IsNotExist(err) { + return err + } + } + Assets = http.Dir(StaticDir) + return nil +} diff --git a/assets.go b/assets.go new file mode 100644 index 0000000..1841ebe --- /dev/null +++ b/assets.go @@ -0,0 +1,28 @@ +//go:build !dev +// +build !dev + +package main + +import ( + "embed" + "io/fs" + "log" + "net/http" +) + +//go:embed static/* static/js/* static/css/* +var _assets embed.FS + +var Assets http.FileSystem + +func init() { + sub, err := fs.Sub(_assets, "static") + if err != nil { + log.Fatal("Unable to cd to static/ directory:", err) + } + Assets = http.FS(sub) +} + +func sanitizeStaticOptions() error { + return nil +} diff --git a/go.mod b/go.mod index 5fc81f9..2103e1f 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module git.nemunai.re/youp0m -go 1.10 +go 1.16 require ( github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 diff --git a/main.go b/main.go index a77b44e..994bd66 100644 --- a/main.go +++ b/main.go @@ -59,7 +59,8 @@ func main() { } mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - serveStaticAsset(w, r, "index.html") + r.URL.Path = "/" + http.FileServer(Assets).ServeHTTP(w, r) }) mux.Handle("/api/", http.StripPrefix("/api", ApiHandler(authFunc))) @@ -95,7 +96,8 @@ func main() { w.Header().Set("WWW-Authenticate", "Basic realm=\"YouP0m\"") http.Error(w, "You are not allowed to perform this request.", http.StatusUnauthorized) } else { - serveStaticAsset(w, r, "admin.html") + r.URL.Path = "/admin.html" + http.FileServer(Assets).ServeHTTP(w, r) } }) diff --git a/static-dev.go b/static-dev.go deleted file mode 100644 index 0dcb2dd..0000000 --- a/static-dev.go +++ /dev/null @@ -1,45 +0,0 @@ -// +build dev - -package main - -import ( - "flag" - "net/http" - "os" - "path/filepath" -) - -var StaticDir string = "static/" - -func init() { - mux.HandleFunc("/css/", func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "text/css") - serveStaticAsset(w, r, r.URL.Path) - }) - mux.HandleFunc("/js/", func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "text/javascript") - serveStaticAsset(w, r, r.URL.Path) - }) - - flag.StringVar(&StaticDir, "static", StaticDir, "Directory containing static files") -} - -func serveStaticAsset(w http.ResponseWriter, r *http.Request, url string) { - if url == "index.html" { - r.URL.Path = "/" - } else { - r.URL.Path = "/" + url - } - http.FileServer(http.Dir(StaticDir)).ServeHTTP(w, r) -} - -func sanitizeStaticOptions() error { - StaticDir, _ = filepath.Abs(StaticDir) - if _, err := os.Stat(StaticDir); os.IsNotExist(err) { - StaticDir, _ = filepath.Abs(filepath.Join(filepath.Dir(os.Args[0]), "static")) - if _, err := os.Stat(StaticDir); os.IsNotExist(err) { - return err - } - } - return nil -} diff --git a/static.go b/static.go index b4340fe..f8525be 100644 --- a/static.go +++ b/static.go @@ -1,36 +1,14 @@ -// +build !dev - package main import ( "net/http" - "path" ) -//go:generate go-bindata -ignore "\\.go|\\.less" -pkg "main" -o "bindata.go" static/... -//go:generate go fmt bindata.go - -const StaticDir string = "./static/" - func init() { mux.HandleFunc("/css/", func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "text/css") - serveStaticAsset(w, r, r.URL.Path) + http.FileServer(Assets).ServeHTTP(w, r) }) mux.HandleFunc("/js/", func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "text/javascript") - serveStaticAsset(w, r, r.URL.Path) + http.FileServer(Assets).ServeHTTP(w, r) }) } - -func serveStaticAsset(w http.ResponseWriter, r *http.Request, url string) { - if data, err := Asset(path.Join(StaticDir, url)); err != nil { - http.NotFound(w, r) - } else { - w.Write(data) - } -} - -func sanitizeStaticOptions() error { - return nil -} diff --git a/vendor/github.com/nfnt/resize/.travis.yml b/vendor/github.com/nfnt/resize/.travis.yml deleted file mode 100644 index 57bd4a7..0000000 --- a/vendor/github.com/nfnt/resize/.travis.yml +++ /dev/null @@ -1,7 +0,0 @@ -language: go - -go: - - 1.1 - - 1.2 - - 1.3 - - tip diff --git a/vendor/github.com/nfnt/resize/LICENSE b/vendor/github.com/nfnt/resize/LICENSE deleted file mode 100644 index 7836cad..0000000 --- a/vendor/github.com/nfnt/resize/LICENSE +++ /dev/null @@ -1,13 +0,0 @@ -Copyright (c) 2012, Jan Schlicht - -Permission to use, copy, modify, and/or distribute this software for any purpose -with or without fee is hereby granted, provided that the above copyright notice -and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS -OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF -THIS SOFTWARE. diff --git a/vendor/github.com/nfnt/resize/README.md b/vendor/github.com/nfnt/resize/README.md deleted file mode 100644 index 2aefa75..0000000 --- a/vendor/github.com/nfnt/resize/README.md +++ /dev/null @@ -1,149 +0,0 @@ -Resize -====== - -Image resizing for the [Go programming language](http://golang.org) with common interpolation methods. - -[![Build Status](https://travis-ci.org/nfnt/resize.svg)](https://travis-ci.org/nfnt/resize) - -Installation ------------- - -```bash -$ go get github.com/nfnt/resize -``` - -It's that easy! - -Usage ------ - -This package needs at least Go 1.1. Import package with - -```go -import "github.com/nfnt/resize" -``` - -The resize package provides 2 functions: - -* `resize.Resize` creates a scaled image with new dimensions (`width`, `height`) using the interpolation function `interp`. - If either `width` or `height` is set to 0, it will be set to an aspect ratio preserving value. -* `resize.Thumbnail` downscales an image preserving its aspect ratio to the maximum dimensions (`maxWidth`, `maxHeight`). - It will return the original image if original sizes are smaller than the provided dimensions. - -```go -resize.Resize(width, height uint, img image.Image, interp resize.InterpolationFunction) image.Image -resize.Thumbnail(maxWidth, maxHeight uint, img image.Image, interp resize.InterpolationFunction) image.Image -``` - -The provided interpolation functions are (from fast to slow execution time) - -- `NearestNeighbor`: [Nearest-neighbor interpolation](http://en.wikipedia.org/wiki/Nearest-neighbor_interpolation) -- `Bilinear`: [Bilinear interpolation](http://en.wikipedia.org/wiki/Bilinear_interpolation) -- `Bicubic`: [Bicubic interpolation](http://en.wikipedia.org/wiki/Bicubic_interpolation) -- `MitchellNetravali`: [Mitchell-Netravali interpolation](http://dl.acm.org/citation.cfm?id=378514) -- `Lanczos2`: [Lanczos resampling](http://en.wikipedia.org/wiki/Lanczos_resampling) with a=2 -- `Lanczos3`: [Lanczos resampling](http://en.wikipedia.org/wiki/Lanczos_resampling) with a=3 - -Which of these methods gives the best results depends on your use case. - -Sample usage: - -```go -package main - -import ( - "github.com/nfnt/resize" - "image/jpeg" - "log" - "os" -) - -func main() { - // open "test.jpg" - file, err := os.Open("test.jpg") - if err != nil { - log.Fatal(err) - } - - // decode jpeg into image.Image - img, err := jpeg.Decode(file) - if err != nil { - log.Fatal(err) - } - file.Close() - - // resize to width 1000 using Lanczos resampling - // and preserve aspect ratio - m := resize.Resize(1000, 0, img, resize.Lanczos3) - - out, err := os.Create("test_resized.jpg") - if err != nil { - log.Fatal(err) - } - defer out.Close() - - // write new image to file - jpeg.Encode(out, m, nil) -} -``` - -Caveats -------- - -* Optimized access routines are used for `image.RGBA`, `image.NRGBA`, `image.RGBA64`, `image.NRGBA64`, `image.YCbCr`, `image.Gray`, and `image.Gray16` types. All other image types are accessed in a generic way that will result in slow processing speed. -* JPEG images are stored in `image.YCbCr`. This image format stores data in a way that will decrease processing speed. A resize may be up to 2 times slower than with `image.RGBA`. - - -Downsizing Samples -------- - -Downsizing is not as simple as it might look like. Images have to be filtered before they are scaled down, otherwise aliasing might occur. -Filtering is highly subjective: Applying too much will blur the whole image, too little will make aliasing become apparent. -Resize tries to provide sane defaults that should suffice in most cases. - -### Artificial sample - -Original image -![Rings](http://nfnt.github.com/img/rings_lg_orig.png) - - - - - - - - - - - - - - -

Nearest-Neighbor

Bilinear

Bicubic

Mitchell-Netravali

Lanczos2

Lanczos3
- -### Real-Life sample - -Original image -![Original](http://nfnt.github.com/img/IMG_3694_720.jpg) - - - - - - - - - - - - - - -

Nearest-Neighbor

Bilinear

Bicubic

Mitchell-Netravali

Lanczos2

Lanczos3
- - -License -------- - -Copyright (c) 2012 Jan Schlicht -Resize is released under a MIT style license. diff --git a/vendor/github.com/nfnt/resize/converter.go b/vendor/github.com/nfnt/resize/converter.go deleted file mode 100644 index 20ac593..0000000 --- a/vendor/github.com/nfnt/resize/converter.go +++ /dev/null @@ -1,438 +0,0 @@ -/* -Copyright (c) 2012, Jan Schlicht - -Permission to use, copy, modify, and/or distribute this software for any purpose -with or without fee is hereby granted, provided that the above copyright notice -and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS -OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF -THIS SOFTWARE. -*/ - -package resize - -import "image" - -// Keep value in [0,255] range. -func clampUint8(in int32) uint8 { - // casting a negative int to an uint will result in an overflown - // large uint. this behavior will be exploited here and in other functions - // to achieve a higher performance. - if uint32(in) < 256 { - return uint8(in) - } - if in > 255 { - return 255 - } - return 0 -} - -// Keep value in [0,65535] range. -func clampUint16(in int64) uint16 { - if uint64(in) < 65536 { - return uint16(in) - } - if in > 65535 { - return 65535 - } - return 0 -} - -func resizeGeneric(in image.Image, out *image.RGBA64, scale float64, coeffs []int32, offset []int, filterLength int) { - newBounds := out.Bounds() - maxX := in.Bounds().Dx() - 1 - - for x := newBounds.Min.X; x < newBounds.Max.X; x++ { - for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ { - var rgba [4]int64 - var sum int64 - start := offset[y] - ci := y * filterLength - for i := 0; i < filterLength; i++ { - coeff := coeffs[ci+i] - if coeff != 0 { - xi := start + i - switch { - case xi < 0: - xi = 0 - case xi >= maxX: - xi = maxX - } - - r, g, b, a := in.At(xi+in.Bounds().Min.X, x+in.Bounds().Min.Y).RGBA() - - rgba[0] += int64(coeff) * int64(r) - rgba[1] += int64(coeff) * int64(g) - rgba[2] += int64(coeff) * int64(b) - rgba[3] += int64(coeff) * int64(a) - sum += int64(coeff) - } - } - - offset := (y-newBounds.Min.Y)*out.Stride + (x-newBounds.Min.X)*8 - - value := clampUint16(rgba[0] / sum) - out.Pix[offset+0] = uint8(value >> 8) - out.Pix[offset+1] = uint8(value) - value = clampUint16(rgba[1] / sum) - out.Pix[offset+2] = uint8(value >> 8) - out.Pix[offset+3] = uint8(value) - value = clampUint16(rgba[2] / sum) - out.Pix[offset+4] = uint8(value >> 8) - out.Pix[offset+5] = uint8(value) - value = clampUint16(rgba[3] / sum) - out.Pix[offset+6] = uint8(value >> 8) - out.Pix[offset+7] = uint8(value) - } - } -} - -func resizeRGBA(in *image.RGBA, out *image.RGBA, scale float64, coeffs []int16, offset []int, filterLength int) { - newBounds := out.Bounds() - maxX := in.Bounds().Dx() - 1 - - for x := newBounds.Min.X; x < newBounds.Max.X; x++ { - row := in.Pix[x*in.Stride:] - for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ { - var rgba [4]int32 - var sum int32 - start := offset[y] - ci := y * filterLength - for i := 0; i < filterLength; i++ { - coeff := coeffs[ci+i] - if coeff != 0 { - xi := start + i - switch { - case uint(xi) < uint(maxX): - xi *= 4 - case xi >= maxX: - xi = 4 * maxX - default: - xi = 0 - } - - rgba[0] += int32(coeff) * int32(row[xi+0]) - rgba[1] += int32(coeff) * int32(row[xi+1]) - rgba[2] += int32(coeff) * int32(row[xi+2]) - rgba[3] += int32(coeff) * int32(row[xi+3]) - sum += int32(coeff) - } - } - - xo := (y-newBounds.Min.Y)*out.Stride + (x-newBounds.Min.X)*4 - - out.Pix[xo+0] = clampUint8(rgba[0] / sum) - out.Pix[xo+1] = clampUint8(rgba[1] / sum) - out.Pix[xo+2] = clampUint8(rgba[2] / sum) - out.Pix[xo+3] = clampUint8(rgba[3] / sum) - } - } -} - -func resizeNRGBA(in *image.NRGBA, out *image.RGBA, scale float64, coeffs []int16, offset []int, filterLength int) { - newBounds := out.Bounds() - maxX := in.Bounds().Dx() - 1 - - for x := newBounds.Min.X; x < newBounds.Max.X; x++ { - row := in.Pix[x*in.Stride:] - for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ { - var rgba [4]int32 - var sum int32 - start := offset[y] - ci := y * filterLength - for i := 0; i < filterLength; i++ { - coeff := coeffs[ci+i] - if coeff != 0 { - xi := start + i - switch { - case uint(xi) < uint(maxX): - xi *= 4 - case xi >= maxX: - xi = 4 * maxX - default: - xi = 0 - } - - rgba[0] += int32(coeff) * int32(row[xi+0]) - rgba[1] += int32(coeff) * int32(row[xi+1]) - rgba[2] += int32(coeff) * int32(row[xi+2]) - rgba[3] += int32(coeff) * int32(row[xi+3]) - sum += int32(coeff) - - // Forward alpha-premultiplication - a := int32(row[xi+3]) - rgba[0] *= a - rgba[0] /= 0xff - rgba[1] *= a - rgba[1] /= 0xff - rgba[2] *= a - rgba[2] /= 0xff - } - } - - xo := (y-newBounds.Min.Y)*out.Stride + (x-newBounds.Min.X)*4 - - out.Pix[xo+0] = clampUint8(rgba[0] / sum) - out.Pix[xo+1] = clampUint8(rgba[1] / sum) - out.Pix[xo+2] = clampUint8(rgba[2] / sum) - out.Pix[xo+3] = clampUint8(rgba[3] / sum) - } - } -} - -func resizeRGBA64(in *image.RGBA64, out *image.RGBA64, scale float64, coeffs []int32, offset []int, filterLength int) { - newBounds := out.Bounds() - maxX := in.Bounds().Dx() - 1 - - for x := newBounds.Min.X; x < newBounds.Max.X; x++ { - row := in.Pix[x*in.Stride:] - for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ { - var rgba [4]int64 - var sum int64 - start := offset[y] - ci := y * filterLength - for i := 0; i < filterLength; i++ { - coeff := coeffs[ci+i] - if coeff != 0 { - xi := start + i - switch { - case uint(xi) < uint(maxX): - xi *= 8 - case xi >= maxX: - xi = 8 * maxX - default: - xi = 0 - } - - rgba[0] += int64(coeff) * (int64(row[xi+0])<<8 | int64(row[xi+1])) - rgba[1] += int64(coeff) * (int64(row[xi+2])<<8 | int64(row[xi+3])) - rgba[2] += int64(coeff) * (int64(row[xi+4])<<8 | int64(row[xi+5])) - rgba[3] += int64(coeff) * (int64(row[xi+6])<<8 | int64(row[xi+7])) - sum += int64(coeff) - } - } - - xo := (y-newBounds.Min.Y)*out.Stride + (x-newBounds.Min.X)*8 - - value := clampUint16(rgba[0] / sum) - out.Pix[xo+0] = uint8(value >> 8) - out.Pix[xo+1] = uint8(value) - value = clampUint16(rgba[1] / sum) - out.Pix[xo+2] = uint8(value >> 8) - out.Pix[xo+3] = uint8(value) - value = clampUint16(rgba[2] / sum) - out.Pix[xo+4] = uint8(value >> 8) - out.Pix[xo+5] = uint8(value) - value = clampUint16(rgba[3] / sum) - out.Pix[xo+6] = uint8(value >> 8) - out.Pix[xo+7] = uint8(value) - } - } -} - -func resizeNRGBA64(in *image.NRGBA64, out *image.RGBA64, scale float64, coeffs []int32, offset []int, filterLength int) { - newBounds := out.Bounds() - maxX := in.Bounds().Dx() - 1 - - for x := newBounds.Min.X; x < newBounds.Max.X; x++ { - row := in.Pix[x*in.Stride:] - for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ { - var rgba [4]int64 - var sum int64 - start := offset[y] - ci := y * filterLength - for i := 0; i < filterLength; i++ { - coeff := coeffs[ci+i] - if coeff != 0 { - xi := start + i - switch { - case uint(xi) < uint(maxX): - xi *= 8 - case xi >= maxX: - xi = 8 * maxX - default: - xi = 0 - } - - rgba[0] += int64(coeff) * int64(uint16(row[xi+0])<<8|uint16(row[xi+1])) - rgba[1] += int64(coeff) * int64(uint16(row[xi+2])<<8|uint16(row[xi+3])) - rgba[2] += int64(coeff) * int64(uint16(row[xi+4])<<8|uint16(row[xi+5])) - rgba[3] += int64(coeff) * int64(uint16(row[xi+6])<<8|uint16(row[xi+7])) - sum += int64(coeff) - - // Forward alpha-premultiplication - a := int64(uint16(row[xi+6])<<8 | uint16(row[xi+7])) - rgba[0] *= a - rgba[0] /= 0xffff - rgba[1] *= a - rgba[1] /= 0xffff - rgba[2] *= a - rgba[2] /= 0xffff - } - } - - xo := (y-newBounds.Min.Y)*out.Stride + (x-newBounds.Min.X)*8 - - value := clampUint16(rgba[0] / sum) - out.Pix[xo+0] = uint8(value >> 8) - out.Pix[xo+1] = uint8(value) - value = clampUint16(rgba[1] / sum) - out.Pix[xo+2] = uint8(value >> 8) - out.Pix[xo+3] = uint8(value) - value = clampUint16(rgba[2] / sum) - out.Pix[xo+4] = uint8(value >> 8) - out.Pix[xo+5] = uint8(value) - value = clampUint16(rgba[3] / sum) - out.Pix[xo+6] = uint8(value >> 8) - out.Pix[xo+7] = uint8(value) - } - } -} - -func resizeGray(in *image.Gray, out *image.Gray, scale float64, coeffs []int16, offset []int, filterLength int) { - newBounds := out.Bounds() - maxX := in.Bounds().Dx() - 1 - - for x := newBounds.Min.X; x < newBounds.Max.X; x++ { - row := in.Pix[(x-newBounds.Min.X)*in.Stride:] - for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ { - var gray int32 - var sum int32 - start := offset[y] - ci := y * filterLength - for i := 0; i < filterLength; i++ { - coeff := coeffs[ci+i] - if coeff != 0 { - xi := start + i - switch { - case xi < 0: - xi = 0 - case xi >= maxX: - xi = maxX - } - gray += int32(coeff) * int32(row[xi]) - sum += int32(coeff) - } - } - - offset := (y-newBounds.Min.Y)*out.Stride + (x - newBounds.Min.X) - out.Pix[offset] = clampUint8(gray / sum) - } - } -} - -func resizeGray16(in *image.Gray16, out *image.Gray16, scale float64, coeffs []int32, offset []int, filterLength int) { - newBounds := out.Bounds() - maxX := in.Bounds().Dx() - 1 - - for x := newBounds.Min.X; x < newBounds.Max.X; x++ { - row := in.Pix[x*in.Stride:] - for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ { - var gray int64 - var sum int64 - start := offset[y] - ci := y * filterLength - for i := 0; i < filterLength; i++ { - coeff := coeffs[ci+i] - if coeff != 0 { - xi := start + i - switch { - case uint(xi) < uint(maxX): - xi *= 2 - case xi >= maxX: - xi = 2 * maxX - default: - xi = 0 - } - gray += int64(coeff) * int64(uint16(row[xi+0])<<8|uint16(row[xi+1])) - sum += int64(coeff) - } - } - - offset := (y-newBounds.Min.Y)*out.Stride + (x-newBounds.Min.X)*2 - value := clampUint16(gray / sum) - out.Pix[offset+0] = uint8(value >> 8) - out.Pix[offset+1] = uint8(value) - } - } -} - -func resizeYCbCr(in *ycc, out *ycc, scale float64, coeffs []int16, offset []int, filterLength int) { - newBounds := out.Bounds() - maxX := in.Bounds().Dx() - 1 - - for x := newBounds.Min.X; x < newBounds.Max.X; x++ { - row := in.Pix[x*in.Stride:] - for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ { - var p [3]int32 - var sum int32 - start := offset[y] - ci := y * filterLength - for i := 0; i < filterLength; i++ { - coeff := coeffs[ci+i] - if coeff != 0 { - xi := start + i - switch { - case uint(xi) < uint(maxX): - xi *= 3 - case xi >= maxX: - xi = 3 * maxX - default: - xi = 0 - } - p[0] += int32(coeff) * int32(row[xi+0]) - p[1] += int32(coeff) * int32(row[xi+1]) - p[2] += int32(coeff) * int32(row[xi+2]) - sum += int32(coeff) - } - } - - xo := (y-newBounds.Min.Y)*out.Stride + (x-newBounds.Min.X)*3 - out.Pix[xo+0] = clampUint8(p[0] / sum) - out.Pix[xo+1] = clampUint8(p[1] / sum) - out.Pix[xo+2] = clampUint8(p[2] / sum) - } - } -} - -func nearestYCbCr(in *ycc, out *ycc, scale float64, coeffs []bool, offset []int, filterLength int) { - newBounds := out.Bounds() - maxX := in.Bounds().Dx() - 1 - - for x := newBounds.Min.X; x < newBounds.Max.X; x++ { - row := in.Pix[x*in.Stride:] - for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ { - var p [3]float32 - var sum float32 - start := offset[y] - ci := y * filterLength - for i := 0; i < filterLength; i++ { - if coeffs[ci+i] { - xi := start + i - switch { - case uint(xi) < uint(maxX): - xi *= 3 - case xi >= maxX: - xi = 3 * maxX - default: - xi = 0 - } - p[0] += float32(row[xi+0]) - p[1] += float32(row[xi+1]) - p[2] += float32(row[xi+2]) - sum++ - } - } - - xo := (y-newBounds.Min.Y)*out.Stride + (x-newBounds.Min.X)*3 - out.Pix[xo+0] = floatToUint8(p[0] / sum) - out.Pix[xo+1] = floatToUint8(p[1] / sum) - out.Pix[xo+2] = floatToUint8(p[2] / sum) - } - } -} diff --git a/vendor/github.com/nfnt/resize/converter_test.go b/vendor/github.com/nfnt/resize/converter_test.go deleted file mode 100644 index 85639ef..0000000 --- a/vendor/github.com/nfnt/resize/converter_test.go +++ /dev/null @@ -1,43 +0,0 @@ -package resize - -import ( - "testing" -) - -func Test_ClampUint8(t *testing.T) { - var testData = []struct { - in int32 - expected uint8 - }{ - {0, 0}, - {255, 255}, - {128, 128}, - {-2, 0}, - {256, 255}, - } - for _, test := range testData { - actual := clampUint8(test.in) - if actual != test.expected { - t.Fail() - } - } -} - -func Test_ClampUint16(t *testing.T) { - var testData = []struct { - in int64 - expected uint16 - }{ - {0, 0}, - {65535, 65535}, - {128, 128}, - {-2, 0}, - {65536, 65535}, - } - for _, test := range testData { - actual := clampUint16(test.in) - if actual != test.expected { - t.Fail() - } - } -} diff --git a/vendor/github.com/nfnt/resize/filters.go b/vendor/github.com/nfnt/resize/filters.go deleted file mode 100644 index 4ce04e3..0000000 --- a/vendor/github.com/nfnt/resize/filters.go +++ /dev/null @@ -1,143 +0,0 @@ -/* -Copyright (c) 2012, Jan Schlicht - -Permission to use, copy, modify, and/or distribute this software for any purpose -with or without fee is hereby granted, provided that the above copyright notice -and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS -OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF -THIS SOFTWARE. -*/ - -package resize - -import ( - "math" -) - -func nearest(in float64) float64 { - if in >= -0.5 && in < 0.5 { - return 1 - } - return 0 -} - -func linear(in float64) float64 { - in = math.Abs(in) - if in <= 1 { - return 1 - in - } - return 0 -} - -func cubic(in float64) float64 { - in = math.Abs(in) - if in <= 1 { - return in*in*(1.5*in-2.5) + 1.0 - } - if in <= 2 { - return in*(in*(2.5-0.5*in)-4.0) + 2.0 - } - return 0 -} - -func mitchellnetravali(in float64) float64 { - in = math.Abs(in) - if in <= 1 { - return (7.0*in*in*in - 12.0*in*in + 5.33333333333) * 0.16666666666 - } - if in <= 2 { - return (-2.33333333333*in*in*in + 12.0*in*in - 20.0*in + 10.6666666667) * 0.16666666666 - } - return 0 -} - -func sinc(x float64) float64 { - x = math.Abs(x) * math.Pi - if x >= 1.220703e-4 { - return math.Sin(x) / x - } - return 1 -} - -func lanczos2(in float64) float64 { - if in > -2 && in < 2 { - return sinc(in) * sinc(in*0.5) - } - return 0 -} - -func lanczos3(in float64) float64 { - if in > -3 && in < 3 { - return sinc(in) * sinc(in*0.3333333333333333) - } - return 0 -} - -// range [-256,256] -func createWeights8(dy, filterLength int, blur, scale float64, kernel func(float64) float64) ([]int16, []int, int) { - filterLength = filterLength * int(math.Max(math.Ceil(blur*scale), 1)) - filterFactor := math.Min(1./(blur*scale), 1) - - coeffs := make([]int16, dy*filterLength) - start := make([]int, dy) - for y := 0; y < dy; y++ { - interpX := scale*(float64(y)+0.5) - 0.5 - start[y] = int(interpX) - filterLength/2 + 1 - interpX -= float64(start[y]) - for i := 0; i < filterLength; i++ { - in := (interpX - float64(i)) * filterFactor - coeffs[y*filterLength+i] = int16(kernel(in) * 256) - } - } - - return coeffs, start, filterLength -} - -// range [-65536,65536] -func createWeights16(dy, filterLength int, blur, scale float64, kernel func(float64) float64) ([]int32, []int, int) { - filterLength = filterLength * int(math.Max(math.Ceil(blur*scale), 1)) - filterFactor := math.Min(1./(blur*scale), 1) - - coeffs := make([]int32, dy*filterLength) - start := make([]int, dy) - for y := 0; y < dy; y++ { - interpX := scale*(float64(y)+0.5) - 0.5 - start[y] = int(interpX) - filterLength/2 + 1 - interpX -= float64(start[y]) - for i := 0; i < filterLength; i++ { - in := (interpX - float64(i)) * filterFactor - coeffs[y*filterLength+i] = int32(kernel(in) * 65536) - } - } - - return coeffs, start, filterLength -} - -func createWeightsNearest(dy, filterLength int, blur, scale float64) ([]bool, []int, int) { - filterLength = filterLength * int(math.Max(math.Ceil(blur*scale), 1)) - filterFactor := math.Min(1./(blur*scale), 1) - - coeffs := make([]bool, dy*filterLength) - start := make([]int, dy) - for y := 0; y < dy; y++ { - interpX := scale*(float64(y)+0.5) - 0.5 - start[y] = int(interpX) - filterLength/2 + 1 - interpX -= float64(start[y]) - for i := 0; i < filterLength; i++ { - in := (interpX - float64(i)) * filterFactor - if in >= -0.5 && in < 0.5 { - coeffs[y*filterLength+i] = true - } else { - coeffs[y*filterLength+i] = false - } - } - } - - return coeffs, start, filterLength -} diff --git a/vendor/github.com/nfnt/resize/nearest.go b/vendor/github.com/nfnt/resize/nearest.go deleted file mode 100644 index 888039d..0000000 --- a/vendor/github.com/nfnt/resize/nearest.go +++ /dev/null @@ -1,318 +0,0 @@ -/* -Copyright (c) 2014, Charlie Vieth - -Permission to use, copy, modify, and/or distribute this software for any purpose -with or without fee is hereby granted, provided that the above copyright notice -and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS -OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF -THIS SOFTWARE. -*/ - -package resize - -import "image" - -func floatToUint8(x float32) uint8 { - // Nearest-neighbor values are always - // positive no need to check lower-bound. - if x > 0xfe { - return 0xff - } - return uint8(x) -} - -func floatToUint16(x float32) uint16 { - if x > 0xfffe { - return 0xffff - } - return uint16(x) -} - -func nearestGeneric(in image.Image, out *image.RGBA64, scale float64, coeffs []bool, offset []int, filterLength int) { - newBounds := out.Bounds() - maxX := in.Bounds().Dx() - 1 - - for x := newBounds.Min.X; x < newBounds.Max.X; x++ { - for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ { - var rgba [4]float32 - var sum float32 - start := offset[y] - ci := y * filterLength - for i := 0; i < filterLength; i++ { - if coeffs[ci+i] { - xi := start + i - switch { - case xi < 0: - xi = 0 - case xi >= maxX: - xi = maxX - } - r, g, b, a := in.At(xi+in.Bounds().Min.X, x+in.Bounds().Min.Y).RGBA() - rgba[0] += float32(r) - rgba[1] += float32(g) - rgba[2] += float32(b) - rgba[3] += float32(a) - sum++ - } - } - - offset := (y-newBounds.Min.Y)*out.Stride + (x-newBounds.Min.X)*8 - value := floatToUint16(rgba[0] / sum) - out.Pix[offset+0] = uint8(value >> 8) - out.Pix[offset+1] = uint8(value) - value = floatToUint16(rgba[1] / sum) - out.Pix[offset+2] = uint8(value >> 8) - out.Pix[offset+3] = uint8(value) - value = floatToUint16(rgba[2] / sum) - out.Pix[offset+4] = uint8(value >> 8) - out.Pix[offset+5] = uint8(value) - value = floatToUint16(rgba[3] / sum) - out.Pix[offset+6] = uint8(value >> 8) - out.Pix[offset+7] = uint8(value) - } - } -} - -func nearestRGBA(in *image.RGBA, out *image.RGBA, scale float64, coeffs []bool, offset []int, filterLength int) { - newBounds := out.Bounds() - maxX := in.Bounds().Dx() - 1 - - for x := newBounds.Min.X; x < newBounds.Max.X; x++ { - row := in.Pix[x*in.Stride:] - for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ { - var rgba [4]float32 - var sum float32 - start := offset[y] - ci := y * filterLength - for i := 0; i < filterLength; i++ { - if coeffs[ci+i] { - xi := start + i - switch { - case uint(xi) < uint(maxX): - xi *= 4 - case xi >= maxX: - xi = 4 * maxX - default: - xi = 0 - } - rgba[0] += float32(row[xi+0]) - rgba[1] += float32(row[xi+1]) - rgba[2] += float32(row[xi+2]) - rgba[3] += float32(row[xi+3]) - sum++ - } - } - - xo := (y-newBounds.Min.Y)*out.Stride + (x-newBounds.Min.X)*4 - out.Pix[xo+0] = floatToUint8(rgba[0] / sum) - out.Pix[xo+1] = floatToUint8(rgba[1] / sum) - out.Pix[xo+2] = floatToUint8(rgba[2] / sum) - out.Pix[xo+3] = floatToUint8(rgba[3] / sum) - } - } -} - -func nearestNRGBA(in *image.NRGBA, out *image.NRGBA, scale float64, coeffs []bool, offset []int, filterLength int) { - newBounds := out.Bounds() - maxX := in.Bounds().Dx() - 1 - - for x := newBounds.Min.X; x < newBounds.Max.X; x++ { - row := in.Pix[x*in.Stride:] - for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ { - var rgba [4]float32 - var sum float32 - start := offset[y] - ci := y * filterLength - for i := 0; i < filterLength; i++ { - if coeffs[ci+i] { - xi := start + i - switch { - case uint(xi) < uint(maxX): - xi *= 4 - case xi >= maxX: - xi = 4 * maxX - default: - xi = 0 - } - rgba[0] += float32(row[xi+0]) - rgba[1] += float32(row[xi+1]) - rgba[2] += float32(row[xi+2]) - rgba[3] += float32(row[xi+3]) - sum++ - } - } - - xo := (y-newBounds.Min.Y)*out.Stride + (x-newBounds.Min.X)*4 - out.Pix[xo+0] = floatToUint8(rgba[0] / sum) - out.Pix[xo+1] = floatToUint8(rgba[1] / sum) - out.Pix[xo+2] = floatToUint8(rgba[2] / sum) - out.Pix[xo+3] = floatToUint8(rgba[3] / sum) - } - } -} - -func nearestRGBA64(in *image.RGBA64, out *image.RGBA64, scale float64, coeffs []bool, offset []int, filterLength int) { - newBounds := out.Bounds() - maxX := in.Bounds().Dx() - 1 - - for x := newBounds.Min.X; x < newBounds.Max.X; x++ { - row := in.Pix[x*in.Stride:] - for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ { - var rgba [4]float32 - var sum float32 - start := offset[y] - ci := y * filterLength - for i := 0; i < filterLength; i++ { - if coeffs[ci+i] { - xi := start + i - switch { - case uint(xi) < uint(maxX): - xi *= 8 - case xi >= maxX: - xi = 8 * maxX - default: - xi = 0 - } - rgba[0] += float32(uint16(row[xi+0])<<8 | uint16(row[xi+1])) - rgba[1] += float32(uint16(row[xi+2])<<8 | uint16(row[xi+3])) - rgba[2] += float32(uint16(row[xi+4])<<8 | uint16(row[xi+5])) - rgba[3] += float32(uint16(row[xi+6])<<8 | uint16(row[xi+7])) - sum++ - } - } - - xo := (y-newBounds.Min.Y)*out.Stride + (x-newBounds.Min.X)*8 - value := floatToUint16(rgba[0] / sum) - out.Pix[xo+0] = uint8(value >> 8) - out.Pix[xo+1] = uint8(value) - value = floatToUint16(rgba[1] / sum) - out.Pix[xo+2] = uint8(value >> 8) - out.Pix[xo+3] = uint8(value) - value = floatToUint16(rgba[2] / sum) - out.Pix[xo+4] = uint8(value >> 8) - out.Pix[xo+5] = uint8(value) - value = floatToUint16(rgba[3] / sum) - out.Pix[xo+6] = uint8(value >> 8) - out.Pix[xo+7] = uint8(value) - } - } -} - -func nearestNRGBA64(in *image.NRGBA64, out *image.NRGBA64, scale float64, coeffs []bool, offset []int, filterLength int) { - newBounds := out.Bounds() - maxX := in.Bounds().Dx() - 1 - - for x := newBounds.Min.X; x < newBounds.Max.X; x++ { - row := in.Pix[x*in.Stride:] - for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ { - var rgba [4]float32 - var sum float32 - start := offset[y] - ci := y * filterLength - for i := 0; i < filterLength; i++ { - if coeffs[ci+i] { - xi := start + i - switch { - case uint(xi) < uint(maxX): - xi *= 8 - case xi >= maxX: - xi = 8 * maxX - default: - xi = 0 - } - rgba[0] += float32(uint16(row[xi+0])<<8 | uint16(row[xi+1])) - rgba[1] += float32(uint16(row[xi+2])<<8 | uint16(row[xi+3])) - rgba[2] += float32(uint16(row[xi+4])<<8 | uint16(row[xi+5])) - rgba[3] += float32(uint16(row[xi+6])<<8 | uint16(row[xi+7])) - sum++ - } - } - - xo := (y-newBounds.Min.Y)*out.Stride + (x-newBounds.Min.X)*8 - value := floatToUint16(rgba[0] / sum) - out.Pix[xo+0] = uint8(value >> 8) - out.Pix[xo+1] = uint8(value) - value = floatToUint16(rgba[1] / sum) - out.Pix[xo+2] = uint8(value >> 8) - out.Pix[xo+3] = uint8(value) - value = floatToUint16(rgba[2] / sum) - out.Pix[xo+4] = uint8(value >> 8) - out.Pix[xo+5] = uint8(value) - value = floatToUint16(rgba[3] / sum) - out.Pix[xo+6] = uint8(value >> 8) - out.Pix[xo+7] = uint8(value) - } - } -} - -func nearestGray(in *image.Gray, out *image.Gray, scale float64, coeffs []bool, offset []int, filterLength int) { - newBounds := out.Bounds() - maxX := in.Bounds().Dx() - 1 - - for x := newBounds.Min.X; x < newBounds.Max.X; x++ { - row := in.Pix[x*in.Stride:] - for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ { - var gray float32 - var sum float32 - start := offset[y] - ci := y * filterLength - for i := 0; i < filterLength; i++ { - if coeffs[ci+i] { - xi := start + i - switch { - case xi < 0: - xi = 0 - case xi >= maxX: - xi = maxX - } - gray += float32(row[xi]) - sum++ - } - } - - offset := (y-newBounds.Min.Y)*out.Stride + (x - newBounds.Min.X) - out.Pix[offset] = floatToUint8(gray / sum) - } - } -} - -func nearestGray16(in *image.Gray16, out *image.Gray16, scale float64, coeffs []bool, offset []int, filterLength int) { - newBounds := out.Bounds() - maxX := in.Bounds().Dx() - 1 - - for x := newBounds.Min.X; x < newBounds.Max.X; x++ { - row := in.Pix[x*in.Stride:] - for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ { - var gray float32 - var sum float32 - start := offset[y] - ci := y * filterLength - for i := 0; i < filterLength; i++ { - if coeffs[ci+i] { - xi := start + i - switch { - case uint(xi) < uint(maxX): - xi *= 2 - case xi >= maxX: - xi = 2 * maxX - default: - xi = 0 - } - gray += float32(uint16(row[xi+0])<<8 | uint16(row[xi+1])) - sum++ - } - } - - offset := (y-newBounds.Min.Y)*out.Stride + (x-newBounds.Min.X)*2 - value := floatToUint16(gray / sum) - out.Pix[offset+0] = uint8(value >> 8) - out.Pix[offset+1] = uint8(value) - } - } -} diff --git a/vendor/github.com/nfnt/resize/nearest_test.go b/vendor/github.com/nfnt/resize/nearest_test.go deleted file mode 100644 index d4a76dd..0000000 --- a/vendor/github.com/nfnt/resize/nearest_test.go +++ /dev/null @@ -1,57 +0,0 @@ -/* -Copyright (c) 2014, Charlie Vieth - -Permission to use, copy, modify, and/or distribute this software for any purpose -with or without fee is hereby granted, provided that the above copyright notice -and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS -OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF -THIS SOFTWARE. -*/ - -package resize - -import "testing" - -func Test_FloatToUint8(t *testing.T) { - var testData = []struct { - in float32 - expected uint8 - }{ - {0, 0}, - {255, 255}, - {128, 128}, - {1, 1}, - {256, 255}, - } - for _, test := range testData { - actual := floatToUint8(test.in) - if actual != test.expected { - t.Fail() - } - } -} - -func Test_FloatToUint16(t *testing.T) { - var testData = []struct { - in float32 - expected uint16 - }{ - {0, 0}, - {65535, 65535}, - {128, 128}, - {1, 1}, - {65536, 65535}, - } - for _, test := range testData { - actual := floatToUint16(test.in) - if actual != test.expected { - t.Fail() - } - } -} diff --git a/vendor/github.com/nfnt/resize/resize.go b/vendor/github.com/nfnt/resize/resize.go deleted file mode 100644 index 57bd1fc..0000000 --- a/vendor/github.com/nfnt/resize/resize.go +++ /dev/null @@ -1,614 +0,0 @@ -/* -Copyright (c) 2012, Jan Schlicht - -Permission to use, copy, modify, and/or distribute this software for any purpose -with or without fee is hereby granted, provided that the above copyright notice -and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS -OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF -THIS SOFTWARE. -*/ - -// Package resize implements various image resizing methods. -// -// The package works with the Image interface described in the image package. -// Various interpolation methods are provided and multiple processors may be -// utilized in the computations. -// -// Example: -// imgResized := resize.Resize(1000, 0, imgOld, resize.MitchellNetravali) -package resize - -import ( - "image" - "runtime" - "sync" -) - -// An InterpolationFunction provides the parameters that describe an -// interpolation kernel. It returns the number of samples to take -// and the kernel function to use for sampling. -type InterpolationFunction int - -// InterpolationFunction constants -const ( - // Nearest-neighbor interpolation - NearestNeighbor InterpolationFunction = iota - // Bilinear interpolation - Bilinear - // Bicubic interpolation (with cubic hermite spline) - Bicubic - // Mitchell-Netravali interpolation - MitchellNetravali - // Lanczos interpolation (a=2) - Lanczos2 - // Lanczos interpolation (a=3) - Lanczos3 -) - -// kernal, returns an InterpolationFunctions taps and kernel. -func (i InterpolationFunction) kernel() (int, func(float64) float64) { - switch i { - case Bilinear: - return 2, linear - case Bicubic: - return 4, cubic - case MitchellNetravali: - return 4, mitchellnetravali - case Lanczos2: - return 4, lanczos2 - case Lanczos3: - return 6, lanczos3 - default: - // Default to NearestNeighbor. - return 2, nearest - } -} - -// values <1 will sharpen the image -var blur = 1.0 - -// Resize scales an image to new width and height using the interpolation function interp. -// A new image with the given dimensions will be returned. -// If one of the parameters width or height is set to 0, its size will be calculated so that -// the aspect ratio is that of the originating image. -// The resizing algorithm uses channels for parallel computation. -func Resize(width, height uint, img image.Image, interp InterpolationFunction) image.Image { - scaleX, scaleY := calcFactors(width, height, float64(img.Bounds().Dx()), float64(img.Bounds().Dy())) - if width == 0 { - width = uint(0.7 + float64(img.Bounds().Dx())/scaleX) - } - if height == 0 { - height = uint(0.7 + float64(img.Bounds().Dy())/scaleY) - } - - // Trivial case: return input image - if int(width) == img.Bounds().Dx() && int(height) == img.Bounds().Dy() { - return img - } - - if interp == NearestNeighbor { - return resizeNearest(width, height, scaleX, scaleY, img, interp) - } - - taps, kernel := interp.kernel() - cpus := runtime.GOMAXPROCS(0) - wg := sync.WaitGroup{} - - // Generic access to image.Image is slow in tight loops. - // The optimal access has to be determined from the concrete image type. - switch input := img.(type) { - case *image.RGBA: - // 8-bit precision - temp := image.NewRGBA(image.Rect(0, 0, input.Bounds().Dy(), int(width))) - result := image.NewRGBA(image.Rect(0, 0, int(width), int(height))) - - // horizontal filter, results in transposed temporary image - coeffs, offset, filterLength := createWeights8(temp.Bounds().Dy(), taps, blur, scaleX, kernel) - wg.Add(cpus) - for i := 0; i < cpus; i++ { - slice := makeSlice(temp, i, cpus).(*image.RGBA) - go func() { - defer wg.Done() - resizeRGBA(input, slice, scaleX, coeffs, offset, filterLength) - }() - } - wg.Wait() - - // horizontal filter on transposed image, result is not transposed - coeffs, offset, filterLength = createWeights8(result.Bounds().Dy(), taps, blur, scaleY, kernel) - wg.Add(cpus) - for i := 0; i < cpus; i++ { - slice := makeSlice(result, i, cpus).(*image.RGBA) - go func() { - defer wg.Done() - resizeRGBA(temp, slice, scaleY, coeffs, offset, filterLength) - }() - } - wg.Wait() - return result - case *image.NRGBA: - // 8-bit precision - temp := image.NewRGBA(image.Rect(0, 0, input.Bounds().Dy(), int(width))) - result := image.NewRGBA(image.Rect(0, 0, int(width), int(height))) - - // horizontal filter, results in transposed temporary image - coeffs, offset, filterLength := createWeights8(temp.Bounds().Dy(), taps, blur, scaleX, kernel) - wg.Add(cpus) - for i := 0; i < cpus; i++ { - slice := makeSlice(temp, i, cpus).(*image.RGBA) - go func() { - defer wg.Done() - resizeNRGBA(input, slice, scaleX, coeffs, offset, filterLength) - }() - } - wg.Wait() - - // horizontal filter on transposed image, result is not transposed - coeffs, offset, filterLength = createWeights8(result.Bounds().Dy(), taps, blur, scaleY, kernel) - wg.Add(cpus) - for i := 0; i < cpus; i++ { - slice := makeSlice(result, i, cpus).(*image.RGBA) - go func() { - defer wg.Done() - resizeRGBA(temp, slice, scaleY, coeffs, offset, filterLength) - }() - } - wg.Wait() - return result - - case *image.YCbCr: - // 8-bit precision - // accessing the YCbCr arrays in a tight loop is slow. - // converting the image to ycc increases performance by 2x. - temp := newYCC(image.Rect(0, 0, input.Bounds().Dy(), int(width)), input.SubsampleRatio) - result := newYCC(image.Rect(0, 0, int(width), int(height)), image.YCbCrSubsampleRatio444) - - coeffs, offset, filterLength := createWeights8(temp.Bounds().Dy(), taps, blur, scaleX, kernel) - in := imageYCbCrToYCC(input) - wg.Add(cpus) - for i := 0; i < cpus; i++ { - slice := makeSlice(temp, i, cpus).(*ycc) - go func() { - defer wg.Done() - resizeYCbCr(in, slice, scaleX, coeffs, offset, filterLength) - }() - } - wg.Wait() - - coeffs, offset, filterLength = createWeights8(result.Bounds().Dy(), taps, blur, scaleY, kernel) - wg.Add(cpus) - for i := 0; i < cpus; i++ { - slice := makeSlice(result, i, cpus).(*ycc) - go func() { - defer wg.Done() - resizeYCbCr(temp, slice, scaleY, coeffs, offset, filterLength) - }() - } - wg.Wait() - return result.YCbCr() - case *image.RGBA64: - // 16-bit precision - temp := image.NewRGBA64(image.Rect(0, 0, input.Bounds().Dy(), int(width))) - result := image.NewRGBA64(image.Rect(0, 0, int(width), int(height))) - - // horizontal filter, results in transposed temporary image - coeffs, offset, filterLength := createWeights16(temp.Bounds().Dy(), taps, blur, scaleX, kernel) - wg.Add(cpus) - for i := 0; i < cpus; i++ { - slice := makeSlice(temp, i, cpus).(*image.RGBA64) - go func() { - defer wg.Done() - resizeRGBA64(input, slice, scaleX, coeffs, offset, filterLength) - }() - } - wg.Wait() - - // horizontal filter on transposed image, result is not transposed - coeffs, offset, filterLength = createWeights16(result.Bounds().Dy(), taps, blur, scaleY, kernel) - wg.Add(cpus) - for i := 0; i < cpus; i++ { - slice := makeSlice(result, i, cpus).(*image.RGBA64) - go func() { - defer wg.Done() - resizeRGBA64(temp, slice, scaleY, coeffs, offset, filterLength) - }() - } - wg.Wait() - return result - case *image.NRGBA64: - // 16-bit precision - temp := image.NewRGBA64(image.Rect(0, 0, input.Bounds().Dy(), int(width))) - result := image.NewRGBA64(image.Rect(0, 0, int(width), int(height))) - - // horizontal filter, results in transposed temporary image - coeffs, offset, filterLength := createWeights16(temp.Bounds().Dy(), taps, blur, scaleX, kernel) - wg.Add(cpus) - for i := 0; i < cpus; i++ { - slice := makeSlice(temp, i, cpus).(*image.RGBA64) - go func() { - defer wg.Done() - resizeNRGBA64(input, slice, scaleX, coeffs, offset, filterLength) - }() - } - wg.Wait() - - // horizontal filter on transposed image, result is not transposed - coeffs, offset, filterLength = createWeights16(result.Bounds().Dy(), taps, blur, scaleY, kernel) - wg.Add(cpus) - for i := 0; i < cpus; i++ { - slice := makeSlice(result, i, cpus).(*image.RGBA64) - go func() { - defer wg.Done() - resizeRGBA64(temp, slice, scaleY, coeffs, offset, filterLength) - }() - } - wg.Wait() - return result - case *image.Gray: - // 8-bit precision - temp := image.NewGray(image.Rect(0, 0, input.Bounds().Dy(), int(width))) - result := image.NewGray(image.Rect(0, 0, int(width), int(height))) - - // horizontal filter, results in transposed temporary image - coeffs, offset, filterLength := createWeights8(temp.Bounds().Dy(), taps, blur, scaleX, kernel) - wg.Add(cpus) - for i := 0; i < cpus; i++ { - slice := makeSlice(temp, i, cpus).(*image.Gray) - go func() { - defer wg.Done() - resizeGray(input, slice, scaleX, coeffs, offset, filterLength) - }() - } - wg.Wait() - - // horizontal filter on transposed image, result is not transposed - coeffs, offset, filterLength = createWeights8(result.Bounds().Dy(), taps, blur, scaleY, kernel) - wg.Add(cpus) - for i := 0; i < cpus; i++ { - slice := makeSlice(result, i, cpus).(*image.Gray) - go func() { - defer wg.Done() - resizeGray(temp, slice, scaleY, coeffs, offset, filterLength) - }() - } - wg.Wait() - return result - case *image.Gray16: - // 16-bit precision - temp := image.NewGray16(image.Rect(0, 0, input.Bounds().Dy(), int(width))) - result := image.NewGray16(image.Rect(0, 0, int(width), int(height))) - - // horizontal filter, results in transposed temporary image - coeffs, offset, filterLength := createWeights16(temp.Bounds().Dy(), taps, blur, scaleX, kernel) - wg.Add(cpus) - for i := 0; i < cpus; i++ { - slice := makeSlice(temp, i, cpus).(*image.Gray16) - go func() { - defer wg.Done() - resizeGray16(input, slice, scaleX, coeffs, offset, filterLength) - }() - } - wg.Wait() - - // horizontal filter on transposed image, result is not transposed - coeffs, offset, filterLength = createWeights16(result.Bounds().Dy(), taps, blur, scaleY, kernel) - wg.Add(cpus) - for i := 0; i < cpus; i++ { - slice := makeSlice(result, i, cpus).(*image.Gray16) - go func() { - defer wg.Done() - resizeGray16(temp, slice, scaleY, coeffs, offset, filterLength) - }() - } - wg.Wait() - return result - default: - // 16-bit precision - temp := image.NewRGBA64(image.Rect(0, 0, img.Bounds().Dy(), int(width))) - result := image.NewRGBA64(image.Rect(0, 0, int(width), int(height))) - - // horizontal filter, results in transposed temporary image - coeffs, offset, filterLength := createWeights16(temp.Bounds().Dy(), taps, blur, scaleX, kernel) - wg.Add(cpus) - for i := 0; i < cpus; i++ { - slice := makeSlice(temp, i, cpus).(*image.RGBA64) - go func() { - defer wg.Done() - resizeGeneric(img, slice, scaleX, coeffs, offset, filterLength) - }() - } - wg.Wait() - - // horizontal filter on transposed image, result is not transposed - coeffs, offset, filterLength = createWeights16(result.Bounds().Dy(), taps, blur, scaleY, kernel) - wg.Add(cpus) - for i := 0; i < cpus; i++ { - slice := makeSlice(result, i, cpus).(*image.RGBA64) - go func() { - defer wg.Done() - resizeRGBA64(temp, slice, scaleY, coeffs, offset, filterLength) - }() - } - wg.Wait() - return result - } -} - -func resizeNearest(width, height uint, scaleX, scaleY float64, img image.Image, interp InterpolationFunction) image.Image { - taps, _ := interp.kernel() - cpus := runtime.GOMAXPROCS(0) - wg := sync.WaitGroup{} - - switch input := img.(type) { - case *image.RGBA: - // 8-bit precision - temp := image.NewRGBA(image.Rect(0, 0, input.Bounds().Dy(), int(width))) - result := image.NewRGBA(image.Rect(0, 0, int(width), int(height))) - - // horizontal filter, results in transposed temporary image - coeffs, offset, filterLength := createWeightsNearest(temp.Bounds().Dy(), taps, blur, scaleX) - wg.Add(cpus) - for i := 0; i < cpus; i++ { - slice := makeSlice(temp, i, cpus).(*image.RGBA) - go func() { - defer wg.Done() - nearestRGBA(input, slice, scaleX, coeffs, offset, filterLength) - }() - } - wg.Wait() - - // horizontal filter on transposed image, result is not transposed - coeffs, offset, filterLength = createWeightsNearest(result.Bounds().Dy(), taps, blur, scaleY) - wg.Add(cpus) - for i := 0; i < cpus; i++ { - slice := makeSlice(result, i, cpus).(*image.RGBA) - go func() { - defer wg.Done() - nearestRGBA(temp, slice, scaleY, coeffs, offset, filterLength) - }() - } - wg.Wait() - return result - case *image.NRGBA: - // 8-bit precision - temp := image.NewNRGBA(image.Rect(0, 0, input.Bounds().Dy(), int(width))) - result := image.NewNRGBA(image.Rect(0, 0, int(width), int(height))) - - // horizontal filter, results in transposed temporary image - coeffs, offset, filterLength := createWeightsNearest(temp.Bounds().Dy(), taps, blur, scaleX) - wg.Add(cpus) - for i := 0; i < cpus; i++ { - slice := makeSlice(temp, i, cpus).(*image.NRGBA) - go func() { - defer wg.Done() - nearestNRGBA(input, slice, scaleX, coeffs, offset, filterLength) - }() - } - wg.Wait() - - // horizontal filter on transposed image, result is not transposed - coeffs, offset, filterLength = createWeightsNearest(result.Bounds().Dy(), taps, blur, scaleY) - wg.Add(cpus) - for i := 0; i < cpus; i++ { - slice := makeSlice(result, i, cpus).(*image.NRGBA) - go func() { - defer wg.Done() - nearestNRGBA(temp, slice, scaleY, coeffs, offset, filterLength) - }() - } - wg.Wait() - return result - case *image.YCbCr: - // 8-bit precision - // accessing the YCbCr arrays in a tight loop is slow. - // converting the image to ycc increases performance by 2x. - temp := newYCC(image.Rect(0, 0, input.Bounds().Dy(), int(width)), input.SubsampleRatio) - result := newYCC(image.Rect(0, 0, int(width), int(height)), image.YCbCrSubsampleRatio444) - - coeffs, offset, filterLength := createWeightsNearest(temp.Bounds().Dy(), taps, blur, scaleX) - in := imageYCbCrToYCC(input) - wg.Add(cpus) - for i := 0; i < cpus; i++ { - slice := makeSlice(temp, i, cpus).(*ycc) - go func() { - defer wg.Done() - nearestYCbCr(in, slice, scaleX, coeffs, offset, filterLength) - }() - } - wg.Wait() - - coeffs, offset, filterLength = createWeightsNearest(result.Bounds().Dy(), taps, blur, scaleY) - wg.Add(cpus) - for i := 0; i < cpus; i++ { - slice := makeSlice(result, i, cpus).(*ycc) - go func() { - defer wg.Done() - nearestYCbCr(temp, slice, scaleY, coeffs, offset, filterLength) - }() - } - wg.Wait() - return result.YCbCr() - case *image.RGBA64: - // 16-bit precision - temp := image.NewRGBA64(image.Rect(0, 0, input.Bounds().Dy(), int(width))) - result := image.NewRGBA64(image.Rect(0, 0, int(width), int(height))) - - // horizontal filter, results in transposed temporary image - coeffs, offset, filterLength := createWeightsNearest(temp.Bounds().Dy(), taps, blur, scaleX) - wg.Add(cpus) - for i := 0; i < cpus; i++ { - slice := makeSlice(temp, i, cpus).(*image.RGBA64) - go func() { - defer wg.Done() - nearestRGBA64(input, slice, scaleX, coeffs, offset, filterLength) - }() - } - wg.Wait() - - // horizontal filter on transposed image, result is not transposed - coeffs, offset, filterLength = createWeightsNearest(result.Bounds().Dy(), taps, blur, scaleY) - wg.Add(cpus) - for i := 0; i < cpus; i++ { - slice := makeSlice(result, i, cpus).(*image.RGBA64) - go func() { - defer wg.Done() - nearestRGBA64(temp, slice, scaleY, coeffs, offset, filterLength) - }() - } - wg.Wait() - return result - case *image.NRGBA64: - // 16-bit precision - temp := image.NewNRGBA64(image.Rect(0, 0, input.Bounds().Dy(), int(width))) - result := image.NewNRGBA64(image.Rect(0, 0, int(width), int(height))) - - // horizontal filter, results in transposed temporary image - coeffs, offset, filterLength := createWeightsNearest(temp.Bounds().Dy(), taps, blur, scaleX) - wg.Add(cpus) - for i := 0; i < cpus; i++ { - slice := makeSlice(temp, i, cpus).(*image.NRGBA64) - go func() { - defer wg.Done() - nearestNRGBA64(input, slice, scaleX, coeffs, offset, filterLength) - }() - } - wg.Wait() - - // horizontal filter on transposed image, result is not transposed - coeffs, offset, filterLength = createWeightsNearest(result.Bounds().Dy(), taps, blur, scaleY) - wg.Add(cpus) - for i := 0; i < cpus; i++ { - slice := makeSlice(result, i, cpus).(*image.NRGBA64) - go func() { - defer wg.Done() - nearestNRGBA64(temp, slice, scaleY, coeffs, offset, filterLength) - }() - } - wg.Wait() - return result - case *image.Gray: - // 8-bit precision - temp := image.NewGray(image.Rect(0, 0, input.Bounds().Dy(), int(width))) - result := image.NewGray(image.Rect(0, 0, int(width), int(height))) - - // horizontal filter, results in transposed temporary image - coeffs, offset, filterLength := createWeightsNearest(temp.Bounds().Dy(), taps, blur, scaleX) - wg.Add(cpus) - for i := 0; i < cpus; i++ { - slice := makeSlice(temp, i, cpus).(*image.Gray) - go func() { - defer wg.Done() - nearestGray(input, slice, scaleX, coeffs, offset, filterLength) - }() - } - wg.Wait() - - // horizontal filter on transposed image, result is not transposed - coeffs, offset, filterLength = createWeightsNearest(result.Bounds().Dy(), taps, blur, scaleY) - wg.Add(cpus) - for i := 0; i < cpus; i++ { - slice := makeSlice(result, i, cpus).(*image.Gray) - go func() { - defer wg.Done() - nearestGray(temp, slice, scaleY, coeffs, offset, filterLength) - }() - } - wg.Wait() - return result - case *image.Gray16: - // 16-bit precision - temp := image.NewGray16(image.Rect(0, 0, input.Bounds().Dy(), int(width))) - result := image.NewGray16(image.Rect(0, 0, int(width), int(height))) - - // horizontal filter, results in transposed temporary image - coeffs, offset, filterLength := createWeightsNearest(temp.Bounds().Dy(), taps, blur, scaleX) - wg.Add(cpus) - for i := 0; i < cpus; i++ { - slice := makeSlice(temp, i, cpus).(*image.Gray16) - go func() { - defer wg.Done() - nearestGray16(input, slice, scaleX, coeffs, offset, filterLength) - }() - } - wg.Wait() - - // horizontal filter on transposed image, result is not transposed - coeffs, offset, filterLength = createWeightsNearest(result.Bounds().Dy(), taps, blur, scaleY) - wg.Add(cpus) - for i := 0; i < cpus; i++ { - slice := makeSlice(result, i, cpus).(*image.Gray16) - go func() { - defer wg.Done() - nearestGray16(temp, slice, scaleY, coeffs, offset, filterLength) - }() - } - wg.Wait() - return result - default: - // 16-bit precision - temp := image.NewRGBA64(image.Rect(0, 0, img.Bounds().Dy(), int(width))) - result := image.NewRGBA64(image.Rect(0, 0, int(width), int(height))) - - // horizontal filter, results in transposed temporary image - coeffs, offset, filterLength := createWeightsNearest(temp.Bounds().Dy(), taps, blur, scaleX) - wg.Add(cpus) - for i := 0; i < cpus; i++ { - slice := makeSlice(temp, i, cpus).(*image.RGBA64) - go func() { - defer wg.Done() - nearestGeneric(img, slice, scaleX, coeffs, offset, filterLength) - }() - } - wg.Wait() - - // horizontal filter on transposed image, result is not transposed - coeffs, offset, filterLength = createWeightsNearest(result.Bounds().Dy(), taps, blur, scaleY) - wg.Add(cpus) - for i := 0; i < cpus; i++ { - slice := makeSlice(result, i, cpus).(*image.RGBA64) - go func() { - defer wg.Done() - nearestRGBA64(temp, slice, scaleY, coeffs, offset, filterLength) - }() - } - wg.Wait() - return result - } - -} - -// Calculates scaling factors using old and new image dimensions. -func calcFactors(width, height uint, oldWidth, oldHeight float64) (scaleX, scaleY float64) { - if width == 0 { - if height == 0 { - scaleX = 1.0 - scaleY = 1.0 - } else { - scaleY = oldHeight / float64(height) - scaleX = scaleY - } - } else { - scaleX = oldWidth / float64(width) - if height == 0 { - scaleY = scaleX - } else { - scaleY = oldHeight / float64(height) - } - } - return -} - -type imageWithSubImage interface { - image.Image - SubImage(image.Rectangle) image.Image -} - -func makeSlice(img imageWithSubImage, i, n int) image.Image { - return img.SubImage(image.Rect(img.Bounds().Min.X, img.Bounds().Min.Y+i*img.Bounds().Dy()/n, img.Bounds().Max.X, img.Bounds().Min.Y+(i+1)*img.Bounds().Dy()/n)) -} diff --git a/vendor/github.com/nfnt/resize/resize_test.go b/vendor/github.com/nfnt/resize/resize_test.go deleted file mode 100644 index d4b80be..0000000 --- a/vendor/github.com/nfnt/resize/resize_test.go +++ /dev/null @@ -1,330 +0,0 @@ -package resize - -import ( - "image" - "image/color" - "runtime" - "testing" -) - -var img = image.NewGray16(image.Rect(0, 0, 3, 3)) - -func init() { - runtime.GOMAXPROCS(runtime.NumCPU()) - img.Set(1, 1, color.White) -} - -func Test_Param1(t *testing.T) { - m := Resize(0, 0, img, NearestNeighbor) - if m.Bounds() != img.Bounds() { - t.Fail() - } -} - -func Test_Param2(t *testing.T) { - m := Resize(100, 0, img, NearestNeighbor) - if m.Bounds() != image.Rect(0, 0, 100, 100) { - t.Fail() - } -} - -func Test_ZeroImg(t *testing.T) { - zeroImg := image.NewGray16(image.Rect(0, 0, 0, 0)) - - m := Resize(0, 0, zeroImg, NearestNeighbor) - if m.Bounds() != zeroImg.Bounds() { - t.Fail() - } -} - -func Test_CorrectResize(t *testing.T) { - zeroImg := image.NewGray16(image.Rect(0, 0, 256, 256)) - - m := Resize(60, 0, zeroImg, NearestNeighbor) - if m.Bounds() != image.Rect(0, 0, 60, 60) { - t.Fail() - } -} - -func Test_SameColorWithRGBA(t *testing.T) { - img := image.NewRGBA(image.Rect(0, 0, 20, 20)) - for y := img.Bounds().Min.Y; y < img.Bounds().Max.Y; y++ { - for x := img.Bounds().Min.X; x < img.Bounds().Max.X; x++ { - img.SetRGBA(x, y, color.RGBA{0x80, 0x80, 0x80, 0xFF}) - } - } - out := Resize(10, 10, img, Lanczos3) - for y := out.Bounds().Min.Y; y < out.Bounds().Max.Y; y++ { - for x := out.Bounds().Min.X; x < out.Bounds().Max.X; x++ { - color := out.At(x, y).(color.RGBA) - if color.R != 0x80 || color.G != 0x80 || color.B != 0x80 || color.A != 0xFF { - t.Errorf("%+v", color) - } - } - } -} - -func Test_SameColorWithNRGBA(t *testing.T) { - img := image.NewNRGBA(image.Rect(0, 0, 20, 20)) - for y := img.Bounds().Min.Y; y < img.Bounds().Max.Y; y++ { - for x := img.Bounds().Min.X; x < img.Bounds().Max.X; x++ { - img.SetNRGBA(x, y, color.NRGBA{0x80, 0x80, 0x80, 0xFF}) - } - } - out := Resize(10, 10, img, Lanczos3) - for y := out.Bounds().Min.Y; y < out.Bounds().Max.Y; y++ { - for x := out.Bounds().Min.X; x < out.Bounds().Max.X; x++ { - color := out.At(x, y).(color.RGBA) - if color.R != 0x80 || color.G != 0x80 || color.B != 0x80 || color.A != 0xFF { - t.Errorf("%+v", color) - } - } - } -} - -func Test_SameColorWithRGBA64(t *testing.T) { - img := image.NewRGBA64(image.Rect(0, 0, 20, 20)) - for y := img.Bounds().Min.Y; y < img.Bounds().Max.Y; y++ { - for x := img.Bounds().Min.X; x < img.Bounds().Max.X; x++ { - img.SetRGBA64(x, y, color.RGBA64{0x8000, 0x8000, 0x8000, 0xFFFF}) - } - } - out := Resize(10, 10, img, Lanczos3) - for y := out.Bounds().Min.Y; y < out.Bounds().Max.Y; y++ { - for x := out.Bounds().Min.X; x < out.Bounds().Max.X; x++ { - color := out.At(x, y).(color.RGBA64) - if color.R != 0x8000 || color.G != 0x8000 || color.B != 0x8000 || color.A != 0xFFFF { - t.Errorf("%+v", color) - } - } - } -} - -func Test_SameColorWithNRGBA64(t *testing.T) { - img := image.NewNRGBA64(image.Rect(0, 0, 20, 20)) - for y := img.Bounds().Min.Y; y < img.Bounds().Max.Y; y++ { - for x := img.Bounds().Min.X; x < img.Bounds().Max.X; x++ { - img.SetNRGBA64(x, y, color.NRGBA64{0x8000, 0x8000, 0x8000, 0xFFFF}) - } - } - out := Resize(10, 10, img, Lanczos3) - for y := out.Bounds().Min.Y; y < out.Bounds().Max.Y; y++ { - for x := out.Bounds().Min.X; x < out.Bounds().Max.X; x++ { - color := out.At(x, y).(color.RGBA64) - if color.R != 0x8000 || color.G != 0x8000 || color.B != 0x8000 || color.A != 0xFFFF { - t.Errorf("%+v", color) - } - } - } -} - -func Test_SameColorWithGray(t *testing.T) { - img := image.NewGray(image.Rect(0, 0, 20, 20)) - for y := img.Bounds().Min.Y; y < img.Bounds().Max.Y; y++ { - for x := img.Bounds().Min.X; x < img.Bounds().Max.X; x++ { - img.SetGray(x, y, color.Gray{0x80}) - } - } - out := Resize(10, 10, img, Lanczos3) - for y := out.Bounds().Min.Y; y < out.Bounds().Max.Y; y++ { - for x := out.Bounds().Min.X; x < out.Bounds().Max.X; x++ { - color := out.At(x, y).(color.Gray) - if color.Y != 0x80 { - t.Errorf("%+v", color) - } - } - } -} - -func Test_SameColorWithGray16(t *testing.T) { - img := image.NewGray16(image.Rect(0, 0, 20, 20)) - for y := img.Bounds().Min.Y; y < img.Bounds().Max.Y; y++ { - for x := img.Bounds().Min.X; x < img.Bounds().Max.X; x++ { - img.SetGray16(x, y, color.Gray16{0x8000}) - } - } - out := Resize(10, 10, img, Lanczos3) - for y := out.Bounds().Min.Y; y < out.Bounds().Max.Y; y++ { - for x := out.Bounds().Min.X; x < out.Bounds().Max.X; x++ { - color := out.At(x, y).(color.Gray16) - if color.Y != 0x8000 { - t.Errorf("%+v", color) - } - } - } -} - -func Test_Bounds(t *testing.T) { - img := image.NewRGBA(image.Rect(20, 10, 200, 99)) - out := Resize(80, 80, img, Lanczos2) - out.At(0, 0) -} - -func Test_SameSizeReturnsOriginal(t *testing.T) { - img := image.NewRGBA(image.Rect(0, 0, 10, 10)) - out := Resize(0, 0, img, Lanczos2) - - if img != out { - t.Fail() - } - - out = Resize(10, 10, img, Lanczos2) - - if img != out { - t.Fail() - } -} - -func Test_PixelCoordinates(t *testing.T) { - checkers := image.NewGray(image.Rect(0, 0, 4, 4)) - checkers.Pix = []uint8{ - 255, 0, 255, 0, - 0, 255, 0, 255, - 255, 0, 255, 0, - 0, 255, 0, 255, - } - - resized := Resize(12, 12, checkers, NearestNeighbor).(*image.Gray) - - if resized.Pix[0] != 255 || resized.Pix[1] != 255 || resized.Pix[2] != 255 { - t.Fail() - } - - if resized.Pix[3] != 0 || resized.Pix[4] != 0 || resized.Pix[5] != 0 { - t.Fail() - } -} - -func Test_ResizeWithPremultipliedAlpha(t *testing.T) { - img := image.NewRGBA(image.Rect(0, 0, 1, 4)) - for y := img.Bounds().Min.Y; y < img.Bounds().Max.Y; y++ { - // 0x80 = 0.5 * 0xFF. - img.SetRGBA(0, y, color.RGBA{0x80, 0x80, 0x80, 0x80}) - } - - out := Resize(1, 2, img, MitchellNetravali) - - outputColor := out.At(0, 0).(color.RGBA) - if outputColor.R != 0x80 { - t.Fail() - } -} - -func Test_ResizeWithTranslucentColor(t *testing.T) { - img := image.NewNRGBA(image.Rect(0, 0, 1, 2)) - - // Set the pixel colors to an "invisible green" and white. - // After resizing, the green shouldn't be visible. - img.SetNRGBA(0, 0, color.NRGBA{0x00, 0xFF, 0x00, 0x00}) - img.SetNRGBA(0, 1, color.NRGBA{0x00, 0x00, 0x00, 0xFF}) - - out := Resize(1, 1, img, Bilinear) - - _, g, _, _ := out.At(0, 0).RGBA() - if g != 0x00 { - t.Errorf("%+v", g) - } -} - -const ( - // Use a small image size for benchmarks. We don't want memory performance - // to affect the benchmark results. - benchMaxX = 250 - benchMaxY = 250 - - // Resize values near the original size require increase the amount of time - // resize spends converting the image. - benchWidth = 200 - benchHeight = 200 -) - -func benchRGBA(b *testing.B, interp InterpolationFunction) { - m := image.NewRGBA(image.Rect(0, 0, benchMaxX, benchMaxY)) - // Initialize m's pixels to create a non-uniform image. - for y := m.Rect.Min.Y; y < m.Rect.Max.Y; y++ { - for x := m.Rect.Min.X; x < m.Rect.Max.X; x++ { - i := m.PixOffset(x, y) - m.Pix[i+0] = uint8(y + 4*x) - m.Pix[i+1] = uint8(y + 4*x) - m.Pix[i+2] = uint8(y + 4*x) - m.Pix[i+3] = uint8(4*y + x) - } - } - - var out image.Image - b.ResetTimer() - for i := 0; i < b.N; i++ { - out = Resize(benchWidth, benchHeight, m, interp) - } - out.At(0, 0) -} - -// The names of some interpolation functions are truncated so that the columns -// of 'go test -bench' line up. -func Benchmark_Nearest_RGBA(b *testing.B) { - benchRGBA(b, NearestNeighbor) -} - -func Benchmark_Bilinear_RGBA(b *testing.B) { - benchRGBA(b, Bilinear) -} - -func Benchmark_Bicubic_RGBA(b *testing.B) { - benchRGBA(b, Bicubic) -} - -func Benchmark_Mitchell_RGBA(b *testing.B) { - benchRGBA(b, MitchellNetravali) -} - -func Benchmark_Lanczos2_RGBA(b *testing.B) { - benchRGBA(b, Lanczos2) -} - -func Benchmark_Lanczos3_RGBA(b *testing.B) { - benchRGBA(b, Lanczos3) -} - -func benchYCbCr(b *testing.B, interp InterpolationFunction) { - m := image.NewYCbCr(image.Rect(0, 0, benchMaxX, benchMaxY), image.YCbCrSubsampleRatio422) - // Initialize m's pixels to create a non-uniform image. - for y := m.Rect.Min.Y; y < m.Rect.Max.Y; y++ { - for x := m.Rect.Min.X; x < m.Rect.Max.X; x++ { - yi := m.YOffset(x, y) - ci := m.COffset(x, y) - m.Y[yi] = uint8(16*y + x) - m.Cb[ci] = uint8(y + 16*x) - m.Cr[ci] = uint8(y + 16*x) - } - } - var out image.Image - b.ResetTimer() - for i := 0; i < b.N; i++ { - out = Resize(benchWidth, benchHeight, m, interp) - } - out.At(0, 0) -} - -func Benchmark_Nearest_YCC(b *testing.B) { - benchYCbCr(b, NearestNeighbor) -} - -func Benchmark_Bilinear_YCC(b *testing.B) { - benchYCbCr(b, Bilinear) -} - -func Benchmark_Bicubic_YCC(b *testing.B) { - benchYCbCr(b, Bicubic) -} - -func Benchmark_Mitchell_YCC(b *testing.B) { - benchYCbCr(b, MitchellNetravali) -} - -func Benchmark_Lanczos2_YCC(b *testing.B) { - benchYCbCr(b, Lanczos2) -} - -func Benchmark_Lanczos3_YCC(b *testing.B) { - benchYCbCr(b, Lanczos3) -} diff --git a/vendor/github.com/nfnt/resize/thumbnail.go b/vendor/github.com/nfnt/resize/thumbnail.go deleted file mode 100644 index 9efc246..0000000 --- a/vendor/github.com/nfnt/resize/thumbnail.go +++ /dev/null @@ -1,55 +0,0 @@ -/* -Copyright (c) 2012, Jan Schlicht - -Permission to use, copy, modify, and/or distribute this software for any purpose -with or without fee is hereby granted, provided that the above copyright notice -and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS -OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF -THIS SOFTWARE. -*/ - -package resize - -import ( - "image" -) - -// Thumbnail will downscale provided image to max width and height preserving -// original aspect ratio and using the interpolation function interp. -// It will return original image, without processing it, if original sizes -// are already smaller than provided constraints. -func Thumbnail(maxWidth, maxHeight uint, img image.Image, interp InterpolationFunction) image.Image { - origBounds := img.Bounds() - origWidth := uint(origBounds.Dx()) - origHeight := uint(origBounds.Dy()) - newWidth, newHeight := origWidth, origHeight - - // Return original image if it have same or smaller size as constraints - if maxWidth >= origWidth && maxHeight >= origHeight { - return img - } - - // Preserve aspect ratio - if origWidth > maxWidth { - newHeight = uint(origHeight * maxWidth / origWidth) - if newHeight < 1 { - newHeight = 1 - } - newWidth = maxWidth - } - - if newHeight > maxHeight { - newWidth = uint(newWidth * maxHeight / newHeight) - if newWidth < 1 { - newWidth = 1 - } - newHeight = maxHeight - } - return Resize(newWidth, newHeight, img, interp) -} diff --git a/vendor/github.com/nfnt/resize/thumbnail_test.go b/vendor/github.com/nfnt/resize/thumbnail_test.go deleted file mode 100644 index bd9875b..0000000 --- a/vendor/github.com/nfnt/resize/thumbnail_test.go +++ /dev/null @@ -1,47 +0,0 @@ -package resize - -import ( - "image" - "runtime" - "testing" -) - -func init() { - runtime.GOMAXPROCS(runtime.NumCPU()) -} - -var thumbnailTests = []struct { - origWidth int - origHeight int - maxWidth uint - maxHeight uint - expectedWidth uint - expectedHeight uint -}{ - {5, 5, 10, 10, 5, 5}, - {10, 10, 5, 5, 5, 5}, - {10, 50, 10, 10, 2, 10}, - {50, 10, 10, 10, 10, 2}, - {50, 100, 60, 90, 45, 90}, - {120, 100, 60, 90, 60, 50}, - {200, 250, 200, 150, 120, 150}, -} - -func TestThumbnail(t *testing.T) { - for i, tt := range thumbnailTests { - img := image.NewGray16(image.Rect(0, 0, tt.origWidth, tt.origHeight)) - - outImg := Thumbnail(tt.maxWidth, tt.maxHeight, img, NearestNeighbor) - - newWidth := uint(outImg.Bounds().Dx()) - newHeight := uint(outImg.Bounds().Dy()) - if newWidth != tt.expectedWidth || - newHeight != tt.expectedHeight { - t.Errorf("%d. Thumbnail(%v, %v, img, NearestNeighbor) => "+ - "width: %v, height: %v, want width: %v, height: %v", - i, tt.maxWidth, tt.maxHeight, - newWidth, newHeight, tt.expectedWidth, tt.expectedHeight, - ) - } - } -} diff --git a/vendor/github.com/nfnt/resize/ycc.go b/vendor/github.com/nfnt/resize/ycc.go deleted file mode 100644 index 1041599..0000000 --- a/vendor/github.com/nfnt/resize/ycc.go +++ /dev/null @@ -1,227 +0,0 @@ -/* -Copyright (c) 2014, Charlie Vieth - -Permission to use, copy, modify, and/or distribute this software for any purpose -with or without fee is hereby granted, provided that the above copyright notice -and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS -OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF -THIS SOFTWARE. -*/ - -package resize - -import ( - "image" - "image/color" -) - -// ycc is an in memory YCbCr image. The Y, Cb and Cr samples are held in a -// single slice to increase resizing performance. -type ycc struct { - // Pix holds the image's pixels, in Y, Cb, Cr order. The pixel at - // (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*3]. - Pix []uint8 - // Stride is the Pix stride (in bytes) between vertically adjacent pixels. - Stride int - // Rect is the image's bounds. - Rect image.Rectangle - // SubsampleRatio is the subsample ratio of the original YCbCr image. - SubsampleRatio image.YCbCrSubsampleRatio -} - -// PixOffset returns the index of the first element of Pix that corresponds to -// the pixel at (x, y). -func (p *ycc) PixOffset(x, y int) int { - return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*3 -} - -func (p *ycc) Bounds() image.Rectangle { - return p.Rect -} - -func (p *ycc) ColorModel() color.Model { - return color.YCbCrModel -} - -func (p *ycc) At(x, y int) color.Color { - if !(image.Point{x, y}.In(p.Rect)) { - return color.YCbCr{} - } - i := p.PixOffset(x, y) - return color.YCbCr{ - p.Pix[i+0], - p.Pix[i+1], - p.Pix[i+2], - } -} - -func (p *ycc) Opaque() bool { - return true -} - -// SubImage returns an image representing the portion of the image p visible -// through r. The returned value shares pixels with the original image. -func (p *ycc) SubImage(r image.Rectangle) image.Image { - r = r.Intersect(p.Rect) - if r.Empty() { - return &ycc{SubsampleRatio: p.SubsampleRatio} - } - i := p.PixOffset(r.Min.X, r.Min.Y) - return &ycc{ - Pix: p.Pix[i:], - Stride: p.Stride, - Rect: r, - SubsampleRatio: p.SubsampleRatio, - } -} - -// newYCC returns a new ycc with the given bounds and subsample ratio. -func newYCC(r image.Rectangle, s image.YCbCrSubsampleRatio) *ycc { - w, h := r.Dx(), r.Dy() - buf := make([]uint8, 3*w*h) - return &ycc{Pix: buf, Stride: 3 * w, Rect: r, SubsampleRatio: s} -} - -// YCbCr converts ycc to a YCbCr image with the same subsample ratio -// as the YCbCr image that ycc was generated from. -func (p *ycc) YCbCr() *image.YCbCr { - ycbcr := image.NewYCbCr(p.Rect, p.SubsampleRatio) - var off int - - switch ycbcr.SubsampleRatio { - case image.YCbCrSubsampleRatio422: - for y := ycbcr.Rect.Min.Y; y < ycbcr.Rect.Max.Y; y++ { - yy := (y - ycbcr.Rect.Min.Y) * ycbcr.YStride - cy := (y - ycbcr.Rect.Min.Y) * ycbcr.CStride - for x := ycbcr.Rect.Min.X; x < ycbcr.Rect.Max.X; x++ { - xx := (x - ycbcr.Rect.Min.X) - yi := yy + xx - ci := cy + xx/2 - ycbcr.Y[yi] = p.Pix[off+0] - ycbcr.Cb[ci] = p.Pix[off+1] - ycbcr.Cr[ci] = p.Pix[off+2] - off += 3 - } - } - case image.YCbCrSubsampleRatio420: - for y := ycbcr.Rect.Min.Y; y < ycbcr.Rect.Max.Y; y++ { - yy := (y - ycbcr.Rect.Min.Y) * ycbcr.YStride - cy := (y/2 - ycbcr.Rect.Min.Y/2) * ycbcr.CStride - for x := ycbcr.Rect.Min.X; x < ycbcr.Rect.Max.X; x++ { - xx := (x - ycbcr.Rect.Min.X) - yi := yy + xx - ci := cy + xx/2 - ycbcr.Y[yi] = p.Pix[off+0] - ycbcr.Cb[ci] = p.Pix[off+1] - ycbcr.Cr[ci] = p.Pix[off+2] - off += 3 - } - } - case image.YCbCrSubsampleRatio440: - for y := ycbcr.Rect.Min.Y; y < ycbcr.Rect.Max.Y; y++ { - yy := (y - ycbcr.Rect.Min.Y) * ycbcr.YStride - cy := (y/2 - ycbcr.Rect.Min.Y/2) * ycbcr.CStride - for x := ycbcr.Rect.Min.X; x < ycbcr.Rect.Max.X; x++ { - xx := (x - ycbcr.Rect.Min.X) - yi := yy + xx - ci := cy + xx - ycbcr.Y[yi] = p.Pix[off+0] - ycbcr.Cb[ci] = p.Pix[off+1] - ycbcr.Cr[ci] = p.Pix[off+2] - off += 3 - } - } - default: - // Default to 4:4:4 subsampling. - for y := ycbcr.Rect.Min.Y; y < ycbcr.Rect.Max.Y; y++ { - yy := (y - ycbcr.Rect.Min.Y) * ycbcr.YStride - cy := (y - ycbcr.Rect.Min.Y) * ycbcr.CStride - for x := ycbcr.Rect.Min.X; x < ycbcr.Rect.Max.X; x++ { - xx := (x - ycbcr.Rect.Min.X) - yi := yy + xx - ci := cy + xx - ycbcr.Y[yi] = p.Pix[off+0] - ycbcr.Cb[ci] = p.Pix[off+1] - ycbcr.Cr[ci] = p.Pix[off+2] - off += 3 - } - } - } - return ycbcr -} - -// imageYCbCrToYCC converts a YCbCr image to a ycc image for resizing. -func imageYCbCrToYCC(in *image.YCbCr) *ycc { - w, h := in.Rect.Dx(), in.Rect.Dy() - r := image.Rect(0, 0, w, h) - buf := make([]uint8, 3*w*h) - p := ycc{Pix: buf, Stride: 3 * w, Rect: r, SubsampleRatio: in.SubsampleRatio} - var off int - - switch in.SubsampleRatio { - case image.YCbCrSubsampleRatio422: - for y := in.Rect.Min.Y; y < in.Rect.Max.Y; y++ { - yy := (y - in.Rect.Min.Y) * in.YStride - cy := (y - in.Rect.Min.Y) * in.CStride - for x := in.Rect.Min.X; x < in.Rect.Max.X; x++ { - xx := (x - in.Rect.Min.X) - yi := yy + xx - ci := cy + xx/2 - p.Pix[off+0] = in.Y[yi] - p.Pix[off+1] = in.Cb[ci] - p.Pix[off+2] = in.Cr[ci] - off += 3 - } - } - case image.YCbCrSubsampleRatio420: - for y := in.Rect.Min.Y; y < in.Rect.Max.Y; y++ { - yy := (y - in.Rect.Min.Y) * in.YStride - cy := (y/2 - in.Rect.Min.Y/2) * in.CStride - for x := in.Rect.Min.X; x < in.Rect.Max.X; x++ { - xx := (x - in.Rect.Min.X) - yi := yy + xx - ci := cy + xx/2 - p.Pix[off+0] = in.Y[yi] - p.Pix[off+1] = in.Cb[ci] - p.Pix[off+2] = in.Cr[ci] - off += 3 - } - } - case image.YCbCrSubsampleRatio440: - for y := in.Rect.Min.Y; y < in.Rect.Max.Y; y++ { - yy := (y - in.Rect.Min.Y) * in.YStride - cy := (y/2 - in.Rect.Min.Y/2) * in.CStride - for x := in.Rect.Min.X; x < in.Rect.Max.X; x++ { - xx := (x - in.Rect.Min.X) - yi := yy + xx - ci := cy + xx - p.Pix[off+0] = in.Y[yi] - p.Pix[off+1] = in.Cb[ci] - p.Pix[off+2] = in.Cr[ci] - off += 3 - } - } - default: - // Default to 4:4:4 subsampling. - for y := in.Rect.Min.Y; y < in.Rect.Max.Y; y++ { - yy := (y - in.Rect.Min.Y) * in.YStride - cy := (y - in.Rect.Min.Y) * in.CStride - for x := in.Rect.Min.X; x < in.Rect.Max.X; x++ { - xx := (x - in.Rect.Min.X) - yi := yy + xx - ci := cy + xx - p.Pix[off+0] = in.Y[yi] - p.Pix[off+1] = in.Cb[ci] - p.Pix[off+2] = in.Cr[ci] - off += 3 - } - } - } - return &p -} diff --git a/vendor/github.com/nfnt/resize/ycc_test.go b/vendor/github.com/nfnt/resize/ycc_test.go deleted file mode 100644 index 54d53d1..0000000 --- a/vendor/github.com/nfnt/resize/ycc_test.go +++ /dev/null @@ -1,214 +0,0 @@ -/* -Copyright (c) 2014, Charlie Vieth - -Permission to use, copy, modify, and/or distribute this software for any purpose -with or without fee is hereby granted, provided that the above copyright notice -and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS -OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF -THIS SOFTWARE. -*/ - -package resize - -import ( - "image" - "image/color" - "testing" -) - -type Image interface { - image.Image - SubImage(image.Rectangle) image.Image -} - -func TestImage(t *testing.T) { - testImage := []Image{ - newYCC(image.Rect(0, 0, 10, 10), image.YCbCrSubsampleRatio420), - newYCC(image.Rect(0, 0, 10, 10), image.YCbCrSubsampleRatio422), - newYCC(image.Rect(0, 0, 10, 10), image.YCbCrSubsampleRatio440), - newYCC(image.Rect(0, 0, 10, 10), image.YCbCrSubsampleRatio444), - } - for _, m := range testImage { - if !image.Rect(0, 0, 10, 10).Eq(m.Bounds()) { - t.Errorf("%T: want bounds %v, got %v", - m, image.Rect(0, 0, 10, 10), m.Bounds()) - continue - } - m = m.SubImage(image.Rect(3, 2, 9, 8)).(Image) - if !image.Rect(3, 2, 9, 8).Eq(m.Bounds()) { - t.Errorf("%T: sub-image want bounds %v, got %v", - m, image.Rect(3, 2, 9, 8), m.Bounds()) - continue - } - // Test that taking an empty sub-image starting at a corner does not panic. - m.SubImage(image.Rect(0, 0, 0, 0)) - m.SubImage(image.Rect(10, 0, 10, 0)) - m.SubImage(image.Rect(0, 10, 0, 10)) - m.SubImage(image.Rect(10, 10, 10, 10)) - } -} - -func TestConvertYCbCr(t *testing.T) { - testImage := []Image{ - image.NewYCbCr(image.Rect(0, 0, 50, 50), image.YCbCrSubsampleRatio420), - image.NewYCbCr(image.Rect(0, 0, 50, 50), image.YCbCrSubsampleRatio422), - image.NewYCbCr(image.Rect(0, 0, 50, 50), image.YCbCrSubsampleRatio440), - image.NewYCbCr(image.Rect(0, 0, 50, 50), image.YCbCrSubsampleRatio444), - } - - for _, img := range testImage { - m := img.(*image.YCbCr) - for y := m.Rect.Min.Y; y < m.Rect.Max.Y; y++ { - for x := m.Rect.Min.X; x < m.Rect.Max.X; x++ { - yi := m.YOffset(x, y) - ci := m.COffset(x, y) - m.Y[yi] = uint8(16*y + x) - m.Cb[ci] = uint8(y + 16*x) - m.Cr[ci] = uint8(y + 16*x) - } - } - - // test conversion from YCbCr to ycc - yc := imageYCbCrToYCC(m) - for y := m.Rect.Min.Y; y < m.Rect.Max.Y; y++ { - for x := m.Rect.Min.X; x < m.Rect.Max.X; x++ { - ystride := 3 * (m.Rect.Max.X - m.Rect.Min.X) - xstride := 3 - yi := m.YOffset(x, y) - ci := m.COffset(x, y) - si := (y * ystride) + (x * xstride) - if m.Y[yi] != yc.Pix[si] { - t.Errorf("Err Y - found: %d expected: %d x: %d y: %d yi: %d si: %d", - m.Y[yi], yc.Pix[si], x, y, yi, si) - } - if m.Cb[ci] != yc.Pix[si+1] { - t.Errorf("Err Cb - found: %d expected: %d x: %d y: %d ci: %d si: %d", - m.Cb[ci], yc.Pix[si+1], x, y, ci, si+1) - } - if m.Cr[ci] != yc.Pix[si+2] { - t.Errorf("Err Cr - found: %d expected: %d x: %d y: %d ci: %d si: %d", - m.Cr[ci], yc.Pix[si+2], x, y, ci, si+2) - } - } - } - - // test conversion from ycc back to YCbCr - ym := yc.YCbCr() - for y := m.Rect.Min.Y; y < m.Rect.Max.Y; y++ { - for x := m.Rect.Min.X; x < m.Rect.Max.X; x++ { - yi := m.YOffset(x, y) - ci := m.COffset(x, y) - if m.Y[yi] != ym.Y[yi] { - t.Errorf("Err Y - found: %d expected: %d x: %d y: %d yi: %d", - m.Y[yi], ym.Y[yi], x, y, yi) - } - if m.Cb[ci] != ym.Cb[ci] { - t.Errorf("Err Cb - found: %d expected: %d x: %d y: %d ci: %d", - m.Cb[ci], ym.Cb[ci], x, y, ci) - } - if m.Cr[ci] != ym.Cr[ci] { - t.Errorf("Err Cr - found: %d expected: %d x: %d y: %d ci: %d", - m.Cr[ci], ym.Cr[ci], x, y, ci) - } - } - } - } -} - -func TestYCbCr(t *testing.T) { - rects := []image.Rectangle{ - image.Rect(0, 0, 16, 16), - image.Rect(1, 0, 16, 16), - image.Rect(0, 1, 16, 16), - image.Rect(1, 1, 16, 16), - image.Rect(1, 1, 15, 16), - image.Rect(1, 1, 16, 15), - image.Rect(1, 1, 15, 15), - image.Rect(2, 3, 14, 15), - image.Rect(7, 0, 7, 16), - image.Rect(0, 8, 16, 8), - image.Rect(0, 0, 10, 11), - image.Rect(5, 6, 16, 16), - image.Rect(7, 7, 8, 8), - image.Rect(7, 8, 8, 9), - image.Rect(8, 7, 9, 8), - image.Rect(8, 8, 9, 9), - image.Rect(7, 7, 17, 17), - image.Rect(8, 8, 17, 17), - image.Rect(9, 9, 17, 17), - image.Rect(10, 10, 17, 17), - } - subsampleRatios := []image.YCbCrSubsampleRatio{ - image.YCbCrSubsampleRatio444, - image.YCbCrSubsampleRatio422, - image.YCbCrSubsampleRatio420, - image.YCbCrSubsampleRatio440, - } - deltas := []image.Point{ - image.Pt(0, 0), - image.Pt(1000, 1001), - image.Pt(5001, -400), - image.Pt(-701, -801), - } - for _, r := range rects { - for _, subsampleRatio := range subsampleRatios { - for _, delta := range deltas { - testYCbCr(t, r, subsampleRatio, delta) - } - } - if testing.Short() { - break - } - } -} - -func testYCbCr(t *testing.T, r image.Rectangle, subsampleRatio image.YCbCrSubsampleRatio, delta image.Point) { - // Create a YCbCr image m, whose bounds are r translated by (delta.X, delta.Y). - r1 := r.Add(delta) - img := image.NewYCbCr(r1, subsampleRatio) - - // Initialize img's pixels. For 422 and 420 subsampling, some of the Cb and Cr elements - // will be set multiple times. That's OK. We just want to avoid a uniform image. - for y := r1.Min.Y; y < r1.Max.Y; y++ { - for x := r1.Min.X; x < r1.Max.X; x++ { - yi := img.YOffset(x, y) - ci := img.COffset(x, y) - img.Y[yi] = uint8(16*y + x) - img.Cb[ci] = uint8(y + 16*x) - img.Cr[ci] = uint8(y + 16*x) - } - } - - m := imageYCbCrToYCC(img) - - // Make various sub-images of m. - for y0 := delta.Y + 3; y0 < delta.Y+7; y0++ { - for y1 := delta.Y + 8; y1 < delta.Y+13; y1++ { - for x0 := delta.X + 3; x0 < delta.X+7; x0++ { - for x1 := delta.X + 8; x1 < delta.X+13; x1++ { - subRect := image.Rect(x0, y0, x1, y1) - sub := m.SubImage(subRect).(*ycc) - - // For each point in the sub-image's bounds, check that m.At(x, y) equals sub.At(x, y). - for y := sub.Rect.Min.Y; y < sub.Rect.Max.Y; y++ { - for x := sub.Rect.Min.X; x < sub.Rect.Max.X; x++ { - color0 := m.At(x, y).(color.YCbCr) - color1 := sub.At(x, y).(color.YCbCr) - if color0 != color1 { - t.Errorf("r=%v, subsampleRatio=%v, delta=%v, x=%d, y=%d, color0=%v, color1=%v", - r, subsampleRatio, delta, x, y, color0, color1) - return - } - } - } - } - } - } - } -} diff --git a/vendor/gitlab.com/nyarla/go-crypt/.travis.yml b/vendor/gitlab.com/nyarla/go-crypt/.travis.yml deleted file mode 100644 index 57bd4a7..0000000 --- a/vendor/gitlab.com/nyarla/go-crypt/.travis.yml +++ /dev/null @@ -1,7 +0,0 @@ -language: go - -go: - - 1.1 - - 1.2 - - 1.3 - - tip diff --git a/vendor/gitlab.com/nyarla/go-crypt/LICENSE b/vendor/gitlab.com/nyarla/go-crypt/LICENSE deleted file mode 100644 index 72b0500..0000000 --- a/vendor/gitlab.com/nyarla/go-crypt/LICENSE +++ /dev/null @@ -1,14 +0,0 @@ -Copyright (c) 2009, -Copyright (c) 2013-2014 Naoki OKAMURA (Nyarla) - -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/gitlab.com/nyarla/go-crypt/README.md b/vendor/gitlab.com/nyarla/go-crypt/README.md deleted file mode 100644 index 5b1322e..0000000 --- a/vendor/gitlab.com/nyarla/go-crypt/README.md +++ /dev/null @@ -1,42 +0,0 @@ -crypt -===== - -A golang implementation of crypt(3). - - -[![Build Status](https://travis-ci.org/nyarla/go-crypt.svg?branch=master)](https://travis-ci.org/nyarla/go-crypt) [![GoDoc](http://godoc.org/github.com/nyarla/go-crypt?status.svg)](https://godoc.org/github.com/nyarla/go-crypt) - -EXAMPLES CODE -------------- - -```go -import ( - "fmt" - - "github.com/nyarlabo/go-crypt" -) - -func main() { - fmt.Println(crypt.Crypt("testtest", "es")); // esDRYJnY4VaGM -} -``` - -WHY I FROKED IT? ----------------- - -Original implementation is writte by iasija at 2009-12-08, -and original implementation is not supported golang 1.1 or later. - -So I fork it for fix this issue, and I added documenation and test code. - -Original implementation is hosting on [code.google.com/p/go-crypt](https://code.google.com/p/go-crypt), -and that source code is under the 3-Clause BSD. - -NOTE: I could't find to iasija's contact address. - -COPYRIGTS AND LICENSE ---------------------- - - 1. Original Implementation: Copyright (c) 2009 iasija All Rights Reserved. ([BSD-3-Clause](http://opensource.org/licenses/BSD-3-Clause)) - 2. Modification Codes: Copyright (c) 22013-2015 Naoki OKAMURA a.k.a nyarla Some Rights Reserved. ([BSD-3-Clause](http://opensource.org/licenses/BSD-3-Clause)) - diff --git a/vendor/gitlab.com/nyarla/go-crypt/crypt.go b/vendor/gitlab.com/nyarla/go-crypt/crypt.go deleted file mode 100644 index 2dee9f1..0000000 --- a/vendor/gitlab.com/nyarla/go-crypt/crypt.go +++ /dev/null @@ -1,276 +0,0 @@ -package crypt - -import ( - "bytes" -) - -var PC1_C = []byte{ - 57, 49, 41, 33, 25, 17, 9, - 1, 58, 50, 42, 34, 26, 18, - 10, 2, 59, 51, 43, 35, 27, - 19, 11, 3, 60, 52, 44, 36, -} - -var PC1_D = []byte{ - 63, 55, 47, 39, 31, 23, 15, - 7, 62, 54, 46, 38, 30, 22, - 14, 6, 61, 53, 45, 37, 29, - 21, 13, 5, 28, 20, 12, 4, -} - -var PC2_C = []byte{ - 14, 17, 11, 24, 1, 5, - 3, 28, 15, 6, 21, 10, - 23, 19, 12, 4, 26, 8, - 16, 7, 27, 20, 13, 2, -} -var PC2_D = []byte{ - 41, 52, 31, 37, 47, 55, - 30, 40, 51, 45, 33, 48, - 44, 49, 39, 56, 34, 53, - 46, 42, 50, 36, 29, 32, -} - -var e2 = []byte{ - 32, 1, 2, 3, 4, 5, - 4, 5, 6, 7, 8, 9, - 8, 9, 10, 11, 12, 13, - 12, 13, 14, 15, 16, 17, - 16, 17, 18, 19, 20, 21, - 20, 21, 22, 23, 24, 25, - 24, 25, 26, 27, 28, 29, - 28, 29, 30, 31, 32, 1, -} - -var IP = []byte{ - 58, 50, 42, 34, 26, 18, 10, 2, - 60, 52, 44, 36, 28, 20, 12, 4, - 62, 54, 46, 38, 30, 22, 14, 6, - 64, 56, 48, 40, 32, 24, 16, 8, - 57, 49, 41, 33, 25, 17, 9, 1, - 59, 51, 43, 35, 27, 19, 11, 3, - 61, 53, 45, 37, 29, 21, 13, 5, - 63, 55, 47, 39, 31, 23, 15, 7, -} - -var FP = []byte{ - 40, 8, 48, 16, 56, 24, 64, 32, - 39, 7, 47, 15, 55, 23, 63, 31, - 38, 6, 46, 14, 54, 22, 62, 30, - 37, 5, 45, 13, 53, 21, 61, 29, - 36, 4, 44, 12, 52, 20, 60, 28, - 35, 3, 43, 11, 51, 19, 59, 27, - 34, 2, 42, 10, 50, 18, 58, 26, - 33, 1, 41, 9, 49, 17, 57, 25, -} - -var S = [][]byte{ - []byte{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, - 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, - 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, - 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}, - []byte{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, - 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, - 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, - 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}, - []byte{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, - 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, - 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, - 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}, - []byte{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, - 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, - 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, - 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}, - []byte{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, - 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, - 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, - 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}, - []byte{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, - 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, - 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, - 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}, - []byte{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, - 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, - 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, - 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}, - []byte{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, - 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, - 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, - 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}, -} - -var P = []byte{ - 16, 7, 20, 21, 29, 12, 28, 17, - 1, 15, 23, 26, 5, 18, 31, 10, - 2, 8, 24, 14, 32, 27, 3, 9, - 19, 13, 30, 6, 22, 11, 4, 25, -} - -var shift = []int{1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1} - -// Crypt is a implementation of crypt(3) like as perl or ruby and ...etc. -// -// Behavior of this func is same as perl-5.18.2's crypt on OSX Yosemite. -func Crypt(pw string, salt string) string { - if sLen := len(salt); sLen < 2 { - src := []byte(salt) - for len(src) < 2 { - src = append(src, 0x00) - } - salt = string(src) - } - - block := make([]byte, 66) - - for i := 0; i < 8 && i < len(pw); i++ { - for j := 0; j < 7; j++ { - block[(8*i)+j] = (pw[i] >> byte(6-j)) & 1 - } - } - - C := make([]byte, 28) - D := make([]byte, 28) - - for i := 0; i < 28; i++ { - C[i] = block[PC1_C[i]-1] - D[i] = block[PC1_D[i]-1] - } - - KS := make([][]byte, 16) - for i := 0; i < 16; i++ { - KS[i] = make([]byte, 48) - } - - for i := 0; i < 16; i++ { - for k := 0; k < shift[i]; k++ { - t := C[0] - for j := 0; j < 28-1; j++ { - C[j] = C[j+1] - } - C[27] = t - t = D[0] - for j := 0; j < 28-1; j++ { - D[j] = D[j+1] - } - D[27] = t - } - for j := 0; j < 24; j++ { - KS[i][j] = C[PC2_C[j]-1] - KS[i][j+24] = D[PC2_D[j]-28-1] - } - } - - E := make([]byte, 48) - for i := 0; i < 48; i++ { - E[i] = e2[i] - } - - iobuf := make([]byte, 16) - for i := 0; i < 2; i++ { - c := byte(salt[i]) - iobuf[i] = c - - if c > 'Z' { - c -= 6 - } - if c > '9' { - c -= 7 - } - - c -= '.' - - for j := 0; j < 6; j++ { - if (c>>byte(j))&1 != 0 { - k := E[6*i+j] - E[6*i+j] = E[6*i+j+24] - E[6*i+j+24] = k - } - } - } - - for i := 0; i < 66; i++ { - block[i] = 0 - } - - R := make([]byte, 32) - L := make([]byte, 32) - DMY := make([]byte, 32) - preS := make([]byte, 48) - f := make([]byte, 32) - dmy_block := make([]byte, 64) - - for m := 0; m < 25; m++ { - for i := 0; i < 32; i++ { - L[i] = block[IP[i]-1] - } - for i := 32; i < 64; i++ { - R[i-32] = block[IP[i]-1] - } - - for i := 0; i < 16; i++ { - for j := 0; j < 32; j++ { - DMY[j] = R[j] - } - for j := 0; j < 48; j++ { - preS[j] = R[E[j]-1] ^ KS[i][j] - } - for j := 0; j < 8; j++ { - t := 6 * j - k := S[j][(preS[t+0]<<5)+ - (preS[t+1]<<3)+ - (preS[t+2]<<2)+ - (preS[t+3]<<1)+ - (preS[t+4]<<0)+ - (preS[t+5]<<4)] - - t = 4 * j - f[t+0] = (k >> 3) & 01 - f[t+1] = (k >> 2) & 01 - f[t+2] = (k >> 1) & 01 - f[t+3] = (k >> 0) & 01 - } - for j := 0; j < 32; j++ { - R[j] = L[j] ^ f[P[j]-1] - } - for j := 0; j < 32; j++ { - L[j] = DMY[j] - } - } - - for i := 0; i < 32; i++ { - L[i], R[i] = R[i], L[i] - } - - for i := 0; i < 32; i++ { - dmy_block[i] = L[i] - } - for i := 32; i < 64; i++ { - dmy_block[i] = R[i-32] - } - for i := 0; i < 64; i++ { - block[i] = dmy_block[FP[i]-1] - } - } - var i int - for i = 0; i < 11; i++ { - c := byte(0) - for j := 0; j < 6; j++ { - c = c << 1 - c = c | block[6*i+j] - } - c = c + '.' - - if c > '9' { - c += 7 - } - if c > 'Z' { - c += 6 - } - - iobuf[i+2] = c - } - - iobuf[i+2] = 0 - - return string(bytes.Replace(iobuf, []byte{0x00}, []byte{}, -1)) -} diff --git a/vendor/gitlab.com/nyarla/go-crypt/crypt_test.go b/vendor/gitlab.com/nyarla/go-crypt/crypt_test.go deleted file mode 100644 index 0d28902..0000000 --- a/vendor/gitlab.com/nyarla/go-crypt/crypt_test.go +++ /dev/null @@ -1,18 +0,0 @@ -package crypt - -import ( - "fmt" - "testing" -) - -func TestCrypt(t *testing.T) { - if ret := Crypt("testtest", "es"); ret != `esDRYJnY4VaGM` { - t.Fatal(fmt.Sprintf(`result of Crypt is musmatch: %+v`, []byte(ret))) - } -} - -func ExampleCrypt() { - fmt.Println(Crypt("testtest", "es")) - // Output: - // esDRYJnY4VaGM -} diff --git a/vendor/gitlab.com/nyarla/go-crypt/doc.go b/vendor/gitlab.com/nyarla/go-crypt/doc.go deleted file mode 100644 index 005fa51..0000000 --- a/vendor/gitlab.com/nyarla/go-crypt/doc.go +++ /dev/null @@ -1,11 +0,0 @@ -// Package crypt is a implementation of crypt(3) by golang. -// -// This is a fork of iasija's orignal implementation. -// -// Orignal soruce code Copyrights (C) iasija All rights reserved, -// and original source code is under the 3-Clause BSD. -// -// Modification codes for supporting latest golang and added test codes are -// Copyright (c) 2013-2014 Naoki OKAMURA , -// and modifiration code and test codes are under same as the orignal source code license. (3-Clause BSD) -package crypt From 4fcf12dff2e2e786b1175c85b0b50d42a4211369 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sun, 4 Sep 2022 21:45:39 +0200 Subject: [PATCH 20/62] Huge rework to more modern code --- api.go | 35 +++++---- api_images.go | 82 +++++++++++---------- backend.go | 44 ++++++++++++ backend_local.go | 106 +++++++++++++++++++++++++++ images.go | 6 +- main.go | 40 +++++------ picture.go | 181 +++++++++++++++++------------------------------ version.go | 4 +- 8 files changed, 306 insertions(+), 192 deletions(-) create mode 100644 backend.go create mode 100644 backend_local.go diff --git a/api.go b/api.go index d955498..6fcd695 100644 --- a/api.go +++ b/api.go @@ -12,24 +12,31 @@ import ( type DispatchFunction func(*User, []string, io.ReadCloser) (interface{}, error) -var apiRoutes = map[string]*(map[string]struct { - AuthFunction - DispatchFunction -}){ - "images": &ApiImagesRouting, - "next": &ApiNextImagesRouting, - "version": &ApiVersionRouting, -} - type apiHandler struct { + PE *PictureExplorer Authenticate func(*http.Request) *User + routes map[string](map[string]struct { + AuthFunction + DispatchFunction + }) } -func ApiHandler(Authenticate func(*http.Request) *User) apiHandler { - return apiHandler{Authenticate} +func NewAPIHandler(pe *PictureExplorer, authenticate func(*http.Request) *User) *apiHandler { + return &apiHandler{ + pe, + authenticate, + map[string](map[string]struct { + AuthFunction + DispatchFunction + }){ + "images": ApiImagesRouting(pe), + "next": ApiNextImagesRouting(pe), + "version": ApiVersionRouting, + }, + } } -func (a apiHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { +func (a *apiHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { user := a.Authenticate(r) log.Printf("Handling %s API request from %s: %s %s [%s]\n", r.Method, r.RemoteAddr, r.URL.Path, user, r.UserAgent()) @@ -55,8 +62,8 @@ func (a apiHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { // Route request if len(sURL) == 0 { err = errors.New(fmt.Sprintf("No action provided")) - } else if h, ok := apiRoutes[sURL[0]]; ok { - if f, ok := (*h)[r.Method]; ok { + } else if h, ok := a.routes[sURL[0]]; ok { + if f, ok := h[r.Method]; ok { if f.AuthFunction(user, sURL[1:]) { ret, err = f.DispatchFunction(user, sURL[1:], r.Body) } else { diff --git a/api_images.go b/api_images.go index a54d8f2..685215b 100644 --- a/api_images.go +++ b/api_images.go @@ -5,78 +5,88 @@ import ( "io" ) -var ApiImagesRouting = map[string]struct { +func ApiImagesRouting(pe *PictureExplorer) map[string]struct { AuthFunction DispatchFunction -}{ - "GET": {PublicPage, listImages}, - "POST": {PublicPage, addImage}, - "DELETE": {PrivatePage, hideImage}, -} - -var ApiNextImagesRouting = map[string]struct { - AuthFunction - DispatchFunction -}{ - "GET": {PrivatePage, listNextImages}, - "POST": {PublicPage, addImage}, - "DELETE": {PrivatePage, deleteImage}, -} - -func listImages(u *User, args []string, body io.ReadCloser) (interface{}, error) { - if len(args) < 1 { - return GetPublishedImages() - } else if args[0] == "last" { - return GetLastImage() - } else { - return GetPublishedImage(args[0]) +} { + return map[string]struct { + AuthFunction + DispatchFunction + }{ + "GET": {PublicPage, pe.listImages}, + "POST": {PublicPage, pe.addImage}, + "DELETE": {PrivatePage, pe.hideImage}, } } -func listNextImages(u *User, args []string, body io.ReadCloser) (interface{}, error) { +func ApiNextImagesRouting(pe *PictureExplorer) map[string]struct { + AuthFunction + DispatchFunction +} { + return map[string]struct { + AuthFunction + DispatchFunction + }{ + "GET": {PrivatePage, pe.listNextImages}, + "POST": {PublicPage, pe.addImage}, + "DELETE": {PrivatePage, pe.deleteImage}, + } +} + +func (pe *PictureExplorer) listImages(u *User, args []string, body io.ReadCloser) (interface{}, error) { if len(args) < 1 { - return GetNextImages() + return pe.GetPublishedImages() + } else if args[0] == "last" { + return pe.GetLastImage() + } else { + return pe.GetPublishedImage(args[0]) + } +} + +func (pe *PictureExplorer) listNextImages(u *User, args []string, body io.ReadCloser) (interface{}, error) { + if len(args) < 1 { + return pe.GetNextImages() } else if len(args) >= 2 && args[1] == "publish" { - if pict, err := GetNextImage(args[0]); err != nil { + if pict, err := pe.GetNextImage(args[0]); err != nil { return nil, err - } else if err := pict.Publish(); err != nil { + } else if err := pe.Publish(pict); err != nil { return nil, err } else { return true, nil } } else { - return GetNextImage(args[0]) + return pe.GetNextImage(args[0]) } } -func addImage(u *User, args []string, body io.ReadCloser) (interface{}, error) { +func (pe *PictureExplorer) addImage(u *User, args []string, body io.ReadCloser) (interface{}, error) { if len(args) < 1 { return nil, errors.New("Need an image identifier to create") - } else if err := AddImage(args[0], body); err != nil { + } else if err := pe.AddImage(args[0], body); err != nil { return nil, err } else { return true, nil } } -func hideImage(u *User, args []string, body io.ReadCloser) (interface{}, error) { +func (pe *PictureExplorer) hideImage(u *User, args []string, body io.ReadCloser) (interface{}, error) { if len(args) < 1 { return nil, errors.New("Need an image identifier to delete") - } else if pict, err := GetPublishedImage(args[0]); err != nil { + } else if pict, err := pe.GetPublishedImage(args[0]); err != nil { return nil, errors.New("No matching image") - } else if err := pict.Unpublish(); err != nil { + } else if err := pe.Unpublish(pict); err != nil { return nil, err } else { return true, nil } } -func deleteImage(u *User, args []string, body io.ReadCloser) (interface{}, error) { +func (pe *PictureExplorer) deleteImage(u *User, args []string, body io.ReadCloser) (interface{}, error) { if len(args) < 1 { return nil, errors.New("Need an image identifier to delete") - } else if pict, err := GetNextImage(args[0]); err != nil { + } else if pict, err := pe.GetNextImage(args[0]); err != nil { return nil, errors.New("No matching image") - } else if err := pict.Remove(); err != nil { + } else if err := pe.Remove(pict); err != nil { return nil, err } else { return true, nil diff --git a/backend.go b/backend.go new file mode 100644 index 0000000..e5d2073 --- /dev/null +++ b/backend.go @@ -0,0 +1,44 @@ +package main + +import ( + "fmt" + "image" + "io" + "net/http" + "strings" +) + +var existing_backends []string + +type BackendSelector string + +func (s *BackendSelector) String() string { + return string(*s) +} + +func (s *BackendSelector) Set(v string) error { + found := false + for _, b := range existing_backends { + if strings.ToLower(v) == b { + found = true + tmp := BackendSelector(v) + s = &tmp + break + } + } + + if !found { + return fmt.Errorf("%q is not a known file backend (existing backends: %v)", v, existing_backends) + } + return nil +} + +type FileBackend interface { + DeletePicture(string, string) error + ServeFile() http.Handler + GetPicture(string, string, io.Writer) error + GetPictureInfo(string, string) (*Picture, error) + ListPictures(string) ([]*Picture, error) + MovePicture(string, string, string) error + PutPicture(string, string, *image.Image) error +} diff --git a/backend_local.go b/backend_local.go new file mode 100644 index 0000000..ade2f86 --- /dev/null +++ b/backend_local.go @@ -0,0 +1,106 @@ +package main + +import ( + "image" + "image/jpeg" + "io" + "io/ioutil" + "net/http" + "os" + "path" + "time" +) + +func init() { + existing_backends = append(existing_backends, "local") +} + +type LocalFileBackend struct { + BaseDir string +} + +func (l *LocalFileBackend) getPath(box, name string) string { + return path.Join(l.BaseDir, box, name+".jpg") +} + +func (l *LocalFileBackend) DeletePicture(box, name string) error { + return os.Remove(l.getPath(box, name)) +} + +func (l *LocalFileBackend) ServeFile() http.Handler { + return http.FileServer(http.Dir(l.BaseDir)) +} + +func (l *LocalFileBackend) createPictureInfo(local_path, name string, file os.FileInfo) *Picture { + return &Picture{ + local_path, // Path + name, // Basename + name[:len(name)-len(path.Ext(name))], // Sanitized filename + file.ModTime(), // UploadTime + } +} + +func (l *LocalFileBackend) GetPicture(box, name string, w io.Writer) error { + local_path := l.getPath(box, name) + + fd, err := os.Open(local_path) + if err != nil { + return err + } + defer fd.Close() + + _, err = io.Copy(w, fd) + + return err +} + +func (l *LocalFileBackend) GetPictureInfo(box, name string) (*Picture, error) { + local_path := l.getPath(box, name) + + file, err := os.Stat(local_path) + if err != nil { + return nil, err + } + + return l.createPictureInfo(path.Join(box, name+".jpg"), name, file), nil +} + +func (l *LocalFileBackend) ListPictures(box string) ([]*Picture, error) { + files, err := ioutil.ReadDir(path.Join(l.BaseDir, box)) + if err != nil { + return nil, err + } + + var pictures []*Picture + for _, file := range files { + if !file.IsDir() { + pictures = append(pictures, l.createPictureInfo(path.Join(box, file.Name()), file.Name(), file)) + } + } + + return pictures, nil +} + +func (l *LocalFileBackend) MovePicture(box_from, box_to, name string) error { + newpath := l.getPath(box_to, name) + + err := os.Rename( + l.getPath(box_from, name), + newpath, + ) + if err != nil { + return err + } + + return os.Chtimes(newpath, time.Now(), time.Now()) +} + +func (l *LocalFileBackend) PutPicture(box, name string, img *image.Image) error { + fd, err := os.OpenFile(l.getPath(box, name), os.O_RDWR|os.O_CREATE, 0644) + if err != nil { + return err + } + defer fd.Close() + + return jpeg.Encode(fd, *img, nil) +} diff --git a/images.go b/images.go index 56b38eb..af74ce7 100644 --- a/images.go +++ b/images.go @@ -10,10 +10,10 @@ type imagesHandler struct { name string auth func(*http.Request) bool hndlr http.Handler - getter func(fname string) (Picture, error) + getter func(fname string) (*Picture, error) } -func ImagesHandler(name string, auth func(*http.Request) bool, hndlr http.Handler, getter func(fname string) (Picture, error)) imagesHandler { +func ImagesHandler(name string, auth func(*http.Request) bool, hndlr http.Handler, getter func(fname string) (*Picture, error)) imagesHandler { return imagesHandler{name, auth, hndlr, getter} } @@ -50,7 +50,7 @@ func (i imagesHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusNotFound) return } else { - r.URL.Path = "/" + pict.basename + r.URL.Path = "/" + pict.path i.hndlr.ServeHTTP(w, r) } } diff --git a/main.go b/main.go index 994bd66..dbbe066 100644 --- a/main.go +++ b/main.go @@ -9,15 +9,13 @@ import ( var mux = http.NewServeMux() -var PublishedImgDir string -var NextImgDir string var ThumbsDir string func main() { bind := flag.String("bind", ":8080", "Bind port/socket") htpasswd_file := flag.String("htpasswd", "", "Admin passwords file, Apache htpasswd format") - flag.StringVar(&PublishedImgDir, "publishedimgdir", "./images/published/", "Directory where save published pictures") - flag.StringVar(&NextImgDir, "nextimgdir", "./images/next/", "Directory where save pictures to review") + publishedImgDir := flag.String("publishedimgdir", "published/", "Directory where save published pictures") + nextImgDir := flag.String("nextimgdir", "next/", "Directory where save pictures to review") flag.StringVar(&ThumbsDir, "thumbsdir", "./images/thumbs/", "Directory where generate thumbs") flag.Parse() @@ -29,22 +27,12 @@ func main() { if htpasswd, err = NewHtpasswd(*htpasswd_file); htpasswd == nil { log.Fatal("Unable to parse htpasswd:", err) } - } else if NextImgDir == "./images/next/" { + } else if *nextImgDir == "./images/next/" { log.Println("Disable admin interface, images will be published without moderation") - NextImgDir = PublishedImgDir + nextImgDir = publishedImgDir } log.Println("Checking paths...") - if _, err := os.Stat(PublishedImgDir); os.IsNotExist(err) { - if err := os.MkdirAll(PublishedImgDir, 0755); err != nil { - log.Fatal(err) - } - } - if _, err := os.Stat(NextImgDir); os.IsNotExist(err) { - if err := os.MkdirAll(NextImgDir, 0755); err != nil { - log.Fatal(err) - } - } if _, err := os.Stat(ThumbsDir); os.IsNotExist(err) { if err := os.MkdirAll(ThumbsDir, 0755); err != nil { log.Fatal(err) @@ -63,32 +51,38 @@ func main() { http.FileServer(Assets).ServeHTTP(w, r) }) - mux.Handle("/api/", http.StripPrefix("/api", ApiHandler(authFunc))) + pe := &PictureExplorer{ + FileBackend: &LocalFileBackend{"./images/"}, + PublishedImgDir: *publishedImgDir, + NextImgDir: *nextImgDir, + } + + mux.Handle("/api/", http.StripPrefix("/api", NewAPIHandler(pe, authFunc))) mux.Handle("/images/", http.StripPrefix("/images", ImagesHandler( "images", func(*http.Request) bool { return true }, - http.FileServer(http.Dir(PublishedImgDir)), - GetPublishedImage, + pe.ServeFile(), + pe.GetPublishedImage, ))) mux.Handle("/images/next/", http.StripPrefix("/images/next", ImagesHandler( "next", func(r *http.Request) bool { return authFunc(r) != nil }, - http.FileServer(http.Dir(NextImgDir)), - GetNextImage, + pe.ServeFile(), + pe.GetNextImage, ))) mux.Handle("/images/thumbs/", http.StripPrefix("/images/thumbs", ImagesHandler( "thumbs", func(*http.Request) bool { return true }, http.FileServer(http.Dir(ThumbsDir)), - GetPublishedImage, + pe.GetPublishedImage, ))) mux.Handle("/images/next/thumbs/", http.StripPrefix("/images/next/thumbs", ImagesHandler( "nexthumbs", func(r *http.Request) bool { return authFunc(r) != nil }, http.FileServer(http.Dir(ThumbsDir)), - GetNextImage, + pe.GetNextImage, ))) mux.HandleFunc("/admin/", func(w http.ResponseWriter, r *http.Request) { diff --git a/picture.go b/picture.go index 3904cfc..42fb39a 100644 --- a/picture.go +++ b/picture.go @@ -8,16 +8,20 @@ import ( "image/jpeg" _ "image/png" "io" - "io/ioutil" "os" - "path/filepath" + "path" "sort" - "strconv" "time" "github.com/nfnt/resize" ) +type PictureExplorer struct { + FileBackend + PublishedImgDir string + NextImgDir string +} + type Picture struct { path string basename string @@ -25,7 +29,7 @@ type Picture struct { UploadTime time.Time `json:"upload_time"` } -type ByUploadTime []Picture +type ByUploadTime []*Picture func (a ByUploadTime) Len() int { return len(a) } func (a ByUploadTime) Swap(i, j int) { a[i], a[j] = a[j], a[i] } @@ -33,137 +37,84 @@ func (a ByUploadTime) Less(i, j int) bool { return a[i].UploadTime.Sub(a[j].UploadTime).Nanoseconds() < 0 } -func getImages(dir string) ([]Picture, error) { - if files, err := ioutil.ReadDir(dir); err != nil { +func (e *PictureExplorer) GetNextImages() (pictures []*Picture, err error) { + pictures, err = e.ListPictures(e.NextImgDir) + sort.Sort(ByUploadTime(pictures)) + return +} + +func (e *PictureExplorer) GetPublishedImages() (pictures []*Picture, err error) { + pictures, err = e.ListPictures(e.PublishedImgDir) + sort.Sort(ByUploadTime(pictures)) + return +} + +func (e *PictureExplorer) GetLastImage() (*Picture, error) { + picts, err := e.GetPublishedImages() + if err != nil { return nil, err - } else { - pictures := make([]Picture, 0) - for _, file := range files { - if !file.IsDir() { - filename := file.Name() - pictures = append(pictures, Picture{ - filepath.Join(dir, filename), // Path - filename, // Basename - filename[:len(filename)-len(filepath.Ext(filename))], // Sanitized filename - file.ModTime(), // UploadTime - }) - } - } - sort.Sort(ByUploadTime(pictures)) - return pictures, nil } + + return picts[len(picts)-1], nil } -func GetNextImages() ([]Picture, error) { - return getImages(NextImgDir) +func (e *PictureExplorer) GetPublishedImage(fname string) (*Picture, error) { + return e.GetPictureInfo(e.PublishedImgDir, fname) } -func GetPublishedImages() ([]Picture, error) { - return getImages(PublishedImgDir) +func (e *PictureExplorer) GetNextImage(fname string) (*Picture, error) { + return e.GetPictureInfo(e.NextImgDir, fname) } -func GetLastImage() (Picture, error) { - if picts, err := GetPublishedImages(); err != nil { - return Picture{}, err - } else { - return picts[len(picts)-1], nil - } -} - -func getImage(flist func() ([]Picture, error), fname string) (Picture, error) { - if picts, err := flist(); err != nil { - return Picture{}, err - } else if pid, err := strconv.Atoi(fname); err == nil { - if pid < len(picts) { - return picts[pid], nil - } else { - return Picture{}, errors.New("Invalid picture identifier") - } - } else { - for _, pict := range picts { - if pict.Name == fname || pict.basename == fname { - return pict, nil - } - } - return Picture{}, errors.New("No such picture") - } -} - -func GetPublishedImage(fname string) (Picture, error) { - return getImage(GetPublishedImages, fname) -} - -func GetNextImage(fname string) (Picture, error) { - return getImage(GetNextImages, fname) -} - -func UniqueImage(filename string) bool { - if pict, _ := GetPublishedImage(filename); pict.path != "" { +func (e *PictureExplorer) IsUniqueName(filename string) bool { + if pict, _ := e.GetPublishedImage(filename); pict != nil { return false - } else { - if pict, _ := GetNextImage(filename); pict.path != "" { - return false - } else { - return true - } } + + if pict, _ := e.GetNextImage(filename); pict != nil { + return false + } + + return true } -func AddImage(filename string, blob io.ReadCloser) error { +func (e *PictureExplorer) AddImage(filename string, blob io.ReadCloser) error { // Check the name is not already used - if ok := UniqueImage(filename); !ok { + if ok := e.IsUniqueName(filename); !ok { return errors.New("This filename is already used, please choose another one.") - - // Convert to JPEG - } else if img, _, err := image.Decode(base64.NewDecoder(base64.StdEncoding, blob)); err != nil { - return err - - // Save file - } else if fw, err := os.Create(filepath.Join(NextImgDir, filename+".jpg")); err != nil { - return err - } else if err := jpeg.Encode(fw, img, nil); err != nil { - return err - } else { - fw.Close() - - thumb := resize.Thumbnail(300, 185, img, resize.Lanczos3) - - // Save thumbnail - if fw, err := os.Create(filepath.Join(ThumbsDir, filename+".jpg")); err != nil { - return err - } else if err := jpeg.Encode(fw, thumb, nil); err != nil { - return err - } else { - fw.Close() - } } - return nil + // Convert to JPEG + img, _, err := image.Decode(base64.NewDecoder(base64.StdEncoding, blob)) + if err != nil { + return err + } + + // Save file + if err := e.PutPicture(e.NextImgDir, filename, &img); err != nil { + return err + } + + thumb := resize.Thumbnail(300, 185, img, resize.Lanczos3) + + // Save thumbnail + fw, err := os.Create(path.Join(ThumbsDir, filename+".jpg")) + if err != nil { + return err + } + defer fw.Close() + + return jpeg.Encode(fw, thumb, nil) } -func (p Picture) Publish() error { - npath := filepath.Join(PublishedImgDir, p.basename) - if err := os.Rename(p.path, npath); err != nil { - return err - } else if err := os.Chtimes(npath, time.Now(), time.Now()); err != nil { - return err - } else { - return nil - } +func (e *PictureExplorer) Publish(p *Picture) error { + return e.MovePicture(e.NextImgDir, e.PublishedImgDir, p.Name) } -func (p Picture) Unpublish() error { - if err := os.Rename(p.path, filepath.Join(NextImgDir, p.basename)); err != nil { - return err - } else { - return nil - } +func (e *PictureExplorer) Unpublish(p *Picture) error { + return e.MovePicture(e.PublishedImgDir, e.NextImgDir, p.Name) } -func (p Picture) Remove() error { - if err := os.Remove(p.path); err != nil { - return err - } else { - return nil - } +func (e *PictureExplorer) Remove(p *Picture) error { + return e.DeletePicture(path.Dir(p.path), p.Name) } diff --git a/version.go b/version.go index 82911a9..f6ffa95 100644 --- a/version.go +++ b/version.go @@ -4,6 +4,8 @@ import ( "io" ) +const VERSION = 0.3 + var ApiVersionRouting = map[string]struct { AuthFunction DispatchFunction @@ -12,7 +14,7 @@ var ApiVersionRouting = map[string]struct { } func showVersion(u *User, args []string, body io.ReadCloser) (interface{}, error) { - m := map[string]interface{}{"version": 0.2} + m := map[string]interface{}{"version": VERSION} if u != nil { m["youare"] = *u From d4764ce4850f928cae50b253eb250a99feecc436 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sun, 4 Sep 2022 22:45:30 +0200 Subject: [PATCH 21/62] Avoid infinite loop when no picture to load --- backend_local.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend_local.go b/backend_local.go index ade2f86..55aa353 100644 --- a/backend_local.go +++ b/backend_local.go @@ -71,7 +71,7 @@ func (l *LocalFileBackend) ListPictures(box string) ([]*Picture, error) { return nil, err } - var pictures []*Picture + pictures := make([]*Picture, 0) for _, file := range files { if !file.IsDir() { pictures = append(pictures, l.createPictureInfo(path.Join(box, file.Name()), file.Name(), file)) From f1d98b605f87f6d07ff28dc2202561ea25e139b3 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sun, 4 Sep 2022 23:15:16 +0200 Subject: [PATCH 22/62] Add s3 backend --- backend_s3.go | 239 ++++++++++++++++++++++++++++++++++++++++++++++++++ go.mod | 1 + go.sum | 17 ++++ 3 files changed, 257 insertions(+) create mode 100644 backend_s3.go diff --git a/backend_s3.go b/backend_s3.go new file mode 100644 index 0000000..3bfd1f9 --- /dev/null +++ b/backend_s3.go @@ -0,0 +1,239 @@ +package main + +import ( + "bytes" + "fmt" + "image" + "image/jpeg" + "io" + "log" + "net/http" + "path" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/s3" + "github.com/aws/aws-sdk-go/service/s3/s3manager" +) + +func init() { + existing_backends = append(existing_backends, "s3") +} + +type S3FileBackend struct { + Endpoint string + Region string + Bucket string + AccessKey string + SecretKey string + PathStyle bool + BaseDir string +} + +func (l *S3FileBackend) getPath(box, name string) string { + if l.BaseDir == "" { + return path.Join(box, name+".jpg") + } else { + return path.Join(l.BaseDir, box, name+".jpg") + } +} + +func (l *S3FileBackend) newSession() (*session.Session, error) { + return session.NewSession(&aws.Config{ + Credentials: credentials.NewStaticCredentials(l.AccessKey, l.SecretKey, ""), + Endpoint: &l.Endpoint, + Region: &l.Region, + S3ForcePathStyle: &l.PathStyle, + }) +} + +func (l *S3FileBackend) DeletePicture(box, name string) error { + s, err := l.newSession() + if err != nil { + return err + } + + log.Println(l.getPath(box, name)) + + input := &s3.DeleteObjectsInput{ + Bucket: aws.String(l.Bucket), + Delete: &s3.Delete{ + Objects: []*s3.ObjectIdentifier{ + { + Key: aws.String(l.getPath(box, name)), + }, + }, + }, + } + + _, err = s3.New(s).DeleteObjects(input) + return err +} + +func (l *S3FileBackend) ServeFile() http.Handler { + return l +} + +func (l *S3FileBackend) ServeHTTP(w http.ResponseWriter, r *http.Request) { + s, err := l.newSession() + if err != nil { + return + } + + result, err := s3.New(s).GetObject(&s3.GetObjectInput{ + Bucket: aws.String(l.Bucket), + Key: aws.String(r.URL.Path), + }) + if err != nil { + return + } + + io.Copy(w, result.Body) +} + +func (l *S3FileBackend) createPictureInfo(local_path, name string, file *s3.Object) *Picture { + return &Picture{ + local_path, // Path + name, // Basename + name[:len(name)-len(path.Ext(name))], // Sanitized filename + *file.LastModified, // UploadTime + } +} + +func (l *S3FileBackend) GetPicture(box, name string, w io.Writer) error { + s, err := l.newSession() + if err != nil { + return err + } + + s3_path := l.getPath(box, name) + + input := &s3.GetObjectInput{ + Bucket: aws.String(l.Bucket), + Key: aws.String(s3_path), + } + + result, err := s3.New(s).GetObject(input) + if err != nil { + return err + } + + _, err = io.Copy(w, result.Body) + + return err +} + +func (l *S3FileBackend) GetPictureInfo(box, name string) (*Picture, error) { + s, err := l.newSession() + if err != nil { + return nil, err + } + + input := &s3.ListObjectsInput{ + Bucket: aws.String(l.Bucket), + Prefix: aws.String(l.getPath(box, name)), + } + + result, err := s3.New(s).ListObjects(input) + if err != nil { + return nil, err + } + + var pictures []*Picture + for _, file := range result.Contents { + pictures = append(pictures, l.createPictureInfo(*file.Key, path.Base(*file.Key), file)) + break + } + + if len(pictures) == 0 { + return nil, fmt.Errorf("Object not found") + } + + return pictures[0], nil +} + +func (l *S3FileBackend) ListPictures(box string) ([]*Picture, error) { + s, err := l.newSession() + if err != nil { + return nil, err + } + + input := &s3.ListObjectsInput{ + Bucket: aws.String(l.Bucket), + } + + if l.BaseDir == "" { + input.Prefix = aws.String(box) + } else { + input.Prefix = aws.String(path.Join(l.BaseDir, box)) + } + + result, err := s3.New(s).ListObjects(input) + if err != nil { + return nil, err + } + + pictures := make([]*Picture, 0) + for _, file := range result.Contents { + pictures = append(pictures, l.createPictureInfo(path.Join(box, *file.Key), path.Base(*file.Key), file)) + } + + return pictures, nil +} + +func (l *S3FileBackend) MovePicture(box_from, box_to, name string) error { + s, err := l.newSession() + if err != nil { + return err + } + + log.Println(l.getPath(box_from, name), l.getPath(box_to, name)) + + _, err = s3.New(s).CopyObject(&s3.CopyObjectInput{ + Bucket: aws.String(l.Bucket), + CopySource: aws.String(path.Join("", l.Bucket, l.getPath(box_from, name))), + Key: aws.String(l.getPath(box_to, name)), + }) + if err != nil { + return err + } + + log.Println(l.getPath(box_from, name)) + + input := &s3.DeleteObjectsInput{ + Bucket: aws.String(l.Bucket), + Delete: &s3.Delete{ + Objects: []*s3.ObjectIdentifier{ + { + Key: aws.String(l.getPath(box_from, name)), + }, + }, + }, + } + + _, err = s3.New(s).DeleteObjects(input) + return err +} + +func (l *S3FileBackend) PutPicture(box, name string, img *image.Image) error { + s, err := l.newSession() + if err != nil { + return err + } + + bbuf := new(bytes.Buffer) + err = jpeg.Encode(bbuf, *img, nil) + if err != nil { + return err + } + + _, err = s3manager.NewUploader(s).Upload(&s3manager.UploadInput{ + Bucket: aws.String(l.Bucket), + ACL: aws.String("public-read"), + Key: aws.String(l.getPath(box, name)), + Body: bbuf, + }) + + return err +} diff --git a/go.mod b/go.mod index 2103e1f..1680c74 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module git.nemunai.re/youp0m go 1.16 require ( + github.com/aws/aws-sdk-go v1.44.91 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b ) diff --git a/go.sum b/go.sum index 2acb4d9..3fb513e 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,21 @@ +github.com/aws/aws-sdk-go v1.44.91 h1:SRWmuX7PTyhBdLuvSfM7KWrWISJsrRsUPcFDSFduRxY= +github.com/aws/aws-sdk-go v1.44.91/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b h1:7gd+rd8P3bqcn/96gOZa3F5dpJr/vEiDQYlNb/y2uNs= gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2cqquPa0MKWeNkmOM5RQsRhkrwMWonFMN7fE= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= From f008669bd869e0664abff89c7f967600ffa3e0d2 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sun, 4 Sep 2022 23:32:03 +0200 Subject: [PATCH 23/62] Handle option to switch between local and s3 --- backend_s3.go | 29 +++++++++++++++++++++++++++++ main.go | 14 +++++++++++++- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/backend_s3.go b/backend_s3.go index 3bfd1f9..ad71106 100644 --- a/backend_s3.go +++ b/backend_s3.go @@ -2,12 +2,14 @@ package main import ( "bytes" + "flag" "fmt" "image" "image/jpeg" "io" "log" "net/http" + "os" "path" "github.com/aws/aws-sdk-go/aws" @@ -17,8 +19,35 @@ import ( "github.com/aws/aws-sdk-go/service/s3/s3manager" ) +var ( + s3_endpoint string + s3_region = "us" + s3_bucket string + s3_access_key string + s3_secret_key string + s3_path_style bool +) + func init() { existing_backends = append(existing_backends, "s3") + + s3_endpoint, _ = os.LookupEnv("S3_ENDPOINT") + if region, ok := os.LookupEnv("S3_REGION"); ok { + s3_region = region + } + s3_bucket, _ = os.LookupEnv("S3_BUCKET") + s3_access_key, _ = os.LookupEnv("S3_ACCESS_KEY") + s3_secret_key, _ = os.LookupEnv("S3_SECRET_KEY") + if path_style, ok := os.LookupEnv("S3_PATH_STYLE"); ok { + s3_path_style = path_style == "1" || path_style == "ON" || path_style == "on" || path_style == "TRUE" || path_style == "true" || path_style == "yes" || path_style == "YES" + } + + flag.StringVar(&s3_endpoint, "s3-endpoint", s3_endpoint, "When using S3 backend, endpoint to use") + flag.StringVar(&s3_region, "s3-region", s3_region, "When using S3 backend, region to use") + flag.StringVar(&s3_bucket, "s3-bucket", s3_bucket, "When using S3 backend, bucket to use") + flag.StringVar(&s3_access_key, "s3-access-key", s3_access_key, "When using S3 backend, Access Key") + flag.StringVar(&s3_secret_key, "s3-secret-key", s3_secret_key, "When using S3 backend, Secret Key") + flag.BoolVar(&s3_path_style, "s3-path-style", s3_path_style, "When using S3 backend, force path style (when using minio)") } type S3FileBackend struct { diff --git a/main.go b/main.go index dbbe066..6832338 100644 --- a/main.go +++ b/main.go @@ -2,6 +2,7 @@ package main import ( "flag" + "fmt" "log" "net/http" "os" @@ -16,6 +17,8 @@ func main() { htpasswd_file := flag.String("htpasswd", "", "Admin passwords file, Apache htpasswd format") publishedImgDir := flag.String("publishedimgdir", "published/", "Directory where save published pictures") nextImgDir := flag.String("nextimgdir", "next/", "Directory where save pictures to review") + baseDir := flag.String("basedir", "images/", "Local base directory where find published and next dirs") + backend := flag.String("storage-backend", "local", fmt.Sprintf("Storage backend to use (between: %s)", existing_backends)) flag.StringVar(&ThumbsDir, "thumbsdir", "./images/thumbs/", "Directory where generate thumbs") flag.Parse() @@ -51,8 +54,17 @@ func main() { http.FileServer(Assets).ServeHTTP(w, r) }) + var storage_backend FileBackend + if backend == nil || *backend == "local" { + storage_backend = &LocalFileBackend{*baseDir} + } else if *backend == "s3" { + storage_backend = &S3FileBackend{s3_endpoint, s3_region, s3_bucket, s3_access_key, s3_secret_key, s3_path_style, *baseDir} + } else { + log.Fatalf("%q is not a valid storage backend.", *backend) + } + pe := &PictureExplorer{ - FileBackend: &LocalFileBackend{"./images/"}, + FileBackend: storage_backend, PublishedImgDir: *publishedImgDir, NextImgDir: *nextImgDir, } From 15be0cf46518435d24bc06ff21624ee5d3f65369 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Mon, 5 Sep 2022 19:12:51 +0200 Subject: [PATCH 24/62] Also publish to registry.nemunai.re --- .drone-manifest-local.yml | 22 ++++++++++++++++ .drone.yml | 53 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 .drone-manifest-local.yml diff --git a/.drone-manifest-local.yml b/.drone-manifest-local.yml new file mode 100644 index 0000000..d9da4dd --- /dev/null +++ b/.drone-manifest-local.yml @@ -0,0 +1,22 @@ +image: registry.nemunai.re/youp0m:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}latest{{/if}} +{{#if build.tags}} +tags: +{{#each build.tags}} + - {{this}} +{{/each}} +{{/if}} +manifests: + - image: registry.nemunai.re/youp0m:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}linux-amd64 + platform: + architecture: amd64 + os: linux + - image: registry.nemunai.re/youp0m:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}linux-arm64 + platform: + architecture: arm64 + os: linux + variant: v8 + - image: registry.nemunai.re/youp0m:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}linux-arm + platform: + architecture: arm + os: linux + variant: v7 diff --git a/.drone.yml b/.drone.yml index ca48e19..de06f5f 100644 --- a/.drone.yml +++ b/.drone.yml @@ -31,6 +31,20 @@ steps: password: from_secret: docker_password + - name: publish on nemunai.re + image: plugins/docker + settings: + registry: registry.nemunai.re + repo: registry.nemunai.re/youp0m + auto_tag: true + auto_tag_suffix: ${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH} + experimental: true + squash: true + username: + from_secret: docker_nemunai.re_username + password: + from_secret: docker_nemunai.re_password + --- kind: pipeline type: docker @@ -64,6 +78,20 @@ steps: password: from_secret: docker_password + - name: publish on nemunai.re + image: plugins/docker + settings: + registry: registry.nemunai.re + repo: registry.nemunai.re/youp0m + auto_tag: true + auto_tag_suffix: ${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH} + experimental: true + squash: true + username: + from_secret: docker_nemunai.re_username + password: + from_secret: docker_nemunai.re_password + --- kind: pipeline type: docker @@ -97,6 +125,20 @@ steps: password: from_secret: docker_password + - name: publish on nemunai.re + image: plugins/docker + settings: + registry: registry.nemunai.re + repo: registry.nemunai.re/youp0m + auto_tag: true + auto_tag_suffix: ${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH} + experimental: true + squash: true + username: + from_secret: docker_nemunai.re_username + password: + from_secret: docker_nemunai.re_password + --- kind: pipeline name: docker-manifest @@ -113,6 +155,17 @@ steps: password: from_secret: docker_password +- name: publish on nemunai.re + image: plugins/manifest + settings: + auto_tag: true + ignore_missing: true + spec: .drone-manifest-local.yml + username: + from_secret: docker_nemunai.re_username + password: + from_secret: docker_nemunai.re_password + trigger: event: - cron From 3c14a3685c3a5393c48f84e847120b74c603bcf1 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Wed, 7 Sep 2022 10:43:13 +0200 Subject: [PATCH 25/62] Fix launch problem when directories doesn't exist --- main.go | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/main.go b/main.go index 6832338..1b0465c 100644 --- a/main.go +++ b/main.go @@ -6,6 +6,7 @@ import ( "log" "net/http" "os" + "path" ) var mux = http.NewServeMux() @@ -30,7 +31,7 @@ func main() { if htpasswd, err = NewHtpasswd(*htpasswd_file); htpasswd == nil { log.Fatal("Unable to parse htpasswd:", err) } - } else if *nextImgDir == "./images/next/" { + } else if *nextImgDir == "next/" { log.Println("Disable admin interface, images will be published without moderation") nextImgDir = publishedImgDir } @@ -57,6 +58,16 @@ func main() { var storage_backend FileBackend if backend == nil || *backend == "local" { storage_backend = &LocalFileBackend{*baseDir} + if _, err := os.Stat(path.Join(*baseDir, *publishedImgDir)); os.IsNotExist(err) { + if err := os.MkdirAll(path.Join(*baseDir, *publishedImgDir), 0755); err != nil { + log.Fatal(err) + } + } + if _, err := os.Stat(path.Join(*baseDir, *nextImgDir)); os.IsNotExist(err) { + if err := os.MkdirAll(path.Join(*baseDir, *nextImgDir), 0755); err != nil { + log.Fatal(err) + } + } } else if *backend == "s3" { storage_backend = &S3FileBackend{s3_endpoint, s3_region, s3_bucket, s3_access_key, s3_secret_key, s3_path_style, *baseDir} } else { From a2903b73a07175d673ac90175ac3113cf774c200 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Wed, 7 Sep 2022 11:37:13 +0200 Subject: [PATCH 26/62] Add a log entry about which storage backend is in use --- main.go | 1 + 1 file changed, 1 insertion(+) diff --git a/main.go b/main.go index 1b0465c..3515f3d 100644 --- a/main.go +++ b/main.go @@ -73,6 +73,7 @@ func main() { } else { log.Fatalf("%q is not a valid storage backend.", *backend) } + log.Printf("Using %s storage backend", *backend) pe := &PictureExplorer{ FileBackend: storage_backend, From ecda17fc7dde5ac31634a95272291bf37bab7c29 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Wed, 7 Sep 2022 11:48:28 +0200 Subject: [PATCH 27/62] Automatically select s3 backend storage if S3_xxx env are presents --- backend_s3.go | 6 +++++- main.go | 15 +++++++++------ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/backend_s3.go b/backend_s3.go index ad71106..4d6c589 100644 --- a/backend_s3.go +++ b/backend_s3.go @@ -31,8 +31,12 @@ var ( func init() { existing_backends = append(existing_backends, "s3") - s3_endpoint, _ = os.LookupEnv("S3_ENDPOINT") + if endpoint, ok := os.LookupEnv("S3_ENDPOINT"); ok { + backend = "s3" + s3_endpoint = endpoint + } if region, ok := os.LookupEnv("S3_REGION"); ok { + backend = "s3" s3_region = region } s3_bucket, _ = os.LookupEnv("S3_BUCKET") diff --git a/main.go b/main.go index 3515f3d..7203564 100644 --- a/main.go +++ b/main.go @@ -11,7 +11,10 @@ import ( var mux = http.NewServeMux() -var ThumbsDir string +var ( + ThumbsDir string + backend = "local" +) func main() { bind := flag.String("bind", ":8080", "Bind port/socket") @@ -19,7 +22,7 @@ func main() { publishedImgDir := flag.String("publishedimgdir", "published/", "Directory where save published pictures") nextImgDir := flag.String("nextimgdir", "next/", "Directory where save pictures to review") baseDir := flag.String("basedir", "images/", "Local base directory where find published and next dirs") - backend := flag.String("storage-backend", "local", fmt.Sprintf("Storage backend to use (between: %s)", existing_backends)) + flag.StringVar(&backend, "storage-backend", backend, fmt.Sprintf("Storage backend to use (between: %s)", existing_backends)) flag.StringVar(&ThumbsDir, "thumbsdir", "./images/thumbs/", "Directory where generate thumbs") flag.Parse() @@ -56,7 +59,7 @@ func main() { }) var storage_backend FileBackend - if backend == nil || *backend == "local" { + if backend == "local" { storage_backend = &LocalFileBackend{*baseDir} if _, err := os.Stat(path.Join(*baseDir, *publishedImgDir)); os.IsNotExist(err) { if err := os.MkdirAll(path.Join(*baseDir, *publishedImgDir), 0755); err != nil { @@ -68,12 +71,12 @@ func main() { log.Fatal(err) } } - } else if *backend == "s3" { + } else if backend == "s3" { storage_backend = &S3FileBackend{s3_endpoint, s3_region, s3_bucket, s3_access_key, s3_secret_key, s3_path_style, *baseDir} } else { - log.Fatalf("%q is not a valid storage backend.", *backend) + log.Fatalf("%q is not a valid storage backend.", backend) } - log.Printf("Using %s storage backend", *backend) + log.Printf("Using %s storage backend", backend) pe := &PictureExplorer{ FileBackend: storage_backend, From 0c4a9e49353e8c233935a97bd6bf76751d395f86 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sat, 10 Sep 2022 23:04:41 +0200 Subject: [PATCH 28/62] renovate: Auto-merge aws-sdk-go updates --- renovate.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/renovate.json b/renovate.json index 7190a60..7979833 100644 --- a/renovate.json +++ b/renovate.json @@ -1,3 +1,10 @@ { - "$schema": "https://docs.renovatebot.com/renovate-schema.json" + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "packageRules": [ + { + "matchPackageNames": ["github.com/aws/aws-sdk-go"], + "automerge": true, + "automergeType": "branch" + } + ] } From ef9cec5b4ab631d31269f84a837e98bf5f1555b3 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Sat, 10 Sep 2022 22:42:28 +0000 Subject: [PATCH 29/62] chore(deps): update module github.com/aws/aws-sdk-go to v1.44.95 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 1680c74..795248b 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.nemunai.re/youp0m go 1.16 require ( - github.com/aws/aws-sdk-go v1.44.91 + github.com/aws/aws-sdk-go v1.44.95 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b ) diff --git a/go.sum b/go.sum index 3fb513e..e5ed55a 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ github.com/aws/aws-sdk-go v1.44.91 h1:SRWmuX7PTyhBdLuvSfM7KWrWISJsrRsUPcFDSFduRxY= github.com/aws/aws-sdk-go v1.44.91/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.95 h1:QwmA+PeR6v4pF0f/dPHVPWGAshAhb9TnGZBTM5uKuI8= +github.com/aws/aws-sdk-go v1.44.95/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= From f48d9c463a73dd5f81eb2103e4fdc6dea86cfb60 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 12 Sep 2022 19:33:56 +0000 Subject: [PATCH 30/62] chore(deps): update module github.com/aws/aws-sdk-go to v1.44.96 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 795248b..bd2103a 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.nemunai.re/youp0m go 1.16 require ( - github.com/aws/aws-sdk-go v1.44.95 + github.com/aws/aws-sdk-go v1.44.96 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b ) diff --git a/go.sum b/go.sum index e5ed55a..71d94ae 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,8 @@ github.com/aws/aws-sdk-go v1.44.91 h1:SRWmuX7PTyhBdLuvSfM7KWrWISJsrRsUPcFDSFduRx github.com/aws/aws-sdk-go v1.44.91/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.95 h1:QwmA+PeR6v4pF0f/dPHVPWGAshAhb9TnGZBTM5uKuI8= github.com/aws/aws-sdk-go v1.44.95/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.96 h1:S9paaqnJ0AJ95t5AB+iK8RM6YNZN0W0Lek1gOVJsEr8= +github.com/aws/aws-sdk-go v1.44.96/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= From 8c36c3ff6ed6f13cda4f0bafa37e51cd4c933fee Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Tue, 13 Sep 2022 19:34:37 +0000 Subject: [PATCH 31/62] chore(deps): update module github.com/aws/aws-sdk-go to v1.44.97 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index bd2103a..103a8df 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.nemunai.re/youp0m go 1.16 require ( - github.com/aws/aws-sdk-go v1.44.96 + github.com/aws/aws-sdk-go v1.44.97 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b ) diff --git a/go.sum b/go.sum index 71d94ae..b0cae53 100644 --- a/go.sum +++ b/go.sum @@ -4,6 +4,8 @@ github.com/aws/aws-sdk-go v1.44.95 h1:QwmA+PeR6v4pF0f/dPHVPWGAshAhb9TnGZBTM5uKuI github.com/aws/aws-sdk-go v1.44.95/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.96 h1:S9paaqnJ0AJ95t5AB+iK8RM6YNZN0W0Lek1gOVJsEr8= github.com/aws/aws-sdk-go v1.44.96/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.97 h1:lxgxp7d6uuGsP7jHKIX3GHd7ExFigCIF04VuKf8XUII= +github.com/aws/aws-sdk-go v1.44.97/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= From 0710a3f77e69b89aefdf04c8406594d6c6a3e8a3 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Wed, 14 Sep 2022 19:28:46 +0000 Subject: [PATCH 32/62] chore(deps): update module github.com/aws/aws-sdk-go to v1.44.98 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 103a8df..fcb9bd5 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.nemunai.re/youp0m go 1.16 require ( - github.com/aws/aws-sdk-go v1.44.97 + github.com/aws/aws-sdk-go v1.44.98 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b ) diff --git a/go.sum b/go.sum index b0cae53..aa6d2bf 100644 --- a/go.sum +++ b/go.sum @@ -6,6 +6,8 @@ github.com/aws/aws-sdk-go v1.44.96 h1:S9paaqnJ0AJ95t5AB+iK8RM6YNZN0W0Lek1gOVJsEr github.com/aws/aws-sdk-go v1.44.96/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.97 h1:lxgxp7d6uuGsP7jHKIX3GHd7ExFigCIF04VuKf8XUII= github.com/aws/aws-sdk-go v1.44.97/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.98 h1:fX+NxebSdO/9T6DTNOLhpC+Vv6RNkKRfsMg0a7o/yBo= +github.com/aws/aws-sdk-go v1.44.98/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= From 064b72b13edc1ec85cb71dd9f0a5acef27b59276 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Fri, 16 Sep 2022 13:41:17 +0000 Subject: [PATCH 33/62] chore(deps): update module github.com/aws/aws-sdk-go to v1.44.99 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index fcb9bd5..5d80424 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.nemunai.re/youp0m go 1.16 require ( - github.com/aws/aws-sdk-go v1.44.98 + github.com/aws/aws-sdk-go v1.44.99 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b ) diff --git a/go.sum b/go.sum index aa6d2bf..e08a5e1 100644 --- a/go.sum +++ b/go.sum @@ -8,6 +8,8 @@ github.com/aws/aws-sdk-go v1.44.97 h1:lxgxp7d6uuGsP7jHKIX3GHd7ExFigCIF04VuKf8XUI github.com/aws/aws-sdk-go v1.44.97/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.98 h1:fX+NxebSdO/9T6DTNOLhpC+Vv6RNkKRfsMg0a7o/yBo= github.com/aws/aws-sdk-go v1.44.98/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.99 h1:ITZ9q/fmH+Ksaz2TbyMU2d19vOOWs/hAlt8NbXAieHw= +github.com/aws/aws-sdk-go v1.44.99/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= From f4ee5108781a6b56c282423e04dbba980123b185 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Fri, 16 Sep 2022 19:33:16 +0000 Subject: [PATCH 34/62] chore(deps): update module github.com/aws/aws-sdk-go to v1.44.100 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 5d80424..2d94216 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.nemunai.re/youp0m go 1.16 require ( - github.com/aws/aws-sdk-go v1.44.99 + github.com/aws/aws-sdk-go v1.44.100 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b ) diff --git a/go.sum b/go.sum index e08a5e1..f0f6d80 100644 --- a/go.sum +++ b/go.sum @@ -10,6 +10,8 @@ github.com/aws/aws-sdk-go v1.44.98 h1:fX+NxebSdO/9T6DTNOLhpC+Vv6RNkKRfsMg0a7o/yB github.com/aws/aws-sdk-go v1.44.98/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.99 h1:ITZ9q/fmH+Ksaz2TbyMU2d19vOOWs/hAlt8NbXAieHw= github.com/aws/aws-sdk-go v1.44.99/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.100 h1:7I86bWNQB+HGDT5z/dJy61J7qgbgLoZ7O51C9eL6hrA= +github.com/aws/aws-sdk-go v1.44.100/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= From 531c1a35c8cf271353f236de210945f5147c2584 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 19 Sep 2022 18:37:26 +0000 Subject: [PATCH 35/62] chore(deps): update module github.com/aws/aws-sdk-go to v1.44.101 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 2d94216..00c1917 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.nemunai.re/youp0m go 1.16 require ( - github.com/aws/aws-sdk-go v1.44.100 + github.com/aws/aws-sdk-go v1.44.101 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b ) diff --git a/go.sum b/go.sum index f0f6d80..f37db43 100644 --- a/go.sum +++ b/go.sum @@ -12,6 +12,8 @@ github.com/aws/aws-sdk-go v1.44.99 h1:ITZ9q/fmH+Ksaz2TbyMU2d19vOOWs/hAlt8NbXAieH github.com/aws/aws-sdk-go v1.44.99/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.100 h1:7I86bWNQB+HGDT5z/dJy61J7qgbgLoZ7O51C9eL6hrA= github.com/aws/aws-sdk-go v1.44.100/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.101 h1:O/em5aIxKI/FkwcWAFKEY+JhPDCRsqoVUC6xEF4tGic= +github.com/aws/aws-sdk-go v1.44.101/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= From 8b4d44cbc65b26fc6b18566926d3750d2f8939e4 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Tue, 20 Sep 2022 19:32:26 +0000 Subject: [PATCH 36/62] chore(deps): update module github.com/aws/aws-sdk-go to v1.44.102 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 00c1917..b884612 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.nemunai.re/youp0m go 1.16 require ( - github.com/aws/aws-sdk-go v1.44.101 + github.com/aws/aws-sdk-go v1.44.102 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b ) diff --git a/go.sum b/go.sum index f37db43..6df5648 100644 --- a/go.sum +++ b/go.sum @@ -14,6 +14,8 @@ github.com/aws/aws-sdk-go v1.44.100 h1:7I86bWNQB+HGDT5z/dJy61J7qgbgLoZ7O51C9eL6h github.com/aws/aws-sdk-go v1.44.100/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.101 h1:O/em5aIxKI/FkwcWAFKEY+JhPDCRsqoVUC6xEF4tGic= github.com/aws/aws-sdk-go v1.44.101/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.102 h1:6tUCTGL2UDbFZae1TLGk8vTgeXuzkb8KbAe2FiAeKHc= +github.com/aws/aws-sdk-go v1.44.102/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= From dafb75337ca73724e4571a566a703c5cc875f9c1 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Wed, 21 Sep 2022 19:34:06 +0000 Subject: [PATCH 37/62] chore(deps): update module github.com/aws/aws-sdk-go to v1.44.103 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index b884612..b44dbf1 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.nemunai.re/youp0m go 1.16 require ( - github.com/aws/aws-sdk-go v1.44.102 + github.com/aws/aws-sdk-go v1.44.103 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b ) diff --git a/go.sum b/go.sum index 6df5648..1b6bb8e 100644 --- a/go.sum +++ b/go.sum @@ -16,6 +16,8 @@ github.com/aws/aws-sdk-go v1.44.101 h1:O/em5aIxKI/FkwcWAFKEY+JhPDCRsqoVUC6xEF4tG github.com/aws/aws-sdk-go v1.44.101/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.102 h1:6tUCTGL2UDbFZae1TLGk8vTgeXuzkb8KbAe2FiAeKHc= github.com/aws/aws-sdk-go v1.44.102/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.103 h1:tbhBHKgiZSIUkG8FcHy3wYKpPVvp65Wn7ZiX0B8phpY= +github.com/aws/aws-sdk-go v1.44.103/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= From 4952b6f4850b9aaba678c64bfeb697ddc9dc436e Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Thu, 22 Sep 2022 18:36:00 +0000 Subject: [PATCH 38/62] chore(deps): update module github.com/aws/aws-sdk-go to v1.44.104 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index b44dbf1..9c7331e 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.nemunai.re/youp0m go 1.16 require ( - github.com/aws/aws-sdk-go v1.44.103 + github.com/aws/aws-sdk-go v1.44.104 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b ) diff --git a/go.sum b/go.sum index 1b6bb8e..90542b0 100644 --- a/go.sum +++ b/go.sum @@ -18,6 +18,8 @@ github.com/aws/aws-sdk-go v1.44.102 h1:6tUCTGL2UDbFZae1TLGk8vTgeXuzkb8KbAe2FiAeK github.com/aws/aws-sdk-go v1.44.102/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.103 h1:tbhBHKgiZSIUkG8FcHy3wYKpPVvp65Wn7ZiX0B8phpY= github.com/aws/aws-sdk-go v1.44.103/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.104 h1:NiPYL60aOSH0TsAzQngx/aBdxC12TXhgw07DQFh76GU= +github.com/aws/aws-sdk-go v1.44.104/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= From 819294659c4a3d907574d3848c753ff1c3f384eb Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Fri, 23 Sep 2022 19:33:07 +0000 Subject: [PATCH 39/62] chore(deps): update module github.com/aws/aws-sdk-go to v1.44.105 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 9c7331e..82a4654 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.nemunai.re/youp0m go 1.16 require ( - github.com/aws/aws-sdk-go v1.44.104 + github.com/aws/aws-sdk-go v1.44.105 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b ) diff --git a/go.sum b/go.sum index 90542b0..6e563bc 100644 --- a/go.sum +++ b/go.sum @@ -20,6 +20,8 @@ github.com/aws/aws-sdk-go v1.44.103 h1:tbhBHKgiZSIUkG8FcHy3wYKpPVvp65Wn7ZiX0B8ph github.com/aws/aws-sdk-go v1.44.103/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.104 h1:NiPYL60aOSH0TsAzQngx/aBdxC12TXhgw07DQFh76GU= github.com/aws/aws-sdk-go v1.44.104/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.105 h1:UUwoD1PRKIj3ltrDUYTDQj5fOTK3XsnqolLpRTMmSEM= +github.com/aws/aws-sdk-go v1.44.105/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= From 9a46f6ee7bbc58c26a95e465cb4c9cf6834067d7 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Sat, 1 Oct 2022 10:13:42 +0000 Subject: [PATCH 40/62] chore(deps): update module github.com/aws/aws-sdk-go to v1.44.109 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 82a4654..0789fba 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.nemunai.re/youp0m go 1.16 require ( - github.com/aws/aws-sdk-go v1.44.105 + github.com/aws/aws-sdk-go v1.44.109 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b ) diff --git a/go.sum b/go.sum index 6e563bc..f7443b3 100644 --- a/go.sum +++ b/go.sum @@ -22,6 +22,8 @@ github.com/aws/aws-sdk-go v1.44.104 h1:NiPYL60aOSH0TsAzQngx/aBdxC12TXhgw07DQFh76 github.com/aws/aws-sdk-go v1.44.104/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.105 h1:UUwoD1PRKIj3ltrDUYTDQj5fOTK3XsnqolLpRTMmSEM= github.com/aws/aws-sdk-go v1.44.105/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.109 h1:+Na5JPeS0kiEHoBp5Umcuuf+IDqXqD0lXnM920E31YI= +github.com/aws/aws-sdk-go v1.44.109/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= From 6b58cf4a3be6e4cd7721fa48dc69565765ca68c9 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Fri, 14 Oct 2022 16:30:16 +0000 Subject: [PATCH 41/62] chore(deps): update module github.com/aws/aws-sdk-go to v1.44.115 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 0789fba..da2e86a 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.nemunai.re/youp0m go 1.16 require ( - github.com/aws/aws-sdk-go v1.44.109 + github.com/aws/aws-sdk-go v1.44.115 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b ) diff --git a/go.sum b/go.sum index f7443b3..085cf64 100644 --- a/go.sum +++ b/go.sum @@ -24,6 +24,8 @@ github.com/aws/aws-sdk-go v1.44.105 h1:UUwoD1PRKIj3ltrDUYTDQj5fOTK3XsnqolLpRTMmS github.com/aws/aws-sdk-go v1.44.105/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.109 h1:+Na5JPeS0kiEHoBp5Umcuuf+IDqXqD0lXnM920E31YI= github.com/aws/aws-sdk-go v1.44.109/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.115 h1:qFYIx97cT3k54Bn/lfM6idHbqRHILJyG0SY/0qlKiG0= +github.com/aws/aws-sdk-go v1.44.115/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= From 705d28ef4aa3342e843891c33fd871cffb9e9a98 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Fri, 14 Oct 2022 19:27:47 +0000 Subject: [PATCH 42/62] chore(deps): update module github.com/aws/aws-sdk-go to v1.44.116 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index da2e86a..cbcd79a 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.nemunai.re/youp0m go 1.16 require ( - github.com/aws/aws-sdk-go v1.44.115 + github.com/aws/aws-sdk-go v1.44.116 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b ) diff --git a/go.sum b/go.sum index 085cf64..b514276 100644 --- a/go.sum +++ b/go.sum @@ -26,6 +26,8 @@ github.com/aws/aws-sdk-go v1.44.109 h1:+Na5JPeS0kiEHoBp5Umcuuf+IDqXqD0lXnM920E31 github.com/aws/aws-sdk-go v1.44.109/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.115 h1:qFYIx97cT3k54Bn/lfM6idHbqRHILJyG0SY/0qlKiG0= github.com/aws/aws-sdk-go v1.44.115/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.116 h1:NpLIhcvLWXJZAEwvPj3TDHeqp7DleK6ZUVYyW01WNHY= +github.com/aws/aws-sdk-go v1.44.116/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= From dc4ea96e40372190777b9ecc9b6c3d9de134f091 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 17 Oct 2022 19:23:40 +0000 Subject: [PATCH 43/62] chore(deps): update module github.com/aws/aws-sdk-go to v1.44.117 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index cbcd79a..91c08c0 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.nemunai.re/youp0m go 1.16 require ( - github.com/aws/aws-sdk-go v1.44.116 + github.com/aws/aws-sdk-go v1.44.117 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b ) diff --git a/go.sum b/go.sum index b514276..f88fe51 100644 --- a/go.sum +++ b/go.sum @@ -28,6 +28,8 @@ github.com/aws/aws-sdk-go v1.44.115 h1:qFYIx97cT3k54Bn/lfM6idHbqRHILJyG0SY/0qlKi github.com/aws/aws-sdk-go v1.44.115/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.116 h1:NpLIhcvLWXJZAEwvPj3TDHeqp7DleK6ZUVYyW01WNHY= github.com/aws/aws-sdk-go v1.44.116/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.117 h1:mZuODB3Y4soG9QWAXyGb2po+6Easa/enifpj4MnZ91s= +github.com/aws/aws-sdk-go v1.44.117/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= From c94b7de36593084361e234a7e9eef527cf6f3e98 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Tue, 18 Oct 2022 19:23:20 +0000 Subject: [PATCH 44/62] chore(deps): update module github.com/aws/aws-sdk-go to v1.44.118 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 91c08c0..5f7f3c9 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.nemunai.re/youp0m go 1.16 require ( - github.com/aws/aws-sdk-go v1.44.117 + github.com/aws/aws-sdk-go v1.44.118 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b ) diff --git a/go.sum b/go.sum index f88fe51..55e672b 100644 --- a/go.sum +++ b/go.sum @@ -30,6 +30,8 @@ github.com/aws/aws-sdk-go v1.44.116 h1:NpLIhcvLWXJZAEwvPj3TDHeqp7DleK6ZUVYyW01WN github.com/aws/aws-sdk-go v1.44.116/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.117 h1:mZuODB3Y4soG9QWAXyGb2po+6Easa/enifpj4MnZ91s= github.com/aws/aws-sdk-go v1.44.117/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.118 h1:FJOqIRTukf7+Ulp047/k7JB6eqMXNnj7eb+coORThHQ= +github.com/aws/aws-sdk-go v1.44.118/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= From 1fb6dfa3e693133ca8067666575fe767391bc67f Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Wed, 19 Oct 2022 19:24:03 +0000 Subject: [PATCH 45/62] chore(deps): update module github.com/aws/aws-sdk-go to v1.44.119 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 5f7f3c9..5675b6b 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.nemunai.re/youp0m go 1.16 require ( - github.com/aws/aws-sdk-go v1.44.118 + github.com/aws/aws-sdk-go v1.44.119 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b ) diff --git a/go.sum b/go.sum index 55e672b..9ed2dff 100644 --- a/go.sum +++ b/go.sum @@ -32,6 +32,8 @@ github.com/aws/aws-sdk-go v1.44.117 h1:mZuODB3Y4soG9QWAXyGb2po+6Easa/enifpj4MnZ9 github.com/aws/aws-sdk-go v1.44.117/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.118 h1:FJOqIRTukf7+Ulp047/k7JB6eqMXNnj7eb+coORThHQ= github.com/aws/aws-sdk-go v1.44.118/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.119 h1:TPkpDsanBMcZaF5wHwpKhjkapRV/b7d2qdC+a+IPbmY= +github.com/aws/aws-sdk-go v1.44.119/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= From cec1160a09ff322fada4e564a7c291c54789f89c Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Thu, 20 Oct 2022 19:32:14 +0000 Subject: [PATCH 46/62] chore(deps): update module github.com/aws/aws-sdk-go to v1.44.120 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 5675b6b..053db52 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.nemunai.re/youp0m go 1.16 require ( - github.com/aws/aws-sdk-go v1.44.119 + github.com/aws/aws-sdk-go v1.44.120 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b ) diff --git a/go.sum b/go.sum index 9ed2dff..033acca 100644 --- a/go.sum +++ b/go.sum @@ -34,6 +34,8 @@ github.com/aws/aws-sdk-go v1.44.118 h1:FJOqIRTukf7+Ulp047/k7JB6eqMXNnj7eb+coORTh github.com/aws/aws-sdk-go v1.44.118/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.119 h1:TPkpDsanBMcZaF5wHwpKhjkapRV/b7d2qdC+a+IPbmY= github.com/aws/aws-sdk-go v1.44.119/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.120 h1:dsOxGf17H9hCVCA4aWpFWEcJMHkX+Uw7l4pGcxb27wM= +github.com/aws/aws-sdk-go v1.44.120/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= From b31cb19326086c1999f9f6440a650aec77f14a30 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Fri, 21 Oct 2022 21:21:55 +0000 Subject: [PATCH 47/62] chore(deps): update module github.com/aws/aws-sdk-go to v1.44.121 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 053db52..c120fa6 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.nemunai.re/youp0m go 1.16 require ( - github.com/aws/aws-sdk-go v1.44.120 + github.com/aws/aws-sdk-go v1.44.121 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b ) diff --git a/go.sum b/go.sum index 033acca..60da941 100644 --- a/go.sum +++ b/go.sum @@ -36,6 +36,8 @@ github.com/aws/aws-sdk-go v1.44.119 h1:TPkpDsanBMcZaF5wHwpKhjkapRV/b7d2qdC+a+IPb github.com/aws/aws-sdk-go v1.44.119/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.120 h1:dsOxGf17H9hCVCA4aWpFWEcJMHkX+Uw7l4pGcxb27wM= github.com/aws/aws-sdk-go v1.44.120/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.121 h1:ahBRUqUp4qLyGmSM5KKn+TVpZkRmtuLxTWw+6Hq/ebs= +github.com/aws/aws-sdk-go v1.44.121/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= From 4d7a596556f1e3a8a868e72238018d8669f38912 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 24 Oct 2022 20:23:17 +0000 Subject: [PATCH 48/62] chore(deps): update module github.com/aws/aws-sdk-go to v1.44.122 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index c120fa6..8339f61 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.nemunai.re/youp0m go 1.16 require ( - github.com/aws/aws-sdk-go v1.44.121 + github.com/aws/aws-sdk-go v1.44.122 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b ) diff --git a/go.sum b/go.sum index 60da941..72ea28d 100644 --- a/go.sum +++ b/go.sum @@ -38,6 +38,8 @@ github.com/aws/aws-sdk-go v1.44.120 h1:dsOxGf17H9hCVCA4aWpFWEcJMHkX+Uw7l4pGcxb27 github.com/aws/aws-sdk-go v1.44.120/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.121 h1:ahBRUqUp4qLyGmSM5KKn+TVpZkRmtuLxTWw+6Hq/ebs= github.com/aws/aws-sdk-go v1.44.121/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.122 h1:p6mw01WBaNpbdP2xrisz5tIkcNwzj/HysobNoaAHjgo= +github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= From aeb006ce8c923eaa88425909034804b082644cbc Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Tue, 25 Oct 2022 19:23:40 +0000 Subject: [PATCH 49/62] chore(deps): update module github.com/aws/aws-sdk-go to v1.44.123 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 8339f61..fd1f03e 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.nemunai.re/youp0m go 1.16 require ( - github.com/aws/aws-sdk-go v1.44.122 + github.com/aws/aws-sdk-go v1.44.123 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b ) diff --git a/go.sum b/go.sum index 72ea28d..58e10f0 100644 --- a/go.sum +++ b/go.sum @@ -40,6 +40,8 @@ github.com/aws/aws-sdk-go v1.44.121 h1:ahBRUqUp4qLyGmSM5KKn+TVpZkRmtuLxTWw+6Hq/e github.com/aws/aws-sdk-go v1.44.121/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.122 h1:p6mw01WBaNpbdP2xrisz5tIkcNwzj/HysobNoaAHjgo= github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.123 h1:+vVGJ7+vQU6/wRcgRwSBBrIuG/lLL/0LB3HlN5jFv3c= +github.com/aws/aws-sdk-go v1.44.123/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= From 6177eb693a6239a5db0d08e160b9f91020a53f65 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Wed, 26 Oct 2022 19:21:17 +0000 Subject: [PATCH 50/62] chore(deps): update module github.com/aws/aws-sdk-go to v1.44.124 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index fd1f03e..07a9c4c 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.nemunai.re/youp0m go 1.16 require ( - github.com/aws/aws-sdk-go v1.44.123 + github.com/aws/aws-sdk-go v1.44.124 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b ) diff --git a/go.sum b/go.sum index 58e10f0..b839707 100644 --- a/go.sum +++ b/go.sum @@ -42,6 +42,8 @@ github.com/aws/aws-sdk-go v1.44.122 h1:p6mw01WBaNpbdP2xrisz5tIkcNwzj/HysobNoaAHj github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.123 h1:+vVGJ7+vQU6/wRcgRwSBBrIuG/lLL/0LB3HlN5jFv3c= github.com/aws/aws-sdk-go v1.44.123/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.124 h1:Xe1WQRUUekZf6ZFm3SD0vplB/AP/hymVqMiRS9LQRIs= +github.com/aws/aws-sdk-go v1.44.124/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= From 9bdad10889288cfd41741d3dff7b540aee6a930a Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Thu, 27 Oct 2022 20:24:00 +0000 Subject: [PATCH 51/62] chore(deps): update module github.com/aws/aws-sdk-go to v1.44.125 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 07a9c4c..2ae5178 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.nemunai.re/youp0m go 1.16 require ( - github.com/aws/aws-sdk-go v1.44.124 + github.com/aws/aws-sdk-go v1.44.125 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b ) diff --git a/go.sum b/go.sum index b839707..8173fa9 100644 --- a/go.sum +++ b/go.sum @@ -44,6 +44,8 @@ github.com/aws/aws-sdk-go v1.44.123 h1:+vVGJ7+vQU6/wRcgRwSBBrIuG/lLL/0LB3HlN5jFv github.com/aws/aws-sdk-go v1.44.123/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.124 h1:Xe1WQRUUekZf6ZFm3SD0vplB/AP/hymVqMiRS9LQRIs= github.com/aws/aws-sdk-go v1.44.124/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.125 h1:yIyCs6HX1BOj6SFTirvBwVM1tTfplKrJOyilIZPtKV8= +github.com/aws/aws-sdk-go v1.44.125/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= From 77309af9a4e614c1fd98b339cb7cbbc4ac3e7d3d Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Fri, 28 Oct 2022 19:23:33 +0000 Subject: [PATCH 52/62] chore(deps): update module github.com/aws/aws-sdk-go to v1.44.126 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 2ae5178..72f970a 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.nemunai.re/youp0m go 1.16 require ( - github.com/aws/aws-sdk-go v1.44.125 + github.com/aws/aws-sdk-go v1.44.126 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b ) diff --git a/go.sum b/go.sum index 8173fa9..97560f8 100644 --- a/go.sum +++ b/go.sum @@ -46,6 +46,8 @@ github.com/aws/aws-sdk-go v1.44.124 h1:Xe1WQRUUekZf6ZFm3SD0vplB/AP/hymVqMiRS9LQR github.com/aws/aws-sdk-go v1.44.124/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.125 h1:yIyCs6HX1BOj6SFTirvBwVM1tTfplKrJOyilIZPtKV8= github.com/aws/aws-sdk-go v1.44.125/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.126 h1:7HQJw2DNiwpxqMe2H7odGNT2rhO4SRrUe5/8dYXl0Jk= +github.com/aws/aws-sdk-go v1.44.126/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= From f1081e7805d944eabeafe1d5bc602d46caf8013f Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 31 Oct 2022 19:24:11 +0000 Subject: [PATCH 53/62] chore(deps): update module github.com/aws/aws-sdk-go to v1.44.127 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 72f970a..ef73963 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.nemunai.re/youp0m go 1.16 require ( - github.com/aws/aws-sdk-go v1.44.126 + github.com/aws/aws-sdk-go v1.44.127 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b ) diff --git a/go.sum b/go.sum index 97560f8..77e9dd6 100644 --- a/go.sum +++ b/go.sum @@ -48,6 +48,8 @@ github.com/aws/aws-sdk-go v1.44.125 h1:yIyCs6HX1BOj6SFTirvBwVM1tTfplKrJOyilIZPtK github.com/aws/aws-sdk-go v1.44.125/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.126 h1:7HQJw2DNiwpxqMe2H7odGNT2rhO4SRrUe5/8dYXl0Jk= github.com/aws/aws-sdk-go v1.44.126/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.127 h1:IoO2VfuIQg1aMXnl8l6OpNUKT4Qq5CnJMOyIWoTYXj0= +github.com/aws/aws-sdk-go v1.44.127/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= From d7ce810fdf4e084af235deacc70f533d0e127c6e Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Tue, 1 Nov 2022 19:23:35 +0000 Subject: [PATCH 54/62] chore(deps): update module github.com/aws/aws-sdk-go to v1.44.128 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index ef73963..7ee6f07 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.nemunai.re/youp0m go 1.16 require ( - github.com/aws/aws-sdk-go v1.44.127 + github.com/aws/aws-sdk-go v1.44.128 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b ) diff --git a/go.sum b/go.sum index 77e9dd6..3885d80 100644 --- a/go.sum +++ b/go.sum @@ -50,6 +50,8 @@ github.com/aws/aws-sdk-go v1.44.126 h1:7HQJw2DNiwpxqMe2H7odGNT2rhO4SRrUe5/8dYXl0 github.com/aws/aws-sdk-go v1.44.126/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.127 h1:IoO2VfuIQg1aMXnl8l6OpNUKT4Qq5CnJMOyIWoTYXj0= github.com/aws/aws-sdk-go v1.44.127/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.128 h1:X34pX5t0LIZXjBY11yf9JKMP3c1aZgirh+5PjtaZyJ4= +github.com/aws/aws-sdk-go v1.44.128/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= From 6078a885fb3387fabde062ccb53dcbfe4a6904b0 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Wed, 2 Nov 2022 19:22:06 +0000 Subject: [PATCH 55/62] chore(deps): update module github.com/aws/aws-sdk-go to v1.44.129 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 7ee6f07..e41c3ab 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.nemunai.re/youp0m go 1.16 require ( - github.com/aws/aws-sdk-go v1.44.128 + github.com/aws/aws-sdk-go v1.44.129 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b ) diff --git a/go.sum b/go.sum index 3885d80..57842d8 100644 --- a/go.sum +++ b/go.sum @@ -52,6 +52,8 @@ github.com/aws/aws-sdk-go v1.44.127 h1:IoO2VfuIQg1aMXnl8l6OpNUKT4Qq5CnJMOyIWoTYX github.com/aws/aws-sdk-go v1.44.127/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.128 h1:X34pX5t0LIZXjBY11yf9JKMP3c1aZgirh+5PjtaZyJ4= github.com/aws/aws-sdk-go v1.44.128/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.129 h1:yld8Rc8OCahLtenY1mnve4w1jVeBu/rSiscGzodaDOs= +github.com/aws/aws-sdk-go v1.44.129/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= From bfc360dfdae7be1ba106072d586722c4e5ccf2a9 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Thu, 3 Nov 2022 19:24:28 +0000 Subject: [PATCH 56/62] chore(deps): update module github.com/aws/aws-sdk-go to v1.44.130 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index e41c3ab..30956d9 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.nemunai.re/youp0m go 1.16 require ( - github.com/aws/aws-sdk-go v1.44.129 + github.com/aws/aws-sdk-go v1.44.130 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b ) diff --git a/go.sum b/go.sum index 57842d8..326731f 100644 --- a/go.sum +++ b/go.sum @@ -54,6 +54,8 @@ github.com/aws/aws-sdk-go v1.44.128 h1:X34pX5t0LIZXjBY11yf9JKMP3c1aZgirh+5PjtaZy github.com/aws/aws-sdk-go v1.44.128/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.129 h1:yld8Rc8OCahLtenY1mnve4w1jVeBu/rSiscGzodaDOs= github.com/aws/aws-sdk-go v1.44.129/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.130 h1:a/qwOxmYJF47xTZvTjECSJXnfRbjegb3YxvCXfETtnY= +github.com/aws/aws-sdk-go v1.44.130/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= From 51e06b4e8cc38bd046ea5722a5a4fd33c41e4ce9 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 7 Nov 2022 20:23:30 +0000 Subject: [PATCH 57/62] chore(deps): update module github.com/aws/aws-sdk-go to v1.44.132 --- go.mod | 2 +- go.sum | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 30956d9..1850c03 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.nemunai.re/youp0m go 1.16 require ( - github.com/aws/aws-sdk-go v1.44.130 + github.com/aws/aws-sdk-go v1.44.132 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b ) diff --git a/go.sum b/go.sum index 326731f..bb349aa 100644 --- a/go.sum +++ b/go.sum @@ -56,6 +56,8 @@ github.com/aws/aws-sdk-go v1.44.129 h1:yld8Rc8OCahLtenY1mnve4w1jVeBu/rSiscGzodaD github.com/aws/aws-sdk-go v1.44.129/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.130 h1:a/qwOxmYJF47xTZvTjECSJXnfRbjegb3YxvCXfETtnY= github.com/aws/aws-sdk-go v1.44.130/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.132 h1:+IjL9VoR0OXScQ5gyme9xjcolwUkd3uaH144f4Ao+4s= +github.com/aws/aws-sdk-go v1.44.132/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= @@ -65,13 +67,36 @@ github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b h1:7gd+rd8P3bqcn/96gOZa3F5dpJr/vEiDQYlNb/y2uNs= gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2cqquPa0MKWeNkmOM5RQsRhkrwMWonFMN7fE= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= From 28155ce861ed3ff2254547842b495f199448342c Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Tue, 8 Nov 2022 20:25:47 +0000 Subject: [PATCH 58/62] chore(deps): update module github.com/aws/aws-sdk-go to v1.44.133 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 1850c03..642495b 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.nemunai.re/youp0m go 1.16 require ( - github.com/aws/aws-sdk-go v1.44.132 + github.com/aws/aws-sdk-go v1.44.133 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b ) diff --git a/go.sum b/go.sum index bb349aa..b57387b 100644 --- a/go.sum +++ b/go.sum @@ -58,6 +58,8 @@ github.com/aws/aws-sdk-go v1.44.130 h1:a/qwOxmYJF47xTZvTjECSJXnfRbjegb3YxvCXfETt github.com/aws/aws-sdk-go v1.44.130/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.132 h1:+IjL9VoR0OXScQ5gyme9xjcolwUkd3uaH144f4Ao+4s= github.com/aws/aws-sdk-go v1.44.132/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/aws/aws-sdk-go v1.44.133 h1:+pWxt9nyKc0jf33rORBaQ93KPjYpmIIy3ozVXdJ82Oo= +github.com/aws/aws-sdk-go v1.44.133/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= From dd76f7753c6f9cce13e67bb0d7d8dc7e9d83ed0a Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Thu, 10 Nov 2022 20:26:19 +0000 Subject: [PATCH 59/62] chore(deps): update module github.com/aws/aws-sdk-go to v1.44.135 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 642495b..e48cdeb 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.nemunai.re/youp0m go 1.16 require ( - github.com/aws/aws-sdk-go v1.44.133 + github.com/aws/aws-sdk-go v1.44.135 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b ) diff --git a/go.sum b/go.sum index b57387b..f45d7c9 100644 --- a/go.sum +++ b/go.sum @@ -60,6 +60,8 @@ github.com/aws/aws-sdk-go v1.44.132 h1:+IjL9VoR0OXScQ5gyme9xjcolwUkd3uaH144f4Ao+ github.com/aws/aws-sdk-go v1.44.132/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/aws/aws-sdk-go v1.44.133 h1:+pWxt9nyKc0jf33rORBaQ93KPjYpmIIy3ozVXdJ82Oo= github.com/aws/aws-sdk-go v1.44.133/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/aws/aws-sdk-go v1.44.135 h1:DJJP/CkEpgafA5p5jlY9VzDRyKrfABVixzIxrK/3tWU= +github.com/aws/aws-sdk-go v1.44.135/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= From e72a787a594fa8520376911b64cc40d69e31adcf Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Fri, 11 Nov 2022 21:25:25 +0000 Subject: [PATCH 60/62] chore(deps): update module github.com/aws/aws-sdk-go to v1.44.136 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index e48cdeb..20b88a8 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.nemunai.re/youp0m go 1.16 require ( - github.com/aws/aws-sdk-go v1.44.135 + github.com/aws/aws-sdk-go v1.44.136 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b ) diff --git a/go.sum b/go.sum index f45d7c9..7195d1a 100644 --- a/go.sum +++ b/go.sum @@ -62,6 +62,8 @@ github.com/aws/aws-sdk-go v1.44.133 h1:+pWxt9nyKc0jf33rORBaQ93KPjYpmIIy3ozVXdJ82 github.com/aws/aws-sdk-go v1.44.133/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/aws/aws-sdk-go v1.44.135 h1:DJJP/CkEpgafA5p5jlY9VzDRyKrfABVixzIxrK/3tWU= github.com/aws/aws-sdk-go v1.44.135/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/aws/aws-sdk-go v1.44.136 h1:J1KJJssa8pjU8jETYUxwRS37KTcxjACfKd9GK8t+5ZU= +github.com/aws/aws-sdk-go v1.44.136/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= From afc05c5419472d7c095d01e39bf6390a5c73128f Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sun, 22 Jan 2023 20:30:24 +0100 Subject: [PATCH 61/62] Fix build on arm --- .drone.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.drone.yml b/.drone.yml index de06f5f..0c5bb9e 100644 --- a/.drone.yml +++ b/.drone.yml @@ -113,7 +113,7 @@ steps: - wget -O entrypoint.sh https://ankh.serekh.nemunai.re/local/entrypoint.sh-youp0m && chmod +x entrypoint.sh - name: publish - image: plugins/docker + image: plugins/docker:linux-arm settings: repo: nemunaire/youp0m auto_tag: true @@ -126,7 +126,7 @@ steps: from_secret: docker_password - name: publish on nemunai.re - image: plugins/docker + image: plugins/docker:linux-arm settings: registry: registry.nemunai.re repo: registry.nemunai.re/youp0m From cf5254ad5f20562bbf2e1506d7c8fc65bd596c8c Mon Sep 17 00:00:00 2001 From: nemunaire Date: Wed, 7 Jan 2026 03:22:59 +0000 Subject: [PATCH 62/62] Don't build to arm anymore --- .drone.yml | 48 ------------------------------------------------ 1 file changed, 48 deletions(-) diff --git a/.drone.yml b/.drone.yml index 0c5bb9e..358f8fc 100644 --- a/.drone.yml +++ b/.drone.yml @@ -92,53 +92,6 @@ steps: password: from_secret: docker_nemunai.re_password ---- -kind: pipeline -type: docker -name: build-arm - -platform: - os: linux - arch: arm - -steps: - - name: build - image: golang:alpine - commands: - - apk --no-cache add git go-bindata - - go generate -v - - go get -v -d - - go build -v -ldflags="-s -w" -o youp0m - - wget -O Dockerfile https://ankh.serekh.nemunai.re/local/Dockerfile-youp0m - - wget -O entrypoint.sh https://ankh.serekh.nemunai.re/local/entrypoint.sh-youp0m && chmod +x entrypoint.sh - - - name: publish - image: plugins/docker:linux-arm - settings: - repo: nemunaire/youp0m - auto_tag: true - auto_tag_suffix: ${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH} - experimental: true - squash: true - username: - from_secret: docker_username - password: - from_secret: docker_password - - - name: publish on nemunai.re - image: plugins/docker:linux-arm - settings: - registry: registry.nemunai.re - repo: registry.nemunai.re/youp0m - auto_tag: true - auto_tag_suffix: ${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH} - experimental: true - squash: true - username: - from_secret: docker_nemunai.re_username - password: - from_secret: docker_nemunai.re_password - --- kind: pipeline name: docker-manifest @@ -173,6 +126,5 @@ trigger: - tag depends_on: -- build-arm - build-arm64 - build-amd64