Maybe make a blank account because this is probably the most inefficient way to communicate with me after work other than writing me a letter. Plus we could have a group message going with the 3 of us.

David Wells
Bioinformatics Analyst I
Leidos Biomedical Research, Inc. (Contractor)
Laboratory of Molecular Technology
Cancer Research Technology Program
Frederick National Laboratory for Cancer Research
301-228-4198
wellsd2@mail.nih.gov<mailto:wellsd2@mail.nih.gov>

From: Viking33 <notifications@github.com>
Reply-To: wellsd2/BIFX553-project-1 <reply@reply.github.com>
Date: Tuesday, January 31, 2017 at 9:17 AM
To: wellsd2/BIFX553-project-1 <BIFX553-project-1@noreply.github.com>
Cc: "Wells, David (NIH/NCI) [C]" <wellsd2@mail.nih.gov>, Author <author@noreply.github.com>
Subject: Re: [wellsd2/BIFX553-project-1] first commit (2b85f28)

Don't use facebook

On Mon, Jan 30, 2017 at 3:06 PM, wellsd2 <notifications@github.com> wrote:

> Add me on facebook. It’ll be much easier to chat. These messages are going
> to my work email which I rarely check when I’m at home.
>
> https://www.facebook.com/profile.php?id=9388533
>
>
> David Wells
> Bioinformatics Analyst I
> Leidos Biomedical Research, Inc. (Contractor)
> Laboratory of Molecular Technology
> Cancer Research Technology Program
> Frederick National Laboratory for Cancer Research
> 301-228-4198 <(301)%20228-4198>
> wellsd2@mail.nih.gov<mailto:wellsd2@mail.nih.gov>
>
> From: Viking33 <notifications@github.com>
> Reply-To: wellsd2/BIFX553-project-1 <reply@reply.github.com>
> Date: Monday, January 30, 2017 at 3:02 PM
> To: wellsd2/BIFX553-project-1 <BIFX553-project-1@noreply.github.com>
> Cc: "Wells, David (NIH/NCI) [C]" <wellsd2@mail.nih.gov>, Author <
> author@noreply.github.com>
> Subject: Re: [wellsd2/BIFX553-project-1] first commit (2b85f28)
>
> Began looking for reference papers for report
>
> On Sun, Jan 29, 2017 at 6:17 AM, Justin Clabaugh <clabjustin5@gmail.com>
> wrote:
>
> > Good idea. I have started a methods section already. I have also used a
> > word document to track what I do each day since we are required to do
> so.
> >
> > On Sat, Jan 28, 2017 at 7:47 PM, wellsd2 <notifications@github.com>
> wrote:
> >
> >> Since you feel you’re not a strong writer, would you like to take the
> >> methods section, since it’s more straight forward?
> >>
> >> We haven’t decided the exact variables. The last idea we had was to
> break
> >> the women into three groups based on condom use, then look at the
> >> probability of having HIV at certain ages and if they engage in other
> risky
> >> behaviors. How about we each work on a few DAGs for different scenarios
> and
> >> meet up a little early on Thursday and pick/create a good one to show
> >> Randy?
> >>
> >>
> >> David Wells
> >> Bioinformatics Analyst I
> >> Leidos Biomedical Research, Inc. (Contractor)
> >> Laboratory of Molecular Technology
> >> Cancer Research Technology Program
> >> Frederick National Laboratory for Cancer Research
> >> 301-228-4198 <(301)%20228-4198> <(301)%20228-4198>
> >> wellsd2@mail.nih.gov<mailto:wellsd2@mail.nih.gov>
> >>
> >> From: Viking33 <notifications@github.com>
> >> Reply-To: wellsd2/BIFX553-project-1 <reply@reply.github.com>
> >> Date: Saturday, January 28, 2017 at 9:09 AM
> >> To: wellsd2/BIFX553-project-1 <BIFX553-project-1@noreply.github.com>
> >> Cc: "Wells, David (NIH/NCI) [C]" <wellsd2@mail.nih.gov>, Author <
> >> author@noreply.github.com>
> >> Subject: Re: [wellsd2/BIFX553-project-1] first commit (2b85f28)
> >>
> >> Were the variable we decided on were paid sex and protected sex, and
> did
> >> we
> >> add any others?
> >>
> >> On Fri, Jan 27, 2017 at 6:41 PM, Justin Clabaugh <clabjustin5@gmail.com>
>
> >> wrote:
> >>
> >> > I suggested it because of time restraints compared to what we might
> get
> >> > during other classes. For me, I am not the best writer, but I don't
> >> mind
> >> > what section I get as long as we can edit it together later to make a
> >> > coherent paper.
> >> >
> >> > On Fri, Jan 27, 2017 at 10:00 AM, wellsd2 <notifications@github.com>
> >> > wrote:
> >> >
> >> >> If we decided now, I’d ask to do the methods, but we might also want
> >> to
> >> >> wait a little bit so we can see if one of us is better suited for a
> >> >> particular section.
> >> >>
> >> >>
> >> >> David Wells
> >> >> Bioinformatics Analyst I
> >> >> Leidos Biomedical Research, Inc. (Contractor)
> >> >> Laboratory of Molecular Technology
> >> >> Cancer Research Technology Program
> >> >> Frederick National Laboratory for Cancer Research
> >> >> 301-228-4198 <(301)%20228-4198> <(301)%20228-4198>
> <(301)%20228-4198>
> >> >> wellsd2@mail.nih.gov<mailto:wellsd2@mail.nih.gov>
> >> >>
> >> >> From: Viking33 <notifications@github.com>
> >> >> Reply-To: wellsd2/BIFX553-project-1 <reply@reply.github.com>
> >> >> Date: Friday, January 27, 2017 at 9:52 AM
> >> >> To: wellsd2/BIFX553-project-1 <BIFX553-project-1@noreply.github.com>
>
> >> >> Cc: "Wells, David (NIH/NCI) [C]" <wellsd2@mail.nih.gov>, Author <
> >> >> author@noreply.github.com>
> >> >> Subject: Re: [wellsd2/BIFX553-project-1] first commit (2b85f28)
> >> >>
> >> >>
> >> >> The project requires us to do a lab report. Do you want to assign us
> >> with
> >> >> writing specific sections of the report?
> >> >>
> >> >> —
> >> >> You are receiving this because you authored the thread.
> >> >> Reply to this email directly, view it on GitHub<
> >> https://github.com/well
> >> >> sd2/BIFX553-project-1/commit/2b85f281074c255e7b3f14e121b25a9
> >> >> 486304abb#commitcomment-20641889>, or mute the thread<
> >> >> https://github.com/notifications/unsubscribe-auth/APf
> >> >> YSB557zGIV90yXsEZ2eqPXg7edejsks5rWgSvgaJpZM4Lv2G0>.
> >> >>
> >> >> —
> >> >> You are receiving this because you commented.
> >> >> Reply to this email directly, view it on GitHub
> >> >> <https://github.com/wellsd2/BIFX553-project-1/commit/2b85f28
> >> 1074c255e7b3f14e121b25a9486304abb#commitcomment-20642010>,
> >> >> or mute the thread
> >> >> <https://github.com/notifications/unsubscribe-auth/
> >> AYEO3TC0ROeTY_R1Wl5A1QgF--Cld-jgks5rWgadgaJpZM4Lv2G0>
> >> >> .
> >> >>
> >> >
> >> >
> >>
> >>
> >> —
> >> You are receiving this because you authored the thread.
> >> Reply to this email directly, view it on GitHub<https://github.com/well
> >> sd2/BIFX553-project-1/commit/2b85f281074c255e7b3f14e121b25a9
> >> 486304abb#commitcomment-20651106>, or mute the thread<
> >> https://github.com/notifications/unsubscribe-auth/
> >> APfYSBysDv-ffnNWOnuo7xDZuABcowAFks5rW0wQgaJpZM4Lv2G0>.
> >>
> >> —
> >> You are receiving this because you commented.
> >> Reply to this email directly, view it on GitHub
> >> <https://github.com/wellsd2/BIFX553-project-1/commit/
> 2b85f281074c255e7b3f14e121b25a9486304abb#commitcomment-20652943>,
> >> or mute the thread
> >> <https://github.com/notifications/unsubscribe-auth/AYEO3ftmOa03y-wDvU-
> gtvsvKtS-V99xks5rW-GRgaJpZM4Lv2G0>
> >> .
> >>
> >
> >
>
>
> —
> You are receiving this because you authored the thread.
> Reply to this email directly, view it on GitHub<https://github.com/
> wellsd2/BIFX553-project-1/commit/2b85f281074c255e7b3f14e121b25a
> 9486304abb#commitcomment-20668165>, or mute the thread<https://github.com/
> notifications/unsubscribe-auth/APfYSKvkCixMKdB8sv7JsMGT3myqJq
> lmks5rXkHmgaJpZM4Lv2G0>.
>
> —
> You are receiving this because you commented.
> Reply to this email directly, view it on GitHub
> <https://github.com/wellsd2/BIFX553-project-1/commit/2b85f281074c255e7b3f14e121b25a9486304abb#commitcomment-20668215>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/AYEO3RIsZJoldcXGJnh5sUNlzhmMrnZQks5rXkKqgaJpZM4Lv2G0>
> .
>

—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub<https://github.com/wellsd2/BIFX553-project-1/commit/2b85f281074c255e7b3f14e121b25a9486304abb#commitcomment-20679846>, or mute the thread<https://github.com/notifications/unsubscribe-auth/APfYSBiK27ne1BOAPue64c5YmJKA2Dnfks5rX0JsgaJpZM4Lv2G0>.


@jonfen
#14 Most of the functionality of that ticket is done with this commit.

There isn't a selection dropdown for searching thru existing users, but everything else regarding Racer-Race interaction on this page is take care of.  Could use a few more styles to like a `hover` for the swap icons.

BTW I tweaked the design to fit all the requirements.  At least this page is mostly working now and any improvements will be minor compared to this work.  💥

Enjoy!  I will upload a few screenshots of what it looks like after work today.


@davidguerette I see where you are going with this. Excellent and steady progress!


ok


TeamCity Platform Services :: Environment Manager :: Test Client [Build 1211](http://infra.teamcity.ci.ttldev/viewLog.html?buildId=48306&buildTypeId=PlatformServices_EnvironmentManager_TestClient) outcome was **SUCCESS**
Summary: Tests passed: 33 Build time: 00:06:08


I see uses still there personally.


@nickdotreid you are right, that makes a lot of sense! Thanks for pointing that out.


@RubenVerborgh I have no idea! - the comment has been there since I came on board.

On the contrary, I've been planning to take a look at what the latest versions of N3.js are up to, and curious to follow the rdfjs compatibility progress there. (Perfect, thanks for the link to the branch!) With an eye towards updating rdflib's N3 dep to the later versions.


Ja, das muss ich mir selbst nochmal genauer anschaun. Dürfte stark mti der HTML-Struktur zu tun haben, wie das konfiguriert gehört.


Does this also address the `/f02_prod` issue?


I also added a folder which contains a copy of the php API code.
this code will be hosted online to get the required information to the app's new jsfunction.js file which will feed information to the the controllers.


Forgot to write a comment.
Was just going to be complaints so there's the summary of what the commit comment would be,


https://github.com/drewnoakes/metadata-extractor-dotnet/issues/35

https://github.com/drewnoakes/metadata-extractor-dotnet/pull/36


to chyba bedzie kiepskie. Raczej sie nie daje na stale wysokosci. Chyba ze masz grafike  jako banner stala. To jakos inaczej trzeba rozwiazac


odstepy :)


Rohit Sir had asked me to create that field to save the amount of money that the user will pay us.


For reference: https://github.com/ezsystems/ezplatform-solr-search-engine/pull/72#issuecomment-267569608

The issue was fixed in `1.2.1` of `ezsystems/ezplatform-solr-search-engine`: https://github.com/ezsystems/ezplatform-solr-search-engine/pull/85


zamiast br powinno sie to zalatwic css


Ah, thanks! I saw the minify stuff in `package.json` but wasn't sure where it was being used so I rolled my own. I also included the external resources that are currently being served via cdn. Any reason you decided not to include those in your minification? After gzip, it brings the whole thing down to a single ~223kb hit.

On a fast wired connection it probably makes little difference but it should add up on mobile which is where I'm primarily going to be using this.


Currently, commit includes the unit test for DynamoDB config class.
Working on DynamoDB client mocking, for unit testing the complete functionality.


It's at stage 2 and not finalised.


Relation between this commit & issue #8 was made by a mistake


@dideler thanks

I've also shared my experience in the [comments below](https://github.com/mathiasbynens/dotfiles/commit/a3f91f67e07b6b31760b52320e0e890f93ff4e97#commitcomment-4555932).

I would definitely consider to leave this at the default value of `3`


It does :)

On 31 Jan 2017 3:29 p.m., "Marcus Ottosson" <notifications@github.com>
wrote:

> Does this also address the /f02_prod issue?
>
> —
> You are receiving this because you commented.
> Reply to this email directly, view it on GitHub
> <https://github.com/mindbender-studio/core/commit/89a8500069f8ddd22ff5c8a10137ed50026e6021#commitcomment-20679995>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/AXV2oKJEEzjat2h7rr-HmFvlewKYNMVmks5rX0U4gaJpZM4Lycru>
> .
>


Hello,

The use of a constant could optimize out the if branch at compile time.

Regards.


fixed in last release with `type(of: self)` which is more general


umm i noted too that i cannot update without a registration user.. damm... maybe my version 12.0.X also could have that bug.. well i have and idea..

tell me what are (detailed) the bug and i can made some effors to take and upgrade trick with some friends, and then share it with all a feedback or files also


test


This was the line crashing when `creationTime` was **after** `DateTime.now` - you can't create an `Interval` like that.


I have a lot of errors, include the
[ERROR] :  art:   at dk.napp.drawer.DrawerProxy.handleMessage(DrawerProxy.java:96)


- [ ] code

- [ ] test

- [ ] review


I admit I don't understand why this is wrong. When I test it without onChange handler, it the checkbox just does not allow changing the state (so if it's checked, it stays checked and vice versa). What else is expected of it / the code? (From my perspective, it does what it's supposed to do and does not introduce errors, so I suppose I'm missing something here.)


😂 when beginners code


it worked.


Or is it about the warning from propType? That either 'onChange' or 'readOnly' should be set?


Use $app instead of $this->app.


@nicpottier thanks, that'd be Praekelt.org & https://github.com/praekeltfoundation


Github me donne de mauvaise infos :)

https://help.github.com/articles/adding-images-to-wikis/


broken! should be `import java.util.ArrayList;`


Hi,

This commit overrides this pull request : https://github.com/primefaces/primeng/pull/1741

Is it normal ? Does the PR contains any bugs ?

Thanks :-)


- [ ] code
- [ ] test
- [ ] review


Oops, updated.


TeamCity Platform Services :: Environment Manager 2 :: Package [Build 3.27.0](http://infra.teamcity.ci.ttldev/viewLog.html?buildId=48316&buildTypeId=PlatformServices_EnvironmentManager2_Package) outcome was **SUCCESS**
Summary: Running Build time: 00:00:42


TeamCity OTA+ :: rvi_sota_server :: ci [Build 2048](http://teamcity.prod01.internal.advancedtelematic.com:8111/viewLog.html?buildId=23244&buildTypeId=ota_plus_RviSotaServer_Ci) is now running


@QuiteQuite I'm aware just waiting to be to be on a computer again


TeamCity Platform Services :: Environment Manager 2 :: Package [Build 3.27.0-pre-17-g6707173](http://infra.teamcity.ci.ttldev/viewLog.html?buildId=48320&buildTypeId=PlatformServices_EnvironmentManager2_Package) outcome was **FAILURE**
Summary: Snapshot dependency failed: ... Test Server Build time: 00:00:01


@Seldaek what happened here?

We're getting failed inspections (from QA tools and PhpStorm) in our implementations since upgrading to `1.0.0` of this package.

`iterable` isn't valid before PHP 7.1, so this is a problem even for projects targeting PHP `>=7`.

I know you're not *statically* type-hinting, so this doesn't affect functionality - but it's unlikely you can get passing inspections with any tool for code targeting PHP 7.0, and with PHP 7.1 not even supported on Ubuntu yet, it's unlikely projects will be able to get working inspections again anytime soon.

What was wrong with `array|\Traversable`?

Doesn't it mean essentially the same thing?


NN


TeamCity OTA+ :: rvi_sota_server :: ci [Build 2048](http://teamcity.prod01.internal.advancedtelematic.com:8111/viewLog.html?buildId=23244&buildTypeId=ota_plus_RviSotaServer_Ci) outcome was **FAILURE**
Summary: Compilation error: Scala compiler (new) Build time: 00:02:54


TeamCity Platform Services :: Environment Manager 2 :: Package [Build 3.27.0-pre-2-gff1821a](http://infra.teamcity.ci.ttldev/viewLog.html?buildId=48324&buildTypeId=PlatformServices_EnvironmentManager2_Package) outcome was **FAILURE**
Summary: Snapshot dependency failed: ... Test Server Build time: 00:00:02


I pushed a fix to the `\x` typo for now.
Still pending some more analysis on extending standard objects.


oha! die zeile muss ich gleich mal übernehmen...


No need to insult your readers ;-)


You to match `true` and `false`. That'll make this code a lot simpler.


Why was the option to avoid building the docs removed?


what's that ?


It looks like that you're not updated openembedded submodules.
Ofono 1.18 no longer exists in the currently used openembedded-core.


Hi,

It would be awesome if you could release this as I really want to delete the monkeypatch. :)

Thank you!


TeamCity Platform Services :: Environment Manager 2 :: Package [Build 3.27.0-pre-3-gec03101](http://infra.teamcity.ci.ttldev/viewLog.html?buildId=48328&buildTypeId=PlatformServices_EnvironmentManager2_Package) outcome was **SUCCESS**
Summary: Running Build time: 00:00:52


What is the purpose of this variable assignment?


And now my commit combo was broken due to @MagicDroidX merge commit
![http://i.imgur.com/vEbEQWV.png](http://i.imgur.com/vEbEQWV.png)


Technically, you don't have to assign a default value to make it optional. Parameters are optional by default (and default to null, _even when that's not otherwise possible_). E.g.:

```posh
function Test-Parameter {
param([IO.FileAttributes]$Attrib)
$Attrib -eq $Null
}
```


Options break so we're trying to be more diligent about when we use them.


ah, hatte ich schon vom rangle-beispiel übernommen!
dort verwenden die nur:

```
    ngRedux.configureStore(
      rootReducer,
      {},
      middleware,
      devTools.isEnabled() ? [...enhancers, devTools.enhancer()] : enhancers);
```

ich fände es gut die devTools immer dabei zu haben. die datei ist auch nur winzig klein:
https://github.com/angular-redux/ng2-redux/blob/master/src/components/dev-tools.ts


It looks like that you're not update openembedded submodules.
In the currently used openembedded-core nfs-utils version is 1.3.4 instead of 1.3.3.


Reviewed by Rupert


we need to prevent the first slide from getting the back button


1. 前言
-----

安卓属于小团队开发，架构的重要性在很多公司其实不是那么的明显，加上现在的开源框架层出不穷，更好的帮助我们上手android项目的开发。我前两年也在公司主导过项目开发，搭建过不少项目，以前主要的倾向是MVC，导致了activity/fragment过大，而且很多公共功能杂乱在项目中，后期维护起来不方便，最近刚好有时间，重新搭建了一个新的框架。（ps：有建议或者更好想法的可以留言。）

2. 用到的知识点：
----------

UI----面向对象
数据交互----MVP模式
数据库------GreenDao
网络图片加载-----picasso
json解析-----gson
http请求----OKHttp
事件总线----eventbus

----------

以上知识点不熟悉的，可以先熟悉下基本知识，如果已经了解过，可以直接跳过下面的链接，直接看下文的使用。
MVP模式   讲解地址：http://blog.csdn.net/dfskhgalshgkajghljgh/article/details/51317956
GreenDao 讲解地址：http://blog.csdn.net/dfskhgalshgkajghljgh/article/details/51304390
picasso    讲解地址：http://blog.csdn.net/dfskhgalshgkajghljgh/article/details/51684693
OKHttp   讲解地址：鸿神的博客讲解地址：
http://blog.csdn.net/lmj623565791/article/details/47911083
eventbus  讲解地址：http://blog.csdn.net/dfskhgalshgkajghljgh/article/details/51681705

----------

3. 框架整体结构：
----------
![这里写图片描述](http://img.blog.csdn.net/20160612124551431)

4.项目目录结构：
-------
![这里写图片描述](http://img.blog.csdn.net/20160612124751434)

bean---------------------------------------------------存放java model对象
biz-----------------------------------------------------业务模块，根据不能业务建立子模块
bridge-------------------------------------------------底层功能实现跟UI层的衔接层
capabilities--------------------------------------------底层功能具体实现（后期项目迭代到一定程度稳定后会考虑以jar形式导入）
constant-----------------------------------------------常量
ui------------------------------------------------------界面，根据不同业务建立子模块
util-----------------------------------------------------业务层公共方法
view---------------------------------------------------自定义view实现

5.具体解析
------
还是按照大家的习惯思维，从界面--->数据---->网络----->交互，这样的层次讲解。

1）UI层

UI层其实比较简单，主要就是用到面向对象的封装,BaseActivity为基类，同时BaseActivity实现三个接口，分别为CreateInit, PublishActivityCallBack, PresentationLayerFunc，这三个接口的作用依次是：界面初始化，页面跳转封装，页面交互封装。PresentationLayerFunc的具体实现是在PresentationLayerFuncHelper里面，BaseActivity类会初始化该类，把复杂的功能实现抽象出去，轻量化基类。

![这里写图片描述](http://img.blog.csdn.net/20160612131858162)

BaseActivity代码如下所示：

```
/**
 * <基础activity>
 *
 * @author caoyinfei
 * @version [版本号, 2014-3-24]
 * @see [相关类/方法]
 * @since [V1]
 */
public abstract class BaseActivity extends Activity implements CreateInit, PublishActivityCallBack, PresentationLayerFunc, IMvpView, OnClickListener {

    private PresentationLayerFuncHelper presentationLayerFuncHelper;

    /**
     * 返回按钮
     */
    private LinearLayout back;

    /**
     * 标题，右边字符
     */
    protected TextView title, right;

    public BasePresenter presenter;

    public final String TAG = this.getClass().getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        presentationLayerFuncHelper = new PresentationLayerFuncHelper(this);

        initViews();
        initListeners();
        initData();
        setHeader();
        EBApplication.ebApplication.addActivity(this);
        EventBus.getDefault().register(this);
    }

    @Override
    public void setHeader() {
        back = (LinearLayout) findViewById(R.id.ll_back);
        title = (TextView) findViewById(R.id.tv_title);
        right = (TextView) findViewById(R.id.tv_right);
        back.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.ll_back:
                finish();
                break;
        }
    }

    public void onEventMainThread(Event event) {

    }

    @Override
    protected void onResume() {
        EBApplication.ebApplication.currentActivityName = this.getClass().getName();
        super.onResume();
    }

    @Override
    public void startActivity(Class<?> openClass, Bundle bundle) {
        Intent intent = new Intent(this, openClass);
        if (null != bundle)
            intent.putExtras(bundle);
        startActivity(intent);
    }

    @Override
    public void openActivityForResult(Class<?> openClass, int requestCode, Bundle bundle) {
        Intent intent = new Intent(this, openClass);
        if (null != bundle)
            intent.putExtras(bundle);
        startActivityForResult(intent, requestCode);
    }

    @Override
    public void setResultOk(Bundle bundle) {
        Intent intent = new Intent();
        if (bundle != null) ;
        intent.putExtras(bundle);
        setResult(RESULT_OK, intent);
        finish();
    }

    @Override
    public void showToast(String msg) {
        presentationLayerFuncHelper.showToast(msg);
    }

    @Override
    public void showProgressDialog() {
        presentationLayerFuncHelper.showProgressDialog();
    }

    @Override
    public void hideProgressDialog() {
        presentationLayerFuncHelper.hideProgressDialog();
    }

    @Override
    public void showSoftKeyboard(View focusView) {
        presentationLayerFuncHelper.showSoftKeyboard(focusView);
    }

    @Override
    public void hideSoftKeyboard() {
        presentationLayerFuncHelper.hideSoftKeyboard();
    }

    @Override
    protected void onDestroy() {
        EBApplication.ebApplication.deleteActivity(this);
        EventBus.getDefault().unregister(this);
        if (presenter != null) {
            presenter.detachView(this);
        }
        OkHttpManager httpManager = BridgeFactory.getBridge(Bridges.HTTP);
        httpManager.cancelActivityRequest(TAG);
        super.onDestroy();
    }

}
```
PresentationLayerFuncHelper代码如下所示：

```
/**
 * <页面基础公共功能实现>
 *
 * @author caoyinfei
 * @version [版本号, 2016/6/6]
 * @see [相关类/方法]
 * @since [V1]
 */
public class PresentationLayerFuncHelper implements PresentationLayerFunc {

    private Context context;

    public PresentationLayerFuncHelper(Context context) {
        this.context = context;
    }

    @Override
    public void showToast(String msg) {
        ToastUtil.makeText(context, msg);
    }

    @Override
    public void showProgressDialog() {

    }

    @Override
    public void hideProgressDialog() {

    }

    @Override
    public void showSoftKeyboard(View focusView) {

    }

    @Override
    public void hideSoftKeyboard() {

    }
}

```

三个接口，分别为CreateInit, PublishActivityCallBack, PresentationLayerFunc代码如下所示：

```

/**
 * <公共方法抽象>
 *
 * @author caoyinfei
 * @version [版本号, 2014-3-24]
 * @see [相关类/方法]
 * @since [V1]
 */
public interface CreateInit {
    /**
     * 初始化布局组件
     */
    public void initViews();

    /**
     * 增加按钮点击事件
     */
    void initListeners();

    /**
     * 初始化数据
     */
    public void initData();

    /**
     * 初始化公共头部
     */
    public void setHeader();
}

```

```
/**
 * <页面跳转封装>
 *
 * @author caoyinfei
 * @version [版本号, 2016/6/6]
 * @see [相关类/方法]
 * @since [V1]
 */
public interface PublishActivityCallBack {
    /**
     * 打开新界面
     *
     * @param openClass 新开页面
     * @param bundle    参数
     */
    public void startActivity(Class<?> openClass, Bundle bundle);

    /**
     * 打开新界面，期待返回
     *
     * @param openClass 新界面
     * @param requestCode 请求码
     * @param bundle 参数
     */
    public void openActivityForResult(Class<?> openClass, int requestCode, Bundle bundle);

    /**
     * 返回到上个页面
     *
     * @param bundle 参数
     */
    public void setResultOk(Bundle bundle);
}

```

```
/**
 * <页面基础公共功能抽象>
 *
 * @author caoyinfei
 * @version [版本号, 2016/6/6]
 * @see [相关类/方法]
 * @since [V1]
 */
public interface PresentationLayerFunc {
    /**
     * 弹出消息
     *
     * @param msg
     */
    public void showToast(String msg);

    /**
     * 网络请求加载框
     */
    public void showProgressDialog();

    /**
     * 隐藏网络请求加载框
     */
    public void hideProgressDialog();

    /**
     * 显示软键盘
     *
     * @param focusView
     */
    public void showSoftKeyboard(View focusView);

    /**
     * 隐藏软键盘
     */
    public void hideSoftKeyboard();
}

```
对于上层开发而言，工作就比较简单了，比如登录界面（LoginActivity），只要继承BaseActivity则可以了，然后用IDE工具，自动导入必要的override方法。
代码如下：

```
public class LoginActivity extends BaseActivity implements IUserLoginView {

    /**
     * 用户名
     */
    private EditText userName;

    /**
     * 用户密码
     */
    private EditText password;

    /**
     * 登录
     */
    private Button login;

    private LoginPresenter mUserLoginPresenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        setContentView(R.layout.activity_main);
        super.onCreate(savedInstanceState);

        presenter = mUserLoginPresenter = new LoginPresenter();
        mUserLoginPresenter.attachView(this);
    }

    @Override
    public void initViews() {
        userName = (EditText) findViewById(R.id.username);
        password = (EditText) findViewById(R.id.passowrd);
        login = (Button) findViewById(R.id.login);
    }

    @Override
    public void initListeners() {
        login.setOnClickListener(this);
    }

    @Override
    public void initData() {

    }

    @Override
    public void setHeader() {
        super.setHeader();
        title.setText("登录");
    }

    @Override
    public void onEventMainThread(Event event) {
        super.onEventMainThread(event);
        switch (event){
            case IMAGE_LOADER_SUCCESS:
                clearEditContent();
                break;
        }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.login:
                //13914786934   123456  可以登录
                mUserLoginPresenter.login(userName.getText().toString(), password.getText().toString());
                break;
        }
        super.onClick(v);
    }

    @Override
    public void clearEditContent() {
        userName.setText("");
        password.setText("");
    }

    @Override
    public void onError(String errorMsg, String code) {
        showToast(errorMsg);
    }

    @Override
    public void onSuccess() {
        startActivity(HomeActivity.class,null);
    }

    @Override
    public void showLoading() {

    }

    @Override
    public void hideLoading() {

    }
}

```
大家应该看得出，acitivty里面全是接口，开发gg只要把想应实现填到对应的接口中即可，这样实现的好处有几个：
1.每个页面都是这种统一的格式，后期人员流动后维护方便。
2.公共处理，比如title栏，每个页面都有，各个页面去单独实现，代码冗余，这边抽到BaseActivity 里面setHeader（）方法去统一处理，当时各个子类也可以自定义特殊格式，比如title栏上面的titleName的不同。
3.公共方法抽象，避免每个activity重复大量代码。

2）数据交互层
可能有人会看到上面的代码中有MVP的代码，会看不太懂？别急，接下来讲解MVP的作用。
之前activity层既做界面，又做业务逻辑，代码量特别大，动不动几百上千行，之前项目上线的时候，领导让我混淆一下，我当时说，这种代码，过几个月我们自己都看不懂了，还需要混淆吗？哈哈~~当然是开玩笑。
言归正传，我们这边用MVP代替了MVC，从上面activity可以看出，activity只做两件事：1、view的创建。2、用户交互。那业务逻辑我们放在哪里呢？这里我们引入Presenter层，用来专门处理业务逻辑，并通过IMvpView接口实现跟activity的交互（mvp具体讲解，前面已经很详细的介绍过，地址：http://blog.csdn.net/dfskhgalshgkajghljgh/article/details/51317956）

代码如下：
上面我们说过，Presenter与View交互是通过接口。所以我们这里需要定义一个IUserLoginView ，难点就在于应该有哪些方法，我们这个是登录页面，其实有哪些功能，就应该有哪些方法，比如登录成功，失败，弹出加载框这些都要通知ui（Activity）去更新。所以定义了如下方法：
```
/**
 * <功能详细描述>
 *
 * @author caoyinfei
 * @version [版本号, 2016/5/4]
 * @see [相关类/方法]
 * @since [V1]
 */
public interface IMvpView {
    void onError(String errorMsg, String code);

    void onSuccess();

    void showLoading();

    void hideLoading();
}
```

```
/**
 * <功能详细描述>
 *
 * @author caoyinfei
 * @version [版本号, 2016/5/4]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
public interface IUserLoginView extends IMvpView {
    void clearEditContent();
}
```
LoginPresenter 为登录的业务实现类，他需要做两件事：1、业务处理。2.通知页面数据刷新。业务处理很简单，这边不做介绍了。Presenter与页面交互是通过接口实现的，这边通过继承基类BasePresenter，从而实现接口attachView（V view），这边的view是个泛型，在这里，他其实是IUserLoginView，LoginActivity会实现这个接口，在初始化LoginPresenter 的时候，会把自身传过来mUserLoginPresenter.attachView(this);-----这段代码是在LoginActivity的onCreate中，这样 Presenter通知页面刷新就只要通过接口就可以了。

```
/**
 * <基础业务类>
 *
 * @author caoyinfei
 * @version [版本号, 2016/6/6]
 * @see [相关类/方法]
 * @since [V1]
 */
public interface Presenter<V> {
    void attachView(V view);

    void detachView(V view);
}

```

```
/**
 * <基础业务类>
 *
 * @author caoyinfei
 * @version [版本号, 2016/6/6]
 * @see [相关类/方法]
 * @since [V1]
 */
public abstract class BasePresenter<V extends IMvpView> implements Presenter<V> {
    protected V mvpView;

    public void attachView(V view) {
        mvpView = view;
    }

    @Override
    public void detachView(V view) {
        mvpView = null;
    }
}

```

```
/**
 * <功能详细描述>
 *
 * @author caoyinfei
 * @version [版本号, 2016/5/4]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
public class LoginPresenter extends BasePresenter<IUserLoginView> {

    public LoginPresenter() {

    }

    public void login(String useName, String password) {
        //网络层
        mvpView.showLoading();
        SecurityManager securityManager = BridgeFactory.getBridge(Bridges.SECURITY);
        OkHttpManager httpManager = BridgeFactory.getBridge(Bridges.HTTP);

        httpManager.requestAsyncPostByTag(URLUtil.USER_LOGIN, getName(), new ITRequestResult<LoginResp>() {
                    @Override
                    public void onCompleted() {
                        mvpView.hideLoading();
                    }

                    @Override
                    public void onSuccessful(LoginResp entity) {
                        mvpView.onSuccess();
                        EBSharedPrefManager manager = BridgeFactory.getBridge(Bridges.SHARED_PREFERENCE);
                        manager.getKDPreferenceUserInfo().saveString(EBSharedPrefUser.USER_NAME, "abc");
                    }

                    @Override
                    public void onFailure(String errorMsg) {
                        mvpView.onError(errorMsg, "");
                    }

                }, LoginResp.class, new Param("username", useName),
                new Param("pas", securityManager.get32MD5Str(password)));
    }
}
```

```
public class LoginActivity extends BaseActivity implements IUserLoginView {

    /**
     * 用户名
     */
    private EditText userName;

    /**
     * 用户密码
     */
    private EditText password;

    /**
     * 登录
     */
    private Button login;

    private LoginPresenter mUserLoginPresenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        setContentView(R.layout.activity_main);
        super.onCreate(savedInstanceState);

        presenter = mUserLoginPresenter = new LoginPresenter();
        mUserLoginPresenter.attachView(this);
    }

    @Override
    public void initViews() {
        userName = (EditText) findViewById(R.id.username);
        password = (EditText) findViewById(R.id.passowrd);
        login = (Button) findViewById(R.id.login);
    }

    @Override
    public void initListeners() {
        login.setOnClickListener(this);
    }

    @Override
    public void initData() {

    }

    @Override
    public void setHeader() {
        super.setHeader();
        title.setText("登录");
    }

    @Override
    public void onEventMainThread(Event event) {
        super.onEventMainThread(event);
        switch (event){
            case IMAGE_LOADER_SUCCESS:
                clearEditContent();
                break;
        }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.login:
                //13914786934   123456  可以登录
                mUserLoginPresenter.login(userName.getText().toString(), password.getText().toString());
                break;
        }
        super.onClick(v);
    }

    @Override
    public void clearEditContent() {
        userName.setText("");
        password.setText("");
    }

    @Override
    public void onError(String errorMsg, String code) {
        showToast(errorMsg);
    }

    @Override
    public void onSuccess() {
        startActivity(HomeActivity.class,null);
    }

    @Override
    public void showLoading() {

    }

    @Override
    public void hideLoading() {

    }
}
```

3）网络层
网络由于google在6.0后不再使用httpclient，之前项目中通过httpclient实现了网络通信，现在跟随google，换成OKHttp框架。这个框架的讲解不再介绍了，比较简单，我贴一个鸿神的博客讲解地址：
http://blog.csdn.net/lmj623565791/article/details/47911083有兴趣的可以去看看。
我这边做的事情是，对OKHttp再做了一层封装，更方便我们使用。

```
/**
 * <http公共解析库>
 *
 * @author caoyinfei
 * @version [版本号, 2016/6/6]
 * @see [相关类/方法]
 * @since [V1]
 */
public class OkHttpUtil {

    Handler handler = new Handler() {

    };

    private final String TAG = OkHttpUtil.class.getSimpleName();

    private static OkHttpUtil manager;

    private OkHttpClient mOkHttpClient;

    public final int TIMEOUT = 20;

    public final int WRITE_TIMEOUT = 20;

    public final int READ_TIMEOUT = 20;

    /**
     * 请求url集合
     */
    private HashMap<String, Set<String>> requestMap;

    public OkHttpUtil() {
        requestMap = new HashMap<String, Set<String>>();
        mOkHttpClient = new OkHttpClient();

        mOkHttpClient.setConnectTimeout(TIMEOUT, TimeUnit.SECONDS);
        mOkHttpClient.setWriteTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS);
        mOkHttpClient.setReadTimeout(READ_TIMEOUT, TimeUnit.SECONDS);
    }

    public static OkHttpUtil getInstance() {
        if (manager == null) {
            synchronized (OkHttpUtil.class) {
                if (manager == null) {
                    return new OkHttpUtil();
                }
            }
        }
        return manager;
    }
    /*********************************************************** get请求*********************************************************/

    /**
     * 异步Get请求 具体实现
     *
     * @param url             请求url
     * @param iTRequestResult 请求回调
     * @param clazz           Class<T>
     * @param params          请求参数
     * @param <T>             泛型模板
     */
    public <T> void requestAsyncGetEnqueue(String url, ITRequestResult<T> iTRequestResult, Class<T> clazz, Param... params) {
        String constructUrl = constructUrl(url, params);
        Request request = new Request.Builder()
                .get()
                .url(constructUrl)
                .build();
        mOkHttpClient.newCall(request).enqueue(new TRequestCallBack(iTRequestResult, clazz));
    }

    /**
     * 异步Get请求 具体实现（可取消）
     *
     * @param url             请求url
     * @param activityName    请求activityName
     * @param iTRequestResult 请求回调
     * @param clazz           Class<T>
     * @param params          请求参数
     * @param <T>             泛型模板
     */
    public <T> void requestAsyncGetEnqueueByTag(String url, String activityName, ITRequestResult<T> iTRequestResult, Class<T> clazz, Param... params) {
        addRequestUrl(activityName, url);
        String constructUrl = constructUrl(url, params);
        Request request = new Request.Builder()
                .get()
                .url(constructUrl)
                .tag(url)
                .build();
        mOkHttpClient.newCall(request).enqueue(new TRequestCallBack(iTRequestResult, clazz, activityName));
    }

    /**
     * 构造get请求的url
     *
     * @param url    不带参数的url
     * @param params 参数
     * @return 带参数的url
     */
    private String constructUrl(String url, Param... params) {
        StringBuilder sb = new StringBuilder();
        sb.append(url);
        if (params.length != 0) {
            sb.append("?");
        } else {
            return sb.toString();
        }

        for (Param param :
                params) {
            sb.append(param.key + "=" + param.value + "&");
        }
        return sb.toString().substring(0, sb.length() - 1);
    }

    /*********************************************************** post请求*********************************************************/
    /**
     * 异步POST请求  具体实现
     *
     * @param url             请求url
     * @param iTRequestResult 请求回调
     * @param clazz           Class<T>
     * @param params          请求参数
     * @param <T>             泛型模板
     */
    public <T> void requestAsyncPost(String url, ITRequestResult<T> iTRequestResult, Class<T> clazz, Param... params) {
        FormEncodingBuilder builder = new FormEncodingBuilder();
        for (Param param :
                params) {
            builder.add(param.key, param.value);
        }
        RequestBody body = builder.build();
        Request request = new Request.Builder().post(body).url(url).build();
        mOkHttpClient.newCall(request).enqueue(new TRequestCallBack(iTRequestResult, clazz));
    }

    /**
     * 异步POST请求  具体实现（可取消）
     *
     * @param url             请求url
     * @param activityName    请求activityName
     * @param iTRequestResult 请求回调
     * @param clazz           Class<T>
     * @param params          请求参数
     * @param <T>             泛型模板
     */
    public <T> void requestAsyncPostByTag(String url, String activityName, ITRequestResult<T> iTRequestResult, Class<T> clazz, Param... params) {
        addRequestUrl(activityName, url);
        FormEncodingBuilder builder = new FormEncodingBuilder();
        for (Param param :
                params) {
            builder.add(param.key, param.value);
        }
        RequestBody body = builder.build();
        Request request = new Request.Builder().post(body).url(url).tag(url).build();
        mOkHttpClient.newCall(request).enqueue(new TRequestCallBack(iTRequestResult, clazz, activityName));
    }

    /**
     * 异步DELETE请求  具体实现
     *
     * @param url             请求url
     * @param iTRequestResult 请求回调
     * @param clazz           Class<T>
     * @param params          请求参数
     * @param <T>             泛型模板
     */
    public <T> void requestAsyncDelete(String url, ITRequestResult<T> iTRequestResult, Class<T> clazz, Param... params) {
        String finalUrl = constructUrl(url, params);
        Request request = new Request.Builder()
                .delete()
                .url(finalUrl)
                .build();
        mOkHttpClient.newCall(request).enqueue(new TRequestCallBack(iTRequestResult, clazz));
    }
    /*********************************************************** 文件请求*********************************************************/
    /**
     * 异步POST请求 单文件上传
     *
     * @param url             请求url
     * @param file            待上传的文件
     * @param key             待上传的key
     * @param iTRequestResult 请求回调
     * @param clazz           Class<T>
     * @param params          请求参数
     */
    public <T> void requestAsyncPost(String url, File file, String key, ITRequestResult<T> iTRequestResult, Class<T> clazz, Param... params) {
        MultipartBuilder builder = new MultipartBuilder().type(MultipartBuilder.FORM);
        for (Param param :
                params) {
            builder.addFormDataPart(param.key, param.value);
        }
        builder = constructMultipartBuilder(builder, file, key);
        RequestBody body = builder.build();
        Request request = new Request.Builder().post(body).url(url).build();
        mOkHttpClient.newCall(request).enqueue(new TRequestCallBack(iTRequestResult, clazz));
    }

    /**
     * 异步POST请求 单文件上传（可取消）
     *
     * @param url             请求url
     * @param activityName    请求activityName
     * @param file            待上传的文件
     * @param key             待上传的key
     * @param iTRequestResult 请求回调
     * @param clazz           Class<T>
     * @param params          请求参数
     */
    public <T> void requestAsyncPostByTag(String url, String activityName, File file, String key, ITRequestResult<T> iTRequestResult, Class<T> clazz, Param... params) {
        addRequestUrl(activityName, url);
        MultipartBuilder builder = new MultipartBuilder().type(MultipartBuilder.FORM);
        for (Param param :
                params) {
            builder.addFormDataPart(param.key, param.value);
        }
        builder = constructMultipartBuilder(builder, file, key);
        RequestBody body = builder.build();
        Request request = new Request.Builder().post(body).url(url).tag(url).build();
        mOkHttpClient.newCall(request).enqueue(new TRequestCallBack(iTRequestResult, clazz, activityName));
    }

    /**
     * 异步POST请求 多文件上传
     *
     * @param url             请求url
     * @param files           待上传的文件s
     * @param keys            待上传文件的keys
     * @param iTRequestResult 请求回调
     * @param clazz           Class<T>
     * @param params          请求参数
     */
    public <T> void requestAsyncPost(String url, File[] files, String[] keys, ITRequestResult<T> iTRequestResult, Class<T> clazz, Param... params) {
        MultipartBuilder builder = new MultipartBuilder().type(MultipartBuilder.FORM);
        for (Param param :
                params) {
            builder.addFormDataPart(param.key, param.value);
        }
        for (int i = 0; i < files.length; i++) {
            builder = constructMultipartBuilder(builder, files[i], keys[i]);
        }
        RequestBody body = builder.build();
        Request request = new Request.Builder().post(body).url(url).build();
        mOkHttpClient.newCall(request).enqueue(new TRequestCallBack(iTRequestResult, clazz));
    }

    /**
     * 异步POST请求 多文件上传（可取消）
     *
     * @param url             请求url
     * @param activityName    请求activityName
     * @param files           待上传的文件s
     * @param keys            待上传文件的keys
     * @param iTRequestResult 请求回调
     * @param clazz           Class<T>
     * @param params          请求参数
     */
    public <T> void requestAsyncPostByTag(String url, String activityName, File[] files, String[] keys, ITRequestResult<T> iTRequestResult, Class<T> clazz, Param... params) {
        addRequestUrl(activityName, url);
        MultipartBuilder builder = new MultipartBuilder().type(MultipartBuilder.FORM);
        for (Param param :
                params) {
            builder.addFormDataPart(param.key, param.value);
        }
        for (int i = 0; i < files.length; i++) {
            builder = constructMultipartBuilder(builder, files[i], keys[i]);
        }
        RequestBody body = builder.build();
        Request request = new Request.Builder().post(body).url(url).tag(url).build();
        mOkHttpClient.newCall(request).enqueue(new TRequestCallBack(iTRequestResult, clazz, activityName));
    }

    /**
     * 异步POST请求 单图片上传上传
     *
     * @param url             请求url
     * @param files           待上传图片数组
     * @param fileName        待上传图片名
     * @param key             待上传的key
     * @param iTRequestResult 请求回调
     * @param clazz           Class<T>
     * @param params          请求参数
     */
    public <T> void requestAsyncPost(String url, byte[] files, String fileName, String key, ITRequestResult<T> iTRequestResult, Class<T> clazz, Param... params) {
        MultipartBuilder builder = new MultipartBuilder().type(MultipartBuilder.FORM);
        for (Param param :
                params) {
            builder.addFormDataPart(param.key, param.value);
        }
        RequestBody requestBody = RequestBody.create(MediaType.parse("image/*"), files);
        builder.addFormDataPart(key, fileName, requestBody);
        RequestBody body = builder.build();
        Request request = new Request.Builder().post(body).url(url).build();
        mOkHttpClient.newCall(request).enqueue(new TRequestCallBack(iTRequestResult, clazz));
    }

    /**
     * 异步POST请求 单图片上传上传（可取消）
     *
     * @param url             请求url
     * @param activityName    请求activityName
     * @param files           待上传图片数组
     * @param fileName        待上传图片名
     * @param key             待上传的key
     * @param iTRequestResult 请求回调
     * @param clazz           Class<T>
     * @param params          请求参数
     */
    public <T> void requestAsyncPostByTag(String url, String activityName, byte[] files, String fileName, String key, ITRequestResult<T> iTRequestResult, Class<T> clazz, Param... params) {
        addRequestUrl(activityName, url);
        MultipartBuilder builder = new MultipartBuilder().type(MultipartBuilder.FORM);
        for (Param param :
                params) {
            builder.addFormDataPart(param.key, param.value);
        }
        RequestBody requestBody = RequestBody.create(MediaType.parse("image/*"), files);
        builder.addFormDataPart(key, fileName, requestBody);
        RequestBody body = builder.build();
        Request request = new Request.Builder().post(body).url(url).tag(url).build();
        mOkHttpClient.newCall(request).enqueue(new TRequestCallBack(iTRequestResult, clazz, activityName));
    }

    /**
     * 构造多部件builer
     *
     * @param builder 当前实例化MultipartBuilder
     * @param file    待上传文件
     * @param key     对应的参数名
     * @return 构造后的MultipartBuilder
     */
    private MultipartBuilder constructMultipartBuilder(MultipartBuilder builder, File file, String key) {
        String name = file.getName();
        RequestBody requestBody = RequestBody.create(MediaType.parse(guessMimeType(name)), file);
        builder.addFormDataPart(key, name, requestBody);
        return builder;
    }

    /**
     * 获取文件类型
     *
     * @param path
     * @return
     */
    private String guessMimeType(String path) {
        FileNameMap fileNameMap = URLConnection.getFileNameMap();
        String contentTypeFor = fileNameMap.getContentTypeFor(path);
        if (contentTypeFor == null) {
            contentTypeFor = "application/octet-stream";
        }
        return contentTypeFor;
    }

    /**
     * 增加请求标志
     *
     * @param activityName
     * @param url
     */
    private void addRequestUrl(String activityName, String url) {
        if (requestMap.containsKey(activityName)) {
            requestMap.get(activityName).add(url);
        } else {
            Set<String> urlSet = new HashSet<String>();
            urlSet.add(url);
            requestMap.put(activityName, urlSet);
        }
    }

    /**
     * 取消正在请求的url
     *
     * @param url 请求url
     */
    public void cancelRequest(String url) {
        try {
            mOkHttpClient.getDispatcher().cancel(url);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /**
     * 取消当前页面正在的请求
     *
     * @param activityName
     */
    public void cancelActivityRequest(String activityName) {
        try {
            if (requestMap.containsKey(activityName)) {
                Set<String> urlSet = requestMap.get(activityName);
                for (String url : urlSet) {
                    mOkHttpClient.getDispatcher().cancel(url);
                }
                requestMap.remove(activityName);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /*************************************************************
     * 回调方法
     *********************************************************/
    class TRequestCallBack<T> implements Callback {

        private ITRequestResult<T> mITRequestResult;

        private Class<T> clazz;

        private String notifyMsg = "";

        private String activityName;

        public TRequestCallBack(ITRequestResult<T> mITRequestResult, Class<T> clazz) {
            this.mITRequestResult = mITRequestResult;
            this.clazz = clazz;
        }

        public TRequestCallBack(ITRequestResult<T> mITRequestResult, Class<T> clazz, String activityName) {
            this.mITRequestResult = mITRequestResult;
            this.clazz = clazz;
            this.activityName = activityName;
        }

        @Override
        public void onFailure(Request request, IOException e) {
            EBLog.e(TAG, request.toString() + e.toString());
            if (!isHaveActivtyName(activityName)) return;
            notifyMsg = NETWORK_ERROR;
            postErrorMsg();
        }

        @Override
        public void onResponse(Response response) throws IOException {
            if (!isHaveActivtyName(activityName)) return;
            if (response.isSuccessful()) {
                String result = response.body().string(); //方法只能调用一次
                EBLog.i(TAG, result);
                final T res = GsonHelper.toType(result, clazz);
                int code = -1;
                if (res != null && res instanceof BaseResp) {
                    code = ((BaseResp) res).getRetcode();
                    switch (code) {
                        case 000000:
                            postSucessMsg(res);
                            break;
                        case 10005:
                        case 10011:
                            //自动登录
                        default:
                            notifyMsg = ((BaseResp) res).getRetinfo();
                            postErrorMsg();
                            break;
                    }
                } else {
                    notifyMsg = SERVER_ERROR;
                    postErrorMsg();
                }
            } else {
                notifyMsg = NETWORK_ERROR;
                postErrorMsg();
            }
        }

        /**
         * 主线程发送错误消息
         */
        private void postErrorMsg() {
            handler.post(new Runnable() {
                @Override
                public void run() {
                    mITRequestResult.onCompleted();
                    mITRequestResult.onFailure(notifyMsg);
                }
            });
        }

        /**
         * 主线程发送正确消息
         */
        private void postSucessMsg(final T res) {
            handler.post(new Runnable() {
                @Override
                public void run() {
                    mITRequestResult.onCompleted();
                    mITRequestResult.onSuccessful(res);
                }
            });
        }

        /**
         * 当前activity是否存在
         *
         * @param activityName
         */
        private boolean isHaveActivtyName(String activityName) {
            if (GeneralUtils.isNotNullOrZeroLenght(activityName)) {
                return requestMap.containsKey(activityName);
            } else {
                return true;
            }
        }
    }

    public static String SERVER_ERROR = "请求失败，请稍后再试";

    public static String NETWORK_ERROR = "您的网络状况不佳，请检查网络连接";

    public void destory() {
        manager = null;
    }
}

```

```
/**
 * <功能详细描述>
 *
 * @author caoyinfei
 * @version [版本号, 2016/6/8]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
public interface ITRequestResult<T> {

    public void onSuccessful(T entity);

    public void onFailure(String errorMsg);

}

```

```
/**
 * <参数类>
 *
 * @author caoyinfei
 * @version [版本号, 2016/6/8]
 * @see [相关类/方法]
 * @since [V1]
 */
public class Param {
    public Param() {
    }

    public Param(String key, String value) {
        this.key = key;
        this.value = value != null ? value : "";
    }

    public Param(String key, int value) {
        this.key = key;
        this.value = value + "";
    }

    String key;

    String value;
}
```
应该已经很清楚了，我的做的事情有三个：
1.定义ITRequestResult接口，用于处理网络请求后的回调，并且此接口中的回调在主线程中（OKHttp返回接口Callback是在子线程中 ）。
2.TRequestCallBack接口实现。
集中统一处理网络层异常码然后返回到UI层。
集中统一处理网络层正常情况，通过json库，把网络返回解析成java model返回给UI层。
3.get，post，cancel方法封装，方便调用。

4）Bridge层抽象

每个项目中的重复代码特别多，很多项目喜欢抽象公共方法类，但是项目的时间一久，可能你自己都不清楚，这个方法是否定义过，写在哪里，勤快的人会全局搜一遍，有些同学可能会嫌麻烦，自己新建一个util类，写上自己的名字，顿时感觉自己萌萌的。

这边，我们引入了BridgeFactory，用来统一管理基础功能,类似本地服务的实现原理。
BridgeFactory里面实现了文件，网络，数据库，安全等等管理类的实现，并保存了各类管理类的引用。业务层或者上层调用底层实现时，一律通过BridgeFactory去访问，而不是直接的调用。

```
/**
 * <中间连接层>
 *
 * @author caoyinfei
 * @version [版本号, 2016/6/6]
 * @see [相关类/方法]
 * @since [V1]
 */
public class BridgeFactory {

    private static BridgeFactory model;

    private HashMap<String, Object> mBridges;

    private BridgeFactory() {
        mBridges = new HashMap<String, Object>();
    }

    public static void init(Context context) {
        model = new BridgeFactory();
        model.iniLocalFileStorageManager();
        model.initPreferenceManager();
        model.initSecurityManager();
        model.initUserSession();
        model.initCoreServiceManager(context);
        model.initOkHttpManager();
    }

    public static void destroy() {
        model.mBridges = null;
        model = null;
    }

    /**
     * 初始化本地存储路径管理类
     */
    private void iniLocalFileStorageManager() {
        LocalFileStorageManager localFileStorageManager = new LocalFileStorageManager();
        model.mBridges.put(Bridges.LOCAL_FILE_STORAGE, localFileStorageManager);
        BridgeLifeCycleSetKeeper.getInstance().trustBridgeLifeCycle(localFileStorageManager);
    }

    /**
     * 初始化SharedPreference管理类
     */
    private void initPreferenceManager() {
        EBSharedPrefManager ebSharedPrefManager = new EBSharedPrefManager();
        model.mBridges.put(Bridges.SHARED_PREFERENCE, ebSharedPrefManager);
        BridgeLifeCycleSetKeeper.getInstance().trustBridgeLifeCycle(ebSharedPrefManager);
    }

    /**
     * 网络请求管理类
     */
    private void initOkHttpManager() {
        OkHttpManager mOkHttpManager = new OkHttpManager();
        model.mBridges.put(Bridges.HTTP, mOkHttpManager);
        BridgeLifeCycleSetKeeper.getInstance().trustBridgeLifeCycle(mOkHttpManager);
    }

    /**
     * 初始化安全模块
     */
    private void initSecurityManager() {
        SecurityManager securityManager = new SecurityManager();
        model.mBridges.put(Bridges.SECURITY, securityManager);
        BridgeLifeCycleSetKeeper.getInstance().trustBridgeLifeCycle(securityManager);
    }

    /**
     * 初始化用户信息模块
     */
    private void initUserSession() {
    }

    /**
     * 初始化Tcp服务
     *
     * @param context
     */
    private void initCoreServiceManager(Context context) {
    }

    private void initDBManager() {
    }

    /**
     * 通过bridgeKey {@link Bridges}来获取对应的Bridge模块
     *
     * @param bridgeKey {@link Bridges}
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <V extends Object> V getBridge(String bridgeKey) {
        final Object bridge = model.mBridges.get(bridgeKey);
        if (bridge == null) {
            throw new NullPointerException("-no defined bridge-");
        }
        return (V) bridge;
    }
}

```
并且，通过BridgeLifeCycleListener 接口，实现各个底层功能管理类的统一初始化跟销毁工作，保持跟app的生命周期一致。代码如下：

```
/**
 * 如果Bridge层的生命周期和App的生命周期相关（在Application
 * onCreate的时候初始化，在用户双击back键退出），则实现此接口，届时统一初始化和销毁
 */
public interface BridgeLifeCycleListener {
    public void initOnApplicationCreate(Context context);

    public void clearOnApplicationQuit();
}

```
Manager类代码如下：
```
/**
 * <http公共解析库>
 *
 * @author caoyinfei
 * @version [版本号, 2016/6/6]
 * @see [相关类/方法]
 * @since [V1]
 */
public class OkHttpManager implements BridgeLifeCycleListener {

    @Override
    public void initOnApplicationCreate(Context context) {

    }

    /**
     * 异步Get请求 泛型返回
     *
     * @param url             请求url
     * @param iTRequestResult 请求回调
     * @param clazz           Class<T>
     * @param params          请求参数
     * @param <T>             泛型模板
     */
    public <T> void requestAsyncGet(String url, ITRequestResult<T> iTRequestResult, Class<T> clazz, Param... params) {
        OkHttpUtil.getInstance().requestAsyncGetEnqueue(url, iTRequestResult, clazz, params);
    }

    /**
     * 异步Get请求 带tag(关闭页面则取消请求)
     *
     * @param url             请求url
     * @param activityName    请求activityName
     * @param iTRequestResult 请求回调
     * @param clazz           Class<T>
     * @param params          请求参数
     * @param <T>             泛型模板
     */
    public <T> void requestAsyncGetByTag(String url, String activityName, ITRequestResult<T> iTRequestResult, Class<T> clazz, Param... params) {
        OkHttpUtil.getInstance().requestAsyncGetEnqueueByTag(url, activityName, iTRequestResult, clazz, params);
    }

    /**
     * 异步POST请求
     *
     * @param url             请求url
     * @param iTRequestResult 请求回调
     * @param clazz           Class<T>
     * @param params          请求参数
     * @param <T>             泛型模板
     */
    public <T> void requestAsyncPost(String url, ITRequestResult<T> iTRequestResult, Class<T> clazz, Param... params) {
        OkHttpUtil.getInstance().requestAsyncPost(url, iTRequestResult, clazz, params);
    }

    /**
     * 异步POST请求 带tag(关闭页面则取消请求)
     *
     * @param url             请求url
     * @param activityName    请求activityName
     * @param iTRequestResult 请求回调
     * @param clazz           Class<T>
     * @param params          请求参数
     * @param <T>             泛型模板
     */
    public <T> void requestAsyncPostByTag(String url, String activityName, ITRequestResult<T> iTRequestResult, Class<T> clazz, Param... params) {
        OkHttpUtil.getInstance().requestAsyncPostByTag(url, activityName, iTRequestResult, clazz, params);
    }

    /**
     * 异步DELETE请求
     *
     * @param url             请求url
     * @param iTRequestResult 请求回调
     * @param clazz           Class<T>
     * @param params          请求参数
     * @param <T>             泛型模板
     */
    public <T> void requestAsyncDelete(String url, ITRequestResult<T> iTRequestResult, Class<T> clazz, Param... params) {
        OkHttpUtil.getInstance().requestAsyncDelete(url, iTRequestResult, clazz, params);
    }

    /**
     * 异步POST请求 单文件上传
     *
     * @param url             请求url
     * @param file            待上传的文件
     * @param key             待上传的key
     * @param iTRequestResult 请求回调
     * @param clazz           Class<T>
     * @param params          请求参数
     */
    public <T> void requestAsyncPost(String url, File file, String key, ITRequestResult<T> iTRequestResult, Class<T> clazz, Param... params) {
        OkHttpUtil.getInstance().requestAsyncPost(url, file, key, iTRequestResult, clazz, params);
    }

    /**
     * 异步POST请求 单文件上传 带tag(关闭页面则取消请求)
     *
     * @param url             请求url
     * @param activityName    请求activityName
     * @param file            待上传的文件
     * @param key             待上传的key
     * @param iTRequestResult 请求回调
     * @param clazz           Class<T>
     * @param params          请求参数
     */
    public <T> void requestAsyncPostByTag(String url, String activityName, File file, String key, ITRequestResult<T> iTRequestResult, Class<T> clazz, Param... params) {
        OkHttpUtil.getInstance().requestAsyncPostByTag(url, activityName, file, key, iTRequestResult, clazz, params);
    }

    /**
     * 异步POST请求 多文件上传
     *
     * @param url             请求url
     * @param files           待上传的文件s
     * @param keys            待上传文件的keys
     * @param iTRequestResult 请求回调
     * @param clazz           Class<T>
     * @param params          请求参数
     */
    public <T> void requestAsyncPost(String url, File[] files, String[] keys, ITRequestResult<T> iTRequestResult, Class<T> clazz, Param... params) {
        OkHttpUtil.getInstance().requestAsyncPost(url, files, keys, iTRequestResult, clazz, params);
    }

    /**
     * 异步POST请求 多文件上传  带tag(关闭页面则取消请求)
     *
     * @param url             请求url
     * @param activityName    请求activityName
     * @param files           待上传的文件s
     * @param keys            待上传文件的keys
     * @param iTRequestResult 请求回调
     * @param clazz           Class<T>
     * @param params          请求参数
     */
    public <T> void requestAsyncPostByTag(String url, String activityName, File[] files, String[] keys, ITRequestResult<T> iTRequestResult, Class<T> clazz, Param... params) {
        OkHttpUtil.getInstance().requestAsyncPostByTag(url, activityName, files, keys, iTRequestResult, clazz, params);
    }

    /**
     * 异步POST请求 单图片上传上传
     *
     * @param url             请求url
     * @param files           待上传图片数组
     * @param fileName        待上传图片名
     * @param key             待上传的key
     * @param iTRequestResult 请求回调
     * @param clazz           Class<T>
     * @param params          请求参数
     */
    public <T> void requestAsyncPost(String url, byte[] files, String fileName, String key, ITRequestResult<T> iTRequestResult, Class<T> clazz, Param... params) {
        OkHttpUtil.getInstance().requestAsyncPost(url, files, fileName, key, iTRequestResult, clazz, params);
    }

    /**
     * 异步POST请求 单图片上传上传 带tag(关闭页面则取消请求)
     *
     * @param url             请求url
     * @param activityName    请求activityName
     * @param files           待上传图片数组
     * @param fileName        待上传图片名
     * @param key             待上传的key
     * @param iTRequestResult 请求回调
     * @param clazz           Class<T>
     * @param params          请求参数
     */
    public <T> void requestAsyncPostByTag(String url, String activityName, byte[] files, String fileName, String key, ITRequestResult<T> iTRequestResult, Class<T> clazz, Param... params) {
        OkHttpUtil.getInstance().requestAsyncPostByTag(url, activityName, files, fileName, key, iTRequestResult, clazz, params);
    }

    /**
     * 取消正在请求的url
     *
     * @param url
     */
    public void cancelRequest(String url) {
        OkHttpUtil.getInstance().cancelRequest(url);
    }

    /**
     * 取消当前页面正在请求的请求
     *
     * @param activity
     */
    public void cancelActivityRequest(String activity) {
        OkHttpUtil.getInstance().cancelActivityRequest(activity);
    }

    @Override
    public void clearOnApplicationQuit() {
        OkHttpUtil.getInstance().destory();
    }
}

```

5）多页面交互
可能会有多个页面存在逻辑关系，比如HomeActivity加载图片成功后，要通知LoginActivity上面的EditText内容清除，当然这个需求是我瞎扯的，然而真正开发中的需求何尝不是这样呢。我擦，无意间流露出对产品经理的喜爱~~~~。
可能会有人用广播，用观察者，应该还有人会定义静态方法，去直接调用，不管怎么，我不评价，因为我之前也都用过。。。。
我们这边改成eventbus去做页面之间的交互，eventbus的好处，相信大家都清楚。
EventBus是一款针对Android优化的发布/订阅事件总线。主要功能是替代Intent,Handler,BroadCast在Fragment，Activity，Service，线程之间传递消息.优点是开销小，代码更优雅。以及将发送者和接收者解耦。

使用的代码如下：

HomeActivity.java类
```
 @Override
    public void initData() {
        Picasso.with(this).load("http://i.imgur.com/DvpvklR.png").resize(DensityUtil.dip2px(this,200), DensityUtil.dip2px(this,200)).centerCrop().into(image);
        EventBus.getDefault().post(Event.IMAGE_LOADER_SUCCESS);//发送刷新通知
    }
```
LoginActivity.java类

```
 @Override
    public void onEventMainThread(Event event) {
        super.onEventMainThread(event);
        switch (event){
            //接受通知
            case IMAGE_LOADER_SUCCESS:
                clearEditContent();
                break;
        }
    }
```

```
 /**
 * <事件类型>
 *
 * @author caoyinfei
 * @version [版本号, 2016/6/6]
 * @see [相关类/方法]
 * @since [V1]
 */
public enum Event {
    /**
     * 图片成功
     */
    IMAGE_LOADER_SUCCESS,

}
```
6）其他公共类的封装
当然还有很多类的封装，框架中都有涉及，这边由于时间问题不一一介绍了，大家可以自行研究。

 - Gson的封装使用
 - Log的封装，方便上线，调整优先级，关闭日志
 - FileUtil常用文件操作的封装
 - LocalFileStorageManager  本地文件缓存目录封装
 - SecurityUtils 加解密的封装(前面有文章介绍过原理，代码中不宜出现加密过程，暂时删除了)
 - 数据库封装 （前面有文章介绍过GreenDao，并有例子，这边不介绍了）
 http://blog.csdn.net/dfskhgalshgkajghljgh/article/details/51304390
 ......

6.其他思考
----

1.Android依赖注入的框架：Dagger、RoboGuice和ButterKnife，依赖注入的框架，见仁见智，有些人很推崇，但是我个人不怎么喜欢，首先影响了代码结构，代码交接成本高，个人小项目可以尝试使用，大的公司项目还是在考虑。
2.rxjava先在个人项目中使用，熟练后再在框架中会引入。

由于框架暂时还没有在项目中试用一段时间，细节方面，好的或者不足的还希望大家勿喷，提出来我会持续改进。

----------

欢迎一起交流讨论
群号：469890293


ja, und hier unterscheidet sich die Implementierung von deinem Snippet!?


we have to remove it from all docs since vpaas doesnt support </br>


According to the analytics, in the last 30 days, out of 25,417 libevent installs, that option was used ... once.


@ramonh  Hello, just wondering if you mean 2017 instead of 2016?  Would like to attend if the meetup happens tomorrow? Cheers.


Hi @jesusbagpuss - I've just made a quick update to this as encountered an issue where EPrints decides to pad out any short year dates with leading zero's which Time::Piece doesn't handle very gracefully. This is aimed to resolve those situations as well as any situations where EPrints may already return just 2 digits for a year (because this should be valid considering Time::Piece is able to interpret the most sensible value in such a case). Let me know if you think it all looks sensible!

In the meantime I see there are a couple of other updates previously committed and you said you had some stuff on the way, so I suspect we could release a new version of this shortly?


Interesting thought. Looks like we need the `Principal` anyway for the return value.


KKJJJ


Wondering if there is anything else we should allow big stacks for.


Hm, I was going to use the real entry name in the exception message, but looks like missed that. Although it feels like that name doesn't matter. We need `AMQP` and that's all. Anything else doesn't work.

So, we can revert this variable or just leave as is, because I don't see how it hurts.

Thank you for coming with review!


Splatting? I'm pretty sure this is off-topic here -- I'm not sure how you're thinking of using splatting to make it optional?


確認済


dead...your lame


ok done! check next commit!


I get that nothing will break, I just assumed it was good practise to avoid running it if it wasn't necessary... Though by the time you've checked that there probably isn't alot in it time wise I guess 👍


Has this worked for you for proxying websockets?  I'm struggling to get this to work.


![](https://github.trello.services/images/mini-trello-icon.png) [[Anwendung] Bewertungsfunktion optimieren](https://trello.com/c/xmc8D4Bv/16-anwendung-bewertungsfunktion-optimieren)


Grovelling apologies, LraiZer! Didn't realiZe that I'd uploaded this file into /var/etc by mistake, until you pointed this gaffe out above.

Next mistake was thinking that the tv-channels.ref file was personal to my devbox only. Wrong! It's part of ABS (and conditional epgusermaps cleanup) in C16 now! So I dopily deleted the right file in the right folder, and left the wrong file in the wrong folder!

All rectified and double-checked, so build should work again overnight? Cheers- AL (Zeimers)


@michield I made a mess of trying to make a pull request for the dev33 branch, and in deleting my local copy also removed the branch from this repository instead of my clone.
I think it is back to where it was but also has my proposed change. There is still a problem in removing the '4' characters from UUIDs. The code is replacing one character by two. My change fixes that and also tries to clarify the code layout.


# Google
^(.*\.)?2mdn\.net$
^(.*\.)?admob\.com$
^(.*\.)?ads\.gmodules\.com$
^(.*\.)?ads\.google\.com$
^(.*\.)?afd\.l\.google\.com$
^(.*\.)?badad\.googleplex\.com$
^(.*\.)?csi\.gstatic\.com$
^(.*\.)?doubleclick\.com$
^(.*\.)?doubleclick\.net$
# Disable customized fonts
^(.*\.)?fonts\.googleapis\.com$
^(.*\.)?googleadsserving\.cn$
^(.*\.)?googlecommerce\.com$
^(.*\.)?googletagmanager\.com$
^(.*\.)?mobileads\.google\.com$
^(.*\.)?pagead-tpc\.l\.google\.com$
^(.*\.)?pagead\.google\.com$
^(.*\.)?pagead\.l\.google\.com$
^(.*\.)?service\.urchin\.com$


sorry about that, just pushed v1.4.1 to rubygems with this fix


I downloaded this file and when I opened it in GM Studio, it complained about the lack of sprites. I could not look at the code because of that error. I'm guessing you need to include those assets as well if you want me to take a look at the save/load code.

Or maybe you could locate the script files that GMS generates and just include those on this repo if you don't feel like sharing everything on here.


Danke für den Hinweis.

Das "Achtung" müsste ich umschreiben: alle Versionen ab 0.3.0 funktionieren mit e10s. Aber du hast Recht - kann man eigentlich entfernen.


ㄸ


Collaborator: Review for this commit was created. [Link to review](http://127.0.0.1:8080/ui#review:id=26)


NP; it can remain on the other branches - I just pushed a commit using the `Supplier` variant to master.


看[小米推送的文档](http://dev.xiaomi.com/doc/?p=544#d5e12)，没看到这个action呀，这个处方真的有用吗？


Congratulations on the most shit commit message yet.


I don't think this makes sense to implement in async proper any more.


Shouldn't this be `...sources.gz`?


Additional changes have been made to conform to the coding standards and committed to QC-91.

Reviewed by Farhaad.


ach komm, du wolltest doch nur die 🌟  aktualisieren ;-)


Oh, nevermind, I failed to grep correctly. I was led astray by these messages during a docker run:
```
Failed posting state to 'http://192.168.168.168:7778/update': Post http://192.168.168.168:7778/update: dial tcp 192.168.168.168:7778: getsockopt: connection refused
```
7778 appears to be the HAProxy port, which if it's disabled, seems weird to be sending traffic there.


clearly


Сделал, спс, получается я удаляю файлы которые остались (
http://prntscr.com/e2pqjz)
И делаю:
$ git merge c твоей веткой
$ push -f

2017-01-30 3:56 GMT+05:00 Vyacheslav Semushin <notifications@github.com>:

> Похоже, что не все так ужасно:
>
> $ git checkout gh001_update_series
> $ git diff master gh001_update_series >changes.diff
> $ git reset --hard HEAD~2
> $ git rebase master gh001_update_series
> $ cat changes.diff|patch -p1
> $ git add src/main/resources/liquibase/version/0.4/2017-01-29--add_updater_data_to_collections.xml
> $ git commit -a
> $ git push -f
> $ rm -fv changes.diff
>
> —
> You are receiving this because you authored the thread.
> Reply to this email directly, view it on GitHub
> <https://github.com/php-coder/mystamps/commit/ec5be531ed6157efd203f227f1f574f82b7fda89#commitcomment-20656128>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/AVJDAbXdXdE3EKGtxVvfwVoOgeeRiYydks5rXRkhgaJpZM4Lw7_h>
> .
>


- It was the idea of Tom Truscott and Jim Ellis in 1979.


TeamCity Platform Services :: Environment Manager 2 :: Package [Build 3.27.0-pre-21-g7bf8178](http://infra.teamcity.ci.ttldev/viewLog.html?buildId=48338&buildTypeId=PlatformServices_EnvironmentManager2_Package) outcome was **SUCCESS**
Summary: Running Build time: 00:00:54


TeamCity OTA+ :: rvi_sota_server :: ci [Build 2049](http://teamcity.prod01.internal.advancedtelematic.com:8111/viewLog.html?buildId=23250&buildTypeId=ota_plus_RviSotaServer_Ci) is now running


Thanks for that...


What are the for-loops doing in this function?  To me, it appears the return statement will cause the function to return after evaluating only the first interface of the first configuration in the device.  Are the for-loops used because the object type of device does not allow direct indexing (i.e. "cfg = device[0]") ?


Please don't use `rgb()`. And reuse colors that are already defined (e.g. `-fx-accent`)


The information is accurate.


Yes, possibly :-)


lole


And for this too. Instagram is not working because of this.


Ok, reworked it a bit to make it more readable.


TeamCity Platform Services :: Environment Manager 2 :: Package [Build 3.27.0-pre-9-gb77b8ad](http://infra.teamcity.ci.ttldev/viewLog.html?buildId=48342&buildTypeId=PlatformServices_EnvironmentManager2_Package) outcome was **SUCCESS**
Summary: Running Build time: 00:00:36


[inst/examples/globe/server.R:5:55:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/inst/examples/globe/server.R#L5) *style:* **Commas should always have a space after.**
```r
earth_dark <- list(img=system.file("images/world.jpg",package="threejs"),
                                                      ^
```
[inst/examples/globe/server.R:14:42:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/inst/examples/globe/server.R#L14) *style:* **Commas should always have a space after.**
```r
     world.cities[order(world.cities$pop,decreasing=TRUE)[1:input$N],]
                                         ^
```
[inst/examples/globe/server.R:14:70:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/inst/examples/globe/server.R#L14) *style:* **Commas should always have a space after.**
```r
     world.cities[order(world.cities$pop,decreasing=TRUE)[1:input$N],]
                                                                     ^
```
[inst/examples/globe/server.R:20:38:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/inst/examples/globe/server.R#L20) *style:* **Commas should always have a space after.**
```r
    col <- rainbow(10, start=2.8 / 6,end=3.4 / 6)
                                     ^
```
[inst/examples/globe/server.R:30:26:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/inst/examples/globe/server.R#L30) *style:* **Commas should never have a space before.**
```r
    args <- c(earth_dark , list(lat=v$cities$lat, long=v$cities$long, value=v$value, color=v$color, atmosphere=TRUE))
                        ~^
```
[inst/examples/scatterplot/server.R:15:40:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/inst/examples/scatterplot/server.R#L15) *style:* **Commas should always have a space after.**
```r
    color <- rep(rainbow(input$colors),length.out = nrow(data))
                                       ^
```
[R/globe.R:167:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/globe.R#L167) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if(missing(lat) || missing(long))
    ^
```
[R/globe.R:174:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/globe.R#L174) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if(length(i) > 0)
    ^
```
[R/globe.R:177:7:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/globe.R#L177) *style:* **Place a space before left parenthesis, except in a function call.**
```r
    if(any(j))
      ^
```
[R/globe.R:183:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/globe.R#L183) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if(length(i) > 0)
    ^
```
[R/globe.R:186:7:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/globe.R#L186) *style:* **Place a space before left parenthesis, except in a function call.**
```r
    if(any(j))
      ^
```
[R/globe.R:192:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/globe.R#L192) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if(length(i) > 0) bg <- substr(bg, 1, 7)
    ^
```
[R/globe.R:193:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/globe.R#L193) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if(missing(arcs))
    ^
```
[R/globe.R:207:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/globe.R#L207) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if(length(additional_args) > 0) options <- c(options, additional_args)
    ^
```
[R/globe.R:209:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/globe.R#L209) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if("bodycolor" %in% names(options))
    ^
```
[R/globe.R:211:20:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/globe.R#L211) *style:* **Commas should always have a space after.**
```r
    i <- grep("^#",options$bodycolor)
                   ^
```
[R/globe.R:212:7:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/globe.R#L212) *style:* **Place a space before left parenthesis, except in a function call.**
```r
    if(length(i) > 0) options$bodycolor <- substr(options$bodycolor, 1, 7)
      ^
```
[R/globe.R:214:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/globe.R#L214) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if("emissive" %in% names(options))
    ^
```
[R/globe.R:217:7:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/globe.R#L217) *style:* **Place a space before left parenthesis, except in a function call.**
```r
    if(length(i) > 0) options$emissive <- substr(options$emissive, 1, 7)
      ^
```
[R/globe.R:219:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/globe.R#L219) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if("lightcolor" %in% names(options))
    ^
```
[R/globe.R:222:7:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/globe.R#L222) *style:* **Place a space before left parenthesis, except in a function call.**
```r
    if(length(i) > 0) options$lightcolor <- substr(options$lightcolor, 1, 7)
      ^
```
[R/graph.R:144:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/graph.R#L144) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if(is.list(g) && "igraph" %in% class(g[[1]]))
    ^
```
[R/graph.R:149:7:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/graph.R#L149) *style:* **Place a space before left parenthesis, except in a function call.**
```r
    if(missing(edge.color)) edge.color <- lapply(g, function(x) { ifel(is.null(E(x)$color), NA, E(x)$color) })
      ^
```
[R/graph.R:150:7:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/graph.R#L150) *style:* **Place a space before left parenthesis, except in a function call.**
```r
    if(missing(layout)) layout <- lapply(g, function(x) {ifel(is.null(x$layout), layout_with_fr(x, dim=3, niter=50), x$layout)})
      ^
```
[R/graph.R:151:12:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/graph.R#L151) *style:* **Place a space before left parenthesis, except in a function call.**
```r
    else if(is.function(layout)) layout <- lapply(g, layout)
           ^
```
[R/graph.R:152:12:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/graph.R#L152) *style:* **Place a space before left parenthesis, except in a function call.**
```r
    else if(!is.list(layout)) layout <- list(layout)
           ^
```
[R/graph.R:153:7:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/graph.R#L153) *style:* **Place a space before left parenthesis, except in a function call.**
```r
    if(missing(vertex.color)) vertex.color <- lapply(g, function(x) ifel(is.null(V(x)$color), "orange", V(x)$color))
      ^
```
[R/graph.R:157:7:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/graph.R#L157) *style:* **Place a space before left parenthesis, except in a function call.**
```r
    if(!("igraph" %in% class(g))) stop("g must be an igraph object")
      ^
```
[R/graph.R:161:7:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/graph.R#L161) *style:* **Place a space before left parenthesis, except in a function call.**
```r
    if(missing(layout)) layout <- list(ifel(is.null(g$layout), layout_with_fr(g, dim=3, niter=50), g$layout))
      ^
```
[R/graph.R:162:12:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/graph.R#L162) *style:* **Place a space before left parenthesis, except in a function call.**
```r
    else if(is.function(layout)) layout <- list(layout(g))
           ^
```
[R/graph.R:163:12:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/graph.R#L163) *style:* **Place a space before left parenthesis, except in a function call.**
```r
    else if(!is.list(layout)) layout <- list(layout)
           ^
```
[R/graph.R:164:7:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/graph.R#L164) *style:* **Place a space before left parenthesis, except in a function call.**
```r
    if(missing(vertex.color)) vertex.color <- list(ifel(is.null(V(g)$color), "orange", V(g)$color))
      ^
```
[R/graph.R:165:7:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/graph.R#L165) *style:* **Place a space before left parenthesis, except in a function call.**
```r
    if(missing(edge.color)) edge.color <- ifel(is.null(E(g)$color), NA, E(g)$color)
      ^
```
[R/graph.R:168:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/graph.R#L168) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if(missing(vertex.size)) vertex.size <- ifel(is.null(V(g)$size), 2, V(g)$size / 7)
    ^
```
[R/graph.R:169:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/graph.R#L169) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if(missing(vertex.shape)) vertex.shape <- ifel(is.null(V(g)$shape), "circle", V(g)$shape)
    ^
```
[R/graph.R:170:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/graph.R#L170) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if(missing(vertex.label)) vertex.label <- ifel(is.null(V(g)$label), NA, V(g)$label)
    ^
```
[R/graph.R:171:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/graph.R#L171) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if(missing(edge.width)) edge.width <- ifel(is.null(E(g)$width), 1, E(g)$width)
    ^
```
[R/graph.R:172:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/graph.R#L172) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if(length(edge.width) > 1)
    ^
```
[R/graph.R:177:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/graph.R#L177) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if(missing(edge.alpha))
    ^
```
[R/graph.R:179:7:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/graph.R#L179) *style:* **Place a space before left parenthesis, except in a function call.**
```r
    if(length(E(g)) > 1000) edge.alpha <- 0.3
      ^
```
[R/graph.R:181:7:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/graph.R#L181) *style:* **Place a space before left parenthesis, except in a function call.**
```r
    if(!is.null(E(g)$alpha)) edge.alpha <- E(g)$alpha
      ^
```
[R/graph.R:187:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/graph.R#L187) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if(!is.list(main)) main <- as.list(main)
    ^
```
[R/graph.R:192:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/graph.R#L192) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if("pie" %in% u) pch <- gsub("pie", "@", pch)
    ^
```
[R/graph.R:193:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/graph.R#L193) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if("sphere" %in% u) pch <- gsub("sphere", "o", pch)
    ^
```
[R/graph.R:194:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/graph.R#L194) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if("square" %in% u) pch <- gsub("square", ".", pch)
    ^
```
[R/graph.R:195:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/graph.R#L195) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if("csquare" %in% u) pch <- gsub("csquare", ".", pch)
    ^
```
[R/graph.R:196:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/graph.R#L196) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if("rectangle" %in% u) pch <- gsub("rectangle", ".", pch)
    ^
```
[R/graph.R:197:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/graph.R#L197) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if("crectangle" %in% u) pch <- gsub("crectangle", ".", pch)
    ^
```
[R/graph.R:198:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/graph.R#L198) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if("vrectangle" %in% u) pch <- gsub("vrectangle", ".", pch)
    ^
```
[R/graph.R:203:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/graph.R#L203) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if("click" %in% names(opts))
    ^
```
[R/graph.R:208:1:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/graph.R#L208) *style:* **Trailing whitespace is superfluous.**
```r

^~
```
[R/graph.R:212:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/graph.R#L212) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if(!all(unlist(Map(is.na, edge.color)))) options$lcol <- edge.color
    ^
```
[R/graph.R:213:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/graph.R#L213) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if(!(length(vertex.label) == 1 && is.na(vertex.label))) options$labels <- vertex.label
    ^
```
[R/scatterplot.R:214:7:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/scatterplot.R#L214) *style:* **Place a space before left parenthesis, except in a function call.**
```r
    if(is.matrix(x))
      ^
```
[R/scatterplot.R:218:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/scatterplot.R#L218) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if(is.list(x))
    ^
```
[R/scatterplot.R:222:18:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/scatterplot.R#L222) *style:* **Place a space before left parenthesis, except in a function call.**
```r
        ans <- if(is.data.frame(y)) as.matrix(y) else y
                 ^
```
[R/scatterplot.R:233:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/scatterplot.R#L233) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if(missing(pch)) pch <- rep("o", NROW)
    ^
```
[R/scatterplot.R:234:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/scatterplot.R#L234) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if(length(pch) != NROW) pch <- rep_len(pch, NROW)
    ^
```
[R/scatterplot.R:238:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/scatterplot.R#L238) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if(!is.list(color)) color <- list(color)
    ^
```
[R/scatterplot.R:243:39:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/scatterplot.R#L243) *style:* **Commas should always have a space after.**
```r
  bg <- sub("^(#[[:xdigit:]]{6}+).*$","\\1", bg, perl = TRUE)
                                      ^
```
[R/scatterplot.R:289:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/scatterplot.R#L289) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if("center" %in% names(options) && options$center) # not yet documented, useful for graph
    ^
```
[R/scatterplot.R:294:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/scatterplot.R#L294) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if(!("linealpha" %in% names(options))) options$linealpha <- 1
    ^
```
[R/scatterplot.R:295:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/scatterplot.R#L295) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if(!("alpha" %in% names(options))) options$alpha <- a
    ^
```
[R/scatterplot.R:305:40:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/scatterplot.R#L305) *style:* **Commas should always have a space after.**
```r
    num.ticks <- pmax(1, num.ticks[c(1,3,2)])
                                       ^
```
[R/scatterplot.R:305:42:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/scatterplot.R#L305) *style:* **Commas should always have a space after.**
```r
    num.ticks <- pmax(1, num.ticks[c(1,3,2)])
                                         ^
```
[R/scatterplot.R:313:7:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/scatterplot.R#L313) *style:* **Place a space before left parenthesis, except in a function call.**
```r
    if(flip.y) t3 <- t3[length(t3):1]
      ^
```
[R/scatterplot.R:319:9:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/scatterplot.R#L319) *style:* **Place a space before left parenthesis, except in a function call.**
```r
      if(any(i))
        ^
```
[R/scatterplot.R:329:7:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/scatterplot.R#L329) *style:* **Place a space before left parenthesis, except in a function call.**
```r
    if(!is.null(x.ticklabs)) options$xticklab <- x.ticklabs
      ^
```
[R/scatterplot.R:330:7:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/scatterplot.R#L330) *style:* **Place a space before left parenthesis, except in a function call.**
```r
    if(!is.null(y.ticklabs)) options$zticklab <- y.ticklabs
      ^
```
[R/scatterplot.R:331:7:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/scatterplot.R#L331) *style:* **Place a space before left parenthesis, except in a function call.**
```r
    if(!is.null(z.ticklabs)) options$yticklab <- z.ticklabs
      ^
```
[R/scatterplot.R:338:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/scatterplot.R#L338) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if("from" %in% names(options))
    ^
```
[R/scatterplot.R:340:7:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/scatterplot.R#L340) *style:* **Place a space before left parenthesis, except in a function call.**
```r
    if(!("to" %in% names(options))) stop("both from and to must be specified")
      ^
```
[R/scatterplot.R:341:7:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/scatterplot.R#L341) *style:* **Place a space before left parenthesis, except in a function call.**
```r
    if(!is.list(options$from)) options$from <- list(options$from)
      ^
```
[R/scatterplot.R:342:7:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/scatterplot.R#L342) *style:* **Place a space before left parenthesis, except in a function call.**
```r
    if(!is.list(options$to)) options$to <- list(options$to)
      ^
```
[R/scatterplot.R:346:9:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/scatterplot.R#L346) *style:* **Place a space before left parenthesis, except in a function call.**
```r
      if(length(a) == 1) a <- list(a)
        ^
```
[R/scatterplot.R:351:7:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/scatterplot.R#L351) *style:* **Place a space before left parenthesis, except in a function call.**
```r
    if(!("lwd" %in% names(options))) options$lwd <- 1L
      ^
```
[R/scatterplot.R:352:7:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/scatterplot.R#L352) *style:* **Place a space before left parenthesis, except in a function call.**
```r
    if("lcol" %in% names(options)) # discard alpha, normalize line colors
      ^
```
[R/scatterplot.R:359:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/scatterplot.R#L359) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if(length(options$from) != length(options$to)) stop("mismatched line from/to animation coordinates")
    ^
```
[R/scatterplot.R:361:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/scatterplot.R#L361) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if(N > 0) # not enough vertex positions, replicate as needed
    ^
```
[R/utilities.R:43:23:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/utilities.R#L43) *style:* **Commas should always have a space after.**
```r
  ext <- gsub(".*\\.","", data)
                      ^
```
[R/utilities.R:44:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/utilities.R#L44) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if(grepl("^http", data))
    ^
```
[R/utilities.R:53:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/utilities.R#L53) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if(nchar(ext) < 1) ext <- "png"
    ^
```
[R/utilities.R:61:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/utilities.R#L61) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if(isTRUE(a)) return(b)
    ^
```
[R/utilities.R:76:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/utilities.R#L76) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if("igraph" %in% class(g[[1]]))
    ^
```
[R/utilities.R:87:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/utilities.R#L87) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if("layout" %in% names(g)) layout <- g$layout
    ^
```
[R/utilities.R:88:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/utilities.R#L88) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if("vertex.color" %in% names(g))
    ^
```
[R/utilities.R:94:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/utilities.R#L94) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if("edge.color" %in% names(g)) lcol <- gcol(g$edge.color)$color
    ^
```
[R/utilities.R:96:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/utilities.R#L96) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if(!is.null(ans$cumulative) && !ans$cumulative) ans$cumulative <- NULL
    ^
```
[R/utilities.R:98:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/utilities.R#L98) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if(!("layout" %in% names(ans))) stop("missing layout")
    ^
```
[R/utilities.R:110:5:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/R/utilities.R#L110) *style:* **Place a space before left parenthesis, except in a function call.**
```r
  if(is.null(x)) return(list(color=NULL, alpha=NULL))
    ^
```
[tests/threejs.R:11:18:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/tests/threejs.R#L11) *style:* **Commas should always have a space after.**
```r
scatterplot3js(x,y,z, color=rainbow(length(z)))
                 ^
```
[tests/threejs.R:11:20:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/tests/threejs.R#L11) *style:* **Commas should always have a space after.**
```r
scatterplot3js(x,y,z, color=rainbow(length(z)))
                   ^
```
[tests/threejs.R:12:18:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/tests/threejs.R#L12) *style:* **Commas should always have a space after.**
```r
scatterplot3js(x,y,z, color=rainbow(length(z)), axisLabels=c("a", "b", "c"))
                 ^
```
[tests/threejs.R:12:20:](https://github.com/bwlewis/rthreejs/blob/03643383eadd5e21c7b77592d3cf6f46b8155333/tests/threejs.R#L12) *style:* **Commas should always have a space after.**
```r
scatterplot3js(x,y,z, color=rainbow(length(z)), axisLabels=c("a", "b", "c"))
                   ^
```