flatten = function(args){
                    args = xui.toArr(args);
                    var arr=[], t, i=0,l=args.length;
                    for(;i<l;i++){
                        if(xui.isArr(t=args[i])) arr=arr.concat(t);
                        else arr.push(t);
                    }
                    return arr;
                }
unsubscribe
                var t,id=profile.$xid;
                if(t=profile.properties.msgType){
                    xui.arr.each(t.split(/[\s,;:]+/),function(t){
                        xui.unsubscribe(t,id);
                    });
                }
                //free profile
                profile.__gc();
            });
        },
        broadcast:function(recipientType, msg1, msg2, msg3, msg4, msg5,  msg6, msg7, msg8, msg9, readReceipt){
            return this.each(function(profile){
                var ins=profile.boxing()
                xui.arr.each(recipientType.split(/[\s,;:]+/),function(t){
                    xui.publish(t, [msg1, msg2, msg3, msg4, msg5,  msg6, msg7, msg8, msg9,function(){
                        xui.tryF(readReceipt, xui.toArr(arguments));
                        if(profile.onReceipt) profile.boxing().onReceipt.apply(ins, [profile, t, xui.toArr(arguments)]);
                    }], null, ins);
                });
            });
        },
        getParent:xui.Timer.prototype.getParent,
        getContainerId:xui.Timer.prototype.getContainerId
    },
    Static:{
        _objectProp:xui.Timer._objectProp,
        _beforeSerialized:xui.Timer._beforeSerialized,
        DataModel:{
            dataBinder:null,
            dataField:null,
            recipientType:{
                ini:"",
                set:function(value){
                        var profile=this, t, p=profile.properties,id=profile.$xid;
                        if(t = p.recipientType){
                            xui.arr.each(t.split(/[\s,;:]+/),function(t){
                                xui.unsubscribe(t,id);
                            });
                        }
                        if(t = p.recipientType = value||""){
                            xui.arr.each(t.split(/[\s,;:]+/),function(t){
                                xui.subscribe(t, id, function(){
                                    var a=xui.toArr(arguments), ins=profile.boxing();
                                    a.unshift(profile);
                                    if(profile.onMessageReceived) ins.onMessageReceived.apply(ins,a);
                                },p.asynReceive);
                            });
                        }
                }
            },
            asynReceive:false
        },
        EventHandlers:{
            onMessageReceived:function(profile, msg1, msg2, msg3, msg4, msg5,  msg6, msg7, msg8, msg9, readReceipt){},
            onReceipt:function(profile, recipientType, args){}
        }
    }
});

new function(){
    var receivers = [];
    xui.broadcast = function(id, msg1, msg2, msg3, msg4, msg5,  msg6, msg7, msg8, msg9, sender){
        var arr=xui.toArr(arguments);
        for(var i=0,l=receivers.length; i<l; i++)
            if(false===xui.tryF(receivers[i], arr))
                return;
        if(xui.Module){
            xui.arr.each(xui.Module._cache,function(o){
                 o.fireEvent && o.fireEvent('onGlobalMessage',  arr);
            });
        }
    };
    xui.registerReceiver = function(receiver){
        xui.isFun(receiver) && receivers.push(receiver);
    };
};
/*** xui.ExcelFormula.calculate
formula :
     "=FIXED(SUM(1:1, AVERAGE(A:A, B3)) + ROUND(B5)*C6 + MAX(A1:B2, B3) + MIN(10, B3)/ 1000, 2)"
     "=FIXED(SUM(1, AVERAGE(1, 3)) + ROUND(3.3)*1 + MAX(4, 2) + MIN(10, 5)/ 3, 2)" => 11.67
     "=CHOOSE(2,'a','b','c')" => 'b'
cellsMap :
     true: force to return something without cell value maps
     {}: returns the result of the formula with cell value maps
*