<commit_before>/*jslint newcap: true, nomen: true */

/*global joynrTestRequire: true */

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

joynrTestRequire("joynr/Util/TestTyping", [
    "joynr/util/Typing",
    "joynr/start/TypeRegistry",
    "joynr/types/TypeRegistrySingleton",
    "joynr/vehicle/radiotypes/RadioStation",
    "joynr/datatypes/exampleTypes/ComplexRadioStation",
    "joynr/datatypes/exampleTypes/Country",
    "joynr/tests/testTypes/TestEnum"
], function(
        Typing,
        TypeRegistry,
        TypeRegistrySingleton,
        RadioStation,
        ComplexRadioStation,
        Country,
        TestEnum) {

    function MyCustomObj() {}
    function _TestConstructor123_() {}
    function MyType(a, b, c, d, e) {
        this._typeName = "MyTypeName";
        this.a = a;
        this.b = b;
        this.c = c;
        this.d = d;
        this.e = e;
    }

    function MySecondType(a, b, c, d, e) {
        this._typeName = "MySecondTypeName";
        this.a = a;
        this.b = b;
        this.c = c;
        this.d = d;
        this.e = e;
    }

    describe("libjoynr-js.joynr.Typing", function() {
        it("is defined and of correct type", function() {
            expect(Typing).toBeDefined();
            expect(Typing).not.toBeNull();
            expect(typeof Typing === "object").toBeTruthy();
        });
    });

    describe("libjoynr-js.joynr.Typing.getObjectType", function() {
        it("returns the correct type strings", function() {
            expect(Typing.getObjectType(true)).toEqual("Boolean");
            expect(Typing.getObjectType(false)).toEqual("Boolean");

            expect(Typing.getObjectType(-123)).toEqual("Number");
            expect(Typing.getObjectType(0)).toEqual("Number");
            expect(Typing.getObjectType(123)).toEqual("Number");
            expect(Typing.getObjectType(1.2345678)).toEqual("Number");

            expect(Typing.getObjectType("a string")).toEqual("String");

            expect(Typing.getObjectType(function() {})).toEqual("Function");

            expect(Typing.getObjectType(new MyCustomObj())).toEqual("MyCustomObj");
            expect(Typing.getObjectType(new _TestConstructor123_()))
                    .toEqual("_TestConstructor123_");

            expect(Typing.getObjectType("a String")).toEqual("String");

            expect(Typing.getObjectType([])).toEqual("Array");
            expect(Typing.getObjectType({})).toEqual("Object");
        });

        it("throws if no object is provided", function() {
            expect(function() {
                Typing.getObjectType();
            }).toThrow();
            expect(function() {
                Typing.getObjectType(null);
            }).toThrow();
            expect(function() {
                Typing.getObjectType(undefined);
            }).toThrow();
        });
    });

    describe("libjoynr-js.joynr.Typing.translateJoynrTypeToJavascriptType", function() {
        it("returns the correct type strings", function() {
            expect(Typing.translateJoynrTypeToJavascriptType("Boolean")).toEqual("Boolean");
            expect(Typing.translateJoynrTypeToJavascriptType("Byte")).toEqual("Number");
            expect(Typing.translateJoynrTypeToJavascriptType("Short")).toEqual("Number");
            expect(Typing.translateJoynrTypeToJavascriptType("Integer")).toEqual("Number");
            expect(Typing.translateJoynrTypeToJavascriptType("Long")).toEqual("Number");
            expect(Typing.translateJoynrTypeToJavascriptType("Float")).toEqual("Number");
            expect(Typing.translateJoynrTypeToJavascriptType("Double")).toEqual("Number");
            expect(Typing.translateJoynrTypeToJavascriptType("String")).toEqual("String");
            expect(Typing.translateJoynrTypeToJavascriptType("List")).toEqual("Array");
            expect(Typing.translateJoynrTypeToJavascriptType("some.custom.namespace.and.Class"))
                    .toEqual("some.custom.namespace.and.Class");
        });

        it("throws if no object is provided", function() {
            expect(function() {
                Typing.translateJoynrTypeToJavascriptType();
            }).toThrow();
            expect(function() {
                Typing.translateJoynrTypeToJavascriptType(null);
            }).toThrow();
            expect(function() {
                Typing.translateJoynrTypeToJavascriptType(undefined);
            }).toThrow();
        });
    });

    describe("libjoynr-js.joynr.Typing.augmentType", function() {

        var tests =
                [
                    {
                        untyped : null,
                        typed : null
                    },
                    {
                        untyped : undefined,
                        typed : undefined
                    },
                    {
                        untyped : true,
                        typed : true
                    },
                    {
                        untyped : false,
                        typed : false
                    },
                    {
                        untyped : 12345,
                        typed : 12345
                    },
                    {
                        untyped : 0,
                        typed : 0
                    },
                    {
                        untyped : -12345,
                        typed : -12345
                    },
                    {
                        untyped : 1.23456789,
                        typed : 1.23456789
                    },
                    {
                        untyped : "123456",
                        typed : "123456"
                    },
                    {
                        untyped : "-123456",
                        typed : "-123456"
                    },
                    {
                        untyped : "1.23456789",
                        typed : "1.23456789"
                    },
                    {
                        untyped : "myString",
                        typed : "myString"
                    },
                    {
                        untyped : {
                            a : 1,
                            b : 2,
                            c : 3,
                            d : 4,
                            e : 5,
                            "_typeName" : "MyTypeName"
                        },
                        typed : new MyType(1, 2, 3, 4, 5)
                    },
                    {
                        untyped : {
                            a : 1,
                            b : 2,
                            c : 3,
                            d : 4,
                            e : 5,
                            "_typeName" : "MySecondTypeName"
                        },
                        typed : new MySecondType(1, 2, 3, 4, 5)
                    },
                    {
                        untyped : {
                            a : 1,
                            b : [
                                1,
                                2,
                                3
                            ],
                            c : "3",
                            d : "asdf",
                            "_typeName" : "MyTypeName"
                        },
                        typed : new MyType(1, [
                            1,
                            2,
                            3
                        ], "3", "asdf")
                    },
                    {
                        untyped : {
                            a : 1,
                            b : [
                                1,
                                2,
                                3
                            ],
                            c : "3",
                            d : "asdf",
                            "_typeName" : "MySecondTypeName"
                        },
                        typed : new MySecondType(1, [
                            1,
                            2,
                            3
                        ], "3", "asdf")
                    },
                    {
                        untyped : {
                            a : 1,
                            b : {
                                a : 1,
                                b : {
                                    a : 1,
                                    b : 2,
                                    c : 3,
                                    d : 4,
                                    e : 5,
                                    "_typeName" : "MyTypeName"
                                },
                                c : 3,
                                d : {
                                    a : 1,
                                    b : 2,
                                    c : 3,
                                    d : 4,
                                    e : 5,
                                    "_typeName" : "MyTypeName"
                                },
                                e : 5,
                                "_typeName" : "MySecondTypeName"
                            },
                            c : 3,
                            d : {
                                a : 1,
                                b : {
                                    a : 1,
                                    b : 2,
                                    c : 3,
                                    d : 4,
                                    e : 5,
                                    "_typeName" : "MyTypeName"
                                },
                                c : 3,
                                d : {
                                    a : 1,
                                    b : 2,
                                    c : 3,
                                    d : 4,
                                    e : 5,
                                    "_typeName" : "MyTypeName"
                                },
                                e : 5,
                                "_typeName" : "MySecondTypeName"
                            },
                            e : 5,
                            "_typeName" : "MyTypeName"
                        },
                        typed : new MyType(1, new MySecondType(
                                1,
                                new MyType(1, 2, 3, 4, 5),
                                3,
                                new MyType(1, 2, 3, 4, 5),
                                5), 3, new MySecondType(
                                1,
                                new MyType(1, 2, 3, 4, 5),
                                3,
                                new MyType(1, 2, 3, 4, 5),
                                5), 5)
                    }
                ];

        var typeRegistry = new TypeRegistry();
        typeRegistry.addType("MyTypeName", MyType);
        typeRegistry.addType("MySecondTypeName", MySecondType);

        it("types all objects correctly", function() {
            var i, typed;
            for (i = 0; i < tests.length; ++i) {
                typed = Typing.augmentTypes(tests[i].untyped, typeRegistry);
                expect(typed).toEqual(tests[i].typed);
                if (tests[i].untyped) { // filter out undefined and null
                    expect(Typing.getObjectType(typed)).toEqual(
                            Typing.getObjectType(tests[i].typed));
                }
            }
        });

        it("throws when giving a function or an object with a custom type", function() {
            expect(function() {
                Typing.augmentTypes(function() {}, typeRegistry);
            }).toThrow();

            expect(function() {
                Typing.augmentTypes(new MyType(), typeRegistry);
            }).toThrow();

            expect(function() {
                Typing.augmentTypes(new MySecondType(), typeRegistry);
            }).toThrow();
        });

        it(
                "augmentTypes is able to deal with enums as input",
                function() {
                    var fixture, expected;
                    fixture = "ZERO";
                    expected = TestEnum.ZERO;
                    expect(Typing.augmentTypes(fixture, TypeRegistrySingleton.getInstance())).toBe(
                            fixture);
                    expect(
                            Typing.augmentTypes(
                                    fixture,
                                    TypeRegistrySingleton.getInstance(),
                                    "joynr.tests.testTypes.TestEnum")).toBe(expected);
                });

        it("augmentTypes is able to deal with structs containing enum members", function() {
            var fixture, expected;
            /*jslint nomen: true */
            fixture = {
                _typeName : "joynr.datatypes.exampleTypes.ComplexRadioStation",
                name : "name",
                station : "station",
                source : "AUSTRIA"
            };
            /*jslint nomen: false */
            expected = new ComplexRadioStation({
                name : fixture.name,
                station : fixture.station,
                source : Country.AUSTRIA
            });
            expect(Typing.augmentTypes(fixture, TypeRegistrySingleton.getInstance())).toEqual(
                    expected);
        });

    });

    function augmentTypeName(obj, expectedType, customMember) {
        var objWithTypeName = Typing.augmentTypeName(obj, "joynr", customMember);
        /*jslint nomen: true */
        expect(objWithTypeName[customMember || "_typeName"]).toEqual("joynr." + expectedType);
        /*jslint nomen: false */
    }

    describe("libjoynr-js.joynr.Typing.augmentTypeName", function() {
        it("augments type into _typeName member", function() {
            augmentTypeName(new MyCustomObj(), "MyCustomObj");
            augmentTypeName(new _TestConstructor123_(), "_TestConstructor123_");
            augmentTypeName(new MyType(), "MyType");
            augmentTypeName(new MySecondType(), "MySecondType");
        });

        it("augments type into custom member", function() {
            augmentTypeName(new MyCustomObj(), "MyCustomObj", "myCustomMember");
            augmentTypeName(new _TestConstructor123_(), "_TestConstructor123_", "myCustomMember");
            augmentTypeName(new MyType(), "MyType", "myCustomMember");
            augmentTypeName(new MySecondType(), "MySecondType", "myCustomMember");
        });

        it("throws if no object is provided", function() {
            expect(function() {
                Typing.augmentTypeName();
            }).toThrow();
            expect(function() {
                Typing.augmentTypeName(null);
            }).toThrow();
            expect(function() {
                Typing.augmentTypeName(undefined);
            }).toThrow();
        });

        it("isEnumType accepts enum types", function() {
            var fixture = TestEnum.ZERO, radioStation;
            radioStation = new RadioStation({
                name : "name",
                trafficService : false,
                country : {}
            });
            expect(Typing.isEnumType(fixture)).toBe(true);
            expect(Typing.isEnumType("TestString")).toBe(false);
            expect(Typing.isEnumType(123)).toBe(false);
            expect(Typing.isEnumType(radioStation)).toBe(false);
        });

    });

});<commit_msg>[JS] Add unit test for TestTyping.augmentTypes<commit_after>/*jslint newcap: true, nomen: true */

/*global joynrTestRequire: true */

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

joynrTestRequire(
        "joynr/Util/TestTyping",
        [
            "joynr/util/Typing",
            "joynr/start/TypeRegistry",
            "joynr/types/TypeRegistrySingleton",
            "joynr/types/DiscoveryEntry",
            "joynr/types/CommunicationMiddleware",
            "joynr/types/ProviderQos",
            "joynr/types/ProviderScope",
            "joynr/vehicle/radiotypes/RadioStation",
            "joynr/datatypes/exampleTypes/ComplexRadioStation",
            "joynr/datatypes/exampleTypes/Country",
            "joynr/tests/testTypes/TestEnum"
        ],
        function(
                Typing,
                TypeRegistry,
                TypeRegistrySingleton,
                DiscoveryEntry,
                CommunicationMiddleware,
                ProviderQos,
                ProviderScope,
                RadioStation,
                ComplexRadioStation,
                Country,
                TestEnum) {

            function MyCustomObj() {}
            function _TestConstructor123_() {}
            function MyType(a, b, c, d, e) {
                this._typeName = "MyTypeName";
                this.a = a;
                this.b = b;
                this.c = c;
                this.d = d;
                this.e = e;
            }

            function MySecondType(a, b, c, d, e) {
                this._typeName = "MySecondTypeName";
                this.a = a;
                this.b = b;
                this.c = c;
                this.d = d;
                this.e = e;
            }

            describe("libjoynr-js.joynr.Typing", function() {
                it("is defined and of correct type", function() {
                    expect(Typing).toBeDefined();
                    expect(Typing).not.toBeNull();
                    expect(typeof Typing === "object").toBeTruthy();
                });
            });

            describe("libjoynr-js.joynr.Typing.getObjectType", function() {
                it("returns the correct type strings", function() {
                    expect(Typing.getObjectType(true)).toEqual("Boolean");
                    expect(Typing.getObjectType(false)).toEqual("Boolean");

                    expect(Typing.getObjectType(-123)).toEqual("Number");
                    expect(Typing.getObjectType(0)).toEqual("Number");
                    expect(Typing.getObjectType(123)).toEqual("Number");
                    expect(Typing.getObjectType(1.2345678)).toEqual("Number");

                    expect(Typing.getObjectType("a string")).toEqual("String");

                    expect(Typing.getObjectType(function() {})).toEqual("Function");

                    expect(Typing.getObjectType(new MyCustomObj())).toEqual("MyCustomObj");
                    expect(Typing.getObjectType(new _TestConstructor123_())).toEqual(
                            "_TestConstructor123_");

                    expect(Typing.getObjectType("a String")).toEqual("String");

                    expect(Typing.getObjectType([])).toEqual("Array");
                    expect(Typing.getObjectType({})).toEqual("Object");
                });

                it("throws if no object is provided", function() {
                    expect(function() {
                        Typing.getObjectType();
                    }).toThrow();
                    expect(function() {
                        Typing.getObjectType(null);
                    }).toThrow();
                    expect(function() {
                        Typing.getObjectType(undefined);
                    }).toThrow();
                });
            });

            describe(
                    "libjoynr-js.joynr.Typing.translateJoynrTypeToJavascriptType",
                    function() {
                        it(
                                "returns the correct type strings",
                                function() {
                                    expect(Typing.translateJoynrTypeToJavascriptType("Boolean"))
                                            .toEqual("Boolean");
                                    expect(Typing.translateJoynrTypeToJavascriptType("Byte"))
                                            .toEqual("Number");
                                    expect(Typing.translateJoynrTypeToJavascriptType("Short"))
                                            .toEqual("Number");
                                    expect(Typing.translateJoynrTypeToJavascriptType("Integer"))
                                            .toEqual("Number");
                                    expect(Typing.translateJoynrTypeToJavascriptType("Long"))
                                            .toEqual("Number");
                                    expect(Typing.translateJoynrTypeToJavascriptType("Float"))
                                            .toEqual("Number");
                                    expect(Typing.translateJoynrTypeToJavascriptType("Double"))
                                            .toEqual("Number");
                                    expect(Typing.translateJoynrTypeToJavascriptType("String"))
                                            .toEqual("String");
                                    expect(Typing.translateJoynrTypeToJavascriptType("List"))
                                            .toEqual("Array");
                                    expect(
                                            Typing
                                                    .translateJoynrTypeToJavascriptType("some.custom.namespace.and.Class"))
                                            .toEqual("some.custom.namespace.and.Class");
                                });

                        it("throws if no object is provided", function() {
                            expect(function() {
                                Typing.translateJoynrTypeToJavascriptType();
                            }).toThrow();
                            expect(function() {
                                Typing.translateJoynrTypeToJavascriptType(null);
                            }).toThrow();
                            expect(function() {
                                Typing.translateJoynrTypeToJavascriptType(undefined);
                            }).toThrow();
                        });
                    });

            describe(
                    "libjoynr-js.joynr.Typing.augmentType",
                    function() {

                        var tests =
                                [
                                    {
                                        untyped : null,
                                        typed : null
                                    },
                                    {
                                        untyped : undefined,
                                        typed : undefined
                                    },
                                    {
                                        untyped : true,
                                        typed : true
                                    },
                                    {
                                        untyped : false,
                                        typed : false
                                    },
                                    {
                                        untyped : 12345,
                                        typed : 12345
                                    },
                                    {
                                        untyped : 0,
                                        typed : 0
                                    },
                                    {
                                        untyped : -12345,
                                        typed : -12345
                                    },
                                    {
                                        untyped : 1.23456789,
                                        typed : 1.23456789
                                    },
                                    {
                                        untyped : "123456",
                                        typed : "123456"
                                    },
                                    {
                                        untyped : "-123456",
                                        typed : "-123456"
                                    },
                                    {
                                        untyped : "1.23456789",
                                        typed : "1.23456789"
                                    },
                                    {
                                        untyped : "myString",
                                        typed : "myString"
                                    },
                                    {
                                        untyped : {
                                            a : 1,
                                            b : 2,
                                            c : 3,
                                            d : 4,
                                            e : 5,
                                            "_typeName" : "MyTypeName"
                                        },
                                        typed : new MyType(1, 2, 3, 4, 5)
                                    },
                                    {
                                        untyped : {
                                            a : 1,
                                            b : 2,
                                            c : 3,
                                            d : 4,
                                            e : 5,
                                            "_typeName" : "MySecondTypeName"
                                        },
                                        typed : new MySecondType(1, 2, 3, 4, 5)
                                    },
                                    {
                                        untyped : {
                                            a : 1,
                                            b : [
                                                1,
                                                2,
                                                3
                                            ],
                                            c : "3",
                                            d : "asdf",
                                            "_typeName" : "MyTypeName"
                                        },
                                        typed : new MyType(1, [
                                            1,
                                            2,
                                            3
                                        ], "3", "asdf")
                                    },
                                    {
                                        untyped : {
                                            a : 1,
                                            b : [
                                                1,
                                                2,
                                                3
                                            ],
                                            c : "3",
                                            d : "asdf",
                                            "_typeName" : "MySecondTypeName"
                                        },
                                        typed : new MySecondType(1, [
                                            1,
                                            2,
                                            3
                                        ], "3", "asdf")
                                    },
                                    {
                                        untyped : {
                                            a : 1,
                                            b : {
                                                a : 1,
                                                b : {
                                                    a : 1,
                                                    b : 2,
                                                    c : 3,
                                                    d : 4,
                                                    e : 5,
                                                    "_typeName" : "MyTypeName"
                                                },
                                                c : 3,
                                                d : {
                                                    a : 1,
                                                    b : 2,
                                                    c : 3,
                                                    d : 4,
                                                    e : 5,
                                                    "_typeName" : "MyTypeName"
                                                },
                                                e : 5,
                                                "_typeName" : "MySecondTypeName"
                                            },
                                            c : 3,
                                            d : {
                                                a : 1,
                                                b : {
                                                    a : 1,
                                                    b : 2,
                                                    c : 3,
                                                    d : 4,
                                                    e : 5,
                                                    "_typeName" : "MyTypeName"
                                                },
                                                c : 3,
                                                d : {
                                                    a : 1,
                                                    b : 2,
                                                    c : 3,
                                                    d : 4,
                                                    e : 5,
                                                    "_typeName" : "MyTypeName"
                                                },
                                                e : 5,
                                                "_typeName" : "MySecondTypeName"
                                            },
                                            e : 5,
                                            "_typeName" : "MyTypeName"
                                        },
                                        typed : new MyType(
                                                1,
                                                new MySecondType(
                                                        1,
                                                        new MyType(1, 2, 3, 4, 5),
                                                        3,
                                                        new MyType(1, 2, 3, 4, 5),
                                                        5),
                                                3,
                                                new MySecondType(
                                                        1,
                                                        new MyType(1, 2, 3, 4, 5),
                                                        3,
                                                        new MyType(1, 2, 3, 4, 5),
                                                        5),
                                                5)
                                    }
                                ];

                        var typeRegistry = new TypeRegistry();
                        typeRegistry.addType("MyTypeName", MyType);
                        typeRegistry.addType("MySecondTypeName", MySecondType);

                        it("types all objects correctly", function() {
                            var i, typed;
                            for (i = 0; i < tests.length; ++i) {
                                typed = Typing.augmentTypes(tests[i].untyped, typeRegistry);
                                expect(typed).toEqual(tests[i].typed);
                                if (tests[i].untyped) { // filter out undefined and null
                                    expect(Typing.getObjectType(typed)).toEqual(
                                            Typing.getObjectType(tests[i].typed));
                                }
                            }
                        });

                        it(
                                "throws when giving a function or an object with a custom type",
                                function() {
                                    expect(function() {
                                        Typing.augmentTypes(function() {}, typeRegistry);
                                    }).toThrow();

                                    expect(function() {
                                        Typing.augmentTypes(new MyType(), typeRegistry);
                                    }).toThrow();

                                    expect(function() {
                                        Typing.augmentTypes(new MySecondType(), typeRegistry);
                                    }).toThrow();
                                });

                        it("augmentTypes is able to deal with enums as input", function() {
                            var fixture, expected;
                            fixture = "ZERO";
                            expected = TestEnum.ZERO;
                            expect(
                                    Typing.augmentTypes(fixture, TypeRegistrySingleton
                                            .getInstance())).toBe(fixture);
                            expect(
                                    Typing.augmentTypes(fixture, TypeRegistrySingleton
                                            .getInstance(), "joynr.tests.testTypes.TestEnum"))
                                    .toBe(expected);
                        });

                        it(
                                "augmentTypes is able to deal with structs containing enum members",
                                function() {
                                    var fixture, expected;
                                    /*jslint nomen: true */
                                    fixture =
                                            {
                                                _typeName : "joynr.datatypes.exampleTypes.ComplexRadioStation",
                                                name : "name",
                                                station : "station",
                                                source : "AUSTRIA"
                                            };
                                    /*jslint nomen: false */
                                    expected = new ComplexRadioStation({
                                        name : fixture.name,
                                        station : fixture.station,
                                        source : Country.AUSTRIA
                                    });
                                    expect(
                                            Typing.augmentTypes(fixture, TypeRegistrySingleton
                                                    .getInstance())).toEqual(expected);
                                });

                        it(
                                "augmentTypes is able to deal with complex structs containing enum array and other structs as members",
                                function() {
                                    var fixture, providerQos, expected;
                                    providerQos = {
                                        _typeName : "joynr.types.ProviderQos",
                                        customParameters : [],
                                        providerVersion : 123,
                                        priority : 234,
                                        scope : "GLOBAL",
                                        supportsOnChangeSubscriptions : false
                                    };
                                    /*jslint nomen: true */
                                    fixture = {
                                        _typeName : "joynr.types.DiscoveryEntry",
                                        domain : "domain",
                                        interfaceName : "interfaceName",
                                        participantId : "participantId",
                                        qos : providerQos,
                                        connections : [
                                            "COMMONAPI_DBUS",
                                            "JOYNR"
                                        ]
                                    };
                                    /*jslint nomen: false */

                                    expected =
                                            new DiscoveryEntry(
                                                    {
                                                        domain : fixture.domain,
                                                        interfaceName : fixture.interfaceName,
                                                        participantId : fixture.participantId,
                                                        qos : new ProviderQos(
                                                                {
                                                                    customParameters : providerQos.customParameters,
                                                                    providerVersion : providerQos.providerVersion,
                                                                    priority : providerQos.priority,
                                                                    scope : ProviderScope.GLOBAL,
                                                                    supportsOnChangeSubscriptions : providerQos.supportsOnChangeSubscriptions
                                                                }),
                                                        connections : [
                                                            CommunicationMiddleware.COMMONAPI_DBUS,
                                                            CommunicationMiddleware.JOYNR
                                                        ]
                                                    });
                                    expect(
                                            Typing.augmentTypes(fixture, TypeRegistrySingleton
                                                    .getInstance())).toEqual(expected);
                                });

                    });

            function augmentTypeName(obj, expectedType, customMember) {
                var objWithTypeName = Typing.augmentTypeName(obj, "joynr", customMember);
                /*jslint nomen: true */
                expect(objWithTypeName[customMember || "_typeName"]).toEqual(
                        "joynr." + expectedType);
                /*jslint nomen: false */
            }

            describe("libjoynr-js.joynr.Typing.augmentTypeName", function() {
                it("augments type into _typeName member", function() {
                    augmentTypeName(new MyCustomObj(), "MyCustomObj");
                    augmentTypeName(new _TestConstructor123_(), "_TestConstructor123_");
                    augmentTypeName(new MyType(), "MyType");
                    augmentTypeName(new MySecondType(), "MySecondType");
                });

                it("augments type into custom member", function() {
                    augmentTypeName(new MyCustomObj(), "MyCustomObj", "myCustomMember");
                    augmentTypeName(
                            new _TestConstructor123_(),
                            "_TestConstructor123_",
                            "myCustomMember");
                    augmentTypeName(new MyType(), "MyType", "myCustomMember");
                    augmentTypeName(new MySecondType(), "MySecondType", "myCustomMember");
                });

                it("throws if no object is provided", function() {
                    expect(function() {
                        Typing.augmentTypeName();
                    }).toThrow();
                    expect(function() {
                        Typing.augmentTypeName(null);
                    }).toThrow();
                    expect(function() {
                        Typing.augmentTypeName(undefined);
                    }).toThrow();
                });

                it("isEnumType accepts enum types", function() {
                    var fixture = TestEnum.ZERO, radioStation;
                    radioStation = new RadioStation({
                        name : "name",
                        trafficService : false,
                        country : {}
                    });
                    expect(Typing.isEnumType(fixture)).toBe(true);
                    expect(Typing.isEnumType("TestString")).toBe(false);
                    expect(Typing.isEnumType(123)).toBe(false);
                    expect(Typing.isEnumType(radioStation)).toBe(false);
                });

            });

        });<|endoftext|>


<commit_before>const resources = require('./resources')

module.exports = async function me (obj, info, { session, state, log }) {
  const allResources = await resources(obj, info, { state })
  const servers = Array.from(state.serversPool.values()).map(server => server.config.id)

  allResources.forEach(resource => {
    resource.permissions.forEach(permission => {
      permission.allowed = state.acl.hasPermission(resource.name, permission.name)
      permission.serversAllowed = servers.filter(serverId => state.acl.hasServerPermission(serverId, resource.name, permission.name))
    })
  })

  if (!session || !session.playerId) {
    return {
      resources: allResources
    }
  }

  const [checkResult] = await state.dbPool('bm_web_users').select('email').where('player_id', session.playerId)
  let playerData = {}

  try {
    playerData = await state.loaders.player.load({ id: session.playerId, fields: ['id', 'name'] })
  } catch (e) {
    log.error(e, 'failed to load player')
  }

  const me = {
    ...playerData,
    hasAccount: Boolean(checkResult?.email),
    email: checkResult ? checkResult.email : null,
    session: {
      type: session.type
    },
    resources: allResources
  }

  return me
}
<commit_msg>fix: return id on failure for me query<commit_after>const resources = require('./resources')

module.exports = async function me (obj, info, { session, state, log }) {
  const allResources = await resources(obj, info, { state })
  const servers = Array.from(state.serversPool.values()).map(server => server.config.id)

  allResources.forEach(resource => {
    resource.permissions.forEach(permission => {
      permission.allowed = state.acl.hasPermission(resource.name, permission.name)
      permission.serversAllowed = servers.filter(serverId => state.acl.hasServerPermission(serverId, resource.name, permission.name))
    })
  })

  if (!session || !session.playerId) {
    return {
      resources: allResources
    }
  }

  const [checkResult] = await state.dbPool('bm_web_users').select('email').where('player_id', session.playerId)
  let playerData = {}

  try {
    playerData = await state.loaders.player.load({ id: session.playerId, fields: ['id', 'name'] })
  } catch (e) {
    log.error(e, 'failed to load player')

    playerData = { id: session.playerId }
  }

  const me = {
    ...playerData,
    hasAccount: Boolean(checkResult?.email),
    email: checkResult ? checkResult.email : null,
    session: {
      type: session.type
    },
    resources: allResources
  }

  return me
}
<|endoftext|>


<commit_before>var configuration = require('../../../config/configuration.json')

module.exports = {
  getsubcampaignSettingModel: function (redisClient, CampaignHashID, subCampaignHashID, callback) {

  }
}<commit_msg>Implement Read SubCampaign Setting Model Logic<commit_after>var configuration = require('../../../config/configuration.json')

module.exports = {
  getsubcampaignSettingModel: function (redisClient, subCampaignHashID, callback) {
    var tableName = configuration.TableMASubcampaignModelSettingModel + subCampaignHashID
    var model = {}
    redisClient.hget(tableName, configuration.ConstantSMPriority, function (err, replies) {
      if (err) {
        callback(err, null)
        return
      }
      var settingKeys = Object.keys(configuration.settingEnum)
      var counter = 0
      for (var i = 1; i < settingKeys.length; i++) {
        var key = settingKeys[i]
        var table = configuration.TableModel.general.SubcampaignModel + subCampaignHashID
        utility.stringReplace(table, '@', key)
        multi.zrange(table, '0', '-1', function (err, replies) {
          if (err) {
            callback(err, null)
            return
          }
          model[settingKeys[i]] = replies
          counter++
          if (counter == (settingKeys.length - 1))
            callback(null, model)
        })
      }
    })
  }
}<|endoftext|>


<commit_before>// Defaults - override in URL
var showInterval = 5000;        //milliseconds, use 'interval' in URL
var mySide = 'top';             //'top', 'left', or 'right', use 'side' in URL

// Slides - need to come in triples
var slides = [
    {'top':'test.001.png', 'left':'test.001.png', 'right':'test.001.png'},
    {'top':'test.002.png', 'left':'test.002.png', 'right':'test.002.png'},
    {'top':'test.003.png', 'left':'test.003.png', 'right':'test.003.png'}
];

function report(message) {
    $('#image').html('
' + JSON.stringify(message) + '
' + $('#image').html());
};

function showSlide(url, message) {
    $('#image').css('background-image', 'url(' + url + ')');
    slideDelay();
}

function slideDelay() {
    // Assuming that the clocks of all the computers are in sync, this code will make
    // sure that all computers will be showing synced slides.
    //
    // Imagine that the day is divided into a series of time periods of equal length.
    // These periods are called slots here. This code does two things.
    // 1. Change slides only at the beginning of the next slot
    // 2. Put slides into specific slots. Slot 0 - slide 0, slot 1 - slide 1, etc.
    //    when you run out of slides, start from slide 0.
    // This means that there may be a short slot at the end of the day and that
    // the last group of slots may not cover all the slides.

    var now = new Date();
    var millisecondsOfDay = (((now.getHours() * 60) + now.getMinutes() * 60) + now.getSeconds()) * 1000 + now.getMilliseconds();
    var slot = Math.floor(millisecondsOfDay / showInterval);
    var millisecondsLeft = showInterval * (slot + 1) - millisecondsOfDay;

    var url = slides[slot % slides.length][mySide];

    //report({'msg':'slideDelay', 'millisLeft':millisecondsLeft, 'slot':slot, 'slide':slot%slides.length, 'url':url});
    setTimeout(function(){showSlide(url);}, millisecondsLeft);
}

/////////////////////////////////////////////////////
//
// Adapted from http://stackoverflow.com/a/4209094 //
//
function getQueryVariable(variable) {
  var query = window.location.search.substring(1);
  var vars = query.split("&");
  for (var i=0;i<vars.length;i++)
  {
    var pair = vars[i].split("=");
    if (pair[0] == variable)
    {
      return pair[1];
    }
  }
  return ''; //not found
}
//
/////////////////////////////////////////////////////

$(document).ready(function(){

    var interval = getQueryVariable('interval');
    if(interval) {
        showInterval = parseInt(interval, 10);
    }

    var side = getQueryVariable('side');
    if(side) {
        mySide = side;
    }

    slideDelay();
});
<commit_msg>Changed default timeout to 15 secs<commit_after>// Defaults - override in URL
var showInterval = 15000;        //milliseconds, use 'interval' in URL
var mySide = 'top';             //'top', 'left', or 'right', use 'side' in URL

// Slides - need to come in triples
var slides = [
    {'top':'test.001.png', 'left':'test.001.png', 'right':'test.001.png'},
    {'top':'test.002.png', 'left':'test.002.png', 'right':'test.002.png'},
    {'top':'test.003.png', 'left':'test.003.png', 'right':'test.003.png'}
];

function report(message) {
    $('#image').html('
' + JSON.stringify(message) + '
' + $('#image').html());
};

function showSlide(url, message) {
    $('#image').css('background-image', 'url(' + url + ')');
    slideDelay();
}

function slideDelay() {
    // Assuming that the clocks of all the computers are in sync, this code will make
    // sure that all computers will be showing synced slides.
    //
    // Imagine that the day is divided into a series of time periods of equal length.
    // These periods are called slots here. This code does two things.
    // 1. Change slides only at the beginning of the next slot
    // 2. Put slides into specific slots. Slot 0 - slide 0, slot 1 - slide 1, etc.
    //    when you run out of slides, start from slide 0.
    // This means that there may be a short slot at the end of the day and that
    // the last group of slots may not cover all the slides.

    var now = new Date();
    var millisecondsOfDay = (((now.getHours() * 60) + now.getMinutes() * 60) + now.getSeconds()) * 1000 + now.getMilliseconds();
    var slot = Math.floor(millisecondsOfDay / showInterval);
    var millisecondsLeft = showInterval * (slot + 1) - millisecondsOfDay;

    var url = slides[slot % slides.length][mySide];

    // report({'msg':'slideDelay', 'millisLeft':millisecondsLeft, 'slot':slot, 'slide':slot%slides.length, 'url':url});
    setTimeout(function(){showSlide(url);}, millisecondsLeft);
}

/////////////////////////////////////////////////////
//
// Adapted from http://stackoverflow.com/a/4209094 //
//
function getQueryVariable(variable) {
  var query = window.location.search.substring(1);
  var vars = query.split("&");
  for (var i=0;i<vars.length;i++)
  {
    var pair = vars[i].split("=");
    if (pair[0] == variable)
    {
      return pair[1];
    }
  }
  return ''; //not found
}
//
/////////////////////////////////////////////////////

$(document).ready(function(){

    var interval = getQueryVariable('interval');
    if(interval) {
        showInterval = parseInt(interval, 10);
    }

    var side = getQueryVariable('side');
    if(side) {
        mySide = side;
    }

    slideDelay();
});
<|endoftext|>


<commit_before>'use strict';

// ----------------------------------------------------------------------------

const assert = require ('assert');

//  ---------------------------------------------------------------------------

function testOHLCV (exchange, ohlcv, symbol, now) {

    const json = exchange.json (ohlcv);
    assert (ohlcv);
    assert (Array.isArray (ohlcv), json);
    const length = ohlcv.length;
    assert (length >= 6);
    for (let i = 0; i < ohlcv.length; i++) {
        assert ((ohlcv[i] === undefined) || (typeof ohlcv[i] === 'number'), json);
    }

    assert (ohlcv[0] > 1230940800000, json); // 03 Jan 2009 - first block
    assert (ohlcv[0] < 2147483648000, json); // 19 Jan 2038 - int32 overflows

    const skippedExchanges = [
        'bitmex', // BitMEX API docs: also note the open price is equal to the close price of the previous timeframe bucket.
        'vcc', // same as BitMEX, the open price is equal to the close price of the previous timeframe bucket.
        'delta',
        'cryptocom',
    ];

    if (!exchange.inArray (exchange.id, skippedExchanges)) {
        assert ((ohlcv[1] === undefined) || (ohlcv[2] === undefined) || (ohlcv[1] <= ohlcv[2]), 'open > high, ' + exchange.safeString (ohlcv, 1, 'undefined') + ' > ' + exchange.safeString (ohlcv, 2, 'undefined')); // open <= high
        assert ((ohlcv[3] === undefined) || (ohlcv[2] === undefined) || (ohlcv[3] <= ohlcv[2]), 'low > high, ' + exchange.safeString (ohlcv, 2, 'undefined') + ' > ' + exchange.safeString (ohlcv, 3, 'undefined')); // low <= high
        assert ((ohlcv[3] === undefined) || (ohlcv[4] === undefined) || (ohlcv[3] <= ohlcv[4]), 'low > close, ' + exchange.safeString (ohlcv, 3, 'undefined') + ' > ' + exchange.safeString (ohlcv, 4, 'undefined')); // low <= close
    }
}

module.exports = testOHLCV;
<commit_msg>test.ohlcv.js cleanup<commit_after>'use strict';

const assert = require ('assert');

function testOHLCV (exchange, ohlcv, symbol, now) {

    const json = exchange.json (ohlcv);
    assert (ohlcv);
    assert (Array.isArray (ohlcv), json);
    const length = ohlcv.length;
    assert (length >= 6);
    for (let i = 0; i < ohlcv.length; i++) {
        assert ((ohlcv[i] === undefined) || (typeof ohlcv[i] === 'number'), json);
    }

    assert (ohlcv[0] > 1230940800000, json); // 03 Jan 2009 - first block
    assert (ohlcv[0] < 2147483648000, json); // 19 Jan 2038 - int32 overflows

    const skippedExchanges = [
        'bitmex', // BitMEX API docs: also note the open price is equal to the close price of the previous timeframe bucket.
        'vcc', // same as BitMEX, the open price is equal to the close price of the previous timeframe bucket.
        'delta',
        'cryptocom',
    ];

    if (!exchange.inArray (exchange.id, skippedExchanges)) {
        assert ((ohlcv[1] === undefined) || (ohlcv[2] === undefined) || (ohlcv[1] <= ohlcv[2]), 'open > high, ' + exchange.safeString (ohlcv, 1, 'undefined') + ' > ' + exchange.safeString (ohlcv, 2, 'undefined')); // open <= high
        assert ((ohlcv[3] === undefined) || (ohlcv[2] === undefined) || (ohlcv[3] <= ohlcv[2]), 'low > high, ' + exchange.safeString (ohlcv, 2, 'undefined') + ' > ' + exchange.safeString (ohlcv, 3, 'undefined')); // low <= high
        assert ((ohlcv[3] === undefined) || (ohlcv[4] === undefined) || (ohlcv[3] <= ohlcv[4]), 'low > close, ' + exchange.safeString (ohlcv, 3, 'undefined') + ' > ' + exchange.safeString (ohlcv, 4, 'undefined')); // low <= close
    }
}

module.exports = testOHLCV;
<|endoftext|>


<commit_before>// Copyright 2013 Joyent, Inc.  All rights reserved.

var assert = require('assert');
var fs = require('fs');
var http = require('http');
var path = require('path');
var sprintf = require('util').format;

var Logger = require('bunyan');
var ldap = require('ldapjs');
var nopt = require('nopt');
var restify = require('restify');
var uuid = require('node-uuid');

var customers = require('./capi/customers');
var keys = require('./capi/keys');
var login = require('./capi/login');
var limits = require('./capi/limits');
var metadata = require('./capi/metadata');
var utils = require('./capi/util');

function entitify(str) {
    str = '' + str;
    /* BEGIN JSSTYLED */
    str = str.replace(/&/g, '&').replace(/</g, '<')
        .replace(/>/g, '>').replace(/'/g, ''')
        .replace(/"/g, '"');
    /* END JSSTYLED */
    return str;
}

function toXml(elm) {
    var xml = '';
    if (Array.isArray(elm)) {
        xml += elm.map(function (e) {
            return (toXml(e));
        }).join('\n');
    } else if (typeof (elm) === 'object' && Object.keys(elm)) {
        Object.keys(elm).forEach(function (k) {
            if (elm[k]) {
                xml += sprintf('<%s>%s</%s>', k, toXml(elm[k]), k);
            }
        });
    } else {
        xml += entitify(elm);
    }
    return (xml);
}

///--- Globals

var opts = {
    'certificate': String,
    'config': String,
    'debug': Boolean,
    'file': String,
    'key': String,
    'port': Number,
    'ufds': String,
    'help': Boolean
};

var shortOpts = {
    'c': ['--certiifcate'],
    'd': ['--debug'],
    'f': ['--file'],
    'k': ['--key'],
    'p': ['--port'],
    'h': ['--help'],
    'u': ['--ufds']
};

///--- Helpers

function usage(code, message) {
    var _opts = '';
    Object.keys(shortOpts).forEach(function (k) {
        var longOpt = shortOpts[k][0].replace('--', '');
        var type = opts[longOpt].name || 'string';
        if (type && type === 'boolean') type = '';
        type = type.toLowerCase();

        _opts += ' [--' + longOpt + ' ' + type + ']';
    });
    _opts += ' dn attribute value(s)';

    var msg = (message ? message + '\n' : '') +
        'usage: ' + path.basename(process.argv[1]) + _opts;

    process.stderr.write(msg + '\n');
    process.exit(code);
}

///--- CAPI shim

function CAPI(config) {

    var log = new Logger({
        name: 'capi',
        level: config.logLevel,
        stream: process.stdout,
        serializers: restify.bunyan.serializers
    });

    var client;

    function before(req, res, next) {
        req.ldap = client;
        return next();
    }

    var server = restify.createServer({
        name: 'capi',
        log: log,
        formatters: {
            'application/xml': function formatXml(req, res, body) {
                var o;
                var xml = '<?xml version="1.0" encoding="utf-8"?>\n';
                if (body instanceof Error) {
                    o = { errors: { error: body.body } };
                } else if (Buffer.isBuffer(body)) {
                    o = JSON.parse(body.toString('base64'));
                } else {
                    o = body;
                }

                xml += toXml(o);

                res.setHeader('Content-Length', Buffer.byteLength(xml));
                return xml;
            }
        }
    });

    server.use(restify.acceptParser(server.acceptable));
    server.use(restify.dateParser());
    server.use(restify.queryParser());
    server.use(restify.bodyParser());
    server.use(restify.fullResponse());

    server.on('after', restify.auditLogger({log: log}));

    server.use(before);

    // Show
    server.get('/customers', customers.list);
    server.head('/customers', customers.list);

    // CreateCustomer
    server.post('/customers', customers.create);

    // UpdateCustomer
    server.put('/customers/:uuid', before, utils.loadCustomer,
            customers.update, utils.loadCustomer,
            function respond(req, res, next) {
                var customer = utils.translateCustomer(
                    req.customer.toObject());
                res.send(200, customer);
                return next();
            });

    // GetCustomer
    server.get('/customers/:uuid', utils.loadCustomer, customers.get);
    server.head('/customers/:uuid', utils.loadCustomer, customers.get);

    // DeleteCustomer
    server.del('/customers/:uuid', utils.loadCustomer, customers.del);

    // GetSalt
    server.get('/login/:login', login.getSalt);
    server.head('/login/:login', login.getSalt);

    // Login
    server.post('/login', login.login);

    // ForgotPassword
    server.post('/auth/forgot_password', login.forgotPassword);

    server.use(utils.loadCustomer);

    /// Metadata
    server.get('/auth/customers/:uuid/metadata/:appkey', metadata.list);
    server.put('/auth/customers/:uuid/metadata/:appkey/:key', metadata.put);
    server.get('/auth/customers/:uuid/metadata/:appkey/:key', metadata.get);
    server.del('/auth/customers/:uuid/metadata/:appkey/:key', metadata.del);

    /// Keys
    server.post('/customers/:uuid/keys', keys.post);
    server.get('/customers/:uuid/keys', keys.list);
    server.get('/customers/:uuid/keys/:id', keys.get);
    server.put('/customers/:uuid/keys/:id', keys.put);
    server.del('/customers/:uuid/keys/:id', keys.del);

    /// Smartlogin

    server.post('/customers/:uuid/ssh_sessions', keys.smartlogin);

    /// Limits

    server.get('/customers/:uuid/limits', limits.list);
    server.put('/customers/:uuid/limits/:dc/:dataset', limits.put);
    server.del('/customers/:uuid/limits/:dc/:dataset', limits.del);

    // FIXME: Replace with proper backoff
    // hack to get backoff+retry
    var _attempt = 0;
    var _sleep = 1000;
    var _try = 10;

    function initError(err) {
        if (err) {
            process.stderr.write('Unable to bind to UFDS: ');
            process.stderr.write(err.stack);
            process.stderr.write('\n');
            if (++_attempt <= _try) {
                setTimeout(connect, _sleep);
            } else {
                process.stderr.write('Giving up trying to connect to UFDS\n');
                process.exit(1);
            }
        }
    }

    ///-- Start up

    function connect() {
        client = ldap.createClient({
            url: config.ufds,
            log: log
        });
        client.on('error', initError);
        client.on('connect', function () {
            client.bind(config.rootDN, config.rootPassword, function (err) {
                client.removeListener('error', initError);
                if (err) {
                    console.error('Unable to bind to UFDS: ' + err.stack);
                    process.exit(1);
                }
                server.listen(config.port, function () {
                    console.error('CAPI listening on port %d', config.port);
                });
            });
        });
    }

    return {
        server: server,
        client: client,
        log: log,
        connect: connect
    };
}

function processConfig() {

    var _config;
    var parsed = nopt(opts, shortOpts, process.argv, 2);
    var file = parsed.file || __dirname + '/etc/ufds.config.json';

    if (parsed.help) {
        usage(0);
    }

    try {

        _config = JSON.parse(fs.readFileSync(file, 'utf8'));

    } catch (e) {
        console.error('Unable to parse configuration file: ' + e.message);
        process.exit(1);
    }

    if (!_config.ufds) {
        _config.ufds = 'ldaps://127.0.0.1';
        if (_config.port) {
            _config.ufds += ':' + parsed.port;
        }
    }

    if (parsed.debug) {
        _config.logLevel = 'debug';
    }

    if (!_config.logLevel) {
        _config.logLevel = 'info';
    }

    // We need to override config.port here, b/c the port in config is for LDAP
    _config.port = (process.env.PORT) ? process.env.PORT : 8080;

    return _config;
}

var cfg = processConfig();

var capi = CAPI(cfg);

capi.connect();

// Increase/decrease loggers levels using SIGUSR2/SIGUSR1:
var sigyan = require('sigyan');
sigyan.add([capi.log]);
<commit_msg>CAPI-226: Erroneusly removed res.sendError on previous commit<commit_after>// Copyright 2013 Joyent, Inc.  All rights reserved.

var assert = require('assert');
var fs = require('fs');
var http = require('http');
var path = require('path');
var sprintf = require('util').format;

var Logger = require('bunyan');
var ldap = require('ldapjs');
var nopt = require('nopt');
var restify = require('restify');
var uuid = require('node-uuid');

var customers = require('./capi/customers');
var keys = require('./capi/keys');
var login = require('./capi/login');
var limits = require('./capi/limits');
var metadata = require('./capi/metadata');
var utils = require('./capi/util');

function entitify(str) {
    str = '' + str;
    /* BEGIN JSSTYLED */
    str = str.replace(/&/g, '&').replace(/</g, '<')
        .replace(/>/g, '>').replace(/'/g, ''')
        .replace(/"/g, '"');
    /* END JSSTYLED */
    return str;
}

function toXml(elm) {
    var xml = '';
    if (Array.isArray(elm)) {
        xml += elm.map(function (e) {
            return (toXml(e));
        }).join('\n');
    } else if (typeof (elm) === 'object' && Object.keys(elm)) {
        Object.keys(elm).forEach(function (k) {
            if (elm[k]) {
                xml += sprintf('<%s>%s</%s>', k, toXml(elm[k]), k);
            }
        });
    } else {
        xml += entitify(elm);
    }
    return (xml);
}

///--- Globals

var opts = {
    'certificate': String,
    'config': String,
    'debug': Boolean,
    'file': String,
    'key': String,
    'port': Number,
    'ufds': String,
    'help': Boolean
};

var shortOpts = {
    'c': ['--certiifcate'],
    'd': ['--debug'],
    'f': ['--file'],
    'k': ['--key'],
    'p': ['--port'],
    'h': ['--help'],
    'u': ['--ufds']
};

///--- Helpers

function usage(code, message) {
    var _opts = '';
    Object.keys(shortOpts).forEach(function (k) {
        var longOpt = shortOpts[k][0].replace('--', '');
        var type = opts[longOpt].name || 'string';
        if (type && type === 'boolean') type = '';
        type = type.toLowerCase();

        _opts += ' [--' + longOpt + ' ' + type + ']';
    });
    _opts += ' dn attribute value(s)';

    var msg = (message ? message + '\n' : '') +
        'usage: ' + path.basename(process.argv[1]) + _opts;

    process.stderr.write(msg + '\n');
    process.exit(code);
}

///--- CAPI shim

function CAPI(config) {

    var log = new Logger({
        name: 'capi',
        level: config.logLevel,
        stream: process.stdout,
        serializers: restify.bunyan.serializers
    });

    var client;

    function before(req, res, next) {
        req.ldap = client;
        res.sendError = function sendError(errors) {
            if (req.xml) {
                errors = { errors: { error: errors } };
            } else {
                errors = { errors: errors };
            }
            log.warn({errors: errors}, 'These are the errors');
            res.send(409, errors);
        };
        return next();
    }

    var server = restify.createServer({
        name: 'capi',
        log: log,
        formatters: {
            'application/xml': function formatXml(req, res, body) {
                var o;
                var xml = '<?xml version="1.0" encoding="utf-8"?>\n';
                if (body instanceof Error) {
                    o = { errors: { error: body.body } };
                } else if (Buffer.isBuffer(body)) {
                    o = JSON.parse(body.toString('base64'));
                } else {
                    o = body;
                }

                xml += toXml(o);

                res.setHeader('Content-Length', Buffer.byteLength(xml));
                return xml;
            }
        }
    });

    server.use(restify.acceptParser(server.acceptable));
    server.use(restify.dateParser());
    server.use(restify.queryParser());
    server.use(restify.bodyParser());
    server.use(restify.fullResponse());

    server.on('after', restify.auditLogger({log: log}));

    server.use(before);

    // Show
    server.get('/customers', customers.list);
    server.head('/customers', customers.list);

    // CreateCustomer
    server.post('/customers', customers.create);

    // UpdateCustomer
    server.put('/customers/:uuid', before, utils.loadCustomer,
            customers.update, utils.loadCustomer,
            function respond(req, res, next) {
                var customer = utils.translateCustomer(
                    req.customer.toObject());
                res.send(200, customer);
                return next();
            });

    // GetCustomer
    server.get('/customers/:uuid', utils.loadCustomer, customers.get);
    server.head('/customers/:uuid', utils.loadCustomer, customers.get);

    // DeleteCustomer
    server.del('/customers/:uuid', utils.loadCustomer, customers.del);

    // GetSalt
    server.get('/login/:login', login.getSalt);
    server.head('/login/:login', login.getSalt);

    // Login
    server.post('/login', login.login);

    // ForgotPassword
    server.post('/auth/forgot_password', login.forgotPassword);

    server.use(utils.loadCustomer);

    /// Metadata
    server.get('/auth/customers/:uuid/metadata/:appkey', metadata.list);
    server.put('/auth/customers/:uuid/metadata/:appkey/:key', metadata.put);
    server.get('/auth/customers/:uuid/metadata/:appkey/:key', metadata.get);
    server.del('/auth/customers/:uuid/metadata/:appkey/:key', metadata.del);

    /// Keys
    server.post('/customers/:uuid/keys', keys.post);
    server.get('/customers/:uuid/keys', keys.list);
    server.get('/customers/:uuid/keys/:id', keys.get);
    server.put('/customers/:uuid/keys/:id', keys.put);
    server.del('/customers/:uuid/keys/:id', keys.del);

    /// Smartlogin

    server.post('/customers/:uuid/ssh_sessions', keys.smartlogin);

    /// Limits

    server.get('/customers/:uuid/limits', limits.list);
    server.put('/customers/:uuid/limits/:dc/:dataset', limits.put);
    server.del('/customers/:uuid/limits/:dc/:dataset', limits.del);

    // FIXME: Replace with proper backoff
    // hack to get backoff+retry
    var _attempt = 0;
    var _sleep = 1000;
    var _try = 10;

    function initError(err) {
        if (err) {
            process.stderr.write('Unable to bind to UFDS: ');
            process.stderr.write(err.stack);
            process.stderr.write('\n');
            if (++_attempt <= _try) {
                setTimeout(connect, _sleep);
            } else {
                process.stderr.write('Giving up trying to connect to UFDS\n');
                process.exit(1);
            }
        }
    }

    ///-- Start up

    function connect() {
        client = ldap.createClient({
            url: config.ufds,
            log: log
        });
        client.on('error', initError);
        client.on('connect', function () {
            client.bind(config.rootDN, config.rootPassword, function (err) {
                client.removeListener('error', initError);
                if (err) {
                    console.error('Unable to bind to UFDS: ' + err.stack);
                    process.exit(1);
                }
                server.listen(config.port, function () {
                    console.error('CAPI listening on port %d', config.port);
                });
            });
        });
    }

    return {
        server: server,
        client: client,
        log: log,
        connect: connect
    };
}

function processConfig() {

    var _config;
    var parsed = nopt(opts, shortOpts, process.argv, 2);
    var file = parsed.file || __dirname + '/etc/ufds.config.json';

    if (parsed.help) {
        usage(0);
    }

    try {

        _config = JSON.parse(fs.readFileSync(file, 'utf8'));

    } catch (e) {
        console.error('Unable to parse configuration file: ' + e.message);
        process.exit(1);
    }

    if (!_config.ufds) {
        _config.ufds = 'ldaps://127.0.0.1';
        if (_config.port) {
            _config.ufds += ':' + parsed.port;
        }
    }

    if (parsed.debug) {
        _config.logLevel = 'debug';
    }

    if (!_config.logLevel) {
        _config.logLevel = 'info';
    }

    // We need to override config.port here, b/c the port in config is for LDAP
    _config.port = (process.env.PORT) ? process.env.PORT : 8080;

    return _config;
}

var cfg = processConfig();

var capi = CAPI(cfg);

capi.connect();

// Increase/decrease loggers levels using SIGUSR2/SIGUSR1:
var sigyan = require('sigyan');
sigyan.add([capi.log]);
<|endoftext|>


<commit_before>import R from 'ramda';

export default {
  roll: (bot, msg, suffix) => {
    let times = suffix.split(' ')[0];
    let sides = suffix.split(' ')[1];

    if (!times) times = 1;
    if (!sides) sides = 6;

    let total = 0;
    let msg_array = R.map(num => {
      let number = Math.floor(Math.random() * sides) + 1;
      total += number;
      return number;
    }, R.range(0, Number(times)));

    let average = total / times;

    if (isNaN(times) || isNaN(sides)) {
      return bot.sendMessage(msg.channel, `${msg.author} rolled ${suffix}\nUsage: **\`!roll\`** \`times\` \`sides\``);
    }

    let return_next = `${msg.author} rolled a ${sides} sided dice ${times} times for a total of ${total} (average: ${average}):\n${msg_array}`;
    if (return_next.length >= 1999) {
      return bot.sendMessage(msg.channel, `${msg.author} I\'m too high to calculate that high number.`);
    }

    bot.sendMessage(msg.channel, return_next);
  }
};
<commit_msg>Added a safeguard regarding very big numbers to !roll<commit_after>import R from 'ramda';

export default {
  roll: (bot, msg, suffix) => {
    let times = suffix.split(' ')[0];
    let sides = suffix.split(' ')[1];

    if (times > 1000 || sides > 1000000) {
      return bot.sendMessage(msg.channel, `${msg.author} I\'m too high to calculate that high number.`);
    }

    if (!times) times = 1;
    if (!sides) sides = 6;

    let total = 0;
    let msg_array = R.map(num => {
      let number = Math.floor(Math.random() * sides) + 1;
      total += number;
      return number;
    }, R.range(0, Number(times)));

    let average = total / times;

    if (isNaN(times) || isNaN(sides)) {
      return bot.sendMessage(msg.channel, `${msg.author} rolled ${suffix}\nUsage: **\`!roll\`** \`times\` \`sides\``);
    }

    let return_next = `${msg.author} rolled a ${sides} sided dice ${times} times for a total of ${total} (average: ${average}):\n${msg_array}`;
    if (return_next.length >= 1999) {
      return bot.sendMessage(msg.channel, `${msg.author} I\'m too high to calculate that high number.`);
    }

    bot.sendMessage(msg.channel, return_next);
  }
};
<|endoftext|>


<commit_before>define(["dojo/has", "put-selector/put", "dojo/_base/declare", "dojo/on", "./Editor", "./List", "dojo/_base/sniff"], function(has, put, declare, listen, Editor, List){
	var contentBoxSizing = has("ie") < 8 && !has("quirks");

	return declare([List], {
		columns: null,
		// summary:
		//		This indicates that focus is at the cell level. This may be set to false to cause
		//		focus to be at the row level, which is useful if you want only want row-level
		//		navigation.
		cellNavigation: true,
		tabableHeader: true,
		column: function(target){
			// summary:
			//		Get the column object by node, or event, or a columnId
			if(typeof target == "string"){
				return this.columns[target];
			}else{
				return this.cell(target).column;
			}
		},
		cell: function(target, columnId){
			// summary:
			//		Get the cell object by node, or event, id, plus a columnId
			if(target.target && target.target.nodeType){
				// event
				target = target.target;
			}
			var element;
			if(target.nodeType){
				var object;
				do{
					if(this._rowIdToObject[target.id]){
						break;
					}
					var colId = target.columnId;
					if(colId){
						columnId = colId;
						element = target;
						break;
					}
					target = target.parentNode;
				}while(target && target != this.domNode);
			}
			if(!element && columnId){
				var row = this.row(target),
					rowElement = row.element;
				if(rowElement){
					var elements = rowElement.getElementsByTagName("td");
					for(var i = 0; i < elements.length; i++){
						if(elements[i].columnId == columnId){
							element = elements[i];
							break;
						}
					}
				}
			}
			if(target != null){
				return {
					row: row || this.row(target),
					column: columnId && this.column(columnId),
					element: element
				};
			}
		},
		_columnsCss: function(rule){
			// This is an attempt at integration with xstyle, will probably change
			rule.fullSelector = function(){
				return this.parent.fullSelector() + " .dgrid-cell";
			};
			for(var i = 0;i < rule.children.length;i++){
				var child = rule.children[i];
				child.field = child.className = child.selector.substring(1);
			}
			return rule.children;
		},
		createRowCells: function(tag, each){
			// summary:
			//		Generates the grid for each row (used by renderHeader and and renderRow)
			var tr, row = put("table.dgrid-row-table[role=presentation]"),
				cellNavigation = this.cellNavigation;
			if(has("ie") < 9 || has("quirks")){
				// this is the only browser that needs a tbody
				var tbody = put(row, "tbody");
			}else{
				var tbody = row;
			}
			var subRows = this.subRows;
			for(var si = 0, sl = subRows.length; si < sl; si++){
				var subRow = subRows[si];
				if(sl == 1 && !has("ie")){
					// shortcut for modern browsers
					tr = tbody;
				}else{
					tr = put(tbody, "tr");
				}
				for(var i = 0, l = subRow.length; i < l; i++){
					// iterate through the columns
					var column = subRow[i];
					var id = column.id;
					var extraClassName = column.className || (column.field && "field-" + column.field);
					var cell = put(tag + ".dgrid-cell.dgrid-cell-padding.column-" + id + (extraClassName ? '.' + extraClassName : ''));
					cell.columnId = id;
					if(contentBoxSizing){
						// The browser (IE7-) does not support box-sizing: border-box, so we emulate it with a padding div
						var innerCell = put(cell, "!dgrid-cell-padding div.dgrid-cell-padding");// remove the dgrid-cell-padding, and create a child with that class
						cell.contents = innerCell;
					}else{
						innerCell = cell;
					}
					var colSpan = column.colSpan;
					if(colSpan){
						cell.colSpan = colSpan;
					}
					var rowSpan = column.rowSpan;
					if(rowSpan){
						cell.rowSpan = rowSpan;
					}
					each(innerCell, column);
					// add the td to the tr at the end for better performance
					tr.appendChild(cell);
				}
			}
			return row;
		},
		left: function(cell, steps){
			return this.cell(this._move(cell, -(steps || 1), "dgrid-cell"));
		},
		right: function(cell, steps){
			return this.cell(this._move(cell, steps || 1, "dgrid-cell"));
		},
		renderRow: function(object, options){
			var row = this.createRowCells("td", function(td, column){
				var data = object;
				// we support the field, get, and formatter properties like the DataGrid
				if(column.get){
					// FIXME: signature of get is (inRowIndex, inItem)
					// Is it possible for us to produce row index here for first arg?
					data = column.get(0, object);
				}else if("field" in column && column.field != "_item"){
					data = data[column.field];
				}
				if(column.formatter){
					td.innerHTML = column.formatter(data);
				}else if(column.renderCell){
					// A column can provide a renderCell method to do its own DOM manipulation,
					// event handling, etc.
					var subNode = column.renderCell(object, data, td, options);
					if(subNode && subNode.nodeType){
						td.appendChild(subNode);
					}
				}else if(data != null){
					td.appendChild(document.createTextNode(data));
				}
			});
			// row gets a wrapper div for a couple reasons:
			//	1. So that one can set a fixed height on rows (heights can't be set on
's AFAICT)
			// 2. So that outline style can be set on a row when it is focused, and Safari's outline style is broken on

			return put("div[role=gridcell]>", row);
		},
		renderHeader: function(headerNode){
			// summary:
			//		Setup the headers for the grid
			var grid = this;
			var columns = this.columns;
			var row = this.createRowCells("th[role=columnheader]", function(th, column){
				var contentNode = th;
				if(contentBoxSizing){
					// we're interested in the th, but we're passed the inner div
					th = th.parentNode;
				}
				column.grid = grid;
				var field = column.field;
				if(field){
					th.field = field;
				}
				// allow for custom header content manipulation
				if(column.renderHeaderCell){
					column.renderHeaderCell(contentNode);
				}else if(column.label || column.field){
					contentNode.appendChild(document.createTextNode(column.label || column.field));
				}
				if(column.sortable !== false){
					th.sortable = true;
					th.className += " dgrid-sortable";
				}
			});
			this._rowIdToObject[row.id = this.id + "-header"] = this.columns;
			//put(headerNode, "div.dgrid-header-columns>", row, ".dgrid-row<+div.dgrid-header-scroll.ui-widget-header");
			//row = put("div.dgrid-row[role=columnheader]>", row);
			headerNode.appendChild(row);
			var lastSortedArrow, arrowParent;
			// if it columns are sortable, resort on clicks
			listen(row, "click,keydown", function(event){
				if(event.type == "click" || event.keyCode == 32){
					var
						target = event.target,
						field, descending, parentNode;
					do{
						if(target.sortable){
							field = target.field || target.columnId;
							target = target.contents || target;
							// re-sort
							descending = grid.sortOrder && grid.sortOrder[0].attribute == field && !grid.sortOrder[0].descending;
							/*var sortTarget = target.firstChild;
							if(sortTarget.firstChild){
								sortTarget = sortTarget.firstChild;
								arrowParent = lastSortedArrow ? lastSortedArrow.parentNode : null;
								if(contentBoxSizing && sortTarget.firstChild){
									sortTarget = sortTarget.firstChild;
									arrowParent = lastSortedArrow ? arrowParent.parentNode : null;
								}
							}else{
								arrowParent = lastSortedArrow;
							}*/
							if(lastSortedArrow){
								put(lastSortedArrow, "<!dgrid-sort-up!dgrid-sort-down"); // remove the sort classes from parent node
								put(lastSortedArrow, "!"); // destroy the lastSortedArrow node
							}
							lastSortedArrow = put(target.firstChild, "-div.dgrid-sort-arrow.ui-icon[role=presentation]");
							lastSortedArrow.innerHTML = " ";
							put(target, descending ? ".dgrid-sort-down" : ".dgrid-sort-up");
							grid.resize();
							return grid.sort(field, descending);
						}
					}while((target = target.parentNode) && target != headerNode);
				}
			});
		},
		styleColumn: function(colId, css){
			// summary:
			//		Changes the column width by creating a dynamic stylesheet

			// now add a rule to style the column
			return this.addCssRule("#" + this.domNode.id + ' .column-' + colId, css);
		},
		_configColumns: function(prefix, rowColumns){
			// configure the current column
			var subRow = [];
			var isArray = rowColumns instanceof Array;
			for(var columnId in rowColumns){
				var column = rowColumns[columnId];
				if(typeof column == "string"){
					rowColumns[columnId] = column = {label:column};
				}
				if(!isArray && !column.field){
					column.field = columnId;
				}
				columnId = column.id = column.id || (isNaN(columnId) ? columnId : (prefix + columnId));
				if(prefix){
					this.columns[columnId] = column;
				}
				subRow.push(column); // make sure it can be iterated on
			}
			return isArray ? rowColumns : subRow;
		},
		configStructure: function(){
			// configure the columns and subRows
			var subRows = this.subRows;
			if(subRows){
				// we have subRows, but no columns yet, need to create the columns
				this.columns = {};
				for(var i = 0; i < subRows.length; i++){
					subRows[i] = this._configColumns(i + '-', subRows[i]);
				}
			}else{
				this.subRows = [this._configColumns("", this.columns)];
			}
		}
	});
});
<commit_msg>Undo errant changes<commit_after>define(["dojo/has", "put-selector/put", "dojo/_base/declare", "dojo/on", "./Editor", "./List", "dojo/_base/sniff"], function(has, put, declare, listen, Editor, List){
	var contentBoxSizing = has("ie") < 8 && !has("quirks");

	return declare([List], {
		columns: null,
		// summary:
		//		This indicates that focus is at the cell level. This may be set to false to cause
		//		focus to be at the row level, which is useful if you want only want row-level
		//		navigation.
		cellNavigation: true,
		tabableHeader: true,
		column: function(target){
			// summary:
			//		Get the column object by node, or event, or a columnId
			if(typeof target == "string"){
				return this.columns[target];
			}else{
				return this.cell(target).column;
			}
		},
		listType: "grid",
		cell: function(target, columnId){
			// summary:
			//		Get the cell object by node, or event, id, plus a columnId
			if(target.target && target.target.nodeType){
				// event
				target = target.target;
			}
			var element;
			if(target.nodeType){
				var object;
				do{
					if(this._rowIdToObject[target.id]){
						break;
					}
					var colId = target.columnId;
					if(colId){
						columnId = colId;
						element = target;
						break;
					}
					target = target.parentNode;
				}while(target && target != this.domNode);
			}
			if(!element && columnId){
				var row = this.row(target),
					rowElement = row.element;
				if(rowElement){
					var elements = rowElement.getElementsByTagName("td");
					for(var i = 0; i < elements.length; i++){
						if(elements[i].columnId == columnId){
							element = elements[i];
							break;
						}
					}
				}
			}
			if(target != null){
				return {
					row: row || this.row(target),
					column: columnId && this.column(columnId),
					element: element
				};
			}
		},
		_columnsCss: function(rule){
			// This is an attempt at integration with xstyle, will probably change
			rule.fullSelector = function(){
				return this.parent.fullSelector() + " .dgrid-cell";
			};
			for(var i = 0;i < rule.children.length;i++){
				var child = rule.children[i];
				child.field = child.className = child.selector.substring(1);
			}
			return rule.children;
		},
		createRowCells: function(tag, each){
			// summary:
			//		Generates the grid for each row (used by renderHeader and and renderRow)
			var tr, row = put("table.dgrid-row-table[role=presentation]"),
				cellNavigation = this.cellNavigation;
			if(has("ie") < 9 || has("quirks")){
				// this is the only browser that needs a tbody
				var tbody = put(row, "tbody");
			}else{
				var tbody = row;
			}
			var subRows = this.subRows;
			for(var si = 0, sl = subRows.length; si < sl; si++){
				var subRow = subRows[si];
				if(sl == 1 && !has("ie")){
					// shortcut for modern browsers
					tr = tbody;
				}else{
					tr = put(tbody, "tr");
				}
				for(var i = 0, l = subRow.length; i < l; i++){
					// iterate through the columns
					var column = subRow[i];
					var id = column.id;
					var extraClassName = column.className || (column.field && "field-" + column.field);
					var cell = put(tag + ".dgrid-cell.dgrid-cell-padding.column-" + id + (extraClassName ? '.' + extraClassName : ''));
					cell.columnId = id;
					if(contentBoxSizing){
						// The browser (IE7-) does not support box-sizing: border-box, so we emulate it with a padding div
						var innerCell = put(cell, "!dgrid-cell-padding div.dgrid-cell-padding");// remove the dgrid-cell-padding, and create a child with that class
						cell.contents = innerCell;
					}else{
						innerCell = cell;
					}
					var colSpan = column.colSpan;
					if(colSpan){
						cell.colSpan = colSpan;
					}
					var rowSpan = column.rowSpan;
					if(rowSpan){
						cell.rowSpan = rowSpan;
					}
					each(innerCell, column);
					// add the td to the tr at the end for better performance
					tr.appendChild(cell);
				}
			}
			return row;
		},
		left: function(cell, steps){
			return this.cell(this._move(cell, -(steps || 1), "dgrid-cell"));
		},
		right: function(cell, steps){
			return this.cell(this._move(cell, steps || 1, "dgrid-cell"));
		},
		renderRow: function(object, options){
			var row = this.createRowCells("td", function(td, column){
				var data = object;
				// we support the field, get, and formatter properties like the DataGrid
				if(column.get){
					// FIXME: signature of get is (inRowIndex, inItem)
					// Is it possible for us to produce row index here for first arg?
					data = column.get(0, object);
				}else if("field" in column && column.field != "_item"){
					data = data[column.field];
				}
				if(column.formatter){
					td.innerHTML = column.formatter(data);
				}else if(column.renderCell){
					// A column can provide a renderCell method to do its own DOM manipulation,
					// event handling, etc.
					var subNode = column.renderCell(object, data, td, options);
					if(subNode && subNode.nodeType){
						td.appendChild(subNode);
					}
				}else if(data != null){
					td.appendChild(document.createTextNode(data));
				}
			});
			// row gets a wrapper div for a couple reasons:
			//	1. So that one can set a fixed height on rows (heights can't be set on
's AFAICT)
			// 2. So that outline style can be set on a row when it is focused, and Safari's outline style is broken on

			return put("div[role=gridcell]>", row);
		},
		renderHeader: function(headerNode){
			// summary:
			//		Setup the headers for the grid
			var grid = this;
			var columns = this.columns;
			var row = this.createRowCells("th[role=columnheader]", function(th, column){
				var contentNode = th;
				if(contentBoxSizing){
					// we're interested in the th, but we're passed the inner div
					th = th.parentNode;
				}
				column.grid = grid;
				var field = column.field;
				if(field){
					th.field = field;
				}
				// allow for custom header content manipulation
				if(column.renderHeaderCell){
					column.renderHeaderCell(contentNode);
				}else if(column.label || column.field){
					contentNode.appendChild(document.createTextNode(column.label || column.field));
				}
				if(column.sortable !== false){
					th.sortable = true;
					th.className += " dgrid-sortable";
				}
			});
			this._rowIdToObject[row.id = this.id + "-header"] = this.columns;
			//put(headerNode, "div.dgrid-header-columns>", row, ".dgrid-row<+div.dgrid-header-scroll.ui-widget-header");
			//row = put("div.dgrid-row[role=columnheader]>", row);
			headerNode.appendChild(row);
			var lastSortedArrow;
			// if it columns are sortable, resort on clicks
			listen(row, "click,keydown", function(event){
				if(event.type == "click" || event.keyCode == 32){
					var
						target = event.target,
						field, descending, parentNode;
					do{
						if(target.sortable){
							field = target.field || target.columnId;
							target = target.contents || target;
							// re-sort
							descending = grid.sortOrder && grid.sortOrder[0].attribute == field && !grid.sortOrder[0].descending;
							if(lastSortedArrow){
								put(lastSortedArrow, "<!dgrid-sort-up!dgrid-sort-down"); // remove the sort classes from parent node
								put(lastSortedArrow, "!"); // destroy the lastSortedArrow node
							}
							lastSortedArrow = put(target.firstChild, "-div.dgrid-sort-arrow.ui-icon[role=presentation]");
							lastSortedArrow.innerHTML = " ";
							put(target, descending ? ".dgrid-sort-down" : ".dgrid-sort-up");
							grid.resize();
							return grid.sort(field, descending);
						}
					}while((target = target.parentNode) && target != headerNode);
				}
			});
		},
		styleColumn: function(colId, css){
			// summary:
			//		Changes the column width by creating a dynamic stylesheet

			// now add a rule to style the column
			return this.addCssRule("#" + this.domNode.id + ' .column-' + colId, css);
		},
		_configColumns: function(prefix, rowColumns){
			// configure the current column
			var subRow = [];
			var isArray = rowColumns instanceof Array;
			for(var columnId in rowColumns){
				var column = rowColumns[columnId];
				if(typeof column == "string"){
					rowColumns[columnId] = column = {label:column};
				}
				if(!isArray && !column.field){
					column.field = columnId;
				}
				columnId = column.id = column.id || (isNaN(columnId) ? columnId : (prefix + columnId));
				if(prefix){
					this.columns[columnId] = column;
				}
				subRow.push(column); // make sure it can be iterated on
			}
			return isArray ? rowColumns : subRow;
		},
		configStructure: function(){
			// configure the columns and subRows
			var subRows = this.subRows;
			if(subRows){
				// we have subRows, but no columns yet, need to create the columns
				this.columns = {};
				for(var i = 0; i < subRows.length; i++){
					subRows[i] = this._configColumns(i + '-', subRows[i]);
				}
			}else{
				this.subRows = [this._configColumns("", this.columns)];
			}
		}
	});
});
<|endoftext|>