読者です 読者をやめる 読者になる 読者になる

tweeeetyのぶろぐ的めも

アウトプットが少なかったダメな自分をアウトプット<br>\(^o^)/

【go】golang環境でFailed parsing input: parser: bad import "syscall" というエラーが出るときのメモ

はじめに

golangを開発していて、go getコマンドなどでライブラリなどを入れた場合にこんなエラーが出ることがあります。

2017/01/16 14:00:33 go-app-builder: Failed parsing input: parser: bad import "syscall" in src/golang.org/x/tools/cmd/heapview/internal/core/mmapfile.go

原因

参考にしたサイトからそのまま引用させて頂きますが、以下のような場合に起こるらしいです。

GAE/Go では syscall や unsafe パッケージのインポートが許されていない。 たとえばプロジェクトルート以下に vendor ディレクトリを作っていて、 その下に置いたサードパーティ製のライブラリがこれら利用不可のパッケージを利用していた場合、 アプリケーションから利用していなくても開発サーバの起動やデプロイができなくなることになる。

go getコマンドでライブラリを入れたり、
自分の場合はvimでgo環境を整えるためにvim-go:GoInstallBinariesを行ったあとに起こりました。
※ direnvでGOPATHを変えてたからなど起こった原因は自分環境のせいではありますが...

対応方法

こちらも参考サイトに書かれていますが、
app.yamlnobuild_filesという項目を追記してbuild対象から外してやる事でエラーがでなくなりました。

nobuild_files:
    - src/gopkg.in
    - src/golang.org
    - src/github.com

参考似させて頂いたサイト

おわり

ちょっとしたことでハマると数時間あっというまですね\(^o^)/

【go】mac vimのGo開発環境を設定するメモ - mac x vim x vundle x go

はじめに

macでGo開発するときにvimの環境を整えるメモです。
vimでこんな感じの事ができるようになればいいやーくらいの感じです。

  • 補完
  • lint
  • 関数定義へジャンプ
  • ドキュメント(GoDocを開く)

アジェンダ

  1. GOPATH確認
  2. Vundleでvim-goの設定&インストール
  3. Vundleでvim-goの依存パッケージのインストール
  4. おもむろに動作確認(:GoFmt、補完、:GoRun)
  5. go-commandsメモ(:GoPath、:GoFmt、:GoDef、:GoDoc、:GoLint)

1. GOPATH確認

GOPATHを念のため確認します。

$ echo $GOPATH
/Users/hoge/.go

$ vim ~/.bashrc
---- vi追記 ----
export GOPATH=$HOME/.go
export PATH=$PATH:/usr/local/opt/go/libexec/bin
export PATH=$PATH:$GOPATH/bin
---------------

2. Vundleでvim-goの設定&インストール

vimvim-goの設定

~/.vimrcにVundleの設定を追記します。

$ vim ~/.vimrc
---- vim追記----
set nocompatible              " be iMproved, required
"filetype off                  " required

set rtp+=~/.vim/bundle/Vundle.vim/
call vundle#begin()

Plugin 'VundleVim/Vundle.vim'

" golangに関して以下2行を追記
Plugin 'fatih/vim-go'
Plugin 'nsf/gocode', {'rtp': 'vim/'}                                                                                                                                                                                                                                    

call vundle#end()            " required
filetype plugin indent on    " required
---------------

vim-goインストール

適当にVimを開いた状態で :PluginInstall コマンドを打って
追記したvim-goとgocodeをインストールします。

特に設定を変えていなければ~/.vim/bundle配下にインストールされた事が確認できます。

$ ls -l ~/.vim/bundle/
total 0
drwxr-xr-x  15 hoge  hoge   510 12 12 01:22 Vundle.vim
drwxr-xr-x  36 hoge  hoge  1224  1 16 15:14 gocode
drwxr-xr-x  13 hoge  hoge   442 12 12 01:25 nerdtree
drwxr-xr-x  23 hoge  hoge   782  1 16 15:14 vim-go

Vundle自体の設定についてはこちらをご参考まで。

3. Vundleでvim-goの依存パッケージのインストール

適当にvimを起動している状態で:GoInstallBinariesを打って依存パッケージをインストールします。
こんなコマンドまで用意されていて便利!!

コマンドを打つとxxx not foundな感じで、入っていない依存パッケージをチェックして勝手にインストールしてくれます。

vim-go: goimports not found. Installing golang.org/x/tools/cmd/goimports to folder /Users/hoge/.go/bin/
vim-go: guru not found. Installing golang.org/x/tools/cmd/guru to folder /Users/hoge/.go/bin/
vim-go: gorename not found. Installing golang.org/x/tools/cmd/gorename to folder /Users/hoge/.go/bin/
vim-go: golint not found. Installing github.com/golang/lint/golint to folder /Users/hoge/.go/bin/
vim-go: godef not found. Installing github.com/rogpeppe/godef to folder /Users/hoge/.go/bin/
vim-go: errcheck not found. Installing github.com/kisielk/errcheck to folder /Users/hoge/.go/bin/
vim-go: gotags not found. Installing github.com/jstemmer/gotags to folder /Users/hoge/.go/bin/
vim-go: asmfmt not found. Installing github.com/klauspost/asmfmt/cmd/asmfmt to folder /Users/hoge/.go/bin/
vim-go: motion not found. Installing github.com/fatih/motion to folder /Users/hoge/.go/bin/
vim-go: gogetdoc not found. Installing github.com/zmb3/gogetdoc to folder /Users/hoge/.go/bin/
vim-go: impl not found. Installing github.com/josharian/impl to folder /Users/hoge/.go/bin/

4. おもむろに動作確認

go-commandsが効く事をためす

適当なディレクトリに適当なgoファイルを作って試してみます。
まずは:GoFmt(整形してくれる君)を試します。

# homeディレクトリに適当なディレクトリ適当なgoファイルを作ってみる
$ pwd
/Users/hoge/

$ mkdir sample
$ touch sample.go

# 適当なインデントで書く
$ vim sample/sample.go
  • 新規作成時のファイル
package sample

import (
           "fmt"
)

func main() {
fmt.Print("test\n")
              fmt.Print("test\n")                                                                                                                                                                                                                                  
}
  • :GoFmt実行時 or :wで保存時に自動整形される
package main                                                                                                                                                                                                                                           

import (
  "fmt"
)

func main() {
  fmt.Print("test\n")
  fmt.Print("test\n")
}                                                                                                                                                                                                                          

補完を試す

fmt.Pまで打ってから<C-x><C-o>(Ctrlを押したままx,o)と打つとこんな感じで補完されます。

  • f:id:tweeeety:20170116232602p:plain
  • f:id:tweeeety:20170116232610p:plain

実行を試す

また、:GoRunと打ってみるとこのファイルを実行できます。
ただprintしているだけですが下記のように表示されますね。

Press ENTER or type command to continue
[No write since last change]
test
test

Press ENTER or type command to continue

5. go-commandsメモ(help、:GoPath、:GoFmt、:GoDef、:GoDoc、:GoLint)

おまけ的にいくつかのgo-commandsを書いておきます。

help

基本的にgo-commandsは以下の2つで探せばいろいろでてきます。 * vim-goリポジトリのREADMEを見る * vim開いてる状態で:help vim-goと打つ

README

https://github.com/fatih/vim-go

:help vim-go

こんな素敵な画面でhelpを見れます

f:id:tweeeety:20170116232649p:plain

以下のgo-commandは、簡単な説明との結果も合わせて貼っておきます。

:GoPath

説明

名前からもわかる通り、vimを開いたままGoPathを表示してくれます。
direnvなどでプロジェクトごとにGOPATHを切り替えてる場合は役立ちます。

:help vim-go 引用
:GoPath [path]
    
    GoPath sets and overrides GOPATH with the given {path}. If no {path} is  
    given it shows the current GOPATH. If "" is given as path, it clears
    current GOPATH which was set with :GoPath and restores GOPATH back
    to the initial value which was sourced when Vim was started.

:GoFmt

説明

ソースをよしなにGo形式にフォーマットしてくれます。

:help vim-go 引用
:GoFmt

    Filter the current Go buffer through gofmt.  It tries to preserve cursor
    position and avoids replacing the buffer with stderr output.

:GoDef

説明

ソース中の任意のwordにカーソルがある状態で:GoDefと打つと定義元のファイルに飛んでくれます。
vim側のコマンドの<C-o>で、元いたファイルに戻れます。便利!

また、:help vim-go引用にも記載されてる通り、
デフォルトでショートカットが割り当てられているのでgdと打つだけでも使えます。

:help vim-go 引用
:GoDef [identifier]
gd
CTRL-]

    Goto declaration/definition for the given [identifier]. If no argument is
    given, it will jump to the declaration under the cursor. By default the
    CTRL-] key and the mapping gd are enabled to invoke :GoDef for the
    identifier under the cursor. See 'g:go_def_mapping_enabled' to disable
    them.

    vim-go also keeps a per-window location stack, roughly analogous to how
    Vim's internal tags functionality works. This is pushed to every time a
    jump is made using the GoDef functionality. In essence, this is a LIFO
    list of file locations you have visited with :GoDef that is retained to
    help you navigate software.

:GoDoc

説明

ソース中の任意のwordにカーソルがある状態で:GoDefと打つと定義元のファイルに飛んでくれます。
vim側のコマンドの<C-o>でもといたファイルに戻れます。便利!

また、:help vim-go引用にデフォルトでショートカットも割り当てられているのでgdと打つだけでも使えます。

:help vim-go 引用
:GoDoc [word]

    Open the relevant GoDoc in split window for either the word[s] passed to
    the command or by default, the word under the cursor.

:GoLint

説明

vimで開いているファイルに対してlint(構文チェック)を通してくれます。
PASSと出ればOK、エラーの場合は表示してくれます。

:help vim-go 引用
:GoLint [packages]

    Run golint for the current Go file, or for given packages.

参考

以下のサイトを参考にさせて頂きました!thx! * VimでGoの開発環境を設定する方法のまとめ * vim-goをインストールしてみた(所要時間:15分) * MACで Go言語の開発環境(Go+Vundle+Vimgo+gocode)セットアップ

おわり

GoDocなんかはローカルサーバ立ち上げてみるのも良いですし、goはいろいろ用意されてて便利ですね!\(^o^)/

【vim】macにvimプラグインマネージャvundleをサクっと入れるメモ

はじめに

新しいPCになったタイミングなので改めてvimにvundle入れるメモです。
と、同時に他の記事に引用したかったので自分記事スニペット用。

ながれ

  1. NeoBundleは?
  2. Vundle.vimのインストール
  3. Vundle.vimの初期設定&反映
  4. pluginインストール
  5. インストールするpluginの指定方法
  6. vundleのコマンド

1. NeoBundleは?

NeoBundleも良かったのですが、しばらくSublimeAtomも使っていて少し経つうちにNeoBundle開発終わっちゃったんですね。。。。><

NeoBundle を利用する前に
NeoBundle を使い始めようとしている方は、VimとNeoVimのプラグインマネージャDein.vim を利用しましょう。NeoBundle の開発は終了しました。

ということで、NeoBundleはVundleベースですして基本に立ち返ってVundleに。

2. Vundle.vimのインストール

~/.vim あたりを指定してcloneしてくればインストールは終わりです。

$ git clone https://github.com/gmarik/Vundle.vim.git ~/.vim/bundle/Vundle.vim

インストールすると~/.vimディレクトリ配下に
bundleディレクトリが作成されます。入れたpluginたちもそこに入ります。
vundle自体もpluginなので確認するとVundle.vimというディレクトリが作成されてます。

$ tree ~/.vim/bundle -L 1
/Users/tweeeety/.vim/bundle
└── Vundle.vim

1 directory, 0 files

3. Vundle.vimの初期設定&反映

初期設定

初期設定として~/.vimrcにvundle用の設定をちょこっと追加します。
一旦の最低限であれば下記で良いでしょう。

"
" Vundle.vim
"
set nocompatible              " be iMproved, required
filetype off                  " required

set rtp+=~/.vim/bundle/Vundle.vim/
call vundle#begin()

Plugin 'VundleVim/Vundle.vim'

call vundle#end()            " required
filetype plugin indent on    " required

call vundle#begin()call vundle#end()の間に追加したいpluginを記述していく感じです。

反映

vimを開いている状態で設定ファイルを反映させます。

:source ~/.vimrc

一度閉じて開き直しても反映されるので閉じた場合は不要です。

4. pluginインストール

こちらも簡単です。vimを開いた状態でこれを打ってみましょう。

:PluginInstall

他のpluginも入れてみる

ただし、ここまでの状態だとすでにインストール済みのVundleVim/Vundle.vimが反映されるだけです。
せっかくなのでディレクトリをツリー表示できるプラグインNERDTreeを入れてみます。

.vimrcに下記を追記。:soure ~/.vimrcで設定を読み込んでから:PluginInstallでインストールします。

Plugin 'scrooloose/nerdtree'

しばらく画面が表示されてdoneとでれば終わりです。
f:id:tweeeety:20161212015528p:plain

参考

5. インストールするpluginの指定方法

インストールするプラグインはvimrcに
Plugin 'VundleVim/Vundle.vim' のように指定しましたが置かれている以下の場所によって3つの方法があります。

実際に書くとこんな感じ。

call vundle#begin()

" vim-scripts リポジトリ
Plugin "rails.vim"
 
" github の任意のリポジトリ
Plugin "tpope/vim-fugitive"
 
" github 以外のリポジトリ
Plugin "git://git.wincent.com/command-t.git"

call vundle#end()

これはまんま参考サイトを参考にさせていただきました。thx!!

参考

6. vundleのコマンド

最後はおまけ程度ですがvundleのコマンドです。:PluginInstallのたぐいですね。

コマンド 説明
PluginInstall プラグインのインストール
PluginUpdate プラグインのアップデート
PluginSearch プラグインの検索
PluginClean プラグインの削除。.vimrc上で指定を削除orコメントアウトしてから実行

終わり

しばらくAtom使ってましたがvimvimでいいですよね\(^o^)/

【vim】.vimrcの変更の読み込む - `-bash: syntax: command not found`な感じで.vimrcの読み込みで失敗するという恥ずかしいメモ

はじめに

vimの設定をぼやーといじっていて.vimrcを読み込もうとしたら
エラーが出て小一時間悩んだのですが凡ミス過ぎて恥ずかしいので思わずメモに残しました。

出るエラーと原因

エラーはこんなんです。

$ source ~/.vimrc
-bash: syntax: command not found
-bash: colorscheme: command not found
-bash: autocmd: command not found
-bash: autocmd: command not found

もう見たら一発なんですが、当たり前だけどbashじゃないからね!
. とか sourcebashコマンドに使うものですしね!
恥ずかしい...(ノД`)・゜・。

対応

ただの凡ミスなので対応というまでもないですが、vimrcの読み込みにはvimを開いているコマンドモード時にこう打ちます。

: source ~/.vimrc

おわり

あたりまえすぎて悲しす(ノД`)・゜・。

【Mac】dateコマンドでunixtime <=> 日時 文字列を相互に変換するメモ

はじめに

何らかのシステムに携わっているときって扱う日付がunixtimeな時多いですよね。

例えば下記のようなときにMacでささっと変換できたら便利だと思います。

  • unixtimeなシステムで、データ確認のために人間がわかる表示で日時を確認したい
  • unixtimeなシステムに、debugのために現在日付をunixtimeに変換して入れたい

そういうwebサイトもありますがわざわざ検索して開いて入力して変換して、、、
というのもあれですしそんな時に手元でささっと変換するメモ。

アジェンダ

  1. dateコマンドそのもの
  2. dateコマンドでunixtimeを日時文字列に変換する
  3. dateコマンドで日時文字列をunixtimeに変換する

1. dateコマンドそのもの

dateコマンドはそのまま打つとosの現在日時を表示してくれます。

$ date
2016年 11月28日 月曜日 14時04分39秒 JST

utc時刻を得たいときは-uオプションで表示できます。

# まんま表示
$ date
2016年 11月28日 月曜日 14時05分51秒 JST

# UTCで表示
$ date -u
2016年 11月28日 月曜日 05時05分51秒 UTC

また、1日前1日後もオプションで指定することで表示できます。

# 今
$ date
2016年 11月28日 月曜日 14時09分08秒 JST

# 1日後
$ date -v +1d
2016年 11月29日 火曜日 14時09分08秒 JST

# 1日前
$ date -v -1d
2016年 11月27日 日曜日 14時09分08秒 JST

dateコマンドではないですが、calと打てばカレンダーで前後の日付も確認できますね。

$ cal
     11月 2016
日 月 火 水 木 金 土
       1  2  3  4  5
 6  7  8  9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30

そしてunixtimeで表示したい場合は ``をつけます

$ date +%s
1480310097

2. dateコマンドでunixtimeを日時文字列に変換する

ということで本題です。

これは簡単で-rオプションに続けてunixtimeを指定すると人間がわかる日時の文字列に変換してくれます。

$ date +%s
1480310553

$ date -r 1480310553
2016年 11月28日 月曜日 14時22分33秒 JST

なんとなく見にくいという場合はフォーマットも指定できます。

$ date -r 1480310553 +"%Y/%m/%d %H:%M:%S"
2016/11/28 14:22:33

3. dateコマンドで日時文字列をunixtimeに変換する

日時文字列からunixtimeへの変換はプログラムなんかでもよくある形を使います。
日付文字列を指定しますが、合わせてマシンがその文字列を理解できるようにフォーマット文字列も添えてあげます。

# 日時文字列をunixtimeに変換する
$ date -j -f "%Y-%m-%d %H:%M:%S" "2016-11-28 14:22:33" "+%s"
1480310553

# 変換したunixtimeを戻してみる
$ date -r 1480310553
2016年 11月28日 月曜日 14時22分33秒 JST

-jオプションは詳細は、
PCの日付を変更してしまうので要注意と書いてあったりしますが権限がなければこんな感じでエラーになるので仮に忘れてもまぁ、、、

$ date -f "%Y-%m-%d %H:%M:%S" "2016-11-28 14:22:33" "+%s"
date: bind: Permission denied
date: settimeofday (timeval): Operation not permitted

まとめ

manを見ればわかりますがここまでで使ったオプションは下記のみです。

# `-u` : UTCで表示
$ date -u
2016年 11月28日 月曜日 05時05分51秒 UTC

# -v :-vに続けて`[+-](数値)(単位)`とすることで`n(単位)[前後]`を表示
# (例えば`n日前`とか)
$ date -v +1d
2016年 11月29日 火曜日 14時09分08秒 JST

# +%s : unixtimeを表示
$ date +%s
1480310097

# -r : -rに続けてunixitmeを指定
# フォーマットは`+"フォーマット文字列"`で
$ date -r 1480310553 +"%Y/%m/%d %H:%M:%S"
2016/11/28 14:22:33

# -j -f : -j -fに続けてフォーマット、日付文字列、+%s
$ date -j -f "%Y-%m-%d %H:%M:%S" "2016-11-28 14:22:33" "+%s"
1480310553

必要そうだったらフォーマットを毎回指定するのは面倒なのでaliasにしちゃってもよいかもしれませんね。

参考

おわり

書いたものの、コレ系は使う機会になるたびに調べてはを繰り返してるので
今後はここに来てさっと知りたい情報が得れれば自分的にはオッケーという自分めもでした

【Mac】macOSのバージョンをターミナル(terminal)で確認する

はじめに

タイトルのまんまですがあしからず。
これ他の記事でもついでに使ってたりするのに
いざversion出そうとするといっつも忘れちゃうので改めてこれだけ載せる自分メモ。

やる

おもむろに sw_vers と打つだけです。
software versionの略とかでしょうか。

$ sw_vers 
ProductName:  Mac OS X
ProductVersion: 10.9.5
BuildVersion: 13F1911

おまけ

あまりに載せる事がないのでおまけにmanでも載せておきます。

$ man sw_vers


SW_VERS(1)                BSD General Commands Manual               SW_VERS(1)

NAME
     sw_vers -- print Mac OS X operating system version information

SYNOPSIS
     sw_vers
     sw_vers -productName
     sw_vers -productVersion
     sw_vers -buildVersion

DESCRIPTION
     sw_vers prints version information about the Mac OS X or Mac OS X Server operating
     system running on the local machine.

     When executed with no options sw_vers prints a short list of version properties:

           % sw_vers
           ProductName:    Mac OS X
           ProductVersion: 10.3
           BuildVersion:   7A100

     The ProductName property provides the name of the operating system release (typi-
     cally either "Mac OS X" or "Mac OS X Server").  The ProductVersion property defines
     the version of the operating system release (for example, "10.2.4" or "10.3").  The
     BuildVersion property provides the specific revision of the operating system as gen-
     erated by the Mac OS X build system.

OPTIONS
     The output of sw_vers can be refined by the following options.

     -productName     Print just the value of the ProductName property.

     -productVersion  Print just the value of the ProductVersion property.

     -buildVersion    Print just the value of the BuildVersion property.

EXAMPLES
     % sw_vers -productName
     Mac OS X

     % sw_vers -productVersion
     10.3

     % sw_vers -buildVersion
     7A100

FILES
     /System/Library/CoreServices/SystemVersion.plist
     /System/Library/CoreServices/ServerVersion.plist

Mac OS X                        March 10, 2003                        Mac OS X
~
~

【vi】viやvimを一時停止してshellに戻る - からのviから抜けたシェルであることをわかりやすくする

はじめに

よくありがちかつ初歩的ですがviやvimからshellにもどって何かを実行したいときのメモ、
そしてviやvimからshellに戻ったことをわかりやすくしたいというメモです。

ながれ

  1. vi/vimからshellに戻る、shellからvimに戻る方法いくつか
  2. vi/vimからshellに戻っている中か確認する
  3. vi/vimからshellに戻っているコトをわかりやすくする

1. vi/vimからshellに戻る、shellからvimに戻る方法いくつか

いくつかと書いてますが大きく下記の2点があります。

  • :(コロン)コマンドで戻る
  • バックグラウンド/フォアグラウンドで戻る

:(コロン) コマンドで戻る

コマンドモード中に :shellまたは:shでshellに戻ることができます。
:shでshellに戻り、shellからviに戻りたい場合はexitを実行します。

次に説明するバックグラウンド/フォアグラウンドもありますが基本的にはこちらの方法のほうが良いかと思います。

バックグラウンド/フォアグラウンドで戻る

これはviに限った話しではありませんが、
ctrl + zで実行中のプログラムを一時停止することができます。
vi起動中にctrl + zでshellに戻り、shellからviに戻りたい場合はfgコマンドで戻ります。

ctrl + zで実行中のプログラムを一時停止し(バックグラウンド化し)できるのは
viだけでなく他のプログラムも複数可能なため、複数いる場合はjobsコマンドで確認してjob番号を指定します。

バックグラウンド/フォアグラウンドに関してはこちらをご参考に

2. vi/vimからshellに戻っている中か確認する

ここからは:shell:shで一時停止した場合のはなしです。

viからshellは前述の通りですが、shellからviの場合にexitを打ちますが
ときたまviからshellに戻ってない状態で打ってしまうとターミナル自体が終了してしまうことがあります。

ということで、exitを打つ前にviからshellに戻った状態かどうかを確認する方法です。
これはVIMまたはVIMRUNTIMEという環境変数を確認します。

通常時の(vimから戻るとか何もしてない)環境変数

何もしていない場合におもむろに打ってみると何も出力されません。

$ echo ${VIM}

$ echo ${VIMRUNTIME}
vimからshellに戻っている場合の環境変数

vimからshellに戻っている場合に環境変数を出力すると値が入っています。
これにより見分けます。

# 適当なファイルを開く
$ vi test.txt

# :sh コマンドでshellに戻る
$ echo ${VIM}
/usr/share/vim

$ echo ${VIMRUNTIME}
/usr/share/vim/vim73

3. vi/vimからshellに戻っているコトをわかりやすくする

こちらは下記のサイトを参考にさせて頂きました!thx!!
* vim から :shell で抜けたときにわかりやすくする

上記の変数を使ってシェルの設定を変更します。

ということで .bashrc に追加編集。
やることは簡単で変数があったときにシェルのプロンプトを変更してやります。

# .bashrcに追記します
[~ 00:06:50]$ vi ~/.bashrc
---- vi追記 ----
[[ -n "$VIMRUNTIME" ]] && \
    PS1='(VIM) \W \t $ '
---------------

# viから抜けてshellに戻った状態じゃないことを確認
[~ 00:06:57]$ echo $VIM

# 適当なファイルをviで開く
[~ 00:07:57]$ vi test.txt 

# :sh コマンドで抜ける 
(VIM) ~ 00:08:04 $ 

ということでviから抜けてshellに戻った場合は (VIM)という文字がつくようになりました。

おわり

抜けたときにわかりにくいんだよなーと思っていましたが思ったより簡単にできました。
参考にさせて頂いた記事さんありがとうございます\(^o^)/