Files
VRCX/html/index.html
2019-08-16 22:53:04 +09:00

1722 lines
85 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<meta http-equiv="Cache-Control" content="no-cache">
<meta name="referrer" content="no-referrer">
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
<title>VRCX</title>
<link rel="dns-prefetch" href="https://fonts.gstatic.com">
<link rel="preconnect" href="https://api.vrchat.cloud">
<link rel="preconnect" href="https://d348imysud55la.cloudfront.net">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.7.2/animate.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/noty/3.2.0-beta/noty.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/element-ui/2.11.1/theme-chalk/index.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Noto+Sans+JP|Noto+Sans+KR&display=swap">
</head>
<body>
<div id="x-app" class="x-app" style="display:none">
<!-- login -->
<div v-show="!API.isLoggedIn" class="x-login-container">
<div style="width:300px;margin:auto">
<el-form ref="loginForm" :model="loginForm" :rules="loginForm.rules" v-loading="loginForm.loading" @submit.native.prevent="login()">
<el-form-item label="Username or Email" prop="username" required>
<el-input v-model="loginForm.username" name="username" placeholder="Username or Email" clearable></el-input>
</el-form-item>
<el-form-item label="Password" prop="password" required>
<el-input type="password" v-model="loginForm.password" name="password" placeholder="Password" clearable show-password></el-input>
</el-form-item>
<el-form-item style="margin-top:35px">
<el-button native-type="submit" type="primary" :loading="loginForm.loading" style="width:100%">Login</el-button>
</el-form-item>
<el-form-item>
<el-button :loading="loginForm.loading" style="width:100%" @click="loginWithSteam()">Login with Steam</el-button>
</el-form-item>
</el-form>
<div style="text-align:center;font-size:12px">
<p>&copy; 2019 <a href="https://github.com/pypy-vrc" target="_blank">pypy</a> (mina#5656)</p>
<p>VRCX is an assistant application for provide information about manage friendship. this application uses unofficial VRChat API (VRCSDK).</p>
<p>VRCX isn't endorsed by VRChat and doesn't reflect the views or opinions of VRChat or anyone officially involved in producing or managing VRChat. VRChat is trademark of VRChat Inc. VRChat © VRChat Inc.</p>
<p>pypy is not responsible for any problems caused by VRCX. Use at your own risk!</p>
</div>
</div>
</div>
<!-- menu -->
<div class="x-menu-container">
<el-menu ref="menu" collapse @select="selectMenu">
<el-menu-item index="feed">
<i class="el-icon-news"></i>
<template #title><span>Feed</span></template>
</el-menu-item>
<el-menu-item index="gameLog">
<i class="el-icon-s-data"></i>
<template #title>Game Log</span></template>
</el-menu-item>
<el-menu-item index="search">
<i class="el-icon-search"></i>
<template #title><span>Search</span></template>
</el-menu-item>
<el-menu-item index="favorite">
<i class="el-icon-star-off"></i>
<template #title><span>Favorite</span></template>
</el-menu-item>
<el-menu-item index="friendLog">
<i class="el-icon-notebook-2"></i>
<template #title><span>Friend Log</span></template>
</el-menu-item>
<el-menu-item index="moderation">
<i class="el-icon-finished"></i>
<template #title><span>Moderation</span></template>
</el-menu-item>
<el-menu-item index="notification">
<i class="el-icon-bell"></i>
<template #title><span>Notification</span></template>
</el-menu-item>
<el-menu-item index="more">
<i class="el-icon-s-tools"></i>
<template #title><span>More</span></template>
</el-menu-item>
</el-menu>
</div>
<!-- feed -->
<div v-show="$refs.menu && $refs.menu.activeIndex === 'feed'" class="x-container">
<data-tables v-bind="feedTable">
<template #tool>
<div style="margin:0 0 10px;display:flex;align-items:center">
<div style="flex:none;margin-right:10px">
<el-switch v-model="feedTable.filters[2].value" active-color="#13ce66"></el-switch>
</div>
<el-select v-model="feedTable.filters[0].value" multiple clearable collapse-tags style="flex:1" placeholder="Filter">
<el-option v-once v-for="type in ['GPS', 'Online', 'Offline', 'Status', 'Avatar']" :key="type" :label="type" :value="type"></el-option>
</el-select>
<el-input v-model="feedTable.filters[1].value" placeholder="Search" style="flex:none;width:150px;margin:0 10px"></el-input>
<el-button type="default" @click="clearFeed()" icon="el-icon-delete" circle style="flex:none"></el-button>
</div>
</template>
<el-table-column type="expand">
<template v-once #default="scope">
<div style="position:relative;font-size:14px">
<template v-if="scope.row.type === 'GPS'">
<location :location="scope.row.location[1]"></location>
<el-tag type="info" effect="plain" size="mini" style="margin-left:5px">{{ scope.row.time | timeToText }}</el-tag>
<br>
<span><i class="el-icon-right"></i></span>
<location :location="scope.row.location[0]"></location>
</template>
<template v-else-if="scope.row.type === 'Offline'">
<location :location="scope.row.location"></location>
<el-tag type="info" effect="plain" size="mini" style="margin-left:5px">{{ scope.row.time | timeToText }}</el-tag>
</template>
<template v-else-if="scope.row.type === 'Online'">
<location :location="scope.row.location"></location>
</template>
<template v-else-if="scope.row.type === 'Avatar'">
<el-popover placement="right" width="500px" trigger="click">
<img v-lazy="scope.row.avatar[1]" style="width:500px;height:375px">
<img slot="reference" v-lazy="scope.row.avatar[1]" class="x-link" style="flex:none;width:160px;height:120px;border-radius:4px">
</el-popover>
<span style="position:relative;top:-50px;margin:0 5px"><i class="el-icon-right"></i></span>
<el-popover placement="right" width="500px" trigger="click">
<img v-lazy="scope.row.avatar[0]" style="width:500px;height:375px">
<img slot="reference" v-lazy="scope.row.avatar[0]" class="x-link" style="flex:none;width:160px;height:120px;border-radius:4px">
</el-popover>
</template>
<template v-else-if="scope.row.type === 'Status'">
<el-tooltip placement="top">
<template #content>
<span v-if="scope.row.status[1].status === 'active'">Active</span>
<span v-else-if="scope.row.status[1].status === 'join me'">Join Me</span>
<span v-else-if="scope.row.status[1].status === 'busy'">Busy</span>
<span v-else>Offline</span>
</template>
<i class="x-user-status" :class="userStatusClass(scope.row.status[1])"></i>
</el-tooltip>
<span v-text="scope.row.status[1].statusDescription"></span>
<br>
<span><i class="el-icon-right"></i></span>
<el-tooltip placement="top">
<template #content>
<span v-if="scope.row.status[0].status === 'active'">Active</span>
<span v-else-if="scope.row.status[0].status === 'join me'">Join Me</span>
<span v-else-if="scope.row.status[0].status === 'busy'">Busy</span>
<span v-else>Offline</span>
</template>
<i class="x-user-status" :class="userStatusClass(scope.row.status[0])"></i>
</el-tooltip>
<span v-text="scope.row.status[0].statusDescription"></span>
</div>
</template>
</template>
</el-table-column>
<el-table-column label="Time" prop="created_at" sortable="custom" width="80">
<template v-once #default="scope">
<el-tooltip placement="right">
<template #content>
<span>{{ scope.row.created_at | formatDate('YYYY-MM-DD HH24:MI:SS') }}</span>
</template>
<span>{{ scope.row.created_at | formatDate('HH24:MI') }}</span>
</el-tooltip>
</template>
</el-table-column>
<el-table-column label="Type" prop="type" width="100"></el-table-column>
<el-table-column label="User" prop="displayName">
<template v-once #default="scope">
<span v-text="scope.row.displayName" @click="showUserDialog(scope.row.userId)" class="x-link"></span>
</template>
</el-table-column>
<el-table-column label="Detail">
<template v-once #default="scope">
<template v-if="scope.row.type === 'GPS'">
<location :location="scope.row.location[0]"></location>
</template>
<template v-else-if="scope.row.type === 'Offline' || scope.row.type === 'Online'">
<location :location="scope.row.location"></location>
</template>
<template v-else-if="scope.row.type === 'Status'">
<el-tooltip placement="top">
<template #content>
<span v-if="scope.row.status[0].status === 'active'">Active</span>
<span v-else-if="scope.row.status[0].status === 'join me'">Join Me</span>
<span v-else-if="scope.row.status[0].status === 'busy'">Busy</span>
<span v-else>Offline</span>
</template>
<i class="x-user-status" :class="userStatusClass(scope.row.status[0])"></i>
</el-tooltip>
<span v-text="scope.row.status[0].statusDescription"></span>
</template>
</template>
</el-table-column>
</data-tables>
</div>
<!-- gameLog -->
<div v-show="$refs.menu && $refs.menu.activeIndex === 'gameLog'" class="x-container">
<data-tables v-bind="gameLogTable">
<template #tool>
<div style="margin:0 0 10px;display:flex;align-items:center">
<el-select v-model="gameLogTable.filters[0].value" multiple clearable collapse-tags style="flex:1" placeholder="Filter">
<el-option v-once v-for="type in ['Location', 'OnPlayerJoined', 'OnPlayerLeft']" :key="type" :label="type" :value="type"></el-option>
</el-select>
<el-input v-model="gameLogTable.filters[1].value" placeholder="Search" style="flex:none;width:150px;margin:0 10px"></el-input>
<el-button type="default" @click="resetGameLog()" icon="el-icon-refresh" circle style="flex:none"></el-button>
</div>
</template>
<el-table-column label="Time" prop="created_at" sortable="custom" width="80">
<template v-once #default="scope">
<el-tooltip placement="right">
<template #content>
<span>{{ scope.row.created_at | formatDate('YYYY-MM-DD HH24:MI:SS') }}</span>
</template>
<span>{{ scope.row.created_at | formatDate('HH24:MI') }}</span>
</el-tooltip>
</template>
</el-table-column>
<el-table-column label="Type" prop="type" width="120"></el-table-column>
<el-table-column label="Detail">
<template v-once #default="scope">
<location v-if="scope.row.type === 'Location'" :location="scope.row.data"></location>
<span v-else v-text="scope.row.data" @click="lookupUser(scope.row.data)" class="x-link"></span>
</template>
</el-table-column>
</data-tables>
</div>
<!-- search -->
<div v-show="$refs.menu && $refs.menu.activeIndex === 'search'" class="x-container">
<div style="margin:0 0 10px;display:flex;align-items:center">
<el-input v-model="searchText" clearable placeholder="Search" @keyup.native.13="search()" style="flex:1"></el-input>
<el-button type="default" @click="clearSearch()" icon="el-icon-delete" circle style="flex:none;margin-left:10px"></el-button>
</div>
<el-tabs ref="searchTab" type="card" style="margin-top:15px">
<el-tab-pane label="User" v-loading="isSearchUserLoading" style="min-height:60px">
<div class="x-friend-list">
<div v-for="user in searchUsers" :key="user.id" @click="showUserDialog(user.id)" class="x-friend-item">
<template v-once>
<div class="avatar">
<img v-lazy="user.currentAvatarThumbnailImageUrl">
</div>
<div class="detail">
<span v-text="user.displayName" class="name"></span>
<span v-text="user.username" class="extra" style="font-family:monospace"></span>
</div>
</template>
</div>
</div>
<el-button-group style="margin-top:15px">
<el-button v-if="searchUserParam.offset" @click="moreSearchUser(-1)" icon="el-icon-back" size="small">Prev</el-button>
<el-button v-if="searchUsers.length" @click="moreSearchUser(1)" icon="el-icon-right" size="small">Next</el-button>
</el-button-group>
</el-tab-pane>
<el-tab-pane label="World" v-loading="isSearchWorldLoading" style="min-height:60px">
<el-dropdown @command="(command) => searchWorld(API.config.dynamicWorldRows[command])" size="small" trigger="click" style="margin-bottom:15px">
<el-button size="small">Search by Category <i class="el-icon-arrow-down el-icon--right"></i></el-button>
<el-dropdown-menu #default="dropdown">
<el-dropdown-item v-for="row in API.config.dynamicWorldRows" :key="row.index" v-text="row.name" :command="row.index"></el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<div class="x-friend-list">
<div v-for="world in searchWorlds" :key="world.id" @click="showWorldDialog(world.id)" class="x-friend-item">
<template v-once>
<div class="avatar">
<img v-lazy="world.thumbnailImageUrl">
</div>
<div class="detail">
<span v-text="world.name" class="name"></span>
<span v-if="world.occupants" class="extra">{{ world.authorName }} ({{ world.occupants }})</span>
<span v-else v-text="world.authorName" class="extra"></span>
</div>
</template>
</div>
</div>
<el-button-group style="margin-top:15px">
<el-button v-if="searchWorldParam.offset" @click="moreSearchWorld(-1)" icon="el-icon-back" size="small">Prev</el-button>
<el-button v-if="searchWorlds.length" @click="moreSearchWorld(1)" icon="el-icon-right" size="small">Next</el-button>
</el-button-group>
</el-tab-pane>
<el-tab-pane label="Avatar" v-loading="isSearchAvatarLoading" style="min-height:60px">
<el-dropdown @command="(command) => searchAvatar(command)" size="small" trigger="click" style="margin-bottom:15px">
<el-button size="small">Search by Category <i class="el-icon-arrow-down el-icon--right"></i></el-button>
<el-dropdown-menu #default="dropdown">
<el-dropdown-item command="updated">Updated Recently</el-dropdown-item>
<el-dropdown-item command="created">New</el-dropdown-item>
<el-dropdown-item command="mine">Mine</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<span style="margin-left:10px;font-size:12px;color:#909399">Avatar search is not possible.</span>
<div class="x-friend-list">
<div v-for="avatar in searchAvatars" :key="avatar.id" @click="showAvatarDialog(avatar.id)" class="x-friend-item">
<template v-once>
<div class="avatar">
<img v-lazy="avatar.thumbnailImageUrl">
</div>
<div class="detail">
<span v-text="avatar.name" class="name"></span>
<span v-text="avatar.authorName" class="extra"></span>
</div>
</template>
</div>
</div>
<el-button-group style="margin-top:15px">
<el-button v-if="searchAvatarParam.offset" @click="moreSearchAvatar(-1)" icon="el-icon-back" size="small">Prev</el-button>
<el-button v-if="searchAvatars.length" @click="moreSearchAvatar(1)" icon="el-icon-right" size="small">Next</el-button>
</el-button-group>
</el-tab-pane>
</el-tabs>
</div>
<!-- favorite -->
<div v-show="$refs.menu && $refs.menu.activeIndex === 'favorite'" class="x-container">
<el-button type="default" :loading="API.isFavoriteLoading" @click="API.refreshFavorite()" size="small" icon="el-icon-refresh" circle style="position:relative;float:right;z-index:1"></el-button>
<el-tabs type="card" v-loading="API.isFavoriteLoading">
<el-tab-pane label="Friend">
<el-collapse style="border:0">
<el-collapse-item v-for="group in API.favoriteFriendGroups" :key="group.name">
<template slot="title">
<span v-text="group.displayName" style="font-weight:bold;font-size:14px;margin-left:10px"></span>
<span style="color:#909399;font-size:12px;margin-left:10px">{{ group.count }}/{{ group.capacity }}</span>
<el-button @click.stop="changeFavoriteGroupName(group)" size="mini" icon="el-icon-edit" circle style="margin-left:10px"></el-button>
<el-button @click.stop="clearFavoriteGroup(group)" size="mini" icon="el-icon-delete" circle style="margin-left:5px"></el-button>
</template>
<div v-if="group.count" class="x-friend-list" style="margin-top:10px">
<div v-for="favorite in favoriteFriends" v-if="favorite.group === group.name" :key="favorite.id" @click="showUserDialog(favorite.id)" class="x-friend-item">
<template v-if="favorite.ref">
<div class="avatar" :class="userStatusClass(favorite.ref)">
<img v-lazy="favorite.ref.currentAvatarThumbnailImageUrl">
</div>
<div class="detail">
<span v-text="favorite.ref.displayName" class="name"></span>
<location v-if="favorite.ref.location !== 'offline'" :location="favorite.ref.location" :link="false" class="extra"></location>
<span v-else v-text="favorite.ref.statusDescription"></span>
</div>
</template>
<template v-else>
<span v-text="favorite.name || favorite.id"></span>
<el-button type="text" icon="el-icon-close" size="mini" @click.stop="deleteFavorite(favorite.id)" style="margin-left:5px"></el-button>
</template>
</div>
</div>
</el-collapse-item>
</el-collapse>
</el-tab-pane>
<el-tab-pane label="World">
<el-collapse style="border:0">
<el-collapse-item v-for="group in API.favoriteWorldGroups" :key="group.name">
<template slot="title">
<span v-text="group.displayName" style="font-weight:bold;font-size:14px;margin-left:10px"></span>
<span style="color:#909399;font-size:12px;margin-left:10px">{{ group.count }}/{{ group.capacity }}</span>
<el-button @click.stop="changeFavoriteGroupName(group)" size="mini" icon="el-icon-edit" circle style="margin-left:10px"></el-button>
<el-button @click.stop="clearFavoriteGroup(group)" size="mini" icon="el-icon-delete" circle style="margin-left:5px"></el-button>
</template>
<div v-if="group.count" class="x-friend-list" style="margin-top:10px">
<div v-for="favorite in favoriteWorlds" v-if="favorite.group === group.name" :key="favorite.id" @click="showWorldDialog(favorite.id)" class="x-friend-item">
<template v-if="favorite.ref">
<div class="avatar">
<img v-lazy="favorite.ref.thumbnailImageUrl">
</div>
<div class="detail">
<span v-text="favorite.ref.name" class="name"></span>
<span v-if="favorite.ref.occupants" class="extra">{{ favorite.ref.authorName }} ({{ favorite.ref.occupants }})</span>
<span v-else v-text="favorite.ref.authorName" class="extra"></span>
</div>
</template>
<template v-else>
<span v-text="favorite.name || favorite.id"></span>
<el-button type="text" icon="el-icon-close" size="mini" @click.stop="deleteFavorite(favorite.id)" style="margin-left:5px"></el-button>
</template>
</div>
</div>
</el-collapse-item>
</el-collapse>
</el-tab-pane>
<el-tab-pane label="Avatar">
<el-collapse style="border:0">
<el-collapse-item v-for="group in API.favoriteAvatarGroups" :key="group.name">
<template slot="title">
<span v-text="group.displayName" style="font-weight:bold;font-size:14px;margin-left:10px"></span>
<span style="color:#909399;font-size:12px;margin-left:10px">{{ group.count }}/{{ group.capacity }}</span>
<el-button @click.stop="changeFavoriteGroupName(group)" size="mini" icon="el-icon-edit" circle style="margin-left:10px"></el-button>
<el-button @click.stop="clearFavoriteGroup(group)" size="mini" icon="el-icon-delete" circle style="margin-left:5px"></el-button>
</template>
<div v-if="group.count" class="x-friend-list" style="margin-top:10px">
<div v-for="favorite in favoriteAvatars" v-if="favorite.group === group.name" :key="favorite.id" @click="showAvatarDialog(favorite.id)" class="x-friend-item">
<template v-if="favorite.ref">
<div class="avatar">
<img v-lazy="favorite.ref.thumbnailImageUrl">
</div>
<div class="detail">
<span v-text="favorite.ref.name" class="name"></span>
<span class="extra" v-text="favorite.ref.authorName"></span>
</div>
</template>
<template v-else>
<span v-text="favorite.name || favorite.id"></span>
<el-button type="text" icon="el-icon-close" size="mini" @click.stop="deleteFavorite(favorite.id)" style="margin-left:5px"></el-button>
</template>
</div>
</div>
</el-collapse-item>
</el-collapse>
</el-tab-pane>
</el-tabs>
</div>
<!-- friendLog -->
<div v-show="$refs.menu && $refs.menu.activeIndex === 'friendLog'" class="x-container">
<data-tables v-bind="friendLogTable">
<template #tool>
<div style="margin:0 0 10px;display:flex;align-items:center">
<el-select v-model="friendLogTable.filters[0].value" multiple clearable collapse-tags style="flex:1" placeholder="Filter">
<el-option v-once v-for="type in ['Friend', 'Unfriend', 'FriendRequest', 'CancelFriendRequest', 'DisplayName']" :key="type" :label="type" :value="type"></el-option>
</el-select>
<el-input v-model="friendLogTable.filters[1].value" placeholder="Search" style="flex:none;width:150px;margin-left:10px"></el-input>
</div>
</template>
<el-table-column label="Date" prop="created_at" sortable="custom" width="120">
<template v-once #default="scope">
<el-tooltip placement="right">
<template #content>
<span>{{ scope.row.created_at | formatDate('YYYY-MM-DD HH24:MI:SS') }}</span>
</template>
<span>{{ scope.row.created_at | formatDate('MM-DD HH24:MI') }}</span>
</el-tooltip>
</template>
</el-table-column>
<el-table-column label="Type" prop="type" width="150"></el-table-column>
<el-table-column label="User" prop="displayName">
<template v-once #default="scope">
<span v-if="scope.row.type === 'DisplayName'">{{ scope.row.previousDisplayName }}&nbsp;<i class="el-icon-right"></i>&nbsp;</span>
<span v-text="scope.row.displayName || scope.row.userId" @click="showUserDialog(scope.row.userId)" class="x-link"></span>
</template>
</el-table-column>
<el-table-column label="Action" width="80" align="right">
<template v-once #default="scope">
<el-button type="text" icon="el-icon-close" size="mini" @click="deleteFriendLog(scope.row)"></el-button>
</template>
</el-table-column>
</data-tables>
</div>
<!-- moderation -->
<div v-show="$refs.menu && $refs.menu.activeIndex === 'moderation'" class="x-container">
<data-tables v-bind="playerModerationTable" v-loading="API.isPlayerModerationLoading">
<template #tool>
<div style="margin:0 0 10px;display:flex;align-items:center">
<el-select v-model="playerModerationTable.filters[0].value" multiple clearable collapse-tags style="flex:1" placeholder="Filter">
<el-option v-once v-for="type in ['block', 'mute', 'unmute', 'hideAvatar', 'showAvatar']" :key="type" :label="type" :value="type"></el-option>
</el-select>
<el-input v-model="playerModerationTable.filters[1].value" placeholder="Search" style="flex:none;width:150px;margin:0 10px"></el-input>
<el-button type="default" :loading="API.isPlayerModerationLoading" @click="API.refreshPlayerModeration()" icon="el-icon-refresh" circle style="flex:none"></el-button>
</div>
</template>
<el-table-column label="Date" prop="created" sortable="custom" width="120">
<template v-once #default="scope">
<el-tooltip placement="right">
<template #content>
<span>{{ scope.row.created | formatDate('YYYY-MM-DD HH24:MI:SS') }}</span>
</template>
<span>{{ scope.row.created | formatDate('MM-DD HH24:MI') }}</span>
</el-tooltip>
</template>
</el-table-column>
<el-table-column label="Type" prop="type" width="120"></el-table-column>
<el-table-column label="Source" prop="sourceDisplayName">
<template v-once #default="scope">
<span v-text="scope.row.sourceDisplayName" @click="showUserDialog(scope.row.sourceUserId)" class="x-link"></span>
</template>
</el-table-column>
<el-table-column label="Target" prop="targetDisplayName">
<template v-once #default="scope">
<span v-text="scope.row.targetDisplayName" @click="showUserDialog(scope.row.targetUserId)" class="x-link"></span>
</template>
</el-table-column>
<el-table-column label="Action" width="80" align="right">
<template v-once #default="scope">
<el-button v-if="scope.row.sourceUserId === API.currentUser.id" type="text" icon="el-icon-close" size="mini" @click="deletePlayerModeration(scope.row)"></el-button>
</template>
</el-table-column>
</data-tables>
</div>
<!-- notification -->
<div v-show="$refs.menu && $refs.menu.activeIndex === 'notification'" v-loading="API.isNotificationLoading" class="x-container">
<data-tables v-bind="notificationTable">
<template #tool>
<div style="margin:0 0 10px;display:flex;align-items:center">
<el-select v-model="notificationTable.filters[0].value" multiple clearable collapse-tags style="flex:1" placeholder="Filter">
<el-option v-once v-for="type in ['requestInvite', 'invite', 'friendRequest', 'message']" :key="type" :label="type" :value="type"></el-option>
</el-select>
<el-input v-model="notificationTable.filters[1].value" placeholder="Search" style="flex:none;width:150px;margin:0 10px"></el-input>
<el-button type="default" :loading="API.isNotificationLoading" @click="API.refreshNotification()" icon="el-icon-refresh" circle style="flex:none"></el-button>
</div>
</template>
<el-table-column label="Date" prop="created_at" sortable="custom" width="120">
<template v-once #default="scope">
<el-tooltip placement="right">
<template #content>
<span>{{ scope.row.created_at | formatDate('YYYY-MM-DD HH24:MI:SS') }}</span>
</template>
<span>{{ scope.row.created_at | formatDate('MM-DD HH24:MI') }}</span>
</el-tooltip>
</template>
</el-table-column>
<el-table-column label="Type" prop="type" width="120">
<template v-once #default="scope">
<el-tooltip placement="top" v-if="scope.row.type === 'invite'">
<template #content>
<span v-text="parseInviteLocation(scope.row)"></span>
</template>
<span v-text="scope.row.type" @click="showWorldDialog(scope.row.details.worldId)" class="x-link"></span>
</el-tooltip>
<span v-else v-text="scope.row.type"></span>
</template>
</el-table-column>
<el-table-column label="User" prop="senderUsername">
<template v-once #default="scope">
<span v-text="scope.row.senderUsername" @click="showUserDialog(scope.row.senderUserId)" class="x-link"></span>
</template>
</el-table-column>
<el-table-column label="Action" width="80" align="right">
<template v-once #default="scope">
<el-button v-if="scope.row.type === 'friendRequest'" type="text" icon="el-icon-check" size="mini" @click="acceptNotification(scope.row)"></el-button>
<el-button type="text" icon="el-icon-close" size="mini" @click="hideNotification(scope.row)"></el-button>
</template>
</el-table-column>
</data-tables>
</div>
<!-- more -->
<div v-show="$refs.menu && $refs.menu.activeIndex === 'more'" class="x-container">
<div>
<span style="font-weight:bold">VRCX</span>
<div class="x-friend-list" style="margin-top:10px">
<div class="x-friend-item">
<div class="detail">
<span class="name">Version</span>
<span class="extra" v-text="appVersion"></span>
</div>
</div>
<div class="x-friend-item" @click="checkAppVersion()">
<div class="detail">
<span class="name">Latest Version</span>
<span class="extra" v-if="latestAppVersion" v-text="latestAppVersion"></span>
<span v-else class="extra">Click to refresh</span>
</div>
</div>
<div class="x-friend-item">
<div class="detail">
<span class="name">Repository URL</span>
<span class="extra">https://github.com/pypy-vrc/VRCX</span>
</div>
</div>
</div>
</div>
<div style="margin-top:30px">
<span style="font-weight:bold">Direct Access</span>
<div style="margin-top:5px">
<el-button-group>
<el-button size="small" @click="promptUserDialog()">User</el-button>
<el-button size="small" @click="promptWorldDialog()">World</el-button>
<el-button size="small" @click="promptAvatarDialog()">Avatar</el-button>
</el-button-group>
</div>
</div>
<div style="margin-top:30px">
<span style="font-weight:bold">My Profile</span>
<div class="x-friend-list" style="margin-top:10px">
<div class="x-friend-item" @click="showUserDialog(API.currentUser.id)">
<div class="avatar">
<img v-lazy="API.currentUser.currentAvatarThumbnailImageUrl">
</div>
<div class="detail">
<span class="name" v-text="API.currentUser.displayName"></span>
<span class="extra" v-text="API.currentUser.username"></span>
</div>
</div>
<div class="x-friend-item" @click="showSocialStatusDialog()">
<div class="detail">
<span class="name"><i class="el-icon-edit"></i> Social Status</span>
<span class="extra">
<el-tooltip placement="top">
<template #content>
<span v-if="API.currentUser.status === 'active'">Active</span>
<span v-else-if="API.currentUser.status === 'join me'">Join Me</span>
<span v-else-if="API.currentUser.status === 'busy'">Busy</span>
<span v-else>Offline</span>
</template>
<i class="x-user-status" :class="userStatusClass(API.currentUser)"></i>
</el-tooltip>
<span v-text="API.currentUser.statusDescription"></span>
</span>
</div>
</div>
<div class="x-friend-item">
<div class="detail">
<span class="name">Last Login</span>
<span class="extra">{{ API.currentUser.last_login | formatDate('YYYY-MM-DD HH24:MI:SS') }}</span>
</div>
</div>
<div class="x-friend-item">
<div class="detail">
<span class="name">Two-Factor Auth (2FA)</span>
<span class="extra">{{ API.currentUser.twoFactorAuthEnabled ? 'Enabled' : 'Disabled' }}</span>
</div>
</div>
<div class="x-friend-item" @click="showUserDialog(API.currentUser.id)">
<div class="detail">
<span class="name">User ID</span>
<span class="extra" v-text="API.currentUser.id"></span>
</div>
</div>
<div class="x-friend-item" @click="showAvatarDialog(API.currentUser.currentAvatar)">
<div class="detail">
<span class="name">Avatar ID</span>
<span class="extra" v-text="API.currentUser.currentAvatar"></span>
</div>
</div>
<div class="x-friend-item" v-if="API.currentUser.homeLocation" @click="showWorldDialog(API.currentUser.homeLocation)">
<div class="detail">
<span class="name">Home Location</span>
<span class="extra">
<location :location="API.currentUser.homeLocation" :link="false"></location>
<el-button @click.stop="resetHome()" size="mini" icon="el-icon-delete" circle style="margin-left:5px"></el-button>
</span>
</div>
</div>
</div>
<div style="margin-top:10px">
<el-button-group>
<el-button size="small" icon="el-icon-switch-button" @click="logout()">Logout</el-button>
</el-button-group>
</div>
</div>
<div style="margin-top:30px">
<span style="font-weight:bold">Past Display Names</span>
<data-tables v-bind="pastDisplayNameTable" style="margin-top:5px">
<el-table-column label="Date" prop="updated_at" sortable="custom">
<template v-once #default="scope">
<span>{{ scope.row.updated_at | formatDate('YYYY-MM-DD HH24:MI:SS') }}</span>
</template>
</el-table-column>
<el-table-column label="Name" prop="displayName"></el-table-column>
</data-tables>
</div>
<div style="margin-top:30px">
<span style="font-weight:bold">Game Info</span>
<div style="font-size:12px;margin-top:5px">
</div>
<div class="x-friend-list" style="margin-top:10px">
<div class="x-friend-item">
<div class="detail" @click="API.getVisits()">
<span class="name">Online Users</span>
<span v-if="visits" class="extra">{{visits}} Users online.</span>
<span v-else class="extra">Click to refresh</span>
</div>
</div>
<div class="x-friend-item">
<div class="detail">
<span class="name">SDK Unity Version</span>
<span class="extra" v-text="API.config.sdkUnityVersion"></span>
</div>
</div>
<div class="x-friend-item">
<div class="detail">
<span class="name">SDK Version</span>
<span class="extra" v-text="API.config.releaseSdkVersion"></span>
</div>
</div>
<div class="x-friend-item">
<div class="detail">
<span class="name">SDK URL</span>
<span class="extra" v-text="API.config.releaseSdkUrl"></span>
</div>
</div>
</div>
</div>
<div style="margin-top:30px">
<span style="font-weight:bold">Friends Sort Option</span>
<div style="font-size:12px;margin-top:5px">
<span style="display:inline-block;min-width:150px">VIP</span>
<el-switch v-model="orderFriendGroup0" inactive-text="by name" active-text="by state"></el-switch>
</div>
<div style="font-size:12px;margin-top:5px">
<span style="display:inline-block;min-width:150px">ONLINE</span>
<el-switch v-model="orderFriendGroup1" inactive-text="by name" active-text="by state"></el-switch>
</div>
<div style="font-size:12px;margin-top:5px">
<span style="display:inline-block;min-width:150px">ACTIVE</span>
<el-switch v-model="orderFriendGroup2" inactive-text="by name" active-text="by state"></el-switch>
</div>
<div style="font-size:12px;margin-top:5px">
<span style="display:inline-block;min-width:150px">OFFLINE</span>
<el-switch v-model="orderFriendGroup3" inactive-text="by name" active-text="by state"></el-switch>
</div>
</div>
<div style="margin-top:30px">
<span style="font-weight:bold">Discord Presence</span>
<div style="font-size:12px;margin-top:5px">
<span>* Only works when VRChat is running.</span>
</div>
<div style="font-size:12px;margin-top:5px">
<span style="display:inline-block;min-width:150px">Enable</span>
<el-switch v-model="discordActive"></el-switch>
</div>
<div style="font-size:12px;margin-top:5px">
<span style="display:inline-block;min-width:150px">Instance Details</span>
<el-switch v-model="discordInstance" :disabled="!discordActive"></el-switch>
</div>
</div>
<div style="margin-top:30px">
<span style="font-weight:bold">SteamVR Overlay</span>
<div style="font-size:12px;margin-top:5px">
<span>* It runs automatically when VRChat is running.</span><br>
<span>Vive or Other Controller: Grab Button</span><br>
<span>Oculus Controller: B Button</span><br>
</div>
<div style="font-size:12px;margin-top:5px">
<span style="display:inline-block;min-width:150px">Enable</span>
<el-switch v-model="openVR"></el-switch>
</div>
<div style="font-size:12px;margin-top:5px">
<span style="display:inline-block;min-width:150px">Force Run</span>
<el-switch v-model="openVRAlways"></el-switch>
</div>
</div>
<div style="margin-top:45px;border-top:1px solid #eee;padding-top:30px">
<span style="font-weight:bold">Legal Notice</span>
<div style="margin-top:5px;font-size:12px">
<p>&copy; 2019 <a href="https://github.com/pypy-vrc" target="_blank">pypy</a> (mina#5656)</p>
<p>VRCX is an assistant application for provide information about manage friendship. this application uses unofficial VRChat API (VRCSDK).</p>
<p>VRCX isn't endorsed by VRChat and doesn't reflect the views or opinions of VRChat or anyone officially involved in producing or managing VRChat. VRChat is trademark of VRChat Inc. VRChat © VRChat Inc.</p>
<p>pypy is not responsible for any problems caused by VRCX. Use at your own risk!</p>
</div>
<div style="margin-top:5px;font-size:12px">
<el-button @click="ossDialog = true" size="small">Open Source Software Notice</el-button>
</div>
</div>
</div>
<!-- friends -->
<div class="x-aside-container">
<el-select v-model="quickSearch" clearable placeholder="Search" filterable remote :remote-method="quickSearchRemoteMethod" popper-class="x-quick-search" @change="quickSearchChange" @visible-change="quickSearchVisibleChange" style="flex:none;padding:10px">
<el-option v-for="item in quickSearchItems" :key="item.value" :value="item.value" :label="item.label">
<div class="x-friend-item">
<template v-if="item.ref">
<div class="detail">
<span v-text="item.ref.displayName" class="name"></span>
<location :location="item.ref.location" :link="false" class="extra"></location>
</div>
<img v-lazy="item.ref.currentAvatarThumbnailImageUrl" class="avatar">
</template>
<span v-else>Search More: <span v-text="item.label" style="font-weight:bold"></span></span>
</div>
</el-option>
</el-select>
<div class="x-friend-list" style="padding-bottom:10px">
<div v-show="friendGroup0.length" class="x-friend-group">
<i class="el-icon-arrow-right" :class="{ rotate: isFriendGroup0 }"></i>
<span @click="isFriendGroup0 = !isFriendGroup0" class="x-link" style="margin-left:5px">VIP&horbar;{{ friendGroup0.length }}</span>
</div>
<div v-show="isFriendGroup0">
<div v-for="friend in friendGroup0" :key="friend.id" @click="showUserDialog(friend.id)" class="x-friend-item">
<template v-if="friend.ref">
<div class="avatar" :class="userStatusClass(friend.ref)">
<img v-lazy="friend.ref.currentAvatarThumbnailImageUrl">
</div>
<div class="detail">
<span v-text="friend.ref.displayName" class="name"></span>
<location :location="friend.ref.location" :link="false" class="extra"></location>
</div>
</template>
<template v-else>
<span v-text="friend.name || friend.id"></span>
<el-button type="text" icon="el-icon-close" size="mini" @click.stop="deleteFriend(friend.id)" style="margin-left:5px"></el-button>
</template>
</div>
</div>
<div v-show="friendGroup1.length" class="x-friend-group">
<i class="el-icon-arrow-right" :class="{ rotate: isFriendGroup1 }"></i>
<span @click="isFriendGroup1 = !isFriendGroup1" class="x-link" style="margin-left:5px">ONLINE&horbar;{{ friendGroup1.length }}</span>
</div>
<div v-show="isFriendGroup1">
<div v-for="friend in friendGroup1" :key="friend.id" @click="showUserDialog(friend.id)" class="x-friend-item">
<template v-if="friend.ref">
<div class="avatar" :class="userStatusClass(friend.ref)">
<img v-lazy="friend.ref.currentAvatarThumbnailImageUrl">
</div>
<div class="detail">
<span v-text="friend.ref.displayName" class="name"></span>
<location :location="friend.ref.location" :link="false" class="extra"></location>
</div>
</template>
<template v-else>
<span v-text="friend.name || friend.id"></span>
<el-button type="text" icon="el-icon-close" size="mini" @click.stop="deleteFriend(friend.id)" style="margin-left:5px"></el-button>
</template>
</div>
</div>
<div v-show="friendGroup2.length" class="x-friend-group">
<i class="el-icon-arrow-right" :class="{ rotate: isFriendGroup2 }"></i>
<span @click="isFriendGroup2 = !isFriendGroup2" class="x-link" style="margin-left:5px">ACTIVE&horbar;{{ friendGroup2.length }}</span>
</div>
<div v-show="isFriendGroup2">
<div v-for="friend in friendGroup2" :key="friend.id" @click="showUserDialog(friend.id)" class="x-friend-item">
<template v-if="friend.ref">
<div class="avatar">
<img v-lazy="friend.ref.currentAvatarThumbnailImageUrl">
</div>
<div class="detail">
<span v-text="friend.ref.displayName" class="name"></span>
<span v-text="friend.ref.statusDescription" :link="false" class="extra"></span>
</div>
</template>
<template v-else>
<span v-text="friend.name || friend.id"></span>
<el-button type="text" icon="el-icon-close" size="mini" @click.stop="deleteFriend(friend.id)" style="margin-left:5px"></el-button>
</template>
</div>
</div>
<div v-show="friendGroup3.length" class="x-friend-group">
<i class="el-icon-arrow-right" :class="{ rotate: isFriendGroup3 }"></i>
<span @click="isFriendGroup3 = !isFriendGroup3" class="x-link" style="margin-left:5px">OFFLINE&horbar;{{ friendGroup3.length }}</span>
</div>
<div v-show="isFriendGroup3">
<div v-for="friend in friendGroup3" :key="friend.id" @click="showUserDialog(friend.id)" class="x-friend-item">
<template v-if="friend.ref">
<div class="avatar">
<img v-lazy="friend.ref.currentAvatarThumbnailImageUrl">
</div>
<div class="detail">
<span v-text="friend.ref.displayName" class="name"></span>
<span v-text="friend.ref.statusDescription" class="extra"></span>
</div>
</template>
<template v-else>
<span v-text="friend.name || friend.id"></span>
<el-button type="text" icon="el-icon-close" size="mini" @click.stop="deleteFriend(friend.id)" style="margin-left:5px"></el-button>
</template>
</div>
</div>
</div>
</div>
<!-- dialog: user -->
<el-dialog ref="userDialog" :visible.sync="userDialog.visible" :show-close="false" width="600px" class="x-dialog x-user-dialog">
<div v-loading="userDialog.loading">
<div style="display:flex">
<el-popover placement="right" width="500px" trigger="click">
<img v-lazy="userDialog.ref.currentAvatarThumbnailImageUrl" style="width:500px;height:375px">
<img slot="reference" v-lazy="userDialog.ref.currentAvatarThumbnailImageUrl" class="x-link" style="flex:none;width:160px;height:120px;border-radius:4px">
</el-popover>
<div style="flex:1;display:flex;align-items:center;margin-left:15px">
<div style="flex:1">
<div>
<el-tooltip v-if="userDialog.ref.status" placement="top">
<template #content>
<span v-if="userDialog.ref.location === 'offline'">Offline</span>
<span v-else-if="userDialog.ref.status === 'active'">Active</span>
<span v-else-if="userDialog.ref.status === 'join me'">Join Me</span>
<span v-else-if="userDialog.ref.status === 'busy'">Busy</span>
<span v-else>Offline</span>
</template>
<i class="x-user-status" :class="userStatusClass(userDialog.ref)"></i>
</el-tooltip>
<span v-text="userDialog.ref.displayName" style="font-weight:bold"></span>
</div>
<div style="margin-top:5px">
<el-popover placement="top" trigger="click">
<span style="display:block;text-align:center;font-family:monospace">{{ userDialog.ref.username | textToHex }}</span>
<span slot="reference" v-text="userDialog.ref.username" style="color:#909399;font-family:monospace;cursor:pointer"></span>
</el-popover>
</div>
<div style="margin-top:5px">
<el-tag v-if="userDialog.ref.admin_" type="info" effect="plain" size="mini" class="x-tag-vip">VRChat Team</el-tag>
<el-tag v-else-if="userDialog.ref.trustLevel_ === 'Legendary User'" type="info" effect="plain" size="mini" class="x-tag-legendary">Legendary User</el-tag>
<el-tag v-else-if="userDialog.ref.trustLevel_ === 'Veteran User'" type="info" effect="plain" size="mini" class="x-tag-legend">Veteran User</el-tag>
<el-tag v-else-if="userDialog.ref.trustLevel_ === 'Trusted User'" type="info" effect="plain" size="mini" class="x-tag-veteran">Trusted User</el-tag>
<el-tag v-else-if="userDialog.ref.trustLevel_ === 'Known User'" type="info" effect="plain" size="mini" class="x-tag-trusted">Known User</el-tag>
<el-tag v-else-if="userDialog.ref.trustLevel_ === 'User'" type="info" effect="plain" size="mini" class="x-tag-known">User</el-tag>
<el-tag v-else-if="userDialog.ref.trustLevel_ === 'New User'" type="info" effect="plain" size="mini" class="x-tag-basic">New User</el-tag>
<el-tag v-else type="info" effect="plain" size="mini" class="x-tag-untrusted">Visitor</el-tag>
<el-tag v-if="userDialog.ref.troll_" type="info" effect="plain" size="mini" class="x-tag-troll">Nuisance</el-tag>
<el-tag v-if="userDialog.isFriend && userDialog.friend" type="info" effect="plain" size="mini" class="x-tag-friend">Friend No.{{userDialog.friend.no}}</el-tag>
</div>
<div style="margin-top:5px">
<span v-text="userDialog.ref.statusDescription" style="font-size:12px"></span>
</div>
</div>
<div style="flex:none;margin-left:10px">
<el-button v-if="userDialog.isFavorite" @click="userDialogCommand('Delete Favorite')" type="warning" icon="el-icon-star-on" circle></el-button>
<el-button v-else type="default" @click="userDialogCommand('Add Favorite')" icon="el-icon-star-off" circle></el-button>
<el-dropdown trigger="click" @command="userDialogCommand" size="small">
<el-button :type="(userDialog.incomingRequest || userDialog.outgoingRequest) ? 'success' : (userDialog.isBlock || userDialog.isMute || userDialog.isHideAvatar) ? 'danger' : 'default'" icon="el-icon-more" circle></el-button>
<el-dropdown-menu #default="dropdown">
<template v-if="userDialog.isFriend">
<el-dropdown-item icon="el-icon-message" command="Message">Message</el-dropdown-item>
<el-dropdown-item icon="el-icon-delete" command="Unfriend" divided>Unfriend</el-dropdown-item>
</template>
<template v-else-if="userDialog.incomingRequest">
<el-dropdown-item icon="el-icon-check" command="Accept Friend Request">Accept Friend Request</el-dropdown-item>
<el-dropdown-item icon="el-icon-close" command="Decline Friend Request">Decline Friend Request</el-dropdown-item>
</template>
<el-dropdown-item v-else-if="userDialog.outgoingRequest" icon="el-icon-close" command="Cancel Friend Request">Cancel Friend Request</el-dropdown-item>
<el-dropdown-item v-else icon="el-icon-plus" command="Send Friend Request">Send Friend Request</el-dropdown-item>
<el-dropdown-item v-if="userDialog.isBlock" icon="el-icon-circle-check" command="Unblock" divided>Unblock</el-dropdown-item>
<el-dropdown-item v-else icon="el-icon-circle-close" command="Block" divided>Block</el-dropdown-item>
<el-dropdown-item v-if="userDialog.isMute" icon="el-icon-microphone" command="Unmute">Unmute</el-dropdown-item>
<el-dropdown-item v-else icon="el-icon-turn-off-microphone" command="Mute">Mute</el-dropdown-item>
<el-dropdown-item v-if="userDialog.isHideAvatar" icon="el-icon-user-solid" command="Show Avatar">Show Avatar</el-dropdown-item>
<el-dropdown-item v-else icon="el-icon-user" command="Hide Avatar">Hide Avatar</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
</div>
<el-tabs>
<el-tab-pane label="Info">
<div v-if="userDialog.ref.location" style="display:flex;flex-direction:column;margin-bottom:10px;padding-bottom:10px;border-bottom:1px solid #eee">
<div style="flex:none">
<i class="el-icon-position"></i>
<location :location="userDialog.ref.location">
<template #default v-if="userDialog.instance.occupants"> ({{ userDialog.instance.occupants }})</template>
</location>
<launch :location="userDialog.ref.location" style="margin-left:5px"></launch>
</div>
<div class="x-friend-list" style="flex:1;margin-top:10px">
<div v-if="userDialog.location_.userId" @click="showUserDialog(userDialog.location_.userId)" class="x-friend-item">
<template v-if="userDialog.location_.user">
<div class="avatar">
<img v-lazy="userDialog.location_.user.currentAvatarThumbnailImageUrl">
</div>
<div class="detail">
<span v-text="userDialog.location_.user.displayName" class="name"></span>
<span class="extra">Instance Creator</span>
</div>
</template>
<span v-else v-text="userDialog.location_.userId"></span>
</div>
<div v-for="user in userDialog.users" :key="user.id" @click="showUserDialog(user.id)" class="x-friend-item">
<div class="avatar">
<img v-lazy="user.currentAvatarThumbnailImageUrl">
</div>
<div class="detail">
<span v-text="user.displayName" class="name"></span>
<span class="extra"><timer :epoch="user.location_at_"></timer></span>
</div>
</div>
</div>
</div>
<div class="x-friend-list" style="max-height:none">
<div class="x-friend-item">
<div class="detail">
<span class="name">Avatar Copying</span>
<span class="extra" v-if="userDialog.ref.allowAvatarCopying" style="color:#67C23A">Allow</span>
<span class="extra" v-else style="color:#F56C6C">Deny</span>
</div>
</div>
<div class="x-friend-item">
<div class="detail">
<span class="name">Last Login</span>
<span class="extra">{{ userDialog.ref.last_login | formatDate('YYYY-MM-DD HH24:MI:SS') || '-' }}</span>
</div>
</div>
<div class="x-friend-item">
<div class="detail">
<span class="name">Last Platform</span>
<span class="extra" v-text="userDialog.ref.last_platform"></span>
</div>
</div>
<div class="x-friend-item" style="width:100%">
<div class="detail">
<span class="name">ID</span>
<span class="extra" v-text="userDialog.ref.id"></span>
</div>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="Worlds">
<el-button type="default" :loading="userDialog.isWorldsLoading" @click="refreshUserDialogWorlds()" size="mini" icon="el-icon-refresh" circle></el-button>
<span style="margin-left:5px">Total {{ userDialog.worlds.length }}</span>
<div v-loading="userDialog.isWorldsLoading" class="x-friend-list" style="margin-top:10px;min-height:60px">
<div v-for="world in userDialog.worlds" :key="world.id" @click="showWorldDialog(world.id)" class="x-friend-item">
<div class="avatar">
<img v-lazy="world.thumbnailImageUrl">
</div>
<div class="detail">
<span v-text="world.name" class="name"></span>
<span v-if="world.occupants" class="extra">({{ world.occupants }})</span>
</div>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="Avatars">
<el-button type="default" :loading="userDialog.isAvatarsLoading" @click="refreshUserDialogAvatars()" size="mini" icon="el-icon-refresh" circle></el-button>
<span style="margin-left:5px">Total {{ userDialog.avatars.length }}</span>
<div v-loading="userDialog.isAvatarsLoading" class="x-friend-list" style="margin-top:10px;min-height:60px">
<div v-for="avatar in userDialog.avatars" :key="avatar.id" @click="showAvatarDialog(avatar.id)" class="x-friend-item">
<div class="avatar">
<img v-lazy="avatar.thumbnailImageUrl">
</div>
<div class="detail">
<span v-text="avatar.name" class="name"></span>
</div>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="JSON">
<el-button type="default" @click="refreshUserDialogTreeData()" size="mini" icon="el-icon-refresh" circle></el-button>
<el-tree :data="userDialog.treeData" style="margin-top:5px">
<template #default="scope">
<span>
<span v-text="scope.data.key" style="font-weight:bold;margin-right:5px"></span>
<span v-if="!scope.data.children" v-text="scope.data.value"></span>
</span>
</template>
</el-tree>
</el-tab-pane>
</el-tabs>
</div>
</el-dialog>
<!-- dialog: world -->
<el-dialog ref="worldDialog" :visible.sync="worldDialog.visible" :show-close="false" width="600px" class="x-dialog x-world-dialog">
<div v-loading="worldDialog.loading">
<div style="display:flex">
<el-popover placement="right" width="500px" trigger="click">
<img v-lazy="worldDialog.ref.thumbnailImageUrl" style="width:500px;height:375px">
<img slot="reference" v-lazy="worldDialog.ref.thumbnailImageUrl" class="x-link" style="flex:none;width:160px;height:120px;border-radius:4px">
</el-popover>
<div style="flex:1;display:flex;align-items:center;margin-left:15px">
<div style="flex:1">
<div>
<i class="el-icon-s-home" v-show="worldDialog.location_.worldId === API.currentUser.homeLocation"></i>
<span v-text="worldDialog.ref.name" style="font-weight:bold"></span>
</div>
<div style="margin-top:5px">
<span v-text="worldDialog.ref.authorName" @click="showUserDialog(worldDialog.ref.authorId)" class="x-link" style="color:#909399;font-family:monospace"></span>
</div>
<div style="margin-top:5px">
<el-tag v-if="worldDialog.ref.labs_" type="primary" effect="plain" size="mini">Labs</el-tag>
<el-tag v-else-if="worldDialog.ref.releaseStatus === 'public'" type="success" effect="plain" size="mini">Public</el-tag>
<el-tag v-else type="danger" effect="plain" size="mini">Private</el-tag>
<el-tag type="info" effect="plain" size="mini" v-text="worldDialog.fileSize"></el-tag>
</div>
<div style="margin-top:5px">
<span v-show="worldDialog.ref.name !== worldDialog.ref.description" v-text="worldDialog.ref.description" style="font-size:12px"></span>
</div>
</div>
<div style="flex:none;margin-left:10px">
<el-button v-if="worldDialog.isFavorite" type="warning" icon="el-icon-star-on" circle @click="worldDialogCommand('Delete Favorite')"></el-button>
<el-button v-else type="default" icon="el-icon-star-off" circle @click="worldDialogCommand('Add Favorite')"></el-button>
<el-dropdown trigger="click" @command="worldDialogCommand" size="small">
<el-button type="default" icon="el-icon-more" circle></el-button>
<el-dropdown-menu #default="dropdown">
<el-dropdown-item icon="el-icon-s-flag" command="New Instance">New Instance</el-dropdown-item>
<el-dropdown-item v-if="worldDialog.location_.worldId === API.currentUser.homeLocation" icon="el-icon-magic-stick" command="Reset Home" divided>Reset Home</el-dropdown-item>
<el-dropdown-item v-else icon="el-icon-s-home" command="Make Home" divided>Make Home</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
</div>
<el-tabs>
<el-tab-pane label="Instances">
<div style="margin-bottom:10px">
<i class="el-icon-user"></i> Public {{ worldDialog.ref.publicOccupants | commaNumber }}
<i class="el-icon-user-solid" style="margin-left:10px"></i> Private {{ worldDialog.ref.privateOccupants | commaNumber }}
<i class="el-icon-check" style="margin-left:10px"></i> Capacity {{ worldDialog.ref.capacity | commaNumber }}
</div>
<div v-for="room in worldDialog.rooms" :key="room.id">
<div>
<i class="el-icon-position"></i>
<span @click="showLaunchDialog(room.location_.tag)" class="x-link">#{{ room.location_.instanceName }} {{ room.location_.accessType }}<template v-if="room.occupants"> ({{ room.occupants }})</template></span>
</div>
<div class="x-friend-list" style="margin:10px 0">
<div v-if="room.location_.userId" @click="showUserDialog(room.location_.userId)" class="x-friend-item">
<template v-if="room.location_.user">
<div class="avatar">
<img v-lazy="room.location_.user.currentAvatarThumbnailImageUrl">
</div>
<div class="detail">
<span v-text="room.location_.user.displayName" class="name"></span>
<span class="extra">Instance Creator</span>
</div>
</template>
<span v-else v-text="room.location_.userId"></span>
</div>
<div v-for="user in room.users" :key="user.id" @click="showUserDialog(user.id)" class="x-friend-item">
<div class="avatar">
<img v-lazy="user.currentAvatarThumbnailImageUrl">
</div>
<div class="detail">
<span v-text="user.displayName" class="name"></span>
<span class="extra"><timer :epoch="user.location_at_"></timer></span>
</div>
</div>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="Info">
<div class="x-friend-list" style="max-height:none">
<div class="x-friend-item">
<div class="detail">
<span class="name">Players</span>
<span class="extra">{{ worldDialog.ref.occupants | commaNumber }}</span>
</div>
</div>
<div class="x-friend-item">
<div class="detail">
<span class="name">Favorites</span>
<span class="extra">{{ worldDialog.ref.favorites | commaNumber }}</span>
</div>
</div>
<div class="x-friend-item">
<div class="detail">
<span class="name">Visits</span>
<span class="extra">{{ worldDialog.ref.visits | commaNumber }}</span>
</div>
</div>
<div class="x-friend-item">
<div class="detail">
<span class="name">Capacity</span>
<span class="extra" v-text="worldDialog.ref.capacity"></span>
</div>
</div>
<div class="x-friend-item">
<div class="detail">
<span class="name">Heat</span>
<span class="extra">{{ worldDialog.ref.heat | commaNumber }} {{ '🔥'.repeat(worldDialog.ref.heat) }}</span>
</div>
</div>
<div class="x-friend-item">
<div class="detail">
<span class="name">Popularity</span>
<span class="extra">{{ worldDialog.ref.popularity | commaNumber }} {{ '💖'.repeat(worldDialog.ref.popularity) }}</span>
</div>
</div>
<div class="x-friend-item">
<div class="detail">
<span class="name">Created</span>
<span class="extra">{{ worldDialog.ref.created_at | formatDate('YYYY-MM-DD HH24:MI:SS') || '-' }}</span>
</div>
</div>
<div class="x-friend-item">
<div class="detail">
<span class="name">Last Updated</span>
<span class="extra">{{ worldDialog.fileCreatedAt | formatDate('YYYY-MM-DD HH24:MI:SS') || '-' }}</span>
</div>
</div>
<div class="x-friend-item">
<div class="detail">
<span class="name">Version</span>
<span class="extra" v-text="worldDialog.ref.version"></span>
</div>
</div>
<div class="x-friend-item" style="width:100%">
<div class="detail">
<span class="name">Platform</span>
<span class="extra" v-text="worldDialogPlatform"></span>
</div>
</div>
<div class="x-friend-item" style="width:100%">
<div class="detail">
<span class="name">ID</span>
<span class="extra" v-text="worldDialog.ref.id"></span>
</div>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="JSON">
<el-button type="default" @click="refreshWorldDialogTreeData()" size="mini" icon="el-icon-refresh" circle></el-button>
<el-tree :data="worldDialog.treeData" style="margin-top:5px">
<template #default="scope">
<span>
<span v-text="scope.data.key" style="font-weight:bold;margin-right:5px"></span>
<span v-if="!scope.data.children" v-text="scope.data.value"></span>
</span>
</template>
</el-tree>
</el-tab-pane>
</el-tabs>
</div>
</el-dialog>
<!-- dialog: avatar -->
<el-dialog ref="avatarDialog" :visible.sync="avatarDialog.visible" :show-close="false" width="600px" class="x-dialog x-avatar-dialog">
<div v-loading="avatarDialog.loading">
<div style="display:flex">
<el-popover placement="right" width="500px" trigger="click">
<img v-lazy="avatarDialog.ref.thumbnailImageUrl" style="width:500px;height:375px">
<img slot="reference" v-lazy="avatarDialog.ref.thumbnailImageUrl" class="x-link" style="flex:none;width:160px;height:120px;border-radius:4px">
</el-popover>
<div style="flex:1;display:flex;align-items:center;margin-left:15px">
<div style="flex:1">
<div>
<span v-text="avatarDialog.ref.name" style="font-weight:bold"></span>
</div>
<div style="margin-top:5px">
<span v-text="avatarDialog.ref.authorName" @click="showUserDialog(avatarDialog.ref.authorId)" class="x-link" style="color:#909399;font-family:monospace"></span>
</div>
<div style="margin-top:5px">
<el-tag v-if="avatarDialog.ref.releaseStatus === 'public'" type="success" effect="plain" size="mini">Public</el-tag>
<el-tag v-else type="danger" effect="plain" size="mini">Private</el-tag>
<el-tag type="info" effect="plain" size="mini" v-text="avatarDialog.fileSize"></el-tag>
</div>
<div style="margin-top:5px">
<span v-show="avatarDialog.ref.name !== avatarDialog.ref.description" v-text="avatarDialog.ref.description" style="font-size:12px"></span>
</div>
</div>
<div style="flex:none;margin-left:10px">
<el-button v-if="avatarDialog.isFavorite" type="warning" icon="el-icon-star-on" circle @click="avatarDialogCommand('Delete Favorite')"></el-button>
<el-button v-else type="default" icon="el-icon-star-off" circle @click="avatarDialogCommand('Add Favorite')"></el-button>
<el-dropdown trigger="click" @command="avatarDialogCommand" size="small">
<el-button type="default" icon="el-icon-more" circle></el-button>
<el-dropdown-menu #default="dropdown">
<el-dropdown-item icon="el-icon-check" command="Assign Avatar">Select Avatar</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
</div>
<el-tabs>
<el-tab-pane label="Info">
<div class="x-friend-list">
<div class="x-friend-item">
<div class="detail">
<span class="name">Created</span>
<span class="extra">{{ avatarDialog.ref.created_at | formatDate('YYYY-MM-DD HH24:MI:SS') || '-' }}</span>
</div>
</div>
<div class="x-friend-item">
<div class="detail">
<span class="name">Last Updated</span>
<span class="extra">{{ avatarDialog.fileCreatedAt | formatDate('YYYY-MM-DD HH24:MI:SS') || '-' }}</span>
</div>
</div>
<div class="x-friend-item">
<div class="detail">
<span class="name">Version</span>
<span class="extra" v-text="avatarDialog.ref.version"></span>
</div>
</div>
<div class="x-friend-item" style="width:100%">
<div class="detail">
<span class="name">Platform</span>
<span class="extra" v-text="avatarDialogPlatform"></span>
</div>
</div>
<div class="x-friend-item" style="width:100%">
<div class="detail">
<span class="name">ID</span>
<span class="extra" v-text="avatarDialog.ref.id"></span>
</div>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="JSON">
<el-button type="default" @click="refreshAvatarDialogTreeData()" size="mini" icon="el-icon-refresh" circle></el-button>
<el-tree :data="avatarDialog.treeData" style="margin-top:5px">
<template #default="scope">
<span>
<span v-text="scope.data.key" style="font-weight:bold;margin-right:5px"></span>
<span v-if="!scope.data.children" v-text="scope.data.value"></span>
</span>
</template>
</el-tree>
</el-tab-pane>
</el-tabs>
</div>
</el-dialog>
<!-- dialog: favorite -->
<el-dialog ref="favoriteDialog" :visible.sync="favoriteDialog.visible" title="Choose Group" width="250px" class="x-dialog">
<div v-loading="favoriteDialog.loading">
<el-button v-for="group in favoriteDialog.groups" :key="group.name" style="display:block;width:100%;margin:10px 0" @click="addFavorite(group)" :disabled="group.count >= group.capacity">{{ group.displayName }} ({{ group.count }} / {{ group.capacity }})</el-button>
</div>
</el-dialog>
<!-- dialog: invite -->
<el-dialog ref="inviteDialog" :visible.sync="inviteDialog.visible" title="Invite" width="450px" class="x-dialog">
<div v-loading="inviteDialog.loading">
<location :location="inviteDialog.worldId" :link="false"></location>
<el-select v-model="inviteDialog.userIds" multiple clearable placeholder="Choose Friends" filterable :disabled="inviteDialog.loading" style="width:100%;margin-top:15px">
<el-option-group v-if="friendGroup0.length" label="VIP">
<el-option v-for="friend in friendGroup0" :key="friend.id" :label="friend.name" :value="friend.id" class="x-friend-item" style="height:auto">
<template v-if="friend.ref">
<div class="avatar" :class="userStatusClass(friend.ref)">
<img v-lazy="friend.ref.currentAvatarThumbnailImageUrl">
</div>
<div class="detail">
<span v-text="friend.ref.displayName" class="name"></span>
</div>
</template>
<span v-else v-text="friend.id"></span>
</el-option>
</el-option-group>
<el-option-group v-if="friendGroup1.length" label="ONLINE">
<el-option v-for="friend in friendGroup1" :key="friend.id" :label="friend.name" :value="friend.id" class="x-friend-item" style="height:auto">
<template v-if="friend.ref">
<div class="avatar" :class="userStatusClass(friend.ref)">
<img v-lazy="friend.ref.currentAvatarThumbnailImageUrl">
</div>
<div class="detail">
<span v-text="friend.ref.displayName" class="name"></span>
</div>
</template>
<span v-else v-text="friend.id"></span>
</el-option>
</el-option-group>
<el-option-group v-if="friendGroup2.length" label="ACTIVE">
<el-option v-for="friend in friendGroup2" :key="friend.id" :label="friend.name" :value="friend.id" class="x-friend-item" style="height:auto">
<template v-if="friend.ref">
<div class="avatar">
<img v-lazy="friend.ref.currentAvatarThumbnailImageUrl">
</div>
<div class="detail">
<span v-text="friend.ref.displayName" class="name"></span>
</div>
</template>
<span v-else v-text="friend.id"></span>
</el-option>
</el-option-group>
</el-select>
</div>
<template #footer>
<el-button type="primary" size="small" :disabled="inviteDialog.loading || !inviteDialog.userIds.length" @click="sendInvite()">Invite</el-button>
</template>
</el-dialog>
<!-- dialog: social status -->
<el-dialog ref="socialStatusDialog" :visible.sync="socialStatusDialog.visible" title="Social Status" width="400px" class="x-dialog">
<el-row v-loading="socialStatusDialog.loading">
<el-col :span="9">
<el-select v-model="socialStatusDialog.status">
<el-option label="Active" value="active">
<i class="x-user-status active"></i> Active
</el-option>
<el-option label="Join Me" value="join me">
<i class="x-user-status joinme"></i> Join Me
</el-option>
<el-option label="Busy" value="busy">
<i class="x-user-status busy"></i> Busy
</el-option>
<el-option label="Offline" value="offline">
<i class="x-user-status offline"></i> Offline
</el-option>
</el-select>
</el-col>
<el-col :span="1">&nbsp;</el-col>
<el-col :span="14">
<el-input v-model="socialStatusDialog.statusDescription" placeholder="Status"></el-input>
</el-col>
</el-row>
<template #footer>
<el-button type="primary" size="small" :disabled="socialStatusDialog.loading" @click="saveSocialStatus">Update</el-button>
</template>
</el-dialog>
<!-- dialog: new instance -->
<el-dialog ref="newInstanceDialog" :visible.sync="newInstanceDialog.visible" title="New Instance" width="600px" class="x-dialog">
<el-form :model="newInstanceDialog" label-width="100px">
<el-form-item label="Access Type">
<el-radio-group v-model="newInstanceDialog.accessType" size="mini" @change="buildInstanceTag">
<el-radio-button label="public"></el-radio-button>
<el-radio-button label="friends+"></el-radio-button>
<el-radio-button label="friends"></el-radio-button>
<el-radio-button label="invite+"></el-radio-button>
<el-radio-button label="invite"></el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item label="World ID">
<el-input v-model="newInstanceDialog.worldId" size="mini" @click.native="$event.target.tagName === 'INPUT' && $event.target.select()"></el-input>
</el-form-item>
<el-form-item label="Instance ID">
<el-input v-model="newInstanceDialog.instanceId" size="mini" @click.native="$event.target.tagName === 'INPUT' && $event.target.select()"></el-input>
</el-form-item>
<el-form-item label="Location">
<el-input v-model="newInstanceDialog.location" size="mini" readonly @click.native="$event.target.tagName === 'INPUT' && $event.target.select()"></el-input>
</el-form-item>
<el-form-item label="URL">
<el-input ref="wtf" v-model="newInstanceDialog.url" size="mini" readonly @click.native="$event.target.tagName === 'INPUT' && $event.target.select()"></el-input>
</el-form-item>
</el-form>
<template #footer>
<el-button size="small" @click="makeHome(newInstanceDialog.location)">Make Home</el-button>
<el-button size="small" @click="showInviteDialog(newInstanceDialog.location)">Invite</el-button>
<el-button type="primary" size="small" @click="VRCX.StartGame(newInstanceDialog.location)">Launch</el-button>
</template>
</el-dialog>
<!-- dialog: open source software notice -->
<el-dialog :visible.sync="ossDialog" title="Open Source Software Notice" width="650px" class="x-dialog">
<div style="height:350px;overflow:hidden scroll;word-break:break-all">
<div>
<span>VRCX is based on open source software. It was possible because of their contribution.</span>
</div>
<div style="margin-top:15px">
<p style="font-weight:bold">animate.css</p>
<pre style="font-size:12px;white-space:pre-line">
The MIT License (MIT)
Copyright (c) 2019 Daniel Eden
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
</pre>
</div>
<div style="margin-top:15px">
<p style="font-weight:bold">CefSharp</p>
<pre style="font-size:12px;white-space:pre-line">
// Copyright © The CefSharp Authors. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// * Neither the name of Google Inc. nor the name Chromium Embedded
// Framework nor the name CefSharp nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</pre>
</div>
<div style="margin-top:15px">
<p style="font-weight:bold">DiscordRichPresence</p>
<pre style="font-size:12px;white-space:pre-line">
MIT License
Copyright (c) 2018 Lachee
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
</pre>
</div>
<div style="margin-top:15px">
<p style="font-weight:bold">element</p>
<pre style="font-size:12px;white-space:pre-line">
The MIT License (MIT)
Copyright (c) 2016-present ElemeFE
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
</pre>
</div>
<div style="margin-top:15px">
<p style="font-weight:bold">Newtonsoft.Json</p>
<pre style="font-size:12px;white-space:pre-line">
The MIT License (MIT)
Copyright (c) 2007 James Newton-King
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
</pre>
</div>
<div style="margin-top:15px">
<p style="font-weight:bold">normalize</p>
<pre style="font-size:12px;white-space:pre-line">
The MIT License (MIT)
Copyright © Nicolas Gallagher and Jonathan Neal
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
</pre>
</div>
<div style="margin-top:15px">
<p style="font-weight:bold">noty</p>
<pre style="font-size:12px;white-space:pre-line">
Copyright (c) 2012 Nedim Arabacı
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
</pre>
</div>
<div style="margin-top:15px">
<p style="font-weight:bold">OpenVR SDK</p>
<pre style="font-size:12px;white-space:pre-line">
Copyright (c) 2015, Valve Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</pre>
</div>
<div style="margin-top:15px">
<p style="font-weight:bold">SharpDX</p>
<pre style="font-size:12px;white-space:pre-line">
Copyright (c) 2010-2014 SharpDX - Alexandre Mutel
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
</pre>
</div>
<div style="margin-top:15px">
<p style="font-weight:bold">vue</p>
<pre style="font-size:12px;white-space:pre-line">
The MIT License (MIT)
Copyright (c) 2013-present, Yuxi (Evan) You
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
</pre>
</div>
<div style="margin-top:15px">
<p style="font-weight:bold">vue-data-tables</p>
<pre style="font-size:12px;white-space:pre-line">
The MIT License (MIT)
Copyright (c) 2018 Leon Zhang
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
</pre>
</div>
<div style="margin-top:15px">
<p style="font-weight:bold">vue-lazyload</p>
<pre style="font-size:12px;white-space:pre-line">
The MIT License (MIT)
Copyright (c) 2016 Awe
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
</pre>
</div>
</div>
</el-dialog>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/noty/3.2.0-beta/noty.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-lazyload/1.3.1/vue-lazyload.js"></script>
<script src="https://unpkg.com/vue-data-tables@3.4.4/dist/data-tables.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/element-ui/2.11.1/index.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/element-ui/2.11.1/locale/en.min.js"></script>
<script>
(() => {
var link = document.createElement('link');
link.rel = 'stylesheet';
link.href = `app.css?_=${Date.now()}`;
document.getElementsByTagName('head')[0].appendChild(link);
var script = document.createElement('script');
script.src = `app.js?_=${Date.now()}`;
document.getElementsByTagName('body')[0].appendChild(script);
})();
</script>
</body>
</html>