<commit_before>(function () {
  'use strict';

  function Entity(x, y, width, height, spriteSrc, framesPosition, frameCooldown, speed, renderedWidth, renderedHeight) {
    this.init(x, y, width, height, spriteSrc, framesPosition, frameCooldown, speed, renderedWidth, renderedHeight);
  }

  Entity.prototype.init = function (x, y, width, height, spriteSrc, framesPosition, frameCooldown, speed, renderedWidth, renderedHeight) {
    this.x = x;
    this.y = y;

    this.constructor.width = width;
    this.constructor.height = height;

    this.constructor.renderedWidth = renderedWidth ? renderedWidth : width;
    this.constructor.renderedHeight = renderedHeight ? renderedHeight : height;

    this.constructor.spriteSrc = spriteSrc;
    this.constructor.framesPosition = framesPosition;
    this.constructor.frameCooldown = frameCooldown;
    this.lastFrameUpdate = Date.now();
    this.currentFrame = 0;
    if (spriteSrc) {
      this.loadSprite();
    }

    // Speed is defined as pixels per second
    this.speed = speed || 200;
  };

  Entity.prototype.loadSprite = function () {
    if (this.constructor.spriteLoaded) {
      return;
    }

    var self = this;

    this.constructor.spriteLoaded = false;
    this.constructor.sprite = new Image();

    this.constructor.sprite.src = this.constructor.spriteSrc;
    this.constructor.sprite.onload = function () {
      self.constructor.spriteLoaded = true;
    };
  };

  Entity.prototype.setPosition = function (x, y) {
    this.setX(x);
    this.setY(y);
  };

  Entity.prototype.setX = function (x) {
    this.x = x;
  };

  Entity.prototype.setY = function (y) {
    this.y = y;
  };

  Entity.prototype.render = function (context) {
    if (this.constructor.spriteLoaded) {
      context.drawImage(
        this.constructor.sprite,
        this.constructor.framesPosition[this.currentFrame][0],
        this.constructor.framesPosition[this.currentFrame][1],
        this.constructor.width,
        this.constructor.height,
        this.x,
        this.y,
        this.constructor.renderedWidth,
        this.constructor.renderedHeight);
    }
  };

  Entity.prototype.update = function (now) {
    now = now || Date.now();

    if (now - this.lastFrameUpdate > this.constructor.frameCooldown) {
      this.currentFrame += 1;
      this.lastFrameUpdate = now;
      if (this.constructor.framesPosition.length <= this.currentFrame) {
        this.currentFrame = 0;
      }
    }
  };

  Entity.prototype.isCollided = function (entity2) {
    // no collision if there's any gap
    return !(this.x + this.constructor.renderedWidth <= entity2.x ||
      this.x > entity2.x + this.constructor.renderedWidth         ||
      this.y + this.constructor.renderedHeight <= entity2.y       ||
      this.y > entity2.y + this.constructor.renderedHeight
    );
  };

  // Make Entity available globally
  window.Entity = Entity;

}());
<commit_msg>Allow children classes to define framesPosition array<commit_after>(function () {
  'use strict';

  function Entity(x, y, width, height, spriteSrc, framesPosition, frameCooldown, speed, renderedWidth, renderedHeight) {
    this.init(x, y, width, height, spriteSrc, framesPosition, frameCooldown, speed, renderedWidth, renderedHeight);
  }

  Entity.prototype.init = function (x, y, width, height, spriteSrc, framesPosition, frameCooldown, speed, renderedWidth, renderedHeight) {
    this.x = x;
    this.y = y;

    this.constructor.width = width;
    this.constructor.height = height;

    this.constructor.renderedWidth = renderedWidth ? renderedWidth : width;
    this.constructor.renderedHeight = renderedHeight ? renderedHeight : height;

    this.constructor.spriteSrc = spriteSrc;
    this.constructor.framesPosition = this.constructor.framesPosition || framesPosition;
    this.constructor.frameCooldown = frameCooldown;
    this.lastFrameUpdate = Date.now();
    this.currentFrame = 0;
    if (spriteSrc) {
      this.loadSprite();
    }

    // Speed is defined as pixels per second
    this.speed = speed || 200;
  };

  Entity.prototype.loadSprite = function () {
    if (this.constructor.spriteLoaded) {
      return;
    }

    var self = this;

    this.constructor.spriteLoaded = false;
    this.constructor.sprite = new Image();

    this.constructor.sprite.src = this.constructor.spriteSrc;
    this.constructor.sprite.onload = function () {
      self.constructor.spriteLoaded = true;
    };
  };

  Entity.prototype.setPosition = function (x, y) {
    this.setX(x);
    this.setY(y);
  };

  Entity.prototype.setX = function (x) {
    this.x = x;
  };

  Entity.prototype.setY = function (y) {
    this.y = y;
  };

  Entity.prototype.render = function (context) {
    if (this.constructor.spriteLoaded) {
      context.drawImage(
        this.constructor.sprite,
        this.constructor.framesPosition[this.currentFrame][0],
        this.constructor.framesPosition[this.currentFrame][1],
        this.constructor.width,
        this.constructor.height,
        this.x,
        this.y,
        this.constructor.renderedWidth,
        this.constructor.renderedHeight);
    }
  };

  Entity.prototype.update = function (now) {
    now = now || Date.now();

    if (now - this.lastFrameUpdate > this.constructor.frameCooldown) {
      this.currentFrame += 1;
      this.lastFrameUpdate = now;
      if (this.constructor.framesPosition.length <= this.currentFrame) {
        this.currentFrame = 0;
      }
    }
  };

  Entity.prototype.isCollided = function (entity2) {
    // no collision if there's any gap
    return !(this.x + this.constructor.renderedWidth <= entity2.x ||
      this.x > entity2.x + this.constructor.renderedWidth         ||
      this.y + this.constructor.renderedHeight <= entity2.y       ||
      this.y > entity2.y + this.constructor.renderedHeight
    );
  };

  // Make Entity available globally
  window.Entity = Entity;

}());
<|endoftext|>


<commit_before>/* **************************************************************
 *                  Synapse - Server
 * @author Marco Fernandez Pranno <mfernandezpranno@gmail.com>
 * @licence MIT
 * @link https://github.com/SynapseNetwork/Synapse-Server
 * @version 1.0
 * ************************************************************** */

"use strict";

const socketIO = require('socket.io');
const mongoose = require('mongoose');
const express = require('express');
const dbHandler = require('./db/handler.js');
const dbConfig = require('./config/database.js');

const INDEX = path.join(__dirname, 'index.html');
const env = process.env.NODE_ENV || 'development';
const wsPort = process.env.PORT || 9090;

class ChatServer {
  constructor() {
    this.userSockets = {};
  }

  start() {
    this.server = express()
                  .use((req, res) => res.sendFile(INDEX) )
                  .listen(wsPort, () => console.log(`Listening on ${ wsPort }`));
    this.io = socketIO(this.server);
    this.initDatabase();
    this.listenConnections();
  }

  initDatabase() {
    mongoose.Promise = global.Promise;
    mongoose.connect(dbConfig.url, { useMongoClient: true });
    const db = mongoose.connection;
    db.on('error', function(err) {
      console.error('DB connection error:' + err);
    });
    db.once('open', function() {
      console.log(`> Synapse Server running in [${env}].`);
      console.log('> Success connecting to database.');
      dbHandler.setAllUsersOffline();
    });
  }

  listenConnections() {
    this.io.on('connection', (socket) => {
      const username = socket.handshake.query.username;
      if(username){
        this.handleClientConnection(socket, username);
      } else {
        socket.disconnect(0);
      }
    });
  }

  saveUserSocket(userId, socket) {
    this.userSockets[userId] = socket;
  }

  handleClientConnection(socket, username) {
    dbHandler.findUser(username, (findUserError, user) => {
      if(!findUserError) {
        if(user) {
          dbHandler.setUserConnectionStatus(user, true, (connectedError) => {
            if(!connectedError) {
              console.log(`[connected] ${username}`);
              this.sendUserInitialData(user, socket);
            }
          });
        } else {
          dbHandler.saveUserUsername(username, (saveUserError, user) => {
            if(!saveUserError){
              console.log(`[connected] ${username}`);
              this.sendUserInitialData(user, socket);
            }
          });
        }
      }
    });
  }

  sendUserInitialData(user, socket) {
    let errors = false;
    dbHandler.allUsers((onUsersError, allUsers) => {
      if(!onUsersError){
        dbHandler.pendingMessages(user._id, (pendingError, pendingMessages) => {
          if(!pendingError){
            socket.emit('init-connection-msg', {
              user,
              allUsers,
              pendingMessages
            });
            this.saveUserSocket(user._id, socket);
            this.listenClientEvents(socket, user);
            this.notifyUserStatus(user, 'user-connected');
            dbHandler.clearPendingMessages(user._id, (err, res) => {
              if(err) console.log("Error clearing pending messages: ", err);
            });
          }
        })
      }
    });
  }

  notifyUserStatus(user, eventName) {
    dbHandler.onlineUsers((err, res) => {
      if (!err) {
        res.forEach(usuario => {
          if(usuario._id !== user._id) {
            this.userSockets[usuario._id].emit(eventName, user);
          }
        });
      } else {
        console.log('Error: notifyConnectedUser.onlineUsers');
      }
    });
  }

  listenClientEvents(socket, user){
    socket.on('init-chat', (data) => {
      const receiverSocket = this.userSockets[data.receiverId];
      if (receiverSocket) {
        receiverSocket.emit('init-chat', { emitterId: user._id });
      } else {
        console.log("Error: Socket not found on: init-chat.");
      }
    });

    socket.on('receive-key', data => {
      const userSocket = this.userSockets[data.userId];
      if (userSocket) {
        userSocket.emit('receive-key', data);
      }
    });

    socket.on('request-key', (data) => {
      const generatorSocket = this.userSockets[data.generatorId];
      if (generatorSocket) {
        generatorSocket.emit('request-key', data);
      }
    });

    socket.on('accept-chat', (data) => {
      dbHandler.isOnline(data.receiverId, (isOnError, isOnline) => {
        if (!isOnError) {
          if (isOnline) {
            const emitterSocket = this.userSockets[data.receiverId];
            if (emitterSocket) {
              emitterSocket.emit('accept-chat', { receiverId: data.emitterId });
            } else {
              console.log("Error: Socket not found on: accept-chat.");
            }
          }
        }
      });
    });

    socket.on('chat-msg', (data) => {
      const { receiverId, emitterId } = data.message;
      const { message } = data;
      dbHandler.isOnline(receiverId, (isOnError, isOnline) => {
        if (!isOnError) {
          if (isOnline) {
            const receiverSocket = this.userSockets[receiverId];
            if (receiverSocket) {
              receiverSocket.emit('chat-msg', {
                message
              });
            } else {
              console.log("Error: Socket not found on: accept-chat.");
            }
          } else {
            // TODO: Fix this.
            // dbHandler.savePendingMessage(receiverId, message);
          }
        }
      });
    });

    socket.on('disconnect', () => {
      dbHandler.setUserConnectionStatus(user, false, (err) => {
        if(!err){
          console.log(`[disconnected] ${user.username}`);
          this.notifyUserStatus(user, 'user-disconnected');
        } else {
          console.log(`[disconnected] ${user.username}`);
        }
      });
    });

  }
}

module.exports = ChatServer;
<commit_msg>Closes #15<commit_after>/* **************************************************************
 *                  Synapse - Server
 * @author Marco Fernandez Pranno <mfernandezpranno@gmail.com>
 * @licence MIT
 * @link https://github.com/SynapseNetwork/Synapse-Server
 * @version 1.0
 * ************************************************************** */

"use strict";

const socketIO = require('socket.io');
const mongoose = require('mongoose');
const express = require('express');
const path = require('path');

const dbHandler = require('./db/handler.js');
const dbConfig = require('./config/database.js');

const INDEX = path.join(__dirname, 'index.html');
const env = process.env.NODE_ENV || 'development';
const wsPort = process.env.PORT || 9090;

class ChatServer {
  constructor() {
    this.userSockets = {};
  }

  start() {
    this.server = express()
                  .use((req, res) => res.sendFile(INDEX) )
                  .listen(wsPort, () => console.log(`Listening on ${ wsPort }`));
    this.io = socketIO(this.server);
    this.initDatabase();
    this.listenConnections();
  }

  initDatabase() {
    mongoose.Promise = global.Promise;
    mongoose.connect(dbConfig.url, { useMongoClient: true });
    const db = mongoose.connection;
    db.on('error', function(err) {
      console.error('DB connection error:' + err);
    });
    db.once('open', function() {
      console.log(`> Synapse Server running in [${env}].`);
      console.log('> Success connecting to database.');
      dbHandler.setAllUsersOffline();
    });
  }

  listenConnections() {
    this.io.on('connection', (socket) => {
      const username = socket.handshake.query.username;
      if(username){
        this.handleClientConnection(socket, username);
      } else {
        socket.disconnect(0);
      }
    });
  }

  saveUserSocket(userId, socket) {
    this.userSockets[userId] = socket;
  }

  handleClientConnection(socket, username) {
    dbHandler.findUser(username, (findUserError, user) => {
      if(!findUserError) {
        if(user) {
          dbHandler.setUserConnectionStatus(user, true, (connectedError) => {
            if(!connectedError) {
              console.log(`[connected] ${username}`);
              this.sendUserInitialData(user, socket);
            }
          });
        } else {
          dbHandler.saveUserUsername(username, (saveUserError, user) => {
            if(!saveUserError){
              console.log(`[connected] ${username}`);
              this.sendUserInitialData(user, socket);
            }
          });
        }
      }
    });
  }

  sendUserInitialData(user, socket) {
    let errors = false;
    dbHandler.allUsers((onUsersError, allUsers) => {
      if(!onUsersError){
        dbHandler.pendingMessages(user._id, (pendingError, pendingMessages) => {
          if(!pendingError){
            socket.emit('init-connection-msg', {
              user,
              allUsers,
              pendingMessages
            });
            this.saveUserSocket(user._id, socket);
            this.listenClientEvents(socket, user);
            this.notifyUserStatus(user, 'user-connected');
            dbHandler.clearPendingMessages(user._id, (err, res) => {
              if(err) console.log("Error clearing pending messages: ", err);
            });
          }
        })
      }
    });
  }

  notifyUserStatus(user, eventName) {
    dbHandler.onlineUsers((err, res) => {
      if (!err) {
        res.forEach(usuario => {
          if(usuario._id !== user._id) {
            this.userSockets[usuario._id].emit(eventName, user);
          }
        });
      } else {
        console.log('Error: notifyConnectedUser.onlineUsers');
      }
    });
  }

  listenClientEvents(socket, user){
    socket.on('init-chat', (data) => {
      const receiverSocket = this.userSockets[data.receiverId];
      if (receiverSocket) {
        receiverSocket.emit('init-chat', { emitterId: user._id });
      } else {
        console.log("Error: Socket not found on: init-chat.");
      }
    });

    socket.on('receive-key', data => {
      const userSocket = this.userSockets[data.userId];
      if (userSocket) {
        userSocket.emit('receive-key', data);
      }
    });

    socket.on('request-key', (data) => {
      const generatorSocket = this.userSockets[data.generatorId];
      if (generatorSocket) {
        generatorSocket.emit('request-key', data);
      }
    });

    socket.on('accept-chat', (data) => {
      dbHandler.isOnline(data.receiverId, (isOnError, isOnline) => {
        if (!isOnError) {
          if (isOnline) {
            const emitterSocket = this.userSockets[data.receiverId];
            if (emitterSocket) {
              emitterSocket.emit('accept-chat', { receiverId: data.emitterId });
            } else {
              console.log("Error: Socket not found on: accept-chat.");
            }
          }
        }
      });
    });

    socket.on('chat-msg', (data) => {
      const { receiverId, emitterId } = data.message;
      const { message } = data;
      dbHandler.isOnline(receiverId, (isOnError, isOnline) => {
        if (!isOnError) {
          if (isOnline) {
            const receiverSocket = this.userSockets[receiverId];
            if (receiverSocket) {
              receiverSocket.emit('chat-msg', {
                message
              });
            } else {
              console.log("Error: Socket not found on: accept-chat.");
            }
          } else {
            // TODO: Fix this.
            // dbHandler.savePendingMessage(receiverId, message);
          }
        }
      });
    });

    socket.on('disconnect', () => {
      dbHandler.setUserConnectionStatus(user, false, (err) => {
        if(!err){
          console.log(`[disconnected] ${user.username}`);
          this.notifyUserStatus(user, 'user-disconnected');
        } else {
          console.log(`[disconnected] ${user.username}`);
        }
      });
    });

  }
}

module.exports = ChatServer;
<|endoftext|>


<commit_before>define('Mobile/SalesLogix/Views/Contact/Edit', [
    'dojo/_base/declare',
    'Mobile/SalesLogix/Format',
    'Mobile/SalesLogix/Template',
    'Mobile/SalesLogix/Validator',
    'Sage/Platform/Mobile/Edit',
    'Sage/Platform/Mobile/Utility'
], function(
    declare,
    format,
    template,
    validator,
    Edit,
    utility
) {

    return declare('Mobile.SalesLogix.Views.Contact.Edit', [Edit], {
        //Localization
        titleText: 'Contact',
        nameText: 'name',
        workText: 'phone',
        mobileText: 'mobile',
        emailText: 'email',
        webText: 'web',
        acctMgrText: 'acct mgr',
        accountNameText: 'account',
        homePhoneText: 'home phone',
        faxText: 'fax',
        addressText: 'address',
        contactTitleText: 'title',
        titleTitleText: 'Title',
        addressTitleText: 'Address',
        ownerText: 'owner',
        cuisinePreferenceText: 'cuisine',
        cuisinePreferenceTitleText: 'Cuisine',

        //View Properties
        entityName: 'Contact',
        id: 'contact_edit',
        insertSecurity: 'Entities/Contact/Add',
        updateSecurity: 'Entities/Contact/Edit',
        querySelect: [
            'Account/AccountName',
            'AccountManager/UserInfo/FirstName',
            'AccountManager/UserInfo/LastName',
            'AccountName',
            'Address/*',
            'CuisinePreference',
            'CreateDate',
            'CreateUser',
            'Email',
            'Fax',
            'FirstName',
            'HomePhone',
            'LastName',
            'MiddleName',
            'Mobile',
            'NameLF',
            'Owner/OwnerDescription',
            'Prefix',
            'Suffix',
            'Title',
            'WebAddress',
            'WorkPhone'
        ],
        resourceKind: 'contacts',

        startup: function() {
            this.inherited(arguments);
            this.connect(this.fields['Account'], 'onChange', this.onAccountChange);
        },
        onAccountChange: function(value, field) {
            if (value && value.text)
                this.fields['AccountName'].setValue(value.text);
        },
        applyContext: function() {
            var found = App.queryNavigationContext(function(o) {
                return /^(accounts|opportunities)$/.test(o.resourceKind) && o.key;
            });

            var lookup = {
                'accounts': this.applyAccountContext,
                'opportunities': this.applyOpportunityContext
            };

            this.fields['AccountManager'].setValue(App.context.user);
            this.fields['Owner'].setValue(App.context['defaultOwner']);

            if (found && lookup[found.resourceKind])
                lookup[found.resourceKind].call(this, found);
        },
        applyAccountContext: function(context) {
            var view = App.getView(context.id),
                entry = view && view.entry;

            var account = entry,
                accountName = utility.getValue(entry, 'AccountName'),
                webAddress = utility.getValue(entry, 'WebAddress'),
                mainPhone = utility.getValue(entry, 'MainPhone'),
                address = utility.getValue(entry, 'Address'),
                fax = utility.getValue(entry, 'Fax');

            if (account) this.fields['Account'].setValue(account);
            if (accountName) this.fields['AccountName'].setValue(accountName);
            if (webAddress) this.fields['WebAddress'].setValue(webAddress);
            if (mainPhone) this.fields['WorkPhone'].setValue(mainPhone);
            if (address) this.fields['Address'].setValue(this.cleanAddressEntry(address));
            if (fax) this.fields['Fax'].setValue(fax);
        },
        applyOpportunityContext: function(context) {
            var view = App.getView(context.id),
                entry = view && view.entry;

            var opportunityId = utility.getValue(entry, '$key'),
                account = utility.getValue(entry, 'Account'),
                accountName = utility.getValue(entry, 'Account.AccountName'),
                webAddress = utility.getValue(entry, 'Account.WebAddress'),
                mainPhone = utility.getValue(entry, 'Account.MainPhone'),
                address = utility.getValue(entry, 'Account.Address'),
                fax = utility.getValue(entry, 'Account.Fax');

            if (opportunityId) this.fields['Opportunities.$resources[0].Opportunity.$key'].setValue(opportunityId);
            if (account) this.fields['Account'].setValue(account);
            if (accountName) this.fields['AccountName'].setValue(accountName);
            if (webAddress) this.fields['WebAddress'].setValue(webAddress);
            if (mainPhone) this.fields['WorkPhone'].setValue(mainPhone);
            if (address) this.fields['Address'].setValue(this.cleanAddressEntry(address));
            if (fax) this.fields['Fax'].setValue(fax);
        },
        formatCuisinePrefs: function(selections) {
            if (typeof selections === 'string') return selections;

            var values = [];
            for (var key in selections)
                values.push(selections[key].data['text']);

            return values.join(', ');
        },
        cleanAddressEntry: function(address) {
            if (address)
            {
                var clean = {},
                    skip = {
                        '$key': true,
                        '$lookup': true,
                        '$url': true,
                        'EntityId': true,
                        'ModifyDate': true,
                        'ModifyUser': true,
                        'CreateDate': true,
                        'CreateUser': true
                    };

                for (var name in address)
                    if (!skip[name])
                        clean[name] = address[name];

                return clean;
            }
            else
            {
                return null;
            }
        },
        createLayout: function() {
            return this.layout || (this.layout = [{
                applyTo: '.',
                formatValue: format.nameLF,
                label: this.nameText,
                name: 'ContactName',
                property: 'ContactName',
                type: 'name',
                validator: validator.name,
                view: 'name_edit'
            },
            {
                label: this.accountNameText,
                name: 'Account',
                property: 'Account',
                textProperty: 'AccountName',
                type: 'lookup',
                validator: validator.exists,
                view: 'account_related'
            },
            {
                name: 'AccountName',
                property: 'AccountName',
                type: 'hidden'
            },
            {
                name: 'WebAddress',
                property: 'WebAddress',
                label: this.webText,
                type: 'text',
                inputType: 'url',
                maxTextLength: 128,
                validator: validator.exceedsMaxTextLength
            },
            {
                name: 'WorkPhone',
                property: 'WorkPhone',
                label: this.workText,
                type: 'phone',
                maxTextLength: 32,
                validator: validator.exceedsMaxTextLength
            },
            {
                name: 'Email',
                property: 'Email',
                label: this.emailText,
                type: 'text',
                inputType: 'email'
            },
            {
                label: this.contactTitleText,
                name: 'Title',
                property: 'Title',
                picklist: 'Title',
                title: this.titleTitleText,
                type: 'picklist'
            },
            {
                formatValue: format.address.bindDelegate(this, true),
                label: this.addressText,
                name: 'Address',
                property: 'Address',
                type: 'address',
                view: 'address_edit'
            },
            {
                name: 'HomePhone',
                property: 'HomePhone',
                label: this.homePhoneText,
                type: 'phone',
                maxTextLength: 32,
                validator: validator.exceedsMaxTextLength
            },
            {
                name: 'Mobile',
                property: 'Mobile',
                label: this.mobileText,
                type: 'phone',
                maxTextLength: 32,
                validator: validator.exceedsMaxTextLength
            },
            {
                name: 'Fax',
                property: 'Fax',
                label: this.faxText,
                type: 'phone',
                maxTextLength: 32,
                validator: validator.exceedsMaxTextLength
            },
            {
                label: this.acctMgrText,
                name: 'AccountManager',
                property: 'AccountManager',
                textProperty: 'UserInfo',
                textTemplate: template.nameLF,
                type: 'lookup',
                view: 'user_list'
            },
            {
                label: this.ownerText,
                name: 'Owner',
                property: 'Owner',
                textProperty: 'OwnerDescription',
                type: 'lookup',
                view: 'owner_list'
            },
            {
                name: 'Opportunities.$resources[0].Opportunity.$key',
                property: 'Opportunities.$resources[0].Opportunity.$key',
                type: 'hidden'
            },{
                label: this.cuisinePreferenceText,
                name: 'CuisinePreference',
                property: 'CuisinePreference',
                type: 'picklist',
                picklist: 'CuisinePrefs',
                textRenderer: this.formatCuisinePrefs.bindDelegate(this),
                formatValue: this.formatCuisinePrefs.bindDelegate(this),
                singleSelect: false,
                title: this.cuisinePreferenceTitleText
            }]);
        }
    });
});<commit_msg>[Defect #12089821] add Contact no context from Accounts list. See also SDK update.<commit_after>define('Mobile/SalesLogix/Views/Contact/Edit', [
    'dojo/_base/declare',
    'Mobile/SalesLogix/Format',
    'Mobile/SalesLogix/Template',
    'Mobile/SalesLogix/Validator',
    'Sage/Platform/Mobile/Edit',
    'Sage/Platform/Mobile/Utility'
], function(
    declare,
    format,
    template,
    validator,
    Edit,
    utility
) {

    return declare('Mobile.SalesLogix.Views.Contact.Edit', [Edit], {
        //Localization
        titleText: 'Contact',
        nameText: 'name',
        workText: 'phone',
        mobileText: 'mobile',
        emailText: 'email',
        webText: 'web',
        acctMgrText: 'acct mgr',
        accountNameText: 'account',
        homePhoneText: 'home phone',
        faxText: 'fax',
        addressText: 'address',
        contactTitleText: 'title',
        titleTitleText: 'Title',
        addressTitleText: 'Address',
        ownerText: 'owner',
        cuisinePreferenceText: 'cuisine',
        cuisinePreferenceTitleText: 'Cuisine',

        //View Properties
        entityName: 'Contact',
        id: 'contact_edit',
        insertSecurity: 'Entities/Contact/Add',
        updateSecurity: 'Entities/Contact/Edit',
        querySelect: [
            'Account/AccountName',
            'AccountManager/UserInfo/FirstName',
            'AccountManager/UserInfo/LastName',
            'AccountName',
            'Address/*',
            'CuisinePreference',
            'CreateDate',
            'CreateUser',
            'Email',
            'Fax',
            'FirstName',
            'HomePhone',
            'LastName',
            'MiddleName',
            'Mobile',
            'NameLF',
            'Owner/OwnerDescription',
            'Prefix',
            'Suffix',
            'Title',
            'WebAddress',
            'WorkPhone'
        ],
        resourceKind: 'contacts',

        startup: function() {
            this.inherited(arguments);
            this.connect(this.fields['Account'], 'onChange', this.onAccountChange);
        },
        onAccountChange: function(value, field) {
            if (value && value.text)
                this.fields['AccountName'].setValue(value.text);
        },
        applyContext: function() {
            var found = App.queryNavigationContext(function(o) {
                o =  (o.options && o.options.source) || o;
                return /^(accounts|opportunities)$/.test(o.resourceKind) && o.key;
            });

            var lookup = {
                'accounts': this.applyAccountContext,
                'opportunities': this.applyOpportunityContext
            };

            this.fields['AccountManager'].setValue(App.context.user);
            this.fields['Owner'].setValue(App.context['defaultOwner']);

            if (found && lookup[found.resourceKind])
                lookup[found.resourceKind].call(this, found);
        },
        applyAccountContext: function(context) {
            var view = App.getView(context.id),
                entry = view && view.entry || context.options && context.options.source && context.options.source.entry;

            var account = entry,
                accountName = utility.getValue(entry, 'AccountName'),
                webAddress = utility.getValue(entry, 'WebAddress'),
                mainPhone = utility.getValue(entry, 'MainPhone'),
                address = utility.getValue(entry, 'Address'),
                fax = utility.getValue(entry, 'Fax');

            if (account) this.fields['Account'].setValue(account);
            if (accountName) this.fields['AccountName'].setValue(accountName);
            if (webAddress) this.fields['WebAddress'].setValue(webAddress);
            if (mainPhone) this.fields['WorkPhone'].setValue(mainPhone);
            if (address) this.fields['Address'].setValue(this.cleanAddressEntry(address));
            if (fax) this.fields['Fax'].setValue(fax);
        },
        applyOpportunityContext: function(context) {
            var view = App.getView(context.id),
                entry = view && view.entry;

            var opportunityId = utility.getValue(entry, '$key'),
                account = utility.getValue(entry, 'Account'),
                accountName = utility.getValue(entry, 'Account.AccountName'),
                webAddress = utility.getValue(entry, 'Account.WebAddress'),
                mainPhone = utility.getValue(entry, 'Account.MainPhone'),
                address = utility.getValue(entry, 'Account.Address'),
                fax = utility.getValue(entry, 'Account.Fax');

            if (opportunityId) this.fields['Opportunities.$resources[0].Opportunity.$key'].setValue(opportunityId);
            if (account) this.fields['Account'].setValue(account);
            if (accountName) this.fields['AccountName'].setValue(accountName);
            if (webAddress) this.fields['WebAddress'].setValue(webAddress);
            if (mainPhone) this.fields['WorkPhone'].setValue(mainPhone);
            if (address) this.fields['Address'].setValue(this.cleanAddressEntry(address));
            if (fax) this.fields['Fax'].setValue(fax);
        },
        formatCuisinePrefs: function(selections) {
            if (typeof selections === 'string') return selections;

            var values = [];
            for (var key in selections)
                values.push(selections[key].data['text']);

            return values.join(', ');
        },
        cleanAddressEntry: function(address) {
            if (address)
            {
                var clean = {},
                    skip = {
                        '$key': true,
                        '$lookup': true,
                        '$url': true,
                        'EntityId': true,
                        'ModifyDate': true,
                        'ModifyUser': true,
                        'CreateDate': true,
                        'CreateUser': true
                    };

                for (var name in address)
                    if (!skip[name])
                        clean[name] = address[name];

                return clean;
            }
            else
            {
                return null;
            }
        },
        createLayout: function() {
            return this.layout || (this.layout = [{
                applyTo: '.',
                formatValue: format.nameLF,
                label: this.nameText,
                name: 'ContactName',
                property: 'ContactName',
                type: 'name',
                validator: validator.name,
                view: 'name_edit'
            },
            {
                label: this.accountNameText,
                name: 'Account',
                property: 'Account',
                textProperty: 'AccountName',
                type: 'lookup',
                validator: validator.exists,
                view: 'account_related'
            },
            {
                name: 'AccountName',
                property: 'AccountName',
                type: 'hidden'
            },
            {
                name: 'WebAddress',
                property: 'WebAddress',
                label: this.webText,
                type: 'text',
                inputType: 'url',
                maxTextLength: 128,
                validator: validator.exceedsMaxTextLength
            },
            {
                name: 'WorkPhone',
                property: 'WorkPhone',
                label: this.workText,
                type: 'phone',
                maxTextLength: 32,
                validator: validator.exceedsMaxTextLength
            },
            {
                name: 'Email',
                property: 'Email',
                label: this.emailText,
                type: 'text',
                inputType: 'email'
            },
            {
                label: this.contactTitleText,
                name: 'Title',
                property: 'Title',
                picklist: 'Title',
                title: this.titleTitleText,
                type: 'picklist'
            },
            {
                formatValue: format.address.bindDelegate(this, true),
                label: this.addressText,
                name: 'Address',
                property: 'Address',
                type: 'address',
                view: 'address_edit'
            },
            {
                name: 'HomePhone',
                property: 'HomePhone',
                label: this.homePhoneText,
                type: 'phone',
                maxTextLength: 32,
                validator: validator.exceedsMaxTextLength
            },
            {
                name: 'Mobile',
                property: 'Mobile',
                label: this.mobileText,
                type: 'phone',
                maxTextLength: 32,
                validator: validator.exceedsMaxTextLength
            },
            {
                name: 'Fax',
                property: 'Fax',
                label: this.faxText,
                type: 'phone',
                maxTextLength: 32,
                validator: validator.exceedsMaxTextLength
            },
            {
                label: this.acctMgrText,
                name: 'AccountManager',
                property: 'AccountManager',
                textProperty: 'UserInfo',
                textTemplate: template.nameLF,
                type: 'lookup',
                view: 'user_list'
            },
            {
                label: this.ownerText,
                name: 'Owner',
                property: 'Owner',
                textProperty: 'OwnerDescription',
                type: 'lookup',
                view: 'owner_list'
            },
            {
                name: 'Opportunities.$resources[0].Opportunity.$key',
                property: 'Opportunities.$resources[0].Opportunity.$key',
                type: 'hidden'
            },{
                label: this.cuisinePreferenceText,
                name: 'CuisinePreference',
                property: 'CuisinePreference',
                type: 'picklist',
                picklist: 'CuisinePrefs',
                textRenderer: this.formatCuisinePrefs.bindDelegate(this),
                formatValue: this.formatCuisinePrefs.bindDelegate(this),
                singleSelect: false,
                title: this.cuisinePreferenceTitleText
            }]);
        }
    });
});<|endoftext|>


<commit_before>/**
 * Copyright (c) 2015-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */
'use strict';

var path = require('path');

// Don't forget to everything listed here to `testConfig.json`
// modulePathIgnorePatterns.
var sharedBlacklist = [
  'node_modules/react-tools/src/React.js',
  'node_modules/react-tools/src/renderers/shared/event/EventPropagators.js',
  'node_modules/react-tools/src/renderers/shared/event/eventPlugins/ResponderEventPlugin.js',
  'node_modules/react-tools/src/shared/vendor/core/ExecutionEnvironment.js',

  // Those conflicts with the ones in react-tools/. We need to blacklist the
  // internal version otherwise they won't work in open source.
  'downstream/core/invariant.js',
  'downstream/key-mirror/keyMirror.js',
  'downstream/core/emptyFunction.js',
  'downstream/core/emptyObject.js',
  'downstream/key-mirror/keyOf.js',
  'downstream/core/dom/isNode.js',
  'downstream/core/TouchEventUtils.js',
  'downstream/core/nativeRequestAnimationFrame.js',
  'downstream/core/dom/containsNode.js',
  'downstream/core/dom/isTextNode.js',
  'downstream/functional/mapObject.js',
  'downstream/core/camelize.js',
  'downstream/core/hyphenate.js',
  'downstream/core/createArrayFromMixed.js',
  'downstream/core/toArray.js',
  'downstream/core/dom/getActiveElement.js',
];

// Raw unescaped patterns in case you need to use wildcards
var sharedBlacklistWildcards = [
  'website\/node_modules\/.*',
];

var platformBlacklists = {
  web: [
    '.ios.js',
    '.android.js',
  ],
  ios: [
    '.web.js',
    '.android.js',
  ],
  android: [
    '.web.js',
    '.ios.js',
  ],
};

function escapeRegExp(str) {
  var escaped = str.replace(/[\-\[\]\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
  // convert the '/' into an escaped local file separator
  return escaped.replace(/\//g,'\\' + path.sep);
}

function blacklist(platform, additionalBlacklist) {
  return new RegExp('(' +
    (additionalBlacklist || []).concat(sharedBlacklist)
      .concat(platformBlacklists[platform] || [])
      .map(escapeRegExp)
      .concat(sharedBlacklistWildcards)
      .join('|') +
    ')$'
  );
}

module.exports = blacklist;
<commit_msg>Fix more name collisions<commit_after>/**
 * Copyright (c) 2015-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */
'use strict';

var path = require('path');

// Don't forget to everything listed here to `testConfig.json`
// modulePathIgnorePatterns.
var sharedBlacklist = [
  'node_modules/react-tools/src/React.js',
  'node_modules/react-tools/src/renderers/shared/event/EventPropagators.js',
  'node_modules/react-tools/src/renderers/shared/event/eventPlugins/ResponderEventPlugin.js',
  'node_modules/react-tools/src/shared/vendor/core/ExecutionEnvironment.js',

  // Those conflicts with the ones in react-tools/. We need to blacklist the
  // internal version otherwise they won't work in open source.
  'downstream/core/invariant.js',
  'downstream/key-mirror/keyMirror.js',
  'downstream/core/emptyFunction.js',
  'downstream/core/emptyObject.js',
  'downstream/key-mirror/keyOf.js',
  'downstream/core/dom/isNode.js',
  'downstream/core/TouchEventUtils.js',
  'downstream/core/nativeRequestAnimationFrame.js',
  'downstream/core/dom/containsNode.js',
  'downstream/core/dom/isTextNode.js',
  'downstream/functional/mapObject.js',
  'downstream/core/camelize.js',
  'downstream/core/hyphenate.js',
  'downstream/core/createArrayFromMixed.js',
  'downstream/core/toArray.js',
  'downstream/core/dom/getActiveElement.js',
  'downstream/core/dom/focusNode.js',
  'downstream/core/dom/getUnboundedScrollPosition.js',
  'downstream/core/createNodesFromMarkup.js',
  'downstream/core/CSSCore.js',
  'downstream/core/getMarkupWrap.js',
  'downstream/core/hyphenateStyleName.js',
];

// Raw unescaped patterns in case you need to use wildcards
var sharedBlacklistWildcards = [
  'website\/node_modules\/.*',
];

var platformBlacklists = {
  web: [
    '.ios.js',
    '.android.js',
  ],
  ios: [
    '.web.js',
    '.android.js',
  ],
  android: [
    '.web.js',
    '.ios.js',
  ],
};

function escapeRegExp(str) {
  var escaped = str.replace(/[\-\[\]\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
  // convert the '/' into an escaped local file separator
  return escaped.replace(/\//g,'\\' + path.sep);
}

function blacklist(platform, additionalBlacklist) {
  return new RegExp('(' +
    (additionalBlacklist || []).concat(sharedBlacklist)
      .concat(platformBlacklists[platform] || [])
      .map(escapeRegExp)
      .concat(sharedBlacklistWildcards)
      .join('|') +
    ')$'
  );
}

module.exports = blacklist;
<|endoftext|>


<commit_before>constructor(){
  super({
    requiresPageReload: true
  })
}

enabled(){
  // elements & data
  this.css = null;
  this.htmlModal = null;
  this.config = null;

  this.defaultConfig = {
    columnWidth: "310px",
    fontSize: "12px",
    hideTweetActions: true,
    moveTweetActionsToRight: true,
    revertReplies: false,
    roundedScrollBars: false,
    smallComposeTextSize: false,
    optimizeAnimations: true,
    avatarRadius: 10
  };

  // modal dialog loading
  $TDP.readFileRoot(this.$token, "modal.html").then(contents => {
    this.htmlModal = contents;
  }).catch(err => {
    $TD.alert("error", "Problem loading data for the design edit plugin: "+err.message);
  });

  // configuration
  const configFile = "config.json";
  this.tmpConfig = null;

  var loadConfigObject = obj => {
    this.tmpConfig = obj || {};

    if (window.TD_APP_READY){
      this.onAppReady();
    }

    this.injectDeciderReplyHook(this.tmpConfig.revertReplies);
  };

  this.onAppReady = () => {
    if (this.tmpConfig !== null){
      this.config = $.extend(this.defaultConfig, this.tmpConfig);
      this.tmpConfig = null;
      this.reinjectAll();
    }
  };

  $TDP.checkFileExists(this.$token, configFile).then(exists => {
    if (!exists){
      loadConfigObject(null);
    }
    else{
      $TDP.readFile(this.$token, configFile, true).then(contents => {
        try{
          loadConfigObject(JSON.parse(contents));
        }catch(err){
          loadConfigObject(null);
        }
      }).catch(err => {
        loadConfigObject(null);
        $TD.alert("error", "Problem loading configuration for the design edit plugin: "+err.message);
      });
    }
  });

  this.saveConfig = () => {
    $TDP.writeFile(this.$token, configFile, JSON.stringify(this.config)).catch(err => {
      $TD.alert("error", "Problem saving configuration for the design edit plugin: "+err.message);
    });
  };

  // settings click event
  this.onSettingsMenuClickedEvent = () => {
    if (this.htmlModal === null || this.config === null){
      return;
    }

    setTimeout(() => {
      let menu = $(".js-dropdown-content").children("ul").first();
      if (menu.length === 0)return;

      let itemTD = menu.children("[data-std]").first();
      if (itemTD.length === 0)return;

      if (!itemTD.prev().hasClass("drp-h-divider")){
        itemTD.before('

');
      }

      let itemEditDesign = $('
Edit layout & design
');
      itemTD.after(itemEditDesign);

      itemEditDesign.on("click", "a", function(){
        new customDesignModal();
      });

      itemEditDesign.hover(function(){
        $(this).addClass("is-selected");
      }, function(){
        $(this).removeClass("is-selected");
      });
    }, 1);
  };

  // modal dialog setup
  var me = this;

  var updateKey = function(key, value){
    me.config[key] = value;

    setTimeout(function(){
      me.saveConfig();
      me.reinjectAll();
    }, 1); // delays the slight lag caused by saving and reinjection
  };

  var customDesignModal = TD.components.BaseModal.extend(function(){
    let modal = $("#td-design-plugin-modal");
    this.setAndShowContainer(modal, false);

    // RELOAD
    this.reloadPage = false;
    modal.find("[data-td-reload]").click(() => this.reloadPage = true);

    // UI EVENTS
    let getTextForCustom = function(key){
      return "Custom ("+me.config[key]+")";
    };

    modal.find("[data-td-key]").each(function(){
      let item = $(this);
      let tag = item.prop("tagName");
      let key = item.attr("data-td-key");

      // INPUTS
      if (tag === "INPUT"){
        let type = item.attr("type");

        if (type === "checkbox"){
          item.prop("checked", me.config[key]);

          item.change(function(){
            updateKey(key, item.prop("checked"));
          });
        }
      }
      // SELECTS
      else if (tag === "SELECT"){
        if (!item.val(me.config[key]).val()){
          let custom = item.find("option[value='custom']");

          if (custom.length === 1){
            item.val("custom");
            custom.text(getTextForCustom(key));
          }
        }

        item.change(function(){ // TODO change doesn't fire when Custom is already selected
          let val = item.val();

          if (val === "custom"){
            val = prompt("Enter custom value:");

            if (val){
              updateKey(key, val);
              item.find("option[value='custom']").text(getTextForCustom(key));
            }
          }
          else{
            updateKey(key, item.val());
          }
        });
      }
      // CUSTOM ELEMENTS
      else{
        let value = item.attr("data-td-value");

        if (value == me.config[key]){
          item.addClass("selected");
        }

        item.click(function(){
          modal.find("[data-td-key='"+key+"']").removeClass("selected");
          item.addClass("selected");
          updateKey(key, value);
        });
      }
    });

    // THEMES
    modal.find("[data-td-theme='"+TD.settings.getTheme()+"']").prop("checked", true);

    modal.find("[data-td-theme]").change(function(){
      setTimeout(function(){
        TD.settings.setTheme($(this).attr("data-td-theme"));
        $(document).trigger("uiToggleTheme");
      }, 1);
    });
  }).methods({
    _render: () => $(this.htmlModal),
    destroy: function(){
      if (this.reloadPage){
        location.reload();
        return;
      }

      $("#td-design-plugin-modal").hide();
      this.supr();
    }
  });

  // decider injections
  this.injectDeciderReplyHook = enable => {
    let prevFunc = TD.decider.updateFromBackend;

    TD.decider.updateFromBackend = function(data){
      data["simplified_replies"] = !enable;
      return prevFunc.apply(this, arguments);
    };

    TD.decider.updateForGuestId();
    this.$pluginSettings.requiresPageReload = enable;
  };

  // css and layout injection
  this.resetDesign = () => {
    if (this.css){
      this.css.remove();
    }

    this.css = window.TDPF_createCustomStyle(this);
  };

  this.reinjectAll = () => {
    this.resetDesign();

    this.css.insert(".txt-base-smallest:not(.icon), .txt-base-largest:not(.icon) { font-size: "+this.config.fontSize+" !important }");
    this.css.insert(".avatar { border-radius: "+this.config.avatarRadius+"% !important }");

    if (this.config.hideTweetActions){
      this.css.insert(".tweet-action { opacity: 0; }");
      this.css.insert(".is-favorite .tweet-action, .is-retweet .tweet-action { opacity: 0.5; visibility: visible !important }");
      this.css.insert(".tweet:hover .tweet-action, .is-favorite .tweet-action[rel='favorite'], .is-retweet .tweet-action[rel='retweet'] { opacity: 1; visibility: visible !important }");
    }

    if (this.config.moveTweetActionsToRight){
      this.css.insert(".tweet-actions { float: right !important; width: auto !important }");
      this.css.insert(".tweet-actions > li:nth-child(4) { margin-right: 2px !important }");
    }

    if (this.config.smallComposeTextSize){
      this.css.insert(".compose-text { font-size: 12px !important; height: 120px !important }");
    }

    if (!this.config.roundedScrollBars){
      this.css.insert(".scroll-styled-v:not(.antiscroll-inner)::-webkit-scrollbar { width: 8px }");
      this.css.insert(".scroll-styled-h:not(.antiscroll-inner)::-webkit-scrollbar { height: 8px }");
      this.css.insert(".scroll-styled-v::-webkit-scrollbar-thumb { border-radius: 0 }");
      this.css.insert(".scroll-styled-h::-webkit-scrollbar-thumb { border-radius: 0 }");
      this.css.insert(".antiscroll-scrollbar { border-radius: 0 }");
      this.css.insert(".antiscroll-scrollbar-vertical { margin-top: 0 }");
      this.css.insert(".antiscroll-scrollbar-horizontal { margin-left: 0 }");
    }

    if (this.config.optimizeAnimations){
      this.css.insert(".app-content { will-change: transform }");
      this.css.insert(".column-holder { will-change: transform }");
    }

    if (this.config.columnWidth[0] === '/'){
      let cols = this.config.columnWidth.slice(1);

      this.css.insert(".column { width: calc((100vw - 205px) / "+cols+" - 8px) !important }");
      this.css.insert(".is-condensed .column { width: calc((100vw - 55px) / "+cols+" - 8px) !important }");
    }
    else{
      this.css.insert(".column { width: "+this.config.columnWidth+" !important }");
    }

    switch(this.config.columnWidth){
      case "/6":
        TD.settings.setColumnWidth("narrow");
        break;

      case "310px":
      case "/5":
        TD.settings.setColumnWidth("medium");
        break;

      default:
        TD.settings.setColumnWidth(parseInt(this.config.columnWidth, 10) < 310 ? "narrow" : "wide"); // NaN will give "wide"
        break;
    }

    switch(this.config.fontSize){
      case "13px": TD.settings.setFontSize("small"); break;
      case "14px": TD.settings.setFontSize("medium"); break;
      case "15px": TD.settings.setFontSize("large"); break;
      default: TD.settings.setFontSize(parseInt(this.config.fontSize, 10) >= 16 ? "largest" : "smallest"); break;
    }

    $TDP.injectIntoNotificationsBefore(this.$token, "css", "", [
      ""
    ].join(""));
  };

  this.uiShowActionsMenuEvent = () => {
    if (this.config.moveTweetActionsToRight){
      $(".js-dropdown.pos-r").toggleClass("pos-r pos-l");
    }
  };
}

ready(){
  // configuration
  switch(TD.settings.getColumnWidth()){
    case "wide": this.defaultConfig.columnWidth = "350px"; break;
    case "narrow": this.defaultConfig.columnWidth = "270px"; break;
  }

  switch(TD.settings.getFontSize()){
    case "small": this.defaultConfig.fontSize = "13px"; break;
    case "medium": this.defaultConfig.fontSize = "14px"; break;
    case "large": this.defaultConfig.fontSize = "15px"; break;
    case "largest": this.defaultConfig.fontSize = "16px"; break;
  }

  this.onAppReady();

  // layout events
  $(document).on("uiShowActionsMenu", this.uiShowActionsMenuEvent);

  // modal
  $("[data-action='settings-menu']").on("click", this.onSettingsMenuClickedEvent);
  $(".js-app").append('

');
}

disabled(){
  if (this.css){
    this.css.remove();
  }

  $(document).off("uiShowActionsMenu", this.uiShowActionsMenuEvent);

  $("[data-action='settings-menu']").off("click", this.onSettingsMenuClickedEvent);
  $("#td-design-plugin-modal").remove();
}
<commit_msg>Make the default theme/column/font settings hidden if edit-design plugin is enabled<commit_after>constructor(){
  super({
    requiresPageReload: true
  })
}

enabled(){
  // elements & data
  this.css = null;
  this.htmlModal = null;
  this.config = null;

  this.defaultConfig = {
    columnWidth: "310px",
    fontSize: "12px",
    hideTweetActions: true,
    moveTweetActionsToRight: true,
    revertReplies: false,
    roundedScrollBars: false,
    smallComposeTextSize: false,
    optimizeAnimations: true,
    avatarRadius: 10
  };

  // modal dialog loading
  $TDP.readFileRoot(this.$token, "modal.html").then(contents => {
    this.htmlModal = contents;
  }).catch(err => {
    $TD.alert("error", "Problem loading data for the design edit plugin: "+err.message);
  });

  // configuration
  const configFile = "config.json";
  this.tmpConfig = null;

  var loadConfigObject = obj => {
    this.tmpConfig = obj || {};

    if (window.TD_APP_READY){
      this.onAppReady();
    }

    this.injectDeciderReplyHook(this.tmpConfig.revertReplies);
  };

  this.onAppReady = () => {
    if (this.tmpConfig !== null){
      this.config = $.extend(this.defaultConfig, this.tmpConfig);
      this.tmpConfig = null;
      this.reinjectAll();
    }
  };

  $TDP.checkFileExists(this.$token, configFile).then(exists => {
    if (!exists){
      loadConfigObject(null);
    }
    else{
      $TDP.readFile(this.$token, configFile, true).then(contents => {
        try{
          loadConfigObject(JSON.parse(contents));
        }catch(err){
          loadConfigObject(null);
        }
      }).catch(err => {
        loadConfigObject(null);
        $TD.alert("error", "Problem loading configuration for the design edit plugin: "+err.message);
      });
    }
  });

  this.saveConfig = () => {
    $TDP.writeFile(this.$token, configFile, JSON.stringify(this.config)).catch(err => {
      $TD.alert("error", "Problem saving configuration for the design edit plugin: "+err.message);
    });
  };

  // settings click event
  this.onSettingsMenuClickedEvent = () => {
    if (this.htmlModal === null || this.config === null){
      return;
    }

    setTimeout(() => {
      let menu = $(".js-dropdown-content").children("ul").first();
      if (menu.length === 0)return;

      let itemTD = menu.children("[data-std]").first();
      if (itemTD.length === 0)return;

      if (!itemTD.prev().hasClass("drp-h-divider")){
        itemTD.before('

');
      }

      let itemEditDesign = $('
Edit layout & design
');
      itemTD.after(itemEditDesign);

      itemEditDesign.on("click", "a", function(){
        new customDesignModal();
      });

      itemEditDesign.hover(function(){
        $(this).addClass("is-selected");
      }, function(){
        $(this).removeClass("is-selected");
      });
    }, 1);
  };

  // modal dialog setup
  var me = this;

  var updateKey = function(key, value){
    me.config[key] = value;

    setTimeout(function(){
      me.saveConfig();
      me.reinjectAll();
    }, 1); // delays the slight lag caused by saving and reinjection
  };

  var customDesignModal = TD.components.BaseModal.extend(function(){
    let modal = $("#td-design-plugin-modal");
    this.setAndShowContainer(modal, false);

    // RELOAD
    this.reloadPage = false;
    modal.find("[data-td-reload]").click(() => this.reloadPage = true);

    // UI EVENTS
    let getTextForCustom = function(key){
      return "Custom ("+me.config[key]+")";
    };

    modal.find("[data-td-key]").each(function(){
      let item = $(this);
      let tag = item.prop("tagName");
      let key = item.attr("data-td-key");

      // INPUTS
      if (tag === "INPUT"){
        let type = item.attr("type");

        if (type === "checkbox"){
          item.prop("checked", me.config[key]);

          item.change(function(){
            updateKey(key, item.prop("checked"));
          });
        }
      }
      // SELECTS
      else if (tag === "SELECT"){
        if (!item.val(me.config[key]).val()){
          let custom = item.find("option[value='custom']");

          if (custom.length === 1){
            item.val("custom");
            custom.text(getTextForCustom(key));
          }
        }

        item.change(function(){ // TODO change doesn't fire when Custom is already selected
          let val = item.val();

          if (val === "custom"){
            val = prompt("Enter custom value:");

            if (val){
              updateKey(key, val);
              item.find("option[value='custom']").text(getTextForCustom(key));
            }
          }
          else{
            updateKey(key, item.val());
          }
        });
      }
      // CUSTOM ELEMENTS
      else{
        let value = item.attr("data-td-value");

        if (value == me.config[key]){
          item.addClass("selected");
        }

        item.click(function(){
          modal.find("[data-td-key='"+key+"']").removeClass("selected");
          item.addClass("selected");
          updateKey(key, value);
        });
      }
    });

    // THEMES
    modal.find("[data-td-theme='"+TD.settings.getTheme()+"']").prop("checked", true);

    modal.find("[data-td-theme]").change(function(){
      setTimeout(function(){
        TD.settings.setTheme($(this).attr("data-td-theme"));
        $(document).trigger("uiToggleTheme");
      }, 1);
    });
  }).methods({
    _render: () => $(this.htmlModal),
    destroy: function(){
      if (this.reloadPage){
        location.reload();
        return;
      }

      $("#td-design-plugin-modal").hide();
      this.supr();
    }
  });

  // decider injections
  this.injectDeciderReplyHook = enable => {
    let prevFunc = TD.decider.updateFromBackend;

    TD.decider.updateFromBackend = function(data){
      data["simplified_replies"] = !enable;
      return prevFunc.apply(this, arguments);
    };

    TD.decider.updateForGuestId();
    this.$pluginSettings.requiresPageReload = enable;
  };

  // css and layout injection
  this.resetDesign = () => {
    if (this.css){
      this.css.remove();
    }

    this.css = window.TDPF_createCustomStyle(this);
  };

  this.reinjectAll = () => {
    this.resetDesign();

    this.css.insert("#general_settings .cf { display: none !important }");
    this.css.insert("#general_settings .divider-bar::after { display: inline-block; padding-top: 10px; line-height: 17px; content: 'Use the new | Edit layout & design | option in the Settings to modify TweetDeck theme, column width, font size, and other features.' }");

    this.css.insert(".txt-base-smallest:not(.icon), .txt-base-largest:not(.icon) { font-size: "+this.config.fontSize+" !important }");
    this.css.insert(".avatar { border-radius: "+this.config.avatarRadius+"% !important }");

    if (this.config.hideTweetActions){
      this.css.insert(".tweet-action { opacity: 0; }");
      this.css.insert(".is-favorite .tweet-action, .is-retweet .tweet-action { opacity: 0.5; visibility: visible !important }");
      this.css.insert(".tweet:hover .tweet-action, .is-favorite .tweet-action[rel='favorite'], .is-retweet .tweet-action[rel='retweet'] { opacity: 1; visibility: visible !important }");
    }

    if (this.config.moveTweetActionsToRight){
      this.css.insert(".tweet-actions { float: right !important; width: auto !important }");
      this.css.insert(".tweet-actions > li:nth-child(4) { margin-right: 2px !important }");
    }

    if (this.config.smallComposeTextSize){
      this.css.insert(".compose-text { font-size: 12px !important; height: 120px !important }");
    }

    if (!this.config.roundedScrollBars){
      this.css.insert(".scroll-styled-v:not(.antiscroll-inner)::-webkit-scrollbar { width: 8px }");
      this.css.insert(".scroll-styled-h:not(.antiscroll-inner)::-webkit-scrollbar { height: 8px }");
      this.css.insert(".scroll-styled-v::-webkit-scrollbar-thumb { border-radius: 0 }");
      this.css.insert(".scroll-styled-h::-webkit-scrollbar-thumb { border-radius: 0 }");
      this.css.insert(".antiscroll-scrollbar { border-radius: 0 }");
      this.css.insert(".antiscroll-scrollbar-vertical { margin-top: 0 }");
      this.css.insert(".antiscroll-scrollbar-horizontal { margin-left: 0 }");
    }

    if (this.config.optimizeAnimations){
      this.css.insert(".app-content { will-change: transform }");
      this.css.insert(".column-holder { will-change: transform }");
    }

    if (this.config.columnWidth[0] === '/'){
      let cols = this.config.columnWidth.slice(1);

      this.css.insert(".column { width: calc((100vw - 205px) / "+cols+" - 8px) !important }");
      this.css.insert(".is-condensed .column { width: calc((100vw - 55px) / "+cols+" - 8px) !important }");
    }
    else{
      this.css.insert(".column { width: "+this.config.columnWidth+" !important }");
    }

    switch(this.config.columnWidth){
      case "/6":
        TD.settings.setColumnWidth("narrow");
        break;

      case "310px":
      case "/5":
        TD.settings.setColumnWidth("medium");
        break;

      default:
        TD.settings.setColumnWidth(parseInt(this.config.columnWidth, 10) < 310 ? "narrow" : "wide"); // NaN will give "wide"
        break;
    }

    switch(this.config.fontSize){
      case "13px": TD.settings.setFontSize("small"); break;
      case "14px": TD.settings.setFontSize("medium"); break;
      case "15px": TD.settings.setFontSize("large"); break;
      default: TD.settings.setFontSize(parseInt(this.config.fontSize, 10) >= 16 ? "largest" : "smallest"); break;
    }

    $TDP.injectIntoNotificationsBefore(this.$token, "css", "", [
      ""
    ].join(""));
  };

  this.uiShowActionsMenuEvent = () => {
    if (this.config.moveTweetActionsToRight){
      $(".js-dropdown.pos-r").toggleClass("pos-r pos-l");
    }
  };
}

ready(){
  // configuration
  switch(TD.settings.getColumnWidth()){
    case "wide": this.defaultConfig.columnWidth = "350px"; break;
    case "narrow": this.defaultConfig.columnWidth = "270px"; break;
  }

  switch(TD.settings.getFontSize()){
    case "small": this.defaultConfig.fontSize = "13px"; break;
    case "medium": this.defaultConfig.fontSize = "14px"; break;
    case "large": this.defaultConfig.fontSize = "15px"; break;
    case "largest": this.defaultConfig.fontSize = "16px"; break;
  }

  this.onAppReady();

  // layout events
  $(document).on("uiShowActionsMenu", this.uiShowActionsMenuEvent);

  // modal
  $("[data-action='settings-menu']").on("click", this.onSettingsMenuClickedEvent);
  $(".js-app").append('

');
}

disabled(){
  if (this.css){
    this.css.remove();
  }

  $(document).off("uiShowActionsMenu", this.uiShowActionsMenuEvent);

  $("[data-action='settings-menu']").off("click", this.onSettingsMenuClickedEvent);
  $("#td-design-plugin-modal").remove();
}
<|endoftext|>


<commit_before>/**
 * Created by slanska on 2016-10-25.
 */
"use strict";
var feathers = require('feathers');
var rest = require('feathers-rest');
var hooks = require('feathers-hooks');
var bodyParser = require('body-parser');
var errors = require('feathers-errors/handler');
var nauth2 = require('./lib/index');
var cors = require('cors');
module.exports = function (config) {
    var app = feathers();
    // Enable REST services
    app.configure(rest())
        .configure(hooks())
        .use(cors())
        .use(bodyParser.json())
        .use(bodyParser.urlencoded({ extended: true }))
        .configure(nauth2(app, config));
    // Just like Express your error middleware needs to be
    // set up last in your middleware chain.
    app.use(errors({
        html: function (error, req, res, next) {
            // TODO use ECT to render error view with the error object
            res.render('error', error);
            res.json(error);
        }
    }));
    process.on('unhandledRejection', function (reason, p) {
        console.log("Unhandled Rejection at: Promise ", p, " reason: ", reason);
    });
    /*
     Use extended version of query parser, so that nested objects and other advanced features
     will be available
     */
    app.set('query parser', 'extended');
    return app;
};
//# sourceMappingURL=appFactory.js.map<commit_msg>Delete appFactory.js<commit_after><|endoftext|>


<commit_before>/**
 * @file ColGroup component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';

// Statics
import TableFragment from '../_statics/TableFragment';
import HorizontalAlign from '../_statics/HorizontalAlign';
import SelectMode from '../_statics/SelectMode';
import SelectAllMode from '../_statics/SelectAllMode';
import SortingType from '../_statics/SortingType';

// Vendors
import Util from '../_vendors/Util';
import TC from '../_vendors/TableCalculation';

class ColGroup extends Component {

    static Fragment = TableFragment;
    static Align = HorizontalAlign;
    static SelectMode = SelectMode;
    static SelectAllMode = SelectAllMode;
    static SortingType = SortingType;

    constructor(props, ...restArgs) {
        super(props, ...restArgs);
    }

    getColumnWidth = column => {

        const {columnKeyField, columnsWidth, data} = this.props;

        if (columnKeyField && columnsWidth) {
            const width = columnsWidth.get(TC.getColumnKey(column, columnKeyField));
            if (width) {
                return width;
            }
        }

        if (typeof column.width === 'function') {
            const width = column.width(data);
            if (width) {
                return width;
            }
        }

        return column.width || null;

    };

    getColStyle = column => {

        const result = {
            width: this.getColumnWidth(column)
        };

        // min width
        result.minWidth = column.minWidth ?
            column.minWidth
            :
            result.width;

        return !result.width && !result.minWidth ? null : result;

    };

    render() {

        const {columns, ignoreColumnSpan} = this.props;

        return columns ?
            <colgroup>
                {
                    columns.map(({column, span}, index) => column ?
                        <col key={index}
                             style={this.getColStyle(column)}
                             span={ignoreColumnSpan ? null : (span && span > 1 ? span : null)}/>
                        :
                        null
                    )
                }
            </colgroup>
            :
            null;

    }

}

ColGroup.propTypes = {

    /**
     * Children passed into table header.
     */
    columns: PropTypes.arrayOf(PropTypes.shape({

        /**
         * unique keyof column.
         */
        key: PropTypes.string,

        /**
         * fixed position of column ( 'left' / 'right' ).
         */
        fixed: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * width of column.
         */
        width: PropTypes.oneOfType([PropTypes.number, PropTypes.string, PropTypes.func]),

        /**
         * minimum width of column.
         */
        minWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

        /**
         * align of current column.
         */
        align: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * no wrap of current column.
         */
        noWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * The class name of header.
         */
        headClassName: PropTypes.string,

        /**
         * Override the styles of header.
         */
        headStyle: PropTypes.object,

        /**
         * align of table header cell
         */
        headAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The render content in table head.
         *  (1) callback:
         *      function (tableData, colIndex) {
         *          return colIndex;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        headRenderer: PropTypes.any,

        /**
         * The title in table head.
         *  (1) callback:
         *      function (tableData, colIndex) {
         *          return colIndex;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        headTitle: PropTypes.any,

        /**
         * column span of table header.
         *  (1) function callback:
         *      function (tableData, colIndex) {
         *          return null;
         *      }
         *
         *  (2) number:
         *      render whatever you pass
         */
        headSpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * no wrap of table header.
         */
        headNoWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * The class name of td.
         */
        bodyClassName: PropTypes.string,

        /**
         * Override the styles of td.
         */
        bodyStyle: PropTypes.object,

        /**
         * align of table body cell.
         */
        bodyAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The render content in table body.
         *  (1) callback:
         *      function (rowData, rowIndex, colIndex, parentData, tableData, collapsed, depth, path) {
         *          return rowData.id;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        bodyRenderer: PropTypes.any,

        /**
         * The title in table body.
         *  (1) callback:
         *      function (rowData, rowIndex, colIndex, parentData, tableData, collapsed, depth, path) {
         *          return rowData.id;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        bodyTitle: PropTypes.any,

        /**
         * column span of table body.
         *  (1) function callback:
         *      function (rowData, colIndex, rowIndex) {
         *          return null;
         *      }
         *
         *  (2) number:
         *      render whatever you pass
         */
        bodySpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * no wrap of table body.
         */
        bodyNoWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * The class name of footer.
         */
        footClassName: PropTypes.string,

        /**
         * Override the styles of footer.
         */
        footStyle: PropTypes.object,

        /**
         * align of table footer cell
         */
        footAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The render content in table foot.
         *  (1) callback:
         *      function (tableData, colIndex) {
         *          return colIndex;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        footRenderer: PropTypes.any,

        /**
         * The title in table foot.
         *  (1) callback:
         *      function (tableData, colIndex) {
         *          return colIndex;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        footTitle: PropTypes.any,

        /**
         * column span of table foot.
         *  (1) function callback:
         *      function (tableData, colIndex) {
         *          return null;
         *      }
         *
         *  (2) number:
         *      render whatever you pass
         */
        footSpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * no wrap of table foot.
         */
        footNoWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * If true, this column can be sorted.
         */
        sortable: PropTypes.bool,

        /**
         * Sorting property.
         */
        sortingProp: PropTypes.string,

        defaultSortingType: PropTypes.oneOf(Util.enumerateValue(SortingType)),

        /**
         * whether the column can be resized
         */
        resizable: PropTypes.bool

    })).isRequired,
    columnKeyField: PropTypes.string,
    columnsWidth: PropTypes.object,

    data: PropTypes.array,

    /**
     * column resizable
     */
    defaultColumnWidth: PropTypes.number,
    minColumnWidth: PropTypes.number,

    ignoreColumnSpan: PropTypes.bool

};

ColGroup.defaultProps = {

    columnKeyField: 'key',

    /**
     * column resizable
     */
    defaultColumnWidth: 100,
    minColumnWidth: 64,

    ignoreColumnSpan: false

};

export default ColGroup;
<commit_msg>update ColGroup<commit_after>/**
 * @file ColGroup component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';

// Statics
import TableFragment from '../_statics/TableFragment';
import HorizontalAlign from '../_statics/HorizontalAlign';
import SelectMode from '../_statics/SelectMode';
import SelectAllMode from '../_statics/SelectAllMode';
import SortingType from '../_statics/SortingType';

// Vendors
import Util from '../_vendors/Util';
import TC from '../_vendors/TableCalculation';

class ColGroup extends Component {

    static Fragment = TableFragment;
    static Align = HorizontalAlign;
    static SelectMode = SelectMode;
    static SelectAllMode = SelectAllMode;
    static SortingType = SortingType;

    constructor(props, ...restArgs) {
        super(props, ...restArgs);
    }

    getColumnWidth = column => {

        const {columnKeyField, columnsWidth, useColumnsWidth, data} = this.props;

        if (useColumnsWidth && columnKeyField && columnsWidth) {
            const width = columnsWidth.get(TC.getColumnKey(column, columnKeyField));
            if (width) {
                return width;
            }
        }

        if (typeof column.width === 'function') {
            const width = column.width(data);
            if (width) {
                return width;
            }
        }

        return column.width || null;

    };

    getColStyle = column => {

        const result = {
            width: this.getColumnWidth(column)
        };

        // min width
        result.minWidth = column.minWidth ?
            column.minWidth
            :
            result.width;

        return !result.width && !result.minWidth ? null : result;

    };

    render() {

        const {columns, ignoreColumnSpan} = this.props;

        return columns ?
            <colgroup>
                {
                    columns.map(({column, span}, index) => column ?
                        <col key={index}
                             style={this.getColStyle(column)}
                             span={ignoreColumnSpan ? null : (span && span > 1 ? span : null)}/>
                        :
                        null
                    )
                }
            </colgroup>
            :
            null;

    }

}

ColGroup.propTypes = {

    /**
     * Children passed into table header.
     */
    columns: PropTypes.arrayOf(PropTypes.shape({

        /**
         * unique keyof column.
         */
        key: PropTypes.string,

        /**
         * fixed position of column ( 'left' / 'right' ).
         */
        fixed: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * width of column.
         */
        width: PropTypes.oneOfType([PropTypes.number, PropTypes.string, PropTypes.func]),

        /**
         * minimum width of column.
         */
        minWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

        /**
         * align of current column.
         */
        align: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * no wrap of current column.
         */
        noWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * The class name of header.
         */
        headClassName: PropTypes.string,

        /**
         * Override the styles of header.
         */
        headStyle: PropTypes.object,

        /**
         * align of table header cell
         */
        headAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The render content in table head.
         *  (1) callback:
         *      function (tableData, colIndex) {
         *          return colIndex;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        headRenderer: PropTypes.any,

        /**
         * The title in table head.
         *  (1) callback:
         *      function (tableData, colIndex) {
         *          return colIndex;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        headTitle: PropTypes.any,

        /**
         * column span of table header.
         *  (1) function callback:
         *      function (tableData, colIndex) {
         *          return null;
         *      }
         *
         *  (2) number:
         *      render whatever you pass
         */
        headSpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * no wrap of table header.
         */
        headNoWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * The class name of td.
         */
        bodyClassName: PropTypes.string,

        /**
         * Override the styles of td.
         */
        bodyStyle: PropTypes.object,

        /**
         * align of table body cell.
         */
        bodyAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The render content in table body.
         *  (1) callback:
         *      function (rowData, rowIndex, colIndex, parentData, tableData, collapsed, depth, path) {
         *          return rowData.id;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        bodyRenderer: PropTypes.any,

        /**
         * The title in table body.
         *  (1) callback:
         *      function (rowData, rowIndex, colIndex, parentData, tableData, collapsed, depth, path) {
         *          return rowData.id;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        bodyTitle: PropTypes.any,

        /**
         * column span of table body.
         *  (1) function callback:
         *      function (rowData, colIndex, rowIndex) {
         *          return null;
         *      }
         *
         *  (2) number:
         *      render whatever you pass
         */
        bodySpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * no wrap of table body.
         */
        bodyNoWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * The class name of footer.
         */
        footClassName: PropTypes.string,

        /**
         * Override the styles of footer.
         */
        footStyle: PropTypes.object,

        /**
         * align of table footer cell
         */
        footAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The render content in table foot.
         *  (1) callback:
         *      function (tableData, colIndex) {
         *          return colIndex;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        footRenderer: PropTypes.any,

        /**
         * The title in table foot.
         *  (1) callback:
         *      function (tableData, colIndex) {
         *          return colIndex;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        footTitle: PropTypes.any,

        /**
         * column span of table foot.
         *  (1) function callback:
         *      function (tableData, colIndex) {
         *          return null;
         *      }
         *
         *  (2) number:
         *      render whatever you pass
         */
        footSpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * no wrap of table foot.
         */
        footNoWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * If true, this column can be sorted.
         */
        sortable: PropTypes.bool,

        /**
         * Sorting property.
         */
        sortingProp: PropTypes.string,

        defaultSortingType: PropTypes.oneOf(Util.enumerateValue(SortingType)),

        /**
         * whether the column can be resized
         */
        resizable: PropTypes.bool

    })).isRequired,
    columnKeyField: PropTypes.string,
    columnsWidth: PropTypes.object,
    useColumnsWidth: PropTypes.bool,

    data: PropTypes.array,

    /**
     * column resizable
     */
    defaultColumnWidth: PropTypes.number,
    minColumnWidth: PropTypes.number,

    ignoreColumnSpan: PropTypes.bool

};

ColGroup.defaultProps = {

    columnKeyField: 'key',

    /**
     * column resizable
     */
    defaultColumnWidth: 100,
    minColumnWidth: 64,
    useColumnsWidth: false,

    ignoreColumnSpan: false

};

export default ColGroup;
<|endoftext|>