text:
/* global define, require, document, location, console  */
/*
    # BCD

    **Brix 组件定义规范**(BCD,Brix Component Definition)定义了组件的基本使用方式、公共方法和公共事件。

    **Brix Loader** 是组件加载器,负责管理 Brix Component 的整个生命周期,包括加载、初始化、渲染和销毁。

    所有支持 BCD 组件定义规范的组件,都可以被 Brix Loader 加载和管理。

    ## 使用方式

    使用 Brix Component 的书写格式如下:

    ```html
    <tag bx-name="moduleId" bx-options="{}" bx-type=""></tag>
    ```

    ### bx-name

    必选。

    `bx-name` 是组件模块标识符。Brix Loader 根据 `bx-name` 的值来加载组件。

    ### bx-options

    可选。

    `bx-options` 指定了组件初始化时所需的配置项。

    ### bx-type

    可选。

    `bx-type` 用于配置事件监听函数。其中,`type` 是事件类型,例如 `bx-click`、`bx-change`。

    ## 公开方法

    详见方法注释。

    ### Loader.boot( [ context ] [, callback ]  [, progress ] )
    ### Loader.destroy( component [, callback ] )
    ### Loader.query( moduleId [, context ] )

    ## 公共事件

    ### ready

    当前组件完全渲染完成后触发,包括子组件的渲染。

    ### destroyed

    当前组件销毁后触发,包括子组件的销毁。

    ## 组件

    *建议*组件实现以下方法:

    * .init()

        可选。

        组件初始化方法。如果存在,会由 Brix Loader 自动调用。

    * .render()

        必选。

        组件渲染方法。会由 Brix Loader 自动调用。

    * .destroy()

        可选。

        组件销毁方法。如果存在,会由 Brix Loader 自动调用。

    * .on( types, selector, data, fn )

        可选。

        在当前组件(关联的元素)上,为一个或多个事件类型绑定一个事件监听函数。

    * .off( types, selector, fn )

        可选。

        在当前组件(关联的元素)上,移除绑定的一个或多个类型的监听函数。

    * .trigger( type, data )

        可选。

        在当前组件(关联的元素)上,执行所有绑定的事件监听函数和默认行为,并模拟冒泡过程。

    * .triggerHandler( type, data )

        可选。

        在当前组件(关联的元素)上,执行所有绑定的事件监听函数, 但不模拟冒泡过程,也不触发默认行为。

    ===

    # Why Brix?

    像使用原生元素一样使用组件。

    备忘
        组件的组成
            从用户角度:方法、属性、事件
            从实现角度:数据、模板(展现 HTML)、行为(JavaScript(事件))、样式(CSS)
        历史
            http://etaoux.github.io/brix/
            https://github.com/etaoux/brix/issues
            http://etaoux.github.io/brix/duck/#!/api/Brix.Gallery.Dropdown
        规范
            http://gitlab.alibaba-inc.com/limu/brix-central/wikis/BCD
*/
define(
    [
        './loader/constant',
        './loader/options',
        './loader/util'
    ],
    function(
        Constant,
        Options,
        Util
    ) {

        var CACHE = {}
        var DEBUG = ~location.search.indexOf('brix.loader.debug')

        /*
            #### Loader.boot( [ context ] [, complete( records ) ] [, notify( error, instance, index, count ) ] )

            **初始化节点 `context` 以及节点 `context` 内的所有组件。**当所有组件初始化完成后回调函数 `complete` 被执行,当每个组件初始化完成后回调函数 `notify` 被执行。

            * **Loader.boot( complete, notify )**
                * Loader.boot()
                * Loader.boot( complete )
                * Loader.boot( complete, notify )
            * **Loader.boot( element, complete, notify )**
                * Loader.boot( element )
                * Loader.boot( element, complete )
                * Loader.boot( element, complete, notify )
            * **Loader.boot( array{element}, complete, notify )**
                * Loader.boot( array )
                * Loader.boot( array, complete )
                * Loader.boot( array, complete, notify )

            **参数的含义和默认值**如下:

            * `context` 可选。一个 DOM 元素,或一组 DOM 元素。默认为 `document.body`。
            * `complete( records )` 可选。一个回调函数,当所有组件初始化完成后被执行。
                * `records` 二维数组,记录了组件在初始化过程中的相关信息,包括:异常 `error`、组件实例 `instance`、在初始化队列中的下标 `index`、初始化队列的长度 `count`。数据结构为:

                    ```js
                    [
                        [error, instance, index, count],
                        [error, instance, index, count],
                        ...
                    ]
                    ```

                    详见下一个参数 `notify`。

            * `notify( error, instance, index, count )` 可选。一个回调函数,当每个组件初始化完成后被执行。
                * `error` 初始化过程中可能抛出的 `Error` 对象。如果没有发生任何错误,则为 `undefined`。
                * `instance` 当前组件的实例。
                * `index` 当前组件在初始化队列中的下标,即初始化的顺序。
                * `count` 初始化队列的长度。

            私有方法:

            * **Loader.boot( component, complete, notify )**
                * Loader.boot( component )
                * Loader.boot( component, complete )
                * Loader.boot( component, complete, notify )
            * **Loader.boot( array{component}, complete, notify )**
                * Loader.boot( array )
                * Loader.boot( array, complete )
                * Loader.boot( array, complete, notify )

            简:初始化所有组件。
        */
        function boot(context, complete, extraOptions /* Internal Use Only */ , notify) {
            // boot( component )                    context.element
            // boot( element )                      element
            // boot( array{element|component} )     array
            context = context.element || context

            // 初始化任务队列
            var queue = Util.queue()
            var completeArgs = []

            // 1. 查找组件节点 [bx-name]
            var elements = function() {
                // element or [ element|component ]
                var contextArray = context.nodeType ? [context] : context
                var elements = []
                Util.each(contextArray, function(item /*, index*/ ) {
                    // component or element
                    item = item.element || item
                    if (item.nodeType !== 1) return
                    if (item.getAttribute(Constant.ATTRS.id)) elements.push(item)
                    var descendants = item.getElementsByTagName('*')
                    Util.each(descendants, function(descendant /*, index*/ ) {
                        if (/pre|code/i.test(descendant.parentNode.nodeName)) return
                        if (descendant.nodeType !== 1) return
                        if (descendant.getAttribute(Constant.ATTRS.id)) elements.push(descendant)
                    })
                })
                return elements
            }()

            // 2. 顺序把初始化任务放入队列
            Util.each(elements, function(element, index) {
                if (element.clientId !== undefined) {
                    completeArgs.push([undefined, CACHE[element.clientId], index, elements.length])
                    return
                }
                queue
                    .queue(function(next) {
                        init(element, function(error, instance) {
                            completeArgs.push([error, instance, index, elements.length])
                            if (error) console.error(error.stack || error)
                            if (notify) notify(error, instance, index, elements.length)

                            if (error && Loader.onerror) {
                                error.moduleId = element.getAttribute(Constant.ATTRS.id)
                                Loader.onerror(error) // 运行时异常收集
                            }

                            next()
                        }, extraOptions)
                    })
            })

            // 3. 逐个出队,执行初始化任务
            // 4. 全部任务执行完成(无论成败)
            queue
                .queue(function() {
                    if (complete) complete(completeArgs)
                })
                .dequeue() // 开始出队执行

        }

        /*
            init(element)

            * init(element [, callback( error, instance )])

            初始化元素 element 关联的组件。
            简:初始化单个组件。
        */
        function init(element, callback, extraOptions /* Internal Use Only */ ) {
            // 初始化任务队列
            // var queue = Util.queue() // #20

            // 如果已经被初始化,则立即返回
            var clientId = element.clientId
            if (clientId !== undefined) {
                if (callback) callback(undefined, CACHE[clientId])
                return
            }

            // 如果没有模块标识符,则不需要初始化
            if (!element.getAttribute(Constant.ATTRS.id)) {
                if (callback) callback(undefined, undefined)
                return
            }

            // 1. 解析配置项
            var options = Options.parse(element)
            if (extraOptions) Util.extend(options, extraOptions)

            var BrixImpl, instance

            var label = 'module ' + options.moduleId + ' ' + options.clientId
            if (DEBUG) {
                console.group(label)
                console.time(label)
                var _callback = callback
                callback = function(error, instance) {
                    console.timeEnd(label)
                    console.groupEnd(label)
                    if (_callback) _callback(error, instance)
                }
            }

            __loadModule()

            function __loadModule(next) {
                next = next || __createInstance

                // 2. 加载组件模块
                // load module file
                /* jshint unused:false */
                // try {
                //     // 尝试快速获取已经加载过的模块
                //     BrixImpl = require(options.moduleId)
                //     setTimeout(next, 4)
                //     return
                // } catch (error) {}

                require([options.moduleId], function __loadModuleComplete(module) {
                    BrixImpl = module
                    next()
                }, function(error) {
                    // http://requirejs.org/docs/api.html#errbacks
                    if (callback) callback(new Error(error.message), instance)
                    else console.error(error.stack || error)

                    if (Loader.onerror) {
                        error.moduleId = options.moduleId
                        Loader.onerror(error) // 运行时异常收集
                    }
                })
            }

            function __createInstance(next) {
                next = next || __interceptInstanceDestroy

                try {
                    // 在组件模块上附加标记 __x_created_with,指示负责初始化的是 Brix Loader
                    // Add a mark to component module, indicating the Brix Loader is response for the initializing.
                    var __x_created_with = BrixImpl.__x_created_with
                    BrixImpl.__x_created_with = 'Brix Loader'

                    // 3. 创建组件实例(按需传入参数 options)
                    // Create a new module instance
                    instance = BrixImpl.length ? new BrixImpl(options) : new BrixImpl()

                    // 恢复标记
                    // Recovery the mark
                    BrixImpl.__x_created_with = __x_created_with

                    // 设置实例属性 options
                    instance.options = Util.extend(true, {}, instance.options, options)

                    // 设置其他公共属性
                    Util.extend(instance, Util.pick(options, Constant.OPTIONS))
                    instance.element.setAttribute('data-clientId', options.clientId)

                    next()
                } catch (error) {
                    if (callback) callback(error, instance)
                    else console.error(error.stack || error)

                    if (Loader.onerror) {
                        error.moduleId = options.moduleId
                        Loader.onerror(error) // 运行时异常收集
                    }
                }
            }

            function __interceptInstanceDestroy(next) {
                next = next || __cacheInstance

                // 拦截销毁方法
                // intercept destroy method of the module instance
                instance._destroy = instance.destroy
                instance.destroy = function() {
                    destroy(false, instance)
                }
                next()
            }

            function __cacheInstance(next) {
                next = next || __callInstanceInitialization

                // 缓存起来,关联父组件
                // cache the module instance
                cache(instance)
                next()
            }

            function __callInstanceInitialization(next) {
                next = next || __interceptInstanceRender

                // 4. 执行初始化
                // exec module instance initialize
                if (!instance.init) {
                    next()
                    return
                }

                try {
                    if (DEBUG) console.time(label + ' call  init')
                    var result = instance.init()
                    if (DEBUG) console.timeEnd(label + ' call  init')

                    // 如果返回了 Promise,则依赖 Promise 的状态
                    if (result && result.then) {
                        result.then(function() {
                            next()
                        }, function(error) {
                            throw error
                        })
                    } else {
                        next()
                    }
                } catch (error) {
                    if (callback) callback(error, instance)
                    else console.error(error)

                    if (Loader.onerror) {
                        error.moduleId = options.moduleId
                        Loader.onerror(error) // 运行时异常收集
                    }
                }
            }

            function __interceptInstanceRender(next) {
                next = next || __callInstanceRender

                // 拦截渲染方法
                // intercept render method of the module instance
                if (instance._render) {
                    next()
                    return
                }

                instance._render = instance.render
                instance.render = function() {
                    var deferred = Util.defer()
                    var promise = deferred.promise

                    // 如果存在已经被渲染的子组件,则先销毁
                    var hasRenderedChildren
                    if (instance.childClientIds.length) {
                        hasRenderedChildren = true
                        Util.each(instance.childClientIds, function(childClientId) {
                            if (CACHE[childClientId]) destroy(childClientId)
                        })
                    }
                    // 调用组件的 .render()
                    var result
                    if (instance._render) result = instance._render.apply(instance, arguments)
                    else console.warn(instance.clientId, instance.moduleId, 'render() is not defined')

                    // 如果返回了 Promise,则依赖 Promise 的状态
                    if (result && result.then) {
                        result.then(function() {
                            renderChildren()
                            syncClientId()
                        }, function(error) {
                            throw error
                        })
                    } else {
                        renderChildren()
                        syncClientId()
                    }

                    return promise

                    // 再次初始化子组件
                    function renderChildren() {
                        if (hasRenderedChildren) {
                            boot(instance.element, function( /* context */ ) {
                                deferred.resolve()
                            })
                        } else {
                            deferred.resolve()
                        }
                    }

                    // 同步 clientId
                    function syncClientId() {
                        var relatedElement = instance.relatedElement || instance.$relatedElement
                        if (relatedElement) {
                            // element
                            if (relatedElement.nodeType && (relatedElement.clientId === undefined)) {
                                relatedElement.clientId = options.clientId
                            } else if (relatedElement.length) {
                                // [ element ]
                                Util.each(relatedElement, function(item /*, index*/ ) {
                                    if (item.nodeType && (item.clientId === undefined)) {
                                        item.clientId = options.clientId
                                        item.setAttribute('data-moduleId', options.moduleId)
                                        item.setAttribute('data-clientId', options.clientId)
                                    }
                                })
                            }
                        }
                    }

                }
                next()
            }

            function __callInstanceRender(next) {
                next = next || __bindLifecycleEvent

                // 5. 执行渲染(不存在怎么办?必须有!)
                // exec render method of the module instance
                try {
                    if (DEBUG) console.time(label + ' call  render')
                    var result = instance.render(function(error /*, instance*/ ) {
                        if (error) {}
                    })
                    if (DEBUG) console.timeEnd(label + ' call  render')

                    // deferred
                    if (result && result.then) {
                        result.then(function() {
                            next()
                        }, function(error) {
                            if (callback) callback(error, instance)
                            else console.error(error.stack || error)

                            if (Loader.onerror) {
                                error.moduleId = options.moduleId
                                Loader.onerror(error) // 运行时异常收集
                            }
                        })
                    } else {
                        next()
                    }
                } catch (error) {
                    // TODO 渲染时发生错误的组件是否应该自动销毁?
                    if (callback) callback(error, instance)
                    else console.error(error.stack || error)

                    if (Loader.onerror) {
                        error.moduleId = options.moduleId
                        Loader.onerror(error) // 运行时异常收集
                    }
                }
            }

            function __bindLifecycleEvent(next) {
                next = next || __inspectDescendants

                // 绑定测试事件
                // bind lifecycle event of the module instance
                if (DEBUG && instance.on) {
                    Util.each(Constant.EVENTS, function(type) {
                        instance.on(type + Constant.LOADER_NAMESPACE, function(event) {
                            console.log(label, 'event', event.type)
                        })
                    })
                }
                next()
                    // .delay(100) // 每个组件之间的渲染间隔 100ms,方便观察
            }

            function __inspectDescendants(next) {
                next = next || __triggerReadyEvent

                // 检测是否有后代组件
                var descendants = element.getElementsByTagName('*')
                var hasBrixElement = false
                Util.each(descendants, function(descendant /*, index*/ ) {
                    if (descendant.nodeType !== 1) return
                    if (!hasBrixElement &&
                        descendant.getAttribute(Constant.ATTRS.id)) {
                        hasBrixElement = true
                    }
                })

                // 7. 如果有后代组件,则递归加载
                // boot descendants recursively
                if (hasBrixElement) {
                    boot(instance, function() {
                        next()
                    })
                } else {
                    // 如果没有后代组件,那么此时当前组件已经就绪。
                    next()
                }
            }

            function __triggerReadyEvent( /*next*/ ) {
                // 8. 当前组件和后代组件的渲染都完成后,触发 ready 事件
                // trigger ready event after current module instance and it's descendants are rendered
                if (instance.triggerHandler) {
                    instance.triggerHandler(Constant.EVENTS.ready)
                }
                if (callback) callback(undefined, instance)
            }
        }

        /*
            #### Loader.destroy( component [, complete() ] )

            销毁某个组件,包括它的后代组件。

            * **Loader.destroy( component, complete )**
                * Loader.destroy( component )
                * Loader.destroy( component, complete )
            * **Loader.destroy( element, complete )**
                * Loader.destroy( element )
                * Loader.destroy( element, complete )
            * **Loader.destroy( array{element|component}, complete )**
                * Loader.destroy( array{component} )
                * Loader.destroy( array{element} )
                * Loader.destroy( array{component}, complete )
                * Loader.destroy( array{element}, complete )
            * **Loader.destroy( context, complete )**
                * Loader.destroy( context )
                * Loader.destroy( context, complete )

            **参数的含义和默认值**如下:

            * `component` 某个组件实例。
            * `element` 一个关联了某个组件的 DOM 元素。
            * `array{element|component}` 一个含有组件实例或 DOM 元素的数组。
            * `context` 一个 DOM 元素。
            * `complete()` 可选。一个回调函数,当组件销毁后被执行。

            #### Loader.destroy( moduleId [, context] [, complete() ] )

            * **Loader.destroy( moduleId, complete )**
                * Loader.destroy( moduleId )
                * Loader.destroy( moduleId, complete )
            * **Loader.destroy( moduleId, context, complete )**
                * Loader.destroy( moduleId, context )
                    * Loader.destroy( moduleId, parentModuleId )
                    * Loader.destroy( moduleId, parentComponent )
                    * Loader.destroy( moduleId, parentElement )
                    * Loader.destroy( moduleId, array{parentModuleId} )
                    * Loader.destroy( moduleId, array{parentComponent} )
                    * Loader.destroy( moduleId, array{parentElement} )
                * Loader.destroy( moduleId, context, complete )

            **参数的含义和默认值**如下:

            * `moduleId` 模块标识符。
            * `context` 限定销毁的范围。可以是父(祖先)模块标识符 `parentModuleId`、父(祖先)组件实例 `parentComponent`、父(祖先)节点 `parentElement` 或数组 `array{parentModuleId|parentComponent|parentElement}`。
            * `complete()` 可选。一个回调函数,当组件销毁后被执行。

            私有方法:

            * ~~**Loader.destroy()**~~
            * Loader.destroy( clientId )
            * Loader.destroy( clientId, complete )

        */
        function destroy(remove /* Internal Use Only */ , moduleId, context, complete) {
            var instance

            // destroy( moduleId, context, complete )
            if (!Util.isBoolean(remove)) {
                complete = context
                context = moduleId
                moduleId = remove
                remove = true
            }

            // destroy( remove, moduleId, complete )
            if (Util.isFunction(context)) {
                complete = context
                context = undefined
            }

            // ~~Loader.destroy()~~
            if (moduleId === undefined) {
                if (complete) complete()
                return this
            }

            // destroy( remove, moduleId, context, complete )
            if (Util.isString(moduleId)) {
                instance = query(moduleId, context)
                if (!instance || !instance.length) { // fix #25
                    if (complete) complete()
                    return this
                }
            }

            // destroy( !component )
            // destroy( !clientId )
            // destroy( !element )
            // destroy( !array )
            if (
                (moduleId.clientId === undefined) &&
                !Util.isNumber(moduleId) &&
                !moduleId.nodeType &&
                !moduleId.length
            ) {
                if (complete) complete()
                return this
            }

            // destroy( remove, component, complete )
            if (moduleId.clientId) {
                instance = moduleId
            }

            // destroy( remove, clientId )
            if (Util.isNumber(moduleId)) {
                instance = CACHE[moduleId]
                if (!instance) {
                    if (complete) complete()
                    return this
                }
            }

            // destroy( remove, array )
            if (!Util.isString(moduleId) && !Util.isNumber(moduleId) &&
                !moduleId.nodeType && moduleId.length) {
                Util.each(moduleId, function(item) {
                    destroy(remove, item, context)
                })
                if (complete) complete()
                return this
            }

            // destroy( remove, element )
            if (moduleId.nodeType === 1) {
                // destroy( context )
                if (moduleId.clientId === undefined) {
                    var descendants = moduleId.getElementsByTagName('*')
                        // 倒序遍历,以避免某个元素被移除后,漏掉相邻的元素
                    for (var i = descendants.length - 1, descendant; i >= 0; i--) {
                        descendant = descendants[i]
                        if (!descendant) continue
                        if (descendant.nodeType !== 1) continue
                        if (descendant.getAttribute(Constant.ATTRS.id)) destroy(remove, descendant)
                    }
                    if (complete) complete()
                    return this
                } else {
                    // destroy( element )
                    instance = CACHE[
                        moduleId.clientId
                    ]
                }
            }

            // 如果已经被移除,则立即返回
            if (!instance) {
                if (complete) complete()
                return this
            }

            if (Util.isArray(instance) && instance.length) {
                Util.each(instance, function(item) {
                    destroy(remove, item, context)
                })
                if (complete) complete()
                return this
            }

            var label = 'module ' + instance.moduleId + ' ' + instance.clientId
            if (DEBUG) {
                console.group(label)
                console.time(label)
                var _complete = complete
                complete = function(error, instance) {
                    console.timeEnd(label)
                    console.groupEnd(label)
                    if (_complete) _complete(error, instance)
                }
            }

            // 先递归销毁后代组件
            if (instance.childClientIds.length) {
                Util.each(instance.childClientIds, function(clientId) {
                    destroy(remove, clientId)
                })
            }

            // 调用自定义销毁行为
            if (instance._destroy) {
                try {
                    instance._destroy()
                } catch (error) {
                    if (complete) complete(error)
                    else console.error(error.stack || error)

                    if (Loader.onerror) {
                        error.moduleId = instance.moduleId
                        Loader.onerror(error) // 运行时异常收集
                    }
                }
            }

            // 从缓存中移除
            delete CACHE[instance.clientId]

            // 取消与父组件的关联
            var parent = CACHE[instance.parentClientId]
            if (parent) {
                parent.childClientIds = Util.without(parent.childClientIds, instance.clientId)
            }

            // 触发 destroy 事件
            // 在移除关联的节点后,无法再继续利用浏览器事件模型来传播和触发事件,所以在移除前先触发 destroy 事件。
            if (instance.triggerHandler) instance.triggerHandler(Constant.EVENTS.destroy)

            // 从 DOM 树中移除当前组件关联的元素。
            if (instance.element) {
                instance.element.clientId = undefined
                if (remove && instance.element.parentNode) {
                    instance.element.parentNode.removeChild(instance.element)
                }
            }

            if (DEBUG) console.log(label, 'destroy')

            if (complete) complete()

            return this
        }

        // 缓存组件
        function cache(instance) {
            // 放入缓存
            CACHE[instance.clientId] = instance

            // 关联父组件
            var parent = CACHE[instance.parentClientId]
            if (parent) parent.childClientIds.push(instance.clientId)
        }

        /*
            #### Loader.query( moduleId [, context ] )

            根据模块标识符 `moduleId` 查找组件实例。

            * Loader.query( moduleId, context )
                * Loader.query( moduleId )
                * Loader.query( moduleId, parentModuleId )
                * Loader.query( moduleId, parentComponent )
                * Loader.query( moduleId, parentElement )
                * Loader.query( moduleId, array{parentModuleId} )
                * Loader.query( moduleId, array{parentComponent} )
                * Loader.query( moduleId, array{parentElement} )
            * Loader.query( element )
                * Loader.query( element )
                * Loader.query( array{element} )

            **参数的含义和默认值**如下:

            * `moduleId` 模块标识符。
            * `context` 限定查找的范围。可以是父(祖先)模块标识符 `parentModuleId`、父(祖先)组件实例 `parentComponent`、父(祖先)节点 `parentElement` 或数组 `array{parentModuleId|parentComponent|parentElement}`。
            * `element` 设置了属性 `bx-name` 的节点或节点数组。

            > 该方法的返回值是一个数组,包含了一组 Brix 组件实例,并且,数组上含有所有 Brix 组件实例的方法。
         */
        function query(moduleId, context) {
            var results = []
            var methods = []

            // 1. 根据 element 查找组件实例
            // query( element )
            if (moduleId.nodeType) {
                if (moduleId.clientId !== undefined && CACHE[moduleId.clientId]) {
                    results.push(CACHE[moduleId.clientId])
                }

            } else if (moduleId.length && !Util.isString(moduleId)) {
                // 1. 根据 elementArray 逐个查找组件实例
                // query( elementArray )
                Util.each(moduleId, function(element /*, index*/ ) {
                    if (element.clientId !== undefined && CACHE[element.clientId]) {
                        results.push(CACHE[element.clientId])
                    }
                })

            } else {
                // 1. 根据 moduleId 查找组件实例
                // query( moduleId )
                Util.each(CACHE, function(instance /*, index*/ ) {
                    // 从右向左查找,免去了去重步骤
                    if (instance.moduleId === moduleId) {
                        // 是否在 context 内
                        if (context === undefined || parents(instance, context).length) {
                            results.push(instance)
                        }
                    }
                })
            }

            // 收集组件方法
            Util.each(results, function(instance /*, index*/ ) {
                if (!instance) return // 容错
                Util.each(instance.constructor.prototype, function(value, name) {
                    if (Util.isFunction(value) && (name[0] !== '_')) methods.push(name)
                })
            })

            // 2. 绑定组件方法至 query() 返回的对象上
            Util.each(Util.unique(methods), function(name /*, index*/ ) {
                results[name] = function() {
                    var args = [].slice.call(arguments)
                    var result
                    var hasNewResults = false
                    var tmpNewResults = []
                    Util.each(this, function(instance /*, index*/ ) {
                        if (!instance[name]) return
                        result = instance[name].apply(instance, args)
                        if (result !== undefined && result !== instance) {
                            hasNewResults = true
                            tmpNewResults.push(result)
                        }
                    })
                    if (hasNewResults) return tmpNewResults
                    return this
                }
            })

            return results
        }

        /*
            查找父组件
            context
                moduleId
                component options render
                element   nodeType
                array
         */
        function parents(instance, context) {
            var results = []
            var parent
            if (context === undefined) return results

            // parents(instance, array)
            if (!Util.isString(context) && !context.nodeType && context.length) {
                Util.each(context, function(item /*, index*/ ) {
                    results = results.concat(parents(instance, item))
                })
                return results
            }

            // 从当前组件 instance 开始,逐层向上遍历

            // parents(instance, component)
            if (context.options && context.render) {
                parent = instance

                // 在 instance 的祖先元素中,查找与 context.clientId 匹配的元素
                while ((parent = CACHE[parent.parentClientId])) {
                    if (parent.clientId === context.clientId) {
                        results.push(parent)
                        break
                    }
                }

            } else if (context.nodeType) {
                // parents(instance, element)
                parent = instance.element

                // 在 instance 的祖先元素中,查找与 context 相等的元素
                while ((parent = parent.parentNode)) {
                    if (parent === context) {
                        results.push(parent)
                        break
                    }
                }

            } else {
                // parents(instance, moduleId)
                parent = instance

                // 在 instance 的祖先元素中,查找与 context 匹配的元素
                while ((parent = CACHE[parent.parentClientId])) {
                    if (parent.moduleId === context) {
                        results.push(parent)
                    }
                }
            }

            return results
        }

        /*

            #### Loader.load( element, moduleId [, options ] [, complete( records ) ] )

            加载组件 `moduleId` 到指定的节点 `element` 中。

            * Loader.load( element, moduleId, options, complete )
                * Loader.load( element, moduleId )
                * Loader.load( element, moduleId, options )
                * Loader.load( element, moduleId, complete )
                * Loader.load( element, moduleId, options, complete )
            * Loader.load( array{element}, moduleId, options, complete )
                * Loader.load( array{element}, moduleId)
                * Loader.load( array{element}, moduleId, options)
                * Loader.load( array{element}, moduleId, options, complete)

            **参数的含义和默认值**如下:

            * `moduleId` 必选。模块标识符。
            * `element` 必选。目标节点。
            * `array` 必选。目标节点数组。
            * `complete( records )` 可选。一个回调函数,当组件加载完成后被执行。
                * * `records` 二维数组,记录了组件在初始化过程中的相关信息,包括:异常、实例、在初始化队列中的下标、初始化队列的长度。

            > 因为每个组件的行为不可以预测(例如,`table` 是增强,`dropdwon` 是替换,`pagination` 是插入),导致销毁和再次加载的行为也不可预测,所以不能直接在节点 `element` 上加载,而是在其内新建一个容器元素 `<div>`,在这个容器元素上加载组件 `moduleId`。

            #### Examples

            ```js
            var target = $('<div>').insertBefore(document.body.firstChild)
            Loader.load(target, 'components/hello', {message: 'load' })
            Loader.unload(target)
            ```
         */
        function load(element, moduleId, options, complete) {
            // load(element, moduleId, options, complete)
            if (element.nodeType) element = [element]

            // Loader.load( element, moduleId, complete )
            if (Util.isFunction(options)) {
                complete = options
                options = undefined
            }

            // 如果 element 上设置了 bx-name,则先移除掉
            // 因为在 load() 模式下,element 仅仅当做容器元素使用,否则会和 boot() 模式冲突。
            // Util.each(element, function(item, index) {
            //     if (item.getAttribute(Constant.ATTRS.id)) {
            //         delete item.clientId
            //         item.removeAttribute(Constant.ATTRS.id)
            //     }
            // })

            // 1. 销毁已有组件
            destroy(element)

            // load(elementArray, moduleId, options, complete)
            Util.each(element, function(item /*, index*/ ) {
                // item.setAttribute(Constant.ATTRS.id, moduleId)
                // 2. 为组件 moduleId 新建一个容器元素
                item.innerHTML = '<div bx-name="' + moduleId + '"></div>'
            })

            // 3. 初始化组件 moduleId
            boot(element, complete, options)
            return this
        }

        /*
            #### Loader.unload( element [, complete ] )

            卸载节点 `element` 中加载的组件。

            * Loader.unload( element, complete )
                * Loader.unload( element )
                * Loader.unload( element, complete )
            * Loader.unload( array{element}, complete )
                * Loader.unload( array{element} )
                * Loader.unload( array{element}, complete )

            **参数的含义和默认值**如下:

            * `element` 必选。目标节点。
            * `array` 必选。目标节点数组。
            * `complete` 可选。一个回调函数,当组件卸载完成后被执行。
         */
        function unload(element, callback) {
            destroy(element, callback)
            return this
        }

        /*
            CACHE {
                uuid: {
                    clientId: uuid
                    parentClientId: uuid,
                    instance: brix
                }
            }
            return {
                name: root,
                children: [
                    {
                        name: moduleId + ',' + clientId,
                        children: [
                            {
                                name
                                children
                            }
                        ]
                    }
                ]
            }
        */
        function tree() {
            var result = {
                name: 'root',
                children: []
            }

            function _parseChildren(parentClientId, children) {
                Util.each(CACHE, function(item) {
                    if (item.parentClientId === parentClientId) {
                        children.push({
                            name: item.moduleId + ',' + item.clientId,
                            module: item,
                            children: _parseChildren(item.clientId, [])
                        })
                    }
                })
                return children
            }

            _parseChildren(Constant.ROOT_CLIENT_ID, result.children)

            return result
        }

        var tasks = Util.queue()
        var Loader = {
            CACHE: CACHE,
            tasks: tasks,
            __MAX_STACK_QUEUE: 100,
            booting: false,
            boot: function(force /* Internal Use Only */ , context, callback, progress) {
                // boot( context, callback, progress )
                if (!Util.isBoolean(force)) {
                    progress = callback
                    callback = context
                    context = force
                    force = false
                }

                // boot( callback, progress )
                if (Util.isFunction(context)) {
                    progress = callback
                    callback = context
                    context = document.body
                } else {
                    // boot( component )
                    // boot( element )
                    // boot()
                    context = context ? context.element || context : document.body
                }

                if (DEBUG) console.log('call boot', context)

                var caller = arguments.callee.caller
                tasks.queue(function(next) {
                    var label = 'queue boot'
                    if (DEBUG) {
                        console.group(label)
                        console.time(label)
                        console.log('context:', context)
                        console.log('tasks.list:', tasks.list.length)
                    }

                    Loader.booting = caller
                    boot(context, function(records) {
                        if (callback) {
                            try {
                                callback(records)
                            } catch (error) {
                                console.error(error.stack || error)

                                if (Loader.onerror) Loader.onerror(error) // 运行时异常收集
                            }
                        }

                        Loader.booting = false

                        if (DEBUG) {
                            console.log(records.length, records)
                            console.timeEnd(label)
                            console.groupEnd(label)
                        }

                        next()
                    }, null, progress)
                })
                if (tasks.list.length % Loader.__MAX_STACK_QUEUE === 0) Loader.tasks.delay(0)
                if (!Loader.booting || force) tasks.dequeue()
                return this
            },
            destroy: function() {
                try {
                    destroy.apply(this, arguments)
                } catch (error) {
                    console.error(error.stack || error)

                    if (Loader.onerror) Loader.onerror(error) // 运行时异常收集
                }
                return this
            },
            query: query,
            tree: tree,

            load: function(force /* Internal Use Only */ , element, moduleId, options, complete) {
                // boot( element, moduleId, options, complete )
                if (!Util.isBoolean(force)) {
                    complete = options
                    options = moduleId
                    moduleId = element
                    element = force
                    force = false
                }

                // load( element, moduleId, complete )
                if (Util.isFunction(options)) {
                    complete = options
                    options = undefined
                }

                var caller = arguments.callee.caller
                tasks.queue(function(next) {
                    Loader.booting = caller
                    load(element, moduleId, options, function(records) {
                        Loader.booting = false

                        if (complete) {
                            try {
                                complete(records)
                            } catch (error) {
                                console.error(error.stack || error)
                            }
                        }

                        next()
                    })
                })
                if (tasks.list.length % Loader.__MAX_STACK_QUEUE === 0) Loader.tasks.delay(0)
                if (!Loader.booting || force) tasks.dequeue()
                return this
            },
            unload: unload,

            Util: Util,
            Constant: Constant,
            Options: Options
        }

        return Loader
    }
)

redpajama_set_name: RedPajamaGithub


text:
<?php

/**
 * @see Zend_Feed_Entry_Atom
 */
require_once 'Zend/Feed/Entry/Atom.php';

/**
 * @see Zend_Http_Client_File
 */
require_once 'Zend/Http/Client.php';

/**
 * @category   Zend
 * @package    Zend_Feed
 * @subpackage UnitTests
 * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 * @group      Zend_Feed
 */
class Zend_Feed_AtomPublishingTest extends PHPUnit_Framework_TestCase
{
    protected $_uri;

    public function setUp()
    {
        $this->_uri = 'http://fubar.com/myFeed';
    }

    public function tearDown()
    {
        Zend_Feed::setHttpClient(new Zend_Http_Client());
    }

    public function testPost()
    {
        Zend_Feed::setHttpClient(new TestClient());

        $entry = new Zend_Feed_Entry_Atom();

        /* Give the entry its initial values. */
        $entry->title = 'Entry 1';
        $entry->content = '1.1';
        $entry->content['type'] = 'text';

        /* Do the initial post. The base feed URI is the same as the
         * POST URI, so just supply save() with that. */
        $entry->save($this->_uri);

        /* $entry will be filled in with any elements returned by the
         * server (id, updated, link rel="edit", etc). */
        $this->assertEquals('1', $entry->id(), 'Expected id to be 1');
        $this->assertEquals('Entry 1', $entry->title(), 'Expected title to be "Entry 1"');
        $this->assertEquals('1.1', $entry->content(), 'Expected content to be "1.1"');
        $this->assertEquals('text', $entry->content['type'], 'Expected content/type to be "text"');
        $this->assertEquals('2005-05-23T16:26:00-08:00', $entry->updated(), 'Expected updated date of 2005-05-23T16:26:00-08:00');
        $this->assertEquals('http://fubar.com/myFeed/1/1/', $entry->link('edit'), 'Expected edit URI of http://fubar.com/myFeed/1/1/');
    }

    public function testEdit()
    {
        Zend_Feed::setHttpClient(new TestClient());
        $contents = file_get_contents(dirname(__FILE__) .  '/_files/AtomPublishingTest-before-update.xml');

        /* The base feed URI is the same as the POST URI, so just supply the
         * Zend_Feed_Entry_Atom object with that. */
        $entry = new Zend_Feed_Entry_Atom($this->_uri, $contents);

        /* Initial state. */
        $this->assertEquals('2005-05-23T16:26:00-08:00', $entry->updated(), 'Initial state of updated timestamp does not match');
        $this->assertEquals('http://fubar.com/myFeed/1/1/', $entry->link('edit'), 'Initial state of edit link does not match');

        /* Just change the entry's properties directly. */
        $entry->content = '1.2';

        /* Then save the changes. */
        $entry->save();

        /* New state. */
        $this->assertEquals('1.2', $entry->content(), 'Content change did not stick');
        $this->assertEquals('2005-05-23T16:27:00-08:00', $entry->updated(), 'New updated link is not correct');
        $this->assertEquals('http://fubar.com/myFeed/1/2/', $entry->link('edit'), 'New edit link is not correct');
    }
}

/**
 * A test wrapper around Zend_Http_Client, not actually performing
 * the request.
 *
 */
class TestClient extends Zend_Http_Client
{
    public function request($method = null)
    {
        $code = 400;
        $body = '';

        switch ($method) {
            case self::POST:
                $code = 201;
                $body = file_get_contents(dirname(__FILE__) . '/_files/AtomPublishingTest-created-entry.xml');
                break;

            case self::PUT:
                $doc1 = new DOMDocument();
                $doc1->load(dirname(__FILE__) . '/_files/AtomPublishingTest-expected-update.xml');
                $doc2 = new DOMDocument();
                $doc2->loadXML($this->raw_post_data);
                if ($doc1->saveXml() == $doc2->saveXml()) {
                    $code = 200;
                    $body = file_get_contents(dirname(__FILE__) . '/_files/AtomPublishingTest-updated-entry.xml');
                }
                break;

            default:
                break;
        }

        return new Zend_Http_Response($code, array(), $body);
    }
}


text:
Welcome — Catalysis Club of Chicago
Officers 2022 – 2023
Future Meetings Related to Catalysis
Subscribe to CCC mailing list
Join CCC/Renew Membership
Job Openings in Catalysis
North American Catalysis Society
CCC Bylaws
2023 Young Scientist Symposium
Herman Pines Award in Catalysis
Pines Award – Nominations 2022
2022 Herman Pines Award in Catalysis
Pines Award – Past Winners
Catalysis Club of Chicago
Member-North American Catalysis Society
Prof. Karthish Manthiram
Controlling Interfacial Electron and Atom Transfer Reactions for Chemical Synthesis
Seminar via Zoom teleconferencing.
Click here to be connected.
Abstract – Chemical synthesis is responsible for significant emissions of carbon dioxide worldwide. These emissions arise not only due to the energy requirements of chemical synthesis, but since hydrocarbon feedstocks can be overoxidized or used as hydrogen sources. Using renewable electricity to drive chemical synthesis may provide a route to overcoming these challenges, enabling synthetic routes which operate at benign conditions and utilize sustainable inputs. We are developing an electrosynthetic toolkit in which distributed feedstocks, including carbon dioxide, dinitrogen, water, and renewable electricity, can be converted into diverse fuels, chemicals, and materials.
In this presentation, we will first share recent advances made in our laboratory on nitrogen fixation to synthesize ammonia at ambient conditions. Specifically, our lab has investigated a continuous lithium-mediated approach to ammonia synthesis and understood the reaction network that controls selectivity. We have developed non-aqueous gas-diffusion electrodes which lead to high rates of ammonia synthesis at ambient conditions. Then, we will discuss how water can be used as a sustainable oxygen-atom source for epoxidation of olefins as well as related oxygen-atom transfer reactions, providing a route to utilize oxidative equivalents in a water electrolyzer. These findings will be discussed in the context of a broader range of electrosynthetic transformations which could lead to local and on-demand production of critical chemicals and materials.
Bio – Karthish Manthiram is the Theodore T. Miller Career Development Chair and Assistant Professor in Chemical Engineering at MIT. The Manthiram Lab at MIT is focused on the molecular engineering of electrocatalysts for the synthesis of organic molecules, including pharmaceuticals, fuels, and commodity chemicals, using renewable feedstocks. Karthish received his bachelor's degree in Chemical Engineering from Stanford University in 2010 and his Ph.D. in Chemical Engineering from UC Berkeley in 2015. After a one-year postdoc at the California Institute of Technology, he joined the faculty at MIT in 2017. Karthish's research has been recognized with several awards, including the NSF CAREER Award, DOE Early Career Award, 3M Nontenured Faculty Award, American Institute of Chemical Engineers 35 Under 35, American Chemical Society PRF New Investigator Award, Dan Cubicciotti Award of the Electrochemical Society, and Forbes 30 Under 30 in Science. Karthish's teaching has been recognized with the C. Michael Mohr Outstanding Undergraduate Teaching Award, the MIT Chemical Engineering Outstanding Graduate Teaching Award, and the MIT Teaching with Digital Technology Award. He serves on the Early Career Advisory Board for ACS Catalysis and on the Advisory Board for both Trends in Chemistry and the MIT Science Policy Review.
Join CCC Mailing List
Join CCC or Renew Membership
© 2023 Catalysis Club of Chicago

redpajama_set_name: RedPajamaCommonCrawl


text:
Making a difference: Lafarge transforms the lives of 1 000 learners at KwaDukuza primary school
Friday 4 September was a memorable day for the Sakhamkhanya community near Stanger in KwaZulu-Natal. A major two-year upgrading project for the St Christopher Primary School, sponsored by Lafarge Mining South Africa in partnership with the Lafarge Education Trust, culminated in a handover ceremony for a total school refurbishment, construction and equipping of a kitchen, Grade R classrooms, ablution facilities and a well-equipped playground.
It has been a long journey for this school that was established in a mud-house in 1957. Until Lafarge's involvement classes were overcrowded, meals were prepared in a disused shipping container, and both learners and educators had to use a pit toilet system. Over one thousand (1 000) learners will now benefit from the transformed facilities.
Lafarge South Africa, a member of the LafargeHolcim Group, the world leader in building materials, firmly believes that as a responsible company it must help address the challenges of our society. The company plays an active role in the sustainable development of the communities in which it operates, with particular emphasis on contributing to a better education for the children in those communities, from which will come its future employees, engineers, managers and customers.
The Lafarge Community Trust and Lafarge Education Trust (LET) were created in 2006 by Lafarge South Africa to contribute to building better communities in areas wherein it operates and, in particular, uplift the education of young people in those areas. The LET, has invested over R7,5 million in sustainable education upliftment initiatives at twenty-six participating schools in northern KwaZulu-Natal, benefitting 15 thousand learners.
Lafarge Mining and the Lafarge Community Trust, working together with the Ntwashini Community Trust, were able to identify St Christopher Primary as a school that would most benefit from the company's support. The school is a neighbour of the Lafarge Stanger Quarry.
The formal cutting of the ribbon to hand over the new school facilities was conducted by the KwaDukuza Local Municipality Mayor, Councillor Ricardo Mthembu, together with Chairperson of the Lafarge Education and Community Trusts, Cheryl Carolus, and Lafarge Mining South Africa General Manager, Praveen Bechoo.
"The extensive upgrading of the St Christopher School was an inspiring example of what could be achieved by forming effective partnerships with all stakeholders together with perseverance and good planning," said Carolus. Bechoo added that Lafarge South Africa considered the day a significant one in enhancing the learning of pupils. "It will enable the learners and educators to focus on achieving excellence in the future. Lafarge Mining is an integral part of this community and we are proud to have contributed to making a difference."
About LafargeHolcim
With a well-balanced presence in 90 countries and a focus on Cement, Aggregates and Concrete, LafargeHolcim (SIX Swiss Exchange, Euronext Paris: LHN) is the world leader in the building materials industry. The Group has 115,000 employees around the world and combined net sales of CHF 33 billion (EUR 27 billion) in 2014. LafargeHolcim is the industry benchmark in R&D and serves from the individual homebuilder to the largest and most complex project with the widest range of value-adding products, innovative services and comprehensive building solutions. With a commitment to drive sustainable solutions for better building and infrastructure and to contribute to a higher quality of life, the Group is best positioned to meet the challenges of increasing urbanisation. More information is available on www.lafargeholcim.com
About Lafarge South Africa
Lafarge South Africa, a member of the LafargeHolcim group, manufactures and supplies cement, aggregates and readymixed concrete, fly ash, gypsum plasterboard and interior building fittings through its various business units. It focuses on providing solutions to help the sustainable development of better cities that benefit the country's people. Through having a strong presence in all of its business lines, it is in a unique position to contribute to urban construction, while also helping to build better cities, rural towns and villages. For further information, visit our website on: www.lafarge.co.za
Unathi Batyashe-Fillis
Email: unathi.fillis@lafarge.com


text:
Baltimore (MD) Silhouettes
The Baltimore Chapter of Kappa Silhouettes was founded to provide a vehicle through which Kappa men can obtain support in their endeavors to strengthen and maintain the common bond through the promotion of social, cultural, civic, and benevolent activities. In the beginning, the Baltimore Chapter held its meetings in private homes, local clubs, and at
Chapter Baltimore (MD) Silhouettes
Location Baltimore, MD
President Audrey Bennett
Bowie/Mitchellville (MD) Silhouettes
The Bowie/Mitchellville (MD) Alumni Chapter of Kappa Alpha Psi Fraternity, Inc. was chartered in October 2003. The Chapter Polemarch, Charles Exum, immediately granted approval to Silhouette Joan Crutchfield, a Silhouette in the Bowie/Mitchellville (BMAC) family, to organize a Silhouette Chapter. Silhouette Crutchfield contacted the other Silhouettes of the BMAC family to inquire of interest in
Chapter Bowie/Mitchellville
Location Bowie/Mitchellville, MD
President Joan Crutchfield
Chesapeake/Virginia Beach (VA) Silhouettes
The Chesapeake/Virginia Beach (VA) Alumni Chapter of Silhouettes was chartered on Saturday, October 9, 1993, at the Central Public Library on Virginia Beach Boulevard. This is reflected as the"10/9/93" located below the Silhouette logo on the scroll banner as the "8/47" above it reflects the month and year the National Silhouettes were founded. Likewise, the
Chapter Chesapeake/Virginia Beach
Location Chesapeake/Virginia Beach, VA
President Johne Ewell
College Park/Sandy Spring (MD) Silhouettes
In February 2012, five (5) of the wives of the men of the Kappa Alpha Psi, Inc. College Park/Sandy Spring MD Alumni Chapter met to discuss the creation of a CPSS MD Silhouettes chapter. That group included Jaqeee Cooke Dean, Renee Graves, Monique Salahuddin, and Sonja Osborne. The energy and preliminary work of these Silhouettes
Chapter College Park/Sandy Spring
Location College Park/Sandy Spring, MD
President Kimberly Harris
Columbia (MD) Silhouettes
Columbia MD Chapter of the Kappa Alpha Psi Silhouette was formally installed as a chapter on May 21, 1976, with Silhouette Marlene White serving as the first president. Chapter meetings were held monthly and a member served as a meeting hostess each month. The chapter programs have included various types of activities. For more than
Chapter Columbia
Location Columbia, MD
President Linda Morrow
Fredericksburg (VA) Silhouettes
The first official meeting g of the future Silhouettes of The Fredericksburg Alumni Chapter of Kappa Alpha Psi, Inc., occurred on Memorial Day Weekend of 2012. We were formed for the purpose of supporting the activities of The Fredericksburg Alumni Chapter of Kappa Alpha Psi Fraternity, Inc. including the 2013 Eastern Province Council. The Silhouettes
Chapter Fredericksburg
Location Fredericksburg, VA
President Pamela "PJ" Hood
Hampton-Newport News (VA) Silhouettes
The Hampton-Newport News Silhouettes were formed in February 1951. Its history from 1951 to 1998 is currently being finalized. However, after hosting the Eastern Province Council in 2000, the chapter has a very rich history. Currently, the local chapter is a member of the Eastern Province and the National Silhouettes. The Silhouettes play an important
Chapter Hampton-Newport News
Location Hampton-Newport News, VA
President Althea Johnson
Norfolk (VA) Silhouettes
Chapter Norfolk
Location Norfolk, VA
President Davida Chapman


text:
Kateryna Stepanenko, Karolina Hird and Mason Clark
Russian forces have likely abandoned efforts to complete a single large encirclement of Ukrainian forces in eastern Ukraine and are instead attempting to secure smaller encirclements—enabling them to make incremental measured gains. Russian forces are likely attempting to achieve several simultaneous encirclements of small pockets of Ukrainian forces in Donetsk and Luhansk oblasts: the broader Severodonetsk area (including Rubizhne and Lysychansk), Bakhmut-Lysychansk, around Zolote (just northeast of Popasna), and around Ukrainian fortifications in Avdiivka. Russian forces have begun steadily advancing efforts in these different encirclements daily but have not achieved any major "breakthroughs" or made major progress towards their stated objectives of securing the Donetsk Oblast borders or seizing all of Donbas. Luhansk Oblast Administration Head Serhiy Haidai reported that Ukrainian forces only controlled approximately 10 percent of Luhansk Oblast as of May 15 (compared to 30 percent prior to the full-scale Russian invasion on February 24, 2022).[1] Russian forces have secured more terrain in the past week than efforts earlier in May. However, they have done so by reducing the scope of their objectives—largely abandoning operations around Izyum and concentrating on key frontline towns: Russian performance remains poor.
Russian forces will additionally likely face protracted urban combat if they successfully encircle Severodonetsk (as well as in other large towns like Bakhmut), which Russian forces have struggled with throughout the war. Russian forces are committing a significant number of their troops, artillery, and aircraft to defeat Ukrainian defenders in Luhansk Oblast and are likely pulling necessary resources from the Izyum axis, defensive positions around Kharkiv City, Donetsk City, and the Zaporizhia area. Luhansk Oblast Administration Head Serhiy Haidai has previously compared Ukrainian forces in Luhansk Oblast to the previous defenders of Mariupol, which aimed to wear out Russian forces and prevent further offensive operations.[2] The UK Defense Ministry also noted that a Russian victory over Severodonetsk will only worsen Russian logistical issues and extend Russian ground lines of communication (GLOCs).[3] Russian forces are making greater advances in the past week than throughout the rest of May—but these advances remain slow, confined to smaller objectives than the Kremlin intended, and face continued Ukrainian defenses; they do not constitute a major breakthrough.
Senior Kremlin officials are increasingly openly admitting that the Russian offensive in Ukraine is moving slower than anticipated and are grasping for explanations to justify the slow pace. Russian Defense Minister Sergey Shoigu claimed that Russian operations in Ukraine are progressing slowly because Russian forces want to afford civilians the opportunity to evacuate, though Russian forces have targeted Ukrainian civilians throughout the war and repeatedly denied Ukrainian attempts to negotiate humanitarian evacuation corridors.[4] Shoigu's statement is notably his first admission that Russian forces are behind schedule and is the first official statement on the pace of the war since Belarusian President Alexander Lukashenko stated that the operation was "dragging" on May 4.[5] Russian milbloggers are criticizing Shoigu's claimed consideration for civilians and claimed that Soviet troops would not have cared if "Nazi" civilians evacuated, part of the growing Russian nationalist reaction that the Kremlin is not doing enough to win the war in Ukraine.[6] Director of the Russian Foreign Intelligence Service Sergey Naryshkin stated that the ultimate goal of the Russian offensive is to ensure "Nazism" is "100% eradicated, or it will rear its head in a few years, and in an even uglier form."[7] Naryshkin and Shoigu's statements indicate that Russian officials are likely setting conditions for a protracted war in Ukraine in order to justify slower and more measured advances than initially anticipated.
Forcefully mobilized servicemen from the Donetsk and Luhansk People's Republics continued to protest the Russian and proxy military command. Servicemen of the 3rd Infantry Battalion of the 105th Infantry Regiment from the Donetsk People's Republic (DNR) recorded a video appeal to DNR Head Denis Pushilin wherein they claimed they were mobilized on February 23 and that they have been forced to actively participate in hostilities despite their lack of military experience. The battalion stated that they served on the frontlines in Mariupol and have been redeployed to the territory of the Luhansk People's Republic (LNR) with only 60% of their original personnel and are now dealing with severe morale issues and physical exhaustion. The battalion notably claimed that the servicemen did not go through routine medical inspection prior to service and that many are suffering from chronic illnesses that should have rendered them ineligible for service. The video appeal is consistent with numerous reports from Ukrainian and Western sources that proxy forces are largely forcibly mobilized, poorly trained, and suffering from declining morale, but is notable due to the willingness of the DNR servicemen to publicly express their discontent.[8]
Russian forces have likely abandoned efforts to encircle large Ukrainian formations in eastern Ukraine and are instead attempting to secure smaller encirclements and focus on Severodonetsk.
This change in the Russian approach is enabling gradual advances—but at the cost of abandoning several intended lines of advance and abandoning the Kremlin's intended deep encirclement of Ukrainian forces in eastern Ukraine.
Ukrainian forces are likely conducting a controlled withdrawal southwest of Popasna near Bakhmut to protect Ukrainian supply lines against Russian offensives in the southeast of Bakhmut.
Russian occupation authorities in Mariupol announced that they will hold war crimes trials against Ukrainian soldiers in Mariupol in a likely effort to strengthen judicial control of the city and support false Kremlin narratives of Ukrainian crimes.
Russian forces are attempting to retake Ternova in northern Kharkiv Oblast and seek to stabilize defensive positions near the Russian border against the Ukrainian counteroffensive.
Russian forces are forming reserves and deploying S-400 missile systems in northwest Crimea to reinforce the southern axis.
Several DNR servicemen openly released a video appeal to DNR leader Denis Pushilin stating they have been forced into combat operations without proper support, indicating increasing demoralization among Russian and proxy forces.
Supporting effort 1—Mariupol;
Supporting effort 3—Southern axis.
Russian forces did not launch offensive operations south of Izyum on May 24 but continued to reconnoiter Ukrainian positions in the region.[9] The Ukrainian General Staff reported that Russian forces are likely preparing to resume an offensive toward Slovyansk and deployed additional artillery units to southern neighborhoods of Izyum.[10] Izyum City Council Deputy Maxim Strelnik claimed that over 20,000 Russian personnel in what he reported are 25 battalion tactical groups (BTGs) are preparing to resume a large encirclement of Ukrainian troops from the north.[11] ISW cannot independently confirm these Russian troop numbers or their unit structure, and Strelnik may be referencing a Ukrainian General Staff report from April 22 that twenty-five Russian BTGs were operating around Izyum.[12] The Russian units around Izyum are likely heavily degraded and it is highly unlikely Russia is operating twenty-five full strength BTGs (at 800-900 personnel per BTG, this would be 20,000-22,500 personnel in total). Many Russian personnel on this axis are likely in rear areas or not combat effective. Moreover, poor Russian tactics largely nullify the weight of numbers on this front, as Russian forces remain confined to launching narrow attacks down major roads that often do not employ more than a single BTG—at most—at a time.
Russian forces continued to prioritize attacks against Lyman rather than Slovyansk on May 24, likely to support a shallow encirclement of Ukrainian troops northwest of Severodonetsk. Pro-Russian military Telegram channels also noted that Russian and proxy forces have adopted a new strategy abandoning attacks toward Slovyansk and Barvinkove in favor of the Battle for Severodonetsk.[13] ISW previously forecasted that Russian forces would scale down their initial objectives of reaching the Donetsk Oblast border in favor of securing the Luhansk Oblast borders.[14] Donetsk People's Republic (DNR) Head Denis Pushilin announced that Russian forces began an assault on Lyman but claimed to have only seized the northern half of the settlement.[15] ISW cannot independently confirm Pushilin's claims. Geolocated social media videos showed that Russian forces heavily bombarded Lyman on May 23, likely in preparation for an assault on the town.
Russian forces launched ground assaults on settlements approximately 20 km southwest of Severodonetsk, but have not reached the city.[16] The UK Defense Ministry noted that Russian advances towards Severodonetsk from Rubizhne and advances from the southwest remain separated by approximately 25 km, and Russian forces may be able to encircle Severodonetsk in the coming days.[17] Russian forces will likely struggle to capture the city itself, however, and Russian assaults on major urban terrain have been unable to quickly take ground throughout the war.
Ukrainian forces likely conducted a controlled withdrawal southwest of Popasna to defend Ukrainian ground lines of communication (GLOCs) in Bakhmut against Russian offensives. Russian forces seized Svitlodarsk, approximately 21 km southwest of Popasna, after Ukrainian forces retreated and damaged a bridge and dam over the Myronivskyi Reservoir on May 23.[18] Ukrainian forces previously targeted the reservoir on May 14, likely in preparation for a gradual withdrawal from the area.[19] Russian forces continued to advance just northeast and east of Popasna, with social media footage showing the arrival of reinforcements to support the push toward the Lysychansk and Bakhmut highways.[20] DNR sources also claimed that Russian forces are attempting a shallow encirclement of weakening Ukrainian troops in Avdiivka, but ISW cannot confirm these claims.[21]
Supporting Effort #1—Mariupol (Russian objective: Capture Mariupol and reduce the Ukrainian defenders)
Russian and proxy forces continued to "restore" Mariupol on May 24. Troops focused on demining the ruins of the city, the port, and the sea.[22] Head of the Russian National Defense Control Center Colonel-General Mikhail Mizintsev claimed on May 24 that Russian forces will open a humanitarian "green corridor" in the Black Sea to allow the safe exit of foreign ships from the Port of Mariupol on May 25.[23]
Head of the Donetsk People's Republic (DNR) Denis Pushilin stated that the DNR is developing rules and procedures for tribunals in Mariupol to try and punish Ukrainian soldiers for war crimes.[24] Pushilin's statement notably comes the day after the first Russian soldier was found guilty in a Ukrainian war crimes trial. Mariupol's occupation administration will likely use such tribunals to enforce their rhetorical agendas and strengthen judicial control over Mariupol and other occupied areas.
Russian forces continued to focus on maintaining and improving their positions north of Kharkiv City on May 24. The Ukrainian General Staff reported that Russian forces are conducting ground assaults on the outskirts of Ternova, a village recaptured by Ukrainian forces in early May in the far north of Kharkiv Oblast and 5 km from the international border.[25] A Russian Telegram channel claimed that Russian forces have restored control over the entirety of Ternova, and while this claim cannot be confirmed at this time, it indicates that Russian forces are focusing on retaking control of settlements near the border.[26] Russian troops additionally shelled Kharkiv City and its environs.[27] Sentinel satellite imagery from May 24 notably showed a Russian rear base constructed in Belgorod Oblast in early April within 15 km of the Ukrainian border.[28] Russian forces are likely using this and other rear bases to support operations in northern Kharkiv Oblast and seek to screen them from Ukrainian shelling.
Russian forces continued to reinforce their positions on the Southern Axis but did not make any confirmed advances on May 24.[29] Russian troops are reportedly strengthening their grouping in Vasylivka and Kamyanske (both south of Zaporizhzhia City) in preparation for offensives to the north.[30] The Ukrainian General Staff noted that Russian troops in Crimea are forming reserves and a spokesman for the Odesa Military Administration stated that Russian forces are reportedly deploying S-400 missile systems to northwest Crimea. Russian milblogger Alexander Zhuchkovsky, however, called the situation on the Zaporizhia frontline of the Southern Axis "deplorable," and indicated that Ukrainian artillery pressure has been effective in slowing Russian troop movements.[31] Zhuchkovsky noted that Zaporizhia Oblast is not a priority for Russian command and much of the Russian grouping in the area is comprised of reservists. His assertion is corroborated by the fact that Russian forces continued to shell Ukrainian positions in Kherson, Zaporizhia, and Dnipropetrovsk Oblasts on May 24, but did not engage in any active ground attacks.[32]
Recent Ukrainian partisan actions in Zaporizhia Oblast continue to pressure Russian occupation forces, which are continuing actions to strengthen administrative control of occupied areas.[33] Occupation authorities in Kherson, Berdyansk, and Melitopol stated that both cities will be included in the ruble zone.[34]
Russian forces are likely reinforcing their grouping north of Kharkiv City to prevent further advances of the Ukrainian counteroffensive toward the Russian border. Russian forces may commit elements of the 1st Tank Army to Northern Kharkiv in the near future.
The Russians will continue efforts to encircle Severodonetsk and Lysychansk at least from the south, possibly by focusing on cutting off the last highway connecting Severodonetsk-Lysychansk with the rest of Ukraine.
Russian forces in Mariupol will likely shift their focus to occupational control of the city as the siege of Azovstal has concluded.
[1] https://t.me/luhanskaVTSA/2621
[3] https://twitter.com/DefenceHQ/status/1528965159460425730/photo/1
[4] https://www dot kommersant.ru/doc/5367364
[6] https://t.me/strelkovii/2584
[7] https://ria dot ru/20220524/spetsoperatsiya-1790331445.html
[8] https://twitter.com/DefenceHQ/status/1525762742610804736; https://www.facebook.com/DefenceIntelligenceofUkraine/posts/311906081120819; https://www.facebook.com/GeneralStaff.ua/posts/314771530835932; https://www.facebook.com/GeneralStaff.ua/posts/323526419960443
[11] https://www dot objectiv.tv/objectively/2022/05/24/v-izyume-sosredotocheno-okolo-20-tysyach-rossijskih-voennyh/
[12] https://news dot liga.net/politics/news/rf-styanula-25-btgr-pod-izyum-sem-pod-harkov-i-pytaetsya-idti-na-donbasse-svodka-genshtaba
[15] https://t.me/milinfolive/83950; https://www dot interfax.ru/world/842646; https://t.me/readovkanews/34827; https://t.me/voenkorKotenok/36680; https://t.me/swodki/102268
[16] https://www.facebook.com/GeneralStaff.ua/posts/323858359927249; https://t.me/luhanskaVTSA/2868; https://t.me/luhanskaVTSA/2887; https://t.me/swodki/102548; https://armyinform dot com.ua/2022/05/24/boyiv-u-syevyerodoneczku-nemaye-misto-pid-povnym-kontrolem-ukrayiny/
[17] https://twitter.com/DefenceHQ/status/1528965159460425730/photo/1
[18] https://twitter.com/GeoConfirmed/status/1529104615219798017; https://twitter.com/GeoConfirmed/status/1529103582531883009; https://twitter.com/JulianRoepcke/status/1529045890694057985; https://iz dot ru/1339054/2022-05-24/na-zdanii-merii-svetlodarska-podniali-flag-rossii; https://t.me/stranaua/43692; https://tass dot ru/mezhdunarodnaya-panorama/14709087; https://t.me/stranaua/43724; https://t.me/milinfolive/83924; https://t.me/swodki/102293; https://twitter.com/GeoConfirmed/status/1529097948038152193; https://twitter.com/GeoConfirmed/status/1529094643824091141; https://twitter.com/GeoConfirmed/status/1528822549693575170; https://twitter.com/GuinieZoo_Intel/status/1528625456001556480
[19] https://www.understandingwar.org/backgrounder/russian-offensive-campaign-assessment-may-15
[20] https://twitter.com/Militarylandnet/status/1529008368102297601; https://twitter.com/GeoConfirmed/status/1529098813364920320; https://t.me/swodki/102548; https://www.facebook.com/GeneralStaff.ua/posts/324283196551432
[21] https://t.me/stranaua/43743; https://t.me/swodki/102471; https://tass dot ru/mezhdunarodnaya-panorama/14712851; https://twitter.com/bamr69/status/1529037655572418560; https://t.me/strelkovii/2583
[22] https://t.me/nm_dnr/8060 ; https://t.me/voenkorKotenok/36675; https://t.me/epoddubny/10871; https://t.me/readovkanews/34795; https://t.me/swodki/102583; https://t.me/voenkorKotenok/36670; https://t.me/voenkorKotenok/36668; https://t.me/epoddubny/10871
[23] https://riafan dot ru/23454938-rossiya_planiruet_otkrit_koridor_k_chernomu_moryu_iz_mariupolya_25_maya
[24] https://t.me/milinfolive/83957
[27] https://t.me/swodki/102391; https://www.facebook.com/GeneralStaff.ua/posts/324283196551432; https://twitter.com/GeoConfirmed/status/1529101263010508801
[28] https://twitter.com/COUPSURE/status/1529068877556199433
[30] https://www.facebook.com/GeneralStaff.ua/posts/323858359927249; https://t.me/zoda_gov_ua/8157; https://twitter.com/DefMon3/status/1528833764083879947
[31] https://t.me/juchkovsky/2275
[32] https://t.me/Bratchuk_Sergey/12651; https://t.me/dnipropetrovskaODA/1005; https://t.me/dnipropetrovskaODA/1005?single; https://t.me/dnipropetrovskaODA/1008; https://t.me/mykola_lukashuk/497; https://twitter.com/2022Donetsk1/status/1528811326201647105; https://t.me/stranaua/43679; https://t.me/mykola_lukashuk/497; https://t.me/zoda_gov_ua/8158; https://www.facebook.com/GeneralStaff.ua/posts/324283196551432; https://www.facebook.com/GeneralStaff.ua/posts/323858359927249
[33] https://sprotyv dot mod.gov.ua/2022/05/24/u-melitopoli-diyi-partyzaniv-vyklykaly-paniku-v-okupaczijnij-administracziyi/; https://www.facebook.com/watch/?v=718302112750098
[34] https://t.me/stranaua/43680; https://ria dot ru/20220524/kherson-1790295658.html; https://t.me/stranaua/43712; https://t.me/readovkanews/34777; https://t.me/swodki/102269; https://www.facebook.com/watch/?v=718302112750098; https://t.me/swodki/102564; https://t.me/glava_brd/35


text:
Behind the HYPE: How the Rolex Submariner Remains Relevant After Nearly 70 Years
All credits to Hypebeast:
From diving essential to James Bond's timepiece of choice.
The Rolex Submariner is probably the most recognizable watch on the planet thanks, in part, to a core design that has changed little since the late 1950s.
The iconic silhouette of the rugged tool watch has long-since crossed over from watch and diving circles into mainstream consciousness.
The latest installment of Behind the HYPE looks at the enduring popularity of the Rolex Submariner and the many variations that have fueled a thriving collector's market.
Originally developed to serve the increasingly popular pastime of scuba diving after WWII, Rolex needed to find a way to time dives without using a traditional chronograph, which tended to let in water when activated beneath the surface. Their answer was the rotating bezel found on its earlier Turn-o-Graph model, which could be used underwater without fear of springing a leak.
The Submariner made its big screen debut on the wrist of Sean Connery in the very first James Bond film, Dr. No (1962), when producer Cubby Broccoli is rumoured to have handed Connery the watch off of his own wrist. Bond had always worn a Rolex in the books, as had author Ian Fleming, and the onscreen relationship lasted until the late 1980s, giving the Rolex Submariner a huge role in the longest-running franchise in film history.
Watch the video above as HYPEBEAST looks at the origins of the Submariner and the successful long-game strategy that Rolex has used to keep it relevant. And check out previous instalments of Behind the HYPE featuring among others Grand Theft Auto and the Porsche 911.
Published: Fri, Jan 07, 2022


text:
Максхите-Хајдхоф () град је у њемачкој савезној држави Баварска. Једно је од 33 општинска средишта округа Швандорф. Према процјени из 2010. у граду је живјело 10.474 становника. Посједује регионалну шифру (-{AGS}-) 9376141.

Географски и демографски подаци

Максхите-Хајдхоф се налази у савезној држави Баварска у округу Швандорф. Град се налази на надморској висини од 416 метара. Површина општине износи 34,7 -{km²}-. У самом граду је, према процјени из 2010. године, живјело 10.474 становника. Просјечна густина становништва износи 302 становника/-{km²}-.

Референце

Спољашње везе

 Званични сајт општине
 Њем. Савезни завод за статистику
 Стална конференција градова и општина
 -{KommOn}- - Информациони систем градова, општина и округа.
 План насеља на мапи (-{Mapquest}-)

Максхите-Хајдхоф
Википројект географија/Насеља у Немачкој

redpajama_set_name: RedPajamaWikipedia


On behalf of Duke Law Firm, P.C. on Sunday, August 26, 2018.
Divorce can bring out many different emotions in New York parents. When it comes to the part of the proceedings that involves who gets primary custody of the child, many spouses express their determination to "win" the battle and defeat their ex. While some keep the child's best interest in mind, there are those who let their emotions get the best of them and focus more on making their ex-partner lose.


Their investigation of the drilling mud spill remains ongoing, which includes assessment of environmental effects of the drilling mud, the seabed area, and collection and analysis of the mud from the seabed floor.
The Council of Canadians and our allies responded to the news that BP has resumed drilling, including in this piece by Global News, this one from Y95.5 Yarmouth, and this one by CBC News. The Campaign to Protect Offshore Nova Scotia (CPONS), a project of the South Shore chapter of the Council of Canadians, also sent a media release in response.
Marilyn Keddy of CPONS delivers lawn signs to Marke Slippe in the Wolfville area of NS.
Other than the spill on June 22nd, recent work on this campaign hasn't all been bad. Municipalities along the South Shore are speaking up and raising questions of their provincial and federal counterparts (see Brent Patterson's blogs on these). The CPONS had lawn signs made and has been busy delivering them all over the western half of the province. They also had a party to celebrate the amazing work done so far by a small but mighty group raising concerns with the offshore industry.
To read more about our offshore NS campaign, please click here.


Trained as a painter and graphic designer, Eckelt (German, 1914–1990) took up photography in the 1930s, documenting the streets of Berlin and its inhabitants with his camera. After the Second World War, Eckelt became a professional photojournalist, documenting the destroyed city of Berlin and its slow rebuilding. He worked for several German newspapers and photographed musicians like Yehudi Menuhin, Daniel Barenboim, Stefan Askenase and Gidon Kremer. But he never gave up photographing his favorite subject: the city of Berlin. His photographs depict Berlin between 1945 and 1988, thus capturing the divided city and especially West Berlin in its peculiar beauty and history.


ABSTRACT: A new gondolellid conodont species, Jinogondolella palmata, is described from the lower part of the Bell Canyon Formation in the Apache Mountains of West Texas. This new species and J. aserrata represent two different lineages that evolved from J. nankingensis in the lower and middle Wordian of the Middle Permian. This species has been found in several sections in the Guadalupe Mountains and in Oman.


text:
Thousands attend funeral for murdered Brooklyn boy
By Special to NJJN July 14, 2011, 12:00 am Edit
(JTA) — Thousands of people turned out for the funeral of Leiby Kletzky, the 8-year-old Chasidic boy in Brooklyn found murdered and dismembered after having disappeared two days earlier.
Wednesday night's funeral in the neighborhood of Borough Park came on the same day as his body was discovered and a suspect was arrested in his murder, and it followed a full-community manhunt for the boy after he went missing while walking home from day camp.
At the funeral, Leiby's father, his principal and synagogue rabbi praised the boy's devotion to his studies and prayer and warned parents to look out for their children. Several called the death God's will, according to reports.
Leiby's disappearance set off a massive search that included hundreds of volunteers and involved a huge mobilization of the area's Orthodox community.
New York City Police Commissioner Ray Kelly said at a news conference that police believe the boy asked the suspect, Levi Aron, for directions and entered his car. Police say they do not believe the boy knew Aron, who when confronted by police reportedly led them to the body parts he had stashed in his freezer and in a trash bin a couple of miles away. Police charged Aron with second-degree murder.


Have a Great Day at Muse!
Who would've thought wood could be so much fun, today I decided that maybe I could colour with my Copics onto sticky barc and it worked a treat!
Here is my card for this weeks Muse I can't wait to see how this card inspires you!
Other Supplies: Copics – R05,27. C1,5.
< Previous Time for a new Challenge at Scrapbook Boutique Bloghop & a Giveaway!
What a fun use of the woodgrain! I can't wait to see what this card inspires in our players this week!
W O W ! So cool to use the wood paper for the whole card!
stamping on wood = awesome..
Love this card! The wood is so masculine, perfect for any guy!
Who knew you could use Copics on wood? Well, I'm so glad you tried, Therese! This is such a great card…so innovative and fun, and I love the pop of color with the wood background! Very cool card!
Stunning – both of them! I love the masculine card for Ric and the copics coloured veneer is amazing!
Wow Therese. Now this is amazing.


Hey, I'm seeing you all over the Daycare. I lost interest in it (mostly because I was gone for half a year), and I was wondering if you'd like to take ownership for it.
I've been meaning to say that you need to be an established contributor to make visitor messages as well.
Just had to say 'hi'! I noticed you live in Cardiff. Welsh pride baby!
Never been there, but maybe some day I'll go see where my ancestors are from.
No problem, in my opinion family always comes first. Have a good time with them.
i think we are going to have a problem with talking tonight on ADISC. I just tried to accses the Chat and they have removed the Mibbitt option for me and i dont really know how to accses the ADISC chat through other InterNet Relay Chat's.
Hehe, not upset by any means though. I don't normally see many who live in Wales on here so I thought I would pop by! I'll pretty much be living in England over the next couple of years myself, anyway.
Just popping by to say 'hi' another Welshman. I've been seeing more of us on here recently!
Heh. I thought that I had. I'll have to ask Moo to put in a note.
good ta' see ya' man!
we're gunna be 'the adisc greeting duo'!
Hey, your stealing my job! I like to greet the newbies! and you always get them before I can get on!
hahaha I keed, just wanted to say hi! we both greet in the introductions forum, and I see you a lot... so... Hello!


text:
Anboto Dorrea es un rascacielos de 119 metros y 36 plantas en construcción, que se alzará en Bilbao en el complejo de Garellano. Ubicado junto a la soterrada Estación de Bilbao Intermodal, el edificio se sitúa muy próximo al Hospital de Basurto, al Estadio de San Mamés, a la Escuela de Ingeniería de Bilbao y a la nueva Facultad de Medicina y Enfermería de la UPV-EHU, cuyo traslado desde Lejona está previsto para 2026/2027. Es el noveno edificio y la quinta y última torre de dicho complejo.

Su construcción consta de dos fases. En la primera, iniciada en septiembre de 2020 por la constructora Dragados (Grupo ACS), se procedió a la cimentación del terreno sobre el que se situaría el edificio. Una vez concluida, comenzó la edificación de la torre a cargo de Construcciones Urrutia, cuya finalización completa está prevista para el verano de 2024, con la entrega de llaves para finales de dicho año. Cuando termine su construcción, será el segundo edificio más alto del País Vasco tras la Torre Iberdrola y el edificio residencial más alto de esta comunidad.

La torre, que cuenta con 166 viviendas libres, 239 garajes, 166 trasteros y centro comercial, está diseñada por el prestigioso estudio de arquitectura británico Rogers Stirk Harbour + Partners.

Historia
Garellano es una de las zonas que mayor renovación ha experimentado en la nueva reordenación urbanística de Bilbao. El proyecto del equipo Rogers Stirk Harbour + Partners, liderado por Richard Rogers, fue elegido para el diseño del complejo de ocho viviendas de Garellano, que concluye con la edificación de la Anboto Dorrea.
Su elección, vino motivada por un jurado compuesto por miembros del Ayuntamiento de Bilbao, la sociedad Bilbao Ría 2000, el Gobierno Vasco y arquitectos expertos en urbanismo, de entre cinco proyectos preseleccionados. Estos proyectos fueron los de los equipos Carlos Ferrater/Luis Domínguez, Junquera Arquitectos SLP, MVRDV/IA+B, Suárez & Santas Arquitectos y el citado dirigido por Richard Rogers.

Polémica por el rediseño del original
Una vez presentado el diseño definitivo a finales de octubre de 2019, y después de que el proyecto de Anboto Dorrea sufriera dos modificaciones frente al original, sus propietarios mostraron su disconformidad con lo que no se hubo proyectado ni adquirido sobre plano, señalando tanto a la promotora Arrasate como al estudio de arquitectura de Richard Rogers.

Paralización de las obras
El 8 de marzo de 2023 se dio a conocer la paralización de las obras desde el mes de febrero del mismo año. Las cooperativistas rescindieron el contrato con la constructora y ultimaron el reinicio del tajo con otra empresa. Construcciones Urrutia detuvo la obra al no poder pagar a las subcontratas tras la subida de costes.

Edificio
La promoción Anboto Dorrea constará de 5 plantas de sótano con 239 garajes y 166 trasteros, una torre con las 3 primeras plantas (0, 1, 2) de equipamiento comercial, planta 3ª con equipamiento comunitario (gimnasio, txoko, piscina, sauna, solárium y juegos infantiles) y 32 plantas para un total de 166 viviendas en régimen de cooperativa.

Viviendas
Las viviendas de Anboto Dorrea contarán con un equipamiento de calidad, una eficiente distribución y estancias exteriores que ofrecen una gran luminosidad y vistas de la ciudad. Asimismo, constarán de 2 o 3 dormitorios, amplias terrazas de hasta 26 m², carpintería de doble acristalamiento separado por cámara de aire aislante y un óptimo aislamiento acústico. La calefacción contará con sistema de suelo radiante por agua, mediante aerotermia.
Además, todas las viviendas tendrán instalación domótica que incluye: alarma de intrusión, alarma de incendios, aviso de corte de suministro eléctrico, control de climatización y control telefónico remoto.
El edificio poseerá certificado energético A.

Comunicaciones
La zona donde se ubicará el edificio es la mejor comunicada de la ciudad. Así pues, cuenta en su perímetro con los siguientes servicios:
 Estación de autobuses de Bilbao Intermodal, que se encuentra soterrada bajo la plaza situada frente al edificio.
 Metro de Bilbao, a través del Intercambiador de San Mamés.
 Renfe Cercanías, a través del Intercambiador de San Mamés.
 Tranvía de Bilbao, con tres estaciones circundantes: San Mamés, Hospital y Basurto.
 Renfe Cercanías AM, a través de la estación de Basurto Hospital.

Galería

Véase también
 Bizkaia Dorrea
 Garellano (grupo de viviendas)
 Edificio Museoalde
 Isozaki Atea

Referencias

Edificios y estructuras en construcción en España
Arquitectura de Bilbao
Edificios de viviendas de España
Edificios de viviendas de España del siglo XXI
Arquitectura en el País Vasco en el siglo XXI


Ganesha Games releases are at a hectic pace, always more rules are produced that you can lose something. So here some news on the latest productions by GG.
4 Against Darkness is a huge hit with lots of supplements to upgrade your characters. Future books will expand character progression and focus on other types of adventures. All character types in 4AD will progress up to 20th and more level, and there will be more versatile classes. There will be the use of polyhedral dice, one die step per book.
Deeper Dungeons will have rules for expert characters (levels 6 to 9) who will use a D8 for their rolls. Adventures will focus on the exploration of lower level of dungeons, inhabited by more dangerous monsters. Characters are given a list of skills they can gain instead of levelling up.
Four Against the Wild will have rules for veteran characters (levels 10 to 14) who will use a D10 for their rolls. Adventures will focus on outdoor exploration of uncharted wilderness using a hex-based, sandbox terrain and quest generation system. The terrain generation system will work also for lower levels.
Legends of Norindaal will have rules for legendary characters (levels 15 to 20) who will use a D12 for their rolls. Adventures will focus on building strongholds, setting up thieves and wizards' guilds, gaining political power, waging wars and defending one's land from invading armies.
Among the Immortals will let characters become immortals and mingle with the many Gods of Norindaal. Characters will use a D20 for their rolls. Level will be reset at 1 but on a whole new tier. In this setting, searching for treasure means collecting bits of divine power that let characters affect reality. The party will explore different dimensions and defend their homeworld from extra dimensional invasions.
And more books are planned with this engine. I'm thinking about one too. In the near future we will have an Arthurian variant, in the less near future we will have a sci-fi variant.
However now we have got two new books: Dark Waters and The Three Rings! Play with them if you want to see more 4AD books.
I suppose that English version will be out before the end of the year.
More on the development of Faustus Furius. My translation is almost ready, so we have to wait only the editing and the illustrator work. The new Ben Hur flick will be out in August. I think that you could race with your chariots at that date.
Do you remember Ferrum et Gloria? This blog was born as a way to promote this game development. More than 5 years and half ago. In the meantime the blog became a sort of diary of my passions. And in the meantime, with lots of efforts, the first part of the rules was out for Lucca Comics & Games 2014. I'm still involved with the second part. It is not a matter of laziness. I really have got no time to write the rules. It is a long process but it is not impossible. But I'm blocked by work and life. Moreover I bought a new home and the refurbishment is like building a pyramid. It is only 40mq big. Calling it big it is almost a joke, indeed. But the construction work was so full of stress that it absorbed a lot of time, a lot of life. I want to finish what I started. I want to complete my gladiatorial rules. I thought almost all, but I must still playtest something and write on screen the words that explain the rules in a easy and plain way.
The real name for Ferrum et Gloria 2 is Ferrum et Honor. I defined rules for shooters, dwarves, females, left-handed people, weather, terrain. Now I'm playtesting some things for horsemen, chariots, beasts. Then there will be some other issues but the core of the book is full developed. I wrote half of it too. Only a matter of time. Then the editing phase and next year the effort to produce the English edition. So I wish to release the 2nd Italian book for Lucca C&G 2016 (October), but I expect that it will be realistically realised for Hellana 2017 (March).
In the meantime I'm contributing to the development of a new game, Faustus Furius by Nicholas Wright. It is about chariot races and you can read it in English for late June or July. My Italian edition will be available around September. They are not gladiators but something similar. I hope you will enjoy it. It is only a matter of free time.


text:
Przemysław Kulig (ur. 8 października 1980 w Mrągowie) – polski piłkarz grający na pozycji atakującego w Żagiel Piecki.

Kariera
Przemysław Kulig jest wychowankiem Darz Boru Dobry Lasek. Następnie występował w Mrągowii Mrągowo, Warmii/Stomilu II Olsztyn, Jezioraku Iława, Jagiellonii Białystok i Górniku Łęczna. W 2007 roku podpisał kontrakt z Cracovią.

Linki zewnętrzne

Polscy piłkarze
Piłkarze Cracovii
Piłkarze Jagiellonii Białystok
Piłkarze Jezioraka Iława
Piłkarze Górnika Łęczna
Piłkarze Górnika Zabrze
Piłkarze Warmii Olsztyn
Urodzeni w 1980
Ludzie urodzeni w Mrągowie


When we look at something and see a sequence of activities producing outputs we are observing a process.
A process produces results through work being done in the process.
When we look at something and see the buildings, the people, the relationships, the activities and the interactions we are observing a system.
There are therefore two quite different types of management.
There is process management which will manage the achievement of results by planning, organizing, controlling and continually improving the work required to produce them.
There is system management which will manage a system of interacting elements that function together to achieve an objective.
The boundary between process and system is where the output fulfils a system objective. E.g If we treat the series of steps in frying an egg as a process, we will find that frying the egg is one stage of a meal preparation process. The meal preparation process is one stage in the service delivery process. Any of these processes can interact with the outputs from a process that manages the resources used in meal preparation process. Cut off the supply of electricity and the cook can't fry the egg. We therefore ascend through a hierarchy of processes to a system of processes which together with other elements deliver an experience that will delight the customer – the objective of frying the egg, preparing the meal and delivering the service.